@bubblebrain-ai/bubble 0.0.25 → 0.0.27
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 +4 -2
- package/dist/agent.js +1 -1
- package/dist/clipboard.d.ts +14 -0
- package/dist/clipboard.js +132 -0
- package/dist/model-catalog.d.ts +3 -1
- package/dist/model-catalog.js +17 -28
- package/dist/prompt/compose.js +1 -1
- package/dist/provider-anthropic.d.ts +4 -0
- package/dist/provider-anthropic.js +31 -0
- package/dist/provider-ark-responses.d.ts +17 -0
- package/dist/provider-ark-responses.js +462 -0
- package/dist/provider-transform.js +7 -0
- package/dist/provider.d.ts +7 -0
- package/dist/provider.js +150 -22
- package/dist/slash-commands/commands.js +22 -0
- package/dist/tools/todo.js +22 -38
- package/dist/tui-ink/app.js +82 -62
- package/dist/tui-ink/input-box.d.ts +1 -0
- package/dist/tui-ink/input-box.js +23 -17
- package/dist/tui-ink/message-list.d.ts +17 -1
- package/dist/tui-ink/message-list.js +74 -13
- package/dist/tui-ink/model-picker.d.ts +3 -2
- package/dist/tui-ink/model-picker.js +17 -4
- package/dist/tui-ink/question-dialog.js +36 -10
- package/dist/tui-ink/run.js +14 -22
- package/dist/tui-ink/terminal-mouse.d.ts +11 -0
- package/dist/tui-ink/terminal-mouse.js +13 -0
- package/dist/tui-ink/welcome.js +13 -3
- package/dist/variant/variant-resolver.js +4 -1
- package/package.json +1 -1
- package/dist/tui/transcript-scroll.d.ts +0 -25
- package/dist/tui/transcript-scroll.js +0 -20
- package/dist/tui-ink/transcript-input.d.ts +0 -8
- package/dist/tui-ink/transcript-input.js +0 -9
- package/dist/tui-ink/transcript-viewport-math.d.ts +0 -10
- package/dist/tui-ink/transcript-viewport-math.js +0 -16
- package/dist/tui-ink/transcript-viewport.d.ts +0 -24
- package/dist/tui-ink/transcript-viewport.js +0 -83
package/README.md
CHANGED
|
@@ -69,7 +69,9 @@ Bubble ships with a catalog of built-in providers. Configure them inside the app
|
|
|
69
69
|
| `/key <provider> <key>` | Set the API key for a provider. |
|
|
70
70
|
| `/model` | Pick the active model and reasoning effort. |
|
|
71
71
|
|
|
72
|
-
Built-in providers include OpenAI, Anthropic, Google, DeepSeek, Moonshot (CN and international), Kimi for Coding, Zhipu AI, Z.AI, Alibaba DashScope, MiniMax, StepFun, Groq, Together AI, Fireworks, and a `local` profile for any OpenAI-compatible endpoint (Ollama, vLLM, LM Studio, etc.).
|
|
72
|
+
Built-in providers include OpenAI, Anthropic, Google, DeepSeek, Moonshot (CN and international), Kimi for Coding, Zhipu AI, Z.AI, Alibaba DashScope, Doubao (Volcengine Ark), MiniMax, StepFun, Groq, Together AI, Fireworks, and a `local` profile for any OpenAI-compatible endpoint (Ollama, vLLM, LM Studio, etc.).
|
|
73
|
+
|
|
74
|
+
For Doubao Seed models on Volcengine Ark, run `/provider --add doubao` and paste your Ark API key. The built-in endpoint is `https://ark.cn-beijing.volces.com/api/v3` and uses Ark's Responses API. The model picker exposes `minimal`, `low`, `medium`, and `high`, defaulting to `high`; `minimal` disables Ark thinking, while the other levels enable it.
|
|
73
75
|
|
|
74
76
|
### Custom providers and models
|
|
75
77
|
|
|
@@ -90,7 +92,7 @@ For full control — custom base URLs, self-hosted gateways, extra models, or pi
|
|
|
90
92
|
}
|
|
91
93
|
```
|
|
92
94
|
|
|
93
|
-
`protocol` accepts `openai-chat` (default) or `
|
|
95
|
+
`protocol` accepts `openai-chat` (default), `anthropic-messages`, or `ark-responses`. Entries in `models.json` take precedence over the built-in catalog.
|
|
94
96
|
|
|
95
97
|
### Reasoning effort
|
|
96
98
|
|
package/dist/agent.js
CHANGED
|
@@ -2047,7 +2047,7 @@ export class Agent {
|
|
|
2047
2047
|
}
|
|
2048
2048
|
if (toolCall.argsCorrupt) {
|
|
2049
2049
|
return {
|
|
2050
|
-
content: `Error: The arguments for "${toolCall.name}" failed to parse as JSON, indicating the
|
|
2050
|
+
content: `Error: The arguments for "${toolCall.name}" failed to parse as JSON, indicating the provider returned truncated or malformed tool arguments. ` +
|
|
2051
2051
|
`Re-issue the call with valid JSON arguments; do not assume the previous attempt ran.`,
|
|
2052
2052
|
isError: true,
|
|
2053
2053
|
status: "blocked",
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build the OSC 52 escape sequence for the given text. Returns `null` when the
|
|
3
|
+
* base64 payload exceeds {@link MAX_OSC52_ENCODED_LENGTH}.
|
|
4
|
+
*
|
|
5
|
+
* Format: ESC ] 52 ; c ; <base64> BEL => `\x1b]52;c;<base64>\x07`
|
|
6
|
+
*
|
|
7
|
+
* Exported for unit testing the encoding/cap logic in isolation.
|
|
8
|
+
*/
|
|
9
|
+
export declare function encodeOsc52(text: string): string | null;
|
|
10
|
+
/**
|
|
11
|
+
* Copy `text` to the system clipboard. Resolves once a copy path succeeds and
|
|
12
|
+
* throws only when no path (native tools nor OSC 52) could place the text.
|
|
13
|
+
*/
|
|
14
|
+
export declare function copyToClipboard(text: string): Promise<void>;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { execSync, spawn } from "node:child_process";
|
|
2
|
+
import { platform } from "node:os";
|
|
3
|
+
/**
|
|
4
|
+
* Maximum length of the base64-encoded payload we are willing to emit via
|
|
5
|
+
* OSC 52. Very large payloads can desynchronize terminal rendering and many
|
|
6
|
+
* terminals silently drop sequences past ~100k, so we cap and skip instead.
|
|
7
|
+
*/
|
|
8
|
+
const MAX_OSC52_ENCODED_LENGTH = 100_000;
|
|
9
|
+
function copyToX11Clipboard(options) {
|
|
10
|
+
try {
|
|
11
|
+
execSync("xclip -selection clipboard", options);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
execSync("xsel --clipboard --input", options);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* True when we appear to be running over SSH/Mosh, i.e. the host running this
|
|
19
|
+
* process is not the machine whose clipboard the user is looking at.
|
|
20
|
+
*/
|
|
21
|
+
function isRemoteSession(env = process.env) {
|
|
22
|
+
return Boolean(env.SSH_CONNECTION || env.SSH_CLIENT || env.MOSH_CONNECTION);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* True when running inside a tmux session. tmux intercepts/relays terminal
|
|
26
|
+
* clipboard escapes, so OSC 52 is the reliable path to reach the outer
|
|
27
|
+
* terminal's clipboard (especially tmux-over-ssh). Native pbcopy still works
|
|
28
|
+
* locally, so we treat this as "also emit OSC 52", never as a replacement.
|
|
29
|
+
*/
|
|
30
|
+
function isTmuxSession(env = process.env) {
|
|
31
|
+
return Boolean(env.TMUX);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Build the OSC 52 escape sequence for the given text. Returns `null` when the
|
|
35
|
+
* base64 payload exceeds {@link MAX_OSC52_ENCODED_LENGTH}.
|
|
36
|
+
*
|
|
37
|
+
* Format: ESC ] 52 ; c ; <base64> BEL => `\x1b]52;c;<base64>\x07`
|
|
38
|
+
*
|
|
39
|
+
* Exported for unit testing the encoding/cap logic in isolation.
|
|
40
|
+
*/
|
|
41
|
+
export function encodeOsc52(text) {
|
|
42
|
+
const encoded = Buffer.from(text).toString("base64");
|
|
43
|
+
if (encoded.length > MAX_OSC52_ENCODED_LENGTH) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
return `\x1b]52;c;${encoded}\x07`;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Write the OSC 52 sequence to stdout. Returns false (without writing) when the
|
|
50
|
+
* payload is too large to emit safely.
|
|
51
|
+
*/
|
|
52
|
+
function emitOsc52(text) {
|
|
53
|
+
const sequence = encodeOsc52(text);
|
|
54
|
+
if (sequence === null) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
process.stdout.write(sequence);
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Copy `text` to the system clipboard. Resolves once a copy path succeeds and
|
|
62
|
+
* throws only when no path (native tools nor OSC 52) could place the text.
|
|
63
|
+
*/
|
|
64
|
+
export async function copyToClipboard(text) {
|
|
65
|
+
let copied = false;
|
|
66
|
+
const p = platform();
|
|
67
|
+
const options = { input: text, timeout: 5000, stdio: ["pipe", "ignore", "ignore"] };
|
|
68
|
+
try {
|
|
69
|
+
if (p === "darwin") {
|
|
70
|
+
execSync("pbcopy", options);
|
|
71
|
+
copied = true;
|
|
72
|
+
}
|
|
73
|
+
else if (p === "win32") {
|
|
74
|
+
execSync("clip", options);
|
|
75
|
+
copied = true;
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
// Linux/other. Try Termux, Wayland, then X11 clipboard tools.
|
|
79
|
+
if (process.env.TERMUX_VERSION) {
|
|
80
|
+
try {
|
|
81
|
+
execSync("termux-clipboard-set", options);
|
|
82
|
+
copied = true;
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// Fall back to Wayland or X11 tools.
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (!copied) {
|
|
89
|
+
const hasWaylandDisplay = Boolean(process.env.WAYLAND_DISPLAY);
|
|
90
|
+
const hasX11Display = Boolean(process.env.DISPLAY);
|
|
91
|
+
if (hasWaylandDisplay) {
|
|
92
|
+
try {
|
|
93
|
+
// Verify wl-copy exists (spawn errors are async and won't be caught).
|
|
94
|
+
execSync("which wl-copy", { stdio: "ignore" });
|
|
95
|
+
// wl-copy with execSync hangs due to fork behavior; use spawn instead.
|
|
96
|
+
const proc = spawn("wl-copy", [], { stdio: ["pipe", "ignore", "ignore"] });
|
|
97
|
+
proc.stdin.on("error", () => {
|
|
98
|
+
// Ignore EPIPE errors if wl-copy exits early.
|
|
99
|
+
});
|
|
100
|
+
proc.stdin.write(text);
|
|
101
|
+
proc.stdin.end();
|
|
102
|
+
proc.unref();
|
|
103
|
+
copied = true;
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
if (hasX11Display) {
|
|
107
|
+
copyToX11Clipboard(options);
|
|
108
|
+
copied = true;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
else if (hasX11Display) {
|
|
113
|
+
copyToX11Clipboard(options);
|
|
114
|
+
copied = true;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
// Fall through to the OSC 52 fallback.
|
|
121
|
+
}
|
|
122
|
+
// Emit OSC 52 when the native clipboard may be unreachable from this host
|
|
123
|
+
// (remote sessions, tmux relaying to an outer terminal) or when no native
|
|
124
|
+
// tool succeeded. This is additive — never throw if a native copy worked.
|
|
125
|
+
if (isRemoteSession() || isTmuxSession() || !copied) {
|
|
126
|
+
const osc52Copied = emitOsc52(text);
|
|
127
|
+
copied = copied || osc52Copied;
|
|
128
|
+
}
|
|
129
|
+
if (!copied) {
|
|
130
|
+
throw new Error("Failed to copy to clipboard");
|
|
131
|
+
}
|
|
132
|
+
}
|
package/dist/model-catalog.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ReasoningEffort } from "./types.js";
|
|
2
|
-
export type ProviderProtocol = "openai-chat" | "anthropic-messages";
|
|
2
|
+
export type ProviderProtocol = "openai-chat" | "anthropic-messages" | "ark-responses";
|
|
3
3
|
export interface BuiltinProviderDefinition {
|
|
4
4
|
id: string;
|
|
5
5
|
name: string;
|
|
@@ -13,6 +13,7 @@ export interface BuiltinModelDefinition {
|
|
|
13
13
|
name: string;
|
|
14
14
|
providerId: string;
|
|
15
15
|
reasoningLevels: ReasoningEffort[];
|
|
16
|
+
defaultReasoningLevel?: ReasoningEffort;
|
|
16
17
|
contextWindow?: number;
|
|
17
18
|
/**
|
|
18
19
|
* Server-declared cap on per-tool-output tokens. When set, the agent must
|
|
@@ -27,6 +28,7 @@ export declare const BUILTIN_MODELS: BuiltinModelDefinition[];
|
|
|
27
28
|
export declare function listBuiltinModels(providerId: string): BuiltinModelDefinition[];
|
|
28
29
|
export declare function registerDynamicModelMetadata(model: BuiltinModelDefinition): void;
|
|
29
30
|
export declare function getBuiltinModel(providerId: string, modelId: string): BuiltinModelDefinition | undefined;
|
|
31
|
+
export declare function getModelDefaultReasoningLevel(providerId: string, modelId: string): ReasoningEffort | undefined;
|
|
30
32
|
export declare function getBuiltinProvider(providerId: string): BuiltinProviderDefinition | undefined;
|
|
31
33
|
export declare function getModelContextWindow(providerId: string, modelId: string): number | undefined;
|
|
32
34
|
export declare function getToolOutputTokenLimit(providerId: string, modelId: string): number | undefined;
|
package/dist/model-catalog.js
CHANGED
|
@@ -10,9 +10,9 @@ export const BUILTIN_PROVIDERS = [
|
|
|
10
10
|
{ id: "zai", name: "Z.AI", baseURL: "https://api.z.ai/api/paas/v4" },
|
|
11
11
|
{ id: "zai-coding-plan", name: "Z.AI Coding Plan", baseURL: "https://api.z.ai/api/coding/paas/v4" },
|
|
12
12
|
{ id: "alibaba", name: "Alibaba DashScope", baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1" },
|
|
13
|
+
{ id: "doubao", name: "Doubao (Volcengine Ark)", baseURL: "https://ark.cn-beijing.volces.com/api/v3", protocol: "ark-responses" },
|
|
13
14
|
{ id: "minimax", name: "MiniMax Token Plan", baseURL: "https://api.minimaxi.com/anthropic", protocol: "anthropic-messages" },
|
|
14
|
-
{ id: "minimax-
|
|
15
|
-
{ id: "minimax-anthropic", name: "MiniMax (Anthropic Compatible)", baseURL: "https://api.minimaxi.com/anthropic", protocol: "anthropic-messages", hidden: true },
|
|
15
|
+
{ id: "minimax-anthropic", name: "MiniMax API", baseURL: "https://api.minimaxi.com/anthropic", protocol: "anthropic-messages" },
|
|
16
16
|
{ id: "stepfun", name: "StepFun Step Plan", baseURL: "https://api.stepfun.com/step_plan/v1" },
|
|
17
17
|
{ id: "moonshot-cn", name: "Moonshot (国内 platform.moonshot.cn)", baseURL: "https://api.moonshot.cn/v1" },
|
|
18
18
|
{ id: "moonshot-intl", name: "Moonshot (海外 platform.moonshot.ai)", baseURL: "https://api.moonshot.ai/v1" },
|
|
@@ -40,10 +40,16 @@ const GLM_5_2_LEVELS = ["high", "max", "off"];
|
|
|
40
40
|
const KIMI_THINKING_ONLY_LEVELS = ["medium"];
|
|
41
41
|
const DEEPSEEK_V4_LEVELS = ["high", "max"];
|
|
42
42
|
const STEPFUN_REASONING_LEVELS = ["off", "low", "medium", "high"];
|
|
43
|
+
const DOUBAO_SEED_REASONING_LEVELS = ["minimal", "low", "medium", "high"];
|
|
43
44
|
const MINIMAX_M3_REASONING_LEVELS = ["off", "medium"];
|
|
44
45
|
const MINIMAX_REASONING_LEVELS = ["medium"];
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
// Anthropic exposes reasoning depth through output_config.effort (low | medium
|
|
47
|
+
// | high | xhigh | max), not a token budget. xhigh is Opus 4.7+ only; max is
|
|
48
|
+
// Opus 4.6+/Sonnet 4.6/Fable 5; Haiku 4.5 does not accept the effort param.
|
|
49
|
+
// Fable 5 has thinking always on, so it has no "off". "off" disables thinking.
|
|
50
|
+
const ANTHROPIC_OPUS_EFFORT_LEVELS = ["off", "low", "medium", "high", "xhigh", "max"];
|
|
51
|
+
const ANTHROPIC_SONNET_EFFORT_LEVELS = ["off", "low", "medium", "high", "max"];
|
|
52
|
+
const ANTHROPIC_FABLE_EFFORT_LEVELS = ["low", "medium", "high", "xhigh", "max"];
|
|
47
53
|
const ANTHROPIC_CHAT_LEVELS = ["off"];
|
|
48
54
|
export const BUILTIN_MODELS = [
|
|
49
55
|
{ id: "gpt-5.5", name: "gpt-5.5", providerId: "openai-codex", reasoningLevels: ALL_OPENAI_LEVELS, contextWindow: 272000, toolOutputTokenLimit: 10000 },
|
|
@@ -61,9 +67,9 @@ export const BUILTIN_MODELS = [
|
|
|
61
67
|
{ id: "o1-preview", name: "o1-preview", providerId: "openai", reasoningLevels: ["off", "low", "medium", "high"], contextWindow: 128000 },
|
|
62
68
|
{ id: "o1-mini", name: "o1-mini", providerId: "openai", reasoningLevels: ["off", "low", "medium", "high"], contextWindow: 128000 },
|
|
63
69
|
{ id: "gpt-4-turbo", name: "gpt-4-turbo", providerId: "openai", reasoningLevels: OPENAI_CHAT_LEVELS, contextWindow: 128000 },
|
|
64
|
-
{ id: "claude-fable-5", name: "Claude Fable 5", providerId: "anthropic", reasoningLevels:
|
|
65
|
-
{ id: "claude-opus-4-8", name: "Claude Opus 4.8", providerId: "anthropic", reasoningLevels:
|
|
66
|
-
{ id: "claude-sonnet-4-6", name: "Claude Sonnet 4.6", providerId: "anthropic", reasoningLevels:
|
|
70
|
+
{ id: "claude-fable-5", name: "Claude Fable 5", providerId: "anthropic", reasoningLevels: ANTHROPIC_FABLE_EFFORT_LEVELS, defaultReasoningLevel: "high", contextWindow: 1000000 },
|
|
71
|
+
{ id: "claude-opus-4-8", name: "Claude Opus 4.8", providerId: "anthropic", reasoningLevels: ANTHROPIC_OPUS_EFFORT_LEVELS, defaultReasoningLevel: "high", contextWindow: 1000000 },
|
|
72
|
+
{ id: "claude-sonnet-4-6", name: "Claude Sonnet 4.6", providerId: "anthropic", reasoningLevels: ANTHROPIC_SONNET_EFFORT_LEVELS, defaultReasoningLevel: "high", contextWindow: 1000000 },
|
|
67
73
|
{ id: "claude-haiku-4-5-20251001", name: "Claude Haiku 4.5", providerId: "anthropic", reasoningLevels: ANTHROPIC_CHAT_LEVELS, contextWindow: 200000 },
|
|
68
74
|
{ id: "deepseek-v4-flash", name: "deepseek-v4-flash", providerId: "deepseek", reasoningLevels: DEEPSEEK_V4_LEVELS, contextWindow: 1048576 },
|
|
69
75
|
{ id: "deepseek-v4-pro", name: "deepseek-v4-pro", providerId: "deepseek", reasoningLevels: DEEPSEEK_V4_LEVELS, contextWindow: 1048576 },
|
|
@@ -88,33 +94,13 @@ export const BUILTIN_MODELS = [
|
|
|
88
94
|
{ id: "glm-4.6", name: "GLM-4.6", providerId: "zai-coding-plan", reasoningLevels: TOGGLE_THINKING_LEVELS, contextWindow: 200000 },
|
|
89
95
|
{ id: "qwen3.6-plus", name: "Qwen3.6 Plus", providerId: "alibaba", reasoningLevels: ["off"], contextWindow: 1048576 },
|
|
90
96
|
{ id: "qwen3.7-max", name: "Qwen3.7 Max", providerId: "alibaba", reasoningLevels: ["off"], contextWindow: 1048576 },
|
|
97
|
+
{ id: "doubao-seed-2-1-pro-260628", name: "Doubao Seed 2.1 Pro", providerId: "doubao", reasoningLevels: DOUBAO_SEED_REASONING_LEVELS, defaultReasoningLevel: "high" },
|
|
91
98
|
{ id: "MiniMax-M3", name: "MiniMax M3", providerId: "minimax", reasoningLevels: MINIMAX_M3_REASONING_LEVELS, contextWindow: 1000000 },
|
|
92
99
|
{ id: "MiniMax-M2.7", name: "MiniMax M2.7", providerId: "minimax", reasoningLevels: MINIMAX_REASONING_LEVELS, contextWindow: 204800 },
|
|
93
100
|
{ id: "MiniMax-M2.7-highspeed", name: "MiniMax M2.7 Highspeed", providerId: "minimax", reasoningLevels: MINIMAX_REASONING_LEVELS, contextWindow: 204800 },
|
|
94
|
-
{ id: "MiniMax-M2.5", name: "MiniMax M2.5", providerId: "minimax", reasoningLevels: MINIMAX_REASONING_LEVELS, contextWindow: 204800 },
|
|
95
|
-
{ id: "MiniMax-M2.5-highspeed", name: "MiniMax M2.5 Highspeed", providerId: "minimax", reasoningLevels: MINIMAX_REASONING_LEVELS, contextWindow: 204800 },
|
|
96
|
-
{ id: "MiniMax-M2.1", name: "MiniMax M2.1", providerId: "minimax", reasoningLevels: MINIMAX_REASONING_LEVELS, contextWindow: 204800 },
|
|
97
|
-
{ id: "MiniMax-M2.1-highspeed", name: "MiniMax M2.1 Highspeed", providerId: "minimax", reasoningLevels: MINIMAX_REASONING_LEVELS, contextWindow: 204800 },
|
|
98
|
-
{ id: "MiniMax-M2", name: "MiniMax M2", providerId: "minimax", reasoningLevels: MINIMAX_REASONING_LEVELS, contextWindow: 204800 },
|
|
99
|
-
{ id: "M2-her", name: "M2-her", providerId: "minimax", reasoningLevels: ["off"], contextWindow: 64000 },
|
|
100
|
-
{ id: "MiniMax-M3", name: "MiniMax M3", providerId: "minimax-openai", reasoningLevels: MINIMAX_M3_REASONING_LEVELS, contextWindow: 1000000 },
|
|
101
|
-
{ id: "MiniMax-M2.7", name: "MiniMax M2.7", providerId: "minimax-openai", reasoningLevels: MINIMAX_REASONING_LEVELS, contextWindow: 204800 },
|
|
102
|
-
{ id: "MiniMax-M2.7-highspeed", name: "MiniMax M2.7 Highspeed", providerId: "minimax-openai", reasoningLevels: MINIMAX_REASONING_LEVELS, contextWindow: 204800 },
|
|
103
|
-
{ id: "MiniMax-M2.5", name: "MiniMax M2.5", providerId: "minimax-openai", reasoningLevels: MINIMAX_REASONING_LEVELS, contextWindow: 204800 },
|
|
104
|
-
{ id: "MiniMax-M2.5-highspeed", name: "MiniMax M2.5 Highspeed", providerId: "minimax-openai", reasoningLevels: MINIMAX_REASONING_LEVELS, contextWindow: 204800 },
|
|
105
|
-
{ id: "MiniMax-M2.1", name: "MiniMax M2.1", providerId: "minimax-openai", reasoningLevels: MINIMAX_REASONING_LEVELS, contextWindow: 204800 },
|
|
106
|
-
{ id: "MiniMax-M2.1-highspeed", name: "MiniMax M2.1 Highspeed", providerId: "minimax-openai", reasoningLevels: MINIMAX_REASONING_LEVELS, contextWindow: 204800 },
|
|
107
|
-
{ id: "MiniMax-M2", name: "MiniMax M2", providerId: "minimax-openai", reasoningLevels: MINIMAX_REASONING_LEVELS, contextWindow: 204800 },
|
|
108
|
-
{ id: "M2-her", name: "M2-her", providerId: "minimax-openai", reasoningLevels: ["off"], contextWindow: 64000 },
|
|
109
101
|
{ id: "MiniMax-M3", name: "MiniMax M3", providerId: "minimax-anthropic", reasoningLevels: MINIMAX_M3_REASONING_LEVELS, contextWindow: 1000000 },
|
|
110
102
|
{ id: "MiniMax-M2.7", name: "MiniMax M2.7", providerId: "minimax-anthropic", reasoningLevels: MINIMAX_REASONING_LEVELS, contextWindow: 204800 },
|
|
111
103
|
{ id: "MiniMax-M2.7-highspeed", name: "MiniMax M2.7 Highspeed", providerId: "minimax-anthropic", reasoningLevels: MINIMAX_REASONING_LEVELS, contextWindow: 204800 },
|
|
112
|
-
{ id: "MiniMax-M2.5", name: "MiniMax M2.5", providerId: "minimax-anthropic", reasoningLevels: MINIMAX_REASONING_LEVELS, contextWindow: 204800 },
|
|
113
|
-
{ id: "MiniMax-M2.5-highspeed", name: "MiniMax M2.5 Highspeed", providerId: "minimax-anthropic", reasoningLevels: MINIMAX_REASONING_LEVELS, contextWindow: 204800 },
|
|
114
|
-
{ id: "MiniMax-M2.1", name: "MiniMax M2.1", providerId: "minimax-anthropic", reasoningLevels: MINIMAX_REASONING_LEVELS, contextWindow: 204800 },
|
|
115
|
-
{ id: "MiniMax-M2.1-highspeed", name: "MiniMax M2.1 Highspeed", providerId: "minimax-anthropic", reasoningLevels: MINIMAX_REASONING_LEVELS, contextWindow: 204800 },
|
|
116
|
-
{ id: "MiniMax-M2", name: "MiniMax M2", providerId: "minimax-anthropic", reasoningLevels: MINIMAX_REASONING_LEVELS, contextWindow: 204800 },
|
|
117
|
-
{ id: "M2-her", name: "M2-her", providerId: "minimax-anthropic", reasoningLevels: ["off"], contextWindow: 64000 },
|
|
118
104
|
{ id: "step-3.7-flash", name: "Step 3.7 Flash", providerId: "stepfun", reasoningLevels: STEPFUN_REASONING_LEVELS, contextWindow: 256000 },
|
|
119
105
|
{ id: "step-3.5-flash-2603", name: "Step 3.5 Flash 2603", providerId: "stepfun", reasoningLevels: STEPFUN_REASONING_LEVELS },
|
|
120
106
|
{ id: "step-3.5-flash", name: "Step 3.5 Flash", providerId: "stepfun", reasoningLevels: STEPFUN_REASONING_LEVELS },
|
|
@@ -171,6 +157,9 @@ export function getBuiltinModel(providerId, modelId) {
|
|
|
171
157
|
? BUILTIN_MODELS.find((model) => model.providerId === "openai-codex" && model.id === modelId)
|
|
172
158
|
: undefined);
|
|
173
159
|
}
|
|
160
|
+
export function getModelDefaultReasoningLevel(providerId, modelId) {
|
|
161
|
+
return getBuiltinModel(providerId, modelId)?.defaultReasoningLevel;
|
|
162
|
+
}
|
|
174
163
|
export function getBuiltinProvider(providerId) {
|
|
175
164
|
return BUILTIN_PROVIDERS.find((provider) => provider.id === providerId);
|
|
176
165
|
}
|
package/dist/prompt/compose.js
CHANGED
|
@@ -84,7 +84,7 @@ function buildGuidelines(tools, extraGuidelines) {
|
|
|
84
84
|
add("Skills may provide specialized workflows. When a task appears to match a specialized workflow, call skill_search to find relevant skills, then call skill with the exact name to load the selected skill before applying it");
|
|
85
85
|
}
|
|
86
86
|
if (tools.includes("todo_write")) {
|
|
87
|
-
add("
|
|
87
|
+
add("Default to just doing the work. Reach for todo_write only when tracking progress would genuinely help — multi-phase work with real dependencies, a long task spanning several areas, an explicit user request, or steps you discover mid-task. Don't make a list to pad a task you could just do; when in doubt, skip it. Mark each item completed as soon as it is done; do not batch updates");
|
|
88
88
|
}
|
|
89
89
|
for (const item of extraGuidelines) {
|
|
90
90
|
add(item);
|
|
@@ -22,7 +22,11 @@ interface AnthropicRequest {
|
|
|
22
22
|
thinking?: {
|
|
23
23
|
type: "adaptive";
|
|
24
24
|
};
|
|
25
|
+
output_config?: {
|
|
26
|
+
effort: AnthropicEffort;
|
|
27
|
+
};
|
|
25
28
|
}
|
|
29
|
+
type AnthropicEffort = "low" | "medium" | "high" | "xhigh" | "max";
|
|
26
30
|
type AnthropicCacheControl = typeof ANTHROPIC_PROMPT_CACHE_CONTROL;
|
|
27
31
|
interface AnthropicSystemBlock {
|
|
28
32
|
type: "text";
|
|
@@ -17,6 +17,25 @@ const MINIMAX_PROMPT_CACHE_MODELS = new Set([
|
|
|
17
17
|
"minimax-m2",
|
|
18
18
|
"m2-her",
|
|
19
19
|
]);
|
|
20
|
+
function anthropicEffortForLevel(level) {
|
|
21
|
+
switch (level) {
|
|
22
|
+
case "off":
|
|
23
|
+
return undefined;
|
|
24
|
+
case "minimal":
|
|
25
|
+
case "low":
|
|
26
|
+
return "low";
|
|
27
|
+
case "medium":
|
|
28
|
+
return "medium";
|
|
29
|
+
case "high":
|
|
30
|
+
return "high";
|
|
31
|
+
case "xhigh":
|
|
32
|
+
return "xhigh";
|
|
33
|
+
case "max":
|
|
34
|
+
return "max";
|
|
35
|
+
default:
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
20
39
|
export function createAnthropicMessagesProvider(options) {
|
|
21
40
|
async function* streamChat(messages, chatOptions) {
|
|
22
41
|
const body = buildAnthropicRequest(options, messages, {
|
|
@@ -87,6 +106,18 @@ export function buildAnthropicRequest(options, messages, chatOptions) {
|
|
|
87
106
|
}
|
|
88
107
|
if (effectiveThinkingLevel !== "off") {
|
|
89
108
|
body.thinking = { type: "adaptive" };
|
|
109
|
+
// Apply the selected reasoning depth via output_config.effort. Without this
|
|
110
|
+
// every thinking request silently ran at Anthropic's default (high),
|
|
111
|
+
// ignoring the chosen level. effort is an official-API feature, so only
|
|
112
|
+
// send it to the official endpoint — anthropic-compatible third parties
|
|
113
|
+
// (e.g. MiniMax) reject it. Levels are already clamped to the model's
|
|
114
|
+
// supported set, so the value is always a valid effort for this model.
|
|
115
|
+
if (isOfficialAnthropicBaseUrl(options.baseURL)) {
|
|
116
|
+
const effort = anthropicEffortForLevel(effectiveThinkingLevel);
|
|
117
|
+
if (effort) {
|
|
118
|
+
body.output_config = { effort };
|
|
119
|
+
}
|
|
120
|
+
}
|
|
90
121
|
}
|
|
91
122
|
return body;
|
|
92
123
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Provider, ProviderMessage, StreamChunk, ThinkingLevel, TokenUsage, ToolChoiceMode, ToolDefinition } from "./types.js";
|
|
2
|
+
export interface ArkResponsesProviderOptions {
|
|
3
|
+
providerId?: string;
|
|
4
|
+
apiKey: string;
|
|
5
|
+
baseURL: string;
|
|
6
|
+
thinkingLevel?: ThinkingLevel;
|
|
7
|
+
}
|
|
8
|
+
export declare function createArkResponsesProvider(options: ArkResponsesProviderOptions): Provider;
|
|
9
|
+
export declare function buildArkResponsesBody(messages: ProviderMessage[], options: {
|
|
10
|
+
model: string;
|
|
11
|
+
tools?: ToolDefinition[];
|
|
12
|
+
toolChoice?: ToolChoiceMode;
|
|
13
|
+
thinkingLevel?: ThinkingLevel;
|
|
14
|
+
stream: boolean;
|
|
15
|
+
}): Record<string, unknown>;
|
|
16
|
+
export declare function translateArkResponsesStream(response: Response): AsyncIterable<StreamChunk>;
|
|
17
|
+
export declare function normalizeArkResponsesUsage(usage: any): TokenUsage;
|