@code-yeongyu/senpi-ai 2026.8.1 → 2026.8.3
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/README.md +2 -1
- package/dist/api/anthropic-messages.d.ts.map +1 -1
- package/dist/api/anthropic-messages.js +46 -10
- package/dist/api/anthropic-messages.js.map +1 -1
- package/dist/api/anthropic-tool-pairs.d.ts +3 -0
- package/dist/api/anthropic-tool-pairs.d.ts.map +1 -0
- package/dist/api/anthropic-tool-pairs.js +134 -0
- package/dist/api/anthropic-tool-pairs.js.map +1 -0
- package/dist/api/azure-openai-responses.d.ts.map +1 -1
- package/dist/api/azure-openai-responses.js +5 -1
- package/dist/api/azure-openai-responses.js.map +1 -1
- package/dist/api/bedrock-converse-stream.d.ts.map +1 -1
- package/dist/api/bedrock-converse-stream.js +64 -4
- package/dist/api/bedrock-converse-stream.js.map +1 -1
- package/dist/api/google-generative-ai.d.ts.map +1 -1
- package/dist/api/google-generative-ai.js +12 -2
- package/dist/api/google-generative-ai.js.map +1 -1
- package/dist/api/google-shared.d.ts.map +1 -1
- package/dist/api/google-shared.js +13 -6
- package/dist/api/google-shared.js.map +1 -1
- package/dist/api/google-vertex.d.ts.map +1 -1
- package/dist/api/google-vertex.js +12 -2
- package/dist/api/google-vertex.js.map +1 -1
- package/dist/api/mistral-conversations.d.ts.map +1 -1
- package/dist/api/mistral-conversations.js +19 -10
- package/dist/api/mistral-conversations.js.map +1 -1
- package/dist/api/openai-codex-responses.d.ts.map +1 -1
- package/dist/api/openai-codex-responses.js +84 -47
- package/dist/api/openai-codex-responses.js.map +1 -1
- package/dist/api/openai-completions.d.ts.map +1 -1
- package/dist/api/openai-completions.js +17 -8
- package/dist/api/openai-completions.js.map +1 -1
- package/dist/api/openai-responses-shared.d.ts.map +1 -1
- package/dist/api/openai-responses-shared.js +11 -1
- package/dist/api/openai-responses-shared.js.map +1 -1
- package/dist/api/openai-responses.d.ts.map +1 -1
- package/dist/api/openai-responses.js +7 -3
- package/dist/api/openai-responses.js.map +1 -1
- package/dist/api/openrouter-images.js +3 -2
- package/dist/api/openrouter-images.js.map +1 -1
- package/dist/api/pi-messages.js +2 -2
- package/dist/api/pi-messages.js.map +1 -1
- package/dist/api/simple-options.d.ts.map +1 -1
- package/dist/api/simple-options.js +1 -0
- package/dist/api/simple-options.js.map +1 -1
- package/dist/auth/oauth/openrouter.d.ts +3 -1
- package/dist/auth/oauth/openrouter.d.ts.map +1 -1
- package/dist/auth/oauth/openrouter.js +81 -26
- package/dist/auth/oauth/openrouter.js.map +1 -1
- package/dist/auth/resolve.d.ts +2 -0
- package/dist/auth/resolve.d.ts.map +1 -1
- package/dist/auth/resolve.js +16 -8
- package/dist/auth/resolve.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/providers/data/.manifest.json +1 -1
- package/dist/providers/data/cloudflare-ai-gateway.json +1 -1
- package/dist/providers/data/fireworks.json +1 -1
- package/dist/providers/data/github-copilot.json +1 -1
- package/dist/providers/data/huggingface.json +1 -1
- package/dist/providers/data/mistral.json +1 -1
- package/dist/providers/data/openai-codex.json +1 -1
- package/dist/providers/data/openai.json +1 -1
- package/dist/providers/data/opencode.json +1 -1
- package/dist/providers/data/openrouter.json +1 -1
- package/dist/providers/data/qwen-token-plan-cn.json +1 -1
- package/dist/providers/data/qwen-token-plan.json +1 -1
- package/dist/providers/data/together.json +1 -1
- package/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/dist/providers/data/zai-coding-cn.json +1 -1
- package/dist/providers/data/zai.json +1 -1
- package/dist/providers/faux.d.ts.map +1 -1
- package/dist/providers/faux.js +4 -1
- package/dist/providers/faux.js.map +1 -1
- package/dist/providers/opencode-go.js +1 -1
- package/dist/providers/opencode-go.js.map +1 -1
- package/dist/types.d.ts +13 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/error-body.d.ts.map +1 -1
- package/dist/utils/error-body.js +23 -4
- package/dist/utils/error-body.js.map +1 -1
- package/dist/utils/prompt-cache-ttl.d.ts.map +1 -1
- package/dist/utils/prompt-cache-ttl.js +10 -1
- package/dist/utils/prompt-cache-ttl.js.map +1 -1
- package/dist/utils/provider-retry.d.ts +3 -0
- package/dist/utils/provider-retry.d.ts.map +1 -1
- package/dist/utils/provider-retry.js +13 -12
- package/dist/utils/provider-retry.js.map +1 -1
- package/dist/utils/retry-hint.d.ts +24 -0
- package/dist/utils/retry-hint.d.ts.map +1 -0
- package/dist/utils/retry-hint.js +233 -0
- package/dist/utils/retry-hint.js.map +1 -0
- package/package.json +10 -6
package/README.md
CHANGED
|
@@ -874,7 +874,8 @@ for await (const event of s) {
|
|
|
874
874
|
|
|
875
875
|
Every `AssistantMessage` includes a `stopReason` field that indicates how the generation ended:
|
|
876
876
|
|
|
877
|
-
- `"
|
|
877
|
+
- `"pending"` - Only present in partial messages when we do not know what the stop reason will be
|
|
878
|
+
- `"stop"` - This is the final message the model will produce this turn
|
|
878
879
|
- `"length"` - Output hit the maximum token limit
|
|
879
880
|
- `"toolUse"` - Model is calling tools and expects tool results
|
|
880
881
|
- `"error"` - An error occurred during generation
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic-messages.d.ts","sourceRoot":"","sources":["../../src/api/anthropic-messages.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAU1C,OAAO,KAAK,EAWX,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAOb,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"anthropic-messages.d.ts","sourceRoot":"","sources":["../../src/api/anthropic-messages.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAU1C,OAAO,KAAK,EAWX,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAOb,MAAM,aAAa,CAAC;AAiCrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AA6JlE,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;AAE1E,MAAM,MAAM,wBAAwB,GAAG,YAAY,GAAG,SAAS,CAAC;AAoEhE,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACtD;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB;;;;;;;;;;;OAWG;IACH,eAAe,CAAC,EAAE,wBAAwB,CAAC;IAC3C;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACtE;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;CACnB;AA4zBD,eAAO,MAAM,MAAM,EAAE,cAAc,CAAC,oBAAoB,EAAE,gBAAgB,CA6ZzE,CAAC;AA0FF,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,oBAAoB,EAAE,mBAAmB,CA2ClF,CAAC"}
|
|
@@ -9,11 +9,13 @@ import { parseJsonWithRepair, parseStreamingJson } from "../utils/json-parse.js"
|
|
|
9
9
|
import { getAnthropicCompat, isAnthropicApiBaseUrl } from "../utils/prompt-cache-ttl.js";
|
|
10
10
|
import { getProviderEnvValue } from "../utils/provider-env.js";
|
|
11
11
|
import { retryProviderRequest } from "../utils/provider-retry.js";
|
|
12
|
+
import { appendRetryAfterMsMarker, extract429RetryAfterMs } from "../utils/retry-hint.js";
|
|
12
13
|
import { sanitizeSurrogates } from "../utils/sanitize-unicode.js";
|
|
13
14
|
import { applyServerFallbackAbort, parseServerFallbackReceipt, parseStickyFallbackReceipt, } from "../utils/server-fallback-receipt.js";
|
|
14
15
|
import { normalizeToolCallId } from "../utils/tool-call-id.js";
|
|
15
16
|
import { isForcedToolChoiceUnsupportedError, omitToolChoiceParam } from "../utils/tool-choice-fallback.js";
|
|
16
17
|
import { demotedToolCallText, demotedToolResultText } from "../utils/unavailable-tool-text.js";
|
|
18
|
+
import { sanitizeAnthropicToolPairs } from "./anthropic-tool-pairs.js";
|
|
17
19
|
import { resolveCloudflareBaseUrl } from "./cloudflare.js";
|
|
18
20
|
import { resolveJsonSchemaStrictSampling } from "./constrained-sampling.js";
|
|
19
21
|
import { buildCopilotDynamicHeaders, hasCopilotVisionInput } from "./github-copilot-headers.js";
|
|
@@ -835,7 +837,12 @@ async function* iterateAnthropicEvents(response, signal) {
|
|
|
835
837
|
let sawMessageEnd = false;
|
|
836
838
|
for await (const sse of iterateSseMessages(response.body, signal)) {
|
|
837
839
|
if (sse.event === "error") {
|
|
838
|
-
|
|
840
|
+
let errorText = sse.data;
|
|
841
|
+
const hintMs = extract429RetryAfterMs({ bodyText: sse.data });
|
|
842
|
+
if (hintMs !== undefined) {
|
|
843
|
+
errorText = appendRetryAfterMsMarker(errorText, hintMs);
|
|
844
|
+
}
|
|
845
|
+
throw new Error(errorText);
|
|
839
846
|
}
|
|
840
847
|
if (!ANTHROPIC_MESSAGE_EVENTS.has(sse.event ?? "")) {
|
|
841
848
|
continue;
|
|
@@ -876,7 +883,7 @@ export const stream = (model, context, options) => {
|
|
|
876
883
|
totalTokens: 0,
|
|
877
884
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
878
885
|
},
|
|
879
|
-
stopReason: "
|
|
886
|
+
stopReason: "pending",
|
|
880
887
|
timestamp: Date.now(),
|
|
881
888
|
};
|
|
882
889
|
const serverFallbackAbort = new AbortController();
|
|
@@ -906,7 +913,7 @@ export const stream = (model, context, options) => {
|
|
|
906
913
|
}
|
|
907
914
|
const cacheRetention = resolveCacheRetention(options?.cacheRetention ?? model.cacheRetention, options?.env, "long");
|
|
908
915
|
const cacheSessionId = cacheRetention === "none" ? undefined : options?.sessionId;
|
|
909
|
-
const created = createClient(model, apiKey, options?.interleavedThinking ?? true, shouldUseFineGrainedToolStreamingBeta(model, context), optionsHeaders, copilotDynamicHeaders, cacheSessionId, options?.env);
|
|
916
|
+
const created = createClient(model, apiKey, options?.interleavedThinking ?? true, shouldUseFineGrainedToolStreamingBeta(model, context), optionsHeaders, options?.fetch, copilotDynamicHeaders, cacheSessionId, options?.env);
|
|
910
917
|
client = created.client;
|
|
911
918
|
isOAuth = created.isOAuthToken;
|
|
912
919
|
}
|
|
@@ -922,7 +929,7 @@ export const stream = (model, context, options) => {
|
|
|
922
929
|
}
|
|
923
930
|
params = sanitizeAdaptiveThinkingPayload(model, params, options);
|
|
924
931
|
params = sanitizeUnsupportedNativeTools(model, params);
|
|
925
|
-
params = demoteUnavailableToolReferences(params);
|
|
932
|
+
params = sanitizeAnthropicToolPairs(demoteUnavailableToolReferences(params));
|
|
926
933
|
const payloadRequestMetadata = extractPayloadRequestMetadata(params);
|
|
927
934
|
params = payloadRequestMetadata.params;
|
|
928
935
|
const requestOptions = {
|
|
@@ -1002,7 +1009,7 @@ export const stream = (model, context, options) => {
|
|
|
1002
1009
|
if (event.content_block.type === "text") {
|
|
1003
1010
|
const block = {
|
|
1004
1011
|
type: "text",
|
|
1005
|
-
text: "",
|
|
1012
|
+
text: event.content_block.text ?? "",
|
|
1006
1013
|
index: event.index,
|
|
1007
1014
|
};
|
|
1008
1015
|
output.content.push(block);
|
|
@@ -1011,8 +1018,8 @@ export const stream = (model, context, options) => {
|
|
|
1011
1018
|
else if (event.content_block.type === "thinking") {
|
|
1012
1019
|
const block = {
|
|
1013
1020
|
type: "thinking",
|
|
1014
|
-
thinking: "",
|
|
1015
|
-
thinkingSignature: "",
|
|
1021
|
+
thinking: event.content_block.thinking ?? "",
|
|
1022
|
+
thinkingSignature: event.content_block.signature ?? "",
|
|
1016
1023
|
index: event.index,
|
|
1017
1024
|
};
|
|
1018
1025
|
output.content.push(block);
|
|
@@ -1154,6 +1161,7 @@ export const stream = (model, context, options) => {
|
|
|
1154
1161
|
}
|
|
1155
1162
|
else if (event.type === "message_delta") {
|
|
1156
1163
|
if (event.delta.stop_reason) {
|
|
1164
|
+
output.rawStopReason = event.delta.stop_reason;
|
|
1157
1165
|
const stopReasonResult = mapStopReason(event.delta.stop_reason, event.delta.stop_details);
|
|
1158
1166
|
output.stopReason = stopReasonResult.stopReason;
|
|
1159
1167
|
if (stopReasonResult.errorMessage) {
|
|
@@ -1199,6 +1207,9 @@ export const stream = (model, context, options) => {
|
|
|
1199
1207
|
if (serverFallbackReceipt !== undefined) {
|
|
1200
1208
|
applyServerFallbackAbort(output, serverFallbackReceipt);
|
|
1201
1209
|
}
|
|
1210
|
+
if (output.stopReason === "pending") {
|
|
1211
|
+
throw new Error("Anthropic stream ended without a stop reason");
|
|
1212
|
+
}
|
|
1202
1213
|
if (output.stopReason === "aborted" || output.stopReason === "error") {
|
|
1203
1214
|
throw new Error(output.errorMessage || "An unknown error occurred");
|
|
1204
1215
|
}
|
|
@@ -1221,7 +1232,24 @@ export const stream = (model, context, options) => {
|
|
|
1221
1232
|
delete block.partialJson;
|
|
1222
1233
|
}
|
|
1223
1234
|
output.stopReason = options?.signal?.aborted ? "aborted" : "error";
|
|
1224
|
-
|
|
1235
|
+
let errorMessage = error instanceof Error ? error.message : JSON.stringify(error);
|
|
1236
|
+
// When a 429 SDK error carries response headers, extract the server's
|
|
1237
|
+
// retry-after hint and append the canonical marker so the orchestration
|
|
1238
|
+
// layer can recover the full delay.
|
|
1239
|
+
if (error instanceof Error && error.status === 429) {
|
|
1240
|
+
const sdkHeaders = error.headers;
|
|
1241
|
+
if (sdkHeaders instanceof Headers) {
|
|
1242
|
+
const hintMs = extract429RetryAfterMs({
|
|
1243
|
+
status: 429,
|
|
1244
|
+
headers: sdkHeaders,
|
|
1245
|
+
bodyText: errorMessage,
|
|
1246
|
+
});
|
|
1247
|
+
if (hintMs !== undefined) {
|
|
1248
|
+
errorMessage = appendRetryAfterMsMarker(errorMessage, hintMs);
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
output.errorMessage = errorMessage;
|
|
1225
1253
|
stream.push({ type: "error", reason: output.stopReason, error: output });
|
|
1226
1254
|
stream.end();
|
|
1227
1255
|
}
|
|
@@ -1331,7 +1359,7 @@ export const streamSimple = (model, context, options) => {
|
|
|
1331
1359
|
function isOAuthToken(apiKey) {
|
|
1332
1360
|
return apiKey.includes("sk-ant-oat");
|
|
1333
1361
|
}
|
|
1334
|
-
function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStreamingBeta, optionsHeaders, dynamicHeaders, sessionId, env) {
|
|
1362
|
+
function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStreamingBeta, optionsHeaders, fetch, dynamicHeaders, sessionId, env) {
|
|
1335
1363
|
// Adaptive thinking models have interleaved thinking built in, so skip the beta header.
|
|
1336
1364
|
const needsInterleavedBeta = interleavedThinking && !supportsAdaptiveThinking(model);
|
|
1337
1365
|
const betaFeatures = [];
|
|
@@ -1347,6 +1375,7 @@ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStre
|
|
|
1347
1375
|
authToken: null,
|
|
1348
1376
|
baseURL: resolveCloudflareBaseUrl(model, env),
|
|
1349
1377
|
dangerouslyAllowBrowser: true,
|
|
1378
|
+
fetch,
|
|
1350
1379
|
defaultHeaders: sanitizeAdaptiveThinkingHeaders(model, mergeHeaders({
|
|
1351
1380
|
accept: "application/json",
|
|
1352
1381
|
"anthropic-dangerous-direct-browser-access": "true",
|
|
@@ -1365,6 +1394,7 @@ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStre
|
|
|
1365
1394
|
authToken: apiKey,
|
|
1366
1395
|
baseURL: model.baseUrl,
|
|
1367
1396
|
dangerouslyAllowBrowser: true,
|
|
1397
|
+
fetch,
|
|
1368
1398
|
defaultHeaders: sanitizeAdaptiveThinkingHeaders(model, mergeHeaders({
|
|
1369
1399
|
accept: "application/json",
|
|
1370
1400
|
"anthropic-dangerous-direct-browser-access": "true",
|
|
@@ -1380,6 +1410,7 @@ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStre
|
|
|
1380
1410
|
authToken: apiKey,
|
|
1381
1411
|
baseURL: model.baseUrl,
|
|
1382
1412
|
dangerouslyAllowBrowser: true,
|
|
1413
|
+
fetch,
|
|
1383
1414
|
defaultHeaders: sanitizeAdaptiveThinkingHeaders(model, mergeHeaders({
|
|
1384
1415
|
accept: "application/json",
|
|
1385
1416
|
"anthropic-dangerous-direct-browser-access": "true",
|
|
@@ -1397,6 +1428,7 @@ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStre
|
|
|
1397
1428
|
authToken: null,
|
|
1398
1429
|
baseURL: model.baseUrl,
|
|
1399
1430
|
dangerouslyAllowBrowser: true,
|
|
1431
|
+
fetch,
|
|
1400
1432
|
defaultHeaders: sanitizeAdaptiveThinkingHeaders(model, mergeHeaders({
|
|
1401
1433
|
accept: "application/json",
|
|
1402
1434
|
"anthropic-dangerous-direct-browser-access": "true",
|
|
@@ -1842,7 +1874,11 @@ function mapStopReason(reason, stopDetails) {
|
|
|
1842
1874
|
case "stop_sequence":
|
|
1843
1875
|
return { stopReason: "stop" }; // We don't supply stop sequences, so this should never happen
|
|
1844
1876
|
case "sensitive": // Content flagged by safety filters (not yet in SDK types)
|
|
1845
|
-
return {
|
|
1877
|
+
return {
|
|
1878
|
+
stopReason: "error",
|
|
1879
|
+
errorMessage: "Provider stopped with: sensitive",
|
|
1880
|
+
stopDetails: { type: "sensitive" },
|
|
1881
|
+
};
|
|
1846
1882
|
default:
|
|
1847
1883
|
// Handle unknown stop reasons gracefully (API may add new values)
|
|
1848
1884
|
throw new Error(`Unhandled stop reason: ${reason}`);
|