@gajae-code/ai 0.15.5 → 0.16.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/CHANGELOG.md +40 -0
- package/dist/types/adapter-internals/aws-region.d.ts +7 -0
- package/dist/types/auth-broker/client.d.ts +6 -2
- package/dist/types/auth-broker/remote-store.d.ts +14 -2
- package/dist/types/auth-broker/types.d.ts +6 -0
- package/dist/types/auth-broker/wire-schemas.d.ts +19 -0
- package/dist/types/auth-gateway/server.d.ts +39 -5
- package/dist/types/auth-gateway/types.d.ts +16 -2
- package/dist/types/auth-storage.d.ts +92 -24
- package/dist/types/core.d.ts +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/provider-models/openai-compat.d.ts +1 -0
- package/dist/types/providers/anthropic.d.ts +1 -1
- package/dist/types/providers/google-gemini-headers.d.ts +1 -1
- package/dist/types/providers/openai-codex-responses.d.ts +6 -0
- package/dist/types/providers/register-builtins.d.ts +12 -12
- package/dist/types/stream.d.ts +2 -1
- package/dist/types/types.d.ts +22 -2
- package/dist/types/utils/oauth/api-key-login.d.ts +4 -1
- package/dist/types/utils/oauth/api-key-validation.d.ts +12 -6
- package/dist/types/utils/oauth/commandcode.d.ts +1 -0
- package/dist/types/utils/oauth/types.d.ts +1 -1
- package/dist/types/utils/retry.d.ts +2 -0
- package/dist/types/utils/schema/normalize.d.ts +0 -5
- package/dist/types/utils/sqlite-errors.d.ts +4 -0
- package/package.json +3 -3
- package/src/adapter-internals/aws-region.d.ts +7 -0
- package/src/adapter-internals/aws-region.ts +14 -0
- package/src/auth-broker/client.ts +41 -13
- package/src/auth-broker/redact.ts +25 -1
- package/src/auth-broker/remote-store.ts +374 -115
- package/src/auth-broker/server.ts +131 -91
- package/src/auth-broker/types.ts +6 -0
- package/src/auth-broker/wire-schemas.ts +6 -0
- package/src/auth-gateway/server.ts +447 -79
- package/src/auth-gateway/types.ts +28 -2
- package/src/auth-storage.ts +672 -168
- package/src/cli.ts +1 -0
- package/src/core.ts +1 -0
- package/src/index.ts +1 -0
- package/src/model-thinking.ts +8 -0
- package/src/models.json +1224 -3
- package/src/provider-models/descriptors.ts +3 -1
- package/src/provider-models/openai-compat.ts +102 -1
- package/src/providers/amazon-bedrock.ts +5 -1
- package/src/providers/anthropic.d.ts +1 -1
- package/src/providers/anthropic.ts +8 -2
- package/src/providers/aws-credentials.ts +6 -0
- package/src/providers/azure-openai-responses.ts +4 -1
- package/src/providers/cursor.ts +256 -101
- package/src/providers/gitlab-duo.ts +18 -1
- package/src/providers/google-gemini-cli.ts +3 -0
- package/src/providers/google-gemini-headers.d.ts +1 -1
- package/src/providers/google-gemini-headers.ts +1 -1
- package/src/providers/google-shared.ts +3 -0
- package/src/providers/kiro-api-key.ts +33 -8
- package/src/providers/kiro-codewhisperer.ts +28 -9
- package/src/providers/ollama.ts +3 -0
- package/src/providers/openai-codex-responses.d.ts +6 -0
- package/src/providers/openai-codex-responses.ts +37 -8
- package/src/providers/openai-completions.ts +11 -1
- package/src/providers/openai-responses.ts +10 -1
- package/src/providers/pi-native-client.ts +25 -1
- package/src/providers/pi-native-server.ts +24 -0
- package/src/providers/register-builtins.d.ts +12 -12
- package/src/providers/register-builtins.ts +16 -3
- package/src/stream.d.ts +2 -1
- package/src/stream.ts +175 -67
- package/src/types.d.ts +22 -2
- package/src/types.ts +27 -1
- package/src/utils/oauth/api-key-login.ts +13 -2
- package/src/utils/oauth/api-key-validation.ts +242 -41
- package/src/utils/oauth/commandcode.ts +17 -0
- package/src/utils/oauth/index.ts +20 -5
- package/src/utils/oauth/kiro.ts +91 -22
- package/src/utils/oauth/types.d.ts +1 -1
- package/src/utils/oauth/types.ts +1 -0
- package/src/utils/retry.d.ts +2 -0
- package/src/utils/retry.ts +15 -2
- package/src/utils/schema/dereference.ts +169 -49
- package/src/utils/schema/draft.ts +46 -23
- package/src/utils/schema/normalize.d.ts +0 -5
- package/src/utils/schema/normalize.ts +396 -119
- package/src/utils/schema/types.ts +3 -1
- package/src/utils/schema/zod-decontaminate.ts +83 -29
- package/src/utils/sqlite-errors.d.ts +4 -0
- package/src/utils/sqlite-errors.ts +13 -0
- package/src/utils/tool-choice-capability.ts +2 -3
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export const GEMINI_CLI_VERSION_ENV = "GJC_AI_GEMINI_CLI_VERSION";
|
|
7
7
|
export const LEGACY_GEMINI_CLI_VERSION_ENV = "PI_AI_GEMINI_CLI_VERSION";
|
|
8
|
-
export const DEFAULT_GEMINI_CLI_VERSION = "0.
|
|
8
|
+
export const DEFAULT_GEMINI_CLI_VERSION = "0.58.0";
|
|
9
9
|
|
|
10
10
|
export function getGeminiCliUserAgent(modelId = "gemini-3.1-pro-preview"): string {
|
|
11
11
|
const version =
|
|
@@ -921,6 +921,7 @@ export function streamGoogleGenAI<T extends "google-generative-ai" | "google-ver
|
|
|
921
921
|
options.toolChoice !== "auto" &&
|
|
922
922
|
options.toolChoice !== "none";
|
|
923
923
|
const fetchImpl = plan.fetch ?? options?.fetch ?? (globalThis.fetch.bind(globalThis) as FetchImpl);
|
|
924
|
+
options?.onStreamCreated?.();
|
|
924
925
|
let response = await fetchImpl(plan.url, {
|
|
925
926
|
method: "POST",
|
|
926
927
|
headers: { ...plan.headers, "Content-Type": "application/json", Accept: "text/event-stream" },
|
|
@@ -935,6 +936,7 @@ export function streamGoogleGenAI<T extends "google-generative-ai" | "google-ver
|
|
|
935
936
|
);
|
|
936
937
|
if (
|
|
937
938
|
!options?.fallbackManaged &&
|
|
939
|
+
!options?.disableProviderRetries &&
|
|
938
940
|
firstTokenTime === undefined &&
|
|
939
941
|
isForcedToolChoiceUnsupportedError(error, true)
|
|
940
942
|
) {
|
|
@@ -957,6 +959,7 @@ export function streamGoogleGenAI<T extends "google-generative-ai" | "google-ver
|
|
|
957
959
|
params = retryParams;
|
|
958
960
|
rawRequestDump = { ...rawRequestDump, body: params };
|
|
959
961
|
wireBody = paramsToWireBody(params);
|
|
962
|
+
options?.onStreamCreated?.();
|
|
960
963
|
response = await fetchImpl(plan.url, {
|
|
961
964
|
method: "POST",
|
|
962
965
|
headers: { ...plan.headers, "Content-Type": "application/json", Accept: "text/event-stream" },
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* AWS SSO OIDC / CodeWhisperer streaming path used by `gjc auth-broker login kiro`.
|
|
7
7
|
*/
|
|
8
8
|
import { $env } from "@gajae-code/utils";
|
|
9
|
+
import { assertAwsRegionLabel } from "../adapter-internals/aws-region";
|
|
9
10
|
import { Effort } from "../model-thinking";
|
|
10
11
|
import type {
|
|
11
12
|
Api,
|
|
@@ -53,19 +54,40 @@ export function isKiroApiKey(value: string | undefined): value is string {
|
|
|
53
54
|
|
|
54
55
|
export function kiroApiRegion(options?: { region?: string }): string {
|
|
55
56
|
return (
|
|
56
|
-
options?.region
|
|
57
|
-
$env.KIRO_API_REGION
|
|
58
|
-
$env.KIRO_REGION
|
|
59
|
-
$env.AWS_REGION
|
|
60
|
-
$env.AWS_DEFAULT_REGION
|
|
57
|
+
options?.region ??
|
|
58
|
+
$env.KIRO_API_REGION ??
|
|
59
|
+
$env.KIRO_REGION ??
|
|
60
|
+
$env.AWS_REGION ??
|
|
61
|
+
$env.AWS_DEFAULT_REGION ??
|
|
61
62
|
DEFAULT_REGION
|
|
62
63
|
);
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
export function kiroApiBaseUrl(region: string): string {
|
|
67
|
+
assertAwsRegionLabel(region);
|
|
66
68
|
return `https://q.${region}.amazonaws.com/`;
|
|
67
69
|
}
|
|
68
70
|
|
|
71
|
+
function isRegionDerivedKiroApiBaseUrl(baseUrl: string): boolean {
|
|
72
|
+
try {
|
|
73
|
+
const url = new URL(baseUrl);
|
|
74
|
+
const match = /^q\.([a-z0-9-]+)\.amazonaws\.com$/.exec(url.hostname);
|
|
75
|
+
if (!match) return false;
|
|
76
|
+
assertAwsRegionLabel(match[1]);
|
|
77
|
+
return (
|
|
78
|
+
url.protocol === "https:" &&
|
|
79
|
+
url.username === "" &&
|
|
80
|
+
url.password === "" &&
|
|
81
|
+
url.port === "" &&
|
|
82
|
+
url.pathname === "/" &&
|
|
83
|
+
url.search === "" &&
|
|
84
|
+
url.hash === ""
|
|
85
|
+
);
|
|
86
|
+
} catch {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
69
91
|
export function toKiroModelId(modelId: string): string {
|
|
70
92
|
return modelId.replace(/(\d)-(\d)/g, "$1.$2");
|
|
71
93
|
}
|
|
@@ -279,12 +301,13 @@ export async function fetchKiroApiModels(
|
|
|
279
301
|
apiKey: string,
|
|
280
302
|
region?: string,
|
|
281
303
|
): Promise<Model<"kiro-codewhisperer-stream">[]> {
|
|
282
|
-
const resolvedRegion = region
|
|
304
|
+
const resolvedRegion = region ?? kiroApiRegion();
|
|
283
305
|
const baseUrl = kiroApiBaseUrl(resolvedRegion);
|
|
284
306
|
const response = await fetch(baseUrl, {
|
|
285
307
|
method: "POST",
|
|
286
308
|
headers: kiroApiHeaders(apiKey, LIST_TARGET),
|
|
287
309
|
body: JSON.stringify({ origin: KIRO_ORIGIN }),
|
|
310
|
+
redirect: "error",
|
|
288
311
|
signal: AbortSignal.timeout(15_000),
|
|
289
312
|
});
|
|
290
313
|
if (!response.ok) {
|
|
@@ -585,8 +608,9 @@ export const streamKiroApiKey: StreamFunction<"kiro-codewhisperer-stream"> = (
|
|
|
585
608
|
"Kiro API key missing. Set KIRO_API_KEY to a ksk_ key from https://app.kiro.dev/settings/api-keys.",
|
|
586
609
|
);
|
|
587
610
|
}
|
|
588
|
-
const
|
|
589
|
-
const
|
|
611
|
+
const configuredBaseUrl = model.baseUrl;
|
|
612
|
+
const usesExplicitBaseUrl = Boolean(configuredBaseUrl) && !isRegionDerivedKiroApiBaseUrl(configuredBaseUrl);
|
|
613
|
+
const endpoint = configuredBaseUrl || kiroApiBaseUrl(kiroApiRegion(options));
|
|
590
614
|
const request = buildApiKeyRequest(model, context, options);
|
|
591
615
|
options?.onPayload?.(request, model, options?.attemptScope);
|
|
592
616
|
|
|
@@ -594,6 +618,7 @@ export const streamKiroApiKey: StreamFunction<"kiro-codewhisperer-stream"> = (
|
|
|
594
618
|
method: "POST",
|
|
595
619
|
headers: { ...kiroApiHeaders(apiKey, CHAT_TARGET), ...(options.headers ?? {}) },
|
|
596
620
|
body: JSON.stringify(request),
|
|
621
|
+
...(usesExplicitBaseUrl ? {} : { redirect: "error" as const }),
|
|
597
622
|
signal: options.signal,
|
|
598
623
|
});
|
|
599
624
|
if (!response.ok) {
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* not from any AGPL reference implementation.
|
|
12
12
|
*/
|
|
13
13
|
import { $credentialEnv, $env, extractHttpStatusFromError } from "@gajae-code/utils";
|
|
14
|
+
import { assertAwsRegionLabel } from "../adapter-internals/aws-region";
|
|
14
15
|
import type { Effort } from "../model-thinking";
|
|
15
16
|
import type {
|
|
16
17
|
Api,
|
|
@@ -29,7 +30,7 @@ import { transportFailureFacts } from "../utils/fallback-transport";
|
|
|
29
30
|
import { withHttpStatus } from "../utils/http-inspector";
|
|
30
31
|
import { captureUnicodeEscapeEvidence } from "../utils/json-parse";
|
|
31
32
|
import { decodeEventStream } from "./aws-eventstream";
|
|
32
|
-
import { isKiroApiKey, streamKiroApiKey } from "./kiro-api-key";
|
|
33
|
+
import { isKiroApiKey, streamKiroApiKey, toKiroModelId } from "./kiro-api-key";
|
|
33
34
|
|
|
34
35
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
35
36
|
// Provider options
|
|
@@ -67,6 +68,7 @@ interface WireToolResult {
|
|
|
67
68
|
interface WireUserMessage {
|
|
68
69
|
userInputMessage: {
|
|
69
70
|
content: string;
|
|
71
|
+
modelId?: string;
|
|
70
72
|
userInputMessageContext?: {
|
|
71
73
|
tools?: { tools: WireToolSpec[] };
|
|
72
74
|
toolResults?: { toolResults: WireToolResult[][] };
|
|
@@ -177,9 +179,10 @@ export const streamKiroCodeWhisperer: StreamFunction<"kiro-codewhisperer-stream"
|
|
|
177
179
|
};
|
|
178
180
|
|
|
179
181
|
const blocks = output.content as Block[];
|
|
180
|
-
const region = options.region
|
|
182
|
+
const region = options.region ?? $env.KIRO_REGION ?? $env.AWS_REGION ?? $env.AWS_DEFAULT_REGION ?? DEFAULT_REGION;
|
|
181
183
|
|
|
182
184
|
try {
|
|
185
|
+
assertAwsRegionLabel(region);
|
|
183
186
|
// Resolve bearer token
|
|
184
187
|
const bearerToken = resolveBearerToken(options.apiKey);
|
|
185
188
|
if (!bearerToken) {
|
|
@@ -221,6 +224,7 @@ export const streamKiroCodeWhisperer: StreamFunction<"kiro-codewhisperer-stream"
|
|
|
221
224
|
method: "POST",
|
|
222
225
|
headers: requestHeaders,
|
|
223
226
|
body,
|
|
227
|
+
redirect: "error",
|
|
224
228
|
signal: options.signal,
|
|
225
229
|
});
|
|
226
230
|
|
|
@@ -353,7 +357,7 @@ export const streamKiroCodeWhisperer: StreamFunction<"kiro-codewhisperer-stream"
|
|
|
353
357
|
|
|
354
358
|
function buildConversationState(
|
|
355
359
|
context: Context,
|
|
356
|
-
|
|
360
|
+
model: Model<"kiro-codewhisperer-stream">,
|
|
357
361
|
options: KiroCodeWhispererOptions,
|
|
358
362
|
): ConversationState {
|
|
359
363
|
const messages = context.messages;
|
|
@@ -361,18 +365,24 @@ function buildConversationState(
|
|
|
361
365
|
throw new Error("Kiro CodeWhisperer requires at least one message");
|
|
362
366
|
}
|
|
363
367
|
|
|
368
|
+
// Normalize the local dashed selector/wire id (e.g. "claude-haiku-4-5") to
|
|
369
|
+
// the canonical dotted upstream Kiro model id (e.g. "claude-haiku-4.5"),
|
|
370
|
+
// matching the sibling ksk_ API-key transport (kiro-api-key.ts) so both
|
|
371
|
+
// auth methods send the same wire form for the same catalog entry.
|
|
372
|
+
const modelId = toKiroModelId(model.wireModelId || model.id);
|
|
373
|
+
|
|
364
374
|
// Build history from all messages except the last
|
|
365
375
|
const history: WireHistoryMessage[] = [];
|
|
366
376
|
const systemPrompt = context.systemPrompt?.join("\n") ?? "";
|
|
367
377
|
|
|
368
378
|
for (let i = 0; i < messages.length - 1; i++) {
|
|
369
379
|
const msg = messages[i];
|
|
370
|
-
history.push(convertToWireMessage(msg, i === 0 ? systemPrompt : undefined));
|
|
380
|
+
history.push(convertToWireMessage(msg, modelId, i === 0 ? systemPrompt : undefined));
|
|
371
381
|
}
|
|
372
382
|
|
|
373
383
|
// Convert the last message as currentMessage
|
|
374
384
|
const lastMsg = messages[messages.length - 1];
|
|
375
|
-
const currentMessage = convertToWireUserMessage(lastMsg, systemPrompt);
|
|
385
|
+
const currentMessage = convertToWireUserMessage(lastMsg, modelId, systemPrompt);
|
|
376
386
|
|
|
377
387
|
// Add tools to the current message context
|
|
378
388
|
if (context.tools && context.tools.length > 0) {
|
|
@@ -392,12 +402,16 @@ function buildConversationState(
|
|
|
392
402
|
};
|
|
393
403
|
}
|
|
394
404
|
|
|
395
|
-
function convertToWireMessage(
|
|
405
|
+
function convertToWireMessage(
|
|
406
|
+
msg: Context["messages"][number],
|
|
407
|
+
modelId: string,
|
|
408
|
+
systemPrompt?: string,
|
|
409
|
+
): WireHistoryMessage {
|
|
396
410
|
if (msg.role === "user") {
|
|
397
|
-
return convertToWireUserMessage(msg, systemPrompt);
|
|
411
|
+
return convertToWireUserMessage(msg, modelId, systemPrompt);
|
|
398
412
|
}
|
|
399
413
|
if (msg.role === "toolResult") {
|
|
400
|
-
return convertToWireUserMessage(msg, systemPrompt);
|
|
414
|
+
return convertToWireUserMessage(msg, modelId, systemPrompt);
|
|
401
415
|
}
|
|
402
416
|
// assistant → assistant response
|
|
403
417
|
const textParts: string[] = [];
|
|
@@ -417,7 +431,11 @@ function convertToWireMessage(msg: Context["messages"][number], systemPrompt?: s
|
|
|
417
431
|
};
|
|
418
432
|
}
|
|
419
433
|
|
|
420
|
-
function convertToWireUserMessage(
|
|
434
|
+
function convertToWireUserMessage(
|
|
435
|
+
msg: Context["messages"][number],
|
|
436
|
+
modelId: string,
|
|
437
|
+
systemPrompt?: string,
|
|
438
|
+
): WireUserMessage {
|
|
421
439
|
let content = extractTextContent(msg);
|
|
422
440
|
if (systemPrompt) {
|
|
423
441
|
content = `${systemPrompt}\n\n${content}`;
|
|
@@ -426,6 +444,7 @@ function convertToWireUserMessage(msg: Context["messages"][number], systemPrompt
|
|
|
426
444
|
const userMsg: WireUserMessage = {
|
|
427
445
|
userInputMessage: {
|
|
428
446
|
content,
|
|
447
|
+
modelId,
|
|
429
448
|
},
|
|
430
449
|
};
|
|
431
450
|
|
package/src/providers/ollama.ts
CHANGED
|
@@ -419,6 +419,7 @@ export const streamOllama: StreamFunction<"ollama-chat"> = (
|
|
|
419
419
|
url: `${baseUrl}/api/chat`,
|
|
420
420
|
body,
|
|
421
421
|
};
|
|
422
|
+
options?.onStreamCreated?.();
|
|
422
423
|
let response = await fetchWithRetry(`${baseUrl}/api/chat`, {
|
|
423
424
|
method: "POST",
|
|
424
425
|
headers: {
|
|
@@ -441,6 +442,7 @@ export const streamOllama: StreamFunction<"ollama-chat"> = (
|
|
|
441
442
|
if (
|
|
442
443
|
firstTokenTime === undefined &&
|
|
443
444
|
!options.fallbackManaged &&
|
|
445
|
+
!options.disableProviderRetries &&
|
|
444
446
|
isForcedToolChoiceUnsupportedError(error, true)
|
|
445
447
|
) {
|
|
446
448
|
markToolChoiceIncapability(model, "auto", error.message);
|
|
@@ -457,6 +459,7 @@ export const streamOllama: StreamFunction<"ollama-chat"> = (
|
|
|
457
459
|
body = { ...body };
|
|
458
460
|
delete (body as { tool_choice?: unknown }).tool_choice;
|
|
459
461
|
rawRequestDump = { ...rawRequestDump, body };
|
|
462
|
+
options?.onStreamCreated?.();
|
|
460
463
|
response = await fetchWithRetry(`${baseUrl}/api/chat`, {
|
|
461
464
|
method: "POST",
|
|
462
465
|
headers: {
|
|
@@ -25,6 +25,12 @@ export declare function normalizeCodexToolChoice(choice: ToolChoice | undefined,
|
|
|
25
25
|
export declare function formatCodexUserAgent(platform: string, release: string, arch: string): string;
|
|
26
26
|
export declare const streamOpenAICodexResponses: StreamFunction<"openai-codex-responses">;
|
|
27
27
|
export declare function prewarmOpenAICodexResponses(model: Model<"openai-codex-responses">, options?: Pick<OpenAICodexResponsesOptions, "apiKey" | "headers" | "sessionId" | "signal" | "preferWebsockets" | "providerSessionState">): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Bun 1.4.0's Windows WebSocket client can segfault during TLS handshakes.
|
|
30
|
+
* Keep the model's websocket preference available on other platforms, while
|
|
31
|
+
* requiring an explicit opt-in on Windows until the bundled runtime is fixed.
|
|
32
|
+
*/
|
|
33
|
+
export declare function isCodexWebSocketSafeByDefault(platform?: NodeJS.Platform): boolean;
|
|
28
34
|
export interface OpenAICodexTransportDetails {
|
|
29
35
|
websocketPreferred: boolean;
|
|
30
36
|
lastTransport?: CodexTransport;
|
|
@@ -844,6 +844,7 @@ async function openInitialCodexEventStream(
|
|
|
844
844
|
if (websocketState && shouldUseCodexWebSocket(model, websocketState, options?.preferWebsockets)) {
|
|
845
845
|
const websocketRetryBudget = getCodexWebSocketRetryBudget(options);
|
|
846
846
|
let websocketRetries = 0;
|
|
847
|
+
let lastWebsocketError: Error | undefined;
|
|
847
848
|
while (true) {
|
|
848
849
|
try {
|
|
849
850
|
return await openCodexWebSocketTransport(
|
|
@@ -855,6 +856,7 @@ async function openInitialCodexEventStream(
|
|
|
855
856
|
);
|
|
856
857
|
} catch (error) {
|
|
857
858
|
const websocketError = error instanceof Error ? error : new Error(String(error));
|
|
859
|
+
lastWebsocketError = websocketError;
|
|
858
860
|
const isFatal = isCodexWebSocketFatalError(websocketError);
|
|
859
861
|
const activateFallback = isFatal || websocketRetries >= websocketRetryBudget;
|
|
860
862
|
recordCodexWebSocketFailure(websocketState, activateFallback);
|
|
@@ -875,6 +877,9 @@ async function openInitialCodexEventStream(
|
|
|
875
877
|
break;
|
|
876
878
|
}
|
|
877
879
|
}
|
|
880
|
+
if (options?.fallbackManaged || options?.disableProviderRetries) {
|
|
881
|
+
throw lastWebsocketError ?? new Error("Codex websocket transport failed");
|
|
882
|
+
}
|
|
878
883
|
}
|
|
879
884
|
return openCodexSseTransport(model, requestContext, requestSetup, options, websocketState, transformedBody);
|
|
880
885
|
}
|
|
@@ -1739,6 +1744,7 @@ async function tryRetryWithoutForcedToolChoice(
|
|
|
1739
1744
|
): Promise<boolean> {
|
|
1740
1745
|
if (
|
|
1741
1746
|
context.options?.fallbackManaged ||
|
|
1747
|
+
context.options?.disableProviderRetries ||
|
|
1742
1748
|
runtime.toolChoiceFallbackAttempted ||
|
|
1743
1749
|
context.output.content.length > 0 ||
|
|
1744
1750
|
context.firstTokenTime !== undefined ||
|
|
@@ -1842,7 +1848,8 @@ async function tryReconnectCodexWebSocketOnConnectionLimit(
|
|
|
1842
1848
|
!websocketState ||
|
|
1843
1849
|
runtime.transport !== "websocket" ||
|
|
1844
1850
|
context.options?.signal?.aborted ||
|
|
1845
|
-
context.options?.fallbackManaged
|
|
1851
|
+
context.options?.fallbackManaged ||
|
|
1852
|
+
context.options?.disableProviderRetries
|
|
1846
1853
|
) {
|
|
1847
1854
|
return false;
|
|
1848
1855
|
}
|
|
@@ -1905,6 +1912,7 @@ async function tryRecoverCodexPreviousResponseNotFound(
|
|
|
1905
1912
|
runtime.previousResponseRecoveryAttempted ||
|
|
1906
1913
|
!websocketState ||
|
|
1907
1914
|
context.options?.fallbackManaged ||
|
|
1915
|
+
context.options?.disableProviderRetries ||
|
|
1908
1916
|
runtime.transport !== "websocket" ||
|
|
1909
1917
|
context.output.content.length > 0 ||
|
|
1910
1918
|
context.options?.signal?.aborted ||
|
|
@@ -1945,7 +1953,8 @@ async function tryReplayWebsocketFailureOverSse(
|
|
|
1945
1953
|
runtime.canSafelyReplayWebsocketOverSse &&
|
|
1946
1954
|
!runtime.sawTerminalEvent &&
|
|
1947
1955
|
!context.options?.signal?.aborted &&
|
|
1948
|
-
!context.options?.fallbackManaged
|
|
1956
|
+
!context.options?.fallbackManaged &&
|
|
1957
|
+
!context.options?.disableProviderRetries;
|
|
1949
1958
|
if (!canReplay) return false;
|
|
1950
1959
|
|
|
1951
1960
|
const state = websocketState;
|
|
@@ -1999,7 +2008,8 @@ async function tryRetryCodexProviderError(
|
|
|
1999
2008
|
context.output.content.length > 0 ||
|
|
2000
2009
|
runtime.providerRetryAttempt >= resolveRetryBudget(context.options?.streamMaxRetries, CODEX_MAX_RETRIES) ||
|
|
2001
2010
|
context.options?.signal?.aborted ||
|
|
2002
|
-
context.options?.fallbackManaged
|
|
2011
|
+
context.options?.fallbackManaged ||
|
|
2012
|
+
context.options?.disableProviderRetries
|
|
2003
2013
|
) {
|
|
2004
2014
|
return false;
|
|
2005
2015
|
}
|
|
@@ -2119,7 +2129,7 @@ export const streamOpenAICodexResponses: StreamFunction<"openai-codex-responses"
|
|
|
2119
2129
|
try {
|
|
2120
2130
|
initialTransport = await openInitialCodexEventStream(model, streamOptions, requestSetup, requestContext);
|
|
2121
2131
|
} catch (error) {
|
|
2122
|
-
if (streamOptions.fallbackManaged) throw error;
|
|
2132
|
+
if (streamOptions.fallbackManaged || streamOptions.disableProviderRetries) throw error;
|
|
2123
2133
|
initialTransport = await retryCodexInitialTransportWithoutToolChoice(
|
|
2124
2134
|
model,
|
|
2125
2135
|
streamOptions,
|
|
@@ -2297,6 +2307,15 @@ function recordCodexWebSocketFailure(state: CodexWebSocketSessionState, activate
|
|
|
2297
2307
|
}
|
|
2298
2308
|
}
|
|
2299
2309
|
|
|
2310
|
+
/**
|
|
2311
|
+
* Bun 1.4.0's Windows WebSocket client can segfault during TLS handshakes.
|
|
2312
|
+
* Keep the model's websocket preference available on other platforms, while
|
|
2313
|
+
* requiring an explicit opt-in on Windows until the bundled runtime is fixed.
|
|
2314
|
+
*/
|
|
2315
|
+
export function isCodexWebSocketSafeByDefault(platform: NodeJS.Platform = process.platform): boolean {
|
|
2316
|
+
return platform !== "win32";
|
|
2317
|
+
}
|
|
2318
|
+
|
|
2300
2319
|
function shouldUseCodexWebSocket(
|
|
2301
2320
|
model: Model<"openai-codex-responses">,
|
|
2302
2321
|
state: CodexWebSocketSessionState | undefined,
|
|
@@ -2304,7 +2323,11 @@ function shouldUseCodexWebSocket(
|
|
|
2304
2323
|
): boolean {
|
|
2305
2324
|
if (!state || state.disableWebsocket) return false;
|
|
2306
2325
|
if (preferWebsockets === false) return false;
|
|
2307
|
-
return
|
|
2326
|
+
return (
|
|
2327
|
+
isCodexWebSocketEnvEnabled() ||
|
|
2328
|
+
preferWebsockets === true ||
|
|
2329
|
+
(isCodexWebSocketSafeByDefault() && model.preferWebsockets === true)
|
|
2330
|
+
);
|
|
2308
2331
|
}
|
|
2309
2332
|
|
|
2310
2333
|
export interface OpenAICodexTransportDetails {
|
|
@@ -2362,7 +2385,9 @@ export function getOpenAICodexTransportDetails(
|
|
|
2362
2385
|
const websocketPreferred =
|
|
2363
2386
|
options?.preferWebsockets === false
|
|
2364
2387
|
? false
|
|
2365
|
-
: isCodexWebSocketEnvEnabled() ||
|
|
2388
|
+
: isCodexWebSocketEnvEnabled() ||
|
|
2389
|
+
options?.preferWebsockets === true ||
|
|
2390
|
+
(isCodexWebSocketSafeByDefault() && model.preferWebsockets === true);
|
|
2366
2391
|
const state = getCodexWebSocketStateForPublicSession(model, options);
|
|
2367
2392
|
|
|
2368
2393
|
return {
|
|
@@ -2633,6 +2658,7 @@ class CodexWebSocketConnection {
|
|
|
2633
2658
|
signal?: AbortSignal,
|
|
2634
2659
|
firstEventTimeoutMs?: number,
|
|
2635
2660
|
idleTimeoutMs = this.#idleTimeoutMs,
|
|
2661
|
+
onStreamCreated?: () => void,
|
|
2636
2662
|
): AsyncGenerator<Record<string, unknown>> {
|
|
2637
2663
|
if (!this.#socket || this.#socket.readyState !== WebSocket.OPEN) {
|
|
2638
2664
|
throw createCodexWebSocketTransportError("websocket connection is unavailable");
|
|
@@ -2654,6 +2680,7 @@ class CodexWebSocketConnection {
|
|
|
2654
2680
|
}
|
|
2655
2681
|
|
|
2656
2682
|
try {
|
|
2683
|
+
onStreamCreated?.();
|
|
2657
2684
|
this.#socket.send(JSON.stringify(request));
|
|
2658
2685
|
let sawFirstProgress = false;
|
|
2659
2686
|
const startedAt = Date.now();
|
|
@@ -2795,7 +2822,7 @@ async function openCodexSseEventStream(
|
|
|
2795
2822
|
signal?: AbortSignal,
|
|
2796
2823
|
onSseEvent?: OpenAICodexResponsesOptions["onSseEvent"],
|
|
2797
2824
|
fetchOverride?: FetchImpl,
|
|
2798
|
-
options?: Pick<OpenAICodexResponsesOptions, "requestMaxRetries">,
|
|
2825
|
+
options?: Pick<OpenAICodexResponsesOptions, "requestMaxRetries" | "onStreamCreated">,
|
|
2799
2826
|
): Promise<AsyncGenerator<Record<string, unknown>>> {
|
|
2800
2827
|
const headers = createCodexHeaders(requestHeaders, accountId, apiKey, sessionId, "sse", state);
|
|
2801
2828
|
logCodexDebug("codex request", {
|
|
@@ -2805,6 +2832,7 @@ async function openCodexSseEventStream(
|
|
|
2805
2832
|
sentTurnStateHeader: headers.has(X_CODEX_TURN_STATE_HEADER),
|
|
2806
2833
|
sentModelsEtagHeader: headers.has(X_MODELS_ETAG_HEADER),
|
|
2807
2834
|
});
|
|
2835
|
+
options?.onStreamCreated?.();
|
|
2808
2836
|
const response = await fetchWithRetry(url, {
|
|
2809
2837
|
method: "POST",
|
|
2810
2838
|
headers,
|
|
@@ -2845,7 +2873,7 @@ async function openCodexWebSocketEventStream(
|
|
|
2845
2873
|
request: Record<string, unknown>,
|
|
2846
2874
|
state: CodexWebSocketSessionState,
|
|
2847
2875
|
signal?: AbortSignal,
|
|
2848
|
-
options?: Pick<OpenAICodexResponsesOptions, "streamFirstEventTimeoutMs" | "streamIdleTimeoutMs">,
|
|
2876
|
+
options?: Pick<OpenAICodexResponsesOptions, "streamFirstEventTimeoutMs" | "streamIdleTimeoutMs" | "onStreamCreated">,
|
|
2849
2877
|
firstEventTimeoutMs?: number,
|
|
2850
2878
|
): Promise<AsyncGenerator<Record<string, unknown>>> {
|
|
2851
2879
|
const connection = await getOrCreateCodexWebSocketConnection(state, url, headers, signal, options);
|
|
@@ -2854,6 +2882,7 @@ async function openCodexWebSocketEventStream(
|
|
|
2854
2882
|
signal,
|
|
2855
2883
|
firstEventTimeoutMs,
|
|
2856
2884
|
getCodexWebSocketIdleTimeoutMs(options?.streamIdleTimeoutMs),
|
|
2885
|
+
options?.onStreamCreated,
|
|
2857
2886
|
);
|
|
2858
2887
|
}
|
|
2859
2888
|
|
|
@@ -636,6 +636,7 @@ export const streamOpenAICompletions: StreamFunction<"openai-completions"> = (
|
|
|
636
636
|
headers: requestHeaders,
|
|
637
637
|
body: params,
|
|
638
638
|
};
|
|
639
|
+
options?.onStreamCreated?.();
|
|
639
640
|
const { data, response, request_id } = await client.chat.completions
|
|
640
641
|
.create(params as OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming, { signal: requestSignal })
|
|
641
642
|
.withResponse();
|
|
@@ -648,6 +649,8 @@ export const streamOpenAICompletions: StreamFunction<"openai-completions"> = (
|
|
|
648
649
|
provider: model.provider,
|
|
649
650
|
signal: requestSignal,
|
|
650
651
|
fallbackManaged: options?.fallbackManaged,
|
|
652
|
+
requestMaxRetries: options?.requestMaxRetries,
|
|
653
|
+
disableProviderRetries: options?.disableProviderRetries,
|
|
651
654
|
});
|
|
652
655
|
} catch (error) {
|
|
653
656
|
const capturedErrorResponse = getCapturedErrorResponse();
|
|
@@ -656,6 +659,7 @@ export const streamOpenAICompletions: StreamFunction<"openai-completions"> = (
|
|
|
656
659
|
);
|
|
657
660
|
if (
|
|
658
661
|
!options?.fallbackManaged &&
|
|
662
|
+
!options?.disableProviderRetries &&
|
|
659
663
|
firstTokenTime === undefined &&
|
|
660
664
|
isForcedToolChoiceUnsupportedError(error, sentForcedToolChoice)
|
|
661
665
|
) {
|
|
@@ -675,6 +679,7 @@ export const streamOpenAICompletions: StreamFunction<"openai-completions"> = (
|
|
|
675
679
|
openaiStream = await createCompletionsStream();
|
|
676
680
|
} else if (
|
|
677
681
|
!options?.fallbackManaged &&
|
|
682
|
+
!options?.disableProviderRetries &&
|
|
678
683
|
isOpenRouterAnthropicModel(model) &&
|
|
679
684
|
!disableStrictTools &&
|
|
680
685
|
isCompiledGrammarTooLargeStrictError(error, capturedErrorResponse)
|
|
@@ -689,6 +694,7 @@ export const streamOpenAICompletions: StreamFunction<"openai-completions"> = (
|
|
|
689
694
|
} else {
|
|
690
695
|
if (
|
|
691
696
|
options?.fallbackManaged ||
|
|
697
|
+
options?.disableProviderRetries ||
|
|
692
698
|
!shouldRetryWithoutStrictTools(error, capturedErrorResponse, appliedToolStrictMode, context.tools)
|
|
693
699
|
) {
|
|
694
700
|
throw error;
|
|
@@ -733,7 +739,11 @@ export const streamOpenAICompletions: StreamFunction<"openai-completions"> = (
|
|
|
733
739
|
continue;
|
|
734
740
|
}
|
|
735
741
|
replaySafeChunks.push(chunk);
|
|
736
|
-
if (
|
|
742
|
+
if (
|
|
743
|
+
hasNetworkErrorFinishReason(chunk) &&
|
|
744
|
+
!options?.fallbackManaged &&
|
|
745
|
+
!options?.disableProviderRetries
|
|
746
|
+
) {
|
|
737
747
|
retryNetworkError = true;
|
|
738
748
|
break;
|
|
739
749
|
}
|
|
@@ -402,16 +402,24 @@ export const streamOpenAIResponses: StreamFunction<"openai-responses"> = (
|
|
|
402
402
|
};
|
|
403
403
|
const openaiStream = await callWithCopilotModelRetry(
|
|
404
404
|
async () => {
|
|
405
|
+
options?.onStreamCreated?.();
|
|
405
406
|
const { data, response, request_id } = await client.responses
|
|
406
407
|
.create(params, { signal: requestSignal })
|
|
407
408
|
.withResponse();
|
|
408
409
|
await notifyProviderResponse(options, response, model, request_id);
|
|
409
410
|
return data;
|
|
410
411
|
},
|
|
411
|
-
{
|
|
412
|
+
{
|
|
413
|
+
provider: model.provider,
|
|
414
|
+
signal: requestSignal,
|
|
415
|
+
fallbackManaged: options?.fallbackManaged,
|
|
416
|
+
requestMaxRetries: options?.requestMaxRetries,
|
|
417
|
+
disableProviderRetries: options?.disableProviderRetries,
|
|
418
|
+
},
|
|
412
419
|
).catch(async error => {
|
|
413
420
|
if (
|
|
414
421
|
options?.fallbackManaged ||
|
|
422
|
+
options?.disableProviderRetries ||
|
|
415
423
|
!isForcedToolChoiceUnsupportedError(error, isForcedOpenAIResponsesToolChoice(params.tool_choice))
|
|
416
424
|
) {
|
|
417
425
|
throw error;
|
|
@@ -431,6 +439,7 @@ export const streamOpenAIResponses: StreamFunction<"openai-responses"> = (
|
|
|
431
439
|
});
|
|
432
440
|
delete params.tool_choice;
|
|
433
441
|
if (rawRequestDump) rawRequestDump.body = params;
|
|
442
|
+
options?.onStreamCreated?.();
|
|
434
443
|
const { data, response, request_id } = await client.responses
|
|
435
444
|
.create(params, { signal: requestSignal })
|
|
436
445
|
.withResponse();
|
|
@@ -37,6 +37,7 @@ import { AssistantMessageEventStream } from "../utils/event-stream";
|
|
|
37
37
|
const NON_WIRE_KEYS = new Set<keyof SimpleStreamOptions>([
|
|
38
38
|
"signal",
|
|
39
39
|
"apiKey",
|
|
40
|
+
"onStreamCreated",
|
|
40
41
|
"fetch",
|
|
41
42
|
"onPayload",
|
|
42
43
|
"onResponse",
|
|
@@ -48,6 +49,29 @@ const NON_WIRE_KEYS = new Set<keyof SimpleStreamOptions>([
|
|
|
48
49
|
"fallbackAttempt",
|
|
49
50
|
]);
|
|
50
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Project the caller's {@link Context} onto the wire schema. Runtime tool
|
|
54
|
+
* objects routinely carry harness-only state (runners, session managers,
|
|
55
|
+
* fs-stat BigInts) that must never be serialized: BigInt fields make
|
|
56
|
+
* `JSON.stringify` throw outright, and the rest is dead weight the gateway
|
|
57
|
+
* re-derives from its own tool registry. Only the protocol-meaningful,
|
|
58
|
+
* JSON-safe `Tool` fields cross the wire.
|
|
59
|
+
*/
|
|
60
|
+
function buildWireContext(context: Context): Context {
|
|
61
|
+
if (!context.tools || context.tools.length === 0) return context;
|
|
62
|
+
return {
|
|
63
|
+
...context,
|
|
64
|
+
tools: context.tools.map(tool => ({
|
|
65
|
+
name: tool.name,
|
|
66
|
+
description: tool.description,
|
|
67
|
+
parameters: tool.parameters,
|
|
68
|
+
...(tool.strict !== undefined ? { strict: tool.strict } : {}),
|
|
69
|
+
...(tool.customFormat !== undefined ? { customFormat: tool.customFormat } : {}),
|
|
70
|
+
...(tool.customWireName !== undefined ? { customWireName: tool.customWireName } : {}),
|
|
71
|
+
})),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
51
75
|
function buildWireOptions(options: SimpleStreamOptions | undefined): Record<string, unknown> {
|
|
52
76
|
if (!options) return {};
|
|
53
77
|
const wire: Record<string, unknown> = {};
|
|
@@ -165,7 +189,7 @@ export function streamPiNative<TApi extends Api>(
|
|
|
165
189
|
const headers = buildHeaders(model as Model<Api>, options?.apiKey);
|
|
166
190
|
const body = JSON.stringify({
|
|
167
191
|
modelId: model.id,
|
|
168
|
-
context,
|
|
192
|
+
context: buildWireContext(context),
|
|
169
193
|
options: buildWireOptions(options),
|
|
170
194
|
stream: true,
|
|
171
195
|
});
|
|
@@ -78,6 +78,21 @@ const ALLOWED_OPTION_KEYS: ReadonlySet<keyof SimpleStreamOptions> = new Set([
|
|
|
78
78
|
"preferWebsockets",
|
|
79
79
|
] as const satisfies readonly (keyof SimpleStreamOptions)[]);
|
|
80
80
|
|
|
81
|
+
const CREDENTIAL_HEADER_NAMES = new Set([
|
|
82
|
+
"authorization",
|
|
83
|
+
"proxy-authorization",
|
|
84
|
+
"cookie",
|
|
85
|
+
"set-cookie",
|
|
86
|
+
"api-key",
|
|
87
|
+
"x-api-key",
|
|
88
|
+
"x-goog-api-key",
|
|
89
|
+
"anthropic-api-key",
|
|
90
|
+
"x-auth-token",
|
|
91
|
+
"x-access-token",
|
|
92
|
+
"x-api-token",
|
|
93
|
+
"x-client-secret",
|
|
94
|
+
]);
|
|
95
|
+
|
|
81
96
|
// ---------------------------------------------------------------------------
|
|
82
97
|
// parseRequest
|
|
83
98
|
// ---------------------------------------------------------------------------
|
|
@@ -132,6 +147,15 @@ export function parseRequest(body: unknown, _headers?: Headers): PiNativeParsedR
|
|
|
132
147
|
for (const [k, v] of Object.entries(rawOpts)) {
|
|
133
148
|
if (v === undefined || v === null) continue;
|
|
134
149
|
if (!ALLOWED_OPTION_KEYS.has(k as keyof SimpleStreamOptions)) continue;
|
|
150
|
+
if (k === "headers" && typeof v === "object" && v !== null && !Array.isArray(v)) {
|
|
151
|
+
const safeHeaders: Record<string, string> = {};
|
|
152
|
+
for (const [name, value] of Object.entries(v)) {
|
|
153
|
+
if (CREDENTIAL_HEADER_NAMES.has(name.toLowerCase())) continue;
|
|
154
|
+
if (typeof value === "string") safeHeaders[name] = value;
|
|
155
|
+
}
|
|
156
|
+
optsBag[k] = safeHeaders;
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
135
159
|
optsBag[k] = v;
|
|
136
160
|
}
|
|
137
161
|
}
|
|
@@ -44,16 +44,16 @@ export declare function resolveLazyStreamFirstEventFallbackMs(provider: string,
|
|
|
44
44
|
export declare const PROVIDER_RUNTIME_DESCRIPTORS: readonly ProviderRuntimeDescriptor<Api, unknown>[];
|
|
45
45
|
/** Return the lazy descriptor for a built-in API, if one is registered. */
|
|
46
46
|
export declare function getProviderRuntimeDescriptor<TApi extends Api>(api: TApi): ProviderRuntimeDescriptor<TApi, unknown> | undefined;
|
|
47
|
-
export declare const streamAnthropic: (model: Model<"anthropic-messages">, context: Context, options: OptionsForApi<"anthropic-messages"
|
|
48
|
-
export declare const streamAzureOpenAIResponses: (model: Model<"azure-openai-responses">, context: Context, options: OptionsForApi<"azure-openai-responses"
|
|
49
|
-
export declare const streamGoogle: (model: Model<"google-generative-ai">, context: Context, options: OptionsForApi<"google-generative-ai"
|
|
50
|
-
export declare const streamGoogleGeminiCli: (model: Model<"google-gemini-cli">, context: Context, options: OptionsForApi<"google-gemini-cli"
|
|
51
|
-
export declare const streamGoogleVertex: (model: Model<"google-vertex">, context: Context, options: OptionsForApi<"google-vertex"
|
|
52
|
-
export declare const streamOpenAICodexResponses: (model: Model<"openai-codex-responses">, context: Context, options: OptionsForApi<"openai-codex-responses"
|
|
53
|
-
export declare const streamOpenAICompletions: (model: Model<"openai-completions">, context: Context, options: OptionsForApi<"openai-completions"
|
|
54
|
-
export declare const streamOpenAIResponses: (model: Model<"openai-responses">, context: Context, options: OptionsForApi<"openai-responses"
|
|
55
|
-
export declare const streamCursor: (model: Model<"cursor-agent">, context: Context, options: OptionsForApi<"cursor-agent"
|
|
56
|
-
export declare const streamOllama: (model: Model<"ollama-chat">, context: Context, options: OptionsForApi<"ollama-chat"
|
|
57
|
-
export declare const streamBedrock: (model: Model<"bedrock-converse-stream">, context: Context, options: OptionsForApi<"bedrock-converse-stream"
|
|
58
|
-
export declare const streamKiroCodeWhisperer: (model: Model<"kiro-codewhisperer-stream">, context: Context, options: OptionsForApi<"kiro-codewhisperer-stream"
|
|
47
|
+
export declare const streamAnthropic: (model: Model<"anthropic-messages">, context: Context, options: OptionsForApi<"anthropic-messages">, onStreamCreated?: () => void) => EventStreamImpl;
|
|
48
|
+
export declare const streamAzureOpenAIResponses: (model: Model<"azure-openai-responses">, context: Context, options: OptionsForApi<"azure-openai-responses">, onStreamCreated?: () => void) => EventStreamImpl;
|
|
49
|
+
export declare const streamGoogle: (model: Model<"google-generative-ai">, context: Context, options: OptionsForApi<"google-generative-ai">, onStreamCreated?: () => void) => EventStreamImpl;
|
|
50
|
+
export declare const streamGoogleGeminiCli: (model: Model<"google-gemini-cli">, context: Context, options: OptionsForApi<"google-gemini-cli">, onStreamCreated?: () => void) => EventStreamImpl;
|
|
51
|
+
export declare const streamGoogleVertex: (model: Model<"google-vertex">, context: Context, options: OptionsForApi<"google-vertex">, onStreamCreated?: () => void) => EventStreamImpl;
|
|
52
|
+
export declare const streamOpenAICodexResponses: (model: Model<"openai-codex-responses">, context: Context, options: OptionsForApi<"openai-codex-responses">, onStreamCreated?: () => void) => EventStreamImpl;
|
|
53
|
+
export declare const streamOpenAICompletions: (model: Model<"openai-completions">, context: Context, options: OptionsForApi<"openai-completions">, onStreamCreated?: () => void) => EventStreamImpl;
|
|
54
|
+
export declare const streamOpenAIResponses: (model: Model<"openai-responses">, context: Context, options: OptionsForApi<"openai-responses">, onStreamCreated?: () => void) => EventStreamImpl;
|
|
55
|
+
export declare const streamCursor: (model: Model<"cursor-agent">, context: Context, options: OptionsForApi<"cursor-agent">, onStreamCreated?: () => void) => EventStreamImpl;
|
|
56
|
+
export declare const streamOllama: (model: Model<"ollama-chat">, context: Context, options: OptionsForApi<"ollama-chat">, onStreamCreated?: () => void) => EventStreamImpl;
|
|
57
|
+
export declare const streamBedrock: (model: Model<"bedrock-converse-stream">, context: Context, options: OptionsForApi<"bedrock-converse-stream">, onStreamCreated?: () => void) => EventStreamImpl;
|
|
58
|
+
export declare const streamKiroCodeWhisperer: (model: Model<"kiro-codewhisperer-stream">, context: Context, options: OptionsForApi<"kiro-codewhisperer-stream">, onStreamCreated?: () => void) => EventStreamImpl;
|
|
59
59
|
export {};
|