@assistant-ui/react-ag-ui 0.0.71 → 0.1.1
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 +1 -1
- package/dist/agUiExtras.js +1 -2
- package/dist/hooks.js +1 -2
- package/dist/runtime/{AgUiThreadRuntimeCore.d.ts → AgUiThreadController.d.ts} +6 -12
- package/dist/runtime/AgUiThreadController.d.ts.map +1 -0
- package/dist/runtime/{AgUiThreadRuntimeCore.js → AgUiThreadController.js} +567 -194
- package/dist/runtime/AgUiThreadController.js.map +1 -0
- package/dist/runtime/adapter/conversions.d.ts +4 -4
- package/dist/runtime/adapter/conversions.d.ts.map +1 -1
- package/dist/runtime/adapter/conversions.js +120 -35
- package/dist/runtime/adapter/conversions.js.map +1 -1
- package/dist/runtime/adapter/replay-content.d.ts +9 -0
- package/dist/runtime/adapter/replay-content.d.ts.map +1 -0
- package/dist/runtime/adapter/replay-content.js +185 -0
- package/dist/runtime/adapter/replay-content.js.map +1 -0
- package/dist/runtime/adapter/run-aggregator.d.ts +3 -5
- package/dist/runtime/adapter/run-aggregator.d.ts.map +1 -1
- package/dist/runtime/adapter/run-aggregator.js +48 -63
- package/dist/runtime/adapter/run-aggregator.js.map +1 -1
- package/dist/runtime/adapter/subscriber.d.ts +0 -24
- package/dist/runtime/adapter/subscriber.d.ts.map +1 -1
- package/dist/runtime/adapter/subscriber.js +2 -24
- package/dist/runtime/adapter/subscriber.js.map +1 -1
- package/dist/runtime/adapter/tool-approval.d.ts +2 -0
- package/dist/runtime/adapter/tool-approval.d.ts.map +1 -1
- package/dist/runtime/adapter/tool-approval.js +23 -6
- package/dist/runtime/adapter/tool-approval.js.map +1 -1
- package/dist/runtime/agUiThreadState.d.ts +60 -0
- package/dist/runtime/agUiThreadState.d.ts.map +1 -0
- package/dist/runtime/agUiThreadState.js +94 -0
- package/dist/runtime/agUiThreadState.js.map +1 -0
- package/dist/runtime/event-parser.d.ts.map +1 -1
- package/dist/runtime/event-parser.js +46 -50
- package/dist/runtime/event-parser.js.map +1 -1
- package/dist/runtime/interrupt-internals.js +1 -2
- package/dist/runtime/logger.js +1 -2
- package/dist/runtime/mcp-tool-result.d.ts +3 -1
- package/dist/runtime/mcp-tool-result.d.ts.map +1 -1
- package/dist/runtime/mcp-tool-result.js +7 -5
- package/dist/runtime/mcp-tool-result.js.map +1 -1
- package/dist/runtime/types.d.ts +11 -35
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js +1 -2
- package/dist/runtime/types.js.map +1 -1
- package/dist/useAgUiRuntime.js +3 -4
- package/dist/useAgUiRuntime.js.map +1 -1
- package/package.json +12 -11
- package/src/runtime/AgUiThreadController.deferred-results.test.ts +548 -0
- package/src/runtime/{AgUiThreadRuntimeCore.interrupt-cancel.test.ts → AgUiThreadController.interrupt-cancel.test.ts} +4 -4
- package/src/runtime/AgUiThreadController.replay.test.ts +3932 -0
- package/src/runtime/{AgUiThreadRuntimeCore.test.ts → AgUiThreadController.test.ts} +114 -6
- package/src/runtime/{AgUiThreadRuntimeCore.ts → AgUiThreadController.ts} +1037 -236
- package/src/runtime/adapter/conversions.content.test.ts +149 -5
- package/src/runtime/adapter/conversions.tools.test.ts +2 -1
- package/src/runtime/adapter/conversions.ts +249 -62
- package/src/runtime/adapter/replay-content.test.ts +235 -0
- package/src/runtime/adapter/replay-content.ts +306 -0
- package/src/runtime/adapter/run-aggregator.ts +79 -114
- package/src/runtime/adapter/subscriber.ts +1 -44
- package/src/runtime/adapter/tool-approval.ts +41 -3
- package/src/runtime/agUiThreadState.test.ts +224 -0
- package/src/runtime/agUiThreadState.ts +139 -0
- package/src/runtime/event-parser.ts +40 -58
- package/src/runtime/mcp-tool-result.ts +16 -2
- package/src/runtime/types.ts +16 -28
- package/src/useAgUiRuntime.fast-refresh.test.tsx +3 -3
- package/src/useAgUiRuntime.thread-switch.test.tsx +4 -4
- package/src/useAgUiRuntime.ts +3 -3
- package/dist/runtime/AgUiThreadRuntimeCore.d.ts.map +0 -1
- package/dist/runtime/AgUiThreadRuntimeCore.js.map +0 -1
|
@@ -6,7 +6,7 @@ import type {
|
|
|
6
6
|
ThreadHistoryAdapter,
|
|
7
7
|
ThreadMessage,
|
|
8
8
|
} from "@assistant-ui/core";
|
|
9
|
-
import {
|
|
9
|
+
import { AgUiThreadController } from "./AgUiThreadController";
|
|
10
10
|
import { makeLogger } from "./logger";
|
|
11
11
|
|
|
12
12
|
const flush = () => new Promise((resolve) => setTimeout(resolve, 0));
|
|
@@ -15,7 +15,7 @@ function createCore(
|
|
|
15
15
|
history?: ThreadHistoryAdapter,
|
|
16
16
|
agent = {} as AbstractAgent,
|
|
17
17
|
) {
|
|
18
|
-
const core = new
|
|
18
|
+
const core = new AgUiThreadController({
|
|
19
19
|
agent,
|
|
20
20
|
logger: makeLogger(),
|
|
21
21
|
showThinking: true,
|
|
@@ -141,7 +141,7 @@ function deferredHistory(messages: ThreadMessage[] = [storedUser]) {
|
|
|
141
141
|
};
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
-
describe("
|
|
144
|
+
describe("AgUiThreadController late history loading", () => {
|
|
145
145
|
it("drops a queued send when loading is cancelled", async () => {
|
|
146
146
|
const { history, finish } = deferredHistory();
|
|
147
147
|
const runAgent = vi.fn(async () => {});
|
|
@@ -479,7 +479,7 @@ describe("AgUiThreadRuntimeCore late history loading", () => {
|
|
|
479
479
|
});
|
|
480
480
|
});
|
|
481
481
|
|
|
482
|
-
describe("
|
|
482
|
+
describe("AgUiThreadController steerAway parent selection", () => {
|
|
483
483
|
it("starts a root branch for an explicit null parent", async () => {
|
|
484
484
|
const { core } = createCore();
|
|
485
485
|
await core.append(userMessage("old"));
|
|
@@ -497,7 +497,7 @@ describe("AgUiThreadRuntimeCore steerAway parent selection", () => {
|
|
|
497
497
|
});
|
|
498
498
|
});
|
|
499
499
|
|
|
500
|
-
describe("
|
|
500
|
+
describe("AgUiThreadController activity deltas", () => {
|
|
501
501
|
it("applies a delta to the snapshot the run streamed", async () => {
|
|
502
502
|
type Subscriber = Record<string, ((payload?: unknown) => void) | undefined>;
|
|
503
503
|
const runAgent = vi.fn(async (_input: unknown, subscriber: Subscriber) => {
|
|
@@ -521,7 +521,7 @@ describe("AgUiThreadRuntimeCore activity deltas", () => {
|
|
|
521
521
|
subscriber.onRunFinalized?.();
|
|
522
522
|
});
|
|
523
523
|
const agent = { runAgent, abortRun: vi.fn() } as unknown as AbstractAgent;
|
|
524
|
-
const core = new
|
|
524
|
+
const core = new AgUiThreadController({
|
|
525
525
|
agent,
|
|
526
526
|
logger: makeLogger(),
|
|
527
527
|
showThinking: true,
|
|
@@ -538,3 +538,111 @@ describe("AgUiThreadRuntimeCore activity deltas", () => {
|
|
|
538
538
|
});
|
|
539
539
|
});
|
|
540
540
|
});
|
|
541
|
+
|
|
542
|
+
describe("AgUiThreadController setState", () => {
|
|
543
|
+
it("keeps a cancel the updater makes while a send waits for history", async () => {
|
|
544
|
+
const { history, finish } = deferredHistory();
|
|
545
|
+
const runAgent = vi.fn(async () => {});
|
|
546
|
+
const { core } = createCore(history, {
|
|
547
|
+
runAgent,
|
|
548
|
+
abortRun: vi.fn(),
|
|
549
|
+
} as unknown as AbstractAgent);
|
|
550
|
+
const loading = core.__internal_load();
|
|
551
|
+
const sending = core.append({
|
|
552
|
+
...userMessage("cancelled"),
|
|
553
|
+
startRun: true,
|
|
554
|
+
});
|
|
555
|
+
|
|
556
|
+
core.setState(() => {
|
|
557
|
+
void core.cancel();
|
|
558
|
+
return { count: 1 };
|
|
559
|
+
});
|
|
560
|
+
finish();
|
|
561
|
+
await Promise.all([loading, sending]);
|
|
562
|
+
|
|
563
|
+
expect(core.getState()).toEqual({ count: 1 });
|
|
564
|
+
expect(core.getMessages().map((message) => message.id)).toEqual([
|
|
565
|
+
"restored",
|
|
566
|
+
]);
|
|
567
|
+
expect(runAgent).not.toHaveBeenCalled();
|
|
568
|
+
});
|
|
569
|
+
});
|
|
570
|
+
|
|
571
|
+
describe("AgUiThreadController resuming a disconnected run", () => {
|
|
572
|
+
type Subscriber = {
|
|
573
|
+
onTextMessageStartEvent?: (payload: { event: unknown }) => void;
|
|
574
|
+
onTextMessageContentEvent?: (payload: { event: unknown }) => void;
|
|
575
|
+
onTextMessageEndEvent?: (payload: { event: unknown }) => void;
|
|
576
|
+
onRunFinishedEvent?: (payload: { event: unknown }) => void;
|
|
577
|
+
};
|
|
578
|
+
const sendText = (
|
|
579
|
+
subscriber: Subscriber,
|
|
580
|
+
messageId: string,
|
|
581
|
+
text: string,
|
|
582
|
+
end = true,
|
|
583
|
+
) => {
|
|
584
|
+
subscriber.onTextMessageStartEvent?.({
|
|
585
|
+
event: { type: "TEXT_MESSAGE_START", messageId },
|
|
586
|
+
});
|
|
587
|
+
subscriber.onTextMessageContentEvent?.({
|
|
588
|
+
event: { type: "TEXT_MESSAGE_CONTENT", messageId, delta: text },
|
|
589
|
+
});
|
|
590
|
+
if (end) {
|
|
591
|
+
subscriber.onTextMessageEndEvent?.({
|
|
592
|
+
event: { type: "TEXT_MESSAGE_END", messageId },
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
};
|
|
596
|
+
|
|
597
|
+
it.each(["user", "assistant"] as const)(
|
|
598
|
+
"preserves replayed IDs and content when resume uses the %s parent",
|
|
599
|
+
async (parent) => {
|
|
600
|
+
const runAgent = vi.fn(
|
|
601
|
+
async (input: { runId: string }, subscriber: Subscriber) => {
|
|
602
|
+
if (runAgent.mock.calls.length === 1) {
|
|
603
|
+
sendText(subscriber, "assistant-a", "first", false);
|
|
604
|
+
throw new Error("stream disconnected");
|
|
605
|
+
}
|
|
606
|
+
sendText(subscriber, "assistant-a", "first and more");
|
|
607
|
+
sendText(subscriber, "assistant-b", "second answer");
|
|
608
|
+
subscriber.onRunFinishedEvent?.({
|
|
609
|
+
event: { type: "RUN_FINISHED", runId: input.runId },
|
|
610
|
+
});
|
|
611
|
+
},
|
|
612
|
+
);
|
|
613
|
+
const { core } = createCore(undefined, {
|
|
614
|
+
runAgent,
|
|
615
|
+
abortRun: vi.fn(),
|
|
616
|
+
} as unknown as AbstractAgent);
|
|
617
|
+
|
|
618
|
+
await expect(
|
|
619
|
+
core.append({ ...userMessage("question"), startRun: true }),
|
|
620
|
+
).rejects.toThrow("stream disconnected");
|
|
621
|
+
const userId = core.getMessages()[0]!.id;
|
|
622
|
+
expect(core.getMessages()[1]).toMatchObject({
|
|
623
|
+
id: "assistant-a",
|
|
624
|
+
content: [{ type: "text", text: "first" }],
|
|
625
|
+
});
|
|
626
|
+
|
|
627
|
+
await core.resume({
|
|
628
|
+
parentId: parent === "user" ? userId : "assistant-a",
|
|
629
|
+
sourceId: null,
|
|
630
|
+
runConfig: {},
|
|
631
|
+
});
|
|
632
|
+
|
|
633
|
+
expect(runAgent).toHaveBeenCalledTimes(2);
|
|
634
|
+
expect(core.getMessages().map((message) => message.id)).toEqual([
|
|
635
|
+
userId,
|
|
636
|
+
"assistant-a",
|
|
637
|
+
"assistant-b",
|
|
638
|
+
]);
|
|
639
|
+
expect(core.getMessages().slice(1)).toMatchObject([
|
|
640
|
+
{ content: [{ type: "text", text: "first and more" }] },
|
|
641
|
+
{ content: [{ type: "text", text: "second answer" }] },
|
|
642
|
+
]);
|
|
643
|
+
expect(
|
|
644
|
+
core.getMessageRepository().messages.map(({ parentId }) => parentId),
|
|
645
|
+
).toEqual([null, userId, "assistant-a"]);
|
|
646
|
+
},
|
|
647
|
+
);
|
|
648
|
+
});
|