@invergent/agent-chat-react 2.4.13 → 2.5.0

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/index.d.cts CHANGED
@@ -326,6 +326,13 @@ interface AgentChatBrowserControlResponse {
326
326
  outcome: "granted" | "refreshed" | "conflict";
327
327
  ownerUserId: string;
328
328
  }
329
+ /** One source the planner curated with research_memory(add). */
330
+ interface AgentChatResearchSource {
331
+ /** Stable identifier — citations in the report refer to this (e.g. "S3"). */
332
+ sourceId: string;
333
+ url: string;
334
+ title: string;
335
+ }
329
336
  interface AgentChatState {
330
337
  messages: AgentChatMessage[];
331
338
  isRunning: boolean;
@@ -339,6 +346,9 @@ interface AgentChatState {
339
346
  workspaceRefreshKey: number;
340
347
  browser: AgentChatBrowserState | null;
341
348
  viewMode: AgentChatViewMode;
349
+ /** Sources collected from successful research_memory(add) tool
350
+ * results. Deduped by sourceId on insertion. */
351
+ researchSources: AgentChatResearchSource[];
342
352
  }
343
353
  type AgentChatViewMode = "simple" | "expert";
344
354
  type AgentChatArtifactKind = "markdown" | "table" | "chart" | "html" | "svg";
@@ -678,6 +688,10 @@ interface AgentChatRuntimeApi {
678
688
  viewMode: AgentChatViewMode;
679
689
  /** Update the chat view mode + persist via adapter / localStorage. */
680
690
  setViewMode(mode: AgentChatViewMode): void;
691
+ /** Sources collected from ``research_memory(add)`` tool results.
692
+ * Hosts render the sources/citations panel from this array; the
693
+ * ``CitationText`` helper resolves ``[S#]`` markers against it. */
694
+ researchSources: AgentChatResearchSource[];
681
695
  }
682
696
  type ChatMessage = AgentChatMessage;
683
697
  type SessionTreeNode = AgentChatSessionTreeNode;
@@ -731,8 +745,17 @@ interface AgentChatProps {
731
745
  * their toast system; the SDK does not surface these on its own.
732
746
  */
733
747
  onComposerError?: (err: ChatComposerError) => void;
748
+ /**
749
+ * Per-agent capability flag. When true, the composer surfaces the
750
+ * ``/deep-research`` slash command in its builtin menu. Off by
751
+ * default; the host (Studio) reads it from the agent record and
752
+ * passes it through. Wired this way (not via the runtime) because
753
+ * the SDK has no notion of the agent's settings -- the host owns
754
+ * that domain.
755
+ */
756
+ deepResearchEnabled?: boolean;
734
757
  }
735
- declare function AgentChat({ adapter, agentId, sessionId, onSessionChange, onFileSelect, onMessagesChange, disabled, onComposerError, }: AgentChatProps): react_jsx_runtime.JSX.Element;
758
+ declare function AgentChat({ adapter, agentId, sessionId, onSessionChange, onFileSelect, onMessagesChange, disabled, onComposerError, deepResearchEnabled, }: AgentChatProps): react_jsx_runtime.JSX.Element;
736
759
 
737
760
  interface AgentChatAdapterContextValue {
738
761
  adapter: AgentChatAdapter;
@@ -818,6 +841,36 @@ declare function groupMissionTasksByBucket(tasks: AgentChatMissionTask[]): Recor
818
841
  */
819
842
  declare function deriveMissionWorkerActivityLabel(worker: AgentChatMissionWorker): string;
820
843
 
844
+ declare function ResearchSourcesPanel({ sources, }: {
845
+ sources: AgentChatResearchSource[];
846
+ }): react_jsx_runtime.JSX.Element;
847
+
848
+ type CitationSegment = {
849
+ kind: "text";
850
+ value: string;
851
+ } | {
852
+ kind: "cite";
853
+ value: string;
854
+ };
855
+ /**
856
+ * Split *text* into plain-text and citation segments.
857
+ *
858
+ * Comma-grouped markers expand into one ``cite`` segment per ID.
859
+ * Empty input returns an empty array. Invalid markers are passed
860
+ * through verbatim as ``text``.
861
+ */
862
+ declare function splitCitations(text: string): CitationSegment[];
863
+ /**
864
+ * Render *text* with each ``[S#]`` marker as a chip that links to the
865
+ * matching :class:`AgentChatResearchSource`. Hosts pass
866
+ * ``onCitationClick`` to scroll the sources panel to the entry.
867
+ */
868
+ declare function CitationText({ text, sources, onCitationClick, }: {
869
+ text: string;
870
+ sources: AgentChatResearchSource[];
871
+ onCitationClick?: (sourceId: string) => void;
872
+ }): react_jsx_runtime.JSX.Element;
873
+
821
874
  interface ScheduledWorkPanelProps {
822
875
  adapter: AgentChatAdapter;
823
876
  agentId?: string;
@@ -854,4 +907,4 @@ interface SessionTreePanelProps {
854
907
  }
855
908
  declare function SessionTreePanel({ adapter, sessionId, activeSessionId, agentId, title, sessionListLimit, hideRoot, hideHeader, loadList, onSessionSelect, onSessionDelete, }: SessionTreePanelProps): react_jsx_runtime.JSX.Element | null;
856
909
 
857
- export { ACTIVE_MISSION_STATUSES, AgentChat, type AgentChatAdapter, type AgentChatAdapterContextValue, AgentChatAdapterProvider, type AgentChatArtifactKind, type AgentChatArtifactMeta, type AgentChatArtifactPayload, type AgentChatAskUserQuestionAnswer, type AgentChatAskUserQuestionArgs, type AgentChatAskUserQuestionChoice, type AgentChatAskUserQuestionQuestion, type AgentChatAttachment, type AgentChatChartArtifactSpec, type AgentChatDisplayAttachment, type AgentChatErrorCategory, type AgentChatErrorInfo, type AgentChatEventStream, type AgentChatEventType, type AgentChatExpertFeedbackRating, type AgentChatHtmlArtifactSpec, type AgentChatImageAttachment, type AgentChatInboxEventStream, type AgentChatInboxItem, type AgentChatInboxKind, type AgentChatInboxList, type AgentChatInboxListInput, type AgentChatInboxStatus, type AgentChatInboxStreamEvent, type AgentChatMarkdownArtifactSpec, type AgentChatMessage, type AgentChatMessageStatus, type AgentChatMissionList, type AgentChatMissionStatus, type AgentChatMissionSummary, type AgentChatMissionTask, type AgentChatMissionWorker, type AgentChatPendingAttachment, type AgentChatProps, type AgentChatRole, type AgentChatRuntimeApi, type AgentChatRuntimeEvent, type AgentChatScheduledWorkItem, type AgentChatScheduledWorkKind, type AgentChatScheduledWorkList, type AgentChatSession, type AgentChatSessionList, type AgentChatSessionTree, type AgentChatSessionTreeNode, type AgentChatSlashCommand, type AgentChatSseMessageEvent, type AgentChatState, type AgentChatSvgArtifactSpec, type AgentChatSystemKind, type AgentChatTableArtifactSpec, type AgentChatTokenUsage, type AgentChatToolCallInfo, type AgentChatWorkspaceEntry, type AgentChatWorkspaceFile, type AgentChatWorkspaceTree, type AgentChatWorkspaceUpload, type ArtifactKind, type ArtifactPayload, type AskUserQuestionAnswer, type AskUserQuestionArgs, type AskUserQuestionChoice, type AskUserQuestionQuestion, type ChartArtifactSpec, type ChatComposerError, type ChatMessage, type ErrorInfo, type HtmlArtifactSpec, type InboxItem, type InboxList, InboxPanel, type InboxPanelProps, type InboxUnreadCountState, type MarkdownArtifactSpec, MessageResponse, type MessageResponseProps, MissionDashboard, type MissionDashboardProps, type MissionTaskBucket, MissionsPanel, type MissionsPanelProps, type RetryIndicator, type ScheduledWorkItem, type ScheduledWorkList, ScheduledWorkPanel, type ScheduledWorkPanelProps, type SessionTree, type SessionTreeNode, SessionTreePanel, type SessionTreePanelProps, type SvgArtifactSpec, type TableArtifactSpec, type TokenUsage, type ToolCallInfo, type WorkspaceEntry, type WorkspaceFile, type WorkspaceTree, type WorkspaceUpload, deriveMissionWorkerActivityLabel, groupMissionTasksByBucket, isTerminalMissionStatus, missionTaskBucket, useAgentChatAdapterContext, useAgentChatRuntime, useChatViewMode, useInboxUnreadCount };
910
+ export { ACTIVE_MISSION_STATUSES, AgentChat, type AgentChatAdapter, type AgentChatAdapterContextValue, AgentChatAdapterProvider, type AgentChatArtifactKind, type AgentChatArtifactMeta, type AgentChatArtifactPayload, type AgentChatAskUserQuestionAnswer, type AgentChatAskUserQuestionArgs, type AgentChatAskUserQuestionChoice, type AgentChatAskUserQuestionQuestion, type AgentChatAttachment, type AgentChatChartArtifactSpec, type AgentChatDisplayAttachment, type AgentChatErrorCategory, type AgentChatErrorInfo, type AgentChatEventStream, type AgentChatEventType, type AgentChatExpertFeedbackRating, type AgentChatHtmlArtifactSpec, type AgentChatImageAttachment, type AgentChatInboxEventStream, type AgentChatInboxItem, type AgentChatInboxKind, type AgentChatInboxList, type AgentChatInboxListInput, type AgentChatInboxStatus, type AgentChatInboxStreamEvent, type AgentChatMarkdownArtifactSpec, type AgentChatMessage, type AgentChatMessageStatus, type AgentChatMissionList, type AgentChatMissionStatus, type AgentChatMissionSummary, type AgentChatMissionTask, type AgentChatMissionWorker, type AgentChatPendingAttachment, type AgentChatProps, type AgentChatResearchSource, type AgentChatRole, type AgentChatRuntimeApi, type AgentChatRuntimeEvent, type AgentChatScheduledWorkItem, type AgentChatScheduledWorkKind, type AgentChatScheduledWorkList, type AgentChatSession, type AgentChatSessionList, type AgentChatSessionTree, type AgentChatSessionTreeNode, type AgentChatSlashCommand, type AgentChatSseMessageEvent, type AgentChatState, type AgentChatSvgArtifactSpec, type AgentChatSystemKind, type AgentChatTableArtifactSpec, type AgentChatTokenUsage, type AgentChatToolCallInfo, type AgentChatWorkspaceEntry, type AgentChatWorkspaceFile, type AgentChatWorkspaceTree, type AgentChatWorkspaceUpload, type ArtifactKind, type ArtifactPayload, type AskUserQuestionAnswer, type AskUserQuestionArgs, type AskUserQuestionChoice, type AskUserQuestionQuestion, type ChartArtifactSpec, type ChatComposerError, type ChatMessage, type CitationSegment, CitationText, type ErrorInfo, type HtmlArtifactSpec, type InboxItem, type InboxList, InboxPanel, type InboxPanelProps, type InboxUnreadCountState, type MarkdownArtifactSpec, MessageResponse, type MessageResponseProps, MissionDashboard, type MissionDashboardProps, type MissionTaskBucket, MissionsPanel, type MissionsPanelProps, ResearchSourcesPanel, type RetryIndicator, type ScheduledWorkItem, type ScheduledWorkList, ScheduledWorkPanel, type ScheduledWorkPanelProps, type SessionTree, type SessionTreeNode, SessionTreePanel, type SessionTreePanelProps, type SvgArtifactSpec, type TableArtifactSpec, type TokenUsage, type ToolCallInfo, type WorkspaceEntry, type WorkspaceFile, type WorkspaceTree, type WorkspaceUpload, deriveMissionWorkerActivityLabel, groupMissionTasksByBucket, isTerminalMissionStatus, missionTaskBucket, splitCitations, useAgentChatAdapterContext, useAgentChatRuntime, useChatViewMode, useInboxUnreadCount };
package/dist/index.d.ts CHANGED
@@ -326,6 +326,13 @@ interface AgentChatBrowserControlResponse {
326
326
  outcome: "granted" | "refreshed" | "conflict";
327
327
  ownerUserId: string;
328
328
  }
329
+ /** One source the planner curated with research_memory(add). */
330
+ interface AgentChatResearchSource {
331
+ /** Stable identifier — citations in the report refer to this (e.g. "S3"). */
332
+ sourceId: string;
333
+ url: string;
334
+ title: string;
335
+ }
329
336
  interface AgentChatState {
330
337
  messages: AgentChatMessage[];
331
338
  isRunning: boolean;
@@ -339,6 +346,9 @@ interface AgentChatState {
339
346
  workspaceRefreshKey: number;
340
347
  browser: AgentChatBrowserState | null;
341
348
  viewMode: AgentChatViewMode;
349
+ /** Sources collected from successful research_memory(add) tool
350
+ * results. Deduped by sourceId on insertion. */
351
+ researchSources: AgentChatResearchSource[];
342
352
  }
343
353
  type AgentChatViewMode = "simple" | "expert";
344
354
  type AgentChatArtifactKind = "markdown" | "table" | "chart" | "html" | "svg";
@@ -678,6 +688,10 @@ interface AgentChatRuntimeApi {
678
688
  viewMode: AgentChatViewMode;
679
689
  /** Update the chat view mode + persist via adapter / localStorage. */
680
690
  setViewMode(mode: AgentChatViewMode): void;
691
+ /** Sources collected from ``research_memory(add)`` tool results.
692
+ * Hosts render the sources/citations panel from this array; the
693
+ * ``CitationText`` helper resolves ``[S#]`` markers against it. */
694
+ researchSources: AgentChatResearchSource[];
681
695
  }
682
696
  type ChatMessage = AgentChatMessage;
683
697
  type SessionTreeNode = AgentChatSessionTreeNode;
@@ -731,8 +745,17 @@ interface AgentChatProps {
731
745
  * their toast system; the SDK does not surface these on its own.
732
746
  */
733
747
  onComposerError?: (err: ChatComposerError) => void;
748
+ /**
749
+ * Per-agent capability flag. When true, the composer surfaces the
750
+ * ``/deep-research`` slash command in its builtin menu. Off by
751
+ * default; the host (Studio) reads it from the agent record and
752
+ * passes it through. Wired this way (not via the runtime) because
753
+ * the SDK has no notion of the agent's settings -- the host owns
754
+ * that domain.
755
+ */
756
+ deepResearchEnabled?: boolean;
734
757
  }
735
- declare function AgentChat({ adapter, agentId, sessionId, onSessionChange, onFileSelect, onMessagesChange, disabled, onComposerError, }: AgentChatProps): react_jsx_runtime.JSX.Element;
758
+ declare function AgentChat({ adapter, agentId, sessionId, onSessionChange, onFileSelect, onMessagesChange, disabled, onComposerError, deepResearchEnabled, }: AgentChatProps): react_jsx_runtime.JSX.Element;
736
759
 
737
760
  interface AgentChatAdapterContextValue {
738
761
  adapter: AgentChatAdapter;
@@ -818,6 +841,36 @@ declare function groupMissionTasksByBucket(tasks: AgentChatMissionTask[]): Recor
818
841
  */
819
842
  declare function deriveMissionWorkerActivityLabel(worker: AgentChatMissionWorker): string;
820
843
 
844
+ declare function ResearchSourcesPanel({ sources, }: {
845
+ sources: AgentChatResearchSource[];
846
+ }): react_jsx_runtime.JSX.Element;
847
+
848
+ type CitationSegment = {
849
+ kind: "text";
850
+ value: string;
851
+ } | {
852
+ kind: "cite";
853
+ value: string;
854
+ };
855
+ /**
856
+ * Split *text* into plain-text and citation segments.
857
+ *
858
+ * Comma-grouped markers expand into one ``cite`` segment per ID.
859
+ * Empty input returns an empty array. Invalid markers are passed
860
+ * through verbatim as ``text``.
861
+ */
862
+ declare function splitCitations(text: string): CitationSegment[];
863
+ /**
864
+ * Render *text* with each ``[S#]`` marker as a chip that links to the
865
+ * matching :class:`AgentChatResearchSource`. Hosts pass
866
+ * ``onCitationClick`` to scroll the sources panel to the entry.
867
+ */
868
+ declare function CitationText({ text, sources, onCitationClick, }: {
869
+ text: string;
870
+ sources: AgentChatResearchSource[];
871
+ onCitationClick?: (sourceId: string) => void;
872
+ }): react_jsx_runtime.JSX.Element;
873
+
821
874
  interface ScheduledWorkPanelProps {
822
875
  adapter: AgentChatAdapter;
823
876
  agentId?: string;
@@ -854,4 +907,4 @@ interface SessionTreePanelProps {
854
907
  }
855
908
  declare function SessionTreePanel({ adapter, sessionId, activeSessionId, agentId, title, sessionListLimit, hideRoot, hideHeader, loadList, onSessionSelect, onSessionDelete, }: SessionTreePanelProps): react_jsx_runtime.JSX.Element | null;
856
909
 
857
- export { ACTIVE_MISSION_STATUSES, AgentChat, type AgentChatAdapter, type AgentChatAdapterContextValue, AgentChatAdapterProvider, type AgentChatArtifactKind, type AgentChatArtifactMeta, type AgentChatArtifactPayload, type AgentChatAskUserQuestionAnswer, type AgentChatAskUserQuestionArgs, type AgentChatAskUserQuestionChoice, type AgentChatAskUserQuestionQuestion, type AgentChatAttachment, type AgentChatChartArtifactSpec, type AgentChatDisplayAttachment, type AgentChatErrorCategory, type AgentChatErrorInfo, type AgentChatEventStream, type AgentChatEventType, type AgentChatExpertFeedbackRating, type AgentChatHtmlArtifactSpec, type AgentChatImageAttachment, type AgentChatInboxEventStream, type AgentChatInboxItem, type AgentChatInboxKind, type AgentChatInboxList, type AgentChatInboxListInput, type AgentChatInboxStatus, type AgentChatInboxStreamEvent, type AgentChatMarkdownArtifactSpec, type AgentChatMessage, type AgentChatMessageStatus, type AgentChatMissionList, type AgentChatMissionStatus, type AgentChatMissionSummary, type AgentChatMissionTask, type AgentChatMissionWorker, type AgentChatPendingAttachment, type AgentChatProps, type AgentChatRole, type AgentChatRuntimeApi, type AgentChatRuntimeEvent, type AgentChatScheduledWorkItem, type AgentChatScheduledWorkKind, type AgentChatScheduledWorkList, type AgentChatSession, type AgentChatSessionList, type AgentChatSessionTree, type AgentChatSessionTreeNode, type AgentChatSlashCommand, type AgentChatSseMessageEvent, type AgentChatState, type AgentChatSvgArtifactSpec, type AgentChatSystemKind, type AgentChatTableArtifactSpec, type AgentChatTokenUsage, type AgentChatToolCallInfo, type AgentChatWorkspaceEntry, type AgentChatWorkspaceFile, type AgentChatWorkspaceTree, type AgentChatWorkspaceUpload, type ArtifactKind, type ArtifactPayload, type AskUserQuestionAnswer, type AskUserQuestionArgs, type AskUserQuestionChoice, type AskUserQuestionQuestion, type ChartArtifactSpec, type ChatComposerError, type ChatMessage, type ErrorInfo, type HtmlArtifactSpec, type InboxItem, type InboxList, InboxPanel, type InboxPanelProps, type InboxUnreadCountState, type MarkdownArtifactSpec, MessageResponse, type MessageResponseProps, MissionDashboard, type MissionDashboardProps, type MissionTaskBucket, MissionsPanel, type MissionsPanelProps, type RetryIndicator, type ScheduledWorkItem, type ScheduledWorkList, ScheduledWorkPanel, type ScheduledWorkPanelProps, type SessionTree, type SessionTreeNode, SessionTreePanel, type SessionTreePanelProps, type SvgArtifactSpec, type TableArtifactSpec, type TokenUsage, type ToolCallInfo, type WorkspaceEntry, type WorkspaceFile, type WorkspaceTree, type WorkspaceUpload, deriveMissionWorkerActivityLabel, groupMissionTasksByBucket, isTerminalMissionStatus, missionTaskBucket, useAgentChatAdapterContext, useAgentChatRuntime, useChatViewMode, useInboxUnreadCount };
910
+ export { ACTIVE_MISSION_STATUSES, AgentChat, type AgentChatAdapter, type AgentChatAdapterContextValue, AgentChatAdapterProvider, type AgentChatArtifactKind, type AgentChatArtifactMeta, type AgentChatArtifactPayload, type AgentChatAskUserQuestionAnswer, type AgentChatAskUserQuestionArgs, type AgentChatAskUserQuestionChoice, type AgentChatAskUserQuestionQuestion, type AgentChatAttachment, type AgentChatChartArtifactSpec, type AgentChatDisplayAttachment, type AgentChatErrorCategory, type AgentChatErrorInfo, type AgentChatEventStream, type AgentChatEventType, type AgentChatExpertFeedbackRating, type AgentChatHtmlArtifactSpec, type AgentChatImageAttachment, type AgentChatInboxEventStream, type AgentChatInboxItem, type AgentChatInboxKind, type AgentChatInboxList, type AgentChatInboxListInput, type AgentChatInboxStatus, type AgentChatInboxStreamEvent, type AgentChatMarkdownArtifactSpec, type AgentChatMessage, type AgentChatMessageStatus, type AgentChatMissionList, type AgentChatMissionStatus, type AgentChatMissionSummary, type AgentChatMissionTask, type AgentChatMissionWorker, type AgentChatPendingAttachment, type AgentChatProps, type AgentChatResearchSource, type AgentChatRole, type AgentChatRuntimeApi, type AgentChatRuntimeEvent, type AgentChatScheduledWorkItem, type AgentChatScheduledWorkKind, type AgentChatScheduledWorkList, type AgentChatSession, type AgentChatSessionList, type AgentChatSessionTree, type AgentChatSessionTreeNode, type AgentChatSlashCommand, type AgentChatSseMessageEvent, type AgentChatState, type AgentChatSvgArtifactSpec, type AgentChatSystemKind, type AgentChatTableArtifactSpec, type AgentChatTokenUsage, type AgentChatToolCallInfo, type AgentChatWorkspaceEntry, type AgentChatWorkspaceFile, type AgentChatWorkspaceTree, type AgentChatWorkspaceUpload, type ArtifactKind, type ArtifactPayload, type AskUserQuestionAnswer, type AskUserQuestionArgs, type AskUserQuestionChoice, type AskUserQuestionQuestion, type ChartArtifactSpec, type ChatComposerError, type ChatMessage, type CitationSegment, CitationText, type ErrorInfo, type HtmlArtifactSpec, type InboxItem, type InboxList, InboxPanel, type InboxPanelProps, type InboxUnreadCountState, type MarkdownArtifactSpec, MessageResponse, type MessageResponseProps, MissionDashboard, type MissionDashboardProps, type MissionTaskBucket, MissionsPanel, type MissionsPanelProps, ResearchSourcesPanel, type RetryIndicator, type ScheduledWorkItem, type ScheduledWorkList, ScheduledWorkPanel, type ScheduledWorkPanelProps, type SessionTree, type SessionTreeNode, SessionTreePanel, type SessionTreePanelProps, type SvgArtifactSpec, type TableArtifactSpec, type TokenUsage, type ToolCallInfo, type WorkspaceEntry, type WorkspaceFile, type WorkspaceTree, type WorkspaceUpload, deriveMissionWorkerActivityLabel, groupMissionTasksByBucket, isTerminalMissionStatus, missionTaskBucket, splitCitations, useAgentChatAdapterContext, useAgentChatRuntime, useChatViewMode, useInboxUnreadCount };
package/dist/index.js CHANGED
@@ -4216,6 +4216,51 @@ function DefaultToolBlock({ tc }) {
4216
4216
  ] })
4217
4217
  ] });
4218
4218
  }
