@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
package/dist/tools/edit.js
CHANGED
|
@@ -5,14 +5,22 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { constants } from "node:fs";
|
|
7
7
|
import { access, readFile, writeFile } from "node:fs/promises";
|
|
8
|
-
import { resolve } from "node:path";
|
|
8
|
+
import { isAbsolute, relative, resolve } from "node:path";
|
|
9
9
|
import { createTwoFilesPatch } from "diff";
|
|
10
10
|
import { gateToolAction } from "../approval/tool-helper.js";
|
|
11
11
|
import { formatDiagnosticBlocks } from "../lsp/index.js";
|
|
12
|
+
import { applyEditsToContent, EditApplyError, formatEditMatchNotes } from "./edit-apply.js";
|
|
13
|
+
import { withFileMutationQueue } from "./file-mutation-queue.js";
|
|
14
|
+
function isWithinWorkspace(cwd, filePath) {
|
|
15
|
+
const rel = relative(resolve(cwd), filePath);
|
|
16
|
+
return rel === "" || (!rel.startsWith("..") && !isAbsolute(rel));
|
|
17
|
+
}
|
|
12
18
|
export function createEditTool(cwd, approval, lsp) {
|
|
13
19
|
return {
|
|
14
20
|
name: "edit",
|
|
15
|
-
|
|
21
|
+
effect: "write_direct",
|
|
22
|
+
requiresApproval: true,
|
|
23
|
+
description: "Apply targeted string replacements to a file. Prefer exact oldText. The tool can tolerate line ending, trailing whitespace, Unicode punctuation/space, and blank-line differences only when the target is unique.",
|
|
16
24
|
parameters: {
|
|
17
25
|
type: "object",
|
|
18
26
|
properties: {
|
|
@@ -34,62 +42,66 @@ export function createEditTool(cwd, approval, lsp) {
|
|
|
34
42
|
},
|
|
35
43
|
async execute(args) {
|
|
36
44
|
const filePath = resolve(cwd, args.path);
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
if (!isWithinWorkspace(cwd, filePath)) {
|
|
46
|
+
return {
|
|
47
|
+
content: `Error: Edit path is outside the workspace: ${filePath}`,
|
|
48
|
+
isError: true,
|
|
49
|
+
status: "blocked",
|
|
50
|
+
metadata: {
|
|
51
|
+
kind: "security",
|
|
52
|
+
path: filePath,
|
|
53
|
+
reason: "Edit path is outside the workspace.",
|
|
54
|
+
},
|
|
55
|
+
};
|
|
48
56
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if (count === 0) {
|
|
53
|
-
return {
|
|
54
|
-
content: `Error: oldText not found in file: "${edit.oldText.slice(0, 50)}..."`,
|
|
55
|
-
isError: true,
|
|
56
|
-
};
|
|
57
|
+
return withFileMutationQueue(filePath, async () => {
|
|
58
|
+
try {
|
|
59
|
+
await access(filePath, constants.R_OK | constants.W_OK);
|
|
57
60
|
}
|
|
58
|
-
|
|
59
|
-
return {
|
|
60
|
-
content: `Error: oldText appears ${count} times in file. Must be unique: "${edit.oldText.slice(0, 50)}..."`,
|
|
61
|
-
isError: true,
|
|
62
|
-
};
|
|
61
|
+
catch {
|
|
62
|
+
return { content: `Error: Cannot read/write file: ${filePath}`, isError: true };
|
|
63
63
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
for (const edit of edits) {
|
|
67
|
-
content = content.replace(edit.oldText, edit.newText);
|
|
68
|
-
}
|
|
69
|
-
const diff = createTwoFilesPatch(filePath, filePath, original, content, "original", "modified", { context: 3 });
|
|
70
|
-
// Gate on the approval controller BEFORE persisting the change.
|
|
71
|
-
const gate = await gateToolAction(approval, {
|
|
72
|
-
type: "edit",
|
|
73
|
-
path: filePath,
|
|
74
|
-
diff,
|
|
75
|
-
fileExists: true,
|
|
76
|
-
});
|
|
77
|
-
if (!gate.approved)
|
|
78
|
-
return gate.result;
|
|
79
|
-
await writeFile(filePath, content, "utf-8");
|
|
80
|
-
let output = `Edited ${filePath}\n\nDiff:\n${diff}`;
|
|
81
|
-
if (lsp) {
|
|
64
|
+
const original = await readFile(filePath, "utf-8");
|
|
65
|
+
let applied;
|
|
82
66
|
try {
|
|
83
|
-
|
|
84
|
-
output += formatDiagnosticBlocks(cwd, filePath, lsp.diagnostics());
|
|
67
|
+
applied = applyEditsToContent(original, args.edits);
|
|
85
68
|
}
|
|
86
|
-
catch {
|
|
87
|
-
|
|
69
|
+
catch (err) {
|
|
70
|
+
if (err instanceof EditApplyError) {
|
|
71
|
+
return { content: err.message, isError: true, status: err.status };
|
|
72
|
+
}
|
|
73
|
+
throw err;
|
|
88
74
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
75
|
+
const diff = createTwoFilesPatch(filePath, filePath, original, applied.content, "original", "modified", { context: 3 });
|
|
76
|
+
// Gate on the approval controller BEFORE persisting the change.
|
|
77
|
+
const gate = await gateToolAction(approval, {
|
|
78
|
+
type: "edit",
|
|
79
|
+
path: filePath,
|
|
80
|
+
diff,
|
|
81
|
+
fileExists: true,
|
|
82
|
+
});
|
|
83
|
+
if (!gate.approved)
|
|
84
|
+
return gate.result;
|
|
85
|
+
await writeFile(filePath, applied.content, "utf-8");
|
|
86
|
+
let output = `Edited ${filePath}${formatEditMatchNotes(applied.matches)}\n\nDiff:\n${diff}`;
|
|
87
|
+
if (lsp) {
|
|
88
|
+
try {
|
|
89
|
+
await lsp.touchFile(filePath, "document");
|
|
90
|
+
output += formatDiagnosticBlocks(cwd, filePath, lsp.diagnostics());
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
// LSP diagnostics should not turn a successful edit into a failed tool call.
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
content: output,
|
|
98
|
+
status: "success",
|
|
99
|
+
metadata: {
|
|
100
|
+
kind: "edit",
|
|
101
|
+
path: filePath,
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
});
|
|
93
105
|
},
|
|
94
106
|
};
|
|
95
107
|
}
|
|
@@ -9,7 +9,9 @@ export function createExitPlanModeTool(controller) {
|
|
|
9
9
|
return {
|
|
10
10
|
name: "exit_plan_mode",
|
|
11
11
|
readOnly: true,
|
|
12
|
-
|
|
12
|
+
effect: "read",
|
|
13
|
+
requiresApproval: true,
|
|
14
|
+
description: "ONLY call this tool when the harness has told you via a runtime reminder that plan mode is ACTIVE. " +
|
|
13
15
|
"Do NOT call it during ordinary work — in default mode you should just use the regular tools directly. " +
|
|
14
16
|
"In plan mode: after investigating, call this with a concrete step-by-step plan so the user can approve, edit, or reject. " +
|
|
15
17
|
"Approval automatically switches the agent out of plan mode.",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function withFileMutationQueue<T>(filePath: string, fn: () => Promise<T>): Promise<T>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { realpathSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
const queues = new Map();
|
|
4
|
+
function queueKey(filePath) {
|
|
5
|
+
const resolved = resolve(filePath);
|
|
6
|
+
try {
|
|
7
|
+
return realpathSync.native(resolved);
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return resolved;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export async function withFileMutationQueue(filePath, fn) {
|
|
14
|
+
const key = queueKey(filePath);
|
|
15
|
+
const current = queues.get(key) ?? Promise.resolve();
|
|
16
|
+
let release;
|
|
17
|
+
const next = new Promise((resolveNext) => {
|
|
18
|
+
release = resolveNext;
|
|
19
|
+
});
|
|
20
|
+
const chained = current.then(() => next);
|
|
21
|
+
queues.set(key, chained);
|
|
22
|
+
await current;
|
|
23
|
+
try {
|
|
24
|
+
return await fn();
|
|
25
|
+
}
|
|
26
|
+
finally {
|
|
27
|
+
release();
|
|
28
|
+
if (queues.get(key) === chained) {
|
|
29
|
+
queues.delete(key);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
package/dist/tools/glob.js
CHANGED
|
@@ -20,6 +20,7 @@ export function createGlobTool(cwd) {
|
|
|
20
20
|
return {
|
|
21
21
|
name: "glob",
|
|
22
22
|
readOnly: true,
|
|
23
|
+
effect: "read",
|
|
23
24
|
description: `Find files by glob pattern without using the shell. Use this for project structure discovery and filename searches. Returns up to ${MAX_RESULTS} files sorted by recent modification time.`,
|
|
24
25
|
parameters: {
|
|
25
26
|
type: "object",
|
package/dist/tools/grep.js
CHANGED
|
@@ -10,6 +10,7 @@ export function createGrepTool(cwd) {
|
|
|
10
10
|
return {
|
|
11
11
|
name: "grep",
|
|
12
12
|
readOnly: true,
|
|
13
|
+
effect: "read",
|
|
13
14
|
description: `Search file contents using regex (via ripgrep). Use this instead of running grep, rg, or ripgrep through bash. Returns up to ${MAX_MATCHES} matches.`,
|
|
14
15
|
parameters: {
|
|
15
16
|
type: "object",
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export { createLspTool } from "./lsp.js";
|
|
|
11
11
|
export { createWebFetchTool } from "./web-fetch.js";
|
|
12
12
|
export { createWebSearchTool } from "./web-search.js";
|
|
13
13
|
export { createSkillTool } from "./skill.js";
|
|
14
|
-
export {
|
|
14
|
+
export { createAgentLifecycleTools, createCloseAgentTool, createSendInputTool, createSpawnAgentTool, createWaitAgentTool } from "./agent-lifecycle.js";
|
|
15
15
|
export { createTodoTool, type TodoStore } from "./todo.js";
|
|
16
16
|
export { createExitPlanModeTool, type PlanController } from "./exit-plan-mode.js";
|
|
17
17
|
export { createToolSearchTool, type ToolSearchController } from "./tool-search.js";
|
package/dist/tools/index.js
CHANGED
|
@@ -11,7 +11,7 @@ export { createLspTool } from "./lsp.js";
|
|
|
11
11
|
export { createWebFetchTool } from "./web-fetch.js";
|
|
12
12
|
export { createWebSearchTool } from "./web-search.js";
|
|
13
13
|
export { createSkillTool } from "./skill.js";
|
|
14
|
-
export {
|
|
14
|
+
export { createAgentLifecycleTools, createCloseAgentTool, createSendInputTool, createSpawnAgentTool, createWaitAgentTool } from "./agent-lifecycle.js";
|
|
15
15
|
export { createTodoTool } from "./todo.js";
|
|
16
16
|
export { createExitPlanModeTool } from "./exit-plan-mode.js";
|
|
17
17
|
export { createToolSearchTool } from "./tool-search.js";
|
|
@@ -26,7 +26,7 @@ import { getLspService } from "../lsp/index.js";
|
|
|
26
26
|
import { createLspTool } from "./lsp.js";
|
|
27
27
|
import { createReadTool } from "./read.js";
|
|
28
28
|
import { createSkillTool } from "./skill.js";
|
|
29
|
-
import {
|
|
29
|
+
import { createAgentLifecycleTools } from "./agent-lifecycle.js";
|
|
30
30
|
import { createTodoTool } from "./todo.js";
|
|
31
31
|
import { createToolSearchTool } from "./tool-search.js";
|
|
32
32
|
import { createWebFetchTool } from "./web-fetch.js";
|
|
@@ -49,7 +49,7 @@ export function createAllTools(cwd, skillRegistry, options = {}) {
|
|
|
49
49
|
createWebFetchTool(approval),
|
|
50
50
|
createMemorySearchTool(cwd),
|
|
51
51
|
createMemoryReadSummaryTool(cwd),
|
|
52
|
-
|
|
52
|
+
...createAgentLifecycleTools(),
|
|
53
53
|
...(options.questionController ? [createQuestionTool(options.questionController)] : []),
|
|
54
54
|
...(skillRegistry ? [createSkillTool(skillRegistry)] : []),
|
|
55
55
|
...(options.todoStore ? [createTodoTool(options.todoStore)] : []),
|
package/dist/tools/lsp.js
CHANGED
|
@@ -18,6 +18,8 @@ export function createLspTool(cwd, lsp = getLspService(cwd), approval) {
|
|
|
18
18
|
return {
|
|
19
19
|
name: "lsp",
|
|
20
20
|
readOnly: true,
|
|
21
|
+
effect: "read",
|
|
22
|
+
requiresApproval: true,
|
|
21
23
|
description: "Use the language server for code navigation. Supports goToDefinition, findReferences, hover, documentSymbol, workspaceSymbol, goToImplementation, prepareCallHierarchy, incomingCalls, and outgoingCalls.",
|
|
22
24
|
parameters: {
|
|
23
25
|
type: "object",
|
package/dist/tools/memory.js
CHANGED
|
@@ -5,6 +5,7 @@ export function createMemorySearchTool(cwd) {
|
|
|
5
5
|
name: "memory_search",
|
|
6
6
|
description: "Search persistent Bubble memory for prior project facts, user preferences, workflows, decisions, and gotchas.",
|
|
7
7
|
readOnly: true,
|
|
8
|
+
effect: "read",
|
|
8
9
|
parameters: {
|
|
9
10
|
type: "object",
|
|
10
11
|
properties: {
|
|
@@ -56,6 +57,7 @@ export function createMemoryReadSummaryTool(cwd) {
|
|
|
56
57
|
name: "memory_read_summary",
|
|
57
58
|
description: "Read the concise persistent memory summary for the current project, global scope, or both.",
|
|
58
59
|
readOnly: true,
|
|
60
|
+
effect: "read",
|
|
59
61
|
parameters: {
|
|
60
62
|
type: "object",
|
|
61
63
|
properties: {
|
package/dist/tools/question.js
CHANGED
package/dist/tools/read.js
CHANGED
|
@@ -11,6 +11,7 @@ export function createReadTool(cwd, approval, lsp) {
|
|
|
11
11
|
return {
|
|
12
12
|
name: "read",
|
|
13
13
|
readOnly: true,
|
|
14
|
+
effect: "read",
|
|
14
15
|
description: `Read the contents of a file. Output is truncated to ${MAX_LINES} lines or ${MAX_BYTES / 1024}KB (whichever is hit first). Use offset/limit for large files.`,
|
|
15
16
|
parameters: {
|
|
16
17
|
type: "object",
|
package/dist/tools/skill.js
CHANGED
|
@@ -21,6 +21,7 @@ export function createSkillTool(registry) {
|
|
|
21
21
|
return {
|
|
22
22
|
name: "skill",
|
|
23
23
|
readOnly: true,
|
|
24
|
+
effect: "read",
|
|
24
25
|
description: "Load a named skill on demand. Use this when a task clearly matches one of the available skills.",
|
|
25
26
|
parameters: {
|
|
26
27
|
type: "object",
|
package/dist/tools/task.js
CHANGED
package/dist/tools/todo.js
CHANGED
|
@@ -8,6 +8,7 @@ export function createTodoTool(store) {
|
|
|
8
8
|
return {
|
|
9
9
|
name: "todo_write",
|
|
10
10
|
readOnly: true,
|
|
11
|
+
effect: "read",
|
|
11
12
|
description: `Create or update the task list for the current work. Send the COMPLETE list each call; this overwrites the prior list entirely.
|
|
12
13
|
|
|
13
14
|
## When to use
|
|
@@ -17,8 +17,9 @@ export function createToolSearchTool(controller) {
|
|
|
17
17
|
return {
|
|
18
18
|
name: "tool_search",
|
|
19
19
|
readOnly: true,
|
|
20
|
+
effect: "read",
|
|
20
21
|
description: 'Fetches full schema definitions for deferred tools so they can be called. ' +
|
|
21
|
-
'Deferred tools appear by name in
|
|
22
|
+
'Deferred tools appear by name in hidden runtime reminders; their parameters are unknown ' +
|
|
22
23
|
'until loaded. Use this tool with query "select:<name>[,<name>...]" to load specific tools, ' +
|
|
23
24
|
'or with free-text keywords to search for relevant tools.',
|
|
24
25
|
parameters: {
|
package/dist/tools/web-fetch.js
CHANGED
package/dist/tools/web-search.js
CHANGED
package/dist/tools/write.js
CHANGED
|
@@ -10,6 +10,8 @@ import { formatDiagnosticBlocks } from "../lsp/index.js";
|
|
|
10
10
|
export function createWriteTool(cwd, options = {}, approval, lsp) {
|
|
11
11
|
return {
|
|
12
12
|
name: "write",
|
|
13
|
+
effect: "write_direct",
|
|
14
|
+
requiresApproval: true,
|
|
13
15
|
description: `Write a file to disk. Creates parent directories if needed.${options.refuseOverwrite ? " Will not overwrite existing files." : ""}`,
|
|
14
16
|
parameters: {
|
|
15
17
|
type: "object",
|
|
@@ -67,7 +69,14 @@ export function createWriteTool(cwd, options = {}, approval, lsp) {
|
|
|
67
69
|
// LSP diagnostics should not turn a successful write into a failed tool call.
|
|
68
70
|
}
|
|
69
71
|
}
|
|
70
|
-
return {
|
|
72
|
+
return {
|
|
73
|
+
content,
|
|
74
|
+
status: "success",
|
|
75
|
+
metadata: {
|
|
76
|
+
kind: "write",
|
|
77
|
+
path: filePath,
|
|
78
|
+
},
|
|
79
|
+
};
|
|
71
80
|
}
|
|
72
81
|
catch (err) {
|
|
73
82
|
return { content: `Error: ${err.message}`, isError: true };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ToolResultMetadata } from "../types.js";
|
|
1
|
+
import type { ToolResultMetadata, TokenUsage } from "../types.js";
|
|
2
2
|
export interface CompactionMeta {
|
|
3
3
|
turns: number;
|
|
4
4
|
messages: number;
|
|
@@ -20,15 +20,22 @@ export interface DisplayMessage {
|
|
|
20
20
|
syntheticKind?: "ui_compact_card";
|
|
21
21
|
hiddenCount?: number;
|
|
22
22
|
compactionMeta?: CompactionMeta;
|
|
23
|
+
turnStartedAt?: number;
|
|
24
|
+
turnCompletedAt?: number;
|
|
25
|
+
turnUsage?: TokenUsage;
|
|
23
26
|
}
|
|
24
27
|
export interface DisplayToolCall {
|
|
25
28
|
id: string;
|
|
26
29
|
name: string;
|
|
27
30
|
args: Record<string, any>;
|
|
31
|
+
rawArguments?: string;
|
|
32
|
+
streamingArgs?: boolean;
|
|
28
33
|
status?: "pending" | "running" | "completed" | "error";
|
|
29
34
|
result?: string;
|
|
30
35
|
isError?: boolean;
|
|
31
36
|
metadata?: ToolResultMetadata;
|
|
37
|
+
startedAt?: number;
|
|
38
|
+
completedAt?: number;
|
|
32
39
|
}
|
|
33
40
|
export declare function compactDisplayMessages(messages: DisplayMessage[]): DisplayMessage[];
|
|
34
41
|
export declare function truncateText(value: string, maxChars: number): string;
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* TemporaryItems path and the clipboard — the path often gets cleaned up before
|
|
8
8
|
* we can read it, so we fall back to the clipboard.
|
|
9
9
|
*/
|
|
10
|
+
import type { ContentPart } from "../types.js";
|
|
10
11
|
export interface ImageAttachment {
|
|
11
12
|
base64: string;
|
|
12
13
|
mediaType: string;
|
|
@@ -17,7 +18,41 @@ export interface ImageAttachment {
|
|
|
17
18
|
filename?: string;
|
|
18
19
|
sourcePath?: string;
|
|
19
20
|
}
|
|
21
|
+
export interface ImagePathToken {
|
|
22
|
+
rawPath: string;
|
|
23
|
+
start: number;
|
|
24
|
+
end: number;
|
|
25
|
+
}
|
|
26
|
+
export interface ImageInputResolution {
|
|
27
|
+
actualInput: string | ContentPart[];
|
|
28
|
+
displayInput: string;
|
|
29
|
+
errors: string[];
|
|
30
|
+
attachments: ImageAttachment[];
|
|
31
|
+
imagePathCount: number;
|
|
32
|
+
}
|
|
33
|
+
export interface LabeledImageAttachment extends ImageAttachment {
|
|
34
|
+
label: string;
|
|
35
|
+
}
|
|
36
|
+
export interface ComposerImageResolution {
|
|
37
|
+
text: string;
|
|
38
|
+
attachments: LabeledImageAttachment[];
|
|
39
|
+
errors: string[];
|
|
40
|
+
imagePathCount: number;
|
|
41
|
+
nextLabelIndex: number;
|
|
42
|
+
}
|
|
20
43
|
export declare function isImageFilePath(raw: string): boolean;
|
|
44
|
+
export declare function extractImagePathTokens(input: string): ImagePathToken[];
|
|
45
|
+
export declare function removeImagePathTokens(input: string, tokens: ImagePathToken[]): string;
|
|
46
|
+
export declare function imageAttachmentLabel(att: ImageAttachment, index: number): string;
|
|
47
|
+
export declare function imageAttachmentReference(att: ImageAttachment, index: number): string;
|
|
48
|
+
export declare function imageAttachmentLabelPattern(): RegExp;
|
|
49
|
+
export declare function buildImageContentParts(promptText: string, attachments: ImageAttachment[]): ContentPart[];
|
|
50
|
+
export declare function formatImageDisplayInput(promptText: string, attachments: ImageAttachment[], labelStart?: number): string;
|
|
51
|
+
export declare function buildImageContentPartsFromLabels(input: string, attachmentsByLabel: Map<string, ImageAttachment>): {
|
|
52
|
+
actualInput?: ContentPart[];
|
|
53
|
+
displayInput: string;
|
|
54
|
+
usedLabels: string[];
|
|
55
|
+
};
|
|
21
56
|
/**
|
|
22
57
|
* Split a pasted blob into candidate path tokens.
|
|
23
58
|
*
|
|
@@ -52,3 +87,9 @@ export declare function ingestClipboardImage(): Promise<{
|
|
|
52
87
|
attachment?: ImageAttachment;
|
|
53
88
|
error?: string;
|
|
54
89
|
}>;
|
|
90
|
+
export declare function resolveImageInput(input: string, options?: {
|
|
91
|
+
labelStart?: number;
|
|
92
|
+
}): Promise<ImageInputResolution>;
|
|
93
|
+
export declare function resolveComposerImagePaths(input: string, options?: {
|
|
94
|
+
labelStart?: number;
|
|
95
|
+
}): Promise<ComposerImageResolution>;
|