@pencil-agent/nano-pencil 1.14.2 → 1.14.4
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/dist/build-meta.json +3 -3
- package/dist/builtin-extensions.d.ts +4 -0
- package/dist/builtin-extensions.js +16 -16
- package/dist/core/config/settings-manager.d.ts +8 -1
- package/dist/core/config/settings-manager.js +9 -0
- package/dist/core/extensions/runner.d.ts +70 -4
- package/dist/core/extensions/runner.js +188 -8
- package/dist/core/extensions/types.d.ts +8 -1
- package/dist/core/i18n/slash-commands.d.ts +12 -0
- package/dist/core/i18n/slash-commands.js +16 -4
- package/dist/core/i18n/slash-commands.zh.d.ts +12 -0
- package/dist/core/i18n/slash-commands.zh.js +16 -4
- package/dist/core/runtime/agent-session.d.ts +5 -0
- package/dist/core/runtime/agent-session.js +85 -27
- package/dist/core/runtime/extension-core-bindings.d.ts +3 -3
- package/dist/core/runtime/extension-core-bindings.js +73 -20
- package/dist/core/runtime/retry-coordinator.d.ts +10 -1
- package/dist/core/runtime/retry-coordinator.js +20 -4
- package/dist/core/runtime/sdk.js +2 -1
- package/dist/core/runtime/slash-command-catalog.d.ts +2 -1
- package/dist/core/runtime/slash-command-catalog.js +9 -1
- package/dist/core/slash-commands.d.ts +12 -1
- package/dist/core/slash-commands.js +81 -32
- package/dist/core/telemetry/batching-dispatcher.d.ts +41 -0
- package/dist/core/telemetry/batching-dispatcher.js +89 -0
- package/dist/core/telemetry/build-meta.d.ts +12 -0
- package/dist/core/telemetry/build-meta.js +57 -0
- package/dist/core/telemetry/caller-context.d.ts +32 -0
- package/dist/core/telemetry/caller-context.js +19 -0
- package/dist/core/telemetry/credentials.d.ts +27 -0
- package/dist/core/telemetry/credentials.js +87 -0
- package/dist/core/telemetry/ext-events.d.ts +89 -0
- package/dist/core/telemetry/ext-events.js +189 -0
- package/dist/core/telemetry/index.d.ts +13 -0
- package/dist/core/telemetry/index.js +6 -0
- package/dist/core/telemetry/insforge-base.d.ts +37 -0
- package/dist/core/telemetry/insforge-base.js +160 -0
- package/dist/core/telemetry/types.d.ts +33 -0
- package/dist/core/telemetry/types.js +7 -0
- package/dist/extensions/defaults/browser/index.js +14 -6
- package/dist/extensions/defaults/btw/index.js +2 -2
- package/dist/extensions/defaults/debug/index.js +38 -3
- package/dist/extensions/defaults/diagnostics/index.js +12 -0
- package/dist/extensions/defaults/grub/grub-parser.d.ts +15 -1
- package/dist/extensions/defaults/grub/grub-parser.js +31 -1
- package/dist/extensions/defaults/grub/index.d.ts +1 -1
- package/dist/extensions/defaults/grub/index.js +4 -3
- package/dist/extensions/defaults/interview/index.js +2 -2
- package/dist/extensions/defaults/link-world/index.js +14 -6
- package/dist/extensions/defaults/loop/cron/cron-scheduler.js +19 -0
- package/dist/extensions/defaults/loop/index.js +35 -0
- package/dist/extensions/defaults/mcp/index.js +18 -0
- package/dist/extensions/defaults/plan/index.js +29 -11
- package/dist/extensions/defaults/presence/index.d.ts +12 -2
- package/dist/extensions/defaults/presence/index.js +77 -23
- package/dist/extensions/defaults/presence/presence-memory.d.ts +2 -1
- package/dist/extensions/defaults/presence/presence-memory.js +37 -1
- package/dist/extensions/defaults/recap/index.js +12 -0
- package/dist/extensions/defaults/sal/eval/insforge-sink.d.ts +6 -17
- package/dist/extensions/defaults/sal/eval/insforge-sink.js +40 -183
- package/dist/extensions/defaults/sal/index.js +31 -8
- package/dist/extensions/defaults/sal/sal-config.d.ts +5 -0
- package/dist/extensions/defaults/sal/sal-config.js +15 -82
- package/dist/extensions/defaults/security-audit/index.js +141 -83
- package/dist/extensions/defaults/subagent/index.js +29 -5
- package/dist/extensions/defaults/team/index.js +10 -9
- package/dist/extensions/defaults/team/team-parser.d.ts +18 -0
- package/dist/extensions/defaults/team/team-parser.js +91 -3
- package/dist/extensions/defaults/team/team-ui.js +4 -14
- package/dist/extensions/defaults/token-save/index.js +14 -1
- package/dist/extensions/optional/export-html/index.js +19 -5
- package/dist/extensions/optional/simplify/index.js +11 -5
- package/dist/modes/interactive/interactive-mode.d.ts +2 -1
- package/dist/modes/interactive/interactive-mode.js +68 -19
- package/dist/modes/interactive/slash-command-arguments.d.ts +16 -0
- package/dist/modes/interactive/slash-command-arguments.js +97 -0
- package/dist/modes/rpc/rpc-mode.d.ts +3 -0
- package/dist/modes/rpc/rpc-mode.js +40 -31
- package/dist/modes/rpc/rpc-types.d.ts +3 -0
- package/dist/node_modules/@pencil-agent/agent-core/agent.d.ts +15 -1
- package/dist/node_modules/@pencil-agent/agent-core/agent.js +13 -1
- package/dist/node_modules/@pencil-agent/agent-core/index.d.ts +2 -1
- package/dist/node_modules/@pencil-agent/agent-core/index.js +2 -1
- package/dist/node_modules/@pencil-agent/agent-core/structured-adaptive-agent-loop.d.ts +1 -1
- package/dist/node_modules/@pencil-agent/agent-core/structured-adaptive-agent-loop.js +293 -20
- package/dist/node_modules/@pencil-agent/agent-core/structured-adaptive-streaming-tool-executor.d.ts +33 -0
- package/dist/node_modules/@pencil-agent/agent-core/structured-adaptive-streaming-tool-executor.js +189 -0
- package/dist/node_modules/@pencil-agent/agent-core/structured-adaptive-tool-orchestration.d.ts +9 -0
- package/dist/node_modules/@pencil-agent/agent-core/structured-adaptive-tool-orchestration.js +30 -5
- package/dist/node_modules/@pencil-agent/agent-core/types.d.ts +90 -3
- package/dist/node_modules/@pencil-agent/agent-core/types.js +1 -1
- package/dist/node_modules/@pencil-agent/ai/models.generated.d.ts +0 -17
- package/dist/node_modules/@pencil-agent/ai/models.generated.js +29 -46
- package/dist/node_modules/@pencil-agent/tui/autocomplete.d.ts +8 -1
- package/dist/node_modules/@pencil-agent/tui/autocomplete.js +18 -2
- package/dist/node_modules/@pencil-agent/tui/index.d.ts +1 -1
- package/dist/node_modules/@pencil-agent/tui/tui.d.ts +8 -3
- package/dist/node_modules/@pencil-agent/tui/tui.js +68 -33
- package/dist/packages/mem-core/extension.js +154 -83
- package/dist/packages/mem-core/full-insights-sections.d.ts +48 -0
- package/dist/packages/mem-core/full-insights-sections.js +231 -0
- package/dist/packages/mem-core/full-insights.d.ts +1 -1
- package/dist/packages/mem-core/full-insights.js +102 -42
- package/package.json +2 -2
|
@@ -306,6 +306,7 @@ export declare class InteractiveMode {
|
|
|
306
306
|
private promptAfterRender;
|
|
307
307
|
private updateEditorBorderColor;
|
|
308
308
|
private cycleThinkingLevel;
|
|
309
|
+
private handleThinkingCommand;
|
|
309
310
|
private handleAgentLoopCommand;
|
|
310
311
|
private cycleModel;
|
|
311
312
|
private toggleToolOutputExpansion;
|
|
@@ -398,7 +399,7 @@ export declare class InteractiveMode {
|
|
|
398
399
|
private getEditorKeyDisplay;
|
|
399
400
|
private handleHotkeysCommand;
|
|
400
401
|
private handleClearCommand;
|
|
401
|
-
private
|
|
402
|
+
private handleRenderDebugCommand;
|
|
402
403
|
private handleArminSaysHi;
|
|
403
404
|
private handleShowResourcesCommand;
|
|
404
405
|
private handleDaxnuts;
|
|
@@ -13,7 +13,7 @@ import { createCompactionSummaryMessage } from "../../core/messages.js";
|
|
|
13
13
|
import { listMCPServers, setMCPServerEnabled } from "../../core/mcp/mcp-config.js";
|
|
14
14
|
import { resolveModelScope } from "../../core/model-resolver.js";
|
|
15
15
|
import { SessionManager, } from "../../core/session/session-manager.js";
|
|
16
|
-
import { getLocalizedCommands } from "../../core/slash-commands.js";
|
|
16
|
+
import { getExtensionBackedBuiltinCommandNames, formatSlashCommandDescription, getLocalizedCommands, inferSlashCommandCategory, } from "../../core/slash-commands.js";
|
|
17
17
|
import { t } from "../../core/i18n/index.js";
|
|
18
18
|
import { getActivePersonaId, getPersonaDir, getPersonaMcpConfigPath, getPersonaMemoryDir, getPersonaSoulDir, listPersonas, setActivePersonaId, toAbsolutePath, } from "../../core/persona/persona-manager.js";
|
|
19
19
|
import { NANOPENCIL_ALI_TOKEN_PLAN_ANTHROPIC_PROVIDER, NANOPENCIL_ALI_TOKEN_PLAN_OPENAI_PROVIDER, NANOPENCIL_WHATS_NEW, } from "../../nanopencil-defaults.js";
|
|
@@ -58,6 +58,7 @@ import { UserMessageComponent } from "./components/user-message.js";
|
|
|
58
58
|
import { UserMessageSelectorComponent } from "./components/user-message-selector.js";
|
|
59
59
|
import { RawText } from "./components/raw-text.js";
|
|
60
60
|
import { getAvailableThemes, getAvailableThemesWithPaths, getEditorTheme, getMarkdownTheme, getThemeByName, initTheme, onThemeChange, setRegisteredThemes, setTheme, setThemeInstance, Theme, theme, } from "./theme/theme.js";
|
|
61
|
+
import { getAgentLoopArgumentCompletions, getLanguageArgumentCompletions, getMcpArgumentCompletions, getPersonaArgumentCompletions, getThinkingArgumentCompletions, } from "./slash-command-arguments.js";
|
|
61
62
|
function isExpandable(obj) {
|
|
62
63
|
return (typeof obj === "object" &&
|
|
63
64
|
obj !== null &&
|
|
@@ -230,7 +231,7 @@ export class InteractiveMode {
|
|
|
230
231
|
const localizedCommands = getLocalizedCommands(t);
|
|
231
232
|
const slashCommands = localizedCommands.map((command) => ({
|
|
232
233
|
name: command.name,
|
|
233
|
-
description: command.description,
|
|
234
|
+
description: formatSlashCommandDescription(command.description, command.category, t),
|
|
234
235
|
}));
|
|
235
236
|
const modelCommand = slashCommands.find((command) => command.name === "model");
|
|
236
237
|
if (modelCommand) {
|
|
@@ -258,16 +259,53 @@ export class InteractiveMode {
|
|
|
258
259
|
}));
|
|
259
260
|
};
|
|
260
261
|
}
|
|
262
|
+
const thinkingCommand = slashCommands.find((command) => command.name === "thinking");
|
|
263
|
+
if (thinkingCommand) {
|
|
264
|
+
thinkingCommand.getArgumentCompletions = (prefix, context) => getThinkingArgumentCompletions(prefix, context, this.session.getAvailableThinkingLevels());
|
|
265
|
+
}
|
|
266
|
+
const agentLoopCommand = slashCommands.find((command) => command.name === "agent-loop");
|
|
267
|
+
if (agentLoopCommand) {
|
|
268
|
+
agentLoopCommand.getArgumentCompletions = getAgentLoopArgumentCompletions;
|
|
269
|
+
}
|
|
270
|
+
const mcpCommand = slashCommands.find((command) => command.name === "mcp");
|
|
271
|
+
if (mcpCommand) {
|
|
272
|
+
mcpCommand.getArgumentCompletions = (prefix, context) => getMcpArgumentCompletions(prefix, context, listMCPServers());
|
|
273
|
+
}
|
|
274
|
+
const languageCommand = slashCommands.find((command) => command.name === "language");
|
|
275
|
+
if (languageCommand) {
|
|
276
|
+
languageCommand.getArgumentCompletions = getLanguageArgumentCompletions;
|
|
277
|
+
}
|
|
278
|
+
const personaCommand = slashCommands.find((command) => command.name === "persona");
|
|
279
|
+
if (personaCommand) {
|
|
280
|
+
personaCommand.getArgumentCompletions = (prefix, context) => getPersonaArgumentCompletions(prefix, context, listPersonas(), getActivePersonaId());
|
|
281
|
+
}
|
|
261
282
|
// Convert prompt templates to SlashCommand format for autocomplete
|
|
262
283
|
const templateCommands = this.session.promptTemplates.map((cmd) => ({
|
|
263
284
|
name: cmd.name,
|
|
264
|
-
description: cmd.description,
|
|
285
|
+
description: formatSlashCommandDescription(cmd.description, inferSlashCommandCategory(cmd.name, "prompt"), t),
|
|
265
286
|
}));
|
|
266
|
-
// Convert extension commands to SlashCommand format
|
|
287
|
+
// Convert extension commands to SlashCommand format. Some discoverable
|
|
288
|
+
// built-ins are implemented by default extensions; merge their argument
|
|
289
|
+
// completions into the built-in entry instead of showing duplicates.
|
|
267
290
|
const builtinCommandNames = new Set(slashCommands.map((c) => c.name));
|
|
268
|
-
const
|
|
291
|
+
const extensionBackedBuiltinNames = getExtensionBackedBuiltinCommandNames();
|
|
292
|
+
const reservedCommandNames = new Set([...builtinCommandNames].filter((name) => !extensionBackedBuiltinNames.has(name)));
|
|
293
|
+
const registeredExtensionCommands = this.session.extensionRunner?.getRegisteredCommands(reservedCommandNames) ?? [];
|
|
294
|
+
const extensionCommandByName = new Map(registeredExtensionCommands.map((command) => [command.name, command]));
|
|
295
|
+
for (const command of slashCommands) {
|
|
296
|
+
if (!extensionBackedBuiltinNames.has(command.name))
|
|
297
|
+
continue;
|
|
298
|
+
const extensionCommand = extensionCommandByName.get(command.name);
|
|
299
|
+
if (extensionCommand?.getArgumentCompletions) {
|
|
300
|
+
command.getArgumentCompletions =
|
|
301
|
+
extensionCommand.getArgumentCompletions;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
const extensionCommands = registeredExtensionCommands
|
|
305
|
+
.filter((cmd) => !builtinCommandNames.has(cmd.name))
|
|
306
|
+
.map((cmd) => ({
|
|
269
307
|
name: cmd.name,
|
|
270
|
-
description: cmd.description ?? "(extension command)",
|
|
308
|
+
description: formatSlashCommandDescription(cmd.description ?? "(extension command)", inferSlashCommandCategory(cmd.name, "extension"), t),
|
|
271
309
|
getArgumentCompletions: cmd.getArgumentCompletions,
|
|
272
310
|
}));
|
|
273
311
|
// Build skill commands from session.skills (if enabled)
|
|
@@ -279,7 +317,7 @@ export class InteractiveMode {
|
|
|
279
317
|
this.skillCommands.set(commandName, skill.filePath);
|
|
280
318
|
skillCommandList.push({
|
|
281
319
|
name: commandName,
|
|
282
|
-
description: skill.description,
|
|
320
|
+
description: formatSlashCommandDescription(skill.description, inferSlashCommandCategory(skill.name, "skill"), t),
|
|
283
321
|
});
|
|
284
322
|
}
|
|
285
323
|
}
|
|
@@ -1691,7 +1729,7 @@ export class InteractiveMode {
|
|
|
1691
1729
|
this.defaultEditor.onAction("cycleModelForward", () => this.cycleModel("forward"));
|
|
1692
1730
|
this.defaultEditor.onAction("cycleModelBackward", () => this.cycleModel("backward"));
|
|
1693
1731
|
// Global debug handler on TUI (works regardless of focus)
|
|
1694
|
-
this.ui.onDebug = () => this.
|
|
1732
|
+
this.ui.onDebug = () => this.handleRenderDebugCommand();
|
|
1695
1733
|
this.defaultEditor.onAction("selectModel", () => this.showProviderThenModelSelector());
|
|
1696
1734
|
this.defaultEditor.onAction("selectProviderThenModel", () => this.showProviderThenModelSelector());
|
|
1697
1735
|
this.defaultEditor.onAction("expandTools", () => this.toggleToolOutputExpansion());
|
|
@@ -1984,11 +2022,6 @@ export class InteractiveMode {
|
|
|
1984
2022
|
this.editor.setText("");
|
|
1985
2023
|
return;
|
|
1986
2024
|
}
|
|
1987
|
-
if (text === "/debug") {
|
|
1988
|
-
this.handleDebugCommand();
|
|
1989
|
-
this.editor.setText("");
|
|
1990
|
-
return;
|
|
1991
|
-
}
|
|
1992
2025
|
if (text === "/arminsayshi") {
|
|
1993
2026
|
this.handleArminSaysHi();
|
|
1994
2027
|
this.editor.setText("");
|
|
@@ -2209,6 +2242,11 @@ export class InteractiveMode {
|
|
|
2209
2242
|
await this.handleModelCommand(searchTerm);
|
|
2210
2243
|
return true;
|
|
2211
2244
|
}
|
|
2245
|
+
if (text === "/thinking" || text.startsWith("/thinking ")) {
|
|
2246
|
+
this.handleThinkingCommand(text);
|
|
2247
|
+
clear();
|
|
2248
|
+
return true;
|
|
2249
|
+
}
|
|
2212
2250
|
if (text === "/agent-loop" || text.startsWith("/agent-loop ")) {
|
|
2213
2251
|
this.handleAgentLoopCommand(text);
|
|
2214
2252
|
clear();
|
|
@@ -2337,11 +2375,6 @@ export class InteractiveMode {
|
|
|
2337
2375
|
clear();
|
|
2338
2376
|
return true;
|
|
2339
2377
|
}
|
|
2340
|
-
if (text === "/debug") {
|
|
2341
|
-
this.handleDebugCommand();
|
|
2342
|
-
clear();
|
|
2343
|
-
return true;
|
|
2344
|
-
}
|
|
2345
2378
|
if (text === "/arminsayshi") {
|
|
2346
2379
|
this.handleArminSaysHi();
|
|
2347
2380
|
clear();
|
|
@@ -3165,6 +3198,22 @@ export class InteractiveMode {
|
|
|
3165
3198
|
this.showStatus(`Thinking level: ${newLevel}`);
|
|
3166
3199
|
}
|
|
3167
3200
|
}
|
|
3201
|
+
handleThinkingCommand(text) {
|
|
3202
|
+
const arg = text.slice("/thinking".length).trim().toLowerCase();
|
|
3203
|
+
const levels = this.session.getAvailableThinkingLevels();
|
|
3204
|
+
if (!arg) {
|
|
3205
|
+
this.showStatus(`Thinking level: ${this.session.thinkingLevel} (available: ${levels.join(", ")})`);
|
|
3206
|
+
return;
|
|
3207
|
+
}
|
|
3208
|
+
if (!levels.includes(arg)) {
|
|
3209
|
+
this.showStatus(`Unknown thinking level: ${arg} (available: ${levels.join(", ")})`);
|
|
3210
|
+
return;
|
|
3211
|
+
}
|
|
3212
|
+
this.session.setThinkingLevel(arg);
|
|
3213
|
+
this.footer.invalidate();
|
|
3214
|
+
this.updateEditorBorderColor();
|
|
3215
|
+
this.showStatus(`Thinking level: ${this.session.thinkingLevel}`);
|
|
3216
|
+
}
|
|
3168
3217
|
handleAgentLoopCommand(text) {
|
|
3169
3218
|
const arg = text.slice("/agent-loop".length).trim().toLowerCase();
|
|
3170
3219
|
const choices = ["standard", "weak-model-compatible"];
|
|
@@ -5129,7 +5178,7 @@ export class InteractiveMode {
|
|
|
5129
5178
|
this.chatContainer.addChild(new Text(`${theme.fg("accent", "✓ New session started")}`, 1, 1));
|
|
5130
5179
|
this.ui.requestRender();
|
|
5131
5180
|
}
|
|
5132
|
-
|
|
5181
|
+
handleRenderDebugCommand() {
|
|
5133
5182
|
const width = this.ui.terminal.columns;
|
|
5134
5183
|
const height = this.ui.terminal.rows;
|
|
5135
5184
|
const allLines = this.ui.render(width);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* [WHO]: getAgentLoopArgumentCompletions(), getThinkingArgumentCompletions(), getMcpArgumentCompletions(), getLanguageArgumentCompletions(), getPersonaArgumentCompletions()
|
|
3
|
+
* [FROM]: Depends on @pencil-agent/agent-core, @pencil-agent/tui, core/i18n, core/mcp/mcp-client
|
|
4
|
+
* [TO]: Consumed by modes/interactive/interactive-mode.ts
|
|
5
|
+
* [HERE]: modes/interactive/slash-command-arguments.ts - pure argument completion helpers for built-in TUI slash commands
|
|
6
|
+
*/
|
|
7
|
+
import type { ThinkingLevel } from "@pencil-agent/agent-core";
|
|
8
|
+
import type { ArgumentCompletionContext, AutocompleteItem } from "@pencil-agent/tui";
|
|
9
|
+
import type { MCPServerConfig } from "../../core/mcp/mcp-client.js";
|
|
10
|
+
type McpCompletionServer = Pick<MCPServerConfig, "id" | "name" | "enabled">;
|
|
11
|
+
export declare function getThinkingArgumentCompletions(argumentPrefix: string, context: Pick<ArgumentCompletionContext, "tokenIndex"> | undefined, levels: readonly ThinkingLevel[]): AutocompleteItem[] | null;
|
|
12
|
+
export declare function getAgentLoopArgumentCompletions(argumentPrefix: string, context?: Pick<ArgumentCompletionContext, "tokenIndex">): AutocompleteItem[] | null;
|
|
13
|
+
export declare function getMcpArgumentCompletions(argumentPrefix: string, context?: Pick<ArgumentCompletionContext, "tokenIndex" | "previousTokens">, servers?: readonly McpCompletionServer[]): AutocompleteItem[] | null;
|
|
14
|
+
export declare function getLanguageArgumentCompletions(argumentPrefix: string, context?: Pick<ArgumentCompletionContext, "tokenIndex">): AutocompleteItem[] | null;
|
|
15
|
+
export declare function getPersonaArgumentCompletions(argumentPrefix: string, context?: Pick<ArgumentCompletionContext, "tokenIndex" | "previousTokens">, personas?: readonly string[], activePersonaId?: string): AutocompleteItem[] | null;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* [WHO]: getAgentLoopArgumentCompletions(), getThinkingArgumentCompletions(), getMcpArgumentCompletions(), getLanguageArgumentCompletions(), getPersonaArgumentCompletions()
|
|
3
|
+
* [FROM]: Depends on @pencil-agent/agent-core, @pencil-agent/tui, core/i18n, core/mcp/mcp-client
|
|
4
|
+
* [TO]: Consumed by modes/interactive/interactive-mode.ts
|
|
5
|
+
* [HERE]: modes/interactive/slash-command-arguments.ts - pure argument completion helpers for built-in TUI slash commands
|
|
6
|
+
*/
|
|
7
|
+
import { AVAILABLE_LOCALES, LOCALE_NAMES } from "../../core/i18n/index.js";
|
|
8
|
+
const THINKING_COMPLETIONS = {
|
|
9
|
+
off: "Skip extra reasoning",
|
|
10
|
+
minimal: "Very small reasoning budget",
|
|
11
|
+
low: "Light reasoning for simple tasks",
|
|
12
|
+
medium: "Balanced reasoning for everyday coding",
|
|
13
|
+
high: "Deeper reasoning for complex work",
|
|
14
|
+
xhigh: "Maximum reasoning when the model supports it",
|
|
15
|
+
};
|
|
16
|
+
const AGENT_LOOP_COMPLETIONS = [
|
|
17
|
+
{
|
|
18
|
+
value: "standard",
|
|
19
|
+
label: "standard",
|
|
20
|
+
description: "Use the normal agent loop",
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
value: "weak-model-compatible",
|
|
24
|
+
label: "weak-model-compatible",
|
|
25
|
+
description: "Keep working with simpler models",
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
const MCP_ACTION_COMPLETIONS = [
|
|
29
|
+
{ value: "list", label: "list", description: "Show configured MCP servers" },
|
|
30
|
+
{ value: "status", label: "status", description: "Show loaded MCP tools and runtime status" },
|
|
31
|
+
{ value: "tools", label: "tools", description: "Show loaded MCP tools and runtime status" },
|
|
32
|
+
{ value: "enable", label: "enable", description: "Turn on an MCP server" },
|
|
33
|
+
{ value: "disable", label: "disable", description: "Turn off an MCP server" },
|
|
34
|
+
];
|
|
35
|
+
const PERSONA_ACTION_COMPLETIONS = [
|
|
36
|
+
{ value: "list", label: "list", description: "Show available personas" },
|
|
37
|
+
{ value: "use", label: "use", description: "Switch to a persona" },
|
|
38
|
+
];
|
|
39
|
+
function matchCompletions(items, prefix) {
|
|
40
|
+
const lowerPrefix = prefix.trim().toLowerCase();
|
|
41
|
+
const matches = items.filter((item) => item.value.toLowerCase().startsWith(lowerPrefix));
|
|
42
|
+
return matches.length > 0 ? matches.map((item) => ({ ...item })) : null;
|
|
43
|
+
}
|
|
44
|
+
function isFirstToken(context) {
|
|
45
|
+
return !context || context.tokenIndex === 0;
|
|
46
|
+
}
|
|
47
|
+
export function getThinkingArgumentCompletions(argumentPrefix, context, levels) {
|
|
48
|
+
if (!isFirstToken(context))
|
|
49
|
+
return null;
|
|
50
|
+
return matchCompletions(levels.map((level) => ({
|
|
51
|
+
value: level,
|
|
52
|
+
label: level,
|
|
53
|
+
description: THINKING_COMPLETIONS[level],
|
|
54
|
+
})), argumentPrefix);
|
|
55
|
+
}
|
|
56
|
+
export function getAgentLoopArgumentCompletions(argumentPrefix, context) {
|
|
57
|
+
if (!isFirstToken(context))
|
|
58
|
+
return null;
|
|
59
|
+
return matchCompletions(AGENT_LOOP_COMPLETIONS, argumentPrefix);
|
|
60
|
+
}
|
|
61
|
+
export function getMcpArgumentCompletions(argumentPrefix, context, servers = []) {
|
|
62
|
+
if (isFirstToken(context))
|
|
63
|
+
return matchCompletions(MCP_ACTION_COMPLETIONS, argumentPrefix);
|
|
64
|
+
if (context?.tokenIndex !== 1)
|
|
65
|
+
return null;
|
|
66
|
+
const action = context.previousTokens[0]?.toLowerCase();
|
|
67
|
+
if (action !== "enable" && action !== "disable")
|
|
68
|
+
return null;
|
|
69
|
+
const targetEnabledState = action === "disable";
|
|
70
|
+
return matchCompletions(servers
|
|
71
|
+
.filter((server) => (server.enabled !== false) === targetEnabledState)
|
|
72
|
+
.map((server) => ({
|
|
73
|
+
value: server.id,
|
|
74
|
+
label: server.id,
|
|
75
|
+
description: `${server.name} (${server.enabled === false ? "disabled" : "enabled"})`,
|
|
76
|
+
})), argumentPrefix);
|
|
77
|
+
}
|
|
78
|
+
export function getLanguageArgumentCompletions(argumentPrefix, context) {
|
|
79
|
+
if (!isFirstToken(context))
|
|
80
|
+
return null;
|
|
81
|
+
return matchCompletions(AVAILABLE_LOCALES.map((locale) => ({
|
|
82
|
+
value: locale,
|
|
83
|
+
label: locale,
|
|
84
|
+
description: LOCALE_NAMES[locale],
|
|
85
|
+
})), argumentPrefix);
|
|
86
|
+
}
|
|
87
|
+
export function getPersonaArgumentCompletions(argumentPrefix, context, personas = [], activePersonaId) {
|
|
88
|
+
if (isFirstToken(context))
|
|
89
|
+
return matchCompletions(PERSONA_ACTION_COMPLETIONS, argumentPrefix);
|
|
90
|
+
if (context?.tokenIndex !== 1 || context.previousTokens[0]?.toLowerCase() !== "use")
|
|
91
|
+
return null;
|
|
92
|
+
return matchCompletions(personas.map((personaId) => ({
|
|
93
|
+
value: personaId,
|
|
94
|
+
label: personaId,
|
|
95
|
+
description: personaId === activePersonaId ? "Current persona" : `Switch to ${personaId}`,
|
|
96
|
+
})), argumentPrefix);
|
|
97
|
+
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { AgentSession } from "../../core/runtime/agent-session.js";
|
|
2
|
+
import type { RpcSlashCommand } from "./rpc-types.js";
|
|
2
3
|
export type { RpcCommand, RpcExtensionUIRequest, RpcExtensionUIResponse, RpcResponse, RpcSessionState, } from "./rpc-types.js";
|
|
4
|
+
type RpcSlashCommandCatalogSession = Pick<AgentSession, "extensionRunner" | "promptTemplates" | "resourceLoader">;
|
|
5
|
+
export declare function buildRpcSlashCommands(session: RpcSlashCommandCatalogSession): RpcSlashCommand[];
|
|
3
6
|
/**
|
|
4
7
|
* Run in RPC mode.
|
|
5
8
|
* Listens for JSON commands on stdin, outputs events and responses on stdout.
|
|
@@ -6,7 +6,46 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import * as crypto from "node:crypto";
|
|
8
8
|
import * as readline from "readline";
|
|
9
|
+
import { buildExtensionSlashCommands } from "../../core/runtime/slash-command-catalog.js";
|
|
10
|
+
import { inferSlashCommandCategory } from "../../core/slash-commands.js";
|
|
9
11
|
import { theme } from "../interactive/theme/theme.js";
|
|
12
|
+
function toRpcSlashCommand(command) {
|
|
13
|
+
return {
|
|
14
|
+
name: command.name,
|
|
15
|
+
description: command.description,
|
|
16
|
+
source: command.source,
|
|
17
|
+
category: command.category,
|
|
18
|
+
location: command.location,
|
|
19
|
+
path: command.path,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export function buildRpcSlashCommands(session) {
|
|
23
|
+
if (session.extensionRunner) {
|
|
24
|
+
return buildExtensionSlashCommands({
|
|
25
|
+
promptTemplates: session.promptTemplates,
|
|
26
|
+
resourceLoader: session.resourceLoader,
|
|
27
|
+
extensionRunner: session.extensionRunner,
|
|
28
|
+
}).map(toRpcSlashCommand);
|
|
29
|
+
}
|
|
30
|
+
return [
|
|
31
|
+
...session.promptTemplates.map((template) => ({
|
|
32
|
+
name: template.name,
|
|
33
|
+
description: template.description,
|
|
34
|
+
source: "prompt",
|
|
35
|
+
category: inferSlashCommandCategory(template.name, "prompt"),
|
|
36
|
+
location: template.source,
|
|
37
|
+
path: template.filePath,
|
|
38
|
+
})),
|
|
39
|
+
...session.resourceLoader.getSkills().skills.map((skill) => ({
|
|
40
|
+
name: `skill:${skill.name}`,
|
|
41
|
+
description: skill.description,
|
|
42
|
+
source: "skill",
|
|
43
|
+
category: inferSlashCommandCategory(skill.name, "skill"),
|
|
44
|
+
location: skill.source,
|
|
45
|
+
path: skill.filePath,
|
|
46
|
+
})),
|
|
47
|
+
];
|
|
48
|
+
}
|
|
10
49
|
/**
|
|
11
50
|
* Run in RPC mode.
|
|
12
51
|
* Listens for JSON commands on stdin, outputs events and responses on stdout.
|
|
@@ -436,37 +475,7 @@ export async function runRpcMode(session) {
|
|
|
436
475
|
// Commands (available for invocation via prompt)
|
|
437
476
|
// =================================================================
|
|
438
477
|
case "get_commands": {
|
|
439
|
-
|
|
440
|
-
// Extension commands
|
|
441
|
-
for (const { command, extensionPath } of session.extensionRunner?.getRegisteredCommandsWithPaths() ?? []) {
|
|
442
|
-
commands.push({
|
|
443
|
-
name: command.name,
|
|
444
|
-
description: command.description,
|
|
445
|
-
source: "extension",
|
|
446
|
-
path: extensionPath,
|
|
447
|
-
});
|
|
448
|
-
}
|
|
449
|
-
// Prompt templates (source is always "user" | "project" | "path" in coding-agent)
|
|
450
|
-
for (const template of session.promptTemplates) {
|
|
451
|
-
commands.push({
|
|
452
|
-
name: template.name,
|
|
453
|
-
description: template.description,
|
|
454
|
-
source: "prompt",
|
|
455
|
-
location: template.source,
|
|
456
|
-
path: template.filePath,
|
|
457
|
-
});
|
|
458
|
-
}
|
|
459
|
-
// Skills (source is always "user" | "project" | "path" in coding-agent)
|
|
460
|
-
for (const skill of session.resourceLoader.getSkills().skills) {
|
|
461
|
-
commands.push({
|
|
462
|
-
name: `skill:${skill.name}`,
|
|
463
|
-
description: skill.description,
|
|
464
|
-
source: "skill",
|
|
465
|
-
location: skill.source,
|
|
466
|
-
path: skill.filePath,
|
|
467
|
-
});
|
|
468
|
-
}
|
|
469
|
-
return success(id, "get_commands", { commands });
|
|
478
|
+
return success(id, "get_commands", { commands: buildRpcSlashCommands(session) });
|
|
470
479
|
}
|
|
471
480
|
default: {
|
|
472
481
|
const unknownCommand = command;
|
|
@@ -9,6 +9,7 @@ import type { ImageContent, Model } from "@pencil-agent/ai";
|
|
|
9
9
|
import type { SessionStats } from "../../core/runtime/agent-session.js";
|
|
10
10
|
import type { BashResult } from "../../core/bash-executor.js";
|
|
11
11
|
import type { CompactionResult } from "../../core/session/compaction/index.js";
|
|
12
|
+
import type { SlashCommandCategory } from "../../core/slash-commands.js";
|
|
12
13
|
type AgentLoopFrameworkInput = AgentLoopFramework | "high-intelligence" | "low-intelligence" | "structured-adaptive";
|
|
13
14
|
export type RpcCommand = {
|
|
14
15
|
id?: string;
|
|
@@ -128,6 +129,8 @@ export interface RpcSlashCommand {
|
|
|
128
129
|
description?: string;
|
|
129
130
|
/** What kind of command this is */
|
|
130
131
|
source: "extension" | "prompt" | "skill";
|
|
132
|
+
/** Human-facing command category for grouping and filtering */
|
|
133
|
+
category?: SlashCommandCategory;
|
|
131
134
|
/** Where the command was loaded from (undefined for extensions) */
|
|
132
135
|
location?: "user" | "project" | "path";
|
|
133
136
|
/** File path to the command source */
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* No transport abstraction - calls streamSimple via the loop.
|
|
4
4
|
*/
|
|
5
5
|
/**
|
|
6
|
-
* [WHO]: AgentOptions, Agent
|
|
6
|
+
* [WHO]: AgentOptions, Agent, in-loop model error recovery and loop budget option plumbing
|
|
7
7
|
* [FROM]: Depends on ./agent-loop.js and ./structured-adaptive-agent-loop.js
|
|
8
8
|
* [TO]: Consumed by packages/agent-core/src/index.ts
|
|
9
9
|
* [HERE]: packages/agent-core/src/agent.ts -
|
|
@@ -68,6 +68,16 @@ export interface AgentOptions {
|
|
|
68
68
|
* Optional tool permission gate used by weak-model-compatible loop execution.
|
|
69
69
|
*/
|
|
70
70
|
canUseTool?: AgentLoopConfig["canUseTool"];
|
|
71
|
+
/**
|
|
72
|
+
* Optional aggregate tool-result batch budget used by weak-model-compatible loop execution.
|
|
73
|
+
*/
|
|
74
|
+
maxToolResultBatchSizeChars?: AgentLoopConfig["maxToolResultBatchSizeChars"];
|
|
75
|
+
/**
|
|
76
|
+
* Optional in-loop model error recovery hook used by weak-model-compatible loop execution.
|
|
77
|
+
*/
|
|
78
|
+
recoverModelError?: AgentLoopConfig["recoverModelError"];
|
|
79
|
+
/** Maximum in-loop model error recoveries per prompt. */
|
|
80
|
+
maxModelErrorRecoveryAttempts?: number;
|
|
71
81
|
}
|
|
72
82
|
export declare class Agent {
|
|
73
83
|
private _state;
|
|
@@ -89,6 +99,9 @@ export declare class Agent {
|
|
|
89
99
|
private _maxRetryDelayMs?;
|
|
90
100
|
private _agentLoopFramework?;
|
|
91
101
|
private canUseTool?;
|
|
102
|
+
private maxToolResultBatchSizeChars?;
|
|
103
|
+
private recoverModelError?;
|
|
104
|
+
private maxModelErrorRecoveryAttempts?;
|
|
92
105
|
constructor(opts?: AgentOptions);
|
|
93
106
|
/**
|
|
94
107
|
* Get the current session ID used for provider caching.
|
|
@@ -136,6 +149,7 @@ export declare class Agent {
|
|
|
136
149
|
setFollowUpMode(mode: "all" | "one-at-a-time"): void;
|
|
137
150
|
getFollowUpMode(): "all" | "one-at-a-time";
|
|
138
151
|
setTools(t: AgentTool<any>[]): void;
|
|
152
|
+
setModelErrorRecovery(recoverModelError: AgentLoopConfig["recoverModelError"] | undefined): void;
|
|
139
153
|
replaceMessages(ms: AgentMessage[]): void;
|
|
140
154
|
appendMessage(m: AgentMessage): void;
|
|
141
155
|
/**
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* No transport abstraction - calls streamSimple via the loop.
|
|
4
4
|
*/
|
|
5
5
|
/**
|
|
6
|
-
* [WHO]: AgentOptions, Agent
|
|
6
|
+
* [WHO]: AgentOptions, Agent, in-loop model error recovery and loop budget option plumbing
|
|
7
7
|
* [FROM]: Depends on ./agent-loop.js and ./structured-adaptive-agent-loop.js
|
|
8
8
|
* [TO]: Consumed by packages/agent-core/src/index.ts
|
|
9
9
|
* [HERE]: packages/agent-core/src/agent.ts -
|
|
@@ -48,6 +48,9 @@ export class Agent {
|
|
|
48
48
|
_maxRetryDelayMs;
|
|
49
49
|
_agentLoopFramework;
|
|
50
50
|
canUseTool;
|
|
51
|
+
maxToolResultBatchSizeChars;
|
|
52
|
+
recoverModelError;
|
|
53
|
+
maxModelErrorRecoveryAttempts;
|
|
51
54
|
constructor(opts = {}) {
|
|
52
55
|
this._state = { ...this._state, ...opts.initialState };
|
|
53
56
|
this.convertToLlm = opts.convertToLlm || defaultConvertToLlm;
|
|
@@ -62,6 +65,9 @@ export class Agent {
|
|
|
62
65
|
this._maxRetryDelayMs = opts.maxRetryDelayMs;
|
|
63
66
|
this._agentLoopFramework = normalizeAgentLoopFramework(opts.agentLoopFramework);
|
|
64
67
|
this.canUseTool = opts.canUseTool;
|
|
68
|
+
this.maxToolResultBatchSizeChars = opts.maxToolResultBatchSizeChars;
|
|
69
|
+
this.recoverModelError = opts.recoverModelError;
|
|
70
|
+
this.maxModelErrorRecoveryAttempts = opts.maxModelErrorRecoveryAttempts;
|
|
65
71
|
}
|
|
66
72
|
/**
|
|
67
73
|
* Get the current session ID used for provider caching.
|
|
@@ -151,6 +157,9 @@ export class Agent {
|
|
|
151
157
|
setTools(t) {
|
|
152
158
|
this._state.tools = t;
|
|
153
159
|
}
|
|
160
|
+
setModelErrorRecovery(recoverModelError) {
|
|
161
|
+
this.recoverModelError = recoverModelError;
|
|
162
|
+
}
|
|
154
163
|
replaceMessages(ms) {
|
|
155
164
|
this._state.messages = ms.slice();
|
|
156
165
|
}
|
|
@@ -318,6 +327,9 @@ export class Agent {
|
|
|
318
327
|
transformContext: this.transformContext,
|
|
319
328
|
getApiKey: this.getApiKey,
|
|
320
329
|
canUseTool: this.canUseTool,
|
|
330
|
+
maxToolResultBatchSizeChars: this.maxToolResultBatchSizeChars,
|
|
331
|
+
recoverModelError: this.recoverModelError,
|
|
332
|
+
maxModelErrorRecoveryAttempts: this.maxModelErrorRecoveryAttempts,
|
|
321
333
|
getSteeringMessages: async () => {
|
|
322
334
|
if (skipInitialSteeringPoll) {
|
|
323
335
|
skipInitialSteeringPoll = false;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* [WHO]: agent-core barrel exports
|
|
3
|
-
* [FROM]: Depends on agent.js, agent-loop.js, structured-adaptive-agent-loop.js, structured-adaptive-tool-orchestration.js, proxy.js, types.js
|
|
3
|
+
* [FROM]: Depends on agent.js, agent-loop.js, structured-adaptive-agent-loop.js, structured-adaptive-tool-orchestration.js, structured-adaptive-streaming-tool-executor.js, proxy.js, types.js
|
|
4
4
|
* [TO]: Consumed by @pencil-agent/agent-core package consumers
|
|
5
5
|
* [HERE]: packages/agent-core/src/index.ts - agent-core entry point
|
|
6
6
|
*/
|
|
@@ -8,6 +8,7 @@ export * from "./agent.js";
|
|
|
8
8
|
export * from "./agent-loop.js";
|
|
9
9
|
export * from "./structured-adaptive-agent-loop.js";
|
|
10
10
|
export * from "./structured-adaptive-tool-orchestration.js";
|
|
11
|
+
export * from "./structured-adaptive-streaming-tool-executor.js";
|
|
11
12
|
export * from "./proxy.js";
|
|
12
13
|
export * from "./types.js";
|
|
13
14
|
export * from "./errors.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* [WHO]: agent-core barrel exports
|
|
3
|
-
* [FROM]: Depends on agent.js, agent-loop.js, structured-adaptive-agent-loop.js, structured-adaptive-tool-orchestration.js, proxy.js, types.js
|
|
3
|
+
* [FROM]: Depends on agent.js, agent-loop.js, structured-adaptive-agent-loop.js, structured-adaptive-tool-orchestration.js, structured-adaptive-streaming-tool-executor.js, proxy.js, types.js
|
|
4
4
|
* [TO]: Consumed by @pencil-agent/agent-core package consumers
|
|
5
5
|
* [HERE]: packages/agent-core/src/index.ts - agent-core entry point
|
|
6
6
|
*/
|
|
@@ -10,6 +10,7 @@ export * from "./agent.js";
|
|
|
10
10
|
export * from "./agent-loop.js";
|
|
11
11
|
export * from "./structured-adaptive-agent-loop.js";
|
|
12
12
|
export * from "./structured-adaptive-tool-orchestration.js";
|
|
13
|
+
export * from "./structured-adaptive-streaming-tool-executor.js";
|
|
13
14
|
// Proxy utilities
|
|
14
15
|
export * from "./proxy.js";
|
|
15
16
|
// Types
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
/**
|
|
7
7
|
* [WHO]: structuredAdaptiveAgentLoop, structuredAdaptiveAgentLoopContinue
|
|
8
|
-
* [FROM]: Depends on @pencil-agent/ai, ./types, ./errors, ./structured-adaptive-tool-orchestration
|
|
8
|
+
* [FROM]: Depends on @pencil-agent/ai, ./types, ./errors, ./structured-adaptive-tool-orchestration, ./structured-adaptive-streaming-tool-executor
|
|
9
9
|
* [TO]: Consumed by packages/agent-core/src/agent.ts and index.ts
|
|
10
10
|
* [HERE]: packages/agent-core/src/structured-adaptive-agent-loop.ts - selectable structured-adaptive query loop framework
|
|
11
11
|
*/
|