@mariozechner/pi-coding-agent 0.46.0 → 0.47.0
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 +29 -0
- package/dist/core/agent-session.d.ts +11 -3
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +81 -14
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/export-html/ansi-to-html.d.ts +22 -0
- package/dist/core/export-html/ansi-to-html.d.ts.map +1 -0
- package/dist/core/export-html/ansi-to-html.js +249 -0
- package/dist/core/export-html/ansi-to-html.js.map +1 -0
- package/dist/core/export-html/index.d.ts +17 -0
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js +52 -23
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/export-html/template.css +0 -33
- package/dist/core/export-html/template.js +171 -18
- package/dist/core/export-html/tool-renderer.d.ts +35 -0
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -0
- package/dist/core/export-html/tool-renderer.js +57 -0
- package/dist/core/export-html/tool-renderer.js.map +1 -0
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +5 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +41 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +24 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js +4 -27
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +6 -37
- package/dist/core/skills.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +19 -14
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/path-utils.d.ts +1 -0
- package/dist/core/tools/path-utils.d.ts.map +1 -1
- package/dist/core/tools/path-utils.js +7 -0
- package/dist/core/tools/path-utils.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +13 -2
- package/dist/core/tools/read.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +32 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +2 -2
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +2 -2
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +1 -1
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts +7 -0
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +140 -4
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +0 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +4 -29
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +1 -1
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +1 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/utils/frontmatter.d.ts +8 -0
- package/dist/utils/frontmatter.d.ts.map +1 -0
- package/dist/utils/frontmatter.js +26 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/docs/extensions.md +51 -0
- package/docs/rpc.md +15 -15
- package/docs/tui.md +26 -0
- package/examples/extensions/input-transform.ts +43 -0
- package/examples/extensions/modal-editor.ts +1 -1
- package/examples/extensions/overlay-test.ts +8 -3
- package/examples/extensions/question.ts +1 -1
- package/examples/extensions/questionnaire.ts +1 -1
- package/examples/extensions/rainbow-editor.ts +1 -8
- package/examples/extensions/subagent/agents.ts +3 -32
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +6 -5
|
@@ -12,11 +12,15 @@
|
|
|
12
12
|
*
|
|
13
13
|
* Modes use this class and add their own I/O layer on top.
|
|
14
14
|
*/
|
|
15
|
+
import { readFileSync } from "node:fs";
|
|
15
16
|
import { isContextOverflow, modelsAreEqual, supportsXhigh } from "@mariozechner/pi-ai";
|
|
16
17
|
import { getAuthPath } from "../config.js";
|
|
18
|
+
import { theme } from "../modes/interactive/theme/theme.js";
|
|
19
|
+
import { stripFrontmatter } from "../utils/frontmatter.js";
|
|
17
20
|
import { executeBash as executeBashCommand, executeBashWithOperations } from "./bash-executor.js";
|
|
18
21
|
import { calculateContextTokens, collectEntriesForBranchSummary, compact, generateBranchSummary, prepareCompaction, shouldCompact, } from "./compaction/index.js";
|
|
19
22
|
import { exportSessionToHtml } from "./export-html/index.js";
|
|
23
|
+
import { createToolHtmlRenderer } from "./export-html/tool-renderer.js";
|
|
20
24
|
import { expandPromptTemplate } from "./prompt-templates.js";
|
|
21
25
|
// ============================================================================
|
|
22
26
|
// Constants
|
|
@@ -394,8 +398,25 @@ export class AgentSession {
|
|
|
394
398
|
return;
|
|
395
399
|
}
|
|
396
400
|
}
|
|
397
|
-
//
|
|
398
|
-
|
|
401
|
+
// Emit input event for extension interception (before skill/template expansion)
|
|
402
|
+
let currentText = text;
|
|
403
|
+
let currentImages = options?.images;
|
|
404
|
+
if (this._extensionRunner?.hasHandlers("input")) {
|
|
405
|
+
const inputResult = await this._extensionRunner.emitInput(currentText, currentImages, options?.source ?? "interactive");
|
|
406
|
+
if (inputResult.action === "handled") {
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
if (inputResult.action === "transform") {
|
|
410
|
+
currentText = inputResult.text;
|
|
411
|
+
currentImages = inputResult.images ?? currentImages;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
// Expand skill commands (/skill:name args) and prompt templates (/template args)
|
|
415
|
+
let expandedText = currentText;
|
|
416
|
+
if (expandPromptTemplates) {
|
|
417
|
+
expandedText = this._expandSkillCommand(expandedText);
|
|
418
|
+
expandedText = expandPromptTemplate(expandedText, [...this._promptTemplates]);
|
|
419
|
+
}
|
|
399
420
|
// If streaming, queue via steer() or followUp() based on option
|
|
400
421
|
if (this.isStreaming) {
|
|
401
422
|
if (!options?.streamingBehavior) {
|
|
@@ -432,8 +453,8 @@ export class AgentSession {
|
|
|
432
453
|
const messages = [];
|
|
433
454
|
// Add user message
|
|
434
455
|
const userContent = [{ type: "text", text: expandedText }];
|
|
435
|
-
if (
|
|
436
|
-
userContent.push(...
|
|
456
|
+
if (currentImages) {
|
|
457
|
+
userContent.push(...currentImages);
|
|
437
458
|
}
|
|
438
459
|
messages.push({
|
|
439
460
|
role: "user",
|
|
@@ -447,7 +468,7 @@ export class AgentSession {
|
|
|
447
468
|
this._pendingNextTurnMessages = [];
|
|
448
469
|
// Emit before_agent_start extension event
|
|
449
470
|
if (this._extensionRunner) {
|
|
450
|
-
const result = await this._extensionRunner.emitBeforeAgentStart(expandedText,
|
|
471
|
+
const result = await this._extensionRunner.emitBeforeAgentStart(expandedText, currentImages, this._baseSystemPrompt);
|
|
451
472
|
// Add all custom messages from extensions
|
|
452
473
|
if (result?.messages) {
|
|
453
474
|
for (const msg of result.messages) {
|
|
@@ -502,10 +523,41 @@ export class AgentSession {
|
|
|
502
523
|
return true;
|
|
503
524
|
}
|
|
504
525
|
}
|
|
526
|
+
/**
|
|
527
|
+
* Expand skill commands (/skill:name args) to their full content.
|
|
528
|
+
* Returns the expanded text, or the original text if not a skill command or skill not found.
|
|
529
|
+
* Emits errors via extension runner if file read fails.
|
|
530
|
+
*/
|
|
531
|
+
_expandSkillCommand(text) {
|
|
532
|
+
if (!text.startsWith("/skill:"))
|
|
533
|
+
return text;
|
|
534
|
+
const spaceIndex = text.indexOf(" ");
|
|
535
|
+
const skillName = spaceIndex === -1 ? text.slice(7) : text.slice(7, spaceIndex);
|
|
536
|
+
const args = spaceIndex === -1 ? "" : text.slice(spaceIndex + 1).trim();
|
|
537
|
+
const skill = this._skills.find((s) => s.name === skillName);
|
|
538
|
+
if (!skill)
|
|
539
|
+
return text; // Unknown skill, pass through
|
|
540
|
+
try {
|
|
541
|
+
const content = readFileSync(skill.filePath, "utf-8");
|
|
542
|
+
const body = stripFrontmatter(content).trim();
|
|
543
|
+
const header = `Skill location: ${skill.filePath}\nReferences are relative to ${skill.baseDir}.`;
|
|
544
|
+
const skillMessage = `${header}\n\n${body}`;
|
|
545
|
+
return args ? `${skillMessage}\n\n---\n\nUser: ${args}` : skillMessage;
|
|
546
|
+
}
|
|
547
|
+
catch (err) {
|
|
548
|
+
// Emit error like extension commands do
|
|
549
|
+
this._extensionRunner?.emitError({
|
|
550
|
+
extensionPath: skill.filePath,
|
|
551
|
+
event: "skill_expansion",
|
|
552
|
+
error: err instanceof Error ? err.message : String(err),
|
|
553
|
+
});
|
|
554
|
+
return text; // Return original on error
|
|
555
|
+
}
|
|
556
|
+
}
|
|
505
557
|
/**
|
|
506
558
|
* Queue a steering message to interrupt the agent mid-run.
|
|
507
559
|
* Delivered after current tool execution, skips remaining tools.
|
|
508
|
-
* Expands
|
|
560
|
+
* Expands skill commands and prompt templates. Errors on extension commands.
|
|
509
561
|
* @throws Error if text is an extension command
|
|
510
562
|
*/
|
|
511
563
|
async steer(text) {
|
|
@@ -513,14 +565,15 @@ export class AgentSession {
|
|
|
513
565
|
if (text.startsWith("/")) {
|
|
514
566
|
this._throwIfExtensionCommand(text);
|
|
515
567
|
}
|
|
516
|
-
// Expand
|
|
517
|
-
|
|
568
|
+
// Expand skill commands and prompt templates
|
|
569
|
+
let expandedText = this._expandSkillCommand(text);
|
|
570
|
+
expandedText = expandPromptTemplate(expandedText, [...this._promptTemplates]);
|
|
518
571
|
await this._queueSteer(expandedText);
|
|
519
572
|
}
|
|
520
573
|
/**
|
|
521
574
|
* Queue a follow-up message to be processed after the agent finishes.
|
|
522
575
|
* Delivered only when agent has no more tool calls or steering messages.
|
|
523
|
-
* Expands
|
|
576
|
+
* Expands skill commands and prompt templates. Errors on extension commands.
|
|
524
577
|
* @throws Error if text is an extension command
|
|
525
578
|
*/
|
|
526
579
|
async followUp(text) {
|
|
@@ -528,8 +581,9 @@ export class AgentSession {
|
|
|
528
581
|
if (text.startsWith("/")) {
|
|
529
582
|
this._throwIfExtensionCommand(text);
|
|
530
583
|
}
|
|
531
|
-
// Expand
|
|
532
|
-
|
|
584
|
+
// Expand skill commands and prompt templates
|
|
585
|
+
let expandedText = this._expandSkillCommand(text);
|
|
586
|
+
expandedText = expandPromptTemplate(expandedText, [...this._promptTemplates]);
|
|
533
587
|
await this._queueFollowUp(expandedText);
|
|
534
588
|
}
|
|
535
589
|
/**
|
|
@@ -641,6 +695,7 @@ export class AgentSession {
|
|
|
641
695
|
expandPromptTemplates: false,
|
|
642
696
|
streamingBehavior: options?.deliverAs,
|
|
643
697
|
images,
|
|
698
|
+
source: "extension",
|
|
644
699
|
});
|
|
645
700
|
}
|
|
646
701
|
/**
|
|
@@ -1203,8 +1258,8 @@ export class AgentSession {
|
|
|
1203
1258
|
if (isContextOverflow(message, contextWindow))
|
|
1204
1259
|
return false;
|
|
1205
1260
|
const err = message.errorMessage;
|
|
1206
|
-
// Match: overloaded_error, rate limit, 429, 500, 502, 503, 504, service unavailable, connection
|
|
1207
|
-
return /overloaded|rate.?limit|too many requests|429|500|502|503|504|service.?unavailable|server error|internal error|connection.?error|other side closed|fetch failed/i.test(err);
|
|
1261
|
+
// Match: overloaded_error, rate limit, 429, 500, 502, 503, 504, service unavailable, connection errors, fetch failed
|
|
1262
|
+
return /overloaded|rate.?limit|too many requests|429|500|502|503|504|service.?unavailable|server error|internal error|connection.?error|connection.?refused|other side closed|fetch failed|upstream.?connect|reset before headers/i.test(err);
|
|
1208
1263
|
}
|
|
1209
1264
|
/**
|
|
1210
1265
|
* Handle retryable errors with exponential backoff.
|
|
@@ -1743,7 +1798,19 @@ export class AgentSession {
|
|
|
1743
1798
|
*/
|
|
1744
1799
|
async exportToHtml(outputPath) {
|
|
1745
1800
|
const themeName = this.settingsManager.getTheme();
|
|
1746
|
-
|
|
1801
|
+
// Create tool renderer if we have an extension runner (for custom tool HTML rendering)
|
|
1802
|
+
let toolRenderer;
|
|
1803
|
+
if (this._extensionRunner) {
|
|
1804
|
+
toolRenderer = createToolHtmlRenderer({
|
|
1805
|
+
getToolDefinition: (name) => this._extensionRunner.getToolDefinition(name),
|
|
1806
|
+
theme,
|
|
1807
|
+
});
|
|
1808
|
+
}
|
|
1809
|
+
return await exportSessionToHtml(this.sessionManager, this.state, {
|
|
1810
|
+
outputPath,
|
|
1811
|
+
themeName,
|
|
1812
|
+
toolRenderer,
|
|
1813
|
+
});
|
|
1747
1814
|
}
|
|
1748
1815
|
// =========================================================================
|
|
1749
1816
|
// Utilities
|