@bubblebrain-ai/bubble 0.0.24 → 0.0.26
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 +5 -3
- package/dist/agent.js +1 -1
- package/dist/clipboard.d.ts +14 -0
- package/dist/clipboard.js +132 -0
- package/dist/config.d.ts +3 -0
- package/dist/config.js +22 -6
- package/dist/goal/format.js +34 -4
- package/dist/goal/store.d.ts +3 -0
- package/dist/goal/store.js +14 -1
- package/dist/goal/usage.d.ts +2 -0
- package/dist/goal/usage.js +3 -0
- package/dist/main.js +23 -42
- 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 +170 -27
- package/dist/slash-commands/commands.js +22 -0
- package/dist/tools/todo.js +22 -38
- package/dist/tui/detect-theme.d.ts +1 -0
- package/dist/tui/detect-theme.js +23 -0
- package/dist/tui/image-display.d.ts +13 -0
- package/dist/tui/image-display.js +49 -0
- package/dist/tui/input-history.d.ts +37 -6
- package/dist/tui/input-history.js +194 -23
- package/dist/tui/model-switch.d.ts +42 -0
- package/dist/tui/model-switch.js +55 -0
- package/dist/tui-ink/app.d.ts +32 -2
- package/dist/tui-ink/app.js +1409 -549
- package/dist/tui-ink/approval/select.js +10 -0
- package/dist/tui-ink/detect-theme.d.ts +1 -2
- package/dist/tui-ink/detect-theme.js +1 -87
- package/dist/tui-ink/display-history.d.ts +1 -0
- package/dist/tui-ink/display-history.js +11 -0
- package/dist/tui-ink/feedback-dialog.js +10 -0
- package/dist/tui-ink/feishu-setup-picker.js +10 -0
- package/dist/tui-ink/footer.d.ts +1 -0
- package/dist/tui-ink/footer.js +8 -2
- package/dist/tui-ink/input-box.d.ts +71 -9
- package/dist/tui-ink/input-box.js +359 -121
- package/dist/tui-ink/input-history.d.ts +1 -16
- package/dist/tui-ink/input-history.js +1 -79
- package/dist/tui-ink/input-queue.d.ts +12 -0
- package/dist/tui-ink/input-queue.js +17 -0
- package/dist/tui-ink/key-events.d.ts +9 -0
- package/dist/tui-ink/key-events.js +8 -0
- package/dist/tui-ink/markdown.js +1 -1
- package/dist/tui-ink/message-list.d.ts +19 -1
- package/dist/tui-ink/message-list.js +111 -32
- package/dist/tui-ink/model-picker.d.ts +25 -2
- package/dist/tui-ink/model-picker.js +237 -20
- package/dist/tui-ink/plan-confirm.js +10 -0
- package/dist/tui-ink/question-dialog.js +46 -10
- package/dist/tui-ink/run.d.ts +10 -1
- package/dist/tui-ink/run.js +27 -42
- package/dist/tui-ink/session-picker.js +3 -0
- package/dist/tui-ink/submit-dedupe.d.ts +5 -0
- package/dist/tui-ink/submit-dedupe.js +25 -0
- package/dist/tui-ink/terminal-mouse.d.ts +24 -1
- package/dist/tui-ink/terminal-mouse.js +76 -21
- package/dist/tui-ink/theme.d.ts +6 -3
- package/dist/tui-ink/theme.js +10 -4
- package/dist/tui-ink/welcome.d.ts +1 -0
- package/dist/tui-ink/welcome.js +34 -27
- package/dist/variant/variant-resolver.js +4 -1
- package/package.json +1 -5
- package/dist/tui/clipboard.d.ts +0 -1
- package/dist/tui/clipboard.js +0 -53
- package/dist/tui/escape-confirmation.d.ts +0 -15
- package/dist/tui/escape-confirmation.js +0 -30
- package/dist/tui/global-key-router.d.ts +0 -3
- package/dist/tui/global-key-router.js +0 -87
- package/dist/tui/markdown-inline.d.ts +0 -22
- package/dist/tui/markdown-inline.js +0 -68
- package/dist/tui/markdown-theme-rules.d.ts +0 -23
- package/dist/tui/markdown-theme-rules.js +0 -164
- package/dist/tui/markdown-theme.d.ts +0 -5
- package/dist/tui/markdown-theme.js +0 -27
- package/dist/tui/opencode-spinner.d.ts +0 -22
- package/dist/tui/opencode-spinner.js +0 -216
- package/dist/tui/prompt-keybindings.d.ts +0 -42
- package/dist/tui/prompt-keybindings.js +0 -35
- package/dist/tui/render-signature.d.ts +0 -1
- package/dist/tui/render-signature.js +0 -7
- package/dist/tui/run.d.ts +0 -67
- package/dist/tui/run.js +0 -10166
- package/dist/tui/sidebar-mcp.d.ts +0 -31
- package/dist/tui/sidebar-mcp.js +0 -62
- package/dist/tui/sidebar-state.d.ts +0 -12
- package/dist/tui/sidebar-state.js +0 -69
- package/dist/tui/streaming-tool-args.d.ts +0 -15
- package/dist/tui/streaming-tool-args.js +0 -30
- package/dist/tui/tool-renderers/fallback.d.ts +0 -2
- package/dist/tui/tool-renderers/fallback.js +0 -75
- package/dist/tui/tool-renderers/registry.d.ts +0 -3
- package/dist/tui/tool-renderers/registry.js +0 -11
- package/dist/tui/tool-renderers/subagent.d.ts +0 -2
- package/dist/tui/tool-renderers/subagent.js +0 -135
- package/dist/tui/tool-renderers/types.d.ts +0 -36
- package/dist/tui/tool-renderers/types.js +0 -1
- package/dist/tui/tool-renderers/write-preview.d.ts +0 -12
- package/dist/tui/tool-renderers/write-preview.js +0 -32
- package/dist/tui/tool-renderers/write.d.ts +0 -6
- package/dist/tui/tool-renderers/write.js +0 -88
- package/dist/tui/transcript-scroll.d.ts +0 -25
- package/dist/tui/transcript-scroll.js +0 -20
- package/dist/tui-ink/transcript-viewport-math.d.ts +0 -11
- package/dist/tui-ink/transcript-viewport-math.js +0 -17
- package/dist/tui-ink/transcript-viewport.d.ts +0 -24
- package/dist/tui-ink/transcript-viewport.js +0 -83
- package/dist/tui-opentui/app.d.ts +0 -54
- package/dist/tui-opentui/app.js +0 -1371
- package/dist/tui-opentui/approval/approval-dialog.d.ts +0 -15
- package/dist/tui-opentui/approval/approval-dialog.js +0 -155
- package/dist/tui-opentui/approval/diff-view.d.ts +0 -9
- package/dist/tui-opentui/approval/diff-view.js +0 -43
- package/dist/tui-opentui/approval/select.d.ts +0 -37
- package/dist/tui-opentui/approval/select.js +0 -91
- package/dist/tui-opentui/detect-theme.d.ts +0 -2
- package/dist/tui-opentui/detect-theme.js +0 -87
- package/dist/tui-opentui/display-history.d.ts +0 -56
- package/dist/tui-opentui/display-history.js +0 -130
- package/dist/tui-opentui/edit-diff.d.ts +0 -11
- package/dist/tui-opentui/edit-diff.js +0 -57
- package/dist/tui-opentui/feedback-dialog.d.ts +0 -21
- package/dist/tui-opentui/feedback-dialog.js +0 -164
- package/dist/tui-opentui/feishu-setup-picker.d.ts +0 -7
- package/dist/tui-opentui/feishu-setup-picker.js +0 -272
- package/dist/tui-opentui/file-mentions.d.ts +0 -29
- package/dist/tui-opentui/file-mentions.js +0 -174
- package/dist/tui-opentui/footer.d.ts +0 -26
- package/dist/tui-opentui/footer.js +0 -40
- package/dist/tui-opentui/image-paste.d.ts +0 -54
- package/dist/tui-opentui/image-paste.js +0 -288
- package/dist/tui-opentui/input-box.d.ts +0 -32
- package/dist/tui-opentui/input-box.js +0 -462
- package/dist/tui-opentui/input-history.d.ts +0 -16
- package/dist/tui-opentui/input-history.js +0 -79
- package/dist/tui-opentui/markdown.d.ts +0 -66
- package/dist/tui-opentui/markdown.js +0 -127
- package/dist/tui-opentui/message-list.d.ts +0 -31
- package/dist/tui-opentui/message-list.js +0 -131
- package/dist/tui-opentui/model-picker.d.ts +0 -63
- package/dist/tui-opentui/model-picker.js +0 -450
- package/dist/tui-opentui/plan-confirm.d.ts +0 -9
- package/dist/tui-opentui/plan-confirm.js +0 -124
- package/dist/tui-opentui/question-dialog.d.ts +0 -10
- package/dist/tui-opentui/question-dialog.js +0 -110
- package/dist/tui-opentui/recent-activity.d.ts +0 -8
- package/dist/tui-opentui/recent-activity.js +0 -71
- package/dist/tui-opentui/run-session-picker.d.ts +0 -10
- package/dist/tui-opentui/run-session-picker.js +0 -28
- package/dist/tui-opentui/run.d.ts +0 -38
- package/dist/tui-opentui/run.js +0 -48
- package/dist/tui-opentui/session-picker.d.ts +0 -12
- package/dist/tui-opentui/session-picker.js +0 -120
- package/dist/tui-opentui/theme.d.ts +0 -89
- package/dist/tui-opentui/theme.js +0 -157
- package/dist/tui-opentui/todos.d.ts +0 -9
- package/dist/tui-opentui/todos.js +0 -45
- package/dist/tui-opentui/trace-groups.d.ts +0 -27
- package/dist/tui-opentui/trace-groups.js +0 -455
- package/dist/tui-opentui/use-terminal-size.d.ts +0 -4
- package/dist/tui-opentui/use-terminal-size.js +0 -5
- package/dist/tui-opentui/welcome.d.ts +0 -25
- package/dist/tui-opentui/welcome.js +0 -77
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
|
|
|
@@ -249,7 +251,7 @@ npm test # run the test suite (vitest)
|
|
|
249
251
|
npm start # run the built agent
|
|
250
252
|
```
|
|
251
253
|
|
|
252
|
-
`npm run dev` compiles and launches in one step. The TUI is built on
|
|
254
|
+
`npm run dev` compiles and launches in one step. The interactive TUI is built on React Ink.
|
|
253
255
|
|
|
254
256
|
## Feishu host (optional)
|
|
255
257
|
|
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/config.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export type ThemeMode = "auto" | "light" | "dark";
|
|
|
10
10
|
export interface ThemeConfig {
|
|
11
11
|
mode: ThemeMode;
|
|
12
12
|
overrides?: Record<string, string>;
|
|
13
|
+
explicit?: boolean;
|
|
13
14
|
}
|
|
14
15
|
export interface UserConfigData {
|
|
15
16
|
defaultModel?: string;
|
|
@@ -65,5 +66,7 @@ export declare class UserConfig {
|
|
|
65
66
|
getAgentCategories(): AgentCategoriesConfig;
|
|
66
67
|
getSubagents(): SubagentsUserConfig;
|
|
67
68
|
}
|
|
69
|
+
export declare function shouldProbeTerminalTheme(config: ThemeConfig): boolean;
|
|
70
|
+
export declare function effectiveThemeModeForTerminal(config: ThemeConfig, detectedTheme: Exclude<ThemeMode, "auto">): ThemeMode;
|
|
68
71
|
/** Mask an API key for safe display. */
|
|
69
72
|
export declare function maskKey(key: string): string;
|
package/dist/config.js
CHANGED
|
@@ -55,7 +55,7 @@ function sanitizeTheme(value) {
|
|
|
55
55
|
return undefined;
|
|
56
56
|
if (typeof value === "string") {
|
|
57
57
|
return value === "auto" || value === "light" || value === "dark"
|
|
58
|
-
? { mode: value }
|
|
58
|
+
? { mode: value, explicit: true }
|
|
59
59
|
: undefined;
|
|
60
60
|
}
|
|
61
61
|
if (typeof value !== "object" || Array.isArray(value))
|
|
@@ -68,7 +68,12 @@ function sanitizeTheme(value) {
|
|
|
68
68
|
if (mode !== "auto" && mode !== "light" && mode !== "dark")
|
|
69
69
|
return undefined;
|
|
70
70
|
const overrides = isStringMap(maybeNew.overrides) ? maybeNew.overrides : undefined;
|
|
71
|
-
|
|
71
|
+
const explicit = maybeNew.explicit === true ? true : undefined;
|
|
72
|
+
return {
|
|
73
|
+
mode,
|
|
74
|
+
...(overrides ? { overrides } : {}),
|
|
75
|
+
...(explicit ? { explicit } : {}),
|
|
76
|
+
};
|
|
72
77
|
}
|
|
73
78
|
const overrides = pickStringEntries(value);
|
|
74
79
|
if (Object.keys(overrides).length === 0)
|
|
@@ -188,15 +193,15 @@ export class UserConfig {
|
|
|
188
193
|
setThemeMode(mode) {
|
|
189
194
|
const current = this.getTheme();
|
|
190
195
|
this.data.theme = current.overrides
|
|
191
|
-
? { mode, overrides: current.overrides }
|
|
192
|
-
: { mode };
|
|
196
|
+
? { mode, overrides: current.overrides, explicit: true }
|
|
197
|
+
: { mode, explicit: true };
|
|
193
198
|
this.save();
|
|
194
199
|
}
|
|
195
200
|
setThemeOverrides(overrides) {
|
|
196
201
|
const current = this.getTheme();
|
|
197
202
|
this.data.theme = Object.keys(overrides).length === 0
|
|
198
|
-
? { mode: current.mode }
|
|
199
|
-
: { mode: current.mode, overrides: { ...overrides } };
|
|
203
|
+
? { mode: current.mode, ...(current.explicit ? { explicit: true } : {}) }
|
|
204
|
+
: { mode: current.mode, overrides: { ...overrides }, ...(current.explicit ? { explicit: true } : {}) };
|
|
200
205
|
this.save();
|
|
201
206
|
}
|
|
202
207
|
getAgentCategories() {
|
|
@@ -206,6 +211,17 @@ export class UserConfig {
|
|
|
206
211
|
return sanitizeSubagentsConfig(this.data.subagents) ?? {};
|
|
207
212
|
}
|
|
208
213
|
}
|
|
214
|
+
export function shouldProbeTerminalTheme(config) {
|
|
215
|
+
return config.mode === "auto" || isLegacyBareDarkTheme(config);
|
|
216
|
+
}
|
|
217
|
+
export function effectiveThemeModeForTerminal(config, detectedTheme) {
|
|
218
|
+
if (isLegacyBareDarkTheme(config) && detectedTheme === "light")
|
|
219
|
+
return "auto";
|
|
220
|
+
return config.mode;
|
|
221
|
+
}
|
|
222
|
+
function isLegacyBareDarkTheme(config) {
|
|
223
|
+
return config.mode === "dark" && config.explicit !== true && !config.overrides;
|
|
224
|
+
}
|
|
209
225
|
/** Mask an API key for safe display. */
|
|
210
226
|
export function maskKey(key) {
|
|
211
227
|
if (key.length <= 12)
|
package/dist/goal/format.js
CHANGED
|
@@ -30,6 +30,20 @@ function trimZero(value) {
|
|
|
30
30
|
return Number.isInteger(rounded) ? String(rounded) : rounded.toFixed(1);
|
|
31
31
|
}
|
|
32
32
|
function tokensPart(goal) {
|
|
33
|
+
const untracked = goal.untrackedTokenTurns ?? 0;
|
|
34
|
+
if (untracked > 0) {
|
|
35
|
+
const turns = `${untracked} ${untracked === 1 ? "turn" : "turns"}`;
|
|
36
|
+
if (goal.tokensUsed > 0) {
|
|
37
|
+
const budget = goal.tokenBudget !== undefined
|
|
38
|
+
? `/${formatTokensCompact(goal.tokenBudget)}`
|
|
39
|
+
: "";
|
|
40
|
+
return `${formatTokensCompact(goal.tokensUsed)}${budget} tok tracked; usage unavailable for ${turns}`;
|
|
41
|
+
}
|
|
42
|
+
if (goal.tokenBudget !== undefined) {
|
|
43
|
+
return `usage unavailable for ${turns}; budget ${formatTokensCompact(goal.tokenBudget)} tok`;
|
|
44
|
+
}
|
|
45
|
+
return `usage unavailable for ${turns}`;
|
|
46
|
+
}
|
|
33
47
|
if (goal.tokenBudget !== undefined) {
|
|
34
48
|
return `${formatTokensCompact(goal.tokensUsed)}/${formatTokensCompact(goal.tokenBudget)} tok`;
|
|
35
49
|
}
|
|
@@ -59,11 +73,27 @@ export function goalSummaryText(goal) {
|
|
|
59
73
|
* update_goal tool can't report this — see goal/tools.ts).
|
|
60
74
|
*/
|
|
61
75
|
export function goalCompleteNotice(goal) {
|
|
62
|
-
const tokens = goal
|
|
63
|
-
? `${formatTokensCompact(goal.tokensUsed)}/${formatTokensCompact(goal.tokenBudget)} tok`
|
|
64
|
-
: `${formatTokensCompact(goal.tokensUsed)} tok`;
|
|
76
|
+
const tokens = completionTokenUsagePhrase(goal);
|
|
65
77
|
const turns = `${goal.turnsSpent} ${goal.turnsSpent === 1 ? "turn" : "turns"}`;
|
|
66
|
-
return `Goal complete — ${tokens}
|
|
78
|
+
return `Goal complete — ${tokens} over ${turns}.`;
|
|
79
|
+
}
|
|
80
|
+
function completionTokenUsagePhrase(goal) {
|
|
81
|
+
const untracked = goal.untrackedTokenTurns ?? 0;
|
|
82
|
+
if (untracked > 0) {
|
|
83
|
+
if (goal.tokensUsed > 0) {
|
|
84
|
+
const budget = goal.tokenBudget !== undefined
|
|
85
|
+
? `/${formatTokensCompact(goal.tokenBudget)}`
|
|
86
|
+
: "";
|
|
87
|
+
return `${formatTokensCompact(goal.tokensUsed)}${budget} tok used, plus unavailable usage`;
|
|
88
|
+
}
|
|
89
|
+
if (goal.tokenBudget !== undefined) {
|
|
90
|
+
return `token usage unavailable (budget ${formatTokensCompact(goal.tokenBudget)} tok)`;
|
|
91
|
+
}
|
|
92
|
+
return "token usage unavailable";
|
|
93
|
+
}
|
|
94
|
+
return goal.tokenBudget !== undefined
|
|
95
|
+
? `${formatTokensCompact(goal.tokensUsed)}/${formatTokensCompact(goal.tokenBudget)} tok used`
|
|
96
|
+
: `${formatTokensCompact(goal.tokensUsed)} tok used`;
|
|
67
97
|
}
|
|
68
98
|
/** Compact single-line indicator for the status line / sidebar. */
|
|
69
99
|
export function goalIndicatorLine(goal, maxObjective = 48) {
|
package/dist/goal/store.d.ts
CHANGED
|
@@ -15,6 +15,8 @@ export interface GoalState {
|
|
|
15
15
|
/** Optional positive token budget; auto-continuation stops once reached. */
|
|
16
16
|
tokenBudget?: number;
|
|
17
17
|
tokensUsed: number;
|
|
18
|
+
/** Goal turns where the provider did not report token usage. */
|
|
19
|
+
untrackedTokenTurns?: number;
|
|
18
20
|
/** Number of completed goal turns (including the initial turn). */
|
|
19
21
|
turnsSpent: number;
|
|
20
22
|
createdAt: number;
|
|
@@ -52,6 +54,7 @@ export declare class GoalStore {
|
|
|
52
54
|
markBudgetLimited(): GoalState | null;
|
|
53
55
|
private setStatus;
|
|
54
56
|
addTokens(n: number): void;
|
|
57
|
+
markTokenUsageUnavailable(): void;
|
|
55
58
|
incrementTurn(): void;
|
|
56
59
|
/** True when a token budget is set and usage has reached or exceeded it. */
|
|
57
60
|
isBudgetExceeded(): boolean;
|
package/dist/goal/store.js
CHANGED
|
@@ -54,6 +54,7 @@ export class GoalStore {
|
|
|
54
54
|
status: "active",
|
|
55
55
|
tokenBudget,
|
|
56
56
|
tokensUsed: 0,
|
|
57
|
+
untrackedTokenTurns: 0,
|
|
57
58
|
turnsSpent: 0,
|
|
58
59
|
createdAt: ts,
|
|
59
60
|
updatedAt: ts,
|
|
@@ -131,6 +132,13 @@ export class GoalStore {
|
|
|
131
132
|
this.touch();
|
|
132
133
|
this.emit();
|
|
133
134
|
}
|
|
135
|
+
markTokenUsageUnavailable() {
|
|
136
|
+
if (!this.goal)
|
|
137
|
+
return;
|
|
138
|
+
this.goal.untrackedTokenTurns = (this.goal.untrackedTokenTurns ?? 0) + 1;
|
|
139
|
+
this.touch();
|
|
140
|
+
this.emit();
|
|
141
|
+
}
|
|
134
142
|
incrementTurn() {
|
|
135
143
|
if (!this.goal)
|
|
136
144
|
return;
|
|
@@ -154,7 +162,12 @@ export class GoalStore {
|
|
|
154
162
|
this.goal = null;
|
|
155
163
|
}
|
|
156
164
|
else {
|
|
157
|
-
this.goal = {
|
|
165
|
+
this.goal = {
|
|
166
|
+
...state,
|
|
167
|
+
untrackedTokenTurns: state.untrackedTokenTurns !== undefined && state.untrackedTokenTurns > 0
|
|
168
|
+
? Math.round(state.untrackedTokenTurns)
|
|
169
|
+
: 0,
|
|
170
|
+
};
|
|
158
171
|
}
|
|
159
172
|
this.emit();
|
|
160
173
|
}
|
package/dist/main.js
CHANGED
|
@@ -6,7 +6,7 @@ import chalk from "chalk";
|
|
|
6
6
|
import { Agent } from "./agent.js";
|
|
7
7
|
import { BudgetLedger } from "./agent/budget-ledger.js";
|
|
8
8
|
import { parseArgs, printHelp } from "./cli.js";
|
|
9
|
-
import { UserConfig } from "./config.js";
|
|
9
|
+
import { effectiveThemeModeForTerminal, shouldProbeTerminalTheme, UserConfig } from "./config.js";
|
|
10
10
|
import { createProviderInstance, createUnavailableProvider } from "./provider.js";
|
|
11
11
|
import { resolveConfiguredModel } from "./model-selection.js";
|
|
12
12
|
import { getDefaultThinkingLevel } from "./provider-transform.js";
|
|
@@ -31,10 +31,6 @@ import { basename } from "node:path";
|
|
|
31
31
|
import { normalizeSingleLine, truncateVisual } from "./text-display.js";
|
|
32
32
|
import { BUBBLE_WORDMARK } from "./tui/wordmark.js";
|
|
33
33
|
import { configureDebugTrace, summarizeAgentEventForTrace, summarizeTraceMessage, traceEvent, } from "./debug-trace.js";
|
|
34
|
-
// OpenTUI is the default renderer. The React Ink implementation (alt-screen
|
|
35
|
-
// viewport, src/tui-ink) is feature-complete but still maturing — opt in with
|
|
36
|
-
// BUBBLE_TUI=ink.
|
|
37
|
-
const USE_OPENTUI = process.env.BUBBLE_TUI !== "ink";
|
|
38
34
|
async function main() {
|
|
39
35
|
const args = parseArgs(process.argv.slice(2));
|
|
40
36
|
if (process.argv.includes("-h") || process.argv.includes("--help")) {
|
|
@@ -229,21 +225,21 @@ async function main() {
|
|
|
229
225
|
}
|
|
230
226
|
else {
|
|
231
227
|
const themeConfig = userConfig.getTheme();
|
|
232
|
-
if (themeConfig
|
|
228
|
+
if (shouldProbeTerminalTheme(themeConfig)) {
|
|
233
229
|
const { detectTerminalTheme } = await import("./tui/detect-theme.js");
|
|
234
230
|
preResolvedTheme = await detectTerminalTheme();
|
|
235
231
|
}
|
|
236
232
|
else {
|
|
237
|
-
preResolvedTheme = themeConfig.mode;
|
|
233
|
+
preResolvedTheme = themeConfig.mode === "light" ? "light" : "dark";
|
|
238
234
|
}
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
|
|
235
|
+
const pickerThemeMode = effectiveThemeModeForTerminal(themeConfig, preResolvedTheme);
|
|
236
|
+
const pickerResolvedTheme = pickerThemeMode === "auto" ? preResolvedTheme : pickerThemeMode;
|
|
237
|
+
const { runSessionPicker } = await import("./tui-ink/run-session-picker.js");
|
|
242
238
|
const picked = await runSessionPicker({
|
|
243
239
|
currentCwd: args.cwd,
|
|
244
240
|
currentSessions,
|
|
245
241
|
allSessions,
|
|
246
|
-
resolvedTheme:
|
|
242
|
+
resolvedTheme: pickerResolvedTheme,
|
|
247
243
|
themeOverrides: themeConfig.overrides,
|
|
248
244
|
});
|
|
249
245
|
if (picked) {
|
|
@@ -317,7 +313,7 @@ async function main() {
|
|
|
317
313
|
sessionFile: sessionManager?.getSessionFile(),
|
|
318
314
|
provider: activeProviderId || "none",
|
|
319
315
|
model: activeModel || "none",
|
|
320
|
-
renderer: printMode ? "print" :
|
|
316
|
+
renderer: printMode ? "print" : "ink",
|
|
321
317
|
});
|
|
322
318
|
if (traceInfo.enabled) {
|
|
323
319
|
traceEvent("run_start", {
|
|
@@ -508,15 +504,16 @@ async function main() {
|
|
|
508
504
|
if (preResolvedTheme) {
|
|
509
505
|
detectedTheme = preResolvedTheme;
|
|
510
506
|
}
|
|
511
|
-
else if (themeConfig
|
|
512
|
-
// Probe before
|
|
507
|
+
else if (shouldProbeTerminalTheme(themeConfig)) {
|
|
508
|
+
// Probe before the renderer owns stdin. OSC 11 needs raw mode, and the
|
|
513
509
|
// runtime renderer can consume the reply before startup code sees it.
|
|
514
510
|
const { detectTerminalTheme } = await import("./tui/detect-theme.js");
|
|
515
511
|
detectedTheme = await detectTerminalTheme();
|
|
516
512
|
}
|
|
517
513
|
else {
|
|
518
|
-
detectedTheme = themeConfig.mode;
|
|
514
|
+
detectedTheme = themeConfig.mode === "light" ? "light" : "dark";
|
|
519
515
|
}
|
|
516
|
+
const effectiveThemeMode = effectiveThemeModeForTerminal(themeConfig, detectedTheme);
|
|
520
517
|
// In-place session switch for the /session picker: rebind every closure
|
|
521
518
|
// that persists to the session (onMessageAppend, markers, title updater)
|
|
522
519
|
// by reassigning the outer `sessionManager`, then replace the agent's
|
|
@@ -572,33 +569,17 @@ async function main() {
|
|
|
572
569
|
const { startStartupUpdateCheck } = await import("./update/index.js");
|
|
573
570
|
const updateCheck = await startStartupUpdateCheck();
|
|
574
571
|
const updateNotice = updateCheck.notice;
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
updateNotice: updateNotice ?? undefined,
|
|
587
|
-
updateNoticeRefresh: updateCheck.refreshed,
|
|
588
|
-
});
|
|
589
|
-
}
|
|
590
|
-
else {
|
|
591
|
-
const { runTui } = await import("./tui-ink/run.js");
|
|
592
|
-
const summary = await runTui(agent, args, {
|
|
593
|
-
...commonOptions,
|
|
594
|
-
themeMode: themeConfig.mode,
|
|
595
|
-
themeOverrides: themeConfig.overrides,
|
|
596
|
-
detectedTheme,
|
|
597
|
-
onThemeModeChange: (mode) => userConfig.setThemeMode(mode),
|
|
598
|
-
updateNotice: updateNotice ?? undefined,
|
|
599
|
-
});
|
|
600
|
-
exitWallMs = summary?.wallMs;
|
|
601
|
-
}
|
|
572
|
+
const { runTui } = await import("./tui-ink/run.js");
|
|
573
|
+
const summary = await runTui(agent, args, {
|
|
574
|
+
...commonOptions,
|
|
575
|
+
themeMode: effectiveThemeMode,
|
|
576
|
+
themeOverrides: themeConfig.overrides,
|
|
577
|
+
detectedTheme,
|
|
578
|
+
onThemeModeChange: (mode) => userConfig.setThemeMode(mode),
|
|
579
|
+
updateNotice: updateNotice ?? undefined,
|
|
580
|
+
updateNoticeRefresh: updateCheck.refreshed,
|
|
581
|
+
});
|
|
582
|
+
const exitWallMs = summary?.wallMs;
|
|
602
583
|
if (sessionManager) {
|
|
603
584
|
printExitSummary(sessionManager, {
|
|
604
585
|
resumed: resumedExistingSession,
|
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";
|