@nghyane/arcane 0.1.16 → 0.1.18
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 +21 -0
- package/package.json +7 -15
- package/src/cli/setup-cli.ts +2 -62
- package/src/commands/setup.ts +1 -1
- package/src/config/keybindings.ts +1 -4
- package/src/config/settings-schema.ts +23 -98
- package/src/config/settings.ts +0 -1
- package/src/exa/mcp-client.ts +57 -2
- package/src/extensibility/custom-tools/types.ts +2 -2
- package/src/extensibility/custom-tools/wrapper.ts +1 -1
- package/src/extensibility/extensions/wrapper.ts +1 -1
- package/src/extensibility/hooks/tool-wrapper.ts +1 -1
- package/src/internal-urls/docs-index.generated.ts +1 -2
- package/src/internal-urls/index.ts +2 -4
- package/src/internal-urls/router.ts +2 -2
- package/src/internal-urls/types.ts +2 -2
- package/src/mcp/oauth-flow.ts +1 -1
- package/src/modes/components/custom-editor.ts +6 -2
- package/src/modes/controllers/command-controller.ts +4 -46
- package/src/modes/controllers/input-controller.ts +123 -6
- package/src/modes/interactive-mode.ts +1 -84
- package/src/modes/types.ts +0 -1
- package/src/patch/edit-tool.ts +2 -11
- package/src/patch/hashline.ts +42 -0
- package/src/prompts/agents/explore.md +4 -2
- package/src/prompts/agents/librarian.md +4 -6
- package/src/prompts/agents/reviewer.md +1 -1
- package/src/prompts/agents/task.md +5 -1
- package/src/prompts/system/system-prompt.md +29 -18
- package/src/prompts/thread-extract.md +16 -0
- package/src/prompts/tools/render-mermaid.md +9 -0
- package/src/sdk.ts +12 -37
- package/src/session/agent-session.ts +5 -10
- package/src/session/retry-utils.ts +1 -1
- package/src/session/session-index.ts +329 -0
- package/src/session/session-manager.ts +0 -30
- package/src/session/streaming-edit.ts +1 -36
- package/src/slash-commands/builtin-registry.ts +0 -16
- package/src/task/index.ts +1 -1
- package/src/tools/ask.ts +9 -6
- package/src/tools/bash-skill-urls.ts +3 -3
- package/src/tools/bash.ts +2 -1
- package/src/tools/create-tools.ts +28 -33
- package/src/tools/fetch.ts +1 -1
- package/src/tools/find-thread.ts +120 -0
- package/src/tools/grep.ts +2 -1
- package/src/tools/index.ts +5 -0
- package/src/tools/python.ts +53 -1
- package/src/tools/read-thread.ts +409 -0
- package/src/tools/read.ts +4 -3
- package/src/tools/render-mermaid.ts +68 -0
- package/src/tools/save-memory.ts +182 -0
- package/src/tools/write.ts +1 -1
- package/src/web/search/index.ts +4 -1
- package/src/web/search/provider.ts +3 -0
- package/src/web/search/providers/anthropic.ts +1 -0
- package/src/web/search/providers/gemini.ts +122 -37
- package/src/web/search/providers/kagi.ts +163 -0
- package/src/web/search/types.ts +1 -0
- package/src/internal-urls/memory-protocol.ts +0 -133
- package/src/memories/index.ts +0 -1099
- package/src/memories/storage.ts +0 -563
- package/src/patch/normative.ts +0 -72
- package/src/prompts/memories/consolidation.md +0 -30
- package/src/prompts/memories/read_path.md +0 -11
- package/src/prompts/memories/stage_one_input.md +0 -6
- package/src/prompts/memories/stage_one_system.md +0 -21
- package/src/stt/downloader.ts +0 -68
- package/src/stt/index.ts +0 -3
- package/src/stt/recorder.ts +0 -351
- package/src/stt/setup.ts +0 -50
- package/src/stt/stt-controller.ts +0 -160
- package/src/stt/transcribe.py +0 -70
- package/src/stt/transcriber.ts +0 -91
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.1.17] - 2026-03-02
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Thread search and retrieval tools (find-thread, read-thread)
|
|
10
|
+
- Save-memory tool for cross-session fact storage
|
|
11
|
+
- Mermaid diagram rendering tool (render-mermaid)
|
|
12
|
+
- Kagi web search provider
|
|
13
|
+
- Codex OAuth authentication support
|
|
14
|
+
- AST auto-inclusion in subagent context
|
|
15
|
+
- Ask tool abort support
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- Improved Gemini provider retry logic
|
|
20
|
+
- Enhanced hashline tab handling
|
|
21
|
+
|
|
22
|
+
### Removed
|
|
23
|
+
|
|
24
|
+
- Memory system (replaced by thread/save-memory tools)
|
|
25
|
+
|
|
5
26
|
## [0.1.14] - 2026-03-02
|
|
6
27
|
|
|
7
28
|
### Removed
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@nghyane/arcane",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.18",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://github.com/nghyane/arcane",
|
|
7
7
|
"author": "Can Bölük",
|
|
@@ -44,12 +44,12 @@
|
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@mozilla/readability": "0.6.0",
|
|
47
|
-
"@nghyane/arcane-stats": "^0.1.
|
|
48
|
-
"@nghyane/arcane-agent": "^0.1.
|
|
49
|
-
"@nghyane/arcane-ai": "^0.1.
|
|
50
|
-
"@nghyane/arcane-natives": "^0.1.
|
|
51
|
-
"@nghyane/arcane-tui": "^0.1.
|
|
52
|
-
"@nghyane/arcane-utils": "^0.1.
|
|
47
|
+
"@nghyane/arcane-stats": "^0.1.11",
|
|
48
|
+
"@nghyane/arcane-agent": "^0.1.14",
|
|
49
|
+
"@nghyane/arcane-ai": "^0.1.11",
|
|
50
|
+
"@nghyane/arcane-natives": "^0.1.9",
|
|
51
|
+
"@nghyane/arcane-tui": "^0.1.13",
|
|
52
|
+
"@nghyane/arcane-utils": "^0.1.7",
|
|
53
53
|
"@sinclair/typebox": "^0.34.48",
|
|
54
54
|
"@xterm/headless": "^6.0.0",
|
|
55
55
|
"ajv": "^8.18.0",
|
|
@@ -242,14 +242,6 @@
|
|
|
242
242
|
"types": "./src/mcp/transports/*.ts",
|
|
243
243
|
"import": "./src/mcp/transports/*.ts"
|
|
244
244
|
},
|
|
245
|
-
"./memories": {
|
|
246
|
-
"types": "./src/memories/index.ts",
|
|
247
|
-
"import": "./src/memories/index.ts"
|
|
248
|
-
},
|
|
249
|
-
"./memories/*": {
|
|
250
|
-
"types": "./src/memories/*.ts",
|
|
251
|
-
"import": "./src/memories/*.ts"
|
|
252
|
-
},
|
|
253
245
|
"./modes": {
|
|
254
246
|
"types": "./src/modes/index.ts",
|
|
255
247
|
"import": "./src/modes/index.ts"
|
package/src/cli/setup-cli.ts
CHANGED
|
@@ -9,7 +9,7 @@ import { $ } from "bun";
|
|
|
9
9
|
import chalk from "chalk";
|
|
10
10
|
import { theme } from "../theme/theme";
|
|
11
11
|
|
|
12
|
-
export type SetupComponent = "python"
|
|
12
|
+
export type SetupComponent = "python";
|
|
13
13
|
|
|
14
14
|
export interface SetupCommandArgs {
|
|
15
15
|
component: SetupComponent;
|
|
@@ -19,7 +19,7 @@ export interface SetupCommandArgs {
|
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
const VALID_COMPONENTS: SetupComponent[] = ["python"
|
|
22
|
+
const VALID_COMPONENTS: SetupComponent[] = ["python"];
|
|
23
23
|
|
|
24
24
|
const PYTHON_PACKAGES = ["jupyter_kernel_gateway", "ipykernel"];
|
|
25
25
|
const MANAGED_PYTHON_ENV = getPythonEnvDir();
|
|
@@ -206,9 +206,6 @@ export async function runSetupCommand(cmd: SetupCommandArgs): Promise<void> {
|
|
|
206
206
|
case "python":
|
|
207
207
|
await handlePythonSetup(cmd.flags);
|
|
208
208
|
break;
|
|
209
|
-
case "stt":
|
|
210
|
-
await handleSttSetup(cmd.flags);
|
|
211
|
-
break;
|
|
212
209
|
}
|
|
213
210
|
}
|
|
214
211
|
|
|
@@ -295,60 +292,6 @@ async function handlePythonSetup(flags: { json?: boolean; check?: boolean }): Pr
|
|
|
295
292
|
}
|
|
296
293
|
}
|
|
297
294
|
|
|
298
|
-
async function handleSttSetup(flags: { json?: boolean; check?: boolean }): Promise<void> {
|
|
299
|
-
const { checkDependencies, formatDependencyStatus } = await import("../stt/setup");
|
|
300
|
-
const status = await checkDependencies();
|
|
301
|
-
|
|
302
|
-
if (flags.json) {
|
|
303
|
-
console.log(JSON.stringify(status, null, 2));
|
|
304
|
-
if (!status.recorder.available || !status.python.available || !status.whisper.available) process.exit(1);
|
|
305
|
-
return;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
console.log(formatDependencyStatus(status));
|
|
309
|
-
|
|
310
|
-
if (status.recorder.available && status.python.available && status.whisper.available) {
|
|
311
|
-
console.log(chalk.green(`\n${theme.status.success} Speech-to-text is ready`));
|
|
312
|
-
return;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
if (flags.check) {
|
|
316
|
-
process.exit(1);
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
if (!status.python.available) {
|
|
320
|
-
console.error(chalk.red(`\n${theme.status.error} Python not found`));
|
|
321
|
-
console.error(chalk.dim("Install Python 3.8+ and ensure it's in your PATH"));
|
|
322
|
-
process.exit(1);
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
if (!status.recorder.available) {
|
|
326
|
-
console.error(chalk.yellow(`\n${theme.status.warning} No recording tool found`));
|
|
327
|
-
console.error(chalk.dim(status.recorder.installHint));
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
if (!status.whisper.available) {
|
|
331
|
-
console.log(chalk.dim(`\nInstalling openai-whisper...`));
|
|
332
|
-
const { resolvePython } = await import("../stt/transcriber");
|
|
333
|
-
const pythonCmd = resolvePython()!;
|
|
334
|
-
const result = await $`${pythonCmd} -m pip install -q openai-whisper`.nothrow();
|
|
335
|
-
if (result.exitCode !== 0) {
|
|
336
|
-
console.error(chalk.red(`\n${theme.status.error} Failed to install openai-whisper`));
|
|
337
|
-
console.error(chalk.dim("Try manually: pip install openai-whisper"));
|
|
338
|
-
process.exit(1);
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
const recheck = await checkDependencies();
|
|
343
|
-
if (recheck.recorder.available && recheck.python.available && recheck.whisper.available) {
|
|
344
|
-
console.log(chalk.green(`\n${theme.status.success} Speech-to-text is ready`));
|
|
345
|
-
} else {
|
|
346
|
-
console.error(chalk.red(`\n${theme.status.error} Setup incomplete`));
|
|
347
|
-
console.log(formatDependencyStatus(recheck));
|
|
348
|
-
process.exit(1);
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
|
|
352
295
|
/**
|
|
353
296
|
* Print setup command help.
|
|
354
297
|
*/
|
|
@@ -360,7 +303,6 @@ ${chalk.bold("Usage:")}
|
|
|
360
303
|
|
|
361
304
|
${chalk.bold("Components:")}
|
|
362
305
|
python Install Jupyter kernel dependencies for Python code execution
|
|
363
|
-
stt Install speech-to-text dependencies (openai-whisper, recording tools)
|
|
364
306
|
Packages: ${PYTHON_PACKAGES.join(", ")}
|
|
365
307
|
|
|
366
308
|
${chalk.bold("Options:")}
|
|
@@ -369,8 +311,6 @@ ${chalk.bold("Options:")}
|
|
|
369
311
|
|
|
370
312
|
${chalk.bold("Examples:")}
|
|
371
313
|
${APP_NAME} setup python Install Python execution dependencies
|
|
372
|
-
${APP_NAME} setup stt Install speech-to-text dependencies
|
|
373
|
-
${APP_NAME} setup stt --check Check if STT dependencies are available
|
|
374
314
|
${APP_NAME} setup python --check Check if Python execution is available
|
|
375
315
|
`);
|
|
376
316
|
}
|
package/src/commands/setup.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { Args, Command, Flags, renderCommandHelp } from "@nghyane/arcane-utils/c
|
|
|
5
5
|
import { runSetupCommand, type SetupCommandArgs, type SetupComponent } from "../cli/setup-cli";
|
|
6
6
|
import { initTheme } from "../theme/theme";
|
|
7
7
|
|
|
8
|
-
const COMPONENTS: SetupComponent[] = ["python"
|
|
8
|
+
const COMPONENTS: SetupComponent[] = ["python"];
|
|
9
9
|
|
|
10
10
|
export default class Setup extends Command {
|
|
11
11
|
static description = "Install dependencies for optional features";
|
|
@@ -34,8 +34,7 @@ export type AppAction =
|
|
|
34
34
|
| "newSession"
|
|
35
35
|
| "tree"
|
|
36
36
|
| "fork"
|
|
37
|
-
| "resume"
|
|
38
|
-
| "toggleSTT";
|
|
37
|
+
| "resume";
|
|
39
38
|
|
|
40
39
|
/**
|
|
41
40
|
* All configurable actions.
|
|
@@ -73,7 +72,6 @@ export const DEFAULT_APP_KEYBINDINGS: Record<AppAction, KeyId | KeyId[]> = {
|
|
|
73
72
|
tree: [],
|
|
74
73
|
fork: [],
|
|
75
74
|
resume: [],
|
|
76
|
-
toggleSTT: "alt+h",
|
|
77
75
|
};
|
|
78
76
|
|
|
79
77
|
/**
|
|
@@ -106,7 +104,6 @@ const APP_ACTIONS: AppAction[] = [
|
|
|
106
104
|
"tree",
|
|
107
105
|
"fork",
|
|
108
106
|
"resume",
|
|
109
|
-
"toggleSTT",
|
|
110
107
|
];
|
|
111
108
|
|
|
112
109
|
function isAppAction(action: string): action is AppAction {
|
|
@@ -204,7 +204,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
204
204
|
steeringMode: {
|
|
205
205
|
type: "enum",
|
|
206
206
|
values: ["all", "one-at-a-time"] as const,
|
|
207
|
-
default: "
|
|
207
|
+
default: "all",
|
|
208
208
|
ui: {
|
|
209
209
|
tab: "agent",
|
|
210
210
|
label: "Steering mode",
|
|
@@ -214,7 +214,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
214
214
|
followUpMode: {
|
|
215
215
|
type: "enum",
|
|
216
216
|
values: ["all", "one-at-a-time"] as const,
|
|
217
|
-
default: "
|
|
217
|
+
default: "all",
|
|
218
218
|
ui: {
|
|
219
219
|
tab: "agent",
|
|
220
220
|
label: "Follow-up mode",
|
|
@@ -253,15 +253,6 @@ export const SETTINGS_SCHEMA = {
|
|
|
253
253
|
submenu: true,
|
|
254
254
|
},
|
|
255
255
|
},
|
|
256
|
-
normativeRewrite: {
|
|
257
|
-
type: "boolean",
|
|
258
|
-
default: false,
|
|
259
|
-
ui: {
|
|
260
|
-
tab: "agent",
|
|
261
|
-
label: "Normative rewrite",
|
|
262
|
-
description: "Rewrite tool call arguments to normalized format in session history",
|
|
263
|
-
},
|
|
264
|
-
},
|
|
265
256
|
readLineNumbers: {
|
|
266
257
|
type: "boolean",
|
|
267
258
|
default: false,
|
|
@@ -345,33 +336,6 @@ export const SETTINGS_SCHEMA = {
|
|
|
345
336
|
},
|
|
346
337
|
"branchSummary.reserveTokens": { type: "number", default: 16384 },
|
|
347
338
|
|
|
348
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
349
|
-
// Memories settings
|
|
350
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
351
|
-
"memories.enabled": {
|
|
352
|
-
type: "boolean",
|
|
353
|
-
default: false,
|
|
354
|
-
ui: {
|
|
355
|
-
tab: "agent",
|
|
356
|
-
label: "Memories",
|
|
357
|
-
description: "Enable autonomous memory extraction and consolidation",
|
|
358
|
-
},
|
|
359
|
-
},
|
|
360
|
-
"memories.maxRolloutsPerStartup": { type: "number", default: 64 },
|
|
361
|
-
"memories.maxRolloutAgeDays": { type: "number", default: 30 },
|
|
362
|
-
"memories.minRolloutIdleHours": { type: "number", default: 12 },
|
|
363
|
-
"memories.threadScanLimit": { type: "number", default: 300 },
|
|
364
|
-
"memories.maxRawMemoriesForGlobal": { type: "number", default: 200 },
|
|
365
|
-
"memories.stage1Concurrency": { type: "number", default: 8 },
|
|
366
|
-
"memories.stage1LeaseSeconds": { type: "number", default: 120 },
|
|
367
|
-
"memories.stage1RetryDelaySeconds": { type: "number", default: 120 },
|
|
368
|
-
"memories.phase2LeaseSeconds": { type: "number", default: 180 },
|
|
369
|
-
"memories.phase2RetryDelaySeconds": { type: "number", default: 180 },
|
|
370
|
-
"memories.phase2HeartbeatSeconds": { type: "number", default: 30 },
|
|
371
|
-
"memories.rolloutPayloadPercent": { type: "number", default: 0.7 },
|
|
372
|
-
"memories.fallbackTokenLimit": { type: "number", default: 16000 },
|
|
373
|
-
"memories.summaryInjectionTokenLimit": { type: "number", default: 5000 },
|
|
374
|
-
|
|
375
339
|
// ─────────────────────────────────────────────────────────────────────────
|
|
376
340
|
// Retry settings
|
|
377
341
|
// ─────────────────────────────────────────────────────────────────────────
|
|
@@ -468,6 +432,25 @@ export const SETTINGS_SCHEMA = {
|
|
|
468
432
|
submenu: true,
|
|
469
433
|
},
|
|
470
434
|
},
|
|
435
|
+
"astGrep.enabled": {
|
|
436
|
+
type: "boolean",
|
|
437
|
+
default: false,
|
|
438
|
+
ui: { tab: "tools", label: "AST Grep", description: "Enable ast_grep tool for structural code search" },
|
|
439
|
+
},
|
|
440
|
+
"astEdit.enabled": {
|
|
441
|
+
type: "boolean",
|
|
442
|
+
default: false,
|
|
443
|
+
ui: { tab: "tools", label: "AST Edit", description: "Enable ast_edit tool for structural code rewrites" },
|
|
444
|
+
},
|
|
445
|
+
"renderMermaid.enabled": {
|
|
446
|
+
type: "boolean",
|
|
447
|
+
default: true,
|
|
448
|
+
ui: {
|
|
449
|
+
tab: "tools",
|
|
450
|
+
label: "Render Mermaid",
|
|
451
|
+
description: "Enable the render_mermaid tool for ASCII diagram output",
|
|
452
|
+
},
|
|
453
|
+
},
|
|
471
454
|
"notebook.enabled": {
|
|
472
455
|
type: "boolean",
|
|
473
456
|
default: true,
|
|
@@ -594,7 +577,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
594
577
|
type: "boolean",
|
|
595
578
|
default: true,
|
|
596
579
|
ui: {
|
|
597
|
-
tab: "
|
|
580
|
+
tab: "input",
|
|
598
581
|
label: "Auto-resize images",
|
|
599
582
|
description: "Resize large images to 2000x2000 max for better model compatibility",
|
|
600
583
|
},
|
|
@@ -602,7 +585,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
602
585
|
"images.blockImages": {
|
|
603
586
|
type: "boolean",
|
|
604
587
|
default: false,
|
|
605
|
-
ui: { tab: "
|
|
588
|
+
ui: { tab: "input", label: "Block images", description: "Prevent images from being sent to LLM providers" },
|
|
606
589
|
},
|
|
607
590
|
|
|
608
591
|
// ─────────────────────────────────────────────────────────────────────────
|
|
@@ -804,36 +787,6 @@ export const SETTINGS_SCHEMA = {
|
|
|
804
787
|
},
|
|
805
788
|
},
|
|
806
789
|
|
|
807
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
808
|
-
// STT settings
|
|
809
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
810
|
-
"stt.enabled": {
|
|
811
|
-
type: "boolean",
|
|
812
|
-
default: false,
|
|
813
|
-
ui: { tab: "input", label: "Speech-to-text", description: "Enable speech-to-text input via microphone" },
|
|
814
|
-
},
|
|
815
|
-
"stt.language": {
|
|
816
|
-
type: "string",
|
|
817
|
-
default: "en",
|
|
818
|
-
ui: {
|
|
819
|
-
tab: "input",
|
|
820
|
-
label: "STT language",
|
|
821
|
-
description: "Language code for transcription (e.g., en, es, fr)",
|
|
822
|
-
submenu: true,
|
|
823
|
-
},
|
|
824
|
-
},
|
|
825
|
-
"stt.modelName": {
|
|
826
|
-
type: "enum",
|
|
827
|
-
values: ["tiny", "tiny.en", "base", "base.en", "small", "small.en", "medium", "medium.en", "large"] as const,
|
|
828
|
-
default: "base.en",
|
|
829
|
-
ui: {
|
|
830
|
-
tab: "input",
|
|
831
|
-
label: "STT model",
|
|
832
|
-
description: "Whisper model size (larger = more accurate but slower)",
|
|
833
|
-
submenu: true,
|
|
834
|
-
},
|
|
835
|
-
},
|
|
836
|
-
|
|
837
790
|
// ─────────────────────────────────────────────────────────────────────────
|
|
838
791
|
// Edit settings
|
|
839
792
|
// ─────────────────────────────────────────────────────────────────────────
|
|
@@ -1061,24 +1014,6 @@ export interface RetrySettings {
|
|
|
1061
1014
|
baseDelayMs: number;
|
|
1062
1015
|
}
|
|
1063
1016
|
|
|
1064
|
-
export interface MemoriesSettings {
|
|
1065
|
-
enabled: boolean;
|
|
1066
|
-
maxRolloutsPerStartup: number;
|
|
1067
|
-
maxRolloutAgeDays: number;
|
|
1068
|
-
minRolloutIdleHours: number;
|
|
1069
|
-
threadScanLimit: number;
|
|
1070
|
-
maxRawMemoriesForGlobal: number;
|
|
1071
|
-
stage1Concurrency: number;
|
|
1072
|
-
stage1LeaseSeconds: number;
|
|
1073
|
-
stage1RetryDelaySeconds: number;
|
|
1074
|
-
phase2LeaseSeconds: number;
|
|
1075
|
-
phase2RetryDelaySeconds: number;
|
|
1076
|
-
phase2HeartbeatSeconds: number;
|
|
1077
|
-
rolloutPayloadPercent: number;
|
|
1078
|
-
fallbackTokenLimit: number;
|
|
1079
|
-
summaryInjectionTokenLimit: number;
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
1017
|
export interface TodoCompletionSettings {
|
|
1083
1018
|
enabled: boolean;
|
|
1084
1019
|
maxReminders: number;
|
|
@@ -1135,14 +1070,6 @@ export interface ThinkingBudgetsSettings {
|
|
|
1135
1070
|
high: number;
|
|
1136
1071
|
}
|
|
1137
1072
|
|
|
1138
|
-
export interface SttSettings {
|
|
1139
|
-
enabled: boolean;
|
|
1140
|
-
language: string | undefined;
|
|
1141
|
-
modelName: string;
|
|
1142
|
-
whisperPath: string | undefined;
|
|
1143
|
-
modelPath: string | undefined;
|
|
1144
|
-
}
|
|
1145
|
-
|
|
1146
1073
|
export interface BashInterceptorRule {
|
|
1147
1074
|
pattern: string;
|
|
1148
1075
|
flags?: string;
|
|
@@ -1156,14 +1083,12 @@ export interface GroupTypeMap {
|
|
|
1156
1083
|
compaction: CompactionSettings;
|
|
1157
1084
|
contextPromotion: ContextPromotionSettings;
|
|
1158
1085
|
retry: RetrySettings;
|
|
1159
|
-
memories: MemoriesSettings;
|
|
1160
1086
|
branchSummary: BranchSummarySettings;
|
|
1161
1087
|
skills: SkillsSettings;
|
|
1162
1088
|
ttsr: TtsrSettings;
|
|
1163
1089
|
exa: ExaSettings;
|
|
1164
1090
|
statusLine: StatusLineSettings;
|
|
1165
1091
|
thinkingBudgets: ThinkingBudgetsSettings;
|
|
1166
|
-
stt: SttSettings;
|
|
1167
1092
|
modelRoles: Record<string, string>;
|
|
1168
1093
|
}
|
|
1169
1094
|
|
package/src/config/settings.ts
CHANGED
package/src/exa/mcp-client.ts
CHANGED
|
@@ -17,6 +17,61 @@ export function findApiKey(): string | null {
|
|
|
17
17
|
return $env.EXA_API_KEY;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
function asRecord(value: unknown): Record<string, unknown> | null {
|
|
21
|
+
if (typeof value !== "object" || value === null) return null;
|
|
22
|
+
return value as Record<string, unknown>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function parseJsonContent(text: string): unknown | null {
|
|
26
|
+
try {
|
|
27
|
+
return JSON.parse(text);
|
|
28
|
+
} catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Normalize tools/call payloads across MCP servers.
|
|
35
|
+
*
|
|
36
|
+
* Exa currently returns different shapes depending on deployment/environment:
|
|
37
|
+
* - direct payload in result
|
|
38
|
+
* - structured payload under result.structuredContent / result.data / result.result
|
|
39
|
+
* - JSON payload embedded as text in result.content[]
|
|
40
|
+
*/
|
|
41
|
+
function normalizeMcpToolPayload(payload: unknown): unknown {
|
|
42
|
+
const candidates: unknown[] = [];
|
|
43
|
+
const root = asRecord(payload);
|
|
44
|
+
|
|
45
|
+
if (root) {
|
|
46
|
+
if (root.structuredContent !== undefined) candidates.push(root.structuredContent);
|
|
47
|
+
if (root.data !== undefined) candidates.push(root.data);
|
|
48
|
+
if (root.result !== undefined) candidates.push(root.result);
|
|
49
|
+
candidates.push(root);
|
|
50
|
+
|
|
51
|
+
const content = root.content;
|
|
52
|
+
if (Array.isArray(content)) {
|
|
53
|
+
for (const item of content) {
|
|
54
|
+
const part = asRecord(item);
|
|
55
|
+
if (!part) continue;
|
|
56
|
+
const text = part.text;
|
|
57
|
+
if (typeof text !== "string" || text.trim().length === 0) continue;
|
|
58
|
+
const parsed = parseJsonContent(text);
|
|
59
|
+
if (parsed !== null) candidates.push(parsed);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
candidates.push(payload);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
for (const candidate of candidates) {
|
|
67
|
+
if (isSearchResponse(candidate)) {
|
|
68
|
+
return candidate;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return payload;
|
|
73
|
+
}
|
|
74
|
+
|
|
20
75
|
/** Fetch available tools from Exa MCP */
|
|
21
76
|
export async function fetchExaTools(apiKey: string | null, toolNames: string[]): Promise<MCPTool[]> {
|
|
22
77
|
const params = new URLSearchParams();
|
|
@@ -66,7 +121,7 @@ export async function callExaTool(
|
|
|
66
121
|
throw new Error(`MCP error: ${response.error.message}`);
|
|
67
122
|
}
|
|
68
123
|
|
|
69
|
-
return response.result;
|
|
124
|
+
return normalizeMcpToolPayload(response.result);
|
|
70
125
|
}
|
|
71
126
|
|
|
72
127
|
/** Call a tool on Websets MCP */
|
|
@@ -86,7 +141,7 @@ export async function callWebsetsTool(
|
|
|
86
141
|
throw new Error(`MCP error: ${response.error.message}`);
|
|
87
142
|
}
|
|
88
143
|
|
|
89
|
-
return response.result;
|
|
144
|
+
return normalizeMcpToolPayload(response.result);
|
|
90
145
|
}
|
|
91
146
|
|
|
92
147
|
/** Parse Exa markdown format into SearchResponse */
|
|
@@ -178,10 +178,10 @@ export interface CustomTool<TParams extends TSchema = TSchema, TDetails = any> {
|
|
|
178
178
|
execute(
|
|
179
179
|
toolCallId: string,
|
|
180
180
|
params: Static<TParams>,
|
|
181
|
-
onUpdate: AgentToolUpdateCallback<TDetails
|
|
181
|
+
onUpdate: AgentToolUpdateCallback<TDetails> | undefined,
|
|
182
182
|
ctx: CustomToolContext,
|
|
183
183
|
signal?: AbortSignal,
|
|
184
|
-
): Promise<AgentToolResult<TDetails
|
|
184
|
+
): Promise<AgentToolResult<TDetails>>;
|
|
185
185
|
|
|
186
186
|
/** Called on session lifecycle events - use to reconstruct state or cleanup resources */
|
|
187
187
|
onSession?: (event: CustomToolSessionEvent, ctx: CustomToolContext) => void | Promise<void>;
|
|
@@ -26,7 +26,7 @@ export class CustomToolAdapter<TParams extends TSchema = TSchema, TDetails = any
|
|
|
26
26
|
toolCallId: string,
|
|
27
27
|
params: Static<TParams>,
|
|
28
28
|
signal?: AbortSignal,
|
|
29
|
-
onUpdate?: AgentToolUpdateCallback<TDetails
|
|
29
|
+
onUpdate?: AgentToolUpdateCallback<TDetails>,
|
|
30
30
|
context?: CustomToolContext,
|
|
31
31
|
) {
|
|
32
32
|
return this.tool.execute(toolCallId, params, onUpdate, context ?? this.getContext(), signal);
|
|
@@ -96,7 +96,7 @@ export class ExtensionToolWrapper<TParameters extends TSchema = TSchema, TDetail
|
|
|
96
96
|
toolCallId: string,
|
|
97
97
|
params: Static<TParameters>,
|
|
98
98
|
signal?: AbortSignal,
|
|
99
|
-
onUpdate?: AgentToolUpdateCallback<TDetails
|
|
99
|
+
onUpdate?: AgentToolUpdateCallback<TDetails>,
|
|
100
100
|
context?: AgentToolContext,
|
|
101
101
|
) {
|
|
102
102
|
// Emit tool_call event - extensions can block execution
|
|
@@ -34,7 +34,7 @@ export class HookToolWrapper<TParameters extends TSchema = TSchema, TDetails = u
|
|
|
34
34
|
toolCallId: string,
|
|
35
35
|
params: Static<TParameters>,
|
|
36
36
|
signal?: AbortSignal,
|
|
37
|
-
onUpdate?: AgentToolUpdateCallback<TDetails
|
|
37
|
+
onUpdate?: AgentToolUpdateCallback<TDetails>,
|
|
38
38
|
context?: AgentToolContext,
|
|
39
39
|
) {
|
|
40
40
|
// Emit tool_call event - hooks can block execution
|