@oh-my-pi/pi-ai 17.2.6 → 17.2.8
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 +11 -0
- package/dist/types/auth-broker/client.d.ts +7 -0
- package/dist/types/auth-broker/server.d.ts +11 -0
- package/dist/types/auth-broker/wire-schema-resource.d.ts +1 -1
- package/dist/types/auth-broker/wire-schemas.d.ts +4 -2
- package/dist/types/index.d.ts +1 -1
- package/dist/types/providers/anthropic-messages-server-schema.d.ts +695 -255
- package/dist/types/providers/openai-chat-server-schema.d.ts +909 -293
- package/dist/types/providers/openai-responses-server-schema.d.ts +980 -353
- package/dist/types/types.d.ts +8 -5
- package/dist/types/usage.d.ts +152 -46
- package/dist/types/utils/schema/wire.d.ts +1 -1
- package/dist/types/utils/validation.d.ts +24 -0
- package/package.json +5 -5
- package/src/auth-broker/client.ts +2 -1
- package/src/auth-broker/server.ts +2 -1
- package/src/auth-broker/wire-schema-resource.ts +1 -6
- package/src/index.ts +1 -1
- package/src/providers/anthropic-messages-server-schema.ts +1 -1
- package/src/providers/anthropic-messages-server.ts +1 -1
- package/src/providers/cursor.ts +31 -3
- package/src/providers/google-gemini-cli.ts +1 -1
- package/src/providers/openai-chat-server-schema.ts +1 -1
- package/src/providers/openai-chat-server.ts +1 -1
- package/src/providers/openai-codex-responses.ts +1 -1
- package/src/providers/openai-responses-server-schema.ts +1 -1
- package/src/providers/openai-responses-server.ts +1 -1
- package/src/types.ts +9 -6
- package/src/usage.ts +1 -1
- package/src/utils/schema/wire.ts +1 -1
- package/src/utils/validation.ts +2 -1
package/dist/types/types.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export * from "@oh-my-pi/pi-catalog/effort";
|
|
2
2
|
export * from "@oh-my-pi/pi-catalog/types";
|
|
3
|
+
import type { Type } from "@oh-my-pi/omptype";
|
|
3
4
|
import type { DeleteArgs, DeleteResult, DiagnosticsArgs, DiagnosticsResult, GrepArgs, GrepResult, LsArgs, LsResult, McpResult, PiBashExecArgs, PiBashExecResult, PiEditExecArgs, PiEditExecResult, PiFindExecArgs, PiFindExecResult, PiGrepExecArgs, PiGrepExecResult, PiLsExecArgs, PiLsExecResult, PiReadExecArgs, PiReadExecResult, PiWriteExecArgs, PiWriteExecResult, ReadArgs, ReadResult, ShellArgs, ShellResult, WriteArgs, WriteResult } from "@oh-my-pi/pi-catalog/discovery/cursor-gen/agent_pb";
|
|
4
5
|
import type { Effort } from "@oh-my-pi/pi-catalog/effort";
|
|
5
6
|
import type { Api, FetchImpl, Model, Provider, ThinkingBudgets, Usage } from "@oh-my-pi/pi-catalog/types";
|
|
6
|
-
import type { Type } from "arktype";
|
|
7
7
|
import type { ZodType, z } from "zod/v4";
|
|
8
8
|
import type { ApiKey } from "./auth-retry.js";
|
|
9
9
|
import type { BedrockOptions } from "./providers/amazon-bedrock.js";
|
|
@@ -124,10 +124,13 @@ export declare function serviceTierFamily(model: ServiceTierModel): ServiceTierF
|
|
|
124
124
|
export declare function resolveModelServiceTier(tiers: ServiceTierByFamily | null | undefined, model: Pick<Model, "provider" | "api" | "id">): ServiceTier | undefined;
|
|
125
125
|
/**
|
|
126
126
|
* True when the tier should be sent on the wire as the provider's service-tier
|
|
127
|
-
* request field.
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
127
|
+
* request field. `auto` is never forwarded — it is OpenAI's implicit default, so
|
|
128
|
+
* omitting `service_tier` is identical to requesting `auto`, and the Codex
|
|
129
|
+
* (ChatGPT OAuth) endpoint rejects an explicit `auto` outright. OpenAI /
|
|
130
|
+
* OpenAI-Codex accept every other {@link ServiceTier}; Google (Gemini API +
|
|
131
|
+
* Vertex) and OpenRouter accept `flex`/`priority`; Fireworks Serverless
|
|
132
|
+
* realizes only its Priority serving path. Anthropic is absent because it
|
|
133
|
+
* realizes `priority` via `speed: "fast"`.
|
|
131
134
|
*/
|
|
132
135
|
export declare function shouldSendServiceTier(serviceTier: ServiceTier | null | undefined, target: Provider | ServiceTierModel | undefined): boolean;
|
|
133
136
|
/**
|
package/dist/types/usage.d.ts
CHANGED
|
@@ -206,125 +206,231 @@ export interface ClientUsageClientSummary {
|
|
|
206
206
|
export interface ClientUsageSummary {
|
|
207
207
|
clients: ClientUsageClientSummary[];
|
|
208
208
|
}
|
|
209
|
-
export declare const usageUnitSchema: import("
|
|
210
|
-
export declare const usageStatusSchema: import("
|
|
211
|
-
export declare const usageWindowSchema: import("
|
|
209
|
+
export declare const usageUnitSchema: import("@oh-my-pi/omptype").FluentType<"bytes" | "minutes" | "percent" | "requests" | "tokens" | "unknown" | "usd", "bytes" | "minutes" | "percent" | "requests" | "tokens" | "unknown" | "usd">;
|
|
210
|
+
export declare const usageStatusSchema: import("@oh-my-pi/omptype").FluentType<"exhausted" | "ok" | "unknown" | "warning", "exhausted" | "ok" | "unknown" | "warning">;
|
|
211
|
+
export declare const usageWindowSchema: import("@oh-my-pi/omptype").FluentType<{
|
|
212
|
+
durationMs?: number | undefined;
|
|
212
213
|
id: string;
|
|
213
214
|
label: string;
|
|
214
|
-
|
|
215
|
+
resetLabel?: string | undefined;
|
|
215
216
|
resetsAt?: number | undefined;
|
|
217
|
+
}, {
|
|
218
|
+
durationMs?: number | undefined;
|
|
219
|
+
id: string;
|
|
220
|
+
label: string;
|
|
216
221
|
resetLabel?: string | undefined;
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
222
|
+
resetsAt?: number | undefined;
|
|
223
|
+
}>;
|
|
224
|
+
export declare const usageAmountSchema: import("@oh-my-pi/omptype").FluentType<{
|
|
220
225
|
limit?: number | undefined;
|
|
221
226
|
remaining?: number | undefined;
|
|
227
|
+
remainingFraction?: number | undefined;
|
|
228
|
+
unit: "bytes" | "minutes" | "percent" | "requests" | "tokens" | "unknown" | "usd";
|
|
229
|
+
used?: number | undefined;
|
|
222
230
|
usedFraction?: number | undefined;
|
|
231
|
+
}, {
|
|
232
|
+
limit?: number | undefined;
|
|
233
|
+
remaining?: number | undefined;
|
|
223
234
|
remainingFraction?: number | undefined;
|
|
224
235
|
unit: "bytes" | "minutes" | "percent" | "requests" | "tokens" | "unknown" | "usd";
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
236
|
+
used?: number | undefined;
|
|
237
|
+
usedFraction?: number | undefined;
|
|
238
|
+
}>;
|
|
239
|
+
export declare const usageScopeSchema: import("@oh-my-pi/omptype").FluentType<{
|
|
228
240
|
accountId?: string | undefined;
|
|
229
|
-
projectId?: string | undefined;
|
|
230
|
-
orgId?: string | undefined;
|
|
231
241
|
modelId?: string | undefined;
|
|
242
|
+
orgId?: string | undefined;
|
|
243
|
+
projectId?: string | undefined;
|
|
244
|
+
provider: string;
|
|
245
|
+
shared?: boolean | undefined;
|
|
232
246
|
tier?: string | undefined;
|
|
233
247
|
windowId?: string | undefined;
|
|
248
|
+
}, {
|
|
249
|
+
accountId?: string | undefined;
|
|
250
|
+
modelId?: string | undefined;
|
|
251
|
+
orgId?: string | undefined;
|
|
252
|
+
projectId?: string | undefined;
|
|
253
|
+
provider: string;
|
|
234
254
|
shared?: boolean | undefined;
|
|
235
|
-
|
|
236
|
-
|
|
255
|
+
tier?: string | undefined;
|
|
256
|
+
windowId?: string | undefined;
|
|
257
|
+
}>;
|
|
258
|
+
export declare const usageLimitSchema: import("@oh-my-pi/omptype").FluentType<{
|
|
259
|
+
amount: {
|
|
260
|
+
limit?: number | undefined;
|
|
261
|
+
remaining?: number | undefined;
|
|
262
|
+
remainingFraction?: number | undefined;
|
|
263
|
+
unit: "bytes" | "minutes" | "percent" | "requests" | "tokens" | "unknown" | "usd";
|
|
264
|
+
used?: number | undefined;
|
|
265
|
+
usedFraction?: number | undefined;
|
|
266
|
+
};
|
|
237
267
|
id: string;
|
|
238
268
|
label: string;
|
|
269
|
+
notes?: string[] | undefined;
|
|
239
270
|
scope: {
|
|
240
|
-
provider: string;
|
|
241
271
|
accountId?: string | undefined;
|
|
242
|
-
projectId?: string | undefined;
|
|
243
|
-
orgId?: string | undefined;
|
|
244
272
|
modelId?: string | undefined;
|
|
273
|
+
orgId?: string | undefined;
|
|
274
|
+
projectId?: string | undefined;
|
|
275
|
+
provider: string;
|
|
276
|
+
shared?: boolean | undefined;
|
|
245
277
|
tier?: string | undefined;
|
|
246
278
|
windowId?: string | undefined;
|
|
247
|
-
shared?: boolean | undefined;
|
|
248
279
|
};
|
|
280
|
+
status?: "exhausted" | "ok" | "unknown" | "warning" | undefined;
|
|
249
281
|
window?: {
|
|
282
|
+
durationMs?: number | undefined;
|
|
250
283
|
id: string;
|
|
251
284
|
label: string;
|
|
252
|
-
durationMs?: number | undefined;
|
|
253
|
-
resetsAt?: number | undefined;
|
|
254
285
|
resetLabel?: string | undefined;
|
|
286
|
+
resetsAt?: number | undefined;
|
|
255
287
|
} | undefined;
|
|
288
|
+
}, {
|
|
256
289
|
amount: {
|
|
257
|
-
used?: number | undefined;
|
|
258
290
|
limit?: number | undefined;
|
|
259
291
|
remaining?: number | undefined;
|
|
260
|
-
usedFraction?: number | undefined;
|
|
261
292
|
remainingFraction?: number | undefined;
|
|
262
293
|
unit: "bytes" | "minutes" | "percent" | "requests" | "tokens" | "unknown" | "usd";
|
|
294
|
+
used?: number | undefined;
|
|
295
|
+
usedFraction?: number | undefined;
|
|
263
296
|
};
|
|
264
|
-
|
|
297
|
+
id: string;
|
|
298
|
+
label: string;
|
|
265
299
|
notes?: string[] | undefined;
|
|
266
|
-
|
|
267
|
-
|
|
300
|
+
scope: {
|
|
301
|
+
accountId?: string | undefined;
|
|
302
|
+
modelId?: string | undefined;
|
|
303
|
+
orgId?: string | undefined;
|
|
304
|
+
projectId?: string | undefined;
|
|
305
|
+
provider: string;
|
|
306
|
+
shared?: boolean | undefined;
|
|
307
|
+
tier?: string | undefined;
|
|
308
|
+
windowId?: string | undefined;
|
|
309
|
+
};
|
|
310
|
+
status?: "exhausted" | "ok" | "unknown" | "warning" | undefined;
|
|
311
|
+
window?: {
|
|
312
|
+
durationMs?: number | undefined;
|
|
313
|
+
id: string;
|
|
314
|
+
label: string;
|
|
315
|
+
resetLabel?: string | undefined;
|
|
316
|
+
resetsAt?: number | undefined;
|
|
317
|
+
} | undefined;
|
|
318
|
+
}>;
|
|
319
|
+
export declare const usageResetCreditDetailSchema: import("@oh-my-pi/omptype").FluentType<{
|
|
320
|
+
expiresAt?: string | undefined;
|
|
268
321
|
grantedAt?: string | undefined;
|
|
322
|
+
status?: string | undefined;
|
|
323
|
+
}, {
|
|
269
324
|
expiresAt?: string | undefined;
|
|
325
|
+
grantedAt?: string | undefined;
|
|
270
326
|
status?: string | undefined;
|
|
271
|
-
}
|
|
272
|
-
export declare const usageResetCreditsSchema: import("
|
|
327
|
+
}>;
|
|
328
|
+
export declare const usageResetCreditsSchema: import("@oh-my-pi/omptype").FluentType<{
|
|
273
329
|
availableCount: number;
|
|
274
330
|
credits?: {
|
|
331
|
+
expiresAt?: string | undefined;
|
|
275
332
|
grantedAt?: string | undefined;
|
|
333
|
+
status?: string | undefined;
|
|
334
|
+
}[] | undefined;
|
|
335
|
+
}, {
|
|
336
|
+
availableCount: number;
|
|
337
|
+
credits?: {
|
|
276
338
|
expiresAt?: string | undefined;
|
|
339
|
+
grantedAt?: string | undefined;
|
|
277
340
|
status?: string | undefined;
|
|
278
341
|
}[] | undefined;
|
|
279
|
-
}
|
|
280
|
-
export declare const usageReportSchema: import("
|
|
281
|
-
provider: string;
|
|
342
|
+
}>;
|
|
343
|
+
export declare const usageReportSchema: import("@oh-my-pi/omptype").FluentType<{
|
|
282
344
|
fetchedAt: number;
|
|
283
345
|
limits: {
|
|
346
|
+
amount: {
|
|
347
|
+
limit?: number | undefined;
|
|
348
|
+
remaining?: number | undefined;
|
|
349
|
+
remainingFraction?: number | undefined;
|
|
350
|
+
unit: "bytes" | "minutes" | "percent" | "requests" | "tokens" | "unknown" | "usd";
|
|
351
|
+
used?: number | undefined;
|
|
352
|
+
usedFraction?: number | undefined;
|
|
353
|
+
};
|
|
284
354
|
id: string;
|
|
285
355
|
label: string;
|
|
356
|
+
notes?: string[] | undefined;
|
|
286
357
|
scope: {
|
|
287
|
-
provider: string;
|
|
288
358
|
accountId?: string | undefined;
|
|
289
|
-
projectId?: string | undefined;
|
|
290
|
-
orgId?: string | undefined;
|
|
291
359
|
modelId?: string | undefined;
|
|
360
|
+
orgId?: string | undefined;
|
|
361
|
+
projectId?: string | undefined;
|
|
362
|
+
provider: string;
|
|
363
|
+
shared?: boolean | undefined;
|
|
292
364
|
tier?: string | undefined;
|
|
293
365
|
windowId?: string | undefined;
|
|
294
|
-
shared?: boolean | undefined;
|
|
295
366
|
};
|
|
367
|
+
status?: "exhausted" | "ok" | "unknown" | "warning" | undefined;
|
|
296
368
|
window?: {
|
|
369
|
+
durationMs?: number | undefined;
|
|
297
370
|
id: string;
|
|
298
371
|
label: string;
|
|
299
|
-
durationMs?: number | undefined;
|
|
300
|
-
resetsAt?: number | undefined;
|
|
301
372
|
resetLabel?: string | undefined;
|
|
373
|
+
resetsAt?: number | undefined;
|
|
302
374
|
} | undefined;
|
|
375
|
+
}[];
|
|
376
|
+
metadata?: Record<string, unknown> | undefined;
|
|
377
|
+
notes?: string[] | undefined;
|
|
378
|
+
provider: string;
|
|
379
|
+
raw?: unknown;
|
|
380
|
+
resetCredits?: {
|
|
381
|
+
availableCount: number;
|
|
382
|
+
credits?: {
|
|
383
|
+
expiresAt?: string | undefined;
|
|
384
|
+
grantedAt?: string | undefined;
|
|
385
|
+
status?: string | undefined;
|
|
386
|
+
}[] | undefined;
|
|
387
|
+
} | undefined;
|
|
388
|
+
}, {
|
|
389
|
+
fetchedAt: number;
|
|
390
|
+
limits: {
|
|
303
391
|
amount: {
|
|
304
|
-
used?: number | undefined;
|
|
305
392
|
limit?: number | undefined;
|
|
306
393
|
remaining?: number | undefined;
|
|
307
|
-
usedFraction?: number | undefined;
|
|
308
394
|
remainingFraction?: number | undefined;
|
|
309
395
|
unit: "bytes" | "minutes" | "percent" | "requests" | "tokens" | "unknown" | "usd";
|
|
396
|
+
used?: number | undefined;
|
|
397
|
+
usedFraction?: number | undefined;
|
|
310
398
|
};
|
|
311
|
-
|
|
399
|
+
id: string;
|
|
400
|
+
label: string;
|
|
312
401
|
notes?: string[] | undefined;
|
|
402
|
+
scope: {
|
|
403
|
+
accountId?: string | undefined;
|
|
404
|
+
modelId?: string | undefined;
|
|
405
|
+
orgId?: string | undefined;
|
|
406
|
+
projectId?: string | undefined;
|
|
407
|
+
provider: string;
|
|
408
|
+
shared?: boolean | undefined;
|
|
409
|
+
tier?: string | undefined;
|
|
410
|
+
windowId?: string | undefined;
|
|
411
|
+
};
|
|
412
|
+
status?: "exhausted" | "ok" | "unknown" | "warning" | undefined;
|
|
413
|
+
window?: {
|
|
414
|
+
durationMs?: number | undefined;
|
|
415
|
+
id: string;
|
|
416
|
+
label: string;
|
|
417
|
+
resetLabel?: string | undefined;
|
|
418
|
+
resetsAt?: number | undefined;
|
|
419
|
+
} | undefined;
|
|
313
420
|
}[];
|
|
421
|
+
metadata?: Record<string, unknown> | undefined;
|
|
422
|
+
notes?: string[] | undefined;
|
|
423
|
+
provider: string;
|
|
424
|
+
raw?: unknown;
|
|
314
425
|
resetCredits?: {
|
|
315
426
|
availableCount: number;
|
|
316
427
|
credits?: {
|
|
317
|
-
grantedAt?: string | undefined;
|
|
318
428
|
expiresAt?: string | undefined;
|
|
429
|
+
grantedAt?: string | undefined;
|
|
319
430
|
status?: string | undefined;
|
|
320
431
|
}[] | undefined;
|
|
321
432
|
} | undefined;
|
|
322
|
-
|
|
323
|
-
metadata?: {
|
|
324
|
-
[x: string]: unknown;
|
|
325
|
-
} | undefined;
|
|
326
|
-
raw?: unknown;
|
|
327
|
-
}, {}>;
|
|
433
|
+
}>;
|
|
328
434
|
/** Optional logger for usage fetchers. */
|
|
329
435
|
export interface UsageLogger {
|
|
330
436
|
debug(message: string, meta?: Record<string, unknown>): void;
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* All three are normalized at the boundary so providers and validators see the same
|
|
11
11
|
* JSON Schema dialect.
|
|
12
12
|
*/
|
|
13
|
-
import type { Type } from "
|
|
13
|
+
import type { Type } from "@oh-my-pi/omptype";
|
|
14
14
|
import { type ZodType } from "zod/v4";
|
|
15
15
|
import type { Tool } from "../../types.js";
|
|
16
16
|
/**
|
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool-call argument validation pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Tools may declare their parameters as either Zod schemas (canonical) or
|
|
5
|
+
* plain JSON Schema (legacy / extensions). This module is the single
|
|
6
|
+
* entrypoint the agent calls before dispatching a tool — it:
|
|
7
|
+
*
|
|
8
|
+
* 1. Builds (or fetches from cache) a `ValidationContext` for the tool —
|
|
9
|
+
* the Zod schema if available plus the equivalent wire JSON Schema, or
|
|
10
|
+
* just the JSON Schema for non-Zod tools.
|
|
11
|
+
* 2. Normalizes LLM quirks (null / "null" → omit-or-default substitution)
|
|
12
|
+
* against the JSON Schema before validation.
|
|
13
|
+
* 3. Validates with the Zod or JSON-Schema validator.
|
|
14
|
+
* 4. On failure, walks the resulting issues and coerces common LLM type
|
|
15
|
+
* drift (JSON-stringified values, boolean/number/string scalar drift),
|
|
16
|
+
* drops unrecognized keys, and retries up to `MAX_COERCION_PASSES` times.
|
|
17
|
+
* 5. Throws a formatted error if reconciliation fails; otherwise returns
|
|
18
|
+
* the parsed arguments with original unknown root fields preserved (so
|
|
19
|
+
* hallucinated top-level keys still surface to the caller).
|
|
20
|
+
*
|
|
21
|
+
* The goal is to be conservative: every coercion is a structural rewrite that
|
|
22
|
+
* keeps the schema in charge of acceptance — we never invent values, only
|
|
23
|
+
* massage shapes the LLM almost got right.
|
|
24
|
+
*/
|
|
1
25
|
import type { Tool, ToolCall } from "../types.js";
|
|
2
26
|
/**
|
|
3
27
|
* Finds a tool by name and validates the tool call arguments against its schema.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-ai",
|
|
4
|
-
"version": "17.2.
|
|
4
|
+
"version": "17.2.8",
|
|
5
5
|
"description": "Unified LLM API with automatic model discovery and provider configuration",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -38,10 +38,10 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@bufbuild/protobuf": "^2.12.1",
|
|
41
|
-
"@oh-my-pi/
|
|
42
|
-
"@oh-my-pi/pi-
|
|
43
|
-
"@oh-my-pi/pi-
|
|
44
|
-
"
|
|
41
|
+
"@oh-my-pi/omptype": "17.2.8",
|
|
42
|
+
"@oh-my-pi/pi-catalog": "17.2.8",
|
|
43
|
+
"@oh-my-pi/pi-utils": "17.2.8",
|
|
44
|
+
"@oh-my-pi/pi-wire": "17.2.8",
|
|
45
45
|
"zod": "^4"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
* `omp auth-broker status` (liveness checks). All endpoints except
|
|
6
6
|
* `/v1/healthz` require a bearer token.
|
|
7
7
|
*/
|
|
8
|
+
|
|
9
|
+
import { type } from "@oh-my-pi/omptype";
|
|
8
10
|
import { readSseEvents } from "@oh-my-pi/pi-utils";
|
|
9
|
-
import { type } from "arktype";
|
|
10
11
|
import type { AuthCredential, DisabledCredentialSummary } from "../auth-storage";
|
|
11
12
|
import type {
|
|
12
13
|
ClientUsageReportRequest,
|
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
* Transport security is delegated to the operator (Tailscale / Wireguard);
|
|
10
10
|
* the server only checks a bearer token against an allow-list per request.
|
|
11
11
|
*/
|
|
12
|
+
|
|
13
|
+
import { type Type, type } from "@oh-my-pi/omptype";
|
|
12
14
|
import { logger } from "@oh-my-pi/pi-utils";
|
|
13
|
-
import { type Type, type } from "arktype";
|
|
14
15
|
import type { AuthStorage, StoredCredentialBlock } from "../auth-storage";
|
|
15
16
|
import { parseBind } from "../utils/parse-bind";
|
|
16
17
|
import { AuthBrokerRefresher, type AuthBrokerRefresherSchedule } from "./refresher";
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* exception (standard type keeps extra keys): it preserves provider-specific extension fields so
|
|
13
13
|
* they round-trip through the broker instead of being dropped (see below).
|
|
14
14
|
*/
|
|
15
|
-
import {
|
|
15
|
+
import { type Type, type } from "@oh-my-pi/omptype";
|
|
16
16
|
import {
|
|
17
17
|
type ApiKeyCredential,
|
|
18
18
|
type AuthCredential,
|
|
@@ -84,11 +84,6 @@ export interface AuthBrokerWireSchemas {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
function buildAuthBrokerWireSchemas(): AuthBrokerWireSchemas {
|
|
87
|
-
// Wire schemas validate only a handful of times per process, so ArkType's
|
|
88
|
-
// definition-time JIT codegen is startup tax. A local jitless scope skips
|
|
89
|
-
// that codegen and uses interpreted traversal; correctness is unchanged.
|
|
90
|
-
const { type } = scope({}, { jitless: true });
|
|
91
|
-
|
|
92
87
|
// ─── Credential payloads ───────────────────────────────────────────────────
|
|
93
88
|
|
|
94
89
|
/** Real OAuth credential (broker-side) — refresh token is the actual upstream value. */
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { type } from "@oh-my-pi/omptype";
|
|
1
2
|
import { Effort } from "@oh-my-pi/pi-catalog/effort";
|
|
2
3
|
import { logger } from "@oh-my-pi/pi-utils";
|
|
3
|
-
import { type } from "arktype";
|
|
4
4
|
import { captureRequestHeaders, resolvePromptCacheKey } from "../auth-gateway/http";
|
|
5
5
|
import * as AIError from "../error";
|
|
6
6
|
import type {
|
package/src/providers/cursor.ts
CHANGED
|
@@ -144,6 +144,7 @@ import { isKimiK3ModelId } from "@oh-my-pi/pi-catalog/identity";
|
|
|
144
144
|
import { calculateCost } from "@oh-my-pi/pi-catalog/models";
|
|
145
145
|
import {
|
|
146
146
|
$env,
|
|
147
|
+
logger,
|
|
147
148
|
parseJsonWithRepair,
|
|
148
149
|
parseStreamingJson,
|
|
149
150
|
parseStreamingJsonThrottled,
|
|
@@ -233,6 +234,7 @@ const NOT_IMPLEMENTED = `Not implemented by this client`;
|
|
|
233
234
|
|
|
234
235
|
const conversationStateCache = new Map<string, ConversationStateStructure>();
|
|
235
236
|
const conversationBlobStores = new Map<string, Map<string, Uint8Array>>();
|
|
237
|
+
const warnedCursorKimiK3ReplayMessages = new Set<string>();
|
|
236
238
|
|
|
237
239
|
export interface CursorOptions extends StreamOptions {
|
|
238
240
|
customSystemPrompt?: string;
|
|
@@ -3902,6 +3904,15 @@ export function processInteractionUpdate(
|
|
|
3902
3904
|
}
|
|
3903
3905
|
} else if (updateCase === "turnEnded") {
|
|
3904
3906
|
output.stopReason = "stop";
|
|
3907
|
+
if (
|
|
3908
|
+
isKimiK3ModelId(output.model) &&
|
|
3909
|
+
!output.content.some(item => item.type === "thinking" && item.thinking.length > 0)
|
|
3910
|
+
) {
|
|
3911
|
+
logger.warn(
|
|
3912
|
+
"Cursor kimi-k3 turn completed without thinking blocks; persisted history will replay this turn without reasoning",
|
|
3913
|
+
{ model: output.model, messageTimestamp: output.timestamp },
|
|
3914
|
+
);
|
|
3915
|
+
}
|
|
3905
3916
|
} else if (updateCase === "tokenDelta") {
|
|
3906
3917
|
const tokenDelta = update.message.value;
|
|
3907
3918
|
usageState.sawTokenDelta = true;
|
|
@@ -4113,17 +4124,34 @@ function assertCursorKimiK3HistoryReplayable(
|
|
|
4113
4124
|
): void {
|
|
4114
4125
|
if (!targetModelId || !isKimiK3ModelId(targetModelId)) return;
|
|
4115
4126
|
const historyEnd = activeUserMessageIndex >= 0 ? activeUserMessageIndex : messages.length;
|
|
4127
|
+
const missingThinkingTurns: number[] = [];
|
|
4128
|
+
const newlyWarnedKeys: string[] = [];
|
|
4129
|
+
let assistantTurn = 0;
|
|
4116
4130
|
for (let i = 0; i < historyEnd; i++) {
|
|
4117
4131
|
const msg = messages[i];
|
|
4118
4132
|
if (msg.role !== "assistant") continue;
|
|
4133
|
+
assistantTurn++;
|
|
4119
4134
|
const isSameCursorModel = msg.api === "cursor-agent" && msg.provider === "cursor" && msg.model === targetModelId;
|
|
4120
|
-
|
|
4121
|
-
|
|
4135
|
+
if (!isSameCursorModel) {
|
|
4136
|
+
// Foreign history genuinely cannot replay K3 thinking: another model's
|
|
4137
|
+
// turns carry no K3-signed reasoning to reconstruct.
|
|
4122
4138
|
throw new AIError.ValidationError(
|
|
4123
|
-
`Cursor ${targetModelId}
|
|
4139
|
+
`Cursor ${targetModelId} cannot continue history from a different model (${msg.provider}/${msg.model}); start a new session.`,
|
|
4124
4140
|
);
|
|
4125
4141
|
}
|
|
4142
|
+
const hasThinking = msg.content.some(item => item.type === "thinking" && item.thinking.length > 0);
|
|
4143
|
+
if (hasThinking) continue;
|
|
4144
|
+
const warningKey = `${msg.api}\0${msg.provider}\0${msg.model}\0${msg.timestamp}`;
|
|
4145
|
+
if (warnedCursorKimiK3ReplayMessages.has(warningKey)) continue;
|
|
4146
|
+
missingThinkingTurns.push(assistantTurn);
|
|
4147
|
+
newlyWarnedKeys.push(warningKey);
|
|
4126
4148
|
}
|
|
4149
|
+
if (missingThinkingTurns.length === 0) return;
|
|
4150
|
+
for (const key of newlyWarnedKeys) warnedCursorKimiK3ReplayMessages.add(key);
|
|
4151
|
+
logger.warn(
|
|
4152
|
+
`Cursor kimi-k3 history contains same-model assistant turn(s) ${missingThinkingTurns.join(", ")} without thinking blocks; replaying those spans without reasoning may make generation less stable`,
|
|
4153
|
+
{ model: targetModelId, assistantTurns: missingThinkingTurns },
|
|
4154
|
+
);
|
|
4127
4155
|
}
|
|
4128
4156
|
|
|
4129
4157
|
/**
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
7
7
|
import { scheduler } from "node:timers/promises";
|
|
8
|
+
import { type } from "@oh-my-pi/omptype";
|
|
8
9
|
import { calculateCost } from "@oh-my-pi/pi-catalog/models";
|
|
9
10
|
import {
|
|
10
11
|
ANTIGRAVITY_SYSTEM_INSTRUCTION,
|
|
@@ -13,7 +14,6 @@ import {
|
|
|
13
14
|
getGeminiCliHeaders,
|
|
14
15
|
} from "@oh-my-pi/pi-catalog/wire/gemini-headers";
|
|
15
16
|
import { extractHttpStatusFromError, fetchWithRetry, readSseJson } from "@oh-my-pi/pi-utils";
|
|
16
|
-
import { type } from "arktype";
|
|
17
17
|
import * as AIError from "../error";
|
|
18
18
|
import type {
|
|
19
19
|
Api,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as os from "node:os";
|
|
2
2
|
import { scheduler } from "node:timers/promises";
|
|
3
|
+
import { type } from "@oh-my-pi/omptype";
|
|
3
4
|
import { calculateCost } from "@oh-my-pi/pi-catalog/models";
|
|
4
5
|
import {
|
|
5
6
|
CODEX_BASE_URL,
|
|
@@ -19,7 +20,6 @@ import {
|
|
|
19
20
|
readSseJson,
|
|
20
21
|
structuredCloneJSON,
|
|
21
22
|
} from "@oh-my-pi/pi-utils";
|
|
22
|
-
import { type } from "arktype";
|
|
23
23
|
import packageJson from "../../package.json" with { type: "json" };
|
|
24
24
|
import * as AIError from "../error";
|
|
25
25
|
import { getEnvApiKey, isOfficialCodexApiUrl } from "../stream";
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
* Inverse direction (source-of-truth for item shapes): ../../providers/openai-responses.ts
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
+
import { type } from "@oh-my-pi/omptype";
|
|
12
13
|
import { logger, structuredCloneJSON } from "@oh-my-pi/pi-utils";
|
|
13
|
-
import { type } from "arktype";
|
|
14
14
|
import { resolvePromptCacheKey } from "../auth-gateway/http";
|
|
15
15
|
import type { AuthGatewayStreamControl, AuthGatewayParsedRequest as ParsedRequest } from "../auth-gateway/types";
|
|
16
16
|
import * as AIError from "../error";
|
package/src/types.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from "@oh-my-pi/pi-catalog/effort";
|
|
2
2
|
export * from "@oh-my-pi/pi-catalog/types";
|
|
3
3
|
|
|
4
|
+
import type { Type } from "@oh-my-pi/omptype";
|
|
4
5
|
import type {
|
|
5
6
|
DeleteArgs,
|
|
6
7
|
DeleteResult,
|
|
@@ -35,7 +36,6 @@ import type {
|
|
|
35
36
|
import type { Effort } from "@oh-my-pi/pi-catalog/effort";
|
|
36
37
|
import { isOpenAIModelId } from "@oh-my-pi/pi-catalog/identity/family";
|
|
37
38
|
import type { Api, FetchImpl, KnownApi, Model, Provider, ThinkingBudgets, Usage } from "@oh-my-pi/pi-catalog/types";
|
|
38
|
-
import type { Type } from "arktype";
|
|
39
39
|
import type { ZodType, z } from "zod/v4";
|
|
40
40
|
import type { ApiKey } from "./auth-retry";
|
|
41
41
|
import type { BedrockOptions } from "./providers/amazon-bedrock";
|
|
@@ -214,16 +214,19 @@ export function resolveModelServiceTier(
|
|
|
214
214
|
|
|
215
215
|
/**
|
|
216
216
|
* True when the tier should be sent on the wire as the provider's service-tier
|
|
217
|
-
* request field.
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
217
|
+
* request field. `auto` is never forwarded — it is OpenAI's implicit default, so
|
|
218
|
+
* omitting `service_tier` is identical to requesting `auto`, and the Codex
|
|
219
|
+
* (ChatGPT OAuth) endpoint rejects an explicit `auto` outright. OpenAI /
|
|
220
|
+
* OpenAI-Codex accept every other {@link ServiceTier}; Google (Gemini API +
|
|
221
|
+
* Vertex) and OpenRouter accept `flex`/`priority`; Fireworks Serverless
|
|
222
|
+
* realizes only its Priority serving path. Anthropic is absent because it
|
|
223
|
+
* realizes `priority` via `speed: "fast"`.
|
|
221
224
|
*/
|
|
222
225
|
export function shouldSendServiceTier(
|
|
223
226
|
serviceTier: ServiceTier | null | undefined,
|
|
224
227
|
target: Provider | ServiceTierModel | undefined,
|
|
225
228
|
): boolean {
|
|
226
|
-
if (!serviceTier) return false;
|
|
229
|
+
if (!serviceTier || serviceTier === "auto") return false;
|
|
227
230
|
const provider = typeof target === "string" ? target : target?.provider;
|
|
228
231
|
if (provider === "openai" || provider === "openai-codex") return true;
|
|
229
232
|
if (provider === "openrouter") {
|
package/src/usage.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Provides a normalized schema to represent multiple limit windows, model tiers,
|
|
5
5
|
* and shared quotas across providers.
|
|
6
6
|
*/
|
|
7
|
-
import { type } from "
|
|
7
|
+
import { type } from "@oh-my-pi/omptype";
|
|
8
8
|
import type { FetchImpl, Provider } from "./types";
|
|
9
9
|
export type UsageUnit = "percent" | "tokens" | "requests" | "usd" | "minutes" | "bytes" | "unknown";
|
|
10
10
|
|
package/src/utils/schema/wire.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* JSON Schema dialect.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import type { Type } from "
|
|
14
|
+
import type { Type } from "@oh-my-pi/omptype";
|
|
15
15
|
// We import the Zod *value* (z) for runtime APIs. Marker checks rely on the
|
|
16
16
|
// `_zod` symbol that every Zod v4 schema instance carries.
|
|
17
17
|
import { type ZodType, z } from "zod/v4";
|