@copilotkit/channels-core 0.4.1-canary.perfall1 → 0.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/README.md +7 -8
- package/dist/canonical-run-loop.test.d.ts +2 -0
- package/dist/canonical-run-loop.test.d.ts.map +1 -0
- package/dist/canonical-run-loop.test.js +453 -0
- package/dist/codec.d.ts +2 -3
- package/dist/codec.d.ts.map +1 -1
- package/dist/create-channel.d.ts +110 -4
- package/dist/create-channel.d.ts.map +1 -1
- package/dist/create-channel.js +258 -92
- package/dist/create-channel.test.js +552 -29
- package/dist/delivery-error.d.ts +17 -0
- package/dist/delivery-error.d.ts.map +1 -0
- package/dist/delivery-error.js +22 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/managed-v1-await-choice-guard.test.d.ts +2 -0
- package/dist/managed-v1-await-choice-guard.test.d.ts.map +1 -0
- package/dist/managed-v1-await-choice-guard.test.js +52 -0
- package/dist/platform-adapter.d.ts +74 -11
- package/dist/platform-adapter.d.ts.map +1 -1
- package/dist/run-loop.d.ts +25 -6
- package/dist/run-loop.d.ts.map +1 -1
- package/dist/run-loop.js +289 -39
- package/dist/run-loop.test.js +37 -0
- package/dist/sanitize-agent-events.d.ts +24 -0
- package/dist/sanitize-agent-events.d.ts.map +1 -0
- package/dist/sanitize-agent-events.js +88 -0
- package/dist/sanitize-agent-events.test.d.ts +2 -0
- package/dist/sanitize-agent-events.test.d.ts.map +1 -0
- package/dist/sanitize-agent-events.test.js +194 -0
- package/dist/source-platform.test.d.ts +2 -0
- package/dist/source-platform.test.d.ts.map +1 -0
- package/dist/source-platform.test.js +149 -0
- package/dist/testing/fake-adapter.d.ts +8 -1
- package/dist/testing/fake-adapter.d.ts.map +1 -1
- package/dist/testing/fake-adapter.js +30 -1
- package/dist/testing/fake-agent.d.ts +5 -0
- package/dist/testing/fake-agent.d.ts.map +1 -1
- package/dist/testing/fake-agent.js +12 -0
- package/dist/thread-promise-contract.test.d.ts +2 -0
- package/dist/thread-promise-contract.test.d.ts.map +1 -0
- package/dist/thread-promise-contract.test.js +37 -0
- package/dist/thread.d.ts +5 -0
- package/dist/thread.d.ts.map +1 -1
- package/dist/thread.js +338 -243
- package/package.json +4 -4
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { HttpAgent } from "@ag-ui/client";
|
|
3
|
+
import { sanitizeAgentEventStream } from "./sanitize-agent-events.js";
|
|
4
|
+
import { createChannel } from "./create-channel.js";
|
|
5
|
+
import { FakeAdapter } from "./testing/fake-adapter.js";
|
|
6
|
+
import { FakeAgent } from "./testing/fake-agent.js";
|
|
7
|
+
const tick = () => new Promise((r) => setTimeout(r, 0));
|
|
8
|
+
const encoder = new TextEncoder();
|
|
9
|
+
/** Serialize an AG-UI event as one SSE frame. */
|
|
10
|
+
const frame = (event) => `data: ${JSON.stringify(event)}\n\n`;
|
|
11
|
+
/** A Response whose body streams `chunks` verbatim, one enqueue per chunk. */
|
|
12
|
+
function streamResponse(chunks, contentType = "text/event-stream") {
|
|
13
|
+
const body = new ReadableStream({
|
|
14
|
+
start(c) {
|
|
15
|
+
for (const chunk of chunks)
|
|
16
|
+
c.enqueue(encoder.encode(chunk));
|
|
17
|
+
c.close();
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
return new Response(body, {
|
|
21
|
+
status: 200,
|
|
22
|
+
headers: { "content-type": contentType },
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* A run whose `TOOL_CALL_START` carries `parentMessageId: null` — the shape
|
|
27
|
+
* `@ag-ui/langgraph` emits for the tool call that triggers an interrupt, and
|
|
28
|
+
* the one `EventSchemas.parse` rejects with "Expected string, received null".
|
|
29
|
+
*/
|
|
30
|
+
const nullParentRun = () => [
|
|
31
|
+
frame({ type: "RUN_STARTED", threadId: "t1", runId: "r1" }),
|
|
32
|
+
frame({
|
|
33
|
+
type: "TOOL_CALL_START",
|
|
34
|
+
toolCallId: "tc1",
|
|
35
|
+
toolCallName: "ask_human",
|
|
36
|
+
parentMessageId: null,
|
|
37
|
+
}),
|
|
38
|
+
frame({ type: "TOOL_CALL_ARGS", toolCallId: "tc1", delta: "{}" }),
|
|
39
|
+
frame({ type: "TOOL_CALL_END", toolCallId: "tc1" }),
|
|
40
|
+
frame({ type: "RUN_FINISHED", threadId: "t1", runId: "r1" }),
|
|
41
|
+
];
|
|
42
|
+
/** An `HttpAgent` whose transport replays `chunks` instead of hitting a server. */
|
|
43
|
+
function agentServing(chunks, contentType) {
|
|
44
|
+
return new HttpAgent({
|
|
45
|
+
url: "http://agent.test/run",
|
|
46
|
+
fetch: (async () => streamResponse(chunks, contentType)),
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/** Read a wrapped transport's response body back as text. */
|
|
50
|
+
async function bodyText(agent) {
|
|
51
|
+
const res = await agent.fetch("http://agent.test/run", {});
|
|
52
|
+
return await res.text();
|
|
53
|
+
}
|
|
54
|
+
describe("sanitizeAgentEventStream", () => {
|
|
55
|
+
it("lets a run carrying a null parentMessageId reach RUN_FINISHED", async () => {
|
|
56
|
+
const agent = sanitizeAgentEventStream(agentServing(nullParentRun()));
|
|
57
|
+
const started = [];
|
|
58
|
+
await agent.runAgent({}, {
|
|
59
|
+
onToolCallStartEvent: ({ event }) => void started.push(event.toolCallName),
|
|
60
|
+
});
|
|
61
|
+
expect(started).toEqual(["ask_human"]);
|
|
62
|
+
});
|
|
63
|
+
it("aborts that same run when the sanitizer is not applied", async () => {
|
|
64
|
+
const agent = agentServing(nullParentRun());
|
|
65
|
+
await expect(agent.runAgent({})).rejects.toThrow(/parentMessageId|received null/);
|
|
66
|
+
});
|
|
67
|
+
it("coerces the null to an empty string and leaves every other byte alone", async () => {
|
|
68
|
+
const agent = sanitizeAgentEventStream(agentServing([
|
|
69
|
+
": keep-alive\n\n",
|
|
70
|
+
frame({
|
|
71
|
+
type: "TOOL_CALL_START",
|
|
72
|
+
toolCallId: "tc1",
|
|
73
|
+
toolCallName: "ask_human",
|
|
74
|
+
parentMessageId: null,
|
|
75
|
+
}),
|
|
76
|
+
frame({
|
|
77
|
+
type: "TOOL_CALL_START",
|
|
78
|
+
toolCallId: "tc2",
|
|
79
|
+
toolCallName: "other",
|
|
80
|
+
parentMessageId: "msg-1",
|
|
81
|
+
}),
|
|
82
|
+
]));
|
|
83
|
+
expect(await bodyText(agent)).toBe(": keep-alive\n\n" +
|
|
84
|
+
`data: {"type":"TOOL_CALL_START","toolCallId":"tc1","toolCallName":"ask_human","parentMessageId":""}\n\n` +
|
|
85
|
+
`data: {"type":"TOOL_CALL_START","toolCallId":"tc2","toolCallName":"other","parentMessageId":"msg-1"}\n\n`);
|
|
86
|
+
});
|
|
87
|
+
it("coerces a null split across two transport chunks", async () => {
|
|
88
|
+
const whole = frame({
|
|
89
|
+
type: "TOOL_CALL_START",
|
|
90
|
+
toolCallId: "tc1",
|
|
91
|
+
toolCallName: "ask_human",
|
|
92
|
+
parentMessageId: null,
|
|
93
|
+
});
|
|
94
|
+
const split = whole.indexOf("null") + 2;
|
|
95
|
+
const agent = sanitizeAgentEventStream(agentServing([whole.slice(0, split), whole.slice(split)]));
|
|
96
|
+
expect(await bodyText(agent)).toContain(`"parentMessageId":""`);
|
|
97
|
+
});
|
|
98
|
+
it("still converts a mid-stream abort into RUN_ERROR rather than failing the run", async () => {
|
|
99
|
+
// The stock transform turns an AbortError into a synthetic RUN_ERROR and
|
|
100
|
+
// completes the stream. Replacing the transform (as SanitizingHttpAgent
|
|
101
|
+
// does) forfeits that; wrapping the transport must not.
|
|
102
|
+
const abort = Object.assign(new Error("aborted"), { name: "AbortError" });
|
|
103
|
+
const body = new ReadableStream({
|
|
104
|
+
start(c) {
|
|
105
|
+
c.enqueue(encoder.encode(frame({ type: "RUN_STARTED", threadId: "t1", runId: "r1" })));
|
|
106
|
+
c.error(abort);
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
const agent = sanitizeAgentEventStream(new HttpAgent({
|
|
110
|
+
url: "http://agent.test/run",
|
|
111
|
+
fetch: (async () => new Response(body, {
|
|
112
|
+
status: 200,
|
|
113
|
+
headers: { "content-type": "text/event-stream" },
|
|
114
|
+
})),
|
|
115
|
+
}));
|
|
116
|
+
const errors = [];
|
|
117
|
+
await agent.runAgent({}, { onRunErrorEvent: ({ event }) => void errors.push(event.code ?? "") });
|
|
118
|
+
expect(errors).toEqual(["abort"]);
|
|
119
|
+
});
|
|
120
|
+
it("passes a non-SSE body through untouched so protobuf still negotiates", async () => {
|
|
121
|
+
const proto = '\u0000\u0001"parentMessageId":null';
|
|
122
|
+
const agent = sanitizeAgentEventStream(agentServing([proto], "application/vnd.ag-ui+proto"));
|
|
123
|
+
expect(await bodyText(agent)).toBe(proto);
|
|
124
|
+
});
|
|
125
|
+
it("does not re-wrap a transport it has already wrapped", () => {
|
|
126
|
+
const agent = sanitizeAgentEventStream(agentServing(nullParentRun()));
|
|
127
|
+
const wrapped = agent.fetch;
|
|
128
|
+
sanitizeAgentEventStream(agent);
|
|
129
|
+
expect(agent.fetch).toBe(wrapped);
|
|
130
|
+
});
|
|
131
|
+
it("leaves an agent that has no HTTP transport alone", () => {
|
|
132
|
+
const agent = new FakeAgent();
|
|
133
|
+
expect(sanitizeAgentEventStream(agent)).toBe(agent);
|
|
134
|
+
expect("fetch" in agent).toBe(false);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
describe("createChannel({ sanitizeAgentEvents })", () => {
|
|
138
|
+
/** Run one turn through a channel backed by `agent`; resolve the run's error, if any. */
|
|
139
|
+
async function runTurn(agent, opts) {
|
|
140
|
+
const fake = new FakeAdapter();
|
|
141
|
+
const channel = createChannel({
|
|
142
|
+
adapters: [fake],
|
|
143
|
+
agent: () => agent,
|
|
144
|
+
...opts,
|
|
145
|
+
});
|
|
146
|
+
let failure;
|
|
147
|
+
channel.onMention(async ({ thread }) => {
|
|
148
|
+
try {
|
|
149
|
+
await thread.runAgent();
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
failure = err;
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
await channel.ɵruntime.start();
|
|
156
|
+
fake.emitTurn({ userText: "yo", conversationKey: "c1" });
|
|
157
|
+
await tick();
|
|
158
|
+
await tick();
|
|
159
|
+
return failure;
|
|
160
|
+
}
|
|
161
|
+
it("sanitizes a null parentMessageId by default", async () => {
|
|
162
|
+
expect(await runTurn(agentServing(nullParentRun()))).toBeUndefined();
|
|
163
|
+
});
|
|
164
|
+
it("survives the per-run clone of a singleton agent", async () => {
|
|
165
|
+
// A singleton `agent` is cloned per turn (isolateAgentInstance). HttpAgent's
|
|
166
|
+
// clone() copies the transport but not own-property overrides of run(), so
|
|
167
|
+
// sanitizing has to live on the transport to reach the cloned instance.
|
|
168
|
+
const fake = new FakeAdapter();
|
|
169
|
+
const channel = createChannel({
|
|
170
|
+
adapters: [fake],
|
|
171
|
+
agent: agentServing(nullParentRun()),
|
|
172
|
+
});
|
|
173
|
+
let failure;
|
|
174
|
+
channel.onMention(async ({ thread }) => {
|
|
175
|
+
try {
|
|
176
|
+
await thread.runAgent();
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
failure = err;
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
await channel.ɵruntime.start();
|
|
183
|
+
fake.emitTurn({ userText: "yo", conversationKey: "c1" });
|
|
184
|
+
await tick();
|
|
185
|
+
await tick();
|
|
186
|
+
expect(failure).toBeUndefined();
|
|
187
|
+
});
|
|
188
|
+
it("lets the run abort when sanitizing is disabled", async () => {
|
|
189
|
+
const failure = await runTurn(agentServing(nullParentRun()), {
|
|
190
|
+
sanitizeAgentEvents: false,
|
|
191
|
+
});
|
|
192
|
+
expect(String(failure)).toMatch(/parentMessageId|received null/);
|
|
193
|
+
});
|
|
194
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-platform.test.d.ts","sourceRoot":"","sources":["../src/source-platform.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { expect, test, vi } from "vitest";
|
|
3
|
+
import { createChannel } from "./create-channel.js";
|
|
4
|
+
import { MemoryStore } from "./state/memory-store.js";
|
|
5
|
+
import { FakeAdapter } from "./testing/fake-adapter.js";
|
|
6
|
+
import { FakeAgent } from "./testing/fake-agent.js";
|
|
7
|
+
test("an ingress source platform reaches the text thread and its tool context", async () => {
|
|
8
|
+
const observed = {};
|
|
9
|
+
const adapter = new FakeAdapter({ platform: "intelligence" });
|
|
10
|
+
const agent = new FakeAgent([
|
|
11
|
+
(subscriber) => {
|
|
12
|
+
subscriber.onToolCallEndEvent?.({
|
|
13
|
+
event: { toolCallId: "tool-call-1" },
|
|
14
|
+
toolCallName: "capture_platform",
|
|
15
|
+
toolCallArgs: {},
|
|
16
|
+
});
|
|
17
|
+
subscriber.onRunFinishedEvent?.({ event: {} });
|
|
18
|
+
},
|
|
19
|
+
(subscriber) => {
|
|
20
|
+
subscriber.onRunFinishedEvent?.({ event: {} });
|
|
21
|
+
},
|
|
22
|
+
]);
|
|
23
|
+
const channel = createChannel({
|
|
24
|
+
adapters: [adapter],
|
|
25
|
+
agent: () => agent,
|
|
26
|
+
tools: [
|
|
27
|
+
{
|
|
28
|
+
name: "capture_platform",
|
|
29
|
+
description: "Capture the handler platform",
|
|
30
|
+
parameters: z.object({}),
|
|
31
|
+
handler: (_args, ctx) => {
|
|
32
|
+
observed.toolPlatform = ctx.platform;
|
|
33
|
+
observed.toolThreadPlatform = ctx.thread.platform;
|
|
34
|
+
return "captured";
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
});
|
|
39
|
+
channel.onMessage(async ({ message, thread }) => {
|
|
40
|
+
observed.messagePlatform = message.platform;
|
|
41
|
+
observed.threadPlatform = thread.platform;
|
|
42
|
+
await thread.runAgent();
|
|
43
|
+
});
|
|
44
|
+
await channel.ɵruntime.start();
|
|
45
|
+
await adapter.getSink().onTurn({
|
|
46
|
+
conversationKey: "conversation-1",
|
|
47
|
+
replyTarget: {},
|
|
48
|
+
userText: "hello",
|
|
49
|
+
platform: "slack",
|
|
50
|
+
});
|
|
51
|
+
expect(observed).toEqual({
|
|
52
|
+
messagePlatform: "slack",
|
|
53
|
+
threadPlatform: "slack",
|
|
54
|
+
toolPlatform: "slack",
|
|
55
|
+
toolThreadPlatform: "slack",
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
test("an ingress source platform scopes identity resolution and event dedupe", async () => {
|
|
59
|
+
const state = new MemoryStore();
|
|
60
|
+
const dedupeSeen = vi.spyOn(state.dedup, "seen").mockResolvedValue(false);
|
|
61
|
+
const identity = vi.fn(() => "person-1");
|
|
62
|
+
const adapter = new FakeAdapter({ platform: "intelligence" });
|
|
63
|
+
const channel = createChannel({
|
|
64
|
+
adapters: [adapter],
|
|
65
|
+
store: {
|
|
66
|
+
adapter: state,
|
|
67
|
+
identity,
|
|
68
|
+
transcripts: {},
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
let userKey;
|
|
72
|
+
channel.onMessage(({ message }) => {
|
|
73
|
+
userKey = message.userKey;
|
|
74
|
+
});
|
|
75
|
+
await channel.ɵruntime.start();
|
|
76
|
+
await adapter.getSink().onTurn({
|
|
77
|
+
conversationKey: "conversation-1",
|
|
78
|
+
replyTarget: {},
|
|
79
|
+
userText: "hello",
|
|
80
|
+
platform: "teams",
|
|
81
|
+
eventId: "event-1",
|
|
82
|
+
user: { id: "user-1" },
|
|
83
|
+
});
|
|
84
|
+
expect(dedupeSeen).toHaveBeenCalledWith("message:teams:created:event-1:event-1", 300_000);
|
|
85
|
+
expect(identity).toHaveBeenCalledWith(expect.objectContaining({
|
|
86
|
+
adapter: "teams",
|
|
87
|
+
message: expect.objectContaining({ platform: "teams" }),
|
|
88
|
+
}));
|
|
89
|
+
expect(userKey).toBe("person-1");
|
|
90
|
+
});
|
|
91
|
+
test("non-text ingress keeps source platform in handler contexts and dedupe keys", async () => {
|
|
92
|
+
const state = new MemoryStore();
|
|
93
|
+
const dedupeSeen = vi.spyOn(state.dedup, "seen").mockResolvedValue(false);
|
|
94
|
+
const adapter = new FakeAdapter({ platform: "intelligence" });
|
|
95
|
+
const observed = {};
|
|
96
|
+
const channel = createChannel({
|
|
97
|
+
adapters: [adapter],
|
|
98
|
+
store: { adapter: state },
|
|
99
|
+
});
|
|
100
|
+
channel.onCommand("triage", ({ platform, thread }) => {
|
|
101
|
+
observed.commandPlatform = platform;
|
|
102
|
+
observed.commandThreadPlatform = thread.platform;
|
|
103
|
+
});
|
|
104
|
+
channel.onInteraction("approve", ({ message, platform, thread }) => {
|
|
105
|
+
observed.interactionMessagePlatform = message.platform;
|
|
106
|
+
observed.interactionPlatform = platform;
|
|
107
|
+
observed.interactionThreadPlatform = thread.platform;
|
|
108
|
+
});
|
|
109
|
+
channel.onReaction(({ thread }) => {
|
|
110
|
+
observed.reactionThreadPlatform = thread.platform;
|
|
111
|
+
});
|
|
112
|
+
await channel.ɵruntime.start();
|
|
113
|
+
const sink = adapter.getSink();
|
|
114
|
+
await sink.onCommand({
|
|
115
|
+
command: "triage",
|
|
116
|
+
conversationKey: "command-conversation",
|
|
117
|
+
eventId: "command-event",
|
|
118
|
+
platform: "teams",
|
|
119
|
+
replyTarget: {},
|
|
120
|
+
text: "",
|
|
121
|
+
});
|
|
122
|
+
const interaction = {
|
|
123
|
+
id: "approve",
|
|
124
|
+
conversationKey: "interaction-conversation",
|
|
125
|
+
eventId: "interaction-event",
|
|
126
|
+
platform: "slack",
|
|
127
|
+
replyTarget: {},
|
|
128
|
+
};
|
|
129
|
+
await sink.onInteraction(interaction);
|
|
130
|
+
await sink.onReaction({
|
|
131
|
+
added: true,
|
|
132
|
+
conversationKey: "reaction-conversation",
|
|
133
|
+
messageId: "message-1",
|
|
134
|
+
platform: "teams",
|
|
135
|
+
raw: {},
|
|
136
|
+
rawEmoji: "👍",
|
|
137
|
+
replyTarget: {},
|
|
138
|
+
});
|
|
139
|
+
expect(observed).toEqual({
|
|
140
|
+
commandPlatform: "teams",
|
|
141
|
+
commandThreadPlatform: "teams",
|
|
142
|
+
interactionMessagePlatform: "slack",
|
|
143
|
+
interactionPlatform: "slack",
|
|
144
|
+
interactionThreadPlatform: "slack",
|
|
145
|
+
reactionThreadPlatform: "teams",
|
|
146
|
+
});
|
|
147
|
+
expect(dedupeSeen).toHaveBeenCalledWith("evt:teams:command-event", 300_000);
|
|
148
|
+
expect(dedupeSeen).toHaveBeenCalledWith("evt:slack:interaction-event", 300_000);
|
|
149
|
+
});
|
|
@@ -35,6 +35,8 @@ export declare class FakeAdapter implements PlatformAdapter {
|
|
|
35
35
|
reactions?: boolean;
|
|
36
36
|
nativeEphemeral?: boolean;
|
|
37
37
|
modals?: boolean;
|
|
38
|
+
/** When true, activation requires an onMention or onMessage handler. */
|
|
39
|
+
messageEvents?: boolean;
|
|
38
40
|
/** Platform name override (defaults to "fake"); useful when a test needs distinct adapters. */
|
|
39
41
|
platform?: string;
|
|
40
42
|
/** When true, `start()` rejects — simulates an adapter that fails to come up. */
|
|
@@ -60,8 +62,13 @@ export declare class FakeAdapter implements PlatformAdapter {
|
|
|
60
62
|
stateStore?: StateStore;
|
|
61
63
|
private sink?;
|
|
62
64
|
private counter;
|
|
65
|
+
private turnCounter;
|
|
63
66
|
/** Expose the registered sink so tests can invoke onTurn() directly for overlap/lock tests. */
|
|
64
|
-
getSink(): IngressSink
|
|
67
|
+
getSink(): Omit<IngressSink, "onTurn"> & {
|
|
68
|
+
onTurn(turn: Omit<IncomingTurn, "operation"> & {
|
|
69
|
+
operation?: IncomingTurn["operation"];
|
|
70
|
+
}): void | Promise<void>;
|
|
71
|
+
};
|
|
65
72
|
start(sink: IngressSink): Promise<void>;
|
|
66
73
|
stop(): Promise<void>;
|
|
67
74
|
render(ir: ChannelNode[]): NativePayload;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fake-adapter.d.ts","sourceRoot":"","sources":["../../src/testing/fake-adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,YAAY,EACZ,aAAa,EACd,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EACV,eAAe,EACf,mBAAmB,EACnB,WAAW,EACX,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,eAAe,EACf,WAAW,EAGX,WAAW,EACX,aAAa,EACb,SAAS,EACT,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D,oHAAoH;AACpH,wBAAgB,mBAAmB,IAAI,WAAW,CAgCjD;AAED,qBAAa,WAAY,YAAW,eAAe;IACjD,QAAQ,SAAU;IAClB,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAC;IAC3C,QAAQ,CAAC,aAAa,QAAQ;IAE9B,sEAAsE;IACtE,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,4FAA4F;IAC5F,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAC;IACvC,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,mGAAmG;IACnG,OAAO,UAAS;IAEhB;;;;;;;;;;;;;OAaG;gBAED,QAAQ,GAAE;QACR,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,+FAA+F;QAC/F,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,iFAAiF;QACjF,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,0FAA0F;QAC1F,oBAAoB,CAAC,EAAE,OAAO,CAAC;QAC/B,kEAAkE;QAClE,QAAQ,CAAC,EAAE,OAAO,CAAC;KACf;
|
|
1
|
+
{"version":3,"file":"fake-adapter.d.ts","sourceRoot":"","sources":["../../src/testing/fake-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -71,6 +71,7 @@ export class FakeAdapter {
|
|
|
71
71
|
supportsTyping: false,
|
|
72
72
|
supportsReactions: fakeOpts.reactions !== false,
|
|
73
73
|
supportsStreaming: true,
|
|
74
|
+
supportsMessageEvents: fakeOpts.messageEvents === true,
|
|
74
75
|
supportsSuggestedPrompts: paneMethods,
|
|
75
76
|
supportsThreadTitle: paneMethods,
|
|
76
77
|
supportsEphemeral: fakeOpts.nativeEphemeral === true,
|
|
@@ -139,11 +140,32 @@ export class FakeAdapter {
|
|
|
139
140
|
stateStore;
|
|
140
141
|
sink;
|
|
141
142
|
counter = 0;
|
|
143
|
+
turnCounter = 0;
|
|
142
144
|
/** Expose the registered sink so tests can invoke onTurn() directly for overlap/lock tests. */
|
|
143
145
|
getSink() {
|
|
144
146
|
if (!this.sink)
|
|
145
147
|
throw new Error("FakeAdapter: sink not set — start the channel (channel.ɵruntime.start()) first");
|
|
146
|
-
|
|
148
|
+
const sink = this.sink;
|
|
149
|
+
const adapter = this;
|
|
150
|
+
return new Proxy(sink, {
|
|
151
|
+
get(target, property, receiver) {
|
|
152
|
+
if (property !== "onTurn") {
|
|
153
|
+
return Reflect.get(target, property, receiver);
|
|
154
|
+
}
|
|
155
|
+
return (turn) => {
|
|
156
|
+
const syntheticId = turn.eventId ?? `fake-message-${++adapter.turnCounter}`;
|
|
157
|
+
return sink.onTurn({
|
|
158
|
+
...turn,
|
|
159
|
+
operation: turn.operation ?? {
|
|
160
|
+
kind: "created",
|
|
161
|
+
logicalMessageId: syntheticId,
|
|
162
|
+
revisionId: syntheticId,
|
|
163
|
+
mentioned: true,
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
};
|
|
167
|
+
},
|
|
168
|
+
});
|
|
147
169
|
}
|
|
148
170
|
async start(sink) {
|
|
149
171
|
if (this.failStart)
|
|
@@ -207,12 +229,19 @@ export class FakeAdapter {
|
|
|
207
229
|
openModal;
|
|
208
230
|
// --- test helpers ---
|
|
209
231
|
emitTurn(partial) {
|
|
232
|
+
const syntheticId = partial.eventId ?? `fake-message-${++this.turnCounter}`;
|
|
210
233
|
void this.sink?.onTurn({
|
|
211
234
|
conversationKey: "c",
|
|
212
235
|
replyTarget: {},
|
|
213
236
|
userText: "",
|
|
214
237
|
platform: "fake",
|
|
215
238
|
...partial,
|
|
239
|
+
operation: partial.operation ?? {
|
|
240
|
+
kind: "created",
|
|
241
|
+
logicalMessageId: syntheticId,
|
|
242
|
+
revisionId: syntheticId,
|
|
243
|
+
mentioned: true,
|
|
244
|
+
},
|
|
216
245
|
});
|
|
217
246
|
}
|
|
218
247
|
emitThreadStarted(partial) {
|
|
@@ -24,5 +24,10 @@ export declare class FakeAgent extends AbstractAgent {
|
|
|
24
24
|
run(_input: RunAgentInput): ReturnType<AbstractAgent["run"]>;
|
|
25
25
|
runAgent(_parameters?: RunAgentParameters, subscriber?: AgentSubscriber): Promise<RunAgentResult>;
|
|
26
26
|
abortRun(): void;
|
|
27
|
+
/**
|
|
28
|
+
* Distinct instance for concurrent channel turns (singleton agent isolation).
|
|
29
|
+
* Copies the remaining script so both prototype and clone can still drive steps.
|
|
30
|
+
*/
|
|
31
|
+
clone(): FakeAgent;
|
|
27
32
|
}
|
|
28
33
|
//# sourceMappingURL=fake-agent.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fake-agent.d.ts","sourceRoot":"","sources":["../../src/testing/fake-agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EAClB,cAAc,EACf,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAChC,UAAU,EAAE,eAAe,KACxB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B;;;;GAIG;AACH,qBAAa,SAAU,SAAQ,aAAa;IAC1C,OAAO,CAAC,MAAM,CAAwB;IACtC,kFAAkF;IAClF,aAAa,SAAK;IAClB,uCAAuC;IACvC,OAAO,UAAS;gBAEJ,MAAM,GAAE,mBAAmB,EAAO;IAK9C,SAAS,CAAC,MAAM,EAAE,mBAAmB,EAAE,GAAG,IAAI;IAM9C,GAAG,CAAC,MAAM,EAAE,aAAa,GAAG,UAAU,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAI7C,QAAQ,CACrB,WAAW,CAAC,EAAE,kBAAkB,EAChC,UAAU,CAAC,EAAE,eAAe,GAC3B,OAAO,CAAC,cAAc,CAAC;IASjB,QAAQ,IAAI,IAAI;
|
|
1
|
+
{"version":3,"file":"fake-agent.d.ts","sourceRoot":"","sources":["../../src/testing/fake-agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EAClB,cAAc,EACf,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAChC,UAAU,EAAE,eAAe,KACxB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B;;;;GAIG;AACH,qBAAa,SAAU,SAAQ,aAAa;IAC1C,OAAO,CAAC,MAAM,CAAwB;IACtC,kFAAkF;IAClF,aAAa,SAAK;IAClB,uCAAuC;IACvC,OAAO,UAAS;gBAEJ,MAAM,GAAE,mBAAmB,EAAO;IAK9C,SAAS,CAAC,MAAM,EAAE,mBAAmB,EAAE,GAAG,IAAI;IAM9C,GAAG,CAAC,MAAM,EAAE,aAAa,GAAG,UAAU,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAI7C,QAAQ,CACrB,WAAW,CAAC,EAAE,kBAAkB,EAChC,UAAU,CAAC,EAAE,eAAe,GAC3B,OAAO,CAAC,cAAc,CAAC;IASjB,QAAQ,IAAI,IAAI;IAIzB;;;OAGG;IACM,KAAK,IAAI,SAAS;CAQ5B"}
|
|
@@ -33,4 +33,16 @@ export class FakeAgent extends AbstractAgent {
|
|
|
33
33
|
abortRun() {
|
|
34
34
|
this.aborted = true;
|
|
35
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Distinct instance for concurrent channel turns (singleton agent isolation).
|
|
38
|
+
* Copies the remaining script so both prototype and clone can still drive steps.
|
|
39
|
+
*/
|
|
40
|
+
clone() {
|
|
41
|
+
const cloned = new FakeAgent(this.script);
|
|
42
|
+
cloned.threadId = this.threadId;
|
|
43
|
+
cloned.agentId = this.agentId;
|
|
44
|
+
cloned.messages = structuredClone(this.messages);
|
|
45
|
+
cloned.state = structuredClone(this.state);
|
|
46
|
+
return cloned;
|
|
47
|
+
}
|
|
36
48
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thread-promise-contract.test.d.ts","sourceRoot":"","sources":["../src/thread-promise-contract.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { expect, test } from "vitest";
|
|
2
|
+
import { ActionRegistry } from "./action-registry.js";
|
|
3
|
+
import { InMemoryActionStore } from "./action-store.js";
|
|
4
|
+
import { MemoryStore } from "./state/memory-store.js";
|
|
5
|
+
import { FakeAdapter } from "./testing/fake-adapter.js";
|
|
6
|
+
import { Thread } from "./thread.js";
|
|
7
|
+
function setupThreadWithSyncDeleteFailure(failure) {
|
|
8
|
+
const adapter = new FakeAdapter();
|
|
9
|
+
adapter.delete = () => {
|
|
10
|
+
throw failure;
|
|
11
|
+
};
|
|
12
|
+
const deps = {
|
|
13
|
+
adapter,
|
|
14
|
+
replyTarget: {},
|
|
15
|
+
conversationKey: "thread-promise-contract",
|
|
16
|
+
registry: new ActionRegistry({ store: new InMemoryActionStore() }),
|
|
17
|
+
agentFactory: (threadId) => {
|
|
18
|
+
throw new Error(`agentFactory not needed in this test: ${threadId}`);
|
|
19
|
+
},
|
|
20
|
+
tools: new Map(),
|
|
21
|
+
toolDescriptors: [],
|
|
22
|
+
context: [],
|
|
23
|
+
registerWaiter: () => undefined,
|
|
24
|
+
interruptHandlers: new Map(),
|
|
25
|
+
state: new MemoryStore(),
|
|
26
|
+
};
|
|
27
|
+
return new Thread(deps);
|
|
28
|
+
}
|
|
29
|
+
test("a synchronous non-managed adapter failure returns a rejected Promise", async () => {
|
|
30
|
+
const failure = new Error("adapter delete failed synchronously");
|
|
31
|
+
const thread = setupThreadWithSyncDeleteFailure(failure);
|
|
32
|
+
let deletion;
|
|
33
|
+
expect(() => {
|
|
34
|
+
deletion = thread.delete({ id: "message-1" });
|
|
35
|
+
}).not.toThrow();
|
|
36
|
+
await expect(deletion).rejects.toBe(failure);
|
|
37
|
+
});
|
package/dist/thread.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ import type { StateStore } from "./state/state-store.js";
|
|
|
8
8
|
import type { StandardSchemaV1 } from "./standard-schema.js";
|
|
9
9
|
export interface ThreadDeps {
|
|
10
10
|
adapter: PlatformAdapter;
|
|
11
|
+
/** Source provider for this ingress event; falls back to the adapter identity. */
|
|
12
|
+
platform?: string;
|
|
11
13
|
replyTarget: ReplyTarget;
|
|
12
14
|
conversationKey: string;
|
|
13
15
|
registry: ActionRegistry;
|
|
@@ -50,8 +52,10 @@ export declare class Thread implements ThreadInterface {
|
|
|
50
52
|
/** Mirrors the adapter's `supportsBlockingChoice` capability (see SurfaceCapabilities). */
|
|
51
53
|
readonly supportsBlockingChoice?: boolean;
|
|
52
54
|
private readonly store;
|
|
55
|
+
private implicitInboundConsumed;
|
|
53
56
|
constructor(deps: ThreadDeps);
|
|
54
57
|
private bindForPost;
|
|
58
|
+
private trackOperation;
|
|
55
59
|
/**
|
|
56
60
|
* Wire a posted message's `onReaction` to its returned id: cache it for this
|
|
57
61
|
* process and, when it came from a component, persist a durable snapshot so a
|
|
@@ -70,6 +74,7 @@ export declare class Thread implements ThreadInterface {
|
|
|
70
74
|
}): Promise<{
|
|
71
75
|
ok: boolean;
|
|
72
76
|
fileId?: string;
|
|
77
|
+
assetId?: string;
|
|
73
78
|
error?: string;
|
|
74
79
|
}>;
|
|
75
80
|
/** Pin suggested prompts (returns `{ ok: false }` on surfaces without support). */
|
package/dist/thread.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thread.d.ts","sourceRoot":"","sources":["../src/thread.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAC1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EACV,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,YAAY,EACZ,aAAa,EACb,eAAe,EACf,MAAM,IAAI,eAAe,EACzB,UAAU,EACV,eAAe,EAChB,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"thread.d.ts","sourceRoot":"","sources":["../src/thread.ts"],"names":[],"mappings":"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"}
|