@fradser/pi-agent-teams 0.10.0 → 1.0.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.
@@ -1,92 +0,0 @@
1
- export const TEAMMATE_REPORT_MESSAGE_TYPE = "agent-teams-report";
2
- export const TEAMMATE_HARNESS_MESSAGE_TYPE = "agent-teams-harness";
3
-
4
- export interface LeaderReport {
5
- teammate?: string;
6
- agent?: string;
7
- spawnId?: string;
8
- assignmentId?: string;
9
- workId?: string;
10
- body: string;
11
- /** Worker-authored reports are the default; harness events use a separate envelope. */
12
- origin?: "teammate" | "harness";
13
- harnessEvent?: {
14
- type: string;
15
- subject: string;
16
- };
17
- finished?: boolean;
18
- /** Original append-only outbox event identifier, retained for session forensics. */
19
- eventId?: string;
20
- /** Original worker status, including omitted status, retained for session forensics. */
21
- status?: "in_progress" | "completed" | "failed" | "inform" | "request" | "handoff";
22
- runId?: string;
23
- /** Wall-clock time the message was authored, not when Pi consumed it. */
24
- timestamp?: number;
25
- deliveredAt?: number;
26
- processStoppedAt?: number;
27
- deliveredAfterStop?: boolean;
28
- }
29
-
30
- export interface LeaderReportGroup {
31
- teammate: string;
32
- reports: LeaderReport[];
33
- }
34
-
35
- export function groupReportsByTeammate(reports: LeaderReport[]): LeaderReportGroup[] {
36
- const groups = new Map<string, LeaderReportGroup>();
37
- for (const report of reports) {
38
- const teammate = report.teammate ?? report.agent ?? "teammate";
39
- if (report.origin === "harness" || report.harnessEvent) {
40
- groups.set(`harness:${groups.size}:${teammate}`, { teammate, reports: [report] });
41
- continue;
42
- }
43
- const key = `message:${teammate}`;
44
- const group = groups.get(key);
45
- if (group) {
46
- group.reports.push(report);
47
- } else {
48
- groups.set(key, { teammate, reports: [report] });
49
- }
50
- }
51
- return [...groups.values()];
52
- }
53
-
54
- export function annotateReportDelivery(report: LeaderReport, deliveredAt: number, processStoppedAt?: number): LeaderReport {
55
- if (processStoppedAt === undefined || deliveredAt < processStoppedAt) return { ...report, deliveredAt };
56
- return { ...report, deliveredAt, processStoppedAt, deliveredAfterStop: true };
57
- }
58
-
59
- function timestampAttribute(name: string, timestamp: number | undefined): string {
60
- return timestamp !== undefined && Number.isFinite(timestamp)
61
- ? ` ${name}="${new Date(timestamp).toISOString()}"`
62
- : "";
63
- }
64
-
65
- export function formatReports(reports: LeaderReport[]): string {
66
- return reports
67
- .map((report) => {
68
- const { teammate, body, timestamp, origin, harnessEvent } = report;
69
- const at = timestampAttribute("at", timestamp);
70
- if (origin === "harness" || harnessEvent) {
71
- const type = escapeAttribute(harnessEvent?.type ?? "event");
72
- const subject = escapeAttribute(harnessEvent?.subject ?? "Agent Teams event");
73
- return `<harness-event type="${type}" subject="${subject}"${at}>\n${body}\n</harness-event>`;
74
- }
75
- const name = teammate ?? "teammate";
76
- const delivery = timestampAttribute("delivered-at", report.deliveredAt);
77
- const stopped = timestampAttribute("process-stopped-at", report.processStoppedAt);
78
- const late = report.deliveredAfterStop ? ' delivery="after-stop"' : "";
79
- const work = report.workId ? ` work="${escapeAttribute(report.workId)}"` : "";
80
- const assignment = report.assignmentId ? ` assignment="${escapeAttribute(report.assignmentId)}"` : "";
81
- const status = report.status ? ` status="${escapeAttribute(report.status)}"` : "";
82
- const note = report.deliveredAfterStop
83
- ? "Delivery note: this report was queued before shutdown and delivered after the process stopped. It does not reopen the assignment.\n\n"
84
- : "";
85
- return `<agent-message from="${escapeAttribute(name)}"${at}${delivery}${stopped}${late}${work}${assignment}${status}>\n${note}${body}\n</agent-message>`;
86
- })
87
- .join("\n\n");
88
- }
89
-
90
- function escapeAttribute(value: string): string {
91
- return value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
92
- }