@nghyane/arcane 0.1.19 → 0.1.20
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/CHANGELOG.md +22 -0
- package/package.json +7 -7
- package/src/lsp/clients/biome-client.ts +1 -1
- package/src/lsp/edits.ts +1 -1
- package/src/lsp/index.ts +1 -1
- package/src/lsp/render.ts +3 -2
- package/src/lsp/utils.ts +1 -1
- package/src/main.ts +2 -2
- package/src/modes/components/assistant-message.ts +55 -25
- package/src/modes/components/bash-execution.ts +31 -0
- package/src/modes/components/context-group.ts +30 -3
- package/src/modes/components/model-selector.ts +35 -9
- package/src/modes/components/python-execution.ts +37 -0
- package/src/modes/components/tool-execution.ts +3 -4
- package/src/modes/controllers/event-controller.ts +43 -11
- package/src/modes/utils/ui-helpers.ts +1 -1
- package/src/patch/edit-tool.ts +13 -24
- package/src/patch/hashline.ts +105 -3
- package/src/patch/schemas.ts +2 -2
- package/src/prompts/agents/explore.md +1 -1
- package/src/prompts/agents/librarian.md +1 -1
- package/src/prompts/system/system-prompt.md +0 -1
- package/src/session/agent-session.ts +28 -27
- package/src/task/index.ts +1 -9
- package/src/task/render.ts +3 -3
- package/src/tools/ask.ts +0 -2
- package/src/tools/bash.ts +6 -3
- package/src/tools/browser.ts +1 -1
- package/src/tools/default-renderer.ts +7 -5
- package/src/tools/fetch.ts +5 -2
- package/src/tools/find-thread.ts +5 -2
- package/src/tools/find.ts +3 -3
- package/src/tools/gemini-image.ts +18 -10
- package/src/tools/github.ts +2 -2
- package/src/tools/grep.ts +3 -3
- package/src/tools/notebook.ts +8 -2
- package/src/tools/python.ts +3 -2
- package/src/tools/read-thread.ts +5 -2
- package/src/tools/read.ts +6 -3
- package/src/tools/render-mermaid.ts +3 -7
- package/src/tools/save-memory.ts +6 -3
- package/src/tools/ssh.ts +6 -3
- package/src/tools/todo-write.ts +6 -3
- package/src/tools/undo-edit.ts +5 -2
- package/src/ui/render-utils.ts +1 -1
- package/src/utils/file-mentions.ts +1 -1
- package/src/web/github-client.ts +2 -1
- package/src/web/scrapers/youtube.ts +1 -1
- package/src/web/search/render.ts +11 -2
- package/src/prompts/tools/render-mermaid.md +0 -9
package/src/tools/github.ts
CHANGED
|
@@ -429,10 +429,10 @@ export class GitHubTool implements AgentTool<typeof schema, GitHubToolDetails, T
|
|
|
429
429
|
|
|
430
430
|
async execute(
|
|
431
431
|
_toolCallId: string,
|
|
432
|
-
params:
|
|
432
|
+
params: GitHubInput,
|
|
433
433
|
signal?: AbortSignal,
|
|
434
434
|
): Promise<AgentToolResult<GitHubToolDetails>> {
|
|
435
|
-
const input = params
|
|
435
|
+
const input = params;
|
|
436
436
|
const details: GitHubToolDetails = {
|
|
437
437
|
action: input.action,
|
|
438
438
|
owner: input.owner,
|
package/src/tools/grep.ts
CHANGED
|
@@ -18,7 +18,7 @@ import { resolveToCwd } from "./path-utils";
|
|
|
18
18
|
import { ToolError } from "./tool-errors";
|
|
19
19
|
|
|
20
20
|
const grepSchema = Type.Object({
|
|
21
|
-
pattern: Type.String({ description: "Regex pattern to search for" }),
|
|
21
|
+
pattern: Type.String({ description: "Regex pattern to search for", minLength: 1 }),
|
|
22
22
|
path: Type.Optional(Type.String({ description: "Directory or file to search (default: cwd)" })),
|
|
23
23
|
glob: Type.Optional(Type.String({ description: 'Glob filter for file paths (e.g. "*.ts")' })),
|
|
24
24
|
type: Type.Optional(Type.String({ description: 'File extension filter without dot (e.g. "ts")' })),
|
|
@@ -278,7 +278,7 @@ export class GrepTool implements AgentTool<typeof grepSchema, GrepToolDetails, T
|
|
|
278
278
|
});
|
|
279
279
|
}
|
|
280
280
|
|
|
281
|
-
renderCall(args: GrepRenderArgs,
|
|
281
|
+
renderCall(args: GrepRenderArgs, options: RenderResultOptions, uiTheme: Theme): Component {
|
|
282
282
|
const meta: string[] = [];
|
|
283
283
|
if (args.path) meta.push(`in ${args.path}`);
|
|
284
284
|
if (args.glob) meta.push(`glob:${args.glob}`);
|
|
@@ -295,7 +295,7 @@ export class GrepTool implements AgentTool<typeof grepSchema, GrepToolDetails, T
|
|
|
295
295
|
if (args.offset !== undefined && args.offset > 0) meta.push(`offset:${args.offset}`);
|
|
296
296
|
|
|
297
297
|
const text = renderStatusLine(
|
|
298
|
-
{ icon: "
|
|
298
|
+
{ icon: "running", spinnerFrame: options.spinnerFrame, title: "Grep", description: args.pattern || "?", meta },
|
|
299
299
|
uiTheme,
|
|
300
300
|
);
|
|
301
301
|
return new Text(text, 0, 0);
|
package/src/tools/notebook.ts
CHANGED
|
@@ -178,7 +178,7 @@ export class NotebookTool implements AgentTool<typeof notebookSchema, NotebookTo
|
|
|
178
178
|
});
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
renderCall(args: NotebookRenderArgs,
|
|
181
|
+
renderCall(args: NotebookRenderArgs, options: RenderResultOptions, uiTheme: Theme): Component {
|
|
182
182
|
const meta: string[] = [];
|
|
183
183
|
const notebookPath = args.notebookPath ?? args.notebook_path;
|
|
184
184
|
const cellNumber = args.cellNumber ?? args.cell_index;
|
|
@@ -188,7 +188,13 @@ export class NotebookTool implements AgentTool<typeof notebookSchema, NotebookTo
|
|
|
188
188
|
if (cellType) meta.push(`type:${cellType}`);
|
|
189
189
|
|
|
190
190
|
const text = renderStatusLine(
|
|
191
|
-
{
|
|
191
|
+
{
|
|
192
|
+
icon: "running",
|
|
193
|
+
spinnerFrame: options.spinnerFrame,
|
|
194
|
+
title: "Notebook",
|
|
195
|
+
description: args.action || "?",
|
|
196
|
+
meta,
|
|
197
|
+
},
|
|
192
198
|
uiTheme,
|
|
193
199
|
);
|
|
194
200
|
return new Text(text, 0, 0);
|
package/src/tools/python.ts
CHANGED
|
@@ -476,7 +476,7 @@ export class PythonTool implements AgentTool<typeof pythonSchema, any, Theme> {
|
|
|
476
476
|
return context;
|
|
477
477
|
}
|
|
478
478
|
|
|
479
|
-
renderCall(args: PythonRenderArgs,
|
|
479
|
+
renderCall(args: PythonRenderArgs, options: RenderResultOptions, uiTheme: Theme): Component {
|
|
480
480
|
const cells = args.cells ?? [];
|
|
481
481
|
const cwd = getProjectDir();
|
|
482
482
|
let displayWorkdir = args.cwd;
|
|
@@ -526,8 +526,9 @@ export class PythonTool implements AgentTool<typeof pythonSchema, any, Theme> {
|
|
|
526
526
|
index: i,
|
|
527
527
|
total: cells.length,
|
|
528
528
|
title: combinedTitle,
|
|
529
|
-
status: "
|
|
529
|
+
status: "running",
|
|
530
530
|
width,
|
|
531
|
+
spinnerFrame: options.spinnerFrame,
|
|
531
532
|
codeMaxLines: PYTHON_DEFAULT_PREVIEW_LINES,
|
|
532
533
|
expanded: true,
|
|
533
534
|
},
|
package/src/tools/read-thread.ts
CHANGED
|
@@ -377,9 +377,12 @@ export class ReadThreadTool implements AgentTool<typeof readThreadSchema, ReadTh
|
|
|
377
377
|
};
|
|
378
378
|
}
|
|
379
379
|
|
|
380
|
-
renderCall(args: ReadThreadRenderArgs,
|
|
380
|
+
renderCall(args: ReadThreadRenderArgs, options: RenderResultOptions, uiTheme: Theme): Component {
|
|
381
381
|
const meta = args.threadId ? [args.threadId] : [];
|
|
382
|
-
const text = renderStatusLine(
|
|
382
|
+
const text = renderStatusLine(
|
|
383
|
+
{ icon: "running", spinnerFrame: options.spinnerFrame, title: "Read Thread", meta },
|
|
384
|
+
uiTheme,
|
|
385
|
+
);
|
|
383
386
|
return new Text(text, 0, 0);
|
|
384
387
|
}
|
|
385
388
|
|
package/src/tools/read.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as fs from "node:fs/promises";
|
|
2
|
-
import path from "node:path";
|
|
2
|
+
import * as path from "node:path";
|
|
3
3
|
import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@nghyane/arcane-agent";
|
|
4
4
|
import type { ImageContent, TextContent } from "@nghyane/arcane-ai";
|
|
5
5
|
import { FileType, glob } from "@nghyane/arcane-natives";
|
|
@@ -1055,7 +1055,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails, T
|
|
|
1055
1055
|
return resultBuilder.done();
|
|
1056
1056
|
}
|
|
1057
1057
|
|
|
1058
|
-
renderCall(args: ReadRenderArgs,
|
|
1058
|
+
renderCall(args: ReadRenderArgs, options: RenderResultOptions, uiTheme: Theme): Component {
|
|
1059
1059
|
const rawPath = args.file_path || args.path || "";
|
|
1060
1060
|
const filePath = shortenPath(rawPath);
|
|
1061
1061
|
const offset = args.offset;
|
|
@@ -1068,7 +1068,10 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails, T
|
|
|
1068
1068
|
pathDisplay += `:${startLine}${endLine ? `-${endLine}` : ""}`;
|
|
1069
1069
|
}
|
|
1070
1070
|
|
|
1071
|
-
const text = renderStatusLine(
|
|
1071
|
+
const text = renderStatusLine(
|
|
1072
|
+
{ icon: "running", spinnerFrame: options.spinnerFrame, title: "Read", description: pathDisplay },
|
|
1073
|
+
uiTheme,
|
|
1074
|
+
);
|
|
1072
1075
|
return new Text(text, 0, 0);
|
|
1073
1076
|
}
|
|
1074
1077
|
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@nghyane/arcane-agent";
|
|
2
2
|
import { type AsciiRenderOptions, renderMermaidAscii } from "@nghyane/arcane-utils";
|
|
3
3
|
import { type Static, Type } from "@sinclair/typebox";
|
|
4
|
-
import { renderPromptTemplate } from "../config/prompt-templates";
|
|
5
|
-
import renderMermaidDescription from "../prompts/tools/render-mermaid.md" with { type: "text" };
|
|
6
4
|
import type { ToolSession } from "./index";
|
|
7
5
|
import { allocateOutputArtifact } from "./output-utils";
|
|
8
6
|
|
|
@@ -38,14 +36,12 @@ export interface RenderMermaidToolDetails {
|
|
|
38
36
|
export class RenderMermaidTool implements AgentTool<typeof renderMermaidSchema, RenderMermaidToolDetails> {
|
|
39
37
|
readonly name = "render_mermaid";
|
|
40
38
|
readonly label = "RenderMermaid";
|
|
41
|
-
readonly description
|
|
39
|
+
readonly description =
|
|
40
|
+
"Convert Mermaid graph source into ASCII diagram output. Returns ASCII diagram text. Saves full output to an artifact URL when artifact storage is available.";
|
|
42
41
|
readonly parameters = renderMermaidSchema;
|
|
43
42
|
readonly strict = true;
|
|
44
43
|
|
|
45
|
-
constructor(private readonly session: ToolSession) {
|
|
46
|
-
this.description = renderPromptTemplate(renderMermaidDescription);
|
|
47
|
-
}
|
|
48
|
-
|
|
44
|
+
constructor(private readonly session: ToolSession) {}
|
|
49
45
|
async execute(
|
|
50
46
|
_toolCallId: string,
|
|
51
47
|
params: RenderMermaidParams,
|
package/src/tools/save-memory.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { shortenPath, TRUNCATE_LENGTHS, truncateToWidth } from "../ui/render-uti
|
|
|
11
11
|
import type { ToolSession } from ".";
|
|
12
12
|
|
|
13
13
|
const saveMemorySchema = Type.Object({
|
|
14
|
-
fact: Type.String({ description: "A clear, self-contained statement to remember across sessions" }),
|
|
14
|
+
fact: Type.String({ description: "A clear, self-contained statement to remember across sessions", minLength: 1 }),
|
|
15
15
|
});
|
|
16
16
|
|
|
17
17
|
type SaveMemoryParams = Static<typeof saveMemorySchema>;
|
|
@@ -153,10 +153,13 @@ export class SaveMemoryTool implements AgentTool<typeof saveMemorySchema, SaveMe
|
|
|
153
153
|
};
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
renderCall(args: SaveMemoryRenderArgs,
|
|
156
|
+
renderCall(args: SaveMemoryRenderArgs, options: RenderResultOptions, uiTheme: Theme): Component {
|
|
157
157
|
const preview = args.fact ? truncateToWidth(args.fact, TRUNCATE_LENGTHS.CONTENT) : "";
|
|
158
158
|
const meta = preview ? [preview] : [];
|
|
159
|
-
const text = renderStatusLine(
|
|
159
|
+
const text = renderStatusLine(
|
|
160
|
+
{ icon: "running", spinnerFrame: options.spinnerFrame, title: "Save Memory", meta },
|
|
161
|
+
uiTheme,
|
|
162
|
+
);
|
|
160
163
|
return new Text(text, 0, 0);
|
|
161
164
|
}
|
|
162
165
|
|
package/src/tools/ssh.ts
CHANGED
|
@@ -22,7 +22,7 @@ const sshSchema = Type.Object({
|
|
|
22
22
|
host: Type.String({ description: "SSH host alias (from ~/.ssh/config)" }),
|
|
23
23
|
command: Type.String({ description: "Shell command to execute on the remote host" }),
|
|
24
24
|
cwd: Type.Optional(Type.String({ description: "Working directory on the remote host" })),
|
|
25
|
-
timeout: Type.Optional(Type.Number({ description: "Timeout in
|
|
25
|
+
timeout: Type.Optional(Type.Number({ description: "Timeout in seconds" })),
|
|
26
26
|
});
|
|
27
27
|
|
|
28
28
|
export interface SSHToolDetails {
|
|
@@ -187,10 +187,13 @@ export class SshTool implements AgentTool<typeof sshSchema, SSHToolDetails, Them
|
|
|
187
187
|
return resultBuilder.done();
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
-
renderCall(args: SshRenderArgs,
|
|
190
|
+
renderCall(args: SshRenderArgs, options: RenderResultOptions, uiTheme: Theme): Component {
|
|
191
191
|
const host = args.host || "…";
|
|
192
192
|
const command = args.command || "…";
|
|
193
|
-
const text = renderStatusLine(
|
|
193
|
+
const text = renderStatusLine(
|
|
194
|
+
{ icon: "running", spinnerFrame: options.spinnerFrame, title: "SSH", description: `[${host}] $ ${command}` },
|
|
195
|
+
uiTheme,
|
|
196
|
+
);
|
|
194
197
|
return new Text(text, 0, 0);
|
|
195
198
|
}
|
|
196
199
|
|
package/src/tools/todo-write.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import path from "node:path";
|
|
1
|
+
import * as path from "node:path";
|
|
2
2
|
import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@nghyane/arcane-agent";
|
|
3
3
|
import { StringEnum } from "@nghyane/arcane-ai";
|
|
4
4
|
import type { Component } from "@nghyane/arcane-tui";
|
|
@@ -162,10 +162,13 @@ export class TodoWriteTool implements AgentTool<typeof todoWriteSchema, TodoWrit
|
|
|
162
162
|
};
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
renderCall(args: TodoWriteRenderArgs,
|
|
165
|
+
renderCall(args: TodoWriteRenderArgs, options: RenderResultOptions, uiTheme: Theme): Component {
|
|
166
166
|
const count = args.todos?.length ?? 0;
|
|
167
167
|
const meta = count > 0 ? [`${count} items`] : ["empty"];
|
|
168
|
-
const text = renderStatusLine(
|
|
168
|
+
const text = renderStatusLine(
|
|
169
|
+
{ icon: "running", spinnerFrame: options.spinnerFrame, title: "Todo Write", meta },
|
|
170
|
+
uiTheme,
|
|
171
|
+
);
|
|
169
172
|
return new Text(text, 0, 0);
|
|
170
173
|
}
|
|
171
174
|
|
package/src/tools/undo-edit.ts
CHANGED
|
@@ -75,10 +75,13 @@ export class UndoEditTool implements AgentTool<typeof undoEditSchema, UndoEditTo
|
|
|
75
75
|
});
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
renderCall(args: UndoEditRenderArgs,
|
|
78
|
+
renderCall(args: UndoEditRenderArgs, options: RenderResultOptions, uiTheme: Theme): Component {
|
|
79
79
|
const filePath = shortenPath(args.path ?? "");
|
|
80
80
|
const pathDisplay = filePath ? uiTheme.fg("accent", filePath) : uiTheme.fg("toolOutput", "…");
|
|
81
|
-
const text = renderStatusLine(
|
|
81
|
+
const text = renderStatusLine(
|
|
82
|
+
{ icon: "running", spinnerFrame: options.spinnerFrame, title: "Undo", description: pathDisplay },
|
|
83
|
+
uiTheme,
|
|
84
|
+
);
|
|
82
85
|
return new Text(text, 0, 0);
|
|
83
86
|
}
|
|
84
87
|
|
package/src/ui/render-utils.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* so the agent doesn't need to read them manually.
|
|
7
7
|
*/
|
|
8
8
|
import * as fs from "node:fs/promises";
|
|
9
|
-
import path from "node:path";
|
|
9
|
+
import * as path from "node:path";
|
|
10
10
|
import type { AgentMessage } from "@nghyane/arcane-agent";
|
|
11
11
|
import { glob } from "@nghyane/arcane-natives";
|
|
12
12
|
import { formatHashLines } from "../patch/hashline";
|
package/src/web/github-client.ts
CHANGED
|
@@ -197,7 +197,8 @@ async function request<T = unknown>(endpoint: string, options: RequestOptions =
|
|
|
197
197
|
return { data: null as T, ok: false, status: response.status, rateLimit };
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
-
const
|
|
200
|
+
const isRaw = response.headers.get("content-type")?.includes("application/json") === false;
|
|
201
|
+
const data = (isRaw ? await response.text() : await response.json()) as T;
|
|
201
202
|
|
|
202
203
|
// Cache with ETag
|
|
203
204
|
const etag = response.headers.get("etag");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as fs from "node:fs/promises";
|
|
2
2
|
import * as os from "node:os";
|
|
3
|
-
import path from "node:path";
|
|
3
|
+
import * as path from "node:path";
|
|
4
4
|
import { ptree, Snowflake } from "@nghyane/arcane-utils";
|
|
5
5
|
import { throwIfAborted } from "../../tools/tool-errors";
|
|
6
6
|
import { ensureTool } from "../../utils/tools-manager";
|
package/src/web/search/render.ts
CHANGED
|
@@ -102,11 +102,20 @@ export function renderSearchResult(
|
|
|
102
102
|
/** Render web search call (query preview) */
|
|
103
103
|
export function renderSearchCall(
|
|
104
104
|
args: { query?: string; provider?: string; [key: string]: unknown },
|
|
105
|
-
|
|
105
|
+
options: RenderResultOptions,
|
|
106
106
|
theme: Theme,
|
|
107
107
|
): Component {
|
|
108
108
|
const provider = args.provider ?? "auto";
|
|
109
109
|
const query = truncateToWidth(args.query ?? "", 80);
|
|
110
|
-
const text = renderStatusLine(
|
|
110
|
+
const text = renderStatusLine(
|
|
111
|
+
{
|
|
112
|
+
icon: "running",
|
|
113
|
+
spinnerFrame: options.spinnerFrame,
|
|
114
|
+
title: "Web Search",
|
|
115
|
+
description: query,
|
|
116
|
+
meta: [provider],
|
|
117
|
+
},
|
|
118
|
+
theme,
|
|
119
|
+
);
|
|
111
120
|
return new Text(text, 0, 0);
|
|
112
121
|
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
Convert Mermaid graph source into ASCII diagram output.
|
|
2
|
-
|
|
3
|
-
Parameters:
|
|
4
|
-
- `mermaid` (required): Mermaid graph text to render.
|
|
5
|
-
- `config` (optional): JSON render configuration (spacing and layout options).
|
|
6
|
-
Behavior:
|
|
7
|
-
- Returns ASCII diagram text.
|
|
8
|
-
- Saves full ASCII output to an artifact URL (`artifact://<id>`) when artifact storage is available.
|
|
9
|
-
- Returns an error when the Mermaid input is invalid or rendering fails.
|