@falai/agent 3.1.1 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.d.ts +2 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/providers/DeepSeekProvider.d.ts +7 -1
- package/dist/cjs/providers/DeepSeekProvider.d.ts.map +1 -1
- package/dist/cjs/providers/DeepSeekProvider.js +1 -0
- package/dist/cjs/providers/DeepSeekProvider.js.map +1 -1
- package/dist/cjs/providers/GeminiProvider.d.ts +8 -0
- package/dist/cjs/providers/GeminiProvider.d.ts.map +1 -1
- package/dist/cjs/providers/GeminiProvider.js +1 -0
- package/dist/cjs/providers/GeminiProvider.js.map +1 -1
- package/dist/cjs/providers/GenericOpenAICompatibleProvider.d.ts +6 -1
- package/dist/cjs/providers/GenericOpenAICompatibleProvider.d.ts.map +1 -1
- package/dist/cjs/providers/GenericOpenAICompatibleProvider.js +1 -0
- package/dist/cjs/providers/GenericOpenAICompatibleProvider.js.map +1 -1
- package/dist/cjs/providers/OpenAICompatibleProvider.d.ts +23 -0
- package/dist/cjs/providers/OpenAICompatibleProvider.d.ts.map +1 -1
- package/dist/cjs/providers/OpenAICompatibleProvider.js +1 -0
- package/dist/cjs/providers/OpenAICompatibleProvider.js.map +1 -1
- package/dist/cjs/providers/OpenRouterProvider.d.ts +9 -1
- package/dist/cjs/providers/OpenRouterProvider.d.ts.map +1 -1
- package/dist/cjs/providers/OpenRouterProvider.js +1 -0
- package/dist/cjs/providers/OpenRouterProvider.js.map +1 -1
- package/dist/cjs/providers/ProviderAdapter.d.ts +18 -1
- package/dist/cjs/providers/ProviderAdapter.d.ts.map +1 -1
- package/dist/cjs/providers/ProviderAdapter.js +22 -0
- package/dist/cjs/providers/ProviderAdapter.js.map +1 -1
- package/dist/cjs/providers/index.d.ts +1 -1
- package/dist/cjs/providers/index.d.ts.map +1 -1
- package/dist/cjs/providers/index.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/providers/DeepSeekProvider.d.ts +7 -1
- package/dist/providers/DeepSeekProvider.d.ts.map +1 -1
- package/dist/providers/DeepSeekProvider.js +1 -0
- package/dist/providers/DeepSeekProvider.js.map +1 -1
- package/dist/providers/GeminiProvider.d.ts +8 -0
- package/dist/providers/GeminiProvider.d.ts.map +1 -1
- package/dist/providers/GeminiProvider.js +1 -0
- package/dist/providers/GeminiProvider.js.map +1 -1
- package/dist/providers/GenericOpenAICompatibleProvider.d.ts +6 -1
- package/dist/providers/GenericOpenAICompatibleProvider.d.ts.map +1 -1
- package/dist/providers/GenericOpenAICompatibleProvider.js +1 -0
- package/dist/providers/GenericOpenAICompatibleProvider.js.map +1 -1
- package/dist/providers/OpenAICompatibleProvider.d.ts +23 -0
- package/dist/providers/OpenAICompatibleProvider.d.ts.map +1 -1
- package/dist/providers/OpenAICompatibleProvider.js +1 -0
- package/dist/providers/OpenAICompatibleProvider.js.map +1 -1
- package/dist/providers/OpenRouterProvider.d.ts +9 -1
- package/dist/providers/OpenRouterProvider.d.ts.map +1 -1
- package/dist/providers/OpenRouterProvider.js +1 -0
- package/dist/providers/OpenRouterProvider.js.map +1 -1
- package/dist/providers/ProviderAdapter.d.ts +18 -1
- package/dist/providers/ProviderAdapter.d.ts.map +1 -1
- package/dist/providers/ProviderAdapter.js +23 -1
- package/dist/providers/ProviderAdapter.js.map +1 -1
- package/dist/providers/index.d.ts +1 -1
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js.map +1 -1
- package/docs/reference/providers.md +39 -0
- package/package.json +2 -2
- package/src/index.ts +4 -0
- package/src/providers/DeepSeekProvider.ts +8 -1
- package/src/providers/GeminiProvider.ts +9 -0
- package/src/providers/GenericOpenAICompatibleProvider.ts +7 -0
- package/src/providers/OpenAICompatibleProvider.ts +25 -0
- package/src/providers/OpenRouterProvider.ts +10 -1
- package/src/providers/ProviderAdapter.ts +26 -0
- package/src/providers/index.ts +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GeminiProvider.d.ts","sourceRoot":"","sources":["../../src/providers/GeminiProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE3E,MAAM,WAAW,qBAAqB;IACpC,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,4CAA4C;IAC5C,WAAW,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD;gFAC4E;IAC5E,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED,qBAAa,cAAe,SAAQ,eAAe;IACjD,SAAgB,IAAI,YAAY;IAChC,SAAgB,YAAY,EAAE,oBAAoB,CAMhD;gBAEU,OAAO,EAAE,qBAAqB;
|
|
1
|
+
{"version":3,"file":"GeminiProvider.d.ts","sourceRoot":"","sources":["../../src/providers/GeminiProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE3E,MAAM,WAAW,qBAAqB;IACpC,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,4CAA4C;IAC5C,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,4CAA4C;IAC5C,WAAW,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD;gFAC4E;IAC5E,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED,qBAAa,cAAe,SAAQ,eAAe;IACjD,SAAgB,IAAI,YAAY;IAChC,SAAgB,YAAY,EAAE,oBAAoB,CAMhD;gBAEU,OAAO,EAAE,qBAAqB;CAuB3C"}
|
|
@@ -24,6 +24,7 @@ export class GeminiProvider extends ProviderAdapter {
|
|
|
24
24
|
model: options.model,
|
|
25
25
|
id: "gemini",
|
|
26
26
|
...(options.baseUrl ? { baseUrl: options.baseUrl } : {}),
|
|
27
|
+
...(options.jsonWithTools ? { jsonWithTools: options.jsonWithTools } : {}),
|
|
27
28
|
...(options.config?.maxTokens ? { maxTokens: options.config.maxTokens } : {}),
|
|
28
29
|
...(options.config?.effort ? { effort: options.config.effort } : {}),
|
|
29
30
|
...(options.fetchImpl ? { fetchImpl: options.fetchImpl } : {}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GeminiProvider.js","sourceRoot":"","sources":["../../src/providers/GeminiProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"GeminiProvider.js","sourceRoot":"","sources":["../../src/providers/GeminiProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAIzD,OAAO,EAAE,eAAe,EAAsB,MAAM,sBAAsB,CAAC;AA2B3E,MAAM,OAAO,cAAe,SAAQ,eAAe;IAUjD,YAAY,OAA8B;QACxC,IAAI,CAAC,OAAO,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QACnE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;QAC1E,CAAC;QAED,KAAK,CAAC;YACJ,QAAQ,EAAE,oBAAoB,CAAC;gBAC7B,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,EAAE,EAAE,QAAQ;gBACZ,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACxD,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC1E,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7E,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACpE,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC/D,CAAC;YACF,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvD,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvE,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACrE,CAAC,CAAC;QA9BW,SAAI,GAAG,QAAQ,CAAC;QAChB,iBAAY,GAAyB;YACnD,aAAa,EAAE,IAAI;YACnB,wBAAwB,EAAE,IAAI;YAC9B,iBAAiB,EAAE,IAAI;YACvB,0BAA0B,EAAE,IAAI;YAChC,qBAAqB,EAAE,IAAI;SAC5B,CAAC;IAwBF,CAAC;CACF"}
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* provider classes.
|
|
27
27
|
*/
|
|
28
28
|
import type { ProviderCapabilities } from "../types/ai.js";
|
|
29
|
-
import { OpenAICompatibleProvider, type StructuredOutputMode } from "./OpenAICompatibleProvider.js";
|
|
29
|
+
import { OpenAICompatibleProvider, type JsonWithTools, type StructuredOutputMode } from "./OpenAICompatibleProvider.js";
|
|
30
30
|
import type { RequestConfig } from "./ProviderAdapter.js";
|
|
31
31
|
export interface OpenAICompatibleOptions {
|
|
32
32
|
/** Provider identifier, e.g. "azure", "ollama", "groq". */
|
|
@@ -49,6 +49,11 @@ export interface OpenAICompatibleOptions {
|
|
|
49
49
|
* is OpenAI-only). See {@link StructuredOutputMode}.
|
|
50
50
|
*/
|
|
51
51
|
structuredOutput?: StructuredOutputMode;
|
|
52
|
+
/**
|
|
53
|
+
* See {@link JsonWithTools}. Only affects calls that carry tools, and the
|
|
54
|
+
* answer is the model's, not the endpoint's — measure the one you serve.
|
|
55
|
+
*/
|
|
56
|
+
jsonWithTools?: JsonWithTools;
|
|
52
57
|
/** Default request parameters merged into every call. */
|
|
53
58
|
config?: RequestConfig;
|
|
54
59
|
/** Idle-stream deadline (ms) and retry count. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GenericOpenAICompatibleProvider.d.ts","sourceRoot":"","sources":["../../src/providers/GenericOpenAICompatibleProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EACL,wBAAwB,EACxB,KAAK,oBAAoB,EAC1B,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,WAAW,uBAAuB;IACtC,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,gFAAgF;IAChF,YAAY,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC7C,+EAA+E;IAC/E,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,oBAAoB,CAAC;IACxC,yDAAyD;IACzD,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,iDAAiD;IACjD,WAAW,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,2DAA2D;IAC3D,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;
|
|
1
|
+
{"version":3,"file":"GenericOpenAICompatibleProvider.d.ts","sourceRoot":"","sources":["../../src/providers/GenericOpenAICompatibleProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EACL,wBAAwB,EACxB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EAC1B,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,WAAW,uBAAuB;IACtC,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,gFAAgF;IAChF,YAAY,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC7C,+EAA+E;IAC/E,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,oBAAoB,CAAC;IACxC;;;OAGG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,yDAAyD;IACzD,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,iDAAiD;IACjD,WAAW,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,2DAA2D;IAC3D,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AA2DD;;;;GAIG;AACH,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,uBAAuB,GAC/B,wBAAwB,CAE1B"}
|
|
@@ -63,6 +63,7 @@ class GenericOpenAICompatibleProvider extends OpenAICompatibleProvider {
|
|
|
63
63
|
// Arbitrary compatible endpoints rarely serve the Responses API; default
|
|
64
64
|
// to the broadly-supported chat json_schema strategy.
|
|
65
65
|
structuredOutput: options.structuredOutput ?? "json_schema",
|
|
66
|
+
...(options.jsonWithTools ? { jsonWithTools: options.jsonWithTools } : {}),
|
|
66
67
|
...(options.defaultHeaders ? { headers: options.defaultHeaders } : {}),
|
|
67
68
|
...(options.backupModels ? { backupModels: options.backupModels } : {}),
|
|
68
69
|
...(options.config ? { config: options.config } : {}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GenericOpenAICompatibleProvider.js","sourceRoot":"","sources":["../../src/providers/GenericOpenAICompatibleProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,EACL,wBAAwB,
|
|
1
|
+
{"version":3,"file":"GenericOpenAICompatibleProvider.js","sourceRoot":"","sources":["../../src/providers/GenericOpenAICompatibleProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,EACL,wBAAwB,GAGzB,MAAM,+BAA+B,CAAC;AAqCvC,iEAAiE;AACjE,MAAM,oBAAoB,GAAyB;IACjD,aAAa,EAAE,IAAI;IACnB,wBAAwB,EAAE,IAAI;IAC9B,iBAAiB,EAAE,IAAI;IACvB,0BAA0B,EAAE,IAAI;IAChC,qBAAqB,EAAE,KAAK;CAC7B,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,+BAAgC,SAAQ,wBAAwB;IAIpE,YAAY,OAAgC;QAC1C,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,8BAA8B,CAAC,CAAC;QAClE,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CACb,IAAI,OAAO,CAAC,IAAI,oFAAoF,CACrG,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,4BAA4B,CAAC,CAAC;QAChE,CAAC;QAED,KAAK,CAAC;YACJ,EAAE,EAAE,OAAO,CAAC,IAAI;YAChB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,yEAAyE;YACzE,sDAAsD;YACtD,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,aAAa;YAC3D,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1E,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACtE,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvE,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrD,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACpE,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC/D,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,YAAY,GAAG,EAAE,GAAG,oBAAoB,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAC3E,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,UAAU,8BAA8B,CAC5C,OAAgC;IAEhC,OAAO,IAAI,+BAA+B,CAAC,OAAO,CAAC,CAAC;AACtD,CAAC"}
|
|
@@ -18,6 +18,27 @@ import { ProviderAdapter, type ProviderAdapterInit, type RequestConfig } from ".
|
|
|
18
18
|
* no schema enforcement at all. The caller validates.
|
|
19
19
|
*/
|
|
20
20
|
export type StructuredOutputMode = "responses_parse" | "json_schema" | "json_object";
|
|
21
|
+
/**
|
|
22
|
+
* How the schema rides on a call that ALSO carries tools — the one turn shape
|
|
23
|
+
* an agent makes constantly and a provider seam cannot get right by itself.
|
|
24
|
+
*
|
|
25
|
+
* `"response_format"` sends both, which every shape documents and most models
|
|
26
|
+
* honour. `"prompt"` leaves the response format off those calls and sends the
|
|
27
|
+
* schema as prompt instead.
|
|
28
|
+
*
|
|
29
|
+
* Set it to `"prompt"` when the model answers a tool-worthy turn by NARRATING
|
|
30
|
+
* the tool — "let me look that up for you" — and then stopping. That is not a
|
|
31
|
+
* model without initiative: its decoder is pinned to the schema, so the tool
|
|
32
|
+
* call has nowhere to go, and no instruction can make it emit one. Nothing is
|
|
33
|
+
* logged, because from the wire's point of view nothing failed.
|
|
34
|
+
*
|
|
35
|
+
* Measured 2026-09-07, one request, sampled: `z-ai/glm-5.3-flash` called its
|
|
36
|
+
* tool 0/10 under a response format and 8/8 without one, `deepseek-v4-flash`
|
|
37
|
+
* 0/5, `gemini-3.8-flash` 3/10. It stays a setting rather than a default
|
|
38
|
+
* because the reverse is just as real — `qwen3.8-flash` went 10/10 → 1/6 the
|
|
39
|
+
* other way. Measure the model you ship; one call answers it.
|
|
40
|
+
*/
|
|
41
|
+
export type JsonWithTools = "response_format" | "prompt";
|
|
21
42
|
export interface OpenAICompatibleProviderInit extends Omit<ProviderAdapterInit, "provider"> {
|
|
22
43
|
apiKey: string;
|
|
23
44
|
baseUrl?: string;
|
|
@@ -26,6 +47,8 @@ export interface OpenAICompatibleProviderInit extends Omit<ProviderAdapterInit,
|
|
|
26
47
|
headers?: Record<string, string>;
|
|
27
48
|
config?: RequestConfig;
|
|
28
49
|
structuredOutput?: StructuredOutputMode;
|
|
50
|
+
/** See {@link JsonWithTools}. Only affects calls that carry tools. */
|
|
51
|
+
jsonWithTools?: JsonWithTools;
|
|
29
52
|
/** OpenRouter upstream-host pin, to keep a conversation's prompt cache warm. */
|
|
30
53
|
providerOrder?: string[];
|
|
31
54
|
/** Replacement `fetch`, for tests that script the wire. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OpenAICompatibleProvider.d.ts","sourceRoot":"","sources":["../../src/providers/OpenAICompatibleProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,eAAe,EAAE,KAAK,mBAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErG;;;;;;;;GAQG;AACH,MAAM,MAAM,oBAAoB,GAAG,iBAAiB,GAAG,aAAa,GAAG,aAAa,CAAC;AAErF,MAAM,WAAW,4BACf,SAAQ,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,gBAAgB,CAAC,EAAE,oBAAoB,CAAC;IACxC,gFAAgF;IAChF,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED,8BAAsB,wBAAyB,SAAQ,eAAe;IACpE,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;IAE1C,SAAS,aAAa,IAAI,EAAE,4BAA4B;CAWzD"}
|
|
1
|
+
{"version":3,"file":"OpenAICompatibleProvider.d.ts","sourceRoot":"","sources":["../../src/providers/OpenAICompatibleProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,eAAe,EAAE,KAAK,mBAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErG;;;;;;;;GAQG;AACH,MAAM,MAAM,oBAAoB,GAAG,iBAAiB,GAAG,aAAa,GAAG,aAAa,CAAC;AAErF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,aAAa,GAAG,iBAAiB,GAAG,QAAQ,CAAC;AAEzD,MAAM,WAAW,4BACf,SAAQ,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,gBAAgB,CAAC,EAAE,oBAAoB,CAAC;IACxC,sEAAsE;IACtE,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,gFAAgF;IAChF,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED,8BAAsB,wBAAyB,SAAQ,eAAe;IACpE,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;IAE1C,SAAS,aAAa,IAAI,EAAE,4BAA4B;CAWzD"}
|
|
@@ -40,6 +40,7 @@ function buildProvider(init, mode) {
|
|
|
40
40
|
model: init.model,
|
|
41
41
|
id: init.id,
|
|
42
42
|
jsonMode: mode === "json_schema" ? "schema" : "object",
|
|
43
|
+
...(init.jsonWithTools ? { jsonWithTools: init.jsonWithTools } : {}),
|
|
43
44
|
...(init.baseUrl ? { baseUrl: init.baseUrl } : {}),
|
|
44
45
|
...(init.headers ? { headers: init.headers } : {}),
|
|
45
46
|
...(init.config?.maxTokens ? { maxTokens: init.config.maxTokens } : {}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OpenAICompatibleProvider.js","sourceRoot":"","sources":["../../src/providers/OpenAICompatibleProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAiB,MAAM,mBAAmB,CAAC;AAEjG,OAAO,EAAE,eAAe,EAAgD,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"OpenAICompatibleProvider.js","sourceRoot":"","sources":["../../src/providers/OpenAICompatibleProvider.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* OpenRouter — one OpenAI-compatible endpoint in front of many models.
|
|
3
3
|
*/
|
|
4
4
|
import type { ProviderCapabilities } from "../types/ai.js";
|
|
5
|
-
import { OpenAICompatibleProvider } from "./OpenAICompatibleProvider.js";
|
|
5
|
+
import { OpenAICompatibleProvider, type JsonWithTools } from "./OpenAICompatibleProvider.js";
|
|
6
6
|
import type { RequestConfig } from "./ProviderAdapter.js";
|
|
7
7
|
export interface OpenRouterProviderOptions {
|
|
8
8
|
/** OpenRouter API key */
|
|
@@ -22,6 +22,14 @@ export interface OpenRouterProviderOptions {
|
|
|
22
22
|
* conversation's rounds. Fallbacks stay on: this is a preference, not a lock.
|
|
23
23
|
*/
|
|
24
24
|
providerOrder?: string[];
|
|
25
|
+
/**
|
|
26
|
+
* See {@link JsonWithTools} — and reach for it here first. One gateway serves
|
|
27
|
+
* hundreds of models and they do not agree: measured through this provider,
|
|
28
|
+
* `z-ai/glm-5.3-flash` called a tool 0/10 with the schema on the response
|
|
29
|
+
* format and 8/8 with it in the prompt, while `qwen3.8-flash` went the other
|
|
30
|
+
* way, 10/10 → 1/6. Changing `model` can change the right answer here.
|
|
31
|
+
*/
|
|
32
|
+
jsonWithTools?: JsonWithTools;
|
|
25
33
|
/** Request defaults sent with every call */
|
|
26
34
|
config?: RequestConfig;
|
|
27
35
|
/** Idle-stream deadline and retry budget */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OpenRouterProvider.d.ts","sourceRoot":"","sources":["../../src/providers/OpenRouterProvider.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"OpenRouterProvider.d.ts","sourceRoot":"","sources":["../../src/providers/OpenRouterProvider.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,wBAAwB,EAAE,KAAK,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC7F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,WAAW,yBAAyB;IACxC,yBAAyB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,4CAA4C;IAC5C,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,4CAA4C;IAC5C,WAAW,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,2DAA2D;IAC3D,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED,qBAAa,kBAAmB,SAAQ,wBAAwB;IAC9D,SAAgB,IAAI,gBAAgB;IACpC,SAAgB,YAAY,EAAE,oBAAoB,CAMhD;gBAEU,OAAO,EAAE,yBAAyB;CAwB/C"}
|
|
@@ -16,6 +16,7 @@ export class OpenRouterProvider extends OpenAICompatibleProvider {
|
|
|
16
16
|
// Chat completions rather than the Responses API: this gateway's
|
|
17
17
|
// json_schema passthrough is what its models actually support.
|
|
18
18
|
structuredOutput: "json_schema",
|
|
19
|
+
...(options.jsonWithTools ? { jsonWithTools: options.jsonWithTools } : {}),
|
|
19
20
|
headers: {
|
|
20
21
|
...(options.siteUrl ? { "HTTP-Referer": options.siteUrl } : {}),
|
|
21
22
|
...(options.siteName ? { "X-Title": options.siteName } : {}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OpenRouterProvider.js","sourceRoot":"","sources":["../../src/providers/OpenRouterProvider.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,wBAAwB,
|
|
1
|
+
{"version":3,"file":"OpenRouterProvider.js","sourceRoot":"","sources":["../../src/providers/OpenRouterProvider.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,wBAAwB,EAAsB,MAAM,+BAA+B,CAAC;AAqC7F,MAAM,OAAO,kBAAmB,SAAQ,wBAAwB;IAU9D,YAAY,OAAkC;QAC5C,IAAI,CAAC,OAAO,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACvE,IAAI,CAAC,OAAO,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;QAE3F,KAAK,CAAC;YACJ,EAAE,EAAE,YAAY;YAChB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,OAAO,EAAE,2BAA2B;YACpC,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,iEAAiE;YACjE,+DAA+D;YAC/D,gBAAgB,EAAE,aAAa;YAC/B,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1E,OAAO,EAAE;gBACP,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC/D,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC7D;YACD,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1E,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvE,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrD,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACpE,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC/D,CAAC,CAAC;QA/BW,SAAI,GAAG,YAAY,CAAC;QACpB,iBAAY,GAAyB;YACnD,aAAa,EAAE,IAAI;YACnB,wBAAwB,EAAE,IAAI;YAC9B,iBAAiB,EAAE,IAAI;YACvB,0BAA0B,EAAE,IAAI;YAChC,qBAAqB,EAAE,IAAI;SAC5B,CAAC;IAyBF,CAAC;CACF"}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* the pair drifted (the streaming path silently lost native schema enforcement
|
|
18
18
|
* because only the non-streaming one could reach `responses.parse`).
|
|
19
19
|
*/
|
|
20
|
-
import { type ChatMessage, type Effort, type Provider } from "@providerkit/core";
|
|
20
|
+
import { type ChatMessage, type Effort, type JsonWithToolsProbe, type ProbeOptions, type Provider } from "@providerkit/core";
|
|
21
21
|
import type { AgentStructuredResponse, AiProvider, GenerateMessageInput, GenerateMessageOutput, GenerateMessageStreamChunk, ProviderCapabilities } from "../types/ai.js";
|
|
22
22
|
import type { HistoryItem } from "../types/history.js";
|
|
23
23
|
/** Provider timeout (ms) + retry count, after defaults are applied. */
|
|
@@ -96,6 +96,23 @@ export declare abstract class ProviderAdapter implements AiProvider {
|
|
|
96
96
|
protected readonly retryConfig: RetryConfig;
|
|
97
97
|
private readonly defaults;
|
|
98
98
|
protected constructor(init: ProviderAdapterInit);
|
|
99
|
+
/**
|
|
100
|
+
* Ask this provider's MODEL whether it can still call a tool while its output
|
|
101
|
+
* is pinned to a schema — the shape every turn here sends, because that is how
|
|
102
|
+
* `message` and the step's `collect` fields come back.
|
|
103
|
+
*
|
|
104
|
+
* Some models cannot, and they do not report it: the call has nowhere to go,
|
|
105
|
+
* so the model narrates it ("let me look that up for you") and stops. On the
|
|
106
|
+
* wire the turn succeeded. Downstream it reads as an agent that will not use
|
|
107
|
+
* its tools, and no instruction fixes it — which is why this is a measurement
|
|
108
|
+
* rather than a setting to reason about.
|
|
109
|
+
*
|
|
110
|
+
* Run it once, at boot, and pass `use` back as `jsonWithTools` (or fail the
|
|
111
|
+
* boot when it is `null` — that model cannot serve this framework's turns).
|
|
112
|
+
* Log `calls`: `0/3 and 3/3` is what makes the next model swap's regression
|
|
113
|
+
* obvious. Costs `samples × 2` short calls, and errors propagate.
|
|
114
|
+
*/
|
|
115
|
+
probeJsonWithTools(opts?: ProbeOptions): Promise<JsonWithToolsProbe>;
|
|
99
116
|
generateMessage<TContext = unknown, TStructured = AgentStructuredResponse>(input: GenerateMessageInput<TContext>): Promise<GenerateMessageOutput<TStructured>>;
|
|
100
117
|
generateMessageStream<TContext = unknown, TStructured = AgentStructuredResponse>(input: GenerateMessageInput<TContext>): AsyncGenerator<GenerateMessageStreamChunk<TStructured>>;
|
|
101
118
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProviderAdapter.d.ts","sourceRoot":"","sources":["../../src/providers/ProviderAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"ProviderAdapter.d.ts","sourceRoot":"","sources":["../../src/providers/ProviderAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAUL,KAAK,WAAW,EAChB,KAAK,MAAM,EAEX,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,QAAQ,EAId,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EACV,uBAAuB,EACvB,UAAU,EACV,oBAAoB,EACpB,qBAAqB,EACrB,0BAA0B,EAC1B,oBAAoB,EACrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAIvD,uEAAuE;AACvE,MAAM,WAAW,WAAW;IAC1B;;;;;;;;OAQG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC;CACjB;AAID;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,WAAW,CAK9F;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,wCAAwC;IACxC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACtD;AAgBD,gEAAgE;AAChE,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,EAAE,CAuChF;AAsED,8BAAsB,eAAgB,YAAW,UAAU;IACzD,kBAAyB,IAAI,EAAE,MAAM,CAAC;IACtC,kBAAyB,YAAY,EAAE,oBAAoB,CAAC;IAE5D,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IACtC,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IACxC,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC;IAC1C,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAC5C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkC;IAE3D,SAAS,aAAa,IAAI,EAAE,mBAAmB;IAQ/C;;;;;;;;;;;;;;;OAeG;IACG,kBAAkB,CAAC,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAOpE,eAAe,CAAC,QAAQ,GAAG,OAAO,EAAE,WAAW,GAAG,uBAAuB,EAC7E,KAAK,EAAE,oBAAoB,CAAC,QAAQ,CAAC,GACpC,OAAO,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC;IAWvC,qBAAqB,CAAC,QAAQ,GAAG,OAAO,EAAE,WAAW,GAAG,uBAAuB,EACpF,KAAK,EAAE,oBAAoB,CAAC,QAAQ,CAAC,GACpC,cAAc,CAAC,0BAA0B,CAAC,WAAW,CAAC,CAAC;CAmG3D"}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* the pair drifted (the streaming path silently lost native schema enforcement
|
|
18
18
|
* because only the non-streaming one could reach `responses.parse`).
|
|
19
19
|
*/
|
|
20
|
-
import { ProviderError, classify, isBackupEligible, requireContent, streamWatch, streamWithBackupModels, watchChunks, withStreamRetry, } from "@providerkit/core";
|
|
20
|
+
import { ProviderError, classify, isBackupEligible, probeJsonWithTools, requireContent, streamWatch, streamWithBackupModels, watchChunks, withStreamRetry, } from "@providerkit/core";
|
|
21
21
|
import { assertUsableCompletion } from "../utils/completion.js";
|
|
22
22
|
import { logger } from "../utils/logger.js";
|
|
23
23
|
const DEFAULT_RETRY_CONFIG = { timeout: 60000, retries: 3 };
|
|
@@ -154,6 +154,28 @@ export class ProviderAdapter {
|
|
|
154
154
|
this.backupModels = init.backupModels ?? [];
|
|
155
155
|
this.retryConfig = resolveRetryConfig(init.retryConfig);
|
|
156
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* Ask this provider's MODEL whether it can still call a tool while its output
|
|
159
|
+
* is pinned to a schema — the shape every turn here sends, because that is how
|
|
160
|
+
* `message` and the step's `collect` fields come back.
|
|
161
|
+
*
|
|
162
|
+
* Some models cannot, and they do not report it: the call has nowhere to go,
|
|
163
|
+
* so the model narrates it ("let me look that up for you") and stops. On the
|
|
164
|
+
* wire the turn succeeded. Downstream it reads as an agent that will not use
|
|
165
|
+
* its tools, and no instruction fixes it — which is why this is a measurement
|
|
166
|
+
* rather than a setting to reason about.
|
|
167
|
+
*
|
|
168
|
+
* Run it once, at boot, and pass `use` back as `jsonWithTools` (or fail the
|
|
169
|
+
* boot when it is `null` — that model cannot serve this framework's turns).
|
|
170
|
+
* Log `calls`: `0/3 and 3/3` is what makes the next model swap's regression
|
|
171
|
+
* obvious. Costs `samples × 2` short calls, and errors propagate.
|
|
172
|
+
*/
|
|
173
|
+
async probeJsonWithTools(opts) {
|
|
174
|
+
return probeJsonWithTools(this.provider, {
|
|
175
|
+
model: this.primaryModel,
|
|
176
|
+
...(opts ?? {}),
|
|
177
|
+
});
|
|
178
|
+
}
|
|
157
179
|
async generateMessage(input) {
|
|
158
180
|
let last;
|
|
159
181
|
for await (const chunk of this.generateMessageStream(input)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProviderAdapter.js","sourceRoot":"","sources":["../../src/providers/ProviderAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EACL,aAAa,EACb,QAAQ,EACR,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,sBAAsB,EACtB,WAAW,EACX,eAAe,
|
|
1
|
+
{"version":3,"file":"ProviderAdapter.js","sourceRoot":"","sources":["../../src/providers/ProviderAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EACL,aAAa,EACb,QAAQ,EACR,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,WAAW,EACX,sBAAsB,EACtB,WAAW,EACX,eAAe,GAUhB,MAAM,mBAAmB,CAAC;AAW3B,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAkB5C,MAAM,oBAAoB,GAAgB,EAAE,OAAO,EAAE,KAAM,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;AAE1E;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAA8C;IAC/E,OAAO;QACL,OAAO,EAAE,KAAK,EAAE,OAAO,IAAI,oBAAoB,CAAC,OAAO;QACvD,OAAO,EAAE,KAAK,EAAE,OAAO,IAAI,oBAAoB,CAAC,OAAO;KACxD,CAAC;AACJ,CAAC;AAyCD;;;;;;;;GAQG;AACH,SAAS,eAAe,CAAC,KAAc;IACrC,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC7B,OAAO,gBAAgB,CAAC,IAAI,CAAC,IAAI,IAAI,KAAK,OAAO,CAAC;AACpD,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,UAAU,CAAC,OAAsB,EAAE,MAAc;IAC/D,MAAM,GAAG,GAAkB,EAAE,CAAC;IAC9B,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,KAAK,QAAQ;gBACX,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;gBACpD,MAAM;YACR,KAAK,MAAM;gBACT,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;gBAClD,MAAM;YACR,KAAK,WAAW;gBACd,GAAG,CAAC,IAAI,CAAC;oBACP,IAAI,EAAE,WAAW;oBACjB,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE;oBAC3B,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM;wBACzB,CAAC,CAAC;4BACE,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gCACxC,EAAE,EAAE,IAAI,CAAC,EAAE;gCACX,IAAI,EAAE,IAAI,CAAC,IAAI;gCACf,+DAA+D;gCAC/D,6DAA6D;gCAC7D,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC;6BAC1C,CAAC,CAAC;yBACJ;wBACH,CAAC,CAAC,EAAE,CAAC;iBACR,CAAC,CAAC;gBACH,MAAM;YACR,KAAK,MAAM;gBACT,GAAG,CAAC,IAAI,CAAC;oBACP,IAAI,EAAE,MAAM;oBACZ,UAAU,EAAE,IAAI,CAAC,YAAY;oBAC7B,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,OAAO,EAAE,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC;iBACxF,CAAC,CAAC;gBACH,MAAM;QACV,CAAC;IACH,CAAC;IACD,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IAC5C,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,OAAO,CAAC,KAA6C;IAC5D,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAClC,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE;QAC1B,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;QACnC,WAAW,EAAE,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAqB;KACzE,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;;;GAIG;AACH,SAAS,YAAY,CAAC,KAAoC;IACxD,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,EAAE,UAAU,CAAC;IAC5C,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAClE,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,UAAU,EAAE,UAAU,IAAI,mBAAmB;QACzD,MAAM,EAAE,MAA0B;KACnC,CAAC;AACJ,CAAC;AAaD,SAAS,IAAI,CAAC,GAAgB,EAAE,KAAoB;IAClD,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,GAAG,CAAC,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC;QAC3C,GAAG,CAAC,gBAAgB,GAAG,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC;QAChD,GAAG,CAAC,iBAAiB,GAAG,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC;IACxD,CAAC;IACD,IAAI,KAAK,CAAC,YAAY;QAAE,GAAG,CAAC,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;IAC9D,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;QACvE,IAAI,IAAI,CAAC,IAAI;YAAE,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtC,IAAI,IAAI,CAAC,SAAS;YAAE,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC;QACtD,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACnC,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IAC9B,GAAG,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC;IAC1B,OAAO,KAAK,CAAC,OAAO,CAAC;AACvB,CAAC;AAID,SAAS,WAAW,CAAC,GAAgB,EAAE,KAAa;IAClD,MAAM,GAAG,GAAiB,EAAE,CAAC;IAC7B,KAAK,MAAM,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QAC3E,IAAI,CAAC,KAAK,CAAC,IAAI;YAAE,SAAS;QAC1B,IAAI,IAAI,GAA4B,EAAE,CAAC;QACvC,IAAI,CAAC;YACH,IAAI,KAAK,CAAC,SAAS;gBAAE,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAA4B,CAAC;QACrF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,wCAAwC,EAAE,KAAK,CAAC,CAAC;QACxE,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,OAAgB,eAAe;IAUnC,YAAsB,IAAyB;QAC7C,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC;QAC/B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC;QAC5C,IAAI,CAAC,WAAW,GAAG,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC1D,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,kBAAkB,CAAC,IAAmB;QAC1C,OAAO,kBAAkB,CAAC,IAAI,CAAC,QAAQ,EAAE;YACvC,KAAK,EAAE,IAAI,CAAC,YAAY;YACxB,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;SAChB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,eAAe,CACnB,KAAqC;QAErC,IAAI,IAAyD,CAAC;QAC9D,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,IAAI,CAAC,qBAAqB,CAAwB,KAAK,CAAC,EAAE,CAAC;YACnF,IAAI,GAAG,KAAK,CAAC;QACf,CAAC;QACD,yEAAyE;QACzE,uDAAuD;QACvD,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,IAAI,eAAe,CAAC,CAAC;QACvF,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;IAC7F,CAAC;IAED,KAAK,CAAC,CAAC,qBAAqB,CAC1B,KAAqC;QAErC,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QACzD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QACjC,MAAM,GAAG,GAAgB,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,KAAK,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC;QAElF,MAAM,IAAI,GAAkB;YAC1B,GAAG,IAAI,CAAC,QAAQ;YAChB,GAAG,CAAC,KAAK,CAAC,UAAU,EAAE,eAAe,KAAK,SAAS;gBACjD,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,UAAU,CAAC,eAAe,EAAE;gBACjD,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,KAAK,CAAC,UAAU,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7F,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1B,CAAC;QAEF,MAAM,OAAO,GAAG,CAAC,KAAa,EAAE,EAAE,CAChC,eAAe,CACb,CAAC,MAAM,EAAE,EAAE;YACT,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC;YAClB,MAAM,KAAK,GAAG,WAAW,CAAC;gBACxB,QAAQ,EAAE,IAAI,CAAC,IAAI;gBACnB,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,OAAO;gBAChC,MAAM;aACP,CAAC,CAAC;YACH,OAAO,cAAc,CACnB,IAAI,CAAC,IAAI,EACT,WAAW,CACT,KAAK,EACL,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,QAAQ,EAAE,KAAK,EAAE;gBAC1C,GAAG,IAAI;gBACP,KAAK;gBACL,MAAM,EAAE,KAAK,CAAC,MAAM;aACrB,CAAC,CACH,CACF,CAAC;QACJ,CAAC,EACD;YACE,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,OAAO,GAAG,CAAC;YACzC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjD,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,CACjC,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,YAAY,CAAC,oBAAoB,EAAE,KAAK,CAAC;SAC/E,CACF,CAAC;QAEJ,MAAM,MAAM,GAAG,sBAAsB,CAAgB,OAAO,EAAE;YAC5D,MAAM,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC;YACjD,aAAa,EAAE,eAAe;YAC9B,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE,CACzC,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,qBAAqB,KAAK,KAAK,QAAQ,IAAI,KAAK,GAAG,CAAC;SAChF,CAAC,CAAC;QAEH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAC/B,IAAI,KAAK;gBAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;QACjE,CAAC;QAED,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,UAAmC,CAAC;QACxC,IAAI,IAAI,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;YACrB,IAAI,CAAC;gBACH,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAgB,CAAC;YACnD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,kCAAkC,EAAE,KAAK,CAAC,CAAC;YACtE,CAAC;QACH,CAAC;QACD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,UAAU,GAAG;gBACX,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC;gBACrB,OAAO,EAAG,UAAkD,EAAE,OAAO,IAAI,GAAG,CAAC,IAAI;gBACjF,SAAS;aACK,CAAC;QACnB,CAAC;QAED,4EAA4E;QAC5E,yEAAyE;QACzE,yEAAyE;QACzE,sBAAsB,CAAC,UAAU,EAAE,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAE1E,MAAM;YACJ,KAAK,EAAE,EAAE;YACT,WAAW,EAAE,GAAG,CAAC,IAAI;YACrB,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE;gBACR,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC/D,GAAG,CAAC,GAAG,CAAC,YAAY,KAAK,SAAS;oBAChC,CAAC,CAAC;wBACE,UAAU,EAAE,GAAG,CAAC,YAAY,GAAG,CAAC,GAAG,CAAC,gBAAgB,IAAI,CAAC,CAAC;wBAC1D,YAAY,EAAE,GAAG,CAAC,YAAY;wBAC9B,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;wBACtC,+DAA+D;wBAC/D,uDAAuD;wBACvD,iBAAiB,EAAE,GAAG,CAAC,iBAAiB;qBACzC;oBACH,CAAC,CAAC,EAAE,CAAC;aACR;YACD,UAAU;SACX,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -16,7 +16,7 @@ export type { OpenRouterProviderOptions } from "./OpenRouterProvider.js";
|
|
|
16
16
|
export { DeepSeekProvider } from "./DeepSeekProvider.js";
|
|
17
17
|
export type { DeepSeekProviderOptions } from "./DeepSeekProvider.js";
|
|
18
18
|
export { OpenAICompatibleProvider } from "./OpenAICompatibleProvider.js";
|
|
19
|
-
export type { OpenAICompatibleProviderInit, StructuredOutputMode, } from "./OpenAICompatibleProvider.js";
|
|
19
|
+
export type { JsonWithTools, OpenAICompatibleProviderInit, StructuredOutputMode, } from "./OpenAICompatibleProvider.js";
|
|
20
20
|
export { createOpenAICompatibleProvider } from "./GenericOpenAICompatibleProvider.js";
|
|
21
21
|
export type { OpenAICompatibleOptions } from "./GenericOpenAICompatibleProvider.js";
|
|
22
22
|
export { ProviderAdapter, resolveRetryConfig } from "./ProviderAdapter.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,YAAY,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAEvE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAEjE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAEjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,YAAY,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAEzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,YAAY,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAErE,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,YAAY,EACV,4BAA4B,EAC5B,oBAAoB,GACrB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,8BAA8B,EAAE,MAAM,sCAAsC,CAAC;AACtF,YAAY,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAEpF,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC3E,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,YAAY,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAEvE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAEjE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAEjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,YAAY,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAEzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,YAAY,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAErE,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,YAAY,EACV,aAAa,EACb,4BAA4B,EAC5B,oBAAoB,GACrB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,8BAA8B,EAAE,MAAM,sCAAsC,CAAC;AACtF,YAAY,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAEpF,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC3E,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAG3D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGrD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAG7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAG3D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGrD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAG7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAOzE,OAAO,EAAE,8BAA8B,EAAE,MAAM,sCAAsC,CAAC;AAGtF,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -49,6 +49,39 @@ The five built-ins:
|
|
|
49
49
|
|
|
50
50
|
The two asymmetries: Anthropic reports `supportsNativeJsonSchema: false` because its JSON output is enforced via a prompt instruction, not a native schema mode — and it is the only built-in that reports `supportsPromptCaching: true`.
|
|
51
51
|
|
|
52
|
+
These flags describe the vendor. What a given **model** does is a separate question, and one of them will cost you a production agent if you guess it — see below.
|
|
53
|
+
|
|
54
|
+
## When the agent narrates a tool instead of calling it
|
|
55
|
+
|
|
56
|
+
The symptom: the model answers a turn that clearly needs a tool by *describing* the tool call — _"let me look that price up for you"_ — and stops. The tool handler never runs. It looks like a model with no initiative, and no instruction fixes it.
|
|
57
|
+
|
|
58
|
+
It is not the prompt. Every turn this framework sends carries a response schema, because that is how `message` and `collect` fields come back. Some models cannot emit a tool call while their output is pinned to a schema: the call has nowhere to go, so they write the announcement instead. Nothing fails, nothing is logged, and the turn succeeds on the wire.
|
|
59
|
+
|
|
60
|
+
Measured 2026-09-07, same request, sampled:
|
|
61
|
+
|
|
62
|
+
| model | tool called | with `jsonWithTools: "prompt"` |
|
|
63
|
+
|-------|-------------|-------------------------------|
|
|
64
|
+
| `z-ai/glm-5.3-flash` | 0/10 | 8/8 |
|
|
65
|
+
| `deepseek-v4-flash-0731` | 0/5 | — |
|
|
66
|
+
| `gemini-3.8-flash` | 3/10 | — |
|
|
67
|
+
| `gemini-3.5-flash-lite` | 10/10 | 6/6 |
|
|
68
|
+
| `gpt-5.6-luna` | 10/10 | 6/6 |
|
|
69
|
+
| `qwen3.8-flash` | 10/10 | 1/6 |
|
|
70
|
+
|
|
71
|
+
`jsonWithTools: "prompt"` on `OpenRouterProvider`, `DeepSeekProvider`, `GeminiProvider` or `createOpenAICompatibleProvider` leaves the response format off the calls that carry tools and sends the schema as prompt there instead. Calls without tools are untouched.
|
|
72
|
+
|
|
73
|
+
Do not pick it from the table — the qwen row is why. Ask the model, once, at boot:
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import { probeJsonWithTools } from "@providerkit/core";
|
|
77
|
+
|
|
78
|
+
const probe = await probeJsonWithTools(provider);
|
|
79
|
+
// { use: "prompt", calls: { response_format: 0, prompt: 3 }, samples: 3 }
|
|
80
|
+
if (!probe.use) throw new Error("this model cannot use tools with a schema at all");
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Log `calls`, not just `use`. `0/3 and 3/3` is what makes the next model swap's regression obvious.
|
|
84
|
+
|
|
52
85
|
## Use with createAgent
|
|
53
86
|
|
|
54
87
|
`createAgent({ provider })` accepts any class that implements `AiProvider`. Swap providers by changing the constructor; nothing else in your agent has to move.
|
|
@@ -89,6 +122,7 @@ interface GeminiProviderOptions {
|
|
|
89
122
|
model: string;
|
|
90
123
|
backupModels?: string[];
|
|
91
124
|
baseUrl?: string;
|
|
125
|
+
jsonWithTools?: "response_format" | "prompt";
|
|
92
126
|
config?: RequestConfig; // temperature, topP, maxTokens, stopSequences
|
|
93
127
|
retryConfig?: { timeout?: number; retries?: number };
|
|
94
128
|
fetchImpl?: typeof fetch; // scripted wire, for tests
|
|
@@ -102,6 +136,7 @@ interface GeminiProviderOptions {
|
|
|
102
136
|
| `apiKey` | `string` | yes* | — | Throws if empty (unless `client` is set). |
|
|
103
137
|
| `model` | `string` | yes | — | Use the model id, e.g. `"gemini-3.1-pro-preview"`. |
|
|
104
138
|
| `backupModels` | `string[]` | no | `[]` | Tried in order on retriable failures (rate limits, overload, timeouts, network). |
|
|
139
|
+
| `jsonWithTools` | `"response_format" \| "prompt"` | no | `"response_format"` | How the schema rides on calls that also carry tools. `gemini-3.5-flash` and `-flash-lite` need nothing; `gemini-3.8-flash` measured 3/10 — [see above](#when-the-agent-narrates-a-tool-instead-of-calling-it). |
|
|
105
140
|
| `config` | `Partial<GenerateContentConfig>` | no | — | Vendor-typed defaults (e.g. `temperature`, `systemInstruction`). |
|
|
106
141
|
| `retryConfig.timeout` | `number` | no | `60000` | Per-attempt timeout in ms. On streams it also bounds time-to-first-token. |
|
|
107
142
|
| `retryConfig.retries` | `number` | no | `3` | Total attempts before giving up. |
|
|
@@ -212,6 +247,7 @@ interface OpenRouterProviderOptions {
|
|
|
212
247
|
backupModels?: string[];
|
|
213
248
|
siteUrl?: string;
|
|
214
249
|
siteName?: string;
|
|
250
|
+
jsonWithTools?: "response_format" | "prompt";
|
|
215
251
|
config?: Partial<Omit<ChatCompletionCreateParamsNonStreaming, "model" | "messages">>;
|
|
216
252
|
retryConfig?: { timeout?: number; retries?: number };
|
|
217
253
|
}
|
|
@@ -226,6 +262,7 @@ interface OpenRouterProviderOptions {
|
|
|
226
262
|
| `backupModels` | `string[]` | no | `[]` | Tried in order on overload/capacity errors. |
|
|
227
263
|
| `siteUrl` | `string` | no | `""` | Sent as `HTTP-Referer` for OpenRouter rankings. |
|
|
228
264
|
| `siteName` | `string` | no | `""` | Sent as `X-Title` for OpenRouter rankings. |
|
|
265
|
+
| `jsonWithTools` | `"response_format" \| "prompt"` | no | `"response_format"` | How the schema rides on calls that also carry tools. One gateway, hundreds of models, and they disagree — [see above](#when-the-agent-narrates-a-tool-instead-of-calling-it). |
|
|
229
266
|
| `config` | OpenAI params | no | — | OpenAI-shaped defaults (forwarded to OpenRouter). |
|
|
230
267
|
| `retryConfig.timeout` | `number` | no | `60000` | Per-attempt timeout in ms. |
|
|
231
268
|
| `retryConfig.retries` | `number` | no | `3` | Total attempts. |
|
|
@@ -255,6 +292,7 @@ interface DeepSeekProviderOptions {
|
|
|
255
292
|
model: string;
|
|
256
293
|
backupModels?: string[];
|
|
257
294
|
baseURL?: string;
|
|
295
|
+
jsonWithTools?: "response_format" | "prompt";
|
|
258
296
|
config?: Partial<Omit<ChatCompletionCreateParamsNonStreaming, "model" | "messages">>;
|
|
259
297
|
retryConfig?: { timeout?: number; retries?: number };
|
|
260
298
|
}
|
|
@@ -267,6 +305,7 @@ interface DeepSeekProviderOptions {
|
|
|
267
305
|
| `apiKey` | `string` | yes | — | Throws if empty. |
|
|
268
306
|
| `model` | `string` | yes | — | e.g. `"deepseek-chat"`, `"deepseek-reasoner"`. |
|
|
269
307
|
| `backupModels` | `string[]` | no | `[]` | Tried in order on overload/rate-limit errors. |
|
|
308
|
+
| `jsonWithTools` | `"response_format" \| "prompt"` | no | `"response_format"` | Reach for it here first: the measured DeepSeek flash models called a tool 0/5 under a response format — [see above](#when-the-agent-narrates-a-tool-instead-of-calling-it). |
|
|
270
309
|
| `baseURL` | `string` | no | `"https://api.deepseek.com"` | Custom endpoint for self-hosted or proxy deployments. |
|
|
271
310
|
| `config` | OpenAI params | no | — | OpenAI-shaped defaults (forwarded to DeepSeek). |
|
|
272
311
|
| `retryConfig.timeout` | `number` | no | `60000` | Per-attempt timeout in ms. |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@falai/agent",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "Conversational state engine for TypeScript where the AI understands, but the code is in control",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/cjs/index.js",
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
"typescript-eslint": "^8.18.2"
|
|
93
93
|
},
|
|
94
94
|
"dependencies": {
|
|
95
|
-
"@providerkit/core": "^0.
|
|
95
|
+
"@providerkit/core": "^0.5.0",
|
|
96
96
|
"loglevel": "^1.9.2"
|
|
97
97
|
},
|
|
98
98
|
"peerDependencies": {
|
package/src/index.ts
CHANGED
|
@@ -36,6 +36,7 @@ export type { DeepSeekProviderOptions } from "./providers/DeepSeekProvider.js";
|
|
|
36
36
|
// Base class for building OpenAI-compatible providers (Groq, Together, etc.)
|
|
37
37
|
export { OpenAICompatibleProvider } from "./providers/OpenAICompatibleProvider.js";
|
|
38
38
|
export type {
|
|
39
|
+
JsonWithTools,
|
|
39
40
|
OpenAICompatibleProviderInit,
|
|
40
41
|
StructuredOutputMode,
|
|
41
42
|
} from "./providers/OpenAICompatibleProvider.js";
|
|
@@ -44,6 +45,9 @@ export type { OpenAICompatibleOptions } from "./providers/GenericOpenAICompatibl
|
|
|
44
45
|
// The bridge every provider above is built on — subclass it to bind any
|
|
45
46
|
// `@providerkit/core` provider to this framework's seam.
|
|
46
47
|
export { ProviderAdapter, resolveRetryConfig } from "./providers/ProviderAdapter.js";
|
|
48
|
+
// The probe's own shapes, re-exported so a consumer reading `probeJsonWithTools`
|
|
49
|
+
// off a provider does not have to add `@providerkit/core` to see its result.
|
|
50
|
+
export type { JsonWithToolsProbe, ProbeOptions } from "@providerkit/core";
|
|
47
51
|
export type {
|
|
48
52
|
ProviderAdapterInit,
|
|
49
53
|
RequestConfig,
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import type { ProviderCapabilities } from "../types/ai.js";
|
|
8
|
-
import { OpenAICompatibleProvider } from "./OpenAICompatibleProvider.js";
|
|
8
|
+
import { OpenAICompatibleProvider, type JsonWithTools } from "./OpenAICompatibleProvider.js";
|
|
9
9
|
import type { RequestConfig } from "./ProviderAdapter.js";
|
|
10
10
|
|
|
11
11
|
export interface DeepSeekProviderOptions {
|
|
@@ -19,6 +19,12 @@ export interface DeepSeekProviderOptions {
|
|
|
19
19
|
baseURL?: string;
|
|
20
20
|
/** Request defaults sent with every call */
|
|
21
21
|
config?: RequestConfig;
|
|
22
|
+
/**
|
|
23
|
+
* See {@link JsonWithTools} — and reach for it here first. The measured
|
|
24
|
+
* DeepSeek flash models called a tool 0/5 with the schema on the response
|
|
25
|
+
* format, and narrated it instead.
|
|
26
|
+
*/
|
|
27
|
+
jsonWithTools?: JsonWithTools;
|
|
22
28
|
/** Idle-stream deadline and retry budget */
|
|
23
29
|
retryConfig?: { timeout?: number; retries?: number };
|
|
24
30
|
/** Replacement `fetch`, for tests that script the wire. */
|
|
@@ -48,6 +54,7 @@ export class DeepSeekProvider extends OpenAICompatibleProvider {
|
|
|
48
54
|
model: options.model,
|
|
49
55
|
// No Responses API here; chat completions enforces the schema natively.
|
|
50
56
|
structuredOutput: "json_schema",
|
|
57
|
+
...(options.jsonWithTools ? { jsonWithTools: options.jsonWithTools } : {}),
|
|
51
58
|
...(options.backupModels ? { backupModels: options.backupModels } : {}),
|
|
52
59
|
...(options.config ? { config: options.config } : {}),
|
|
53
60
|
...(options.retryConfig ? { retryConfig: options.retryConfig } : {}),
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
import { createGeminiProvider } from "@providerkit/core";
|
|
14
14
|
|
|
15
15
|
import type { ProviderCapabilities } from "../types/ai.js";
|
|
16
|
+
import type { JsonWithTools } from "./OpenAICompatibleProvider.js";
|
|
16
17
|
import { ProviderAdapter, type RequestConfig } from "./ProviderAdapter.js";
|
|
17
18
|
|
|
18
19
|
export interface GeminiProviderOptions {
|
|
@@ -24,6 +25,13 @@ export interface GeminiProviderOptions {
|
|
|
24
25
|
backupModels?: string[];
|
|
25
26
|
/** Any endpoint speaking the Gemini generateContent dialect. */
|
|
26
27
|
baseUrl?: string;
|
|
28
|
+
/**
|
|
29
|
+
* See {@link JsonWithTools}. The answer is the MODEL's, not the endpoint's:
|
|
30
|
+
* `gemini-3.5-flash` and `-flash-lite` called their tool under
|
|
31
|
+
* `responseJsonSchema` every time, while `gemini-3.8-flash` managed 3/10
|
|
32
|
+
* (2026-09-07). `probeJsonWithTools()` asks the one you serve.
|
|
33
|
+
*/
|
|
34
|
+
jsonWithTools?: JsonWithTools;
|
|
27
35
|
/** Request defaults sent with every call */
|
|
28
36
|
config?: RequestConfig;
|
|
29
37
|
/** Idle-stream deadline and retry budget */
|
|
@@ -55,6 +63,7 @@ export class GeminiProvider extends ProviderAdapter {
|
|
|
55
63
|
model: options.model,
|
|
56
64
|
id: "gemini",
|
|
57
65
|
...(options.baseUrl ? { baseUrl: options.baseUrl } : {}),
|
|
66
|
+
...(options.jsonWithTools ? { jsonWithTools: options.jsonWithTools } : {}),
|
|
58
67
|
...(options.config?.maxTokens ? { maxTokens: options.config.maxTokens } : {}),
|
|
59
68
|
...(options.config?.effort ? { effort: options.config.effort } : {}),
|
|
60
69
|
...(options.fetchImpl ? { fetchImpl: options.fetchImpl } : {}),
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
import type { ProviderCapabilities } from "../types/ai.js";
|
|
30
30
|
import {
|
|
31
31
|
OpenAICompatibleProvider,
|
|
32
|
+
type JsonWithTools,
|
|
32
33
|
type StructuredOutputMode,
|
|
33
34
|
} from "./OpenAICompatibleProvider.js";
|
|
34
35
|
import type { RequestConfig } from "./ProviderAdapter.js";
|
|
@@ -54,6 +55,11 @@ export interface OpenAICompatibleOptions {
|
|
|
54
55
|
* is OpenAI-only). See {@link StructuredOutputMode}.
|
|
55
56
|
*/
|
|
56
57
|
structuredOutput?: StructuredOutputMode;
|
|
58
|
+
/**
|
|
59
|
+
* See {@link JsonWithTools}. Only affects calls that carry tools, and the
|
|
60
|
+
* answer is the model's, not the endpoint's — measure the one you serve.
|
|
61
|
+
*/
|
|
62
|
+
jsonWithTools?: JsonWithTools;
|
|
57
63
|
/** Default request parameters merged into every call. */
|
|
58
64
|
config?: RequestConfig;
|
|
59
65
|
/** Idle-stream deadline (ms) and retry count. */
|
|
@@ -106,6 +112,7 @@ class GenericOpenAICompatibleProvider extends OpenAICompatibleProvider {
|
|
|
106
112
|
// Arbitrary compatible endpoints rarely serve the Responses API; default
|
|
107
113
|
// to the broadly-supported chat json_schema strategy.
|
|
108
114
|
structuredOutput: options.structuredOutput ?? "json_schema",
|
|
115
|
+
...(options.jsonWithTools ? { jsonWithTools: options.jsonWithTools } : {}),
|
|
109
116
|
...(options.defaultHeaders ? { headers: options.defaultHeaders } : {}),
|
|
110
117
|
...(options.backupModels ? { backupModels: options.backupModels } : {}),
|
|
111
118
|
...(options.config ? { config: options.config } : {}),
|
|
@@ -23,6 +23,28 @@ import { ProviderAdapter, type ProviderAdapterInit, type RequestConfig } from ".
|
|
|
23
23
|
*/
|
|
24
24
|
export type StructuredOutputMode = "responses_parse" | "json_schema" | "json_object";
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* How the schema rides on a call that ALSO carries tools — the one turn shape
|
|
28
|
+
* an agent makes constantly and a provider seam cannot get right by itself.
|
|
29
|
+
*
|
|
30
|
+
* `"response_format"` sends both, which every shape documents and most models
|
|
31
|
+
* honour. `"prompt"` leaves the response format off those calls and sends the
|
|
32
|
+
* schema as prompt instead.
|
|
33
|
+
*
|
|
34
|
+
* Set it to `"prompt"` when the model answers a tool-worthy turn by NARRATING
|
|
35
|
+
* the tool — "let me look that up for you" — and then stopping. That is not a
|
|
36
|
+
* model without initiative: its decoder is pinned to the schema, so the tool
|
|
37
|
+
* call has nowhere to go, and no instruction can make it emit one. Nothing is
|
|
38
|
+
* logged, because from the wire's point of view nothing failed.
|
|
39
|
+
*
|
|
40
|
+
* Measured 2026-09-07, one request, sampled: `z-ai/glm-5.3-flash` called its
|
|
41
|
+
* tool 0/10 under a response format and 8/8 without one, `deepseek-v4-flash`
|
|
42
|
+
* 0/5, `gemini-3.8-flash` 3/10. It stays a setting rather than a default
|
|
43
|
+
* because the reverse is just as real — `qwen3.8-flash` went 10/10 → 1/6 the
|
|
44
|
+
* other way. Measure the model you ship; one call answers it.
|
|
45
|
+
*/
|
|
46
|
+
export type JsonWithTools = "response_format" | "prompt";
|
|
47
|
+
|
|
26
48
|
export interface OpenAICompatibleProviderInit
|
|
27
49
|
extends Omit<ProviderAdapterInit, "provider"> {
|
|
28
50
|
apiKey: string;
|
|
@@ -32,6 +54,8 @@ export interface OpenAICompatibleProviderInit
|
|
|
32
54
|
headers?: Record<string, string>;
|
|
33
55
|
config?: RequestConfig;
|
|
34
56
|
structuredOutput?: StructuredOutputMode;
|
|
57
|
+
/** See {@link JsonWithTools}. Only affects calls that carry tools. */
|
|
58
|
+
jsonWithTools?: JsonWithTools;
|
|
35
59
|
/** OpenRouter upstream-host pin, to keep a conversation's prompt cache warm. */
|
|
36
60
|
providerOrder?: string[];
|
|
37
61
|
/** Replacement `fetch`, for tests that script the wire. */
|
|
@@ -72,6 +96,7 @@ function buildProvider(init: OpenAICompatibleProviderInit, mode: StructuredOutpu
|
|
|
72
96
|
model: init.model,
|
|
73
97
|
id: init.id,
|
|
74
98
|
jsonMode: mode === "json_schema" ? "schema" : "object",
|
|
99
|
+
...(init.jsonWithTools ? { jsonWithTools: init.jsonWithTools } : {}),
|
|
75
100
|
...(init.baseUrl ? { baseUrl: init.baseUrl } : {}),
|
|
76
101
|
...(init.headers ? { headers: init.headers } : {}),
|
|
77
102
|
...(init.config?.maxTokens ? { maxTokens: init.config.maxTokens } : {}),
|