@optilogic/chat 1.3.3 → 1.3.4
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.cjs +184 -179
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +43 -2
- package/dist/index.d.ts +43 -2
- package/dist/index.js +184 -180
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/components/agent-response/hooks/useAgentResponseAccumulator.ts +6 -216
- package/src/components/agent-response/index.ts +3 -0
- package/src/components/agent-response/reducer.ts +252 -0
- package/src/components/agent-response/types.ts +8 -0
- package/src/index.ts +3 -0
package/dist/index.d.cts
CHANGED
|
@@ -197,6 +197,14 @@ interface AgentMessage {
|
|
|
197
197
|
message?: string;
|
|
198
198
|
/** Alternative content field */
|
|
199
199
|
content?: string;
|
|
200
|
+
/**
|
|
201
|
+
* Optional event timestamp (epoch ms). When supplied, the reducer uses this
|
|
202
|
+
* for the item's `timestamp` and any state-level timing fields it sets
|
|
203
|
+
* (`firstMessageTime`, `thinkingStartTime`, `responseCompleteTime`) instead
|
|
204
|
+
* of `Date.now()`. Provide this when replaying historical events so durations
|
|
205
|
+
* reflect the original run rather than load time.
|
|
206
|
+
*/
|
|
207
|
+
timestamp?: number;
|
|
200
208
|
/** For status messages */
|
|
201
209
|
status?: string;
|
|
202
210
|
/** Agent name (multi-agent scenarios) */
|
|
@@ -672,7 +680,10 @@ declare function useThinkingTimer({ startTime, endTime, status, }: UseThinkingTi
|
|
|
672
680
|
/**
|
|
673
681
|
* useAgentResponseAccumulator Hook
|
|
674
682
|
*
|
|
675
|
-
* Accumulates agent response messages into a unified state
|
|
683
|
+
* Accumulates agent response messages into a unified state.
|
|
684
|
+
*
|
|
685
|
+
* Thin wrapper around `reduceAgentMessage` — the pure reducer can be used
|
|
686
|
+
* directly outside React for replaying historical events.
|
|
676
687
|
*/
|
|
677
688
|
|
|
678
689
|
interface UseAgentResponseAccumulatorOptions {
|
|
@@ -700,6 +711,36 @@ interface UseAgentResponseAccumulatorReturn {
|
|
|
700
711
|
*/
|
|
701
712
|
declare function useAgentResponseAccumulator(options?: UseAgentResponseAccumulatorOptions): UseAgentResponseAccumulatorReturn;
|
|
702
713
|
|
|
714
|
+
/**
|
|
715
|
+
* Pure reducer for agent response messages.
|
|
716
|
+
*
|
|
717
|
+
* Used by `useAgentResponseAccumulator` for live streaming, and exported so
|
|
718
|
+
* non-React callers (e.g. server-side or store-based replay of historical
|
|
719
|
+
* conversations) can rebuild the same `AgentResponseState` from a sequence of
|
|
720
|
+
* `AgentMessage` events without rendering a component.
|
|
721
|
+
*
|
|
722
|
+
* Replay note on stable IDs: when a payload omits a per-item id
|
|
723
|
+
* (`tool.id`, `thinkingStep.id`, `knowledge.id`, `memory.id`,
|
|
724
|
+
* `statusUpdate.id`), the reducer falls back to `${type}-${Date.now()}`. That
|
|
725
|
+
* is fine for live streams but will produce different React keys on each
|
|
726
|
+
* replay. Callers reconstructing `AgentMessage` events from persisted rows
|
|
727
|
+
* should populate these ids from a stable source (e.g. the supplement-row
|
|
728
|
+
* primary key) so timeline keys remain consistent across reloads.
|
|
729
|
+
*/
|
|
730
|
+
|
|
731
|
+
/**
|
|
732
|
+
* Pure reducer: apply a single `AgentMessage` to the accumulated state.
|
|
733
|
+
*
|
|
734
|
+
* `payload.timestamp` (epoch ms), if supplied, is used for the new item's
|
|
735
|
+
* `timestamp` and any state-level timing fields this call sets
|
|
736
|
+
* (`firstMessageTime`, `thinkingStartTime`, `responseCompleteTime`). When
|
|
737
|
+
* absent, `Date.now()` is used — matching the prior live-streaming behaviour.
|
|
738
|
+
*
|
|
739
|
+
* @example
|
|
740
|
+
* const state = events.reduce(reduceAgentMessage, initialAgentResponseState);
|
|
741
|
+
*/
|
|
742
|
+
declare function reduceAgentMessage(prev: AgentResponseState, payload: AgentMessage): AgentResponseState;
|
|
743
|
+
|
|
703
744
|
/**
|
|
704
745
|
* Agent Response Utility Functions
|
|
705
746
|
*/
|
|
@@ -938,4 +979,4 @@ declare function parseResponseSegments(text: string): ResponseSegment[];
|
|
|
938
979
|
*/
|
|
939
980
|
declare const INLINE_ACTION_PROMPT = "\n<inline_actions>\nWhen your response should include interactive components (like query viewers,\ndata tables, or executable actions), embed them as fenced code blocks using\nthe `json:action` language tag:\n\n```json:action\n{\n \"type\": \"action-type-here\",\n ...action-specific fields\n}\n```\n\nRules:\n- Each block must contain valid JSON with a \"type\" field.\n- The \"type\" must match a registered action component on the frontend.\n- Multiple action blocks per response are allowed.\n- Surround action blocks with normal markdown text for user context.\n- The action block is rendered as an interactive component in the chat UI.\n- SQL strings inside JSON must be properly escaped (newlines as \\n, quotes as \\\").\n\nAvailable action types:\n\n- \"optimap-query\": Displays SQL queries with a button to execute them and\n update the 3D globe map.\n Required fields:\n - type: \"optimap-query\"\n - locations_sql: string (the validated locations SQL query)\n - routes_sql: string (the validated routes SQL query)\n - database_name: string (the target database name)\n</inline_actions>\n";
|
|
940
981
|
|
|
941
|
-
export { ActionBar, type ActionBarProps, type ActionComponentRegistry, ActionMarkdownRenderer, type ActionMarkdownRendererProps, type ActionSegment, ActivityIndicators, type ActivityIndicatorsProps, type AgentMessage, AgentResponse, type AgentResponseProps, type AgentResponseState, type AgentResponseStatus, type AgentRun, AgentTimeline, type DisplayEntry, type FeedbackValue, type GenericWebSocketMessage, type HITLInteraction, HITLInteractionRecord, type HITLInteractionRecordProps, type HITLQuestion, HITLQuestionPanel, type HITLQuestionPanelProps, type HITLResponseData, HITLSection, type HITLSectionProps, INLINE_ACTION_PROMPT, type InlineActionProps, type KnowledgeItem, type MarkdownSegment, type MemoryItem, MetadataRow, type MetadataRowProps, type PotentialResponse, type ResponseSegment, type StatusItem, type ThinkingContent, ThinkingSection, type ThinkingSectionProps, type ThinkingStep, type TimelineEntry, type TimelineEntryType, type TimelineUIState, type ToolCall, TruncatedMessage, type TruncatedMessageProps, type UseAgentResponseAccumulatorOptions, type UseAgentResponseAccumulatorReturn, type UseThinkingTimerOptions, UserPrompt, UserPromptInput, type UserPromptInputProps, type UserPromptInputRef, type UserPromptProps, buildResponseString, buildTimelineEntries, createTimelineUIState, deduplicateEntries, formatTime, formatTotalTime, groupIntoAgentRuns, initialAgentResponseState, parseResponseSegments, useAgentResponseAccumulator, useThinkingTimer };
|
|
982
|
+
export { ActionBar, type ActionBarProps, type ActionComponentRegistry, ActionMarkdownRenderer, type ActionMarkdownRendererProps, type ActionSegment, ActivityIndicators, type ActivityIndicatorsProps, type AgentMessage, AgentResponse, type AgentResponseProps, type AgentResponseState, type AgentResponseStatus, type AgentRun, AgentTimeline, type DisplayEntry, type FeedbackValue, type GenericWebSocketMessage, type HITLInteraction, HITLInteractionRecord, type HITLInteractionRecordProps, type HITLQuestion, HITLQuestionPanel, type HITLQuestionPanelProps, type HITLResponseData, HITLSection, type HITLSectionProps, INLINE_ACTION_PROMPT, type InlineActionProps, type KnowledgeItem, type MarkdownSegment, type MemoryItem, MetadataRow, type MetadataRowProps, type PotentialResponse, type ResponseSegment, type StatusItem, type ThinkingContent, ThinkingSection, type ThinkingSectionProps, type ThinkingStep, type TimelineEntry, type TimelineEntryType, type TimelineUIState, type ToolCall, TruncatedMessage, type TruncatedMessageProps, type UseAgentResponseAccumulatorOptions, type UseAgentResponseAccumulatorReturn, type UseThinkingTimerOptions, UserPrompt, UserPromptInput, type UserPromptInputProps, type UserPromptInputRef, type UserPromptProps, buildResponseString, buildTimelineEntries, createTimelineUIState, deduplicateEntries, formatTime, formatTotalTime, groupIntoAgentRuns, initialAgentResponseState, parseResponseSegments, reduceAgentMessage, useAgentResponseAccumulator, useThinkingTimer };
|
package/dist/index.d.ts
CHANGED
|
@@ -197,6 +197,14 @@ interface AgentMessage {
|
|
|
197
197
|
message?: string;
|
|
198
198
|
/** Alternative content field */
|
|
199
199
|
content?: string;
|
|
200
|
+
/**
|
|
201
|
+
* Optional event timestamp (epoch ms). When supplied, the reducer uses this
|
|
202
|
+
* for the item's `timestamp` and any state-level timing fields it sets
|
|
203
|
+
* (`firstMessageTime`, `thinkingStartTime`, `responseCompleteTime`) instead
|
|
204
|
+
* of `Date.now()`. Provide this when replaying historical events so durations
|
|
205
|
+
* reflect the original run rather than load time.
|
|
206
|
+
*/
|
|
207
|
+
timestamp?: number;
|
|
200
208
|
/** For status messages */
|
|
201
209
|
status?: string;
|
|
202
210
|
/** Agent name (multi-agent scenarios) */
|
|
@@ -672,7 +680,10 @@ declare function useThinkingTimer({ startTime, endTime, status, }: UseThinkingTi
|
|
|
672
680
|
/**
|
|
673
681
|
* useAgentResponseAccumulator Hook
|
|
674
682
|
*
|
|
675
|
-
* Accumulates agent response messages into a unified state
|
|
683
|
+
* Accumulates agent response messages into a unified state.
|
|
684
|
+
*
|
|
685
|
+
* Thin wrapper around `reduceAgentMessage` — the pure reducer can be used
|
|
686
|
+
* directly outside React for replaying historical events.
|
|
676
687
|
*/
|
|
677
688
|
|
|
678
689
|
interface UseAgentResponseAccumulatorOptions {
|
|
@@ -700,6 +711,36 @@ interface UseAgentResponseAccumulatorReturn {
|
|
|
700
711
|
*/
|
|
701
712
|
declare function useAgentResponseAccumulator(options?: UseAgentResponseAccumulatorOptions): UseAgentResponseAccumulatorReturn;
|
|
702
713
|
|
|
714
|
+
/**
|
|
715
|
+
* Pure reducer for agent response messages.
|
|
716
|
+
*
|
|
717
|
+
* Used by `useAgentResponseAccumulator` for live streaming, and exported so
|
|
718
|
+
* non-React callers (e.g. server-side or store-based replay of historical
|
|
719
|
+
* conversations) can rebuild the same `AgentResponseState` from a sequence of
|
|
720
|
+
* `AgentMessage` events without rendering a component.
|
|
721
|
+
*
|
|
722
|
+
* Replay note on stable IDs: when a payload omits a per-item id
|
|
723
|
+
* (`tool.id`, `thinkingStep.id`, `knowledge.id`, `memory.id`,
|
|
724
|
+
* `statusUpdate.id`), the reducer falls back to `${type}-${Date.now()}`. That
|
|
725
|
+
* is fine for live streams but will produce different React keys on each
|
|
726
|
+
* replay. Callers reconstructing `AgentMessage` events from persisted rows
|
|
727
|
+
* should populate these ids from a stable source (e.g. the supplement-row
|
|
728
|
+
* primary key) so timeline keys remain consistent across reloads.
|
|
729
|
+
*/
|
|
730
|
+
|
|
731
|
+
/**
|
|
732
|
+
* Pure reducer: apply a single `AgentMessage` to the accumulated state.
|
|
733
|
+
*
|
|
734
|
+
* `payload.timestamp` (epoch ms), if supplied, is used for the new item's
|
|
735
|
+
* `timestamp` and any state-level timing fields this call sets
|
|
736
|
+
* (`firstMessageTime`, `thinkingStartTime`, `responseCompleteTime`). When
|
|
737
|
+
* absent, `Date.now()` is used — matching the prior live-streaming behaviour.
|
|
738
|
+
*
|
|
739
|
+
* @example
|
|
740
|
+
* const state = events.reduce(reduceAgentMessage, initialAgentResponseState);
|
|
741
|
+
*/
|
|
742
|
+
declare function reduceAgentMessage(prev: AgentResponseState, payload: AgentMessage): AgentResponseState;
|
|
743
|
+
|
|
703
744
|
/**
|
|
704
745
|
* Agent Response Utility Functions
|
|
705
746
|
*/
|
|
@@ -938,4 +979,4 @@ declare function parseResponseSegments(text: string): ResponseSegment[];
|
|
|
938
979
|
*/
|
|
939
980
|
declare const INLINE_ACTION_PROMPT = "\n<inline_actions>\nWhen your response should include interactive components (like query viewers,\ndata tables, or executable actions), embed them as fenced code blocks using\nthe `json:action` language tag:\n\n```json:action\n{\n \"type\": \"action-type-here\",\n ...action-specific fields\n}\n```\n\nRules:\n- Each block must contain valid JSON with a \"type\" field.\n- The \"type\" must match a registered action component on the frontend.\n- Multiple action blocks per response are allowed.\n- Surround action blocks with normal markdown text for user context.\n- The action block is rendered as an interactive component in the chat UI.\n- SQL strings inside JSON must be properly escaped (newlines as \\n, quotes as \\\").\n\nAvailable action types:\n\n- \"optimap-query\": Displays SQL queries with a button to execute them and\n update the 3D globe map.\n Required fields:\n - type: \"optimap-query\"\n - locations_sql: string (the validated locations SQL query)\n - routes_sql: string (the validated routes SQL query)\n - database_name: string (the target database name)\n</inline_actions>\n";
|
|
940
981
|
|
|
941
|
-
export { ActionBar, type ActionBarProps, type ActionComponentRegistry, ActionMarkdownRenderer, type ActionMarkdownRendererProps, type ActionSegment, ActivityIndicators, type ActivityIndicatorsProps, type AgentMessage, AgentResponse, type AgentResponseProps, type AgentResponseState, type AgentResponseStatus, type AgentRun, AgentTimeline, type DisplayEntry, type FeedbackValue, type GenericWebSocketMessage, type HITLInteraction, HITLInteractionRecord, type HITLInteractionRecordProps, type HITLQuestion, HITLQuestionPanel, type HITLQuestionPanelProps, type HITLResponseData, HITLSection, type HITLSectionProps, INLINE_ACTION_PROMPT, type InlineActionProps, type KnowledgeItem, type MarkdownSegment, type MemoryItem, MetadataRow, type MetadataRowProps, type PotentialResponse, type ResponseSegment, type StatusItem, type ThinkingContent, ThinkingSection, type ThinkingSectionProps, type ThinkingStep, type TimelineEntry, type TimelineEntryType, type TimelineUIState, type ToolCall, TruncatedMessage, type TruncatedMessageProps, type UseAgentResponseAccumulatorOptions, type UseAgentResponseAccumulatorReturn, type UseThinkingTimerOptions, UserPrompt, UserPromptInput, type UserPromptInputProps, type UserPromptInputRef, type UserPromptProps, buildResponseString, buildTimelineEntries, createTimelineUIState, deduplicateEntries, formatTime, formatTotalTime, groupIntoAgentRuns, initialAgentResponseState, parseResponseSegments, useAgentResponseAccumulator, useThinkingTimer };
|
|
982
|
+
export { ActionBar, type ActionBarProps, type ActionComponentRegistry, ActionMarkdownRenderer, type ActionMarkdownRendererProps, type ActionSegment, ActivityIndicators, type ActivityIndicatorsProps, type AgentMessage, AgentResponse, type AgentResponseProps, type AgentResponseState, type AgentResponseStatus, type AgentRun, AgentTimeline, type DisplayEntry, type FeedbackValue, type GenericWebSocketMessage, type HITLInteraction, HITLInteractionRecord, type HITLInteractionRecordProps, type HITLQuestion, HITLQuestionPanel, type HITLQuestionPanelProps, type HITLResponseData, HITLSection, type HITLSectionProps, INLINE_ACTION_PROMPT, type InlineActionProps, type KnowledgeItem, type MarkdownSegment, type MemoryItem, MetadataRow, type MetadataRowProps, type PotentialResponse, type ResponseSegment, type StatusItem, type ThinkingContent, ThinkingSection, type ThinkingSectionProps, type ThinkingStep, type TimelineEntry, type TimelineEntryType, type TimelineUIState, type ToolCall, TruncatedMessage, type TruncatedMessageProps, type UseAgentResponseAccumulatorOptions, type UseAgentResponseAccumulatorReturn, type UseThinkingTimerOptions, UserPrompt, UserPromptInput, type UserPromptInputProps, type UserPromptInputRef, type UserPromptProps, buildResponseString, buildTimelineEntries, createTimelineUIState, deduplicateEntries, formatTime, formatTotalTime, groupIntoAgentRuns, initialAgentResponseState, parseResponseSegments, reduceAgentMessage, useAgentResponseAccumulator, useThinkingTimer };
|
package/dist/index.js
CHANGED
|
@@ -824,6 +824,188 @@ function deduplicateEntries(entries) {
|
|
|
824
824
|
return result;
|
|
825
825
|
}
|
|
826
826
|
|
|
827
|
+
// src/components/agent-response/reducer.ts
|
|
828
|
+
function reduceAgentMessage(prev, payload) {
|
|
829
|
+
const now = payload.timestamp ?? Date.now();
|
|
830
|
+
let newStatus = prev.status;
|
|
831
|
+
const isFirstMessage = prev.status === "idle" && payload.type !== "status";
|
|
832
|
+
if (isFirstMessage) {
|
|
833
|
+
newStatus = "processing";
|
|
834
|
+
}
|
|
835
|
+
const firstMessageTime = prev.firstMessageTime ?? (isFirstMessage ? now : null);
|
|
836
|
+
switch (payload.type) {
|
|
837
|
+
case "status":
|
|
838
|
+
if (payload.message === "Harness connected" || payload.status === "Harness connected") {
|
|
839
|
+
return { ...initialAgentResponseState };
|
|
840
|
+
}
|
|
841
|
+
return { ...prev, status: newStatus };
|
|
842
|
+
case "thinking": {
|
|
843
|
+
if (payload.thinkingStep) {
|
|
844
|
+
const newStep = {
|
|
845
|
+
id: payload.thinkingStep.id || `step-${now}`,
|
|
846
|
+
label: payload.thinkingStep.label,
|
|
847
|
+
content: payload.thinkingStep.content,
|
|
848
|
+
depth: payload.thinkingStep.depth ?? payload.depth ?? 0,
|
|
849
|
+
isCollapsed: payload.thinkingStep.isCollapsed,
|
|
850
|
+
timestamp: now,
|
|
851
|
+
agentName: payload.agentName,
|
|
852
|
+
parentAgent: payload.parentAgent
|
|
853
|
+
};
|
|
854
|
+
const thinkingStartTime2 = prev.thinkingStartTime ?? now;
|
|
855
|
+
const next2 = {
|
|
856
|
+
...prev,
|
|
857
|
+
status: newStatus,
|
|
858
|
+
thinkingSteps: [...prev.thinkingSteps || [], newStep],
|
|
859
|
+
thinkingStartTime: thinkingStartTime2,
|
|
860
|
+
firstMessageTime
|
|
861
|
+
};
|
|
862
|
+
return { ...next2, timelineEntries: buildTimelineEntries(next2) };
|
|
863
|
+
}
|
|
864
|
+
const newThinking = payload.message || payload.content || "";
|
|
865
|
+
const separator = prev.thinking && newThinking ? "\n\n" : "";
|
|
866
|
+
const thinkingStartTime = prev.thinkingStartTime ?? (newThinking ? now : null);
|
|
867
|
+
const prevSteps = prev.thinkingSteps || [];
|
|
868
|
+
const plainStep = {
|
|
869
|
+
id: `step-${prevSteps.length}`,
|
|
870
|
+
label: newThinking,
|
|
871
|
+
content: newThinking,
|
|
872
|
+
depth: payload.depth ?? 0,
|
|
873
|
+
timestamp: now,
|
|
874
|
+
agentName: payload.agentName,
|
|
875
|
+
parentAgent: payload.parentAgent
|
|
876
|
+
};
|
|
877
|
+
const next = {
|
|
878
|
+
...prev,
|
|
879
|
+
status: newStatus,
|
|
880
|
+
thinking: prev.thinking + separator + newThinking,
|
|
881
|
+
thinkingSteps: [...prevSteps, plainStep],
|
|
882
|
+
thinkingStartTime,
|
|
883
|
+
firstMessageTime
|
|
884
|
+
};
|
|
885
|
+
return { ...next, timelineEntries: buildTimelineEntries(next) };
|
|
886
|
+
}
|
|
887
|
+
case "tool_call": {
|
|
888
|
+
const toolName = payload.message || payload.tool?.name;
|
|
889
|
+
if (toolName) {
|
|
890
|
+
const newToolCall = {
|
|
891
|
+
id: payload.tool?.id || `tool-${now}`,
|
|
892
|
+
name: toolName,
|
|
893
|
+
arguments: payload.tool?.arguments,
|
|
894
|
+
timestamp: now,
|
|
895
|
+
agentName: payload.agentName,
|
|
896
|
+
parentAgent: payload.parentAgent,
|
|
897
|
+
depth: payload.depth
|
|
898
|
+
};
|
|
899
|
+
const next = {
|
|
900
|
+
...prev,
|
|
901
|
+
status: newStatus,
|
|
902
|
+
toolCalls: [...prev.toolCalls, newToolCall],
|
|
903
|
+
firstMessageTime
|
|
904
|
+
};
|
|
905
|
+
return { ...next, timelineEntries: buildTimelineEntries(next) };
|
|
906
|
+
}
|
|
907
|
+
return { ...prev, status: newStatus, firstMessageTime };
|
|
908
|
+
}
|
|
909
|
+
case "knowledge": {
|
|
910
|
+
const knowledgeContent = payload.message || payload.knowledge?.content;
|
|
911
|
+
if (knowledgeContent) {
|
|
912
|
+
const newKnowledge = {
|
|
913
|
+
id: payload.knowledge?.id || `knowledge-${now}`,
|
|
914
|
+
source: payload.knowledge?.source || "unknown",
|
|
915
|
+
content: knowledgeContent,
|
|
916
|
+
timestamp: now,
|
|
917
|
+
agentName: payload.agentName,
|
|
918
|
+
parentAgent: payload.parentAgent,
|
|
919
|
+
depth: payload.depth
|
|
920
|
+
};
|
|
921
|
+
const next = {
|
|
922
|
+
...prev,
|
|
923
|
+
status: newStatus,
|
|
924
|
+
knowledge: [...prev.knowledge, newKnowledge],
|
|
925
|
+
firstMessageTime
|
|
926
|
+
};
|
|
927
|
+
return { ...next, timelineEntries: buildTimelineEntries(next) };
|
|
928
|
+
}
|
|
929
|
+
return { ...prev, status: newStatus, firstMessageTime };
|
|
930
|
+
}
|
|
931
|
+
case "memory": {
|
|
932
|
+
const memoryContent = payload.message || payload.memory?.content;
|
|
933
|
+
if (memoryContent) {
|
|
934
|
+
const newMemory = {
|
|
935
|
+
id: payload.memory?.id || `memory-${now}`,
|
|
936
|
+
type: payload.memory?.type || "unknown",
|
|
937
|
+
content: memoryContent,
|
|
938
|
+
timestamp: now,
|
|
939
|
+
agentName: payload.agentName,
|
|
940
|
+
parentAgent: payload.parentAgent,
|
|
941
|
+
depth: payload.depth
|
|
942
|
+
};
|
|
943
|
+
const next = {
|
|
944
|
+
...prev,
|
|
945
|
+
status: newStatus,
|
|
946
|
+
memory: [...prev.memory, newMemory],
|
|
947
|
+
firstMessageTime
|
|
948
|
+
};
|
|
949
|
+
return { ...next, timelineEntries: buildTimelineEntries(next) };
|
|
950
|
+
}
|
|
951
|
+
return { ...prev, status: newStatus, firstMessageTime };
|
|
952
|
+
}
|
|
953
|
+
case "response":
|
|
954
|
+
return {
|
|
955
|
+
...prev,
|
|
956
|
+
status: "complete",
|
|
957
|
+
response: payload.message || payload.content || "",
|
|
958
|
+
responseCompleteTime: now,
|
|
959
|
+
firstMessageTime: prev.firstMessageTime ?? now
|
|
960
|
+
};
|
|
961
|
+
case "status_update": {
|
|
962
|
+
const statusMessage = payload.message || payload.statusUpdate?.message;
|
|
963
|
+
if (statusMessage) {
|
|
964
|
+
const newStatusItem = {
|
|
965
|
+
id: payload.statusUpdate?.id || `status-${now}`,
|
|
966
|
+
message: statusMessage,
|
|
967
|
+
agent: payload.statusUpdate?.agent,
|
|
968
|
+
timestamp: now,
|
|
969
|
+
agentName: payload.agentName,
|
|
970
|
+
parentAgent: payload.parentAgent,
|
|
971
|
+
depth: payload.depth
|
|
972
|
+
};
|
|
973
|
+
const next = {
|
|
974
|
+
...prev,
|
|
975
|
+
status: newStatus,
|
|
976
|
+
statusUpdates: [...prev.statusUpdates, newStatusItem],
|
|
977
|
+
firstMessageTime
|
|
978
|
+
};
|
|
979
|
+
return { ...next, timelineEntries: buildTimelineEntries(next) };
|
|
980
|
+
}
|
|
981
|
+
return { ...prev, status: newStatus, firstMessageTime };
|
|
982
|
+
}
|
|
983
|
+
case "potential_response": {
|
|
984
|
+
const respContent = payload.message || payload.content || "";
|
|
985
|
+
if (respContent) {
|
|
986
|
+
const newResp = {
|
|
987
|
+
id: `resp-${now}`,
|
|
988
|
+
content: respContent,
|
|
989
|
+
timestamp: now,
|
|
990
|
+
agentName: payload.agentName,
|
|
991
|
+
parentAgent: payload.parentAgent,
|
|
992
|
+
depth: payload.depth
|
|
993
|
+
};
|
|
994
|
+
const next = {
|
|
995
|
+
...prev,
|
|
996
|
+
status: newStatus,
|
|
997
|
+
potentialResponses: [...prev.potentialResponses || [], newResp],
|
|
998
|
+
firstMessageTime
|
|
999
|
+
};
|
|
1000
|
+
return { ...next, timelineEntries: buildTimelineEntries(next) };
|
|
1001
|
+
}
|
|
1002
|
+
return { ...prev, status: newStatus, firstMessageTime };
|
|
1003
|
+
}
|
|
1004
|
+
default:
|
|
1005
|
+
return { ...prev, status: newStatus, firstMessageTime };
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
|
|
827
1009
|
// src/components/agent-response/hooks/useAgentResponseAccumulator.ts
|
|
828
1010
|
function useAgentResponseAccumulator(options) {
|
|
829
1011
|
const [state, setState] = useState(initialAgentResponseState);
|
|
@@ -838,185 +1020,7 @@ function useAgentResponseAccumulator(options) {
|
|
|
838
1020
|
} else {
|
|
839
1021
|
payload = message;
|
|
840
1022
|
}
|
|
841
|
-
setState((prev) =>
|
|
842
|
-
let newStatus = prev.status;
|
|
843
|
-
const isFirstMessage = prev.status === "idle" && payload.type !== "status";
|
|
844
|
-
if (isFirstMessage) {
|
|
845
|
-
newStatus = "processing";
|
|
846
|
-
}
|
|
847
|
-
const firstMessageTime = prev.firstMessageTime ?? (isFirstMessage ? Date.now() : null);
|
|
848
|
-
switch (payload.type) {
|
|
849
|
-
case "status":
|
|
850
|
-
if (payload.message === "Harness connected" || payload.status === "Harness connected") {
|
|
851
|
-
return { ...initialAgentResponseState };
|
|
852
|
-
}
|
|
853
|
-
return { ...prev, status: newStatus };
|
|
854
|
-
case "thinking": {
|
|
855
|
-
if (payload.thinkingStep) {
|
|
856
|
-
const newStep = {
|
|
857
|
-
id: payload.thinkingStep.id || `step-${Date.now()}`,
|
|
858
|
-
label: payload.thinkingStep.label,
|
|
859
|
-
content: payload.thinkingStep.content,
|
|
860
|
-
depth: payload.thinkingStep.depth ?? payload.depth ?? 0,
|
|
861
|
-
isCollapsed: payload.thinkingStep.isCollapsed,
|
|
862
|
-
timestamp: Date.now(),
|
|
863
|
-
agentName: payload.agentName,
|
|
864
|
-
parentAgent: payload.parentAgent
|
|
865
|
-
};
|
|
866
|
-
const thinkingStartTime2 = prev.thinkingStartTime ?? Date.now();
|
|
867
|
-
const next2 = {
|
|
868
|
-
...prev,
|
|
869
|
-
status: newStatus,
|
|
870
|
-
thinkingSteps: [...prev.thinkingSteps || [], newStep],
|
|
871
|
-
thinkingStartTime: thinkingStartTime2,
|
|
872
|
-
firstMessageTime
|
|
873
|
-
};
|
|
874
|
-
return { ...next2, timelineEntries: buildTimelineEntries(next2) };
|
|
875
|
-
}
|
|
876
|
-
const newThinking = payload.message || payload.content || "";
|
|
877
|
-
const separator = prev.thinking && newThinking ? "\n\n" : "";
|
|
878
|
-
const thinkingStartTime = prev.thinkingStartTime ?? (newThinking ? Date.now() : null);
|
|
879
|
-
const prevSteps = prev.thinkingSteps || [];
|
|
880
|
-
const plainStep = {
|
|
881
|
-
id: `step-${prevSteps.length}`,
|
|
882
|
-
label: newThinking,
|
|
883
|
-
content: newThinking,
|
|
884
|
-
depth: payload.depth ?? 0,
|
|
885
|
-
timestamp: Date.now(),
|
|
886
|
-
agentName: payload.agentName,
|
|
887
|
-
parentAgent: payload.parentAgent
|
|
888
|
-
};
|
|
889
|
-
const next = {
|
|
890
|
-
...prev,
|
|
891
|
-
status: newStatus,
|
|
892
|
-
thinking: prev.thinking + separator + newThinking,
|
|
893
|
-
thinkingSteps: [...prevSteps, plainStep],
|
|
894
|
-
thinkingStartTime,
|
|
895
|
-
firstMessageTime
|
|
896
|
-
};
|
|
897
|
-
return { ...next, timelineEntries: buildTimelineEntries(next) };
|
|
898
|
-
}
|
|
899
|
-
case "tool_call": {
|
|
900
|
-
const toolName = payload.message || payload.tool?.name;
|
|
901
|
-
if (toolName) {
|
|
902
|
-
const newToolCall = {
|
|
903
|
-
id: payload.tool?.id || `tool-${Date.now()}`,
|
|
904
|
-
name: toolName,
|
|
905
|
-
arguments: payload.tool?.arguments,
|
|
906
|
-
timestamp: Date.now(),
|
|
907
|
-
agentName: payload.agentName,
|
|
908
|
-
parentAgent: payload.parentAgent,
|
|
909
|
-
depth: payload.depth
|
|
910
|
-
};
|
|
911
|
-
const next = {
|
|
912
|
-
...prev,
|
|
913
|
-
status: newStatus,
|
|
914
|
-
toolCalls: [...prev.toolCalls, newToolCall],
|
|
915
|
-
firstMessageTime
|
|
916
|
-
};
|
|
917
|
-
return { ...next, timelineEntries: buildTimelineEntries(next) };
|
|
918
|
-
}
|
|
919
|
-
return { ...prev, status: newStatus, firstMessageTime };
|
|
920
|
-
}
|
|
921
|
-
case "knowledge": {
|
|
922
|
-
const knowledgeContent = payload.message || payload.knowledge?.content;
|
|
923
|
-
if (knowledgeContent) {
|
|
924
|
-
const newKnowledge = {
|
|
925
|
-
id: payload.knowledge?.id || `knowledge-${Date.now()}`,
|
|
926
|
-
source: payload.knowledge?.source || "unknown",
|
|
927
|
-
content: knowledgeContent,
|
|
928
|
-
timestamp: Date.now(),
|
|
929
|
-
agentName: payload.agentName,
|
|
930
|
-
parentAgent: payload.parentAgent,
|
|
931
|
-
depth: payload.depth
|
|
932
|
-
};
|
|
933
|
-
const next = {
|
|
934
|
-
...prev,
|
|
935
|
-
status: newStatus,
|
|
936
|
-
knowledge: [...prev.knowledge, newKnowledge],
|
|
937
|
-
firstMessageTime
|
|
938
|
-
};
|
|
939
|
-
return { ...next, timelineEntries: buildTimelineEntries(next) };
|
|
940
|
-
}
|
|
941
|
-
return { ...prev, status: newStatus, firstMessageTime };
|
|
942
|
-
}
|
|
943
|
-
case "memory": {
|
|
944
|
-
const memoryContent = payload.message || payload.memory?.content;
|
|
945
|
-
if (memoryContent) {
|
|
946
|
-
const newMemory = {
|
|
947
|
-
id: payload.memory?.id || `memory-${Date.now()}`,
|
|
948
|
-
type: payload.memory?.type || "unknown",
|
|
949
|
-
content: memoryContent,
|
|
950
|
-
timestamp: Date.now(),
|
|
951
|
-
agentName: payload.agentName,
|
|
952
|
-
parentAgent: payload.parentAgent,
|
|
953
|
-
depth: payload.depth
|
|
954
|
-
};
|
|
955
|
-
const next = {
|
|
956
|
-
...prev,
|
|
957
|
-
status: newStatus,
|
|
958
|
-
memory: [...prev.memory, newMemory],
|
|
959
|
-
firstMessageTime
|
|
960
|
-
};
|
|
961
|
-
return { ...next, timelineEntries: buildTimelineEntries(next) };
|
|
962
|
-
}
|
|
963
|
-
return { ...prev, status: newStatus, firstMessageTime };
|
|
964
|
-
}
|
|
965
|
-
case "response":
|
|
966
|
-
return {
|
|
967
|
-
...prev,
|
|
968
|
-
status: "complete",
|
|
969
|
-
response: payload.message || payload.content || "",
|
|
970
|
-
responseCompleteTime: Date.now(),
|
|
971
|
-
firstMessageTime: prev.firstMessageTime ?? Date.now()
|
|
972
|
-
};
|
|
973
|
-
case "status_update": {
|
|
974
|
-
const statusMessage = payload.message || payload.statusUpdate?.message;
|
|
975
|
-
if (statusMessage) {
|
|
976
|
-
const newStatusItem = {
|
|
977
|
-
id: payload.statusUpdate?.id || `status-${Date.now()}`,
|
|
978
|
-
message: statusMessage,
|
|
979
|
-
agent: payload.statusUpdate?.agent,
|
|
980
|
-
timestamp: Date.now(),
|
|
981
|
-
agentName: payload.agentName,
|
|
982
|
-
parentAgent: payload.parentAgent,
|
|
983
|
-
depth: payload.depth
|
|
984
|
-
};
|
|
985
|
-
const next = {
|
|
986
|
-
...prev,
|
|
987
|
-
status: newStatus,
|
|
988
|
-
statusUpdates: [...prev.statusUpdates, newStatusItem],
|
|
989
|
-
firstMessageTime
|
|
990
|
-
};
|
|
991
|
-
return { ...next, timelineEntries: buildTimelineEntries(next) };
|
|
992
|
-
}
|
|
993
|
-
return { ...prev, status: newStatus, firstMessageTime };
|
|
994
|
-
}
|
|
995
|
-
case "potential_response": {
|
|
996
|
-
const respContent = payload.message || payload.content || "";
|
|
997
|
-
if (respContent) {
|
|
998
|
-
const newResp = {
|
|
999
|
-
id: `resp-${Date.now()}`,
|
|
1000
|
-
content: respContent,
|
|
1001
|
-
timestamp: Date.now(),
|
|
1002
|
-
agentName: payload.agentName,
|
|
1003
|
-
parentAgent: payload.parentAgent,
|
|
1004
|
-
depth: payload.depth
|
|
1005
|
-
};
|
|
1006
|
-
const next = {
|
|
1007
|
-
...prev,
|
|
1008
|
-
status: newStatus,
|
|
1009
|
-
potentialResponses: [...prev.potentialResponses || [], newResp],
|
|
1010
|
-
firstMessageTime
|
|
1011
|
-
};
|
|
1012
|
-
return { ...next, timelineEntries: buildTimelineEntries(next) };
|
|
1013
|
-
}
|
|
1014
|
-
return { ...prev, status: newStatus, firstMessageTime };
|
|
1015
|
-
}
|
|
1016
|
-
default:
|
|
1017
|
-
return { ...prev, status: newStatus, firstMessageTime };
|
|
1018
|
-
}
|
|
1019
|
-
});
|
|
1023
|
+
setState((prev) => reduceAgentMessage(prev, payload));
|
|
1020
1024
|
},
|
|
1021
1025
|
[topic]
|
|
1022
1026
|
);
|
|
@@ -1814,6 +1818,6 @@ Available action types:
|
|
|
1814
1818
|
</inline_actions>
|
|
1815
1819
|
`;
|
|
1816
1820
|
|
|
1817
|
-
export { ActionBar, ActionMarkdownRenderer, ActivityIndicators, AgentResponse, AgentTimeline, HITLInteractionRecord, HITLQuestionPanel, HITLSection, INLINE_ACTION_PROMPT, MetadataRow, ThinkingSection, TruncatedMessage, UserPrompt, UserPromptInput, buildResponseString, buildTimelineEntries, createTimelineUIState, deduplicateEntries, formatTime, formatTotalTime, groupIntoAgentRuns, initialAgentResponseState, parseResponseSegments, useAgentResponseAccumulator, useThinkingTimer };
|
|
1821
|
+
export { ActionBar, ActionMarkdownRenderer, ActivityIndicators, AgentResponse, AgentTimeline, HITLInteractionRecord, HITLQuestionPanel, HITLSection, INLINE_ACTION_PROMPT, MetadataRow, ThinkingSection, TruncatedMessage, UserPrompt, UserPromptInput, buildResponseString, buildTimelineEntries, createTimelineUIState, deduplicateEntries, formatTime, formatTotalTime, groupIntoAgentRuns, initialAgentResponseState, parseResponseSegments, reduceAgentMessage, useAgentResponseAccumulator, useThinkingTimer };
|
|
1818
1822
|
//# sourceMappingURL=index.js.map
|
|
1819
1823
|
//# sourceMappingURL=index.js.map
|