gemi 0.60.0 → 0.61.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/ai/Agent.d.ts +533 -25
- package/dist/ai/Agent.d.ts.map +1 -1
- package/dist/ai/Agent.test-d.d.ts +2 -0
- package/dist/ai/Agent.test-d.d.ts.map +1 -0
- package/dist/ai/AgentController.d.ts +275 -6
- package/dist/ai/AgentController.d.ts.map +1 -1
- package/dist/ai/AgentProvider.d.ts +255 -0
- package/dist/ai/AgentProvider.d.ts.map +1 -0
- package/dist/ai/Schema.d.ts +125 -0
- package/dist/ai/Schema.d.ts.map +1 -0
- package/dist/ai/Schema.test-d.d.ts +2 -0
- package/dist/ai/Schema.test-d.d.ts.map +1 -0
- package/dist/ai/client/index.d.ts +24 -0
- package/dist/ai/client/index.d.ts.map +1 -0
- package/dist/ai/client/index.js +1053 -0
- package/dist/ai/client/index.js.map +1 -0
- package/dist/ai/client/reducer.d.ts +127 -0
- package/dist/ai/client/reducer.d.ts.map +1 -0
- package/dist/ai/client/reducer.test-d.d.ts +2 -0
- package/dist/ai/client/reducer.test-d.d.ts.map +1 -0
- package/dist/ai/client/sse.d.ts +54 -0
- package/dist/ai/client/sse.d.ts.map +1 -0
- package/dist/ai/example.d.ts +129 -0
- package/dist/ai/example.d.ts.map +1 -0
- package/dist/ai/index.d.ts +35 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +20 -0
- package/dist/ai/index.js.map +23 -0
- package/dist/ai/live/harness.d.ts +137 -0
- package/dist/ai/live/harness.d.ts.map +1 -0
- package/dist/ai/providers/call.d.ts +42 -0
- package/dist/ai/providers/call.d.ts.map +1 -0
- package/dist/ai/providers/capabilities.d.ts +50 -0
- package/dist/ai/providers/capabilities.d.ts.map +1 -0
- package/dist/ai/providers/errors.d.ts +37 -0
- package/dist/ai/providers/errors.d.ts.map +1 -0
- package/dist/ai/providers/fakeProvider.d.ts +35 -0
- package/dist/ai/providers/fakeProvider.d.ts.map +1 -0
- package/dist/ai/providers/http.d.ts +46 -0
- package/dist/ai/providers/http.d.ts.map +1 -0
- package/dist/ai/providers/request.d.ts +69 -0
- package/dist/ai/providers/request.d.ts.map +1 -0
- package/dist/ai/providers/stream.d.ts +42 -0
- package/dist/ai/providers/stream.d.ts.map +1 -0
- package/dist/ai/signing.d.ts +195 -0
- package/dist/ai/signing.d.ts.map +1 -0
- package/dist/ai/store/LiveRuns.d.ts +142 -0
- package/dist/ai/store/LiveRuns.d.ts.map +1 -0
- package/dist/ai/store/MemoryAgentStore.d.ts +61 -0
- package/dist/ai/store/MemoryAgentStore.d.ts.map +1 -0
- package/dist/ai/store/index.d.ts +4 -0
- package/dist/ai/store/index.d.ts.map +1 -0
- package/dist/ai/store/sse.d.ts +58 -0
- package/dist/ai/store/sse.d.ts.map +1 -0
- package/dist/ai/store/stubAgentRun.d.ts +56 -0
- package/dist/ai/store/stubAgentRun.d.ts.map +1 -0
- package/dist/ai/types.d.ts +443 -0
- package/dist/ai/types.d.ts.map +1 -0
- package/dist/ai/useChat.d.ts +253 -7
- package/dist/ai/useChat.d.ts.map +1 -1
- package/dist/chunk-1aqzcgfr.js +5 -0
- package/dist/chunk-1aqzcgfr.js.map +10 -0
- package/dist/{chunk-get4mkx8.js → chunk-1b7e9rj7.js} +2 -2
- package/dist/{chunk-get4mkx8.js.map → chunk-1b7e9rj7.js.map} +1 -1
- package/dist/{chunk-x8beq9c4.js → chunk-3aemqfdr.js} +2 -2
- package/dist/{chunk-x8beq9c4.js.map → chunk-3aemqfdr.js.map} +1 -1
- package/dist/{chunk-j06g4sqc.js → chunk-528n3vgy.js} +2 -2
- package/dist/{chunk-j06g4sqc.js.map → chunk-528n3vgy.js.map} +1 -1
- package/dist/{chunk-2khdxyjb.js → chunk-57a0nqfj.js} +1 -1
- package/dist/chunk-57a0nqfj.js.map +10 -0
- package/dist/{chunk-c40n5r4v.js → chunk-5mhcwnyd.js} +2 -2
- package/dist/{chunk-c40n5r4v.js.map → chunk-5mhcwnyd.js.map} +1 -1
- package/dist/{chunk-gwchvzdp.js → chunk-71pk1mxx.js} +2 -2
- package/dist/{chunk-gwchvzdp.js.map → chunk-71pk1mxx.js.map} +1 -1
- package/dist/{chunk-spbgpndn.js → chunk-7t1hjs9f.js} +2 -2
- package/dist/{chunk-spbgpndn.js.map → chunk-7t1hjs9f.js.map} +1 -1
- package/dist/{chunk-9gsdcjt7.js → chunk-7xvaace2.js} +3 -3
- package/dist/{chunk-9gsdcjt7.js.map → chunk-7xvaace2.js.map} +1 -1
- package/dist/{chunk-fxy42w6n.js → chunk-8ag0da2s.js} +2 -2
- package/dist/{chunk-fxy42w6n.js.map → chunk-8ag0da2s.js.map} +1 -1
- package/dist/chunk-8r8epsef.js +5 -0
- package/dist/chunk-8r8epsef.js.map +11 -0
- package/dist/chunk-91cj3nxk.js +6 -0
- package/dist/{chunk-y3zz410b.js.map → chunk-91cj3nxk.js.map} +2 -2
- package/dist/{chunk-0fm6jh9b.js → chunk-9nmvm20t.js} +2 -2
- package/dist/{chunk-0fm6jh9b.js.map → chunk-9nmvm20t.js.map} +1 -1
- package/dist/{chunk-98a3k7bp.js → chunk-9xpa7dpy.js} +2 -2
- package/dist/{chunk-98a3k7bp.js.map → chunk-9xpa7dpy.js.map} +1 -1
- package/dist/{chunk-qva4841r.js → chunk-a1exbqcq.js} +3 -3
- package/dist/{chunk-qva4841r.js.map → chunk-a1exbqcq.js.map} +1 -1
- package/dist/{chunk-cw9y6k15.js → chunk-bb19bwg6.js} +2 -2
- package/dist/{chunk-cw9y6k15.js.map → chunk-bb19bwg6.js.map} +1 -1
- package/dist/{chunk-3gvjn3q4.js → chunk-cf7bvd12.js} +1 -1
- package/dist/{chunk-rkbv3df7.js → chunk-djp2xeqe.js} +2 -2
- package/dist/{chunk-rkbv3df7.js.map → chunk-djp2xeqe.js.map} +1 -1
- package/dist/chunk-ds44bqr9.js +4 -0
- package/dist/{chunk-4mcyyh1v.js.map → chunk-ds44bqr9.js.map} +4 -9
- package/dist/{chunk-wzvs3sym.js → chunk-exndjhza.js} +3 -3
- package/dist/{chunk-wzvs3sym.js.map → chunk-exndjhza.js.map} +1 -1
- package/dist/{chunk-f6dd4gd8.js → chunk-f233yzxf.js} +2 -2
- package/dist/{chunk-f6dd4gd8.js.map → chunk-f233yzxf.js.map} +1 -1
- package/dist/chunk-fz5g2z6h.js +4 -0
- package/dist/{chunk-fbvvqf9b.js.map → chunk-fz5g2z6h.js.map} +2 -2
- package/dist/{chunk-vj9538yn.js → chunk-gcszdwcb.js} +2 -2
- package/dist/{chunk-vj9538yn.js.map → chunk-gcszdwcb.js.map} +1 -1
- package/dist/{chunk-pkjq9833.js → chunk-htesx7ym.js} +4 -4
- package/dist/{chunk-pkjq9833.js.map → chunk-htesx7ym.js.map} +1 -1
- package/dist/chunk-hyxmmj9b.js +5 -0
- package/dist/{chunk-khf9xda6.js.map → chunk-hyxmmj9b.js.map} +2 -2
- package/dist/{chunk-stq96kya.js → chunk-k2sjvt0c.js} +2 -2
- package/dist/{chunk-stq96kya.js.map → chunk-k2sjvt0c.js.map} +1 -1
- package/dist/{chunk-zhbrkpb3.js → chunk-k75phgj4.js} +4 -4
- package/dist/{chunk-zhbrkpb3.js.map → chunk-k75phgj4.js.map} +1 -1
- package/dist/{chunk-y64j80v9.js → chunk-m0tp7zjp.js} +2 -2
- package/dist/{chunk-y64j80v9.js.map → chunk-m0tp7zjp.js.map} +1 -1
- package/dist/{chunk-06j6rsew.js → chunk-m45j7p1y.js} +2 -2
- package/dist/{chunk-06j6rsew.js.map → chunk-m45j7p1y.js.map} +1 -1
- package/dist/chunk-mca9wsvs.js +5 -0
- package/dist/{chunk-z2tcxwyr.js.map → chunk-mca9wsvs.js.map} +3 -4
- package/dist/{chunk-tey1xayb.js → chunk-ms13evzp.js} +2 -2
- package/dist/{chunk-tey1xayb.js.map → chunk-ms13evzp.js.map} +1 -1
- package/dist/{chunk-bn1v4sfs.js → chunk-r962ae93.js} +2 -2
- package/dist/{chunk-bn1v4sfs.js.map → chunk-r962ae93.js.map} +1 -1
- package/dist/{chunk-23h0dmx2.js → chunk-s41ees18.js} +2 -2
- package/dist/{chunk-23h0dmx2.js.map → chunk-s41ees18.js.map} +1 -1
- package/dist/chunk-snb68dgr.js +4 -0
- package/dist/{chunk-hwhw98hc.js.map → chunk-snb68dgr.js.map} +1 -1
- package/dist/chunk-sz051605.js +5 -0
- package/dist/chunk-sz051605.js.map +14 -0
- package/dist/{chunk-2cwcfwg3.js → chunk-tr3cbx8k.js} +2 -2
- package/dist/{chunk-2cwcfwg3.js.map → chunk-tr3cbx8k.js.map} +2 -2
- package/dist/{chunk-dgasxgsm.js → chunk-vqcswg7h.js} +2 -2
- package/dist/{chunk-dgasxgsm.js.map → chunk-vqcswg7h.js.map} +2 -2
- package/dist/{chunk-zqsfanvk.js → chunk-wpb1xpdp.js} +2 -2
- package/dist/{chunk-zqsfanvk.js.map → chunk-wpb1xpdp.js.map} +1 -1
- package/dist/{chunk-z1e55w67.js → chunk-ybqss0jy.js} +2 -2
- package/dist/{chunk-z1e55w67.js.map → chunk-ybqss0jy.js.map} +1 -1
- package/dist/{chunk-cejf873g.js → chunk-yk5wqmyh.js} +2 -2
- package/dist/{chunk-cejf873g.js.map → chunk-yk5wqmyh.js.map} +1 -1
- package/dist/{chunk-8kj3zrm9.js → chunk-ywntv8yw.js} +4 -4
- package/dist/{chunk-8kj3zrm9.js.map → chunk-ywntv8yw.js.map} +1 -1
- package/dist/chunks/{ThemeProvider-ByU4BQdL.js → ThemeProvider-BZ2SsSZ3.js} +60 -39
- package/dist/chunks/ThemeProvider-BZ2SsSZ3.js.map +1 -0
- package/dist/chunks/useParams-BN3XXfmG.js +20 -0
- package/dist/chunks/useParams-BN3XXfmG.js.map +1 -0
- package/dist/client/index.js +3 -3
- package/dist/client/index.js.map +1 -1
- package/dist/client/useDictionary.d.ts.map +1 -1
- package/dist/database/index.js +1 -1
- package/dist/facades/index.js +2 -2
- package/dist/facades/index.js.map +1 -1
- package/dist/http/ApiRouter.d.ts +30 -2
- package/dist/http/ApiRouter.d.ts.map +1 -1
- package/dist/http/index.js +2 -2
- package/dist/http/index.js.map +1 -1
- package/dist/i18n/defineDictionary.d.ts +7 -4
- package/dist/i18n/defineDictionary.d.ts.map +1 -1
- package/dist/i18n/dictionaryRegistry.d.ts +38 -14
- package/dist/i18n/dictionaryRegistry.d.ts.map +1 -1
- package/dist/i18n/dictionaryRuntime.js +1 -1
- package/dist/i18n/index.js +2 -2
- package/dist/i18n/index.js.map +2 -2
- package/dist/kernel/index.js +2 -2
- package/dist/kernel/index.js.map +2 -2
- package/dist/orm/index.js +2 -2
- package/dist/orm/index.js.map +2 -2
- package/dist/server/index.js +1 -1
- package/dist/services/index.js +2 -2
- package/dist/services/index.js.map +2 -2
- package/dist/testing/index.js +2 -1
- package/dist/testing/index.js.map +1 -1
- package/package.json +3 -1
- package/dist/chunk-2khdxyjb.js.map +0 -10
- package/dist/chunk-4mcyyh1v.js +0 -4
- package/dist/chunk-fbvvqf9b.js +0 -4
- package/dist/chunk-hwhw98hc.js +0 -4
- package/dist/chunk-khf9xda6.js +0 -5
- package/dist/chunk-q0y0j3ne.js +0 -5
- package/dist/chunk-q0y0j3ne.js.map +0 -11
- package/dist/chunk-y3zz410b.js +0 -6
- package/dist/chunk-z2tcxwyr.js +0 -5
- package/dist/chunks/ThemeProvider-ByU4BQdL.js.map +0 -1
- /package/dist/{chunk-3gvjn3q4.js.map → chunk-cf7bvd12.js.map} +0 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The plumbing the live suite needs, kept out of the suite so the tests read as
|
|
3
|
+
* claims about the API rather than as setup.
|
|
4
|
+
*
|
|
5
|
+
* NOTHING IN THIS DIRECTORY READS A KEY BY VALUE. The providers pull
|
|
6
|
+
* `OPENAI_API_KEY` / `AZURE_OPENAI_API_KEY` out of `process.env` themselves —
|
|
7
|
+
* see `AgentProvider.endpoint()` — so the only thing this file does with a
|
|
8
|
+
* credential is ask whether one is set. That is deliberate: a harness that
|
|
9
|
+
* carried the key around would eventually put it in a failure message, and a
|
|
10
|
+
* failure message is the one place a secret is guaranteed to be printed.
|
|
11
|
+
*/
|
|
12
|
+
import type { AgentProvider, ProviderEvent, ProviderStream, ProviderStreamParams } from "../AgentProvider";
|
|
13
|
+
import type { AgentMessage, AgentStreamFrame, Usage } from "../types";
|
|
14
|
+
/**
|
|
15
|
+
* The model the suite is written against. `gpt-5.4` is not incidental: it is
|
|
16
|
+
* the generation where tool search exists (see `providers/capabilities.ts`),
|
|
17
|
+
* and the deferred-namespace test is the whole reason this suite exists.
|
|
18
|
+
*
|
|
19
|
+
* Overridable so a resource whose deployment is called something else can still
|
|
20
|
+
* run — Azure lets whoever ran the template name it anything.
|
|
21
|
+
*/
|
|
22
|
+
export declare const LIVE_MODEL: string;
|
|
23
|
+
export declare const LIVE_AZURE_DEPLOYMENT: string;
|
|
24
|
+
/**
|
|
25
|
+
* A key alone is not enough for Azure: the provider also needs to know which
|
|
26
|
+
* resource, and there are three spellings of that. Checking for all three is
|
|
27
|
+
* what stops the suite from running and failing with a 404 for a contributor
|
|
28
|
+
* who exported the key and nothing else.
|
|
29
|
+
*/
|
|
30
|
+
export declare const AZURE_RESOURCE_VARS: readonly ["AZURE_OPENAI_ENDPOINT", "AZURE_OPENAI_RESOURCE_NAME", "AZURE_RESOURCE_NAME"];
|
|
31
|
+
export declare const openaiConfigured: boolean;
|
|
32
|
+
export declare const azureConfigured: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* A provider that records what went through it and caps what it costs.
|
|
35
|
+
*
|
|
36
|
+
* Two jobs, and both are load-bearing rather than convenience:
|
|
37
|
+
*
|
|
38
|
+
* `calls` is evidence. The memoization claim in the escalation test — that a
|
|
39
|
+
* sub-run which finished on turn one is replayed from the transcript rather
|
|
40
|
+
* than run again — is not observable from the transcript, because a replayed
|
|
41
|
+
* run and a re-run one produce the same messages. The only difference is
|
|
42
|
+
* whether a request was made, so the test counts requests.
|
|
43
|
+
*
|
|
44
|
+
* `maxOutputTokens` is a cap `Agent` has no way to set: `AgentStreamParams`
|
|
45
|
+
* carries no token budget, deliberately, and `ProviderStreamParams` does. So
|
|
46
|
+
* the cap goes on the seam between them. Without it a reasoning model asked a
|
|
47
|
+
* puzzle can spend thousands of tokens deciding how to say "nine".
|
|
48
|
+
*/
|
|
49
|
+
export declare class RecordingProvider implements AgentProvider {
|
|
50
|
+
private readonly inner;
|
|
51
|
+
private readonly maxOutputTokens;
|
|
52
|
+
readonly model: string;
|
|
53
|
+
readonly capabilities: AgentProvider["capabilities"];
|
|
54
|
+
/** One entry per model call, in order. */
|
|
55
|
+
readonly requests: ProviderStreamParams[];
|
|
56
|
+
/** Every `ProviderEvent` the parser produced, flattened across calls — this
|
|
57
|
+
* is where the tool-search and namespace assertions read from, because
|
|
58
|
+
* `AgentStreamEvent` carries only half of what the parser knows. */
|
|
59
|
+
readonly events: ProviderEvent[];
|
|
60
|
+
constructor(inner: AgentProvider, maxOutputTokens: number);
|
|
61
|
+
get calls(): number;
|
|
62
|
+
/**
|
|
63
|
+
* What the provider itself reported spending, summed over every call.
|
|
64
|
+
*
|
|
65
|
+
* Deliberately a second implementation of `Agent`'s `addUsage` rather than a
|
|
66
|
+
* call to it: the claim being checked is that the run's total is the sum of
|
|
67
|
+
* what the provider billed, and asking the accumulator whether it accumulated
|
|
68
|
+
* would check nothing. The optional members follow the same rule the real one
|
|
69
|
+
* does — present as soon as any call reported them, so a run whose provider
|
|
70
|
+
* never mentions reasoning tokens keeps the smaller shape.
|
|
71
|
+
*/
|
|
72
|
+
spent(): Usage;
|
|
73
|
+
stream(params: ProviderStreamParams): ProviderStream;
|
|
74
|
+
upload(file: File): Promise<string>;
|
|
75
|
+
normalizeError(error: unknown): import("../types").AgentError;
|
|
76
|
+
}
|
|
77
|
+
export type LiveTarget = {
|
|
78
|
+
/** Appears in every suite name, so `vitest -t openai` selects one provider. */
|
|
79
|
+
label: "openai" | "azure";
|
|
80
|
+
provider: (maxOutputTokens?: number) => RecordingProvider;
|
|
81
|
+
};
|
|
82
|
+
export declare const TARGETS: LiveTarget[];
|
|
83
|
+
export declare const configuredFor: (label: LiveTarget["label"]) => boolean;
|
|
84
|
+
export declare const textOf: (message: AgentMessage | undefined) => string;
|
|
85
|
+
export declare const partsOf: (messages: AgentMessage[], type: string) => any[];
|
|
86
|
+
export declare const lastOf: <T>(items: T[]) => T;
|
|
87
|
+
/** Every text part in the run, joined — what the user ends up reading. */
|
|
88
|
+
export declare const transcriptText: (messages: AgentMessage[]) => string;
|
|
89
|
+
/**
|
|
90
|
+
* The same text with digit grouping removed, for the assertions that look for a
|
|
91
|
+
* number the tool produced.
|
|
92
|
+
*
|
|
93
|
+
* A model writes 7413 as "7,413" about half the time, and on a French system
|
|
94
|
+
* prompt it would write "7 413". Stripping the separators is not a weaker
|
|
95
|
+
* assertion — it is the same number — and the alternative, telling the model
|
|
96
|
+
* how to format its digits, would make the test pass by changing what is being
|
|
97
|
+
* measured.
|
|
98
|
+
*/
|
|
99
|
+
export declare const withoutDigitGrouping: (text: string) => string;
|
|
100
|
+
/**
|
|
101
|
+
* Drains a run's numbered frames while it is still going, twice over.
|
|
102
|
+
*
|
|
103
|
+
* `frames()` rather than the plain async iterator because half the claims in
|
|
104
|
+
* this suite are about `seq` — that nested events are numbered in the parent's
|
|
105
|
+
* sequence, and that a client replaying them lands on the same transcript.
|
|
106
|
+
*
|
|
107
|
+
* WHY TWO ARRAYS, AND WHY THIS IS NOT PEDANTRY. A `tool-call` frame carries the
|
|
108
|
+
* `ToolCallPart` BY REFERENCE, and the part goes on being written to after the
|
|
109
|
+
* frame is emitted: `nestedRunner` hangs `nested` on it, and the sub-run's
|
|
110
|
+
* transcript grows there for the rest of the call. In process, that means a
|
|
111
|
+
* frame collected at the top of a run has a *different* value by the end of it.
|
|
112
|
+
*
|
|
113
|
+
* `AgentRunImpl.toResponse` does `JSON.stringify(frame.event)` at yield time,
|
|
114
|
+
* so a browser watching live receives the part as it was when the frame went
|
|
115
|
+
* out — which is what `wire` is: a clone taken the instant the frame arrived.
|
|
116
|
+
* That is the only honest input for a test of the client reducer. Feeding the
|
|
117
|
+
* live objects instead would hand the reducer a nested transcript it never had
|
|
118
|
+
* to build, and a reducer that dropped `nested-event` entirely would still
|
|
119
|
+
* pass. (It did. That is how this was found.)
|
|
120
|
+
*
|
|
121
|
+
* `live` is kept because the other shape is real too: a client that calls
|
|
122
|
+
* `/attach?from=0` after the run has finished gets the buffered frames
|
|
123
|
+
* serialized *then*, nested transcript already on the part, and then every
|
|
124
|
+
* `nested-event` again on top of it. Converging from there is a claim worth
|
|
125
|
+
* making rather than an accident worth relying on.
|
|
126
|
+
*/
|
|
127
|
+
export declare function collectFrames(run: {
|
|
128
|
+
frames(from?: number): AsyncIterable<AgentStreamFrame>;
|
|
129
|
+
}): {
|
|
130
|
+
wire: AgentStreamFrame[];
|
|
131
|
+
live: AgentStreamFrame[];
|
|
132
|
+
done: Promise<void>;
|
|
133
|
+
};
|
|
134
|
+
/** The request that has no user in it: these tests call `Agent.stream` directly
|
|
135
|
+
* rather than through the controller, and no tool here reads the request. */
|
|
136
|
+
export declare const req: any;
|
|
137
|
+
//# sourceMappingURL=harness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness.d.ts","sourceRoot":"","sources":["../../../ai/live/harness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,cAAc,EACd,oBAAoB,EACrB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEtE;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,QAAyC,CAAC;AACjE,eAAO,MAAM,qBAAqB,QAC8C,CAAC;AAEjF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,yFAItB,CAAC;AAEX,eAAO,MAAM,gBAAgB,SAAsC,CAAC;AACpE,eAAO,MAAM,eAAe,SAEoC,CAAC;AAEjE;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,iBAAkB,YAAW,aAAa;IAWnD,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,eAAe;IAXlC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,aAAa,CAAC,cAAc,CAAC,CAAC;IACrD,0CAA0C;IAC1C,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,EAAE,CAAM;IAC/C;;yEAEqE;IACrE,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,CAAM;gBAGnB,KAAK,EAAE,aAAa,EACpB,eAAe,EAAE,MAAM;IAM1C,IAAI,KAAK,IAAI,MAAM,CAElB;IAED;;;;;;;;;OASG;IACH,KAAK,IAAI,KAAK;IAkBd,MAAM,CAAC,MAAM,EAAE,oBAAoB,GAAG,cAAc;IAYpD,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC;IAInC,cAAc,CAAC,KAAK,EAAE,OAAO;CAG9B;AAMD,MAAM,MAAM,UAAU,GAAG;IACvB,+EAA+E;IAC/E,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC1B,QAAQ,EAAE,CAAC,eAAe,CAAC,EAAE,MAAM,KAAK,iBAAiB,CAAC;CAC3D,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,UAAU,EAW/B,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,OAAO,UAAU,CAAC,OAAO,CAAC,YACC,CAAC;AAI1D,eAAO,MAAM,MAAM,GAAI,SAAS,YAAY,GAAG,SAAS,KAAG,MAI9C,CAAC;AAEd,eAAO,MAAM,OAAO,GAAI,UAAU,YAAY,EAAE,EAAE,MAAM,MAAM,KAAG,GAAG,EAC0B,CAAC;AAE/F,eAAO,MAAM,MAAM,GAAI,CAAC,EAAE,OAAO,CAAC,EAAE,KAAG,CAA4B,CAAC;AAEpE,0EAA0E;AAC1E,eAAO,MAAM,cAAc,GAAI,UAAU,YAAY,EAAE,WAAoC,CAAC;AAE5F;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,GAAI,MAAM,MAAM,WACG,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE;IAAE,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC,gBAAgB,CAAC,CAAA;CAAE;;;;EAU5F;AAED;8EAC8E;AAC9E,eAAO,MAAM,GAAG,EAAS,GAAG,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ProviderEvent } from "../AgentProvider";
|
|
2
|
+
import { type FetchLike } from "./http";
|
|
3
|
+
import type { ResponsesRequest } from "./request";
|
|
4
|
+
/**
|
|
5
|
+
* The parts of a call that differ between OpenAI and Azure, and nothing else.
|
|
6
|
+
*
|
|
7
|
+
* Two classes, one request path: the differences are a URL, a header and when
|
|
8
|
+
* the credential is read, so those are what gets passed in. Everything below
|
|
9
|
+
* this line — retries, decoding, event translation, what an error looks like —
|
|
10
|
+
* is identical, and duplicating it into the Azure class is how the two would
|
|
11
|
+
* start behaving differently by accident.
|
|
12
|
+
*/
|
|
13
|
+
export type ResponsesEndpoint = {
|
|
14
|
+
responsesUrl: string;
|
|
15
|
+
filesUrl: string;
|
|
16
|
+
/** Async because Entra tokens expire mid-conversation, so the credential has
|
|
17
|
+
* to be read per request rather than per provider. */
|
|
18
|
+
headers: () => Promise<Record<string, string>>;
|
|
19
|
+
timeoutMs: number;
|
|
20
|
+
maxRetries: number;
|
|
21
|
+
fetchImpl?: FetchLike;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Errors reach the consumer as events, not exceptions.
|
|
25
|
+
*
|
|
26
|
+
* A `ProviderStream` that threw would make every caller wrap its `for await`,
|
|
27
|
+
* and would lose the deltas already yielded — the agent needs the text it got
|
|
28
|
+
* before the socket died, because the user has already read it.
|
|
29
|
+
*/
|
|
30
|
+
export declare function streamResponses(endpoint: ResponsesEndpoint, body: ResponsesRequest, params: {
|
|
31
|
+
signal?: AbortSignal;
|
|
32
|
+
structuredOutput: boolean;
|
|
33
|
+
}): AsyncGenerator<ProviderEvent>;
|
|
34
|
+
/**
|
|
35
|
+
* Uploads an attachment and returns the id a `FilePart` carries.
|
|
36
|
+
*
|
|
37
|
+
* `user_data` rather than `assistants`: this is a file a person attached to a
|
|
38
|
+
* message, not a corpus for a retrieval store, and the purpose is what decides
|
|
39
|
+
* which of the two the file can be used for.
|
|
40
|
+
*/
|
|
41
|
+
export declare function uploadFile(endpoint: ResponsesEndpoint, file: File): Promise<string>;
|
|
42
|
+
//# sourceMappingURL=call.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call.d.ts","sourceRoot":"","sources":["../../../ai/providers/call.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAGlD;;;;;;;;GAQG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB;2DACuD;IACvD,OAAO,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAuB,eAAe,CACpC,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,gBAAgB,EACtB,MAAM,EAAE;IAAE,MAAM,CAAC,EAAE,WAAW,CAAC;IAAC,gBAAgB,EAAE,OAAO,CAAA;CAAE,GAC1D,cAAc,CAAC,aAAa,CAAC,CA4C/B;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,iBAAiB,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAyBzF"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { ProviderCapabilities } from "../AgentProvider";
|
|
2
|
+
/**
|
|
3
|
+
* What a model can do, read off its id.
|
|
4
|
+
*
|
|
5
|
+
* Hardcoding `true` was never an option — `reasoning: { effort }` is a 400 on
|
|
6
|
+
* gpt-4o, and `defer_loading` is a 400 on anything that predates tool search —
|
|
7
|
+
* but neither is a table lookup that only answers for ids we shipped knowing
|
|
8
|
+
* about.
|
|
9
|
+
*
|
|
10
|
+
* SO AN UNKNOWN ID GETS EVERY CAPABILITY. That is the whole point: a model
|
|
11
|
+
* released next Tuesday must be usable by writing its name, not by waiting for
|
|
12
|
+
* a gemi release. The default is chosen for how it fails, not for how often it
|
|
13
|
+
* is right. Guessing high fails loudly and once — the API rejects the request
|
|
14
|
+
* and names the parameter it disliked, and the fix is one line of config.
|
|
15
|
+
* Guessing low fails silently and forever: reasoning is dropped, every deferred
|
|
16
|
+
* schema is inlined, and the only symptom is a bigger bill and a worse answer.
|
|
17
|
+
* Unknown ids also skew new rather than old, because nobody invents the name of
|
|
18
|
+
* a model that already shipped.
|
|
19
|
+
*
|
|
20
|
+
* The named families below exist to make the *known-old* cases right, which is
|
|
21
|
+
* the only place a guess can be wrong in the quiet direction.
|
|
22
|
+
*
|
|
23
|
+
* Note what an answer of `false` does and does not buy. `reasoning: false` and
|
|
24
|
+
* `toolSearch: false` change the request, because both are optimizations and
|
|
25
|
+
* the run is identical without them. `structuredOutput: false` does not: it is
|
|
26
|
+
* reported honestly for a caller that wants to branch on it, but the request
|
|
27
|
+
* builder still sends the schema, because an agent that declared an `output`
|
|
28
|
+
* has an app waiting on a typed result and dropping the parameter would answer
|
|
29
|
+
* prose forever with nothing to branch on. See `request.ts`.
|
|
30
|
+
*/
|
|
31
|
+
export declare function capabilitiesForModel(model: string): ProviderCapabilities;
|
|
32
|
+
export type Family = {
|
|
33
|
+
kind: "gpt" | "o";
|
|
34
|
+
major: number;
|
|
35
|
+
minor: number;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Reads the generation out of `gpt-5.4-mini-2025-01-01` or `o3-mini`.
|
|
39
|
+
*
|
|
40
|
+
* The minor number is read as well as the major, and it is load-bearing: tool
|
|
41
|
+
* search arrived at gpt-5.2, so `gpt-5` and `gpt-5.4` are two different answers
|
|
42
|
+
* to the same question and a major-only reading gets one of them wrong. An id
|
|
43
|
+
* with no minor — `gpt-5`, `gpt-4o`, `o3` — is minor 0, which is what it is.
|
|
44
|
+
*
|
|
45
|
+
* Exported for its own test: the classification is what the guards below are
|
|
46
|
+
* really about, and it is the only place they are observable — two ids can
|
|
47
|
+
* classify differently and still land on the same capability answer today.
|
|
48
|
+
*/
|
|
49
|
+
export declare function parseFamily(id: string): Family | null;
|
|
50
|
+
//# sourceMappingURL=capabilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../../ai/providers/capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,oBAAoB,CAgDxE;AA4CD,MAAM,MAAM,MAAM,GAAG;IAAE,IAAI,EAAE,KAAK,GAAG,GAAG,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzE;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAcrD"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { AgentError } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* A non-2xx response, carried as an exception so the retry loop and
|
|
4
|
+
* `normalizeError` can both read it.
|
|
5
|
+
*
|
|
6
|
+
* The body is kept parsed-if-possible and raw-if-not: OpenAI and Azure both
|
|
7
|
+
* answer `{ error: { message, type, code } }` on a good day, and an HTML error
|
|
8
|
+
* page from a proxy on a bad one, and the bad day is exactly when the text
|
|
9
|
+
* matters.
|
|
10
|
+
*/
|
|
11
|
+
export declare class ProviderHttpError extends Error {
|
|
12
|
+
readonly status: number;
|
|
13
|
+
readonly body: unknown;
|
|
14
|
+
readonly requestId?: string;
|
|
15
|
+
constructor(status: number, body: unknown, requestId?: string);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The request ran out of time. Its own class because it must not read as a
|
|
19
|
+
* user abort: `stop()` means the person is done, and a timeout means the
|
|
20
|
+
* network was, and only one of those is worth trying again.
|
|
21
|
+
*/
|
|
22
|
+
export declare class ProviderTimeoutError extends Error {
|
|
23
|
+
readonly timeoutMs: number;
|
|
24
|
+
constructor(timeoutMs: number);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Provider failures onto `AgentErrorCode`.
|
|
28
|
+
*
|
|
29
|
+
* The contract an app is buying here is that it can branch on `rate_limited`
|
|
30
|
+
* without knowing whose rate limit it was, and on `retryable` without knowing
|
|
31
|
+
* which of the two APIs answered. So `retryable` is set from what is actually
|
|
32
|
+
* true of the failure — a 429 from a spent quota is not retryable no matter
|
|
33
|
+
* what its status code says, and neither is a request that will be too long
|
|
34
|
+
* again next time.
|
|
35
|
+
*/
|
|
36
|
+
export declare function normalizeProviderError(error: unknown): AgentError;
|
|
37
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../ai/providers/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C;;;;;;;;GAQG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;gBAEhB,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM;CAO9D;AAED;;;;GAIG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAEf,SAAS,EAAE,MAAM;CAK9B;AAyBD;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CA4BjE"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { AgentProvider, ProviderEvent, ProviderStreamParams } from "../AgentProvider";
|
|
2
|
+
/**
|
|
3
|
+
* Scripted `ProviderEvent`s, one script per model call.
|
|
4
|
+
*
|
|
5
|
+
* The real provider is written against the same interface elsewhere; depending
|
|
6
|
+
* on it in a test would make that test a test of two things at once, and would
|
|
7
|
+
* need a network.
|
|
8
|
+
*
|
|
9
|
+
* It lives in source rather than in a test file for the same reason
|
|
10
|
+
* `store/stubAgentRun.ts` does: both the `Agent` tests and the controller tests
|
|
11
|
+
* need it, and a test file that imports another test file gets that file's
|
|
12
|
+
* suites collected twice.
|
|
13
|
+
*/
|
|
14
|
+
export declare class FakeProvider {
|
|
15
|
+
private scripts;
|
|
16
|
+
readonly model = "fake";
|
|
17
|
+
readonly capabilities: {
|
|
18
|
+
reasoning: boolean;
|
|
19
|
+
structuredOutput: boolean;
|
|
20
|
+
fileInput: boolean;
|
|
21
|
+
parallelToolCalls: boolean;
|
|
22
|
+
toolSearch: boolean;
|
|
23
|
+
};
|
|
24
|
+
readonly calls: ProviderStreamParams[];
|
|
25
|
+
constructor(scripts: ProviderEvent[][]);
|
|
26
|
+
stream(params: ProviderStreamParams): AsyncGenerator<ProviderEvent, void, unknown>;
|
|
27
|
+
upload(): Promise<string>;
|
|
28
|
+
normalizeError(error: unknown): {
|
|
29
|
+
code: "provider_error";
|
|
30
|
+
message: string;
|
|
31
|
+
retryable: boolean;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export declare function fakeProvider(...scripts: ProviderEvent[][]): AgentProvider & FakeProvider;
|
|
35
|
+
//# sourceMappingURL=fakeProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fakeProvider.d.ts","sourceRoot":"","sources":["../../../ai/providers/fakeProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE3F;;;;;;;;;;;GAWG;AACH,qBAAa,YAAY;IAWX,OAAO,CAAC,OAAO;IAV3B,QAAQ,CAAC,KAAK,UAAU;IACxB,QAAQ,CAAC,YAAY;;;;;;MAMnB;IACF,QAAQ,CAAC,KAAK,EAAE,oBAAoB,EAAE,CAAM;gBAExB,OAAO,EAAE,aAAa,EAAE,EAAE;IAE9C,MAAM,CAAC,MAAM,EAAE,oBAAoB;IAc7B,MAAM;IAIZ,cAAc,CAAC,KAAK,EAAE,OAAO;;;;;CAO9B;AAED,wBAAgB,YAAY,CAAC,GAAG,OAAO,EAAE,aAAa,EAAE,EAAE,GACT,aAAa,GAAG,YAAY,CAC5E"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export type FetchLike = (input: string, init: RequestInit) => Promise<Response>;
|
|
2
|
+
export type RequestOptions = {
|
|
3
|
+
maxRetries: number;
|
|
4
|
+
timeoutMs: number;
|
|
5
|
+
signal?: AbortSignal;
|
|
6
|
+
/** Injected by the tests. Nothing here should ever need a real socket to be
|
|
7
|
+
* exercised, and a retry policy that is only tested against a live API is
|
|
8
|
+
* one that gets tested during an outage. */
|
|
9
|
+
fetchImpl?: FetchLike;
|
|
10
|
+
/** Takes the caller's signal so the default can clear its timer rather than
|
|
11
|
+
* hold the process open for a backoff nobody is waiting for any more. An
|
|
12
|
+
* injected sleep may ignore it: the wait is raced against the abort either
|
|
13
|
+
* way. */
|
|
14
|
+
sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;
|
|
15
|
+
random?: () => number;
|
|
16
|
+
now?: () => number;
|
|
17
|
+
};
|
|
18
|
+
export declare const MAX_DELAY_MS = 20000;
|
|
19
|
+
/**
|
|
20
|
+
* `Retry-After` in either of its two legal forms: seconds, or an HTTP date.
|
|
21
|
+
*
|
|
22
|
+
* Honoured rather than ignored because the server knows when its window
|
|
23
|
+
* reopens and we are guessing. A value in the past clamps to zero; a garbage
|
|
24
|
+
* value falls back to the computed backoff, since a header we cannot read is
|
|
25
|
+
* not a reason to give up on the request.
|
|
26
|
+
*
|
|
27
|
+
* Parsed here, bounded at the call site: this returns what the server said.
|
|
28
|
+
*/
|
|
29
|
+
export declare function parseRetryAfter(value: string | null | undefined, now: number): number | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Exponential backoff with full jitter. The jitter is the point: without it,
|
|
32
|
+
* every request that got rate limited at the same moment retries at the same
|
|
33
|
+
* moment, and the second wave is the same size as the first.
|
|
34
|
+
*/
|
|
35
|
+
export declare function backoffDelayMs(attempt: number, random: () => number): number;
|
|
36
|
+
/**
|
|
37
|
+
* One HTTP call, retried.
|
|
38
|
+
*
|
|
39
|
+
* The timeout covers getting a response, not consuming one. A streamed answer
|
|
40
|
+
* legitimately takes minutes, and a timeout that kept running would cut off
|
|
41
|
+
* long completions at exactly the point where they were most expensive to
|
|
42
|
+
* abandon — so the timer is cleared once the headers land, and only the
|
|
43
|
+
* caller's own signal can end the body.
|
|
44
|
+
*/
|
|
45
|
+
export declare function requestWithRetry(url: string, init: RequestInit, options: RequestOptions): Promise<Response>;
|
|
46
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../ai/providers/http.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEhF,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;iDAE6C;IAC7C,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;eAGW;IACX,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB,CAAC;AAMF,eAAO,MAAM,YAAY,QAAS,CAAC;AAEnC;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAOjG;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,MAAM,GAAG,MAAM,CAG5E;AA6CD;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,QAAQ,CAAC,CAqGnB"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { ProviderCapabilities, ProviderStreamParams, ProviderToolNamespace, ProviderToolSpec } from "../AgentProvider";
|
|
2
|
+
import type { AgentMessage, ToolResultPart } from "../types";
|
|
3
|
+
/**
|
|
4
|
+
* Building the request body is a pure function, on purpose.
|
|
5
|
+
*
|
|
6
|
+
* Everything hard about this provider is in here — item ordering, tool-call
|
|
7
|
+
* pairing, what a denied call looks like on the wire — and none of it needs a
|
|
8
|
+
* socket to be wrong. So it is separated from the class that posts it, and the
|
|
9
|
+
* tests assert the object rather than mocking `fetch` and reading a string.
|
|
10
|
+
*/
|
|
11
|
+
export type ResponsesInputItem = Record<string, unknown>;
|
|
12
|
+
export type ResponsesTool = Record<string, unknown>;
|
|
13
|
+
export type ResponsesRequest = {
|
|
14
|
+
model: string;
|
|
15
|
+
input: ResponsesInputItem[];
|
|
16
|
+
stream: true;
|
|
17
|
+
instructions?: string;
|
|
18
|
+
tools?: ResponsesTool[];
|
|
19
|
+
parallel_tool_calls?: boolean;
|
|
20
|
+
text?: {
|
|
21
|
+
format: Record<string, unknown>;
|
|
22
|
+
};
|
|
23
|
+
reasoning?: {
|
|
24
|
+
effort: string;
|
|
25
|
+
summary: "auto";
|
|
26
|
+
};
|
|
27
|
+
temperature?: number;
|
|
28
|
+
max_output_tokens?: number;
|
|
29
|
+
};
|
|
30
|
+
export declare function buildResponsesRequest(params: ProviderStreamParams, ctx: {
|
|
31
|
+
model: string;
|
|
32
|
+
capabilities: ProviderCapabilities;
|
|
33
|
+
}): ResponsesRequest;
|
|
34
|
+
/**
|
|
35
|
+
* `AgentMessage[]` to Responses input items.
|
|
36
|
+
*
|
|
37
|
+
* Order is preserved *within* a message, not just between messages: a message
|
|
38
|
+
* that holds reasoning, then a tool call, then its result has to arrive in that
|
|
39
|
+
* order, because the API validates the pairing positionally. So text and file
|
|
40
|
+
* parts are buffered into one message item and that buffer is flushed the
|
|
41
|
+
* moment a non-message item appears, rather than emitting all the text first
|
|
42
|
+
* and all the calls after.
|
|
43
|
+
*/
|
|
44
|
+
export declare function toResponsesInput(messages: AgentMessage[], capabilities: ProviderCapabilities): ResponsesInputItem[];
|
|
45
|
+
/**
|
|
46
|
+
* Every tool call gets an output, including the ones that never ran.
|
|
47
|
+
*
|
|
48
|
+
* The API rejects a history containing a `function_call` with no matching
|
|
49
|
+
* `function_call_output`, so a denial cannot be expressed by omission — and a
|
|
50
|
+
* conversation where the user said no has to stay continuable, which is the
|
|
51
|
+
* whole reason `denied` exists in the first place.
|
|
52
|
+
*
|
|
53
|
+
* What is sent is prose rather than a status enum, because the reader is a
|
|
54
|
+
* language model: it has to be able to tell "the user refused this" from "this
|
|
55
|
+
* blew up", and those two lead to genuinely different next moves — apologize
|
|
56
|
+
* and ask, versus try another way.
|
|
57
|
+
*/
|
|
58
|
+
export declare function toolResultOutput(part: ToolResultPart): string;
|
|
59
|
+
/**
|
|
60
|
+
* Tools and namespaces onto the Responses `tools` array.
|
|
61
|
+
*
|
|
62
|
+
* Without tool search the grouping has nothing to do — a namespace exists to be
|
|
63
|
+
* searched — so it is flattened away and every schema is sent inline with
|
|
64
|
+
* `deferred` ignored. That is the promise `capabilities.toolSearch` makes:
|
|
65
|
+
* deferral is a token optimization, and an optimization that changed which
|
|
66
|
+
* tools the model can reach would not be one.
|
|
67
|
+
*/
|
|
68
|
+
export declare function toResponsesTools(tools: (ProviderToolSpec | ProviderToolNamespace)[] | undefined, capabilities: ProviderCapabilities): ResponsesTool[];
|
|
69
|
+
//# sourceMappingURL=request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../../ai/providers/request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE7D;;;;;;;GAOG;AAKH,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACzD,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEpD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,MAAM,EAAE,IAAI,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IACxB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,IAAI,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IAC3C,SAAS,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,oBAAoB,EAC5B,GAAG,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,oBAAoB,CAAA;CAAE,GACzD,gBAAgB,CAiDlB;AAID;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,YAAY,EAAE,EACxB,YAAY,EAAE,oBAAoB,GACjC,kBAAkB,EAAE,CA0EtB;AA0FD;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAgB7D;AAUD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,CAAC,gBAAgB,GAAG,qBAAqB,CAAC,EAAE,GAAG,SAAS,EAC/D,YAAY,EAAE,oBAAoB,GACjC,aAAa,EAAE,CA2CjB"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ProviderEvent } from "../AgentProvider";
|
|
2
|
+
import type { Usage } from "../types";
|
|
3
|
+
/**
|
|
4
|
+
* The Responses SSE stream to `ProviderEvent`.
|
|
5
|
+
*
|
|
6
|
+
* Also a pure function over chunks, for the same reason the request builder is:
|
|
7
|
+
* everything that breaks here breaks on a byte boundary or a malformed frame,
|
|
8
|
+
* and neither needs a network to reproduce. The tests drive it with recorded
|
|
9
|
+
* fixture strings, including one fed a byte at a time.
|
|
10
|
+
*/
|
|
11
|
+
export type SSEMessage = {
|
|
12
|
+
event: string;
|
|
13
|
+
data: string;
|
|
14
|
+
id?: string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Chunks to SSE messages.
|
|
18
|
+
*
|
|
19
|
+
* Written out rather than reached for as a one-liner because every shortcut
|
|
20
|
+
* here is a bug that only shows up under load. A frame split across two chunks
|
|
21
|
+
* is the normal case, not the edge case — TCP has no idea what an event is.
|
|
22
|
+
* Multi-line `data:` is spec, comment lines beginning with `:` are what
|
|
23
|
+
* keepalives look like, and a `\r\n` stream is what you get through some
|
|
24
|
+
* proxies.
|
|
25
|
+
*/
|
|
26
|
+
export declare function sseMessages(chunks: AsyncIterable<string> | Iterable<string>): AsyncGenerator<SSEMessage>;
|
|
27
|
+
type ParseOptions = {
|
|
28
|
+
/**
|
|
29
|
+
* Set when the agent declared an `output` schema. The same
|
|
30
|
+
* `response.output_text.delta` carries prose in one case and the JSON of the
|
|
31
|
+
* final answer in the other, and only the caller knows which it asked for.
|
|
32
|
+
*/
|
|
33
|
+
structuredOutput?: boolean;
|
|
34
|
+
};
|
|
35
|
+
export declare function parseResponsesStream(chunks: AsyncIterable<string> | Iterable<string>, options?: ParseOptions): AsyncGenerator<ProviderEvent>;
|
|
36
|
+
export declare function emptyUsage(): Usage;
|
|
37
|
+
export declare function toUsage(raw: any): Usage;
|
|
38
|
+
/** A `ReadableStream` of bytes to the string chunks the parser wants. Split out
|
|
39
|
+
* so the parser never has to know it came from a socket. */
|
|
40
|
+
export declare function decodeChunks(body: ReadableStream<Uint8Array> | null): AsyncGenerator<string>;
|
|
41
|
+
export {};
|
|
42
|
+
//# sourceMappingURL=stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../../ai/providers/stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEtC;;;;;;;GAOG;AAEH,MAAM,MAAM,UAAU,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtE;;;;;;;;;GASG;AACH,wBAAuB,WAAW,CAChC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,GAC/C,cAAc,CAAC,UAAU,CAAC,CAwD5B;AAED,KAAK,YAAY,GAAG;IAClB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC;AAIF,wBAAuB,oBAAoB,CACzC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,EAChD,OAAO,GAAE,YAAiB,GACzB,cAAc,CAAC,aAAa,CAAC,CA4P/B;AA+HD,wBAAgB,UAAU,IAAI,KAAK,CAElC;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,KAAK,CAcvC;AAED;6DAC6D;AAC7D,wBAAuB,YAAY,CACjC,IAAI,EAAE,cAAc,CAAC,UAAU,CAAC,GAAG,IAAI,GACtC,cAAc,CAAC,MAAM,CAAC,CAiBxB"}
|