@agentskit/angular
Advanced tools
| import * as i0 from '@angular/core'; | ||
| import { signal, Injectable, ViewChild, Component, Input } from '@angular/core'; | ||
| import { BehaviorSubject } from 'rxjs'; | ||
| import { createChatController } from '@agentskit/core'; | ||
| /** | ||
| * Angular service wrapping the shared `ChatController`. Exposes | ||
| * chat state both as a Signal (template-friendly) and as a | ||
| * BehaviorSubject (RxJS interop). | ||
| * | ||
| * Usage: | ||
| * @Component({ ... }) | ||
| * export class ChatPage { | ||
| * constructor(public chat: AgentskitChat) { | ||
| * chat.init({ adapter }) | ||
| * } | ||
| * } | ||
| */ | ||
| class AgentskitChat { | ||
| constructor() { | ||
| this.state = signal(null, ...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ [])); | ||
| this._stream$ = new BehaviorSubject(null); | ||
| this.stream$ = this._stream$.asObservable(); | ||
| this.send = (text) => { | ||
| void this.requireController().send(text); | ||
| }; | ||
| this.stop = () => this.requireController().stop(); | ||
| this.retry = () => { | ||
| void this.requireController().retry(); | ||
| }; | ||
| this.setInput = (value) => this.requireController().setInput(value); | ||
| this.clear = () => { | ||
| void this.requireController().clear(); | ||
| }; | ||
| this.proposeToolCall = (proposal) => this.requireController().proposeToolCall(proposal); | ||
| this.approve = (id) => { | ||
| void this.requireController().approve(id); | ||
| }; | ||
| this.deny = (id) => { | ||
| void this.requireController().deny(id); | ||
| }; | ||
| } | ||
| init(config) { | ||
| if (this.controller) | ||
| this.destroy(); | ||
| this.controller = createChatController(config); | ||
| const push = () => { | ||
| const current = this.controller?.getState() ?? null; | ||
| this.state.set(current); | ||
| this._stream$.next(current); | ||
| }; | ||
| push(); | ||
| this.unsubscribe = this.controller.subscribe(push); | ||
| return this.snapshot(); | ||
| } | ||
| snapshot() { | ||
| const c = this.requireController(); | ||
| return { | ||
| ...c.getState(), | ||
| send: c.send, | ||
| stop: c.stop, | ||
| retry: c.retry, | ||
| edit: c.edit, | ||
| regenerate: c.regenerate, | ||
| setInput: c.setInput, | ||
| clear: c.clear, | ||
| proposeToolCall: c.proposeToolCall, | ||
| approve: c.approve, | ||
| deny: c.deny, | ||
| }; | ||
| } | ||
| destroy() { | ||
| this.unsubscribe?.(); | ||
| this.controller?.stop(); | ||
| this.unsubscribe = undefined; | ||
| this.controller = undefined; | ||
| this.state.set(null); | ||
| this._stream$.next(null); | ||
| } | ||
| ngOnDestroy() { | ||
| this.destroy(); | ||
| } | ||
| requireController() { | ||
| if (!this.controller) | ||
| throw new Error('AgentskitChat.init(...) must be called first'); | ||
| return this.controller; | ||
| } | ||
| static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: AgentskitChat, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } | ||
| static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: AgentskitChat, providedIn: 'root' }); } | ||
| } | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: AgentskitChat, decorators: [{ | ||
| type: Injectable, | ||
| args: [{ providedIn: 'root' }] | ||
| }] }); | ||
| /** | ||
| * Headless Angular chat components mirroring `@agentskit/react`'s set. Each | ||
| * renders `data-ak-*` attributes only — bring your own CSS. Standalone + | ||
| * JIT-friendly (inline templates); pairs with the `AgentskitChat` service. | ||
| */ | ||
| class ChatContainerComponent { | ||
| ngAfterViewInit() { | ||
| const el = this.scrollRef?.nativeElement; | ||
| if (!el || typeof MutationObserver === 'undefined') | ||
| return; | ||
| const observer = new MutationObserver(() => { | ||
| el.scrollTop = el.scrollHeight; | ||
| }); | ||
| // Some non-browser envs (e.g. happy-dom) expose a partial MutationObserver. | ||
| if (typeof observer.observe !== 'function') | ||
| return; | ||
| this.observer = observer; | ||
| observer.observe(el, { childList: true, subtree: true, characterData: true }); | ||
| } | ||
| ngOnDestroy() { | ||
| if (typeof this.observer?.disconnect === 'function') | ||
| this.observer.disconnect(); | ||
| } | ||
| static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ChatContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } | ||
| static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.18", type: ChatContainerComponent, isStandalone: true, selector: "ak-chat-container", viewQueries: [{ propertyName: "scrollRef", first: true, predicate: ["scroll"], descendants: true, static: true }], ngImport: i0, template: `<div #scroll data-ak-chat-container data-testid="ak-chat-container"><ng-content /></div>`, isInline: true }); } | ||
| } | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ChatContainerComponent, decorators: [{ | ||
| type: Component, | ||
| args: [{ | ||
| selector: 'ak-chat-container', | ||
| standalone: true, | ||
| template: `<div #scroll data-ak-chat-container data-testid="ak-chat-container"><ng-content /></div>`, | ||
| }] | ||
| }], propDecorators: { scrollRef: [{ | ||
| type: ViewChild, | ||
| args: ['scroll', { static: true }] | ||
| }] } }); | ||
| class MessageComponent { | ||
| static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: MessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } | ||
| static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.18", type: MessageComponent, isStandalone: true, selector: "ak-message", inputs: { message: "message" }, ngImport: i0, template: `<div | ||
| data-ak-message | ||
| [attr.data-ak-role]="message.role" | ||
| [attr.data-ak-status]="message.status" | ||
| > | ||
| <div data-ak-content>{{ message.content }}</div> | ||
| </div>`, isInline: true }); } | ||
| } | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: MessageComponent, decorators: [{ | ||
| type: Component, | ||
| args: [{ | ||
| selector: 'ak-message', | ||
| standalone: true, | ||
| template: `<div | ||
| data-ak-message | ||
| [attr.data-ak-role]="message.role" | ||
| [attr.data-ak-status]="message.status" | ||
| > | ||
| <div data-ak-content>{{ message.content }}</div> | ||
| </div>`, | ||
| }] | ||
| }], propDecorators: { message: [{ | ||
| type: Input, | ||
| args: [{ required: true }] | ||
| }] } }); | ||
| class InputBarComponent { | ||
| constructor() { | ||
| this.placeholder = 'Type a message...'; | ||
| this.disabled = false; | ||
| } | ||
| onSubmit(e) { | ||
| e.preventDefault(); | ||
| this.submit(); | ||
| } | ||
| onEnter(e) { | ||
| if (!e.shiftKey) { | ||
| e.preventDefault(); | ||
| this.submit(); | ||
| } | ||
| } | ||
| submit() { | ||
| if (this.chat.input.trim()) | ||
| this.chat.send(this.chat.input); | ||
| } | ||
| static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: InputBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } | ||
| static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.18", type: InputBarComponent, isStandalone: true, selector: "ak-input-bar", inputs: { chat: "chat", placeholder: "placeholder", disabled: "disabled" }, ngImport: i0, template: `<form data-ak-input-bar (submit)="onSubmit($event)"> | ||
| <textarea | ||
| role="textbox" | ||
| data-ak-input | ||
| rows="1" | ||
| [value]="chat.input" | ||
| [attr.placeholder]="placeholder" | ||
| [disabled]="disabled" | ||
| (input)="chat.setInput($any($event.target).value)" | ||
| (keydown.enter)="onEnter($event)" | ||
| ></textarea> | ||
| <button data-ak-send type="submit" [disabled]="disabled || !chat.input.trim()">Send</button> | ||
| </form>`, isInline: true }); } | ||
| } | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: InputBarComponent, decorators: [{ | ||
| type: Component, | ||
| args: [{ | ||
| selector: 'ak-input-bar', | ||
| standalone: true, | ||
| template: `<form data-ak-input-bar (submit)="onSubmit($event)"> | ||
| <textarea | ||
| role="textbox" | ||
| data-ak-input | ||
| rows="1" | ||
| [value]="chat.input" | ||
| [attr.placeholder]="placeholder" | ||
| [disabled]="disabled" | ||
| (input)="chat.setInput($any($event.target).value)" | ||
| (keydown.enter)="onEnter($event)" | ||
| ></textarea> | ||
| <button data-ak-send type="submit" [disabled]="disabled || !chat.input.trim()">Send</button> | ||
| </form>`, | ||
| }] | ||
| }], propDecorators: { chat: [{ | ||
| type: Input, | ||
| args: [{ required: true }] | ||
| }], placeholder: [{ | ||
| type: Input | ||
| }], disabled: [{ | ||
| type: Input | ||
| }] } }); | ||
| class MarkdownComponent { | ||
| constructor() { | ||
| this.content = ''; | ||
| this.streaming = false; | ||
| } | ||
| static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: MarkdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } | ||
| static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.18", type: MarkdownComponent, isStandalone: true, selector: "ak-markdown", inputs: { content: "content", streaming: "streaming" }, ngImport: i0, template: `<div data-ak-markdown [attr.data-ak-streaming]="streaming ? 'true' : null">{{ content }}</div>`, isInline: true }); } | ||
| } | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: MarkdownComponent, decorators: [{ | ||
| type: Component, | ||
| args: [{ | ||
| selector: 'ak-markdown', | ||
| standalone: true, | ||
| template: `<div data-ak-markdown [attr.data-ak-streaming]="streaming ? 'true' : null">{{ content }}</div>`, | ||
| }] | ||
| }], propDecorators: { content: [{ | ||
| type: Input, | ||
| args: [{ required: true }] | ||
| }], streaming: [{ | ||
| type: Input | ||
| }] } }); | ||
| class CodeBlockComponent { | ||
| constructor() { | ||
| this.code = ''; | ||
| this.copyable = false; | ||
| } | ||
| copy() { | ||
| void globalThis.navigator?.clipboard?.writeText(this.code); | ||
| } | ||
| static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: CodeBlockComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } | ||
| static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: CodeBlockComponent, isStandalone: true, selector: "ak-code-block", inputs: { code: "code", language: "language", copyable: "copyable" }, ngImport: i0, template: `<div data-ak-code-block [attr.data-ak-language]="language"> | ||
| <pre><code>{{ code }}</code></pre> | ||
| @if (copyable) { | ||
| <button data-ak-copy type="button" (click)="copy()">Copy</button> | ||
| } | ||
| </div>`, isInline: true }); } | ||
| } | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: CodeBlockComponent, decorators: [{ | ||
| type: Component, | ||
| args: [{ | ||
| selector: 'ak-code-block', | ||
| standalone: true, | ||
| template: `<div data-ak-code-block [attr.data-ak-language]="language"> | ||
| <pre><code>{{ code }}</code></pre> | ||
| @if (copyable) { | ||
| <button data-ak-copy type="button" (click)="copy()">Copy</button> | ||
| } | ||
| </div>`, | ||
| }] | ||
| }], propDecorators: { code: [{ | ||
| type: Input, | ||
| args: [{ required: true }] | ||
| }], language: [{ | ||
| type: Input | ||
| }], copyable: [{ | ||
| type: Input | ||
| }] } }); | ||
| class ToolCallViewComponent { | ||
| constructor() { | ||
| this.expanded = signal(false, ...(ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ [])); | ||
| } | ||
| get argsJson() { | ||
| return JSON.stringify(this.toolCall.args, null, 2); | ||
| } | ||
| static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ToolCallViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } | ||
| static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: ToolCallViewComponent, isStandalone: true, selector: "ak-tool-call-view", inputs: { toolCall: "toolCall" }, ngImport: i0, template: `<div data-ak-tool-call [attr.data-ak-tool-status]="toolCall.status"> | ||
| <button data-ak-tool-toggle type="button" (click)="expanded.set(!expanded())"> | ||
| {{ toolCall.name }} | ||
| </button> | ||
| @if (expanded()) { | ||
| <div data-ak-tool-details> | ||
| <pre data-ak-tool-args>{{ argsJson }}</pre> | ||
| @if (toolCall.result) { | ||
| <div data-ak-tool-result>{{ toolCall.result }}</div> | ||
| } | ||
| </div> | ||
| } | ||
| </div>`, isInline: true }); } | ||
| } | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ToolCallViewComponent, decorators: [{ | ||
| type: Component, | ||
| args: [{ | ||
| selector: 'ak-tool-call-view', | ||
| standalone: true, | ||
| template: `<div data-ak-tool-call [attr.data-ak-tool-status]="toolCall.status"> | ||
| <button data-ak-tool-toggle type="button" (click)="expanded.set(!expanded())"> | ||
| {{ toolCall.name }} | ||
| </button> | ||
| @if (expanded()) { | ||
| <div data-ak-tool-details> | ||
| <pre data-ak-tool-args>{{ argsJson }}</pre> | ||
| @if (toolCall.result) { | ||
| <div data-ak-tool-result>{{ toolCall.result }}</div> | ||
| } | ||
| </div> | ||
| } | ||
| </div>`, | ||
| }] | ||
| }], propDecorators: { toolCall: [{ | ||
| type: Input, | ||
| args: [{ required: true }] | ||
| }] } }); | ||
| class ThinkingIndicatorComponent { | ||
| constructor() { | ||
| this.visible = false; | ||
| this.label = 'Thinking...'; | ||
| } | ||
| static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ThinkingIndicatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } | ||
| static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: ThinkingIndicatorComponent, isStandalone: true, selector: "ak-thinking-indicator", inputs: { visible: "visible", label: "label" }, ngImport: i0, template: `@if (visible) { | ||
| <div data-ak-thinking> | ||
| <span data-ak-thinking-dots><span>•</span><span>•</span><span>•</span></span> | ||
| <span data-ak-thinking-label>{{ label }}</span> | ||
| </div> | ||
| }`, isInline: true }); } | ||
| } | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ThinkingIndicatorComponent, decorators: [{ | ||
| type: Component, | ||
| args: [{ | ||
| selector: 'ak-thinking-indicator', | ||
| standalone: true, | ||
| template: `@if (visible) { | ||
| <div data-ak-thinking> | ||
| <span data-ak-thinking-dots><span>•</span><span>•</span><span>•</span></span> | ||
| <span data-ak-thinking-label>{{ label }}</span> | ||
| </div> | ||
| }`, | ||
| }] | ||
| }], propDecorators: { visible: [{ | ||
| type: Input, | ||
| args: [{ required: true }] | ||
| }], label: [{ | ||
| type: Input | ||
| }] } }); | ||
| class ToolConfirmationComponent { | ||
| get argsJson() { | ||
| return JSON.stringify(this.toolCall.args, null, 2); | ||
| } | ||
| static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ToolConfirmationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } | ||
| static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: ToolConfirmationComponent, isStandalone: true, selector: "ak-tool-confirmation", inputs: { toolCall: "toolCall", onApprove: "onApprove", onDeny: "onDeny" }, ngImport: i0, template: `@if (toolCall.status === 'requires_confirmation') { | ||
| <div data-ak-tool-confirmation [attr.data-ak-tool-name]="toolCall.name"> | ||
| <div data-ak-tool-confirmation-header> | ||
| <span data-ak-tool-confirmation-name>{{ toolCall.name }}</span> | ||
| <span data-ak-tool-confirmation-status>requires confirmation</span> | ||
| </div> | ||
| <div data-ak-tool-confirmation-args>{{ argsJson }}</div> | ||
| <div data-ak-tool-confirmation-actions> | ||
| <button data-ak-tool-confirmation-approve type="button" (click)="onApprove(toolCall.id)"> | ||
| Approve | ||
| </button> | ||
| <button data-ak-tool-confirmation-deny type="button" (click)="onDeny(toolCall.id)"> | ||
| Deny | ||
| </button> | ||
| </div> | ||
| </div> | ||
| }`, isInline: true }); } | ||
| } | ||
| i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ToolConfirmationComponent, decorators: [{ | ||
| type: Component, | ||
| args: [{ | ||
| selector: 'ak-tool-confirmation', | ||
| standalone: true, | ||
| template: `@if (toolCall.status === 'requires_confirmation') { | ||
| <div data-ak-tool-confirmation [attr.data-ak-tool-name]="toolCall.name"> | ||
| <div data-ak-tool-confirmation-header> | ||
| <span data-ak-tool-confirmation-name>{{ toolCall.name }}</span> | ||
| <span data-ak-tool-confirmation-status>requires confirmation</span> | ||
| </div> | ||
| <div data-ak-tool-confirmation-args>{{ argsJson }}</div> | ||
| <div data-ak-tool-confirmation-actions> | ||
| <button data-ak-tool-confirmation-approve type="button" (click)="onApprove(toolCall.id)"> | ||
| Approve | ||
| </button> | ||
| <button data-ak-tool-confirmation-deny type="button" (click)="onDeny(toolCall.id)"> | ||
| Deny | ||
| </button> | ||
| </div> | ||
| </div> | ||
| }`, | ||
| }] | ||
| }], propDecorators: { toolCall: [{ | ||
| type: Input, | ||
| args: [{ required: true }] | ||
| }], onApprove: [{ | ||
| type: Input, | ||
| args: [{ required: true }] | ||
| }], onDeny: [{ | ||
| type: Input, | ||
| args: [{ required: true }] | ||
| }] } }); | ||
| /** | ||
| * Generated bundle index. Do not edit. | ||
| */ | ||
| export { AgentskitChat, ChatContainerComponent, CodeBlockComponent, InputBarComponent, MarkdownComponent, MessageComponent, ThinkingIndicatorComponent, ToolCallViewComponent, ToolConfirmationComponent }; | ||
| //# sourceMappingURL=agentskit-angular.mjs.map |
| {"version":3,"file":"agentskit-angular.mjs","sources":["../../src/chat.service.ts","../../src/components.ts","../../src/agentskit-angular.ts"],"sourcesContent":["import { Injectable, OnDestroy, signal, type WritableSignal } from '@angular/core'\nimport { BehaviorSubject, type Observable } from 'rxjs'\nimport { createChatController } from '@agentskit/core'\nimport type {\n ChatConfig,\n ChatController,\n ChatReturn,\n ChatState,\n ToolCall,\n} from '@agentskit/core'\n\n/**\n * Angular service wrapping the shared `ChatController`. Exposes\n * chat state both as a Signal (template-friendly) and as a\n * BehaviorSubject (RxJS interop).\n *\n * Usage:\n * @Component({ ... })\n * export class ChatPage {\n * constructor(public chat: AgentskitChat) {\n * chat.init({ adapter })\n * }\n * }\n */\n@Injectable({ providedIn: 'root' })\nexport class AgentskitChat implements OnDestroy {\n private controller?: ChatController\n private unsubscribe?: () => void\n\n readonly state: WritableSignal<ChatState | null> = signal(null)\n private readonly _stream$ = new BehaviorSubject<ChatState | null>(null)\n readonly stream$: Observable<ChatState | null> = this._stream$.asObservable()\n\n init(config: ChatConfig): ChatReturn {\n if (this.controller) this.destroy()\n this.controller = createChatController(config)\n const push = (): void => {\n const current = this.controller?.getState() ?? null\n this.state.set(current)\n this._stream$.next(current)\n }\n push()\n this.unsubscribe = this.controller.subscribe(push)\n return this.snapshot()\n }\n\n snapshot(): ChatReturn {\n const c = this.requireController()\n return {\n ...c.getState(),\n send: c.send,\n stop: c.stop,\n retry: c.retry,\n edit: c.edit,\n regenerate: c.regenerate,\n setInput: c.setInput,\n clear: c.clear,\n proposeToolCall: c.proposeToolCall,\n approve: c.approve,\n deny: c.deny,\n }\n }\n\n send = (text: string): void => {\n void this.requireController().send(text)\n }\n\n stop = (): void => this.requireController().stop()\n retry = (): void => {\n void this.requireController().retry()\n }\n setInput = (value: string): void => this.requireController().setInput(value)\n clear = (): void => {\n void this.requireController().clear()\n }\n proposeToolCall = (proposal: Parameters<ChatReturn['proposeToolCall']>[0]): Promise<ToolCall> =>\n this.requireController().proposeToolCall(proposal)\n approve = (id: string): void => {\n void this.requireController().approve(id)\n }\n deny = (id: string): void => {\n void this.requireController().deny(id)\n }\n\n destroy(): void {\n this.unsubscribe?.()\n this.controller?.stop()\n this.unsubscribe = undefined\n this.controller = undefined\n this.state.set(null)\n this._stream$.next(null)\n }\n\n ngOnDestroy(): void {\n this.destroy()\n }\n\n private requireController(): ChatController {\n if (!this.controller) throw new Error('AgentskitChat.init(...) must be called first')\n return this.controller\n }\n}\n","import {\n Component,\n Input,\n ViewChild,\n ElementRef,\n signal,\n type AfterViewInit,\n type OnDestroy,\n} from '@angular/core'\nimport type { Message as MessageType, ChatReturn, ToolCall } from '@agentskit/core'\n\n/**\n * Headless Angular chat components mirroring `@agentskit/react`'s set. Each\n * renders `data-ak-*` attributes only — bring your own CSS. Standalone +\n * JIT-friendly (inline templates); pairs with the `AgentskitChat` service.\n */\n\n@Component({\n selector: 'ak-chat-container',\n standalone: true,\n template: `<div #scroll data-ak-chat-container data-testid=\"ak-chat-container\"><ng-content /></div>`,\n})\nexport class ChatContainerComponent implements AfterViewInit, OnDestroy {\n @ViewChild('scroll', { static: true }) scrollRef!: ElementRef<HTMLDivElement>\n private observer?: MutationObserver\n\n ngAfterViewInit(): void {\n const el = this.scrollRef?.nativeElement\n if (!el || typeof MutationObserver === 'undefined') return\n const observer = new MutationObserver(() => {\n el.scrollTop = el.scrollHeight\n })\n // Some non-browser envs (e.g. happy-dom) expose a partial MutationObserver.\n if (typeof observer.observe !== 'function') return\n this.observer = observer\n observer.observe(el, { childList: true, subtree: true, characterData: true })\n }\n\n ngOnDestroy(): void {\n if (typeof this.observer?.disconnect === 'function') this.observer.disconnect()\n }\n}\n\n@Component({\n selector: 'ak-message',\n standalone: true,\n template: `<div\n data-ak-message\n [attr.data-ak-role]=\"message.role\"\n [attr.data-ak-status]=\"message.status\"\n >\n <div data-ak-content>{{ message.content }}</div>\n </div>`,\n})\nexport class MessageComponent {\n @Input({ required: true }) message!: MessageType\n}\n\n@Component({\n selector: 'ak-input-bar',\n standalone: true,\n template: `<form data-ak-input-bar (submit)=\"onSubmit($event)\">\n <textarea\n role=\"textbox\"\n data-ak-input\n rows=\"1\"\n [value]=\"chat.input\"\n [attr.placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n (input)=\"chat.setInput($any($event.target).value)\"\n (keydown.enter)=\"onEnter($event)\"\n ></textarea>\n <button data-ak-send type=\"submit\" [disabled]=\"disabled || !chat.input.trim()\">Send</button>\n </form>`,\n})\nexport class InputBarComponent {\n @Input({ required: true }) chat!: ChatReturn\n @Input() placeholder = 'Type a message...'\n @Input() disabled = false\n\n onSubmit(e: Event): void {\n e.preventDefault()\n this.submit()\n }\n\n onEnter(e: Event): void {\n if (!(e as KeyboardEvent).shiftKey) {\n e.preventDefault()\n this.submit()\n }\n }\n\n private submit(): void {\n if (this.chat.input.trim()) this.chat.send(this.chat.input)\n }\n}\n\n@Component({\n selector: 'ak-markdown',\n standalone: true,\n template: `<div data-ak-markdown [attr.data-ak-streaming]=\"streaming ? 'true' : null\">{{ content }}</div>`,\n})\nexport class MarkdownComponent {\n @Input({ required: true }) content = ''\n @Input() streaming = false\n}\n\n@Component({\n selector: 'ak-code-block',\n standalone: true,\n template: `<div data-ak-code-block [attr.data-ak-language]=\"language\">\n <pre><code>{{ code }}</code></pre>\n @if (copyable) {\n <button data-ak-copy type=\"button\" (click)=\"copy()\">Copy</button>\n }\n </div>`,\n})\nexport class CodeBlockComponent {\n @Input({ required: true }) code = ''\n @Input() language?: string\n @Input() copyable = false\n\n copy(): void {\n void globalThis.navigator?.clipboard?.writeText(this.code)\n }\n}\n\n@Component({\n selector: 'ak-tool-call-view',\n standalone: true,\n template: `<div data-ak-tool-call [attr.data-ak-tool-status]=\"toolCall.status\">\n <button data-ak-tool-toggle type=\"button\" (click)=\"expanded.set(!expanded())\">\n {{ toolCall.name }}\n </button>\n @if (expanded()) {\n <div data-ak-tool-details>\n <pre data-ak-tool-args>{{ argsJson }}</pre>\n @if (toolCall.result) {\n <div data-ak-tool-result>{{ toolCall.result }}</div>\n }\n </div>\n }\n </div>`,\n})\nexport class ToolCallViewComponent {\n @Input({ required: true }) toolCall!: ToolCall\n readonly expanded = signal(false)\n\n get argsJson(): string {\n return JSON.stringify(this.toolCall.args, null, 2)\n }\n}\n\n@Component({\n selector: 'ak-thinking-indicator',\n standalone: true,\n template: `@if (visible) {\n <div data-ak-thinking>\n <span data-ak-thinking-dots><span>•</span><span>•</span><span>•</span></span>\n <span data-ak-thinking-label>{{ label }}</span>\n </div>\n }`,\n})\nexport class ThinkingIndicatorComponent {\n @Input({ required: true }) visible = false\n @Input() label = 'Thinking...'\n}\n\n@Component({\n selector: 'ak-tool-confirmation',\n standalone: true,\n template: `@if (toolCall.status === 'requires_confirmation') {\n <div data-ak-tool-confirmation [attr.data-ak-tool-name]=\"toolCall.name\">\n <div data-ak-tool-confirmation-header>\n <span data-ak-tool-confirmation-name>{{ toolCall.name }}</span>\n <span data-ak-tool-confirmation-status>requires confirmation</span>\n </div>\n <div data-ak-tool-confirmation-args>{{ argsJson }}</div>\n <div data-ak-tool-confirmation-actions>\n <button data-ak-tool-confirmation-approve type=\"button\" (click)=\"onApprove(toolCall.id)\">\n Approve\n </button>\n <button data-ak-tool-confirmation-deny type=\"button\" (click)=\"onDeny(toolCall.id)\">\n Deny\n </button>\n </div>\n </div>\n }`,\n})\nexport class ToolConfirmationComponent {\n @Input({ required: true }) toolCall!: ToolCall\n @Input({ required: true }) onApprove!: (toolCallId: string) => void\n @Input({ required: true }) onDeny!: (toolCallId: string, reason?: string) => void\n\n get argsJson(): string {\n return JSON.stringify(this.toolCall.args, null, 2)\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"} |
+109
| # @agentskit/angular | ||
| <p align="center"><img src="https://raw.githubusercontent.com/AgentsKit-io/agentskit/main/apps/docs-next/public/brand/logo-wordmark.svg" alt="AgentsKit" width="180" /></p> | ||
| Angular 18+ service (Signal + RxJS) + headless chat components. Same `ChatReturn` contract every AgentsKit framework binding ships. | ||
| [](https://www.npmjs.com/package/@agentskit/angular) | ||
| [](https://www.npmjs.com/package/@agentskit/angular) | ||
| [](https://bundlejs.com/?q=@agentskit/angular) | ||
| [](../../LICENSE) | ||
| [](../../docs/STABILITY.md) | ||
| [](https://github.com/AgentsKit-io/agentskit) | ||
| **Tags:** `ai` · `agents` · `llm` · `agentskit` · `angular` · `signals` · `rxjs` · `chat` · `streaming` | ||
| ## How this fits the ecosystem | ||
| @agentskit/angular brings the shared AgentsKit chat contract to Angular with Signals, RxJS, streaming, tools, and memory. | ||
| - **AgentsKit**: compose it with the other packages in this repo to build agents from small, swappable parts. | ||
| - **Registry**: look for ready agents and templates that already use this layer at [registry.agentskit.io](https://registry.agentskit.io). | ||
| - **Playbook**: learn the production patterns behind this layer at [playbook.agentskit.io](https://playbook.agentskit.io). | ||
| - **AKOS**: run the same concepts with enterprise deployment, governance, and observability at [akos.agentskit.io](https://akos.agentskit.io). | ||
| Docs: [package guide](https://www.agentskit.io/docs/packages/angular) · [agent handoff](https://github.com/AgentsKit-io/agentskit/blob/main/llms.txt) | ||
| ## Why | ||
| - **One contract, every framework** — `AgentskitChat` service surfaces the exact same shape as the React / Vue / Svelte / Solid / RN / Ink bindings. | ||
| - **Angular-native reactivity** — state exposed as `Signal`; events as RxJS `Observable`. | ||
| - **Headless by default** — components emit `data-ak-*` attributes; style with your design system. | ||
| - **Streaming, tools, HITL** — all core features work identically to `@agentskit/react`. | ||
| ## Install | ||
| ```bash | ||
| npm install @agentskit/angular @agentskit/adapters | ||
| ``` | ||
| Peers: `@angular/core ^18 || ^19 || ^20`, `rxjs ^7`. | ||
| ## Quick example | ||
| ```ts | ||
| import { Component, inject } from '@angular/core' | ||
| import { AgentskitChat, ChatContainerComponent, MessageComponent } from '@agentskit/angular' | ||
| import { anthropic } from '@agentskit/adapters' | ||
| @Component({ | ||
| standalone: true, | ||
| imports: [ChatContainerComponent, MessageComponent], | ||
| template: ` | ||
| <ak-chat-container> | ||
| @for (m of chat.state()?.messages ?? []; track m.id) { | ||
| <ak-message [message]="m" /> | ||
| } | ||
| </ak-chat-container> | ||
| <form (submit)="$event.preventDefault(); chat.send(chat.state()?.input ?? '')"> | ||
| <input [value]="chat.state()?.input ?? ''" (input)="chat.setInput($any($event.target).value)" /> | ||
| </form> | ||
| `, | ||
| }) | ||
| export class ChatWidget { | ||
| protected readonly chat = inject(AgentskitChat) | ||
| constructor() { | ||
| this.chat.init({ | ||
| adapter: anthropic({ apiKey: process.env['NG_APP_ANTHROPIC_API_KEY']!, model: 'claude-sonnet-4-6' }), | ||
| }) | ||
| } | ||
| } | ||
| ``` | ||
| The headless components compile in **JIT** (inline templates). Most Angular apps | ||
| are JIT-capable in dev/test; for fully AOT-only prod builds, render via the | ||
| `AgentskitChat` service + your own templates (an `ng-packagr`/AOT build of these | ||
| components is tracked for a future release). | ||
| `init(config)` wires the controller and returns a `ChatReturn` snapshot; read live | ||
| state from the `state` `Signal` (`chat.state()`) or the `stream$` `Observable`. | ||
| ## API | ||
| - `AgentskitChat` service — DI-friendly. `init(config)` returns a `ChatReturn` snapshot and starts the session; `state: Signal<ChatState | null>` and `stream$: Observable<ChatState | null>` expose live state. Actions: `send(text)`, `setInput(v)`, `stop`, `retry`, `clear`, `approve`, `deny`, `edit`, `regenerate`, `destroy`. | ||
| - Headless standalone components at parity with `@agentskit/react` (`data-ak-*` only): `ChatContainerComponent` (`<ak-chat-container>`), `MessageComponent`, `InputBarComponent`, `MarkdownComponent`, `CodeBlockComponent`, `ToolCallViewComponent`, `ThinkingIndicatorComponent`, `ToolConfirmationComponent`. | ||
| ## Ecosystem | ||
| | Package | Role | | ||
| |---------|------| | ||
| | [@agentskit/core](https://www.npmjs.com/package/@agentskit/core) | `ChatReturn` contract | | ||
| | [@agentskit/adapters](https://www.npmjs.com/package/@agentskit/adapters) | LLM providers | | ||
| | [@agentskit/tools](https://www.npmjs.com/package/@agentskit/tools) | Built-in + integration tools | | ||
| | [@agentskit/memory](https://www.npmjs.com/package/@agentskit/memory) | Chat + vector backends | | ||
| | [@agentskit/react](https://www.npmjs.com/package/@agentskit/react) · [vue](https://www.npmjs.com/package/@agentskit/vue) · [svelte](https://www.npmjs.com/package/@agentskit/svelte) · [solid](https://www.npmjs.com/package/@agentskit/solid) · [react-native](https://www.npmjs.com/package/@agentskit/react-native) · [ink](https://www.npmjs.com/package/@agentskit/ink) | Same contract, different host | | ||
| ## Contributors | ||
| <a href="https://github.com/AgentsKit-io/agentskit/graphs/contributors"> | ||
| <img src="https://contrib.rocks/image?repo=AgentsKit-io/agentskit" alt="AgentsKit contributors" /> | ||
| </a> | ||
| ## License | ||
| MIT — see [LICENSE](../../LICENSE). | ||
| ## Docs | ||
| [Full documentation](https://www.agentskit.io/docs/packages/angular) · [GitHub](https://github.com/AgentsKit-io/agentskit) |
| import * as i0 from '@angular/core'; | ||
| import { OnDestroy, WritableSignal, AfterViewInit, ElementRef } from '@angular/core'; | ||
| import { Observable } from 'rxjs'; | ||
| import { ChatState, ChatConfig, ChatReturn, ToolCall, Message } from '@agentskit/core'; | ||
| /** | ||
| * Angular service wrapping the shared `ChatController`. Exposes | ||
| * chat state both as a Signal (template-friendly) and as a | ||
| * BehaviorSubject (RxJS interop). | ||
| * | ||
| * Usage: | ||
| * @Component({ ... }) | ||
| * export class ChatPage { | ||
| * constructor(public chat: AgentskitChat) { | ||
| * chat.init({ adapter }) | ||
| * } | ||
| * } | ||
| */ | ||
| declare class AgentskitChat implements OnDestroy { | ||
| private controller?; | ||
| private unsubscribe?; | ||
| readonly state: WritableSignal<ChatState | null>; | ||
| private readonly _stream$; | ||
| readonly stream$: Observable<ChatState | null>; | ||
| init(config: ChatConfig): ChatReturn; | ||
| snapshot(): ChatReturn; | ||
| send: (text: string) => void; | ||
| stop: () => void; | ||
| retry: () => void; | ||
| setInput: (value: string) => void; | ||
| clear: () => void; | ||
| proposeToolCall: (proposal: Parameters<ChatReturn["proposeToolCall"]>[0]) => Promise<ToolCall>; | ||
| approve: (id: string) => void; | ||
| deny: (id: string) => void; | ||
| destroy(): void; | ||
| ngOnDestroy(): void; | ||
| private requireController; | ||
| static ɵfac: i0.ɵɵFactoryDeclaration<AgentskitChat, never>; | ||
| static ɵprov: i0.ɵɵInjectableDeclaration<AgentskitChat>; | ||
| } | ||
| /** | ||
| * Headless Angular chat components mirroring `@agentskit/react`'s set. Each | ||
| * renders `data-ak-*` attributes only — bring your own CSS. Standalone + | ||
| * JIT-friendly (inline templates); pairs with the `AgentskitChat` service. | ||
| */ | ||
| declare class ChatContainerComponent implements AfterViewInit, OnDestroy { | ||
| scrollRef: ElementRef<HTMLDivElement>; | ||
| private observer?; | ||
| ngAfterViewInit(): void; | ||
| ngOnDestroy(): void; | ||
| static ɵfac: i0.ɵɵFactoryDeclaration<ChatContainerComponent, never>; | ||
| static ɵcmp: i0.ɵɵComponentDeclaration<ChatContainerComponent, "ak-chat-container", never, {}, {}, never, ["*"], true, never>; | ||
| } | ||
| declare class MessageComponent { | ||
| message: Message; | ||
| static ɵfac: i0.ɵɵFactoryDeclaration<MessageComponent, never>; | ||
| static ɵcmp: i0.ɵɵComponentDeclaration<MessageComponent, "ak-message", never, { "message": { "alias": "message"; "required": true; }; }, {}, never, never, true, never>; | ||
| } | ||
| declare class InputBarComponent { | ||
| chat: ChatReturn; | ||
| placeholder: string; | ||
| disabled: boolean; | ||
| onSubmit(e: Event): void; | ||
| onEnter(e: Event): void; | ||
| private submit; | ||
| static ɵfac: i0.ɵɵFactoryDeclaration<InputBarComponent, never>; | ||
| static ɵcmp: i0.ɵɵComponentDeclaration<InputBarComponent, "ak-input-bar", never, { "chat": { "alias": "chat"; "required": true; }; "placeholder": { "alias": "placeholder"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; }, {}, never, never, true, never>; | ||
| } | ||
| declare class MarkdownComponent { | ||
| content: string; | ||
| streaming: boolean; | ||
| static ɵfac: i0.ɵɵFactoryDeclaration<MarkdownComponent, never>; | ||
| static ɵcmp: i0.ɵɵComponentDeclaration<MarkdownComponent, "ak-markdown", never, { "content": { "alias": "content"; "required": true; }; "streaming": { "alias": "streaming"; "required": false; }; }, {}, never, never, true, never>; | ||
| } | ||
| declare class CodeBlockComponent { | ||
| code: string; | ||
| language?: string; | ||
| copyable: boolean; | ||
| copy(): void; | ||
| static ɵfac: i0.ɵɵFactoryDeclaration<CodeBlockComponent, never>; | ||
| static ɵcmp: i0.ɵɵComponentDeclaration<CodeBlockComponent, "ak-code-block", never, { "code": { "alias": "code"; "required": true; }; "language": { "alias": "language"; "required": false; }; "copyable": { "alias": "copyable"; "required": false; }; }, {}, never, never, true, never>; | ||
| } | ||
| declare class ToolCallViewComponent { | ||
| toolCall: ToolCall; | ||
| readonly expanded: i0.WritableSignal<boolean>; | ||
| get argsJson(): string; | ||
| static ɵfac: i0.ɵɵFactoryDeclaration<ToolCallViewComponent, never>; | ||
| static ɵcmp: i0.ɵɵComponentDeclaration<ToolCallViewComponent, "ak-tool-call-view", never, { "toolCall": { "alias": "toolCall"; "required": true; }; }, {}, never, never, true, never>; | ||
| } | ||
| declare class ThinkingIndicatorComponent { | ||
| visible: boolean; | ||
| label: string; | ||
| static ɵfac: i0.ɵɵFactoryDeclaration<ThinkingIndicatorComponent, never>; | ||
| static ɵcmp: i0.ɵɵComponentDeclaration<ThinkingIndicatorComponent, "ak-thinking-indicator", never, { "visible": { "alias": "visible"; "required": true; }; "label": { "alias": "label"; "required": false; }; }, {}, never, never, true, never>; | ||
| } | ||
| declare class ToolConfirmationComponent { | ||
| toolCall: ToolCall; | ||
| onApprove: (toolCallId: string) => void; | ||
| onDeny: (toolCallId: string, reason?: string) => void; | ||
| get argsJson(): string; | ||
| static ɵfac: i0.ɵɵFactoryDeclaration<ToolConfirmationComponent, never>; | ||
| static ɵcmp: i0.ɵɵComponentDeclaration<ToolConfirmationComponent, "ak-tool-confirmation", never, { "toolCall": { "alias": "toolCall"; "required": true; }; "onApprove": { "alias": "onApprove"; "required": true; }; "onDeny": { "alias": "onDeny"; "required": true; }; }, {}, never, never, true, never>; | ||
| } | ||
| export { AgentskitChat, ChatContainerComponent, CodeBlockComponent, InputBarComponent, MarkdownComponent, MessageComponent, ThinkingIndicatorComponent, ToolCallViewComponent, ToolConfirmationComponent }; | ||
| //# sourceMappingURL=agentskit-angular.d.ts.map |
| {"version":3,"file":"agentskit-angular.d.ts","sources":["../../src/chat.service.ts","../../src/components.ts"],"mappings":";;;;;AAWA;;;;;;;;;;;;AAYG;AACH,cACa,aAAc,YAAW,SAAS;;;oBAI7B,cAAc,CAAC,SAAS;AACxC;sBACkB,UAAU,CAAC,SAAS;AAEtC,iBAAa,UAAU,GAAG,UAAU;AAapC,gBAAY,UAAU;AAiBtB;;;AAQA;;AAIA,gCAA6B,UAAU,CAAC,UAAU,4BAA0B,OAAO,CAAC,QAAQ;AAE5F;AAGA;AAIA;AASA;AAIA;yCAxEW,aAAa;6CAAb,aAAa;AA4EzB;;AC1FD;;;;AAIG;AAEH,cAKa,sBAAuB,YAAW,aAAa,EAAE,SAAS;AAC9B,eAAY,UAAU,CAAC,cAAc;;AAG5E;AAYA;yCAhBW,sBAAsB;2CAAtB,sBAAsB;AAmBlC;AAED,cAWa,gBAAgB;aACUA,OAAW;yCADrC,gBAAgB;2CAAhB,gBAAgB;AAE5B;AAED,cAiBa,iBAAiB;UACM,UAAU;AACnC;AACA;AAET,gBAAY,KAAK;AAKjB,eAAW,KAAK;AAOhB;yCAjBW,iBAAiB;2CAAjB,iBAAiB;AAoB7B;AAED,cAKa,iBAAiB;AACD;AAClB;yCAFE,iBAAiB;2CAAjB,iBAAiB;AAG7B;AAED,cAUa,kBAAkB;AACF;;AAElB;AAET;yCALW,kBAAkB;2CAAlB,kBAAkB;AAQ9B;AAED,cAiBa,qBAAqB;cACM,QAAQ;uBAC7BC,EAAA,CAAA,cAAA;;yCAFN,qBAAqB;2CAArB,qBAAqB;AAOjC;AAED,cAUa,0BAA0B;AACV;AAClB;yCAFE,0BAA0B;2CAA1B,0BAA0B;AAGtC;AAED,cAqBa,yBAAyB;cACE,QAAQ;AACnB;AACA;;yCAHhB,yBAAyB;2CAAzB,yBAAyB;AAQrC;;;;","names":["MessageType","_angular_core"]} |
+10
-7
| { | ||
| "name": "@agentskit/angular", | ||
| "version": "0.4.4", | ||
| "version": "0.4.5", | ||
| "description": "Angular signals service + headless chat components for AgentsKit — streaming, tools, and memory across any LLM provider.", | ||
@@ -27,4 +27,4 @@ "keywords": [ | ||
| "sideEffects": false, | ||
| "main": "./dist/index.cjs", | ||
| "module": "./dist/index.js", | ||
| "main": "./dist/fesm2022/agentskit-angular.mjs", | ||
| "module": "./dist/fesm2022/agentskit-angular.mjs", | ||
| "types": "./dist/index.d.ts", | ||
@@ -34,4 +34,4 @@ "exports": { | ||
| "types": "./dist/index.d.ts", | ||
| "import": "./dist/index.js", | ||
| "require": "./dist/index.cjs" | ||
| "import": "./dist/fesm2022/agentskit-angular.mjs", | ||
| "default": "./dist/fesm2022/agentskit-angular.mjs" | ||
| } | ||
@@ -43,2 +43,3 @@ }, | ||
| "dependencies": { | ||
| "tslib": "^2.8.1", | ||
| "@agentskit/core": "1.12.2" | ||
@@ -53,2 +54,3 @@ }, | ||
| "@angular/compiler": "^21.2.18", | ||
| "@angular/compiler-cli": "^21.2.18", | ||
| "@angular/core": "^21.2.18", | ||
@@ -59,2 +61,3 @@ "@angular/platform-browser": "^21.2.18", | ||
| "happy-dom": "^20.10.6", | ||
| "ng-packagr": "^21.2.4", | ||
| "rxjs": "^7.8.2", | ||
@@ -85,4 +88,4 @@ "tsup": "^8.5.1", | ||
| "scripts": { | ||
| "build": "tsup", | ||
| "test": "vitest run", | ||
| "build": "ng-packagr -p ng-package.json -c tsconfig.lib.json", | ||
| "test": "pnpm build && vitest run", | ||
| "test:coverage": "vitest run --coverage", | ||
@@ -89,0 +92,0 @@ "lint": "tsc --noEmit", |
-319
| 'use strict'; | ||
| var core = require('@angular/core'); | ||
| var rxjs = require('rxjs'); | ||
| var core$1 = require('@agentskit/core'); | ||
| var __defProp = Object.defineProperty; | ||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
| var __decorateClass = (decorators, target, key, kind) => { | ||
| var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target; | ||
| for (var i = decorators.length - 1, decorator; i >= 0; i--) | ||
| if (decorator = decorators[i]) | ||
| result = (kind ? decorator(target, key, result) : decorator(result)) || result; | ||
| if (kind && result) __defProp(target, key, result); | ||
| return result; | ||
| }; | ||
| exports.AgentskitChat = class AgentskitChat { | ||
| constructor() { | ||
| this.state = core.signal(null); | ||
| this._stream$ = new rxjs.BehaviorSubject(null); | ||
| this.stream$ = this._stream$.asObservable(); | ||
| this.send = (text) => { | ||
| void this.requireController().send(text); | ||
| }; | ||
| this.stop = () => this.requireController().stop(); | ||
| this.retry = () => { | ||
| void this.requireController().retry(); | ||
| }; | ||
| this.setInput = (value) => this.requireController().setInput(value); | ||
| this.clear = () => { | ||
| void this.requireController().clear(); | ||
| }; | ||
| this.proposeToolCall = (proposal) => this.requireController().proposeToolCall(proposal); | ||
| this.approve = (id) => { | ||
| void this.requireController().approve(id); | ||
| }; | ||
| this.deny = (id) => { | ||
| void this.requireController().deny(id); | ||
| }; | ||
| } | ||
| init(config) { | ||
| if (this.controller) this.destroy(); | ||
| this.controller = core$1.createChatController(config); | ||
| const push = () => { | ||
| const current = this.controller?.getState() ?? null; | ||
| this.state.set(current); | ||
| this._stream$.next(current); | ||
| }; | ||
| push(); | ||
| this.unsubscribe = this.controller.subscribe(push); | ||
| return this.snapshot(); | ||
| } | ||
| snapshot() { | ||
| const c = this.requireController(); | ||
| return { | ||
| ...c.getState(), | ||
| send: c.send, | ||
| stop: c.stop, | ||
| retry: c.retry, | ||
| edit: c.edit, | ||
| regenerate: c.regenerate, | ||
| setInput: c.setInput, | ||
| clear: c.clear, | ||
| proposeToolCall: c.proposeToolCall, | ||
| approve: c.approve, | ||
| deny: c.deny | ||
| }; | ||
| } | ||
| destroy() { | ||
| this.unsubscribe?.(); | ||
| this.controller?.stop(); | ||
| this.unsubscribe = void 0; | ||
| this.controller = void 0; | ||
| this.state.set(null); | ||
| this._stream$.next(null); | ||
| } | ||
| ngOnDestroy() { | ||
| this.destroy(); | ||
| } | ||
| requireController() { | ||
| if (!this.controller) throw new Error("AgentskitChat.init(...) must be called first"); | ||
| return this.controller; | ||
| } | ||
| }; | ||
| exports.AgentskitChat = __decorateClass([ | ||
| core.Injectable({ providedIn: "root" }) | ||
| ], exports.AgentskitChat); | ||
| exports.ChatContainerComponent = class ChatContainerComponent { | ||
| ngAfterViewInit() { | ||
| const el = this.scrollRef?.nativeElement; | ||
| if (!el || typeof MutationObserver === "undefined") return; | ||
| const observer = new MutationObserver(() => { | ||
| el.scrollTop = el.scrollHeight; | ||
| }); | ||
| if (typeof observer.observe !== "function") return; | ||
| this.observer = observer; | ||
| observer.observe(el, { childList: true, subtree: true, characterData: true }); | ||
| } | ||
| ngOnDestroy() { | ||
| if (typeof this.observer?.disconnect === "function") this.observer.disconnect(); | ||
| } | ||
| }; | ||
| __decorateClass([ | ||
| core.ViewChild("scroll", { static: true }) | ||
| ], exports.ChatContainerComponent.prototype, "scrollRef", 2); | ||
| exports.ChatContainerComponent = __decorateClass([ | ||
| core.Component({ | ||
| selector: "ak-chat-container", | ||
| standalone: true, | ||
| template: `<div #scroll data-ak-chat-container data-testid="ak-chat-container"><ng-content /></div>` | ||
| }) | ||
| ], exports.ChatContainerComponent); | ||
| exports.MessageComponent = class MessageComponent { | ||
| }; | ||
| __decorateClass([ | ||
| core.Input({ required: true }) | ||
| ], exports.MessageComponent.prototype, "message", 2); | ||
| exports.MessageComponent = __decorateClass([ | ||
| core.Component({ | ||
| selector: "ak-message", | ||
| standalone: true, | ||
| template: `<div | ||
| data-ak-message | ||
| [attr.data-ak-role]="message.role" | ||
| [attr.data-ak-status]="message.status" | ||
| > | ||
| <div data-ak-content>{{ message.content }}</div> | ||
| </div>` | ||
| }) | ||
| ], exports.MessageComponent); | ||
| exports.InputBarComponent = class InputBarComponent { | ||
| constructor() { | ||
| this.placeholder = "Type a message..."; | ||
| this.disabled = false; | ||
| } | ||
| onSubmit(e) { | ||
| e.preventDefault(); | ||
| this.submit(); | ||
| } | ||
| onEnter(e) { | ||
| if (!e.shiftKey) { | ||
| e.preventDefault(); | ||
| this.submit(); | ||
| } | ||
| } | ||
| submit() { | ||
| if (this.chat.input.trim()) this.chat.send(this.chat.input); | ||
| } | ||
| }; | ||
| __decorateClass([ | ||
| core.Input({ required: true }) | ||
| ], exports.InputBarComponent.prototype, "chat", 2); | ||
| __decorateClass([ | ||
| core.Input() | ||
| ], exports.InputBarComponent.prototype, "placeholder", 2); | ||
| __decorateClass([ | ||
| core.Input() | ||
| ], exports.InputBarComponent.prototype, "disabled", 2); | ||
| exports.InputBarComponent = __decorateClass([ | ||
| core.Component({ | ||
| selector: "ak-input-bar", | ||
| standalone: true, | ||
| template: `<form data-ak-input-bar (submit)="onSubmit($event)"> | ||
| <textarea | ||
| role="textbox" | ||
| data-ak-input | ||
| rows="1" | ||
| [value]="chat.input" | ||
| [attr.placeholder]="placeholder" | ||
| [disabled]="disabled" | ||
| (input)="chat.setInput($any($event.target).value)" | ||
| (keydown.enter)="onEnter($event)" | ||
| ></textarea> | ||
| <button data-ak-send type="submit" [disabled]="disabled || !chat.input.trim()">Send</button> | ||
| </form>` | ||
| }) | ||
| ], exports.InputBarComponent); | ||
| exports.MarkdownComponent = class MarkdownComponent { | ||
| constructor() { | ||
| this.content = ""; | ||
| this.streaming = false; | ||
| } | ||
| }; | ||
| __decorateClass([ | ||
| core.Input({ required: true }) | ||
| ], exports.MarkdownComponent.prototype, "content", 2); | ||
| __decorateClass([ | ||
| core.Input() | ||
| ], exports.MarkdownComponent.prototype, "streaming", 2); | ||
| exports.MarkdownComponent = __decorateClass([ | ||
| core.Component({ | ||
| selector: "ak-markdown", | ||
| standalone: true, | ||
| template: `<div data-ak-markdown [attr.data-ak-streaming]="streaming ? 'true' : null">{{ content }}</div>` | ||
| }) | ||
| ], exports.MarkdownComponent); | ||
| exports.CodeBlockComponent = class CodeBlockComponent { | ||
| constructor() { | ||
| this.code = ""; | ||
| this.copyable = false; | ||
| } | ||
| copy() { | ||
| void globalThis.navigator?.clipboard?.writeText(this.code); | ||
| } | ||
| }; | ||
| __decorateClass([ | ||
| core.Input({ required: true }) | ||
| ], exports.CodeBlockComponent.prototype, "code", 2); | ||
| __decorateClass([ | ||
| core.Input() | ||
| ], exports.CodeBlockComponent.prototype, "language", 2); | ||
| __decorateClass([ | ||
| core.Input() | ||
| ], exports.CodeBlockComponent.prototype, "copyable", 2); | ||
| exports.CodeBlockComponent = __decorateClass([ | ||
| core.Component({ | ||
| selector: "ak-code-block", | ||
| standalone: true, | ||
| template: `<div data-ak-code-block [attr.data-ak-language]="language"> | ||
| <pre><code>{{ code }}</code></pre> | ||
| @if (copyable) { | ||
| <button data-ak-copy type="button" (click)="copy()">Copy</button> | ||
| } | ||
| </div>` | ||
| }) | ||
| ], exports.CodeBlockComponent); | ||
| exports.ToolCallViewComponent = class ToolCallViewComponent { | ||
| constructor() { | ||
| this.expanded = core.signal(false); | ||
| } | ||
| get argsJson() { | ||
| return JSON.stringify(this.toolCall.args, null, 2); | ||
| } | ||
| }; | ||
| __decorateClass([ | ||
| core.Input({ required: true }) | ||
| ], exports.ToolCallViewComponent.prototype, "toolCall", 2); | ||
| exports.ToolCallViewComponent = __decorateClass([ | ||
| core.Component({ | ||
| selector: "ak-tool-call-view", | ||
| standalone: true, | ||
| template: `<div data-ak-tool-call [attr.data-ak-tool-status]="toolCall.status"> | ||
| <button data-ak-tool-toggle type="button" (click)="expanded.set(!expanded())"> | ||
| {{ toolCall.name }} | ||
| </button> | ||
| @if (expanded()) { | ||
| <div data-ak-tool-details> | ||
| <pre data-ak-tool-args>{{ argsJson }}</pre> | ||
| @if (toolCall.result) { | ||
| <div data-ak-tool-result>{{ toolCall.result }}</div> | ||
| } | ||
| </div> | ||
| } | ||
| </div>` | ||
| }) | ||
| ], exports.ToolCallViewComponent); | ||
| exports.ThinkingIndicatorComponent = class ThinkingIndicatorComponent { | ||
| constructor() { | ||
| this.visible = false; | ||
| this.label = "Thinking..."; | ||
| } | ||
| }; | ||
| __decorateClass([ | ||
| core.Input({ required: true }) | ||
| ], exports.ThinkingIndicatorComponent.prototype, "visible", 2); | ||
| __decorateClass([ | ||
| core.Input() | ||
| ], exports.ThinkingIndicatorComponent.prototype, "label", 2); | ||
| exports.ThinkingIndicatorComponent = __decorateClass([ | ||
| core.Component({ | ||
| selector: "ak-thinking-indicator", | ||
| standalone: true, | ||
| template: `@if (visible) { | ||
| <div data-ak-thinking> | ||
| <span data-ak-thinking-dots><span>\u2022</span><span>\u2022</span><span>\u2022</span></span> | ||
| <span data-ak-thinking-label>{{ label }}</span> | ||
| </div> | ||
| }` | ||
| }) | ||
| ], exports.ThinkingIndicatorComponent); | ||
| exports.ToolConfirmationComponent = class ToolConfirmationComponent { | ||
| get argsJson() { | ||
| return JSON.stringify(this.toolCall.args, null, 2); | ||
| } | ||
| }; | ||
| __decorateClass([ | ||
| core.Input({ required: true }) | ||
| ], exports.ToolConfirmationComponent.prototype, "toolCall", 2); | ||
| __decorateClass([ | ||
| core.Input({ required: true }) | ||
| ], exports.ToolConfirmationComponent.prototype, "onApprove", 2); | ||
| __decorateClass([ | ||
| core.Input({ required: true }) | ||
| ], exports.ToolConfirmationComponent.prototype, "onDeny", 2); | ||
| exports.ToolConfirmationComponent = __decorateClass([ | ||
| core.Component({ | ||
| selector: "ak-tool-confirmation", | ||
| standalone: true, | ||
| template: `@if (toolCall.status === 'requires_confirmation') { | ||
| <div data-ak-tool-confirmation [attr.data-ak-tool-name]="toolCall.name"> | ||
| <div data-ak-tool-confirmation-header> | ||
| <span data-ak-tool-confirmation-name>{{ toolCall.name }}</span> | ||
| <span data-ak-tool-confirmation-status>requires confirmation</span> | ||
| </div> | ||
| <div data-ak-tool-confirmation-args>{{ argsJson }}</div> | ||
| <div data-ak-tool-confirmation-actions> | ||
| <button data-ak-tool-confirmation-approve type="button" (click)="onApprove(toolCall.id)"> | ||
| Approve | ||
| </button> | ||
| <button data-ak-tool-confirmation-deny type="button" (click)="onDeny(toolCall.id)"> | ||
| Deny | ||
| </button> | ||
| </div> | ||
| </div> | ||
| }` | ||
| }) | ||
| ], exports.ToolConfirmationComponent); | ||
| //# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
| {"version":3,"sources":["../src/chat.service.ts","../src/components.ts"],"names":["AgentskitChat","signal","BehaviorSubject","createChatController","Injectable","ChatContainerComponent","ViewChild","Component","MessageComponent","Input","InputBarComponent","MarkdownComponent","CodeBlockComponent","ToolCallViewComponent","ThinkingIndicatorComponent","ToolConfirmationComponent"],"mappings":"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","file":"index.cjs","sourcesContent":["import { Injectable, OnDestroy, signal, type WritableSignal } from '@angular/core'\nimport { BehaviorSubject, type Observable } from 'rxjs'\nimport { createChatController } from '@agentskit/core'\nimport type {\n ChatConfig,\n ChatController,\n ChatReturn,\n ChatState,\n ToolCall,\n} from '@agentskit/core'\n\n/**\n * Angular service wrapping the shared `ChatController`. Exposes\n * chat state both as a Signal (template-friendly) and as a\n * BehaviorSubject (RxJS interop).\n *\n * Usage:\n * @Component({ ... })\n * export class ChatPage {\n * constructor(public chat: AgentskitChat) {\n * chat.init({ adapter })\n * }\n * }\n */\n@Injectable({ providedIn: 'root' })\nexport class AgentskitChat implements OnDestroy {\n private controller?: ChatController\n private unsubscribe?: () => void\n\n readonly state: WritableSignal<ChatState | null> = signal(null)\n private readonly _stream$ = new BehaviorSubject<ChatState | null>(null)\n readonly stream$: Observable<ChatState | null> = this._stream$.asObservable()\n\n init(config: ChatConfig): ChatReturn {\n if (this.controller) this.destroy()\n this.controller = createChatController(config)\n const push = (): void => {\n const current = this.controller?.getState() ?? null\n this.state.set(current)\n this._stream$.next(current)\n }\n push()\n this.unsubscribe = this.controller.subscribe(push)\n return this.snapshot()\n }\n\n snapshot(): ChatReturn {\n const c = this.requireController()\n return {\n ...c.getState(),\n send: c.send,\n stop: c.stop,\n retry: c.retry,\n edit: c.edit,\n regenerate: c.regenerate,\n setInput: c.setInput,\n clear: c.clear,\n proposeToolCall: c.proposeToolCall,\n approve: c.approve,\n deny: c.deny,\n }\n }\n\n send = (text: string): void => {\n void this.requireController().send(text)\n }\n\n stop = (): void => this.requireController().stop()\n retry = (): void => {\n void this.requireController().retry()\n }\n setInput = (value: string): void => this.requireController().setInput(value)\n clear = (): void => {\n void this.requireController().clear()\n }\n proposeToolCall = (proposal: Parameters<ChatReturn['proposeToolCall']>[0]): Promise<ToolCall> =>\n this.requireController().proposeToolCall(proposal)\n approve = (id: string): void => {\n void this.requireController().approve(id)\n }\n deny = (id: string): void => {\n void this.requireController().deny(id)\n }\n\n destroy(): void {\n this.unsubscribe?.()\n this.controller?.stop()\n this.unsubscribe = undefined\n this.controller = undefined\n this.state.set(null)\n this._stream$.next(null)\n }\n\n ngOnDestroy(): void {\n this.destroy()\n }\n\n private requireController(): ChatController {\n if (!this.controller) throw new Error('AgentskitChat.init(...) must be called first')\n return this.controller\n }\n}\n","import {\n Component,\n Input,\n ViewChild,\n ElementRef,\n signal,\n type AfterViewInit,\n type OnDestroy,\n} from '@angular/core'\nimport type { Message as MessageType, ChatReturn, ToolCall } from '@agentskit/core'\n\n/**\n * Headless Angular chat components mirroring `@agentskit/react`'s set. Each\n * renders `data-ak-*` attributes only — bring your own CSS. Standalone +\n * JIT-friendly (inline templates); pairs with the `AgentskitChat` service.\n */\n\n@Component({\n selector: 'ak-chat-container',\n standalone: true,\n template: `<div #scroll data-ak-chat-container data-testid=\"ak-chat-container\"><ng-content /></div>`,\n})\nexport class ChatContainerComponent implements AfterViewInit, OnDestroy {\n @ViewChild('scroll', { static: true }) scrollRef!: ElementRef<HTMLDivElement>\n private observer?: MutationObserver\n\n ngAfterViewInit(): void {\n const el = this.scrollRef?.nativeElement\n if (!el || typeof MutationObserver === 'undefined') return\n const observer = new MutationObserver(() => {\n el.scrollTop = el.scrollHeight\n })\n // Some non-browser envs (e.g. happy-dom) expose a partial MutationObserver.\n if (typeof observer.observe !== 'function') return\n this.observer = observer\n observer.observe(el, { childList: true, subtree: true, characterData: true })\n }\n\n ngOnDestroy(): void {\n if (typeof this.observer?.disconnect === 'function') this.observer.disconnect()\n }\n}\n\n@Component({\n selector: 'ak-message',\n standalone: true,\n template: `<div\n data-ak-message\n [attr.data-ak-role]=\"message.role\"\n [attr.data-ak-status]=\"message.status\"\n >\n <div data-ak-content>{{ message.content }}</div>\n </div>`,\n})\nexport class MessageComponent {\n @Input({ required: true }) message!: MessageType\n}\n\n@Component({\n selector: 'ak-input-bar',\n standalone: true,\n template: `<form data-ak-input-bar (submit)=\"onSubmit($event)\">\n <textarea\n role=\"textbox\"\n data-ak-input\n rows=\"1\"\n [value]=\"chat.input\"\n [attr.placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n (input)=\"chat.setInput($any($event.target).value)\"\n (keydown.enter)=\"onEnter($event)\"\n ></textarea>\n <button data-ak-send type=\"submit\" [disabled]=\"disabled || !chat.input.trim()\">Send</button>\n </form>`,\n})\nexport class InputBarComponent {\n @Input({ required: true }) chat!: ChatReturn\n @Input() placeholder = 'Type a message...'\n @Input() disabled = false\n\n onSubmit(e: Event): void {\n e.preventDefault()\n this.submit()\n }\n\n onEnter(e: Event): void {\n if (!(e as KeyboardEvent).shiftKey) {\n e.preventDefault()\n this.submit()\n }\n }\n\n private submit(): void {\n if (this.chat.input.trim()) this.chat.send(this.chat.input)\n }\n}\n\n@Component({\n selector: 'ak-markdown',\n standalone: true,\n template: `<div data-ak-markdown [attr.data-ak-streaming]=\"streaming ? 'true' : null\">{{ content }}</div>`,\n})\nexport class MarkdownComponent {\n @Input({ required: true }) content = ''\n @Input() streaming = false\n}\n\n@Component({\n selector: 'ak-code-block',\n standalone: true,\n template: `<div data-ak-code-block [attr.data-ak-language]=\"language\">\n <pre><code>{{ code }}</code></pre>\n @if (copyable) {\n <button data-ak-copy type=\"button\" (click)=\"copy()\">Copy</button>\n }\n </div>`,\n})\nexport class CodeBlockComponent {\n @Input({ required: true }) code = ''\n @Input() language?: string\n @Input() copyable = false\n\n copy(): void {\n void globalThis.navigator?.clipboard?.writeText(this.code)\n }\n}\n\n@Component({\n selector: 'ak-tool-call-view',\n standalone: true,\n template: `<div data-ak-tool-call [attr.data-ak-tool-status]=\"toolCall.status\">\n <button data-ak-tool-toggle type=\"button\" (click)=\"expanded.set(!expanded())\">\n {{ toolCall.name }}\n </button>\n @if (expanded()) {\n <div data-ak-tool-details>\n <pre data-ak-tool-args>{{ argsJson }}</pre>\n @if (toolCall.result) {\n <div data-ak-tool-result>{{ toolCall.result }}</div>\n }\n </div>\n }\n </div>`,\n})\nexport class ToolCallViewComponent {\n @Input({ required: true }) toolCall!: ToolCall\n readonly expanded = signal(false)\n\n get argsJson(): string {\n return JSON.stringify(this.toolCall.args, null, 2)\n }\n}\n\n@Component({\n selector: 'ak-thinking-indicator',\n standalone: true,\n template: `@if (visible) {\n <div data-ak-thinking>\n <span data-ak-thinking-dots><span>•</span><span>•</span><span>•</span></span>\n <span data-ak-thinking-label>{{ label }}</span>\n </div>\n }`,\n})\nexport class ThinkingIndicatorComponent {\n @Input({ required: true }) visible = false\n @Input() label = 'Thinking...'\n}\n\n@Component({\n selector: 'ak-tool-confirmation',\n standalone: true,\n template: `@if (toolCall.status === 'requires_confirmation') {\n <div data-ak-tool-confirmation [attr.data-ak-tool-name]=\"toolCall.name\">\n <div data-ak-tool-confirmation-header>\n <span data-ak-tool-confirmation-name>{{ toolCall.name }}</span>\n <span data-ak-tool-confirmation-status>requires confirmation</span>\n </div>\n <div data-ak-tool-confirmation-args>{{ argsJson }}</div>\n <div data-ak-tool-confirmation-actions>\n <button data-ak-tool-confirmation-approve type=\"button\" (click)=\"onApprove(toolCall.id)\">\n Approve\n </button>\n <button data-ak-tool-confirmation-deny type=\"button\" (click)=\"onDeny(toolCall.id)\">\n Deny\n </button>\n </div>\n </div>\n }`,\n})\nexport class ToolConfirmationComponent {\n @Input({ required: true }) toolCall!: ToolCall\n @Input({ required: true }) onApprove!: (toolCallId: string) => void\n @Input({ required: true }) onDeny!: (toolCallId: string, reason?: string) => void\n\n get argsJson(): string {\n return JSON.stringify(this.toolCall.args, null, 2)\n }\n}\n"]} |
| import * as _angular_core from '@angular/core'; | ||
| import { OnDestroy, WritableSignal, AfterViewInit, ElementRef } from '@angular/core'; | ||
| import { Observable } from 'rxjs'; | ||
| import { ChatState, ChatConfig, ChatReturn, ToolCall, Message } from '@agentskit/core'; | ||
| /** | ||
| * Angular service wrapping the shared `ChatController`. Exposes | ||
| * chat state both as a Signal (template-friendly) and as a | ||
| * BehaviorSubject (RxJS interop). | ||
| * | ||
| * Usage: | ||
| * @Component({ ... }) | ||
| * export class ChatPage { | ||
| * constructor(public chat: AgentskitChat) { | ||
| * chat.init({ adapter }) | ||
| * } | ||
| * } | ||
| */ | ||
| declare class AgentskitChat implements OnDestroy { | ||
| private controller?; | ||
| private unsubscribe?; | ||
| readonly state: WritableSignal<ChatState | null>; | ||
| private readonly _stream$; | ||
| readonly stream$: Observable<ChatState | null>; | ||
| init(config: ChatConfig): ChatReturn; | ||
| snapshot(): ChatReturn; | ||
| send: (text: string) => void; | ||
| stop: () => void; | ||
| retry: () => void; | ||
| setInput: (value: string) => void; | ||
| clear: () => void; | ||
| proposeToolCall: (proposal: Parameters<ChatReturn["proposeToolCall"]>[0]) => Promise<ToolCall>; | ||
| approve: (id: string) => void; | ||
| deny: (id: string) => void; | ||
| destroy(): void; | ||
| ngOnDestroy(): void; | ||
| private requireController; | ||
| } | ||
| /** | ||
| * Headless Angular chat components mirroring `@agentskit/react`'s set. Each | ||
| * renders `data-ak-*` attributes only — bring your own CSS. Standalone + | ||
| * JIT-friendly (inline templates); pairs with the `AgentskitChat` service. | ||
| */ | ||
| declare class ChatContainerComponent implements AfterViewInit, OnDestroy { | ||
| scrollRef: ElementRef<HTMLDivElement>; | ||
| private observer?; | ||
| ngAfterViewInit(): void; | ||
| ngOnDestroy(): void; | ||
| } | ||
| declare class MessageComponent { | ||
| message: Message; | ||
| } | ||
| declare class InputBarComponent { | ||
| chat: ChatReturn; | ||
| placeholder: string; | ||
| disabled: boolean; | ||
| onSubmit(e: Event): void; | ||
| onEnter(e: Event): void; | ||
| private submit; | ||
| } | ||
| declare class MarkdownComponent { | ||
| content: string; | ||
| streaming: boolean; | ||
| } | ||
| declare class CodeBlockComponent { | ||
| code: string; | ||
| language?: string; | ||
| copyable: boolean; | ||
| copy(): void; | ||
| } | ||
| declare class ToolCallViewComponent { | ||
| toolCall: ToolCall; | ||
| readonly expanded: _angular_core.WritableSignal<boolean>; | ||
| get argsJson(): string; | ||
| } | ||
| declare class ThinkingIndicatorComponent { | ||
| visible: boolean; | ||
| label: string; | ||
| } | ||
| declare class ToolConfirmationComponent { | ||
| toolCall: ToolCall; | ||
| onApprove: (toolCallId: string) => void; | ||
| onDeny: (toolCallId: string, reason?: string) => void; | ||
| get argsJson(): string; | ||
| } | ||
| export { AgentskitChat, ChatContainerComponent, CodeBlockComponent, InputBarComponent, MarkdownComponent, MessageComponent, ThinkingIndicatorComponent, ToolCallViewComponent, ToolConfirmationComponent }; |
| import * as _angular_core from '@angular/core'; | ||
| import { OnDestroy, WritableSignal, AfterViewInit, ElementRef } from '@angular/core'; | ||
| import { Observable } from 'rxjs'; | ||
| import { ChatState, ChatConfig, ChatReturn, ToolCall, Message } from '@agentskit/core'; | ||
| /** | ||
| * Angular service wrapping the shared `ChatController`. Exposes | ||
| * chat state both as a Signal (template-friendly) and as a | ||
| * BehaviorSubject (RxJS interop). | ||
| * | ||
| * Usage: | ||
| * @Component({ ... }) | ||
| * export class ChatPage { | ||
| * constructor(public chat: AgentskitChat) { | ||
| * chat.init({ adapter }) | ||
| * } | ||
| * } | ||
| */ | ||
| declare class AgentskitChat implements OnDestroy { | ||
| private controller?; | ||
| private unsubscribe?; | ||
| readonly state: WritableSignal<ChatState | null>; | ||
| private readonly _stream$; | ||
| readonly stream$: Observable<ChatState | null>; | ||
| init(config: ChatConfig): ChatReturn; | ||
| snapshot(): ChatReturn; | ||
| send: (text: string) => void; | ||
| stop: () => void; | ||
| retry: () => void; | ||
| setInput: (value: string) => void; | ||
| clear: () => void; | ||
| proposeToolCall: (proposal: Parameters<ChatReturn["proposeToolCall"]>[0]) => Promise<ToolCall>; | ||
| approve: (id: string) => void; | ||
| deny: (id: string) => void; | ||
| destroy(): void; | ||
| ngOnDestroy(): void; | ||
| private requireController; | ||
| } | ||
| /** | ||
| * Headless Angular chat components mirroring `@agentskit/react`'s set. Each | ||
| * renders `data-ak-*` attributes only — bring your own CSS. Standalone + | ||
| * JIT-friendly (inline templates); pairs with the `AgentskitChat` service. | ||
| */ | ||
| declare class ChatContainerComponent implements AfterViewInit, OnDestroy { | ||
| scrollRef: ElementRef<HTMLDivElement>; | ||
| private observer?; | ||
| ngAfterViewInit(): void; | ||
| ngOnDestroy(): void; | ||
| } | ||
| declare class MessageComponent { | ||
| message: Message; | ||
| } | ||
| declare class InputBarComponent { | ||
| chat: ChatReturn; | ||
| placeholder: string; | ||
| disabled: boolean; | ||
| onSubmit(e: Event): void; | ||
| onEnter(e: Event): void; | ||
| private submit; | ||
| } | ||
| declare class MarkdownComponent { | ||
| content: string; | ||
| streaming: boolean; | ||
| } | ||
| declare class CodeBlockComponent { | ||
| code: string; | ||
| language?: string; | ||
| copyable: boolean; | ||
| copy(): void; | ||
| } | ||
| declare class ToolCallViewComponent { | ||
| toolCall: ToolCall; | ||
| readonly expanded: _angular_core.WritableSignal<boolean>; | ||
| get argsJson(): string; | ||
| } | ||
| declare class ThinkingIndicatorComponent { | ||
| visible: boolean; | ||
| label: string; | ||
| } | ||
| declare class ToolConfirmationComponent { | ||
| toolCall: ToolCall; | ||
| onApprove: (toolCallId: string) => void; | ||
| onDeny: (toolCallId: string, reason?: string) => void; | ||
| get argsJson(): string; | ||
| } | ||
| export { AgentskitChat, ChatContainerComponent, CodeBlockComponent, InputBarComponent, MarkdownComponent, MessageComponent, ThinkingIndicatorComponent, ToolCallViewComponent, ToolConfirmationComponent }; |
-319
| import { Injectable, ViewChild, Component, Input, signal } from '@angular/core'; | ||
| import { BehaviorSubject } from 'rxjs'; | ||
| import { createChatController } from '@agentskit/core'; | ||
| var __defProp = Object.defineProperty; | ||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
| var __decorateClass = (decorators, target, key, kind) => { | ||
| var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target; | ||
| for (var i = decorators.length - 1, decorator; i >= 0; i--) | ||
| if (decorator = decorators[i]) | ||
| result = (kind ? decorator(target, key, result) : decorator(result)) || result; | ||
| if (kind && result) __defProp(target, key, result); | ||
| return result; | ||
| }; | ||
| var AgentskitChat = class { | ||
| constructor() { | ||
| this.state = signal(null); | ||
| this._stream$ = new BehaviorSubject(null); | ||
| this.stream$ = this._stream$.asObservable(); | ||
| this.send = (text) => { | ||
| void this.requireController().send(text); | ||
| }; | ||
| this.stop = () => this.requireController().stop(); | ||
| this.retry = () => { | ||
| void this.requireController().retry(); | ||
| }; | ||
| this.setInput = (value) => this.requireController().setInput(value); | ||
| this.clear = () => { | ||
| void this.requireController().clear(); | ||
| }; | ||
| this.proposeToolCall = (proposal) => this.requireController().proposeToolCall(proposal); | ||
| this.approve = (id) => { | ||
| void this.requireController().approve(id); | ||
| }; | ||
| this.deny = (id) => { | ||
| void this.requireController().deny(id); | ||
| }; | ||
| } | ||
| init(config) { | ||
| if (this.controller) this.destroy(); | ||
| this.controller = createChatController(config); | ||
| const push = () => { | ||
| const current = this.controller?.getState() ?? null; | ||
| this.state.set(current); | ||
| this._stream$.next(current); | ||
| }; | ||
| push(); | ||
| this.unsubscribe = this.controller.subscribe(push); | ||
| return this.snapshot(); | ||
| } | ||
| snapshot() { | ||
| const c = this.requireController(); | ||
| return { | ||
| ...c.getState(), | ||
| send: c.send, | ||
| stop: c.stop, | ||
| retry: c.retry, | ||
| edit: c.edit, | ||
| regenerate: c.regenerate, | ||
| setInput: c.setInput, | ||
| clear: c.clear, | ||
| proposeToolCall: c.proposeToolCall, | ||
| approve: c.approve, | ||
| deny: c.deny | ||
| }; | ||
| } | ||
| destroy() { | ||
| this.unsubscribe?.(); | ||
| this.controller?.stop(); | ||
| this.unsubscribe = void 0; | ||
| this.controller = void 0; | ||
| this.state.set(null); | ||
| this._stream$.next(null); | ||
| } | ||
| ngOnDestroy() { | ||
| this.destroy(); | ||
| } | ||
| requireController() { | ||
| if (!this.controller) throw new Error("AgentskitChat.init(...) must be called first"); | ||
| return this.controller; | ||
| } | ||
| }; | ||
| AgentskitChat = __decorateClass([ | ||
| Injectable({ providedIn: "root" }) | ||
| ], AgentskitChat); | ||
| var ChatContainerComponent = class { | ||
| ngAfterViewInit() { | ||
| const el = this.scrollRef?.nativeElement; | ||
| if (!el || typeof MutationObserver === "undefined") return; | ||
| const observer = new MutationObserver(() => { | ||
| el.scrollTop = el.scrollHeight; | ||
| }); | ||
| if (typeof observer.observe !== "function") return; | ||
| this.observer = observer; | ||
| observer.observe(el, { childList: true, subtree: true, characterData: true }); | ||
| } | ||
| ngOnDestroy() { | ||
| if (typeof this.observer?.disconnect === "function") this.observer.disconnect(); | ||
| } | ||
| }; | ||
| __decorateClass([ | ||
| ViewChild("scroll", { static: true }) | ||
| ], ChatContainerComponent.prototype, "scrollRef", 2); | ||
| ChatContainerComponent = __decorateClass([ | ||
| Component({ | ||
| selector: "ak-chat-container", | ||
| standalone: true, | ||
| template: `<div #scroll data-ak-chat-container data-testid="ak-chat-container"><ng-content /></div>` | ||
| }) | ||
| ], ChatContainerComponent); | ||
| var MessageComponent = class { | ||
| }; | ||
| __decorateClass([ | ||
| Input({ required: true }) | ||
| ], MessageComponent.prototype, "message", 2); | ||
| MessageComponent = __decorateClass([ | ||
| Component({ | ||
| selector: "ak-message", | ||
| standalone: true, | ||
| template: `<div | ||
| data-ak-message | ||
| [attr.data-ak-role]="message.role" | ||
| [attr.data-ak-status]="message.status" | ||
| > | ||
| <div data-ak-content>{{ message.content }}</div> | ||
| </div>` | ||
| }) | ||
| ], MessageComponent); | ||
| var InputBarComponent = class { | ||
| constructor() { | ||
| this.placeholder = "Type a message..."; | ||
| this.disabled = false; | ||
| } | ||
| onSubmit(e) { | ||
| e.preventDefault(); | ||
| this.submit(); | ||
| } | ||
| onEnter(e) { | ||
| if (!e.shiftKey) { | ||
| e.preventDefault(); | ||
| this.submit(); | ||
| } | ||
| } | ||
| submit() { | ||
| if (this.chat.input.trim()) this.chat.send(this.chat.input); | ||
| } | ||
| }; | ||
| __decorateClass([ | ||
| Input({ required: true }) | ||
| ], InputBarComponent.prototype, "chat", 2); | ||
| __decorateClass([ | ||
| Input() | ||
| ], InputBarComponent.prototype, "placeholder", 2); | ||
| __decorateClass([ | ||
| Input() | ||
| ], InputBarComponent.prototype, "disabled", 2); | ||
| InputBarComponent = __decorateClass([ | ||
| Component({ | ||
| selector: "ak-input-bar", | ||
| standalone: true, | ||
| template: `<form data-ak-input-bar (submit)="onSubmit($event)"> | ||
| <textarea | ||
| role="textbox" | ||
| data-ak-input | ||
| rows="1" | ||
| [value]="chat.input" | ||
| [attr.placeholder]="placeholder" | ||
| [disabled]="disabled" | ||
| (input)="chat.setInput($any($event.target).value)" | ||
| (keydown.enter)="onEnter($event)" | ||
| ></textarea> | ||
| <button data-ak-send type="submit" [disabled]="disabled || !chat.input.trim()">Send</button> | ||
| </form>` | ||
| }) | ||
| ], InputBarComponent); | ||
| var MarkdownComponent = class { | ||
| constructor() { | ||
| this.content = ""; | ||
| this.streaming = false; | ||
| } | ||
| }; | ||
| __decorateClass([ | ||
| Input({ required: true }) | ||
| ], MarkdownComponent.prototype, "content", 2); | ||
| __decorateClass([ | ||
| Input() | ||
| ], MarkdownComponent.prototype, "streaming", 2); | ||
| MarkdownComponent = __decorateClass([ | ||
| Component({ | ||
| selector: "ak-markdown", | ||
| standalone: true, | ||
| template: `<div data-ak-markdown [attr.data-ak-streaming]="streaming ? 'true' : null">{{ content }}</div>` | ||
| }) | ||
| ], MarkdownComponent); | ||
| var CodeBlockComponent = class { | ||
| constructor() { | ||
| this.code = ""; | ||
| this.copyable = false; | ||
| } | ||
| copy() { | ||
| void globalThis.navigator?.clipboard?.writeText(this.code); | ||
| } | ||
| }; | ||
| __decorateClass([ | ||
| Input({ required: true }) | ||
| ], CodeBlockComponent.prototype, "code", 2); | ||
| __decorateClass([ | ||
| Input() | ||
| ], CodeBlockComponent.prototype, "language", 2); | ||
| __decorateClass([ | ||
| Input() | ||
| ], CodeBlockComponent.prototype, "copyable", 2); | ||
| CodeBlockComponent = __decorateClass([ | ||
| Component({ | ||
| selector: "ak-code-block", | ||
| standalone: true, | ||
| template: `<div data-ak-code-block [attr.data-ak-language]="language"> | ||
| <pre><code>{{ code }}</code></pre> | ||
| @if (copyable) { | ||
| <button data-ak-copy type="button" (click)="copy()">Copy</button> | ||
| } | ||
| </div>` | ||
| }) | ||
| ], CodeBlockComponent); | ||
| var ToolCallViewComponent = class { | ||
| constructor() { | ||
| this.expanded = signal(false); | ||
| } | ||
| get argsJson() { | ||
| return JSON.stringify(this.toolCall.args, null, 2); | ||
| } | ||
| }; | ||
| __decorateClass([ | ||
| Input({ required: true }) | ||
| ], ToolCallViewComponent.prototype, "toolCall", 2); | ||
| ToolCallViewComponent = __decorateClass([ | ||
| Component({ | ||
| selector: "ak-tool-call-view", | ||
| standalone: true, | ||
| template: `<div data-ak-tool-call [attr.data-ak-tool-status]="toolCall.status"> | ||
| <button data-ak-tool-toggle type="button" (click)="expanded.set(!expanded())"> | ||
| {{ toolCall.name }} | ||
| </button> | ||
| @if (expanded()) { | ||
| <div data-ak-tool-details> | ||
| <pre data-ak-tool-args>{{ argsJson }}</pre> | ||
| @if (toolCall.result) { | ||
| <div data-ak-tool-result>{{ toolCall.result }}</div> | ||
| } | ||
| </div> | ||
| } | ||
| </div>` | ||
| }) | ||
| ], ToolCallViewComponent); | ||
| var ThinkingIndicatorComponent = class { | ||
| constructor() { | ||
| this.visible = false; | ||
| this.label = "Thinking..."; | ||
| } | ||
| }; | ||
| __decorateClass([ | ||
| Input({ required: true }) | ||
| ], ThinkingIndicatorComponent.prototype, "visible", 2); | ||
| __decorateClass([ | ||
| Input() | ||
| ], ThinkingIndicatorComponent.prototype, "label", 2); | ||
| ThinkingIndicatorComponent = __decorateClass([ | ||
| Component({ | ||
| selector: "ak-thinking-indicator", | ||
| standalone: true, | ||
| template: `@if (visible) { | ||
| <div data-ak-thinking> | ||
| <span data-ak-thinking-dots><span>\u2022</span><span>\u2022</span><span>\u2022</span></span> | ||
| <span data-ak-thinking-label>{{ label }}</span> | ||
| </div> | ||
| }` | ||
| }) | ||
| ], ThinkingIndicatorComponent); | ||
| var ToolConfirmationComponent = class { | ||
| get argsJson() { | ||
| return JSON.stringify(this.toolCall.args, null, 2); | ||
| } | ||
| }; | ||
| __decorateClass([ | ||
| Input({ required: true }) | ||
| ], ToolConfirmationComponent.prototype, "toolCall", 2); | ||
| __decorateClass([ | ||
| Input({ required: true }) | ||
| ], ToolConfirmationComponent.prototype, "onApprove", 2); | ||
| __decorateClass([ | ||
| Input({ required: true }) | ||
| ], ToolConfirmationComponent.prototype, "onDeny", 2); | ||
| ToolConfirmationComponent = __decorateClass([ | ||
| Component({ | ||
| selector: "ak-tool-confirmation", | ||
| standalone: true, | ||
| template: `@if (toolCall.status === 'requires_confirmation') { | ||
| <div data-ak-tool-confirmation [attr.data-ak-tool-name]="toolCall.name"> | ||
| <div data-ak-tool-confirmation-header> | ||
| <span data-ak-tool-confirmation-name>{{ toolCall.name }}</span> | ||
| <span data-ak-tool-confirmation-status>requires confirmation</span> | ||
| </div> | ||
| <div data-ak-tool-confirmation-args>{{ argsJson }}</div> | ||
| <div data-ak-tool-confirmation-actions> | ||
| <button data-ak-tool-confirmation-approve type="button" (click)="onApprove(toolCall.id)"> | ||
| Approve | ||
| </button> | ||
| <button data-ak-tool-confirmation-deny type="button" (click)="onDeny(toolCall.id)"> | ||
| Deny | ||
| </button> | ||
| </div> | ||
| </div> | ||
| }` | ||
| }) | ||
| ], ToolConfirmationComponent); | ||
| export { AgentskitChat, ChatContainerComponent, CodeBlockComponent, InputBarComponent, MarkdownComponent, MessageComponent, ThinkingIndicatorComponent, ToolCallViewComponent, ToolConfirmationComponent }; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
| {"version":3,"sources":["../src/chat.service.ts","../src/components.ts"],"names":["signal"],"mappings":"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","file":"index.js","sourcesContent":["import { Injectable, OnDestroy, signal, type WritableSignal } from '@angular/core'\nimport { BehaviorSubject, type Observable } from 'rxjs'\nimport { createChatController } from '@agentskit/core'\nimport type {\n ChatConfig,\n ChatController,\n ChatReturn,\n ChatState,\n ToolCall,\n} from '@agentskit/core'\n\n/**\n * Angular service wrapping the shared `ChatController`. Exposes\n * chat state both as a Signal (template-friendly) and as a\n * BehaviorSubject (RxJS interop).\n *\n * Usage:\n * @Component({ ... })\n * export class ChatPage {\n * constructor(public chat: AgentskitChat) {\n * chat.init({ adapter })\n * }\n * }\n */\n@Injectable({ providedIn: 'root' })\nexport class AgentskitChat implements OnDestroy {\n private controller?: ChatController\n private unsubscribe?: () => void\n\n readonly state: WritableSignal<ChatState | null> = signal(null)\n private readonly _stream$ = new BehaviorSubject<ChatState | null>(null)\n readonly stream$: Observable<ChatState | null> = this._stream$.asObservable()\n\n init(config: ChatConfig): ChatReturn {\n if (this.controller) this.destroy()\n this.controller = createChatController(config)\n const push = (): void => {\n const current = this.controller?.getState() ?? null\n this.state.set(current)\n this._stream$.next(current)\n }\n push()\n this.unsubscribe = this.controller.subscribe(push)\n return this.snapshot()\n }\n\n snapshot(): ChatReturn {\n const c = this.requireController()\n return {\n ...c.getState(),\n send: c.send,\n stop: c.stop,\n retry: c.retry,\n edit: c.edit,\n regenerate: c.regenerate,\n setInput: c.setInput,\n clear: c.clear,\n proposeToolCall: c.proposeToolCall,\n approve: c.approve,\n deny: c.deny,\n }\n }\n\n send = (text: string): void => {\n void this.requireController().send(text)\n }\n\n stop = (): void => this.requireController().stop()\n retry = (): void => {\n void this.requireController().retry()\n }\n setInput = (value: string): void => this.requireController().setInput(value)\n clear = (): void => {\n void this.requireController().clear()\n }\n proposeToolCall = (proposal: Parameters<ChatReturn['proposeToolCall']>[0]): Promise<ToolCall> =>\n this.requireController().proposeToolCall(proposal)\n approve = (id: string): void => {\n void this.requireController().approve(id)\n }\n deny = (id: string): void => {\n void this.requireController().deny(id)\n }\n\n destroy(): void {\n this.unsubscribe?.()\n this.controller?.stop()\n this.unsubscribe = undefined\n this.controller = undefined\n this.state.set(null)\n this._stream$.next(null)\n }\n\n ngOnDestroy(): void {\n this.destroy()\n }\n\n private requireController(): ChatController {\n if (!this.controller) throw new Error('AgentskitChat.init(...) must be called first')\n return this.controller\n }\n}\n","import {\n Component,\n Input,\n ViewChild,\n ElementRef,\n signal,\n type AfterViewInit,\n type OnDestroy,\n} from '@angular/core'\nimport type { Message as MessageType, ChatReturn, ToolCall } from '@agentskit/core'\n\n/**\n * Headless Angular chat components mirroring `@agentskit/react`'s set. Each\n * renders `data-ak-*` attributes only — bring your own CSS. Standalone +\n * JIT-friendly (inline templates); pairs with the `AgentskitChat` service.\n */\n\n@Component({\n selector: 'ak-chat-container',\n standalone: true,\n template: `<div #scroll data-ak-chat-container data-testid=\"ak-chat-container\"><ng-content /></div>`,\n})\nexport class ChatContainerComponent implements AfterViewInit, OnDestroy {\n @ViewChild('scroll', { static: true }) scrollRef!: ElementRef<HTMLDivElement>\n private observer?: MutationObserver\n\n ngAfterViewInit(): void {\n const el = this.scrollRef?.nativeElement\n if (!el || typeof MutationObserver === 'undefined') return\n const observer = new MutationObserver(() => {\n el.scrollTop = el.scrollHeight\n })\n // Some non-browser envs (e.g. happy-dom) expose a partial MutationObserver.\n if (typeof observer.observe !== 'function') return\n this.observer = observer\n observer.observe(el, { childList: true, subtree: true, characterData: true })\n }\n\n ngOnDestroy(): void {\n if (typeof this.observer?.disconnect === 'function') this.observer.disconnect()\n }\n}\n\n@Component({\n selector: 'ak-message',\n standalone: true,\n template: `<div\n data-ak-message\n [attr.data-ak-role]=\"message.role\"\n [attr.data-ak-status]=\"message.status\"\n >\n <div data-ak-content>{{ message.content }}</div>\n </div>`,\n})\nexport class MessageComponent {\n @Input({ required: true }) message!: MessageType\n}\n\n@Component({\n selector: 'ak-input-bar',\n standalone: true,\n template: `<form data-ak-input-bar (submit)=\"onSubmit($event)\">\n <textarea\n role=\"textbox\"\n data-ak-input\n rows=\"1\"\n [value]=\"chat.input\"\n [attr.placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n (input)=\"chat.setInput($any($event.target).value)\"\n (keydown.enter)=\"onEnter($event)\"\n ></textarea>\n <button data-ak-send type=\"submit\" [disabled]=\"disabled || !chat.input.trim()\">Send</button>\n </form>`,\n})\nexport class InputBarComponent {\n @Input({ required: true }) chat!: ChatReturn\n @Input() placeholder = 'Type a message...'\n @Input() disabled = false\n\n onSubmit(e: Event): void {\n e.preventDefault()\n this.submit()\n }\n\n onEnter(e: Event): void {\n if (!(e as KeyboardEvent).shiftKey) {\n e.preventDefault()\n this.submit()\n }\n }\n\n private submit(): void {\n if (this.chat.input.trim()) this.chat.send(this.chat.input)\n }\n}\n\n@Component({\n selector: 'ak-markdown',\n standalone: true,\n template: `<div data-ak-markdown [attr.data-ak-streaming]=\"streaming ? 'true' : null\">{{ content }}</div>`,\n})\nexport class MarkdownComponent {\n @Input({ required: true }) content = ''\n @Input() streaming = false\n}\n\n@Component({\n selector: 'ak-code-block',\n standalone: true,\n template: `<div data-ak-code-block [attr.data-ak-language]=\"language\">\n <pre><code>{{ code }}</code></pre>\n @if (copyable) {\n <button data-ak-copy type=\"button\" (click)=\"copy()\">Copy</button>\n }\n </div>`,\n})\nexport class CodeBlockComponent {\n @Input({ required: true }) code = ''\n @Input() language?: string\n @Input() copyable = false\n\n copy(): void {\n void globalThis.navigator?.clipboard?.writeText(this.code)\n }\n}\n\n@Component({\n selector: 'ak-tool-call-view',\n standalone: true,\n template: `<div data-ak-tool-call [attr.data-ak-tool-status]=\"toolCall.status\">\n <button data-ak-tool-toggle type=\"button\" (click)=\"expanded.set(!expanded())\">\n {{ toolCall.name }}\n </button>\n @if (expanded()) {\n <div data-ak-tool-details>\n <pre data-ak-tool-args>{{ argsJson }}</pre>\n @if (toolCall.result) {\n <div data-ak-tool-result>{{ toolCall.result }}</div>\n }\n </div>\n }\n </div>`,\n})\nexport class ToolCallViewComponent {\n @Input({ required: true }) toolCall!: ToolCall\n readonly expanded = signal(false)\n\n get argsJson(): string {\n return JSON.stringify(this.toolCall.args, null, 2)\n }\n}\n\n@Component({\n selector: 'ak-thinking-indicator',\n standalone: true,\n template: `@if (visible) {\n <div data-ak-thinking>\n <span data-ak-thinking-dots><span>•</span><span>•</span><span>•</span></span>\n <span data-ak-thinking-label>{{ label }}</span>\n </div>\n }`,\n})\nexport class ThinkingIndicatorComponent {\n @Input({ required: true }) visible = false\n @Input() label = 'Thinking...'\n}\n\n@Component({\n selector: 'ak-tool-confirmation',\n standalone: true,\n template: `@if (toolCall.status === 'requires_confirmation') {\n <div data-ak-tool-confirmation [attr.data-ak-tool-name]=\"toolCall.name\">\n <div data-ak-tool-confirmation-header>\n <span data-ak-tool-confirmation-name>{{ toolCall.name }}</span>\n <span data-ak-tool-confirmation-status>requires confirmation</span>\n </div>\n <div data-ak-tool-confirmation-args>{{ argsJson }}</div>\n <div data-ak-tool-confirmation-actions>\n <button data-ak-tool-confirmation-approve type=\"button\" (click)=\"onApprove(toolCall.id)\">\n Approve\n </button>\n <button data-ak-tool-confirmation-deny type=\"button\" (click)=\"onDeny(toolCall.id)\">\n Deny\n </button>\n </div>\n </div>\n }`,\n})\nexport class ToolConfirmationComponent {\n @Input({ required: true }) toolCall!: ToolCall\n @Input({ required: true }) onApprove!: (toolCallId: string) => void\n @Input({ required: true }) onDeny!: (toolCallId: string, reason?: string) => void\n\n get argsJson(): string {\n return JSON.stringify(this.toolCall.args, null, 2)\n }\n}\n"]} |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
58981
-14.06%4
33.33%14
16.67%8
-11.11%523
-27.06%1
Infinity%+ Added