@shanepadgett/tau-agent 0.22.1 → 0.23.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.
@@ -71,54 +71,82 @@ function cap(text: string | undefined, limit: number): string {
71
71
  return `${normalized.slice(0, limit - 1)}…`;
72
72
  }
73
73
 
74
+ function tableCell(text: string, limit: number): string {
75
+ const compact = cap(text.replace(/\s+/g, " ").trim(), limit);
76
+ return compact.replaceAll("|", "&#124;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
77
+ }
78
+
79
+ function quote(text: string): string {
80
+ return cap(text, 1200)
81
+ .replaceAll("<", "&lt;")
82
+ .replaceAll(">", "&gt;")
83
+ .split("\n")
84
+ .map((line) => `> ${line}`)
85
+ .join("\n");
86
+ }
87
+
88
+ function elapsed(durationMs: number): string {
89
+ if (durationMs < 1000) return "<1s";
90
+ if (durationMs < 60_000) return `${(durationMs / 1000).toFixed(1)}s`;
91
+ const minutes = Math.floor(durationMs / 60_000);
92
+ const seconds = Math.floor((durationMs % 60_000) / 1000);
93
+ return `${minutes}m ${seconds}s`;
94
+ }
95
+
96
+ function dashboardState(status: SubagentInvocationSnapshot["status"]): string {
97
+ switch (status) {
98
+ case "waiting":
99
+ return "queued";
100
+ case "completed":
101
+ return "done";
102
+ case "aborted":
103
+ return "stopped";
104
+ default:
105
+ return status;
106
+ }
107
+ }
108
+
74
109
  export function formatDashboardMarkdown(snapshots: readonly SubagentInvocationSnapshot[]): string {
75
110
  const ordered = [...snapshots].sort(
76
111
  (a, b) => a.startedAt - b.startedAt || a.invocationId.localeCompare(b.invocationId),
77
112
  );
78
- const activeCount = ordered.filter(
79
- (snapshot) => snapshot.status !== "completed" && snapshot.status !== "failed" && snapshot.status !== "aborted",
113
+ const activeCount = ordered.filter((snapshot) =>
114
+ ["waiting", "starting", "running"].includes(snapshot.status),
80
115
  ).length;
81
- const lines = [
82
- "# Subagent dashboard",
83
- "",
84
- `Active: ${activeCount} · Completed: ${ordered.length - activeCount}`,
85
- "",
86
- ];
116
+ const doneCount = ordered.filter((snapshot) => snapshot.status === "completed").length;
117
+ const failedCount = ordered.filter((snapshot) => snapshot.status === "failed").length;
118
+ const stoppedCount = ordered.filter((snapshot) => snapshot.status === "aborted").length;
119
+ const counts = [`${activeCount} active`, `${doneCount} done`];
120
+ if (failedCount > 0) counts.push(`${failedCount} failed`);
121
+ if (stoppedCount > 0) counts.push(`${stoppedCount} stopped`);
122
+ const lines = ["# Subagents", "", counts.join(" · "), ""];
87
123
  if (ordered.length === 0) {
88
- lines.push("_No active invocations._", "");
124
+ lines.push("_No subagents._", "");
89
125
  return lines.join("\n");
90
126
  }
127
+ lines.push("| Agent | State | Request | Last tool | Calls | Time |", "| --- | --- | --- | --- | ---: | ---: |");
91
128
  for (const details of ordered) {
92
- const identity = `${details.displayName} (${details.agent})`;
129
+ const latest = details.actions.at(-1);
130
+ const currentTool = details.currentActivity?.match(/^\S+/)?.[0];
131
+ const lastTool = currentTool ?? latest?.tool ?? "";
93
132
  lines.push(
94
- `## ${identity}`,
95
- "",
96
- `\`${details.status}${details.phase ? ` · ${details.phase}` : ""}\` · inv ${details.invocationId} · tools ${details.toolCalls} · ${(details.durationMs / 1000).toFixed(1)}s`,
97
- `model ${details.model} · thinking ${details.thinkingLevel}`,
133
+ `| ${tableCell(`${details.displayName} (${details.agent})`, 48)} | ${dashboardState(details.status)} | ${tableCell(details.task, 90)} | ${tableCell(lastTool, 32) || "—"} | ${details.toolCalls} | ${elapsed(details.durationMs)} |`,
134
+ );
135
+ }
136
+ lines.push("", "## Inputs", "");
137
+ for (const details of ordered) {
138
+ lines.push(
139
+ `### ${tableCell(details.displayName, 80)}`,
98
140
  "",
99
- "### Task",
141
+ `${tableCell(details.agent, 80)} · ${tableCell(details.invocationId, 80)}`,
100
142
  "",
101
- cap(details.task, 1200) || "_(empty)_",
143
+ quote(details.task) || "> _(empty)_",
102
144
  );
103
- if (details.currentActivity) {
104
- lines.push("", "### Current", "", cap(details.currentActivity, 400));
105
- }
106
- if (details.actions.length > 0) {
107
- lines.push("", "### Actions", "");
108
- for (const action of details.actions.slice(-12)) {
109
- const mark = action.error ? "!" : "·";
110
- lines.push(`- ${mark} ${cap(action.summary, 200)}`);
111
- }
112
- if (details.omittedActions > 0) {
113
- lines.push(`- _${details.omittedActions} earlier actions omitted_`);
114
- }
115
- }
116
- if (details.response) {
117
- lines.push("", "### Response", "", cap(details.response, 3000));
118
- }
119
- if (details.error) {
120
- lines.push("", "### Error", "", cap(details.error, 800));
145
+ if (details.files.length > 0) {
146
+ lines.push("", "**Files**", "");
147
+ for (const file of details.files) lines.push(`- ${tableCell(file, 300)}`);
121
148
  }
149
+ if (details.error) lines.push("", "**Error**", "", quote(details.error));
122
150
  lines.push("");
123
151
  }
124
152
  return lines.join("\n");
@@ -77,6 +77,7 @@ export interface SubagentDetails {
77
77
  export interface SubagentInvocationSnapshot extends SubagentDetails {
78
78
  invocationId: string;
79
79
  startedAt: number;
80
+ files: readonly string[];
80
81
  }
81
82
 
82
83
  export interface SubagentThread {
@@ -243,6 +243,7 @@ export class SubagentRuntime {
243
243
  }),
244
244
  invocationId,
245
245
  startedAt,
246
+ files: [...(options.files ?? [])],
246
247
  };
247
248
  const active: ActiveInvocation = {
248
249
  snapshot: initialSnapshot,
@@ -330,6 +331,7 @@ export class SubagentRuntime {
330
331
  ...details,
331
332
  invocationId,
332
333
  startedAt,
334
+ files: current.snapshot.files,
333
335
  threadId: details.threadId ?? threadId,
334
336
  agent: details.agent || agent,
335
337
  displayName: details.displayName || displayName,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shanepadgett/tau-agent",
3
- "version": "0.22.1",
3
+ "version": "0.23.0",
4
4
  "description": "Tau is a custom agentic harness built with pi extensions",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -34,7 +34,7 @@
34
34
  "README.md"
35
35
  ],
36
36
  "dependencies": {
37
- "@shanepadgett/tau-tui": "0.22.1",
37
+ "@shanepadgett/tau-tui": "0.23.0",
38
38
  "@toon-format/toon": "2.3.0",
39
39
  "image-size": "2.0.2",
40
40
  "smol-toml": "1.7.0"