🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@agentskit/angular

Package Overview
Dependencies
Maintainers
1
Versions
25
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@agentskit/angular - npm Package Compare versions

Comparing version
0.4.4
to
0.4.5
+416
dist/fesm2022/agentskit-angular.mjs
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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"}
# @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.
[![npm version](https://img.shields.io/npm/v/@agentskit/angular?color=blue)](https://www.npmjs.com/package/@agentskit/angular)
[![npm downloads](https://img.shields.io/npm/dm/@agentskit/angular)](https://www.npmjs.com/package/@agentskit/angular)
[![bundle size](https://img.shields.io/bundlejs/size/@agentskit/angular?label=bundle)](https://bundlejs.com/?q=@agentskit/angular)
[![license](https://img.shields.io/badge/license-MIT-blue.svg)](../../LICENSE)
[![stability](https://img.shields.io/badge/stability-beta-yellow)](../../docs/STABILITY.md)
[![GitHub stars](https://img.shields.io/github/stars/AgentsKit-io/agentskit?style=social)](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",

'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 };
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"]}