bs-agent 0.0.27 → 0.0.29
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/README.md +84 -58
- package/dist/react/index.cjs +149 -179
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +27 -33
- package/dist/react/index.d.ts +27 -33
- package/dist/react/index.js +150 -179
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,8 +10,8 @@ streaming support.
|
|
|
10
10
|
- ⚛️ **React bindings** — hooks & context for chat UIs with session management
|
|
11
11
|
- 💬 **Multi-turn** — session-based conversations with persistent history
|
|
12
12
|
- 🛑 **Abort** — cancel any streaming request mid-flight
|
|
13
|
-
- 🐛 **
|
|
14
|
-
|
|
13
|
+
- 🐛 **Inline debug info** — tool calls, reasoning, handoffs & errors as
|
|
14
|
+
message parts
|
|
15
15
|
- 📦 **Zero extra deps** — native `fetch` + `ReadableStream`, only `zod` as a
|
|
16
16
|
dependency
|
|
17
17
|
|
|
@@ -318,7 +318,7 @@ function App() {
|
|
|
318
318
|
## `useAgent` Hook
|
|
319
319
|
|
|
320
320
|
The main hook for interacting with an agent. Manages messages, streaming,
|
|
321
|
-
|
|
321
|
+
and sessions.
|
|
322
322
|
|
|
323
323
|
```tsx
|
|
324
324
|
import { useAgent } from "@buildship/agent/react";
|
|
@@ -335,7 +335,6 @@ function ChatPage() {
|
|
|
335
335
|
switchSession, // (sessionId?) => void — switch to a session (or create new)
|
|
336
336
|
deleteSession, // (sessionId) => void — delete a session
|
|
337
337
|
addOptimisticMessage, // (input) => void — add a user message immediately
|
|
338
|
-
debugData, // Record<string, DebugDataType> — debug entries by execution ID
|
|
339
338
|
} = useAgent(
|
|
340
339
|
"agent-id",
|
|
341
340
|
"https://your-project.buildship.run/executeAgent/AGENT_ID",
|
|
@@ -416,9 +415,9 @@ raw delta → textDeltaModifier(delta) → accumulated text → fullTextModifier
|
|
|
416
415
|
`textDeltaModifier` acts as a per-chunk preprocessor; `fullTextModifier` acts as
|
|
417
416
|
a post-accumulation formatter on top of the already-modified text.
|
|
418
417
|
|
|
419
|
-
> **Note:** `
|
|
420
|
-
>
|
|
421
|
-
>
|
|
418
|
+
> **Note:** If `textDeltaModifier` strips or transforms content,
|
|
419
|
+
> `fullTextModifier` will only see the already-modified accumulation — the
|
|
420
|
+
> original unmodified stream text is not preserved.
|
|
422
421
|
|
|
423
422
|
## `useAgentContext` Hook
|
|
424
423
|
|
|
@@ -564,8 +563,8 @@ Messages can contain rich, interleaved content via `parts`:
|
|
|
564
563
|
type Message = {
|
|
565
564
|
role: "user" | "agent";
|
|
566
565
|
content: string; // Full text content
|
|
567
|
-
parts?: MessagePart[]; // Rich content (text
|
|
568
|
-
executionId?: string; //
|
|
566
|
+
parts?: MessagePart[]; // Rich content (text, widgets, tool calls, reasoning, etc.)
|
|
567
|
+
executionId?: string; // Execution ID for this turn
|
|
569
568
|
attachments?: Array<ImagePart | FilePart>; // Multimodal user message attachments
|
|
570
569
|
};
|
|
571
570
|
|
|
@@ -579,11 +578,26 @@ type MessagePart =
|
|
|
579
578
|
paused?: boolean;
|
|
580
579
|
status?: "pending" | "submitted";
|
|
581
580
|
result?: any;
|
|
582
|
-
}
|
|
581
|
+
}
|
|
582
|
+
| {
|
|
583
|
+
type: "tool_call";
|
|
584
|
+
toolName: string;
|
|
585
|
+
callId: string;
|
|
586
|
+
toolType: ToolType;
|
|
587
|
+
status: "progress" | "complete" | "error";
|
|
588
|
+
inputs?: unknown;
|
|
589
|
+
output?: unknown;
|
|
590
|
+
error?: string;
|
|
591
|
+
serverName?: string; // MCP server name
|
|
592
|
+
}
|
|
593
|
+
| { type: "reasoning"; reasoning: string; index?: number }
|
|
594
|
+
| { type: "handoff"; agentName: string }
|
|
595
|
+
| { type: "run_error"; message: string; code?: string };
|
|
583
596
|
```
|
|
584
597
|
|
|
585
598
|
> **Tip:** When rendering messages, iterate over `msg.parts` instead of
|
|
586
|
-
> `msg.content` to get
|
|
599
|
+
> `msg.content` to get text, widgets, tool calls, reasoning, handoffs, and
|
|
600
|
+
> errors interleaved in chronological order.
|
|
587
601
|
|
|
588
602
|
## Sessions
|
|
589
603
|
|
|
@@ -618,48 +632,27 @@ type Session = {
|
|
|
618
632
|
};
|
|
619
633
|
```
|
|
620
634
|
|
|
621
|
-
## Debug
|
|
635
|
+
## Inline Debug Info
|
|
622
636
|
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
637
|
+
Tool calls, reasoning, agent handoffs, and errors are all embedded directly in
|
|
638
|
+
the agent message's `parts` array — no separate debug state. Filter by `type`
|
|
639
|
+
to render them:
|
|
626
640
|
|
|
627
641
|
```tsx
|
|
628
|
-
const {
|
|
629
|
-
|
|
630
|
-
// Get debug
|
|
631
|
-
const
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
type
|
|
642
|
+
const { messages } = useAgent(...);
|
|
643
|
+
|
|
644
|
+
// Get debug parts from an agent message
|
|
645
|
+
const debugParts = message.parts?.filter(
|
|
646
|
+
(p) =>
|
|
647
|
+
p.type === "tool_call" ||
|
|
648
|
+
p.type === "reasoning" ||
|
|
649
|
+
p.type === "handoff" ||
|
|
650
|
+
p.type === "run_error",
|
|
651
|
+
);
|
|
635
652
|
```
|
|
636
653
|
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
```ts
|
|
640
|
-
type ToolExecutionItem = {
|
|
641
|
-
itemType: "tool_call";
|
|
642
|
-
toolName: string;
|
|
643
|
-
callId: string;
|
|
644
|
-
toolType: ToolType; // "flow" | "node" | "mcp" | "client" | "builtin" | "agent"
|
|
645
|
-
status: "progress" | "complete" | "error";
|
|
646
|
-
inputs?: unknown;
|
|
647
|
-
output?: unknown;
|
|
648
|
-
error?: string;
|
|
649
|
-
serverName?: string; // For MCP tools
|
|
650
|
-
};
|
|
651
|
-
|
|
652
|
-
type ReasoningItem = {
|
|
653
|
-
itemType: "reasoning";
|
|
654
|
-
reasoning: string;
|
|
655
|
-
index?: number;
|
|
656
|
-
};
|
|
657
|
-
|
|
658
|
-
type HandoffItem = {
|
|
659
|
-
itemType: "handoff";
|
|
660
|
-
agentName: string;
|
|
661
|
-
};
|
|
662
|
-
```
|
|
654
|
+
See the [Message Parts](#message-parts) section above for the full type
|
|
655
|
+
definitions of each part.
|
|
663
656
|
|
|
664
657
|
## React API Reference
|
|
665
658
|
|
|
@@ -667,7 +660,7 @@ type HandoffItem = {
|
|
|
667
660
|
|
|
668
661
|
| Hook | Description |
|
|
669
662
|
| ------------------------------------------ | ------------------------------------------------ |
|
|
670
|
-
| `useAgent(agentId, agentUrl, accessKey?)` | Main hook — messages, streaming, sessions
|
|
663
|
+
| `useAgent(agentId, agentUrl, accessKey?)` | Main hook — messages, streaming, sessions |
|
|
671
664
|
| `useAgentContext(agentId, agentUrl, key?)` | Context-based alternative for multi-agent setups |
|
|
672
665
|
| `useClientTool(agentId, config)` | Register a client tool (headless or widget) |
|
|
673
666
|
|
|
@@ -675,7 +668,7 @@ type HandoffItem = {
|
|
|
675
668
|
|
|
676
669
|
| Component | Description |
|
|
677
670
|
| ------------------------------------------- | -------------------------------------------------- |
|
|
678
|
-
| `<AgentContextProvider>` | Provides shared agent state (sessions
|
|
671
|
+
| `<AgentContextProvider>` | Provides shared agent state (sessions) |
|
|
679
672
|
| `<ToolRenderer agentId={id} part={part} />` | Renders a widget tool from a message part |
|
|
680
673
|
|
|
681
674
|
### Utilities
|
|
@@ -708,7 +701,7 @@ function App() {
|
|
|
708
701
|
}
|
|
709
702
|
|
|
710
703
|
function Chat() {
|
|
711
|
-
const { messages, handleSend, inProgress, resumeTool, abort
|
|
704
|
+
const { messages, handleSend, inProgress, resumeTool, abort } =
|
|
712
705
|
useAgent(AGENT_ID, AGENT_URL);
|
|
713
706
|
const [input, setInput] = useState("");
|
|
714
707
|
|
|
@@ -748,13 +741,46 @@ function Chat() {
|
|
|
748
741
|
{messages.map((msg, i) => (
|
|
749
742
|
<div key={i}>
|
|
750
743
|
<strong>{msg.role}:</strong>
|
|
751
|
-
{msg.parts?.map((part) =>
|
|
752
|
-
part.type === "text"
|
|
753
|
-
<span key={
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
744
|
+
{msg.parts?.map((part, j) => {
|
|
745
|
+
if (part.type === "text") {
|
|
746
|
+
return <span key={j}>{part.text}</span>;
|
|
747
|
+
}
|
|
748
|
+
if (part.type === "widget") {
|
|
749
|
+
return <ToolRenderer key={j} agentId={AGENT_ID} part={part} />;
|
|
750
|
+
}
|
|
751
|
+
if (part.type === "tool_call") {
|
|
752
|
+
return (
|
|
753
|
+
<div key={j} style={{ opacity: 0.7, fontSize: "0.85em" }}>
|
|
754
|
+
🔧 {part.toolName}{" "}
|
|
755
|
+
{part.status === "progress"
|
|
756
|
+
? "running..."
|
|
757
|
+
: part.status === "error"
|
|
758
|
+
? `failed: ${part.error}`
|
|
759
|
+
: "✓"}
|
|
760
|
+
</div>
|
|
761
|
+
);
|
|
762
|
+
}
|
|
763
|
+
if (part.type === "reasoning") {
|
|
764
|
+
return (
|
|
765
|
+
<div key={j} style={{ fontStyle: "italic", opacity: 0.6 }}>
|
|
766
|
+
💭 {part.reasoning}
|
|
767
|
+
</div>
|
|
768
|
+
);
|
|
769
|
+
}
|
|
770
|
+
if (part.type === "handoff") {
|
|
771
|
+
return (
|
|
772
|
+
<div key={j}>→ Handed off to {part.agentName}</div>
|
|
773
|
+
);
|
|
774
|
+
}
|
|
775
|
+
if (part.type === "run_error") {
|
|
776
|
+
return (
|
|
777
|
+
<div key={j} style={{ color: "red" }}>
|
|
778
|
+
⚠️ {part.message}
|
|
779
|
+
</div>
|
|
780
|
+
);
|
|
781
|
+
}
|
|
782
|
+
return null;
|
|
783
|
+
}) ?? msg.content}
|
|
758
784
|
</div>
|
|
759
785
|
))}
|
|
760
786
|
|