@bubblebrain-ai/bubble 0.0.15 → 0.0.17
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 +24 -0
- package/dist/agent/discovery-barrier.d.ts +21 -0
- package/dist/agent/discovery-barrier.js +173 -0
- package/dist/agent/internal-reminder-sanitizer.d.ts +9 -0
- package/dist/agent/internal-reminder-sanitizer.js +198 -0
- package/dist/agent/task-classifier.js +23 -5
- package/dist/agent.js +215 -30
- package/dist/context/budget.js +15 -0
- package/dist/context/projector.js +4 -3
- package/dist/debug-trace.js +14 -0
- package/dist/feishu/serve.js +1 -0
- package/dist/main.js +2 -0
- package/dist/model-catalog.d.ts +3 -0
- package/dist/model-catalog.js +44 -0
- package/dist/model-config.d.ts +3 -0
- package/dist/model-config.js +3 -0
- package/dist/model-pricing.d.ts +3 -2
- package/dist/model-pricing.js +8 -0
- package/dist/network/chatgpt-transport.d.ts +16 -0
- package/dist/network/chatgpt-transport.js +240 -0
- package/dist/oauth/openai-codex.d.ts +7 -2
- package/dist/oauth/openai-codex.js +7 -4
- package/dist/orchestrator/default-hooks.js +13 -2
- package/dist/orchestrator/hooks.d.ts +2 -0
- package/dist/prompt/compose.js +1 -1
- package/dist/prompt/reminders.js +3 -3
- package/dist/prompt/runtime.js +1 -0
- package/dist/provider-anthropic.d.ts +77 -0
- package/dist/provider-anthropic.js +544 -0
- package/dist/provider-openai-codex.d.ts +3 -0
- package/dist/provider-openai-codex.js +11 -2
- package/dist/provider-registry.d.ts +2 -0
- package/dist/provider-registry.js +29 -3
- package/dist/provider-transform.d.ts +1 -1
- package/dist/provider-transform.js +23 -0
- package/dist/provider.d.ts +4 -1
- package/dist/provider.js +119 -40
- package/dist/reasoning-debug.js +4 -1
- package/dist/session-log.js +17 -2
- package/dist/slash-commands/commands.js +4 -2
- package/dist/stats/usage.d.ts +4 -0
- package/dist/stats/usage.js +48 -11
- package/dist/tools/glob.js +3 -0
- package/dist/tools/grep.js +7 -0
- package/dist/tui/run.js +22 -12
- package/dist/tui-ink/app.js +3 -0
- package/dist/tui-ink/message-list.js +6 -3
- package/dist/tui-opentui/app.js +3 -0
- package/dist/tui-opentui/message-list.js +6 -3
- package/dist/types.d.ts +14 -1
- package/package.json +2 -1
package/dist/tui/run.js
CHANGED
|
@@ -9,6 +9,8 @@ import { homedir } from "node:os";
|
|
|
9
9
|
import { AgentAbortError } from "../agent.js";
|
|
10
10
|
import { AgentRunInputQueue } from "../agent/input-controller.js";
|
|
11
11
|
import { debugReasoningStream, summarizeDebugText } from "../reasoning-debug.js";
|
|
12
|
+
import { isHiddenToolMetadata } from "../agent/discovery-barrier.js";
|
|
13
|
+
import { sanitizeInternalReminderBlocks } from "../agent/internal-reminder-sanitizer.js";
|
|
12
14
|
import { summarizeAgentEventForTrace, summarizeTraceError, summarizeTraceValue, traceEvent, } from "../debug-trace.js";
|
|
13
15
|
import { BUILTIN_PROVIDERS, decodeModel, displayModel, isUserVisibleProvider } from "../provider-registry.js";
|
|
14
16
|
import { calculateUsageCost } from "../model-pricing.js";
|
|
@@ -60,6 +62,7 @@ const PROVIDER_PRIORITY = new Map([
|
|
|
60
62
|
["zai", 5],
|
|
61
63
|
["zai-coding-plan", 6],
|
|
62
64
|
["kimi-for-coding", 7],
|
|
65
|
+
["stepfun", 8],
|
|
63
66
|
]);
|
|
64
67
|
const DEFAULT_THEME = {
|
|
65
68
|
primary: "#fab283",
|
|
@@ -5075,6 +5078,7 @@ function OpenTuiApp(props) {
|
|
|
5075
5078
|
"zhipuai-coding-plan": "Coding Plan",
|
|
5076
5079
|
"zai-coding-plan": "Coding Plan",
|
|
5077
5080
|
"kimi-for-coding": "Coding Plan",
|
|
5081
|
+
stepfun: "Step Plan API key",
|
|
5078
5082
|
local: "OpenAI-compatible local endpoint",
|
|
5079
5083
|
};
|
|
5080
5084
|
return descriptions[providerId] ?? "API key";
|
|
@@ -6581,7 +6585,7 @@ function OpenTuiApp(props) {
|
|
|
6581
6585
|
completionTokens: usage.completionTokens,
|
|
6582
6586
|
reasoningTokens: usage.reasoningTokens,
|
|
6583
6587
|
turns: usage.turns,
|
|
6584
|
-
costText: cost ? `${formatCurrency(cost.cost)} spent${cost.estimated ? " est." : ""}` : "cost unavailable",
|
|
6588
|
+
costText: cost ? `${formatCurrency(cost.cost, cost.currency)} spent${cost.estimated ? " est." : ""}` : "cost unavailable",
|
|
6585
6589
|
};
|
|
6586
6590
|
}
|
|
6587
6591
|
function sidebarMcpStates() {
|
|
@@ -6950,12 +6954,14 @@ function renderUserMessage(message, index) {
|
|
|
6950
6954
|
}, h("box", { paddingTop: 1, paddingBottom: 1, paddingLeft: 2, backgroundColor: theme.backgroundPanel, flexShrink: 0, flexDirection: "column" }, ...userChildren));
|
|
6951
6955
|
}
|
|
6952
6956
|
function renderAssistantMessage(message, syntaxStyle, subtleSyntaxStyle, showThinking = true, verboseTrace = false, width = 80) {
|
|
6957
|
+
const visibleReasoning = showThinking
|
|
6958
|
+
? sanitizeInternalReminderBlocks(message.reasoning ?? "").trim()
|
|
6959
|
+
: "";
|
|
6953
6960
|
const modelSwitch = parseModelSwitchMessage(message.content);
|
|
6954
|
-
if (modelSwitch && !
|
|
6961
|
+
if (modelSwitch && !visibleReasoning && !(message.toolCalls?.length)) {
|
|
6955
6962
|
return renderModelSwitchMessage(modelSwitch);
|
|
6956
6963
|
}
|
|
6957
6964
|
const children = [];
|
|
6958
|
-
const visibleReasoning = showThinking ? message.reasoning?.trim() : "";
|
|
6959
6965
|
const parts = message.parts ?? [];
|
|
6960
6966
|
const hasParts = parts.length > 0;
|
|
6961
6967
|
if (message.status && !visibleReasoning && !message.content.trim() && !(message.toolCalls?.length) && !hasParts) {
|
|
@@ -8433,12 +8439,14 @@ function pickerTitle(kind, providerId) {
|
|
|
8433
8439
|
function getModelPickerReasoningLevels(providerId, modelId) {
|
|
8434
8440
|
// Only expand into one picker row per effort for models that genuinely have a
|
|
8435
8441
|
// reasoning-effort spectrum: OpenAI's reasoning models (codex gpt-5.x:
|
|
8436
|
-
// off/minimal/low/medium/high/xhigh)
|
|
8442
|
+
// off/minimal/low/medium/high/xhigh), DeepSeek's v4 models, and StepFun
|
|
8443
|
+
// Step Plan models. Other providers
|
|
8437
8444
|
// (e.g. GLM, Moonshot/Kimi) only have a thinking on/off toggle, not an effort
|
|
8438
8445
|
// control, so they stay as a single row.
|
|
8439
8446
|
const isOpenAIReasoning = providerId === "openai" || providerId === "openai-codex";
|
|
8440
8447
|
const isDeepseekReasoning = providerId === "deepseek" && (modelId === "deepseek-v4-flash" || modelId === "deepseek-v4-pro");
|
|
8441
|
-
|
|
8448
|
+
const isStepFunReasoning = providerId === "stepfun";
|
|
8449
|
+
if (!isOpenAIReasoning && !isDeepseekReasoning && !isStepFunReasoning)
|
|
8442
8450
|
return [];
|
|
8443
8451
|
const levels = getAvailableThinkingLevels(providerId, modelId);
|
|
8444
8452
|
// gpt-4o and friends report only ["off"] — keep those as a single row too.
|
|
@@ -8451,8 +8459,9 @@ function displayModelWithThinking(model, thinkingLevel) {
|
|
|
8451
8459
|
if (!providerId)
|
|
8452
8460
|
return displayModel(model);
|
|
8453
8461
|
// Use the same scoping as the picker: only models with a real reasoning-effort
|
|
8454
|
-
// spectrum (OpenAI codex gpt-5.x, deepseek v4
|
|
8455
|
-
// on/off thinking toggle on GLM / Moonshot(Kimi) is
|
|
8462
|
+
// spectrum (OpenAI codex gpt-5.x, deepseek v4, StepFun Step Plan) get the
|
|
8463
|
+
// "(level)" suffix. The on/off thinking toggle on GLM / Moonshot(Kimi) is
|
|
8464
|
+
// not an effort control.
|
|
8456
8465
|
const levels = getModelPickerReasoningLevels(providerId, modelId);
|
|
8457
8466
|
if (levels.length > 1 && thinkingLevel !== "off") {
|
|
8458
8467
|
return `${displayModel(model)} (${thinkingLevel})`;
|
|
@@ -8649,6 +8658,8 @@ function reconstructDisplayMessages(agentMessages) {
|
|
|
8649
8658
|
}
|
|
8650
8659
|
catch { }
|
|
8651
8660
|
const toolResult = agentMessages.find((candidate) => candidate.role === "tool" && candidate.toolCallId === tc.id);
|
|
8661
|
+
if (isHiddenToolMetadata(toolResult ? toolResult.metadata : undefined))
|
|
8662
|
+
continue;
|
|
8652
8663
|
toolCalls.push({
|
|
8653
8664
|
id: tc.id,
|
|
8654
8665
|
name: tc.name,
|
|
@@ -9389,12 +9400,11 @@ function formatCompactNumber(value) {
|
|
|
9389
9400
|
return `${(value / 1_000).toFixed(1)}K`;
|
|
9390
9401
|
return String(value);
|
|
9391
9402
|
}
|
|
9392
|
-
function formatCurrency(value) {
|
|
9403
|
+
function formatCurrency(value, currency = "USD") {
|
|
9393
9404
|
if (value < 0.0001)
|
|
9394
|
-
return "$0.0000";
|
|
9395
|
-
|
|
9396
|
-
|
|
9397
|
-
return `$${value.toFixed(2)}`;
|
|
9405
|
+
return currency === "USD" ? "$0.0000" : "CNY 0.0000";
|
|
9406
|
+
const amount = value < 1 ? value.toFixed(4) : value.toFixed(2);
|
|
9407
|
+
return currency === "USD" ? `$${amount}` : `CNY ${amount}`;
|
|
9398
9408
|
}
|
|
9399
9409
|
function sidebarStatusColor(kind) {
|
|
9400
9410
|
if (kind === "connected")
|
package/dist/tui-ink/app.js
CHANGED
|
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
3
3
|
import { Box, Text, useApp, useInput } from "ink";
|
|
4
4
|
import { AgentAbortError } from "../agent.js";
|
|
5
|
+
import { isHiddenToolMetadata } from "../agent/discovery-barrier.js";
|
|
5
6
|
import { registry as slashRegistry } from "../slash-commands/index.js";
|
|
6
7
|
import { UserConfig, maskKey } from "../config.js";
|
|
7
8
|
import { createPastedContentMarker, InputBox, isCtrlCInput, shouldCollapsePastedContent, } from "./input-box.js";
|
|
@@ -82,6 +83,8 @@ function reconstructDisplayMessages(agentMessages) {
|
|
|
82
83
|
args = {};
|
|
83
84
|
}
|
|
84
85
|
const toolResult = agentMessages.find((tm) => tm.role === "tool" && tm.toolCallId === tc.id);
|
|
86
|
+
if (isHiddenToolMetadata(toolResult ? toolResult.metadata : undefined))
|
|
87
|
+
continue;
|
|
85
88
|
toolCalls.push({
|
|
86
89
|
id: tc.id,
|
|
87
90
|
name: tc.name,
|
|
@@ -7,6 +7,7 @@ import { MarkdownContent, StreamingMarkdown } from "./markdown.js";
|
|
|
7
7
|
import { buildTraceGroups, formatTracePath, traceGroupLabel } from "./trace-groups.js";
|
|
8
8
|
import { EDIT_COLLAPSED_DIFF_LINES, formatEditSuccessSummary, getEditDiffDetails } from "./edit-diff.js";
|
|
9
9
|
import { formatSubagentRoute } from "../agent/subagent-route-format.js";
|
|
10
|
+
import { sanitizeInternalReminderBlocks } from "../agent/internal-reminder-sanitizer.js";
|
|
10
11
|
export function MessageList({ messages, streamingContent, streamingReasoning, streamingTools, streamingParts, terminalColumns, verboseTrace, pendingApproval, nowTick, welcomeBanner, }) {
|
|
11
12
|
const hasStreaming = !!(streamingContent ||
|
|
12
13
|
streamingReasoning ||
|
|
@@ -44,22 +45,24 @@ function MessageItem({ message, terminalColumns, verboseTrace, showExpandHint, n
|
|
|
44
45
|
if (message.syntheticKind === "ui_compact_summary") {
|
|
45
46
|
return _jsx(CompactionSummaryBlock, { message: message });
|
|
46
47
|
}
|
|
48
|
+
const visibleReasoning = sanitizeInternalReminderBlocks(message.reasoning ?? "").trim();
|
|
47
49
|
const hasVisibleAssistantContent = !!message.content ||
|
|
48
50
|
(message.toolCalls?.length ?? 0) > 0 ||
|
|
49
51
|
(message.parts?.length ?? 0) > 0 ||
|
|
50
|
-
(!!
|
|
52
|
+
(!!visibleReasoning && verboseTrace);
|
|
51
53
|
if (!hasVisibleAssistantContent)
|
|
52
54
|
return null;
|
|
53
|
-
return (_jsxs(Box, { marginTop: 1, marginBottom: 1, flexDirection: "column", children: [
|
|
55
|
+
return (_jsxs(Box, { marginTop: 1, marginBottom: 1, flexDirection: "column", children: [visibleReasoning && verboseTrace && _jsx(ReasoningTraceBlock, { reasoning: visibleReasoning }), message.parts && message.parts.length > 0 ? (_jsx(MessageParts, { parts: message.parts, terminalColumns: terminalColumns, verboseTrace: verboseTrace, pendingApproval: undefined, showExpandHint: showExpandHint, nowTick: nowTick })) : (_jsxs(_Fragment, { children: [message.toolCalls && (_jsx(ToolsPart, { toolCalls: message.toolCalls, terminalColumns: terminalColumns, verboseTrace: verboseTrace, pendingApproval: undefined, showExpandHint: showExpandHint, nowTick: nowTick })), message.content && _jsx(MarkdownContent, { content: message.content })] })), verboseTrace && message.toolCalls && message.toolCalls.length > 0 && (_jsx(TurnDigest, { toolCalls: message.toolCalls })), message.taskElapsedMs !== undefined && (_jsx(TaskDurationLine, { elapsedMs: message.taskElapsedMs }))] }));
|
|
54
56
|
}
|
|
55
57
|
function StreamingMessage({ content, reasoning, tools, parts, terminalColumns, verboseTrace, pendingApproval, nowTick, }) {
|
|
56
58
|
const deferredContent = React.useDeferredValue(content);
|
|
57
59
|
const deferredReasoning = React.useDeferredValue(reasoning);
|
|
58
60
|
const deferredParts = React.useDeferredValue(parts);
|
|
61
|
+
const visibleReasoning = sanitizeInternalReminderBlocks(deferredReasoning).trim();
|
|
59
62
|
const visibleParts = deferredParts.length > 0
|
|
60
63
|
? deferredParts
|
|
61
64
|
: fallbackStreamingParts(deferredContent, tools);
|
|
62
|
-
return (_jsxs(Box, { flexDirection: "column", children: [
|
|
65
|
+
return (_jsxs(Box, { flexDirection: "column", children: [visibleReasoning && verboseTrace && (_jsx(Box, { marginTop: 1, flexDirection: "column", children: _jsx(ReasoningTraceBlock, { reasoning: visibleReasoning }) })), visibleParts.length > 0 && (
|
|
63
66
|
// marginTop intentionally 0: this Box only mounts on the first non-empty
|
|
64
67
|
// streaming frame, so a marginTop=1 here would visibly insert a blank
|
|
65
68
|
// line under the user message right at that moment (the "spinner sits
|
package/dist/tui-opentui/app.js
CHANGED
|
@@ -3,6 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "@opentui/reac
|
|
|
3
3
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
4
4
|
import { useKeyboard, useRenderer } from "@opentui/react";
|
|
5
5
|
import { AgentAbortError } from "../agent.js";
|
|
6
|
+
import { isHiddenToolMetadata } from "../agent/discovery-barrier.js";
|
|
6
7
|
import { registry as slashRegistry } from "../slash-commands/index.js";
|
|
7
8
|
import { UserConfig, maskKey } from "../config.js";
|
|
8
9
|
import { createPastedContentMarker, InputBox, shouldCollapsePastedContent, } from "./input-box.js";
|
|
@@ -96,6 +97,8 @@ function reconstructDisplayMessages(agentMessages) {
|
|
|
96
97
|
args = {};
|
|
97
98
|
}
|
|
98
99
|
const toolResult = agentMessages.find((tm) => tm.role === "tool" && tm.toolCallId === tc.id);
|
|
100
|
+
if (isHiddenToolMetadata(toolResult ? toolResult.metadata : undefined))
|
|
101
|
+
continue;
|
|
99
102
|
toolCalls.push({
|
|
100
103
|
id: tc.id,
|
|
101
104
|
name: tc.name,
|
|
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "@opentui/reac
|
|
|
2
2
|
import { useTheme } from "./theme.js";
|
|
3
3
|
import { MarkdownContent, StreamingMarkdown } from "./markdown.js";
|
|
4
4
|
import { EDIT_COLLAPSED_DIFF_LINES, getEditDiffDetails } from "./edit-diff.js";
|
|
5
|
+
import { sanitizeInternalReminderBlocks } from "../agent/internal-reminder-sanitizer.js";
|
|
5
6
|
/**
|
|
6
7
|
* Scrollback-style message list following opencode visual rules:
|
|
7
8
|
*
|
|
@@ -29,18 +30,20 @@ function MessageItem({ message, terminalColumns, verboseTrace, }) {
|
|
|
29
30
|
if (message.syntheticKind === "ui_compact_summary") {
|
|
30
31
|
return _jsx(CompactionSummaryBlock, { message: message, theme: theme });
|
|
31
32
|
}
|
|
33
|
+
const visibleReasoning = sanitizeInternalReminderBlocks(message.reasoning ?? "").trim();
|
|
32
34
|
const hasVisible = !!message.content ||
|
|
33
35
|
(message.toolCalls?.length ?? 0) > 0 ||
|
|
34
36
|
(message.parts?.length ?? 0) > 0 ||
|
|
35
|
-
(!!
|
|
37
|
+
(!!visibleReasoning && verboseTrace);
|
|
36
38
|
if (!hasVisible)
|
|
37
39
|
return null;
|
|
38
|
-
return (_jsxs("box", { style: { marginTop: 1, marginBottom: 1, flexDirection: "column" }, children: [
|
|
40
|
+
return (_jsxs("box", { style: { marginTop: 1, marginBottom: 1, flexDirection: "column" }, children: [visibleReasoning && verboseTrace && _jsx(ReasoningBlock, { reasoning: visibleReasoning, theme: theme }), message.parts && message.parts.length > 0 ? (_jsx(MessageParts, { parts: message.parts, terminalColumns: terminalColumns, verboseTrace: verboseTrace, theme: theme })) : (_jsxs(_Fragment, { children: [message.toolCalls && _jsx(ToolsPart, { toolCalls: message.toolCalls, terminalColumns: terminalColumns, verboseTrace: verboseTrace, theme: theme }), message.content && _jsx(MarkdownContent, { content: message.content, terminalColumns: terminalColumns })] }))] }));
|
|
39
41
|
}
|
|
40
42
|
function StreamingMessage({ content, reasoning, tools, parts, terminalColumns, verboseTrace, }) {
|
|
41
43
|
const theme = useTheme();
|
|
44
|
+
const visibleReasoning = sanitizeInternalReminderBlocks(reasoning).trim();
|
|
42
45
|
const visibleParts = parts.length > 0 ? parts : fallbackStreamingParts(content, tools);
|
|
43
|
-
return (_jsxs("box", { style: { flexDirection: "column", marginTop: 1 }, children: [
|
|
46
|
+
return (_jsxs("box", { style: { flexDirection: "column", marginTop: 1 }, children: [visibleReasoning && verboseTrace && _jsx(ReasoningBlock, { reasoning: visibleReasoning, theme: theme }), visibleParts.length > 0 && (_jsx(MessageParts, { parts: visibleParts, terminalColumns: terminalColumns, verboseTrace: verboseTrace, streaming: true, theme: theme }))] }));
|
|
44
47
|
}
|
|
45
48
|
function fallbackStreamingParts(content, tools) {
|
|
46
49
|
const out = [];
|
package/dist/types.d.ts
CHANGED
|
@@ -14,6 +14,14 @@ export interface ImageContent {
|
|
|
14
14
|
export type ContentPart = TextContent | ImageContent;
|
|
15
15
|
export type ThinkingLevel = "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
|
|
16
16
|
export type ReasoningEffort = ThinkingLevel;
|
|
17
|
+
export type ProviderRawContentBlock = Record<string, unknown> & {
|
|
18
|
+
type: string;
|
|
19
|
+
};
|
|
20
|
+
export interface AssistantProviderMetadata {
|
|
21
|
+
anthropic?: {
|
|
22
|
+
contentBlocks?: ProviderRawContentBlock[];
|
|
23
|
+
};
|
|
24
|
+
}
|
|
17
25
|
export interface UserMessage {
|
|
18
26
|
role: "user";
|
|
19
27
|
content: string | ContentPart[];
|
|
@@ -23,6 +31,7 @@ export interface AssistantMessage {
|
|
|
23
31
|
content: string;
|
|
24
32
|
reasoning?: string;
|
|
25
33
|
toolCalls?: ToolCall[];
|
|
34
|
+
providerMetadata?: AssistantProviderMetadata;
|
|
26
35
|
/** Model metadata captured for local usage statistics. */
|
|
27
36
|
model?: string;
|
|
28
37
|
providerId?: string;
|
|
@@ -102,7 +111,7 @@ export interface ParsedToolCall extends ToolCall {
|
|
|
102
111
|
}
|
|
103
112
|
export type ToolResultStatus = "success" | "no_match" | "partial" | "timeout" | "blocked" | "cancelled" | "command_error";
|
|
104
113
|
export interface ToolResultMetadata {
|
|
105
|
-
kind?: "search" | "read" | "write" | "edit" | "patch" | "shell" | "server" | "web" | "security" | "lsp" | "question" | "subagent";
|
|
114
|
+
kind?: "search" | "read" | "write" | "edit" | "patch" | "shell" | "server" | "web" | "security" | "lsp" | "question" | "subagent" | "internal";
|
|
106
115
|
path?: string;
|
|
107
116
|
pattern?: string;
|
|
108
117
|
matches?: number;
|
|
@@ -239,6 +248,10 @@ export type StreamChunk = {
|
|
|
239
248
|
} | {
|
|
240
249
|
type: "reasoning_delta";
|
|
241
250
|
content: string;
|
|
251
|
+
} | {
|
|
252
|
+
type: "provider_content_block";
|
|
253
|
+
provider: "anthropic";
|
|
254
|
+
block: ProviderRawContentBlock;
|
|
242
255
|
} | {
|
|
243
256
|
type: "tool_call";
|
|
244
257
|
id: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bubblebrain-ai/bubble",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.17",
|
|
4
4
|
"description": "A terminal coding agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"solid-js": "^1.9.12",
|
|
45
45
|
"string-width": "^8.2.1",
|
|
46
46
|
"typescript-language-server": "^5.1.3",
|
|
47
|
+
"undici": "^6.26.0",
|
|
47
48
|
"vscode-jsonrpc": "^8.2.1",
|
|
48
49
|
"vscode-langservers-extracted": "^4.10.0"
|
|
49
50
|
},
|