@townco/ui 0.1.104 → 0.1.105
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/browser-logger.d.ts +10 -0
- package/dist/browser-logger.js +141 -0
- package/dist/core/hooks/index.d.ts +0 -1
- package/dist/core/hooks/index.js +0 -1
- package/dist/core/hooks/use-tool-calls.js +11 -0
- package/dist/gui/components/ChatView.js +10 -0
- package/dist/gui/components/SubAgentDetails.d.ts +3 -12
- package/dist/gui/components/SubAgentDetails.js +27 -31
- package/dist/gui/components/ToolOperation.js +6 -12
- package/package.json +3 -3
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser console capture and server sync
|
|
3
|
+
* Intercepts console methods and sends logs to the agent server
|
|
4
|
+
* Follows the pattern from packages/ui/src/sdk/transports/stdio.ts
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Initialize browser logger
|
|
8
|
+
* Must be called early, before other code that might log
|
|
9
|
+
*/
|
|
10
|
+
export declare function initBrowserLogger(agentServerUrl: string): void;
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser console capture and server sync
|
|
3
|
+
* Intercepts console methods and sends logs to the agent server
|
|
4
|
+
* Follows the pattern from packages/ui/src/sdk/transports/stdio.ts
|
|
5
|
+
*/
|
|
6
|
+
import { createLogger, subscribeToLogs } from "@townco/core";
|
|
7
|
+
let initialized = false;
|
|
8
|
+
let serverUrl = null;
|
|
9
|
+
const logQueue = [];
|
|
10
|
+
let flushTimeoutId = null;
|
|
11
|
+
// Store original console methods to preserve DevTools output
|
|
12
|
+
const originalConsole = {
|
|
13
|
+
log: console.log.bind(console),
|
|
14
|
+
error: console.error.bind(console),
|
|
15
|
+
warn: console.warn.bind(console),
|
|
16
|
+
info: console.info.bind(console),
|
|
17
|
+
debug: console.debug.bind(console),
|
|
18
|
+
};
|
|
19
|
+
const logger = createLogger("gui-console");
|
|
20
|
+
/**
|
|
21
|
+
* Safely stringify arguments for logging
|
|
22
|
+
*/
|
|
23
|
+
function stringifyArgs(args) {
|
|
24
|
+
return args
|
|
25
|
+
.map((arg) => {
|
|
26
|
+
if (typeof arg === "string")
|
|
27
|
+
return arg;
|
|
28
|
+
if (arg instanceof Error)
|
|
29
|
+
return `${arg.name}: ${arg.message}`;
|
|
30
|
+
try {
|
|
31
|
+
return JSON.stringify(arg);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return String(arg);
|
|
35
|
+
}
|
|
36
|
+
})
|
|
37
|
+
.join(" ");
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Queue a log entry to be sent to the server
|
|
41
|
+
*/
|
|
42
|
+
function queueLog(entry) {
|
|
43
|
+
logQueue.push(entry);
|
|
44
|
+
// Immediate flush for errors
|
|
45
|
+
if (entry.level === "error" || entry.level === "fatal") {
|
|
46
|
+
flushLogs();
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
// Debounced flush for other levels
|
|
50
|
+
if (!flushTimeoutId) {
|
|
51
|
+
flushTimeoutId = setTimeout(() => {
|
|
52
|
+
flushTimeoutId = null;
|
|
53
|
+
flushLogs();
|
|
54
|
+
}, 500);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Send queued logs to the server
|
|
59
|
+
*/
|
|
60
|
+
async function flushLogs() {
|
|
61
|
+
if (logQueue.length === 0 || !serverUrl)
|
|
62
|
+
return;
|
|
63
|
+
const logs = logQueue.splice(0);
|
|
64
|
+
try {
|
|
65
|
+
await fetch(`${serverUrl}/logs/browser`, {
|
|
66
|
+
method: "POST",
|
|
67
|
+
headers: { "Content-Type": "application/json" },
|
|
68
|
+
body: JSON.stringify({ logs }),
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// Silent fail - don't break the app if server is unavailable
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Initialize browser logger
|
|
77
|
+
* Must be called early, before other code that might log
|
|
78
|
+
*/
|
|
79
|
+
export function initBrowserLogger(agentServerUrl) {
|
|
80
|
+
if (initialized)
|
|
81
|
+
return;
|
|
82
|
+
initialized = true;
|
|
83
|
+
serverUrl = agentServerUrl;
|
|
84
|
+
// Override console methods - preserve original output, then log
|
|
85
|
+
console.log = (...args) => {
|
|
86
|
+
originalConsole.log(...args);
|
|
87
|
+
logger.info(stringifyArgs(args));
|
|
88
|
+
};
|
|
89
|
+
console.info = (...args) => {
|
|
90
|
+
originalConsole.info(...args);
|
|
91
|
+
logger.info(stringifyArgs(args));
|
|
92
|
+
};
|
|
93
|
+
console.warn = (...args) => {
|
|
94
|
+
originalConsole.warn(...args);
|
|
95
|
+
logger.warn(stringifyArgs(args));
|
|
96
|
+
};
|
|
97
|
+
console.error = (...args) => {
|
|
98
|
+
originalConsole.error(...args);
|
|
99
|
+
logger.error(stringifyArgs(args));
|
|
100
|
+
};
|
|
101
|
+
console.debug = (...args) => {
|
|
102
|
+
originalConsole.debug(...args);
|
|
103
|
+
logger.debug(stringifyArgs(args));
|
|
104
|
+
};
|
|
105
|
+
// Capture uncaught exceptions
|
|
106
|
+
window.onerror = (message, source, line, col, error) => {
|
|
107
|
+
logger.error(String(message), {
|
|
108
|
+
source,
|
|
109
|
+
line,
|
|
110
|
+
col,
|
|
111
|
+
stack: error?.stack,
|
|
112
|
+
});
|
|
113
|
+
return false; // Let default handler run too
|
|
114
|
+
};
|
|
115
|
+
// Capture unhandled promise rejections
|
|
116
|
+
window.onunhandledrejection = (event) => {
|
|
117
|
+
const reason = event.reason instanceof Error
|
|
118
|
+
? `${event.reason.name}: ${event.reason.message}`
|
|
119
|
+
: String(event.reason);
|
|
120
|
+
logger.error(`Unhandled rejection: ${reason}`, {
|
|
121
|
+
stack: event.reason?.stack,
|
|
122
|
+
});
|
|
123
|
+
};
|
|
124
|
+
// Subscribe to logs and queue for server sync
|
|
125
|
+
subscribeToLogs((entry) => {
|
|
126
|
+
// Only sync gui-console logs to avoid duplicates
|
|
127
|
+
if (entry.service === "gui-console") {
|
|
128
|
+
queueLog(entry);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
// Flush logs before page unload
|
|
132
|
+
window.addEventListener("beforeunload", () => {
|
|
133
|
+
if (flushTimeoutId) {
|
|
134
|
+
clearTimeout(flushTimeoutId);
|
|
135
|
+
}
|
|
136
|
+
// Use sendBeacon for reliable delivery on page unload
|
|
137
|
+
if (logQueue.length > 0 && serverUrl) {
|
|
138
|
+
navigator.sendBeacon(`${serverUrl}/logs/browser`, JSON.stringify({ logs: logQueue }));
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}
|
package/dist/core/hooks/index.js
CHANGED
|
@@ -29,10 +29,21 @@ export function useToolCalls(client) {
|
|
|
29
29
|
}
|
|
30
30
|
else if (update.type === "tool_call_update") {
|
|
31
31
|
// Tool call update notification
|
|
32
|
+
_logger.info("[SUBAGENT] Frontend received tool_call_update", {
|
|
33
|
+
sessionId: update.sessionId,
|
|
34
|
+
toolCallId: update.toolCallUpdate.id,
|
|
35
|
+
status: update.toolCallUpdate.status,
|
|
36
|
+
hasSubagentMessages: !!update.toolCallUpdate.subagentMessages,
|
|
37
|
+
subagentMessageCount: update.toolCallUpdate.subagentMessages?.length || 0,
|
|
38
|
+
});
|
|
32
39
|
// Update session-level tool calls (for sidebar)
|
|
33
40
|
updateToolCall(update.sessionId, update.toolCallUpdate);
|
|
34
41
|
// Also update in current assistant message (for inline display)
|
|
35
42
|
updateToolCallInCurrentMessage(update.toolCallUpdate);
|
|
43
|
+
_logger.info("[SUBAGENT] Successfully updated tool call state", {
|
|
44
|
+
sessionId: update.sessionId,
|
|
45
|
+
toolCallId: update.toolCallUpdate.id,
|
|
46
|
+
});
|
|
36
47
|
}
|
|
37
48
|
});
|
|
38
49
|
return () => {
|
|
@@ -3,6 +3,7 @@ import { createLogger } from "@townco/core";
|
|
|
3
3
|
import { ArrowUp, Bug, Moon, PanelRight, Settings, Sun, X } from "lucide-react";
|
|
4
4
|
import * as React from "react";
|
|
5
5
|
import { useEffect, useState } from "react";
|
|
6
|
+
import { initBrowserLogger } from "../../browser-logger.js";
|
|
6
7
|
import { useChatMessages, useChatSession, useToolCalls, } from "../../core/hooks/index.js";
|
|
7
8
|
import { selectTodosForCurrentSession, useChatStore, } from "../../core/store/chat-store.js";
|
|
8
9
|
import { useDocumentTitle } from "../hooks/use-favicon.js";
|
|
@@ -119,6 +120,15 @@ export function ChatView({ client, initialSessionId, error: initError, debuggerU
|
|
|
119
120
|
}, [messages]);
|
|
120
121
|
// Update document title with agent name and animated dots when streaming
|
|
121
122
|
useDocumentTitle(agentName);
|
|
123
|
+
// Initialize browser logger to capture console output and send to server
|
|
124
|
+
useEffect(() => {
|
|
125
|
+
if (client) {
|
|
126
|
+
const baseUrl = client.getBaseUrl();
|
|
127
|
+
if (baseUrl) {
|
|
128
|
+
initBrowserLogger(baseUrl);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}, [client]);
|
|
122
132
|
// Log connection status changes
|
|
123
133
|
useEffect(() => {
|
|
124
134
|
logger.debug("Connection status changed", { status: connectionStatus });
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import type { ToolCall as ToolCallType } from "../../core/schemas/tool-call.js";
|
|
2
2
|
export interface SubAgentDetailsProps {
|
|
3
|
-
/** Sub-agent HTTP port (required for live streaming, not for replay) */
|
|
4
|
-
port?: number | undefined;
|
|
5
|
-
/** Sub-agent session ID (required for live streaming, not for replay) */
|
|
6
|
-
sessionId?: string | undefined;
|
|
7
|
-
/** Optional host (defaults to localhost) */
|
|
8
|
-
host?: string;
|
|
9
3
|
/** Parent tool call status - use this to determine if sub-agent is running */
|
|
10
4
|
parentStatus?: "pending" | "in_progress" | "completed" | "failed";
|
|
11
5
|
/** Sub-agent name (for display) */
|
|
@@ -16,19 +10,16 @@ export interface SubAgentDetailsProps {
|
|
|
16
10
|
isExpanded?: boolean;
|
|
17
11
|
/** Callback when expand state changes */
|
|
18
12
|
onExpandChange?: (expanded: boolean) => void;
|
|
19
|
-
/**
|
|
13
|
+
/** Messages from the subagent (streamed via parent tool_call_update) */
|
|
20
14
|
storedMessages?: ToolCallType["subagentMessages"];
|
|
21
|
-
/** Whether this is a replay (skips SSE connection) */
|
|
22
|
-
isReplay?: boolean | undefined;
|
|
23
15
|
}
|
|
24
16
|
/**
|
|
25
17
|
* SubAgentDetails component - displays streaming content from a sub-agent.
|
|
26
18
|
*
|
|
27
19
|
* This component:
|
|
28
|
-
* -
|
|
29
|
-
* - Or displays stored messages (replay mode)
|
|
20
|
+
* - Displays messages from the subagent (received via parent tool_call_update events)
|
|
30
21
|
* - Displays streaming text and tool calls
|
|
31
22
|
* - Renders content as markdown
|
|
32
23
|
* - Renders in a collapsible section (collapsed by default)
|
|
33
24
|
*/
|
|
34
|
-
export declare function SubAgentDetails({
|
|
25
|
+
export declare function SubAgentDetails({ parentStatus, agentName, query, isExpanded: controlledIsExpanded, onExpandChange, storedMessages }: SubAgentDetailsProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { ChevronDown, Loader2 } from "lucide-react";
|
|
3
|
-
import { useCallback, useEffect,
|
|
4
|
-
import { useSubagentStream } from "../../core/hooks/use-subagent-stream.js";
|
|
3
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
5
4
|
import { MarkdownRenderer } from "./MarkdownRenderer.js";
|
|
6
5
|
const SCROLL_THRESHOLD = 50; // px from bottom to consider "at bottom"
|
|
7
6
|
/**
|
|
8
7
|
* SubAgentDetails component - displays streaming content from a sub-agent.
|
|
9
8
|
*
|
|
10
9
|
* This component:
|
|
11
|
-
* -
|
|
12
|
-
* - Or displays stored messages (replay mode)
|
|
10
|
+
* - Displays messages from the subagent (received via parent tool_call_update events)
|
|
13
11
|
* - Displays streaming text and tool calls
|
|
14
12
|
* - Renders content as markdown
|
|
15
13
|
* - Renders in a collapsible section (collapsed by default)
|
|
16
14
|
*/
|
|
17
|
-
export function SubAgentDetails({
|
|
15
|
+
export function SubAgentDetails({ parentStatus, agentName, query, isExpanded: controlledIsExpanded, onExpandChange, storedMessages, }) {
|
|
18
16
|
const [internalIsExpanded, setInternalIsExpanded] = useState(false);
|
|
19
17
|
// Use controlled state if provided, otherwise use internal state
|
|
20
18
|
const isExpanded = controlledIsExpanded ?? internalIsExpanded;
|
|
@@ -23,31 +21,22 @@ export function SubAgentDetails({ port, sessionId, host, parentStatus, agentName
|
|
|
23
21
|
const [isThinkingExpanded, setIsThinkingExpanded] = useState(true);
|
|
24
22
|
const [isNearBottom, setIsNearBottom] = useState(true);
|
|
25
23
|
const thinkingContainerRef = useRef(null);
|
|
26
|
-
//
|
|
27
|
-
const
|
|
28
|
-
//
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
: streamedMessages;
|
|
43
|
-
// Use parent status as primary indicator, fall back to hook's streaming state
|
|
44
|
-
// Parent is "in_progress" means sub-agent is definitely still running
|
|
45
|
-
// In replay mode, we're never running
|
|
46
|
-
const isRunning = isReplay
|
|
47
|
-
? false
|
|
48
|
-
: parentStatus === "in_progress" ||
|
|
49
|
-
parentStatus === "pending" ||
|
|
50
|
-
hookIsStreaming;
|
|
24
|
+
// Use messages from storedMessages prop (populated by parent via tool_call_update)
|
|
25
|
+
const messages = storedMessages || [];
|
|
26
|
+
// Log when messages are received/updated
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
console.log("[SUBAGENT] SubAgentDetails received messages update", {
|
|
29
|
+
agentName,
|
|
30
|
+
messageCount: messages.length,
|
|
31
|
+
parentStatus,
|
|
32
|
+
hasMessages: messages.length > 0,
|
|
33
|
+
contentPreview: messages[0]?.content?.substring(0, 100),
|
|
34
|
+
toolCallCount: messages[0]?.toolCalls?.length || 0,
|
|
35
|
+
contentBlockCount: messages[0]?.contentBlocks?.length || 0,
|
|
36
|
+
});
|
|
37
|
+
}, [messages, agentName, parentStatus]);
|
|
38
|
+
// Determine if subagent is still running based on parent status
|
|
39
|
+
const isRunning = parentStatus === "in_progress" || parentStatus === "pending";
|
|
51
40
|
// Get the current/latest message
|
|
52
41
|
const currentMessage = messages[messages.length - 1];
|
|
53
42
|
const hasContent = currentMessage &&
|
|
@@ -55,6 +44,13 @@ export function SubAgentDetails({ port, sessionId, host, parentStatus, agentName
|
|
|
55
44
|
(currentMessage.toolCalls && currentMessage.toolCalls.length > 0) ||
|
|
56
45
|
(currentMessage.contentBlocks &&
|
|
57
46
|
currentMessage.contentBlocks.length > 0));
|
|
47
|
+
console.log("[SUBAGENT] SubAgentDetails render state", {
|
|
48
|
+
agentName,
|
|
49
|
+
messageCount: messages.length,
|
|
50
|
+
hasContent,
|
|
51
|
+
isRunning,
|
|
52
|
+
parentStatus,
|
|
53
|
+
});
|
|
58
54
|
// Auto-collapse Thinking when completed (so Output is the primary view)
|
|
59
55
|
const prevIsRunningRef = useRef(isRunning);
|
|
60
56
|
useEffect(() => {
|
|
@@ -125,7 +121,7 @@ export function SubAgentDetails({ port, sessionId, host, parentStatus, agentName
|
|
|
125
121
|
] })), _jsxs("div", { children: [
|
|
126
122
|
_jsxs("button", { type: "button", onClick: () => setIsThinkingExpanded(!isThinkingExpanded), className: "flex items-center gap-2 cursor-pointer bg-transparent border-none p-0 text-left group", children: [
|
|
127
123
|
_jsx("div", { className: "text-[10px] font-bold text-muted-foreground uppercase tracking-wider font-sans", children: "Stream" }), _jsx(ChevronDown, { className: `h-3 w-3 text-muted-foreground/70 transition-transform duration-200 ${isThinkingExpanded ? "rotate-180" : ""}` })
|
|
128
|
-
] }), isThinkingExpanded && (_jsxs("div", { ref: thinkingContainerRef, className: "mt-2 rounded-md overflow-hidden bg-muted/30 border border-border/50 max-h-[200px] overflow-y-auto", children: [
|
|
124
|
+
] }), isThinkingExpanded && (_jsxs("div", { ref: thinkingContainerRef, className: "mt-2 rounded-md overflow-hidden bg-muted/30 border border-border/50 max-h-[200px] overflow-y-auto", children: [!hasContent && isRunning && (_jsx("div", { className: "px-2 py-2 text-[11px] text-muted-foreground", children: "Waiting for sub-agent response..." })), currentMessage && (_jsxs("div", { className: "px-2 py-2 space-y-2", children: [currentMessage.contentBlocks &&
|
|
129
125
|
currentMessage.contentBlocks.length > 0
|
|
130
126
|
? // Render interleaved content blocks
|
|
131
127
|
currentMessage.contentBlocks.map((block, blockIdx) => block.type === "text" ? (_jsx("div", { className: "text-[11px] text-foreground prose prose-sm dark:prose-invert max-w-none prose-p:my-1 prose-pre:my-1 prose-code:text-[10px]", children: _jsx(MarkdownRenderer, { content: block.text }) }, `text-${block.text.slice(0, 30)}-${blockIdx}`)) : (_jsx(SubagentToolCallItem, { toolCall: block.toolCall }, block.toolCall.id)))
|
|
@@ -138,12 +138,9 @@ export function ToolOperation({ toolCalls, isGrouped = false, autoMinimize = tru
|
|
|
138
138
|
(n.metadata?.action === "truncated" ||
|
|
139
139
|
n.metadata?.action === "compacted_then_truncated")))
|
|
140
140
|
: false;
|
|
141
|
-
// Detect subagent calls
|
|
142
|
-
const
|
|
143
|
-
const hasStoredSubagent = !!(singleToolCall?.subagentMessages &&
|
|
141
|
+
// Detect subagent calls (subagents now run in-process, messages in subagentMessages)
|
|
142
|
+
const isSubagentCall = !!(singleToolCall?.subagentMessages &&
|
|
144
143
|
singleToolCall.subagentMessages.length > 0);
|
|
145
|
-
const isSubagentCall = hasLiveSubagent || hasStoredSubagent;
|
|
146
|
-
const isReplaySubagent = hasStoredSubagent;
|
|
147
144
|
// State for subagent expansion
|
|
148
145
|
const [isSubagentExpanded, setIsSubagentExpanded] = useState(false);
|
|
149
146
|
// Safely access ChatLayout context
|
|
@@ -312,7 +309,7 @@ export function ToolOperation({ toolCalls, isGrouped = false, autoMinimize = tru
|
|
|
312
309
|
return (_jsxs("span", { className: "text-paragraph-sm text-text-secondary/70 pl-4.5", children: [compactedCount, " response", compactedCount > 1 ? "s" : "", " ", "compacted"] }));
|
|
313
310
|
}
|
|
314
311
|
return null;
|
|
315
|
-
})()] }), !isTodoWrite && isSubagentCall && singleToolCall && (_jsx("div", { className: "pl-4.5 mt-2", children: _jsx(SubAgentDetails, {
|
|
312
|
+
})()] }), !isTodoWrite && isSubagentCall && singleToolCall && (_jsx("div", { className: "pl-4.5 mt-2", children: _jsx(SubAgentDetails, { parentStatus: singleToolCall.status, agentName: singleToolCall.rawInput?.agentName, query: singleToolCall.rawInput?.query, isExpanded: isSubagentExpanded, onExpandChange: setIsSubagentExpanded, storedMessages: singleToolCall.subagentMessages }) })), !isTodoWrite && isExpanded && (_jsx("div", { className: "mt-1", children: isGrouped ? (
|
|
316
313
|
// Render individual tool calls in group
|
|
317
314
|
_jsx("div", { className: "flex flex-col gap-4 mt-2", children: toolCalls.map((toolCall) => {
|
|
318
315
|
const hookNotification = hookNotifications.find((n) => n.toolCallId === toolCall.id);
|
|
@@ -329,11 +326,8 @@ export function ToolOperation({ toolCalls, isGrouped = false, autoMinimize = tru
|
|
|
329
326
|
*/
|
|
330
327
|
function GroupedToolCallItem({ toolCall, hookNotification, }) {
|
|
331
328
|
const [isExpanded, setIsExpanded] = useState(false);
|
|
332
|
-
// Detect subagent calls
|
|
333
|
-
const
|
|
334
|
-
const hasStoredSubagent = !!(toolCall.subagentMessages && toolCall.subagentMessages.length > 0);
|
|
335
|
-
const isSubagentCall = hasLiveSubagent || hasStoredSubagent;
|
|
336
|
-
const isReplaySubagent = hasStoredSubagent;
|
|
329
|
+
// Detect subagent calls (subagents now run in-process, messages in subagentMessages)
|
|
330
|
+
const isSubagentCall = !!(toolCall.subagentMessages && toolCall.subagentMessages.length > 0);
|
|
337
331
|
// Detect compaction for this individual tool call
|
|
338
332
|
const hasCompaction = !!((hookNotification?.status === "completed" &&
|
|
339
333
|
hookNotification.metadata?.action &&
|
|
@@ -365,7 +359,7 @@ function GroupedToolCallItem({ toolCall, hookNotification, }) {
|
|
|
365
359
|
: "Response was compacted";
|
|
366
360
|
})() })
|
|
367
361
|
] }) })), _jsx(ChevronDown, { className: `h-3 w-3 text-text-secondary/70 group-hover:text-text-secondary transition-colors transition-transform duration-200 ${isExpanded ? "rotate-180" : ""}` })
|
|
368
|
-
] }), _jsx("div", { className: "pl-4.5", children: _jsx(SubAgentDetails, {
|
|
362
|
+
] }), _jsx("div", { className: "pl-4.5", children: _jsx(SubAgentDetails, { parentStatus: toolCall.status, agentName: toolCall.rawInput?.agentName, query: toolCall.rawInput?.query, isExpanded: isExpanded, onExpandChange: setIsExpanded, storedMessages: toolCall.subagentMessages }) })
|
|
369
363
|
] }));
|
|
370
364
|
}
|
|
371
365
|
// Regular tool call - collapsible with clickable header
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@townco/ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.105",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"@radix-ui/react-slot": "^1.2.4",
|
|
50
50
|
"@radix-ui/react-tabs": "^1.1.13",
|
|
51
51
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
52
|
-
"@townco/core": "0.0.
|
|
52
|
+
"@townco/core": "0.0.83",
|
|
53
53
|
"@types/mdast": "^4.0.4",
|
|
54
54
|
"@uiw/react-json-view": "^2.0.0-alpha.39",
|
|
55
55
|
"class-variance-authority": "^0.7.1",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"zustand": "^5.0.8"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
|
-
"@townco/tsconfig": "0.1.
|
|
70
|
+
"@townco/tsconfig": "0.1.102",
|
|
71
71
|
"@types/node": "^24.10.0",
|
|
72
72
|
"@types/react": "^19.2.2",
|
|
73
73
|
"@types/unist": "^3.0.3",
|