Middleware Call Context
What a middleware receives. Contains:
params: the in-going call params, exactly as the upstream invoker constructed them. Middleware may modify and pass a new copy to doGenerate / doStream.
model: the wrapped LanguageModel (i.e., this middleware's enclosing wrapper). Exposed for metadata reads such as
model.modelId. Do NOT callmodel.generate(p)/model.stream(p)from inside a middleware — that re-enters the chain from the top and infinite-loops. Use doGenerate / doStream instead, which targets the rest of the chain past this middleware.doGenerate: invoke the downstream chain (the next middleware's
wrapGenerate, or the underlying model'sgenerateif this is the innermost middleware).doStream: invoke the downstream chain on the streaming axis.
Both doGenerate and doStream reference the SAME downstream depth — so a middleware's wrapStream calling context.doGenerate(...) skips its own wrapGenerate and invokes the rest of the chain's generate path. This is the load-bearing property that lets simulateStreamingMiddleware work.