@townco/agent 0.1.63 → 0.1.71
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.
|
@@ -569,7 +569,8 @@ export class AgentAcpAdapter {
|
|
|
569
569
|
const context_size = calculateContextSize(contextMessages, this.agent.definition.systemPrompt ?? undefined, undefined, // No LLM-reported tokens yet
|
|
570
570
|
this.currentToolOverheadTokens, // Include tool overhead
|
|
571
571
|
this.currentMcpOverheadTokens);
|
|
572
|
-
const contextSnapshot = createContextSnapshot(session.messages.length,
|
|
572
|
+
const contextSnapshot = createContextSnapshot(session.messages.length - 1, // Exclude the newly added user message (it will be passed separately via prompt)
|
|
573
|
+
new Date().toISOString(), previousContext, context_size);
|
|
573
574
|
session.context.push(contextSnapshot);
|
|
574
575
|
await this.saveSessionToDisk(params.sessionId, session);
|
|
575
576
|
}
|
|
@@ -608,6 +609,13 @@ export class AgentAcpAdapter {
|
|
|
608
609
|
sessionId: params.sessionId,
|
|
609
610
|
contextMessageCount: contextMessages.length,
|
|
610
611
|
totalSessionMessages: session.messages.length,
|
|
612
|
+
contextMessages: contextMessages.map((m) => ({
|
|
613
|
+
role: m.role,
|
|
614
|
+
content: JSON.stringify(m.content).slice(0, 100),
|
|
615
|
+
})),
|
|
616
|
+
promptContent: params.prompt
|
|
617
|
+
.map((p) => p.type === "text" ? p.text.slice(0, 100) : `[${p.type}]`)
|
|
618
|
+
.join(" "),
|
|
611
619
|
latestContextEntry: session.context.length > 0 &&
|
|
612
620
|
session.context[session.context.length - 1]
|
|
613
621
|
? {
|
package/dist/acp-server/http.js
CHANGED
|
@@ -553,6 +553,7 @@ export function makeHttpTransport(agent, agentDir, agentName) {
|
|
|
553
553
|
logger.info("Starting HTTP server", { port });
|
|
554
554
|
Bun.serve({
|
|
555
555
|
fetch: app.fetch,
|
|
556
|
+
hostname: Bun.env.BIND_HOST || "localhost",
|
|
556
557
|
port,
|
|
557
558
|
});
|
|
558
559
|
logger.info("HTTP server listening", {
|
|
@@ -82,6 +82,20 @@ export class LangchainAgent {
|
|
|
82
82
|
const countedMessageIds = new Set();
|
|
83
83
|
// Track tool calls for which we've emitted preliminary notifications (from early tool_use blocks)
|
|
84
84
|
const preliminaryToolCallIds = new Set();
|
|
85
|
+
// Buffer tool call notifications until content streaming completes
|
|
86
|
+
const pendingToolCallNotifications = [];
|
|
87
|
+
// Helper to flush all buffered tool calls (called when we detect text streaming is done)
|
|
88
|
+
function* flushPendingToolCalls() {
|
|
89
|
+
if (pendingToolCallNotifications.length === 0) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
// Yield all buffered notifications
|
|
93
|
+
for (const notification of pendingToolCallNotifications) {
|
|
94
|
+
yield notification;
|
|
95
|
+
}
|
|
96
|
+
// Clear the buffer after flushing
|
|
97
|
+
pendingToolCallNotifications.length = 0;
|
|
98
|
+
}
|
|
85
99
|
// Set session_id as a base attribute so all spans in this invocation include it
|
|
86
100
|
telemetry.setBaseAttributes({
|
|
87
101
|
"agent.session_id": req.sessionId,
|
|
@@ -629,8 +643,8 @@ export class LangchainAgent {
|
|
|
629
643
|
// Check if we already emitted a preliminary notification from early tool_use block
|
|
630
644
|
const alreadyEmittedPreliminary = preliminaryToolCallIds.has(toolCall.id);
|
|
631
645
|
if (alreadyEmittedPreliminary) {
|
|
632
|
-
//
|
|
633
|
-
|
|
646
|
+
// Buffer the update notification
|
|
647
|
+
pendingToolCallNotifications.push({
|
|
634
648
|
sessionUpdate: "tool_call_update",
|
|
635
649
|
toolCallId: toolCall.id,
|
|
636
650
|
title: toolCall.name,
|
|
@@ -642,11 +656,11 @@ export class LangchainAgent {
|
|
|
642
656
|
...(icon ? { icon } : {}),
|
|
643
657
|
...(batchId ? { batchId } : {}),
|
|
644
658
|
},
|
|
645
|
-
};
|
|
659
|
+
});
|
|
646
660
|
}
|
|
647
661
|
else {
|
|
648
|
-
//
|
|
649
|
-
|
|
662
|
+
// Buffer full tool_call notification
|
|
663
|
+
pendingToolCallNotifications.push({
|
|
650
664
|
sessionUpdate: "tool_call",
|
|
651
665
|
toolCallId: toolCall.id,
|
|
652
666
|
title: toolCall.name,
|
|
@@ -660,16 +674,21 @@ export class LangchainAgent {
|
|
|
660
674
|
...(icon ? { icon } : {}),
|
|
661
675
|
...(batchId ? { batchId } : {}),
|
|
662
676
|
},
|
|
663
|
-
};
|
|
677
|
+
});
|
|
664
678
|
}
|
|
665
|
-
//
|
|
666
|
-
|
|
679
|
+
// Buffer in_progress status update
|
|
680
|
+
pendingToolCallNotifications.push({
|
|
667
681
|
sessionUpdate: "tool_call_update",
|
|
668
682
|
toolCallId: toolCall.id,
|
|
669
683
|
status: "in_progress",
|
|
670
684
|
...(tokenUsage ? { tokenUsage } : {}),
|
|
671
685
|
_meta: { messageId: req.messageId },
|
|
672
|
-
};
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
// After processing all tool calls in this chunk, flush them
|
|
689
|
+
// (tool calls indicate text streaming is complete)
|
|
690
|
+
if (toolCalls.length > 0) {
|
|
691
|
+
yield* flushPendingToolCalls();
|
|
673
692
|
}
|
|
674
693
|
}
|
|
675
694
|
}
|
|
@@ -776,14 +795,14 @@ export class LangchainAgent {
|
|
|
776
795
|
yield msgToYield;
|
|
777
796
|
}
|
|
778
797
|
else if (part.type === "tool_use") {
|
|
779
|
-
//
|
|
798
|
+
// Buffer early notification for tool use
|
|
780
799
|
// The tool_use block contains { type, id, name, input }
|
|
781
800
|
const toolUseBlock = part;
|
|
782
801
|
if (toolUseBlock.id &&
|
|
783
802
|
toolUseBlock.name &&
|
|
784
803
|
!preliminaryToolCallIds.has(toolUseBlock.id)) {
|
|
785
804
|
preliminaryToolCallIds.add(toolUseBlock.id);
|
|
786
|
-
|
|
805
|
+
pendingToolCallNotifications.push({
|
|
787
806
|
sessionUpdate: "tool_call",
|
|
788
807
|
toolCallId: toolUseBlock.id,
|
|
789
808
|
title: toolUseBlock.name,
|
|
@@ -791,7 +810,7 @@ export class LangchainAgent {
|
|
|
791
810
|
status: "pending",
|
|
792
811
|
rawInput: {}, // Args not available yet
|
|
793
812
|
_meta: { messageId: req.messageId },
|
|
794
|
-
};
|
|
813
|
+
});
|
|
795
814
|
}
|
|
796
815
|
}
|
|
797
816
|
else if (part.type === "input_json_delta") {
|
|
@@ -801,6 +820,8 @@ export class LangchainAgent {
|
|
|
801
820
|
throw new Error(`Unhandled AIMessageChunk content block type: ${part.type}\n${JSON.stringify(part)}`);
|
|
802
821
|
}
|
|
803
822
|
}
|
|
823
|
+
// Don't flush here - these are preliminary tool_use blocks
|
|
824
|
+
// We'll flush when we get the full tool calls in "updates" mode
|
|
804
825
|
}
|
|
805
826
|
else {
|
|
806
827
|
throw new Error(`Unhandled AIMessageChunk content type: ${typeof aiMessage.content}`);
|
|
@@ -822,16 +843,16 @@ export class LangchainAgent {
|
|
|
822
843
|
toolCallId: aiMessage.tool_call_id,
|
|
823
844
|
...(isError ? { error: aiMessage.content } : {}),
|
|
824
845
|
});
|
|
825
|
-
//
|
|
826
|
-
|
|
846
|
+
// Buffer status update (metadata only, no content)
|
|
847
|
+
pendingToolCallNotifications.push({
|
|
827
848
|
sessionUpdate: "tool_call_update",
|
|
828
849
|
toolCallId: aiMessage.tool_call_id,
|
|
829
850
|
status,
|
|
830
851
|
...(isError ? { error: aiMessage.content } : {}),
|
|
831
852
|
_meta: { messageId: req.messageId },
|
|
832
|
-
};
|
|
833
|
-
//
|
|
834
|
-
|
|
853
|
+
});
|
|
854
|
+
// Buffer tool output separately
|
|
855
|
+
pendingToolCallNotifications.push({
|
|
835
856
|
sessionUpdate: "tool_output",
|
|
836
857
|
toolCallId: aiMessage.tool_call_id,
|
|
837
858
|
content: [
|
|
@@ -845,7 +866,9 @@ export class LangchainAgent {
|
|
|
845
866
|
],
|
|
846
867
|
rawOutput: { content: aiMessage.content },
|
|
847
868
|
_meta: { messageId: req.messageId },
|
|
848
|
-
};
|
|
869
|
+
});
|
|
870
|
+
// Flush tool outputs after buffering
|
|
871
|
+
yield* flushPendingToolCalls();
|
|
849
872
|
}
|
|
850
873
|
else {
|
|
851
874
|
throw new Error(`Unhandled ToolMessage content type: ${typeof aiMessage.content}`);
|
|
@@ -863,6 +886,8 @@ export class LangchainAgent {
|
|
|
863
886
|
}
|
|
864
887
|
// Yield any remaining pending subagent connection updates after stream ends
|
|
865
888
|
yield* yieldPendingSubagentUpdates();
|
|
889
|
+
// Now that content streaming is complete, yield all buffered tool call notifications
|
|
890
|
+
yield* flushPendingToolCalls();
|
|
866
891
|
// Clean up subagent connection listener
|
|
867
892
|
subagentEvents.off("connection", onSubagentConnection);
|
|
868
893
|
// Cancel any pending wait
|