@linxiraos/pi-ai 1.3.0 → 1.3.2
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 -21
- package/dist/types/dialect/deepseek.d.ts +13 -0
- package/dist/types/judgment/native.d.ts +13 -2
- package/dist/types/judgment/types.d.ts +32 -5
- package/dist/types/judgment/wire.d.ts +2 -0
- package/dist/types/providers/ollama.d.ts +6 -1
- package/dist/types/providers/transform-messages.d.ts +2 -0
- package/dist/types/usage/muse-code.d.ts +1 -1
- package/dist/types/utils/dsml-leak.d.ts +13 -11
- package/package.json +6 -6
- package/src/dialect/deepseek.ts +344 -81
- package/src/judgment/native.ts +63 -7
- package/src/judgment/openai-decisions.ts +3 -0
- package/src/judgment/systemone.ts +27 -6
- package/src/judgment/text.ts +6 -0
- package/src/judgment/types.ts +41 -5
- package/src/judgment/wire.ts +2 -0
- package/src/providers/ollama.ts +12 -4
- package/src/providers/transform-messages.ts +9 -4
- package/src/usage/muse-code.ts +115 -29
- package/src/utils/dsml-leak.ts +58 -19
package/CHANGELOG.md
CHANGED
|
@@ -1,37 +1,30 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
-
## [1.3.
|
|
3
|
+
## [1.3.2] - 2026-10-19
|
|
4
|
+
|
|
5
|
+
- Version line moves to 1.3.2 with the rest of the suite; no user-visible change in this package.
|
|
6
|
+
|
|
7
|
+
## [1.3.1] - 2026-10-19
|
|
4
8
|
|
|
5
9
|
### Breaking Changes
|
|
6
10
|
|
|
7
11
|
- `isOfficialCodexApiUrl` moved from `@linxiraos/pi-ai` to `@linxiraos/pi-catalog/wire/codex`, next to `CODEX_BASE_URL`, so the catalog's compat resolver classifies Codex endpoints with the same check ([#15434](https://github.com/can1357/oh-my-pi/pull/15434) by [@will-bogusz](https://github.com/will-bogusz))
|
|
8
|
-
- `resolveGatewayApiKey` and `buildGatewayApiKeyResolver` (`@oh-my-pi/pi-ai/auth-gateway`) take the request's route options (`{ storage, client? }`) instead of an `AuthStorage`, their resolver callback receives the resolved credential, and `resolveGatewayAccount` takes that credential ([#15900](https://github.com/can1357/oh-my-pi/pull/15900) by [@alphastorm](https://github.com/alphastorm))
|
|
9
|
-
- `PI_CODEX_ZSTD` is replaced by `PI_REQUEST_COMPRESSION`; set `PI_REQUEST_COMPRESSION=0` to send Codex (and every other) request body uncompressed ([#16086](https://github.com/can1357/oh-my-pi/pull/16086) by [@H4vC](https://github.com/H4vC))
|
|
10
12
|
|
|
11
13
|
### Added
|
|
12
14
|
|
|
13
|
-
- Added
|
|
14
|
-
- Added `
|
|
15
|
-
- Added `reachesOfficialEndpoint(model)`: whether a request to the model reaches the official endpoint its compat was built for, following `ANTHROPIC_BASE_URL` and Foundry's `FOUNDRY_BASE_URL` reroutes of first-party Anthropic models ([#15434](https://github.com/can1357/oh-my-pi/pull/15434) by [@will-bogusz](https://github.com/will-bogusz))
|
|
16
|
-
- Added `AssistantMessage.elidedOutputTokens`, the visible output tokens a history rewrite (shake) has removed from the turn, which `usage.output` still counts ([#15446](https://github.com/can1357/oh-my-pi/pull/15446) by [@will-bogusz](https://github.com/will-bogusz))
|
|
17
|
-
- Exported `shouldDropTruncatedThinkingOnlyAssistant` from `providers/transform-messages`, `isColdReplayableResponsesTurn` from `providers/openai-shared` and the new `openAIResponsesReplaysNativeHistory` from `providers/openai-responses`, so local token estimates can follow which turns replay drops and whether a session replays native history ([#15447](https://github.com/can1357/oh-my-pi/pull/15447) by [@will-bogusz](https://github.com/will-bogusz))
|
|
18
|
-
- Added image support for native OpenAI Decisions and Workers AI judgments, prompted vision chat, and auth-gateway System One requests; images exceeding a judgment API's documented caps (e.g. Clef's 4 images, 4 MiB each) are rejected locally ([#15471](https://github.com/can1357/oh-my-pi/pull/15471) by [@anatoli-tsinovoy](https://github.com/anatoli-tsinovoy)).
|
|
19
|
-
- `isSurvivingAssistant` in `providers/transform-messages`: whether an assistant turn reaches a replay, malformed tool calls dropped first, so callers outside `transformMessages` pick the same latest turn ([#15791](https://github.com/can1357/oh-my-pi/pull/15791) by [@will-bogusz](https://github.com/will-bogusz))
|
|
20
|
-
- Added scoped clients to `startAuthGateway` (`clients`, `setClients`): each client bearer is limited to its own models and OAuth accounts, with no fallback to other accounts or API keys, and request log lines name the client and the credential a request started on ([#5098](https://github.com/can1357/oh-my-pi/issues/5098), [#15900](https://github.com/can1357/oh-my-pi/pull/15900) by [@alphastorm](https://github.com/alphastorm))
|
|
21
|
-
- Added experimental native image judgments for TypeSafe Jev's `jev-latest`, `jev-preview`, `jev-1.13.0`, and `jev-1.14.0`, plus OpenRouter's `typesafe/jev-1.13`, `typesafe/jev-1.14`, and `~typesafe/jev-latest` models; images outside Jev's documented size bounds fall through to a vision chat judge instead of failing ([#15887](https://github.com/can1357/oh-my-pi/pull/15887) by [@anatoli-tsinovoy](https://github.com/anatoli-tsinovoy))
|
|
22
|
-
- Added `ThinkingContent.narration`, set on Anthropic and Bedrock thinking blocks whose signature marks them as between-tool narration, and `presentNarrationAsAnswer(message)` to show those blocks as reply text while replay keeps them as signed thinking
|
|
23
|
-
- Added `keys.peek(provider, { includeExpired: true })` to name the stored account behind an expired OAuth token for reads that never send it, such as keying an offline model-cache lookup ([#16061](https://github.com/can1357/oh-my-pi/pull/16061) by [@gchai](https://github.com/gchai))
|
|
24
|
-
- Added `prewarmModelConnection(model)` (`providers/connection-prewarm`), which opens the model's API connection ahead of a request using the same transport and TLS settings so the request reuses it instead of paying the connection handshake ([#16086](https://github.com/can1357/oh-my-pi/pull/16086) by [@H4vC](https://github.com/H4vC))
|
|
15
|
+
- Added `nativeJudgmentImageBounds()`: the image bounds a native judge enforces, its wire's transport limits tightened by the catalog's model bounds
|
|
16
|
+
- Added Box judgment questions (`BoxQuestion`/`BoxAnswer`, TypeSafe Jev 1.14+ direct or through OpenRouter): each names the request image it searches by `image` index, and comes back as that image's edges as 0–1 fractions; text, OpenAI Decisions, and Workers AI judges reject them
|
|
25
17
|
|
|
26
|
-
###
|
|
18
|
+
### Fixed
|
|
27
19
|
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
|
|
31
|
-
|
|
20
|
+
- Fixed Muse Code usage going stale whenever its 5-hour window sits idle: the idle window now reports as unused, and weekly usage carries over from the last active window until its reset ([#16193](https://github.com/can1357/oh-my-pi/pull/16193) by [@eggpeat](https://github.com/eggpeat))
|
|
21
|
+
- Fixed DeepSeek tool calls never running when the model writes them as chat-template tokens with `_` in place of `▁`, a missing `|`, or no per-call close (e.g. `<|tool_calls_begin|>…<|tool_calls_end|>`): they now run as tool calls, and any that still cannot be parsed are removed from history and reported to the model as a failed call ([#16216](https://github.com/can1357/oh-my-pi/pull/16216) by [@H4vC](https://github.com/H4vC))
|
|
22
|
+
|
|
23
|
+
## [1.3.0] - 2026-10-18
|
|
32
24
|
|
|
33
25
|
### Fixed
|
|
34
26
|
|
|
27
|
+
- Fixed every request failing behind a TLS-inspecting proxy that refuses compressed uploads: a 400/403/415 whose body is not JSON, or the Anthropic API's "request body is not valid JSON" after a proxy drops `Content-Encoding`, now resends the body uncompressed and stops compressing for that host ([#16108](https://github.com/can1357/oh-my-pi/pull/16108) by [@alphastorm](https://github.com/alphastorm))
|
|
35
28
|
- Fixed Claude on Google Antigravity failing every turn with "image exceeds 5 MB maximum" once a large image entered the conversation; images are now downscaled to the host's limits before sending, as on the Anthropic API ([#15444](https://github.com/can1357/oh-my-pi/pull/15444) by [@will-bogusz](https://github.com/will-bogusz))
|
|
36
29
|
- Fixed Codex cybersecurity policy errors incorrectly retrying without Daybreak and disabling it for subsequent requests, while preserving retries without Daybreak when access is rejected ([#15472](https://github.com/can1357/oh-my-pi/pull/15472) by [@taibenvenuti](https://github.com/taibenvenuti))
|
|
37
30
|
- Fixed Codex-hosted image generation ignoring the requested `aspect_ratio`/`image_size`, and `3:2`/`2:3` requests sending no size to OpenAI image models ([#15601](https://github.com/can1357/oh-my-pi/pull/15601) by [@chulmin-dev](https://github.com/chulmin-dev))
|
|
@@ -77,7 +70,33 @@
|
|
|
77
70
|
- Fixed Jev image limits rejecting inputs for unrelated native judges and redundant TypeSafe image judgments when only detail changes ([#16002](https://github.com/can1357/oh-my-pi/pull/16002) by [@anatoli-tsinovoy](https://github.com/anatoli-tsinovoy)).
|
|
78
71
|
- Fixed SIGTERM interrupting an in-flight OAuth token rotation before its replacement refresh token was saved ([#15845](https://github.com/can1357/oh-my-pi/issues/15845)).
|
|
79
72
|
- Fixed sessions getting stuck on HTTP 400 after replaying tool names unsupported by the target provider, including invented `proc://*` calls and Google tool names sent to Bedrock ([#15839](https://github.com/can1357/oh-my-pi/issues/15839))
|
|
80
|
-
|
|
73
|
+
|
|
74
|
+
### Breaking Changes
|
|
75
|
+
|
|
76
|
+
- `resolveGatewayApiKey` and `buildGatewayApiKeyResolver` (`@oh-my-pi/pi-ai/auth-gateway`) take the request's route options (`{ storage, client? }`) instead of an `AuthStorage`, their resolver callback receives the resolved credential, and `resolveGatewayAccount` takes that credential ([#15900](https://github.com/can1357/oh-my-pi/pull/15900) by [@alphastorm](https://github.com/alphastorm))
|
|
77
|
+
- `PI_CODEX_ZSTD` is replaced by `PI_REQUEST_COMPRESSION`; set `PI_REQUEST_COMPRESSION=0` to send Codex (and every other) request body uncompressed ([#16086](https://github.com/can1357/oh-my-pi/pull/16086) by [@H4vC](https://github.com/H4vC))
|
|
78
|
+
|
|
79
|
+
### Added
|
|
80
|
+
|
|
81
|
+
- Added support for `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS` on the `anthropic` provider: when set, requests omit pre-release fields (`context_management`, beta tool fields such as `strict` and `defer_loading`, task budgets, structured-output format, `thinking.block_binding`, and Anthropic server compaction) along with their beta headers, so `ANTHROPIC_BASE_URL` gateways that reject them keep working ([#15458](https://github.com/can1357/oh-my-pi/pull/15458) by [@H4vC](https://github.com/H4vC))
|
|
82
|
+
- Added `withoutUnverifiedThinking` utility to filter reasoning capability from models when no effort is requested
|
|
83
|
+
- Added `reachesOfficialEndpoint(model)`: whether a request to the model reaches the official endpoint its compat was built for, following `ANTHROPIC_BASE_URL` and Foundry's `FOUNDRY_BASE_URL` reroutes of first-party Anthropic models ([#15434](https://github.com/can1357/oh-my-pi/pull/15434) by [@will-bogusz](https://github.com/will-bogusz))
|
|
84
|
+
- Added `AssistantMessage.elidedOutputTokens`, the visible output tokens a history rewrite (shake) has removed from the turn, which `usage.output` still counts ([#15446](https://github.com/can1357/oh-my-pi/pull/15446) by [@will-bogusz](https://github.com/will-bogusz))
|
|
85
|
+
- Exported `shouldDropTruncatedThinkingOnlyAssistant` from `providers/transform-messages`, `isColdReplayableResponsesTurn` from `providers/openai-shared` and the new `openAIResponsesReplaysNativeHistory` from `providers/openai-responses`, so local token estimates can follow which turns replay drops and whether a session replays native history ([#15447](https://github.com/can1357/oh-my-pi/pull/15447) by [@will-bogusz](https://github.com/will-bogusz))
|
|
86
|
+
- Added image support for native OpenAI Decisions and Workers AI judgments, prompted vision chat, and auth-gateway System One requests; images exceeding a judgment API's documented caps (e.g. Clef's 4 images, 4 MiB each) are rejected locally ([#15471](https://github.com/can1357/oh-my-pi/pull/15471) by [@anatoli-tsinovoy](https://github.com/anatoli-tsinovoy)).
|
|
87
|
+
- `isSurvivingAssistant` in `providers/transform-messages`: whether an assistant turn reaches a replay, malformed tool calls dropped first, so callers outside `transformMessages` pick the same latest turn ([#15791](https://github.com/can1357/oh-my-pi/pull/15791) by [@will-bogusz](https://github.com/will-bogusz))
|
|
88
|
+
- Added scoped clients to `startAuthGateway` (`clients`, `setClients`): each client bearer is limited to its own models and OAuth accounts, with no fallback to other accounts or API keys, and request log lines name the client and the credential a request started on ([#5098](https://github.com/can1357/oh-my-pi/issues/5098), [#15900](https://github.com/can1357/oh-my-pi/pull/15900) by [@alphastorm](https://github.com/alphastorm))
|
|
89
|
+
- Added experimental native image judgments for TypeSafe Jev's `jev-latest`, `jev-preview`, `jev-1.13.0`, and `jev-1.14.0`, plus OpenRouter's `typesafe/jev-1.13`, `typesafe/jev-1.14`, and `~typesafe/jev-latest` models; images outside Jev's documented size bounds fall through to a vision chat judge instead of failing ([#15887](https://github.com/can1357/oh-my-pi/pull/15887) by [@anatoli-tsinovoy](https://github.com/anatoli-tsinovoy))
|
|
90
|
+
- Added `ThinkingContent.narration`, set on Anthropic and Bedrock thinking blocks whose signature marks them as between-tool narration, and `presentNarrationAsAnswer(message)` to show those blocks as reply text while replay keeps them as signed thinking
|
|
91
|
+
- Added `keys.peek(provider, { includeExpired: true })` to name the stored account behind an expired OAuth token for reads that never send it, such as keying an offline model-cache lookup ([#16061](https://github.com/can1357/oh-my-pi/pull/16061) by [@gchai](https://github.com/gchai))
|
|
92
|
+
- Added `prewarmModelConnection(model)` (`providers/connection-prewarm`), which opens the model's API connection ahead of a request using the same transport and TLS settings so the request reuses it instead of paying the connection handshake ([#16086](https://github.com/can1357/oh-my-pi/pull/16086) by [@H4vC](https://github.com/H4vC))
|
|
93
|
+
|
|
94
|
+
### Changed
|
|
95
|
+
|
|
96
|
+
- Anthropic requests to the official API now gzip the request body, so long conversations reach the model sooner on slow uplinks; set `PI_REQUEST_COMPRESSION=0` to disable it ([#16044](https://github.com/can1357/oh-my-pi/pull/16044) by [@H4vC](https://github.com/H4vC))
|
|
97
|
+
- GitHub Copilot requests (chat completions, Responses, and Claude messages) now send zstd-compressed bodies, cutting upload size by roughly 60–75% on long conversations; set `PI_REQUEST_COMPRESSION=0` to disable it ([#16086](https://github.com/can1357/oh-my-pi/pull/16086) by [@H4vC](https://github.com/H4vC))
|
|
98
|
+
- A rejected request-body encoding now only disables compression for that host, and only after the uncompressed resend succeeds, so a genuine 400 no longer turns compression off ([#16086](https://github.com/can1357/oh-my-pi/pull/16086) by [@H4vC](https://github.com/H4vC))
|
|
99
|
+
- Connection warm-up now covers every catalog provider, not only the official Anthropic API: it re-warms the origin a model's requests actually reach (Copilot plan hosts, `MOONSHOT_BASE_URL`, regional hosts), throttled per host; custom providers, built-in provider ids routed to a gateway, local hosts, and Anthropic gateways are never probed ([#16086](https://github.com/can1357/oh-my-pi/pull/16086) by [@H4vC](https://github.com/H4vC))
|
|
81
100
|
|
|
82
101
|
### Removed
|
|
83
102
|
|
|
@@ -4,6 +4,19 @@ export declare const DEEPSEEK_TOOL_CALLS_END = "<\uFF5Ctool\u2581calls\u2581end\
|
|
|
4
4
|
export declare const DEEPSEEK_TOOL_CALL_BEGIN = "<\uFF5Ctool\u2581call\u2581begin\uFF5C>";
|
|
5
5
|
export declare const DEEPSEEK_TOOL_CALL_END = "<\uFF5Ctool\u2581call\u2581end\uFF5C>";
|
|
6
6
|
export declare const DEEPSEEK_TOOL_SEPARATOR = "<\uFF5Ctool\u2581sep\uFF5C>";
|
|
7
|
+
/** DeepSeek template tokens that structure a tool call. */
|
|
8
|
+
export declare const DEEPSEEK_TOOL_CALL_TOKENS: Readonly<Record<string, true>>;
|
|
9
|
+
/** A token found in text: its canonical spelling and the text actually written. */
|
|
10
|
+
export interface DeepSeekTokenMatch {
|
|
11
|
+
readonly token: string;
|
|
12
|
+
readonly raw: string;
|
|
13
|
+
readonly index: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Find the earliest of `tokens` in `text` at or after `from`, in its canonical
|
|
17
|
+
* spelling or any re-spelling described at {@link TEMPLATE_TOKEN_SPELLING}.
|
|
18
|
+
*/
|
|
19
|
+
export declare function findDeepSeekTemplateToken(text: string, tokens: Readonly<Record<string, true>>, from?: number): DeepSeekTokenMatch | undefined;
|
|
7
20
|
export declare class DeepSeekInbandScanner implements InbandScanner {
|
|
8
21
|
#private;
|
|
9
22
|
constructor(options?: InbandScannerOptions);
|
|
@@ -41,10 +41,15 @@ export type JudgmentApi = keyof typeof JUDGMENT_WIRES;
|
|
|
41
41
|
export declare function isJudgmentApi(api: Api): api is JudgmentApi;
|
|
42
42
|
/** Whether both the native protocol and catalog model support image input. */
|
|
43
43
|
export declare function nativeJudgmentSupportsImages(model: Model): boolean;
|
|
44
|
+
/** Whether `model`'s native judgment takes images and its wire forwards box questions. The model itself may still refuse them (Box needs Jev 1.14+). */
|
|
45
|
+
export declare function nativeJudgmentSupportsBoxes(model: Model): boolean;
|
|
44
46
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
+
* Every image bound `model`'s native judgment enforces: its wire's transport limits tightened by the
|
|
48
|
+
* catalog's model bounds. `undefined` when it takes no images. Native APIs reject images outside these
|
|
49
|
+
* rather than resizing them, so callers size images to them first.
|
|
47
50
|
*/
|
|
51
|
+
export declare function nativeJudgmentImageBounds(model: Model): JudgmentImageInput | undefined;
|
|
52
|
+
/** Whether `model`'s native judgment API takes these exact images: image support within every {@link nativeJudgmentImageBounds}. */
|
|
48
53
|
export declare function nativeJudgmentAcceptsImages(model: Model, images: readonly ImageContent[]): boolean;
|
|
49
54
|
/**
|
|
50
55
|
* Reject images that `model`'s native judgment API cannot take — no image support, an unsupported or
|
|
@@ -52,6 +57,12 @@ export declare function nativeJudgmentAcceptsImages(model: Model, images: readon
|
|
|
52
57
|
* @throws {AIError.ValidationError} naming the reason.
|
|
53
58
|
*/
|
|
54
59
|
export declare function checkNativeJudgmentImages(model: Model, request: JudgmentRequest, imageAssets?: JudgmentImageAssets): void;
|
|
60
|
+
/**
|
|
61
|
+
* Reject box questions whose `image` is not an index into `request.images`: nothing would say which
|
|
62
|
+
* image their edges measure.
|
|
63
|
+
* @throws {AIError.ValidationError} naming the question.
|
|
64
|
+
*/
|
|
65
|
+
export declare function checkBoxQuestions(request: JudgmentRequest): void;
|
|
55
66
|
/** `TYPESAFE_BASE_URL` when set, else the public API root; trailing slashes stripped. */
|
|
56
67
|
export declare function typesafeBaseUrl(): string;
|
|
57
68
|
/** `TYPESAFE_DEFAULT_MODEL` when set, else {@link TYPESAFE_DEFAULT_MODEL}. */
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* A {@link Judge} answers a map of named questions — {@link ChoiceQuestion}
|
|
5
5
|
* (one option from a fixed set), {@link NoulQuestion} (probability that a
|
|
6
|
-
* yes/no condition holds), {@link ScoreQuestion} (position on ordered levels)
|
|
7
|
-
*
|
|
6
|
+
* yes/no condition holds), {@link ScoreQuestion} (position on ordered levels),
|
|
7
|
+
* {@link BoxQuestion} (where a target is in one of the request's images, native
|
|
8
|
+
* judges only) — about one {@link JudgmentState}. Every question in a request sees the same
|
|
8
9
|
* state and is answered independently, so callers batch independent questions
|
|
9
10
|
* into one call. The shape mirrors TypeSafe's System One API so the native
|
|
10
11
|
* backend ({@link NativeJudge}) forwards requests verbatim, while the text
|
|
@@ -41,7 +42,19 @@ export interface ScoreQuestion {
|
|
|
41
42
|
instructions: string;
|
|
42
43
|
criteria: readonly [string, string, ...string[]];
|
|
43
44
|
}
|
|
44
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Where one target is in an image (TypeSafe Box, Jev 1.14+): https://docs.typesafe.ai/primitives/box.
|
|
47
|
+
* Only native judges answer it. `instructions` must name the target and, among several images, which
|
|
48
|
+
* one to search; `image` stays local and says which entry of {@link JudgmentRequest.images} the
|
|
49
|
+
* answer's edges measure, so a judge that resizes or pads that image can map them back.
|
|
50
|
+
*/
|
|
51
|
+
export interface BoxQuestion {
|
|
52
|
+
type: "box";
|
|
53
|
+
instructions: string;
|
|
54
|
+
/** Index into the request's `images` of the image searched. */
|
|
55
|
+
image: number;
|
|
56
|
+
}
|
|
57
|
+
export type Question = ChoiceQuestion | NoulQuestion | ScoreQuestion | BoxQuestion;
|
|
45
58
|
/** Questions keyed by caller-chosen ids; answers come back under the same ids. */
|
|
46
59
|
export type Questions = Record<string, Question>;
|
|
47
60
|
export interface ChoiceAnswer<L extends string = string> {
|
|
@@ -67,9 +80,23 @@ export interface ScoreAnswer {
|
|
|
67
80
|
/** Concentration of the distribution, 0–1. */
|
|
68
81
|
confidence: number;
|
|
69
82
|
}
|
|
70
|
-
|
|
83
|
+
/** A rectangle's edges as 0–1 fractions of an image's width (`left` < `right`) and height (`top` < `bottom`), from its top-left corner. */
|
|
84
|
+
export interface BoxEdges {
|
|
85
|
+
top: number;
|
|
86
|
+
bottom: number;
|
|
87
|
+
left: number;
|
|
88
|
+
right: number;
|
|
89
|
+
}
|
|
90
|
+
export interface BoxAnswer {
|
|
91
|
+
type: "box";
|
|
92
|
+
/** Smallest rectangle containing the target, on the image the question's `image` names. Always present: absence is a separate yes/no question. */
|
|
93
|
+
box: BoxEdges;
|
|
94
|
+
/** How sure the model is of the box, 0–1. */
|
|
95
|
+
confidence: number;
|
|
96
|
+
}
|
|
97
|
+
export type Answer = ChoiceAnswer | NoulAnswer | ScoreAnswer | BoxAnswer;
|
|
71
98
|
/** The answer type for a question, preserving choice labels. */
|
|
72
|
-
export type AnswerFor<Q extends Question> = Q extends ChoiceQuestion<infer L> ? ChoiceAnswer<L> : Q extends NoulQuestion ? NoulAnswer : ScoreAnswer;
|
|
99
|
+
export type AnswerFor<Q extends Question> = Q extends ChoiceQuestion<infer L> ? ChoiceAnswer<L> : Q extends NoulQuestion ? NoulAnswer : Q extends BoxQuestion ? BoxAnswer : ScoreAnswer;
|
|
73
100
|
export interface JudgmentRequest<Q extends Questions = Questions> {
|
|
74
101
|
state: JudgmentState;
|
|
75
102
|
questions: Q;
|
|
@@ -42,6 +42,8 @@ export interface JudgmentWire {
|
|
|
42
42
|
imagesRequireOptIn?: boolean;
|
|
43
43
|
/** Whether this wire drops per-image detail metadata. */
|
|
44
44
|
ignoresImageDetail?: boolean;
|
|
45
|
+
/** Whether this dialect forwards `box` questions; others reject them before sending. */
|
|
46
|
+
boxes?: boolean;
|
|
45
47
|
/** The response's answers and usage; `undefined` when the payload is not this API's response shape. */
|
|
46
48
|
decode(payload: unknown): DecodedJudgment | undefined;
|
|
47
49
|
}
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
import type { StreamFunction, StreamOptions, ToolChoice } from "../types.js";
|
|
1
|
+
import type { Model, StreamFunction, StreamOptions, ToolChoice } from "../types.js";
|
|
2
2
|
export interface OllamaChatOptions extends StreamOptions {
|
|
3
3
|
reasoning?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
|
|
4
4
|
disableReasoning?: boolean;
|
|
5
5
|
toolChoice?: ToolChoice;
|
|
6
6
|
}
|
|
7
|
+
/** Whether Ollama chat removes assistant thinking from replayed history. */
|
|
8
|
+
export declare function ollamaChatDropsOwnThinking(model: {
|
|
9
|
+
api?: string;
|
|
10
|
+
compat?: Model["compat"];
|
|
11
|
+
} | null | undefined): boolean;
|
|
7
12
|
/** Retry EOS-only Ollama completions before the agent loop sees an empty stop. */
|
|
8
13
|
export declare const streamOllama: StreamFunction<"ollama-chat">;
|
|
@@ -52,6 +52,8 @@ export declare function shouldDropTruncatedThinkingOnlyAssistant(msg: AssistantM
|
|
|
52
52
|
*/
|
|
53
53
|
export declare function isSurvivingAssistant(msg: AssistantMessage, model?: Model): boolean;
|
|
54
54
|
export declare function isAnthropicMessagesModel(model: Model): model is Model<"anthropic-messages">;
|
|
55
|
+
/** Whether `turn` came from `model` itself: its own turns replay their native reasoning unchanged. */
|
|
56
|
+
export declare function isSameModelTurn(turn: Pick<AssistantMessage, "provider" | "api" | "model">, model: Pick<Model, "provider" | "api" | "id">): boolean;
|
|
55
57
|
/**
|
|
56
58
|
* Normalize tool call ID for cross-provider compatibility.
|
|
57
59
|
* OpenAI Responses API generates IDs that are 450+ chars with special characters like `|`.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type UsageProvider } from "../usage.js";
|
|
2
2
|
export declare const museCodeUsageProvider: UsageProvider;
|
|
@@ -1,25 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Removal of DeepSeek
|
|
2
|
+
* Removal of DeepSeek tool-call markup left in visible assistant text.
|
|
3
3
|
*
|
|
4
4
|
* DeepSeek models on OpenAI-compatible hosts sometimes emit their tool calls as
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* runs no healer at all). That markup must not stay
|
|
9
|
-
* teaches the model to keep writing tool calls as text
|
|
10
|
-
* strip it before the message is committed and tell the
|
|
5
|
+
* text in `content`: the V4 `<|DSML|…>` envelope or the V3 chat-template
|
|
6
|
+
* tokens (`<|tool▁calls▁begin|>` …). A well-formed call is healed into a
|
|
7
|
+
* structured call by `StreamMarkupHealing`, but a degraded model can drop
|
|
8
|
+
* required tags (or the host runs no healer at all). That markup must not stay
|
|
9
|
+
* in history: replaying it teaches the model to keep writing tool calls as text
|
|
10
|
+
* (issue #10556). Callers strip it before the message is committed and tell the
|
|
11
|
+
* model its call failed.
|
|
11
12
|
*/
|
|
12
13
|
import type { AssistantMessage, Model } from "../types.js";
|
|
13
14
|
/**
|
|
14
15
|
* Whether DSML leak recovery applies to `model`: a DeepSeek-class model, or one
|
|
15
16
|
* explicitly configured with the `dsml` stream healer (e.g. a `models.yml` entry
|
|
16
|
-
* whose id the classifier cannot place). Other models never write
|
|
17
|
-
* calls, so
|
|
17
|
+
* whose id the classifier cannot place). Other models never write DeepSeek tool
|
|
18
|
+
* calls, so such markup from them is prose and is left alone.
|
|
18
19
|
*/
|
|
19
20
|
export declare function isDsmlLeakRecoveryTarget(model: Model): boolean;
|
|
20
21
|
/**
|
|
21
|
-
* Strip leaked
|
|
22
|
-
* Returns `undefined` when `text` carries
|
|
22
|
+
* Strip leaked DeepSeek tool-call markup (DSML or chat-template tokens) from
|
|
23
|
+
* `text`, leaving quoted code intact. Returns `undefined` when `text` carries
|
|
24
|
+
* no such markup.
|
|
23
25
|
*/
|
|
24
26
|
export declare function stripDsmlToolMarkup(text: string): string | undefined;
|
|
25
27
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@linxiraos/pi-ai",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"description": "Unified LLM API with automatic model discovery and provider configuration",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -152,11 +152,11 @@
|
|
|
152
152
|
"fmt": "oxfmt --no-error-on-unmatched-pattern 'src/**/*.{ts,tsx}' '{test,bench,examples,scripts}/**/*.ts' '*.ts'"
|
|
153
153
|
},
|
|
154
154
|
"dependencies": {
|
|
155
|
-
"@linxiraos/pi-omptype": "1.3.
|
|
156
|
-
"@linxiraos/pi-catalog": "1.3.
|
|
157
|
-
"@linxiraos/pi-natives": "1.3.
|
|
158
|
-
"@linxiraos/pi-utils": "1.3.
|
|
159
|
-
"@linxiraos/pi-wire": "1.3.
|
|
155
|
+
"@linxiraos/pi-omptype": "1.3.2",
|
|
156
|
+
"@linxiraos/pi-catalog": "1.3.2",
|
|
157
|
+
"@linxiraos/pi-natives": "1.3.2",
|
|
158
|
+
"@linxiraos/pi-utils": "1.3.2",
|
|
159
|
+
"@linxiraos/pi-wire": "1.3.2"
|
|
160
160
|
},
|
|
161
161
|
"devDependencies": {
|
|
162
162
|
"@types/bun": "1.4.3"
|