@pi-kaush/pi-tool-call-markers 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +4 -4
- package/package.json +1 -1
- package/src/index.ts +44 -29
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
- Restyle subagent rows: the subagent marker is now `↪` (was `&`), and single
|
|
6
|
+
calls drop the `subagent` tool label — `↪ 🤖 [coder][c3po] Implement the…` —
|
|
7
|
+
with chain/parallel step lines reordered to emoji, profile badge, name badge
|
|
8
|
+
(`1. 🐝 [workhorse][bee] …`). Single-call headings are now scraped too, so
|
|
9
|
+
agent emojis appear on single rows, not just chain/parallel steps.
|
|
10
|
+
|
|
5
11
|
- Color collapsed rows (tool calls, `+ Thought`, subagents) from the
|
|
6
12
|
theme's `syntaxComment` token — which ships with every theme — instead of
|
|
7
13
|
the louder muted/toolTitle/toolOutput split. The bolded tool name and the
|
package/README.md
CHANGED
|
@@ -34,19 +34,19 @@ Collapsed tool rows use semantic theme colors with no gear, background fill, box
|
|
|
34
34
|
|
|
35
35
|
## Subagent plans
|
|
36
36
|
|
|
37
|
-
A recognized `subagent` call renders as an unboxed plan in the shared tool aesthetic, marked with
|
|
37
|
+
A recognized `subagent` call renders as an unboxed plan in the shared tool aesthetic, marked with `↪` instead of the ordinary `%` tool marker:
|
|
38
38
|
|
|
39
39
|
```text
|
|
40
|
-
|
|
40
|
+
↪ subagent chain (3 steps) [repo-review]
|
|
41
41
|
1. 🐝 bee [workhorse] Challenge the compatibility conclusion…
|
|
42
42
|
2. 🐝 bee …
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
Single calls stay on one
|
|
45
|
+
Single calls stay on one `↪ [<emoji>] [<profile>][<agent>] <task preview>` row — no tool label; the `↪` marker identifies it. Chain calls get a heading with the kind, count, and scope followed by numbered steps (parallel tasks list without numbers), with each step ordered emoji, profile badge, name badge. Agent display names (emoji + name) are scraped from the native plan component — including the single-call heading — with an args fallback, and render in `accent`; everything else stays muted, and failed subagents go full red. Subagents never join ordinary tool groups.
|
|
46
46
|
|
|
47
47
|
While a subagent runs, the plan headline's tail shows live progress from the streamed result details — `→ 1 turn · provider/model` in the warning tone — and a settled call keeps the same `→ N turns · provider/model` summary in muted (turns aggregate across tasks; the model shows only when every task used the same one).
|
|
48
48
|
|
|
49
|
-
Malformed, ambiguous, future, or too-narrow shapes fall back to the generic
|
|
49
|
+
Malformed, ambiguous, future, or too-narrow shapes fall back to the generic `↪ subagent …` collapsed row rather than dropping information, and `Ctrl+O` still exposes the native subagent renderer.
|
|
50
50
|
|
|
51
51
|
## Edit diffs
|
|
52
52
|
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -20,7 +20,7 @@ import { fgCollapsed } from "./muted.ts";
|
|
|
20
20
|
|
|
21
21
|
const OUTER_INSET = 2;
|
|
22
22
|
const GROUP_MARKER = "%";
|
|
23
|
-
const SUBAGENT_MARKER = "
|
|
23
|
+
const SUBAGENT_MARKER = "↪";
|
|
24
24
|
const PRESENTATION_PATCHED = Symbol.for("kg.pi.toolPresentation.v3");
|
|
25
25
|
const LEGACY_PRESENTATION_PATCHED = Symbol.for("kg.pi.toolPresentation.v2");
|
|
26
26
|
const GROUPING_PATCHED = Symbol.for("kg.pi.toolGrouping.v1");
|
|
@@ -1028,6 +1028,19 @@ function parseStepContent(content: string): {
|
|
|
1028
1028
|
};
|
|
1029
1029
|
}
|
|
1030
1030
|
|
|
1031
|
+
// Splits a scraped "emoji name" display into its emoji prefix and bare name;
|
|
1032
|
+
// plain names pass through with no emoji.
|
|
1033
|
+
function splitEmojiName(
|
|
1034
|
+
displayName: string,
|
|
1035
|
+
bareName: string,
|
|
1036
|
+
): { emoji: string; name: string } {
|
|
1037
|
+
const tokens = displayName.trim().split(/\s+/).filter(Boolean);
|
|
1038
|
+
if (tokens.length > 1 && tokens[tokens.length - 1] === bareName) {
|
|
1039
|
+
return { emoji: tokens.slice(0, -1).join(" "), name: bareName };
|
|
1040
|
+
}
|
|
1041
|
+
return { emoji: "", name: bareName };
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1031
1044
|
// Agent display names (emoji + name) come from the subagent extension's own
|
|
1032
1045
|
// call component when available; args only carry the bare agent name.
|
|
1033
1046
|
function scrapeSubagentDisplayNames(
|
|
@@ -1042,10 +1055,16 @@ function scrapeSubagentDisplayNames(
|
|
|
1042
1055
|
try {
|
|
1043
1056
|
for (const raw of component.render(120)) {
|
|
1044
1057
|
const line = sanitizeInline(stripAnsi(raw)).trim();
|
|
1045
|
-
if (!line
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1058
|
+
if (!line) continue;
|
|
1059
|
+
// Single calls carry the agent name on their "subagent <name>" heading
|
|
1060
|
+
// line; stripping the heading word (and step numbers) lets both shapes
|
|
1061
|
+
// flow through the same parse. Heading remainders without an emoji
|
|
1062
|
+
// (e.g. "chain (2 steps)") degrade to displayName === bareName and are
|
|
1063
|
+
// skipped by the guard below.
|
|
1064
|
+
const content = line
|
|
1065
|
+
.replace(/^subagent\b\s*/, "")
|
|
1066
|
+
.replace(/^\d+\.\s*/, "");
|
|
1067
|
+
const { displayName, bareName } = parseStepContent(content);
|
|
1049
1068
|
if (displayName && bareName && displayName !== bareName) {
|
|
1050
1069
|
names.set(bareName, displayName);
|
|
1051
1070
|
}
|
|
@@ -1091,10 +1110,11 @@ function subagentProgressText(row: ToolExecutionRow): string | undefined {
|
|
|
1091
1110
|
return parts.length > 0 ? parts.join(" · ") : undefined;
|
|
1092
1111
|
}
|
|
1093
1112
|
|
|
1094
|
-
// Subagents render as an ordinary unboxed tool block: a
|
|
1113
|
+
// Subagents render as an ordinary unboxed tool block: a `↪` heading with the
|
|
1095
1114
|
// plan kind/count/scope, then the numbered chain steps or parallel tasks with
|
|
1096
|
-
// agent
|
|
1097
|
-
//
|
|
1115
|
+
// agent identities (emoji, profile badge, name badge) in accent. Single calls
|
|
1116
|
+
// collapse to one row: `↪ <emoji> [<profile>][<name>] <task preview>`. Everything
|
|
1117
|
+
// else stays muted (or error on failure), matching the shared tool-row aesthetic.
|
|
1098
1118
|
function renderSubagentPlan(
|
|
1099
1119
|
row: ToolExecutionRow,
|
|
1100
1120
|
width: number,
|
|
@@ -1110,19 +1130,21 @@ function renderSubagentPlan(
|
|
|
1110
1130
|
const displayNames = scrapeSubagentDisplayNames(row);
|
|
1111
1131
|
// Agent/profile/task values are model-supplied; sanitize them like every
|
|
1112
1132
|
// other collapsed-row text so control bytes cannot reach the terminal.
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
);
|
|
1133
|
+
// Identity order: emoji, then the profile and agent-name badges.
|
|
1134
|
+
const identityOf = (step: SubagentStep) => {
|
|
1135
|
+
const displayName =
|
|
1136
|
+
displayNames.get(step.agent) ?? sanitizeInline(step.agent);
|
|
1137
|
+
const { emoji, name } = splitEmojiName(displayName, step.agent);
|
|
1138
|
+
const accentPart = (text: string) => fgCollapsed(theme, nameColor, text);
|
|
1139
|
+
const emojiPart = emoji ? `${accentPart(emoji)} ` : "";
|
|
1140
|
+
const profilePart = step.profile
|
|
1141
|
+
? accentPart(`[${sanitizeInline(step.profile)}]`)
|
|
1142
|
+
: "";
|
|
1143
|
+
return `${emojiPart}${profilePart}${accentPart(`[${sanitizeInline(name)}]`)}`;
|
|
1144
|
+
};
|
|
1119
1145
|
const detailColor = failed ? "error" : "toolOutput";
|
|
1120
|
-
const
|
|
1121
|
-
fgCollapsed(
|
|
1122
|
-
theme,
|
|
1123
|
-
detailColor,
|
|
1124
|
-
`${step.profile ? ` [${sanitizeInline(step.profile)}]` : ""} ${subagentStepPreview(step.task)}`,
|
|
1125
|
-
);
|
|
1146
|
+
const previewOf = (step: SubagentStep) =>
|
|
1147
|
+
fgCollapsed(theme, detailColor, ` ${subagentStepPreview(step.task)}`);
|
|
1126
1148
|
|
|
1127
1149
|
const marker = `${fgCollapsed(theme, color, SUBAGENT_MARKER, true)} `;
|
|
1128
1150
|
const budget = Math.max(1, width - visibleWidth(marker));
|
|
@@ -1146,14 +1168,7 @@ function renderSubagentPlan(
|
|
|
1146
1168
|
|
|
1147
1169
|
if (plan.kind === "single") {
|
|
1148
1170
|
const step = plan.steps[0]!;
|
|
1149
|
-
return [
|
|
1150
|
-
headline(
|
|
1151
|
-
fgCollapsed(theme, failed ? "error" : "toolTitle", "subagent", true) +
|
|
1152
|
-
" " +
|
|
1153
|
-
displayOf(step.agent) +
|
|
1154
|
-
detailOf(step),
|
|
1155
|
-
),
|
|
1156
|
-
];
|
|
1171
|
+
return [headline(identityOf(step) + previewOf(step))];
|
|
1157
1172
|
}
|
|
1158
1173
|
|
|
1159
1174
|
const kindLabel =
|
|
@@ -1175,7 +1190,7 @@ function renderSubagentPlan(
|
|
|
1175
1190
|
plan.kind === "chain"
|
|
1176
1191
|
? `${fgCollapsed(theme, color, `${index + 1}.`)} `
|
|
1177
1192
|
: "";
|
|
1178
|
-
lines.push(` ${number}${
|
|
1193
|
+
lines.push(` ${number}${identityOf(step)}${previewOf(step)}`);
|
|
1179
1194
|
}
|
|
1180
1195
|
if (plan.steps.length > shown.length) {
|
|
1181
1196
|
lines.push(
|