@pi-unipi/utility 0.2.4 → 0.2.6
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 +1 -1
- package/src/index.ts +57 -8
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -38,6 +38,12 @@ const VERSION = getPackageVersion(new URL(".", import.meta.url).pathname);
|
|
|
38
38
|
/** Whether we've seen the first user message (for auto badge generation) */
|
|
39
39
|
let firstMessageSeen = false;
|
|
40
40
|
|
|
41
|
+
/** Stored user text from first input, used to build conversation summary after agent responds */
|
|
42
|
+
let firstUserText = "";
|
|
43
|
+
|
|
44
|
+
/** Stored UI context from first input, used to show badge overlay after agent responds */
|
|
45
|
+
let firstInputCtx: any = null;
|
|
46
|
+
|
|
41
47
|
/** All commands registered by this module */
|
|
42
48
|
const ALL_COMMANDS = [
|
|
43
49
|
UTILITY_COMMANDS.CONTINUE,
|
|
@@ -106,7 +112,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
106
112
|
}
|
|
107
113
|
});
|
|
108
114
|
|
|
109
|
-
// First-message hook:
|
|
115
|
+
// First-message hook: capture user text for deferred badge generation
|
|
110
116
|
pi.on("input", async (_event: any, ctx: any) => {
|
|
111
117
|
// Only trigger on first user message
|
|
112
118
|
if (firstMessageSeen) return;
|
|
@@ -120,8 +126,8 @@ export default function (pi: ExtensionAPI) {
|
|
|
120
126
|
const sessionName = pi.getSessionName?.();
|
|
121
127
|
if (sessionName) return;
|
|
122
128
|
|
|
123
|
-
//
|
|
124
|
-
|
|
129
|
+
// Store first message text for later use in agent_end
|
|
130
|
+
firstUserText = typeof _event?.content === "string"
|
|
125
131
|
? _event.content
|
|
126
132
|
: Array.isArray(_event?.content)
|
|
127
133
|
? _event.content
|
|
@@ -130,16 +136,57 @@ export default function (pi: ExtensionAPI) {
|
|
|
130
136
|
.join(" ")
|
|
131
137
|
: "";
|
|
132
138
|
|
|
133
|
-
//
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
139
|
+
// Store ctx for badge overlay show after agent responds
|
|
140
|
+
firstInputCtx = ctx;
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
// After agent completes first response, generate badge name with full conversation context
|
|
144
|
+
pi.on("agent_end", async (event: any, _ctx: any) => {
|
|
145
|
+
// Only act if we captured a first input and are waiting for badge generation
|
|
146
|
+
if (!firstInputCtx) return;
|
|
147
|
+
const ctx = firstInputCtx;
|
|
148
|
+
firstInputCtx = null; // consume — only trigger once
|
|
149
|
+
|
|
150
|
+
// Check if a name was already set (e.g. manually) in the meantime
|
|
151
|
+
const sessionName = pi.getSessionName?.();
|
|
152
|
+
if (sessionName) return;
|
|
138
153
|
|
|
139
154
|
// Show badge overlay if UI available
|
|
140
155
|
if (ctx?.hasUI && !nameBadgeState.isVisible()) {
|
|
141
156
|
await nameBadgeState.show(pi, ctx);
|
|
142
157
|
}
|
|
158
|
+
|
|
159
|
+
// Build conversation summary from full message history (user + assistant)
|
|
160
|
+
const messages: any[] = event?.messages ?? [];
|
|
161
|
+
const summaryParts: string[] = [];
|
|
162
|
+
|
|
163
|
+
// Include the user's first message
|
|
164
|
+
if (firstUserText) {
|
|
165
|
+
summaryParts.push(`User: ${firstUserText}`);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Include assistant's response text
|
|
169
|
+
const assistantMsgs = messages.filter((m: any) => m.role === "assistant");
|
|
170
|
+
for (const msg of assistantMsgs) {
|
|
171
|
+
if (Array.isArray(msg.content)) {
|
|
172
|
+
const textParts = msg.content
|
|
173
|
+
.filter((c: any) => c.type === "text")
|
|
174
|
+
.map((c: any) => c.text)
|
|
175
|
+
.join(" ");
|
|
176
|
+
if (textParts) summaryParts.push(`Assistant: ${textParts}`);
|
|
177
|
+
} else if (typeof msg.content === "string" && msg.content) {
|
|
178
|
+
summaryParts.push(`Assistant: ${msg.content}`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Truncate to reasonable size
|
|
183
|
+
const conversationSummary = summaryParts.join("\n").slice(0, 800);
|
|
184
|
+
|
|
185
|
+
// Emit event for subagents to spawn background agent
|
|
186
|
+
emitEvent(pi, UNIPI_EVENTS.BADGE_GENERATE_REQUEST, {
|
|
187
|
+
source: "input-hook",
|
|
188
|
+
conversationSummary,
|
|
189
|
+
});
|
|
143
190
|
});
|
|
144
191
|
|
|
145
192
|
// Track command usage
|
|
@@ -153,6 +200,8 @@ export default function (pi: ExtensionAPI) {
|
|
|
153
200
|
pi.on("session_shutdown", async () => {
|
|
154
201
|
nameBadgeState.hide();
|
|
155
202
|
firstMessageSeen = false;
|
|
203
|
+
firstUserText = "";
|
|
204
|
+
firstInputCtx = null;
|
|
156
205
|
await lifecycle.shutdown("session_shutdown");
|
|
157
206
|
});
|
|
158
207
|
}
|