@threadplane/ag-ui 0.0.47 → 0.0.49
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 +128 -14
- package/fesm2022/threadplane-ag-ui.mjs +128 -17
- package/fesm2022/threadplane-ag-ui.mjs.map +1 -1
- package/package.json +9 -1
- package/types/threadplane-ag-ui.d.ts +39 -22
package/README.md
CHANGED
|
@@ -1,8 +1,33 @@
|
|
|
1
1
|
# @threadplane/ag-ui
|
|
2
2
|
|
|
3
|
-
Adapter that wraps an [AG-UI](https://github.com/ag-ui-protocol/ag-ui) `AbstractAgent` into the runtime-neutral `Agent` contract from `@threadplane/chat`. Works with any AG-UI-compatible backend
|
|
3
|
+
Adapter that wraps an [AG-UI](https://github.com/ag-ui-protocol/ag-ui) `AbstractAgent` into the runtime-neutral `Agent` contract from `@threadplane/chat`. Works with any AG-UI-compatible backend.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://www.npmjs.com/package/@threadplane/ag-ui">
|
|
7
|
+
<img alt="npm version" src="https://img.shields.io/npm/v/@threadplane%2Fag-ui?color=6C8EFF&labelColor=080B14&style=flat-square" />
|
|
8
|
+
</a>
|
|
9
|
+
<a href="https://angular.dev">
|
|
10
|
+
<img alt="Angular 20+" src="https://img.shields.io/badge/Angular-20%2B%20%7C%2021-6C8EFF?labelColor=080B14&style=flat-square" />
|
|
11
|
+
</a>
|
|
12
|
+
<a href="../../LICENSE">
|
|
13
|
+
<img alt="MIT" src="https://img.shields.io/badge/License-MIT-6C8EFF?labelColor=080B14&style=flat-square" />
|
|
14
|
+
</a>
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
Part of [Threadplane](https://github.com/cacheplane/angular-agent-framework).
|
|
18
|
+
|
|
19
|
+
> Talking to LangGraph Platform directly? See [`@threadplane/langgraph`](https://www.npmjs.com/package/@threadplane/langgraph) — same API shape, LangGraph SDK underneath.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## What it does
|
|
24
|
+
|
|
25
|
+
- Bridges any AG-UI-compatible backend into the Threadplane chat surface via `toAgent()`.
|
|
26
|
+
- Supports: LangGraph, CrewAI, Mastra, Microsoft Agent Framework, AG2, Pydantic AI, AWS Strands, CopilotKit runtime.
|
|
27
|
+
- Exposes messages, status, tool calls, and raw AG-UI state as Angular Signals, plus `submit()`/`stop()`/`regenerate()` actions — coverage depends on what the AG-UI backend emits.
|
|
28
|
+
- Ships `FakeAgent` and `provideFakeAgent` test doubles for unit testing without a live backend.
|
|
29
|
+
|
|
30
|
+
---
|
|
6
31
|
|
|
7
32
|
## Install
|
|
8
33
|
|
|
@@ -10,32 +35,95 @@ Part of [Threadplane](https://github.com/cacheplane/angular-agent-framework). MI
|
|
|
10
35
|
npm install @threadplane/ag-ui @threadplane/chat @ag-ui/client
|
|
11
36
|
```
|
|
12
37
|
|
|
38
|
+
**Peer dependencies:** `@threadplane/chat: *`, `@angular/core: ^20.0.0 || ^21.0.0`, `@ag-ui/client: *`, `rxjs: ~7.8.0`
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
13
42
|
## Quick start
|
|
14
43
|
|
|
15
|
-
|
|
16
|
-
import { provideAgUiAgent, AG_UI_AGENT } from '@threadplane/ag-ui';
|
|
17
|
-
import { ChatComponent } from '@threadplane/chat';
|
|
44
|
+
Register the agent in your `ApplicationConfig`, then inject it into a component and bind it to `<chat>`.
|
|
18
45
|
|
|
46
|
+
```ts
|
|
19
47
|
// app.config.ts
|
|
48
|
+
import { provideAgent } from '@threadplane/ag-ui';
|
|
49
|
+
|
|
20
50
|
export const appConfig: ApplicationConfig = {
|
|
21
|
-
providers: [
|
|
51
|
+
providers: [provideAgent({ url: 'https://your.agent.endpoint' })],
|
|
22
52
|
};
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
// app.component.ts
|
|
57
|
+
import { Component } from '@angular/core';
|
|
58
|
+
import { ChatComponent } from '@threadplane/chat';
|
|
59
|
+
import { injectAgent } from '@threadplane/ag-ui';
|
|
23
60
|
|
|
24
|
-
// component
|
|
25
61
|
@Component({
|
|
26
62
|
imports: [ChatComponent],
|
|
27
63
|
template: `<chat [agent]="agent" />`,
|
|
28
64
|
})
|
|
65
|
+
export class AppComponent {
|
|
66
|
+
protected readonly agent = injectAgent();
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Both `@threadplane/langgraph` and `@threadplane/ag-ui` expose `provideAgent`/`injectAgent` with the same shape — consumer code is identical regardless of which adapter is wired in.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Capabilities
|
|
75
|
+
|
|
76
|
+
`toAgent()` translates AG-UI events into Angular Signals on the runtime-neutral `Agent` contract:
|
|
77
|
+
|
|
78
|
+
| Signal | Description |
|
|
79
|
+
|---|---|
|
|
80
|
+
| `messages()` | Chat message history |
|
|
81
|
+
| `status()` | `'idle' \| 'running' \| 'error'` |
|
|
82
|
+
| `isLoading()` | True while a run is active |
|
|
83
|
+
| `toolCalls()` | In-progress and completed tool calls |
|
|
84
|
+
| `error()` | Last run error, if any |
|
|
85
|
+
| `state()` | Raw AG-UI state snapshot |
|
|
86
|
+
|
|
87
|
+
Which capabilities populate depends on the events the AG-UI backend emits. `submit()`, `stop()`, and `regenerate()` are supported.
|
|
88
|
+
|
|
89
|
+
### Interrupts (human-in-the-loop)
|
|
90
|
+
|
|
91
|
+
`agent.interrupt()` is a `Signal<AgentInterrupt | undefined>` populated from AG-UI `CUSTOM` events with `name: 'on_interrupt'`. The reducer JSON-parses string-serialized `value` payloads automatically (e.g. `ag-ui-langgraph` ships interrupts via `dump_json_safe`), so consumers see the structured object directly.
|
|
92
|
+
|
|
93
|
+
Resume with `agent.submit({ resume })` — this calls `runAgent({ forwardedProps: { command: { resume } } })`, and the server reads `forwarded_props.command.resume` (the `ag-ui-langgraph` convention).
|
|
94
|
+
|
|
95
|
+
Pair with `<chat-approval-card>` from `@threadplane/chat` for the approve/reject/edit UX:
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
import { Component } from '@angular/core';
|
|
99
|
+
import { ChatComponent, ChatApprovalCardComponent } from '@threadplane/chat';
|
|
100
|
+
import { injectAgent } from '@threadplane/ag-ui';
|
|
101
|
+
|
|
102
|
+
@Component({
|
|
103
|
+
imports: [ChatComponent, ChatApprovalCardComponent],
|
|
104
|
+
template: `
|
|
105
|
+
<chat [agent]="agent" />
|
|
106
|
+
<chat-approval-card
|
|
107
|
+
[agent]="agent"
|
|
108
|
+
matchKind="refund_approval"
|
|
109
|
+
(action)="onAction($event)" />
|
|
110
|
+
`,
|
|
111
|
+
})
|
|
29
112
|
export class App {
|
|
30
|
-
protected readonly agent =
|
|
113
|
+
protected readonly agent = injectAgent();
|
|
114
|
+
onAction(a: 'approve' | 'cancel') {
|
|
115
|
+
void this.agent.submit({ resume: { approved: a === 'approve' } });
|
|
116
|
+
}
|
|
31
117
|
}
|
|
32
118
|
```
|
|
33
119
|
|
|
34
|
-
|
|
120
|
+
See `cockpit/ag-ui/interrupts` for a complete working example, and the [LangGraph interrupts guide](https://threadplane.ai/docs/langgraph/guides/interrupts) for the broader HITL contract — the same `Agent.interrupt` / `submit({ resume })` API works across both adapters.
|
|
121
|
+
|
|
122
|
+
### Citations
|
|
35
123
|
|
|
36
|
-
|
|
124
|
+
`bridgeCitationsState(thread, messages)` populates `Message.citations` from AG-UI state. Citations live under the `citations` key of the agent state, keyed by message ID (`state.citations[messageId]`).
|
|
37
125
|
|
|
38
|
-
|
|
126
|
+
Example state shape:
|
|
39
127
|
|
|
40
128
|
```json
|
|
41
129
|
{
|
|
@@ -55,14 +143,40 @@ The `bridgeCitationsState()` function populates `Message.citations` from AG-UI S
|
|
|
55
143
|
}
|
|
56
144
|
```
|
|
57
145
|
|
|
58
|
-
Each citation
|
|
146
|
+
Each citation supports `id`, `index`, `title`, `url`, `snippet`, and custom `extra` fields. The message ID key matches the corresponding message in the chat history.
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Testing
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
// Fake backend — streams canned tokens, no server:
|
|
154
|
+
import { provideFakeAgent } from '@threadplane/ag-ui';
|
|
155
|
+
providers: [provideFakeAgent({ tokens: ['Hello', ' world'] })];
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
For component/unit tests, use the neutral writable-signal mock `mockAgent()`
|
|
159
|
+
from `@threadplane/chat` — the ag-ui agent _is_ the neutral `Agent` contract,
|
|
160
|
+
so there is no adapter-specific mock. See
|
|
161
|
+
[Choosing an adapter → Testing](https://threadplane.ai/docs/choosing-an-adapter#testing).
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Reliability
|
|
166
|
+
|
|
167
|
+
`@threadplane/ag-ui` shares the same runtime-neutral `Agent` contract as `@threadplane/langgraph`, making it interchangeable at the `<chat [agent]>` binding. The library follows a patch-only `0.0.x` release policy. The CI job "Library — lint / test / build" runs lint, test, and build on every pull request.
|
|
168
|
+
|
|
169
|
+
---
|
|
59
170
|
|
|
60
171
|
## Documentation
|
|
61
172
|
|
|
62
|
-
- [Quickstart](https://threadplane.ai/docs/
|
|
173
|
+
- [Quickstart](https://threadplane.ai/docs/ag-ui/getting-started/quickstart)
|
|
63
174
|
- [AG-UI adapter guide](https://threadplane.ai/docs/chat/guides/writing-an-adapter)
|
|
64
175
|
- [AG-UI protocol](https://github.com/ag-ui-protocol/ag-ui)
|
|
176
|
+
- [Choosing an adapter (LangGraph vs AG-UI)](https://threadplane.ai/docs/choosing-an-adapter)
|
|
177
|
+
|
|
178
|
+
---
|
|
65
179
|
|
|
66
180
|
## License
|
|
67
181
|
|
|
68
|
-
MIT
|
|
182
|
+
MIT. See [LICENSE](../../LICENSE).
|
|
@@ -288,6 +288,8 @@ function reduceEvent(event, store) {
|
|
|
288
288
|
store.status.set('running');
|
|
289
289
|
store.isLoading.set(true);
|
|
290
290
|
store.error.set(null);
|
|
291
|
+
store.interrupt.set(undefined);
|
|
292
|
+
store.customEvents.set([]);
|
|
291
293
|
return;
|
|
292
294
|
}
|
|
293
295
|
case 'RUN_FINISHED': {
|
|
@@ -358,6 +360,23 @@ function reduceEvent(event, store) {
|
|
|
358
360
|
...prev,
|
|
359
361
|
{ id: e.toolCallId, name: e.toolCallName, args: {}, status: 'running' },
|
|
360
362
|
]);
|
|
363
|
+
// Link the tool call to its parent assistant message so the chat lib's
|
|
364
|
+
// per-message tool-call resolution (chat-tool-calls / chat-tool-views)
|
|
365
|
+
// can scope it. ag-ui-langgraph emits parentMessageId for every tool
|
|
366
|
+
// call. If the parent assistant message hasn't been created yet (a
|
|
367
|
+
// tool-call-only turn emits no TEXT_MESSAGE_START), create a slot.
|
|
368
|
+
const parentId = e.parentMessageId;
|
|
369
|
+
if (parentId) {
|
|
370
|
+
store.messages.update((prev) => {
|
|
371
|
+
const existing = prev.find((m) => m.id === parentId);
|
|
372
|
+
if (existing) {
|
|
373
|
+
return prev.map((m) => m.id === parentId
|
|
374
|
+
? { ...m, toolCallIds: [...(m.toolCallIds ?? []), e.toolCallId] }
|
|
375
|
+
: m);
|
|
376
|
+
}
|
|
377
|
+
return [...prev, { id: parentId, role: 'assistant', content: '', toolCallIds: [e.toolCallId] }];
|
|
378
|
+
});
|
|
379
|
+
}
|
|
361
380
|
return;
|
|
362
381
|
}
|
|
363
382
|
case 'TOOL_CALL_ARGS': {
|
|
@@ -373,7 +392,11 @@ function reduceEvent(event, store) {
|
|
|
373
392
|
}
|
|
374
393
|
case 'TOOL_CALL_RESULT': {
|
|
375
394
|
const e = event;
|
|
376
|
-
|
|
395
|
+
// ag_ui_langgraph serialises tool results via normalize_tool_content()
|
|
396
|
+
// which always returns a string. Parse it so downstream consumers
|
|
397
|
+
// (chat-tool-views / toToolViewSpec) can spread the object into props.
|
|
398
|
+
const result = typeof e.content === 'string' ? safeParseJson(e.content) : e.content;
|
|
399
|
+
store.toolCalls.update((prev) => prev.map((t) => t.id === e.toolCallId ? { ...t, result } : t));
|
|
377
400
|
return;
|
|
378
401
|
}
|
|
379
402
|
case 'STATE_SNAPSHOT': {
|
|
@@ -392,16 +415,61 @@ function reduceEvent(event, store) {
|
|
|
392
415
|
}
|
|
393
416
|
case 'MESSAGES_SNAPSHOT': {
|
|
394
417
|
const e = event;
|
|
395
|
-
|
|
418
|
+
const raw = e.messages ?? [];
|
|
419
|
+
// AG-UI AssistantMessage carries `toolCalls` (ToolCall objects) on the
|
|
420
|
+
// snapshot wire. Bridge them to `toolCallIds` so that the chat lib's
|
|
421
|
+
// per-message tool-call resolution (resolveMessageToolCalls) can scope
|
|
422
|
+
// correctly. Also merge any snapshot-only tool calls into store.toolCalls
|
|
423
|
+
// so the data is visible to <chat-tool-views>.
|
|
424
|
+
const snapshotToolCalls = [];
|
|
425
|
+
const messages = raw.map((m) => {
|
|
426
|
+
if (m.role !== 'assistant' || !m.toolCalls || m.toolCalls.length === 0) {
|
|
427
|
+
return m;
|
|
428
|
+
}
|
|
429
|
+
const ids = [];
|
|
430
|
+
for (const tc of m.toolCalls) {
|
|
431
|
+
ids.push(tc.id);
|
|
432
|
+
snapshotToolCalls.push({
|
|
433
|
+
id: tc.id,
|
|
434
|
+
name: tc.function.name,
|
|
435
|
+
args: safeParseArgs(tc.function.arguments),
|
|
436
|
+
status: 'complete',
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
const { toolCalls: _dropped, ...rest } = m;
|
|
440
|
+
return { ...rest, toolCallIds: ids };
|
|
441
|
+
});
|
|
442
|
+
store.messages.set(messages);
|
|
443
|
+
if (snapshotToolCalls.length > 0) {
|
|
444
|
+
store.toolCalls.update((prev) => {
|
|
445
|
+
// Merge: keep existing entries (they may carry richer state from
|
|
446
|
+
// streaming) and only insert entries not already present by id.
|
|
447
|
+
const existingIds = new Set(prev.map((tc) => tc.id));
|
|
448
|
+
const toAdd = snapshotToolCalls.filter((tc) => !existingIds.has(tc.id));
|
|
449
|
+
return toAdd.length > 0 ? [...prev, ...toAdd] : prev;
|
|
450
|
+
});
|
|
451
|
+
}
|
|
396
452
|
return;
|
|
397
453
|
}
|
|
398
454
|
case 'CUSTOM': {
|
|
399
455
|
const e = event;
|
|
400
|
-
|
|
401
|
-
|
|
456
|
+
// ag_ui_langgraph serializes interrupt payloads as JSON strings.
|
|
457
|
+
// Parse the value if it arrives as a string so downstream consumers
|
|
458
|
+
// (e.g. ChatApprovalCardComponent) receive a plain object, not a string.
|
|
459
|
+
const parsedValue = typeof e.value === 'string' ? safeParseJson(e.value) : e.value;
|
|
460
|
+
if (e.name === 'on_interrupt') {
|
|
461
|
+
store.interrupt.set({ id: randomId$1(), value: parsedValue, resumable: true });
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
// Surface every other custom event on the customEvents signal so the
|
|
465
|
+
// chat a2ui partial-args bridge (which reads agent.customEvents()) lights
|
|
466
|
+
// up live/progressive a2ui rendering — parity with the LangGraph adapter.
|
|
467
|
+
store.customEvents.update((prev) => [...prev, { name: e.name, data: parsedValue }]);
|
|
468
|
+
if (e.name === 'state_update' && isRecord(parsedValue)) {
|
|
469
|
+
store.events$.next({ type: 'state_update', data: parsedValue });
|
|
402
470
|
}
|
|
403
471
|
else {
|
|
404
|
-
store.events$.next({ type: 'custom', name: e.name, data:
|
|
472
|
+
store.events$.next({ type: 'custom', name: e.name, data: parsedValue });
|
|
405
473
|
}
|
|
406
474
|
return;
|
|
407
475
|
}
|
|
@@ -413,6 +481,9 @@ function reduceEvent(event, store) {
|
|
|
413
481
|
}
|
|
414
482
|
}
|
|
415
483
|
}
|
|
484
|
+
function randomId$1() {
|
|
485
|
+
return Math.random().toString(36).slice(2);
|
|
486
|
+
}
|
|
416
487
|
function messageIdFrom(event) {
|
|
417
488
|
return event.messageId ?? 'unknown';
|
|
418
489
|
}
|
|
@@ -425,6 +496,15 @@ function safeParseArgs(delta) {
|
|
|
425
496
|
return {};
|
|
426
497
|
}
|
|
427
498
|
}
|
|
499
|
+
/** Parse a JSON string to its value; return the original string on failure. */
|
|
500
|
+
function safeParseJson(s) {
|
|
501
|
+
try {
|
|
502
|
+
return JSON.parse(s);
|
|
503
|
+
}
|
|
504
|
+
catch {
|
|
505
|
+
return s;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
428
508
|
function isRecord(v) {
|
|
429
509
|
return typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
430
510
|
}
|
|
@@ -477,7 +557,9 @@ function toAgent(source, options = {}) {
|
|
|
477
557
|
error: signal(null),
|
|
478
558
|
toolCalls: signal([]),
|
|
479
559
|
state: signal({}),
|
|
560
|
+
interrupt: signal(undefined),
|
|
480
561
|
events$: new Subject(),
|
|
562
|
+
customEvents: signal([]),
|
|
481
563
|
};
|
|
482
564
|
const telemetryProperties = { transport: 'ag-ui', surface: 'to_agent' };
|
|
483
565
|
let activeRun = null;
|
|
@@ -534,8 +616,28 @@ function toAgent(source, options = {}) {
|
|
|
534
616
|
error: store.error,
|
|
535
617
|
toolCalls: store.toolCalls,
|
|
536
618
|
state: store.state,
|
|
619
|
+
interrupt: store.interrupt,
|
|
537
620
|
events$: store.events$.asObservable(),
|
|
621
|
+
customEvents: store.customEvents,
|
|
538
622
|
submit: async (input, _opts) => {
|
|
623
|
+
if (input.resume !== undefined) {
|
|
624
|
+
// Resume path: clear the pending interrupt and replay the run with the
|
|
625
|
+
// resume payload forwarded to the LangGraph backend via AG-UI's
|
|
626
|
+
// forwardedProps.command.resume mechanism.
|
|
627
|
+
store.interrupt.set(undefined);
|
|
628
|
+
const run = startRunTelemetry('resume');
|
|
629
|
+
try {
|
|
630
|
+
await source.runAgent({ forwardedProps: { command: { resume: input.resume } } });
|
|
631
|
+
finishRunTelemetry(run);
|
|
632
|
+
}
|
|
633
|
+
catch (err) {
|
|
634
|
+
store.status.set('error');
|
|
635
|
+
store.isLoading.set(false);
|
|
636
|
+
store.error.set(err);
|
|
637
|
+
failRunTelemetry(err, run);
|
|
638
|
+
}
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
539
641
|
// Optimistic append of user message to our signals and to the source
|
|
540
642
|
// agent's own message list so runAgent() sees the new message.
|
|
541
643
|
const userMsg = buildUserMessage(input);
|
|
@@ -617,18 +719,27 @@ function randomId() {
|
|
|
617
719
|
}
|
|
618
720
|
|
|
619
721
|
// SPDX-License-Identifier: MIT
|
|
620
|
-
|
|
722
|
+
/** @internal — exported for spec access only. Consumers must use injectAgent(). */
|
|
723
|
+
const AGENT = new InjectionToken('AGENT');
|
|
621
724
|
/**
|
|
622
725
|
* Provides an Agent instance wired through HttpAgent and toAgent.
|
|
623
726
|
* Constructs an HttpAgent from config and wraps it in the runtime-neutral
|
|
624
727
|
* Agent contract via toAgent(). Returns a provider array suitable for
|
|
625
728
|
* bootstrapApplication or TestBed.configureTestingModule().
|
|
729
|
+
*
|
|
730
|
+
* **Static vs factory config.** Pass a plain `AgentConfig` object when the
|
|
731
|
+
* config is known up front. Pass a `() => AgentConfig` factory when the config
|
|
732
|
+
* depends on runtime/DI state — the factory runs inside an Angular injection
|
|
733
|
+
* context, so it may call `inject()` to read services or route params.
|
|
626
734
|
*/
|
|
627
|
-
function
|
|
735
|
+
function provideAgent(configOrFactory) {
|
|
628
736
|
return [
|
|
629
737
|
{
|
|
630
|
-
provide:
|
|
738
|
+
provide: AGENT,
|
|
631
739
|
useFactory: () => {
|
|
740
|
+
// useFactory runs in an injection context, so a config factory may
|
|
741
|
+
// call inject() to read runtime/DI state.
|
|
742
|
+
const config = typeof configOrFactory === 'function' ? configOrFactory() : configOrFactory;
|
|
632
743
|
const source = new HttpAgent({
|
|
633
744
|
url: config.url,
|
|
634
745
|
...(config.agentId !== undefined ? { agentId: config.agentId } : {}),
|
|
@@ -641,11 +752,11 @@ function provideAgUiAgent(config) {
|
|
|
641
752
|
];
|
|
642
753
|
}
|
|
643
754
|
/**
|
|
644
|
-
* Injects the
|
|
645
|
-
* Use this in components or services that have been provided via
|
|
755
|
+
* Injects the Agent from Angular's dependency injection container.
|
|
756
|
+
* Use this in components or services that have been provided via provideAgent().
|
|
646
757
|
*/
|
|
647
|
-
function
|
|
648
|
-
return inject(
|
|
758
|
+
function injectAgent() {
|
|
759
|
+
return inject(AGENT);
|
|
649
760
|
}
|
|
650
761
|
|
|
651
762
|
// libs/ag-ui/src/lib/testing/fake-agent.ts
|
|
@@ -725,15 +836,15 @@ class FakeAgent extends AbstractAgent {
|
|
|
725
836
|
}
|
|
726
837
|
|
|
727
838
|
/**
|
|
728
|
-
* Registers an in-process FakeAgent under
|
|
839
|
+
* Registers an in-process FakeAgent under AGENT.
|
|
729
840
|
*
|
|
730
841
|
* Use for offline demos and development. Drop-in replacement for
|
|
731
|
-
*
|
|
842
|
+
* provideAgent({ url }) when no real backend is available.
|
|
732
843
|
*/
|
|
733
|
-
function
|
|
844
|
+
function provideFakeAgent(config = {}) {
|
|
734
845
|
return [
|
|
735
846
|
{
|
|
736
|
-
provide:
|
|
847
|
+
provide: AGENT,
|
|
737
848
|
useFactory: () => toAgent(new FakeAgent(config)),
|
|
738
849
|
},
|
|
739
850
|
];
|
|
@@ -745,5 +856,5 @@ function provideFakeAgUiAgent(config = {}) {
|
|
|
745
856
|
* Generated bundle index. Do not edit.
|
|
746
857
|
*/
|
|
747
858
|
|
|
748
|
-
export {
|
|
859
|
+
export { FakeAgent, bridgeCitationsState, injectAgent, provideAgent, provideFakeAgent, toAgent };
|
|
749
860
|
//# sourceMappingURL=threadplane-ag-ui.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"threadplane-ag-ui.mjs","sources":["../../../../libs/ag-ui/src/lib/internal/apply-patch.ts","../../../../libs/ag-ui/src/lib/bridge-citations-state.ts","../../../../libs/ag-ui/src/lib/reducer.ts","../../../../libs/ag-ui/src/lib/to-agent.ts","../../../../libs/ag-ui/src/lib/provide-ag-ui-agent.ts","../../../../libs/ag-ui/src/lib/testing/fake-agent.ts","../../../../libs/ag-ui/src/lib/testing/provide-fake-ag-ui-agent.ts","../../../../libs/ag-ui/src/public-api.ts","../../../../libs/ag-ui/src/threadplane-ag-ui.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\n// Minimal RFC-6902 JSON Patch implementation, scoped to the ops the ag-ui\n// reducer actually receives via STATE_DELTA events: add, replace, remove,\n// move, copy, test. Pure ESM, zero deps. Replaces a CommonJS-only third-party\n// dependency that broke ESM-strict consumers (Vitest, Vite test envs).\n\nexport interface JsonPatchOp {\n readonly op: 'add' | 'replace' | 'remove' | 'move' | 'copy' | 'test';\n readonly path: string;\n readonly value?: unknown;\n readonly from?: string;\n}\n\n/**\n * Apply a sequence of JSON Patch (RFC-6902) operations to `target`. Returns a\n * new document. The input is not mutated.\n *\n * Operations apply in order; if any operation fails (invalid path, failed\n * test, etc.) the whole patch throws — matching `fast-json-patch`'s\n * `validate: false` behavior used by the reducer.\n */\nexport function applyPatch<T>(target: T, ops: readonly JsonPatchOp[]): T {\n let current: unknown = target;\n for (const op of ops) {\n current = applyOne(current, op);\n }\n return current as T;\n}\n\nfunction applyOne(doc: unknown, op: JsonPatchOp): unknown {\n switch (op.op) {\n case 'add': return setAt(doc, parsePointer(op.path), op.value, /*replaceArrayDash*/ true);\n case 'replace': return setAt(doc, parsePointer(op.path), op.value, /*replaceArrayDash*/ false);\n case 'remove': return removeAt(doc, parsePointer(op.path));\n case 'move': {\n if (op.from == null) throw new Error(\"'move' op requires 'from'\");\n const fromTokens = parsePointer(op.from);\n const value = getAt(doc, fromTokens);\n const removed = removeAt(doc, fromTokens);\n return setAt(removed, parsePointer(op.path), value, true);\n }\n case 'copy': {\n if (op.from == null) throw new Error(\"'copy' op requires 'from'\");\n const value = getAt(doc, parsePointer(op.from));\n return setAt(doc, parsePointer(op.path), structuredCloneSafe(value), true);\n }\n case 'test': {\n const actual = getAt(doc, parsePointer(op.path));\n if (!deepEqual(actual, op.value)) {\n throw new Error(`'test' op failed at path ${op.path}`);\n }\n return doc;\n }\n default: {\n const o: { op: string } = op as never;\n throw new Error(`Unsupported JSON Patch op: ${o.op}`);\n }\n }\n}\n\n/**\n * Parse an RFC-6901 JSON Pointer string into its tokens.\n * \"\" → []\n * \"/foo/0\" → [\"foo\", \"0\"]\n * \"/a~1b\" → [\"a/b\"] (~1 → /)\n * \"/a~0b\" → [\"a~b\"] (~0 → ~)\n */\nexport function parsePointer(pointer: string): string[] {\n if (pointer === '') return [];\n if (!pointer.startsWith('/')) {\n throw new Error(`Invalid JSON Pointer: ${pointer}`);\n }\n return pointer\n .slice(1)\n .split('/')\n .map(token => token.replace(/~1/g, '/').replace(/~0/g, '~'));\n}\n\nfunction getAt(doc: unknown, tokens: readonly string[]): unknown {\n let cur: unknown = doc;\n for (const token of tokens) {\n cur = stepInto(cur, token);\n }\n return cur;\n}\n\nfunction stepInto(node: unknown, token: string): unknown {\n if (Array.isArray(node)) {\n const i = parseArrayIndex(token, node.length);\n return node[i];\n }\n if (node !== null && typeof node === 'object') {\n return (node as Record<string, unknown>)[token];\n }\n throw new Error(`Cannot traverse non-container at token \"${token}\"`);\n}\n\nfunction setAt(\n doc: unknown,\n tokens: readonly string[],\n value: unknown,\n allowArrayAppend: boolean,\n): unknown {\n if (tokens.length === 0) {\n // Replace root.\n return structuredCloneSafe(value);\n }\n const [head, ...rest] = tokens;\n if (Array.isArray(doc)) {\n const arr = doc.slice();\n const i = head === '-' && allowArrayAppend ? arr.length : parseArrayIndex(head!, arr.length + (allowArrayAppend ? 1 : 0));\n if (rest.length === 0) {\n if (allowArrayAppend) {\n // RFC-6902 add: insert at index, shifting elements right\n arr.splice(i, 0, structuredCloneSafe(value));\n } else {\n // replace: overwrite at index\n if (i >= arr.length) throw new Error(`Cannot replace beyond array length at \"/${tokens.join('/')}\"`);\n arr[i] = structuredCloneSafe(value);\n }\n } else {\n if (i >= arr.length) throw new Error(`Cannot descend into non-existent array index ${i}`);\n arr[i] = setAt(arr[i], rest, value, allowArrayAppend);\n }\n return arr;\n }\n if (doc === null || typeof doc !== 'object') {\n throw new Error(`Cannot descend into non-container at \"/${tokens.join('/')}\"`);\n }\n const obj = { ...(doc as Record<string, unknown>) };\n if (rest.length === 0) {\n obj[head!] = structuredCloneSafe(value);\n } else {\n if (!(head! in obj)) {\n throw new Error(`Cannot descend into missing path \"/${tokens.join('/')}\"`);\n }\n obj[head!] = setAt(obj[head!], rest, value, allowArrayAppend);\n }\n return obj;\n}\n\nfunction removeAt(doc: unknown, tokens: readonly string[]): unknown {\n if (tokens.length === 0) {\n throw new Error('Cannot remove root');\n }\n const [head, ...rest] = tokens;\n if (Array.isArray(doc)) {\n const arr = doc.slice();\n const i = parseArrayIndex(head!, arr.length);\n if (i >= arr.length) throw new Error(`Cannot remove non-existent array index ${i}`);\n if (rest.length === 0) {\n arr.splice(i, 1);\n } else {\n arr[i] = removeAt(arr[i], rest);\n }\n return arr;\n }\n if (doc === null || typeof doc !== 'object') {\n throw new Error(`Cannot remove from non-container at token \"${head}\"`);\n }\n const obj = { ...(doc as Record<string, unknown>) };\n if (rest.length === 0) {\n if (!(head! in obj)) throw new Error(`Cannot remove non-existent key \"${head}\"`);\n delete obj[head!];\n } else {\n if (!(head! in obj)) throw new Error(`Cannot descend into missing path \"${head}\"`);\n obj[head!] = removeAt(obj[head!], rest);\n }\n return obj;\n}\n\nfunction parseArrayIndex(token: string, lengthBound: number): number {\n if (token === '-') {\n // \"-\" is the \"after-last\" sentinel; only valid for `add` (handled by caller)\n throw new Error(`Array end marker \"-\" not valid in this position`);\n }\n if (!/^(0|[1-9]\\d*)$/.test(token)) {\n throw new Error(`Invalid array index: \"${token}\"`);\n }\n const i = Number.parseInt(token, 10);\n if (i > lengthBound) {\n throw new Error(`Array index ${i} exceeds bound ${lengthBound}`);\n }\n return i;\n}\n\nfunction structuredCloneSafe<T>(v: T): T {\n // Cheap deep clone for JSON-like values (no functions, no cycles) — matches\n // the deep-clone the reducer was already doing pre-applyPatch with the prior\n // dependency.\n if (v === null || typeof v !== 'object') return v;\n return JSON.parse(JSON.stringify(v)) as T;\n}\n\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (a === null || b === null) return false;\n if (typeof a !== 'object' || typeof b !== 'object') return false;\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!deepEqual(a[i], b[i])) return false;\n }\n return true;\n }\n const ao = a as Record<string, unknown>;\n const bo = b as Record<string, unknown>;\n const aKeys = Object.keys(ao);\n const bKeys = Object.keys(bo);\n if (aKeys.length !== bKeys.length) return false;\n for (const k of aKeys) {\n if (!Object.prototype.hasOwnProperty.call(bo, k)) return false;\n if (!deepEqual(ao[k], bo[k])) return false;\n }\n return true;\n}\n","// libs/ag-ui/src/lib/bridge-citations-state.ts\n// SPDX-License-Identifier: MIT\nimport type { Citation, Message } from '@threadplane/chat';\n\ninterface ThreadStateLike {\n state?: Record<string, unknown>;\n}\n\nexport function bridgeCitationsState(thread: ThreadStateLike, messages: Message[]): Message[] {\n const citationsByMsg = (thread.state as { citations?: unknown })?.citations;\n if (!citationsByMsg || typeof citationsByMsg !== 'object') return messages;\n const map = citationsByMsg as Record<string, unknown>;\n return messages.map(msg => {\n const raw = map[msg.id];\n if (!Array.isArray(raw) || raw.length === 0) return msg;\n return { ...msg, citations: raw.map((entry, i) => normalizeCitation(entry, i + 1)) };\n });\n}\n\nfunction normalizeCitation(entry: unknown, fallbackIndex: number): Citation {\n if (typeof entry === 'string') {\n return { id: `c${fallbackIndex}`, index: fallbackIndex, url: entry };\n }\n const e = (entry ?? {}) as Record<string, unknown>;\n const str = (key: string): string | undefined =>\n typeof e[key] === 'string' ? (e[key] as string) : undefined;\n const firstStr = (...keys: string[]): string | undefined => {\n for (const k of keys) {\n const v = str(k);\n if (v !== undefined) return v;\n }\n return undefined;\n };\n return {\n id: str('id') ?? str('refId') ?? `c${fallbackIndex}`,\n index: typeof e['index'] === 'number' ? (e['index'] as number) : fallbackIndex,\n title: firstStr('title', 'name'),\n url: firstStr('url', 'href', 'source'),\n snippet: firstStr('snippet', 'content', 'excerpt'),\n extra:\n typeof e['extra'] === 'object' && e['extra'] !== null\n ? (e['extra'] as Record<string, unknown>)\n : undefined,\n };\n}\n","// SPDX-License-Identifier: MIT\n// @ag-ui/client@0.0.52 — EventType is a string enum with uppercase values.\n// Discriminator strings (e.g. 'RUN_STARTED') match EventType enum members\n// verbatim; the switch cases below use the string literals directly so this\n// file has no runtime dependency on the EventType enum import.\nimport type { WritableSignal } from '@angular/core';\nimport type { Subject } from 'rxjs';\nimport type {\n Message, AgentStatus, ToolCall, AgentEvent,\n} from '@threadplane/chat';\nimport type { BaseEvent } from '@ag-ui/client';\nimport { applyPatch, type JsonPatchOp } from './internal/apply-patch';\nimport { bridgeCitationsState } from './bridge-citations-state';\n\nexport interface ReducerStore {\n messages: WritableSignal<Message[]>;\n status: WritableSignal<AgentStatus>;\n isLoading: WritableSignal<boolean>;\n error: WritableSignal<unknown>;\n toolCalls: WritableSignal<ToolCall[]>;\n state: WritableSignal<Record<string, unknown>>;\n events$: Subject<AgentEvent>;\n}\n\n/**\n * Per-message reasoning timing. Populated by REASONING_MESSAGE_START /\n * REASONING_MESSAGE_END handlers. The map lives on the module — same\n * scope as the reducer function. ReducerStore stays free of timing\n * state; consumers read it via `Message.reasoningDurationMs` on\n * messages that completed reasoning.\n *\n * Keyed by messageId. We do not need cross-thread isolation here:\n * AG-UI's source agent recreates the reducer pipeline per session, and\n * messageIds are unique within a session.\n */\nconst reasoningTimingMap = new Map<string, { startedAt: number; endedAt?: number }>();\n\nfunction resolveReasoningDurationMs(messageId: string): number | undefined {\n const entry = reasoningTimingMap.get(messageId);\n if (!entry || entry.endedAt === undefined) return undefined;\n return entry.endedAt - entry.startedAt;\n}\n\n/**\n * Pure function: applies a single AG-UI BaseEvent to the store. Caller\n * subscribes to source.agent() and forwards each event here. Designed\n * for testability — no side effects beyond the supplied store.\n */\nexport function reduceEvent(event: BaseEvent, store: ReducerStore): void {\n switch (event.type) {\n case 'RUN_STARTED': {\n store.status.set('running');\n store.isLoading.set(true);\n store.error.set(null);\n return;\n }\n case 'RUN_FINISHED': {\n store.status.set('idle');\n store.isLoading.set(false);\n return;\n }\n case 'RUN_ERROR': {\n store.status.set('error');\n store.isLoading.set(false);\n store.error.set((event as { message?: unknown }).message ?? event);\n return;\n }\n case 'TEXT_MESSAGE_START': {\n const id = messageIdFrom(event);\n store.messages.update((prev) =>\n prev.some((m) => m.id === id)\n ? prev.map((m) => m.id === id ? { ...m, content: m.content ?? '' } : m)\n : [...prev, { id, role: 'assistant', content: '' }],\n );\n return;\n }\n case 'REASONING_MESSAGE_START': {\n const id = messageIdFrom(event);\n reasoningTimingMap.set(id, { startedAt: Date.now() });\n // Initialize an assistant slot with empty reasoning if it doesn't already exist.\n store.messages.update((prev) =>\n prev.some((m) => m.id === id)\n ? prev.map((m) => m.id === id\n ? { ...m, reasoning: m.reasoning ?? '' }\n : m)\n : [...prev, { id, role: 'assistant', content: '', reasoning: '' }],\n );\n return;\n }\n case 'REASONING_MESSAGE_CONTENT':\n case 'REASONING_MESSAGE_CHUNK': {\n const id = messageIdFrom(event);\n const delta = (event as { delta?: string }).delta ?? '';\n store.messages.update((prev) =>\n prev.map((m) => m.id === id\n ? { ...m, reasoning: (m.reasoning ?? '') + delta }\n : m),\n );\n return;\n }\n case 'REASONING_MESSAGE_END': {\n const id = messageIdFrom(event);\n const entry = reasoningTimingMap.get(id);\n if (entry) {\n entry.endedAt = Date.now();\n reasoningTimingMap.set(id, entry);\n const duration = resolveReasoningDurationMs(id);\n if (duration !== undefined) {\n store.messages.update((prev) =>\n prev.map((m) => m.id === id ? { ...m, reasoningDurationMs: duration } : m),\n );\n }\n }\n return;\n }\n case 'TEXT_MESSAGE_CONTENT': {\n const id = messageIdFrom(event);\n const delta = (event as { delta?: string }).delta ?? '';\n store.messages.update((prev) =>\n prev.map((m) => m.id === id ? { ...m, content: m.content + delta } : m),\n );\n return;\n }\n case 'TEXT_MESSAGE_END': {\n // No-op — message is finalized by virtue of TEXT_MESSAGE_CONTENT\n // having been applied. Reserved for future hooks.\n return;\n }\n case 'TOOL_CALL_START': {\n const e = event as unknown as { toolCallId: string; toolCallName: string };\n store.toolCalls.update((prev) => [\n ...prev,\n { id: e.toolCallId, name: e.toolCallName, args: {}, status: 'running' },\n ]);\n return;\n }\n case 'TOOL_CALL_ARGS': {\n const e = event as unknown as { toolCallId: string; delta: string };\n const args = safeParseArgs(e.delta);\n store.toolCalls.update((prev) =>\n prev.map((t) => t.id === e.toolCallId ? { ...t, args } : t),\n );\n return;\n }\n case 'TOOL_CALL_END': {\n const e = event as unknown as { toolCallId: string };\n store.toolCalls.update((prev) =>\n prev.map((t) => t.id === e.toolCallId ? { ...t, status: 'complete' } : t),\n );\n return;\n }\n case 'TOOL_CALL_RESULT': {\n const e = event as unknown as { toolCallId: string; content: unknown };\n store.toolCalls.update((prev) =>\n prev.map((t) => t.id === e.toolCallId ? { ...t, result: e.content } : t),\n );\n return;\n }\n case 'STATE_SNAPSHOT': {\n const e = event as unknown as { snapshot: Record<string, unknown> };\n const snapshot = e.snapshot ?? {};\n store.state.set(snapshot);\n store.messages.update(msgs => bridgeCitationsState({ state: snapshot }, msgs));\n return;\n }\n case 'STATE_DELTA': {\n const e = event as unknown as { delta: JsonPatchOp[] };\n const next = applyPatch(deepClone(store.state()), e.delta);\n store.state.set(next);\n store.messages.update(msgs => bridgeCitationsState({ state: next }, msgs));\n return;\n }\n case 'MESSAGES_SNAPSHOT': {\n const e = event as unknown as { messages: Message[] };\n store.messages.set(e.messages ?? []);\n return;\n }\n case 'CUSTOM': {\n const e = event as unknown as { name: string; value: unknown };\n if (e.name === 'state_update' && isRecord(e.value)) {\n store.events$.next({ type: 'state_update', data: e.value });\n } else {\n store.events$.next({ type: 'custom', name: e.name, data: e.value });\n }\n return;\n }\n default: {\n // Unknown event types are ignored; AG-UI may add new ones in\n // future protocol versions. We surface them as no-ops rather\n // than throwing, so a partial-version mismatch doesn't crash.\n return;\n }\n }\n}\n\nfunction messageIdFrom(event: BaseEvent): string {\n return (event as { messageId?: string }).messageId ?? 'unknown';\n}\n\nfunction safeParseArgs(delta: string): Record<string, unknown> {\n try {\n const parsed = JSON.parse(delta);\n return isRecord(parsed) ? parsed : {};\n } catch {\n return {};\n }\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n\nfunction deepClone<T>(v: T): T {\n return JSON.parse(JSON.stringify(v));\n}\n","// SPDX-License-Identifier: MIT\nimport { signal } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport type { AbstractAgent } from '@ag-ui/client';\nimport type {\n Agent, Message, AgentStatus, ToolCall, AgentEvent,\n AgentRuntimeTelemetryEvent,\n AgentRuntimeTelemetryProperties,\n AgentRuntimeTelemetrySink,\n AgentSubmitInput, AgentSubmitOptions,\n} from '@threadplane/chat';\nimport { reduceEvent, type ReducerStore } from './reducer';\n\nexport interface ToAgentOptions {\n /** Optional app-owned telemetry sink. No telemetry is emitted unless this is provided. */\n telemetry?: AgentRuntimeTelemetrySink | false;\n}\n\nfunction captureAgentRuntimeTelemetry(\n sink: AgentRuntimeTelemetrySink | false | undefined,\n event: AgentRuntimeTelemetryEvent,\n properties: AgentRuntimeTelemetryProperties,\n): void {\n if (!sink) return;\n try {\n void Promise.resolve(sink({ event, properties })).catch(() => undefined);\n } catch {\n // Keep telemetry side effects isolated from adapter control flow.\n }\n}\n\nfunction agentRuntimeTelemetryErrorClass(error: unknown): string {\n if (error instanceof Error) return error.name || error.constructor.name || 'Error';\n if (\n error\n && typeof error === 'object'\n && 'name' in error\n && typeof error.name === 'string'\n && error.name.length > 0\n ) {\n return error.name;\n }\n return 'UnknownError';\n}\n\n/**\n * Wraps an AG-UI AbstractAgent into the runtime-neutral Agent contract.\n *\n * The adapter subscribes to source.subscribe({ onEvent }) and reduces every\n * event into the produced Agent's signals. submit() optimistically appends the\n * user message to both our signals and the source agent's internal message\n * list, then calls source.runAgent(). stop() calls source.abortRun().\n *\n * Subscription cleanup: the returned Agent does NOT manage its own lifetime.\n * Callers using DI should rely on the provider's destroy hook; direct callers\n * of toAgent() should treat the returned object's lifecycle as tied to the\n * agent instance they constructed. The subscriber registered via\n * source.subscribe() will fire for the lifetime of source.\n */\nexport function toAgent(source: AbstractAgent, options: ToAgentOptions = {}): Agent {\n const store: ReducerStore = {\n messages: signal<Message[]>([]),\n status: signal<AgentStatus>('idle'),\n isLoading: signal<boolean>(false),\n error: signal<unknown>(null),\n toolCalls: signal<ToolCall[]>([]),\n state: signal<Record<string, unknown>>({}),\n events$: new Subject<AgentEvent>(),\n };\n const telemetryProperties = { transport: 'ag-ui' as const, surface: 'to_agent' };\n let activeRun: { startedAt: number; errored: boolean } | null = null;\n\n captureAgentRuntimeTelemetry(\n options.telemetry,\n 'ngaf:runtime_instance_created',\n telemetryProperties,\n );\n\n function startRunTelemetry(requestType: string): { startedAt: number; errored: boolean } {\n const run = { startedAt: Date.now(), errored: false };\n activeRun = run;\n captureAgentRuntimeTelemetry(options.telemetry, 'ngaf:runtime_request_created', {\n ...telemetryProperties,\n requestType,\n });\n captureAgentRuntimeTelemetry(options.telemetry, 'ngaf:stream_started', telemetryProperties);\n return run;\n }\n\n function finishRunTelemetry(run: { startedAt: number; errored: boolean }): void {\n if (run.errored) return;\n captureAgentRuntimeTelemetry(options.telemetry, 'ngaf:stream_ended', {\n ...telemetryProperties,\n durationMs: Date.now() - run.startedAt,\n });\n if (activeRun === run) activeRun = null;\n }\n\n function failRunTelemetry(error: unknown, run = activeRun): void {\n if (!run || run.errored) return;\n run.errored = true;\n captureAgentRuntimeTelemetry(options.telemetry, 'ngaf:stream_errored', {\n ...telemetryProperties,\n durationMs: Date.now() - run.startedAt,\n errorClass: agentRuntimeTelemetryErrorClass(error),\n });\n if (activeRun === run) activeRun = null;\n }\n\n // Tap all events from the source agent via the AgentSubscriber API.\n // This subscription lives for the lifetime of `source`.\n source.subscribe({\n onEvent({ event }) {\n reduceEvent(event, store);\n },\n onRunFailed({ error }) {\n store.status.set('error');\n store.isLoading.set(false);\n store.error.set(error);\n failRunTelemetry(error);\n },\n });\n\n return {\n messages: store.messages,\n status: store.status,\n isLoading: store.isLoading,\n error: store.error,\n toolCalls: store.toolCalls,\n state: store.state,\n events$: store.events$.asObservable(),\n\n submit: async (input: AgentSubmitInput, _opts?: AgentSubmitOptions) => {\n // Optimistic append of user message to our signals and to the source\n // agent's own message list so runAgent() sees the new message.\n const userMsg = buildUserMessage(input);\n if (userMsg) {\n store.messages.update((prev) => [...prev, userMsg]);\n // Sync to AG-UI source so it's included in the next run's input.\n source.addMessage(userMsg as Parameters<typeof source.addMessage>[0]);\n }\n\n const run = startRunTelemetry('submit');\n try {\n await source.runAgent();\n finishRunTelemetry(run);\n } catch (err) {\n // If the run was aborted via stop(), abortRun() resolves the promise\n // rather than rejecting — but catch any unexpected errors here.\n store.status.set('error');\n store.isLoading.set(false);\n store.error.set(err);\n failRunTelemetry(err, run);\n }\n },\n\n stop: async () => {\n source.abortRun();\n },\n\n regenerate: async (assistantMessageIndex: number): Promise<void> => {\n if (store.isLoading()) {\n throw new Error('Cannot regenerate while agent is loading another response');\n }\n const msgs = store.messages();\n const target = msgs[assistantMessageIndex];\n if (!target || target.role !== 'assistant') {\n throw new Error(`Message at index ${assistantMessageIndex} is not an assistant message`);\n }\n\n // Find the user message immediately preceding the target assistant message.\n const userIdx = msgs\n .slice(0, assistantMessageIndex)\n .map((m, i) => ({ m, i }))\n .reverse()\n .find(({ m }) => m.role === 'user')?.i;\n if (userIdx === undefined) {\n throw new Error('No user message found before the target assistant message');\n }\n\n // Truncate local message buffer INCLUSIVE of the user message. This\n // preserves the user message in the UI (replace-semantics) while the\n // new assistant response streams in. The trailing user message becomes\n // the active prompt for the next run — we must NOT re-add it.\n const trimmed = msgs.slice(0, userIdx + 1);\n store.messages.set(trimmed);\n\n // Sync the trimmed list back to the source agent so its internal state\n // matches what we're about to re-run. source.setMessages() replaces the\n // agent's internal message list without appending — the trailing user\n // message in `trimmed` becomes the active prompt for the next run.\n source.setMessages(trimmed as Parameters<typeof source.setMessages>[0]);\n\n const run = startRunTelemetry('regenerate');\n try {\n await source.runAgent();\n finishRunTelemetry(run);\n } catch (err) {\n store.status.set('error');\n store.isLoading.set(false);\n store.error.set(err);\n failRunTelemetry(err, run);\n }\n },\n };\n}\n\nfunction buildUserMessage(input: AgentSubmitInput): Message | undefined {\n if (input.message === undefined) return undefined;\n const content = typeof input.message === 'string'\n ? input.message\n : input.message.map((b) => b.type === 'text' ? b.text : JSON.stringify(b)).join('');\n return { id: randomId(), role: 'user', content };\n}\n\nfunction randomId(): string {\n return Math.random().toString(36).slice(2);\n}\n","// SPDX-License-Identifier: MIT\nimport { InjectionToken, inject, type Provider } from '@angular/core';\nimport { HttpAgent } from '@ag-ui/client';\nimport type { Agent, AgentRuntimeTelemetrySink } from '@threadplane/chat';\nimport { toAgent } from './to-agent';\n\n/**\n * Configuration for the AG-UI agent provider.\n * HttpAgentConfig shape (from @ag-ui/client@0.0.52):\n * - url: string (required) — endpoint for the HTTP agent\n * - agentId: string (optional) — agent identifier\n * - threadId: string (optional) — thread identifier\n * - headers: Record<string, string> (optional) — custom HTTP headers\n */\nexport interface AgUiAgentConfig {\n url: string;\n agentId?: string;\n threadId?: string;\n headers?: Record<string, string>;\n /** Optional app-owned telemetry sink. No telemetry is emitted unless this is provided. */\n telemetry?: AgentRuntimeTelemetrySink | false;\n}\n\nexport const AG_UI_AGENT = new InjectionToken<Agent>('AG_UI_AGENT');\n\n/**\n * Provides an Agent instance wired through HttpAgent and toAgent.\n * Constructs an HttpAgent from config and wraps it in the runtime-neutral\n * Agent contract via toAgent(). Returns a provider array suitable for\n * bootstrapApplication or TestBed.configureTestingModule().\n */\nexport function provideAgUiAgent(config: AgUiAgentConfig): Provider[] {\n return [\n {\n provide: AG_UI_AGENT,\n useFactory: () => {\n const source = new HttpAgent({\n url: config.url,\n ...(config.agentId !== undefined ? { agentId: config.agentId } : {}),\n ...(config.threadId !== undefined ? { threadId: config.threadId } : {}),\n ...(config.headers !== undefined ? { headers: config.headers } : {}),\n });\n return toAgent(source, { telemetry: config.telemetry });\n },\n },\n ];\n}\n\n/**\n * Injects the AG_UI_AGENT from Angular's dependency injection container.\n * Use this in components or services that have been provided via provideAgUiAgent().\n */\nexport function injectAgUiAgent(): Agent {\n return inject(AG_UI_AGENT);\n}\n","// libs/ag-ui/src/lib/testing/fake-agent.ts\n// SPDX-License-Identifier: MIT\nimport {\n AbstractAgent,\n EventType,\n type BaseEvent,\n type RunAgentInput,\n} from '@ag-ui/client';\nimport { Observable } from 'rxjs';\n\n/**\n * In-process AG-UI agent that emits a canned streaming response.\n *\n * Use for offline demos and tests where a real backend isn't available.\n * Echoes a fixed assistant reply token-by-token with realistic timing.\n *\n * NOT for production use.\n */\nexport class FakeAgent extends AbstractAgent {\n /**\n * Tokens streamed back as the assistant reply. Override with custom\n * tokens via the constructor for varied demo content.\n */\n private readonly tokens: string[];\n\n /** Optional reasoning chunks emitted before the text reply. */\n private readonly reasoningTokens: string[];\n\n /** Milliseconds between successive token emissions. */\n private readonly delayMs: number;\n\n constructor(opts: {\n tokens?: string[];\n /** Optional reasoning chunks emitted before the text reply. */\n reasoningTokens?: string[];\n delayMs?: number;\n } = {}) {\n super();\n this.tokens = opts.tokens ?? [\n 'Hello', ' from', ' the', ' fake', ' AG-UI', ' agent.',\n ' This', ' is', ' a', ' canned', ' streaming', ' reply.',\n ];\n this.reasoningTokens = opts.reasoningTokens ?? [];\n this.delayMs = opts.delayMs ?? 60;\n }\n\n run(input: RunAgentInput): Observable<BaseEvent> {\n const tokens = this.tokens;\n const reasoningTokens = this.reasoningTokens;\n const delayMs = this.delayMs;\n const messageId = `fake-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n\n const sequence: BaseEvent[] = [\n { type: EventType.RUN_STARTED, threadId: input.threadId, runId: input.runId } as BaseEvent,\n ];\n\n if (reasoningTokens.length > 0) {\n sequence.push({ type: EventType.REASONING_MESSAGE_START, messageId, role: 'assistant' } as BaseEvent);\n for (const delta of reasoningTokens) {\n sequence.push({ type: EventType.REASONING_MESSAGE_CONTENT, messageId, delta } as BaseEvent);\n }\n sequence.push({ type: EventType.REASONING_MESSAGE_END, messageId } as BaseEvent);\n }\n\n sequence.push({ type: EventType.TEXT_MESSAGE_START, messageId, role: 'assistant' } as BaseEvent);\n for (const delta of tokens) {\n sequence.push({ type: EventType.TEXT_MESSAGE_CONTENT, messageId, delta } as BaseEvent);\n }\n sequence.push({ type: EventType.TEXT_MESSAGE_END, messageId } as BaseEvent);\n sequence.push({ type: EventType.RUN_FINISHED, threadId: input.threadId, runId: input.runId } as BaseEvent);\n\n return new Observable<BaseEvent>((observer) => {\n let cancelled = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let i = 0;\n\n const emitNext = () => {\n if (cancelled) return;\n if (i >= sequence.length) {\n observer.complete();\n return;\n }\n observer.next(sequence[i]);\n i++;\n // Steady cadence except a tiny initial delay before RUN_STARTED.\n timer = setTimeout(emitNext, delayMs);\n };\n\n timer = setTimeout(emitNext, 30);\n\n return () => {\n cancelled = true;\n if (timer !== undefined) clearTimeout(timer);\n };\n });\n }\n}\n","// libs/ag-ui/src/lib/testing/provide-fake-ag-ui-agent.ts\n// SPDX-License-Identifier: MIT\nimport { type Provider } from '@angular/core';\nimport { AG_UI_AGENT } from '../provide-ag-ui-agent';\nimport { toAgent } from '../to-agent';\nimport { FakeAgent } from './fake-agent';\n\nexport interface FakeAgUiAgentConfig {\n /** Tokens streamed back as the assistant reply. */\n tokens?: string[];\n /** Optional reasoning chunks emitted before the text reply. */\n reasoningTokens?: string[];\n /** Milliseconds between successive token emissions. */\n delayMs?: number;\n}\n\n/**\n * Registers an in-process FakeAgent under AG_UI_AGENT.\n *\n * Use for offline demos and development. Drop-in replacement for\n * provideAgUiAgent({ url }) when no real backend is available.\n */\nexport function provideFakeAgUiAgent(config: FakeAgUiAgentConfig = {}): Provider[] {\n return [\n {\n provide: AG_UI_AGENT,\n useFactory: () => toAgent(new FakeAgent(config)),\n },\n ];\n}\n","// SPDX-License-Identifier: MIT\nexport { toAgent } from './lib/to-agent';\nexport type { ToAgentOptions } from './lib/to-agent';\nexport { provideAgUiAgent, AG_UI_AGENT, injectAgUiAgent } from './lib/provide-ag-ui-agent';\nexport type { AgUiAgentConfig } from './lib/provide-ag-ui-agent';\nexport { FakeAgent } from './lib/testing/fake-agent';\nexport { provideFakeAgUiAgent } from './lib/testing/provide-fake-ag-ui-agent';\nexport type { FakeAgUiAgentConfig } from './lib/testing/provide-fake-ag-ui-agent';\n\n// Citation state bridge — useful for advanced consumers building custom\n// reducers or merging citations from non-standard state paths.\nexport { bridgeCitationsState } from './lib/bridge-citations-state';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"threadplane-ag-ui.mjs","sources":["../../../../libs/ag-ui/src/lib/internal/apply-patch.ts","../../../../libs/ag-ui/src/lib/bridge-citations-state.ts","../../../../libs/ag-ui/src/lib/reducer.ts","../../../../libs/ag-ui/src/lib/to-agent.ts","../../../../libs/ag-ui/src/lib/provide-agent.ts","../../../../libs/ag-ui/src/lib/testing/fake-agent.ts","../../../../libs/ag-ui/src/lib/testing/provide-fake-agent.ts","../../../../libs/ag-ui/src/public-api.ts","../../../../libs/ag-ui/src/threadplane-ag-ui.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\n// Minimal RFC-6902 JSON Patch implementation, scoped to the ops the ag-ui\n// reducer actually receives via STATE_DELTA events: add, replace, remove,\n// move, copy, test. Pure ESM, zero deps. Replaces a CommonJS-only third-party\n// dependency that broke ESM-strict consumers (Vitest, Vite test envs).\n\nexport interface JsonPatchOp {\n readonly op: 'add' | 'replace' | 'remove' | 'move' | 'copy' | 'test';\n readonly path: string;\n readonly value?: unknown;\n readonly from?: string;\n}\n\n/**\n * Apply a sequence of JSON Patch (RFC-6902) operations to `target`. Returns a\n * new document. The input is not mutated.\n *\n * Operations apply in order; if any operation fails (invalid path, failed\n * test, etc.) the whole patch throws — matching `fast-json-patch`'s\n * `validate: false` behavior used by the reducer.\n */\nexport function applyPatch<T>(target: T, ops: readonly JsonPatchOp[]): T {\n let current: unknown = target;\n for (const op of ops) {\n current = applyOne(current, op);\n }\n return current as T;\n}\n\nfunction applyOne(doc: unknown, op: JsonPatchOp): unknown {\n switch (op.op) {\n case 'add': return setAt(doc, parsePointer(op.path), op.value, /*replaceArrayDash*/ true);\n case 'replace': return setAt(doc, parsePointer(op.path), op.value, /*replaceArrayDash*/ false);\n case 'remove': return removeAt(doc, parsePointer(op.path));\n case 'move': {\n if (op.from == null) throw new Error(\"'move' op requires 'from'\");\n const fromTokens = parsePointer(op.from);\n const value = getAt(doc, fromTokens);\n const removed = removeAt(doc, fromTokens);\n return setAt(removed, parsePointer(op.path), value, true);\n }\n case 'copy': {\n if (op.from == null) throw new Error(\"'copy' op requires 'from'\");\n const value = getAt(doc, parsePointer(op.from));\n return setAt(doc, parsePointer(op.path), structuredCloneSafe(value), true);\n }\n case 'test': {\n const actual = getAt(doc, parsePointer(op.path));\n if (!deepEqual(actual, op.value)) {\n throw new Error(`'test' op failed at path ${op.path}`);\n }\n return doc;\n }\n default: {\n const o: { op: string } = op as never;\n throw new Error(`Unsupported JSON Patch op: ${o.op}`);\n }\n }\n}\n\n/**\n * Parse an RFC-6901 JSON Pointer string into its tokens.\n * \"\" → []\n * \"/foo/0\" → [\"foo\", \"0\"]\n * \"/a~1b\" → [\"a/b\"] (~1 → /)\n * \"/a~0b\" → [\"a~b\"] (~0 → ~)\n */\nexport function parsePointer(pointer: string): string[] {\n if (pointer === '') return [];\n if (!pointer.startsWith('/')) {\n throw new Error(`Invalid JSON Pointer: ${pointer}`);\n }\n return pointer\n .slice(1)\n .split('/')\n .map(token => token.replace(/~1/g, '/').replace(/~0/g, '~'));\n}\n\nfunction getAt(doc: unknown, tokens: readonly string[]): unknown {\n let cur: unknown = doc;\n for (const token of tokens) {\n cur = stepInto(cur, token);\n }\n return cur;\n}\n\nfunction stepInto(node: unknown, token: string): unknown {\n if (Array.isArray(node)) {\n const i = parseArrayIndex(token, node.length);\n return node[i];\n }\n if (node !== null && typeof node === 'object') {\n return (node as Record<string, unknown>)[token];\n }\n throw new Error(`Cannot traverse non-container at token \"${token}\"`);\n}\n\nfunction setAt(\n doc: unknown,\n tokens: readonly string[],\n value: unknown,\n allowArrayAppend: boolean,\n): unknown {\n if (tokens.length === 0) {\n // Replace root.\n return structuredCloneSafe(value);\n }\n const [head, ...rest] = tokens;\n if (Array.isArray(doc)) {\n const arr = doc.slice();\n const i = head === '-' && allowArrayAppend ? arr.length : parseArrayIndex(head!, arr.length + (allowArrayAppend ? 1 : 0));\n if (rest.length === 0) {\n if (allowArrayAppend) {\n // RFC-6902 add: insert at index, shifting elements right\n arr.splice(i, 0, structuredCloneSafe(value));\n } else {\n // replace: overwrite at index\n if (i >= arr.length) throw new Error(`Cannot replace beyond array length at \"/${tokens.join('/')}\"`);\n arr[i] = structuredCloneSafe(value);\n }\n } else {\n if (i >= arr.length) throw new Error(`Cannot descend into non-existent array index ${i}`);\n arr[i] = setAt(arr[i], rest, value, allowArrayAppend);\n }\n return arr;\n }\n if (doc === null || typeof doc !== 'object') {\n throw new Error(`Cannot descend into non-container at \"/${tokens.join('/')}\"`);\n }\n const obj = { ...(doc as Record<string, unknown>) };\n if (rest.length === 0) {\n obj[head!] = structuredCloneSafe(value);\n } else {\n if (!(head! in obj)) {\n throw new Error(`Cannot descend into missing path \"/${tokens.join('/')}\"`);\n }\n obj[head!] = setAt(obj[head!], rest, value, allowArrayAppend);\n }\n return obj;\n}\n\nfunction removeAt(doc: unknown, tokens: readonly string[]): unknown {\n if (tokens.length === 0) {\n throw new Error('Cannot remove root');\n }\n const [head, ...rest] = tokens;\n if (Array.isArray(doc)) {\n const arr = doc.slice();\n const i = parseArrayIndex(head!, arr.length);\n if (i >= arr.length) throw new Error(`Cannot remove non-existent array index ${i}`);\n if (rest.length === 0) {\n arr.splice(i, 1);\n } else {\n arr[i] = removeAt(arr[i], rest);\n }\n return arr;\n }\n if (doc === null || typeof doc !== 'object') {\n throw new Error(`Cannot remove from non-container at token \"${head}\"`);\n }\n const obj = { ...(doc as Record<string, unknown>) };\n if (rest.length === 0) {\n if (!(head! in obj)) throw new Error(`Cannot remove non-existent key \"${head}\"`);\n delete obj[head!];\n } else {\n if (!(head! in obj)) throw new Error(`Cannot descend into missing path \"${head}\"`);\n obj[head!] = removeAt(obj[head!], rest);\n }\n return obj;\n}\n\nfunction parseArrayIndex(token: string, lengthBound: number): number {\n if (token === '-') {\n // \"-\" is the \"after-last\" sentinel; only valid for `add` (handled by caller)\n throw new Error(`Array end marker \"-\" not valid in this position`);\n }\n if (!/^(0|[1-9]\\d*)$/.test(token)) {\n throw new Error(`Invalid array index: \"${token}\"`);\n }\n const i = Number.parseInt(token, 10);\n if (i > lengthBound) {\n throw new Error(`Array index ${i} exceeds bound ${lengthBound}`);\n }\n return i;\n}\n\nfunction structuredCloneSafe<T>(v: T): T {\n // Cheap deep clone for JSON-like values (no functions, no cycles) — matches\n // the deep-clone the reducer was already doing pre-applyPatch with the prior\n // dependency.\n if (v === null || typeof v !== 'object') return v;\n return JSON.parse(JSON.stringify(v)) as T;\n}\n\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (a === null || b === null) return false;\n if (typeof a !== 'object' || typeof b !== 'object') return false;\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!deepEqual(a[i], b[i])) return false;\n }\n return true;\n }\n const ao = a as Record<string, unknown>;\n const bo = b as Record<string, unknown>;\n const aKeys = Object.keys(ao);\n const bKeys = Object.keys(bo);\n if (aKeys.length !== bKeys.length) return false;\n for (const k of aKeys) {\n if (!Object.prototype.hasOwnProperty.call(bo, k)) return false;\n if (!deepEqual(ao[k], bo[k])) return false;\n }\n return true;\n}\n","// libs/ag-ui/src/lib/bridge-citations-state.ts\n// SPDX-License-Identifier: MIT\nimport type { Citation, Message } from '@threadplane/chat';\n\ninterface ThreadStateLike {\n state?: Record<string, unknown>;\n}\n\nexport function bridgeCitationsState(thread: ThreadStateLike, messages: Message[]): Message[] {\n const citationsByMsg = (thread.state as { citations?: unknown })?.citations;\n if (!citationsByMsg || typeof citationsByMsg !== 'object') return messages;\n const map = citationsByMsg as Record<string, unknown>;\n return messages.map(msg => {\n const raw = map[msg.id];\n if (!Array.isArray(raw) || raw.length === 0) return msg;\n return { ...msg, citations: raw.map((entry, i) => normalizeCitation(entry, i + 1)) };\n });\n}\n\nfunction normalizeCitation(entry: unknown, fallbackIndex: number): Citation {\n if (typeof entry === 'string') {\n return { id: `c${fallbackIndex}`, index: fallbackIndex, url: entry };\n }\n const e = (entry ?? {}) as Record<string, unknown>;\n const str = (key: string): string | undefined =>\n typeof e[key] === 'string' ? (e[key] as string) : undefined;\n const firstStr = (...keys: string[]): string | undefined => {\n for (const k of keys) {\n const v = str(k);\n if (v !== undefined) return v;\n }\n return undefined;\n };\n return {\n id: str('id') ?? str('refId') ?? `c${fallbackIndex}`,\n index: typeof e['index'] === 'number' ? (e['index'] as number) : fallbackIndex,\n title: firstStr('title', 'name'),\n url: firstStr('url', 'href', 'source'),\n snippet: firstStr('snippet', 'content', 'excerpt'),\n extra:\n typeof e['extra'] === 'object' && e['extra'] !== null\n ? (e['extra'] as Record<string, unknown>)\n : undefined,\n };\n}\n","// SPDX-License-Identifier: MIT\n// @ag-ui/client@0.0.52 — EventType is a string enum with uppercase values.\n// Discriminator strings (e.g. 'RUN_STARTED') match EventType enum members\n// verbatim; the switch cases below use the string literals directly so this\n// file has no runtime dependency on the EventType enum import.\nimport type { WritableSignal } from '@angular/core';\nimport type { Subject } from 'rxjs';\nimport type {\n Message, AgentStatus, ToolCall, AgentEvent, AgentInterrupt,\n} from '@threadplane/chat';\nimport type { BaseEvent } from '@ag-ui/client';\nimport { applyPatch, type JsonPatchOp } from './internal/apply-patch';\nimport { bridgeCitationsState } from './bridge-citations-state';\n\n/**\n * AG-UI AssistantMessage shape as it arrives on the wire in a MESSAGES_SNAPSHOT.\n * The `toolCalls` field carries full ToolCall objects (id + function { name, arguments }).\n * This is distinct from the chat lib's `Message.toolCallIds` which is a plain string[].\n */\ninterface AgUiSnapshotToolCall {\n id: string;\n type: 'function';\n function: { name: string; arguments: string };\n}\n\ninterface AgUiSnapshotMessage {\n id: string;\n role: string;\n content?: string;\n toolCalls?: AgUiSnapshotToolCall[];\n [key: string]: unknown;\n}\n\n/**\n * A custom event surfaced to consumers via the agent's `customEvents` signal.\n * Mirrors the LangGraph adapter's CustomStreamEvent shape so the chat\n * a2ui partial-args bridge consumes both transports identically.\n */\nexport interface CustomStreamEvent {\n /** Event name set by the backend (e.g. 'a2ui-partial', 'state_update'). */\n name: string;\n /** Arbitrary payload from the backend (JSON-string values are parsed). */\n data: unknown;\n}\n\nexport interface ReducerStore {\n messages: WritableSignal<Message[]>;\n status: WritableSignal<AgentStatus>;\n isLoading: WritableSignal<boolean>;\n error: WritableSignal<unknown>;\n toolCalls: WritableSignal<ToolCall[]>;\n state: WritableSignal<Record<string, unknown>>;\n interrupt: WritableSignal<AgentInterrupt | undefined>;\n events$: Subject<AgentEvent>;\n customEvents: WritableSignal<CustomStreamEvent[]>;\n}\n\n/**\n * Per-message reasoning timing. Populated by REASONING_MESSAGE_START /\n * REASONING_MESSAGE_END handlers. The map lives on the module — same\n * scope as the reducer function. ReducerStore stays free of timing\n * state; consumers read it via `Message.reasoningDurationMs` on\n * messages that completed reasoning.\n *\n * Keyed by messageId. We do not need cross-thread isolation here:\n * AG-UI's source agent recreates the reducer pipeline per session, and\n * messageIds are unique within a session.\n */\nconst reasoningTimingMap = new Map<string, { startedAt: number; endedAt?: number }>();\n\nfunction resolveReasoningDurationMs(messageId: string): number | undefined {\n const entry = reasoningTimingMap.get(messageId);\n if (!entry || entry.endedAt === undefined) return undefined;\n return entry.endedAt - entry.startedAt;\n}\n\n/**\n * Pure function: applies a single AG-UI BaseEvent to the store. Caller\n * subscribes to source.agent() and forwards each event here. Designed\n * for testability — no side effects beyond the supplied store.\n */\nexport function reduceEvent(event: BaseEvent, store: ReducerStore): void {\n switch (event.type) {\n case 'RUN_STARTED': {\n store.status.set('running');\n store.isLoading.set(true);\n store.error.set(null);\n store.interrupt.set(undefined);\n store.customEvents.set([]);\n return;\n }\n case 'RUN_FINISHED': {\n store.status.set('idle');\n store.isLoading.set(false);\n return;\n }\n case 'RUN_ERROR': {\n store.status.set('error');\n store.isLoading.set(false);\n store.error.set((event as { message?: unknown }).message ?? event);\n return;\n }\n case 'TEXT_MESSAGE_START': {\n const id = messageIdFrom(event);\n store.messages.update((prev) =>\n prev.some((m) => m.id === id)\n ? prev.map((m) => m.id === id ? { ...m, content: m.content ?? '' } : m)\n : [...prev, { id, role: 'assistant', content: '' }],\n );\n return;\n }\n case 'REASONING_MESSAGE_START': {\n const id = messageIdFrom(event);\n reasoningTimingMap.set(id, { startedAt: Date.now() });\n // Initialize an assistant slot with empty reasoning if it doesn't already exist.\n store.messages.update((prev) =>\n prev.some((m) => m.id === id)\n ? prev.map((m) => m.id === id\n ? { ...m, reasoning: m.reasoning ?? '' }\n : m)\n : [...prev, { id, role: 'assistant', content: '', reasoning: '' }],\n );\n return;\n }\n case 'REASONING_MESSAGE_CONTENT':\n case 'REASONING_MESSAGE_CHUNK': {\n const id = messageIdFrom(event);\n const delta = (event as { delta?: string }).delta ?? '';\n store.messages.update((prev) =>\n prev.map((m) => m.id === id\n ? { ...m, reasoning: (m.reasoning ?? '') + delta }\n : m),\n );\n return;\n }\n case 'REASONING_MESSAGE_END': {\n const id = messageIdFrom(event);\n const entry = reasoningTimingMap.get(id);\n if (entry) {\n entry.endedAt = Date.now();\n reasoningTimingMap.set(id, entry);\n const duration = resolveReasoningDurationMs(id);\n if (duration !== undefined) {\n store.messages.update((prev) =>\n prev.map((m) => m.id === id ? { ...m, reasoningDurationMs: duration } : m),\n );\n }\n }\n return;\n }\n case 'TEXT_MESSAGE_CONTENT': {\n const id = messageIdFrom(event);\n const delta = (event as { delta?: string }).delta ?? '';\n store.messages.update((prev) =>\n prev.map((m) => m.id === id ? { ...m, content: m.content + delta } : m),\n );\n return;\n }\n case 'TEXT_MESSAGE_END': {\n // No-op — message is finalized by virtue of TEXT_MESSAGE_CONTENT\n // having been applied. Reserved for future hooks.\n return;\n }\n case 'TOOL_CALL_START': {\n const e = event as unknown as { toolCallId: string; toolCallName: string; parentMessageId?: string };\n store.toolCalls.update((prev) => [\n ...prev,\n { id: e.toolCallId, name: e.toolCallName, args: {}, status: 'running' },\n ]);\n // Link the tool call to its parent assistant message so the chat lib's\n // per-message tool-call resolution (chat-tool-calls / chat-tool-views)\n // can scope it. ag-ui-langgraph emits parentMessageId for every tool\n // call. If the parent assistant message hasn't been created yet (a\n // tool-call-only turn emits no TEXT_MESSAGE_START), create a slot.\n const parentId = e.parentMessageId;\n if (parentId) {\n store.messages.update((prev) => {\n const existing = prev.find((m) => m.id === parentId);\n if (existing) {\n return prev.map((m) =>\n m.id === parentId\n ? { ...m, toolCallIds: [...(m.toolCallIds ?? []), e.toolCallId] }\n : m,\n );\n }\n return [...prev, { id: parentId, role: 'assistant', content: '', toolCallIds: [e.toolCallId] }];\n });\n }\n return;\n }\n case 'TOOL_CALL_ARGS': {\n const e = event as unknown as { toolCallId: string; delta: string };\n const args = safeParseArgs(e.delta);\n store.toolCalls.update((prev) =>\n prev.map((t) => t.id === e.toolCallId ? { ...t, args } : t),\n );\n return;\n }\n case 'TOOL_CALL_END': {\n const e = event as unknown as { toolCallId: string };\n store.toolCalls.update((prev) =>\n prev.map((t) => t.id === e.toolCallId ? { ...t, status: 'complete' } : t),\n );\n return;\n }\n case 'TOOL_CALL_RESULT': {\n const e = event as unknown as { toolCallId: string; content: unknown };\n // ag_ui_langgraph serialises tool results via normalize_tool_content()\n // which always returns a string. Parse it so downstream consumers\n // (chat-tool-views / toToolViewSpec) can spread the object into props.\n const result = typeof e.content === 'string' ? safeParseJson(e.content) : e.content;\n store.toolCalls.update((prev) =>\n prev.map((t) => t.id === e.toolCallId ? { ...t, result } : t),\n );\n return;\n }\n case 'STATE_SNAPSHOT': {\n const e = event as unknown as { snapshot: Record<string, unknown> };\n const snapshot = e.snapshot ?? {};\n store.state.set(snapshot);\n store.messages.update(msgs => bridgeCitationsState({ state: snapshot }, msgs));\n return;\n }\n case 'STATE_DELTA': {\n const e = event as unknown as { delta: JsonPatchOp[] };\n const next = applyPatch(deepClone(store.state()), e.delta);\n store.state.set(next);\n store.messages.update(msgs => bridgeCitationsState({ state: next }, msgs));\n return;\n }\n case 'MESSAGES_SNAPSHOT': {\n const e = event as unknown as { messages: AgUiSnapshotMessage[] };\n const raw = e.messages ?? [];\n // AG-UI AssistantMessage carries `toolCalls` (ToolCall objects) on the\n // snapshot wire. Bridge them to `toolCallIds` so that the chat lib's\n // per-message tool-call resolution (resolveMessageToolCalls) can scope\n // correctly. Also merge any snapshot-only tool calls into store.toolCalls\n // so the data is visible to <chat-tool-views>.\n const snapshotToolCalls: ToolCall[] = [];\n const messages: Message[] = raw.map((m) => {\n if (m.role !== 'assistant' || !m.toolCalls || m.toolCalls.length === 0) {\n return m as unknown as Message;\n }\n const ids: string[] = [];\n for (const tc of m.toolCalls) {\n ids.push(tc.id);\n snapshotToolCalls.push({\n id: tc.id,\n name: tc.function.name,\n args: safeParseArgs(tc.function.arguments),\n status: 'complete',\n });\n }\n const { toolCalls: _dropped, ...rest } = m;\n return { ...rest, toolCallIds: ids } as unknown as Message;\n });\n store.messages.set(messages);\n if (snapshotToolCalls.length > 0) {\n store.toolCalls.update((prev) => {\n // Merge: keep existing entries (they may carry richer state from\n // streaming) and only insert entries not already present by id.\n const existingIds = new Set(prev.map((tc) => tc.id));\n const toAdd = snapshotToolCalls.filter((tc) => !existingIds.has(tc.id));\n return toAdd.length > 0 ? [...prev, ...toAdd] : prev;\n });\n }\n return;\n }\n case 'CUSTOM': {\n const e = event as unknown as { name: string; value: unknown };\n // ag_ui_langgraph serializes interrupt payloads as JSON strings.\n // Parse the value if it arrives as a string so downstream consumers\n // (e.g. ChatApprovalCardComponent) receive a plain object, not a string.\n const parsedValue = typeof e.value === 'string' ? safeParseJson(e.value) : e.value;\n if (e.name === 'on_interrupt') {\n store.interrupt.set({ id: randomId(), value: parsedValue, resumable: true });\n return;\n }\n // Surface every other custom event on the customEvents signal so the\n // chat a2ui partial-args bridge (which reads agent.customEvents()) lights\n // up live/progressive a2ui rendering — parity with the LangGraph adapter.\n store.customEvents.update((prev) => [...prev, { name: e.name, data: parsedValue }]);\n if (e.name === 'state_update' && isRecord(parsedValue)) {\n store.events$.next({ type: 'state_update', data: parsedValue });\n } else {\n store.events$.next({ type: 'custom', name: e.name, data: parsedValue });\n }\n return;\n }\n default: {\n // Unknown event types are ignored; AG-UI may add new ones in\n // future protocol versions. We surface them as no-ops rather\n // than throwing, so a partial-version mismatch doesn't crash.\n return;\n }\n }\n}\n\nfunction randomId(): string {\n return Math.random().toString(36).slice(2);\n}\n\nfunction messageIdFrom(event: BaseEvent): string {\n return (event as { messageId?: string }).messageId ?? 'unknown';\n}\n\nfunction safeParseArgs(delta: string): Record<string, unknown> {\n try {\n const parsed = JSON.parse(delta);\n return isRecord(parsed) ? parsed : {};\n } catch {\n return {};\n }\n}\n\n/** Parse a JSON string to its value; return the original string on failure. */\nfunction safeParseJson(s: string): unknown {\n try {\n return JSON.parse(s);\n } catch {\n return s;\n }\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n\nfunction deepClone<T>(v: T): T {\n return JSON.parse(JSON.stringify(v));\n}\n","// SPDX-License-Identifier: MIT\nimport { signal, type Signal } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport type { AbstractAgent } from '@ag-ui/client';\nimport type {\n Agent, Message, AgentStatus, ToolCall, AgentEvent,\n AgentInterrupt,\n AgentRuntimeTelemetryEvent,\n AgentRuntimeTelemetryProperties,\n AgentRuntimeTelemetrySink,\n AgentSubmitInput, AgentSubmitOptions,\n} from '@threadplane/chat';\nimport { reduceEvent, type ReducerStore, type CustomStreamEvent } from './reducer';\n\nexport interface ToAgentOptions {\n /** Optional app-owned telemetry sink. No telemetry is emitted unless this is provided. */\n telemetry?: AgentRuntimeTelemetrySink | false;\n}\n\nfunction captureAgentRuntimeTelemetry(\n sink: AgentRuntimeTelemetrySink | false | undefined,\n event: AgentRuntimeTelemetryEvent,\n properties: AgentRuntimeTelemetryProperties,\n): void {\n if (!sink) return;\n try {\n void Promise.resolve(sink({ event, properties })).catch(() => undefined);\n } catch {\n // Keep telemetry side effects isolated from adapter control flow.\n }\n}\n\nfunction agentRuntimeTelemetryErrorClass(error: unknown): string {\n if (error instanceof Error) return error.name || error.constructor.name || 'Error';\n if (\n error\n && typeof error === 'object'\n && 'name' in error\n && typeof error.name === 'string'\n && error.name.length > 0\n ) {\n return error.name;\n }\n return 'UnknownError';\n}\n\n/**\n * The neutral Agent contract, widened with the AG-UI adapter's optional\n * `customEvents` signal (the chat composition feature-detects it to enable\n * live a2ui streaming). Mirrors langgraph's LangGraphAgent extension.\n */\nexport interface AgUiAgent extends Agent {\n customEvents: Signal<CustomStreamEvent[]>;\n}\n\n/**\n * Wraps an AG-UI AbstractAgent into the runtime-neutral Agent contract.\n *\n * The adapter subscribes to source.subscribe({ onEvent }) and reduces every\n * event into the produced Agent's signals. submit() optimistically appends the\n * user message to both our signals and the source agent's internal message\n * list, then calls source.runAgent(). stop() calls source.abortRun().\n *\n * Subscription cleanup: the returned Agent does NOT manage its own lifetime.\n * Callers using DI should rely on the provider's destroy hook; direct callers\n * of toAgent() should treat the returned object's lifecycle as tied to the\n * agent instance they constructed. The subscriber registered via\n * source.subscribe() will fire for the lifetime of source.\n */\nexport function toAgent(source: AbstractAgent, options: ToAgentOptions = {}): AgUiAgent {\n const store: ReducerStore = {\n messages: signal<Message[]>([]),\n status: signal<AgentStatus>('idle'),\n isLoading: signal<boolean>(false),\n error: signal<unknown>(null),\n toolCalls: signal<ToolCall[]>([]),\n state: signal<Record<string, unknown>>({}),\n interrupt: signal<AgentInterrupt | undefined>(undefined),\n events$: new Subject<AgentEvent>(),\n customEvents: signal<CustomStreamEvent[]>([]),\n };\n const telemetryProperties = { transport: 'ag-ui' as const, surface: 'to_agent' };\n let activeRun: { startedAt: number; errored: boolean } | null = null;\n\n captureAgentRuntimeTelemetry(\n options.telemetry,\n 'ngaf:runtime_instance_created',\n telemetryProperties,\n );\n\n function startRunTelemetry(requestType: string): { startedAt: number; errored: boolean } {\n const run = { startedAt: Date.now(), errored: false };\n activeRun = run;\n captureAgentRuntimeTelemetry(options.telemetry, 'ngaf:runtime_request_created', {\n ...telemetryProperties,\n requestType,\n });\n captureAgentRuntimeTelemetry(options.telemetry, 'ngaf:stream_started', telemetryProperties);\n return run;\n }\n\n function finishRunTelemetry(run: { startedAt: number; errored: boolean }): void {\n if (run.errored) return;\n captureAgentRuntimeTelemetry(options.telemetry, 'ngaf:stream_ended', {\n ...telemetryProperties,\n durationMs: Date.now() - run.startedAt,\n });\n if (activeRun === run) activeRun = null;\n }\n\n function failRunTelemetry(error: unknown, run = activeRun): void {\n if (!run || run.errored) return;\n run.errored = true;\n captureAgentRuntimeTelemetry(options.telemetry, 'ngaf:stream_errored', {\n ...telemetryProperties,\n durationMs: Date.now() - run.startedAt,\n errorClass: agentRuntimeTelemetryErrorClass(error),\n });\n if (activeRun === run) activeRun = null;\n }\n\n // Tap all events from the source agent via the AgentSubscriber API.\n // This subscription lives for the lifetime of `source`.\n source.subscribe({\n onEvent({ event }) {\n reduceEvent(event, store);\n },\n onRunFailed({ error }) {\n store.status.set('error');\n store.isLoading.set(false);\n store.error.set(error);\n failRunTelemetry(error);\n },\n });\n\n return {\n messages: store.messages,\n status: store.status,\n isLoading: store.isLoading,\n error: store.error,\n toolCalls: store.toolCalls,\n state: store.state,\n interrupt: store.interrupt,\n events$: store.events$.asObservable(),\n customEvents: store.customEvents,\n\n submit: async (input: AgentSubmitInput, _opts?: AgentSubmitOptions) => {\n if (input.resume !== undefined) {\n // Resume path: clear the pending interrupt and replay the run with the\n // resume payload forwarded to the LangGraph backend via AG-UI's\n // forwardedProps.command.resume mechanism.\n store.interrupt.set(undefined);\n const run = startRunTelemetry('resume');\n try {\n await source.runAgent({ forwardedProps: { command: { resume: input.resume } } });\n finishRunTelemetry(run);\n } catch (err) {\n store.status.set('error');\n store.isLoading.set(false);\n store.error.set(err);\n failRunTelemetry(err, run);\n }\n return;\n }\n\n // Optimistic append of user message to our signals and to the source\n // agent's own message list so runAgent() sees the new message.\n const userMsg = buildUserMessage(input);\n if (userMsg) {\n store.messages.update((prev) => [...prev, userMsg]);\n // Sync to AG-UI source so it's included in the next run's input.\n source.addMessage(userMsg as Parameters<typeof source.addMessage>[0]);\n }\n\n const run = startRunTelemetry('submit');\n try {\n await source.runAgent();\n finishRunTelemetry(run);\n } catch (err) {\n // If the run was aborted via stop(), abortRun() resolves the promise\n // rather than rejecting — but catch any unexpected errors here.\n store.status.set('error');\n store.isLoading.set(false);\n store.error.set(err);\n failRunTelemetry(err, run);\n }\n },\n\n stop: async () => {\n source.abortRun();\n },\n\n regenerate: async (assistantMessageIndex: number): Promise<void> => {\n if (store.isLoading()) {\n throw new Error('Cannot regenerate while agent is loading another response');\n }\n const msgs = store.messages();\n const target = msgs[assistantMessageIndex];\n if (!target || target.role !== 'assistant') {\n throw new Error(`Message at index ${assistantMessageIndex} is not an assistant message`);\n }\n\n // Find the user message immediately preceding the target assistant message.\n const userIdx = msgs\n .slice(0, assistantMessageIndex)\n .map((m, i) => ({ m, i }))\n .reverse()\n .find(({ m }) => m.role === 'user')?.i;\n if (userIdx === undefined) {\n throw new Error('No user message found before the target assistant message');\n }\n\n // Truncate local message buffer INCLUSIVE of the user message. This\n // preserves the user message in the UI (replace-semantics) while the\n // new assistant response streams in. The trailing user message becomes\n // the active prompt for the next run — we must NOT re-add it.\n const trimmed = msgs.slice(0, userIdx + 1);\n store.messages.set(trimmed);\n\n // Sync the trimmed list back to the source agent so its internal state\n // matches what we're about to re-run. source.setMessages() replaces the\n // agent's internal message list without appending — the trailing user\n // message in `trimmed` becomes the active prompt for the next run.\n source.setMessages(trimmed as Parameters<typeof source.setMessages>[0]);\n\n const run = startRunTelemetry('regenerate');\n try {\n await source.runAgent();\n finishRunTelemetry(run);\n } catch (err) {\n store.status.set('error');\n store.isLoading.set(false);\n store.error.set(err);\n failRunTelemetry(err, run);\n }\n },\n };\n}\n\nfunction buildUserMessage(input: AgentSubmitInput): Message | undefined {\n if (input.message === undefined) return undefined;\n const content = typeof input.message === 'string'\n ? input.message\n : input.message.map((b) => b.type === 'text' ? b.text : JSON.stringify(b)).join('');\n return { id: randomId(), role: 'user', content };\n}\n\nfunction randomId(): string {\n return Math.random().toString(36).slice(2);\n}\n","// SPDX-License-Identifier: MIT\nimport { InjectionToken, inject, type Provider } from '@angular/core';\nimport { HttpAgent } from '@ag-ui/client';\nimport type { Agent, AgentRuntimeTelemetrySink } from '@threadplane/chat';\nimport { toAgent } from './to-agent';\n\n/**\n * Configuration for the AG-UI agent provider.\n * HttpAgentConfig shape (from @ag-ui/client@0.0.52):\n * - url: string (required) — endpoint for the HTTP agent\n * - agentId: string (optional) — agent identifier\n * - threadId: string (optional) — thread identifier\n * - headers: Record<string, string> (optional) — custom HTTP headers\n */\nexport interface AgentConfig {\n url: string;\n agentId?: string;\n threadId?: string;\n headers?: Record<string, string>;\n /** Optional app-owned telemetry sink. No telemetry is emitted unless this is provided. */\n telemetry?: AgentRuntimeTelemetrySink | false;\n}\n\n/** @internal — exported for spec access only. Consumers must use injectAgent(). */\nexport const AGENT = new InjectionToken<Agent>('AGENT');\n\n/**\n * Provides an Agent instance wired through HttpAgent and toAgent.\n * Constructs an HttpAgent from config and wraps it in the runtime-neutral\n * Agent contract via toAgent(). Returns a provider array suitable for\n * bootstrapApplication or TestBed.configureTestingModule().\n *\n * **Static vs factory config.** Pass a plain `AgentConfig` object when the\n * config is known up front. Pass a `() => AgentConfig` factory when the config\n * depends on runtime/DI state — the factory runs inside an Angular injection\n * context, so it may call `inject()` to read services or route params.\n */\nexport function provideAgent(\n configOrFactory: AgentConfig | (() => AgentConfig),\n): Provider[] {\n return [\n {\n provide: AGENT,\n useFactory: () => {\n // useFactory runs in an injection context, so a config factory may\n // call inject() to read runtime/DI state.\n const config =\n typeof configOrFactory === 'function' ? configOrFactory() : configOrFactory;\n const source = new HttpAgent({\n url: config.url,\n ...(config.agentId !== undefined ? { agentId: config.agentId } : {}),\n ...(config.threadId !== undefined ? { threadId: config.threadId } : {}),\n ...(config.headers !== undefined ? { headers: config.headers } : {}),\n });\n return toAgent(source, { telemetry: config.telemetry });\n },\n },\n ];\n}\n\n/**\n * Injects the Agent from Angular's dependency injection container.\n * Use this in components or services that have been provided via provideAgent().\n */\nexport function injectAgent(): Agent {\n return inject(AGENT);\n}\n","// libs/ag-ui/src/lib/testing/fake-agent.ts\n// SPDX-License-Identifier: MIT\nimport {\n AbstractAgent,\n EventType,\n type BaseEvent,\n type RunAgentInput,\n} from '@ag-ui/client';\nimport { Observable } from 'rxjs';\n\n/**\n * In-process AG-UI agent that emits a canned streaming response.\n *\n * Use for offline demos and tests where a real backend isn't available.\n * Echoes a fixed assistant reply token-by-token with realistic timing.\n *\n * NOT for production use.\n */\nexport class FakeAgent extends AbstractAgent {\n /**\n * Tokens streamed back as the assistant reply. Override with custom\n * tokens via the constructor for varied demo content.\n */\n private readonly tokens: string[];\n\n /** Optional reasoning chunks emitted before the text reply. */\n private readonly reasoningTokens: string[];\n\n /** Milliseconds between successive token emissions. */\n private readonly delayMs: number;\n\n constructor(opts: {\n tokens?: string[];\n /** Optional reasoning chunks emitted before the text reply. */\n reasoningTokens?: string[];\n delayMs?: number;\n } = {}) {\n super();\n this.tokens = opts.tokens ?? [\n 'Hello', ' from', ' the', ' fake', ' AG-UI', ' agent.',\n ' This', ' is', ' a', ' canned', ' streaming', ' reply.',\n ];\n this.reasoningTokens = opts.reasoningTokens ?? [];\n this.delayMs = opts.delayMs ?? 60;\n }\n\n run(input: RunAgentInput): Observable<BaseEvent> {\n const tokens = this.tokens;\n const reasoningTokens = this.reasoningTokens;\n const delayMs = this.delayMs;\n const messageId = `fake-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n\n const sequence: BaseEvent[] = [\n { type: EventType.RUN_STARTED, threadId: input.threadId, runId: input.runId } as BaseEvent,\n ];\n\n if (reasoningTokens.length > 0) {\n sequence.push({ type: EventType.REASONING_MESSAGE_START, messageId, role: 'assistant' } as BaseEvent);\n for (const delta of reasoningTokens) {\n sequence.push({ type: EventType.REASONING_MESSAGE_CONTENT, messageId, delta } as BaseEvent);\n }\n sequence.push({ type: EventType.REASONING_MESSAGE_END, messageId } as BaseEvent);\n }\n\n sequence.push({ type: EventType.TEXT_MESSAGE_START, messageId, role: 'assistant' } as BaseEvent);\n for (const delta of tokens) {\n sequence.push({ type: EventType.TEXT_MESSAGE_CONTENT, messageId, delta } as BaseEvent);\n }\n sequence.push({ type: EventType.TEXT_MESSAGE_END, messageId } as BaseEvent);\n sequence.push({ type: EventType.RUN_FINISHED, threadId: input.threadId, runId: input.runId } as BaseEvent);\n\n return new Observable<BaseEvent>((observer) => {\n let cancelled = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let i = 0;\n\n const emitNext = () => {\n if (cancelled) return;\n if (i >= sequence.length) {\n observer.complete();\n return;\n }\n observer.next(sequence[i]);\n i++;\n // Steady cadence except a tiny initial delay before RUN_STARTED.\n timer = setTimeout(emitNext, delayMs);\n };\n\n timer = setTimeout(emitNext, 30);\n\n return () => {\n cancelled = true;\n if (timer !== undefined) clearTimeout(timer);\n };\n });\n }\n}\n","// libs/ag-ui/src/lib/testing/provide-fake-agent.ts\n// SPDX-License-Identifier: MIT\nimport { type Provider } from '@angular/core';\nimport type { FakeAgentConfig } from '@threadplane/chat/testing';\nimport { AGENT } from '../provide-agent';\nimport { toAgent } from '../to-agent';\nimport { FakeAgent } from './fake-agent';\n\n/**\n * Registers an in-process FakeAgent under AGENT.\n *\n * Use for offline demos and development. Drop-in replacement for\n * provideAgent({ url }) when no real backend is available.\n */\nexport function provideFakeAgent(config: FakeAgentConfig = {}): Provider[] {\n return [\n {\n provide: AGENT,\n useFactory: () => toAgent(new FakeAgent(config)),\n },\n ];\n}\n","// SPDX-License-Identifier: MIT\nexport { toAgent } from './lib/to-agent';\nexport type { ToAgentOptions, AgUiAgent } from './lib/to-agent';\nexport type { CustomStreamEvent } from './lib/reducer';\nexport { provideAgent, injectAgent } from './lib/provide-agent';\nexport type { AgentConfig } from './lib/provide-agent';\nexport { FakeAgent } from './lib/testing/fake-agent';\nexport { provideFakeAgent } from './lib/testing/provide-fake-agent';\n\n// Citation state bridge\nexport { bridgeCitationsState } from './lib/bridge-citations-state';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["randomId"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@threadplane/ag-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.49",
|
|
4
|
+
"description": "AG-UI protocol adapter for @threadplane/chat — works with any AG-UI-compatible backend.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"angular",
|
|
7
|
+
"ag-ui",
|
|
8
|
+
"agent",
|
|
9
|
+
"adapter",
|
|
10
|
+
"threadplane"
|
|
11
|
+
],
|
|
4
12
|
"peerDependencies": {
|
|
5
13
|
"@threadplane/chat": "*",
|
|
6
14
|
"@angular/core": "^20.0.0 || ^21.0.0",
|
|
@@ -1,12 +1,33 @@
|
|
|
1
|
+
import { Signal, Provider } from '@angular/core';
|
|
1
2
|
import { AbstractAgent, RunAgentInput, BaseEvent } from '@ag-ui/client';
|
|
2
|
-
import {
|
|
3
|
-
import { InjectionToken, Provider } from '@angular/core';
|
|
3
|
+
import { Agent, AgentRuntimeTelemetrySink, Message } from '@threadplane/chat';
|
|
4
4
|
import { Observable } from 'rxjs';
|
|
5
|
+
import { FakeAgentConfig } from '@threadplane/chat/testing';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A custom event surfaced to consumers via the agent's `customEvents` signal.
|
|
9
|
+
* Mirrors the LangGraph adapter's CustomStreamEvent shape so the chat
|
|
10
|
+
* a2ui partial-args bridge consumes both transports identically.
|
|
11
|
+
*/
|
|
12
|
+
interface CustomStreamEvent {
|
|
13
|
+
/** Event name set by the backend (e.g. 'a2ui-partial', 'state_update'). */
|
|
14
|
+
name: string;
|
|
15
|
+
/** Arbitrary payload from the backend (JSON-string values are parsed). */
|
|
16
|
+
data: unknown;
|
|
17
|
+
}
|
|
5
18
|
|
|
6
19
|
interface ToAgentOptions {
|
|
7
20
|
/** Optional app-owned telemetry sink. No telemetry is emitted unless this is provided. */
|
|
8
21
|
telemetry?: AgentRuntimeTelemetrySink | false;
|
|
9
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* The neutral Agent contract, widened with the AG-UI adapter's optional
|
|
25
|
+
* `customEvents` signal (the chat composition feature-detects it to enable
|
|
26
|
+
* live a2ui streaming). Mirrors langgraph's LangGraphAgent extension.
|
|
27
|
+
*/
|
|
28
|
+
interface AgUiAgent extends Agent {
|
|
29
|
+
customEvents: Signal<CustomStreamEvent[]>;
|
|
30
|
+
}
|
|
10
31
|
/**
|
|
11
32
|
* Wraps an AG-UI AbstractAgent into the runtime-neutral Agent contract.
|
|
12
33
|
*
|
|
@@ -21,7 +42,7 @@ interface ToAgentOptions {
|
|
|
21
42
|
* agent instance they constructed. The subscriber registered via
|
|
22
43
|
* source.subscribe() will fire for the lifetime of source.
|
|
23
44
|
*/
|
|
24
|
-
declare function toAgent(source: AbstractAgent, options?: ToAgentOptions):
|
|
45
|
+
declare function toAgent(source: AbstractAgent, options?: ToAgentOptions): AgUiAgent;
|
|
25
46
|
|
|
26
47
|
/**
|
|
27
48
|
* Configuration for the AG-UI agent provider.
|
|
@@ -31,7 +52,7 @@ declare function toAgent(source: AbstractAgent, options?: ToAgentOptions): Agent
|
|
|
31
52
|
* - threadId: string (optional) — thread identifier
|
|
32
53
|
* - headers: Record<string, string> (optional) — custom HTTP headers
|
|
33
54
|
*/
|
|
34
|
-
interface
|
|
55
|
+
interface AgentConfig {
|
|
35
56
|
url: string;
|
|
36
57
|
agentId?: string;
|
|
37
58
|
threadId?: string;
|
|
@@ -39,19 +60,23 @@ interface AgUiAgentConfig {
|
|
|
39
60
|
/** Optional app-owned telemetry sink. No telemetry is emitted unless this is provided. */
|
|
40
61
|
telemetry?: AgentRuntimeTelemetrySink | false;
|
|
41
62
|
}
|
|
42
|
-
declare const AG_UI_AGENT: InjectionToken<Agent>;
|
|
43
63
|
/**
|
|
44
64
|
* Provides an Agent instance wired through HttpAgent and toAgent.
|
|
45
65
|
* Constructs an HttpAgent from config and wraps it in the runtime-neutral
|
|
46
66
|
* Agent contract via toAgent(). Returns a provider array suitable for
|
|
47
67
|
* bootstrapApplication or TestBed.configureTestingModule().
|
|
68
|
+
*
|
|
69
|
+
* **Static vs factory config.** Pass a plain `AgentConfig` object when the
|
|
70
|
+
* config is known up front. Pass a `() => AgentConfig` factory when the config
|
|
71
|
+
* depends on runtime/DI state — the factory runs inside an Angular injection
|
|
72
|
+
* context, so it may call `inject()` to read services or route params.
|
|
48
73
|
*/
|
|
49
|
-
declare function
|
|
74
|
+
declare function provideAgent(configOrFactory: AgentConfig | (() => AgentConfig)): Provider[];
|
|
50
75
|
/**
|
|
51
|
-
* Injects the
|
|
52
|
-
* Use this in components or services that have been provided via
|
|
76
|
+
* Injects the Agent from Angular's dependency injection container.
|
|
77
|
+
* Use this in components or services that have been provided via provideAgent().
|
|
53
78
|
*/
|
|
54
|
-
declare function
|
|
79
|
+
declare function injectAgent(): Agent;
|
|
55
80
|
|
|
56
81
|
/**
|
|
57
82
|
* In-process AG-UI agent that emits a canned streaming response.
|
|
@@ -80,26 +105,18 @@ declare class FakeAgent extends AbstractAgent {
|
|
|
80
105
|
run(input: RunAgentInput): Observable<BaseEvent>;
|
|
81
106
|
}
|
|
82
107
|
|
|
83
|
-
interface FakeAgUiAgentConfig {
|
|
84
|
-
/** Tokens streamed back as the assistant reply. */
|
|
85
|
-
tokens?: string[];
|
|
86
|
-
/** Optional reasoning chunks emitted before the text reply. */
|
|
87
|
-
reasoningTokens?: string[];
|
|
88
|
-
/** Milliseconds between successive token emissions. */
|
|
89
|
-
delayMs?: number;
|
|
90
|
-
}
|
|
91
108
|
/**
|
|
92
|
-
* Registers an in-process FakeAgent under
|
|
109
|
+
* Registers an in-process FakeAgent under AGENT.
|
|
93
110
|
*
|
|
94
111
|
* Use for offline demos and development. Drop-in replacement for
|
|
95
|
-
*
|
|
112
|
+
* provideAgent({ url }) when no real backend is available.
|
|
96
113
|
*/
|
|
97
|
-
declare function
|
|
114
|
+
declare function provideFakeAgent(config?: FakeAgentConfig): Provider[];
|
|
98
115
|
|
|
99
116
|
interface ThreadStateLike {
|
|
100
117
|
state?: Record<string, unknown>;
|
|
101
118
|
}
|
|
102
119
|
declare function bridgeCitationsState(thread: ThreadStateLike, messages: Message[]): Message[];
|
|
103
120
|
|
|
104
|
-
export {
|
|
105
|
-
export type {
|
|
121
|
+
export { FakeAgent, bridgeCitationsState, injectAgent, provideAgent, provideFakeAgent, toAgent };
|
|
122
|
+
export type { AgUiAgent, AgentConfig, CustomStreamEvent, ToAgentOptions };
|