@code-yeongyu/senpi-ai 2026.8.14 → 2026.8.16
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 -0
- package/dist/api/anthropic-messages.d.ts.map +1 -1
- package/dist/api/anthropic-messages.js +40 -14
- package/dist/api/anthropic-messages.js.map +1 -1
- package/dist/api/bedrock-converse-stream.d.ts.map +1 -1
- package/dist/api/bedrock-converse-stream.js +16 -4
- package/dist/api/bedrock-converse-stream.js.map +1 -1
- package/dist/api/cloudflare-gateway-binding.d.ts +69 -0
- package/dist/api/cloudflare-gateway-binding.d.ts.map +1 -0
- package/dist/api/cloudflare-gateway-binding.js +159 -0
- package/dist/api/cloudflare-gateway-binding.js.map +1 -0
- package/dist/api/constrained-sampling.d.ts +3 -0
- package/dist/api/constrained-sampling.d.ts.map +1 -1
- package/dist/api/constrained-sampling.js +125 -5
- package/dist/api/constrained-sampling.js.map +1 -1
- package/dist/api/google-generative-ai.js +7 -3
- package/dist/api/google-generative-ai.js.map +1 -1
- package/dist/api/google-shared.d.ts +1 -1
- package/dist/api/google-shared.d.ts.map +1 -1
- package/dist/api/google-shared.js +13 -9
- package/dist/api/google-shared.js.map +1 -1
- package/dist/api/google-vertex.js +7 -3
- package/dist/api/google-vertex.js.map +1 -1
- package/dist/api/mistral-conversations.d.ts +1 -1
- package/dist/api/mistral-conversations.d.ts.map +1 -1
- package/dist/api/mistral-conversations.js +208 -42
- 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 +13 -4
- 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 +10 -7
- package/dist/api/openai-completions.js.map +1 -1
- package/dist/api/openai-responses-shared.d.ts +1 -0
- package/dist/api/openai-responses-shared.d.ts.map +1 -1
- package/dist/api/openai-responses-shared.js +31 -7
- 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 +8 -1
- package/dist/api/openai-responses.js.map +1 -1
- package/dist/auth/oauth/cursor.d.ts +16 -0
- package/dist/auth/oauth/cursor.d.ts.map +1 -0
- package/dist/auth/oauth/cursor.js +234 -0
- package/dist/auth/oauth/cursor.js.map +1 -0
- package/dist/auth/oauth/github-copilot.d.ts.map +1 -1
- package/dist/auth/oauth/github-copilot.js +6 -3
- package/dist/auth/oauth/github-copilot.js.map +1 -1
- package/dist/auth/oauth/load.d.ts +2 -0
- package/dist/auth/oauth/load.d.ts.map +1 -1
- package/dist/auth/oauth/load.js +5 -0
- package/dist/auth/oauth/load.js.map +1 -1
- package/dist/auth/resolve.js +44 -9
- package/dist/auth/resolve.js.map +1 -1
- package/dist/auth/types.d.ts +2 -0
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/auth/types.js.map +1 -1
- package/dist/bun-oauth.d.ts.map +1 -1
- package/dist/bun-oauth.js +2 -0
- package/dist/bun-oauth.js.map +1 -1
- package/dist/providers/all.d.ts.map +1 -1
- package/dist/providers/all.js +2 -0
- package/dist/providers/all.js.map +1 -1
- package/dist/providers/cursor.d.ts +15 -0
- package/dist/providers/cursor.d.ts.map +1 -0
- package/dist/providers/cursor.js +32 -0
- package/dist/providers/cursor.js.map +1 -0
- package/dist/providers/data/.manifest.json +1 -1
- package/dist/providers/data/alibaba-token-plan.json +1 -1
- package/dist/providers/data/baseten.json +1 -1
- package/dist/providers/data/cloudflare-ai-gateway.json +1 -1
- package/dist/providers/data/cloudflare-workers-ai.json +1 -1
- package/dist/providers/data/deepseek.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/kimi-coding.json +1 -1
- package/dist/providers/data/nvidia.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-go.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/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/types.d.ts +14 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/overflow.d.ts.map +1 -1
- package/dist/utils/overflow.js +2 -0
- package/dist/utils/overflow.js.map +1 -1
- package/dist/utils/pi-user-agent.d.ts +2 -0
- package/dist/utils/pi-user-agent.d.ts.map +1 -0
- package/dist/utils/pi-user-agent.js +12 -0
- package/dist/utils/pi-user-agent.js.map +1 -0
- package/dist/utils/prompt-cache-ttl.d.ts.map +1 -1
- package/dist/utils/prompt-cache-ttl.js +3 -2
- package/dist/utils/prompt-cache-ttl.js.map +1 -1
- package/dist/utils/retry.d.ts.map +1 -1
- package/dist/utils/retry.js +1 -0
- package/dist/utils/retry.js.map +1 -1
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +34 -0
- package/dist/utils/validation.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -90,6 +90,7 @@ Unified LLM API with provider collections, automatic auth resolution, token and
|
|
|
90
90
|
- **Qwen Token Plan** (separate Individual and existing catalogs, with a separate China provider)
|
|
91
91
|
- **Xiaomi MiMo** (defaults to API billing endpoint, with separate Token Plan providers for `cn`/`ams`/`sgp` regions)
|
|
92
92
|
- **Alibaba Token Plan** (Alibaba Cloud Model Studio prepaid Token Plan, OpenAI-compatible `ap-southeast-1` endpoint)
|
|
93
|
+
- **Cursor** (Pro/Ultra/Teams subscription, OAuth authentication only — the Cursor chat protocol is not ported yet, see below)
|
|
93
94
|
- **Any other OpenAI-compatible API**: local Ollama, vLLM, LM Studio, etc.
|
|
94
95
|
|
|
95
96
|
## Installation
|
|
@@ -1483,6 +1484,7 @@ Several providers support OAuth authentication instead of static API keys:
|
|
|
1483
1484
|
- **OpenAI Codex** (ChatGPT Plus/Pro subscription, access to GPT-5.x Codex models)
|
|
1484
1485
|
- **GitHub Copilot** (Copilot subscription)
|
|
1485
1486
|
- **OpenRouter** (OAuth PKCE that mints a user-controlled API key)
|
|
1487
|
+
- **Cursor** (Pro/Ultra/Teams subscription; browser deep-link + poll flow. Login, refresh, and credential storage are fully functional, but the provider exposes no models until the Cursor Connect-RPC chat protocol is ported — the stored access token resolves through `models.getAuth("cursor")` for external integrations)
|
|
1486
1488
|
|
|
1487
1489
|
Each of these providers carries an `OAuthAuth` on `provider.auth.oauth` with three operations: `login(interaction)` uses the provider-neutral `AuthInteraction.prompt()`/`notify()` protocol and returns a credential, `refresh(credential, signal)` refreshes expiring credentials when applicable, and `toAuth(credential)` derives request auth (GitHub Copilot's per-account base URL comes from here). Provider login interactions and refresh calls always carry a concrete abort signal. Refresh is automatic: `models.getAuth(providerId)` and request paths refresh expired tokens under a credential-store lock, so concurrent requests and processes cannot double-refresh. OpenRouter's OAuth flow instead returns a permanent API key, so its refresh operation is a no-op.
|
|
1488
1490
|
|
|
@@ -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;AAC1C,OAAO,KAAK,EAGX,+BAA+B,EAK/B,MAAM,yCAAyC,CAAC;AAEjD,OAAO,KAAK,EAKX,OAAO,EAGP,KAAK,EAGL,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;AAC1C,OAAO,KAAK,EAGX,+BAA+B,EAK/B,MAAM,yCAAyC,CAAC;AAEjD,OAAO,KAAK,EAKX,OAAO,EAGP,KAAK,EAGL,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAOb,MAAM,aAAa,CAAC;AAmCrB,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;AA+1BD,eAAO,MAAM,MAAM,EAAE,cAAc,CAAC,oBAAoB,EAAE,gBAAgB,CA2ZzE,CAAC;AA0FF,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,oBAAoB,EAAE,mBAAmB,CAyClF,CAAC;AAyIF,wBAAgB,mCAAmC,CAClD,KAAK,EAAE,KAAK,CAAC,oBAAoB,CAAC,EAClC,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,gBAAgB,GACxB,+BAA+B,CAkBjC"}
|
|
@@ -6,6 +6,7 @@ import { splitDeferredTools } from "../utils/deferred-tools.js";
|
|
|
6
6
|
import { AssistantMessageEventStream } from "../utils/event-stream.js";
|
|
7
7
|
import { headersToRecord, providerHeadersToRecord } from "../utils/headers.js";
|
|
8
8
|
import { parseJsonWithRepair, parseStreamingJson } from "../utils/json-parse.js";
|
|
9
|
+
import { getPiUserAgent } from "../utils/pi-user-agent.js";
|
|
9
10
|
import { getAnthropicCompat, isAnthropicApiBaseUrl } from "../utils/prompt-cache-ttl.js";
|
|
10
11
|
import { getProviderEnvValue } from "../utils/provider-env.js";
|
|
11
12
|
import { retryProviderRequest } from "../utils/provider-retry.js";
|
|
@@ -18,7 +19,7 @@ import { resolveRootObjectSchema } from "../utils/tool-schema-compat.js";
|
|
|
18
19
|
import { demotedToolCallText, demotedToolResultText } from "../utils/unavailable-tool-text.js";
|
|
19
20
|
import { sanitizeAnthropicToolPairs } from "./anthropic-tool-pairs.js";
|
|
20
21
|
import { resolveCloudflareBaseUrl } from "./cloudflare.js";
|
|
21
|
-
import { resolveJsonSchemaStrictSampling } from "./constrained-sampling.js";
|
|
22
|
+
import { getJsonSchemaToolParameters, resolveJsonSchemaStrictSampling } from "./constrained-sampling.js";
|
|
22
23
|
import { buildCopilotDynamicHeaders, hasCopilotVisionInput } from "./github-copilot-headers.js";
|
|
23
24
|
import { ANTHROPIC_RESERVED_BODY_KEYS, adjustMaxTokensForThinking, buildBaseOptions, clampMaxTokensToContext, } from "./simple-options.js";
|
|
24
25
|
import { transformMessages } from "./transform-messages.js";
|
|
@@ -197,8 +198,36 @@ function mergeHeaders(...headerSources) {
|
|
|
197
198
|
}
|
|
198
199
|
return merged;
|
|
199
200
|
}
|
|
200
|
-
function
|
|
201
|
-
|
|
201
|
+
function mergeClientHeaders(model, ...headerSources) {
|
|
202
|
+
const merged = mergeHeaders(...headerSources);
|
|
203
|
+
if (model.provider === "kimi-coding") {
|
|
204
|
+
for (const name of Object.keys(merged)) {
|
|
205
|
+
if (name.toLowerCase() === "user-agent")
|
|
206
|
+
delete merged[name];
|
|
207
|
+
}
|
|
208
|
+
merged["User-Agent"] = getPiUserAgent();
|
|
209
|
+
}
|
|
210
|
+
return merged;
|
|
211
|
+
}
|
|
212
|
+
function hasHeader(headers, name) {
|
|
213
|
+
if (!headers)
|
|
214
|
+
return false;
|
|
215
|
+
const expected = name.toLowerCase();
|
|
216
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
217
|
+
if (key.toLowerCase() === expected && value !== null && value.trim().length > 0)
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
function assertRequestAuth(provider, apiKey, headers) {
|
|
223
|
+
if (apiKey)
|
|
224
|
+
return;
|
|
225
|
+
if (hasHeader(headers, "authorization") ||
|
|
226
|
+
hasHeader(headers, "x-api-key") ||
|
|
227
|
+
hasHeader(headers, "cf-aig-authorization")) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
throw new Error(`No API key for provider: ${provider}`);
|
|
202
231
|
}
|
|
203
232
|
function isRecord(value) {
|
|
204
233
|
return typeof value === "object" && value !== null;
|
|
@@ -901,9 +930,7 @@ export const stream = (model, context, options) => {
|
|
|
901
930
|
else {
|
|
902
931
|
const apiKey = options?.apiKey;
|
|
903
932
|
const optionsHeaders = providerHeadersToRecord(options?.headers);
|
|
904
|
-
|
|
905
|
-
throw new Error(`No API key for provider: ${model.provider}`);
|
|
906
|
-
}
|
|
933
|
+
assertRequestAuth(model.provider, apiKey, optionsHeaders);
|
|
907
934
|
let copilotDynamicHeaders;
|
|
908
935
|
if (model.provider === "github-copilot") {
|
|
909
936
|
const hasImages = hasCopilotVisionInput(context.messages);
|
|
@@ -1329,9 +1356,7 @@ function mapThinkingLevelToEffort(model, level) {
|
|
|
1329
1356
|
}
|
|
1330
1357
|
export const streamSimple = (model, context, options) => {
|
|
1331
1358
|
const apiKey = options?.apiKey;
|
|
1332
|
-
|
|
1333
|
-
throw new Error(`No API key for provider: ${model.provider}`);
|
|
1334
|
-
}
|
|
1359
|
+
assertRequestAuth(model.provider, apiKey, providerHeadersToRecord(options?.headers));
|
|
1335
1360
|
const base = buildBaseOptions(model, context, options, options?.apiKey);
|
|
1336
1361
|
if (!options?.reasoning) {
|
|
1337
1362
|
return stream(model, context, { ...base, thinkingEnabled: false });
|
|
@@ -1396,7 +1421,7 @@ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStre
|
|
|
1396
1421
|
baseURL: model.baseUrl,
|
|
1397
1422
|
dangerouslyAllowBrowser: true,
|
|
1398
1423
|
fetch,
|
|
1399
|
-
defaultHeaders: sanitizeAdaptiveThinkingHeaders(model,
|
|
1424
|
+
defaultHeaders: sanitizeAdaptiveThinkingHeaders(model, mergeClientHeaders(model, {
|
|
1400
1425
|
accept: "application/json",
|
|
1401
1426
|
"anthropic-dangerous-direct-browser-access": "true",
|
|
1402
1427
|
...(betaFeatures.length > 0 ? { "anthropic-beta": betaFeatures.join(",") } : {}),
|
|
@@ -1412,7 +1437,7 @@ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStre
|
|
|
1412
1437
|
baseURL: model.baseUrl,
|
|
1413
1438
|
dangerouslyAllowBrowser: true,
|
|
1414
1439
|
fetch,
|
|
1415
|
-
defaultHeaders: sanitizeAdaptiveThinkingHeaders(model,
|
|
1440
|
+
defaultHeaders: sanitizeAdaptiveThinkingHeaders(model, mergeClientHeaders(model, {
|
|
1416
1441
|
accept: "application/json",
|
|
1417
1442
|
"anthropic-dangerous-direct-browser-access": "true",
|
|
1418
1443
|
"anthropic-beta": ["claude-code-20250219", "oauth-2025-04-20", ...betaFeatures].join(","),
|
|
@@ -1430,7 +1455,7 @@ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStre
|
|
|
1430
1455
|
baseURL: model.baseUrl,
|
|
1431
1456
|
dangerouslyAllowBrowser: true,
|
|
1432
1457
|
fetch,
|
|
1433
|
-
defaultHeaders: sanitizeAdaptiveThinkingHeaders(model,
|
|
1458
|
+
defaultHeaders: sanitizeAdaptiveThinkingHeaders(model, mergeClientHeaders(model, {
|
|
1434
1459
|
accept: "application/json",
|
|
1435
1460
|
"anthropic-dangerous-direct-browser-access": "true",
|
|
1436
1461
|
...(betaFeatures.length > 0 ? { "anthropic-beta": betaFeatures.join(",") } : {}),
|
|
@@ -1845,9 +1870,10 @@ function convertTools(tools, isOAuthToken, supportsEagerToolInputStreaming, supp
|
|
|
1845
1870
|
return [];
|
|
1846
1871
|
return tools.map((tool, index) => {
|
|
1847
1872
|
const strict = resolveJsonSchemaStrictSampling(tool, supportsStrictTools);
|
|
1873
|
+
const parameters = getJsonSchemaToolParameters(tool, strict);
|
|
1848
1874
|
// A root union carries no top-level properties, so reading them directly
|
|
1849
1875
|
// would advertise the tool to the model as taking no arguments at all.
|
|
1850
|
-
const schema = resolveRootObjectSchema(
|
|
1876
|
+
const schema = resolveRootObjectSchema(parameters);
|
|
1851
1877
|
const legacyInputSchema = {
|
|
1852
1878
|
type: "object",
|
|
1853
1879
|
properties: schema.properties ?? {},
|
|
@@ -1855,7 +1881,7 @@ function convertTools(tools, isOAuthToken, supportsEagerToolInputStreaming, supp
|
|
|
1855
1881
|
};
|
|
1856
1882
|
const inputSchema = strict === true
|
|
1857
1883
|
? {
|
|
1858
|
-
...
|
|
1884
|
+
...parameters,
|
|
1859
1885
|
...legacyInputSchema,
|
|
1860
1886
|
}
|
|
1861
1887
|
: legacyInputSchema;
|