@threadplane/chat 0.0.47 → 0.0.50
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/CHANGELOG.md +3 -0
- package/README.md +233 -90
- package/fesm2022/threadplane-chat-testing.mjs +0 -2
- package/fesm2022/threadplane-chat-testing.mjs.map +1 -1
- package/fesm2022/threadplane-chat.mjs +794 -200
- package/fesm2022/threadplane-chat.mjs.map +1 -1
- package/package.json +2 -2
- package/types/threadplane-chat-testing.d.ts +15 -1
- package/types/threadplane-chat.d.ts +238 -25
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, inject, TemplateRef, Directive, contentChildren, computed, ChangeDetectionStrategy, Component, signal, Injectable, ContentChild, effect, output, DOCUMENT, InjectionToken, ViewEncapsulation, viewChild, model, contentChild, ElementRef, DestroyRef, makeEnvironmentProviders,
|
|
2
|
+
import { input, inject, TemplateRef, Directive, contentChildren, computed, ChangeDetectionStrategy, Component, signal, Injectable, ContentChild, effect, output, DOCUMENT, InjectionToken, ViewEncapsulation, viewChild, model, contentChild, untracked, ElementRef, DestroyRef, makeEnvironmentProviders, Injector, runInInjectionContext, ViewContainerRef, SecurityContext } from '@angular/core';
|
|
3
3
|
import { NgTemplateOutlet, NgComponentOutlet, KeyValuePipe } from '@angular/common';
|
|
4
4
|
import { createPartialMarkdownParser, materialize } from '@cacheplane/partial-markdown';
|
|
5
|
-
import { views, RenderSpecComponent, toRenderRegistry, signalStateStore, RenderElementComponent } from '@threadplane/render';
|
|
6
|
-
export {
|
|
7
|
-
import * as i1 from '@angular/forms';
|
|
8
|
-
import { FormsModule } from '@angular/forms';
|
|
5
|
+
import { views, RenderSpecComponent, toRenderRegistry, signalStateStore, withViews, RenderElementComponent, injectRenderHost } from '@threadplane/render';
|
|
6
|
+
export { toRenderRegistry, views, withViews, withoutViews } from '@threadplane/render';
|
|
9
7
|
import { runLicenseCheck, inferNoncommercial, LICENSE_PUBLIC_KEY } from '@threadplane/licensing';
|
|
10
8
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
9
|
+
import { toJSONSchema } from 'zod/v4';
|
|
11
10
|
import { resolveDynamic, getByPointer, isPathRef, setByPointer, createA2uiMessageParser } from '@threadplane/a2ui';
|
|
12
11
|
export { isLiteralBoolean, isLiteralNumber, isLiteralString, isPathRef } from '@threadplane/a2ui';
|
|
13
12
|
import { materialize as materialize$1, createPartialJsonParser } from '@cacheplane/partial-json';
|
|
@@ -1598,9 +1597,9 @@ const MARKDOWN_VIEW_REGISTRY = new InjectionToken('MARKDOWN_VIEW_REGISTRY');
|
|
|
1598
1597
|
* registry. Each child's `type` is looked up in the registry; the resolved
|
|
1599
1598
|
* component is rendered with `[node]` bound to that child.
|
|
1600
1599
|
*
|
|
1601
|
-
*
|
|
1602
|
-
*
|
|
1603
|
-
*
|
|
1600
|
+
* Position-stable: `track $index` avoids NG0956 re-creation warnings that
|
|
1601
|
+
* occur when the markdown pipeline re-parses content on every stream delta,
|
|
1602
|
+
* producing new child object references even for unchanged nodes.
|
|
1604
1603
|
*/
|
|
1605
1604
|
class MarkdownChildrenComponent {
|
|
1606
1605
|
parent = input.required(...(ngDevMode ? [{ debugName: "parent" }] : []));
|
|
@@ -1620,7 +1619,7 @@ class MarkdownChildrenComponent {
|
|
|
1620
1619
|
}
|
|
1621
1620
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: MarkdownChildrenComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1622
1621
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: MarkdownChildrenComponent, isStandalone: true, selector: "chat-md-children", inputs: { parent: { classPropertyName: "parent", publicName: "parent", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
|
|
1623
|
-
@for (child of children(); track $
|
|
1622
|
+
@for (child of children(); track $index) {
|
|
1624
1623
|
@let comp = resolve(child);
|
|
1625
1624
|
@if (comp) {
|
|
1626
1625
|
<ng-container *ngComponentOutlet="comp; inputs: { node: child }" />
|
|
@@ -1636,7 +1635,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
|
|
|
1636
1635
|
imports: [NgComponentOutlet],
|
|
1637
1636
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1638
1637
|
template: `
|
|
1639
|
-
@for (child of children(); track $
|
|
1638
|
+
@for (child of children(); track $index) {
|
|
1640
1639
|
@let comp = resolve(child);
|
|
1641
1640
|
@if (comp) {
|
|
1642
1641
|
<ng-container *ngComponentOutlet="comp; inputs: { node: child }" />
|
|
@@ -2193,7 +2192,7 @@ class MarkdownTableComponent {
|
|
|
2193
2192
|
}
|
|
2194
2193
|
</thead>
|
|
2195
2194
|
<tbody>
|
|
2196
|
-
@for (row of bodyRows(); track $
|
|
2195
|
+
@for (row of bodyRows(); track $index) {
|
|
2197
2196
|
<chat-md-table-row [node]="row" />
|
|
2198
2197
|
}
|
|
2199
2198
|
</tbody>
|
|
@@ -2215,7 +2214,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
|
|
|
2215
2214
|
}
|
|
2216
2215
|
</thead>
|
|
2217
2216
|
<tbody>
|
|
2218
|
-
@for (row of bodyRows(); track $
|
|
2217
|
+
@for (row of bodyRows(); track $index) {
|
|
2219
2218
|
<chat-md-table-row [node]="row" />
|
|
2220
2219
|
}
|
|
2221
2220
|
</tbody>
|
|
@@ -2793,9 +2792,19 @@ class ChatInputComponent {
|
|
|
2793
2792
|
if (submitted !== null) {
|
|
2794
2793
|
this.submitted.emit(submitted);
|
|
2795
2794
|
this.messageText.set('');
|
|
2795
|
+
const el = this.textareaEl()?.nativeElement;
|
|
2796
|
+
if (el)
|
|
2797
|
+
el.value = '';
|
|
2796
2798
|
requestAnimationFrame(() => this.textareaEl()?.nativeElement.focus());
|
|
2797
2799
|
}
|
|
2798
2800
|
}
|
|
2801
|
+
/** Sync the textarea's value into the signal on user input. A direct
|
|
2802
|
+
* [value]/(input) pair is used instead of ngModel: NgModel does not
|
|
2803
|
+
* reliably write a programmatic clear back to the view under zoneless
|
|
2804
|
+
* + OnPush, leaving sent text visible in the composer (audit F1). */
|
|
2805
|
+
onInput(event) {
|
|
2806
|
+
this.messageText.set(event.target.value);
|
|
2807
|
+
}
|
|
2799
2808
|
/** Abort the current streaming response (if the adapter supports it). */
|
|
2800
2809
|
onStop() {
|
|
2801
2810
|
const a = this.agent();
|
|
@@ -2826,15 +2835,15 @@ class ChatInputComponent {
|
|
|
2826
2835
|
<textarea
|
|
2827
2836
|
#textareaEl
|
|
2828
2837
|
class="chat-input__textarea"
|
|
2829
|
-
[
|
|
2830
|
-
(
|
|
2831
|
-
name="messageText"
|
|
2838
|
+
[value]="messageText()"
|
|
2839
|
+
(input)="onInput($event)"
|
|
2832
2840
|
[placeholder]="placeholder()"
|
|
2833
2841
|
(keydown.enter)="onKeydown($any($event))"
|
|
2834
2842
|
(compositionstart)="composing.set(true)"
|
|
2835
2843
|
(compositionend)="composing.set(false)"
|
|
2836
2844
|
(focus)="focused.set(true)"
|
|
2837
2845
|
(blur)="focused.set(false)"
|
|
2846
|
+
name="messageText"
|
|
2838
2847
|
rows="1"
|
|
2839
2848
|
aria-label="Type a message"
|
|
2840
2849
|
></textarea>
|
|
@@ -2871,11 +2880,11 @@ class ChatInputComponent {
|
|
|
2871
2880
|
</div>
|
|
2872
2881
|
<ng-content select="[chatInputFooter]" />
|
|
2873
2882
|
</div>
|
|
2874
|
-
`, isInline: true, styles: [":host{font-family:var(--ngaf-chat-font-family);color:var(--ngaf-chat-text)}\n", ":host{display:block;width:100%;padding:0 var(--ngaf-chat-edge-pad);box-sizing:border-box}.chat-input__container{width:100%;max-width:var(--ngaf-chat-max-width);margin:0 auto}.chat-input__pill{display:flex;align-items:center;gap:8px;background:var(--ngaf-chat-surface);border:1px solid var(--ngaf-chat-separator);border-radius:9999px;padding:8px 8px 8px 16px;min-height:56px;box-sizing:border-box}.chat-input__textarea{flex:1 1 auto;border:0;outline:none;resize:none;background:transparent;color:var(--ngaf-chat-text);font:inherit;font-size:1rem;line-height:1.5;padding:0;field-sizing:content;overflow-y:auto}.chat-input__textarea::placeholder{color:var(--ngaf-chat-text-muted)}.chat-input__textarea::-webkit-scrollbar{width:4px}.chat-input__textarea::-webkit-scrollbar-thumb{background:var(--ngaf-chat-separator);border-radius:4px}.chat-input__controls{display:flex;align-items:center;gap:4px;flex:none}.chat-input__send,.chat-input__send--stop{width:36px;height:36px;border-radius:50%;border:0;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:opacity .15s ease,transform .15s ease,background .15s ease;padding:0}.chat-input__send{background:var(--ngaf-chat-text);color:var(--ngaf-chat-bg)}.chat-input__send:disabled{opacity:.35;cursor:not-allowed;background:var(--ngaf-chat-text-muted)}.chat-input__send:not(:disabled):hover{transform:scale(1.05)}.chat-input__send svg{width:16px;height:16px}.chat-input__send--stop{background:var(--ngaf-chat-text-muted);color:var(--ngaf-chat-bg)}.chat-input__send--stop:hover{transform:scale(1.05)}.chat-input__send--stop svg{width:14px;height:14px}\n"],
|
|
2883
|
+
`, isInline: true, styles: [":host{font-family:var(--ngaf-chat-font-family);color:var(--ngaf-chat-text)}\n", ":host{display:block;width:100%;padding:0 var(--ngaf-chat-edge-pad);box-sizing:border-box}.chat-input__container{width:100%;max-width:var(--ngaf-chat-max-width);margin:0 auto}.chat-input__pill{display:flex;align-items:center;gap:8px;background:var(--ngaf-chat-surface);border:1px solid var(--ngaf-chat-separator);border-radius:9999px;padding:8px 8px 8px 16px;min-height:56px;box-sizing:border-box}.chat-input__textarea{flex:1 1 auto;border:0;outline:none;resize:none;background:transparent;color:var(--ngaf-chat-text);font:inherit;font-size:1rem;line-height:1.5;padding:0;field-sizing:content;overflow-y:auto}.chat-input__textarea::placeholder{color:var(--ngaf-chat-text-muted)}.chat-input__textarea::-webkit-scrollbar{width:4px}.chat-input__textarea::-webkit-scrollbar-thumb{background:var(--ngaf-chat-separator);border-radius:4px}.chat-input__controls{display:flex;align-items:center;gap:4px;flex:none}.chat-input__send,.chat-input__send--stop{width:36px;height:36px;border-radius:50%;border:0;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:opacity .15s ease,transform .15s ease,background .15s ease;padding:0}.chat-input__send{background:var(--ngaf-chat-text);color:var(--ngaf-chat-bg)}.chat-input__send:disabled{opacity:.35;cursor:not-allowed;background:var(--ngaf-chat-text-muted)}.chat-input__send:not(:disabled):hover{transform:scale(1.05)}.chat-input__send svg{width:16px;height:16px}.chat-input__send--stop{background:var(--ngaf-chat-text-muted);color:var(--ngaf-chat-bg)}.chat-input__send--stop:hover{transform:scale(1.05)}.chat-input__send--stop svg{width:14px;height:14px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2875
2884
|
}
|
|
2876
2885
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: ChatInputComponent, decorators: [{
|
|
2877
2886
|
type: Component,
|
|
2878
|
-
args: [{ selector: 'chat-input', standalone: true, imports: [
|
|
2887
|
+
args: [{ selector: 'chat-input', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
2879
2888
|
<div class="chat-input__container">
|
|
2880
2889
|
<ng-content select="[chatInputBanner]" />
|
|
2881
2890
|
<ng-content select="[chatInputAttachments]" />
|
|
@@ -2884,15 +2893,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
|
|
|
2884
2893
|
<textarea
|
|
2885
2894
|
#textareaEl
|
|
2886
2895
|
class="chat-input__textarea"
|
|
2887
|
-
[
|
|
2888
|
-
(
|
|
2889
|
-
name="messageText"
|
|
2896
|
+
[value]="messageText()"
|
|
2897
|
+
(input)="onInput($event)"
|
|
2890
2898
|
[placeholder]="placeholder()"
|
|
2891
2899
|
(keydown.enter)="onKeydown($any($event))"
|
|
2892
2900
|
(compositionstart)="composing.set(true)"
|
|
2893
2901
|
(compositionend)="composing.set(false)"
|
|
2894
2902
|
(focus)="focused.set(true)"
|
|
2895
2903
|
(blur)="focused.set(false)"
|
|
2904
|
+
name="messageText"
|
|
2896
2905
|
rows="1"
|
|
2897
2906
|
aria-label="Type a message"
|
|
2898
2907
|
></textarea>
|
|
@@ -4152,6 +4161,39 @@ function pluralize(word, count) {
|
|
|
4152
4161
|
return count === 1 ? word : `${word}s`;
|
|
4153
4162
|
}
|
|
4154
4163
|
|
|
4164
|
+
/**
|
|
4165
|
+
* Resolves the tool calls that belong to a specific message, mirroring the
|
|
4166
|
+
* per-message scoping the chat lib uses to avoid every assistant bubble
|
|
4167
|
+
* re-rendering the whole thread's tool-call list.
|
|
4168
|
+
*
|
|
4169
|
+
* - No message context → the agent's global tool-call list.
|
|
4170
|
+
* - Assistant message with `toolCallIds` (LangGraph) → those ids, in order.
|
|
4171
|
+
* - Assistant message with `tool_use` content blocks (Anthropic) → those ids.
|
|
4172
|
+
* - Assistant message with no linkage → [] (this message emitted no calls).
|
|
4173
|
+
* - Any non-assistant message → the global list (callers filter as needed).
|
|
4174
|
+
*
|
|
4175
|
+
* MUST be called inside a reactive context (computed/effect) so the
|
|
4176
|
+
* `agent.toolCalls()` signal read registers a dependency.
|
|
4177
|
+
*/
|
|
4178
|
+
function resolveMessageToolCalls(agent, message) {
|
|
4179
|
+
const all = agent.toolCalls();
|
|
4180
|
+
if (message && message.role === 'assistant') {
|
|
4181
|
+
if (message.toolCallIds && message.toolCallIds.length > 0) {
|
|
4182
|
+
return message.toolCallIds
|
|
4183
|
+
.map((id) => all.find((tc) => tc.id === id))
|
|
4184
|
+
.filter((x) => !!x);
|
|
4185
|
+
}
|
|
4186
|
+
if (Array.isArray(message.content)) {
|
|
4187
|
+
const blocks = message.content.filter((b) => b.type === 'tool_use');
|
|
4188
|
+
return blocks
|
|
4189
|
+
.map((b) => all.find((tc) => tc.id === b.id))
|
|
4190
|
+
.filter((x) => !!x);
|
|
4191
|
+
}
|
|
4192
|
+
return [];
|
|
4193
|
+
}
|
|
4194
|
+
return all;
|
|
4195
|
+
}
|
|
4196
|
+
|
|
4155
4197
|
// libs/chat/src/lib/primitives/chat-tool-calls/chat-tool-calls.component.ts
|
|
4156
4198
|
// SPDX-License-Identifier: MIT
|
|
4157
4199
|
class ChatToolCallsComponent {
|
|
@@ -4175,30 +4217,7 @@ class ChatToolCallsComponent {
|
|
|
4175
4217
|
}
|
|
4176
4218
|
return map;
|
|
4177
4219
|
}, ...(ngDevMode ? [{ debugName: "templateRegistry" }] : []));
|
|
4178
|
-
toolCalls = computed(() => {
|
|
4179
|
-
const msg = this.message();
|
|
4180
|
-
if (msg && msg.role === 'assistant') {
|
|
4181
|
-
const all = this.agent().toolCalls();
|
|
4182
|
-
// Prefer adapter-provided `toolCallIds` (LangGraph populates it from
|
|
4183
|
-
// raw `tool_calls`). This is the per-message scope that prevents
|
|
4184
|
-
// every AI bubble from re-rendering the entire thread's tool-call
|
|
4185
|
-
// list when content is a flat string (the LangGraph adapter's
|
|
4186
|
-
// default — extractTextContent reduces complex content to string).
|
|
4187
|
-
if (msg.toolCallIds && msg.toolCallIds.length > 0) {
|
|
4188
|
-
return msg.toolCallIds.map(id => all.find(tc => tc.id === id)).filter((x) => !!x);
|
|
4189
|
-
}
|
|
4190
|
-
// Anthropic-style content-block path: extract tool_use IDs inline.
|
|
4191
|
-
if (Array.isArray(msg.content)) {
|
|
4192
|
-
const blocks = msg.content.filter((b) => b.type === 'tool_use');
|
|
4193
|
-
return blocks.map(b => all.find(tc => tc.id === b.id)).filter((x) => !!x);
|
|
4194
|
-
}
|
|
4195
|
-
// Assistant message provided but no tool-call linkage available:
|
|
4196
|
-
// this message didn't emit any tool calls. Return empty.
|
|
4197
|
-
return [];
|
|
4198
|
-
}
|
|
4199
|
-
// No message context at all (e.g. agent-level pinning) → global list.
|
|
4200
|
-
return this.agent().toolCalls();
|
|
4201
|
-
}, ...(ngDevMode ? [{ debugName: "toolCalls" }] : []));
|
|
4220
|
+
toolCalls = computed(() => resolveMessageToolCalls(this.agent(), this.message()), ...(ngDevMode ? [{ debugName: "toolCalls" }] : []));
|
|
4202
4221
|
groups = computed(() => {
|
|
4203
4222
|
const excludeSet = new Set(this.excludeToolNames());
|
|
4204
4223
|
const calls = this.toolCalls().filter(tc => !excludeSet.has(tc.name));
|
|
@@ -4314,6 +4333,246 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
|
|
|
4314
4333
|
`, styles: [":host{display:block;margin-bottom:20px}.ctc__group{border:1px solid var(--ngaf-chat-separator);border-radius:var(--ngaf-chat-radius-card);margin:0 0 4px}.ctc__group-header{display:flex;align-items:center;gap:.5rem;width:100%;padding:8px 12px;background:transparent;border:0;font:inherit;color:var(--ngaf-chat-text);cursor:pointer;text-align:left}.ctc__group-chevron{width:10px;height:10px;transition:transform .12s ease}.ctc__group[data-expanded=true] .ctc__group-chevron{transform:rotate(90deg)}.ctc__group-body{padding:0 12px 8px;border-top:1px solid var(--ngaf-chat-separator)}\n"] }]
|
|
4315
4334
|
}], propDecorators: { agent: [{ type: i0.Input, args: [{ isSignal: true, alias: "agent", required: true }] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], grouping: [{ type: i0.Input, args: [{ isSignal: true, alias: "grouping", required: false }] }], groupSummary: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupSummary", required: false }] }], excludeToolNames: [{ type: i0.Input, args: [{ isSignal: true, alias: "excludeToolNames", required: false }] }], templates: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => ChatToolCallTemplateDirective), { isSignal: true }] }] } });
|
|
4316
4335
|
|
|
4336
|
+
// SPDX-License-Identifier: MIT
|
|
4337
|
+
const CHAT_GENERATIVE_UI_STYLES = `
|
|
4338
|
+
:host {
|
|
4339
|
+
display: block;
|
|
4340
|
+
color: var(--ngaf-chat-text);
|
|
4341
|
+
font-size: var(--ngaf-chat-font-size);
|
|
4342
|
+
line-height: var(--ngaf-chat-line-height);
|
|
4343
|
+
}
|
|
4344
|
+
.chat-generative-ui__error {
|
|
4345
|
+
color: var(--ngaf-chat-error-text);
|
|
4346
|
+
background: var(--ngaf-chat-error-bg);
|
|
4347
|
+
border: 1px solid var(--ngaf-chat-error-border);
|
|
4348
|
+
border-radius: var(--ngaf-chat-radius-card);
|
|
4349
|
+
padding: 8px 12px;
|
|
4350
|
+
font-size: var(--ngaf-chat-font-size-sm);
|
|
4351
|
+
}
|
|
4352
|
+
`;
|
|
4353
|
+
|
|
4354
|
+
function isStatePathRef(value) {
|
|
4355
|
+
return (typeof value === 'object' &&
|
|
4356
|
+
value !== null &&
|
|
4357
|
+
!Array.isArray(value) &&
|
|
4358
|
+
typeof value['statePath'] === 'string' &&
|
|
4359
|
+
Object.keys(value).length === 1);
|
|
4360
|
+
}
|
|
4361
|
+
/** Rewrites schema-documented `{ statePath }` prop refs to `$bindState` +
|
|
4362
|
+
* `_bindings`. Returns the input reference unchanged when no rewriting is
|
|
4363
|
+
* needed (keeps downstream memoization intact). */
|
|
4364
|
+
function normalizeJsonRenderSpec(spec) {
|
|
4365
|
+
const sourceElements = (spec.elements ?? {});
|
|
4366
|
+
let specChanged = false;
|
|
4367
|
+
const elements = {};
|
|
4368
|
+
for (const [id, el] of Object.entries(sourceElements)) {
|
|
4369
|
+
const rawProps = el?.props;
|
|
4370
|
+
if (!rawProps) {
|
|
4371
|
+
elements[id] = el;
|
|
4372
|
+
continue;
|
|
4373
|
+
}
|
|
4374
|
+
let elementChanged = false;
|
|
4375
|
+
const props = {};
|
|
4376
|
+
const bindings = {};
|
|
4377
|
+
for (const [key, value] of Object.entries(rawProps)) {
|
|
4378
|
+
if (isStatePathRef(value)) {
|
|
4379
|
+
props[key] = { $bindState: value.statePath };
|
|
4380
|
+
bindings[key] = value.statePath;
|
|
4381
|
+
elementChanged = true;
|
|
4382
|
+
}
|
|
4383
|
+
else {
|
|
4384
|
+
props[key] = value;
|
|
4385
|
+
}
|
|
4386
|
+
}
|
|
4387
|
+
if (elementChanged) {
|
|
4388
|
+
// Merge with any model-emitted `_bindings` (never observed, but cheap
|
|
4389
|
+
// to preserve) — rewritten paths win.
|
|
4390
|
+
const existing = (rawProps['_bindings'] ?? {});
|
|
4391
|
+
props['_bindings'] = { ...existing, ...bindings };
|
|
4392
|
+
elements[id] = { ...el, props };
|
|
4393
|
+
specChanged = true;
|
|
4394
|
+
}
|
|
4395
|
+
else {
|
|
4396
|
+
elements[id] = el;
|
|
4397
|
+
}
|
|
4398
|
+
}
|
|
4399
|
+
return specChanged ? { ...spec, elements } : spec;
|
|
4400
|
+
}
|
|
4401
|
+
|
|
4402
|
+
// libs/chat/src/lib/primitives/chat-generative-ui/chat-generative-ui.component.ts
|
|
4403
|
+
// SPDX-License-Identifier: MIT
|
|
4404
|
+
class ChatGenerativeUiComponent {
|
|
4405
|
+
spec = input(null, ...(ngDevMode ? [{ debugName: "spec" }] : []));
|
|
4406
|
+
registry = input(undefined, ...(ngDevMode ? [{ debugName: "registry" }] : []));
|
|
4407
|
+
store = input(undefined, ...(ngDevMode ? [{ debugName: "store" }] : []));
|
|
4408
|
+
handlers = input(undefined, ...(ngDevMode ? [{ debugName: "handlers" }] : []));
|
|
4409
|
+
loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
4410
|
+
events = output();
|
|
4411
|
+
/** The bound spec with schema-documented `{ statePath }` prop refs
|
|
4412
|
+
* rewritten to engine-native `{ $bindState }` + `_bindings` so values
|
|
4413
|
+
* resolve against the state store instead of interpolating as
|
|
4414
|
+
* "[object Object]" (F4). */
|
|
4415
|
+
normalizedSpec = computed(() => {
|
|
4416
|
+
const s = this.spec();
|
|
4417
|
+
return s ? normalizeJsonRenderSpec(s) : null;
|
|
4418
|
+
}, ...(ngDevMode ? [{ debugName: "normalizedSpec" }] : []));
|
|
4419
|
+
/** Last value this component seeded per state path. Lets the seeding
|
|
4420
|
+
* effect distinguish "still the value we wrote (possibly a partial
|
|
4421
|
+
* chunk from streaming — safe to overwrite with the newer one)" from
|
|
4422
|
+
* "user edited it via a bound control — leave it alone". */
|
|
4423
|
+
seeded = new Map();
|
|
4424
|
+
constructor() {
|
|
4425
|
+
// Seed `spec.state` (the schema's "initial state model") into an
|
|
4426
|
+
// EXPLICIT consumer-provided store, which is typically EMPTY at first —
|
|
4427
|
+
// without this, statePath/$bindState props would resolve to undefined.
|
|
4428
|
+
// A consumer-provided store intentionally has shared/live semantics
|
|
4429
|
+
// across surfaces: every surface bound to it reads (and writes) the same
|
|
4430
|
+
// state, so the first surface to seed a path wins. When NO store input
|
|
4431
|
+
// is given, this effect is a no-op and render-spec self-seeds its own
|
|
4432
|
+
// per-instance internal store from spec.state, keeping surfaces with
|
|
4433
|
+
// overlapping state keys isolated from each other (a2ui parity).
|
|
4434
|
+
effect(() => {
|
|
4435
|
+
const s = this.spec();
|
|
4436
|
+
const store = this.store();
|
|
4437
|
+
const state = s?.state;
|
|
4438
|
+
if (!state || !store)
|
|
4439
|
+
return;
|
|
4440
|
+
// Untracked: store reads/writes must not become dependencies — the
|
|
4441
|
+
// effect re-runs on spec/store-identity changes only, not on every
|
|
4442
|
+
// write to the (possibly shared) store.
|
|
4443
|
+
untracked(() => {
|
|
4444
|
+
for (const [key, value] of Object.entries(state)) {
|
|
4445
|
+
const path = key.startsWith('/') ? key : `/${key}`;
|
|
4446
|
+
const current = store.get(path);
|
|
4447
|
+
const untouched = current === undefined ||
|
|
4448
|
+
(this.seeded.has(path) && current === this.seeded.get(path));
|
|
4449
|
+
if (untouched) {
|
|
4450
|
+
if (current !== value)
|
|
4451
|
+
store.set(path, value);
|
|
4452
|
+
this.seeded.set(path, value);
|
|
4453
|
+
}
|
|
4454
|
+
}
|
|
4455
|
+
});
|
|
4456
|
+
});
|
|
4457
|
+
}
|
|
4458
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: ChatGenerativeUiComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4459
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: ChatGenerativeUiComponent, isStandalone: true, selector: "chat-generative-ui", inputs: { spec: { classPropertyName: "spec", publicName: "spec", isSignal: true, isRequired: false, transformFunction: null }, registry: { classPropertyName: "registry", publicName: "registry", isSignal: true, isRequired: false, transformFunction: null }, store: { classPropertyName: "store", publicName: "store", isSignal: true, isRequired: false, transformFunction: null }, handlers: { classPropertyName: "handlers", publicName: "handlers", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { events: "events" }, ngImport: i0, template: `
|
|
4460
|
+
@if (normalizedSpec()) {
|
|
4461
|
+
<render-spec
|
|
4462
|
+
[spec]="normalizedSpec()"
|
|
4463
|
+
[registry]="registry()"
|
|
4464
|
+
[store]="store()"
|
|
4465
|
+
[handlers]="handlers()"
|
|
4466
|
+
[loading]="loading()"
|
|
4467
|
+
(events)="events.emit($event)"
|
|
4468
|
+
/>
|
|
4469
|
+
}
|
|
4470
|
+
`, isInline: true, styles: [":host{font-family:var(--ngaf-chat-font-family);color:var(--ngaf-chat-text)}\n", ":host{display:block;color:var(--ngaf-chat-text);font-size:var(--ngaf-chat-font-size);line-height:var(--ngaf-chat-line-height)}.chat-generative-ui__error{color:var(--ngaf-chat-error-text);background:var(--ngaf-chat-error-bg);border:1px solid var(--ngaf-chat-error-border);border-radius:var(--ngaf-chat-radius-card);padding:8px 12px;font-size:var(--ngaf-chat-font-size-sm)}\n"], dependencies: [{ kind: "component", type: RenderSpecComponent, selector: "render-spec", inputs: ["spec", "registry", "store", "functions", "handlers", "loading"], outputs: ["events"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4471
|
+
}
|
|
4472
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: ChatGenerativeUiComponent, decorators: [{
|
|
4473
|
+
type: Component,
|
|
4474
|
+
args: [{ selector: 'chat-generative-ui', standalone: true, imports: [RenderSpecComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
4475
|
+
@if (normalizedSpec()) {
|
|
4476
|
+
<render-spec
|
|
4477
|
+
[spec]="normalizedSpec()"
|
|
4478
|
+
[registry]="registry()"
|
|
4479
|
+
[store]="store()"
|
|
4480
|
+
[handlers]="handlers()"
|
|
4481
|
+
[loading]="loading()"
|
|
4482
|
+
(events)="events.emit($event)"
|
|
4483
|
+
/>
|
|
4484
|
+
}
|
|
4485
|
+
`, styles: [":host{font-family:var(--ngaf-chat-font-family);color:var(--ngaf-chat-text)}\n", ":host{display:block;color:var(--ngaf-chat-text);font-size:var(--ngaf-chat-font-size);line-height:var(--ngaf-chat-line-height)}.chat-generative-ui__error{color:var(--ngaf-chat-error-text);background:var(--ngaf-chat-error-bg);border:1px solid var(--ngaf-chat-error-border);border-radius:var(--ngaf-chat-radius-card);padding:8px 12px;font-size:var(--ngaf-chat-font-size-sm)}\n"] }]
|
|
4486
|
+
}], ctorParameters: () => [], propDecorators: { spec: [{ type: i0.Input, args: [{ isSignal: true, alias: "spec", required: false }] }], registry: [{ type: i0.Input, args: [{ isSignal: true, alias: "registry", required: false }] }], store: [{ type: i0.Input, args: [{ isSignal: true, alias: "store", required: false }] }], handlers: [{ type: i0.Input, args: [{ isSignal: true, alias: "handlers", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], events: [{ type: i0.Output, args: ["events"] }] } });
|
|
4487
|
+
|
|
4488
|
+
// libs/chat/src/lib/primitives/chat-tool-views/chat-tool-views.component.ts
|
|
4489
|
+
// SPDX-License-Identifier: MIT
|
|
4490
|
+
/**
|
|
4491
|
+
* Renders a frontend component for a tool call by reusing the chat
|
|
4492
|
+
* composition's `views` registry. A tool call whose `name` matches a
|
|
4493
|
+
* registry key is bridged into a synthetic one-element render spec
|
|
4494
|
+
* (`{ root: name, elements: { [name]: { type: name, props } } }`) and
|
|
4495
|
+
* rendered through the existing render-spec pipeline.
|
|
4496
|
+
*
|
|
4497
|
+
* Props merge the live `args` (present while the call streams) with the
|
|
4498
|
+
* `result` (on completion) and always include `status`, so a view
|
|
4499
|
+
* component can show its own loading/empty/error states. `RenderElement`
|
|
4500
|
+
* filters props down to the component's declared inputs, so extra keys
|
|
4501
|
+
* (and a `status` a component chooses not to declare) are harmless.
|
|
4502
|
+
*/
|
|
4503
|
+
class ChatToolViewsComponent {
|
|
4504
|
+
agent = input.required(...(ngDevMode ? [{ debugName: "agent" }] : []));
|
|
4505
|
+
events = output();
|
|
4506
|
+
message = input(undefined, ...(ngDevMode ? [{ debugName: "message" }] : []));
|
|
4507
|
+
views = input(undefined, ...(ngDevMode ? [{ debugName: "views" }] : []));
|
|
4508
|
+
store = input(undefined, ...(ngDevMode ? [{ debugName: "store" }] : []));
|
|
4509
|
+
handlers = input({}, ...(ngDevMode ? [{ debugName: "handlers" }] : []));
|
|
4510
|
+
registry = computed(() => {
|
|
4511
|
+
const v = this.views();
|
|
4512
|
+
return v ? toRenderRegistry(v) : undefined;
|
|
4513
|
+
}, ...(ngDevMode ? [{ debugName: "registry" }] : []));
|
|
4514
|
+
toolViews = computed(() => {
|
|
4515
|
+
const v = this.views();
|
|
4516
|
+
if (!v)
|
|
4517
|
+
return [];
|
|
4518
|
+
const names = new Set(Object.keys(v));
|
|
4519
|
+
return resolveMessageToolCalls(this.agent(), this.message())
|
|
4520
|
+
.filter((tc) => names.has(tc.name))
|
|
4521
|
+
.map((tc) => ({ id: tc.id, loading: tc.status === 'running', spec: toToolViewSpec(tc) }));
|
|
4522
|
+
}, ...(ngDevMode ? [{ debugName: "toolViews" }] : []));
|
|
4523
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: ChatToolViewsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4524
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: ChatToolViewsComponent, isStandalone: true, selector: "chat-tool-views", inputs: { agent: { classPropertyName: "agent", publicName: "agent", isSignal: true, isRequired: true, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, views: { classPropertyName: "views", publicName: "views", isSignal: true, isRequired: false, transformFunction: null }, store: { classPropertyName: "store", publicName: "store", isSignal: true, isRequired: false, transformFunction: null }, handlers: { classPropertyName: "handlers", publicName: "handlers", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { events: "events" }, ngImport: i0, template: `
|
|
4525
|
+
@for (view of toolViews(); track view.id) {
|
|
4526
|
+
<chat-generative-ui
|
|
4527
|
+
[spec]="view.spec"
|
|
4528
|
+
[registry]="registry()"
|
|
4529
|
+
[store]="store()"
|
|
4530
|
+
[handlers]="handlers()"
|
|
4531
|
+
[loading]="view.loading"
|
|
4532
|
+
(events)="events.emit($event)"
|
|
4533
|
+
/>
|
|
4534
|
+
}
|
|
4535
|
+
`, isInline: true, dependencies: [{ kind: "component", type: ChatGenerativeUiComponent, selector: "chat-generative-ui", inputs: ["spec", "registry", "store", "handlers", "loading"], outputs: ["events"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4536
|
+
}
|
|
4537
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: ChatToolViewsComponent, decorators: [{
|
|
4538
|
+
type: Component,
|
|
4539
|
+
args: [{
|
|
4540
|
+
selector: 'chat-tool-views',
|
|
4541
|
+
standalone: true,
|
|
4542
|
+
imports: [ChatGenerativeUiComponent],
|
|
4543
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
4544
|
+
template: `
|
|
4545
|
+
@for (view of toolViews(); track view.id) {
|
|
4546
|
+
<chat-generative-ui
|
|
4547
|
+
[spec]="view.spec"
|
|
4548
|
+
[registry]="registry()"
|
|
4549
|
+
[store]="store()"
|
|
4550
|
+
[handlers]="handlers()"
|
|
4551
|
+
[loading]="view.loading"
|
|
4552
|
+
(events)="events.emit($event)"
|
|
4553
|
+
/>
|
|
4554
|
+
}
|
|
4555
|
+
`,
|
|
4556
|
+
}]
|
|
4557
|
+
}], propDecorators: { agent: [{ type: i0.Input, args: [{ isSignal: true, alias: "agent", required: true }] }], events: [{ type: i0.Output, args: ["events"] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], views: [{ type: i0.Input, args: [{ isSignal: true, alias: "views", required: false }] }], store: [{ type: i0.Input, args: [{ isSignal: true, alias: "store", required: false }] }], handlers: [{ type: i0.Input, args: [{ isSignal: true, alias: "handlers", required: false }] }] } });
|
|
4558
|
+
/** Wraps a tool call into a synthetic single-element render spec. */
|
|
4559
|
+
function toToolViewSpec(tc) {
|
|
4560
|
+
const args = isRecord$2(tc.args) ? tc.args : {};
|
|
4561
|
+
const result = isRecord$2(tc.result) ? tc.result : {};
|
|
4562
|
+
return {
|
|
4563
|
+
root: tc.name,
|
|
4564
|
+
elements: {
|
|
4565
|
+
[tc.name]: {
|
|
4566
|
+
type: tc.name,
|
|
4567
|
+
props: { ...args, ...result, status: tc.status },
|
|
4568
|
+
},
|
|
4569
|
+
},
|
|
4570
|
+
};
|
|
4571
|
+
}
|
|
4572
|
+
function isRecord$2(v) {
|
|
4573
|
+
return typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
4574
|
+
}
|
|
4575
|
+
|
|
4317
4576
|
// libs/chat/src/lib/compositions/chat-subagent-card/chat-subagent-card.component.ts
|
|
4318
4577
|
// SPDX-License-Identifier: MIT
|
|
4319
4578
|
/**
|
|
@@ -5783,63 +6042,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
|
|
|
5783
6042
|
}]
|
|
5784
6043
|
}], propDecorators: { agent: [{ type: i0.Input, args: [{ isSignal: true, alias: "agent", required: true }] }], checkpointSelected: [{ type: i0.Output, args: ["checkpointSelected"] }], templateRef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }] } });
|
|
5785
6044
|
|
|
5786
|
-
// SPDX-License-Identifier: MIT
|
|
5787
|
-
const CHAT_GENERATIVE_UI_STYLES = `
|
|
5788
|
-
:host {
|
|
5789
|
-
display: block;
|
|
5790
|
-
color: var(--ngaf-chat-text);
|
|
5791
|
-
font-size: var(--ngaf-chat-font-size);
|
|
5792
|
-
line-height: var(--ngaf-chat-line-height);
|
|
5793
|
-
}
|
|
5794
|
-
.chat-generative-ui__error {
|
|
5795
|
-
color: var(--ngaf-chat-error-text);
|
|
5796
|
-
background: var(--ngaf-chat-error-bg);
|
|
5797
|
-
border: 1px solid var(--ngaf-chat-error-border);
|
|
5798
|
-
border-radius: var(--ngaf-chat-radius-card);
|
|
5799
|
-
padding: 8px 12px;
|
|
5800
|
-
font-size: var(--ngaf-chat-font-size-sm);
|
|
5801
|
-
}
|
|
5802
|
-
`;
|
|
5803
|
-
|
|
5804
|
-
// libs/chat/src/lib/primitives/chat-generative-ui/chat-generative-ui.component.ts
|
|
5805
|
-
// SPDX-License-Identifier: MIT
|
|
5806
|
-
class ChatGenerativeUiComponent {
|
|
5807
|
-
spec = input(null, ...(ngDevMode ? [{ debugName: "spec" }] : []));
|
|
5808
|
-
registry = input(undefined, ...(ngDevMode ? [{ debugName: "registry" }] : []));
|
|
5809
|
-
store = input(undefined, ...(ngDevMode ? [{ debugName: "store" }] : []));
|
|
5810
|
-
handlers = input(undefined, ...(ngDevMode ? [{ debugName: "handlers" }] : []));
|
|
5811
|
-
loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
5812
|
-
events = output();
|
|
5813
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: ChatGenerativeUiComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5814
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: ChatGenerativeUiComponent, isStandalone: true, selector: "chat-generative-ui", inputs: { spec: { classPropertyName: "spec", publicName: "spec", isSignal: true, isRequired: false, transformFunction: null }, registry: { classPropertyName: "registry", publicName: "registry", isSignal: true, isRequired: false, transformFunction: null }, store: { classPropertyName: "store", publicName: "store", isSignal: true, isRequired: false, transformFunction: null }, handlers: { classPropertyName: "handlers", publicName: "handlers", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { events: "events" }, ngImport: i0, template: `
|
|
5815
|
-
@if (spec()) {
|
|
5816
|
-
<render-spec
|
|
5817
|
-
[spec]="spec()"
|
|
5818
|
-
[registry]="registry()"
|
|
5819
|
-
[store]="store()"
|
|
5820
|
-
[handlers]="handlers()"
|
|
5821
|
-
[loading]="loading()"
|
|
5822
|
-
(events)="events.emit($event)"
|
|
5823
|
-
/>
|
|
5824
|
-
}
|
|
5825
|
-
`, isInline: true, styles: [":host{font-family:var(--ngaf-chat-font-family);color:var(--ngaf-chat-text)}\n", ":host{display:block;color:var(--ngaf-chat-text);font-size:var(--ngaf-chat-font-size);line-height:var(--ngaf-chat-line-height)}.chat-generative-ui__error{color:var(--ngaf-chat-error-text);background:var(--ngaf-chat-error-bg);border:1px solid var(--ngaf-chat-error-border);border-radius:var(--ngaf-chat-radius-card);padding:8px 12px;font-size:var(--ngaf-chat-font-size-sm)}\n"], dependencies: [{ kind: "component", type: RenderSpecComponent, selector: "render-spec", inputs: ["spec", "registry", "store", "functions", "handlers", "loading"], outputs: ["events"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
5826
|
-
}
|
|
5827
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: ChatGenerativeUiComponent, decorators: [{
|
|
5828
|
-
type: Component,
|
|
5829
|
-
args: [{ selector: 'chat-generative-ui', standalone: true, imports: [RenderSpecComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
5830
|
-
@if (spec()) {
|
|
5831
|
-
<render-spec
|
|
5832
|
-
[spec]="spec()"
|
|
5833
|
-
[registry]="registry()"
|
|
5834
|
-
[store]="store()"
|
|
5835
|
-
[handlers]="handlers()"
|
|
5836
|
-
[loading]="loading()"
|
|
5837
|
-
(events)="events.emit($event)"
|
|
5838
|
-
/>
|
|
5839
|
-
}
|
|
5840
|
-
`, styles: [":host{font-family:var(--ngaf-chat-font-family);color:var(--ngaf-chat-text)}\n", ":host{display:block;color:var(--ngaf-chat-text);font-size:var(--ngaf-chat-font-size);line-height:var(--ngaf-chat-line-height)}.chat-generative-ui__error{color:var(--ngaf-chat-error-text);background:var(--ngaf-chat-error-bg);border:1px solid var(--ngaf-chat-error-border);border-radius:var(--ngaf-chat-radius-card);padding:8px 12px;font-size:var(--ngaf-chat-font-size-sm)}\n"] }]
|
|
5841
|
-
}], propDecorators: { spec: [{ type: i0.Input, args: [{ isSignal: true, alias: "spec", required: false }] }], registry: [{ type: i0.Input, args: [{ isSignal: true, alias: "registry", required: false }] }], store: [{ type: i0.Input, args: [{ isSignal: true, alias: "store", required: false }] }], handlers: [{ type: i0.Input, args: [{ isSignal: true, alias: "handlers", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], events: [{ type: i0.Output, args: ["events"] }] } });
|
|
5842
|
-
|
|
5843
6045
|
// libs/chat/src/lib/styles/chat-welcome.styles.ts
|
|
5844
6046
|
// SPDX-License-Identifier: MIT
|
|
5845
6047
|
const CHAT_WELCOME_STYLES = `
|
|
@@ -6325,6 +6527,143 @@ function provideChat(config) {
|
|
|
6325
6527
|
// SPDX-License-Identifier: MIT
|
|
6326
6528
|
const CHAT_LIFECYCLE = new InjectionToken('CHAT_LIFECYCLE');
|
|
6327
6529
|
|
|
6530
|
+
// SPDX-License-Identifier: MIT
|
|
6531
|
+
/**
|
|
6532
|
+
* Convert a Standard Schema to a JSON Schema for the model's `parameters`.
|
|
6533
|
+
* Uses Zod's converter; throws a clear error for non-Zod validators (callers
|
|
6534
|
+
* should supply a Zod schema — see the client-tools docs).
|
|
6535
|
+
*/
|
|
6536
|
+
function deriveJsonSchema(toolName, schema) {
|
|
6537
|
+
try {
|
|
6538
|
+
return toJSONSchema(schema);
|
|
6539
|
+
}
|
|
6540
|
+
catch (err) {
|
|
6541
|
+
throw new Error(`client tool "${toolName}": could not derive a JSON Schema from its schema. ` +
|
|
6542
|
+
`Use a Zod schema (recommended) or an already-JSON-Schema-compatible validator. ` +
|
|
6543
|
+
`Underlying error: ${err instanceof Error ? err.message : String(err)}`);
|
|
6544
|
+
}
|
|
6545
|
+
}
|
|
6546
|
+
|
|
6547
|
+
/** Validate raw model args against a Standard Schema. */
|
|
6548
|
+
async function validateArgs(schema, args) {
|
|
6549
|
+
const res = await schema['~standard'].validate(args);
|
|
6550
|
+
if (res.issues) {
|
|
6551
|
+
return { ok: false, error: res.issues.map((i) => i.message).join('; ') };
|
|
6552
|
+
}
|
|
6553
|
+
// Cast rather than rely on discriminant narrowing: the cockpit example apps
|
|
6554
|
+
// compile this source with `strictNullChecks: false`, where the
|
|
6555
|
+
// `issues?: undefined` discriminant doesn't narrow `res` to the success type.
|
|
6556
|
+
return { ok: true, value: res.value };
|
|
6557
|
+
}
|
|
6558
|
+
/** Validate args, run the handler, and normalize the outcome to a ClientToolResult. */
|
|
6559
|
+
async function executeFunctionTool(def, rawArgs) {
|
|
6560
|
+
const v = await validateArgs(def.schema, rawArgs);
|
|
6561
|
+
if (!v.ok)
|
|
6562
|
+
return { ok: false, error: `invalid arguments: ${v.error}` };
|
|
6563
|
+
try {
|
|
6564
|
+
const value = await def.handler(v.value);
|
|
6565
|
+
return { ok: true, value };
|
|
6566
|
+
}
|
|
6567
|
+
catch (err) {
|
|
6568
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
6569
|
+
}
|
|
6570
|
+
}
|
|
6571
|
+
|
|
6572
|
+
// SPDX-License-Identifier: MIT
|
|
6573
|
+
/**
|
|
6574
|
+
* Watches the agent's pending client tool calls and auto-runs FUNCTION tools,
|
|
6575
|
+
* resolving each with its result. View/ask (component) tools are handled by the
|
|
6576
|
+
* rendering layer, not here. No-op if the agent lacks the clientTools
|
|
6577
|
+
* capability. MUST be called in an injection context (sets up an effect).
|
|
6578
|
+
*/
|
|
6579
|
+
function startClientToolExecutor(agent, registry) {
|
|
6580
|
+
const cap = agent.clientTools;
|
|
6581
|
+
if (!cap)
|
|
6582
|
+
return;
|
|
6583
|
+
const inFlight = new Set();
|
|
6584
|
+
effect(() => {
|
|
6585
|
+
for (const tc of cap.pending()) {
|
|
6586
|
+
const def = registry[tc.name];
|
|
6587
|
+
if (!def || def.kind !== 'function')
|
|
6588
|
+
continue; // non-function handled elsewhere
|
|
6589
|
+
// NB: do NOT skip on `tc.status === 'complete'`. A client tool call is
|
|
6590
|
+
// marked 'complete' once its args finish streaming, yet it still has no
|
|
6591
|
+
// result and needs the browser to execute it. `pending` already excludes
|
|
6592
|
+
// calls that have a result or were resolved; `inFlight` prevents a
|
|
6593
|
+
// double-dispatch within a render cycle.
|
|
6594
|
+
if (inFlight.has(tc.id))
|
|
6595
|
+
continue;
|
|
6596
|
+
inFlight.add(tc.id);
|
|
6597
|
+
void executeFunctionTool(def, tc.args).then((result) => {
|
|
6598
|
+
cap.resolve(tc.id, result);
|
|
6599
|
+
inFlight.delete(tc.id);
|
|
6600
|
+
});
|
|
6601
|
+
}
|
|
6602
|
+
});
|
|
6603
|
+
}
|
|
6604
|
+
|
|
6605
|
+
// SPDX-License-Identifier: MIT
|
|
6606
|
+
/** Build the catalog spec list shipped to the model. */
|
|
6607
|
+
function toClientToolSpecs(registry) {
|
|
6608
|
+
return Object.entries(registry).map(([name, def]) => ({
|
|
6609
|
+
name,
|
|
6610
|
+
description: def.description,
|
|
6611
|
+
parameters: deriveJsonSchema(name, def.schema),
|
|
6612
|
+
}));
|
|
6613
|
+
}
|
|
6614
|
+
/** Map each view/ask tool to a RenderViewEntry that carries its schema, so the
|
|
6615
|
+
* render lib can gate the real component's mount on schema-readiness (showing
|
|
6616
|
+
* the fallback skeleton while a streaming tool call's args are still
|
|
6617
|
+
* incomplete) instead of mounting a required-input component too early. */
|
|
6618
|
+
function viewComponents(registry) {
|
|
6619
|
+
const out = {};
|
|
6620
|
+
for (const [name, def] of Object.entries(registry)) {
|
|
6621
|
+
if (def.kind === 'view' || def.kind === 'ask') {
|
|
6622
|
+
out[name] = { component: def.component, schema: def.schema };
|
|
6623
|
+
}
|
|
6624
|
+
}
|
|
6625
|
+
return out;
|
|
6626
|
+
}
|
|
6627
|
+
function createClientToolsCoordinator(registry) {
|
|
6628
|
+
const viewRegistry = views(viewComponents(registry));
|
|
6629
|
+
const ackedViews = new Set();
|
|
6630
|
+
return {
|
|
6631
|
+
viewRegistry,
|
|
6632
|
+
connect(agent) {
|
|
6633
|
+
const cap = agent.clientTools;
|
|
6634
|
+
if (!cap)
|
|
6635
|
+
return;
|
|
6636
|
+
cap.setCatalog(toClientToolSpecs(registry));
|
|
6637
|
+
startClientToolExecutor(agent, registry); // function tools
|
|
6638
|
+
// Auto-ack `view` tools: they render but produce no user value.
|
|
6639
|
+
effect(() => {
|
|
6640
|
+
for (const tc of cap.pending()) {
|
|
6641
|
+
const def = registry[tc.name];
|
|
6642
|
+
if (!def || def.kind !== 'view')
|
|
6643
|
+
continue;
|
|
6644
|
+
if (ackedViews.has(tc.id))
|
|
6645
|
+
continue;
|
|
6646
|
+
ackedViews.add(tc.id);
|
|
6647
|
+
cap.resolve(tc.id, { ok: true, value: { shown: true } });
|
|
6648
|
+
}
|
|
6649
|
+
});
|
|
6650
|
+
},
|
|
6651
|
+
handleRenderEvent(agent, event) {
|
|
6652
|
+
if (event.type !== 'result')
|
|
6653
|
+
return;
|
|
6654
|
+
const cap = agent.clientTools;
|
|
6655
|
+
if (!cap)
|
|
6656
|
+
return;
|
|
6657
|
+
// elementKey is the tool NAME in the tool-view spec; resolve the pending `ask`
|
|
6658
|
+
// call for that name with the component's emitted value.
|
|
6659
|
+
const name = event.elementKey;
|
|
6660
|
+
const pending = cap.pending().find((tc) => tc.name === name && registry[tc.name]?.kind === 'ask');
|
|
6661
|
+
if (pending)
|
|
6662
|
+
cap.resolve(pending.id, { ok: true, value: event.value });
|
|
6663
|
+
},
|
|
6664
|
+
};
|
|
6665
|
+
}
|
|
6666
|
+
|
|
6328
6667
|
const RESERVED_PROP_KEYS = new Set(['child', 'children', 'action', 'tabItems', 'entryPointChild', 'contentChild']);
|
|
6329
6668
|
/** Pull the (single) component-type key + its props from a v1 ComponentDef wrapper. */
|
|
6330
6669
|
function unwrapComponentDef(def) {
|
|
@@ -6390,9 +6729,8 @@ function surfaceToSpec(surface) {
|
|
|
6390
6729
|
// snapshot taken at conversion time and never reflects user
|
|
6391
6730
|
// input writes back into the store. The `_bindings` map below
|
|
6392
6731
|
// tells the catalog component which prop names map to which
|
|
6393
|
-
// paths so its
|
|
6394
|
-
//
|
|
6395
|
-
// render-element's emitFn intercepts.
|
|
6732
|
+
// paths so its injectRenderHost().set(path, value) call can
|
|
6733
|
+
// write the typed value back to the render state store.
|
|
6396
6734
|
const path = value.path;
|
|
6397
6735
|
bindings[key] = path;
|
|
6398
6736
|
resolvedProps[key] = { $bindState: path };
|
|
@@ -7695,7 +8033,7 @@ function isStructurallyComplete(env) {
|
|
|
7695
8033
|
* message, so the chat composition can render "Search flights" instead
|
|
7696
8034
|
* of a raw `{"version":"v1","action":...}` JSON dump as a user bubble.
|
|
7697
8035
|
*
|
|
7698
|
-
* Per the A2UI
|
|
8036
|
+
* Per the A2UI spec, action messages flow on the client → agent
|
|
7699
8037
|
* return channel and are framed as typed events (closer to tool calls
|
|
7700
8038
|
* than user utterances). The spec is silent on chat-bubble rendering;
|
|
7701
8039
|
* Google's "A2UI in Practice" article and the Stream Chat reference
|
|
@@ -7831,6 +8169,14 @@ function isPinned(scrollHeight, scrollTop, clientHeight, tolerance = 150) {
|
|
|
7831
8169
|
class ChatComponent {
|
|
7832
8170
|
agent = input.required(...(ngDevMode ? [{ debugName: "agent" }] : []));
|
|
7833
8171
|
views = input(undefined, ...(ngDevMode ? [{ debugName: "views" }] : []));
|
|
8172
|
+
/**
|
|
8173
|
+
* Client-declared tools (`view`/`ask`/`function`) the model may call. When
|
|
8174
|
+
* provided, a coordinator ships their catalog to the agent, runs `function`
|
|
8175
|
+
* tools in the browser, and renders/resolves `view`/`ask` tools through the
|
|
8176
|
+
* same tool-views pipeline as `views`. Additive — leave undefined for the
|
|
8177
|
+
* classic server-tools-only experience.
|
|
8178
|
+
*/
|
|
8179
|
+
clientTools = input(undefined, ...(ngDevMode ? [{ debugName: "clientTools" }] : []));
|
|
7834
8180
|
store = input(undefined, ...(ngDevMode ? [{ debugName: "store" }] : []));
|
|
7835
8181
|
handlers = input({}, ...(ngDevMode ? [{ debugName: "handlers" }] : []));
|
|
7836
8182
|
threads = input([], ...(ngDevMode ? [{ debugName: "threads" }] : []));
|
|
@@ -7887,14 +8233,50 @@ class ChatComponent {
|
|
|
7887
8233
|
const explicit = this.store();
|
|
7888
8234
|
if (explicit)
|
|
7889
8235
|
return explicit;
|
|
7890
|
-
|
|
8236
|
+
// A render store is needed whenever there's any view registry to render
|
|
8237
|
+
// through — user-supplied `views()` OR client-tool view/ask components.
|
|
8238
|
+
if (this.effectiveViews())
|
|
7891
8239
|
return this._internalStore;
|
|
7892
8240
|
return undefined;
|
|
7893
8241
|
}, ...(ngDevMode ? [{ debugName: "resolvedStore" }] : []));
|
|
8242
|
+
/**
|
|
8243
|
+
* Lazily-built client-tools coordinator, memoized on the `clientTools`
|
|
8244
|
+
* registry input. Undefined when no client tools are declared. The
|
|
8245
|
+
* coordinator owns the catalog/executor wiring and the view/ask render
|
|
8246
|
+
* registry; the composition merges and connects it below.
|
|
8247
|
+
*/
|
|
8248
|
+
coordinator = computed(() => {
|
|
8249
|
+
const reg = this.clientTools();
|
|
8250
|
+
return reg ? createClientToolsCoordinator(reg) : undefined;
|
|
8251
|
+
}, ...(ngDevMode ? [{ debugName: "coordinator" }] : []));
|
|
8252
|
+
/**
|
|
8253
|
+
* The view registry actually used for rendering tool-views and for
|
|
8254
|
+
* excluding view-backed tool names from default tool-call cards. Merges
|
|
8255
|
+
* the coordinator's `view`/`ask` components (keyed by tool name) into the
|
|
8256
|
+
* user-supplied `views()` so client-declared component tools render through
|
|
8257
|
+
* the same pipeline. Falls back to `views()` when no client tools exist.
|
|
8258
|
+
*/
|
|
8259
|
+
effectiveViews = computed(() => {
|
|
8260
|
+
const base = this.views();
|
|
8261
|
+
const coord = this.coordinator();
|
|
8262
|
+
if (!coord)
|
|
8263
|
+
return base;
|
|
8264
|
+
return base ? withViews(base, coord.viewRegistry) : coord.viewRegistry;
|
|
8265
|
+
}, ...(ngDevMode ? [{ debugName: "effectiveViews" }] : []));
|
|
7894
8266
|
renderRegistry = computed(() => {
|
|
7895
8267
|
const v = this.views();
|
|
7896
8268
|
return v ? toRenderRegistry(v) : undefined;
|
|
7897
8269
|
}, ...(ngDevMode ? [{ debugName: "renderRegistry" }] : []));
|
|
8270
|
+
/** Tool names that have a registered view (keys of the effective view
|
|
8271
|
+
* registry, including client-declared view/ask tools). These render as
|
|
8272
|
+
* inline tool-views and are excluded from the default tool-call card so
|
|
8273
|
+
* they don't render twice. */
|
|
8274
|
+
viewToolNames = computed(() => Object.keys(this.effectiveViews() ?? {}), ...(ngDevMode ? [{ debugName: "viewToolNames" }] : []));
|
|
8275
|
+
/** Union of GenUI dispatcher tool names and registered view tool names. */
|
|
8276
|
+
excludedToolNames = computed(() => [
|
|
8277
|
+
...this.genuiToolNames(),
|
|
8278
|
+
...this.viewToolNames(),
|
|
8279
|
+
], ...(ngDevMode ? [{ debugName: "excludedToolNames" }] : []));
|
|
7898
8280
|
messageContent = messageContent;
|
|
7899
8281
|
/**
|
|
7900
8282
|
* Renderable content for a human-role message bubble. Most human
|
|
@@ -7903,7 +8285,7 @@ class ChatComponent {
|
|
|
7903
8285
|
* on a rendered surface) flow through the same submit channel and
|
|
7904
8286
|
* land in the message stream as a HumanMessage whose content is a
|
|
7905
8287
|
* JSON-serialized `A2uiActionMessage`. Showing the raw JSON as if
|
|
7906
|
-
* the user typed it leaks the protocol; per the A2UI
|
|
8288
|
+
* the user typed it leaks the protocol; per the A2UI spec
|
|
7907
8289
|
* those events resemble tool calls more than user utterances.
|
|
7908
8290
|
*
|
|
7909
8291
|
* `a2uiActionLabel` returns a short human-readable label for
|
|
@@ -7936,6 +8318,7 @@ class ChatComponent {
|
|
|
7936
8318
|
}
|
|
7937
8319
|
classifiers = new Map();
|
|
7938
8320
|
destroyRef = inject(DestroyRef);
|
|
8321
|
+
injector = inject(Injector);
|
|
7939
8322
|
// Resolved against the component's own `providers` in normal use. The fallback
|
|
7940
8323
|
// is for tests that construct ChatComponent via `new` inside a bare injection
|
|
7941
8324
|
// context (no element injector, so component-level providers are skipped).
|
|
@@ -8015,6 +8398,38 @@ class ChatComponent {
|
|
|
8015
8398
|
store.update(event.data);
|
|
8016
8399
|
});
|
|
8017
8400
|
});
|
|
8401
|
+
// Sync the agent STATE signal into the render store. AG-UI delivers
|
|
8402
|
+
// backend data as agent shared state (STATE_SNAPSHOT/STATE_DELTA); other
|
|
8403
|
+
// adapters expose graph state via the same `state()` signal. The render
|
|
8404
|
+
// store keys are JSON pointers, so map each top-level state key `k` to
|
|
8405
|
+
// `/k`. Exclude `messages` (carried in the snapshot but irrelevant to the
|
|
8406
|
+
// render store and large). Fires for any adapter whose `state()` carries
|
|
8407
|
+
// non-message keys; no-op when no render store is active. Coexists with
|
|
8408
|
+
// the events$ `state_update` path above (both merge into the same store).
|
|
8409
|
+
effect(() => {
|
|
8410
|
+
let agentRef;
|
|
8411
|
+
try {
|
|
8412
|
+
agentRef = this.agent();
|
|
8413
|
+
}
|
|
8414
|
+
catch {
|
|
8415
|
+
return;
|
|
8416
|
+
}
|
|
8417
|
+
const stateFn = agentRef.state;
|
|
8418
|
+
if (typeof stateFn !== 'function')
|
|
8419
|
+
return;
|
|
8420
|
+
const state = stateFn.call(agentRef);
|
|
8421
|
+
const store = this.resolvedStore();
|
|
8422
|
+
if (!store || state == null || typeof state !== 'object' || Array.isArray(state))
|
|
8423
|
+
return;
|
|
8424
|
+
const updates = {};
|
|
8425
|
+
for (const [k, v] of Object.entries(state)) {
|
|
8426
|
+
if (k === 'messages')
|
|
8427
|
+
continue;
|
|
8428
|
+
updates['/' + k] = v;
|
|
8429
|
+
}
|
|
8430
|
+
if (Object.keys(updates).length > 0)
|
|
8431
|
+
store.update(updates);
|
|
8432
|
+
});
|
|
8018
8433
|
// Spec 4: flip CHAT_LIFECYCLE.firstMessageSent when the agent's stream
|
|
8019
8434
|
// starts, regardless of submit path (input-bound, programmatic, suggestion-
|
|
8020
8435
|
// click). Sticky — guarded so we never re-set a flag that's already true.
|
|
@@ -8125,6 +8540,35 @@ class ChatComponent {
|
|
|
8125
8540
|
}
|
|
8126
8541
|
this.partialEventsLastIndex = events.length;
|
|
8127
8542
|
});
|
|
8543
|
+
// Connect the client-tools coordinator to the agent. connect() ships the
|
|
8544
|
+
// tool catalog, starts the function-tool executor, and installs the view
|
|
8545
|
+
// auto-ack effect. Those installs create effect()s of their own, which
|
|
8546
|
+
// Angular forbids from *within* a running effect (NG0602). So this effect
|
|
8547
|
+
// only detects readiness (both coordinator + agent present) and defers the
|
|
8548
|
+
// actual connect() to a microtask that runs OUTSIDE the reactive context,
|
|
8549
|
+
// re-entering the component's injection context so the coordinator's
|
|
8550
|
+
// effects bind to this component's lifecycle. `connected` guards against
|
|
8551
|
+
// re-running per coordinator identity (a new clientTools registry yields a
|
|
8552
|
+
// new coordinator and re-connects; the old one's effects are abandoned).
|
|
8553
|
+
let connected;
|
|
8554
|
+
effect(() => {
|
|
8555
|
+
const coord = this.coordinator();
|
|
8556
|
+
let agentRef;
|
|
8557
|
+
try {
|
|
8558
|
+
agentRef = this.agent();
|
|
8559
|
+
}
|
|
8560
|
+
catch {
|
|
8561
|
+
return;
|
|
8562
|
+
}
|
|
8563
|
+
if (!coord || !agentRef)
|
|
8564
|
+
return;
|
|
8565
|
+
if (connected === coord)
|
|
8566
|
+
return;
|
|
8567
|
+
connected = coord;
|
|
8568
|
+
queueMicrotask(() => {
|
|
8569
|
+
runInInjectionContext(this.injector, () => coord.connect(agentRef));
|
|
8570
|
+
});
|
|
8571
|
+
});
|
|
8128
8572
|
effect(() => {
|
|
8129
8573
|
// janitor: drop classifiers for messages no longer in the agent's list
|
|
8130
8574
|
let liveIds;
|
|
@@ -8342,6 +8786,25 @@ class ChatComponent {
|
|
|
8342
8786
|
onSpecEvent(event, messageIndex) {
|
|
8343
8787
|
this.renderEvent.emit({ messageIndex, event });
|
|
8344
8788
|
}
|
|
8789
|
+
/**
|
|
8790
|
+
* Forwards a render event bubbled up from a `<chat-tool-views>` component
|
|
8791
|
+
* (a client-declared `view`/`ask` tool's rendered UI) to the client-tools
|
|
8792
|
+
* coordinator. The coordinator resolves the matching pending `ask` tool call
|
|
8793
|
+
* when the event is a `result`. No-op when no client tools are wired.
|
|
8794
|
+
*/
|
|
8795
|
+
onClientToolEvent(event) {
|
|
8796
|
+
const coord = this.coordinator();
|
|
8797
|
+
if (!coord)
|
|
8798
|
+
return;
|
|
8799
|
+
let agentRef;
|
|
8800
|
+
try {
|
|
8801
|
+
agentRef = this.agent();
|
|
8802
|
+
}
|
|
8803
|
+
catch {
|
|
8804
|
+
return;
|
|
8805
|
+
}
|
|
8806
|
+
coord.handleRenderEvent(agentRef, event);
|
|
8807
|
+
}
|
|
8345
8808
|
onA2uiAction(message) {
|
|
8346
8809
|
void this.agent().submit({ message: JSON.stringify(message) });
|
|
8347
8810
|
}
|
|
@@ -8362,7 +8825,7 @@ class ChatComponent {
|
|
|
8362
8825
|
this.messageCopy.emit({ messageIndex: idx, content });
|
|
8363
8826
|
}
|
|
8364
8827
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: ChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8365
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: ChatComponent, isStandalone: true, selector: "chat", inputs: { agent: { classPropertyName: "agent", publicName: "agent", isSignal: true, isRequired: true, transformFunction: null }, views: { classPropertyName: "views", publicName: "views", isSignal: true, isRequired: false, transformFunction: null }, store: { classPropertyName: "store", publicName: "store", isSignal: true, isRequired: false, transformFunction: null }, handlers: { classPropertyName: "handlers", publicName: "handlers", isSignal: true, isRequired: false, transformFunction: null }, threads: { classPropertyName: "threads", publicName: "threads", isSignal: true, isRequired: false, transformFunction: null }, activeThreadId: { classPropertyName: "activeThreadId", publicName: "activeThreadId", isSignal: true, isRequired: false, transformFunction: null }, welcomeDisabled: { classPropertyName: "welcomeDisabled", publicName: "welcomeDisabled", isSignal: true, isRequired: false, transformFunction: null }, modelOptions: { classPropertyName: "modelOptions", publicName: "modelOptions", isSignal: true, isRequired: false, transformFunction: null }, showModelPicker: { classPropertyName: "showModelPicker", publicName: "showModelPicker", isSignal: true, isRequired: false, transformFunction: null }, selectedModel: { classPropertyName: "selectedModel", publicName: "selectedModel", isSignal: true, isRequired: false, transformFunction: null }, modelPickerPlaceholder: { classPropertyName: "modelPickerPlaceholder", publicName: "modelPickerPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, genuiToolNames: { classPropertyName: "genuiToolNames", publicName: "genuiToolNames", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedModel: "selectedModelChange", threadSelected: "threadSelected", renderEvent: "renderEvent", regenerate: "regenerate", rate: "rate", messageCopy: "messageCopy" }, providers: [
|
|
8828
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: ChatComponent, isStandalone: true, selector: "chat", inputs: { agent: { classPropertyName: "agent", publicName: "agent", isSignal: true, isRequired: true, transformFunction: null }, views: { classPropertyName: "views", publicName: "views", isSignal: true, isRequired: false, transformFunction: null }, clientTools: { classPropertyName: "clientTools", publicName: "clientTools", isSignal: true, isRequired: false, transformFunction: null }, store: { classPropertyName: "store", publicName: "store", isSignal: true, isRequired: false, transformFunction: null }, handlers: { classPropertyName: "handlers", publicName: "handlers", isSignal: true, isRequired: false, transformFunction: null }, threads: { classPropertyName: "threads", publicName: "threads", isSignal: true, isRequired: false, transformFunction: null }, activeThreadId: { classPropertyName: "activeThreadId", publicName: "activeThreadId", isSignal: true, isRequired: false, transformFunction: null }, welcomeDisabled: { classPropertyName: "welcomeDisabled", publicName: "welcomeDisabled", isSignal: true, isRequired: false, transformFunction: null }, modelOptions: { classPropertyName: "modelOptions", publicName: "modelOptions", isSignal: true, isRequired: false, transformFunction: null }, showModelPicker: { classPropertyName: "showModelPicker", publicName: "showModelPicker", isSignal: true, isRequired: false, transformFunction: null }, selectedModel: { classPropertyName: "selectedModel", publicName: "selectedModel", isSignal: true, isRequired: false, transformFunction: null }, modelPickerPlaceholder: { classPropertyName: "modelPickerPlaceholder", publicName: "modelPickerPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, genuiToolNames: { classPropertyName: "genuiToolNames", publicName: "genuiToolNames", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedModel: "selectedModelChange", threadSelected: "threadSelected", renderEvent: "renderEvent", regenerate: "regenerate", rate: "rate", messageCopy: "messageCopy" }, providers: [
|
|
8366
8829
|
{ provide: CHAT_LIFECYCLE, useFactory: createChatLifecycle },
|
|
8367
8830
|
], viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
8368
8831
|
@if (showWelcome()) {
|
|
@@ -8419,20 +8882,34 @@ class ChatComponent {
|
|
|
8419
8882
|
[durationMs]="message.reasoningDurationMs"
|
|
8420
8883
|
/>
|
|
8421
8884
|
}
|
|
8422
|
-
<chat-tool-calls [agent]="agent()" [message]="message" [excludeToolNames]="
|
|
8885
|
+
<chat-tool-calls [agent]="agent()" [message]="message" [excludeToolNames]="excludedToolNames()">
|
|
8423
8886
|
<ng-container ngProjectAs="[chatToolCallTemplate]">
|
|
8424
8887
|
<ng-content select="[chatToolCallTemplate]" />
|
|
8425
8888
|
</ng-container>
|
|
8426
8889
|
</chat-tool-calls>
|
|
8890
|
+
<chat-tool-views
|
|
8891
|
+
[agent]="agent()"
|
|
8892
|
+
[message]="message"
|
|
8893
|
+
[views]="effectiveViews()"
|
|
8894
|
+
[store]="resolvedStore()"
|
|
8895
|
+
[handlers]="handlers()"
|
|
8896
|
+
(events)="onClientToolEvent($event)"
|
|
8897
|
+
/>
|
|
8427
8898
|
<chat-subagents [agent]="agent()" />
|
|
8428
8899
|
@if (classified.markdown(); as md) {
|
|
8429
8900
|
<chat-streaming-md [content]="md" [streaming]="agent().isLoading() && i === agent().messages().length - 1" />
|
|
8430
8901
|
}
|
|
8431
8902
|
@if (classified.spec(); as spec) {
|
|
8903
|
+
<!-- Pass ONLY the explicit consumer store (may be
|
|
8904
|
+
undefined) — never the conversation-wide internal
|
|
8905
|
+
fallback. Without a consumer store, render-spec
|
|
8906
|
+
self-seeds a per-instance store from spec.state so
|
|
8907
|
+
same-key dashboards across messages stay isolated
|
|
8908
|
+
(a2ui parity). -->
|
|
8432
8909
|
<chat-generative-ui
|
|
8433
8910
|
[spec]="spec"
|
|
8434
8911
|
[registry]="renderRegistry()"
|
|
8435
|
-
[store]="
|
|
8912
|
+
[store]="store()"
|
|
8436
8913
|
[handlers]="handlers()"
|
|
8437
8914
|
[loading]="agent().isLoading()"
|
|
8438
8915
|
(events)="onSpecEvent($event, i)"
|
|
@@ -8506,7 +8983,7 @@ class ChatComponent {
|
|
|
8506
8983
|
</div>
|
|
8507
8984
|
</div>
|
|
8508
8985
|
}
|
|
8509
|
-
`, isInline: true, styles: [":host{font-family:var(--ngaf-chat-font-family);color:var(--ngaf-chat-text)}\n", ":host{display:flex;flex-direction:column;flex:1 1 auto;height:100%;min-height:0;max-height:100%;overflow:hidden;background:var(--ngaf-chat-bg)}:host>chat-welcome{display:flex;flex:1 1 auto;width:100%}.chat-shell{display:flex;flex:1;min-height:0;overflow:hidden}.chat-shell__sidebar{width:240px;flex-shrink:0;border-right:1px solid var(--ngaf-chat-separator);background:var(--ngaf-chat-surface-alt);overflow-y:auto;display:none}@media(min-width:768px){.chat-shell__sidebar{display:block}}.chat-shell__main{flex:1;min-width:0;display:flex;flex-direction:column;min-height:0}.chat-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:60px 20px;color:var(--ngaf-chat-text-muted);text-align:center;flex:1;min-height:0}.chat-empty[hidden]{display:none}.chat-empty__title{font-size:1.125rem;font-weight:500;color:var(--ngaf-chat-text);margin:0}.chat-empty__sub{margin:0;font-size:var(--ngaf-chat-font-size-sm)}.chat-scroll{flex:1;min-height:0;overflow-y:auto;padding-top:var(--ngaf-chat-edge-pad)}.chat-scroll::-webkit-scrollbar{width:6px}.chat-scroll::-webkit-scrollbar-thumb{background:var(--ngaf-chat-separator);border-radius:10px}[chatFooter]{padding-bottom:var(--ngaf-chat-edge-pad)}.chat-footer-wrap{position:relative}\n"], dependencies: [{ kind: "component", type: ChatWindowComponent, selector: "chat-window" }, { kind: "component", type: ChatMessageListComponent, selector: "chat-message-list", inputs: ["agent"] }, { kind: "directive", type: MessageTemplateDirective, selector: "ng-template[chatMessageTemplate]", inputs: ["chatMessageTemplate"] }, { kind: "component", type: ChatMessageComponent, selector: "chat-message", inputs: ["role", "current", "streaming", "prevRole", "message"] }, { kind: "component", type: ChatInputComponent, selector: "chat-input", inputs: ["agent", "submitOnEnter", "placeholder", "showStopButton"], outputs: ["submitted", "stopped"] }, { kind: "component", type: ChatTypingIndicatorComponent, selector: "chat-typing-indicator", inputs: ["agent"] }, { kind: "component", type: ChatErrorComponent, selector: "chat-error", inputs: ["agent"] }, { kind: "component", type: ChatThreadListComponent, selector: "chat-thread-list", inputs: ["threads", "activeThreadId", "showNewThreadButton", "actions", "mode", "projects"], outputs: ["threadSelected", "newThreadRequested"] }, { kind: "component", type: ChatGenerativeUiComponent, selector: "chat-generative-ui", inputs: ["spec", "registry", "store", "handlers", "loading"], outputs: ["events"] }, { kind: "component", type: ChatStreamingMdComponent, selector: "chat-streaming-md", inputs: ["content", "streaming", "viewRegistry"] }, { kind: "component", type: ChatToolCallsComponent, selector: "chat-tool-calls", inputs: ["agent", "message", "grouping", "groupSummary", "excludeToolNames"] }, { kind: "component", type: ChatSubagentsComponent, selector: "chat-subagents", inputs: ["agent"] }, { kind: "component", type: A2uiSurfaceComponent, selector: "a2ui-surface", inputs: ["surface", "state", "catalog", "handlers", "surfaceFallback"], outputs: ["events", "action"] }, { kind: "component", type: ChatMessageActionsComponent, selector: "chat-message-actions", inputs: ["content", "disabled"], outputs: ["regenerate", "rate", "contentCopied"] }, { kind: "component", type: ChatWelcomeComponent, selector: "chat-welcome" }, { kind: "component", type: ChatSelectComponent, selector: "chat-select", inputs: ["options", "value", "placeholder", "disabled", "menuLabel"], outputs: ["valueChange"] }, { kind: "component", type: ChatReasoningComponent, selector: "chat-reasoning", inputs: ["content", "isStreaming", "durationMs", "label", "defaultExpanded"] }, { kind: "component", type: ChatScrollBubbleComponent, selector: "chat-scroll-bubble", inputs: ["mode"], outputs: ["clicked"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
8986
|
+
`, isInline: true, styles: [":host{font-family:var(--ngaf-chat-font-family);color:var(--ngaf-chat-text)}\n", ":host{display:flex;flex-direction:column;flex:1 1 auto;height:100%;min-height:0;max-height:100%;overflow:hidden;background:var(--ngaf-chat-bg)}:host>chat-welcome{display:flex;flex:1 1 auto;width:100%}.chat-shell{display:flex;flex:1;min-height:0;overflow:hidden}.chat-shell__sidebar{width:240px;flex-shrink:0;border-right:1px solid var(--ngaf-chat-separator);background:var(--ngaf-chat-surface-alt);overflow-y:auto;display:none}@media(min-width:768px){.chat-shell__sidebar{display:block}}.chat-shell__main{flex:1;min-width:0;display:flex;flex-direction:column;min-height:0}.chat-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:60px 20px;color:var(--ngaf-chat-text-muted);text-align:center;flex:1;min-height:0}.chat-empty[hidden]{display:none}.chat-empty__title{font-size:1.125rem;font-weight:500;color:var(--ngaf-chat-text);margin:0}.chat-empty__sub{margin:0;font-size:var(--ngaf-chat-font-size-sm)}.chat-scroll{flex:1;min-height:0;overflow-y:auto;padding-top:var(--ngaf-chat-edge-pad)}.chat-scroll::-webkit-scrollbar{width:6px}.chat-scroll::-webkit-scrollbar-thumb{background:var(--ngaf-chat-separator);border-radius:10px}[chatFooter]{padding-bottom:var(--ngaf-chat-edge-pad)}.chat-footer-wrap{position:relative}\n"], dependencies: [{ kind: "component", type: ChatWindowComponent, selector: "chat-window" }, { kind: "component", type: ChatMessageListComponent, selector: "chat-message-list", inputs: ["agent"] }, { kind: "directive", type: MessageTemplateDirective, selector: "ng-template[chatMessageTemplate]", inputs: ["chatMessageTemplate"] }, { kind: "component", type: ChatMessageComponent, selector: "chat-message", inputs: ["role", "current", "streaming", "prevRole", "message"] }, { kind: "component", type: ChatInputComponent, selector: "chat-input", inputs: ["agent", "submitOnEnter", "placeholder", "showStopButton"], outputs: ["submitted", "stopped"] }, { kind: "component", type: ChatTypingIndicatorComponent, selector: "chat-typing-indicator", inputs: ["agent"] }, { kind: "component", type: ChatErrorComponent, selector: "chat-error", inputs: ["agent"] }, { kind: "component", type: ChatThreadListComponent, selector: "chat-thread-list", inputs: ["threads", "activeThreadId", "showNewThreadButton", "actions", "mode", "projects"], outputs: ["threadSelected", "newThreadRequested"] }, { kind: "component", type: ChatGenerativeUiComponent, selector: "chat-generative-ui", inputs: ["spec", "registry", "store", "handlers", "loading"], outputs: ["events"] }, { kind: "component", type: ChatStreamingMdComponent, selector: "chat-streaming-md", inputs: ["content", "streaming", "viewRegistry"] }, { kind: "component", type: ChatToolCallsComponent, selector: "chat-tool-calls", inputs: ["agent", "message", "grouping", "groupSummary", "excludeToolNames"] }, { kind: "component", type: ChatToolViewsComponent, selector: "chat-tool-views", inputs: ["agent", "message", "views", "store", "handlers"], outputs: ["events"] }, { kind: "component", type: ChatSubagentsComponent, selector: "chat-subagents", inputs: ["agent"] }, { kind: "component", type: A2uiSurfaceComponent, selector: "a2ui-surface", inputs: ["surface", "state", "catalog", "handlers", "surfaceFallback"], outputs: ["events", "action"] }, { kind: "component", type: ChatMessageActionsComponent, selector: "chat-message-actions", inputs: ["content", "disabled"], outputs: ["regenerate", "rate", "contentCopied"] }, { kind: "component", type: ChatWelcomeComponent, selector: "chat-welcome" }, { kind: "component", type: ChatSelectComponent, selector: "chat-select", inputs: ["options", "value", "placeholder", "disabled", "menuLabel"], outputs: ["valueChange"] }, { kind: "component", type: ChatReasoningComponent, selector: "chat-reasoning", inputs: ["content", "isStreaming", "durationMs", "label", "defaultExpanded"] }, { kind: "component", type: ChatScrollBubbleComponent, selector: "chat-scroll-bubble", inputs: ["mode"], outputs: ["clicked"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
8510
8987
|
}
|
|
8511
8988
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: ChatComponent, decorators: [{
|
|
8512
8989
|
type: Component,
|
|
@@ -8515,7 +8992,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
|
|
|
8515
8992
|
ChatWindowComponent, ChatMessageListComponent, MessageTemplateDirective, ChatMessageComponent,
|
|
8516
8993
|
ChatInputComponent, ChatTypingIndicatorComponent, ChatErrorComponent,
|
|
8517
8994
|
ChatThreadListComponent, ChatGenerativeUiComponent,
|
|
8518
|
-
ChatStreamingMdComponent, ChatToolCallsComponent, ChatSubagentsComponent, A2uiSurfaceComponent,
|
|
8995
|
+
ChatStreamingMdComponent, ChatToolCallsComponent, ChatToolViewsComponent, ChatSubagentsComponent, A2uiSurfaceComponent,
|
|
8519
8996
|
ChatMessageActionsComponent, ChatWelcomeComponent, ChatSelectComponent, ChatReasoningComponent,
|
|
8520
8997
|
ChatScrollBubbleComponent,
|
|
8521
8998
|
], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
@@ -8575,20 +9052,34 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
|
|
|
8575
9052
|
[durationMs]="message.reasoningDurationMs"
|
|
8576
9053
|
/>
|
|
8577
9054
|
}
|
|
8578
|
-
<chat-tool-calls [agent]="agent()" [message]="message" [excludeToolNames]="
|
|
9055
|
+
<chat-tool-calls [agent]="agent()" [message]="message" [excludeToolNames]="excludedToolNames()">
|
|
8579
9056
|
<ng-container ngProjectAs="[chatToolCallTemplate]">
|
|
8580
9057
|
<ng-content select="[chatToolCallTemplate]" />
|
|
8581
9058
|
</ng-container>
|
|
8582
9059
|
</chat-tool-calls>
|
|
9060
|
+
<chat-tool-views
|
|
9061
|
+
[agent]="agent()"
|
|
9062
|
+
[message]="message"
|
|
9063
|
+
[views]="effectiveViews()"
|
|
9064
|
+
[store]="resolvedStore()"
|
|
9065
|
+
[handlers]="handlers()"
|
|
9066
|
+
(events)="onClientToolEvent($event)"
|
|
9067
|
+
/>
|
|
8583
9068
|
<chat-subagents [agent]="agent()" />
|
|
8584
9069
|
@if (classified.markdown(); as md) {
|
|
8585
9070
|
<chat-streaming-md [content]="md" [streaming]="agent().isLoading() && i === agent().messages().length - 1" />
|
|
8586
9071
|
}
|
|
8587
9072
|
@if (classified.spec(); as spec) {
|
|
9073
|
+
<!-- Pass ONLY the explicit consumer store (may be
|
|
9074
|
+
undefined) — never the conversation-wide internal
|
|
9075
|
+
fallback. Without a consumer store, render-spec
|
|
9076
|
+
self-seeds a per-instance store from spec.state so
|
|
9077
|
+
same-key dashboards across messages stay isolated
|
|
9078
|
+
(a2ui parity). -->
|
|
8588
9079
|
<chat-generative-ui
|
|
8589
9080
|
[spec]="spec"
|
|
8590
9081
|
[registry]="renderRegistry()"
|
|
8591
|
-
[store]="
|
|
9082
|
+
[store]="store()"
|
|
8592
9083
|
[handlers]="handlers()"
|
|
8593
9084
|
[loading]="agent().isLoading()"
|
|
8594
9085
|
(events)="onSpecEvent($event, i)"
|
|
@@ -8663,7 +9154,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
|
|
|
8663
9154
|
</div>
|
|
8664
9155
|
}
|
|
8665
9156
|
`, styles: [":host{font-family:var(--ngaf-chat-font-family);color:var(--ngaf-chat-text)}\n", ":host{display:flex;flex-direction:column;flex:1 1 auto;height:100%;min-height:0;max-height:100%;overflow:hidden;background:var(--ngaf-chat-bg)}:host>chat-welcome{display:flex;flex:1 1 auto;width:100%}.chat-shell{display:flex;flex:1;min-height:0;overflow:hidden}.chat-shell__sidebar{width:240px;flex-shrink:0;border-right:1px solid var(--ngaf-chat-separator);background:var(--ngaf-chat-surface-alt);overflow-y:auto;display:none}@media(min-width:768px){.chat-shell__sidebar{display:block}}.chat-shell__main{flex:1;min-width:0;display:flex;flex-direction:column;min-height:0}.chat-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:60px 20px;color:var(--ngaf-chat-text-muted);text-align:center;flex:1;min-height:0}.chat-empty[hidden]{display:none}.chat-empty__title{font-size:1.125rem;font-weight:500;color:var(--ngaf-chat-text);margin:0}.chat-empty__sub{margin:0;font-size:var(--ngaf-chat-font-size-sm)}.chat-scroll{flex:1;min-height:0;overflow-y:auto;padding-top:var(--ngaf-chat-edge-pad)}.chat-scroll::-webkit-scrollbar{width:6px}.chat-scroll::-webkit-scrollbar-thumb{background:var(--ngaf-chat-separator);border-radius:10px}[chatFooter]{padding-bottom:var(--ngaf-chat-edge-pad)}.chat-footer-wrap{position:relative}\n"] }]
|
|
8666
|
-
}], ctorParameters: () => [], propDecorators: { agent: [{ type: i0.Input, args: [{ isSignal: true, alias: "agent", required: true }] }], views: [{ type: i0.Input, args: [{ isSignal: true, alias: "views", required: false }] }], store: [{ type: i0.Input, args: [{ isSignal: true, alias: "store", required: false }] }], handlers: [{ type: i0.Input, args: [{ isSignal: true, alias: "handlers", required: false }] }], threads: [{ type: i0.Input, args: [{ isSignal: true, alias: "threads", required: false }] }], activeThreadId: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeThreadId", required: false }] }], welcomeDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "welcomeDisabled", required: false }] }], modelOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "modelOptions", required: false }] }], showModelPicker: [{ type: i0.Input, args: [{ isSignal: true, alias: "showModelPicker", required: false }] }], selectedModel: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedModel", required: false }] }, { type: i0.Output, args: ["selectedModelChange"] }], modelPickerPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "modelPickerPlaceholder", required: false }] }], genuiToolNames: [{ type: i0.Input, args: [{ isSignal: true, alias: "genuiToolNames", required: false }] }], threadSelected: [{ type: i0.Output, args: ["threadSelected"] }], renderEvent: [{ type: i0.Output, args: ["renderEvent"] }], regenerate: [{ type: i0.Output, args: ["regenerate"] }], rate: [{ type: i0.Output, args: ["rate"] }], messageCopy: [{ type: i0.Output, args: ["messageCopy"] }], scrollContainer: [{ type: i0.ViewChild, args: ['scrollContainer', { isSignal: true }] }] } });
|
|
9157
|
+
}], ctorParameters: () => [], propDecorators: { agent: [{ type: i0.Input, args: [{ isSignal: true, alias: "agent", required: true }] }], views: [{ type: i0.Input, args: [{ isSignal: true, alias: "views", required: false }] }], clientTools: [{ type: i0.Input, args: [{ isSignal: true, alias: "clientTools", required: false }] }], store: [{ type: i0.Input, args: [{ isSignal: true, alias: "store", required: false }] }], handlers: [{ type: i0.Input, args: [{ isSignal: true, alias: "handlers", required: false }] }], threads: [{ type: i0.Input, args: [{ isSignal: true, alias: "threads", required: false }] }], activeThreadId: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeThreadId", required: false }] }], welcomeDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "welcomeDisabled", required: false }] }], modelOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "modelOptions", required: false }] }], showModelPicker: [{ type: i0.Input, args: [{ isSignal: true, alias: "showModelPicker", required: false }] }], selectedModel: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedModel", required: false }] }, { type: i0.Output, args: ["selectedModelChange"] }], modelPickerPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "modelPickerPlaceholder", required: false }] }], genuiToolNames: [{ type: i0.Input, args: [{ isSignal: true, alias: "genuiToolNames", required: false }] }], threadSelected: [{ type: i0.Output, args: ["threadSelected"] }], renderEvent: [{ type: i0.Output, args: ["renderEvent"] }], regenerate: [{ type: i0.Output, args: ["regenerate"] }], rate: [{ type: i0.Output, args: ["rate"] }], messageCopy: [{ type: i0.Output, args: ["messageCopy"] }], scrollContainer: [{ type: i0.ViewChild, args: ['scrollContainer', { isSignal: true }] }] } });
|
|
8667
9158
|
|
|
8668
9159
|
// libs/chat/src/lib/compositions/chat-popup/chat-popup.component.ts
|
|
8669
9160
|
// SPDX-License-Identifier: MIT
|
|
@@ -8673,6 +9164,8 @@ class ChatPopupComponent {
|
|
|
8673
9164
|
* messages classified as A2UI parse correctly but never mount a
|
|
8674
9165
|
* surface. Pass `a2uiBasicCatalog()` from `@threadplane/chat`. */
|
|
8675
9166
|
views = input(undefined, ...(ngDevMode ? [{ debugName: "views" }] : []));
|
|
9167
|
+
/** Frontend-declared client tools forwarded to the inner `<chat>`. */
|
|
9168
|
+
clientTools = input(undefined, ...(ngDevMode ? [{ debugName: "clientTools" }] : []));
|
|
8676
9169
|
/** Forwarded to the inner <chat>. When non-empty, a model picker pill
|
|
8677
9170
|
* renders in the chat-input chrome. */
|
|
8678
9171
|
modelOptions = input([], ...(ngDevMode ? [{ debugName: "modelOptions" }] : []));
|
|
@@ -8727,7 +9220,7 @@ class ChatPopupComponent {
|
|
|
8727
9220
|
openWindow() { this.open.set(true); }
|
|
8728
9221
|
closeWindow() { this.open.set(false); }
|
|
8729
9222
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: ChatPopupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8730
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.6", type: ChatPopupComponent, isStandalone: true, selector: "chat-popup", inputs: { agent: { classPropertyName: "agent", publicName: "agent", isSignal: true, isRequired: true, transformFunction: null }, views: { classPropertyName: "views", publicName: "views", isSignal: true, isRequired: false, transformFunction: null }, modelOptions: { classPropertyName: "modelOptions", publicName: "modelOptions", isSignal: true, isRequired: false, transformFunction: null }, showModelPicker: { classPropertyName: "showModelPicker", publicName: "showModelPicker", isSignal: true, isRequired: false, transformFunction: null }, selectedModel: { classPropertyName: "selectedModel", publicName: "selectedModel", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, shortcut: { classPropertyName: "shortcut", publicName: "shortcut", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedModel: "selectedModelChange", open: "openChange" }, ngImport: i0, template: `
|
|
9223
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.6", type: ChatPopupComponent, isStandalone: true, selector: "chat-popup", inputs: { agent: { classPropertyName: "agent", publicName: "agent", isSignal: true, isRequired: true, transformFunction: null }, views: { classPropertyName: "views", publicName: "views", isSignal: true, isRequired: false, transformFunction: null }, clientTools: { classPropertyName: "clientTools", publicName: "clientTools", isSignal: true, isRequired: false, transformFunction: null }, modelOptions: { classPropertyName: "modelOptions", publicName: "modelOptions", isSignal: true, isRequired: false, transformFunction: null }, showModelPicker: { classPropertyName: "showModelPicker", publicName: "showModelPicker", isSignal: true, isRequired: false, transformFunction: null }, selectedModel: { classPropertyName: "selectedModel", publicName: "selectedModel", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, shortcut: { classPropertyName: "shortcut", publicName: "shortcut", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedModel: "selectedModelChange", open: "openChange" }, ngImport: i0, template: `
|
|
8731
9224
|
<div class="chat-popup__launcher">
|
|
8732
9225
|
<chat-launcher-button (clicked)="toggle()" />
|
|
8733
9226
|
</div>
|
|
@@ -8738,6 +9231,7 @@ class ChatPopupComponent {
|
|
|
8738
9231
|
<chat
|
|
8739
9232
|
[agent]="agent()"
|
|
8740
9233
|
[views]="views()"
|
|
9234
|
+
[clientTools]="clientTools()"
|
|
8741
9235
|
[modelOptions]="modelOptions()"
|
|
8742
9236
|
[showModelPicker]="showModelPicker()"
|
|
8743
9237
|
[selectedModel]="selectedModel()"
|
|
@@ -8747,7 +9241,7 @@ class ChatPopupComponent {
|
|
|
8747
9241
|
<ng-content select="[chatWelcomeSuggestions]" chatWelcomeSuggestions />
|
|
8748
9242
|
</chat>
|
|
8749
9243
|
</div>
|
|
8750
|
-
`, isInline: true, styles: [":host{font-family:var(--ngaf-chat-font-family);color:var(--ngaf-chat-text)}\n", ":host{position:fixed;bottom:1rem;right:1rem;z-index:var(--ngaf-chat-z-overlay-content, 30)}.chat-popup__launcher{position:relative}.chat-popup__window{position:fixed;bottom:5rem;right:1rem;width:24rem;height:600px;max-height:calc(100vh - 6rem);background:var(--ngaf-chat-bg);border:1px solid var(--ngaf-chat-separator);border-radius:.75rem;box-shadow:0 5px 40px #00000029;transform-origin:bottom right;transform:scale(.95) translateY(20px);opacity:0;pointer-events:none;transition:transform .2s ease-out,opacity .1s ease-out;overflow:hidden;display:flex;flex-direction:column}.chat-popup__window[data-open=true]{transform:scale(1) translateY(0);opacity:1;pointer-events:auto}@media(max-width:640px){.chat-popup__window{inset:0 auto auto 0;width:100vw;height:100vh;max-height:100vh;border-radius:0}}.chat-popup__close{position:absolute;top:8px;right:8px;width:32px;height:32px;background:transparent;border:0;cursor:pointer;color:var(--ngaf-chat-text-muted);border-radius:50%;z-index:1;display:flex;align-items:center;justify-content:center}.chat-popup__close:hover{background:var(--ngaf-chat-surface-alt);color:var(--ngaf-chat-text)}\n"], dependencies: [{ kind: "component", type: ChatComponent, selector: "chat", inputs: ["agent", "views", "store", "handlers", "threads", "activeThreadId", "welcomeDisabled", "modelOptions", "showModelPicker", "selectedModel", "modelPickerPlaceholder", "genuiToolNames"], outputs: ["selectedModelChange", "threadSelected", "renderEvent", "regenerate", "rate", "messageCopy"] }, { kind: "component", type: ChatLauncherButtonComponent, selector: "chat-launcher-button", outputs: ["clicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
9244
|
+
`, isInline: true, styles: [":host{font-family:var(--ngaf-chat-font-family);color:var(--ngaf-chat-text)}\n", ":host{position:fixed;bottom:1rem;right:1rem;z-index:var(--ngaf-chat-z-overlay-content, 30)}.chat-popup__launcher{position:relative}.chat-popup__window{position:fixed;bottom:5rem;right:1rem;width:24rem;height:600px;max-height:calc(100vh - 6rem);background:var(--ngaf-chat-bg);border:1px solid var(--ngaf-chat-separator);border-radius:.75rem;box-shadow:0 5px 40px #00000029;transform-origin:bottom right;transform:scale(.95) translateY(20px);opacity:0;pointer-events:none;transition:transform .2s ease-out,opacity .1s ease-out;overflow:hidden;display:flex;flex-direction:column}.chat-popup__window[data-open=true]{transform:scale(1) translateY(0);opacity:1;pointer-events:auto}@media(max-width:640px){.chat-popup__window{inset:0 auto auto 0;width:100vw;height:100vh;max-height:100vh;border-radius:0}}.chat-popup__close{position:absolute;top:8px;right:8px;width:32px;height:32px;background:transparent;border:0;cursor:pointer;color:var(--ngaf-chat-text-muted);border-radius:50%;z-index:1;display:flex;align-items:center;justify-content:center}.chat-popup__close:hover{background:var(--ngaf-chat-surface-alt);color:var(--ngaf-chat-text)}\n"], dependencies: [{ kind: "component", type: ChatComponent, selector: "chat", inputs: ["agent", "views", "clientTools", "store", "handlers", "threads", "activeThreadId", "welcomeDisabled", "modelOptions", "showModelPicker", "selectedModel", "modelPickerPlaceholder", "genuiToolNames"], outputs: ["selectedModelChange", "threadSelected", "renderEvent", "regenerate", "rate", "messageCopy"] }, { kind: "component", type: ChatLauncherButtonComponent, selector: "chat-launcher-button", outputs: ["clicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
8751
9245
|
}
|
|
8752
9246
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: ChatPopupComponent, decorators: [{
|
|
8753
9247
|
type: Component,
|
|
@@ -8762,6 +9256,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
|
|
|
8762
9256
|
<chat
|
|
8763
9257
|
[agent]="agent()"
|
|
8764
9258
|
[views]="views()"
|
|
9259
|
+
[clientTools]="clientTools()"
|
|
8765
9260
|
[modelOptions]="modelOptions()"
|
|
8766
9261
|
[showModelPicker]="showModelPicker()"
|
|
8767
9262
|
[selectedModel]="selectedModel()"
|
|
@@ -8772,7 +9267,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
|
|
|
8772
9267
|
</chat>
|
|
8773
9268
|
</div>
|
|
8774
9269
|
`, styles: [":host{font-family:var(--ngaf-chat-font-family);color:var(--ngaf-chat-text)}\n", ":host{position:fixed;bottom:1rem;right:1rem;z-index:var(--ngaf-chat-z-overlay-content, 30)}.chat-popup__launcher{position:relative}.chat-popup__window{position:fixed;bottom:5rem;right:1rem;width:24rem;height:600px;max-height:calc(100vh - 6rem);background:var(--ngaf-chat-bg);border:1px solid var(--ngaf-chat-separator);border-radius:.75rem;box-shadow:0 5px 40px #00000029;transform-origin:bottom right;transform:scale(.95) translateY(20px);opacity:0;pointer-events:none;transition:transform .2s ease-out,opacity .1s ease-out;overflow:hidden;display:flex;flex-direction:column}.chat-popup__window[data-open=true]{transform:scale(1) translateY(0);opacity:1;pointer-events:auto}@media(max-width:640px){.chat-popup__window{inset:0 auto auto 0;width:100vw;height:100vh;max-height:100vh;border-radius:0}}.chat-popup__close{position:absolute;top:8px;right:8px;width:32px;height:32px;background:transparent;border:0;cursor:pointer;color:var(--ngaf-chat-text-muted);border-radius:50%;z-index:1;display:flex;align-items:center;justify-content:center}.chat-popup__close:hover{background:var(--ngaf-chat-surface-alt);color:var(--ngaf-chat-text)}\n"] }]
|
|
8775
|
-
}], ctorParameters: () => [], propDecorators: { agent: [{ type: i0.Input, args: [{ isSignal: true, alias: "agent", required: true }] }], views: [{ type: i0.Input, args: [{ isSignal: true, alias: "views", required: false }] }], modelOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "modelOptions", required: false }] }], showModelPicker: [{ type: i0.Input, args: [{ isSignal: true, alias: "showModelPicker", required: false }] }], selectedModel: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedModel", required: false }] }, { type: i0.Output, args: ["selectedModelChange"] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], shortcut: [{ type: i0.Input, args: [{ isSignal: true, alias: "shortcut", required: false }] }], closeOnEscape: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnEscape", required: false }] }] } });
|
|
9270
|
+
}], ctorParameters: () => [], propDecorators: { agent: [{ type: i0.Input, args: [{ isSignal: true, alias: "agent", required: true }] }], views: [{ type: i0.Input, args: [{ isSignal: true, alias: "views", required: false }] }], clientTools: [{ type: i0.Input, args: [{ isSignal: true, alias: "clientTools", required: false }] }], modelOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "modelOptions", required: false }] }], showModelPicker: [{ type: i0.Input, args: [{ isSignal: true, alias: "showModelPicker", required: false }] }], selectedModel: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedModel", required: false }] }, { type: i0.Output, args: ["selectedModelChange"] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], shortcut: [{ type: i0.Input, args: [{ isSignal: true, alias: "shortcut", required: false }] }], closeOnEscape: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnEscape", required: false }] }] } });
|
|
8776
9271
|
|
|
8777
9272
|
// libs/chat/src/lib/compositions/chat-sidebar/chat-sidebar.component.ts
|
|
8778
9273
|
// SPDX-License-Identifier: MIT
|
|
@@ -8782,6 +9277,8 @@ class ChatSidebarComponent {
|
|
|
8782
9277
|
* messages classified as A2UI parse correctly but never mount a
|
|
8783
9278
|
* surface. Pass `a2uiBasicCatalog()` from `@threadplane/chat`. */
|
|
8784
9279
|
views = input(undefined, ...(ngDevMode ? [{ debugName: "views" }] : []));
|
|
9280
|
+
/** Frontend-declared client tools forwarded to the inner `<chat>`. */
|
|
9281
|
+
clientTools = input(undefined, ...(ngDevMode ? [{ debugName: "clientTools" }] : []));
|
|
8785
9282
|
/** Forwarded to the inner <chat>. When non-empty, a model picker pill
|
|
8786
9283
|
* renders in the chat-input chrome. */
|
|
8787
9284
|
modelOptions = input([], ...(ngDevMode ? [{ debugName: "modelOptions" }] : []));
|
|
@@ -8835,7 +9332,7 @@ class ChatSidebarComponent {
|
|
|
8835
9332
|
openWindow() { this.open.set(true); }
|
|
8836
9333
|
closeWindow() { this.open.set(false); }
|
|
8837
9334
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: ChatSidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8838
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.6", type: ChatSidebarComponent, isStandalone: true, selector: "chat-sidebar", inputs: { agent: { classPropertyName: "agent", publicName: "agent", isSignal: true, isRequired: true, transformFunction: null }, views: { classPropertyName: "views", publicName: "views", isSignal: true, isRequired: false, transformFunction: null }, modelOptions: { classPropertyName: "modelOptions", publicName: "modelOptions", isSignal: true, isRequired: false, transformFunction: null }, showModelPicker: { classPropertyName: "showModelPicker", publicName: "showModelPicker", isSignal: true, isRequired: false, transformFunction: null }, selectedModel: { classPropertyName: "selectedModel", publicName: "selectedModel", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null }, pushContent: { classPropertyName: "pushContent", publicName: "pushContent", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedModel: "selectedModelChange", open: "openChange" }, host: { properties: { "attr.data-push": "pushContent() ? \"true\" : \"false\"", "attr.data-open": "open() ? \"true\" : \"false\"" } }, ngImport: i0, template: `
|
|
9335
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.6", type: ChatSidebarComponent, isStandalone: true, selector: "chat-sidebar", inputs: { agent: { classPropertyName: "agent", publicName: "agent", isSignal: true, isRequired: true, transformFunction: null }, views: { classPropertyName: "views", publicName: "views", isSignal: true, isRequired: false, transformFunction: null }, clientTools: { classPropertyName: "clientTools", publicName: "clientTools", isSignal: true, isRequired: false, transformFunction: null }, modelOptions: { classPropertyName: "modelOptions", publicName: "modelOptions", isSignal: true, isRequired: false, transformFunction: null }, showModelPicker: { classPropertyName: "showModelPicker", publicName: "showModelPicker", isSignal: true, isRequired: false, transformFunction: null }, selectedModel: { classPropertyName: "selectedModel", publicName: "selectedModel", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null }, pushContent: { classPropertyName: "pushContent", publicName: "pushContent", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedModel: "selectedModelChange", open: "openChange" }, host: { properties: { "attr.data-push": "pushContent() ? \"true\" : \"false\"", "attr.data-open": "open() ? \"true\" : \"false\"" } }, ngImport: i0, template: `
|
|
8839
9336
|
<div class="chat-sidebar__content"><ng-content /></div>
|
|
8840
9337
|
<div class="chat-sidebar__launcher">
|
|
8841
9338
|
<chat-launcher-button (clicked)="toggle()" />
|
|
@@ -8852,6 +9349,7 @@ class ChatSidebarComponent {
|
|
|
8852
9349
|
<chat
|
|
8853
9350
|
[agent]="agent()"
|
|
8854
9351
|
[views]="views()"
|
|
9352
|
+
[clientTools]="clientTools()"
|
|
8855
9353
|
[modelOptions]="modelOptions()"
|
|
8856
9354
|
[showModelPicker]="showModelPicker()"
|
|
8857
9355
|
[selectedModel]="selectedModel()"
|
|
@@ -8861,7 +9359,7 @@ class ChatSidebarComponent {
|
|
|
8861
9359
|
<ng-content select="[chatWelcomeSuggestions]" chatWelcomeSuggestions />
|
|
8862
9360
|
</chat>
|
|
8863
9361
|
</aside>
|
|
8864
|
-
`, isInline: true, styles: [":host{font-family:var(--ngaf-chat-font-family);color:var(--ngaf-chat-text)}\n", ":host{display:block}.chat-sidebar__content{transition:margin-right .3s ease;min-height:100vh}:host([data-push=\"true\"][data-open=\"true\"]) .chat-sidebar__content{margin-right:28rem}@media(max-width:640px){:host([data-push=\"true\"][data-open=\"true\"]) .chat-sidebar__content{margin-right:0}}.chat-sidebar__panel{position:fixed;top:0;right:0;bottom:var(--ngaf-chat-debug-claim-bottom, 0);width:28rem;background:var(--ngaf-chat-bg);border-left:1px solid var(--ngaf-chat-separator);box-shadow:-8px 0 32px #00000014;transform:translate(100%);transition:transform .2s ease-out,bottom .2s ease-out;z-index:var(--ngaf-chat-z-overlay-content, 30);display:flex;flex-direction:column}.chat-sidebar__panel[data-open=true]{transform:translate(0)}@media(max-width:640px){.chat-sidebar__panel{width:100vw}}.chat-sidebar__panel-header{flex:0 0 auto;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 12px;border-bottom:1px solid var(--ngaf-chat-separator);min-height:48px}.chat-sidebar__panel-title{min-width:0;flex:1 1 auto;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;color:var(--ngaf-chat-text);font-weight:500;font-size:var(--ngaf-chat-font-size-sm)}.chat-sidebar__close{flex:0 0 auto;width:32px;height:32px;background:transparent;border:0;cursor:pointer;color:var(--ngaf-chat-text-muted);border-radius:50%;display:flex;align-items:center;justify-content:center}.chat-sidebar__close:hover{background:var(--ngaf-chat-surface-alt);color:var(--ngaf-chat-text)}.chat-sidebar__launcher{position:fixed;bottom:calc(1rem + var(--ngaf-chat-debug-claim-bottom, 0));right:1rem;z-index:var(--ngaf-chat-z-overlay-content, 30);transition:bottom .2s ease-out}:host([data-open=\"true\"]) .chat-sidebar__launcher{display:none}\n"], dependencies: [{ kind: "component", type: ChatComponent, selector: "chat", inputs: ["agent", "views", "store", "handlers", "threads", "activeThreadId", "welcomeDisabled", "modelOptions", "showModelPicker", "selectedModel", "modelPickerPlaceholder", "genuiToolNames"], outputs: ["selectedModelChange", "threadSelected", "renderEvent", "regenerate", "rate", "messageCopy"] }, { kind: "component", type: ChatLauncherButtonComponent, selector: "chat-launcher-button", outputs: ["clicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
9362
|
+
`, isInline: true, styles: [":host{font-family:var(--ngaf-chat-font-family);color:var(--ngaf-chat-text)}\n", ":host{display:block}.chat-sidebar__content{transition:margin-right .3s ease;min-height:100vh}:host([data-push=\"true\"][data-open=\"true\"]) .chat-sidebar__content{margin-right:28rem}@media(max-width:640px){:host([data-push=\"true\"][data-open=\"true\"]) .chat-sidebar__content{margin-right:0}}.chat-sidebar__panel{position:fixed;top:0;right:0;bottom:var(--ngaf-chat-debug-claim-bottom, 0);width:28rem;background:var(--ngaf-chat-bg);border-left:1px solid var(--ngaf-chat-separator);box-shadow:-8px 0 32px #00000014;transform:translate(100%);transition:transform .2s ease-out,bottom .2s ease-out;z-index:var(--ngaf-chat-z-overlay-content, 30);display:flex;flex-direction:column}.chat-sidebar__panel[data-open=true]{transform:translate(0)}@media(max-width:640px){.chat-sidebar__panel{width:100vw}}.chat-sidebar__panel-header{flex:0 0 auto;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 12px;border-bottom:1px solid var(--ngaf-chat-separator);min-height:48px}.chat-sidebar__panel-title{min-width:0;flex:1 1 auto;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;color:var(--ngaf-chat-text);font-weight:500;font-size:var(--ngaf-chat-font-size-sm)}.chat-sidebar__close{flex:0 0 auto;width:32px;height:32px;background:transparent;border:0;cursor:pointer;color:var(--ngaf-chat-text-muted);border-radius:50%;display:flex;align-items:center;justify-content:center}.chat-sidebar__close:hover{background:var(--ngaf-chat-surface-alt);color:var(--ngaf-chat-text)}.chat-sidebar__launcher{position:fixed;bottom:calc(1rem + var(--ngaf-chat-debug-claim-bottom, 0));right:1rem;z-index:var(--ngaf-chat-z-overlay-content, 30);transition:bottom .2s ease-out}:host([data-open=\"true\"]) .chat-sidebar__launcher{display:none}\n"], dependencies: [{ kind: "component", type: ChatComponent, selector: "chat", inputs: ["agent", "views", "clientTools", "store", "handlers", "threads", "activeThreadId", "welcomeDisabled", "modelOptions", "showModelPicker", "selectedModel", "modelPickerPlaceholder", "genuiToolNames"], outputs: ["selectedModelChange", "threadSelected", "renderEvent", "regenerate", "rate", "messageCopy"] }, { kind: "component", type: ChatLauncherButtonComponent, selector: "chat-launcher-button", outputs: ["clicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
8865
9363
|
}
|
|
8866
9364
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: ChatSidebarComponent, decorators: [{
|
|
8867
9365
|
type: Component,
|
|
@@ -8885,6 +9383,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
|
|
|
8885
9383
|
<chat
|
|
8886
9384
|
[agent]="agent()"
|
|
8887
9385
|
[views]="views()"
|
|
9386
|
+
[clientTools]="clientTools()"
|
|
8888
9387
|
[modelOptions]="modelOptions()"
|
|
8889
9388
|
[showModelPicker]="showModelPicker()"
|
|
8890
9389
|
[selectedModel]="selectedModel()"
|
|
@@ -8895,7 +9394,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
|
|
|
8895
9394
|
</chat>
|
|
8896
9395
|
</aside>
|
|
8897
9396
|
`, styles: [":host{font-family:var(--ngaf-chat-font-family);color:var(--ngaf-chat-text)}\n", ":host{display:block}.chat-sidebar__content{transition:margin-right .3s ease;min-height:100vh}:host([data-push=\"true\"][data-open=\"true\"]) .chat-sidebar__content{margin-right:28rem}@media(max-width:640px){:host([data-push=\"true\"][data-open=\"true\"]) .chat-sidebar__content{margin-right:0}}.chat-sidebar__panel{position:fixed;top:0;right:0;bottom:var(--ngaf-chat-debug-claim-bottom, 0);width:28rem;background:var(--ngaf-chat-bg);border-left:1px solid var(--ngaf-chat-separator);box-shadow:-8px 0 32px #00000014;transform:translate(100%);transition:transform .2s ease-out,bottom .2s ease-out;z-index:var(--ngaf-chat-z-overlay-content, 30);display:flex;flex-direction:column}.chat-sidebar__panel[data-open=true]{transform:translate(0)}@media(max-width:640px){.chat-sidebar__panel{width:100vw}}.chat-sidebar__panel-header{flex:0 0 auto;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 12px;border-bottom:1px solid var(--ngaf-chat-separator);min-height:48px}.chat-sidebar__panel-title{min-width:0;flex:1 1 auto;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;color:var(--ngaf-chat-text);font-weight:500;font-size:var(--ngaf-chat-font-size-sm)}.chat-sidebar__close{flex:0 0 auto;width:32px;height:32px;background:transparent;border:0;cursor:pointer;color:var(--ngaf-chat-text-muted);border-radius:50%;display:flex;align-items:center;justify-content:center}.chat-sidebar__close:hover{background:var(--ngaf-chat-surface-alt);color:var(--ngaf-chat-text)}.chat-sidebar__launcher{position:fixed;bottom:calc(1rem + var(--ngaf-chat-debug-claim-bottom, 0));right:1rem;z-index:var(--ngaf-chat-z-overlay-content, 30);transition:bottom .2s ease-out}:host([data-open=\"true\"]) .chat-sidebar__launcher{display:none}\n"] }]
|
|
8898
|
-
}], ctorParameters: () => [], propDecorators: { agent: [{ type: i0.Input, args: [{ isSignal: true, alias: "agent", required: true }] }], views: [{ type: i0.Input, args: [{ isSignal: true, alias: "views", required: false }] }], modelOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "modelOptions", required: false }] }], showModelPicker: [{ type: i0.Input, args: [{ isSignal: true, alias: "showModelPicker", required: false }] }], selectedModel: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedModel", required: false }] }, { type: i0.Output, args: ["selectedModelChange"] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], closeOnEscape: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnEscape", required: false }] }], pushContent: [{ type: i0.Input, args: [{ isSignal: true, alias: "pushContent", required: false }] }] } });
|
|
9397
|
+
}], ctorParameters: () => [], propDecorators: { agent: [{ type: i0.Input, args: [{ isSignal: true, alias: "agent", required: true }] }], views: [{ type: i0.Input, args: [{ isSignal: true, alias: "views", required: false }] }], clientTools: [{ type: i0.Input, args: [{ isSignal: true, alias: "clientTools", required: false }] }], modelOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "modelOptions", required: false }] }], showModelPicker: [{ type: i0.Input, args: [{ isSignal: true, alias: "showModelPicker", required: false }] }], selectedModel: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedModel", required: false }] }, { type: i0.Output, args: ["selectedModelChange"] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], closeOnEscape: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnEscape", required: false }] }], pushContent: [{ type: i0.Input, args: [{ isSignal: true, alias: "pushContent", required: false }] }] } });
|
|
8899
9398
|
|
|
8900
9399
|
// libs/chat/src/lib/compositions/chat-timeline-slider/chat-timeline-slider.component.ts
|
|
8901
9400
|
// SPDX-License-Identifier: MIT
|
|
@@ -10117,76 +10616,155 @@ class ChatInterruptPanelComponent {
|
|
|
10117
10616
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: ChatInterruptPanelComponent, isStandalone: true, selector: "chat-interrupt-panel", inputs: { agent: { classPropertyName: "agent", publicName: "agent", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { action: "action" }, ngImport: i0, template: `
|
|
10118
10617
|
@if (interrupt()) {
|
|
10119
10618
|
<div role="alert" class="chat-interrupt-panel">
|
|
10120
|
-
<p class="chat-interrupt-
|
|
10121
|
-
<
|
|
10122
|
-
Agent paused
|
|
10619
|
+
<p class="chat-interrupt-panel__eyebrow">
|
|
10620
|
+
<span class="chat-interrupt-panel__dot" aria-hidden="true"></span>
|
|
10621
|
+
Agent paused — review needed
|
|
10123
10622
|
</p>
|
|
10124
10623
|
<p class="chat-interrupt-panel__body">{{ interruptReason() }}</p>
|
|
10125
|
-
|
|
10126
10624
|
<div class="chat-interrupt-panel__actions">
|
|
10127
|
-
<button
|
|
10128
|
-
|
|
10129
|
-
|
|
10130
|
-
|
|
10131
|
-
>Accept</button>
|
|
10132
|
-
<button
|
|
10133
|
-
type="button"
|
|
10134
|
-
class="chat-interrupt-panel__btn chat-interrupt-panel__btn--secondary"
|
|
10135
|
-
(click)="action.emit('edit')"
|
|
10136
|
-
>Edit</button>
|
|
10137
|
-
<button
|
|
10138
|
-
type="button"
|
|
10139
|
-
class="chat-interrupt-panel__btn chat-interrupt-panel__btn--secondary"
|
|
10140
|
-
(click)="action.emit('respond')"
|
|
10141
|
-
>Respond</button>
|
|
10142
|
-
<button
|
|
10143
|
-
type="button"
|
|
10144
|
-
class="chat-interrupt-panel__btn chat-interrupt-panel__btn--tertiary"
|
|
10145
|
-
(click)="action.emit('ignore')"
|
|
10146
|
-
>Ignore</button>
|
|
10625
|
+
<button type="button" class="btn btn-primary" (click)="action.emit('accept')">Accept</button>
|
|
10626
|
+
<button type="button" class="btn btn-secondary" (click)="action.emit('edit')">Edit</button>
|
|
10627
|
+
<button type="button" class="btn btn-secondary" (click)="action.emit('respond')">Respond</button>
|
|
10628
|
+
<button type="button" class="btn btn-text" (click)="action.emit('ignore')">Ignore</button>
|
|
10147
10629
|
</div>
|
|
10148
10630
|
</div>
|
|
10149
10631
|
}
|
|
10150
|
-
`, isInline: true, styles: [":host{font-family:var(--ngaf-chat-font-family);color:var(--ngaf-chat-text)}\n", ".chat-interrupt-panel{background:var(--ngaf-chat-surface);color:var(--ngaf-chat-text);border:1px solid var(--ngaf-chat-separator);border-
|
|
10632
|
+
`, isInline: true, styles: [":host{font-family:var(--ngaf-chat-font-family);color:var(--ngaf-chat-text)}\n", ".chat-interrupt-panel{background:var(--ngaf-chat-surface);color:var(--ngaf-chat-text);border:1px solid var(--ngaf-chat-separator);border-radius:var(--ngaf-chat-radius-card);padding:14px 16px;font-size:var(--ngaf-chat-font-size-sm)}.chat-interrupt-panel__eyebrow{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.12em;color:var(--ngaf-chat-warning-text);margin:0 0 8px;display:flex;align-items:center;gap:6px}.chat-interrupt-panel__dot{width:6px;height:6px;border-radius:999px;background:var(--ngaf-chat-warning-text);flex:0 0 6px}.chat-interrupt-panel__body{margin:0 0 12px;color:var(--ngaf-chat-text);white-space:pre-wrap}.chat-interrupt-panel__actions{display:flex;gap:6px;flex-wrap:wrap;align-items:center}.btn{border:0;padding:6px 14px;border-radius:var(--ngaf-chat-radius-button);font-size:12px;font-weight:500;cursor:pointer;transition:transform .2s ease,opacity .2s ease}.btn:hover{transform:scale(1.03)}.btn-primary{background:var(--ngaf-chat-primary);color:var(--ngaf-chat-on-primary)}.btn-secondary{background:transparent;color:var(--ngaf-chat-text);border:1px solid var(--ngaf-chat-separator)}.btn-text{background:transparent;color:var(--ngaf-chat-text-muted);padding:6px 10px}.btn-text:hover{color:var(--ngaf-chat-text)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
10151
10633
|
}
|
|
10152
10634
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: ChatInterruptPanelComponent, decorators: [{
|
|
10153
10635
|
type: Component,
|
|
10154
10636
|
args: [{ selector: 'chat-interrupt-panel', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
10155
10637
|
@if (interrupt()) {
|
|
10156
10638
|
<div role="alert" class="chat-interrupt-panel">
|
|
10157
|
-
<p class="chat-interrupt-
|
|
10158
|
-
<
|
|
10159
|
-
Agent paused
|
|
10639
|
+
<p class="chat-interrupt-panel__eyebrow">
|
|
10640
|
+
<span class="chat-interrupt-panel__dot" aria-hidden="true"></span>
|
|
10641
|
+
Agent paused — review needed
|
|
10160
10642
|
</p>
|
|
10161
10643
|
<p class="chat-interrupt-panel__body">{{ interruptReason() }}</p>
|
|
10162
|
-
|
|
10163
10644
|
<div class="chat-interrupt-panel__actions">
|
|
10164
|
-
<button
|
|
10165
|
-
|
|
10166
|
-
|
|
10167
|
-
|
|
10168
|
-
>Accept</button>
|
|
10169
|
-
<button
|
|
10170
|
-
type="button"
|
|
10171
|
-
class="chat-interrupt-panel__btn chat-interrupt-panel__btn--secondary"
|
|
10172
|
-
(click)="action.emit('edit')"
|
|
10173
|
-
>Edit</button>
|
|
10174
|
-
<button
|
|
10175
|
-
type="button"
|
|
10176
|
-
class="chat-interrupt-panel__btn chat-interrupt-panel__btn--secondary"
|
|
10177
|
-
(click)="action.emit('respond')"
|
|
10178
|
-
>Respond</button>
|
|
10179
|
-
<button
|
|
10180
|
-
type="button"
|
|
10181
|
-
class="chat-interrupt-panel__btn chat-interrupt-panel__btn--tertiary"
|
|
10182
|
-
(click)="action.emit('ignore')"
|
|
10183
|
-
>Ignore</button>
|
|
10645
|
+
<button type="button" class="btn btn-primary" (click)="action.emit('accept')">Accept</button>
|
|
10646
|
+
<button type="button" class="btn btn-secondary" (click)="action.emit('edit')">Edit</button>
|
|
10647
|
+
<button type="button" class="btn btn-secondary" (click)="action.emit('respond')">Respond</button>
|
|
10648
|
+
<button type="button" class="btn btn-text" (click)="action.emit('ignore')">Ignore</button>
|
|
10184
10649
|
</div>
|
|
10185
10650
|
</div>
|
|
10186
10651
|
}
|
|
10187
|
-
`, styles: [":host{font-family:var(--ngaf-chat-font-family);color:var(--ngaf-chat-text)}\n", ".chat-interrupt-panel{background:var(--ngaf-chat-surface);color:var(--ngaf-chat-text);border:1px solid var(--ngaf-chat-separator);border-
|
|
10652
|
+
`, styles: [":host{font-family:var(--ngaf-chat-font-family);color:var(--ngaf-chat-text)}\n", ".chat-interrupt-panel{background:var(--ngaf-chat-surface);color:var(--ngaf-chat-text);border:1px solid var(--ngaf-chat-separator);border-radius:var(--ngaf-chat-radius-card);padding:14px 16px;font-size:var(--ngaf-chat-font-size-sm)}.chat-interrupt-panel__eyebrow{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.12em;color:var(--ngaf-chat-warning-text);margin:0 0 8px;display:flex;align-items:center;gap:6px}.chat-interrupt-panel__dot{width:6px;height:6px;border-radius:999px;background:var(--ngaf-chat-warning-text);flex:0 0 6px}.chat-interrupt-panel__body{margin:0 0 12px;color:var(--ngaf-chat-text);white-space:pre-wrap}.chat-interrupt-panel__actions{display:flex;gap:6px;flex-wrap:wrap;align-items:center}.btn{border:0;padding:6px 14px;border-radius:var(--ngaf-chat-radius-button);font-size:12px;font-weight:500;cursor:pointer;transition:transform .2s ease,opacity .2s ease}.btn:hover{transform:scale(1.03)}.btn-primary{background:var(--ngaf-chat-primary);color:var(--ngaf-chat-on-primary)}.btn-secondary{background:transparent;color:var(--ngaf-chat-text);border:1px solid var(--ngaf-chat-separator)}.btn-text{background:transparent;color:var(--ngaf-chat-text-muted);padding:6px 10px}.btn-text:hover{color:var(--ngaf-chat-text)}\n"] }]
|
|
10188
10653
|
}], propDecorators: { agent: [{ type: i0.Input, args: [{ isSignal: true, alias: "agent", required: true }] }], action: [{ type: i0.Output, args: ["action"] }] } });
|
|
10189
10654
|
|
|
10655
|
+
// SPDX-License-Identifier: MIT
|
|
10656
|
+
class ChatApprovalCardComponent {
|
|
10657
|
+
agent = input.required(...(ngDevMode ? [{ debugName: "agent" }] : []));
|
|
10658
|
+
matchKind = input(undefined, ...(ngDevMode ? [{ debugName: "matchKind" }] : []));
|
|
10659
|
+
title = input('Approval required', ...(ngDevMode ? [{ debugName: "title" }] : []));
|
|
10660
|
+
showEdit = input(false, ...(ngDevMode ? [{ debugName: "showEdit" }] : []));
|
|
10661
|
+
action = output();
|
|
10662
|
+
bodyTemplate = contentChild('body', ...(ngDevMode ? [{ debugName: "bodyTemplate" }] : []));
|
|
10663
|
+
dialogRef = viewChild('dialogEl', ...(ngDevMode ? [{ debugName: "dialogRef" }] : []));
|
|
10664
|
+
interrupt = computed(() => this.agent().interrupt?.(), ...(ngDevMode ? [{ debugName: "interrupt" }] : []));
|
|
10665
|
+
payload = computed(() => {
|
|
10666
|
+
const i = this.interrupt();
|
|
10667
|
+
if (!i)
|
|
10668
|
+
return undefined;
|
|
10669
|
+
const v = i.value;
|
|
10670
|
+
const want = this.matchKind();
|
|
10671
|
+
if (want !== undefined) {
|
|
10672
|
+
if (!v || typeof v !== 'object' || v.kind !== want) {
|
|
10673
|
+
return undefined;
|
|
10674
|
+
}
|
|
10675
|
+
}
|
|
10676
|
+
return v;
|
|
10677
|
+
}, ...(ngDevMode ? [{ debugName: "payload" }] : []));
|
|
10678
|
+
constructor() {
|
|
10679
|
+
effect(() => {
|
|
10680
|
+
const p = this.payload();
|
|
10681
|
+
const dialog = this.dialogRef()?.nativeElement;
|
|
10682
|
+
if (!dialog)
|
|
10683
|
+
return;
|
|
10684
|
+
if (p && !dialog.open) {
|
|
10685
|
+
dialog.showModal();
|
|
10686
|
+
}
|
|
10687
|
+
else if (!p && dialog.open) {
|
|
10688
|
+
dialog.close();
|
|
10689
|
+
}
|
|
10690
|
+
});
|
|
10691
|
+
}
|
|
10692
|
+
emit(action) {
|
|
10693
|
+
this.action.emit(action);
|
|
10694
|
+
// 'approve' and 'cancel' are terminal — they resolve the interrupt, so the
|
|
10695
|
+
// dialog closes. 'edit' is non-terminal: the caller reveals an inline
|
|
10696
|
+
// editor in the body slot and submits the resume itself, so we leave the
|
|
10697
|
+
// dialog open.
|
|
10698
|
+
if (action !== 'edit') {
|
|
10699
|
+
this.closeDialog();
|
|
10700
|
+
}
|
|
10701
|
+
}
|
|
10702
|
+
onCancelEvent(ev) {
|
|
10703
|
+
// Native dialog's cancel event fires on Escape. Treat as cancel.
|
|
10704
|
+
ev.preventDefault();
|
|
10705
|
+
this.action.emit('cancel');
|
|
10706
|
+
this.closeDialog();
|
|
10707
|
+
}
|
|
10708
|
+
closeDialog() {
|
|
10709
|
+
const dialog = this.dialogRef()?.nativeElement;
|
|
10710
|
+
if (!dialog)
|
|
10711
|
+
return;
|
|
10712
|
+
if (dialog.open)
|
|
10713
|
+
dialog.close();
|
|
10714
|
+
}
|
|
10715
|
+
onDialogClose() {
|
|
10716
|
+
// Native close — no-op; emit happens in emit() / onCancelEvent.
|
|
10717
|
+
}
|
|
10718
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: ChatApprovalCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10719
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: ChatApprovalCardComponent, isStandalone: true, selector: "chat-approval-card", inputs: { agent: { classPropertyName: "agent", publicName: "agent", isSignal: true, isRequired: true, transformFunction: null }, matchKind: { classPropertyName: "matchKind", publicName: "matchKind", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, showEdit: { classPropertyName: "showEdit", publicName: "showEdit", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action" }, queries: [{ propertyName: "bodyTemplate", first: true, predicate: ["body"], descendants: true, isSignal: true }], viewQueries: [{ propertyName: "dialogRef", first: true, predicate: ["dialogEl"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
10720
|
+
<dialog #dialogEl class="chat-approval-card" (close)="onDialogClose()" (cancel)="onCancelEvent($event)">
|
|
10721
|
+
<div class="chat-approval-card__header">
|
|
10722
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
|
|
10723
|
+
<h4>{{ title() }}</h4>
|
|
10724
|
+
</div>
|
|
10725
|
+
<div class="chat-approval-card__body">
|
|
10726
|
+
@if (bodyTemplate(); as tpl) {
|
|
10727
|
+
@if (payload(); as p) {
|
|
10728
|
+
<ng-container *ngTemplateOutlet="tpl; context: { $implicit: p }"></ng-container>
|
|
10729
|
+
}
|
|
10730
|
+
}
|
|
10731
|
+
</div>
|
|
10732
|
+
<div class="chat-approval-card__actions">
|
|
10733
|
+
<button type="button" class="btn btn-text" (click)="emit('cancel')">Cancel</button>
|
|
10734
|
+
@if (showEdit()) {
|
|
10735
|
+
<button type="button" class="btn btn-secondary" (click)="emit('edit')">Edit</button>
|
|
10736
|
+
}
|
|
10737
|
+
<button type="button" class="btn btn-primary" (click)="emit('approve')">Approve</button>
|
|
10738
|
+
</div>
|
|
10739
|
+
</dialog>
|
|
10740
|
+
`, isInline: true, styles: [":host{font-family:var(--ngaf-chat-font-family);color:var(--ngaf-chat-text)}\n", ":host{display:contents}dialog.chat-approval-card{width:440px;max-width:calc(100vw - 32px);margin:auto;padding:0;border:0;border-radius:12px;background:var(--ngaf-chat-surface);color:var(--ngaf-chat-text);box-shadow:0 20px 50px #0000002e}dialog.chat-approval-card::backdrop{background:#00000080;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}.chat-approval-card__header{padding:14px 16px 12px;display:flex;align-items:center;gap:8px;border-bottom:1px solid var(--ngaf-chat-separator)}.chat-approval-card__header h4{margin:0;font-size:14px;font-weight:600;color:var(--ngaf-chat-text)}.chat-approval-card__header svg{color:var(--ngaf-chat-warning-text);width:16px;height:16px;flex:0 0 16px}.chat-approval-card__body{padding:14px 16px;font-size:var(--ngaf-chat-font-size-sm, 13px);color:var(--ngaf-chat-text)}.chat-approval-card__actions{padding:8px 16px 14px;display:flex;gap:6px;justify-content:flex-end;align-items:center}.btn{border:0;padding:6px 14px;border-radius:8px;font-size:12px;font-weight:500;cursor:pointer;transition:transform .2s ease,opacity .2s ease}.btn:hover{transform:scale(1.03)}.btn-primary{background:var(--ngaf-chat-primary);color:var(--ngaf-chat-on-primary)}.btn-secondary{background:transparent;color:var(--ngaf-chat-text);border:1px solid var(--ngaf-chat-separator)}.btn-text{background:transparent;color:var(--ngaf-chat-text-muted);padding:6px 10px}.btn-text:hover{color:var(--ngaf-chat-text)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
10741
|
+
}
|
|
10742
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: ChatApprovalCardComponent, decorators: [{
|
|
10743
|
+
type: Component,
|
|
10744
|
+
args: [{ selector: 'chat-approval-card', standalone: true, imports: [NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
10745
|
+
<dialog #dialogEl class="chat-approval-card" (close)="onDialogClose()" (cancel)="onCancelEvent($event)">
|
|
10746
|
+
<div class="chat-approval-card__header">
|
|
10747
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
|
|
10748
|
+
<h4>{{ title() }}</h4>
|
|
10749
|
+
</div>
|
|
10750
|
+
<div class="chat-approval-card__body">
|
|
10751
|
+
@if (bodyTemplate(); as tpl) {
|
|
10752
|
+
@if (payload(); as p) {
|
|
10753
|
+
<ng-container *ngTemplateOutlet="tpl; context: { $implicit: p }"></ng-container>
|
|
10754
|
+
}
|
|
10755
|
+
}
|
|
10756
|
+
</div>
|
|
10757
|
+
<div class="chat-approval-card__actions">
|
|
10758
|
+
<button type="button" class="btn btn-text" (click)="emit('cancel')">Cancel</button>
|
|
10759
|
+
@if (showEdit()) {
|
|
10760
|
+
<button type="button" class="btn btn-secondary" (click)="emit('edit')">Edit</button>
|
|
10761
|
+
}
|
|
10762
|
+
<button type="button" class="btn btn-primary" (click)="emit('approve')">Approve</button>
|
|
10763
|
+
</div>
|
|
10764
|
+
</dialog>
|
|
10765
|
+
`, styles: [":host{font-family:var(--ngaf-chat-font-family);color:var(--ngaf-chat-text)}\n", ":host{display:contents}dialog.chat-approval-card{width:440px;max-width:calc(100vw - 32px);margin:auto;padding:0;border:0;border-radius:12px;background:var(--ngaf-chat-surface);color:var(--ngaf-chat-text);box-shadow:0 20px 50px #0000002e}dialog.chat-approval-card::backdrop{background:#00000080;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}.chat-approval-card__header{padding:14px 16px 12px;display:flex;align-items:center;gap:8px;border-bottom:1px solid var(--ngaf-chat-separator)}.chat-approval-card__header h4{margin:0;font-size:14px;font-weight:600;color:var(--ngaf-chat-text)}.chat-approval-card__header svg{color:var(--ngaf-chat-warning-text);width:16px;height:16px;flex:0 0 16px}.chat-approval-card__body{padding:14px 16px;font-size:var(--ngaf-chat-font-size-sm, 13px);color:var(--ngaf-chat-text)}.chat-approval-card__actions{padding:8px 16px 14px;display:flex;gap:6px;justify-content:flex-end;align-items:center}.btn{border:0;padding:6px 14px;border-radius:8px;font-size:12px;font-weight:500;cursor:pointer;transition:transform .2s ease,opacity .2s ease}.btn:hover{transform:scale(1.03)}.btn-primary{background:var(--ngaf-chat-primary);color:var(--ngaf-chat-on-primary)}.btn-secondary{background:transparent;color:var(--ngaf-chat-text);border:1px solid var(--ngaf-chat-separator)}.btn-text{background:transparent;color:var(--ngaf-chat-text-muted);padding:6px 10px}.btn-text:hover{color:var(--ngaf-chat-text)}\n"] }]
|
|
10766
|
+
}], ctorParameters: () => [], propDecorators: { agent: [{ type: i0.Input, args: [{ isSignal: true, alias: "agent", required: true }] }], matchKind: [{ type: i0.Input, args: [{ isSignal: true, alias: "matchKind", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], showEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "showEdit", required: false }] }], action: [{ type: i0.Output, args: ["action"] }], bodyTemplate: [{ type: i0.ContentChild, args: ['body', { isSignal: true }] }], dialogRef: [{ type: i0.ViewChild, args: ['dialogEl', { isSignal: true }] }] } });
|
|
10767
|
+
|
|
10190
10768
|
// SPDX-License-Identifier: MIT
|
|
10191
10769
|
let markedParse = null;
|
|
10192
10770
|
let markedLoadAttempted = false;
|
|
@@ -10386,24 +10964,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
|
|
|
10386
10964
|
`, styles: [".a2ui-card{display:flex;flex-direction:column;gap:var(--a2ui-spacing-2);border-radius:var(--a2ui-shape-medium);border:1px solid var(--a2ui-outline);background:var(--a2ui-surface);padding:var(--a2ui-spacing-4);box-shadow:var(--a2ui-elevation-1)}\n"] }]
|
|
10387
10965
|
}], propDecorators: { childKeys: [{ type: i0.Input, args: [{ isSignal: true, alias: "childKeys", required: false }] }], spec: [{ type: i0.Input, args: [{ isSignal: true, alias: "spec", required: true }] }], bindings: [{ type: i0.Input, args: [{ isSignal: true, alias: "bindings", required: false }] }], emit: [{ type: i0.Input, args: [{ isSignal: true, alias: "emit", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }] } });
|
|
10388
10966
|
|
|
10389
|
-
|
|
10390
|
-
|
|
10391
|
-
function emitBinding(emit, bindings, prop, value) {
|
|
10967
|
+
/** Writes a typed value to the render state store if the prop has a binding path. */
|
|
10968
|
+
function emitBinding(host, bindings, prop, value) {
|
|
10392
10969
|
const path = bindings?.[prop];
|
|
10393
10970
|
if (path) {
|
|
10394
|
-
|
|
10971
|
+
host.set(path, value);
|
|
10395
10972
|
}
|
|
10396
10973
|
}
|
|
10397
10974
|
|
|
10398
10975
|
// SPDX-License-Identifier: MIT
|
|
10399
10976
|
class A2uiCheckBoxComponent {
|
|
10977
|
+
host = injectRenderHost();
|
|
10400
10978
|
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
10401
10979
|
/** v1 canonical prop: boolean checked state. */
|
|
10402
10980
|
value = input(undefined, ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
10403
10981
|
/** Pre-v1 alias retained for back-compat. */
|
|
10404
10982
|
checked = input(false, ...(ngDevMode ? [{ debugName: "checked" }] : []));
|
|
10405
10983
|
_bindings = input({}, ...(ngDevMode ? [{ debugName: "_bindings" }] : []));
|
|
10406
|
-
emit = input(() => { }, ...(ngDevMode ? [{ debugName: "emit" }] : []));
|
|
10407
10984
|
// Framework inputs required by the render harness.
|
|
10408
10985
|
bindings = input({}, ...(ngDevMode ? [{ debugName: "bindings" }] : []));
|
|
10409
10986
|
loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
@@ -10416,14 +10993,14 @@ class A2uiCheckBoxComponent {
|
|
|
10416
10993
|
// `value`; pre-v1 used `checked`.
|
|
10417
10994
|
const bound = this._bindings();
|
|
10418
10995
|
if (bound['value']) {
|
|
10419
|
-
emitBinding(this.
|
|
10996
|
+
emitBinding(this.host, bound, 'value', val);
|
|
10420
10997
|
}
|
|
10421
10998
|
else {
|
|
10422
|
-
emitBinding(this.
|
|
10999
|
+
emitBinding(this.host, bound, 'checked', val);
|
|
10423
11000
|
}
|
|
10424
11001
|
}
|
|
10425
11002
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: A2uiCheckBoxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10426
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.6", type: A2uiCheckBoxComponent, isStandalone: true, selector: "a2ui-check-box", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, _bindings: { classPropertyName: "_bindings", publicName: "_bindings", isSignal: true, isRequired: false, transformFunction: null },
|
|
11003
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.6", type: A2uiCheckBoxComponent, isStandalone: true, selector: "a2ui-check-box", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, _bindings: { classPropertyName: "_bindings", publicName: "_bindings", isSignal: true, isRequired: false, transformFunction: null }, bindings: { classPropertyName: "bindings", publicName: "bindings", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, childKeys: { classPropertyName: "childKeys", publicName: "childKeys", isSignal: true, isRequired: false, transformFunction: null }, spec: { classPropertyName: "spec", publicName: "spec", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
10427
11004
|
<label class="a2ui-cb">
|
|
10428
11005
|
<input type="checkbox" [checked]="effectiveValue()" (change)="onChange($event)" class="a2ui-cb__input" />
|
|
10429
11006
|
{{ label() }}
|
|
@@ -10438,7 +11015,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
|
|
|
10438
11015
|
{{ label() }}
|
|
10439
11016
|
</label>
|
|
10440
11017
|
`, styles: [".a2ui-cb{display:flex;align-items:center;gap:var(--a2ui-spacing-2);font-size:var(--a2ui-typography-body-size);cursor:pointer}.a2ui-cb__input{width:16px;height:16px;border-radius:var(--a2ui-shape-extra-small);cursor:pointer;accent-color:var(--a2ui-primary)}\n"] }]
|
|
10441
|
-
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }], _bindings: [{ type: i0.Input, args: [{ isSignal: true, alias: "_bindings", required: false }] }],
|
|
11018
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }], _bindings: [{ type: i0.Input, args: [{ isSignal: true, alias: "_bindings", required: false }] }], bindings: [{ type: i0.Input, args: [{ isSignal: true, alias: "bindings", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], childKeys: [{ type: i0.Input, args: [{ isSignal: true, alias: "childKeys", required: false }] }], spec: [{ type: i0.Input, args: [{ isSignal: true, alias: "spec", required: false }] }] } });
|
|
10442
11019
|
|
|
10443
11020
|
// SPDX-License-Identifier: MIT
|
|
10444
11021
|
const ALIGN_MAP = {
|
|
@@ -10481,6 +11058,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
|
|
|
10481
11058
|
class A2uiDateTimeInputComponent {
|
|
10482
11059
|
static _idCounter = 0;
|
|
10483
11060
|
_inputId = `a2ui-date-time-input-${++A2uiDateTimeInputComponent._idCounter}`;
|
|
11061
|
+
host = injectRenderHost();
|
|
10484
11062
|
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
10485
11063
|
/** v1 prop: value (resolved DynamicString). */
|
|
10486
11064
|
value = input('', ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
@@ -10489,7 +11067,6 @@ class A2uiDateTimeInputComponent {
|
|
|
10489
11067
|
/** v1 prop: enableTime — include time portion. */
|
|
10490
11068
|
enableTime = input(false, ...(ngDevMode ? [{ debugName: "enableTime" }] : []));
|
|
10491
11069
|
_bindings = input({}, ...(ngDevMode ? [{ debugName: "_bindings" }] : []));
|
|
10492
|
-
emit = input(() => { }, ...(ngDevMode ? [{ debugName: "emit" }] : []));
|
|
10493
11070
|
// Framework inputs required by the render harness.
|
|
10494
11071
|
bindings = input({}, ...(ngDevMode ? [{ debugName: "bindings" }] : []));
|
|
10495
11072
|
loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
@@ -10507,10 +11084,10 @@ class A2uiDateTimeInputComponent {
|
|
|
10507
11084
|
}, ...(ngDevMode ? [{ debugName: "htmlInputType" }] : []));
|
|
10508
11085
|
onChange(event) {
|
|
10509
11086
|
const val = event.target.value;
|
|
10510
|
-
emitBinding(this.
|
|
11087
|
+
emitBinding(this.host, this._bindings(), 'value', val);
|
|
10511
11088
|
}
|
|
10512
11089
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: A2uiDateTimeInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10513
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: A2uiDateTimeInputComponent, isStandalone: true, selector: "a2ui-date-time-input", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, enableDate: { classPropertyName: "enableDate", publicName: "enableDate", isSignal: true, isRequired: false, transformFunction: null }, enableTime: { classPropertyName: "enableTime", publicName: "enableTime", isSignal: true, isRequired: false, transformFunction: null }, _bindings: { classPropertyName: "_bindings", publicName: "_bindings", isSignal: true, isRequired: false, transformFunction: null },
|
|
11090
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: A2uiDateTimeInputComponent, isStandalone: true, selector: "a2ui-date-time-input", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, enableDate: { classPropertyName: "enableDate", publicName: "enableDate", isSignal: true, isRequired: false, transformFunction: null }, enableTime: { classPropertyName: "enableTime", publicName: "enableTime", isSignal: true, isRequired: false, transformFunction: null }, _bindings: { classPropertyName: "_bindings", publicName: "_bindings", isSignal: true, isRequired: false, transformFunction: null }, bindings: { classPropertyName: "bindings", publicName: "bindings", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, childKeys: { classPropertyName: "childKeys", publicName: "childKeys", isSignal: true, isRequired: false, transformFunction: null }, spec: { classPropertyName: "spec", publicName: "spec", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
10514
11091
|
<div class="a2ui-dti">
|
|
10515
11092
|
@if (label()) {
|
|
10516
11093
|
<label [htmlFor]="_inputId" class="a2ui-dti__label">{{ label() }}</label>
|
|
@@ -10541,7 +11118,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
|
|
|
10541
11118
|
/>
|
|
10542
11119
|
</div>
|
|
10543
11120
|
`, styles: [".a2ui-dti{display:flex;flex-direction:column;gap:var(--a2ui-spacing-1)}.a2ui-dti__label{font-size:var(--a2ui-typography-label-size);font-weight:var(--a2ui-typography-label-weight);color:var(--a2ui-label)}.a2ui-dti__input{padding:var(--a2ui-spacing-2) var(--a2ui-spacing-3);font-size:var(--a2ui-typography-body-size);border-radius:var(--a2ui-shape-small);background:var(--a2ui-input-bg);color:var(--a2ui-on-surface);border:1px solid var(--a2ui-outline);outline:none;transition:border-color var(--a2ui-motion-duration-short) var(--a2ui-motion-easing-standard)}.a2ui-dti__input:focus{outline:var(--a2ui-focus-ring-width) solid var(--a2ui-focus-ring-color);outline-offset:2px;border-color:var(--a2ui-primary)}\n"] }]
|
|
10544
|
-
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], enableDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableDate", required: false }] }], enableTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableTime", required: false }] }], _bindings: [{ type: i0.Input, args: [{ isSignal: true, alias: "_bindings", required: false }] }],
|
|
11121
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], enableDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableDate", required: false }] }], enableTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableTime", required: false }] }], _bindings: [{ type: i0.Input, args: [{ isSignal: true, alias: "_bindings", required: false }] }], bindings: [{ type: i0.Input, args: [{ isSignal: true, alias: "bindings", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], childKeys: [{ type: i0.Input, args: [{ isSignal: true, alias: "childKeys", required: false }] }], spec: [{ type: i0.Input, args: [{ isSignal: true, alias: "spec", required: false }] }] } });
|
|
10545
11122
|
|
|
10546
11123
|
// SPDX-License-Identifier: MIT
|
|
10547
11124
|
class A2uiDividerComponent {
|
|
@@ -10832,6 +11409,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
|
|
|
10832
11409
|
|
|
10833
11410
|
// SPDX-License-Identifier: MIT
|
|
10834
11411
|
class A2uiMultipleChoiceComponent {
|
|
11412
|
+
host = injectRenderHost();
|
|
10835
11413
|
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
10836
11414
|
/** Resolved current selections from surface-to-spec. Normalized in
|
|
10837
11415
|
* `selectionsArray` because LLMs sometimes seed the data model with a
|
|
@@ -10851,7 +11429,6 @@ class A2uiMultipleChoiceComponent {
|
|
|
10851
11429
|
/** When ≤ 1 — render as single-select <select>; otherwise multi-select checkboxes. */
|
|
10852
11430
|
maxAllowedSelections = input(1, ...(ngDevMode ? [{ debugName: "maxAllowedSelections" }] : []));
|
|
10853
11431
|
_bindings = input({}, ...(ngDevMode ? [{ debugName: "_bindings" }] : []));
|
|
10854
|
-
emit = input(() => { }, ...(ngDevMode ? [{ debugName: "emit" }] : []));
|
|
10855
11432
|
// Framework inputs required by the render harness.
|
|
10856
11433
|
bindings = input({}, ...(ngDevMode ? [{ debugName: "bindings" }] : []));
|
|
10857
11434
|
loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
@@ -10863,7 +11440,7 @@ class A2uiMultipleChoiceComponent {
|
|
|
10863
11440
|
}
|
|
10864
11441
|
onSelectChange(event) {
|
|
10865
11442
|
const val = event.target.value;
|
|
10866
|
-
emitBinding(this.
|
|
11443
|
+
emitBinding(this.host, this._bindings(), 'selections', val);
|
|
10867
11444
|
}
|
|
10868
11445
|
onCheckChange(value, event) {
|
|
10869
11446
|
const checked = event.target.checked;
|
|
@@ -10875,11 +11452,11 @@ class A2uiMultipleChoiceComponent {
|
|
|
10875
11452
|
else if (!checked && idx !== -1) {
|
|
10876
11453
|
current.splice(idx, 1);
|
|
10877
11454
|
}
|
|
10878
|
-
//
|
|
10879
|
-
emitBinding(this.
|
|
11455
|
+
// Pass the updated selections array directly (typed value, no JSON stringification needed).
|
|
11456
|
+
emitBinding(this.host, this._bindings(), 'selections', current);
|
|
10880
11457
|
}
|
|
10881
11458
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: A2uiMultipleChoiceComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10882
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: A2uiMultipleChoiceComponent, isStandalone: true, selector: "a2ui-multiple-choice", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, selections: { classPropertyName: "selections", publicName: "selections", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, maxAllowedSelections: { classPropertyName: "maxAllowedSelections", publicName: "maxAllowedSelections", isSignal: true, isRequired: false, transformFunction: null }, _bindings: { classPropertyName: "_bindings", publicName: "_bindings", isSignal: true, isRequired: false, transformFunction: null },
|
|
11459
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: A2uiMultipleChoiceComponent, isStandalone: true, selector: "a2ui-multiple-choice", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, selections: { classPropertyName: "selections", publicName: "selections", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, maxAllowedSelections: { classPropertyName: "maxAllowedSelections", publicName: "maxAllowedSelections", isSignal: true, isRequired: false, transformFunction: null }, _bindings: { classPropertyName: "_bindings", publicName: "_bindings", isSignal: true, isRequired: false, transformFunction: null }, bindings: { classPropertyName: "bindings", publicName: "bindings", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, childKeys: { classPropertyName: "childKeys", publicName: "childKeys", isSignal: true, isRequired: false, transformFunction: null }, spec: { classPropertyName: "spec", publicName: "spec", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
10883
11460
|
<div class="a2ui-mc">
|
|
10884
11461
|
@if (label()) {
|
|
10885
11462
|
<span class="a2ui-mc__label">{{ label() }}</span>
|
|
@@ -10944,7 +11521,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
|
|
|
10944
11521
|
}
|
|
10945
11522
|
</div>
|
|
10946
11523
|
`, styles: [".a2ui-mc{display:flex;flex-direction:column;gap:var(--a2ui-spacing-1)}.a2ui-mc__label{font-size:var(--a2ui-typography-label-size);font-weight:var(--a2ui-typography-label-weight);color:var(--a2ui-label)}.a2ui-mc__select{padding:var(--a2ui-spacing-2) var(--a2ui-spacing-3);font-size:var(--a2ui-typography-body-size);border-radius:var(--a2ui-shape-small);background:var(--a2ui-input-bg);color:var(--a2ui-on-surface);border:1px solid var(--a2ui-outline);outline:none;transition:border-color var(--a2ui-motion-duration-short) var(--a2ui-motion-easing-standard)}.a2ui-mc__select:focus{outline:var(--a2ui-focus-ring-width) solid var(--a2ui-focus-ring-color);outline-offset:2px;border-color:var(--a2ui-primary)}.a2ui-mc__checks{display:flex;flex-direction:column;gap:var(--a2ui-spacing-2)}.a2ui-mc__check-row{display:flex;align-items:center;gap:var(--a2ui-spacing-2);font-size:var(--a2ui-typography-body-size);cursor:pointer}.a2ui-mc__checkbox{width:16px;height:16px;border-radius:var(--a2ui-shape-extra-small);cursor:pointer;accent-color:var(--a2ui-primary)}\n"] }]
|
|
10947
|
-
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], selections: [{ type: i0.Input, args: [{ isSignal: true, alias: "selections", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], maxAllowedSelections: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxAllowedSelections", required: false }] }], _bindings: [{ type: i0.Input, args: [{ isSignal: true, alias: "_bindings", required: false }] }],
|
|
11524
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], selections: [{ type: i0.Input, args: [{ isSignal: true, alias: "selections", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], maxAllowedSelections: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxAllowedSelections", required: false }] }], _bindings: [{ type: i0.Input, args: [{ isSignal: true, alias: "_bindings", required: false }] }], bindings: [{ type: i0.Input, args: [{ isSignal: true, alias: "bindings", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], childKeys: [{ type: i0.Input, args: [{ isSignal: true, alias: "childKeys", required: false }] }], spec: [{ type: i0.Input, args: [{ isSignal: true, alias: "spec", required: false }] }] } });
|
|
10948
11525
|
|
|
10949
11526
|
// SPDX-License-Identifier: MIT
|
|
10950
11527
|
const ROW_ALIGN_MAP = {
|
|
@@ -11002,6 +11579,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
|
|
|
11002
11579
|
class A2uiSliderComponent {
|
|
11003
11580
|
static _idCounter = 0;
|
|
11004
11581
|
_inputId = `a2ui-slider-${++A2uiSliderComponent._idCounter}`;
|
|
11582
|
+
host = injectRenderHost();
|
|
11005
11583
|
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
11006
11584
|
/** v1 prop: value (resolved DynamicNumber). */
|
|
11007
11585
|
value = input(0, ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
@@ -11011,7 +11589,6 @@ class A2uiSliderComponent {
|
|
|
11011
11589
|
maxValue = input(100, ...(ngDevMode ? [{ debugName: "maxValue" }] : []));
|
|
11012
11590
|
step = input(1, ...(ngDevMode ? [{ debugName: "step" }] : []));
|
|
11013
11591
|
_bindings = input({}, ...(ngDevMode ? [{ debugName: "_bindings" }] : []));
|
|
11014
|
-
emit = input(() => { }, ...(ngDevMode ? [{ debugName: "emit" }] : []));
|
|
11015
11592
|
// Framework inputs required by the render harness.
|
|
11016
11593
|
bindings = input({}, ...(ngDevMode ? [{ debugName: "bindings" }] : []));
|
|
11017
11594
|
loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
@@ -11019,10 +11596,10 @@ class A2uiSliderComponent {
|
|
|
11019
11596
|
spec = input(undefined, ...(ngDevMode ? [{ debugName: "spec" }] : []));
|
|
11020
11597
|
onInput(event) {
|
|
11021
11598
|
const val = Number(event.target.value);
|
|
11022
|
-
emitBinding(this.
|
|
11599
|
+
emitBinding(this.host, this._bindings(), 'value', val);
|
|
11023
11600
|
}
|
|
11024
11601
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: A2uiSliderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
11025
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: A2uiSliderComponent, isStandalone: true, selector: "a2ui-slider", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, minValue: { classPropertyName: "minValue", publicName: "minValue", isSignal: true, isRequired: false, transformFunction: null }, maxValue: { classPropertyName: "maxValue", publicName: "maxValue", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, _bindings: { classPropertyName: "_bindings", publicName: "_bindings", isSignal: true, isRequired: false, transformFunction: null },
|
|
11602
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: A2uiSliderComponent, isStandalone: true, selector: "a2ui-slider", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, minValue: { classPropertyName: "minValue", publicName: "minValue", isSignal: true, isRequired: false, transformFunction: null }, maxValue: { classPropertyName: "maxValue", publicName: "maxValue", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, _bindings: { classPropertyName: "_bindings", publicName: "_bindings", isSignal: true, isRequired: false, transformFunction: null }, bindings: { classPropertyName: "bindings", publicName: "bindings", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, childKeys: { classPropertyName: "childKeys", publicName: "childKeys", isSignal: true, isRequired: false, transformFunction: null }, spec: { classPropertyName: "spec", publicName: "spec", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
11026
11603
|
<div class="a2ui-slider">
|
|
11027
11604
|
@if (label()) {
|
|
11028
11605
|
<label [htmlFor]="_inputId" class="a2ui-slider__label">{{ label() }}: {{ value() }}</label>
|
|
@@ -11059,7 +11636,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
|
|
|
11059
11636
|
/>
|
|
11060
11637
|
</div>
|
|
11061
11638
|
`, styles: [".a2ui-slider{display:flex;flex-direction:column;gap:var(--a2ui-spacing-1)}.a2ui-slider__label{font-size:var(--a2ui-typography-label-size);font-weight:var(--a2ui-typography-label-weight);color:var(--a2ui-label)}.a2ui-slider__input{width:100%;cursor:pointer;accent-color:var(--a2ui-primary)}\n"] }]
|
|
11062
|
-
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], minValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "minValue", required: false }] }], maxValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxValue", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], _bindings: [{ type: i0.Input, args: [{ isSignal: true, alias: "_bindings", required: false }] }],
|
|
11639
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], minValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "minValue", required: false }] }], maxValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxValue", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], _bindings: [{ type: i0.Input, args: [{ isSignal: true, alias: "_bindings", required: false }] }], bindings: [{ type: i0.Input, args: [{ isSignal: true, alias: "bindings", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], childKeys: [{ type: i0.Input, args: [{ isSignal: true, alias: "childKeys", required: false }] }], spec: [{ type: i0.Input, args: [{ isSignal: true, alias: "spec", required: false }] }] } });
|
|
11063
11640
|
|
|
11064
11641
|
// SPDX-License-Identifier: MIT
|
|
11065
11642
|
class A2uiTabsComponent {
|
|
@@ -11166,6 +11743,7 @@ const TYPE_MAP = {
|
|
|
11166
11743
|
class A2uiTextFieldComponent {
|
|
11167
11744
|
static _idCounter = 0;
|
|
11168
11745
|
_inputId = `a2ui-text-field-${++A2uiTextFieldComponent._idCounter}`;
|
|
11746
|
+
host = injectRenderHost();
|
|
11169
11747
|
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
11170
11748
|
/** v1 prop: text (resolved string value). */
|
|
11171
11749
|
text = input('', ...(ngDevMode ? [{ debugName: "text" }] : []));
|
|
@@ -11175,7 +11753,6 @@ class A2uiTextFieldComponent {
|
|
|
11175
11753
|
textFieldType = input('shortText', ...(ngDevMode ? [{ debugName: "textFieldType" }] : []));
|
|
11176
11754
|
validationRegexp = input('', ...(ngDevMode ? [{ debugName: "validationRegexp" }] : []));
|
|
11177
11755
|
_bindings = input({}, ...(ngDevMode ? [{ debugName: "_bindings" }] : []));
|
|
11178
|
-
emit = input(() => { }, ...(ngDevMode ? [{ debugName: "emit" }] : []));
|
|
11179
11756
|
// Framework inputs required by the render harness.
|
|
11180
11757
|
bindings = input({}, ...(ngDevMode ? [{ debugName: "bindings" }] : []));
|
|
11181
11758
|
loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
@@ -11187,14 +11764,14 @@ class A2uiTextFieldComponent {
|
|
|
11187
11764
|
// Emit on 'text' binding (v1 prop name); also try 'value' for compat.
|
|
11188
11765
|
const bound = this._bindings();
|
|
11189
11766
|
if (bound['text']) {
|
|
11190
|
-
emitBinding(this.
|
|
11767
|
+
emitBinding(this.host, bound, 'text', val);
|
|
11191
11768
|
}
|
|
11192
11769
|
else {
|
|
11193
|
-
emitBinding(this.
|
|
11770
|
+
emitBinding(this.host, bound, 'value', val);
|
|
11194
11771
|
}
|
|
11195
11772
|
}
|
|
11196
11773
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: A2uiTextFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
11197
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: A2uiTextFieldComponent, isStandalone: true, selector: "a2ui-text-field", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, textFieldType: { classPropertyName: "textFieldType", publicName: "textFieldType", isSignal: true, isRequired: false, transformFunction: null }, validationRegexp: { classPropertyName: "validationRegexp", publicName: "validationRegexp", isSignal: true, isRequired: false, transformFunction: null }, _bindings: { classPropertyName: "_bindings", publicName: "_bindings", isSignal: true, isRequired: false, transformFunction: null },
|
|
11774
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: A2uiTextFieldComponent, isStandalone: true, selector: "a2ui-text-field", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, textFieldType: { classPropertyName: "textFieldType", publicName: "textFieldType", isSignal: true, isRequired: false, transformFunction: null }, validationRegexp: { classPropertyName: "validationRegexp", publicName: "validationRegexp", isSignal: true, isRequired: false, transformFunction: null }, _bindings: { classPropertyName: "_bindings", publicName: "_bindings", isSignal: true, isRequired: false, transformFunction: null }, bindings: { classPropertyName: "bindings", publicName: "bindings", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, childKeys: { classPropertyName: "childKeys", publicName: "childKeys", isSignal: true, isRequired: false, transformFunction: null }, spec: { classPropertyName: "spec", publicName: "spec", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
11198
11775
|
<div class="a2ui-tf">
|
|
11199
11776
|
@if (label()) {
|
|
11200
11777
|
<label [htmlFor]="_inputId" class="a2ui-tf__label">{{ label() }}</label>
|
|
@@ -11251,7 +11828,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
|
|
|
11251
11828
|
}
|
|
11252
11829
|
</div>
|
|
11253
11830
|
`, styles: [".a2ui-tf{display:flex;flex-direction:column;gap:var(--a2ui-spacing-1)}.a2ui-tf__label{font-size:var(--a2ui-typography-label-size);font-weight:var(--a2ui-typography-label-weight);color:var(--a2ui-label)}.a2ui-tf__input{padding:var(--a2ui-spacing-2) var(--a2ui-spacing-3);font-size:var(--a2ui-typography-body-size);border-radius:var(--a2ui-shape-small);background:var(--a2ui-input-bg);color:var(--a2ui-on-surface);border:1px solid var(--a2ui-outline);outline:none;transition:border-color var(--a2ui-motion-duration-short) var(--a2ui-motion-easing-standard);resize:vertical}.a2ui-tf__input:focus{outline:var(--a2ui-focus-ring-width) solid var(--a2ui-focus-ring-color);outline-offset:2px;border-color:var(--a2ui-primary)}\n"] }]
|
|
11254
|
-
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], text: [{ type: i0.Input, args: [{ isSignal: true, alias: "text", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], textFieldType: [{ type: i0.Input, args: [{ isSignal: true, alias: "textFieldType", required: false }] }], validationRegexp: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationRegexp", required: false }] }], _bindings: [{ type: i0.Input, args: [{ isSignal: true, alias: "_bindings", required: false }] }],
|
|
11831
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], text: [{ type: i0.Input, args: [{ isSignal: true, alias: "text", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], textFieldType: [{ type: i0.Input, args: [{ isSignal: true, alias: "textFieldType", required: false }] }], validationRegexp: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationRegexp", required: false }] }], _bindings: [{ type: i0.Input, args: [{ isSignal: true, alias: "_bindings", required: false }] }], bindings: [{ type: i0.Input, args: [{ isSignal: true, alias: "bindings", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], childKeys: [{ type: i0.Input, args: [{ isSignal: true, alias: "childKeys", required: false }] }], spec: [{ type: i0.Input, args: [{ isSignal: true, alias: "spec", required: false }] }] } });
|
|
11255
11832
|
|
|
11256
11833
|
// SPDX-License-Identifier: MIT
|
|
11257
11834
|
class A2uiVideoComponent {
|
|
@@ -11311,6 +11888,23 @@ function a2uiBasicCatalog() {
|
|
|
11311
11888
|
});
|
|
11312
11889
|
}
|
|
11313
11890
|
|
|
11891
|
+
/** Async function tool — its resolved return value becomes the tool result. */
|
|
11892
|
+
function action(description, schema, handler) {
|
|
11893
|
+
return { kind: 'function', description, schema, handler };
|
|
11894
|
+
}
|
|
11895
|
+
/** Render-only component tool — the model fills its props; auto-acknowledged. */
|
|
11896
|
+
function view(description, schema, component) {
|
|
11897
|
+
return { kind: 'view', description, schema, component };
|
|
11898
|
+
}
|
|
11899
|
+
/** Interactive (HITL) component tool — the value it emits becomes the result. */
|
|
11900
|
+
function ask(description, schema, component) {
|
|
11901
|
+
return { kind: 'ask', description, schema, component };
|
|
11902
|
+
}
|
|
11903
|
+
/** Collect named client tools into a frozen registry (the key is the tool name). */
|
|
11904
|
+
function tools(map) {
|
|
11905
|
+
return Object.freeze({ ...map });
|
|
11906
|
+
}
|
|
11907
|
+
|
|
11314
11908
|
// SPDX-License-Identifier: MIT
|
|
11315
11909
|
function mockAgent(opts = {}) {
|
|
11316
11910
|
const messages = signal(opts.messages ?? [], ...(ngDevMode ? [{ debugName: "messages" }] : []));
|
|
@@ -11362,5 +11956,5 @@ function mockAgent(opts = {}) {
|
|
|
11362
11956
|
* Generated bundle index. Do not edit.
|
|
11363
11957
|
*/
|
|
11364
11958
|
|
|
11365
|
-
export { A2uiAudioPlayerComponent, A2uiButtonComponent, A2uiCardComponent, A2uiCheckBoxComponent, A2uiColumnComponent, A2uiDateTimeInputComponent, A2uiDividerComponent, A2uiIconComponent, A2uiImageComponent, A2uiListComponent, A2uiModalComponent, A2uiMultipleChoiceComponent, A2uiRowComponent, A2uiSliderComponent, A2uiSurfaceComponent, A2uiTabsComponent, A2uiTextComponent, A2uiTextFieldComponent, A2uiVideoComponent, CHAT_CONFIG, CHAT_LIFECYCLE, CHAT_MARKDOWN_STYLES, ChatCitationCardTemplateDirective, ChatCitationsCardComponent, ChatCitationsComponent, ChatComponent, ChatConfirmDialogComponent, ChatErrorComponent, ChatGenerativeUiComponent, ChatGenuiSkeletonComponent, ChatHistorySearchPaletteComponent, ChatInputComponent, ChatInterruptComponent, ChatInterruptPanelComponent, ChatLauncherButtonComponent, ChatMessageActionsComponent, ChatMessageComponent, ChatMessageListComponent, ChatOverflowMenuComponent, ChatPopupComponent, ChatProjectListComponent, ChatReasoningComponent, ChatScrollBubbleComponent, ChatSelectComponent, ChatSidebarComponent, ChatSidenavComponent, ChatSidenavScrimComponent, ChatStreamingMdComponent, ChatSubagentCardComponent, ChatSubagentsComponent, ChatSuggestionsComponent, ChatThreadListComponent, ChatTimelineComponent, ChatTimelineSliderComponent, ChatToolCallCardComponent, ChatToolCallTemplateDirective, ChatToolCallsComponent, ChatTraceComponent, ChatTypingIndicatorComponent, ChatWelcomeComponent, ChatWelcomeSuggestionComponent, ChatWindowComponent, CitationsResolverService, ICON_AGENT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CHEVRON_UP, ICON_SEND, ICON_TOOL, ICON_WARNING, IS_HEADER_ROW, MARKDOWN_VIEW_REGISTRY, MarkdownAutolinkComponent, MarkdownBlockquoteComponent, MarkdownChildrenComponent, MarkdownCitationReferenceComponent, MarkdownCodeBlockComponent, MarkdownDocumentComponent, MarkdownEmphasisComponent, MarkdownHardBreakComponent, MarkdownHeadingComponent, MarkdownImageComponent, MarkdownInlineCodeComponent, MarkdownLinkComponent, MarkdownListComponent, MarkdownListItemComponent, MarkdownParagraphComponent, MarkdownSoftBreakComponent, MarkdownStrikethroughComponent, MarkdownStrongComponent, MarkdownTableCellComponent, MarkdownTableComponent, MarkdownTableRowComponent, MarkdownTextComponent, MarkdownThematicBreakComponent, MessageTemplateDirective, a2uiBasicCatalog, buildA2uiActionMessage, cacheplaneMarkdownViews, createA2uiSurfaceStore, createContentClassifier, createParseTreeStore, createPartialArgsBridge, emitBinding, extractErrorMessage, formatDuration, getInterrupt, getMessageType, isAssistantMessage, isSystemMessage, isToolMessage, isTyping, isUserMessage, messageContent, mockAgent, normalizeEnvelopeArgs, normalizeViewEntry, provideChat, renderMarkdown, statusColor, submitMessage, surfaceToSpec };
|
|
11959
|
+
export { A2uiAudioPlayerComponent, A2uiButtonComponent, A2uiCardComponent, A2uiCheckBoxComponent, A2uiColumnComponent, A2uiDateTimeInputComponent, A2uiDividerComponent, A2uiIconComponent, A2uiImageComponent, A2uiListComponent, A2uiModalComponent, A2uiMultipleChoiceComponent, A2uiRowComponent, A2uiSliderComponent, A2uiSurfaceComponent, A2uiTabsComponent, A2uiTextComponent, A2uiTextFieldComponent, A2uiVideoComponent, CHAT_CONFIG, CHAT_LIFECYCLE, CHAT_MARKDOWN_STYLES, ChatApprovalCardComponent, ChatCitationCardTemplateDirective, ChatCitationsCardComponent, ChatCitationsComponent, ChatComponent, ChatConfirmDialogComponent, ChatErrorComponent, ChatGenerativeUiComponent, ChatGenuiSkeletonComponent, ChatHistorySearchPaletteComponent, ChatInputComponent, ChatInterruptComponent, ChatInterruptPanelComponent, ChatLauncherButtonComponent, ChatMessageActionsComponent, ChatMessageComponent, ChatMessageListComponent, ChatOverflowMenuComponent, ChatPopupComponent, ChatProjectListComponent, ChatReasoningComponent, ChatScrollBubbleComponent, ChatSelectComponent, ChatSidebarComponent, ChatSidenavComponent, ChatSidenavScrimComponent, ChatStreamingMdComponent, ChatSubagentCardComponent, ChatSubagentsComponent, ChatSuggestionsComponent, ChatThreadListComponent, ChatTimelineComponent, ChatTimelineSliderComponent, ChatToolCallCardComponent, ChatToolCallTemplateDirective, ChatToolCallsComponent, ChatToolViewsComponent, ChatTraceComponent, ChatTypingIndicatorComponent, ChatWelcomeComponent, ChatWelcomeSuggestionComponent, ChatWindowComponent, CitationsResolverService, ICON_AGENT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CHEVRON_UP, ICON_SEND, ICON_TOOL, ICON_WARNING, IS_HEADER_ROW, MARKDOWN_VIEW_REGISTRY, MarkdownAutolinkComponent, MarkdownBlockquoteComponent, MarkdownChildrenComponent, MarkdownCitationReferenceComponent, MarkdownCodeBlockComponent, MarkdownDocumentComponent, MarkdownEmphasisComponent, MarkdownHardBreakComponent, MarkdownHeadingComponent, MarkdownImageComponent, MarkdownInlineCodeComponent, MarkdownLinkComponent, MarkdownListComponent, MarkdownListItemComponent, MarkdownParagraphComponent, MarkdownSoftBreakComponent, MarkdownStrikethroughComponent, MarkdownStrongComponent, MarkdownTableCellComponent, MarkdownTableComponent, MarkdownTableRowComponent, MarkdownTextComponent, MarkdownThematicBreakComponent, MessageTemplateDirective, a2uiBasicCatalog, action, ask, buildA2uiActionMessage, cacheplaneMarkdownViews, createA2uiSurfaceStore, createClientToolsCoordinator, createContentClassifier, createParseTreeStore, createPartialArgsBridge, deriveJsonSchema, emitBinding, executeFunctionTool, extractErrorMessage, formatDuration, getInterrupt, getMessageType, isAssistantMessage, isSystemMessage, isToolMessage, isTyping, isUserMessage, messageContent, mockAgent, normalizeEnvelopeArgs, normalizeViewEntry, provideChat, renderMarkdown, startClientToolExecutor, statusColor, submitMessage, surfaceToSpec, toClientToolSpecs, tools, validateArgs, view };
|
|
11366
11960
|
//# sourceMappingURL=threadplane-chat.mjs.map
|