@bubblebrain-ai/bubble 0.0.35 → 0.0.37
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 +27 -7
- package/dist/agent/categories.d.ts +66 -2
- package/dist/agent/categories.js +120 -19
- package/dist/agent/discovery-barrier.js +1 -1
- package/dist/agent/profiles.d.ts +1 -0
- package/dist/agent/profiles.js +25 -11
- package/dist/agent/routing-catalog.d.ts +113 -0
- package/dist/agent/routing-catalog.js +240 -0
- package/dist/agent/workflow/control.d.ts +14 -0
- package/dist/agent/workflow/control.js +30 -9
- package/dist/agent.d.ts +75 -5
- package/dist/agent.js +313 -61
- package/dist/approval/controller.js +28 -0
- package/dist/approval/tool-helper.js +2 -0
- package/dist/approval/types.d.ts +21 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +2 -1
- package/dist/config.d.ts +4 -0
- package/dist/config.js +4 -0
- package/dist/context/compact-llm.d.ts +2 -2
- package/dist/external-runtime/grok-acp.d.ts +56 -0
- package/dist/external-runtime/grok-acp.js +386 -0
- package/dist/external-runtime/grok-binary.d.ts +25 -0
- package/dist/external-runtime/grok-binary.js +108 -0
- package/dist/external-runtime/grok-errors.d.ts +7 -0
- package/dist/external-runtime/grok-errors.js +15 -0
- package/dist/external-runtime/grok-input-policy.d.ts +58 -0
- package/dist/external-runtime/grok-input-policy.js +52 -0
- package/dist/external-runtime/grok-ndjson.d.ts +14 -0
- package/dist/external-runtime/grok-ndjson.js +193 -0
- package/dist/external-runtime/grok-network.d.ts +15 -0
- package/dist/external-runtime/grok-network.js +81 -0
- package/dist/external-runtime/grok-preflight.d.ts +28 -0
- package/dist/external-runtime/grok-preflight.js +194 -0
- package/dist/external-runtime/grok-process.d.ts +26 -0
- package/dist/external-runtime/grok-process.js +184 -0
- package/dist/external-runtime/grok-profile.d.ts +32 -0
- package/dist/external-runtime/grok-profile.js +419 -0
- package/dist/external-runtime/grok-provider.d.ts +31 -0
- package/dist/external-runtime/grok-provider.js +41 -0
- package/dist/external-runtime/grok-runtime.d.ts +91 -0
- package/dist/external-runtime/grok-runtime.js +882 -0
- package/dist/external-runtime/index.d.ts +13 -0
- package/dist/external-runtime/index.js +13 -0
- package/dist/external-runtime/session-policy.d.ts +11 -0
- package/dist/external-runtime/session-policy.js +30 -0
- package/dist/external-runtime/types.d.ts +65 -0
- package/dist/external-runtime/types.js +1 -0
- package/dist/feishu/agent-host/approval-card.js +21 -0
- package/dist/feishu/agent-host/run-driver.js +19 -3
- package/dist/feishu/serve.js +1 -0
- package/dist/goal/tools.d.ts +6 -3
- package/dist/goal/tools.js +7 -19
- package/dist/main.js +105 -27
- package/dist/memory/db.d.ts +2 -0
- package/dist/memory/db.js +10 -0
- package/dist/memory/index.d.ts +1 -0
- package/dist/memory/index.js +1 -0
- package/dist/memory/phase1.js +14 -2
- package/dist/memory/phase2.js +21 -2
- package/dist/memory/prompts.js +1 -1
- package/dist/memory/session-policy.d.ts +25 -0
- package/dist/memory/session-policy.js +55 -0
- package/dist/memory/storage.d.ts +1 -0
- package/dist/memory/storage.js +13 -0
- package/dist/model-catalog.d.ts +18 -0
- package/dist/model-catalog.js +87 -41
- package/dist/model-config.d.ts +3 -1
- package/dist/model-config.js +11 -0
- package/dist/oauth/grok.d.ts +25 -0
- package/dist/oauth/grok.js +218 -0
- package/dist/oauth/index.d.ts +1 -0
- package/dist/oauth/index.js +1 -0
- package/dist/oauth/storage.d.ts +9 -0
- package/dist/oauth/storage.js +25 -0
- package/dist/orchestrator/default-hooks.js +17 -7
- package/dist/prompt/compose.d.ts +3 -0
- package/dist/prompt/compose.js +3 -0
- package/dist/prompt/delegation.js +22 -3
- package/dist/prompt/environment.js +0 -4
- package/dist/prompt/reminders.d.ts +0 -1
- package/dist/prompt/reminders.js +1 -11
- package/dist/prompt/routing.d.ts +14 -0
- package/dist/prompt/routing.js +71 -0
- package/dist/prompt/runtime.js +1 -1
- package/dist/prompt/task-reminders.d.ts +19 -0
- package/dist/prompt/task-reminders.js +49 -0
- package/dist/provider-ai-sdk.js +2 -2
- package/dist/provider-grok.d.ts +26 -0
- package/dist/provider-grok.js +59 -0
- package/dist/provider-openai-codex.d.ts +17 -1
- package/dist/provider-openai-codex.js +101 -29
- package/dist/provider-registry.d.ts +72 -0
- package/dist/provider-registry.js +336 -59
- package/dist/provider-transform.d.ts +1 -1
- package/dist/provider-transform.js +28 -5
- package/dist/provider.d.ts +3 -0
- package/dist/provider.js +14 -0
- package/dist/session-types.d.ts +19 -1
- package/dist/session.d.ts +1 -0
- package/dist/session.js +4 -0
- package/dist/slash-commands/commands.js +224 -14
- package/dist/slash-commands/types.d.ts +14 -1
- package/dist/system-prompt.d.ts +2 -0
- package/dist/tools/agent-lifecycle.js +9 -11
- package/dist/tools/bash.js +1 -1
- package/dist/tools/child-tools.js +2 -0
- package/dist/tools/index.d.ts +2 -2
- package/dist/tools/index.js +7 -5
- package/dist/tools/lsp.js +1 -0
- package/dist/tools/memory.d.ts +7 -2
- package/dist/tools/memory.js +28 -43
- package/dist/tools/server.js +4 -0
- package/dist/tools/tool-search.d.ts +1 -1
- package/dist/tools/tool-search.js +23 -3
- package/dist/tui/model-switch.d.ts +7 -0
- package/dist/tui/model-switch.js +15 -5
- package/dist/tui-ink/app.d.ts +3 -1
- package/dist/tui-ink/app.js +649 -233
- package/dist/tui-ink/approval/approval-dialog.js +36 -0
- package/dist/tui-ink/composer-buffer.d.ts +55 -0
- package/dist/tui-ink/composer-buffer.js +317 -0
- package/dist/tui-ink/footer.d.ts +1 -0
- package/dist/tui-ink/footer.js +7 -2
- package/dist/tui-ink/input-box.d.ts +35 -1
- package/dist/tui-ink/input-box.js +215 -122
- package/dist/tui-ink/message-list.js +5 -5
- package/dist/tui-ink/model-picker.d.ts +61 -4
- package/dist/tui-ink/model-picker.js +486 -133
- package/dist/tui-ink/paste-operation-tracker.d.ts +13 -0
- package/dist/tui-ink/paste-operation-tracker.js +25 -0
- package/dist/tui-ink/run.d.ts +3 -0
- package/dist/tui-ink/run.js +1 -1
- package/dist/tui-ink/subagent-view.d.ts +31 -0
- package/dist/tui-ink/subagent-view.js +82 -1
- package/dist/types.d.ts +5 -5
- package/dist/types.js +1 -1
- package/dist/variant/thinking-level.d.ts +2 -2
- package/dist/variant/thinking-level.js +2 -1
- package/dist/variant/variant-resolver.d.ts +9 -0
- package/dist/variant/variant-resolver.js +17 -0
- package/package.json +2 -1
- package/dist/tools/task.d.ts +0 -2
- package/dist/tools/task.js +0 -58
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tracks overlapping paste operations by identity. Finishing an older paste
|
|
3
|
+
* must never clear the pending state of a newer paste.
|
|
4
|
+
*/
|
|
5
|
+
export declare class PasteOperationTracker {
|
|
6
|
+
private nextId;
|
|
7
|
+
private readonly active;
|
|
8
|
+
begin(): number;
|
|
9
|
+
finish(id: number): void;
|
|
10
|
+
invalidateAll(): void;
|
|
11
|
+
get hasPending(): boolean;
|
|
12
|
+
get pendingCount(): number;
|
|
13
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tracks overlapping paste operations by identity. Finishing an older paste
|
|
3
|
+
* must never clear the pending state of a newer paste.
|
|
4
|
+
*/
|
|
5
|
+
export class PasteOperationTracker {
|
|
6
|
+
nextId = 1;
|
|
7
|
+
active = new Set();
|
|
8
|
+
begin() {
|
|
9
|
+
const id = this.nextId++;
|
|
10
|
+
this.active.add(id);
|
|
11
|
+
return id;
|
|
12
|
+
}
|
|
13
|
+
finish(id) {
|
|
14
|
+
this.active.delete(id);
|
|
15
|
+
}
|
|
16
|
+
invalidateAll() {
|
|
17
|
+
this.active.clear();
|
|
18
|
+
}
|
|
19
|
+
get hasPending() {
|
|
20
|
+
return this.active.size > 0;
|
|
21
|
+
}
|
|
22
|
+
get pendingCount() {
|
|
23
|
+
return this.active.size;
|
|
24
|
+
}
|
|
25
|
+
}
|
package/dist/tui-ink/run.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ import type { QuestionController } from "../question/index.js";
|
|
|
14
14
|
import type { MemoryScope } from "../memory/index.js";
|
|
15
15
|
import type { ExternalHookController } from "../hooks/controller.js";
|
|
16
16
|
import type { ResolvedTheme, ThemeMode } from "./theme.js";
|
|
17
|
+
import type { ExternalRuntimeManager } from "../external-runtime/types.js";
|
|
17
18
|
export interface RunTuiOptions {
|
|
18
19
|
sessionManager?: SessionManager;
|
|
19
20
|
createProvider?: (providerId: string, apiKey: string, baseURL: string) => Provider;
|
|
@@ -48,6 +49,8 @@ export interface RunTuiOptions {
|
|
|
48
49
|
updateNoticeRefresh?: Promise<string | null>;
|
|
49
50
|
/** External lifecycle hooks, threaded into slash-command execution. */
|
|
50
51
|
hookController?: ExternalHookController;
|
|
52
|
+
/** Subscription-backed external agent runtime used by the interactive TUI. */
|
|
53
|
+
externalRuntime?: ExternalRuntimeManager;
|
|
51
54
|
}
|
|
52
55
|
export declare function createInkAppElement(agent: Agent, args: CliArgs, options: RunTuiOptions, onExit: (summary: ExitSummary) => void): React.ReactElement;
|
|
53
56
|
export declare function runTui(agent: Agent, args: CliArgs, options?: RunTuiOptions): Promise<ExitSummary | undefined>;
|
package/dist/tui-ink/run.js
CHANGED
|
@@ -3,7 +3,7 @@ import { render } from "ink";
|
|
|
3
3
|
import { App } from "./app.js";
|
|
4
4
|
import { warmHighlighter } from "./code-highlight.js";
|
|
5
5
|
export function createInkAppElement(agent, args, options, onExit) {
|
|
6
|
-
return (_jsx(App, { agent: agent, args: args, sessionManager: options.sessionManager, switchSession: options.switchSession, createProvider: options.createProvider, registry: options.registry, skillRegistry: options.skillRegistry, planHandlerRef: options.planHandlerRef, approvalHandlerRef: options.approvalHandlerRef, questionController: options.questionController, bashAllowlist: options.bashAllowlist, settingsManager: options.settingsManager, lspService: options.lspService, mcpManager: options.mcpManager, goalStore: options.goalStore, themeMode: options.themeMode, themeOverrides: options.themeOverrides, detectedTheme: options.detectedTheme, onThemeModeChange: options.onThemeModeChange, flushMemory: options.flushMemory, runMemoryCompaction: options.runMemoryCompaction, runMemorySummary: options.runMemorySummary, runMemoryRefresh: options.runMemoryRefresh, bypassEnabled: options.bypassEnabled, updateNotice: options.updateNotice, updateNoticeRefresh: options.updateNoticeRefresh, hookController: options.hookController, onExit: onExit }));
|
|
6
|
+
return (_jsx(App, { agent: agent, args: args, sessionManager: options.sessionManager, switchSession: options.switchSession, createProvider: options.createProvider, registry: options.registry, skillRegistry: options.skillRegistry, planHandlerRef: options.planHandlerRef, approvalHandlerRef: options.approvalHandlerRef, questionController: options.questionController, bashAllowlist: options.bashAllowlist, settingsManager: options.settingsManager, lspService: options.lspService, mcpManager: options.mcpManager, goalStore: options.goalStore, themeMode: options.themeMode, themeOverrides: options.themeOverrides, detectedTheme: options.detectedTheme, onThemeModeChange: options.onThemeModeChange, flushMemory: options.flushMemory, runMemoryCompaction: options.runMemoryCompaction, runMemorySummary: options.runMemorySummary, runMemoryRefresh: options.runMemoryRefresh, bypassEnabled: options.bypassEnabled, updateNotice: options.updateNotice, updateNoticeRefresh: options.updateNoticeRefresh, hookController: options.hookController, externalRuntime: options.externalRuntime, onExit: onExit }));
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
9
|
* Best-effort terminal restore for abnormal exits. Bubble renders into the
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import { type SubagentRouteLike } from "../agent/subagent-route-format.js";
|
|
7
7
|
import type { Theme } from "./theme.js";
|
|
8
8
|
import type { DisplayMessage, DisplayToolCall } from "./display-history.js";
|
|
9
|
+
import type { ToolResultMetadata } from "../types.js";
|
|
9
10
|
export interface SubagentDisplay {
|
|
10
11
|
subAgentId?: string;
|
|
11
12
|
agentName?: string;
|
|
@@ -35,6 +36,36 @@ export interface SubagentGroup {
|
|
|
35
36
|
label: string;
|
|
36
37
|
members: SubagentDisplay[];
|
|
37
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Merges subagent tool metadata, deduping member snapshots by subAgentId so a
|
|
41
|
+
* stream of per-child updates accumulates into one member list instead of each
|
|
42
|
+
* update replacing the last.
|
|
43
|
+
*/
|
|
44
|
+
export declare function mergeToolMetadata(current: ToolResultMetadata | undefined, incoming: ToolResultMetadata | undefined): ToolResultMetadata | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Drops accumulator entries whose every member reached a final status: by then
|
|
47
|
+
* the authoritative snapshot lives in the settled transcript (wait_workflow /
|
|
48
|
+
* wait_agent result), so the entry is dead weight that would otherwise pile up
|
|
49
|
+
* for the life of the process. Entries with running/queued members stay — for
|
|
50
|
+
* a workflow spanning turns they are the only live view. Returns whether the
|
|
51
|
+
* map changed (callers bump their version counter on true).
|
|
52
|
+
*/
|
|
53
|
+
export declare function pruneSettledLiveSubagentTools(map: Map<string, DisplayToolCall>): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Accumulates a subagent tool_update whose originating tool call has already
|
|
56
|
+
* settled out of the current streaming round. The TUI clears its streaming
|
|
57
|
+
* toolCalls on every turn_start, but background children keep reporting
|
|
58
|
+
* against the launching run_workflow/spawn_agent call id across later rounds
|
|
59
|
+
* (e.g. while a wait_workflow blocks) — without this side-channel those
|
|
60
|
+
* updates are dropped and traces only appear after the whole team finishes.
|
|
61
|
+
* Entries act as synthetic tool calls feeding collectSubagentGroups.
|
|
62
|
+
* Returns true when the update was absorbed.
|
|
63
|
+
*/
|
|
64
|
+
export declare function accumulateLiveSubagentUpdate(map: Map<string, DisplayToolCall>, event: {
|
|
65
|
+
id: string;
|
|
66
|
+
name: string;
|
|
67
|
+
metadata?: ToolResultMetadata;
|
|
68
|
+
}): boolean;
|
|
38
69
|
/**
|
|
39
70
|
* Collects every spawned subagent from the live transcript + streaming tools,
|
|
40
71
|
* grouped by their originating tool call, for the inspector. Pure.
|
|
@@ -75,6 +75,84 @@ function subagentFreshness(member) {
|
|
|
75
75
|
function memberKey(member) {
|
|
76
76
|
return member.subAgentId || `${member.nickname ?? ""}|${member.task ?? ""}`;
|
|
77
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Merges subagent tool metadata, deduping member snapshots by subAgentId so a
|
|
80
|
+
* stream of per-child updates accumulates into one member list instead of each
|
|
81
|
+
* update replacing the last.
|
|
82
|
+
*/
|
|
83
|
+
export function mergeToolMetadata(current, incoming) {
|
|
84
|
+
if (!incoming)
|
|
85
|
+
return current;
|
|
86
|
+
if (current?.kind !== "subagent" || incoming.kind !== "subagent") {
|
|
87
|
+
return incoming;
|
|
88
|
+
}
|
|
89
|
+
const currentSubagents = Array.isArray(current.subagents) ? current.subagents : [];
|
|
90
|
+
const incomingSubagents = Array.isArray(incoming.subagents) ? incoming.subagents : [];
|
|
91
|
+
const byId = new Map();
|
|
92
|
+
for (const item of currentSubagents) {
|
|
93
|
+
const subAgentId = typeof item === "object" && item !== null && "subAgentId" in item
|
|
94
|
+
? String(item.subAgentId)
|
|
95
|
+
: "";
|
|
96
|
+
byId.set(subAgentId || `current:${byId.size}`, item);
|
|
97
|
+
}
|
|
98
|
+
for (const item of incomingSubagents) {
|
|
99
|
+
const subAgentId = typeof item === "object" && item !== null && "subAgentId" in item
|
|
100
|
+
? String(item.subAgentId)
|
|
101
|
+
: "";
|
|
102
|
+
byId.set(subAgentId || `incoming:${byId.size}`, item);
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
...current,
|
|
106
|
+
...incoming,
|
|
107
|
+
subagents: [...byId.values()],
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
const FINAL_MEMBER_STATUSES = new Set(["completed", "failed", "blocked", "cancelled", "closed"]);
|
|
111
|
+
/**
|
|
112
|
+
* Drops accumulator entries whose every member reached a final status: by then
|
|
113
|
+
* the authoritative snapshot lives in the settled transcript (wait_workflow /
|
|
114
|
+
* wait_agent result), so the entry is dead weight that would otherwise pile up
|
|
115
|
+
* for the life of the process. Entries with running/queued members stay — for
|
|
116
|
+
* a workflow spanning turns they are the only live view. Returns whether the
|
|
117
|
+
* map changed (callers bump their version counter on true).
|
|
118
|
+
*/
|
|
119
|
+
export function pruneSettledLiveSubagentTools(map) {
|
|
120
|
+
let changed = false;
|
|
121
|
+
for (const [id, tc] of map) {
|
|
122
|
+
const members = Array.isArray(tc.metadata?.subagents) ? tc.metadata.subagents : [];
|
|
123
|
+
const allFinal = members.every((member) => typeof member === "object" && member !== null
|
|
124
|
+
&& FINAL_MEMBER_STATUSES.has(String(member.status)));
|
|
125
|
+
if (allFinal) {
|
|
126
|
+
map.delete(id);
|
|
127
|
+
changed = true;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return changed;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Accumulates a subagent tool_update whose originating tool call has already
|
|
134
|
+
* settled out of the current streaming round. The TUI clears its streaming
|
|
135
|
+
* toolCalls on every turn_start, but background children keep reporting
|
|
136
|
+
* against the launching run_workflow/spawn_agent call id across later rounds
|
|
137
|
+
* (e.g. while a wait_workflow blocks) — without this side-channel those
|
|
138
|
+
* updates are dropped and traces only appear after the whole team finishes.
|
|
139
|
+
* Entries act as synthetic tool calls feeding collectSubagentGroups.
|
|
140
|
+
* Returns true when the update was absorbed.
|
|
141
|
+
*/
|
|
142
|
+
export function accumulateLiveSubagentUpdate(map, event) {
|
|
143
|
+
if (event.metadata?.kind !== "subagent")
|
|
144
|
+
return false;
|
|
145
|
+
const prev = map.get(event.id);
|
|
146
|
+
const metadata = mergeToolMetadata(prev?.metadata, event.metadata);
|
|
147
|
+
if (!metadata)
|
|
148
|
+
return false;
|
|
149
|
+
// Per-child updates carry no mode; group them under the launching workflow
|
|
150
|
+
// call rather than falling back to one single-agent group per member.
|
|
151
|
+
if (event.name === "run_workflow" && metadata.mode === undefined)
|
|
152
|
+
metadata.mode = "workflow";
|
|
153
|
+
map.set(event.id, { id: event.id, name: event.name, args: prev?.args ?? {}, metadata });
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
78
156
|
/**
|
|
79
157
|
* Collects every spawned subagent from the live transcript + streaming tools,
|
|
80
158
|
* grouped by their originating tool call, for the inspector. Pure.
|
|
@@ -159,5 +237,8 @@ export function collectSubagentGroups(messages, streamingTools) {
|
|
|
159
237
|
kind: g.kind,
|
|
160
238
|
label: g.label,
|
|
161
239
|
members: g.memberKeys.map((k) => freshest.get(k)).filter((m) => !!m),
|
|
162
|
-
}))
|
|
240
|
+
}))
|
|
241
|
+
// A group can end up empty when a later echo of the same run (e.g. the
|
|
242
|
+
// wait_workflow result vs the live accumulator) claimed all its members.
|
|
243
|
+
.filter((group) => group.members.length > 0);
|
|
163
244
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -12,7 +12,8 @@ export interface ImageContent {
|
|
|
12
12
|
};
|
|
13
13
|
}
|
|
14
14
|
export type ContentPart = TextContent | ImageContent;
|
|
15
|
-
export
|
|
15
|
+
export declare const THINKING_LEVELS: readonly ["off", "minimal", "low", "medium", "high", "xhigh", "max", "ultra"];
|
|
16
|
+
export type ThinkingLevel = (typeof THINKING_LEVELS)[number];
|
|
16
17
|
export type ReasoningEffort = ThinkingLevel;
|
|
17
18
|
export type ProviderRawContentBlock = Record<string, unknown> & {
|
|
18
19
|
type: string;
|
|
@@ -169,10 +170,9 @@ export interface ToolContext {
|
|
|
169
170
|
name: string;
|
|
170
171
|
};
|
|
171
172
|
agent?: {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}) => Promise<ToolResult>;
|
|
173
|
+
/** Deferred-tool surface; backs tool_search when no controller is wired. */
|
|
174
|
+
listDeferredTools?: () => ToolRegistryEntry[];
|
|
175
|
+
unlockDeferredTools?: (names: string[]) => void;
|
|
176
176
|
runSubAgent?: (input: string | ContentPart[], cwd: string, options: {
|
|
177
177
|
profile: import("./agent/profiles.js").AgentProfile;
|
|
178
178
|
runId: string;
|
package/dist/types.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type
|
|
2
|
-
export
|
|
1
|
+
import { type ThinkingLevel } from "../types.js";
|
|
2
|
+
export { THINKING_LEVELS } from "../types.js";
|
|
3
3
|
export declare function isThinkingLevel(value: string | undefined): value is ThinkingLevel;
|
|
4
4
|
export declare function clampThinkingLevel(requestedLevel: ThinkingLevel, supportedLevels: readonly ThinkingLevel[]): ThinkingLevel;
|
|
5
5
|
export declare function getNextThinkingLevel(currentLevel: ThinkingLevel, supportedLevels: readonly ThinkingLevel[]): ThinkingLevel;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import { THINKING_LEVELS } from "../types.js";
|
|
2
|
+
export { THINKING_LEVELS } from "../types.js";
|
|
2
3
|
export function isThinkingLevel(value) {
|
|
3
4
|
return !!value && THINKING_LEVELS.includes(value);
|
|
4
5
|
}
|
|
@@ -15,3 +15,12 @@ export declare function isThinkingOnlyModel(providerId?: string, modelId?: strin
|
|
|
15
15
|
*/
|
|
16
16
|
export declare function isThinkingToggleModel(providerId?: string, modelId?: string): boolean;
|
|
17
17
|
export declare function normalizeThinkingLevel(level: ThinkingLevel, supportedLevels: readonly ThinkingLevel[]): ThinkingLevel;
|
|
18
|
+
/**
|
|
19
|
+
* Normalizes effort inherited from a previous model or restored session.
|
|
20
|
+
*
|
|
21
|
+
* Unlike an explicit CLI/config choice, an inherited unsupported value does
|
|
22
|
+
* not express a direction the user just chose for the target model. Prefer the
|
|
23
|
+
* target model's declared default in that case, then fall back to the canonical
|
|
24
|
+
* downward clamp for legacy models without an explicit default.
|
|
25
|
+
*/
|
|
26
|
+
export declare function normalizeInheritedThinkingLevel(providerId: string, modelId: string, inheritedLevel: ThinkingLevel): ThinkingLevel;
|
|
@@ -39,3 +39,20 @@ export function isThinkingToggleModel(providerId = "", modelId = "") {
|
|
|
39
39
|
export function normalizeThinkingLevel(level, supportedLevels) {
|
|
40
40
|
return clampThinkingLevel(level, supportedLevels);
|
|
41
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Normalizes effort inherited from a previous model or restored session.
|
|
44
|
+
*
|
|
45
|
+
* Unlike an explicit CLI/config choice, an inherited unsupported value does
|
|
46
|
+
* not express a direction the user just chose for the target model. Prefer the
|
|
47
|
+
* target model's declared default in that case, then fall back to the canonical
|
|
48
|
+
* downward clamp for legacy models without an explicit default.
|
|
49
|
+
*/
|
|
50
|
+
export function normalizeInheritedThinkingLevel(providerId, modelId, inheritedLevel) {
|
|
51
|
+
const supportedLevels = getAvailableThinkingLevels(providerId, modelId);
|
|
52
|
+
if (supportedLevels.includes(inheritedLevel))
|
|
53
|
+
return inheritedLevel;
|
|
54
|
+
const modelDefault = getModelDefaultReasoningLevel(providerId, modelId);
|
|
55
|
+
if (modelDefault && supportedLevels.includes(modelDefault))
|
|
56
|
+
return modelDefault;
|
|
57
|
+
return clampThinkingLevel(inheritedLevel, supportedLevels);
|
|
58
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bubblebrain-ai/bubble",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.37",
|
|
4
4
|
"description": "A terminal coding agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"test:watch": "vitest"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
+
"@agentclientprotocol/sdk": "1.2.1",
|
|
27
28
|
"@ai-sdk/google": "^3.0.88",
|
|
28
29
|
"@ai-sdk/provider": "^3.0.13",
|
|
29
30
|
"@larksuiteoapi/node-sdk": "^1.65.0",
|
package/dist/tools/task.d.ts
DELETED
package/dist/tools/task.js
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
export function createTaskTool() {
|
|
2
|
-
return {
|
|
3
|
-
name: "task",
|
|
4
|
-
readOnly: true,
|
|
5
|
-
effect: "read",
|
|
6
|
-
description: `Delegate a bounded investigative subtask to a read-only sub-agent and return a concise summary.
|
|
7
|
-
|
|
8
|
-
Use this when:
|
|
9
|
-
- a search/investigation can be scoped as a sub-problem
|
|
10
|
-
- you want a focused summary before continuing the main task
|
|
11
|
-
- you need to inspect a specific hypothesis or area without polluting the main loop with exploratory churn
|
|
12
|
-
|
|
13
|
-
Do not use this for edits or shell-heavy workflows. The subtask agent runs in read-only plan mode.`,
|
|
14
|
-
parameters: {
|
|
15
|
-
type: "object",
|
|
16
|
-
properties: {
|
|
17
|
-
prompt: {
|
|
18
|
-
type: "string",
|
|
19
|
-
description: "The focused subtask prompt to investigate.",
|
|
20
|
-
},
|
|
21
|
-
description: {
|
|
22
|
-
type: "string",
|
|
23
|
-
description: "Short description of what this subtask is trying to verify.",
|
|
24
|
-
},
|
|
25
|
-
subtaskType: {
|
|
26
|
-
type: "string",
|
|
27
|
-
enum: ["search", "security_investigation", "evidence_correlation", "general_readonly"],
|
|
28
|
-
description: "The bounded subtask policy to apply.",
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
|
-
required: ["prompt"],
|
|
32
|
-
additionalProperties: false,
|
|
33
|
-
},
|
|
34
|
-
async execute(args, ctx) {
|
|
35
|
-
const prompt = typeof args.prompt === "string" ? args.prompt.trim() : "";
|
|
36
|
-
const description = typeof args.description === "string" ? args.description.trim() : "";
|
|
37
|
-
const subtaskType = typeof args.subtaskType === "string" ? args.subtaskType : undefined;
|
|
38
|
-
if (!prompt) {
|
|
39
|
-
return { content: "Error: task prompt is required", isError: true };
|
|
40
|
-
}
|
|
41
|
-
if (!ctx.agent?.runSubtask) {
|
|
42
|
-
return { content: "Error: task tool requires an agent runtime", isError: true };
|
|
43
|
-
}
|
|
44
|
-
const composed = description
|
|
45
|
-
? `${description}\n\n${prompt}\n\nInvestigate this sub-problem in read-only mode and return a concise evidence-based summary.`
|
|
46
|
-
: `${prompt}\n\nInvestigate this sub-problem in read-only mode and return a concise evidence-based summary.`;
|
|
47
|
-
const result = await ctx.agent.runSubtask(composed, ctx.cwd, { subtaskType, description });
|
|
48
|
-
return {
|
|
49
|
-
...result,
|
|
50
|
-
metadata: {
|
|
51
|
-
...result.metadata,
|
|
52
|
-
kind: "security",
|
|
53
|
-
reason: description || result.metadata?.reason,
|
|
54
|
-
},
|
|
55
|
-
};
|
|
56
|
-
},
|
|
57
|
-
};
|
|
58
|
-
}
|