@opengeni/runtime 4.3.0-canary.36855269964001 → 4.3.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/assets/codemode-client.json +1 -1
- package/dist/{chunk-PEEYZDLS.js → chunk-22M75RJF.js} +622 -890
- package/dist/chunk-22M75RJF.js.map +1 -0
- package/dist/{chunk-BK3S65CI.js → chunk-JUFVYQCY.js} +13 -91
- package/dist/chunk-JUFVYQCY.js.map +1 -0
- package/dist/claude-subscription-usage.d.ts +1 -3
- package/dist/index.d.ts +1 -7
- package/dist/index.js +2 -8
- package/dist/input-wait-yield.d.ts +0 -4
- package/dist/mcp-run-credentials.d.ts +2 -3
- package/dist/model-preparation-diagnostics.d.ts +0 -9
- package/dist/model-provider-routing.d.ts +0 -4
- package/dist/model-provider.d.ts +0 -1
- package/dist/model-request-capture.d.ts +0 -9
- package/dist/replayable-json-body.d.ts +1 -2
- package/dist/sandbox/index.d.ts +1 -1
- package/dist/sandbox/index.js +1 -3
- package/dist/sandbox/provider-command-session.d.ts +0 -6
- package/dist/sandbox/providers/modal-command-router-wire.d.ts +0 -5
- package/dist/sandbox/routing/routing-session.d.ts +4 -5
- package/dist/workspace-tool-gateway.js +2 -2
- package/package.json +12 -12
- package/src/bundled_default_skills/opengeni-client/SKILL.md +0 -5
- package/src/bundled_default_skills/opengeni-client/references/api-workflows.md +0 -8
- package/src/bundled_default_skills/opengeni-client/references/product-shapes-and-ui.md +3 -16
- package/src/claude-subscription-usage.ts +4 -23
- package/src/index.ts +2 -29
- package/src/input-wait-yield.ts +0 -7
- package/src/interaction-tools.ts +2 -12
- package/src/lazy-tool-transport.ts +14 -22
- package/src/mcp-run-credentials.ts +3 -18
- package/src/model-preparation-diagnostics.ts +1 -48
- package/src/model-provider-client.ts +1 -5
- package/src/model-provider-routing.ts +1 -95
- package/src/model-provider.ts +0 -1
- package/src/model-request-capture.ts +1 -28
- package/src/provider-history-adapter.ts +3 -24
- package/src/replayable-json-body.ts +2 -19
- package/src/sandbox/index.ts +0 -1
- package/src/sandbox/provider-command-session.ts +0 -12
- package/src/sandbox/providers/modal-command-control.ts +8 -14
- package/src/sandbox/providers/modal-command-router-wire.ts +3 -20
- package/src/sandbox/providers/modal-command-session.ts +0 -11
- package/src/sandbox/providers/modal.ts +1 -5
- package/src/sandbox/routing/routing-session.ts +6 -61
- package/src/sandbox/turn-tool-cancellation.ts +1 -8
- package/dist/chunk-BK3S65CI.js.map +0 -1
- package/dist/chunk-PEEYZDLS.js.map +0 -1
- package/dist/responses-terminal-error.d.ts +0 -17
- package/src/bundled_default_skills/opengeni-client/references/usage-allowances.md +0 -189
- package/src/responses-terminal-error.ts +0 -136
|
@@ -12,11 +12,7 @@ import {
|
|
|
12
12
|
} from "@openai/agents";
|
|
13
13
|
import { isSearchableMcpFunctionTool, searchToolPool } from "./codex-tool-search";
|
|
14
14
|
import { MCP_MAX_TOOL_SEARCH_DISCLOSURE_BYTES } from "./mcp-network";
|
|
15
|
-
import {
|
|
16
|
-
beforeModelRequest,
|
|
17
|
-
modelResponseSettlement,
|
|
18
|
-
notifyModelRequestCapture,
|
|
19
|
-
} from "./model-request-capture";
|
|
15
|
+
import { notifyModelRequestCapture } from "./model-request-capture";
|
|
20
16
|
|
|
21
17
|
/** Provider-contained progressive-disclosure strategy for one resolved turn. */
|
|
22
18
|
export type LazyToolTransport = "codex_native" | "openai_native" | "generic_dispatch";
|
|
@@ -833,7 +829,6 @@ class LazyToolModel implements Model {
|
|
|
833
829
|
) {}
|
|
834
830
|
|
|
835
831
|
async getResponse(request: ModelRequest): Promise<ModelResponse> {
|
|
836
|
-
await beforeModelRequest();
|
|
837
832
|
const prepared = prepareLazyToolRequest(request, this.runtime);
|
|
838
833
|
rememberPreparedModelRequest(prepared);
|
|
839
834
|
void notifyModelRequestCapture(prepared);
|
|
@@ -847,7 +842,6 @@ class LazyToolModel implements Model {
|
|
|
847
842
|
}
|
|
848
843
|
|
|
849
844
|
async *getStreamedResponse(request: ModelRequest): AsyncIterable<StreamEvent> {
|
|
850
|
-
await beforeModelRequest();
|
|
851
845
|
const prepared = prepareLazyToolRequest(request, this.runtime);
|
|
852
846
|
rememberPreparedModelRequest(prepared);
|
|
853
847
|
void notifyModelRequestCapture(prepared);
|
|
@@ -857,21 +851,19 @@ class LazyToolModel implements Model {
|
|
|
857
851
|
await this.runtime.ensurePrepared();
|
|
858
852
|
}
|
|
859
853
|
}
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
void settlement?.catch(() => undefined);
|
|
874
|
-
yield delivered;
|
|
854
|
+
if (this.runtime.transport === "generic_dispatch" && event.type === "response_done") {
|
|
855
|
+
yield {
|
|
856
|
+
...event,
|
|
857
|
+
response: {
|
|
858
|
+
...event.response,
|
|
859
|
+
output: event.response.output.flatMap((item) =>
|
|
860
|
+
transformGenericDispatchCall(item, this.runtime),
|
|
861
|
+
) as typeof event.response.output,
|
|
862
|
+
},
|
|
863
|
+
} as StreamEvent;
|
|
864
|
+
} else {
|
|
865
|
+
yield event;
|
|
866
|
+
}
|
|
875
867
|
}
|
|
876
868
|
}
|
|
877
869
|
|
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CredentialProviderMcpMaterial,
|
|
3
3
|
normalizeCredentialProviderMcpUrl,
|
|
4
|
-
type McpServerConnectionRef,
|
|
5
4
|
} from "@opengeni/contracts";
|
|
6
5
|
|
|
7
|
-
export type RunMcpCredentialTarget = {
|
|
8
|
-
id: string;
|
|
9
|
-
url: string;
|
|
10
|
-
connectionRef?: McpServerConnectionRef | undefined;
|
|
11
|
-
};
|
|
6
|
+
export type RunMcpCredentialTarget = { id: string; url: string };
|
|
12
7
|
export type RunMcpCredentialMaterial = {
|
|
13
8
|
mcp?: CredentialProviderMcpMaterial;
|
|
14
9
|
expiresAt: Date | null;
|
|
@@ -48,9 +43,7 @@ export class RunMcpCredentials {
|
|
|
48
43
|
targets: readonly RunMcpCredentialTarget[],
|
|
49
44
|
options: { signal?: AbortSignal; now?: () => number } = {},
|
|
50
45
|
) {
|
|
51
|
-
this.#targets = targets
|
|
52
|
-
.filter((target) => !target.connectionRef)
|
|
53
|
-
.map(({ id, url }) => ({ id, url }));
|
|
46
|
+
this.#targets = targets.map(({ id, url }) => ({ id, url }));
|
|
54
47
|
this.#signal = options.signal;
|
|
55
48
|
this.#now = options.now ?? Date.now;
|
|
56
49
|
this.#signal?.addEventListener("abort", this.#onAbort, { once: true });
|
|
@@ -142,12 +135,11 @@ export class RunMcpCredentials {
|
|
|
142
135
|
this.prepare(material)();
|
|
143
136
|
}
|
|
144
137
|
|
|
145
|
-
/** Refuse credentials for
|
|
138
|
+
/** Refuse credentials for omitted, local, or rewritten server routes. */
|
|
146
139
|
assertRemoteTargets(targets: readonly RunMcpCredentialTarget[]): void {
|
|
147
140
|
this.#remoteTargets = this.#targets.filter((original) =>
|
|
148
141
|
targets.some(
|
|
149
142
|
(target) =>
|
|
150
|
-
!target.connectionRef &&
|
|
151
143
|
target.id === original.id &&
|
|
152
144
|
normalizedUrl(target.url) !== null &&
|
|
153
145
|
normalizedUrl(target.url) === normalizedUrl(original.url),
|
|
@@ -203,13 +195,6 @@ export class RunMcpCredentials {
|
|
|
203
195
|
init?: RequestInit,
|
|
204
196
|
): RequestInit | undefined {
|
|
205
197
|
this.#assertOpen();
|
|
206
|
-
// Native connection authority and attribution own all authentication on
|
|
207
|
-
// this route. Even a stale or manually supplied provider grant must never
|
|
208
|
-
// replace its bearer or inject alternate authentication headers.
|
|
209
|
-
if (target.connectionRef) {
|
|
210
|
-
this.excludeLocalTarget(target.id);
|
|
211
|
-
return init;
|
|
212
|
-
}
|
|
213
198
|
this.assertAvailable(target.id);
|
|
214
199
|
const entry = this.#entries.get(target.id);
|
|
215
200
|
if (!entry) return init;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
2
|
import { setTraceProcessors, type Span, type Trace, type TracingProcessor } from "@openai/agents";
|
|
3
|
-
import { beforeModelRequest } from "./model-request-capture";
|
|
4
3
|
|
|
5
4
|
export type ModelPreparationPhase =
|
|
6
5
|
| "sandbox_agent_preparation"
|
|
@@ -65,10 +64,6 @@ type ModelPreparationObservation = {
|
|
|
65
64
|
|
|
66
65
|
const modelPreparationObserver = new AsyncLocalStorage<ModelPreparationObservation>();
|
|
67
66
|
const modelTransportStartedObserver = new AsyncLocalStorage<() => Promise<void> | void>();
|
|
68
|
-
type ModelTransportAdmission = { refusal?: { error: unknown } };
|
|
69
|
-
type ModelTransportFetch = (...args: Parameters<typeof fetch>) => ReturnType<typeof fetch>;
|
|
70
|
-
const modelTransportAdmission = new AsyncLocalStorage<ModelTransportAdmission>();
|
|
71
|
-
const modelTransportRefusals = new WeakMap<Headers, { error: unknown }>();
|
|
72
67
|
|
|
73
68
|
class ModelPreparationTraceProcessor implements TracingProcessor {
|
|
74
69
|
async onTraceStart(_trace: Trace): Promise<void> {}
|
|
@@ -132,49 +127,7 @@ export function withModelTransportStartedObserver<T>(
|
|
|
132
127
|
}
|
|
133
128
|
|
|
134
129
|
export async function recordModelTransportStarted(): Promise<void> {
|
|
135
|
-
|
|
136
|
-
await beforeModelRequest();
|
|
137
|
-
await modelTransportStartedObserver.getStore()?.();
|
|
138
|
-
} catch (error) {
|
|
139
|
-
const admission = modelTransportAdmission.getStore();
|
|
140
|
-
if (admission) admission.refusal = { error };
|
|
141
|
-
throw error;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/** The OpenAI SDK retries thrown fetch errors and replaces their identity with
|
|
146
|
-
* APIConnectionError. Carry only our pre-wire refusal through its HTTP-error
|
|
147
|
-
* path, which honors the retry veto. Native transports keep the original throw.
|
|
148
|
-
* Each fetch owns its context even when concurrent turns share a cached client.
|
|
149
|
-
*/
|
|
150
|
-
export function sdkModelTransportAdmissionFetch(inner: ModelTransportFetch): ModelTransportFetch {
|
|
151
|
-
return async (input, init) => {
|
|
152
|
-
const admission: ModelTransportAdmission = {};
|
|
153
|
-
return modelTransportAdmission.run(admission, async () => {
|
|
154
|
-
try {
|
|
155
|
-
return await inner(input, init);
|
|
156
|
-
} catch (error) {
|
|
157
|
-
if (!admission.refusal || admission.refusal.error !== error) throw error;
|
|
158
|
-
// This is a local SDK handoff, not a provider or public API response.
|
|
159
|
-
// Identity, not response bytes/headers supplied by a provider, grants
|
|
160
|
-
// access to the original error at the SDK's status-error boundary.
|
|
161
|
-
const response = new Response(null, {
|
|
162
|
-
status: 400,
|
|
163
|
-
headers: { "x-should-retry": "false" },
|
|
164
|
-
});
|
|
165
|
-
modelTransportRefusals.set(response.headers, admission.refusal);
|
|
166
|
-
return response;
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/** Restore the exact host-owned error after the SDK has suppressed retries. */
|
|
173
|
-
export function rethrowModelTransportAdmissionRefusal(headers: Headers): void {
|
|
174
|
-
const refusal = modelTransportRefusals.get(headers);
|
|
175
|
-
if (!refusal) return;
|
|
176
|
-
modelTransportRefusals.delete(headers);
|
|
177
|
-
throw refusal.error;
|
|
130
|
+
await modelTransportStartedObserver.getStore()?.();
|
|
178
131
|
}
|
|
179
132
|
|
|
180
133
|
/** Record the first routed sandbox operation boundary without publishing an
|
|
@@ -29,10 +29,7 @@ import { ReplayableJsonOpenAI } from "./replayable-json-body";
|
|
|
29
29
|
import { recordModelTransportStarted } from "./model-preparation-diagnostics";
|
|
30
30
|
import { captureProviderRequestBody } from "./model-request-capture";
|
|
31
31
|
import { withoutQuotaExhaustedRetries } from "./provider-quota";
|
|
32
|
-
import {
|
|
33
|
-
observeClaudeUsageResponse,
|
|
34
|
-
prepareClaudeSubscriptionRequest,
|
|
35
|
-
} from "./claude-subscription-usage";
|
|
32
|
+
import { observeClaudeUsageResponse } from "./claude-subscription-usage";
|
|
36
33
|
|
|
37
34
|
let runtimeMetricsHooks: RuntimeMetricsHooks | null = null;
|
|
38
35
|
|
|
@@ -403,7 +400,6 @@ export function instrumentedModelFetch(provider: string, inner: typeof fetch): t
|
|
|
403
400
|
if (!isModelCallFetch(input)) {
|
|
404
401
|
return await inner(input, init);
|
|
405
402
|
}
|
|
406
|
-
init = await prepareClaudeSubscriptionRequest(provider, input, init);
|
|
407
403
|
// The attempt-local observer durably checkpoints provider dispatch before
|
|
408
404
|
// this process can place request bytes on the network.
|
|
409
405
|
await recordModelTransportStarted();
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
type ModelRequest,
|
|
9
9
|
type ResponseStreamEvent,
|
|
10
10
|
} from "@openai/agents";
|
|
11
|
-
import OpenAI
|
|
11
|
+
import OpenAI from "openai";
|
|
12
12
|
import { AnthropicMessagesModel } from "./anthropic-messages";
|
|
13
13
|
import { instrumentedModelFetch } from "./model-provider-client";
|
|
14
14
|
import { CODEX_MODEL_ID_PREFIX } from "@opengeni/codex";
|
|
@@ -16,10 +16,6 @@ import { XAI_SUBSCRIPTION_MODEL_ID_PREFIX } from "@opengeni/xai-subscription";
|
|
|
16
16
|
|
|
17
17
|
import { AppendOnlyOpenAIResponsesModel } from "./append-only-responses-model";
|
|
18
18
|
import { recordModelPreparationMeasurement } from "./model-preparation-diagnostics";
|
|
19
|
-
import {
|
|
20
|
-
ResponsesStreamingTerminalError,
|
|
21
|
-
responsesStreamingTerminalError,
|
|
22
|
-
} from "./responses-terminal-error";
|
|
23
19
|
import { buildProviderClient } from "./model-provider-client";
|
|
24
20
|
import {
|
|
25
21
|
CodexSubscriptionUnavailableError,
|
|
@@ -85,96 +81,6 @@ export class OpenGeniResponsesModel extends AppendOnlyOpenAIResponsesModel {
|
|
|
85
81
|
super(client, model);
|
|
86
82
|
}
|
|
87
83
|
|
|
88
|
-
protected override _fetchResponse(
|
|
89
|
-
request: ModelRequest,
|
|
90
|
-
stream: false,
|
|
91
|
-
): Promise<OpenAI.Responses.Response>;
|
|
92
|
-
protected _fetchResponse(
|
|
93
|
-
request: ModelRequest,
|
|
94
|
-
stream: true,
|
|
95
|
-
): Promise<AsyncIterable<OpenAI.Responses.ResponseStreamEvent>>;
|
|
96
|
-
protected async _fetchResponse(
|
|
97
|
-
request: ModelRequest,
|
|
98
|
-
stream: boolean,
|
|
99
|
-
): Promise<OpenAI.Responses.Response | AsyncIterable<OpenAI.Responses.ResponseStreamEvent>> {
|
|
100
|
-
if (!stream || !this.ownsResponsesTerminalClassification()) {
|
|
101
|
-
// Subscription transports retain the SDK's request-id and error handling.
|
|
102
|
-
return await super._fetchResponse(request, stream as false);
|
|
103
|
-
}
|
|
104
|
-
// Reuse the SDK's full request conversion, but retain its HTTP receipt
|
|
105
|
-
// before the SDK's stream wrapper discards the response headers.
|
|
106
|
-
const built = this._buildResponsesCreateRequest(request, true);
|
|
107
|
-
const internal = (request as ModelRequest & { _internal?: { runnerManagedRetry?: boolean } })
|
|
108
|
-
._internal;
|
|
109
|
-
const pending = this._client.responses.create(
|
|
110
|
-
built.requestData as OpenAI.Responses.ResponseCreateParamsStreaming,
|
|
111
|
-
{
|
|
112
|
-
headers: built.sdkRequestHeaders,
|
|
113
|
-
signal: built.signal,
|
|
114
|
-
...(built.transportExtraQuery ? { query: built.transportExtraQuery } : {}),
|
|
115
|
-
...(internal?.runnerManagedRetry === true ? { maxRetries: 0 } : {}),
|
|
116
|
-
},
|
|
117
|
-
);
|
|
118
|
-
if (typeof pending.withResponse !== "function") {
|
|
119
|
-
// The SDK also permits custom clients returning only the stream promise.
|
|
120
|
-
// Such clients cannot supply HTTP evidence, but must remain usable.
|
|
121
|
-
return this.classifiedResponseStream(await pending, new Headers(), null);
|
|
122
|
-
}
|
|
123
|
-
const receipt = await pending.withResponse();
|
|
124
|
-
return this.classifiedResponseStream(
|
|
125
|
-
receipt.data,
|
|
126
|
-
receipt.response.headers,
|
|
127
|
-
receipt.request_id,
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
private async *classifiedResponseStream(
|
|
132
|
-
stream: AsyncIterable<OpenAI.Responses.ResponseStreamEvent>,
|
|
133
|
-
headers: Headers,
|
|
134
|
-
requestId: string | null,
|
|
135
|
-
): AsyncIterable<OpenAI.Responses.ResponseStreamEvent> {
|
|
136
|
-
try {
|
|
137
|
-
for await (const event of stream) {
|
|
138
|
-
const failure = responsesStreamingTerminalError(event, headers);
|
|
139
|
-
if (failure) throw failure;
|
|
140
|
-
// response.done is supported by the pinned terminal reducer but absent
|
|
141
|
-
// from the OpenAI wire declaration.
|
|
142
|
-
const eventType: string = event.type;
|
|
143
|
-
if (
|
|
144
|
-
requestId &&
|
|
145
|
-
(eventType === "response.completed" || eventType === "response.done") &&
|
|
146
|
-
"response" in event &&
|
|
147
|
-
event.response &&
|
|
148
|
-
!("_request_id" in event.response)
|
|
149
|
-
) {
|
|
150
|
-
// Match the SDK's successful-terminal request-id attachment without
|
|
151
|
-
// making transport metadata enumerable in provider/model data.
|
|
152
|
-
try {
|
|
153
|
-
Object.defineProperty(event.response, "_request_id", {
|
|
154
|
-
value: requestId,
|
|
155
|
-
enumerable: false,
|
|
156
|
-
});
|
|
157
|
-
} catch {
|
|
158
|
-
// Frozen custom response objects remain usable, as in the SDK.
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
yield event;
|
|
162
|
-
}
|
|
163
|
-
} catch (error) {
|
|
164
|
-
// The OpenAI parser can throw a top-level `error` before yielding it.
|
|
165
|
-
// Convert inside the stream, before the Agents SDK's span error handler,
|
|
166
|
-
// so even enabled model tracing receives only the structural message.
|
|
167
|
-
if (error instanceof APIError && error.status === undefined && error.error) {
|
|
168
|
-
throw new ResponsesStreamingTerminalError("response.error", error.error, headers);
|
|
169
|
-
}
|
|
170
|
-
throw error;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
private ownsResponsesTerminalClassification(): boolean {
|
|
175
|
-
return this.provider.kind !== "codex-subscription" && this.provider.kind !== "xai-subscription";
|
|
176
|
-
}
|
|
177
|
-
|
|
178
84
|
protected override _buildResponsesCreateRequest(request: ModelRequest, stream: boolean) {
|
|
179
85
|
const startedAt = performance.now();
|
|
180
86
|
let outcome: "completed" | "failed" = "completed";
|
package/src/model-provider.ts
CHANGED
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
import { buildOpenAIClientFromSettings } from "./model-provider-client";
|
|
11
11
|
import { MultiProviderModelProvider } from "./model-provider-routing";
|
|
12
12
|
|
|
13
|
-
export { ResponsesStreamingTerminalError } from "./responses-terminal-error";
|
|
14
13
|
export {
|
|
15
14
|
CodexSubscriptionUnavailableError,
|
|
16
15
|
OrganizationGatewayUnavailableError,
|
|
@@ -14,27 +14,6 @@ export type ModelRequestCapture = ((request: ModelRequest) => void | Promise<voi
|
|
|
14
14
|
const modelRequestCapture = new AsyncLocalStorage<ModelRequestCapture>();
|
|
15
15
|
const captureIndices = new WeakMap<object, number>();
|
|
16
16
|
|
|
17
|
-
/** Awaited producer-side authority, separate from observational request capture. */
|
|
18
|
-
export type ModelCallLifecycle = {
|
|
19
|
-
beforeModelRequest?: () => Promise<void>;
|
|
20
|
-
/** Register before yielding so the next model entry waits for consumer settlement. */
|
|
21
|
-
onModelResponse?: (event: StreamEvent) => Promise<void>;
|
|
22
|
-
};
|
|
23
|
-
const modelCallLifecycle = new AsyncLocalStorage<ModelCallLifecycle>();
|
|
24
|
-
|
|
25
|
-
export function withModelCallLifecycle<T>(lifecycle: ModelCallLifecycle, fn: () => T): T {
|
|
26
|
-
return modelCallLifecycle.run(lifecycle, fn);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export async function beforeModelRequest(): Promise<void> {
|
|
30
|
-
await modelCallLifecycle.getStore()?.beforeModelRequest?.();
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function modelResponseSettlement(event: StreamEvent): Promise<void> | undefined {
|
|
34
|
-
if (event.type !== "response_done") return undefined;
|
|
35
|
-
return modelCallLifecycle.getStore()?.onModelResponse?.(event);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
17
|
/** The same agent can re-enter runAgentStream after in-activity compaction. */
|
|
39
18
|
export function nextModelContextCaptureIndex(agent: object): number {
|
|
40
19
|
const index = (captureIndices.get(agent) ?? 0) + 1;
|
|
@@ -154,21 +133,15 @@ export class ModelRequestCaptureModel implements Model {
|
|
|
154
133
|
constructor(private readonly inner: Model) {}
|
|
155
134
|
|
|
156
135
|
async getResponse(request: ModelRequest) {
|
|
157
|
-
await beforeModelRequest();
|
|
158
136
|
rememberPreparedModelRequest(request);
|
|
159
137
|
void notifyModelRequestCapture(request);
|
|
160
138
|
return this.inner.getResponse(request);
|
|
161
139
|
}
|
|
162
140
|
|
|
163
141
|
async *getStreamedResponse(request: ModelRequest): AsyncIterable<StreamEvent> {
|
|
164
|
-
await beforeModelRequest();
|
|
165
142
|
rememberPreparedModelRequest(request);
|
|
166
143
|
void notifyModelRequestCapture(request);
|
|
167
|
-
|
|
168
|
-
const settlement = modelResponseSettlement(event);
|
|
169
|
-
void settlement?.catch(() => undefined);
|
|
170
|
-
yield event;
|
|
171
|
-
}
|
|
144
|
+
yield* this.inner.getStreamedResponse(request);
|
|
172
145
|
}
|
|
173
146
|
|
|
174
147
|
getRetryAdvice(args: Parameters<NonNullable<Model["getRetryAdvice"]>>[0]) {
|
|
@@ -71,24 +71,6 @@ function isChatIncompatibleHostedToolCall(item: Record<string, unknown>): boolea
|
|
|
71
71
|
return item.type === "hosted_tool_call" && item.name !== "file_search_call";
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
/** The Chat SDK passes system content through instead of converting Responses
|
|
75
|
-
* text parts. Normalize only text-only content; preserve canonical input.
|
|
76
|
-
*/
|
|
77
|
-
function chatSystemContent(content: unknown): unknown {
|
|
78
|
-
if (
|
|
79
|
-
!Array.isArray(content) ||
|
|
80
|
-
!content.every(
|
|
81
|
-
(part) =>
|
|
82
|
-
part !== null &&
|
|
83
|
-
typeof part === "object" &&
|
|
84
|
-
(part.type === "input_text" || part.type === "output_text" || part.type === "text") &&
|
|
85
|
-
typeof part.text === "string",
|
|
86
|
-
)
|
|
87
|
-
)
|
|
88
|
-
return content;
|
|
89
|
-
return content.map((part) => part.text).join("\n");
|
|
90
|
-
}
|
|
91
|
-
|
|
92
74
|
/**
|
|
93
75
|
* Build the one attempt-local history view required by the target wire API.
|
|
94
76
|
* Canonical history remains untouched. SDK-unsupported developer messages use
|
|
@@ -132,12 +114,9 @@ export function projectHistoryForProvider(
|
|
|
132
114
|
|
|
133
115
|
let changed = false;
|
|
134
116
|
const projected = items.map((item) => {
|
|
135
|
-
if (item.type === "message" &&
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
changed = true;
|
|
139
|
-
return { ...item, role: "system", content };
|
|
140
|
-
}
|
|
117
|
+
if (item.type === "message" && item.role === "developer") {
|
|
118
|
+
changed = true;
|
|
119
|
+
return { ...item, role: "system" };
|
|
141
120
|
}
|
|
142
121
|
const resultId = item.type === "function_call_result" ? callId(item) : null;
|
|
143
122
|
if (
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
import OpenAI
|
|
1
|
+
import OpenAI from "openai";
|
|
2
2
|
import type { APIPromise } from "openai/core/api-promise";
|
|
3
3
|
import { types as utilTypes } from "node:util";
|
|
4
|
-
import {
|
|
5
|
-
rethrowModelTransportAdmissionRefusal,
|
|
6
|
-
sdkModelTransportAdmissionFetch,
|
|
7
|
-
} from "./model-preparation-diagnostics";
|
|
8
4
|
|
|
9
5
|
const TARGET_CHUNK_CHARS = 64 * 1024;
|
|
10
6
|
const LARGE_STRING_SOURCE_CHARS = 32 * 1024;
|
|
@@ -103,23 +99,10 @@ export class ReplayableJsonOpenAI extends OpenAI {
|
|
|
103
99
|
private readonly modelRequestPolicy: ModelJsonRequestPolicy | undefined;
|
|
104
100
|
|
|
105
101
|
constructor(options: OpenAIOptions, hooks: ReplayableJsonOpenAIHooks = {}) {
|
|
106
|
-
super(
|
|
107
|
-
...options,
|
|
108
|
-
fetch: sdkModelTransportAdmissionFetch(options?.fetch ?? globalThis.fetch),
|
|
109
|
-
});
|
|
102
|
+
super(options);
|
|
110
103
|
this.modelRequestPolicy = hooks.modelRequestPolicy;
|
|
111
104
|
}
|
|
112
105
|
|
|
113
|
-
protected override makeStatusError(
|
|
114
|
-
status: number,
|
|
115
|
-
error: NonNullable<Parameters<typeof APIError.generate>[1]>,
|
|
116
|
-
message: string | undefined,
|
|
117
|
-
headers: Headers,
|
|
118
|
-
): APIError {
|
|
119
|
-
rethrowModelTransportAdmissionRefusal(headers);
|
|
120
|
-
return super.makeStatusError(status, error, message, headers);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
106
|
override post<Rsp>(path: string, opts?: OpenAIPostOptions): APIPromise<Rsp> {
|
|
124
107
|
if (!isModelRequestPath(path) || opts === undefined) {
|
|
125
108
|
return super.post<Rsp>(path, opts);
|
package/src/sandbox/index.ts
CHANGED
|
@@ -592,7 +592,6 @@ export {
|
|
|
592
592
|
isRoutingMutationOutcomeUnknownError,
|
|
593
593
|
RoutingBackendRecoveryRequiredError,
|
|
594
594
|
RoutingMutationOutcomeUnknownError,
|
|
595
|
-
renderRoutingMutationOutcomeUnknownToolResult,
|
|
596
595
|
RoutingRetainedProcessNotFoundError,
|
|
597
596
|
RoutingSandboxSession,
|
|
598
597
|
RoutingWorkspaceRootChangedError,
|
|
@@ -42,18 +42,6 @@ export class ProviderCommandStartRejectedError extends Error {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
/** Start was attempted exactly once, but its acknowledgement is unavailable.
|
|
46
|
-
* The client-chosen locator is reconciliation authority, never replay authority. */
|
|
47
|
-
export class ProviderCommandStartOutcomeUnknownError extends Error {
|
|
48
|
-
constructor(
|
|
49
|
-
readonly command: ModalRouterProviderCommand,
|
|
50
|
-
cause: unknown,
|
|
51
|
-
) {
|
|
52
|
-
super("Provider command Start outcome is unknown; the invocation was not replayed", { cause });
|
|
53
|
-
this.name = "ProviderCommandStartOutcomeUnknownError";
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
45
|
export type ProviderCommandSession = {
|
|
58
46
|
verifyCommandSupervisionCapability?(): Promise<{ sandboxId: string; taskId: string }>;
|
|
59
47
|
releaseSupervisedCommand?(handle: number): Promise<void>;
|
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
admittedCommandSupervisionReady,
|
|
13
13
|
markPendingCommandSupervised,
|
|
14
14
|
reserveSupervisedLaunch,
|
|
15
|
-
ProviderCommandStartOutcomeUnknownError,
|
|
16
15
|
} from "../provider-command-session";
|
|
17
16
|
import {
|
|
18
17
|
ModalCommandControl as LegacyControl,
|
|
@@ -23,7 +22,6 @@ import {
|
|
|
23
22
|
ModalCommandRouterWire,
|
|
24
23
|
ModalCommandStartPreDispatchUnavailableError,
|
|
25
24
|
ModalCommandStartRejectedError,
|
|
26
|
-
ModalCommandStartNotDispatchedError,
|
|
27
25
|
} from "./modal-command-router-wire";
|
|
28
26
|
|
|
29
27
|
export { modalCommandAbortMiddleware } from "./modal-legacy-command-control";
|
|
@@ -210,11 +208,9 @@ export class ModalCommandControl {
|
|
|
210
208
|
},
|
|
211
209
|
};
|
|
212
210
|
if (supervision) await reserveSupervisedLaunch(command);
|
|
213
|
-
let startAttempted = false;
|
|
214
211
|
try {
|
|
215
|
-
await this.withRouter(taskId, signal,
|
|
216
|
-
|
|
217
|
-
await router.start(
|
|
212
|
+
await this.withRouter(taskId, signal, (router) =>
|
|
213
|
+
router.start(
|
|
218
214
|
{
|
|
219
215
|
taskId,
|
|
220
216
|
execId,
|
|
@@ -235,20 +231,18 @@ export class ModalCommandControl {
|
|
|
235
231
|
: {}),
|
|
236
232
|
},
|
|
237
233
|
signal,
|
|
238
|
-
)
|
|
239
|
-
|
|
234
|
+
),
|
|
235
|
+
);
|
|
240
236
|
} catch (error) {
|
|
241
|
-
// A client-chosen router id remains the only possible invocation.
|
|
242
|
-
//
|
|
243
|
-
//
|
|
237
|
+
// A client-chosen router id remains the only possible invocation. The
|
|
238
|
+
// supervisor is idle, so an ambiguous launch never ran user code. Retain
|
|
239
|
+
// the descriptor and reconcile that id; do not replay the start.
|
|
244
240
|
if (
|
|
245
|
-
!
|
|
246
|
-
error instanceof ModalCommandStartNotDispatchedError ||
|
|
241
|
+
!supervision ||
|
|
247
242
|
error instanceof ModalCommandStartRejectedError ||
|
|
248
243
|
error instanceof ModalCommandStartPreDispatchUnavailableError
|
|
249
244
|
)
|
|
250
245
|
throw error;
|
|
251
|
-
throw new ProviderCommandStartOutcomeUnknownError(command, error);
|
|
252
246
|
}
|
|
253
247
|
return command;
|
|
254
248
|
}
|
|
@@ -81,17 +81,6 @@ export class ModalCommandStartPreDispatchUnavailableError extends Error {
|
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
/** Local cancellation/closure before Start dispatch. This permits exact
|
|
85
|
-
* never-started reservation settlement, NOT another launch or turn recovery. */
|
|
86
|
-
export class ModalCommandStartNotDispatchedError extends Error {
|
|
87
|
-
constructor(cause: unknown) {
|
|
88
|
-
super(cause instanceof Error ? cause.message : "Modal command Start was never dispatched", {
|
|
89
|
-
cause,
|
|
90
|
-
});
|
|
91
|
-
this.name = "ModalCommandStartNotDispatchedError";
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
84
|
export type ModalRouterIdentity = { taskId: string; execId: string };
|
|
96
85
|
export type ModalRouterAccess = { url: string; jwt: string };
|
|
97
86
|
export type ModalRouterStart = ModalRouterIdentity & {
|
|
@@ -181,18 +170,12 @@ export class ModalCommandRouterWire {
|
|
|
181
170
|
}
|
|
182
171
|
|
|
183
172
|
async start(request: ModalRouterStart, signal?: AbortSignal): Promise<void> {
|
|
173
|
+
if (this.closed) throw new Error("Modal command router is closed");
|
|
184
174
|
try {
|
|
185
|
-
if (this.closed) throw new Error("Modal command router is closed");
|
|
186
175
|
await ModalCommandStartPreDispatchUnavailableError.ensureReady(this.client, signal);
|
|
187
|
-
signal?.throwIfAborted();
|
|
188
|
-
if (this.closed) throw new Error("Modal command router is closed");
|
|
189
176
|
} catch (error) {
|
|
190
|
-
if (this.closed)
|
|
191
|
-
|
|
192
|
-
new Error("Modal command router is closed", { cause: error }),
|
|
193
|
-
);
|
|
194
|
-
if (error instanceof ModalCommandStartPreDispatchUnavailableError) throw error;
|
|
195
|
-
throw new ModalCommandStartNotDispatchedError(error);
|
|
177
|
+
if (this.closed) throw new Error("Modal command router is closed", { cause: error });
|
|
178
|
+
throw error;
|
|
196
179
|
}
|
|
197
180
|
try {
|
|
198
181
|
await this.unary(
|
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
type ProviderCommandPersistence,
|
|
11
11
|
type ProviderCommandSession,
|
|
12
12
|
admittedProviderCommandHandle,
|
|
13
|
-
ProviderCommandStartOutcomeUnknownError,
|
|
14
13
|
} from "../provider-command-session";
|
|
15
14
|
import type { ModalCommandControl, ModalProviderCommand } from "./modal-command-control";
|
|
16
15
|
import { verifyModalMaterializedPath } from "./modal-materialization-verification";
|
|
@@ -247,16 +246,6 @@ export function installModalCommandSession(
|
|
|
247
246
|
exitCode: null,
|
|
248
247
|
});
|
|
249
248
|
}
|
|
250
|
-
} catch (error) {
|
|
251
|
-
if (error instanceof ProviderCommandStartOutcomeUnknownError) {
|
|
252
|
-
const entry = entries.get(handle);
|
|
253
|
-
if (entry && !sameExecution(entry.command, error.command))
|
|
254
|
-
throw new Error("Reserved Modal command changed during failed dispatch", {
|
|
255
|
-
cause: error,
|
|
256
|
-
});
|
|
257
|
-
entries.set(handle, entry ?? { command: error.command });
|
|
258
|
-
}
|
|
259
|
-
throw error;
|
|
260
249
|
} finally {
|
|
261
250
|
pendingStarts.delete(cancellation);
|
|
262
251
|
}
|
|
@@ -15,10 +15,7 @@ import { CAPABILITY_DESCRIPTORS } from "../capabilities";
|
|
|
15
15
|
import { SandboxChannelAService, type ChannelASession } from "../channel-a";
|
|
16
16
|
import { installModalCommandSession } from "./modal-command-session";
|
|
17
17
|
import { ModalCommandControl } from "./modal-command-control";
|
|
18
|
-
import {
|
|
19
|
-
ModalCommandStartPreDispatchUnavailableError,
|
|
20
|
-
ModalCommandStartNotDispatchedError,
|
|
21
|
-
} from "./modal-command-router-wire";
|
|
18
|
+
import { ModalCommandStartPreDispatchUnavailableError } from "./modal-command-router-wire";
|
|
22
19
|
import { createModalSessionWithLifecycle, type ModalCreateLifecycle } from "./modal-create-session";
|
|
23
20
|
import { isRoutingMutationOutcomeUnknownError } from "../routing/routing-session";
|
|
24
21
|
import type { ModalClient } from "modal";
|
|
@@ -266,7 +263,6 @@ export function isModalTaskExecStartPreDispatchUnavailableError(error: unknown):
|
|
|
266
263
|
try {
|
|
267
264
|
const record = current.value as Record<string, unknown>;
|
|
268
265
|
if (isRoutingMutationOutcomeUnknownError(current.value)) return false;
|
|
269
|
-
if (current.value instanceof ModalCommandStartNotDispatchedError) return false;
|
|
270
266
|
if (hasContradictoryModalHttpStatus(record)) return false;
|
|
271
267
|
|
|
272
268
|
// This instance is created only by the client's readiness gate before
|