@townco/ui 0.1.133 → 0.1.135
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/core/hooks/use-chat-messages.d.ts +1 -1
- package/dist/core/schemas/chat.d.ts +2 -2
- package/dist/core/schemas/source.d.ts +1 -1
- package/dist/core/schemas/source.js +2 -2
- package/dist/gui/components/ChatView.js +1 -1
- package/dist/gui/components/CitationChip.js +1 -1
- package/dist/gui/components/SubagentStream.d.ts +23 -0
- package/dist/gui/components/SubagentStream.js +98 -0
- package/dist/gui/components/ToolCall.js +10 -2
- package/dist/sdk/schemas/message.d.ts +3 -3
- package/dist/sdk/schemas/message.js +1 -1
- package/dist/sdk/schemas/session.d.ts +1 -1
- package/package.json +3 -3
|
@@ -228,7 +228,7 @@ export declare function useChatMessages(client: AcpClient | null, startSession:
|
|
|
228
228
|
}[] | undefined;
|
|
229
229
|
sources?: {
|
|
230
230
|
id: string;
|
|
231
|
-
url
|
|
231
|
+
url?: string | undefined;
|
|
232
232
|
title: string;
|
|
233
233
|
snippet?: string | undefined;
|
|
234
234
|
favicon?: string | undefined;
|
|
@@ -312,7 +312,7 @@ export declare const DisplayMessage: z.ZodObject<{
|
|
|
312
312
|
}, z.core.$strip>>>;
|
|
313
313
|
sources: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
314
314
|
id: z.ZodString;
|
|
315
|
-
url: z.ZodString
|
|
315
|
+
url: z.ZodOptional<z.ZodString>;
|
|
316
316
|
title: z.ZodString;
|
|
317
317
|
snippet: z.ZodOptional<z.ZodString>;
|
|
318
318
|
favicon: z.ZodOptional<z.ZodString>;
|
|
@@ -607,7 +607,7 @@ export declare const ChatSessionState: z.ZodObject<{
|
|
|
607
607
|
}, z.core.$strip>>>;
|
|
608
608
|
sources: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
609
609
|
id: z.ZodString;
|
|
610
|
-
url: z.ZodString
|
|
610
|
+
url: z.ZodOptional<z.ZodString>;
|
|
611
611
|
title: z.ZodString;
|
|
612
612
|
snippet: z.ZodOptional<z.ZodString>;
|
|
613
613
|
favicon: z.ZodOptional<z.ZodString>;
|
|
@@ -5,8 +5,8 @@ import { z } from "zod";
|
|
|
5
5
|
export const SourceSchema = z.object({
|
|
6
6
|
/** Unique identifier for LLM reference (e.g., "1", "2") */
|
|
7
7
|
id: z.string(),
|
|
8
|
-
/** The URL of the source */
|
|
9
|
-
url: z.string().
|
|
8
|
+
/** The URL of the source (optional for backward compatibility with sessions that have missing URLs) */
|
|
9
|
+
url: z.string().optional(),
|
|
10
10
|
/** Title of the source page/article */
|
|
11
11
|
title: z.string(),
|
|
12
12
|
/** Optional snippet/excerpt from the source */
|
|
@@ -144,7 +144,7 @@ export function ChatView({ client, initialSessionId, error: initError, debuggerU
|
|
|
144
144
|
byId.set(source.id, {
|
|
145
145
|
id: source.id,
|
|
146
146
|
title: source.title,
|
|
147
|
-
url: source.url,
|
|
147
|
+
url: source.url || "",
|
|
148
148
|
snippet: source.snippet || "",
|
|
149
149
|
sourceName: source.sourceName || "",
|
|
150
150
|
favicon: source.favicon || "",
|
|
@@ -39,7 +39,7 @@ export const CitationChip = React.forwardRef(({ sourceId, sources, className },
|
|
|
39
39
|
if (!source) {
|
|
40
40
|
return (_jsxs("span", { ref: ref, className: cn("inline-flex items-center px-1.5 py-0.5 text-xs font-medium", "bg-muted text-muted-foreground rounded-md", "cursor-default", className), children: ["[", sourceId, "]"] }));
|
|
41
41
|
}
|
|
42
|
-
const domain = source.sourceName || getDomain(source.url);
|
|
42
|
+
const domain = source.sourceName || (source.url ? getDomain(source.url) : "");
|
|
43
43
|
return (_jsx(TooltipProvider, { delayDuration: 200, children: _jsxs(Tooltip, { children: [
|
|
44
44
|
_jsx(TooltipTrigger, { asChild: true, children: _jsxs("span", { ref: ref, role: "button", tabIndex: 0, onClick: handleClick, onKeyDown: (e) => {
|
|
45
45
|
if (e.key === "Enter" || e.key === " ") {
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface SubagentStreamProps {
|
|
2
|
+
/** Sub-agent HTTP port */
|
|
3
|
+
port: number;
|
|
4
|
+
/** Sub-agent session ID */
|
|
5
|
+
sessionId: string;
|
|
6
|
+
/** Optional host (defaults to localhost) */
|
|
7
|
+
host?: string;
|
|
8
|
+
/** Parent tool call status - use this to determine if sub-agent is running */
|
|
9
|
+
parentStatus?: "pending" | "in_progress" | "completed" | "failed";
|
|
10
|
+
/** Sub-agent name (for display) */
|
|
11
|
+
agentName?: string | undefined;
|
|
12
|
+
/** Query sent to the sub-agent */
|
|
13
|
+
query?: string | undefined;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* SubagentStream component - displays streaming content from a sub-agent.
|
|
17
|
+
*
|
|
18
|
+
* This component:
|
|
19
|
+
* - Connects directly to the sub-agent's SSE endpoint
|
|
20
|
+
* - Displays streaming text and tool calls
|
|
21
|
+
* - Renders in a collapsible section (collapsed by default)
|
|
22
|
+
*/
|
|
23
|
+
export declare function SubagentStream({ port, sessionId, host, parentStatus, agentName, query, }: SubagentStreamProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ChevronDown, CircleDot, Loader2 } from "lucide-react";
|
|
3
|
+
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
4
|
+
import { useSubagentStream } from "../../core/hooks/use-subagent-stream.js";
|
|
5
|
+
const SCROLL_THRESHOLD = 50; // px from bottom to consider "at bottom"
|
|
6
|
+
/**
|
|
7
|
+
* SubagentStream component - displays streaming content from a sub-agent.
|
|
8
|
+
*
|
|
9
|
+
* This component:
|
|
10
|
+
* - Connects directly to the sub-agent's SSE endpoint
|
|
11
|
+
* - Displays streaming text and tool calls
|
|
12
|
+
* - Renders in a collapsible section (collapsed by default)
|
|
13
|
+
*/
|
|
14
|
+
export function SubagentStream({ port, sessionId, host, parentStatus, agentName, query, }) {
|
|
15
|
+
const [isExpanded, setIsExpanded] = useState(false); // Start collapsed for parallel ops
|
|
16
|
+
const [isThinkingExpanded, setIsThinkingExpanded] = useState(true);
|
|
17
|
+
const [isNearBottom, setIsNearBottom] = useState(true);
|
|
18
|
+
const thinkingContainerRef = useRef(null);
|
|
19
|
+
const { messages, isStreaming: hookIsStreaming, error } = useSubagentStream({
|
|
20
|
+
port,
|
|
21
|
+
sessionId,
|
|
22
|
+
...(host !== undefined ? { host } : {}),
|
|
23
|
+
});
|
|
24
|
+
// Use parent status as primary indicator, fall back to hook's streaming state
|
|
25
|
+
// Parent is "in_progress" means sub-agent is definitely still running
|
|
26
|
+
const isRunning = parentStatus === "in_progress" || parentStatus === "pending" || hookIsStreaming;
|
|
27
|
+
// Get the current/latest message
|
|
28
|
+
const currentMessage = messages[messages.length - 1];
|
|
29
|
+
const hasContent = currentMessage &&
|
|
30
|
+
(currentMessage.content ||
|
|
31
|
+
(currentMessage.toolCalls && currentMessage.toolCalls.length > 0));
|
|
32
|
+
// Auto-collapse Thinking when completed (so Output is the primary view)
|
|
33
|
+
const prevIsRunningRef = useRef(isRunning);
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
if (prevIsRunningRef.current && !isRunning) {
|
|
36
|
+
// Just completed - collapse thinking to show output
|
|
37
|
+
setIsThinkingExpanded(false);
|
|
38
|
+
}
|
|
39
|
+
prevIsRunningRef.current = isRunning;
|
|
40
|
+
}, [isRunning]);
|
|
41
|
+
// Check if user is near bottom of scroll area
|
|
42
|
+
const checkScrollPosition = useCallback(() => {
|
|
43
|
+
const container = thinkingContainerRef.current;
|
|
44
|
+
if (!container)
|
|
45
|
+
return;
|
|
46
|
+
const { scrollTop, scrollHeight, clientHeight } = container;
|
|
47
|
+
const distanceFromBottom = scrollHeight - scrollTop - clientHeight;
|
|
48
|
+
setIsNearBottom(distanceFromBottom < SCROLL_THRESHOLD);
|
|
49
|
+
}, []);
|
|
50
|
+
// Scroll to bottom
|
|
51
|
+
const scrollToBottom = useCallback(() => {
|
|
52
|
+
const container = thinkingContainerRef.current;
|
|
53
|
+
if (!container)
|
|
54
|
+
return;
|
|
55
|
+
container.scrollTop = container.scrollHeight;
|
|
56
|
+
}, []);
|
|
57
|
+
// Auto-scroll when content changes and user is near bottom
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
if (isNearBottom && (isRunning || hasContent)) {
|
|
60
|
+
scrollToBottom();
|
|
61
|
+
}
|
|
62
|
+
}, [currentMessage?.content, currentMessage?.toolCalls, isNearBottom, isRunning, hasContent, scrollToBottom]);
|
|
63
|
+
// Set up scroll listener
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
const container = thinkingContainerRef.current;
|
|
66
|
+
if (!container)
|
|
67
|
+
return;
|
|
68
|
+
const handleScroll = () => checkScrollPosition();
|
|
69
|
+
container.addEventListener("scroll", handleScroll, { passive: true });
|
|
70
|
+
checkScrollPosition(); // Check initial position
|
|
71
|
+
return () => container.removeEventListener("scroll", handleScroll);
|
|
72
|
+
}, [checkScrollPosition, isThinkingExpanded, isExpanded]);
|
|
73
|
+
// Get last line of streaming content for preview
|
|
74
|
+
const lastLine = currentMessage?.content
|
|
75
|
+
? currentMessage.content.split("\n").filter(Boolean).pop() || ""
|
|
76
|
+
: "";
|
|
77
|
+
const previewText = lastLine.length > 100 ? `${lastLine.slice(0, 100)}...` : lastLine;
|
|
78
|
+
return (_jsxs("div", { children: [!isExpanded && (_jsx("button", { type: "button", onClick: () => setIsExpanded(true), className: "w-full max-w-md text-left cursor-pointer bg-transparent border-none p-0", children: previewText ? (_jsx("p", { className: `text-paragraph-sm text-muted-foreground truncate ${isRunning ? "animate-pulse" : ""}`, children: previewText })) : isRunning ? (_jsx("p", { className: "text-paragraph-sm text-muted-foreground/50 italic animate-pulse", children: "Waiting for response..." })) : null })), isExpanded && (_jsxs("div", { className: "space-y-3", children: [(agentName || query) && (_jsxs("div", { children: [_jsx("div", { className: "text-[10px] font-bold text-muted-foreground uppercase tracking-wider mb-1.5 font-sans", children: "Input" }), _jsxs("div", { className: "text-[11px] font-mono space-y-1", children: [agentName && (_jsxs("div", { children: [_jsx("span", { className: "text-muted-foreground", children: "agentName: " }), _jsx("span", { className: "text-foreground", children: agentName })] })), query && (_jsxs("div", { children: [_jsx("span", { className: "text-muted-foreground", children: "query: " }), _jsx("span", { className: "text-foreground", children: query })] }))] })] })), _jsxs("div", { children: [_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: [_jsx("div", { className: "text-[10px] font-bold text-muted-foreground uppercase tracking-wider font-sans", children: "Thinking" }), _jsx(ChevronDown, { className: `h-3 w-3 text-muted-foreground/70 transition-transform duration-200 ${isThinkingExpanded ? "rotate-180" : ""}` })] }), 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: [error && (_jsxs("div", { className: "px-2 py-2 text-[11px] text-destructive", children: ["Error: ", error] })), !error && !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.toolCalls &&
|
|
79
|
+
currentMessage.toolCalls.length > 0 && (_jsx("div", { className: "space-y-1", children: currentMessage.toolCalls.map((tc) => (_jsx(SubagentToolCallItem, { toolCall: tc }, tc.id))) })), currentMessage.content && (_jsxs("div", { className: "text-[11px] text-foreground whitespace-pre-wrap font-mono", children: [currentMessage.content, currentMessage.isStreaming && (_jsx("span", { className: "inline-block w-1.5 h-3 bg-primary/70 ml-0.5 animate-pulse" }))] }))] }))] }))] }), !isRunning && currentMessage?.content && (_jsxs("div", { children: [_jsx("div", { className: "text-[10px] font-bold text-muted-foreground uppercase tracking-wider mb-1.5 font-sans", children: "Output" }), _jsx("div", { className: "text-[11px] text-foreground whitespace-pre-wrap font-mono max-h-[200px] overflow-y-auto rounded-md bg-muted/30 border border-border/50 px-2 py-2", children: currentMessage.content })] }))] }))] }));
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Simple tool call display for sub-agent tool calls
|
|
83
|
+
*/
|
|
84
|
+
function SubagentToolCallItem({ toolCall }) {
|
|
85
|
+
const statusIcon = {
|
|
86
|
+
pending: "...",
|
|
87
|
+
in_progress: "",
|
|
88
|
+
completed: "",
|
|
89
|
+
failed: "",
|
|
90
|
+
}[toolCall.status];
|
|
91
|
+
const statusColor = {
|
|
92
|
+
pending: "text-muted-foreground",
|
|
93
|
+
in_progress: "text-blue-500",
|
|
94
|
+
completed: "text-green-500",
|
|
95
|
+
failed: "text-destructive",
|
|
96
|
+
}[toolCall.status];
|
|
97
|
+
return (_jsxs("div", { className: "flex items-center gap-2 text-[10px] text-muted-foreground", children: [_jsx("span", { className: statusColor, children: statusIcon }), _jsx("span", { className: "font-medium", children: toolCall.prettyName || toolCall.title }), toolCall.status === "in_progress" && (_jsx(Loader2, { className: "h-2.5 w-2.5 animate-spin" }))] }));
|
|
98
|
+
}
|
|
@@ -44,7 +44,15 @@ export function ToolCall({ toolCall }) {
|
|
|
44
44
|
const { resolvedTheme } = useTheme();
|
|
45
45
|
// Detect TodoWrite tool and subagent
|
|
46
46
|
const isTodoWrite = toolCall.title === "todo_write";
|
|
47
|
-
|
|
47
|
+
// A subagent call can be detected by:
|
|
48
|
+
// - Live: has port and sessionId (but no stored messages yet)
|
|
49
|
+
// - Replay: has stored subagentMessages
|
|
50
|
+
const hasLiveSubagent = !!(toolCall.subagentPort && toolCall.subagentSessionId);
|
|
51
|
+
const hasStoredSubagent = !!(toolCall.subagentMessages && toolCall.subagentMessages.length > 0);
|
|
52
|
+
const isSubagentCall = hasLiveSubagent || hasStoredSubagent;
|
|
53
|
+
// Use replay mode if we have stored messages - they should take precedence
|
|
54
|
+
// over trying to connect to SSE (which won't work for replayed sessions)
|
|
55
|
+
const isReplaySubagent = hasStoredSubagent;
|
|
48
56
|
// Safely access ChatLayout context - will be undefined if not within ChatLayout
|
|
49
57
|
const layoutContext = React.useContext(ChatLayout.Context);
|
|
50
58
|
// Click handler: toggle sidepanel for TodoWrite, subagent details for subagents, expand for others
|
|
@@ -139,7 +147,7 @@ export function ToolCall({ toolCall }) {
|
|
|
139
147
|
if (isPreliminary) {
|
|
140
148
|
return (_jsx("div", { className: "flex flex-col my-4", children: _jsxs("span", { className: "text-paragraph-sm text-muted-foreground/50", children: ["Invoking ", displayName] }) }));
|
|
141
149
|
}
|
|
142
|
-
return (_jsxs("div", { className: "flex flex-col my-4", children: [_jsxs("button", { type: "button", className: "flex flex-col items-start gap-0.5 cursor-pointer bg-transparent border-none p-0 text-left group w-fit", onClick: handleHeaderClick, "aria-expanded": isTodoWrite ? undefined : isExpanded, children: [_jsxs("div", { className: "flex items-center gap-1.5 text-[11px] font-medium text-muted-foreground", children: [_jsx("div", { className: iconColorClass, title: statusTooltip, children: _jsx(IconComponent, { className: "h-3 w-3" }) }), _jsx("span", { className: "text-paragraph-sm text-muted-foreground", children: displayName }), hasError && _jsx(AlertCircle, { className: "h-3 w-3 text-destructive" }), isTodoWrite ? (_jsx(ChevronRight, { className: "h-3 w-3 text-muted-foreground/70" })) : (_jsx(ChevronDown, { className: `h-3 w-3 text-muted-foreground/70 transition-transform duration-200 ${isExpanded ? "rotate-180" : ""}` }))] }), toolCall.subline && (_jsx("span", { className: "text-paragraph-sm text-muted-foreground/70 pl-4.5", children: toolCall.subline }))] }), !isTodoWrite && isSubagentCall && (_jsx("div", { className: "pl-4.5", children: _jsx(SubAgentDetails, { port: toolCall.subagentPort, sessionId: toolCall.subagentSessionId, parentStatus: toolCall.status, agentName: toolCall.rawInput?.agentName, query: toolCall.rawInput?.query, isExpanded: isSubagentExpanded, onExpandChange: setIsSubagentExpanded }) })), !isTodoWrite && !isSubagentCall && isExpanded && (_jsxs("div", { className: "mt-2 text-sm border border-border rounded-lg bg-card overflow-hidden w-full", children: [toolCall.rawInput &&
|
|
150
|
+
return (_jsxs("div", { className: "flex flex-col my-4", children: [_jsxs("button", { type: "button", className: "flex flex-col items-start gap-0.5 cursor-pointer bg-transparent border-none p-0 text-left group w-fit", onClick: handleHeaderClick, "aria-expanded": isTodoWrite ? undefined : isExpanded, children: [_jsxs("div", { className: "flex items-center gap-1.5 text-[11px] font-medium text-muted-foreground", children: [_jsx("div", { className: iconColorClass, title: statusTooltip, children: _jsx(IconComponent, { className: "h-3 w-3" }) }), _jsx("span", { className: "text-paragraph-sm text-muted-foreground", children: displayName }), hasError && _jsx(AlertCircle, { className: "h-3 w-3 text-destructive" }), isTodoWrite ? (_jsx(ChevronRight, { className: "h-3 w-3 text-muted-foreground/70" })) : (_jsx(ChevronDown, { className: `h-3 w-3 text-muted-foreground/70 transition-transform duration-200 ${isExpanded ? "rotate-180" : ""}` }))] }), toolCall.subline && (_jsx("span", { className: "text-paragraph-sm text-muted-foreground/70 pl-4.5", children: toolCall.subline }))] }), !isTodoWrite && isSubagentCall && (_jsx("div", { className: "pl-4.5", children: _jsx(SubAgentDetails, { port: toolCall.subagentPort, sessionId: toolCall.subagentSessionId, parentStatus: toolCall.status, agentName: toolCall.rawInput?.agentName, query: toolCall.rawInput?.query, isExpanded: isSubagentExpanded, onExpandChange: setIsSubagentExpanded, storedMessages: toolCall.subagentMessages, isReplay: isReplaySubagent }) })), !isTodoWrite && !isSubagentCall && isExpanded && (_jsxs("div", { className: "mt-2 text-sm border border-border rounded-lg bg-card overflow-hidden w-full", children: [toolCall.rawInput &&
|
|
143
151
|
Object.keys(toolCall.rawInput).length > 0 &&
|
|
144
152
|
!toolCall.subagentPort && (_jsxs("div", { className: "p-3 border-b border-border", children: [_jsx("div", { className: "text-[10px] font-bold text-muted-foreground uppercase tracking-wider mb-1.5 font-sans", children: "Input" }), _jsx("div", { className: "text-[11px] font-mono text-foreground", children: _jsx(JsonView, { value: toolCall.rawInput, collapsed: false, displayDataTypes: false, displayObjectSize: false, enableClipboard: true, style: jsonStyle }) })] })), toolCall.locations && toolCall.locations.length > 0 && (_jsxs("div", { className: "p-3 border-b border-border", children: [_jsx("div", { className: "text-[10px] font-bold text-muted-foreground uppercase tracking-wider mb-1.5 font-sans", children: "Files" }), _jsx("ul", { className: "space-y-1", children: toolCall.locations.map((loc) => (_jsxs("li", { className: "font-mono text-[11px] text-foreground bg-muted px-1.5 py-0.5 rounded w-fit", children: [loc.path, loc.line !== null &&
|
|
145
153
|
loc.line !== undefined &&
|
|
@@ -411,7 +411,7 @@ export type HookNotificationChunk = z.infer<typeof HookNotificationChunk>;
|
|
|
411
411
|
*/
|
|
412
412
|
export declare const CitationSource: z.ZodObject<{
|
|
413
413
|
id: z.ZodString;
|
|
414
|
-
url: z.ZodString
|
|
414
|
+
url: z.ZodOptional<z.ZodString>;
|
|
415
415
|
title: z.ZodString;
|
|
416
416
|
snippet: z.ZodOptional<z.ZodString>;
|
|
417
417
|
favicon: z.ZodOptional<z.ZodString>;
|
|
@@ -426,7 +426,7 @@ export declare const SourcesChunk: z.ZodObject<{
|
|
|
426
426
|
type: z.ZodLiteral<"sources">;
|
|
427
427
|
sources: z.ZodArray<z.ZodObject<{
|
|
428
428
|
id: z.ZodString;
|
|
429
|
-
url: z.ZodString
|
|
429
|
+
url: z.ZodOptional<z.ZodString>;
|
|
430
430
|
title: z.ZodString;
|
|
431
431
|
snippet: z.ZodOptional<z.ZodString>;
|
|
432
432
|
favicon: z.ZodOptional<z.ZodString>;
|
|
@@ -553,7 +553,7 @@ export declare const MessageChunk: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
553
553
|
type: z.ZodLiteral<"sources">;
|
|
554
554
|
sources: z.ZodArray<z.ZodObject<{
|
|
555
555
|
id: z.ZodString;
|
|
556
|
-
url: z.ZodString
|
|
556
|
+
url: z.ZodOptional<z.ZodString>;
|
|
557
557
|
title: z.ZodString;
|
|
558
558
|
snippet: z.ZodOptional<z.ZodString>;
|
|
559
559
|
favicon: z.ZodOptional<z.ZodString>;
|
|
@@ -214,7 +214,7 @@ export const HookNotificationChunk = z.object({
|
|
|
214
214
|
*/
|
|
215
215
|
export const CitationSource = z.object({
|
|
216
216
|
id: z.string(),
|
|
217
|
-
url: z.string().
|
|
217
|
+
url: z.string().optional(), // Optional for backward compatibility with sessions that have missing URLs
|
|
218
218
|
title: z.string(),
|
|
219
219
|
snippet: z.string().optional(),
|
|
220
220
|
favicon: z.string().optional(),
|
|
@@ -758,7 +758,7 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
758
758
|
type: z.ZodLiteral<"sources">;
|
|
759
759
|
sources: z.ZodArray<z.ZodObject<{
|
|
760
760
|
id: z.ZodString;
|
|
761
|
-
url: z.ZodString
|
|
761
|
+
url: z.ZodOptional<z.ZodString>;
|
|
762
762
|
title: z.ZodString;
|
|
763
763
|
snippet: z.ZodOptional<z.ZodString>;
|
|
764
764
|
favicon: z.ZodOptional<z.ZodString>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@townco/ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.135",
|
|
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.113",
|
|
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.132",
|
|
71
71
|
"@types/node": "^24.10.0",
|
|
72
72
|
"@types/react": "^19.2.2",
|
|
73
73
|
"@types/unist": "^3.0.3",
|