@link-assistant/agent 0.27.0 → 0.27.1
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 +47 -5
- package/package.json +41 -42
- package/src/cli/argv.ts +1 -1
- package/src/cli/cmd/run.ts +7 -1
- package/src/cli/continuous-mode.js +38 -12
- package/src/cli/event-handler.js +3 -1
- package/src/cli/model-config.js +20 -4
- package/src/cli/run-options.js +144 -78
- package/src/config/config.ts +306 -105
- package/src/config/defaults.ts +13 -5
- package/src/config/file-config.ts +16 -0
- package/src/file/ripgrep.ts +38 -5
- package/src/file/time.ts +86 -9
- package/src/index.js +39 -33
- package/src/mcp/index.ts +370 -106
- package/src/permission/index.ts +22 -0
- package/src/project/instance.ts +5 -1
- package/src/project/project.ts +35 -2
- package/src/provider/free-tier-error.ts +1 -1
- package/src/provider/kilo-deprecation.ts +30 -0
- package/src/provider/kilo.ts +25 -7
- package/src/provider/provider.ts +53 -22
- package/src/provider/retry-fetch.ts +5 -0
- package/src/provider/transform.ts +139 -17
- package/src/session/compaction.ts +18 -2
- package/src/session/index.ts +30 -3
- package/src/session/message-v2.ts +318 -32
- package/src/session/processor.ts +274 -140
- package/src/session/prompt.ts +154 -128
- package/src/session/retry.ts +26 -13
- package/src/session/summary.ts +4 -1
- package/src/tool/bash.ts +232 -45
- package/src/tool/bash.txt +1 -1
- package/src/tool/codesearch.ts +15 -78
- package/src/tool/edit.ts +111 -30
- package/src/tool/glob.ts +2 -1
- package/src/tool/grep.ts +175 -57
- package/src/tool/ls.ts +2 -1
- package/src/tool/multiedit.ts +3 -1
- package/src/tool/read.ts +169 -41
- package/src/tool/task.ts +26 -18
- package/src/tool/tool.ts +4 -1
- package/src/tool/webfetch.ts +68 -56
- package/src/tool/webfetch.txt +4 -4
- package/src/tool/websearch.ts +20 -75
- package/src/tool/websearch.txt +2 -0
- package/src/tool/write.ts +23 -6
- package/src/util/bom.ts +32 -0
- package/src/util/exa-mcp.ts +82 -0
- package/src/util/legacy-error-names.ts +39 -0
- package/src/util/read-bounded.ts +32 -0
- package/src/util/sse-usage-extractor.ts +67 -13
- package/src/util/timeout.ts +3 -4
- package/src/util/verbose-fetch.ts +40 -1
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ This is an MVP implementation of an OpenCode-compatible CLI agent, focused on ma
|
|
|
24
24
|
|
|
25
25
|
- ✅ **JSON Input/Output**: Compatible with `opencode run --format json`
|
|
26
26
|
- ✅ **Plain Text Input**: Also accepts plain text messages (auto-converted to JSON format)
|
|
27
|
-
- ✅ **Flexible Model Selection**: Defaults to free Kilo Nemotron 3
|
|
27
|
+
- ✅ **Flexible Model Selection**: Defaults to free Kilo Nemotron 3 Ultra (Kilo authentication recommended), supports every [models.dev](https://models.dev) provider OpenCode supports ([full list](../docs/providers.md)), OpenCode's subscription logins, [gpt4free](../docs/gpt4free.md), Pollinations, local servers, [Formal AI](../docs/formal-ai.md) and [Claude OAuth](../docs/claude-oauth.md), with [live model discovery](../docs/model-discovery.md)
|
|
28
28
|
- ✅ **No Restrictions**: Fully unrestricted file system and command execution access (no sandbox)
|
|
29
29
|
- ✅ **Minimal Footprint**: Built with Bun.sh for maximum efficiency
|
|
30
30
|
- ✅ **Full Tool Support**: 13 tools including websearch, codesearch, batch - all enabled by default
|
|
@@ -169,7 +169,7 @@ echo '{"message":"hi"}' | agent
|
|
|
169
169
|
**With custom model:**
|
|
170
170
|
|
|
171
171
|
```bash
|
|
172
|
-
echo "hi" | agent --model kilo/nemotron-3-
|
|
172
|
+
echo "hi" | agent --model kilo/nemotron-3-ultra-free
|
|
173
173
|
```
|
|
174
174
|
|
|
175
175
|
### More Examples
|
|
@@ -190,11 +190,10 @@ echo '{"message":"run command","tools":[{"name":"bash","params":{"command":"ls -
|
|
|
190
190
|
**Using different models:**
|
|
191
191
|
|
|
192
192
|
```bash
|
|
193
|
-
# Default model (free Nemotron 3
|
|
193
|
+
# Default model (free Nemotron 3 Ultra)
|
|
194
194
|
echo "hi" | agent
|
|
195
195
|
|
|
196
196
|
# Built-in free models (authenticate with agent auth login or KILO_API_KEY)
|
|
197
|
-
echo "hi" | agent --model kilo/nemotron-3-super-free
|
|
198
197
|
echo "hi" | agent --model kilo/nemotron-3-ultra-free
|
|
199
198
|
echo "hi" | agent --model kilo/nemotron-3.5-lightning-free
|
|
200
199
|
|
|
@@ -285,7 +284,7 @@ agent [options]
|
|
|
285
284
|
|
|
286
285
|
Options:
|
|
287
286
|
--model Model to use in format providerID/modelID
|
|
288
|
-
Default: kilo/nemotron-3-
|
|
287
|
+
Default: kilo/nemotron-3-ultra-free
|
|
289
288
|
--json-standard JSON output format standard
|
|
290
289
|
Choices: "opencode" (default), "claude" (experimental)
|
|
291
290
|
--output-format Alias for JSON output format
|
|
@@ -311,6 +310,42 @@ Permission Options:
|
|
|
311
310
|
invoked via batch.
|
|
312
311
|
Env: LINK_ASSISTANT_AGENT_DISABLE_TOOLS
|
|
313
312
|
|
|
313
|
+
Compatibility Options (issue #335):
|
|
314
|
+
Each option restores behaviour from before the OpenCode stability sync, or
|
|
315
|
+
tunes a new limit. Every option also has a LINK_ASSISTANT_AGENT_* env var.
|
|
316
|
+
--bash-shell <auto|legacy|path> Shell for the bash tool. "auto" (default):
|
|
317
|
+
$SHELL if POSIX, else bash, else /bin/sh;
|
|
318
|
+
"legacy": /bin/sh as before.
|
|
319
|
+
Env: LINK_ASSISTANT_AGENT_BASH_SHELL
|
|
320
|
+
--legacy-tool-output Empty edit/write output, head-truncated bash
|
|
321
|
+
output, empty read past EOF (as before).
|
|
322
|
+
Env: LINK_ASSISTANT_AGENT_LEGACY_TOOL_OUTPUT
|
|
323
|
+
--legacy-edit-matching Loose fuzzy edit matching; an empty oldString
|
|
324
|
+
overwrites an existing file (as before).
|
|
325
|
+
Env: LINK_ASSISTANT_AGENT_LEGACY_EDIT_MATCHING
|
|
326
|
+
--glob-follow-symlinks Follow symlinked directories in glob/ls.
|
|
327
|
+
Env: LINK_ASSISTANT_AGENT_GLOB_FOLLOW_SYMLINKS
|
|
328
|
+
--no-grep-hidden Do not search hidden files in grep.
|
|
329
|
+
Env: LINK_ASSISTANT_AGENT_GREP_HIDDEN=false
|
|
330
|
+
--grep-timeout-ms <ms> Timeout of one grep search (default 30000,
|
|
331
|
+
0 = none). Env: LINK_ASSISTANT_AGENT_GREP_TIMEOUT_MS
|
|
332
|
+
--read-max-lines <n> Max lines per read call (default 2000,
|
|
333
|
+
0 = no cap). Env: LINK_ASSISTANT_AGENT_READ_MAX_LINES
|
|
334
|
+
--read-max-bytes <n> Max bytes per read call (default 51200,
|
|
335
|
+
0 = no cap). Env: LINK_ASSISTANT_AGENT_READ_MAX_BYTES
|
|
336
|
+
--legacy-error-names Report ContextOverflowError as a
|
|
337
|
+
non-retryable APIError in JSON output.
|
|
338
|
+
Env: LINK_ASSISTANT_AGENT_LEGACY_ERROR_NAMES
|
|
339
|
+
--legacy-token-usage tokens.output includes reasoning tokens.
|
|
340
|
+
Env: LINK_ASSISTANT_AGENT_LEGACY_TOKEN_USAGE
|
|
341
|
+
--legacy-loop-exit End the turn on a "stop" finish even when
|
|
342
|
+
tools ran in that step.
|
|
343
|
+
Env: LINK_ASSISTANT_AGENT_LEGACY_LOOP_EXIT
|
|
344
|
+
--mcp-connect-timeout <ms> Default MCP connect/initialize timeout
|
|
345
|
+
(default 30000, 0 = none). Per server:
|
|
346
|
+
"connect_timeout" in the mcp config.
|
|
347
|
+
Env: LINK_ASSISTANT_AGENT_MCP_CONNECT_TIMEOUT
|
|
348
|
+
|
|
314
349
|
Stdin Mode Options:
|
|
315
350
|
-p, --prompt Direct prompt (bypasses stdin reading)
|
|
316
351
|
--disable-stdin Disable stdin streaming (requires --prompt)
|
|
@@ -509,6 +544,13 @@ This will create a configuration file at `~/.config/link-assistant-agent/opencod
|
|
|
509
544
|
}
|
|
510
545
|
```
|
|
511
546
|
|
|
547
|
+
**MCP timeouts:** each server entry accepts `timeout` (ms for listing tools,
|
|
548
|
+
default 5000; unchanged meaning) and `connect_timeout` (ms for starting the
|
|
549
|
+
server and finishing the `initialize` handshake, default
|
|
550
|
+
`--mcp-connect-timeout`, 30000, or `timeout` if larger; `0` disables the
|
|
551
|
+
bound). A server that does not connect in time is reported as `failed`
|
|
552
|
+
instead of blocking the session.
|
|
553
|
+
|
|
512
554
|
**Available Playwright Tools:**
|
|
513
555
|
|
|
514
556
|
Once configured, the agent gains access to 22+ browser automation tools:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@link-assistant/agent",
|
|
3
|
-
"version": "0.27.
|
|
3
|
+
"version": "0.27.1",
|
|
4
4
|
"description": "A minimal, public domain AI CLI agent compatible with OpenCode's JSON interface. Bun-only runtime.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -51,65 +51,65 @@
|
|
|
51
51
|
"LICENSE"
|
|
52
52
|
],
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@agentclientprotocol/sdk": "^2.0
|
|
55
|
-
"@ai-sdk/alibaba": "^2.0.
|
|
56
|
-
"@ai-sdk/amazon-bedrock": "^5.0.
|
|
57
|
-
"@ai-sdk/anthropic": "^4.0.
|
|
58
|
-
"@ai-sdk/azure": "^4.0.
|
|
59
|
-
"@ai-sdk/cerebras": "^3.0.
|
|
60
|
-
"@ai-sdk/cohere": "^4.0.
|
|
61
|
-
"@ai-sdk/deepinfra": "^3.0.
|
|
62
|
-
"@ai-sdk/deepseek": "^3.0.
|
|
63
|
-
"@ai-sdk/fireworks": "^3.0.
|
|
64
|
-
"@ai-sdk/gateway": "^4.0.
|
|
65
|
-
"@ai-sdk/google": "^4.0.
|
|
66
|
-
"@ai-sdk/google-vertex": "^5.0.
|
|
67
|
-
"@ai-sdk/groq": "^4.0.
|
|
68
|
-
"@ai-sdk/mcp": "^2.0.
|
|
69
|
-
"@ai-sdk/mistral": "^4.0.
|
|
70
|
-
"@ai-sdk/openai": "^4.0.
|
|
71
|
-
"@ai-sdk/openai-compatible": "^3.0.
|
|
72
|
-
"@ai-sdk/perplexity": "^5.0.
|
|
73
|
-
"@ai-sdk/provider": "^4.0.
|
|
74
|
-
"@ai-sdk/togetherai": "^3.0.
|
|
75
|
-
"@ai-sdk/xai": "^5.0.
|
|
54
|
+
"@agentclientprotocol/sdk": "^2.4.0",
|
|
55
|
+
"@ai-sdk/alibaba": "^2.0.81",
|
|
56
|
+
"@ai-sdk/amazon-bedrock": "^5.0.131",
|
|
57
|
+
"@ai-sdk/anthropic": "^4.0.95",
|
|
58
|
+
"@ai-sdk/azure": "^4.0.115",
|
|
59
|
+
"@ai-sdk/cerebras": "^3.0.83",
|
|
60
|
+
"@ai-sdk/cohere": "^4.0.74",
|
|
61
|
+
"@ai-sdk/deepinfra": "^3.0.83",
|
|
62
|
+
"@ai-sdk/deepseek": "^3.0.78",
|
|
63
|
+
"@ai-sdk/fireworks": "^3.0.86",
|
|
64
|
+
"@ai-sdk/gateway": "^4.0.134",
|
|
65
|
+
"@ai-sdk/google": "^4.0.110",
|
|
66
|
+
"@ai-sdk/google-vertex": "^5.0.130",
|
|
67
|
+
"@ai-sdk/groq": "^4.0.75",
|
|
68
|
+
"@ai-sdk/mcp": "^2.0.89",
|
|
69
|
+
"@ai-sdk/mistral": "^4.0.78",
|
|
70
|
+
"@ai-sdk/openai": "^4.0.107",
|
|
71
|
+
"@ai-sdk/openai-compatible": "^3.0.83",
|
|
72
|
+
"@ai-sdk/perplexity": "^5.0.25",
|
|
73
|
+
"@ai-sdk/provider": "^4.0.35",
|
|
74
|
+
"@ai-sdk/togetherai": "^3.0.84",
|
|
75
|
+
"@ai-sdk/xai": "^5.0.37",
|
|
76
76
|
"@clack/prompts": "^1.8.1",
|
|
77
|
-
"@hono/standard-validator": "^0.4.
|
|
77
|
+
"@hono/standard-validator": "^0.4.1",
|
|
78
78
|
"@hono/zod-validator": "^0.9.1",
|
|
79
|
-
"@modelcontextprotocol/sdk": "^1.32.
|
|
79
|
+
"@modelcontextprotocol/sdk": "^1.32.2",
|
|
80
80
|
"@octokit/graphql": "^9.0.5",
|
|
81
81
|
"@octokit/rest": "^22.0.1",
|
|
82
82
|
"@openauthjs/openauth": "^0.4.3",
|
|
83
|
-
"@opencode-ai/sdk": "^1.19.
|
|
83
|
+
"@opencode-ai/sdk": "^1.19.5",
|
|
84
84
|
"@openrouter/ai-sdk-provider": "^3.1.0",
|
|
85
|
-
"@opentui/core": "^0.
|
|
86
|
-
"@opentui/solid": "^0.
|
|
85
|
+
"@opentui/core": "^0.8.1",
|
|
86
|
+
"@opentui/solid": "^0.8.1",
|
|
87
87
|
"@parcel/watcher": "^2.6.0",
|
|
88
88
|
"@solid-primitives/event-bus": "^1.1.4",
|
|
89
|
-
"@standard-community/standard-json": "^0.
|
|
89
|
+
"@standard-community/standard-json": "^0.4.0",
|
|
90
90
|
"@standard-community/standard-openapi": "^0.2.11",
|
|
91
91
|
"@zip.js/zip.js": "^2.24.0",
|
|
92
|
-
"ai": "^7.0.
|
|
92
|
+
"ai": "^7.0.161",
|
|
93
93
|
"chokidar": "^6.0.0",
|
|
94
94
|
"clipboardy": "^5.3.2",
|
|
95
|
-
"command-stream": "^2.
|
|
95
|
+
"command-stream": "^2.6.0",
|
|
96
96
|
"decimal.js": "^10.6.0",
|
|
97
97
|
"diff": "^9.0.0",
|
|
98
98
|
"fuzzysort": "^4.0.2",
|
|
99
|
-
"glob": "^
|
|
100
|
-
"google-auth-library": "^11.3.
|
|
99
|
+
"glob": "^14.0.3",
|
|
100
|
+
"google-auth-library": "^11.3.2",
|
|
101
101
|
"gpt-tokenizer": "^4.1.0",
|
|
102
102
|
"gray-matter": "^4.0.3",
|
|
103
|
-
"hono": "^4.13.
|
|
103
|
+
"hono": "^4.13.16",
|
|
104
104
|
"hono-openapi": "^1.5.0",
|
|
105
|
-
"ignore": "^7.0.
|
|
105
|
+
"ignore": "^7.0.14",
|
|
106
106
|
"jsonc-parser": "^3.3.1",
|
|
107
107
|
"lino-arguments": "^0.3.0",
|
|
108
|
-
"lino-objects-codec": "^0.9.
|
|
108
|
+
"lino-objects-codec": "^0.9.5",
|
|
109
109
|
"log-lazy": "^1.0.4",
|
|
110
|
-
"minimatch": "^
|
|
111
|
-
"remeda": "^2.
|
|
112
|
-
"solid-js": "1.9.
|
|
110
|
+
"minimatch": "^11.0.4",
|
|
111
|
+
"remeda": "^2.58.0",
|
|
112
|
+
"solid-js": "^1.9.18",
|
|
113
113
|
"strip-ansi": "^7.2.0",
|
|
114
114
|
"test-anywhere": "^0.9.1",
|
|
115
115
|
"tree-sitter-bash": "^0.25.1",
|
|
@@ -125,7 +125,7 @@
|
|
|
125
125
|
"devDependencies": {
|
|
126
126
|
"@changesets/cli": "^3.0.3",
|
|
127
127
|
"@eslint/js": "^10.0.1",
|
|
128
|
-
"eslint": "^10.
|
|
128
|
+
"eslint": "^10.14.0",
|
|
129
129
|
"eslint-config-prettier": "^10.1.8",
|
|
130
130
|
"eslint-plugin-prettier": "^5.5.7",
|
|
131
131
|
"eslint-plugin-promise": "^7.3.0",
|
|
@@ -151,11 +151,10 @@
|
|
|
151
151
|
"node-pty@1.1.0": true
|
|
152
152
|
},
|
|
153
153
|
"overrides": {
|
|
154
|
-
"seroval": "^1.6.9",
|
|
155
154
|
"undici": "^7.16.0"
|
|
156
155
|
},
|
|
157
156
|
"dependencyPins": {
|
|
158
|
-
"
|
|
157
|
+
"lino-arguments": "https://github.com/link-foundation/lino-arguments/issues/50",
|
|
159
158
|
"web-tree-sitter": "https://github.com/anomalyco/opentui/issues/1550"
|
|
160
159
|
}
|
|
161
160
|
}
|
package/src/cli/argv.ts
CHANGED
|
@@ -105,7 +105,7 @@ export function getCompactionSafetyMarginFromProcessArgv(): string | null {
|
|
|
105
105
|
/**
|
|
106
106
|
* Extract --compaction-models argument directly from process.argv
|
|
107
107
|
* The value is a links notation references sequence, e.g.:
|
|
108
|
-
* "(kilo/nemotron-3-
|
|
108
|
+
* "(kilo/nemotron-3-ultra-free kilo/nemotron-3.5-lightning-free same)"
|
|
109
109
|
* @returns The compaction models argument from CLI or null if not found
|
|
110
110
|
* @see https://github.com/link-assistant/agent/issues/232
|
|
111
111
|
*/
|
package/src/cli/cmd/run.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { EOL } from 'os';
|
|
|
9
9
|
import { select } from '@clack/prompts';
|
|
10
10
|
import { createOpencodeClient, type OpencodeClient } from '@opencode-ai/sdk';
|
|
11
11
|
import { Provider } from '../../provider/provider';
|
|
12
|
+
import { legacyErrorObject } from '../../util/legacy-error-names';
|
|
12
13
|
|
|
13
14
|
const TOOL: Record<string, [string, string]> = {
|
|
14
15
|
todowrite: ['Todo', UI.Style.TEXT_WARNING_BOLD],
|
|
@@ -267,7 +268,12 @@ export const RunCommand = cmd({
|
|
|
267
268
|
// Always include the human-readable string alongside the
|
|
268
269
|
// machine-readable object so consumers never print
|
|
269
270
|
// "[object Object]" (#289).
|
|
270
|
-
if (
|
|
271
|
+
if (
|
|
272
|
+
outputJsonEvent('error', {
|
|
273
|
+
message: err,
|
|
274
|
+
error: legacyErrorObject(props.error),
|
|
275
|
+
})
|
|
276
|
+
)
|
|
271
277
|
continue;
|
|
272
278
|
UI.error(err);
|
|
273
279
|
}
|
|
@@ -356,6 +356,10 @@ export async function runContinuousServerMode(
|
|
|
356
356
|
const parts = [{ type: 'text', text: messageText }];
|
|
357
357
|
|
|
358
358
|
// Create a promise to wait for this message to complete
|
|
359
|
+
// `stopIdleWait` ends the wait when the prompt settles without ever
|
|
360
|
+
// going idle (it can throw before the loop starts); otherwise the
|
|
361
|
+
// subscription leaked and the input queue hung (issue #335).
|
|
362
|
+
let stopIdleWait = () => {};
|
|
359
363
|
const messagePromise = new Promise((resolve) => {
|
|
360
364
|
const checkIdle = Bus.subscribeAll((event) => {
|
|
361
365
|
if (
|
|
@@ -366,6 +370,10 @@ export async function runContinuousServerMode(
|
|
|
366
370
|
resolve();
|
|
367
371
|
}
|
|
368
372
|
});
|
|
373
|
+
stopIdleWait = () => {
|
|
374
|
+
checkIdle();
|
|
375
|
+
resolve();
|
|
376
|
+
};
|
|
369
377
|
});
|
|
370
378
|
|
|
371
379
|
// Send message
|
|
@@ -383,21 +391,28 @@ export async function runContinuousServerMode(
|
|
|
383
391
|
temperature,
|
|
384
392
|
}),
|
|
385
393
|
}
|
|
386
|
-
)
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
+
)
|
|
395
|
+
// Read the reply to the end: it completes only after the prompt has
|
|
396
|
+
// returned (and released the connection), successful or not.
|
|
397
|
+
.then((response) => response.text())
|
|
398
|
+
.catch((error) => {
|
|
399
|
+
hasError = true;
|
|
400
|
+
eventHandler.output({
|
|
401
|
+
type: 'error',
|
|
402
|
+
timestamp: Date.now(),
|
|
403
|
+
sessionID,
|
|
404
|
+
message: errorText(error),
|
|
405
|
+
error: error instanceof Error ? error.message : String(error),
|
|
406
|
+
});
|
|
394
407
|
});
|
|
395
|
-
});
|
|
396
408
|
|
|
397
409
|
// See the direct-mode comment below: the request rejection must be
|
|
398
|
-
// observed before the process can exit (#290).
|
|
399
|
-
|
|
410
|
+
// observed before the process can exit (#290). `session.idle` is
|
|
411
|
+
// published before the reply is written, so once the reply is complete
|
|
412
|
+
// the idle wait can stop.
|
|
400
413
|
await requestPromise;
|
|
414
|
+
stopIdleWait();
|
|
415
|
+
await messagePromise;
|
|
401
416
|
isProcessing = false;
|
|
402
417
|
|
|
403
418
|
// Process next pending message if any
|
|
@@ -582,6 +597,10 @@ export async function runContinuousDirectMode(
|
|
|
582
597
|
const parts = [{ type: 'text', text: messageText }];
|
|
583
598
|
|
|
584
599
|
// Create a promise to wait for this message to complete
|
|
600
|
+
// `stopIdleWait` ends the wait when the prompt settles without ever
|
|
601
|
+
// going idle (it can throw before the loop starts); otherwise the
|
|
602
|
+
// subscription leaked and the input queue hung (issue #335).
|
|
603
|
+
let stopIdleWait = () => {};
|
|
585
604
|
const messagePromise = new Promise((resolve) => {
|
|
586
605
|
const checkIdle = Bus.subscribeAll((event) => {
|
|
587
606
|
if (
|
|
@@ -592,6 +611,10 @@ export async function runContinuousDirectMode(
|
|
|
592
611
|
resolve();
|
|
593
612
|
}
|
|
594
613
|
});
|
|
614
|
+
stopIdleWait = () => {
|
|
615
|
+
checkIdle();
|
|
616
|
+
resolve();
|
|
617
|
+
};
|
|
595
618
|
});
|
|
596
619
|
|
|
597
620
|
// Send message directly
|
|
@@ -618,8 +641,11 @@ export async function runContinuousDirectMode(
|
|
|
618
641
|
// publishes `session.idle` while unwinding, so waiting only on the idle
|
|
619
642
|
// event let the process exit before the rejection handler above ran —
|
|
620
643
|
// no error record, exit code 0 (#290).
|
|
621
|
-
|
|
644
|
+
// `session.idle` is published synchronously before `prompt` settles,
|
|
645
|
+
// so after it settles the idle wait can stop.
|
|
622
646
|
await promptPromise;
|
|
647
|
+
stopIdleWait();
|
|
648
|
+
await messagePromise;
|
|
623
649
|
isProcessing = false;
|
|
624
650
|
|
|
625
651
|
// Process next pending message if any
|
package/src/cli/event-handler.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import { Bus } from '../bus/index.ts';
|
|
7
7
|
import { errorText } from '../util/error-text.ts';
|
|
8
|
+
import { legacyErrorObject } from '../util/legacy-error-names.ts';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Create a subscription for session bus events that outputs events in the selected JSON format.
|
|
@@ -142,7 +143,8 @@ export function outputBusEvent({
|
|
|
142
143
|
timestamp: Date.now(),
|
|
143
144
|
sessionID,
|
|
144
145
|
message: errorText(props.error),
|
|
145
|
-
error
|
|
146
|
+
// --legacy-error-names maps new error names to the previous ones.
|
|
147
|
+
error: legacyErrorObject(props.error),
|
|
146
148
|
});
|
|
147
149
|
}
|
|
148
150
|
}
|
package/src/cli/model-config.js
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
} from './argv.ts';
|
|
7
7
|
import { Log } from '../util/log.ts';
|
|
8
8
|
import { ExtraProviders } from '../provider/extra-providers.ts';
|
|
9
|
+
import { resolveKiloDeprecatedAlias } from '../provider/kilo-deprecation.ts';
|
|
9
10
|
import {
|
|
10
11
|
DEFAULT_PROVIDER_ID,
|
|
11
12
|
DEFAULT_MODEL_ID,
|
|
@@ -31,6 +32,17 @@ export class ModelResolutionError extends Error {
|
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Map a withdrawn built-in Kilo alias to its replacement, with a warning (#335).
|
|
37
|
+
* Other providers and model IDs are returned unchanged.
|
|
38
|
+
* @param {string} providerID
|
|
39
|
+
* @param {string} modelID
|
|
40
|
+
* @returns {string}
|
|
41
|
+
*/
|
|
42
|
+
function replaceDeprecatedModel(providerID, modelID) {
|
|
43
|
+
return providerID === 'kilo' ? resolveKiloDeprecatedAlias(modelID) : modelID;
|
|
44
|
+
}
|
|
45
|
+
|
|
34
46
|
/**
|
|
35
47
|
* Parse model config from argv. Supports "provider/model" or short "model" format.
|
|
36
48
|
* @param {object} argv - Parsed command line arguments
|
|
@@ -127,7 +139,7 @@ export async function parseModelConfig(
|
|
|
127
139
|
const modelParts = modelArg.split('/');
|
|
128
140
|
// Accept alternative spellings such as `g4f/...` for `gpt4free/...` (#334)
|
|
129
141
|
providerID = ExtraProviders.canonicalID(modelParts[0]);
|
|
130
|
-
modelID = modelParts.slice(1).join('/');
|
|
142
|
+
modelID = replaceDeprecatedModel(providerID, modelParts.slice(1).join('/'));
|
|
131
143
|
|
|
132
144
|
// Validate that providerID and modelID are not empty
|
|
133
145
|
// Do NOT fall back to defaults - if the user provided an invalid format, fail clearly (#196)
|
|
@@ -347,7 +359,7 @@ async function resolveCompactionModelEntry(
|
|
|
347
359
|
const parts = modelArg.split('/');
|
|
348
360
|
return {
|
|
349
361
|
providerID: parts[0],
|
|
350
|
-
modelID: parts.slice(1).join('/'),
|
|
362
|
+
modelID: replaceDeprecatedModel(parts[0], parts.slice(1).join('/')),
|
|
351
363
|
useSameModel: false,
|
|
352
364
|
};
|
|
353
365
|
}
|
|
@@ -399,7 +411,7 @@ async function resolveEntryWithinProvider(
|
|
|
399
411
|
}
|
|
400
412
|
return {
|
|
401
413
|
providerID: parts[0],
|
|
402
|
-
modelID: parts.slice(1).join('/'),
|
|
414
|
+
modelID: replaceDeprecatedModel(parts[0], parts.slice(1).join('/')),
|
|
403
415
|
useSameModel: false,
|
|
404
416
|
};
|
|
405
417
|
}
|
|
@@ -408,7 +420,11 @@ async function resolveEntryWithinProvider(
|
|
|
408
420
|
if (!(await Provider.hasModel(baseProviderID, modelArg))) {
|
|
409
421
|
return null;
|
|
410
422
|
}
|
|
411
|
-
return {
|
|
423
|
+
return {
|
|
424
|
+
providerID: baseProviderID,
|
|
425
|
+
modelID: replaceDeprecatedModel(baseProviderID, modelArg),
|
|
426
|
+
useSameModel: false,
|
|
427
|
+
};
|
|
412
428
|
}
|
|
413
429
|
|
|
414
430
|
/**
|