@bubblebrain-ai/bubble 0.0.3 → 0.0.5
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 +8 -3
- package/dist/agent/budget-ledger.d.ts +20 -0
- package/dist/agent/budget-ledger.js +51 -0
- package/dist/agent/execution-governor.d.ts +14 -0
- package/dist/agent/execution-governor.js +172 -14
- package/dist/agent/profiles.d.ts +59 -0
- package/dist/agent/profiles.js +460 -0
- package/dist/agent/subagent-control.d.ts +52 -0
- package/dist/agent/subagent-control.js +38 -0
- package/dist/agent/task-classifier.d.ts +1 -1
- package/dist/agent/task-classifier.js +60 -0
- package/dist/agent/tool-intent.d.ts +14 -0
- package/dist/agent/tool-intent.js +125 -1
- package/dist/agent.d.ts +60 -1
- package/dist/agent.js +606 -53
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +45 -0
- package/dist/context/budget.js +1 -0
- package/dist/context/compact-llm.js +7 -6
- package/dist/context/compact.js +6 -6
- package/dist/context/projector.d.ts +3 -3
- package/dist/context/projector.js +32 -18
- package/dist/context/prune.d.ts +2 -2
- package/dist/context/prune.js +1 -4
- package/dist/main.d.ts +1 -1
- package/dist/main.js +13 -6
- package/dist/mcp/manager.js +1 -0
- package/dist/orchestrator/default-hooks.js +92 -1
- package/dist/orchestrator/hooks.d.ts +10 -0
- package/dist/prompt/compose.d.ts +1 -0
- package/dist/prompt/compose.js +20 -1
- package/dist/prompt/environment.js +21 -2
- package/dist/prompt/provider-prompts/deepseek.d.ts +1 -0
- package/dist/prompt/provider-prompts/deepseek.js +8 -0
- package/dist/prompt/provider-prompts/glm.d.ts +1 -0
- package/dist/prompt/provider-prompts/glm.js +7 -0
- package/dist/prompt/provider-prompts/kimi.d.ts +1 -0
- package/dist/prompt/provider-prompts/kimi.js +7 -0
- package/dist/prompt/reminders.d.ts +5 -1
- package/dist/prompt/reminders.js +51 -6
- package/dist/prompt/runtime.d.ts +1 -1
- package/dist/prompt/runtime.js +16 -3
- package/dist/prompt/task-reminders.d.ts +2 -0
- package/dist/prompt/task-reminders.js +56 -0
- package/dist/provider-artifacts.d.ts +7 -0
- package/dist/provider-artifacts.js +60 -0
- package/dist/provider.d.ts +6 -7
- package/dist/provider.js +77 -15
- package/dist/session-log.js +3 -1
- package/dist/slash-commands/commands.js +2 -3
- package/dist/system-prompt.d.ts +2 -0
- package/dist/tools/agent-lifecycle.d.ts +6 -0
- package/dist/tools/agent-lifecycle.js +355 -0
- package/dist/tools/bash.js +12 -7
- package/dist/tools/edit-apply.d.ts +25 -0
- package/dist/tools/edit-apply.js +197 -0
- package/dist/tools/edit.js +64 -52
- package/dist/tools/exit-plan-mode.js +3 -1
- package/dist/tools/file-mutation-queue.d.ts +1 -0
- package/dist/tools/file-mutation-queue.js +32 -0
- package/dist/tools/glob.js +1 -0
- package/dist/tools/grep.js +1 -0
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/index.js +3 -3
- package/dist/tools/lsp.js +2 -0
- package/dist/tools/memory.js +2 -0
- package/dist/tools/question.js +2 -0
- package/dist/tools/read.js +1 -0
- package/dist/tools/skill.js +1 -0
- package/dist/tools/task.js +1 -0
- package/dist/tools/todo.js +1 -0
- package/dist/tools/tool-search.js +2 -1
- package/dist/tools/web-fetch.js +1 -0
- package/dist/tools/web-search.js +1 -0
- package/dist/tools/write.js +10 -1
- package/dist/tui/display-history.d.ts +8 -1
- package/dist/tui/image-paste.d.ts +41 -0
- package/dist/tui/image-paste.js +217 -0
- package/dist/tui/markdown-inline.d.ts +22 -0
- package/dist/tui/markdown-inline.js +68 -0
- package/dist/tui/render-signature.d.ts +1 -0
- package/dist/tui/render-signature.js +7 -0
- package/dist/tui/run.js +814 -269
- package/dist/tui/tool-renderers/fallback.d.ts +2 -0
- package/dist/tui/tool-renderers/fallback.js +75 -0
- package/dist/tui/tool-renderers/registry.d.ts +3 -0
- package/dist/tui/tool-renderers/registry.js +11 -0
- package/dist/tui/tool-renderers/subagent.d.ts +2 -0
- package/dist/tui/tool-renderers/subagent.js +114 -0
- package/dist/tui/tool-renderers/types.d.ts +36 -0
- package/dist/tui/tool-renderers/types.js +1 -0
- package/dist/tui/tool-renderers/write-preview.d.ts +12 -0
- package/dist/tui/tool-renderers/write-preview.js +22 -0
- package/dist/tui/tool-renderers/write.d.ts +6 -0
- package/dist/tui/tool-renderers/write.js +82 -0
- package/dist/types.d.ts +90 -10
- package/package.json +3 -3
|
@@ -38,10 +38,20 @@ export function analyzeToolIntent(toolCall) {
|
|
|
38
38
|
search: buildSearchIntent(parsed.pattern, parsed.path, parsed.include),
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
|
+
const parsedRead = parseReadBashCommand(stringArg(toolCall.parsedArgs.command));
|
|
42
|
+
if (parsedRead) {
|
|
43
|
+
return {
|
|
44
|
+
family: "read",
|
|
45
|
+
read: buildReadIntent(parsedRead.path, parsedRead.offset, parsedRead.limit),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
41
48
|
return { family: "shell" };
|
|
42
49
|
}
|
|
43
50
|
case "read":
|
|
44
|
-
return {
|
|
51
|
+
return {
|
|
52
|
+
family: "read",
|
|
53
|
+
read: buildReadIntent(stringArg(toolCall.parsedArgs.path ?? toolCall.parsedArgs.file), numberOrStringArg(toolCall.parsedArgs.offset), numberOrStringArg(toolCall.parsedArgs.limit)),
|
|
54
|
+
};
|
|
45
55
|
case "write":
|
|
46
56
|
return { family: "write" };
|
|
47
57
|
case "edit":
|
|
@@ -99,6 +109,36 @@ export function parseSearchBashCommand(command) {
|
|
|
99
109
|
include,
|
|
100
110
|
};
|
|
101
111
|
}
|
|
112
|
+
export function parseReadBashCommand(command) {
|
|
113
|
+
const trimmed = command.trim();
|
|
114
|
+
if (!trimmed) {
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
if (/[|;&><`]/.test(trimmed)) {
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
const tokens = shellSplit(trimmed);
|
|
121
|
+
if (tokens.length === 0) {
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
const binary = tokens[0];
|
|
125
|
+
if (binary === "cat" || binary === "nl") {
|
|
126
|
+
const path = lastPositional(tokens.slice(1));
|
|
127
|
+
return path ? { path } : undefined;
|
|
128
|
+
}
|
|
129
|
+
if (binary === "head") {
|
|
130
|
+
const { path, lineCount } = parseHeadTailArgs(tokens.slice(1));
|
|
131
|
+
return path ? { path, offset: 1, limit: lineCount ?? "head" } : undefined;
|
|
132
|
+
}
|
|
133
|
+
if (binary === "tail") {
|
|
134
|
+
const { path, lineCount } = parseHeadTailArgs(tokens.slice(1));
|
|
135
|
+
return path ? { path, offset: `tail:${lineCount ?? "default"}`, limit: lineCount ?? "tail" } : undefined;
|
|
136
|
+
}
|
|
137
|
+
if (binary === "sed") {
|
|
138
|
+
return parseSedReadCommand(tokens.slice(1));
|
|
139
|
+
}
|
|
140
|
+
return undefined;
|
|
141
|
+
}
|
|
102
142
|
function buildSearchIntent(pattern, path, include) {
|
|
103
143
|
const normalizedPath = normalizePath(path ?? ".");
|
|
104
144
|
const rawNormalizedPattern = normalizeRawPattern(pattern);
|
|
@@ -114,6 +154,18 @@ function buildSearchIntent(pattern, path, include) {
|
|
|
114
154
|
familyKey,
|
|
115
155
|
};
|
|
116
156
|
}
|
|
157
|
+
function buildReadIntent(path, offset, limit) {
|
|
158
|
+
const normalizedPath = normalizePath(path || ".");
|
|
159
|
+
const normalizedOffset = offset ?? 1;
|
|
160
|
+
const normalizedLimit = limit ?? "default";
|
|
161
|
+
return {
|
|
162
|
+
path,
|
|
163
|
+
offset,
|
|
164
|
+
limit,
|
|
165
|
+
signature: `${normalizedPath}::${normalizedOffset}::${normalizedLimit}`,
|
|
166
|
+
familyKey: normalizedPath,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
117
169
|
function canonicalizeSearchTokens(pattern) {
|
|
118
170
|
const normalized = normalizeRawPattern(pattern);
|
|
119
171
|
const tokens = normalized.split(/[^a-z0-9_]+/).filter(Boolean);
|
|
@@ -132,6 +184,78 @@ function normalizePath(pathValue) {
|
|
|
132
184
|
function stringArg(value) {
|
|
133
185
|
return typeof value === "string" ? value : "";
|
|
134
186
|
}
|
|
187
|
+
function numberOrStringArg(value) {
|
|
188
|
+
return typeof value === "number" || typeof value === "string" ? value : undefined;
|
|
189
|
+
}
|
|
190
|
+
function lastPositional(tokens) {
|
|
191
|
+
for (let index = tokens.length - 1; index >= 0; index--) {
|
|
192
|
+
const token = tokens[index];
|
|
193
|
+
if (!token.startsWith("-")) {
|
|
194
|
+
return token;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return undefined;
|
|
198
|
+
}
|
|
199
|
+
function parseHeadTailArgs(tokens) {
|
|
200
|
+
let lineCount;
|
|
201
|
+
const positional = [];
|
|
202
|
+
for (let index = 0; index < tokens.length; index++) {
|
|
203
|
+
const token = tokens[index];
|
|
204
|
+
if (token === "-n" || token === "--lines") {
|
|
205
|
+
lineCount = parseLineCount(tokens[index + 1]);
|
|
206
|
+
index += 1;
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
if (token.startsWith("-n") && token.length > 2) {
|
|
210
|
+
lineCount = parseLineCount(token.slice(2));
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
if (token.startsWith("--lines=")) {
|
|
214
|
+
lineCount = parseLineCount(token.slice("--lines=".length));
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
if (token.startsWith("-")) {
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
positional.push(token);
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
path: positional[positional.length - 1],
|
|
224
|
+
lineCount,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
function parseSedReadCommand(tokens) {
|
|
228
|
+
const positional = [];
|
|
229
|
+
for (const token of tokens) {
|
|
230
|
+
if (token === "-n" || token.startsWith("-")) {
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
positional.push(token);
|
|
234
|
+
}
|
|
235
|
+
if (positional.length < 2) {
|
|
236
|
+
return undefined;
|
|
237
|
+
}
|
|
238
|
+
const expression = positional[0];
|
|
239
|
+
const path = positional[positional.length - 1];
|
|
240
|
+
const range = expression.match(/^(\d+)(?:,(\d+))?p$/);
|
|
241
|
+
if (!range) {
|
|
242
|
+
return { path, offset: expression };
|
|
243
|
+
}
|
|
244
|
+
const start = Number(range[1]);
|
|
245
|
+
const end = range[2] ? Number(range[2]) : start;
|
|
246
|
+
return {
|
|
247
|
+
path,
|
|
248
|
+
offset: start,
|
|
249
|
+
limit: Math.max(1, end - start + 1),
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
function parseLineCount(value) {
|
|
253
|
+
if (!value) {
|
|
254
|
+
return undefined;
|
|
255
|
+
}
|
|
256
|
+
const parsed = Number(value.replace(/^\+/, ""));
|
|
257
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;
|
|
258
|
+
}
|
|
135
259
|
function shellSplit(command) {
|
|
136
260
|
const tokens = [];
|
|
137
261
|
let current = "";
|
package/dist/agent.d.ts
CHANGED
|
@@ -2,8 +2,12 @@
|
|
|
2
2
|
* Agent - The core decision loop.
|
|
3
3
|
* It maintains message state, calls the LLM, executes tools, and auto-continues.
|
|
4
4
|
*/
|
|
5
|
-
import type { AgentEvent, ContentPart, PermissionMode, Message, Provider, ThinkingLevel, Todo, ToolResult, ToolRegistryEntry } from "./types.js";
|
|
5
|
+
import type { AgentEvent, ContentPart, PermissionMode, Message, Provider, ThinkingLevel, Todo, ToolResult, ToolRegistryEntry, ToolUpdate } from "./types.js";
|
|
6
6
|
import { type TurnHooks } from "./orchestrator/hooks.js";
|
|
7
|
+
import { BudgetLedger } from "./agent/budget-ledger.js";
|
|
8
|
+
import { type AgentProfile, type SubagentRunResult } from "./agent/profiles.js";
|
|
9
|
+
import { type SubagentThreadSnapshot } from "./agent/subagent-control.js";
|
|
10
|
+
import type { SkillSummary } from "./skills/types.js";
|
|
7
11
|
export declare class AgentAbortError extends Error {
|
|
8
12
|
constructor(message?: string);
|
|
9
13
|
}
|
|
@@ -28,6 +32,13 @@ export interface AgentOptions {
|
|
|
28
32
|
onTodosUpdate?: (todos: Todo[]) => void;
|
|
29
33
|
onModeUpdate?: (mode: PermissionMode) => void;
|
|
30
34
|
hooks?: TurnHooks[];
|
|
35
|
+
budgetLedger?: BudgetLedger;
|
|
36
|
+
budgetSource?: {
|
|
37
|
+
runId: string;
|
|
38
|
+
subAgentId?: string;
|
|
39
|
+
};
|
|
40
|
+
skills?: SkillSummary[];
|
|
41
|
+
memoryPrompt?: string;
|
|
31
42
|
}
|
|
32
43
|
export declare class Agent {
|
|
33
44
|
messages: Message[];
|
|
@@ -50,6 +61,12 @@ export declare class Agent {
|
|
|
50
61
|
private hookDefinitions;
|
|
51
62
|
private maxTurns?;
|
|
52
63
|
private taskBudget?;
|
|
64
|
+
private budgetLedger?;
|
|
65
|
+
private budgetSource;
|
|
66
|
+
private skillSummaries;
|
|
67
|
+
private memoryPrompt?;
|
|
68
|
+
private subagentThreads;
|
|
69
|
+
private pendingSubagentUpdates;
|
|
53
70
|
private lastInputTokens;
|
|
54
71
|
private lastAnchorMessageCount;
|
|
55
72
|
constructor(options: AgentOptions);
|
|
@@ -96,6 +113,48 @@ export declare class Agent {
|
|
|
96
113
|
subtaskType?: string;
|
|
97
114
|
description?: string;
|
|
98
115
|
}): Promise<ToolResult>;
|
|
116
|
+
runSubAgent(input: string | ContentPart[], cwd: string, options: {
|
|
117
|
+
profile: AgentProfile;
|
|
118
|
+
runId: string;
|
|
119
|
+
subAgentId: string;
|
|
120
|
+
parentToolCallId: string;
|
|
121
|
+
approval?: "fail" | "disabled";
|
|
122
|
+
emitUpdate?: (update: ToolUpdate) => void;
|
|
123
|
+
description?: string;
|
|
124
|
+
abortSignal?: AbortSignal;
|
|
125
|
+
nickname?: string;
|
|
126
|
+
forkContext?: boolean;
|
|
127
|
+
}): Promise<SubagentRunResult>;
|
|
128
|
+
spawnSubAgent(input: string | ContentPart[], cwd: string, options: {
|
|
129
|
+
profile: AgentProfile;
|
|
130
|
+
parentToolCallId: string;
|
|
131
|
+
approval?: "fail" | "disabled";
|
|
132
|
+
description?: string;
|
|
133
|
+
abortSignal?: AbortSignal;
|
|
134
|
+
forkContext?: boolean;
|
|
135
|
+
}): Promise<SubagentThreadSnapshot>;
|
|
136
|
+
waitSubAgents(options?: {
|
|
137
|
+
agentIds?: string[];
|
|
138
|
+
timeoutMs?: number;
|
|
139
|
+
}): Promise<SubagentThreadSnapshot[]>;
|
|
140
|
+
sendSubAgentInput(agentId: string, input: string | ContentPart[], cwd: string, options?: {
|
|
141
|
+
interrupt?: boolean;
|
|
142
|
+
parentToolCallId?: string;
|
|
143
|
+
abortSignal?: AbortSignal;
|
|
144
|
+
}): Promise<SubagentThreadSnapshot>;
|
|
145
|
+
closeSubAgent(agentId: string): Promise<SubagentThreadSnapshot>;
|
|
146
|
+
listSubAgents(): SubagentThreadSnapshot[];
|
|
147
|
+
private createSubagentThreadRecord;
|
|
148
|
+
private runSubagentThread;
|
|
149
|
+
private runSubagentFinalSummaryTurn;
|
|
150
|
+
private createSubAgentInstance;
|
|
151
|
+
private forkMessagesForSubagent;
|
|
152
|
+
private buildSubagentUpdate;
|
|
153
|
+
private queueSubagentUpdate;
|
|
154
|
+
private drainSubagentToolUpdates;
|
|
155
|
+
private activeSubagentNicknames;
|
|
156
|
+
private resolveSubagentTargets;
|
|
157
|
+
private notifySubagentWaiters;
|
|
99
158
|
private maybeCompactResidentHistory;
|
|
100
159
|
private appendMessage;
|
|
101
160
|
private executeTool;
|