@falai/agent 3.1.1 → 3.2.1
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/core/ResponseModal.d.ts +14 -7
- package/dist/cjs/core/ResponseModal.d.ts.map +1 -1
- package/dist/cjs/core/ResponseModal.js +37 -17
- package/dist/cjs/core/ResponseModal.js.map +1 -1
- 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/cjs/utils/index.d.ts +1 -1
- package/dist/cjs/utils/index.d.ts.map +1 -1
- package/dist/cjs/utils/index.js +2 -1
- package/dist/cjs/utils/index.js.map +1 -1
- package/dist/cjs/utils/json.d.ts +14 -0
- package/dist/cjs/utils/json.d.ts.map +1 -1
- package/dist/cjs/utils/json.js +62 -0
- package/dist/cjs/utils/json.js.map +1 -1
- package/dist/core/ResponseModal.d.ts +14 -7
- package/dist/core/ResponseModal.d.ts.map +1 -1
- package/dist/core/ResponseModal.js +38 -18
- package/dist/core/ResponseModal.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/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/json.d.ts +14 -0
- package/dist/utils/json.d.ts.map +1 -1
- package/dist/utils/json.js +61 -0
- package/dist/utils/json.js.map +1 -1
- package/docs/reference/providers.md +39 -0
- package/package.json +2 -2
- package/src/core/ResponseModal.ts +45 -25
- 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
- package/src/utils/index.ts +1 -1
- package/src/utils/json.ts +61 -0
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
ProviderError,
|
|
23
23
|
classify,
|
|
24
24
|
isBackupEligible,
|
|
25
|
+
probeJsonWithTools,
|
|
25
26
|
requireContent,
|
|
26
27
|
streamWatch,
|
|
27
28
|
streamWithBackupModels,
|
|
@@ -30,6 +31,8 @@ import {
|
|
|
30
31
|
type ChatMessage,
|
|
31
32
|
type Effort,
|
|
32
33
|
type JsonObjectSchema,
|
|
34
|
+
type JsonWithToolsProbe,
|
|
35
|
+
type ProbeOptions,
|
|
33
36
|
type Provider,
|
|
34
37
|
type ProviderChunk,
|
|
35
38
|
type StreamOptions,
|
|
@@ -260,6 +263,29 @@ export abstract class ProviderAdapter implements AiProvider {
|
|
|
260
263
|
this.retryConfig = resolveRetryConfig(init.retryConfig);
|
|
261
264
|
}
|
|
262
265
|
|
|
266
|
+
/**
|
|
267
|
+
* Ask this provider's MODEL whether it can still call a tool while its output
|
|
268
|
+
* is pinned to a schema — the shape every turn here sends, because that is how
|
|
269
|
+
* `message` and the step's `collect` fields come back.
|
|
270
|
+
*
|
|
271
|
+
* Some models cannot, and they do not report it: the call has nowhere to go,
|
|
272
|
+
* so the model narrates it ("let me look that up for you") and stops. On the
|
|
273
|
+
* wire the turn succeeded. Downstream it reads as an agent that will not use
|
|
274
|
+
* its tools, and no instruction fixes it — which is why this is a measurement
|
|
275
|
+
* rather than a setting to reason about.
|
|
276
|
+
*
|
|
277
|
+
* Run it once, at boot, and pass `use` back as `jsonWithTools` (or fail the
|
|
278
|
+
* boot when it is `null` — that model cannot serve this framework's turns).
|
|
279
|
+
* Log `calls`: `0/3 and 3/3` is what makes the next model swap's regression
|
|
280
|
+
* obvious. Costs `samples × 2` short calls, and errors propagate.
|
|
281
|
+
*/
|
|
282
|
+
async probeJsonWithTools(opts?: ProbeOptions): Promise<JsonWithToolsProbe> {
|
|
283
|
+
return probeJsonWithTools(this.provider, {
|
|
284
|
+
model: this.primaryModel,
|
|
285
|
+
...(opts ?? {}),
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
|
|
263
289
|
async generateMessage<TContext = unknown, TStructured = AgentStructuredResponse>(
|
|
264
290
|
input: GenerateMessageInput<TContext>,
|
|
265
291
|
): Promise<GenerateMessageOutput<TStructured>> {
|
package/src/providers/index.ts
CHANGED
|
@@ -23,6 +23,7 @@ export type { DeepSeekProviderOptions } from "./DeepSeekProvider.js";
|
|
|
23
23
|
|
|
24
24
|
export { OpenAICompatibleProvider } from "./OpenAICompatibleProvider.js";
|
|
25
25
|
export type {
|
|
26
|
+
JsonWithTools,
|
|
26
27
|
OpenAICompatibleProviderInit,
|
|
27
28
|
StructuredOutputMode,
|
|
28
29
|
} from "./OpenAICompatibleProvider.js";
|
package/src/utils/index.ts
CHANGED
|
@@ -69,7 +69,7 @@ export {
|
|
|
69
69
|
} from "./condition.js";
|
|
70
70
|
|
|
71
71
|
// JSON utilities
|
|
72
|
-
export { parseJSONResponse, tryParseJSONResponse } from "./json.js";
|
|
72
|
+
export { parseJSONResponse, tryParseJSONResponse, extractEmbeddedJSONObject } from "./json.js";
|
|
73
73
|
|
|
74
74
|
// Serialization utilities
|
|
75
75
|
export { serializeToolResult, isToolResultLike, extractResultDirectives } from "./serialize.js";
|
package/src/utils/json.ts
CHANGED
|
@@ -44,3 +44,64 @@ export function tryParseJSONResponse(text: string): unknown {
|
|
|
44
44
|
return undefined;
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Find a complete JSON object embedded in surrounding text.
|
|
50
|
+
*
|
|
51
|
+
* {@link parseJSONResponse} requires the WHOLE string to be the object. A model
|
|
52
|
+
* told to answer in JSON sometimes answers twice instead — the conversational
|
|
53
|
+
* text for the user, and then the protocol envelope repeating it — and such a
|
|
54
|
+
* turn parses as nothing, so the envelope travels on as user-visible content.
|
|
55
|
+
* This scans for the first balanced `{...}` that parses as an object, ignoring
|
|
56
|
+
* braces that sit inside string literals.
|
|
57
|
+
*
|
|
58
|
+
* Returns `undefined` when no complete object is present (prose that merely
|
|
59
|
+
* contains a brace, or an envelope truncated before its closing brace).
|
|
60
|
+
*/
|
|
61
|
+
export function extractEmbeddedJSONObject(text: string): Record<string, unknown> | undefined {
|
|
62
|
+
if (!text) return undefined;
|
|
63
|
+
|
|
64
|
+
for (let start = text.indexOf("{"); start !== -1; start = text.indexOf("{", start + 1)) {
|
|
65
|
+
const end = findObjectEnd(text, start);
|
|
66
|
+
if (end === -1) continue;
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
const parsed = JSON.parse(text.slice(start, end + 1));
|
|
70
|
+
if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
71
|
+
return parsed as Record<string, unknown>;
|
|
72
|
+
}
|
|
73
|
+
} catch {
|
|
74
|
+
// Not an object after all — keep scanning for a later candidate.
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Index of the `}` closing the object that opens at `start`, or -1 when the
|
|
83
|
+
* text ends first. Quotes and their escapes are tracked so a brace inside a
|
|
84
|
+
* string value never opens or closes a level.
|
|
85
|
+
*/
|
|
86
|
+
function findObjectEnd(text: string, start: number): number {
|
|
87
|
+
let depth = 0;
|
|
88
|
+
let inString = false;
|
|
89
|
+
let escaped = false;
|
|
90
|
+
|
|
91
|
+
for (let i = start; i < text.length; i++) {
|
|
92
|
+
const ch = text[i];
|
|
93
|
+
|
|
94
|
+
if (inString) {
|
|
95
|
+
if (escaped) escaped = false;
|
|
96
|
+
else if (ch === "\\") escaped = true;
|
|
97
|
+
else if (ch === '"') inString = false;
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (ch === '"') inString = true;
|
|
102
|
+
else if (ch === "{") depth++;
|
|
103
|
+
else if (ch === "}" && --depth === 0) return i;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return -1;
|
|
107
|
+
}
|