bs-agent 0.0.24 → 0.0.26

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.
@@ -1,4 +1,5 @@
1
- import { j as ToolType, B as BuildShipAgent } from '../agent-Dr1JI3mA.cjs';
1
+ import { I as ImagePart, F as FilePart, m as ToolType, B as BuildShipAgent, b as AgentInput } from '../agent-D9xuE8wR.cjs';
2
+ export { d as ContentPart, j as TextPart } from '../agent-D9xuE8wR.cjs';
2
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
4
  import * as react from 'react';
4
5
  import { ReactNode } from 'react';
@@ -65,6 +66,8 @@ type Message = {
65
66
  executionId?: string;
66
67
  /** Context passed with this message, persisted for use on resume. */
67
68
  context?: Record<string, any>;
69
+ /** Multimodal attachments for user messages (images, files). */
70
+ attachments?: Array<ImagePart | FilePart>;
68
71
  };
69
72
  type Session = {
70
73
  id: string;
@@ -95,14 +98,14 @@ interface UseAgentOptions {
95
98
  declare function useAgent(agent: BuildShipAgent, options?: UseAgentOptions): {
96
99
  inProgress: boolean;
97
100
  messages: Message[];
98
- handleSend: (input: string, options?: {
101
+ handleSend: (input: AgentInput, options?: {
99
102
  context?: object;
100
103
  skipUserMessage?: boolean;
101
104
  additionalHeaders?: Record<string, string>;
102
105
  additionalBody?: Record<string, unknown>;
103
106
  }) => Promise<void>;
104
107
  resumeTool: (callId: string, result: any) => Promise<void>;
105
- addOptimisticMessage: (input: string) => void;
108
+ addOptimisticMessage: (input: AgentInput) => void;
106
109
  abort: () => void;
107
110
  sessionId: string;
108
111
  switchSession: (sessionId?: string) => void;
@@ -231,7 +234,7 @@ interface AgentRunner {
231
234
  sessionId: string;
232
235
  sessions: Session[];
233
236
  debugData: Record<string, DebugDataType>;
234
- handleSend: (input: string, options?: {
237
+ handleSend: (input: AgentInput, options?: {
235
238
  context?: Record<string, unknown>;
236
239
  skipUserMessage?: boolean;
237
240
  additionalHeaders?: Record<string, string>;
@@ -247,7 +250,7 @@ interface AgentRunner {
247
250
  resumeTool: (callId: string, result: any) => Promise<void>;
248
251
  switchSession: (sessionId?: string) => void;
249
252
  deleteSession: (sessionId: string) => void;
250
- addOptimisticMessage: (input: string) => void;
253
+ addOptimisticMessage: (input: AgentInput) => void;
251
254
  abort: () => void;
252
255
  }
253
256
  interface AgentToolContextValue {
@@ -292,4 +295,4 @@ declare function tryParseJSON(value: unknown): any;
292
295
  */
293
296
  declare function updateAgentMessageParts(parts: MessagePart[], newPart: MessagePart): MessagePart[];
294
297
 
295
- export { AGENT_DEBUG_DATA_KEY, AGENT_SESSIONS_KEY, AgentContextProvider, type AgentRunner, AgentToolContext, type AgentToolContextValue, type ClientToolConfig, type ClientToolDefinition, type ClientToolRenderProps, DEFAULT_SESSION_NAME, type DebugDataType, type HandoffItem, type Message, type MessagePart, type ReasoningItem, type RunErrorItem, type Session, TEMPORARY_SESSION_ID, type ToolConfig, type ToolExecutionItem, ToolRenderer, ToolType, type WidgetExecutionItem, cleanSchema, tryParseJSON, updateAgentMessageParts, useAgent, useAgentContext, useAgentGlobalState, useClientTool };
298
+ export { AGENT_DEBUG_DATA_KEY, AGENT_SESSIONS_KEY, AgentContextProvider, AgentInput, type AgentRunner, AgentToolContext, type AgentToolContextValue, type ClientToolConfig, type ClientToolDefinition, type ClientToolRenderProps, DEFAULT_SESSION_NAME, type DebugDataType, FilePart, type HandoffItem, ImagePart, type Message, type MessagePart, type ReasoningItem, type RunErrorItem, type Session, TEMPORARY_SESSION_ID, type ToolConfig, type ToolExecutionItem, ToolRenderer, ToolType, type WidgetExecutionItem, cleanSchema, tryParseJSON, updateAgentMessageParts, useAgent, useAgentContext, useAgentGlobalState, useClientTool };
@@ -1,4 +1,5 @@
1
- import { j as ToolType, B as BuildShipAgent } from '../agent-Dr1JI3mA.js';
1
+ import { I as ImagePart, F as FilePart, m as ToolType, B as BuildShipAgent, b as AgentInput } from '../agent-D9xuE8wR.js';
2
+ export { d as ContentPart, j as TextPart } from '../agent-D9xuE8wR.js';
2
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
4
  import * as react from 'react';
4
5
  import { ReactNode } from 'react';
@@ -65,6 +66,8 @@ type Message = {
65
66
  executionId?: string;
66
67
  /** Context passed with this message, persisted for use on resume. */
67
68
  context?: Record<string, any>;
69
+ /** Multimodal attachments for user messages (images, files). */
70
+ attachments?: Array<ImagePart | FilePart>;
68
71
  };
69
72
  type Session = {
70
73
  id: string;
@@ -95,14 +98,14 @@ interface UseAgentOptions {
95
98
  declare function useAgent(agent: BuildShipAgent, options?: UseAgentOptions): {
96
99
  inProgress: boolean;
97
100
  messages: Message[];
98
- handleSend: (input: string, options?: {
101
+ handleSend: (input: AgentInput, options?: {
99
102
  context?: object;
100
103
  skipUserMessage?: boolean;
101
104
  additionalHeaders?: Record<string, string>;
102
105
  additionalBody?: Record<string, unknown>;
103
106
  }) => Promise<void>;
104
107
  resumeTool: (callId: string, result: any) => Promise<void>;
105
- addOptimisticMessage: (input: string) => void;
108
+ addOptimisticMessage: (input: AgentInput) => void;
106
109
  abort: () => void;
107
110
  sessionId: string;
108
111
  switchSession: (sessionId?: string) => void;
@@ -231,7 +234,7 @@ interface AgentRunner {
231
234
  sessionId: string;
232
235
  sessions: Session[];
233
236
  debugData: Record<string, DebugDataType>;
234
- handleSend: (input: string, options?: {
237
+ handleSend: (input: AgentInput, options?: {
235
238
  context?: Record<string, unknown>;
236
239
  skipUserMessage?: boolean;
237
240
  additionalHeaders?: Record<string, string>;
@@ -247,7 +250,7 @@ interface AgentRunner {
247
250
  resumeTool: (callId: string, result: any) => Promise<void>;
248
251
  switchSession: (sessionId?: string) => void;
249
252
  deleteSession: (sessionId: string) => void;
250
- addOptimisticMessage: (input: string) => void;
253
+ addOptimisticMessage: (input: AgentInput) => void;
251
254
  abort: () => void;
252
255
  }
253
256
  interface AgentToolContextValue {
@@ -292,4 +295,4 @@ declare function tryParseJSON(value: unknown): any;
292
295
  */
293
296
  declare function updateAgentMessageParts(parts: MessagePart[], newPart: MessagePart): MessagePart[];
294
297
 
295
- export { AGENT_DEBUG_DATA_KEY, AGENT_SESSIONS_KEY, AgentContextProvider, type AgentRunner, AgentToolContext, type AgentToolContextValue, type ClientToolConfig, type ClientToolDefinition, type ClientToolRenderProps, DEFAULT_SESSION_NAME, type DebugDataType, type HandoffItem, type Message, type MessagePart, type ReasoningItem, type RunErrorItem, type Session, TEMPORARY_SESSION_ID, type ToolConfig, type ToolExecutionItem, ToolRenderer, ToolType, type WidgetExecutionItem, cleanSchema, tryParseJSON, updateAgentMessageParts, useAgent, useAgentContext, useAgentGlobalState, useClientTool };
298
+ export { AGENT_DEBUG_DATA_KEY, AGENT_SESSIONS_KEY, AgentContextProvider, AgentInput, type AgentRunner, AgentToolContext, type AgentToolContextValue, type ClientToolConfig, type ClientToolDefinition, type ClientToolRenderProps, DEFAULT_SESSION_NAME, type DebugDataType, FilePart, type HandoffItem, ImagePart, type Message, type MessagePart, type ReasoningItem, type RunErrorItem, type Session, TEMPORARY_SESSION_ID, type ToolConfig, type ToolExecutionItem, ToolRenderer, ToolType, type WidgetExecutionItem, cleanSchema, tryParseJSON, updateAgentMessageParts, useAgent, useAgentContext, useAgentGlobalState, useClientTool };
@@ -341,23 +341,17 @@ function buildStreamCallbacks(deps, debugKey) {
341
341
  return {
342
342
  onComplete: () => {
343
343
  console.log("Agent closed");
344
- setMessages((current) => {
345
- if (syncSessionRef.current) {
346
- syncSessionRef.current(current);
347
- }
348
- return current;
349
- });
350
344
  setInProgress(false);
345
+ if (syncSessionRef.current) {
346
+ syncSessionRef.current(messagesRef.current);
347
+ }
351
348
  },
352
349
  onError: (error) => {
353
350
  console.log("Agent error", error);
354
- setMessages((current) => {
355
- if (syncSessionRef.current) {
356
- syncSessionRef.current(current);
357
- }
358
- return current;
359
- });
360
351
  setInProgress(false);
352
+ if (syncSessionRef.current) {
353
+ syncSessionRef.current(messagesRef.current);
354
+ }
361
355
  },
362
356
  onEvent: (event) => {
363
357
  if (event.type === "text_delta") {
@@ -484,25 +478,7 @@ function handleTextDelta(event, setMessages, syncSessionRef, modifier, fullTextM
484
478
  }
485
479
  function handleClientToolCall(event, setMessages, syncSessionRef, toolContext, agentId) {
486
480
  const tool = toolContext?.getTool(agentId, event.data.toolName);
487
- console.log(
488
- "[DEBUG] handleClientToolCall:",
489
- event.data.toolName,
490
- "paused:",
491
- event.data.paused,
492
- "toolFound:",
493
- !!tool,
494
- "hasRender:",
495
- !!tool?.render
496
- );
497
- if (!tool?.render && !event.data.paused) {
498
- console.log("[DEBUG] handleClientToolCall: SKIPPING part creation \u2014 not paused and no render");
499
- return;
500
- }
501
- console.log(
502
- "[DEBUG] handleClientToolCall: CREATING widget part for",
503
- event.data.toolName,
504
- event.data.callId
505
- );
481
+ if (!tool?.render) return;
506
482
  setMessages((prev) => {
507
483
  const lastMessage = prev[prev.length - 1];
508
484
  const newPart = {
@@ -670,11 +646,29 @@ function useAgent(agent, options) {
670
646
  );
671
647
  const handleSend = useCallback3(
672
648
  async (input, options2) => {
649
+ let displayText;
650
+ let attachments;
651
+ if (typeof input === "string") {
652
+ displayText = input;
653
+ } else {
654
+ const textParts = [];
655
+ const mediaParts = [];
656
+ for (const part of input) {
657
+ if (part.type === "text") {
658
+ textParts.push(part.text);
659
+ } else {
660
+ mediaParts.push(part);
661
+ }
662
+ }
663
+ displayText = textParts.join("\n");
664
+ if (mediaParts.length > 0) attachments = mediaParts;
665
+ }
673
666
  const userMessage = {
674
667
  role: "user",
675
- content: input,
668
+ content: displayText,
676
669
  executionId: Date.now().toString(),
677
- ...options2?.context ? { context: options2.context } : {}
670
+ ...options2?.context ? { context: options2.context } : {},
671
+ ...attachments ? { attachments } : {}
678
672
  };
679
673
  if (!options2?.skipUserMessage) {
680
674
  setMessages((prev) => {
@@ -684,14 +678,15 @@ function useAgent(agent, options) {
684
678
  }
685
679
  return updatedMessages;
686
680
  });
687
- } else if (options2?.context) {
681
+ } else if (options2?.context || attachments) {
688
682
  setMessages((prev) => {
689
683
  const lastUserIdx = prev.findLastIndex((m) => m.role === "user");
690
684
  if (lastUserIdx === -1) return prev;
691
685
  const updatedMessages = [...prev];
692
686
  updatedMessages[lastUserIdx] = {
693
687
  ...updatedMessages[lastUserIdx],
694
- context: options2.context
688
+ ...options2?.context ? { context: options2.context } : {},
689
+ ...attachments ? { attachments } : {}
695
690
  };
696
691
  if (sessionUtils.syncSessionRef.current) {
697
692
  sessionUtils.syncSessionRef.current(updatedMessages);
@@ -766,10 +761,28 @@ function useAgent(agent, options) {
766
761
  );
767
762
  const addOptimisticMessage = useCallback3(
768
763
  (input) => {
764
+ let displayText;
765
+ let attachments;
766
+ if (typeof input === "string") {
767
+ displayText = input;
768
+ } else {
769
+ const textParts = [];
770
+ const mediaParts = [];
771
+ for (const part of input) {
772
+ if (part.type === "text") {
773
+ textParts.push(part.text);
774
+ } else {
775
+ mediaParts.push(part);
776
+ }
777
+ }
778
+ displayText = textParts.join("\n");
779
+ if (mediaParts.length > 0) attachments = mediaParts;
780
+ }
769
781
  const userMessage = {
770
782
  role: "user",
771
- content: input,
772
- executionId: Date.now().toString()
783
+ content: displayText,
784
+ executionId: Date.now().toString(),
785
+ ...attachments ? { attachments } : {}
773
786
  };
774
787
  setMessages((prev) => {
775
788
  const updatedMessages = [...prev, userMessage];
@@ -790,34 +803,19 @@ function useAgent(agent, options) {
790
803
  sessionUtils.syncSessionRef.current(messagesRef.current);
791
804
  }
792
805
  }, [sessionUtils.syncSessionRef]);
793
- return useMemo2(
794
- () => ({
795
- inProgress,
796
- messages,
797
- handleSend,
798
- resumeTool,
799
- addOptimisticMessage,
800
- abort,
801
- sessionId: currentSessionId,
802
- switchSession: sessionUtils.switchSession,
803
- deleteSession: sessionUtils.deleteSession,
804
- sessions: sessionUtils.sessionsList,
805
- debugData
806
- }),
807
- [
808
- inProgress,
809
- messages,
810
- handleSend,
811
- resumeTool,
812
- addOptimisticMessage,
813
- abort,
814
- currentSessionId,
815
- sessionUtils.switchSession,
816
- sessionUtils.deleteSession,
817
- sessionUtils.sessionsList,
818
- debugData
819
- ]
820
- );
806
+ return {
807
+ inProgress,
808
+ messages,
809
+ handleSend,
810
+ resumeTool,
811
+ addOptimisticMessage,
812
+ abort,
813
+ sessionId: currentSessionId,
814
+ switchSession: sessionUtils.switchSession,
815
+ deleteSession: sessionUtils.deleteSession,
816
+ sessions: sessionUtils.sessionsList,
817
+ debugData
818
+ };
821
819
  }
822
820
 
823
821
  // src/core/stream.ts
@@ -1636,19 +1634,6 @@ function ToolRenderer({ agentId, part }) {
1636
1634
  throw new Error("ToolRenderer must be used within <AgentContextProvider>");
1637
1635
  }
1638
1636
  const tool = context.getTool(agentId, part.toolName);
1639
- console.log(
1640
- "[DEBUG] ToolRenderer:",
1641
- part.toolName,
1642
- part.callId,
1643
- "toolFound:",
1644
- !!tool,
1645
- "hasRender:",
1646
- !!tool?.render,
1647
- "paused:",
1648
- part.paused,
1649
- "status:",
1650
- localStatus
1651
- );
1652
1637
  const handleSubmit = useCallback6(
1653
1638
  (result) => {
1654
1639
  if (localStatus === "submitted") return;