@townco/agent 0.1.113 → 0.1.114
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/dist/acp-server/adapter.js +63 -56
- package/dist/runner/langchain/index.js +1 -38
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -7
- package/dist/runner/langchain/tools/artifacts.d.ts +0 -68
- package/dist/runner/langchain/tools/artifacts.js +0 -474
- package/dist/runner/langchain/tools/conversation_search.d.ts +0 -22
- package/dist/runner/langchain/tools/conversation_search.js +0 -137
- package/dist/runner/langchain/tools/generate_image.d.ts +0 -47
- package/dist/runner/langchain/tools/generate_image.js +0 -175
- package/dist/runner/langchain/tools/port-utils.d.ts +0 -8
- package/dist/runner/langchain/tools/port-utils.js +0 -35
|
@@ -273,14 +273,12 @@ export class AgentAcpAdapter {
|
|
|
273
273
|
"url" in result &&
|
|
274
274
|
typeof result.url === "string") {
|
|
275
275
|
// Use the citationId from the tool output if available
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
citationId = String(session.sourceCounter);
|
|
283
|
-
}
|
|
276
|
+
const citationId = typeof result.citationId === "number"
|
|
277
|
+
? String(result.citationId)
|
|
278
|
+
: (() => {
|
|
279
|
+
session.sourceCounter++;
|
|
280
|
+
return String(session.sourceCounter);
|
|
281
|
+
})();
|
|
284
282
|
const url = result.url;
|
|
285
283
|
const title = typeof result.title === "string" ? result.title : "Untitled";
|
|
286
284
|
const snippet = typeof result.text === "string"
|
|
@@ -420,14 +418,11 @@ export class AgentAcpAdapter {
|
|
|
420
418
|
if (!docUrl && !docTitle)
|
|
421
419
|
return null;
|
|
422
420
|
// Use document_id as the citation ID if available, otherwise use counter
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
session.sourceCounter++;
|
|
429
|
-
citationId = String(session.sourceCounter);
|
|
430
|
-
}
|
|
421
|
+
const citationId = docId ||
|
|
422
|
+
(() => {
|
|
423
|
+
session.sourceCounter++;
|
|
424
|
+
return String(session.sourceCounter);
|
|
425
|
+
})();
|
|
431
426
|
// Extract snippet from summary or content
|
|
432
427
|
let snippet;
|
|
433
428
|
if (typeof doc.summary === "string") {
|
|
@@ -1075,7 +1070,7 @@ export class AgentAcpAdapter {
|
|
|
1075
1070
|
}
|
|
1076
1071
|
logger.info("User message received", {
|
|
1077
1072
|
sessionId: params.sessionId,
|
|
1078
|
-
|
|
1073
|
+
message: userMessageText,
|
|
1079
1074
|
noSession: this.noSession,
|
|
1080
1075
|
});
|
|
1081
1076
|
// Only store messages if session persistence is enabled
|
|
@@ -1134,12 +1129,40 @@ export class AgentAcpAdapter {
|
|
|
1134
1129
|
// Build ordered content blocks for the assistant response
|
|
1135
1130
|
const contentBlocks = [];
|
|
1136
1131
|
let pendingText = "";
|
|
1132
|
+
// Buffer for logging agent response in readable chunks
|
|
1133
|
+
let logBuffer = "";
|
|
1134
|
+
const flushLogBuffer = (force = false) => {
|
|
1135
|
+
if (logBuffer.length === 0)
|
|
1136
|
+
return;
|
|
1137
|
+
if (force) {
|
|
1138
|
+
// Flush everything
|
|
1139
|
+
logger.info("Agent response", {
|
|
1140
|
+
sessionId: params.sessionId,
|
|
1141
|
+
text: logBuffer,
|
|
1142
|
+
});
|
|
1143
|
+
logBuffer = "";
|
|
1144
|
+
}
|
|
1145
|
+
else {
|
|
1146
|
+
// Only flush complete lines (up to and including the last newline)
|
|
1147
|
+
const lastNewline = logBuffer.lastIndexOf("\n");
|
|
1148
|
+
if (lastNewline !== -1) {
|
|
1149
|
+
const completeLines = logBuffer.slice(0, lastNewline + 1);
|
|
1150
|
+
logBuffer = logBuffer.slice(lastNewline + 1);
|
|
1151
|
+
logger.info("Agent response", {
|
|
1152
|
+
sessionId: params.sessionId,
|
|
1153
|
+
text: completeLines,
|
|
1154
|
+
});
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
};
|
|
1137
1158
|
// Helper function to flush pending text as a TextBlock
|
|
1138
1159
|
const flushPendingText = () => {
|
|
1139
1160
|
if (pendingText.length > 0) {
|
|
1140
1161
|
contentBlocks.push({ type: "text", text: pendingText });
|
|
1141
1162
|
pendingText = "";
|
|
1142
1163
|
}
|
|
1164
|
+
// Force flush any remaining log buffer when text block completes
|
|
1165
|
+
flushLogBuffer(true);
|
|
1143
1166
|
};
|
|
1144
1167
|
// Helper to save cancelled message to session
|
|
1145
1168
|
const saveCancelledMessage = async () => {
|
|
@@ -1332,6 +1355,11 @@ export class AgentAcpAdapter {
|
|
|
1332
1355
|
const content = msg.content;
|
|
1333
1356
|
if (content.type === "text" && typeof content.text === "string") {
|
|
1334
1357
|
pendingText += content.text;
|
|
1358
|
+
// Buffer for logging - flush on newlines
|
|
1359
|
+
logBuffer += content.text;
|
|
1360
|
+
if (logBuffer.includes("\n")) {
|
|
1361
|
+
flushLogBuffer();
|
|
1362
|
+
}
|
|
1335
1363
|
}
|
|
1336
1364
|
}
|
|
1337
1365
|
// Debug: log if this chunk has tokenUsage in _meta
|
|
@@ -1405,28 +1433,20 @@ export class AgentAcpAdapter {
|
|
|
1405
1433
|
if (toolCallMsg.rawInput) {
|
|
1406
1434
|
toolCall.rawInput = toolCallMsg.rawInput;
|
|
1407
1435
|
}
|
|
1436
|
+
// Log tool call start
|
|
1437
|
+
logger.info("Tool call started", {
|
|
1438
|
+
sessionId: params.sessionId,
|
|
1439
|
+
toolCallId: toolCall.id,
|
|
1440
|
+
tool: toolCall.title,
|
|
1441
|
+
prettyName: toolCall.prettyName,
|
|
1442
|
+
});
|
|
1408
1443
|
contentBlocks.push(toolCall);
|
|
1409
1444
|
}
|
|
1410
1445
|
// Handle tool_call_update - update existing ToolCallBlock
|
|
1411
1446
|
if ("sessionUpdate" in msg &&
|
|
1412
1447
|
msg.sessionUpdate === "tool_call_update") {
|
|
1413
1448
|
const updateMsg = msg;
|
|
1414
|
-
logger.info("[SUBAGENT] Adapter received tool_call_update", {
|
|
1415
|
-
sessionId: params.sessionId,
|
|
1416
|
-
toolCallId: updateMsg.toolCallId,
|
|
1417
|
-
status: updateMsg.status,
|
|
1418
|
-
hasMeta: !!updateMsg._meta,
|
|
1419
|
-
hasSubagentMessages: !!updateMsg._meta?.subagentMessages,
|
|
1420
|
-
subagentMessageCount: updateMsg._meta?.subagentMessages?.length ||
|
|
1421
|
-
0,
|
|
1422
|
-
});
|
|
1423
1449
|
const toolCallBlock = contentBlocks.find((block) => block.type === "tool_call" && block.id === updateMsg.toolCallId);
|
|
1424
|
-
logger.info("[SUBAGENT] Tool call block lookup result", {
|
|
1425
|
-
sessionId: params.sessionId,
|
|
1426
|
-
toolCallId: updateMsg.toolCallId,
|
|
1427
|
-
found: !!toolCallBlock,
|
|
1428
|
-
blockStatus: toolCallBlock?.status,
|
|
1429
|
-
});
|
|
1430
1450
|
if (toolCallBlock) {
|
|
1431
1451
|
if (updateMsg.status) {
|
|
1432
1452
|
toolCallBlock.status =
|
|
@@ -1446,6 +1466,17 @@ export class AgentAcpAdapter {
|
|
|
1446
1466
|
if (toolCallBlock.status === "completed" ||
|
|
1447
1467
|
toolCallBlock.status === "failed") {
|
|
1448
1468
|
toolCallBlock.completedAt = Date.now();
|
|
1469
|
+
// Log tool call completion
|
|
1470
|
+
logger.info("Tool call completed", {
|
|
1471
|
+
sessionId: params.sessionId,
|
|
1472
|
+
toolCallId: updateMsg.toolCallId,
|
|
1473
|
+
tool: toolCallBlock.title,
|
|
1474
|
+
status: toolCallBlock.status,
|
|
1475
|
+
durationMs: toolCallBlock.startedAt
|
|
1476
|
+
? toolCallBlock.completedAt - toolCallBlock.startedAt
|
|
1477
|
+
: undefined,
|
|
1478
|
+
error: toolCallBlock.error,
|
|
1479
|
+
});
|
|
1449
1480
|
}
|
|
1450
1481
|
const meta = updateMsg._meta;
|
|
1451
1482
|
// Update batchId from _meta (comes from tool_call_update after preliminary tool_call)
|
|
@@ -1459,31 +1490,11 @@ export class AgentAcpAdapter {
|
|
|
1459
1490
|
toolCallBlock.subagentSessionId = meta.subagentSessionId;
|
|
1460
1491
|
}
|
|
1461
1492
|
if (meta?.subagentMessages) {
|
|
1462
|
-
logger.info("[SUBAGENT] Storing subagent messages for session replay", {
|
|
1463
|
-
sessionId: params.sessionId,
|
|
1464
|
-
toolCallId: updateMsg.toolCallId,
|
|
1465
|
-
messageCount: meta.subagentMessages.length,
|
|
1466
|
-
contentPreview: meta.subagentMessages[0]?.content?.substring(0, 100),
|
|
1467
|
-
});
|
|
1468
1493
|
toolCallBlock.subagentMessages = meta.subagentMessages;
|
|
1469
|
-
logger.info("[SUBAGENT] Successfully stored messages", {
|
|
1470
|
-
sessionId: params.sessionId,
|
|
1471
|
-
toolCallId: updateMsg.toolCallId,
|
|
1472
|
-
storedCount: toolCallBlock.subagentMessages?.length,
|
|
1473
|
-
});
|
|
1474
1494
|
}
|
|
1475
1495
|
}
|
|
1476
1496
|
// Forward tool_call_update with _meta to the client (for subagent connection info, etc.)
|
|
1477
1497
|
if (updateMsg._meta) {
|
|
1478
|
-
logger.info("[SUBAGENT] Forwarding tool_call_update with _meta to client", {
|
|
1479
|
-
sessionId: params.sessionId,
|
|
1480
|
-
toolCallId: updateMsg.toolCallId,
|
|
1481
|
-
status: updateMsg.status,
|
|
1482
|
-
hasSubagentMessages: !!updateMsg._meta
|
|
1483
|
-
?.subagentMessages,
|
|
1484
|
-
subagentMessageCount: updateMsg._meta?.subagentMessages
|
|
1485
|
-
?.length || 0,
|
|
1486
|
-
});
|
|
1487
1498
|
this.connection.sessionUpdate({
|
|
1488
1499
|
sessionId: params.sessionId,
|
|
1489
1500
|
update: {
|
|
@@ -1493,10 +1504,6 @@ export class AgentAcpAdapter {
|
|
|
1493
1504
|
_meta: updateMsg._meta,
|
|
1494
1505
|
},
|
|
1495
1506
|
});
|
|
1496
|
-
logger.info("[SUBAGENT] Successfully forwarded to client", {
|
|
1497
|
-
sessionId: params.sessionId,
|
|
1498
|
-
toolCallId: updateMsg.toolCallId,
|
|
1499
|
-
});
|
|
1500
1507
|
}
|
|
1501
1508
|
}
|
|
1502
1509
|
// Handle tool_output - update ToolCallBlock with output content
|
|
@@ -181,21 +181,14 @@ export class LangchainAgent {
|
|
|
181
181
|
subagentInvCtx.subagentEventEmitter.on("messages", onSubagentMessages);
|
|
182
182
|
// Helper to check and yield all pending subagent message updates
|
|
183
183
|
async function* yieldPendingSubagentUpdates() {
|
|
184
|
-
_logger.info("[SUBAGENT] yieldPendingSubagentUpdates called", {
|
|
185
|
-
sessionId: req.sessionId,
|
|
186
|
-
queueLength: subagentMessagesQueue.length,
|
|
187
|
-
});
|
|
188
184
|
while (subagentMessagesQueue.length > 0) {
|
|
189
185
|
const messagesUpdate = subagentMessagesQueue.shift();
|
|
190
186
|
if (!messagesUpdate)
|
|
191
187
|
continue;
|
|
192
|
-
_logger.
|
|
188
|
+
_logger.debug("[SUBAGENT] Yielding queued subagent messages update", {
|
|
193
189
|
sessionId: req.sessionId,
|
|
194
190
|
toolCallId: messagesUpdate.toolCallId,
|
|
195
191
|
messageCount: messagesUpdate.messages.length,
|
|
196
|
-
contentPreview: messagesUpdate.messages[0]?.content?.substring(0, 100),
|
|
197
|
-
hasContentBlocks: (messagesUpdate.messages[0]?.contentBlocks?.length ?? 0) > 0,
|
|
198
|
-
toolCallCount: messagesUpdate.messages[0]?.toolCalls?.length ?? 0,
|
|
199
192
|
});
|
|
200
193
|
const updateToYield = {
|
|
201
194
|
sessionUpdate: "tool_call_update",
|
|
@@ -205,17 +198,7 @@ export class LangchainAgent {
|
|
|
205
198
|
subagentMessages: messagesUpdate.messages,
|
|
206
199
|
},
|
|
207
200
|
};
|
|
208
|
-
_logger.info("[SUBAGENT] About to yield update object", {
|
|
209
|
-
sessionId: req.sessionId,
|
|
210
|
-
toolCallId: messagesUpdate.toolCallId,
|
|
211
|
-
updateType: updateToYield.sessionUpdate,
|
|
212
|
-
hasMetaSubagentMessages: !!updateToYield._meta?.subagentMessages,
|
|
213
|
-
});
|
|
214
201
|
yield updateToYield;
|
|
215
|
-
_logger.info("[SUBAGENT] Successfully yielded update", {
|
|
216
|
-
sessionId: req.sessionId,
|
|
217
|
-
toolCallId: messagesUpdate.toolCallId,
|
|
218
|
-
});
|
|
219
202
|
}
|
|
220
203
|
}
|
|
221
204
|
// Add agent.session_id as a base attribute so it propagates to all child spans
|
|
@@ -1330,10 +1313,6 @@ export class LangchainAgent {
|
|
|
1330
1313
|
yield* yieldPendingSubagentUpdates();
|
|
1331
1314
|
// Keep polling for subagent messages after stream ends
|
|
1332
1315
|
// This ensures we capture messages that arrive after LangChain stream completes
|
|
1333
|
-
_logger.info("[SUBAGENT] Starting post-stream polling for subagent messages", {
|
|
1334
|
-
sessionId: req.sessionId,
|
|
1335
|
-
activeSubagentCount: activeSubagentToolCalls.size,
|
|
1336
|
-
});
|
|
1337
1316
|
const checkInterval = 100; // Check every 100ms
|
|
1338
1317
|
const maxIdleTime = 5000; // Stop if no messages for 5 seconds (fallback)
|
|
1339
1318
|
const maxWaitTime = 300000; // Absolute max 5 minutes
|
|
@@ -1343,28 +1322,15 @@ export class LangchainAgent {
|
|
|
1343
1322
|
// Check if all subagent tool calls have completed
|
|
1344
1323
|
if (activeSubagentToolCalls.size > 0 &&
|
|
1345
1324
|
completedSubagentToolCalls.size >= activeSubagentToolCalls.size) {
|
|
1346
|
-
_logger.info("[SUBAGENT] All subagent tool calls completed", {
|
|
1347
|
-
sessionId: req.sessionId,
|
|
1348
|
-
totalSubagents: activeSubagentToolCalls.size,
|
|
1349
|
-
completedCount: completedSubagentToolCalls.size,
|
|
1350
|
-
});
|
|
1351
1325
|
break;
|
|
1352
1326
|
}
|
|
1353
1327
|
// Check if there are pending messages
|
|
1354
1328
|
if (subagentMessagesQueue.length > 0) {
|
|
1355
|
-
_logger.info("[SUBAGENT] Found pending messages, yielding", {
|
|
1356
|
-
sessionId: req.sessionId,
|
|
1357
|
-
queueLength: subagentMessagesQueue.length,
|
|
1358
|
-
});
|
|
1359
1329
|
yield* yieldPendingSubagentUpdates();
|
|
1360
1330
|
lastMessageTime = Date.now();
|
|
1361
1331
|
}
|
|
1362
1332
|
// Stop if we haven't seen messages for maxIdleTime (fallback for no subagents)
|
|
1363
1333
|
if (Date.now() - lastMessageTime > maxIdleTime) {
|
|
1364
|
-
_logger.info("[SUBAGENT] No new messages for 5 seconds, finishing", {
|
|
1365
|
-
sessionId: req.sessionId,
|
|
1366
|
-
hasActiveSubagents: activeSubagentToolCalls.size > 0,
|
|
1367
|
-
});
|
|
1368
1334
|
break;
|
|
1369
1335
|
}
|
|
1370
1336
|
// Wait a bit before checking again
|
|
@@ -1377,9 +1343,6 @@ export class LangchainAgent {
|
|
|
1377
1343
|
}
|
|
1378
1344
|
// Final yield of any remaining messages
|
|
1379
1345
|
yield* yieldPendingSubagentUpdates();
|
|
1380
|
-
_logger.info("[SUBAGENT] Finished post-stream polling", {
|
|
1381
|
-
sessionId: req.sessionId,
|
|
1382
|
-
});
|
|
1383
1346
|
// Now that content streaming is complete, yield all buffered tool call notifications
|
|
1384
1347
|
yield* flushPendingToolCalls();
|
|
1385
1348
|
// Clean up subagent event listener from invocation-scoped emitter
|