@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
|
@@ -1,34 +1,12 @@
|
|
|
1
1
|
import { fetchJson, streamSSE } from "../lib/http.js";
|
|
2
|
-
import { finalizeToolCalls, mergeToolCallDelta } from "../lib/native-tools.js";
|
|
3
2
|
/** Build a chat-completions body in the classic or the newer (compat) dialect. */
|
|
4
|
-
function buildBody(req, compat
|
|
3
|
+
function buildBody(req, compat) {
|
|
5
4
|
const messages = [];
|
|
6
5
|
if (req.system)
|
|
7
6
|
messages.push({ role: "system", content: req.system });
|
|
8
|
-
for (const m of req.messages)
|
|
9
|
-
if (m.role === "tool") {
|
|
10
|
-
messages.push({ role: "tool", tool_call_id: m.toolCallId, content: m.content });
|
|
11
|
-
continue;
|
|
12
|
-
}
|
|
13
|
-
if (m.role === "assistant" && m.toolCalls && m.toolCalls.length > 0) {
|
|
14
|
-
messages.push({
|
|
15
|
-
role: "assistant",
|
|
16
|
-
content: m.content || null,
|
|
17
|
-
tool_calls: m.toolCalls.map((call) => ({
|
|
18
|
-
id: call.id,
|
|
19
|
-
type: "function",
|
|
20
|
-
function: { name: call.name, arguments: call.arguments },
|
|
21
|
-
})),
|
|
22
|
-
});
|
|
23
|
-
continue;
|
|
24
|
-
}
|
|
7
|
+
for (const m of req.messages)
|
|
25
8
|
messages.push({ role: m.role, content: m.content });
|
|
26
|
-
}
|
|
27
9
|
const body = { model: req.model, messages, stream: true };
|
|
28
|
-
if (req.tools && req.tools.length > 0) {
|
|
29
|
-
body.tools = req.tools;
|
|
30
|
-
body.tool_choice = "auto";
|
|
31
|
-
}
|
|
32
10
|
if (req.maxOutputTokens !== undefined) {
|
|
33
11
|
if (compat)
|
|
34
12
|
body.max_completion_tokens = req.maxOutputTokens;
|
|
@@ -37,18 +15,10 @@ function buildBody(req, compat, opts, includeReasoning = true) {
|
|
|
37
15
|
}
|
|
38
16
|
if (req.temperature !== undefined && !compat)
|
|
39
17
|
body.temperature = req.temperature;
|
|
40
|
-
if (includeReasoning && req.reasoningEffort && req.reasoningEffort !== "auto") {
|
|
41
|
-
const effort = req.reasoningEffort === "max" ? "high" : req.reasoningEffort;
|
|
42
|
-
if (opts.reasoning === "openai")
|
|
43
|
-
body.reasoning_effort = effort;
|
|
44
|
-
else if (opts.reasoning === "openrouter")
|
|
45
|
-
body.reasoning = { effort };
|
|
46
|
-
}
|
|
47
18
|
return body;
|
|
48
19
|
}
|
|
49
20
|
export async function* streamChatCompletion(req, opts) {
|
|
50
|
-
const
|
|
51
|
-
const send = async (compat, includeReasoning = hasReasoning) => {
|
|
21
|
+
const send = async (compat) => {
|
|
52
22
|
const headers = {
|
|
53
23
|
"content-type": "application/json",
|
|
54
24
|
accept: "text/event-stream",
|
|
@@ -56,36 +26,27 @@ export async function* streamChatCompletion(req, opts) {
|
|
|
56
26
|
};
|
|
57
27
|
if (opts.apiKey)
|
|
58
28
|
headers["authorization"] = (opts.authHeader ?? "Bearer") + " " + opts.apiKey;
|
|
59
|
-
if (req.clientRequestId)
|
|
60
|
-
headers["idempotency-key"] = req.clientRequestId;
|
|
61
29
|
return await fetch(trim(opts.baseUrl) + "/chat/completions", {
|
|
62
30
|
method: "POST",
|
|
63
31
|
headers,
|
|
64
|
-
body: JSON.stringify(buildBody(req, compat
|
|
32
|
+
body: JSON.stringify(buildBody(req, compat)),
|
|
65
33
|
signal: req.signal,
|
|
66
34
|
});
|
|
67
35
|
};
|
|
68
36
|
let res = await send(false);
|
|
69
37
|
if (!res.ok) {
|
|
70
|
-
|
|
71
|
-
// Some models reject the thinking parameter even though the provider
|
|
72
|
-
// as a whole accepts it. Drop it once, then keep the request alive.
|
|
73
|
-
if (res.status === 400 && hasReasoning && /reasoning|thinking|effort|unsupported|unrecognized|unknown parameter/i.test(detail)) {
|
|
74
|
-
res = await send(false, false);
|
|
75
|
-
detail = res.ok ? detail : await res.text().catch(() => "");
|
|
76
|
-
}
|
|
38
|
+
const detail = await res.text().catch(() => "");
|
|
77
39
|
// Newer OpenAI-style models reject max_tokens and temperature. Retry once
|
|
78
40
|
// in the compatibility dialect before surfacing the real error.
|
|
79
|
-
if (
|
|
80
|
-
res = await send(true
|
|
81
|
-
detail = res.ok ? detail : await res.text().catch(() => "");
|
|
41
|
+
if (res.status === 400 && /max_tokens|max_completion_tokens|temperature|unsupported|unrecognized|unknown parameter/i.test(detail)) {
|
|
42
|
+
res = await send(true);
|
|
82
43
|
}
|
|
83
44
|
if (!res.ok) {
|
|
84
|
-
|
|
45
|
+
const body = await res.text().catch(() => "");
|
|
46
|
+
throw new Error(res.status + " " + res.statusText + ": " + body.slice(0, 500));
|
|
85
47
|
}
|
|
86
48
|
}
|
|
87
49
|
let usage;
|
|
88
|
-
const toolCalls = new Map();
|
|
89
50
|
for await (const ev of streamSSE(res)) {
|
|
90
51
|
if (ev.data === "[DONE]")
|
|
91
52
|
break;
|
|
@@ -100,14 +61,6 @@ export async function* streamChatCompletion(req, opts) {
|
|
|
100
61
|
const choice = obj.choices?.[0];
|
|
101
62
|
const raw = choice?.delta?.content ?? choice?.text;
|
|
102
63
|
const reasoning = choice?.delta?.reasoning_content ?? choice?.delta?.reasoning;
|
|
103
|
-
if (Array.isArray(choice?.delta?.tool_calls)) {
|
|
104
|
-
for (const delta of choice.delta.tool_calls)
|
|
105
|
-
mergeToolCallDelta(toolCalls, delta);
|
|
106
|
-
}
|
|
107
|
-
if (Array.isArray(choice?.message?.tool_calls)) {
|
|
108
|
-
for (const delta of choice.message.tool_calls)
|
|
109
|
-
mergeToolCallDelta(toolCalls, delta);
|
|
110
|
-
}
|
|
111
64
|
if (obj.usage) {
|
|
112
65
|
usage = {
|
|
113
66
|
inputTokens: obj.usage.prompt_tokens,
|
|
@@ -125,8 +78,7 @@ export async function* streamChatCompletion(req, opts) {
|
|
|
125
78
|
else if (typeof reasoning === "string" && reasoning)
|
|
126
79
|
yield { delta: "", done: false, reasoning };
|
|
127
80
|
}
|
|
128
|
-
|
|
129
|
-
yield calls.length > 0 ? { delta: "", done: true, usage, toolCalls: calls } : { delta: "", done: true, usage };
|
|
81
|
+
yield { delta: "", done: true, usage };
|
|
130
82
|
}
|
|
131
83
|
export async function listModelsHttp(opts) {
|
|
132
84
|
const staticModels = opts.staticModels ?? [];
|
|
@@ -10,25 +10,15 @@ export declare const openrouterProvider: {
|
|
|
10
10
|
done: boolean;
|
|
11
11
|
reasoning?: undefined;
|
|
12
12
|
usage?: undefined;
|
|
13
|
-
toolCalls?: undefined;
|
|
14
13
|
} | {
|
|
15
14
|
delta: string;
|
|
16
15
|
done: boolean;
|
|
17
16
|
reasoning: string;
|
|
18
17
|
usage?: undefined;
|
|
19
|
-
toolCalls?: undefined;
|
|
20
18
|
} | {
|
|
21
19
|
delta: string;
|
|
22
20
|
done: boolean;
|
|
23
21
|
usage: any;
|
|
24
|
-
toolCalls: import("../types.js").NativeToolCall[];
|
|
25
22
|
reasoning?: undefined;
|
|
26
|
-
} | {
|
|
27
|
-
delta: string;
|
|
28
|
-
done: boolean;
|
|
29
|
-
usage: any;
|
|
30
|
-
reasoning?: undefined;
|
|
31
|
-
toolCalls?: undefined;
|
|
32
23
|
}, void, unknown>;
|
|
33
|
-
supportsReasoning: () => boolean;
|
|
34
24
|
};
|
|
@@ -22,6 +22,5 @@ export const openrouterProvider = {
|
|
|
22
22
|
baseUrl: BASE,
|
|
23
23
|
defaultModel: "anthropic/claude-sonnet-5.5",
|
|
24
24
|
listModels: (apiKey) => listModelsHttp({ baseUrl: BASE, apiKey, staticModels: STATIC, extraHeaders: EXTRA_HEADERS }),
|
|
25
|
-
stream: (req, apiKey) => streamChatCompletion(req, { baseUrl: BASE, apiKey, staticModels: STATIC, extraHeaders: EXTRA_HEADERS
|
|
26
|
-
supportsReasoning: () => true,
|
|
25
|
+
stream: (req, apiKey) => streamChatCompletion(req, { baseUrl: BASE, apiKey, staticModels: STATIC, extraHeaders: EXTRA_HEADERS }),
|
|
27
26
|
};
|
package/dist/providers/qwen.d.ts
CHANGED
|
@@ -10,25 +10,15 @@ export declare const qwenProvider: {
|
|
|
10
10
|
done: boolean;
|
|
11
11
|
reasoning?: undefined;
|
|
12
12
|
usage?: undefined;
|
|
13
|
-
toolCalls?: undefined;
|
|
14
13
|
} | {
|
|
15
14
|
delta: string;
|
|
16
15
|
done: boolean;
|
|
17
16
|
reasoning: string;
|
|
18
17
|
usage?: undefined;
|
|
19
|
-
toolCalls?: undefined;
|
|
20
18
|
} | {
|
|
21
19
|
delta: string;
|
|
22
20
|
done: boolean;
|
|
23
21
|
usage: any;
|
|
24
|
-
toolCalls: import("../types.js").NativeToolCall[];
|
|
25
22
|
reasoning?: undefined;
|
|
26
|
-
} | {
|
|
27
|
-
delta: string;
|
|
28
|
-
done: boolean;
|
|
29
|
-
usage: any;
|
|
30
|
-
reasoning?: undefined;
|
|
31
|
-
toolCalls?: undefined;
|
|
32
23
|
}, void, unknown>;
|
|
33
|
-
supportsReasoning: () => boolean;
|
|
34
24
|
};
|
package/dist/providers/qwen.js
CHANGED
|
@@ -19,6 +19,5 @@ export const qwenProvider = {
|
|
|
19
19
|
},
|
|
20
20
|
defaultModel: "qwen3.8-max",
|
|
21
21
|
listModels: (apiKey) => listModelsHttp({ baseUrl: baseUrl(), apiKey, staticModels: STATIC }),
|
|
22
|
-
stream: (req, apiKey) => streamChatCompletion(req, { baseUrl: baseUrl(), apiKey, staticModels: STATIC
|
|
23
|
-
supportsReasoning: () => true,
|
|
22
|
+
stream: (req, apiKey) => streamChatCompletion(req, { baseUrl: baseUrl(), apiKey, staticModels: STATIC }),
|
|
24
23
|
};
|
package/dist/providers/xai.d.ts
CHANGED
|
@@ -10,25 +10,15 @@ export declare const xaiProvider: {
|
|
|
10
10
|
done: boolean;
|
|
11
11
|
reasoning?: undefined;
|
|
12
12
|
usage?: undefined;
|
|
13
|
-
toolCalls?: undefined;
|
|
14
13
|
} | {
|
|
15
14
|
delta: string;
|
|
16
15
|
done: boolean;
|
|
17
16
|
reasoning: string;
|
|
18
17
|
usage?: undefined;
|
|
19
|
-
toolCalls?: undefined;
|
|
20
18
|
} | {
|
|
21
19
|
delta: string;
|
|
22
20
|
done: boolean;
|
|
23
21
|
usage: any;
|
|
24
|
-
toolCalls: import("../types.js").NativeToolCall[];
|
|
25
22
|
reasoning?: undefined;
|
|
26
|
-
} | {
|
|
27
|
-
delta: string;
|
|
28
|
-
done: boolean;
|
|
29
|
-
usage: any;
|
|
30
|
-
reasoning?: undefined;
|
|
31
|
-
toolCalls?: undefined;
|
|
32
23
|
}, void, unknown>;
|
|
33
|
-
supportsReasoning: () => boolean;
|
|
34
24
|
};
|
package/dist/providers/xai.js
CHANGED
|
@@ -14,6 +14,5 @@ export const xaiProvider = {
|
|
|
14
14
|
baseUrl: BASE,
|
|
15
15
|
defaultModel: "grok-4.7",
|
|
16
16
|
listModels: (apiKey) => listModelsHttp({ baseUrl: BASE, apiKey, staticModels: STATIC }),
|
|
17
|
-
stream: (req, apiKey) => streamChatCompletion(req, { baseUrl: BASE, apiKey, staticModels: STATIC
|
|
18
|
-
supportsReasoning: () => true,
|
|
17
|
+
stream: (req, apiKey) => streamChatCompletion(req, { baseUrl: BASE, apiKey, staticModels: STATIC }),
|
|
19
18
|
};
|
|
@@ -10,25 +10,15 @@ export declare const zhipuProvider: {
|
|
|
10
10
|
done: boolean;
|
|
11
11
|
reasoning?: undefined;
|
|
12
12
|
usage?: undefined;
|
|
13
|
-
toolCalls?: undefined;
|
|
14
13
|
} | {
|
|
15
14
|
delta: string;
|
|
16
15
|
done: boolean;
|
|
17
16
|
reasoning: string;
|
|
18
17
|
usage?: undefined;
|
|
19
|
-
toolCalls?: undefined;
|
|
20
18
|
} | {
|
|
21
19
|
delta: string;
|
|
22
20
|
done: boolean;
|
|
23
21
|
usage: any;
|
|
24
|
-
toolCalls: import("../types.js").NativeToolCall[];
|
|
25
22
|
reasoning?: undefined;
|
|
26
|
-
} | {
|
|
27
|
-
delta: string;
|
|
28
|
-
done: boolean;
|
|
29
|
-
usage: any;
|
|
30
|
-
reasoning?: undefined;
|
|
31
|
-
toolCalls?: undefined;
|
|
32
23
|
}, void, unknown>;
|
|
33
|
-
supportsReasoning: () => boolean;
|
|
34
24
|
};
|
package/dist/providers/zhipu.js
CHANGED
|
@@ -19,6 +19,5 @@ export const zhipuProvider = {
|
|
|
19
19
|
},
|
|
20
20
|
defaultModel: "glm-5.3",
|
|
21
21
|
listModels: (apiKey) => listModelsHttp({ baseUrl: baseUrl(), apiKey, staticModels: STATIC }),
|
|
22
|
-
stream: (req, apiKey) => streamChatCompletion(req, { baseUrl: baseUrl(), apiKey, staticModels: STATIC
|
|
23
|
-
supportsReasoning: () => true,
|
|
22
|
+
stream: (req, apiKey) => streamChatCompletion(req, { baseUrl: baseUrl(), apiKey, staticModels: STATIC }),
|
|
24
23
|
};
|
package/dist/session/log.d.ts
CHANGED
|
@@ -1,36 +1,15 @@
|
|
|
1
|
-
export interface ActiveFile {
|
|
2
|
-
path: string;
|
|
3
|
-
sha1_8: string;
|
|
4
|
-
mtime: string;
|
|
5
|
-
}
|
|
6
|
-
export interface SessionSummary {
|
|
7
|
-
id: string;
|
|
8
|
-
file: string;
|
|
9
|
-
cwd: string;
|
|
10
|
-
providerId: string;
|
|
11
|
-
model: string;
|
|
12
|
-
turns: number;
|
|
13
|
-
activeFiles: ActiveFile[];
|
|
14
|
-
messages: number;
|
|
15
|
-
lastTs: number;
|
|
16
|
-
}
|
|
17
1
|
export declare function sessionCacheLimitBytes(): number;
|
|
18
2
|
export declare function loggingEnabled(): boolean;
|
|
19
|
-
export declare function
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
id: string;
|
|
24
|
-
file: string;
|
|
25
|
-
append: (entry: Record<string, any>) => number;
|
|
26
|
-
count(): number;
|
|
3
|
+
export declare function createSessionLog(meta?: {}): {
|
|
4
|
+
id: any;
|
|
5
|
+
file: any;
|
|
6
|
+
append: (entry: any) => void;
|
|
27
7
|
close(): void;
|
|
28
8
|
};
|
|
29
|
-
export declare function openSessionLog(file:
|
|
30
|
-
id:
|
|
31
|
-
file:
|
|
32
|
-
append: (entry:
|
|
33
|
-
count(): number;
|
|
9
|
+
export declare function openSessionLog(file: any): {
|
|
10
|
+
id: any;
|
|
11
|
+
file: any;
|
|
12
|
+
append: (entry: any) => void;
|
|
34
13
|
close(): void;
|
|
35
14
|
};
|
|
36
15
|
export declare function listSessions(): {
|
|
@@ -40,13 +19,11 @@ export declare function listSessions(): {
|
|
|
40
19
|
modified: string;
|
|
41
20
|
messages: number;
|
|
42
21
|
}[];
|
|
43
|
-
export declare function resolveSessionFile(idOrFile:
|
|
44
|
-
export declare function readSession(idOrFile:
|
|
45
|
-
export declare function loadSessionMessages(idOrFile:
|
|
22
|
+
export declare function resolveSessionFile(idOrFile: any): any;
|
|
23
|
+
export declare function readSession(idOrFile: any): any[];
|
|
24
|
+
export declare function loadSessionMessages(idOrFile: any): {
|
|
46
25
|
role: any;
|
|
47
26
|
content: any;
|
|
48
27
|
}[];
|
|
49
|
-
export declare function latestSessionFile(): string
|
|
50
|
-
export declare function findUnclosedSessions(): SessionSummary[];
|
|
51
|
-
export declare function latestUnclosedSession(): SessionSummary | undefined;
|
|
28
|
+
export declare function latestSessionFile(): string;
|
|
52
29
|
export declare function pruneSessions(limit?: number): number;
|
package/dist/session/log.js
CHANGED
|
@@ -8,10 +8,9 @@
|
|
|
8
8
|
*
|
|
9
9
|
* FASTCODE_SESSION_LOG=0 disable logging
|
|
10
10
|
* FASTCODE_SESSION_CACHE_MB=N sessions cache cap in MB (default 256)
|
|
11
|
-
* FASTCODE_FSYNC=0|1 force checkpoint fsync off/on
|
|
12
11
|
*/
|
|
13
|
-
import { appendFileSync,
|
|
14
|
-
import {
|
|
12
|
+
import { appendFileSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync } from "node:fs";
|
|
13
|
+
import { join } from "node:path";
|
|
15
14
|
import { getPaths } from "../config/paths.js";
|
|
16
15
|
const NL = String.fromCharCode(10);
|
|
17
16
|
export function sessionCacheLimitBytes() {
|
|
@@ -21,76 +20,19 @@ export function sessionCacheLimitBytes() {
|
|
|
21
20
|
export function loggingEnabled() {
|
|
22
21
|
return process.env["FASTCODE_SESSION_LOG"] !== "0";
|
|
23
22
|
}
|
|
24
|
-
export function projectionPath(file) {
|
|
25
|
-
return file.replace(/[.]jsonl$/, ".projection.json");
|
|
26
|
-
}
|
|
27
|
-
export function fsyncMode() {
|
|
28
|
-
const raw = (process.env["FASTCODE_FSYNC"] ?? "").trim().toLowerCase();
|
|
29
|
-
if (["1", "true", "yes", "on"].includes(raw))
|
|
30
|
-
return "on";
|
|
31
|
-
if (["0", "false", "no", "off"].includes(raw))
|
|
32
|
-
return "off";
|
|
33
|
-
return "auto";
|
|
34
|
-
}
|
|
35
|
-
function onSharedStorage(root) {
|
|
36
|
-
const normalized = root.replace(/\\/g, "/");
|
|
37
|
-
return normalized === "/sdcard"
|
|
38
|
-
|| normalized.startsWith("/sdcard/")
|
|
39
|
-
|| normalized === "/storage/emulated"
|
|
40
|
-
|| normalized.startsWith("/storage/emulated/");
|
|
41
|
-
}
|
|
42
|
-
export function fsyncEnabled(type = "checkpoint") {
|
|
43
|
-
if (type !== "checkpoint")
|
|
44
|
-
return false;
|
|
45
|
-
const mode = fsyncMode();
|
|
46
|
-
if (mode === "on")
|
|
47
|
-
return true;
|
|
48
|
-
if (mode === "off")
|
|
49
|
-
return false;
|
|
50
|
-
return onSharedStorage(getPaths().root);
|
|
51
|
-
}
|
|
52
|
-
function writeLine(file, line, type) {
|
|
53
|
-
if (!fsyncEnabled(type)) {
|
|
54
|
-
appendFileSync(file, line, "utf8");
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
const fd = openSync(file, "a");
|
|
58
|
-
try {
|
|
59
|
-
writeSync(fd, line);
|
|
60
|
-
fsyncSync(fd);
|
|
61
|
-
}
|
|
62
|
-
finally {
|
|
63
|
-
closeSync(fd);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
function countLines(file) {
|
|
67
|
-
if (!existsSync(file))
|
|
68
|
-
return 0;
|
|
69
|
-
try {
|
|
70
|
-
return readFileSync(file, "utf8").split(NL).filter(Boolean).length;
|
|
71
|
-
}
|
|
72
|
-
catch {
|
|
73
|
-
return 0;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
23
|
function newId() {
|
|
77
24
|
return new Date().toISOString().replace(/[:.]/g, "-") + "-" + Math.random().toString(36).slice(2, 6);
|
|
78
25
|
}
|
|
79
26
|
function openLog(id, file, meta) {
|
|
80
27
|
let closed = false;
|
|
81
|
-
let seq = countLines(file);
|
|
82
28
|
const append = (entry) => {
|
|
83
29
|
if (closed || !loggingEnabled())
|
|
84
|
-
return
|
|
85
|
-
const next = seq + 1;
|
|
86
|
-
const line = JSON.stringify({ ts: Date.now(), seq: next, ...entry }) + NL;
|
|
30
|
+
return;
|
|
87
31
|
try {
|
|
88
|
-
|
|
89
|
-
seq = next;
|
|
90
|
-
return next;
|
|
32
|
+
appendFileSync(file, JSON.stringify({ ts: Date.now(), ...entry }) + NL, "utf8");
|
|
91
33
|
}
|
|
92
34
|
catch {
|
|
93
|
-
|
|
35
|
+
// A read-only or full filesystem must not break the TUI.
|
|
94
36
|
}
|
|
95
37
|
};
|
|
96
38
|
append({ type: "session_start", id, cwd: process.cwd(), ...meta });
|
|
@@ -98,9 +40,6 @@ function openLog(id, file, meta) {
|
|
|
98
40
|
id,
|
|
99
41
|
file,
|
|
100
42
|
append,
|
|
101
|
-
count() {
|
|
102
|
-
return seq;
|
|
103
|
-
},
|
|
104
43
|
close() {
|
|
105
44
|
append({ type: "session_end" });
|
|
106
45
|
closed = true;
|
|
@@ -120,10 +59,10 @@ export function createSessionLog(meta = {}) {
|
|
|
120
59
|
const file = join(sessions, id + ".jsonl");
|
|
121
60
|
return openLog(id, file, meta);
|
|
122
61
|
}
|
|
123
|
-
export function openSessionLog(file
|
|
62
|
+
export function openSessionLog(file) {
|
|
124
63
|
const { sessions } = getPaths();
|
|
125
64
|
mkdirSync(sessions, { recursive: true });
|
|
126
|
-
return openLog(undefined, existsSync(file) ? file : join(sessions, file),
|
|
65
|
+
return openLog(undefined, existsSync(file) ? file : join(sessions, file), {});
|
|
127
66
|
}
|
|
128
67
|
export function listSessions() {
|
|
129
68
|
const { sessions } = getPaths();
|
|
@@ -140,8 +79,7 @@ export function listSessions() {
|
|
|
140
79
|
const info = statSync(file);
|
|
141
80
|
bytes = info.size;
|
|
142
81
|
modified = info.mtime.toISOString();
|
|
143
|
-
messages = readFileSync(file, "utf8").split(NL).filter((line) => line.includes('"type":"
|
|
144
|
-
(line.includes('"type":"message"') && line.includes('"role":"user"'))).length;
|
|
82
|
+
messages = readFileSync(file, "utf8").split(NL).filter((line) => line.includes('"type":"message"')).length;
|
|
145
83
|
}
|
|
146
84
|
catch {
|
|
147
85
|
// unreadable: report what we have
|
|
@@ -174,152 +112,18 @@ export function readSession(idOrFile) {
|
|
|
174
112
|
}
|
|
175
113
|
export function loadSessionMessages(idOrFile) {
|
|
176
114
|
return readSession(idOrFile)
|
|
177
|
-
.filter((entry) =>
|
|
178
|
-
.map((entry) => ({
|
|
179
|
-
role: entry.type === "assistant_raw" ? "assistant" : entry.role ?? "user",
|
|
180
|
-
content: entry.content,
|
|
181
|
-
}));
|
|
115
|
+
.filter((entry) => entry.type === "message" && typeof entry.content === "string")
|
|
116
|
+
.map((entry) => ({ role: entry.role, content: entry.content }));
|
|
182
117
|
}
|
|
183
118
|
export function latestSessionFile() {
|
|
184
119
|
const all = listSessions();
|
|
185
120
|
return all.length > 0 ? all[0].file : undefined;
|
|
186
121
|
}
|
|
187
|
-
function summarize(id, file, entries) {
|
|
188
|
-
let cwd = "";
|
|
189
|
-
let providerId = "";
|
|
190
|
-
let model = "";
|
|
191
|
-
let turns = 0;
|
|
192
|
-
let activeFiles = [];
|
|
193
|
-
let messages = 0;
|
|
194
|
-
let lastTs = 0;
|
|
195
|
-
for (const entry of entries) {
|
|
196
|
-
if (typeof entry.ts === "number")
|
|
197
|
-
lastTs = entry.ts;
|
|
198
|
-
if (entry.type === "session_start") {
|
|
199
|
-
cwd = typeof entry.cwd === "string" ? entry.cwd : cwd;
|
|
200
|
-
providerId = typeof entry.providerId === "string" ? entry.providerId : providerId;
|
|
201
|
-
model = typeof entry.model === "string" ? entry.model : model;
|
|
202
|
-
}
|
|
203
|
-
else if (entry.type === "message") {
|
|
204
|
-
messages += 1;
|
|
205
|
-
}
|
|
206
|
-
else if (entry.type === "checkpoint") {
|
|
207
|
-
cwd = typeof entry.cwd === "string" ? entry.cwd : cwd;
|
|
208
|
-
providerId = typeof entry.providerId === "string" ? entry.providerId : providerId;
|
|
209
|
-
model = typeof entry.model === "string" ? entry.model : model;
|
|
210
|
-
if (typeof entry.turn === "number")
|
|
211
|
-
turns = entry.turn;
|
|
212
|
-
if (Array.isArray(entry.activeFiles))
|
|
213
|
-
activeFiles = entry.activeFiles;
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
return { id, file, cwd, providerId, model, turns, activeFiles, messages, lastTs };
|
|
217
|
-
}
|
|
218
|
-
function readLastEntry(file) {
|
|
219
|
-
let size = 0;
|
|
220
|
-
try {
|
|
221
|
-
size = statSync(file).size;
|
|
222
|
-
}
|
|
223
|
-
catch {
|
|
224
|
-
return undefined;
|
|
225
|
-
}
|
|
226
|
-
if (size === 0)
|
|
227
|
-
return undefined;
|
|
228
|
-
const length = Math.min(size, 64 * 1024);
|
|
229
|
-
const fd = openSync(file, "r");
|
|
230
|
-
try {
|
|
231
|
-
const buffer = Buffer.alloc(length);
|
|
232
|
-
readSync(fd, buffer, 0, length, size - length);
|
|
233
|
-
const lines = buffer.toString("utf8").trimEnd().split(NL);
|
|
234
|
-
for (let i = lines.length - 1; i >= 0; i -= 1) {
|
|
235
|
-
if (!lines[i])
|
|
236
|
-
continue;
|
|
237
|
-
try {
|
|
238
|
-
return JSON.parse(lines[i]);
|
|
239
|
-
}
|
|
240
|
-
catch {
|
|
241
|
-
return { type: "unparsable_tail" };
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
return undefined;
|
|
245
|
-
}
|
|
246
|
-
finally {
|
|
247
|
-
closeSync(fd);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
export function findUnclosedSessions() {
|
|
251
|
-
const { sessions } = getPaths();
|
|
252
|
-
if (!existsSync(sessions))
|
|
253
|
-
return [];
|
|
254
|
-
const files = readdirSync(sessions)
|
|
255
|
-
.filter((name) => name.endsWith(".jsonl"))
|
|
256
|
-
.map((name) => {
|
|
257
|
-
const file = join(sessions, name);
|
|
258
|
-
let modified = 0;
|
|
259
|
-
try {
|
|
260
|
-
modified = statSync(file).mtimeMs;
|
|
261
|
-
}
|
|
262
|
-
catch {
|
|
263
|
-
// unreadable
|
|
264
|
-
}
|
|
265
|
-
return { name, file, modified };
|
|
266
|
-
})
|
|
267
|
-
.sort((a, b) => b.modified - a.modified);
|
|
268
|
-
const out = [];
|
|
269
|
-
for (const entry of files) {
|
|
270
|
-
const last = readLastEntry(entry.file);
|
|
271
|
-
if (!last || last.type === "session_end")
|
|
272
|
-
continue;
|
|
273
|
-
let entries;
|
|
274
|
-
try {
|
|
275
|
-
entries = readSession(entry.file);
|
|
276
|
-
}
|
|
277
|
-
catch {
|
|
278
|
-
continue;
|
|
279
|
-
}
|
|
280
|
-
if (entries.length === 0 || !entries.some((item) => item.type === "session_start"))
|
|
281
|
-
continue;
|
|
282
|
-
out.push(summarize(entry.name.replace(/[.]jsonl$/, ""), entry.file, entries));
|
|
283
|
-
}
|
|
284
|
-
return out;
|
|
285
|
-
}
|
|
286
|
-
export function latestUnclosedSession() {
|
|
287
|
-
return findUnclosedSessions()[0];
|
|
288
|
-
}
|
|
289
|
-
function ensureProjection(file) {
|
|
290
|
-
const target = projectionPath(file);
|
|
291
|
-
if (existsSync(target))
|
|
292
|
-
return;
|
|
293
|
-
const entries = readSession(file);
|
|
294
|
-
if (entries.length === 0)
|
|
295
|
-
return;
|
|
296
|
-
const summary = summarize(basename(file).replace(/[.]jsonl$/, ""), file, entries);
|
|
297
|
-
const lastUser = [...entries].reverse().find((entry) => entry.type === "message" && entry.role === "user");
|
|
298
|
-
const lastAssistant = [...entries].reverse().find((entry) => entry.type === "message" && entry.role === "assistant");
|
|
299
|
-
const payload = {
|
|
300
|
-
version: 1,
|
|
301
|
-
kind: "pruned_session",
|
|
302
|
-
source: basename(file),
|
|
303
|
-
createdAt: new Date().toISOString(),
|
|
304
|
-
summary: {
|
|
305
|
-
cwd: summary.cwd,
|
|
306
|
-
providerId: summary.providerId,
|
|
307
|
-
model: summary.model,
|
|
308
|
-
turns: summary.turns,
|
|
309
|
-
messages: summary.messages,
|
|
310
|
-
activeFiles: summary.activeFiles.slice(0, 200),
|
|
311
|
-
lastUser: typeof lastUser?.content === "string" ? lastUser.content.slice(0, 2000) : "",
|
|
312
|
-
lastAssistant: typeof lastAssistant?.content === "string" ? lastAssistant.content.slice(0, 2000) : "",
|
|
313
|
-
},
|
|
314
|
-
};
|
|
315
|
-
writeFileSync(target, JSON.stringify(payload, null, 2), "utf8");
|
|
316
|
-
}
|
|
317
122
|
export function pruneSessions(limit = sessionCacheLimitBytes()) {
|
|
318
123
|
const all = listSessions();
|
|
319
124
|
let total = all.reduce((sum, entry) => sum + entry.bytes, 0);
|
|
320
125
|
for (let i = all.length - 1; i >= 0 && total > limit; i -= 1) {
|
|
321
126
|
try {
|
|
322
|
-
ensureProjection(all[i].file);
|
|
323
127
|
rmSync(all[i].file, { force: true });
|
|
324
128
|
total -= all[i].bytes;
|
|
325
129
|
}
|