* Run the final structured-output adapter call through the middleware * pipeline. Yields chunks to the caller only when * `this.finalStructuredOutput.yieldChunks` is true; otherwise consumes * silently while still piping through middleware. * * On success, populates this.structuredOut
()
| 1949 | * On failure, populates this.finalizationError. |
| 1950 | */ |
| 1951 | private async *runStructuredFinalization(): AsyncGenerator<StreamChunk> { |
| 1952 | if (!this.finalStructuredOutput) { |
| 1953 | throw new Error( |
| 1954 | 'runStructuredFinalization called without finalStructuredOutput config', |
| 1955 | ) |
| 1956 | } |
| 1957 | |
| 1958 | this.middlewareCtx.phase = 'structuredOutput' |
| 1959 | |
| 1960 | // Build the structured-output config view. `tools` is intentionally |
| 1961 | // excluded from the type because it isn't forwarded to the structured- |
| 1962 | // output adapter call — including it here would be misleading API. |
| 1963 | const baseConfig = this.buildMiddlewareConfig() |
| 1964 | const { tools: _omitTools, ...baseWithoutTools } = baseConfig |
| 1965 | let structuredConfig: StructuredOutputMiddlewareConfig = { |
| 1966 | ...baseWithoutTools, |
| 1967 | outputSchema: this.finalStructuredOutput.jsonSchema, |
| 1968 | } |
| 1969 | |
| 1970 | // 1) onStructuredOutputConfig — middleware can transform messages, options, outputSchema |
| 1971 | structuredConfig = await this.middlewareRunner.runOnStructuredOutputConfig( |
| 1972 | this.middlewareCtx, |
| 1973 | structuredConfig, |
| 1974 | ) |
| 1975 | |
| 1976 | // 2) onConfig — phase-aware general-purpose middleware re-runs at the |
| 1977 | // boundary. Re-attach the engine's current tools so onConfig observers |
| 1978 | // see the live tool set (they still won't be forwarded to the structured |
| 1979 | // call — same constraint applies — but the view is consistent with the |
| 1980 | // ChatMiddlewareConfig shape). |
| 1981 | const { outputSchema: pinnedSchema, ...chatConfigSlice } = structuredConfig |
| 1982 | const postOnConfig = await this.middlewareRunner.runOnConfig( |
| 1983 | this.middlewareCtx, |
| 1984 | { ...chatConfigSlice, tools: baseConfig.tools }, |
| 1985 | ) |
| 1986 | |
| 1987 | // Apply merged config back to engine state |
| 1988 | this.applyMiddlewareConfig(postOnConfig) |
| 1989 | |
| 1990 | // Build the StructuredOutputOptions the adapter expects. |
| 1991 | // `this.adapter` is already `TAdapter extends AnyTextAdapter` per the |
| 1992 | // class generics — no cast needed. |
| 1993 | const structuredCallOptions = { |
| 1994 | chatOptions: { |
| 1995 | model: this.params.model, |
| 1996 | messages: this.messages, |
| 1997 | metadata: postOnConfig.metadata, |
| 1998 | modelOptions: postOnConfig.modelOptions, |
| 1999 | systemPrompts: postOnConfig.systemPrompts, |
| 2000 | logger: this.logger, |
| 2001 | threadId: this.threadId, |
| 2002 | runId: this.runIdOverride, |
| 2003 | parentRunId: this.parentRunIdOverride, |
| 2004 | ...(this.effectiveRequest ? { request: this.effectiveRequest } : {}), |
| 2005 | }, |
| 2006 | outputSchema: pinnedSchema, |
| 2007 | } |
| 2008 |
no test coverage detected