portable-agent-layer 0.83.0 → 0.84.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "portable-agent-layer",
3
- "version": "0.83.0",
3
+ "version": "0.84.0",
4
4
  "description": "PAL — Portable Agent Layer: persistent personal context for AI coding assistants",
5
5
  "type": "module",
6
6
  "bin": {
@@ -51,6 +51,7 @@ export interface TurnEvent extends MoodTurn {
51
51
  reaction: Reaction | null;
52
52
  mood?: string;
53
53
  hinted?: boolean;
54
+ runtime?: string;
54
55
  }
55
56
 
56
57
  interface SessionTrack {
@@ -15,7 +15,8 @@ const HELP = `
15
15
  PAL Interaction report
16
16
 
17
17
  Reads the measured turns in memory/signals/interaction/ (features only, no
18
- text) and prints turns, channels, reactions, the hints sent, and for each
18
+ text) and prints turns, channels, reactions, the hints sent, per agent the
19
+ turns, replies filed and hints sent, and for each
19
20
  label (short, long, fast, skimming, friction) how the replies written while
20
21
  it was active compare with the replies written while none was.
21
22
 
@@ -22,10 +22,17 @@ interface ReplyStats {
22
22
  correctedShare: number;
23
23
  }
24
24
 
25
+ interface AgentCounts {
26
+ turns: number;
27
+ replies: number;
28
+ hints: number;
29
+ }
30
+
25
31
  export interface InteractionSummary {
26
32
  turns: number;
27
33
  sessions: number;
28
34
  channels: Record<string, number>;
35
+ agents: Record<string, AgentCounts>;
29
36
  reactions: Record<string, number>;
30
37
  hints: Record<string, number>;
31
38
  unlogged: number;
@@ -70,6 +77,20 @@ function repliesUnderMood(events: TurnEvent[]): ReplyUnderMood[] {
70
77
  return replies;
71
78
  }
72
79
 
80
+ /** A turn carries the reply that answered the turn before it, so a filed reply shows up there. */
81
+ function byAgent(events: TurnEvent[]): Record<string, AgentCounts> {
82
+ const agents: Record<string, AgentCounts> = {};
83
+ for (const e of events) {
84
+ const agent = e.runtime ?? "unknown";
85
+ const counts = agents[agent] ?? { turns: 0, replies: 0, hints: 0 };
86
+ agents[agent] = counts;
87
+ counts.turns++;
88
+ if (e.reply) counts.replies++;
89
+ if (e.hinted) counts.hints++;
90
+ }
91
+ return agents;
92
+ }
93
+
73
94
  export function summarize(events: TurnEvent[]): InteractionSummary {
74
95
  const replies = repliesUnderMood(events);
75
96
  const hinted = events.filter((e) => e.hinted);
@@ -77,6 +98,7 @@ export function summarize(events: TurnEvent[]): InteractionSummary {
77
98
  turns: events.length,
78
99
  sessions: new Set(events.map((e) => e.session)).size,
79
100
  channels: tally(events.map((e) => e.channel ?? "unknown")),
101
+ agents: byAgent(events),
80
102
  reactions: tally(events.flatMap((e) => (e.reaction ? [e.reaction] : []))),
81
103
  hints: tally(hinted.map((e) => e.mood || "back to usual")),
82
104
  unlogged: events.filter((e) => e.mood === undefined).length,
@@ -119,8 +141,20 @@ function labelLine(label: string, s: ReplyStats, usual: ReplyStats): string {
119
141
  ].join(" · ");
120
142
  }
121
143
 
122
- function plural(n: number, noun: string): string {
123
- return `${n} ${noun}${n === 1 ? "" : "s"}`;
144
+ function plural(n: number, noun: string, nouns = `${noun}s`): string {
145
+ return `${n} ${n === 1 ? noun : nouns}`;
146
+ }
147
+
148
+ function agentLines(agents: Record<string, AgentCounts>): string[] {
149
+ return Object.entries(agents)
150
+ .sort(([, a], [, b]) => b.turns - a.turns)
151
+ .map(([agent, c]) =>
152
+ [
153
+ ` ${agent.padEnd(9)} ${plural(c.turns, "turn")}`,
154
+ `${plural(c.replies, "reply", "replies")} filed`,
155
+ `${plural(c.hints, "hint")} sent`,
156
+ ].join(" · ")
157
+ );
124
158
  }
125
159
 
126
160
  export function reportLines(summary: InteractionSummary, days: number): string[] {
@@ -132,6 +166,9 @@ export function reportLines(summary: InteractionSummary, days: number): string[]
132
166
  `Reactions: ${shares(summary.reactions)}`,
133
167
  `Hints sent: ${counts(summary.hints)}`,
134
168
  "",
169
+ "By agent:",
170
+ ...agentLines(summary.agents),
171
+ "",
135
172
  "Replies written while a label was active, against replies while none was:",
136
173
  ...LABELS.map((label) => labelLine(label, summary.byLabel[label], summary.usual)),
137
174
  ];