4219
+ function ResearchOutlineBlock({ tc }) {
4220
+ const args = parseArgs(tc.args) ?? {};
4221
+ const result = tc.result ? parseArgs(tc.result) ?? {} : {};
4222
+ const outline = args.action === "set" ? args.outline ?? "" : result.outline ?? "";
4223
+ const sections = result.sections ?? [];
4224
+ return /* @__PURE__ */ jsxs("div", { className: "rounded-sm border border-border bg-muted/40 p-2 text-xs", children: [
4225
+ /* @__PURE__ */ jsxs("div", { className: "mb-1 font-semibold uppercase tracking-widest text-muted-foreground", children: [
4226
+ "Research outline",
4227
+ sections.length ? ` \xB7 ${sections.length} sections` : ""
4228
+ ] }),
4229
+ outline ? /* @__PURE__ */ jsx("pre", { className: "max-h-48 overflow-auto whitespace-pre-wrap font-mono text-[11px] leading-snug", children: outline }) : /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "updated" })
4230
+ ] });
4231
+ }
4232
+ function ResearchMemoryBlock({ tc }) {
4233
+ const args = parseArgs(tc.args) ?? {};
4234
+ const result = tc.result ? parseArgs(tc.result) ?? {} : {};
4235
+ let label;
4236
+ if (args.action === "add") {
4237
+ const host = args.url ? hostname(args.url) : "";
4238
+ label = `Recorded source ${result.source_id ?? ""}${host ? ` \xB7 ${host}` : ""}`;
4239
+ } else if (args.action === "retrieve") {
4240
+ const n = result.sources?.length ?? 0;
4241
+ label = `Retrieved ${n} source${n === 1 ? "" : "s"}${args.query ? ` for "${truncate2(args.query)}"` : ""}`;
4242
+ } else if (args.action === "list") {
4243
+ const n = result.sources?.length ?? 0;
4244
+ label = `Listed ${n} source${n === 1 ? "" : "s"}`;
4245
+ } else {
4246
+ label = "research_memory";
4247
+ }
4248
+ return /* @__PURE__ */ jsxs("div", { className: "text-xs text-muted-foreground", children: [
4249
+ /* @__PURE__ */ jsx("span", { className: "font-semibold text-foreground", children: "research" }),
4250
+ " ",
4251
+ label
4252
+ ] });
4253
+ }
4254
+ function hostname(url) {
4255
+ try {
4256
+ return new URL(url).hostname.replace(/^www\./, "");
4257
+ } catch {
4258
+ return url;
4259
+ }
4260
+ }
4261
+ function truncate2(s, n = 40) {
4262
+ return s.length > n ? `${s.slice(0, n)}\u2026` : s;
4263
+ }
4219
4264
  function ToolCallBlock({
4220
4265
  tc,
4221
4266
  resolvedArtifactName,
@@ -4268,6 +4313,10 @@ function ToolCallBlock({
4268
4313
  return /* @__PURE__ */ jsx(DelegateToolBlock, { tc });
4269
4314
  case "memory":
4270
4315
  return /* @__PURE__ */ jsx(MemoryToolBlock, { tc });
4316
+ case "research_outline":
4317
+ return /* @__PURE__ */ jsx(ResearchOutlineBlock, { tc });
4318
+ case "research_memory":
4319
+ return /* @__PURE__ */ jsx(ResearchMemoryBlock, { tc });
4271
4320
  case "spawn_worker":
4272
4321
  case "send_worker_message":
4273
4322
  case "stop_worker":
@@ -5792,6 +5841,7 @@ function ChatComposerInner({
5792
5841
  onToggleWorkspace,
5793
5842
  canShowBrowser = false,
5794
5843
  canShowWorkspace = false,
5844
+ deepResearchEnabled = false,
5795
5845
  viewMode = "simple",
5796
5846
  onViewModeChange
5797
5847
  }) {
@@ -5821,24 +5871,34 @@ function ChatComposerInner({
5821
5871
  }
5822
5872
  }, [adapter, showSlashMenu, menuMode]);
5823
5873
  const builtinCommands = useMemo(
5824
- () => [
5825
- { value: "/clear", label: "/clear", description: "Clear conversation" },
5826
- { value: "/compress", label: "/compress", description: "Compress context" },
5827
- { value: "/goal", label: "/goal", description: "Define an outcome goal" },
5828
- { value: "/goal status", label: "/goal status", description: "Show outcome goal status" },
5829
- { value: "/goal pause", label: "/goal pause", description: "Pause automatic goal continuation" },
5830
- { value: "/goal resume", label: "/goal resume", description: "Resume a paused goal" },
5831
- { value: "/goal clear", label: "/goal clear", description: "Clear the current goal" },
5832
- { value: "/mission ", label: "/mission", description: "Start an orchestrated rubric-judged mission" },
5833
- { value: "/mission status", label: "/mission status", description: "Show current mission status" },
5834
- { value: "/mission pause", label: "/mission pause", description: "Pause the mission evaluator" },
5835
- { value: "/mission resume", label: "/mission resume", description: "Resume a paused mission" },
5836
- { value: "/mission cancel", label: "/mission cancel", description: "Cancel the mission" },
5837
- { value: "/loop", label: "/loop", description: "Schedule recurring prompt" },
5838
- { value: "/loop list", label: "/loop list", description: "List active loops" },
5839
- { value: "/loop cancel", label: "/loop cancel", description: "Cancel a loop by ID" }
5840
- ],
5841
- []
5874
+ () => {
5875
+ const base = [
5876
+ { value: "/clear", label: "/clear", description: "Clear conversation" },
5877
+ { value: "/compress", label: "/compress", description: "Compress context" },
5878
+ { value: "/goal", label: "/goal", description: "Define an outcome goal" },
5879
+ { value: "/goal status", label: "/goal status", description: "Show outcome goal status" },
5880
+ { value: "/goal pause", label: "/goal pause", description: "Pause automatic goal continuation" },
5881
+ { value: "/goal resume", label: "/goal resume", description: "Resume a paused goal" },
5882
+ { value: "/goal clear", label: "/goal clear", description: "Clear the current goal" },
5883
+ { value: "/mission ", label: "/mission", description: "Start an orchestrated rubric-judged mission" },
5884
+ { value: "/mission status", label: "/mission status", description: "Show current mission status" },
5885
+ { value: "/mission pause", label: "/mission pause", description: "Pause the mission evaluator" },
5886
+ { value: "/mission resume", label: "/mission resume", description: "Resume a paused mission" },
5887
+ { value: "/mission cancel", label: "/mission cancel", description: "Cancel the mission" },
5888
+ { value: "/loop", label: "/loop", description: "Schedule recurring prompt" },
5889
+ { value: "/loop list", label: "/loop list", description: "List active loops" },
5890
+ { value: "/loop cancel", label: "/loop cancel", description: "Cancel a loop by ID" }
5891
+ ];
5892
+ if (deepResearchEnabled) {
5893
+ base.push({
5894
+ value: "/deep-research ",
5895
+ label: "/deep-research",
5896
+ description: "Delegate a topic to the deep-research workflow"
5897
+ });
5898
+ }
5899
+ return base;
5900
+ },
5901
+ [deepResearchEnabled]
5842
5902
  );
5843
5903
  const scheduledExamples = useMemo(
5844
5904
  () => [
@@ -8503,11 +8563,11 @@ function extractToolDetail(tc) {
8503
8563
  }
8504
8564
  case "terminal": {
8505
8565
  const cmd = stringArg("command");
8506
- return cmd ? truncate2(cmd, 40) : null;
8566
+ return cmd ? truncate3(cmd, 40) : null;
8507
8567
  }
8508
8568
  case "execute_code": {
8509
8569
  const code3 = stringArg("code");
8510
- return code3 ? truncate2(code3.split("\n")[0] ?? "", 40) : null;
8570
+ return code3 ? truncate3(code3.split("\n")[0] ?? "", 40) : null;
8511
8571
  }
8512
8572
  case "web_search":
8513
8573
  case "web_crawl":
@@ -8532,7 +8592,7 @@ function lastPathSegment(path) {
8532
8592
  const idx = cleaned.lastIndexOf("/");
8533
8593
  return idx >= 0 ? cleaned.slice(idx + 1) : cleaned;
8534
8594
  }
8535
- function truncate2(s, max) {
8595
+ function truncate3(s, max) {
8536
8596
  return s.length > max ? `${s.slice(0, max - 1)}\u2026` : s;
8537
8597
  }
8538
8598
  var _SIMPLE_MODE_HIDDEN_TOOLS = /* @__PURE__ */ new Set([
@@ -9033,7 +9093,8 @@ function ChatThread({
9033
9093
  canShowBrowser = false,
9034
9094
  canShowWorkspace = false,
9035
9095
  viewMode = "simple",
9036
- onViewModeChange
9096
+ onViewModeChange,
9097
+ deepResearchEnabled = false
9037
9098
  }) {
9038
9099
  const groups = useMemo(() => groupMessages(messages), [messages]);
9039
9100
  const awaitingInput = useMemo(() => isAwaitingUserInput(messages), [messages]);
@@ -9166,12 +9227,51 @@ function ChatThread({
9166
9227
  canShowBrowser,
9167
9228
  canShowWorkspace,
9168
9229
  viewMode,
9169
- onViewModeChange
9230
+ onViewModeChange,
9231
+ deepResearchEnabled
9170
9232
  }
9171
9233
  )
9172
9234
  ] })
9173
9235
  ] });
9174
9236
  }
9237
+ function ResearchSourcesPanel({
9238
+ sources
9239
+ }) {
9240
+ if (sources.length === 0) {
9241
+ return /* @__PURE__ */ jsx("div", { className: "p-3 text-xs text-muted-foreground", children: "No research sources yet. Sources appear here as the deep-research agent curates evidence." });
9242
+ }
9243
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 p-2", children: [
9244
+ /* @__PURE__ */ jsxs("div", { className: "px-1 pb-1 text-[10px] font-semibold uppercase tracking-widest text-muted-foreground", children: [
9245
+ "Sources \xB7 ",
9246
+ sources.length
9247
+ ] }),
9248
+ sources.map((s) => /* @__PURE__ */ jsxs(
9249
+ "a",
9250
+ {
9251
+ id: `source-${s.sourceId}`,
9252
+ href: s.url,
9253
+ target: "_blank",
9254
+ rel: "noreferrer",
9255
+ className: "group flex items-baseline gap-2 rounded-sm px-1 py-1 hover:bg-muted",
9256
+ children: [
9257
+ /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[10px] font-semibold text-primary", children: s.sourceId }),
9258
+ /* @__PURE__ */ jsxs("span", { className: "flex flex-col overflow-hidden", children: [
9259
+ /* @__PURE__ */ jsx("span", { className: "truncate text-xs text-foreground group-hover:underline", children: s.title || s.url }),
9260
+ /* @__PURE__ */ jsx("span", { className: "truncate text-[10px] text-muted-foreground", children: hostname2(s.url) })
9261
+ ] })
9262
+ ]
9263
+ },
9264
+ s.sourceId
9265
+ ))
9266
+ ] });
9267
+ }
9268
+ function hostname2(url) {
9269
+ try {
9270
+ return new URL(url).hostname.replace(/^www\./, "");
9271
+ } catch {
9272
+ return url;
9273
+ }
9274
+ }
9175
9275
  var noop = () => {
9176
9276
  };
