@datename/fastcode-termux 0.1.6-beta → 0.1.6
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 +6 -24
- package/dist/agent/guards.d.ts +0 -8
- package/dist/agent/guards.js +0 -195
- package/dist/agent/protocol.js +1 -4
- package/dist/agent/tools.d.ts +1 -3
- package/dist/agent/tools.js +377 -2
- package/dist/app.js +103 -335
- package/dist/cli.js +311 -362
- package/dist/commands/index.js +0 -22
- package/dist/commands/login.d.ts +2 -4
- package/dist/commands/login.js +10 -12
- package/dist/commands/logout.js +16 -8
- package/dist/commands/model.d.ts +0 -13
- package/dist/commands/model.js +22 -42
- package/dist/commands/provider.d.ts +0 -13
- package/dist/commands/provider.js +9 -20
- package/dist/commands/whoami.js +5 -6
- package/dist/config/store.d.ts +12 -32
- package/dist/config/store.js +65 -117
- package/dist/config/trust.d.ts +8 -21
- package/dist/config/trust.js +13 -99
- package/dist/lib/diagnostics.d.ts +4 -29
- package/dist/lib/diagnostics.js +4 -60
- package/dist/lib/http.d.ts +1 -11
- package/dist/lib/http.js +4 -62
- package/dist/providers/anthropic.d.ts +0 -1
- package/dist/providers/anthropic.js +0 -12
- package/dist/providers/custom.d.ts +0 -9
- package/dist/providers/deepseek.d.ts +0 -10
- package/dist/providers/deepseek.js +1 -2
- package/dist/providers/google.d.ts +0 -9
- package/dist/providers/groq.d.ts +0 -10
- package/dist/providers/groq.js +1 -2
- package/dist/providers/index.d.ts +201 -10
- package/dist/providers/index.js +0 -30
- package/dist/providers/mistral.d.ts +0 -10
- package/dist/providers/mistral.js +1 -2
- package/dist/providers/moonshot.d.ts +0 -10
- package/dist/providers/moonshot.js +1 -2
- package/dist/providers/ollama.d.ts +0 -9
- package/dist/providers/openai.d.ts +0 -10
- package/dist/providers/openai.js +1 -2
- package/dist/providers/openaiCompatible.d.ts +0 -9
- package/dist/providers/openaiCompatible.js +10 -58
- package/dist/providers/openrouter.d.ts +0 -10
- package/dist/providers/openrouter.js +1 -2
- package/dist/providers/qwen.d.ts +0 -10
- package/dist/providers/qwen.js +1 -2
- package/dist/providers/xai.d.ts +0 -10
- package/dist/providers/xai.js +1 -2
- package/dist/providers/zhipu.d.ts +0 -10
- package/dist/providers/zhipu.js +1 -2
- package/dist/session/log.d.ts +12 -35
- package/dist/session/log.js +10 -206
- package/dist/types.d.ts +1 -60
- package/dist/ui/Message.d.ts +7 -1
- package/dist/ui/Message.js +2 -13
- package/dist/ui/Prompt.d.ts +2 -1
- package/dist/ui/Prompt.js +2 -2
- package/dist/ui/Spinner.js +5 -11
- package/dist/ui/StatusBar.d.ts +1 -2
- package/dist/ui/StatusBar.js +5 -6
- package/package.json +1 -1
- package/src/agent/guards.ts +0 -196
- package/src/agent/protocol.ts +1 -4
- package/src/agent/tools.ts +377 -3
- package/src/app.ts +103 -335
- package/src/cli.ts +3 -30
- package/src/commands/index.ts +0 -22
- package/src/commands/login.ts +10 -12
- package/src/commands/logout.ts +16 -8
- package/src/commands/model.ts +22 -42
- package/src/commands/provider.ts +9 -20
- package/src/commands/whoami.ts +5 -6
- package/src/config/store.ts +69 -122
- package/src/config/trust.ts +21 -137
- package/src/lib/diagnostics.ts +4 -60
- package/src/lib/http.ts +4 -66
- package/src/providers/anthropic.ts +1 -13
- package/src/providers/deepseek.ts +1 -2
- package/src/providers/groq.ts +1 -2
- package/src/providers/index.ts +1 -32
- package/src/providers/mistral.ts +1 -2
- package/src/providers/moonshot.ts +1 -2
- package/src/providers/openai.ts +1 -2
- package/src/providers/openaiCompatible.ts +10 -58
- package/src/providers/openrouter.ts +1 -2
- package/src/providers/qwen.ts +1 -2
- package/src/providers/xai.ts +1 -2
- package/src/providers/zhipu.ts +1 -2
- package/src/session/log.ts +28 -267
- package/src/types.ts +1 -63
- package/src/ui/Message.ts +2 -13
- package/src/ui/Prompt.ts +2 -2
- package/src/ui/Spinner.ts +5 -11
- package/src/ui/StatusBar.ts +5 -6
- package/dist/agent/approval.d.ts +0 -50
- package/dist/agent/approval.js +0 -7
- package/dist/agent/compaction.d.ts +0 -39
- package/dist/agent/compaction.js +0 -227
- package/dist/agent/context.d.ts +0 -29
- package/dist/agent/context.js +0 -62
- package/dist/agent/ignore.d.ts +0 -11
- package/dist/agent/ignore.js +0 -129
- package/dist/agent/process-tree.d.ts +0 -2
- package/dist/agent/process-tree.js +0 -31
- package/dist/agent/protocol-mode.d.ts +0 -6
- package/dist/agent/protocol-mode.js +0 -51
- package/dist/agent/registry.d.ts +0 -17
- package/dist/agent/registry.js +0 -90
- package/dist/agent/runner.d.ts +0 -106
- package/dist/agent/runner.js +0 -352
- package/dist/agent/shell-session.d.ts +0 -37
- package/dist/agent/shell-session.js +0 -400
- package/dist/agent/stream.d.ts +0 -29
- package/dist/agent/stream.js +0 -103
- package/dist/agent/tool-schemas.d.ts +0 -2
- package/dist/agent/tool-schemas.js +0 -63
- package/dist/agent/tools/append_file.d.ts +0 -2
- package/dist/agent/tools/append_file.js +0 -26
- package/dist/agent/tools/apply_patch.d.ts +0 -10
- package/dist/agent/tools/apply_patch.js +0 -52
- package/dist/agent/tools/copy_file.d.ts +0 -2
- package/dist/agent/tools/copy_file.js +0 -30
- package/dist/agent/tools/delete_file.d.ts +0 -2
- package/dist/agent/tools/delete_file.js +0 -24
- package/dist/agent/tools/grep.d.ts +0 -2
- package/dist/agent/tools/grep.js +0 -23
- package/dist/agent/tools/index.d.ts +0 -2
- package/dist/agent/tools/index.js +0 -32
- package/dist/agent/tools/list_files.d.ts +0 -2
- package/dist/agent/tools/list_files.js +0 -17
- package/dist/agent/tools/make_dir.d.ts +0 -2
- package/dist/agent/tools/make_dir.js +0 -24
- package/dist/agent/tools/move_path.d.ts +0 -2
- package/dist/agent/tools/move_path.js +0 -47
- package/dist/agent/tools/paths.d.ts +0 -7
- package/dist/agent/tools/paths.js +0 -84
- package/dist/agent/tools/pwd.d.ts +0 -2
- package/dist/agent/tools/pwd.js +0 -10
- package/dist/agent/tools/read_file.d.ts +0 -2
- package/dist/agent/tools/read_file.js +0 -21
- package/dist/agent/tools/read_many.d.ts +0 -2
- package/dist/agent/tools/read_many.js +0 -25
- package/dist/agent/tools/readers.d.ts +0 -6
- package/dist/agent/tools/readers.js +0 -216
- package/dist/agent/tools/replace_in_file.d.ts +0 -2
- package/dist/agent/tools/replace_in_file.js +0 -30
- package/dist/agent/tools/shell.d.ts +0 -2
- package/dist/agent/tools/shell.js +0 -48
- package/dist/agent/tools/stat_path.d.ts +0 -2
- package/dist/agent/tools/stat_path.js +0 -31
- package/dist/agent/tools/types.d.ts +0 -39
- package/dist/agent/tools/types.js +0 -1
- package/dist/agent/tools/validate.d.ts +0 -6
- package/dist/agent/tools/validate.js +0 -29
- package/dist/agent/tools/write_file.d.ts +0 -2
- package/dist/agent/tools/write_file.js +0 -26
- package/dist/commands/attach.d.ts +0 -9
- package/dist/commands/attach.js +0 -15
- package/dist/commands/bg.d.ts +0 -7
- package/dist/commands/bg.js +0 -9
- package/dist/commands/cancel.d.ts +0 -10
- package/dist/commands/cancel.js +0 -10
- package/dist/commands/compact.d.ts +0 -10
- package/dist/commands/compact.js +0 -22
- package/dist/commands/context.d.ts +0 -7
- package/dist/commands/context.js +0 -24
- package/dist/commands/edit.d.ts +0 -10
- package/dist/commands/edit.js +0 -36
- package/dist/commands/effort.d.ts +0 -25
- package/dist/commands/effort.js +0 -48
- package/dist/commands/expand.d.ts +0 -10
- package/dist/commands/expand.js +0 -8
- package/dist/commands/jobs.d.ts +0 -7
- package/dist/commands/jobs.js +0 -16
- package/dist/commands/kill.d.ts +0 -7
- package/dist/commands/kill.js +0 -11
- package/dist/commands/steer.d.ts +0 -11
- package/dist/commands/steer.js +0 -13
- package/dist/lib/model-meta.d.ts +0 -19
- package/dist/lib/model-meta.js +0 -113
- package/dist/lib/native-tools.d.ts +0 -12
- package/dist/lib/native-tools.js +0 -21
- package/dist/lib/net.d.ts +0 -33
- package/dist/lib/net.js +0 -168
- package/dist/patch/apply.d.ts +0 -15
- package/dist/patch/apply.js +0 -172
- package/dist/patch/parse.d.ts +0 -29
- package/dist/patch/parse.js +0 -112
- package/dist/patch/plan.d.ts +0 -49
- package/dist/patch/plan.js +0 -273
- package/dist/session/projection.d.ts +0 -43
- package/dist/session/projection.js +0 -257
- package/dist/ui/Picker.d.ts +0 -8
- package/dist/ui/Picker.js +0 -24
- package/src/agent/approval.ts +0 -47
- package/src/agent/compaction.ts +0 -276
- package/src/agent/context.ts +0 -97
- package/src/agent/ignore.ts +0 -147
- package/src/agent/process-tree.ts +0 -32
- package/src/agent/protocol-mode.ts +0 -59
- package/src/agent/registry.ts +0 -98
- package/src/agent/runner.ts +0 -443
- package/src/agent/shell-session.ts +0 -449
- package/src/agent/stream.ts +0 -143
- package/src/agent/tool-schemas.ts +0 -67
- package/src/agent/tools/append_file.ts +0 -28
- package/src/agent/tools/apply_patch.ts +0 -54
- package/src/agent/tools/copy_file.ts +0 -32
- package/src/agent/tools/delete_file.ts +0 -26
- package/src/agent/tools/grep.ts +0 -25
- package/src/agent/tools/index.ts +0 -34
- package/src/agent/tools/list_files.ts +0 -19
- package/src/agent/tools/make_dir.ts +0 -26
- package/src/agent/tools/move_path.ts +0 -50
- package/src/agent/tools/paths.ts +0 -92
- package/src/agent/tools/pwd.ts +0 -12
- package/src/agent/tools/read_file.ts +0 -23
- package/src/agent/tools/read_many.ts +0 -27
- package/src/agent/tools/readers.ts +0 -228
- package/src/agent/tools/replace_in_file.ts +0 -32
- package/src/agent/tools/shell.ts +0 -53
- package/src/agent/tools/stat_path.ts +0 -33
- package/src/agent/tools/types.ts +0 -42
- package/src/agent/tools/validate.ts +0 -35
- package/src/agent/tools/write_file.ts +0 -28
- package/src/commands/attach.ts +0 -16
- package/src/commands/bg.ts +0 -9
- package/src/commands/cancel.ts +0 -10
- package/src/commands/compact.ts +0 -23
- package/src/commands/context.ts +0 -25
- package/src/commands/edit.ts +0 -37
- package/src/commands/effort.ts +0 -49
- package/src/commands/expand.ts +0 -8
- package/src/commands/jobs.ts +0 -17
- package/src/commands/kill.ts +0 -12
- package/src/commands/steer.ts +0 -13
- package/src/lib/model-meta.ts +0 -138
- package/src/lib/native-tools.ts +0 -32
- package/src/lib/net.ts +0 -204
- package/src/patch/apply.ts +0 -194
- package/src/patch/parse.ts +0 -131
- package/src/patch/plan.ts +0 -317
- package/src/session/projection.ts +0 -308
- package/src/ui/Picker.ts +0 -24
package/dist/app.js
CHANGED
|
@@ -11,18 +11,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
11
11
|
*/
|
|
12
12
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
13
13
|
import { Box, Static, Text, useApp, useInput } from "ink";
|
|
14
|
-
import { AGENT_SYSTEM_PROMPT, stripToolCalls, } from "./agent/protocol.js";
|
|
15
|
-
import {
|
|
16
|
-
import { resolveToolProtocol, withToolCapability } from "./agent/protocol-mode.js";
|
|
17
|
-
import { runAgent } from "./agent/runner.js";
|
|
18
|
-
import { toolSchemas } from "./agent/tool-schemas.js";
|
|
19
|
-
import { shutdownShells } from "./agent/shell-session.js";
|
|
14
|
+
import { AGENT_SYSTEM_PROMPT, formatToolResults, parseToolCalls, stripToolCalls, } from "./agent/protocol.js";
|
|
15
|
+
import { runAgentTool } from "./agent/tools.js";
|
|
20
16
|
import { Banner } from "./ui/Banner.js";
|
|
21
17
|
import { Spinner } from "./ui/Spinner.js";
|
|
22
18
|
import { StatusBar } from "./ui/StatusBar.js";
|
|
23
19
|
import { MessageBubble } from "./ui/Message.js";
|
|
24
20
|
import { Prompt } from "./ui/Prompt.js";
|
|
25
|
-
import { Picker } from "./ui/Picker.js";
|
|
26
21
|
import { COMMANDS, findCommand, parseSlash } from "./commands/index.js";
|
|
27
22
|
import { saveScopedKey } from "./commands/login.js";
|
|
28
23
|
import { getProvider, getProviderOrThrow, PROVIDERS } from "./providers/index.js";
|
|
@@ -32,8 +27,7 @@ import { createStartupTranscript } from "./lib/startup.js";
|
|
|
32
27
|
import { shouldUseLiveStreamingUi, shouldUseStableTerminalUi } from "./lib/uiMode.js";
|
|
33
28
|
import { buildPluginsPrompt } from "./plugins/manager.js";
|
|
34
29
|
import { buildSkillsPrompt } from "./skills/manager.js";
|
|
35
|
-
import { createSessionLog,
|
|
36
|
-
import { resumeSession } from "./session/projection.js";
|
|
30
|
+
import { createSessionLog, loadSessionMessages, openSessionLog } from "./session/log.js";
|
|
37
31
|
import { isTrusted, trustProject } from "./config/trust.js";
|
|
38
32
|
import { TrustGate } from "./ui/TrustGate.js";
|
|
39
33
|
/**
|
|
@@ -53,89 +47,22 @@ function maskLoginEcho(args) {
|
|
|
53
47
|
}
|
|
54
48
|
return parts.filter((p) => p !== "").join(" ");
|
|
55
49
|
}
|
|
56
|
-
function positiveInt(value, fallback) {
|
|
57
|
-
return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.floor(value) : fallback;
|
|
58
|
-
}
|
|
59
|
-
function streamingTail(text, maxLines = 6) {
|
|
60
|
-
const lines = String(text ?? "").split(/\r?\n/);
|
|
61
|
-
if (lines.length <= maxLines)
|
|
62
|
-
return String(text ?? "");
|
|
63
|
-
return "…\n" + lines.slice(-maxLines).join("\n");
|
|
64
|
-
}
|
|
65
|
-
function collapseToolOutput(output) {
|
|
66
|
-
const text = String(output ?? "");
|
|
67
|
-
const lines = text.split(/\r?\n/);
|
|
68
|
-
const first = (lines.find((line) => line.trim()) ?? "").trim();
|
|
69
|
-
const clipped = first.length > 160 ? first.slice(0, 157) + "..." : first;
|
|
70
|
-
const rest = Math.max(0, lines.length - 1);
|
|
71
|
-
return `${clipped}${clipped ? "\n" : ""}[${rest} more lines, ${text.length} chars]`;
|
|
72
|
-
}
|
|
73
|
-
function optionalBudget(name) {
|
|
74
|
-
const value = Number(process.env[name]);
|
|
75
|
-
return Number.isFinite(value) && value > 0 ? value : undefined;
|
|
76
|
-
}
|
|
77
|
-
function unclosedNotice(session) {
|
|
78
|
-
const where = session.cwd || "(unknown directory)";
|
|
79
|
-
const files = session.activeFiles?.length ?? 0;
|
|
80
|
-
return `Last session did not close normally (${where}, ~${session.turns} turns, ${files} file${files === 1 ? "" : "s"} changed).\n` +
|
|
81
|
-
`Resume it with \`fastcode resume ${session.id}\`, or list sessions with \`fastcode sessions\`.`;
|
|
82
|
-
}
|
|
83
|
-
function streamErrorMessage(message, provider, model) {
|
|
84
|
-
if (/\b(401|403)\b/.test(message) || /invalid api key|unauthorized|authentication/i.test(message)) {
|
|
85
|
-
return `Authentication failed for ${provider.label} · ${model}. The key may be wrong or not allowed for this model.\n` +
|
|
86
|
-
`Check with \`/whoami\`, or re-save: \`/login ${provider.id} ${model} <key>\`.`;
|
|
87
|
-
}
|
|
88
|
-
if (/\b(402|429)\b/.test(message) || /quota|insufficient|rate limit|billing|balance/i.test(message)) {
|
|
89
|
-
return `Request blocked: ${provider.label} reports no remaining quota / rate limit for ${model}.\n` +
|
|
90
|
-
`Top up the account or switch model/provider. (${message.slice(0, 200)})`;
|
|
91
|
-
}
|
|
92
|
-
return `Error: ${message}`;
|
|
93
|
-
}
|
|
94
50
|
export const App = ({ initialPrompt, resume }) => {
|
|
95
51
|
const { exit } = useApp();
|
|
96
52
|
const startupRef = useRef(null);
|
|
97
53
|
if (!startupRef.current) {
|
|
98
54
|
const config = loadConfig();
|
|
99
|
-
const
|
|
100
|
-
if (resumed) {
|
|
101
|
-
const provider = resumed.meta.providerId ? getProvider(resumed.meta.providerId) : undefined;
|
|
102
|
-
if (provider) {
|
|
103
|
-
config.providerId = provider.id;
|
|
104
|
-
if (resumed.meta.model)
|
|
105
|
-
config.model = resumed.meta.model;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
const restored = resumed?.messages ?? [];
|
|
109
|
-
const transcript = restored.length > 0
|
|
110
|
-
? restored.map((message, index) => ({
|
|
111
|
-
id: index + 1,
|
|
112
|
-
role: message.role,
|
|
113
|
-
content: message.role === "assistant" ? stripToolCalls(message.content) : message.content,
|
|
114
|
-
markdown: message.role !== "user",
|
|
115
|
-
}))
|
|
116
|
-
: createStartupTranscript(config);
|
|
117
|
-
if (resumed) {
|
|
118
|
-
const push = (text) => transcript.push({ id: transcript.length + 1, role: "system", content: text, markdown: true });
|
|
119
|
-
if (resumed.meta.providerId && !getProvider(resumed.meta.providerId))
|
|
120
|
-
push(`The session used provider ${resumed.meta.providerId}, which is not available in this build.`);
|
|
121
|
-
push(`Resumed session: ${config.providerId}::${config.model}${resumed.rebuilt ? " (projection rebuilt)" : ""}.`);
|
|
122
|
-
for (const warning of resumed.warnings)
|
|
123
|
-
push(warning);
|
|
124
|
-
}
|
|
125
|
-
else if (!resume && loggingEnabled()) {
|
|
126
|
-
const unclosed = latestUnclosedSession();
|
|
127
|
-
if (unclosed) {
|
|
128
|
-
transcript.push({
|
|
129
|
-
id: transcript.length + 1,
|
|
130
|
-
role: "system",
|
|
131
|
-
content: unclosedNotice(unclosed),
|
|
132
|
-
markdown: true,
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
}
|
|
55
|
+
const restored = resume ? loadSessionMessages(resume) : [];
|
|
136
56
|
startupRef.current = {
|
|
137
57
|
config,
|
|
138
|
-
transcript
|
|
58
|
+
transcript: restored.length > 0
|
|
59
|
+
? restored.map((message, index) => ({
|
|
60
|
+
id: index + 1,
|
|
61
|
+
role: message.role,
|
|
62
|
+
content: message.content,
|
|
63
|
+
markdown: message.role !== "user",
|
|
64
|
+
}))
|
|
65
|
+
: createStartupTranscript(config),
|
|
139
66
|
history: restored.map((message) => ({ role: message.role, content: message.content })),
|
|
140
67
|
};
|
|
141
68
|
}
|
|
@@ -143,40 +70,28 @@ export const App = ({ initialPrompt, resume }) => {
|
|
|
143
70
|
const sessionRef = useRef(null);
|
|
144
71
|
if (!sessionRef.current) {
|
|
145
72
|
sessionRef.current = resume
|
|
146
|
-
? openSessionLog(resume
|
|
147
|
-
providerId: startup.config.providerId,
|
|
148
|
-
model: startup.config.model,
|
|
149
|
-
cwd: process.cwd(),
|
|
150
|
-
})
|
|
73
|
+
? openSessionLog(resume)
|
|
151
74
|
: createSessionLog({
|
|
152
75
|
providerId: startup.config.providerId,
|
|
153
76
|
model: startup.config.model,
|
|
154
77
|
cwd: process.cwd(),
|
|
155
78
|
});
|
|
156
79
|
}
|
|
157
|
-
const [,
|
|
158
|
-
const trusted = isTrusted(process.cwd());
|
|
80
|
+
const [trusted, setTrusted] = useState(() => isTrusted(process.cwd()));
|
|
159
81
|
const [config, setConfig] = useState(startup.config);
|
|
160
82
|
const [history, setHistory] = useState(startup.history ?? []);
|
|
161
83
|
const [transcript, setTranscript] = useState(startup.transcript);
|
|
162
84
|
const [streamingId, setStreamingId] = useState(null);
|
|
163
85
|
const [streamingText, setStreamingText] = useState("");
|
|
164
|
-
const [streamPhase, setStreamPhase] = useState("thinking");
|
|
165
86
|
const [input, setInput] = useState("");
|
|
166
87
|
const [pendingLogin, setPendingLogin] = useState(null);
|
|
167
|
-
const [picker, setPicker] = useState(null);
|
|
168
|
-
const [pickerIndex, setPickerIndex] = useState(0);
|
|
169
88
|
const [busy, setBusy] = useState(false);
|
|
170
|
-
const [expanded, setExpanded] = useState(false);
|
|
171
|
-
const steerQueueRef = useRef([]);
|
|
172
89
|
const [totalIn, setTotalIn] = useState(0);
|
|
173
90
|
const [totalOut, setTotalOut] = useState(0);
|
|
174
91
|
const [totalCost, setTotalCost] = useState(0);
|
|
175
92
|
const [agentActivity, setAgentActivity] = useState(null);
|
|
176
93
|
const idRef = useRef(startup.transcript.length);
|
|
177
94
|
const abortRef = useRef(null);
|
|
178
|
-
const sawDeltaRef = useRef(false);
|
|
179
|
-
const lastStreamFlushRef = useRef(0);
|
|
180
95
|
const ctrlCRef = useRef(0);
|
|
181
96
|
const initialPromptSubmittedRef = useRef(false);
|
|
182
97
|
const theme = getTheme(config.theme);
|
|
@@ -199,38 +114,8 @@ export const App = ({ initialPrompt, resume }) => {
|
|
|
199
114
|
useEffect(() => {
|
|
200
115
|
saveConfig(config);
|
|
201
116
|
}, [config]);
|
|
202
|
-
const chooseItem = useCallback((request, index) => {
|
|
203
|
-
const item = request?.items?.[index];
|
|
204
|
-
setPicker(null);
|
|
205
|
-
if (item)
|
|
206
|
-
request.onSelect(item.value, item);
|
|
207
|
-
}, []);
|
|
208
117
|
// Esc cancels streaming. Double Ctrl+C quits.
|
|
209
118
|
useInput((inputChar, key) => {
|
|
210
|
-
if (picker) {
|
|
211
|
-
if (key.escape) {
|
|
212
|
-
picker.onCancel?.();
|
|
213
|
-
setPicker(null);
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
216
|
-
if (key.upArrow) {
|
|
217
|
-
setPickerIndex((i) => Math.max(0, i - 1));
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
if (key.downArrow) {
|
|
221
|
-
setPickerIndex((i) => Math.min(picker.items.length - 1, i + 1));
|
|
222
|
-
return;
|
|
223
|
-
}
|
|
224
|
-
if (key.return) {
|
|
225
|
-
chooseItem(picker, pickerIndex);
|
|
226
|
-
return;
|
|
227
|
-
}
|
|
228
|
-
if (/^[1-9]$/.test(inputChar)) {
|
|
229
|
-
chooseItem(picker, Number(inputChar) - 1);
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
119
|
if (key.escape) {
|
|
235
120
|
if (pendingLogin) {
|
|
236
121
|
setPendingLogin(null);
|
|
@@ -259,17 +144,15 @@ export const App = ({ initialPrompt, resume }) => {
|
|
|
259
144
|
});
|
|
260
145
|
const pushSystem = useCallback((text) => {
|
|
261
146
|
idRef.current += 1;
|
|
262
|
-
sessionRef.current.append({ type: "
|
|
147
|
+
sessionRef.current.append({ type: "message", role: "system", content: text });
|
|
263
148
|
setTranscript((prev) => [
|
|
264
149
|
...prev,
|
|
265
150
|
{ id: idRef.current, role: "system", content: text, markdown: true },
|
|
266
151
|
]);
|
|
267
152
|
}, []);
|
|
268
|
-
const pushUser = useCallback((text
|
|
153
|
+
const pushUser = useCallback((text) => {
|
|
269
154
|
idRef.current += 1;
|
|
270
|
-
sessionRef.current.append(
|
|
271
|
-
? { type: "user", content: text }
|
|
272
|
-
: { type: "notice", content: text });
|
|
155
|
+
sessionRef.current.append({ type: "message", role: "user", content: text });
|
|
273
156
|
setTranscript((prev) => [
|
|
274
157
|
...prev,
|
|
275
158
|
{ id: idRef.current, role: "user", content: text, markdown: false },
|
|
@@ -278,7 +161,6 @@ export const App = ({ initialPrompt, resume }) => {
|
|
|
278
161
|
const actions = useMemo(() => ({
|
|
279
162
|
setProvider: (id) => setConfig((c) => ({ ...c, providerId: id })),
|
|
280
163
|
setModel: (id) => setConfig((c) => ({ ...c, model: id })),
|
|
281
|
-
setReasoningEffort: (effort) => setConfig((c) => ({ ...c, reasoningEffort: effort })),
|
|
282
164
|
setTheme: (id) => setConfig((c) => ({ ...c, theme: id })),
|
|
283
165
|
setAgentMode: (enabled) => setConfig((c) => ({ ...c, agentMode: enabled })),
|
|
284
166
|
setSystemPrompt: (p) => setConfig((c) => ({ ...c, systemPrompt: p })),
|
|
@@ -303,18 +185,6 @@ export const App = ({ initialPrompt, resume }) => {
|
|
|
303
185
|
setHistory([]);
|
|
304
186
|
setTranscript([]);
|
|
305
187
|
},
|
|
306
|
-
replaceHistory: (messages) => setHistory(messages),
|
|
307
|
-
cancelRun: () => {
|
|
308
|
-
if (abortRef.current) {
|
|
309
|
-
abortRef.current.abort();
|
|
310
|
-
abortRef.current = null;
|
|
311
|
-
}
|
|
312
|
-
},
|
|
313
|
-
steer: (text) => {
|
|
314
|
-
steerQueueRef.current.push(text);
|
|
315
|
-
},
|
|
316
|
-
setExpanded: (value) => setExpanded(value),
|
|
317
|
-
setInput: (value) => setInput(value),
|
|
318
188
|
pushSystemMessage: pushSystem,
|
|
319
189
|
startLogin: ({ provider, model }) => {
|
|
320
190
|
setPendingLogin({
|
|
@@ -333,14 +203,10 @@ export const App = ({ initialPrompt, resume }) => {
|
|
|
333
203
|
pushSystem(`Unknown command "/${parsed.name}". Try /help.`);
|
|
334
204
|
return true;
|
|
335
205
|
}
|
|
336
|
-
if (busy && !["cancel", "steer", "jobs", "kill", "attach", "expand", "context"].includes(cmd.name)) {
|
|
337
|
-
pushSystem(`/${cmd.name} is unavailable while a run is active. Try /cancel or /steer.`);
|
|
338
|
-
return true;
|
|
339
|
-
}
|
|
340
206
|
// Echo the slash invocation for transcript clarity, but never echo a
|
|
341
207
|
// secret: the login key is masked, while provider/model stay readable.
|
|
342
208
|
const echo = parsed.name === "login" ? maskLoginEcho(parsed.args) : raw;
|
|
343
|
-
pushUser(echo
|
|
209
|
+
pushUser(echo);
|
|
344
210
|
try {
|
|
345
211
|
const res = await cmd.run({
|
|
346
212
|
args: parsed.args,
|
|
@@ -358,21 +224,11 @@ export const App = ({ initialPrompt, resume }) => {
|
|
|
358
224
|
enabledSkills: config.enabledSkills,
|
|
359
225
|
enabledPlugins: config.enabledPlugins,
|
|
360
226
|
skillsRegistry: config.skillsRegistry,
|
|
361
|
-
reasoningEffort: config.reasoningEffort,
|
|
362
|
-
expanded,
|
|
363
|
-
busy,
|
|
364
|
-
draft: input,
|
|
365
227
|
},
|
|
366
228
|
actions,
|
|
367
229
|
});
|
|
368
230
|
if (res?.message)
|
|
369
231
|
pushSystem(res.message);
|
|
370
|
-
if (res?.picker) {
|
|
371
|
-
const index = Math.max(0, res.picker.items.findIndex((item) => item.value === res.picker.current));
|
|
372
|
-
setPickerIndex(index);
|
|
373
|
-
setPicker(res.picker);
|
|
374
|
-
setInput("");
|
|
375
|
-
}
|
|
376
232
|
if (res?.quit)
|
|
377
233
|
exit();
|
|
378
234
|
}
|
|
@@ -390,8 +246,6 @@ export const App = ({ initialPrompt, resume }) => {
|
|
|
390
246
|
config.skillsRegistry,
|
|
391
247
|
config.systemPrompt,
|
|
392
248
|
config.theme,
|
|
393
|
-
busy,
|
|
394
|
-
expanded,
|
|
395
249
|
exit,
|
|
396
250
|
history,
|
|
397
251
|
pushSystem,
|
|
@@ -402,16 +256,8 @@ export const App = ({ initialPrompt, resume }) => {
|
|
|
402
256
|
]);
|
|
403
257
|
const handleSubmit = useCallback(async (raw) => {
|
|
404
258
|
const text = raw.trim();
|
|
405
|
-
if (!text)
|
|
259
|
+
if (!text || busy)
|
|
406
260
|
return;
|
|
407
|
-
if (busy) {
|
|
408
|
-
if (text.startsWith("/")) {
|
|
409
|
-
await runSlash(text);
|
|
410
|
-
return;
|
|
411
|
-
}
|
|
412
|
-
pushSystem("A run is active. Use /cancel to stop, /steer <text> to guide it, or wait.");
|
|
413
|
-
return;
|
|
414
|
-
}
|
|
415
261
|
setInput("");
|
|
416
262
|
if (text.startsWith("/")) {
|
|
417
263
|
await runSlash(text);
|
|
@@ -428,185 +274,110 @@ export const App = ({ initialPrompt, resume }) => {
|
|
|
428
274
|
return;
|
|
429
275
|
}
|
|
430
276
|
if (lookup.status === "missing") {
|
|
431
|
-
pushSystem(`Cannot send: no API key for ${provider.label}.\n` +
|
|
432
|
-
`Run \`/login ${provider.id} ${config.model} <key>\`
|
|
277
|
+
pushSystem(`Cannot send: no API key for ${provider.label} · ${config.model}.\n` +
|
|
278
|
+
`Run \`/login ${provider.id} ${config.model} <key>\` for this model, or set ${provider.authEnv[0]} (provider-wide).`);
|
|
433
279
|
return;
|
|
434
280
|
}
|
|
435
281
|
apiKey = lookup.key;
|
|
436
282
|
}
|
|
283
|
+
const nextHistory = [...history, { role: "user", content: text }];
|
|
284
|
+
setHistory(nextHistory);
|
|
437
285
|
idRef.current += 1;
|
|
438
286
|
const bubbleId = idRef.current;
|
|
439
287
|
setStreamingId(bubbleId);
|
|
440
288
|
setStreamingText("");
|
|
441
|
-
setStreamPhase("thinking");
|
|
442
|
-
steerQueueRef.current = [];
|
|
443
|
-
lastStreamFlushRef.current = 0;
|
|
444
289
|
const ctrl = new AbortController();
|
|
445
290
|
abortRef.current = ctrl;
|
|
446
291
|
setBusy(true);
|
|
447
|
-
let receivedDone = false;
|
|
448
292
|
try {
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
.
|
|
455
|
-
.
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
tokenBudget: optionalBudget("FASTCODE_TOKEN_BUDGET"),
|
|
470
|
-
costBudgetUsd: optionalBudget("FASTCODE_COST_BUDGET_USD"),
|
|
471
|
-
signal: ctrl.signal,
|
|
472
|
-
cwd: process.cwd(),
|
|
473
|
-
idleTimeoutMs: config.requestIdleTimeoutMs,
|
|
474
|
-
compaction: compactionConfigFromEnv(),
|
|
475
|
-
reasoningEffort: config.reasoningEffort,
|
|
476
|
-
protocol,
|
|
477
|
-
tools: protocol === "native" ? toolSchemas() : undefined,
|
|
478
|
-
onProtocolFallback: (message) => {
|
|
479
|
-
setConfig((current) => withToolCapability(current, config.providerId, config.model, "pseudo"));
|
|
480
|
-
pushSystem(message);
|
|
481
|
-
},
|
|
482
|
-
onNativeOk: () => {
|
|
483
|
-
if (protocol === "native")
|
|
484
|
-
setConfig((current) => withToolCapability(current, config.providerId, config.model, "native"));
|
|
485
|
-
},
|
|
486
|
-
takeSteering: () => {
|
|
487
|
-
const queued = steerQueueRef.current;
|
|
488
|
-
steerQueueRef.current = [];
|
|
489
|
-
return queued;
|
|
490
|
-
},
|
|
491
|
-
onDelta: (delta, full) => {
|
|
492
|
-
if (!sawDeltaRef.current) {
|
|
493
|
-
sawDeltaRef.current = true;
|
|
494
|
-
setStreamPhase("streaming");
|
|
293
|
+
let workingHistory = nextHistory;
|
|
294
|
+
let finalText = "";
|
|
295
|
+
for (let turn = 0; turn < (config.agentMode ? 8 : 1); turn += 1) {
|
|
296
|
+
const skillsBlock = buildSkillsPrompt(config.enabledSkills);
|
|
297
|
+
const pluginsBlock = buildPluginsPrompt(config.enabledPlugins);
|
|
298
|
+
const agentBlock = config.agentMode ? AGENT_SYSTEM_PROMPT : "";
|
|
299
|
+
const fullSystem = [config.systemPrompt, skillsBlock, pluginsBlock, agentBlock]
|
|
300
|
+
.filter((part) => part.trim())
|
|
301
|
+
.join("\n\n");
|
|
302
|
+
let acc = "";
|
|
303
|
+
for await (const chunk of provider.stream({
|
|
304
|
+
model: config.model,
|
|
305
|
+
messages: workingHistory,
|
|
306
|
+
system: fullSystem,
|
|
307
|
+
signal: ctrl.signal,
|
|
308
|
+
}, apiKey)) {
|
|
309
|
+
if (chunk.delta) {
|
|
310
|
+
acc += chunk.delta;
|
|
311
|
+
if (liveStreamingUi)
|
|
312
|
+
setStreamingText(stripToolCalls(acc));
|
|
495
313
|
}
|
|
496
|
-
if (
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
},
|
|
504
|
-
})) {
|
|
505
|
-
switch (ev.type) {
|
|
506
|
-
case "compaction":
|
|
507
|
-
sessionRef.current.append({
|
|
508
|
-
type: "compacted",
|
|
509
|
-
summaryRef: ev.summaryFile,
|
|
510
|
-
source: ev.source,
|
|
511
|
-
beforeTokens: ev.beforeTokens,
|
|
512
|
-
afterTokens: ev.afterTokens,
|
|
513
|
-
droppedMessages: ev.droppedMessages,
|
|
514
|
-
keepMessages: ev.keptMessages,
|
|
515
|
-
});
|
|
516
|
-
if (!compactionNotified) {
|
|
517
|
-
compactionNotified = true;
|
|
518
|
-
pushSystem(`[context compacted] ${ev.beforeTokens} → ${ev.afterTokens} tokens (${ev.reason}); recent turns kept.` +
|
|
519
|
-
(ev.summaryFile ? `\nSummary: ${ev.summaryFile}` : ""));
|
|
520
|
-
}
|
|
521
|
-
break;
|
|
522
|
-
case "assistant_raw":
|
|
523
|
-
lastRawFact = ev.text;
|
|
524
|
-
sessionRef.current.append({ type: "assistant_raw", content: ev.text, toolCalls: ev.toolCalls });
|
|
525
|
-
break;
|
|
526
|
-
case "assistant_text":
|
|
527
|
-
pushSystem(ev.text);
|
|
528
|
-
break;
|
|
529
|
-
case "tool_call":
|
|
530
|
-
sessionRef.current.append({ type: "tool_call", id: ev.id, tool: ev.call.tool, args: ev.call, native: Boolean(ev.native) });
|
|
531
|
-
setStreamPhase("tool");
|
|
532
|
-
setAgentActivity(`Coding: ${ev.call.tool}`);
|
|
533
|
-
pushSystem(`Running tool: \`${ev.call.tool}\`\n\n\`\`\`json\n${JSON.stringify(ev.call, null, 2)}\n\`\`\``);
|
|
534
|
-
break;
|
|
535
|
-
case "tool_result": {
|
|
536
|
-
sessionRef.current.append({
|
|
537
|
-
type: "tool_result",
|
|
538
|
-
id: ev.id,
|
|
539
|
-
tool: ev.call.tool,
|
|
540
|
-
ok: ev.ok,
|
|
541
|
-
output: ev.output,
|
|
542
|
-
sideEffects: ev.sideEffects,
|
|
543
|
-
});
|
|
544
|
-
const collapsed = stableUi && !expanded;
|
|
545
|
-
const body = collapsed ? collapseToolOutput(ev.output) : ev.output;
|
|
546
|
-
const hint = collapsed ? "\n\n_(output collapsed; /expand to show full output)_" : "";
|
|
547
|
-
pushSystem(`Tool ${ev.ok ? "completed" : "failed"}: \`${ev.call.tool}\`\n\n\`\`\`\n${body}\n\`\`\`${hint}`);
|
|
548
|
-
break;
|
|
314
|
+
if (chunk.done) {
|
|
315
|
+
if (chunk.usage?.inputTokens)
|
|
316
|
+
setTotalIn((n) => n + (chunk.usage.inputTokens ?? 0));
|
|
317
|
+
if (chunk.usage?.outputTokens)
|
|
318
|
+
setTotalOut((n) => n + (chunk.usage.outputTokens ?? 0));
|
|
319
|
+
if (chunk.usage?.costUsd)
|
|
320
|
+
setTotalCost((n) => n + (chunk.usage.costUsd ?? 0));
|
|
549
321
|
}
|
|
550
|
-
case "usage":
|
|
551
|
-
if (ev.usage.inputTokens)
|
|
552
|
-
setTotalIn((n) => n + (ev.usage.inputTokens ?? 0));
|
|
553
|
-
if (ev.usage.outputTokens)
|
|
554
|
-
setTotalOut((n) => n + (ev.usage.outputTokens ?? 0));
|
|
555
|
-
if (ev.usage.costUsd)
|
|
556
|
-
setTotalCost((n) => n + (ev.usage.costUsd ?? 0));
|
|
557
|
-
break;
|
|
558
|
-
case "loop_detected":
|
|
559
|
-
pushSystem(`Loop detected: \`${ev.fingerprint.split(":")[0]}\` repeated ${ev.occurrences} times. Asking the model to change approach.`);
|
|
560
|
-
break;
|
|
561
|
-
case "notice":
|
|
562
|
-
pushSystem(ev.text);
|
|
563
|
-
break;
|
|
564
|
-
case "checkpoint":
|
|
565
|
-
sessionRef.current.append({
|
|
566
|
-
type: "checkpoint",
|
|
567
|
-
turn: ev.turn,
|
|
568
|
-
cwd: ev.cwd,
|
|
569
|
-
providerId: ev.providerId,
|
|
570
|
-
model: ev.model,
|
|
571
|
-
activeFiles: ev.activeFiles,
|
|
572
|
-
lastFactSeq: sessionRef.current.count(),
|
|
573
|
-
});
|
|
574
|
-
break;
|
|
575
|
-
case "error":
|
|
576
|
-
if (ev.kind === "aborted")
|
|
577
|
-
pushSystem("Cancelled.");
|
|
578
|
-
else if (ev.kind === "stream_error")
|
|
579
|
-
pushSystem(streamErrorMessage(ev.message, provider, config.model));
|
|
580
|
-
else
|
|
581
|
-
pushSystem(ev.message);
|
|
582
|
-
break;
|
|
583
|
-
case "done":
|
|
584
|
-
receivedDone = true;
|
|
585
|
-
setHistory(ev.history);
|
|
586
|
-
if (ev.finalText) {
|
|
587
|
-
idRef.current += 1;
|
|
588
|
-
const finalId = idRef.current;
|
|
589
|
-
if (ev.finalText !== lastRawFact)
|
|
590
|
-
sessionRef.current.append({ type: "assistant_raw", content: ev.finalText });
|
|
591
|
-
setTranscript((prev) => [
|
|
592
|
-
...prev,
|
|
593
|
-
{ id: finalId, role: "assistant", content: ev.finalText, markdown: true },
|
|
594
|
-
]);
|
|
595
|
-
}
|
|
596
|
-
break;
|
|
597
322
|
}
|
|
323
|
+
const visibleText = stripToolCalls(acc);
|
|
324
|
+
const calls = config.agentMode ? parseToolCalls(acc) : [];
|
|
325
|
+
if (calls.length === 0) {
|
|
326
|
+
finalText = visibleText || acc;
|
|
327
|
+
break;
|
|
328
|
+
}
|
|
329
|
+
if (visibleText)
|
|
330
|
+
pushSystem(visibleText);
|
|
331
|
+
const results = [];
|
|
332
|
+
for (const call of calls) {
|
|
333
|
+
setAgentActivity(`Coding: ${call.tool}`);
|
|
334
|
+
pushSystem(`Running tool: \`${call.tool}\`\n\n\`\`\`json\n${JSON.stringify(call, null, 2)}\n\`\`\``);
|
|
335
|
+
const result = await runAgentTool(call, process.cwd());
|
|
336
|
+
results.push({ call, ...result });
|
|
337
|
+
pushSystem(`Tool ${result.ok ? "completed" : "failed"}: \`${call.tool}\`\n\n\`\`\`\n${result.output}\n\`\`\``);
|
|
338
|
+
}
|
|
339
|
+
const toolMessage = formatToolResults(results);
|
|
340
|
+
workingHistory = [
|
|
341
|
+
...workingHistory,
|
|
342
|
+
{ role: "assistant", content: acc },
|
|
343
|
+
{ role: "user", content: toolMessage },
|
|
344
|
+
];
|
|
345
|
+
setHistory(workingHistory);
|
|
346
|
+
setStreamingText("");
|
|
347
|
+
setAgentActivity(null);
|
|
348
|
+
}
|
|
349
|
+
if (!finalText) {
|
|
350
|
+
finalText = "Stopped after running the maximum number of agent tool turns.";
|
|
598
351
|
}
|
|
352
|
+
setHistory([...workingHistory, { role: "assistant", content: finalText }]);
|
|
353
|
+
idRef.current = Math.max(idRef.current, bubbleId);
|
|
354
|
+
sessionRef.current.append({ type: "message", role: "assistant", content: finalText });
|
|
355
|
+
setTranscript((prev) => [
|
|
356
|
+
...prev,
|
|
357
|
+
{ id: bubbleId, role: "assistant", content: finalText, markdown: true },
|
|
358
|
+
]);
|
|
599
359
|
}
|
|
600
360
|
catch (err) {
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
361
|
+
const message = String(err?.message ?? err);
|
|
362
|
+
if (err?.name === "AbortError") {
|
|
363
|
+
pushSystem("Cancelled.");
|
|
364
|
+
}
|
|
365
|
+
else if (/\b(401|403)\b/.test(message) || /invalid api key|unauthorized|authentication/i.test(message)) {
|
|
366
|
+
pushSystem(`Authentication failed for ${provider.label} · ${config.model}. The key may be wrong or not allowed for this model.\n` +
|
|
367
|
+
`Check with \`/whoami\`, or re-save: \`/login ${provider.id} ${config.model} <key>\`.`);
|
|
368
|
+
}
|
|
369
|
+
else if (/\b(402|429)\b/.test(message) || /quota|insufficient|rate limit|billing|balance/i.test(message)) {
|
|
370
|
+
pushSystem(`Request blocked: ${provider.label} reports no remaining quota / rate limit for ${config.model}.\n` +
|
|
371
|
+
`Top up the account or switch model/provider. (${message.slice(0, 200)})`);
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
pushSystem(`Error: ${message}`);
|
|
375
|
+
}
|
|
604
376
|
}
|
|
605
377
|
finally {
|
|
606
378
|
setStreamingId(null);
|
|
607
379
|
setStreamingText("");
|
|
608
380
|
setAgentActivity(null);
|
|
609
|
-
setStreamPhase("thinking");
|
|
610
381
|
setBusy(false);
|
|
611
382
|
abortRef.current = null;
|
|
612
383
|
}
|
|
@@ -656,9 +427,7 @@ export const App = ({ initialPrompt, resume }) => {
|
|
|
656
427
|
return;
|
|
657
428
|
}
|
|
658
429
|
setPendingLogin({ step: "key", provider: provider.id, model: value });
|
|
659
|
-
pushSystem(`
|
|
660
|
-
`This key will be reused by every ${provider.label} model.\n` +
|
|
661
|
-
`Paste the API key (input is masked).` +
|
|
430
|
+
pushSystem(`Scope: ${provider.id} · ${value}.\nPaste the API key for this model (input is masked).` +
|
|
662
431
|
(getLegacy(provider.id) ? `\nOr type \`keep\` to re-bind the stored ${provider.label} key.` : ""));
|
|
663
432
|
return;
|
|
664
433
|
}
|
|
@@ -687,7 +456,6 @@ export const App = ({ initialPrompt, resume }) => {
|
|
|
687
456
|
return () => clearTimeout(t);
|
|
688
457
|
}, [handleSubmit, initialPrompt]);
|
|
689
458
|
useEffect(() => () => {
|
|
690
|
-
shutdownShells();
|
|
691
459
|
if (sessionRef.current)
|
|
692
460
|
sessionRef.current.close();
|
|
693
461
|
}, []);
|
|
@@ -700,9 +468,9 @@ export const App = ({ initialPrompt, resume }) => {
|
|
|
700
468
|
setConfig((c) => ({ ...c, agentMode: false }));
|
|
701
469
|
pushSystem("Trust declined: agent tools are off for this session (chat only).");
|
|
702
470
|
}
|
|
703
|
-
|
|
471
|
+
setTrusted(true);
|
|
704
472
|
};
|
|
705
473
|
return _jsx(TrustGate, { theme: theme, cwd: process.cwd(), onDecision: decide });
|
|
706
474
|
}
|
|
707
|
-
return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [showBanner ? _jsx(Banner, { theme: theme, stable: stableUi }) : null, _jsx(Static, { items: transcript, children: (entry) => (_jsx(Box, { marginTop: 1, children: _jsx(MessageBubble, { theme: theme, role: entry.role, content: entry.content, markdown: entry.markdown }) }, entry.id)) }), streamingId !== null && liveStreamingUi ? (_jsx(Box, { marginTop: 1, flexDirection: "column", children: _jsx(MessageBubble, { theme: theme, role: "assistant", content:
|
|
475
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [showBanner ? _jsx(Banner, { theme: theme, stable: stableUi }) : null, _jsx(Static, { items: transcript, children: (entry) => (_jsx(Box, { marginTop: 1, children: _jsx(MessageBubble, { theme: theme, role: entry.role, content: entry.content, markdown: entry.markdown }) }, entry.id)) }), streamingId !== null && liveStreamingUi ? (_jsx(Box, { marginTop: 1, flexDirection: "column", children: _jsx(MessageBubble, { theme: theme, role: "assistant", content: streamingText, markdown: true, streaming: true }) })) : null, _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [busy ? (_jsx(Box, { marginBottom: 1, children: _jsx(Spinner, { theme: theme, label: agentActivity ?? (streamingId !== null ? "Streaming" : "Thinking"), stable: stableUi && !agentActivity }) })) : null, _jsx(Prompt, { theme: theme, value: input, onChange: setInput, onSubmit: pendingLogin ? handleWizardSubmit : handleSubmit, disabled: busy, stable: stableUi, placeholder: promptPlaceholder, mask: promptMask }), _jsx(StatusBar, { theme: theme, providerId: config.providerId, model: config.model, inputTokens: totalIn, outputTokens: totalOut, costUsd: totalCost, enabledSkillCount: config.enabledSkills.length + config.enabledPlugins.length }), _jsxs(Text, { color: theme.muted, children: [COMMANDS.length, " commands \u00B7 ", config.enabledSkills.length, " skill(s) active"] })] })] }));
|
|
708
476
|
};
|