9177
9277
  var FileTreeContext = createContext({
@@ -9909,7 +10009,8 @@ function createInitialAgentChatState(options = {}) {
9909
10009
  terminal: false,
9910
10010
  workspaceRefreshKey: 0,
9911
10011
  browser: null,
9912
- viewMode: options.viewMode ?? "simple"
10012
+ viewMode: options.viewMode ?? "simple",
10013
+ researchSources: []
9913
10014
  };
9914
10015
  }
9915
10016
  function applyAgentChatEvent(state, event) {
@@ -9995,11 +10096,12 @@ function applyAgentChatEvent(state, event) {
9995
10096
  const toolName = findToolNameById(nextState.messages, toolCallId);
9996
10097
  const messages = applyToolResult(nextState.messages, event.data);
9997
10098
  const mutatesWorkspace = toolName !== null && WORKSPACE_MUTATING_TOOLS.has(toolName);
9998
- return {
10099
+ const withResult = {
9999
10100
  ...nextState,
10000
10101
  messages,
10001
10102
  workspaceRefreshKey: mutatesWorkspace ? nextState.workspaceRefreshKey + 1 : nextState.workspaceRefreshKey
10002
10103
  };
10104
+ return collectResearchSource(withResult, toolName, event.data);
10003
10105
  }
10004
10106
  case "harness.wake":
10005
10107
  case "llm.request":
@@ -10731,6 +10833,32 @@ function findToolNameById(messages, toolCallId) {
10731
10833
  }
10732
10834
  return null;
10733
10835
  }
10836
+ function collectResearchSource(state, toolName, data) {
10837
+ if (toolName !== "research_memory") return state;
10838
+ const rawResult = data.content ?? data.result;
10839
+ const resultText = typeof rawResult === "string" ? rawResult : JSON.stringify(rawResult ?? {});
10840
+ let parsed;
10841
+ try {
10842
+ parsed = JSON.parse(resultText);
10843
+ } catch {
10844
+ return state;
10845
+ }
10846
+ if (!parsed.success || !parsed.source_id || !parsed.url) return state;
10847
+ if (state.researchSources.some((s) => s.sourceId === parsed.source_id)) {
10848
+ return state;
10849
+ }
10850
+ return {
10851
+ ...state,
10852
+ researchSources: [
10853
+ ...state.researchSources,
10854
+ {
10855
+ sourceId: parsed.source_id,
10856
+ url: parsed.url,
10857
+ title: parsed.title ?? ""
10858
+ }
10859
+ ]
10860
+ };
10861
+ }
10734
10862
  function findLatestConsultExpertCall(messages) {
10735
10863
  for (let i = messages.length - 1; i >= 0; i--) {
10736
10864
  const msg = messages[i];
@@ -11180,7 +11308,8 @@ function useAgentChatRuntime({
11180
11308
  markSending,
11181
11309
  markSendError,
11182
11310
  viewMode: state.viewMode,
11183
- setViewMode
11311
+ setViewMode,
11312
+ researchSources: state.researchSources
11184
11313
  };
11185
11314
  }
11186
11315
  function parseEventData(data) {
@@ -11239,7 +11368,8 @@ function AgentChat({
11239
11368
  onFileSelect,
11240
11369
  onMessagesChange,
11241
11370
  disabled,
11242
- onComposerError
11371
+ onComposerError,
11372
+ deepResearchEnabled = false
11243
11373
  }) {
11244
11374
  const [workspacePath, setWorkspacePath] = useState(null);
11245
11375
  const [mobileView, setMobileView] = useState("chat");
@@ -11262,7 +11392,8 @@ function AgentChat({
11262
11392
  const browserVisible = browserAvailable && showBrowser;
11263
11393
  const workspaceAvailable = !!sessionId;
11264
11394
  const workspaceVisible = workspaceAvailable && showWorkspace;
11265
- const rightStackVisible = browserVisible || workspaceVisible;
11395
+ const sourcesVisible = runtime.researchSources.length > 0;
11396
+ const rightStackVisible = browserVisible || workspaceVisible || sourcesVisible;
11266
11397
  const bothPanesVisible = browserVisible && workspaceVisible;
11267
11398
  useEffect(() => {
11268
11399
  onMessagesChange?.(runtime.messages);
@@ -11377,7 +11508,8 @@ function AgentChat({
11377
11508
  canShowBrowser: browserAvailable,
11378
11509
  canShowWorkspace: workspaceAvailable,
11379
11510
  viewMode: runtime.viewMode,
11380
- onViewModeChange: runtime.setViewMode
11511
+ onViewModeChange: runtime.setViewMode,
11512
+ deepResearchEnabled
11381
11513
  }
11382
11514
  )
11383
11515
  }
@@ -11437,6 +11569,20 @@ function AgentChat({
11437
11569
  }
11438
11570
  )
11439
11571
  }
11572
+ ),
11573
+ sourcesVisible && /* @__PURE__ */ jsx(
11574
+ "div",
11575
+ {
11576
+ "data-testid": "research-sources-panel-frame",
11577
+ className: cn(
11578
+ "min-h-0 w-full overflow-auto",
11579
+ // When other panes share the stack the sources
11580
+ // panel takes a fixed minimum so the source rows
11581
+ // stay readable; otherwise it fills the column.
11582
+ browserVisible || workspaceVisible ? "max-h-1/3 border-t border-line" : "h-full"
11583
+ ),
11584
+ children: /* @__PURE__ */ jsx(ResearchSourcesPanel, { sources: runtime.researchSources })
11585
+ }
11440
11586
  )
11441
11587
  ]
11442
11588
  }
@@ -12182,7 +12328,7 @@ function groupMissionTasksByBucket(tasks) {
12182
12328
  function deriveMissionWorkerActivityLabel(worker) {
12183
12329
  const kind = worker.latestEventKind;
12184
12330
  if (kind === "tool.call" && worker.latestEventSummary) {
12185
- return `tool: ${truncate3(worker.latestEventSummary, 80)}`;
12331
+ return `tool: ${truncate4(worker.latestEventSummary, 80)}`;
12186
12332
  }
12187
12333
  if (kind === "llm.response") {
12188
12334
  return "thinking";
@@ -12191,11 +12337,11 @@ function deriveMissionWorkerActivityLabel(worker) {
12191
12337
  return "received tool result";
12192
12338
  }
12193
12339
  if (kind && worker.latestEventSummary) {
12194
- return `${kind}: ${truncate3(worker.latestEventSummary, 60)}`;
12340
+ return `${kind}: ${truncate4(worker.latestEventSummary, 60)}`;
12195
12341
  }
12196
12342
  return worker.sessionStatus || "active";
12197
12343
  }
12198
- function truncate3(s, max) {
12344
+ function truncate4(s, max) {
12199
12345
  if (s.length <= max) return s;
12200
12346
  return `${s.slice(0, max - 1)}\u2026`;
12201
12347
  }
@@ -13182,6 +13328,50 @@ function MissionsPanel({
13182
13328
  )) })
13183
13329
  ] });
13184
13330
  }
13331
+ var CITATION_RE = /\[(S\d+(?:\s*,\s*S\d+)*)\]/g;
13332
+ function splitCitations(text) {
13333
+ if (!text) return [];
13334
+ const segments = [];
13335
+ let lastIndex = 0;
13336
+ for (const match of text.matchAll(CITATION_RE)) {
13337
+ const start = match.index ?? 0;
13338
+ if (start > lastIndex) {
13339
+ segments.push({ kind: "text", value: text.slice(lastIndex, start) });
13340
+ }
13341
+ for (const id of match[1].split(",")) {
13342
+ segments.push({ kind: "cite", value: id.trim() });
13343
+ }
13344
+ lastIndex = start + match[0].length;
13345
+ }
13346
+ if (lastIndex < text.length) {
13347
+ segments.push({ kind: "text", value: text.slice(lastIndex) });
13348
+ }
13349
+ return segments;
13350
+ }
13351
+ function CitationText({
13352
+ text,
13353
+ sources,
13354
+ onCitationClick
13355
+ }) {
13356
+ const byId = new Map(sources.map((s) => [s.sourceId, s]));
13357
+ return /* @__PURE__ */ jsx(Fragment, { children: splitCitations(text).map((seg, i) => {
13358
+ if (seg.kind === "text") {
13359
+ return /* @__PURE__ */ jsx("span", { children: seg.value }, i);
13360
+ }
13361
+ const src = byId.get(seg.value);
13362
+ return /* @__PURE__ */ jsx(
13363
+ "button",
13364
+ {
13365
+ type: "button",
13366
+ title: src ? `${src.title} \u2014 ${src.url}` : seg.value,
13367
+ onClick: () => onCitationClick?.(seg.value),
13368
+ className: "mx-0.5 inline-flex items-center rounded-sm bg-muted px-1 text-[10px] font-semibold text-primary hover:bg-primary/10",
13369
+ children: seg.value
13370
+ },
13371
+ i
13372
+ );
13373
+ }) });
13374
+ }
13185
13375
  var DEFAULT_LIMIT2 = 50;
13186
13376
  var DEFAULT_POLL_INTERVAL_MS3 = 3e4;
13187
13377
  function fingerprint2(items) {
@@ -13855,6 +14045,6 @@ function SessionTreePanel({
13855
14045
  ] });
13856
14046
  }
13857
14047
 
13858
- export { ACTIVE_MISSION_STATUSES, AgentChat, AgentChatAdapterProvider, InboxPanel, MessageResponse, MissionDashboard, MissionsPanel, ScheduledWorkPanel, SessionTreePanel, deriveMissionWorkerActivityLabel, groupMissionTasksByBucket, isTerminalMissionStatus, missionTaskBucket, useAgentChatAdapterContext, useAgentChatRuntime, useChatViewMode, useInboxUnreadCount };
14048
+ export { ACTIVE_MISSION_STATUSES, AgentChat, AgentChatAdapterProvider, CitationText, InboxPanel, MessageResponse, MissionDashboard, MissionsPanel, ResearchSourcesPanel, ScheduledWorkPanel, SessionTreePanel, deriveMissionWorkerActivityLabel, groupMissionTasksByBucket, isTerminalMissionStatus, missionTaskBucket, splitCitations, useAgentChatAdapterContext, useAgentChatRuntime, useChatViewMode, useInboxUnreadCount };
13859
14049
  //# sourceMappingURL=index.js.map
13860
14050
  //# sourceMappingURL=index.js.map