@aparte/angular 0.23.0 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -9
- package/dist/README.md +12 -9
- package/dist/fesm2022/aparte-angular.mjs +298 -132
- package/dist/fesm2022/aparte-angular.mjs.map +1 -1
- package/dist/generated/element.directives.d.ts +4 -2
- package/dist/index.d.ts +3 -1
- package/dist/lib/aparte-bubble.directive.d.ts +27 -0
- package/dist/lib/aparte-chat.component.d.ts +58 -51
- package/dist/lib/aparte-tool-ui.directive.d.ts +63 -0
- package/dist/lib/aparte-ui.component.d.ts +7 -0
- package/package.json +8 -7
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* a plain host listener when you need `stopPropagation`.
|
|
12
12
|
*/
|
|
13
13
|
import { ElementRef, EventEmitter } from '@angular/core';
|
|
14
|
-
import type { AparteActionClickEventDetail, AparteActionEventDetail, AparteAttachmentPreviewEventDetail, AparteBranchNavigateEventDetail, AparteCompactEventDetail, AparteComposerChangeEventDetail, AparteContextThresholdEventDetail, AparteConversationArchiveDetail, AparteConversationDeleteDetail, AparteConversationPinDetail, AparteConversationRenameDetail, AparteConversationSelectDetail, AparteEditEventDetail, AparteFeedbackEventDetail, AparteLinkClickEventDetail, AparteMessageInfoEventDetail, AparteOptgroupToggleEventDetail, ApartePathChangedEventDetail, AparteRetryEventDetail, AparteScrollRailJumpDetail, AparteSegmentUpdateEventDetail, AparteSelectChangeDetail, AparteSendEventDetail, AparteSidebarToggleDetail, AparteSplitResizeDetail, AparteSuggestionEventDetail } from '@aparte/core';
|
|
14
|
+
import type { AparteActionClickEventDetail, AparteActionEventDetail, AparteAttachmentPreviewEventDetail, AparteBranchNavigateEventDetail, AparteCompactEventDetail, AparteComposerChangeEventDetail, AparteContextThresholdEventDetail, AparteConversationArchiveDetail, AparteConversationDeleteDetail, AparteConversationListItem, AparteConversationPinDetail, AparteConversationRenameDetail, AparteConversationSelectDetail, AparteEditEventDetail, AparteFeedbackEventDetail, AparteLinkClickEventDetail, AparteMessageInfoEventDetail, AparteOptgroupToggleEventDetail, ApartePathChangedEventDetail, AparteRetryEventDetail, AparteScrollRailJumpDetail, AparteSegmentUpdateEventDetail, AparteSelectChangeDetail, AparteSendEventDetail, AparteSidebarToggleDetail, AparteSplitResizeDetail, AparteSuggestionEventDetail } from '@aparte/core';
|
|
15
15
|
import * as i0 from "@angular/core";
|
|
16
16
|
/**
|
|
17
17
|
* Writes one declared attribute onto the host element.
|
|
@@ -275,6 +275,8 @@ export declare class AparteConversationListDirective extends AparteElementBase {
|
|
|
275
275
|
set loading(v: boolean);
|
|
276
276
|
/** Let the list finish the gesture: rename, pin, unpin, archive, unarchive and delete are performed on the conversation manager registered with `setConversationManager()`, instead of leaving you six listeners to write. The event still fires first, and `preventDefault()` on it takes the gesture back. Off by default, and selecting stays yours either way. */
|
|
277
277
|
set manage(v: boolean);
|
|
278
|
+
/** Set the list of conversations to display. Triggers a re-render. */
|
|
279
|
+
set conversations(v: AparteConversationListItem[] | undefined);
|
|
278
280
|
/** A row's title was activated; the host loads that conversation. */
|
|
279
281
|
readonly conversationSelect: EventEmitter<AparteConversationSelectDetail>;
|
|
280
282
|
/** A rename was committed with a new, non-empty title. Cancelable: `preventDefault()` takes the gesture back from `manage`. Angular: this Output emits the detail, so preventDefault() is not on it — bind the DOM event for that: (aparte-conversation-rename)="$event.preventDefault()". */
|
|
@@ -297,7 +299,7 @@ export declare class AparteConversationListDirective extends AparteElementBase {
|
|
|
297
299
|
protected onConversationUnarchive(e: CustomEvent<AparteConversationArchiveDetail>): void;
|
|
298
300
|
protected onConversationDelete(e: CustomEvent<AparteConversationDeleteDetail>): void;
|
|
299
301
|
static ɵfac: i0.ɵɵFactoryDeclaration<AparteConversationListDirective, never>;
|
|
300
|
-
static ɵdir: i0.ɵɵDirectiveDeclaration<AparteConversationListDirective, "aparte-conversation-list", never, { "activeId": { "alias": "activeId"; "required": false; }; "flat": { "alias": "flat"; "required": false; }; "loading": { "alias": "loading"; "required": false; }; "manage": { "alias": "manage"; "required": false; }; }, { "conversationSelect": "conversationSelect"; "conversationRename": "conversationRename"; "conversationPin": "conversationPin"; "conversationUnpin": "conversationUnpin"; "conversationArchive": "conversationArchive"; "conversationUnarchive": "conversationUnarchive"; "conversationDelete": "conversationDelete"; }, never, never, true, never>;
|
|
302
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<AparteConversationListDirective, "aparte-conversation-list", never, { "activeId": { "alias": "activeId"; "required": false; }; "flat": { "alias": "flat"; "required": false; }; "loading": { "alias": "loading"; "required": false; }; "manage": { "alias": "manage"; "required": false; }; "conversations": { "alias": "conversations"; "required": false; }; }, { "conversationSelect": "conversationSelect"; "conversationRename": "conversationRename"; "conversationPin": "conversationPin"; "conversationUnpin": "conversationUnpin"; "conversationArchive": "conversationArchive"; "conversationUnarchive": "conversationUnarchive"; "conversationDelete": "conversationDelete"; }, never, never, true, never>;
|
|
301
303
|
static ngAcceptInputType_flat: unknown;
|
|
302
304
|
static ngAcceptInputType_loading: unknown;
|
|
303
305
|
static ngAcceptInputType_manage: unknown;
|
package/dist/index.d.ts
CHANGED
|
@@ -5,10 +5,12 @@
|
|
|
5
5
|
export { provideAparte, APARTE_CONFIG_TOKEN } from './lib/provide-aparte';
|
|
6
6
|
export type { ProvideAparteOptions, ApartePluginLoader } from './lib/provide-aparte';
|
|
7
7
|
export { AparteChatComponent } from './lib/aparte-chat.component';
|
|
8
|
+
export { AparteBubbleDirective } from './lib/aparte-bubble.directive';
|
|
9
|
+
export { AparteToolUIDirective, AparteSegmentUIDirective } from './lib/aparte-tool-ui.directive';
|
|
8
10
|
export { AparteUiComponent } from './lib/aparte-ui.component';
|
|
9
11
|
export type { AparteUiHandle, AparteUiProps } from './lib/aparte-ui.component';
|
|
10
12
|
export * from './generated/element.directives';
|
|
11
13
|
export { AparteAiService, APARTE_CLIENT_OPTIONS } from './lib/aparte-ai.service';
|
|
12
14
|
export { ConversationManagerService } from './lib/conversation-manager.service';
|
|
13
|
-
export type { AparteMessage, AparteSendEventDetail, AparteActionEventDetail, AparteSegment, AparteTextSegment, AparteCodeSegment, AparteThinkingSegment, AparteChatImperativeApi, } from '@aparte/core';
|
|
15
|
+
export type { AparteMessage, AparteSendEventDetail, AparteActionEventDetail, AparteSegment, AparteTextSegment, AparteCodeSegment, AparteThinkingSegment, AparteChatImperativeApi, AparteToolCallView, } from '@aparte/core';
|
|
14
16
|
export { aparteGlobalConfig } from '@aparte/core';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { TemplateRef } from '@angular/core';
|
|
2
|
+
import type { AparteMessage } from '@aparte/core';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* Marks the template `<aparte-chat>` draws each message with, in place of
|
|
6
|
+
* `<aparte-chat-bubble>`: write it as content of the chat, the message as `$implicit`.
|
|
7
|
+
*
|
|
8
|
+
* ```html
|
|
9
|
+
* <aparte-chat [messages]="messages">
|
|
10
|
+
* <ng-template aparteBubble let-message>
|
|
11
|
+
* <app-bubble [message]="message" />
|
|
12
|
+
* </ng-template>
|
|
13
|
+
* </aparte-chat>
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* The same thing as passing a `TemplateRef` to `[bubbleTemplate]`, written where Angular
|
|
17
|
+
* developers write a per-item template. When both are given, `[bubbleTemplate]` wins.
|
|
18
|
+
* The built-in action bar (retry, edit, the version picker) belongs to the native bubble;
|
|
19
|
+
* a template of yours owns whatever it wires.
|
|
20
|
+
*/
|
|
21
|
+
export declare class AparteBubbleDirective {
|
|
22
|
+
readonly template: TemplateRef<{
|
|
23
|
+
$implicit: AparteMessage;
|
|
24
|
+
}>;
|
|
25
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AparteBubbleDirective, never>;
|
|
26
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<AparteBubbleDirective, "ng-template[aparteBubble]", never, {}, {}, never, never, true, never>;
|
|
27
|
+
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { ElementRef, OnDestroy, QueryList,
|
|
1
|
+
import { AfterViewInit, ElementRef, OnDestroy, QueryList, TemplateRef } from '@angular/core';
|
|
2
2
|
import { Observable } from 'rxjs';
|
|
3
3
|
import type { AparteMessage, AparteSegment, AparteSendEventDetail, AparteConfig, AparteActionEventDetail, AparteChatImperativeApi } from '@aparte/core';
|
|
4
4
|
import { isAwaitingReply } from '@aparte/core';
|
|
5
|
+
import { AparteBubbleDirective } from './aparte-bubble.directive';
|
|
5
6
|
import * as i0 from "@angular/core";
|
|
6
7
|
/**
|
|
7
|
-
* AparteChatComponent — Angular 19
|
|
8
|
+
* AparteChatComponent — the Angular wrapper (19.2 to 21, zone or zoneless)
|
|
8
9
|
*
|
|
9
10
|
* Standalone component wrapping aparté Web Components with Angular Signals.
|
|
10
11
|
* The streaming / branch-navigation / host-method orchestration (orphan-stream
|
|
@@ -15,25 +16,35 @@ import * as i0 from "@angular/core";
|
|
|
15
16
|
*/
|
|
16
17
|
export declare class AparteChatComponent implements AfterViewInit, OnDestroy, AparteChatImperativeApi {
|
|
17
18
|
constructor();
|
|
19
|
+
ngAfterViewInit(): void;
|
|
18
20
|
private elementRef;
|
|
21
|
+
private readonly _injector;
|
|
22
|
+
private readonly _isBrowser;
|
|
19
23
|
/**
|
|
20
24
|
* Template bridge to core's shared `isAwaitingReply` (an Angular template can't
|
|
21
25
|
* call an imported function). One rule for the four wrappers and core itself,
|
|
22
26
|
* so "is this bubble in flight" can't drift between them.
|
|
23
27
|
*/
|
|
24
28
|
readonly awaitingReply: typeof isAwaitingReply;
|
|
25
|
-
/** Messages to display */
|
|
26
|
-
|
|
29
|
+
/** Messages to display. Two-way: `[(messages)]`, with `(messagesChange)` reporting the chat's own changes. */
|
|
30
|
+
readonly messagesInput: import("@angular/core").InputSignal<AparteMessage[]>;
|
|
31
|
+
/** Every list the host reported — read only by the render-cache rule below. */
|
|
32
|
+
private readonly _emitted;
|
|
33
|
+
/**
|
|
34
|
+
* Under `[(messages)]` each report comes back through the input — possibly an EARLIER one,
|
|
35
|
+
* after the chat appended without reporting (an optimistic append, or core's append right
|
|
36
|
+
* after a flush) — and an echo is not the parent's word: it keeps the local list. The host
|
|
37
|
+
* tells them apart (`takeEcho`), the rule React, Vue and Svelte apply, so a list the parent
|
|
38
|
+
* restores later (a reopened conversation, an undo) is applied. Before the host exists
|
|
39
|
+
* nothing was reported, so the input is taken as it is.
|
|
40
|
+
*/
|
|
27
41
|
readonly messages: import("@angular/core").WritableSignal<AparteMessage[]>;
|
|
28
42
|
/** Input placeholder text */
|
|
29
|
-
|
|
30
|
-
readonly placeholder: import("@angular/core").WritableSignal<string>;
|
|
43
|
+
readonly placeholder: import("@angular/core").InputSignal<string>;
|
|
31
44
|
/** Whether the input is disabled */
|
|
32
|
-
|
|
33
|
-
readonly disabled: import("@angular/core").WritableSignal<boolean>;
|
|
45
|
+
readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
34
46
|
/** When false, Shift+Enter submits and a bare Enter inserts a newline. */
|
|
35
|
-
|
|
36
|
-
readonly submitOnEnter: import("@angular/core").WritableSignal<boolean>;
|
|
47
|
+
readonly submitOnEnter: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
37
48
|
/**
|
|
38
49
|
* Opt in to the "centered composer when empty" layout: the composer sits
|
|
39
50
|
* vertically centered with the `[slot='empty-state']` content above it while
|
|
@@ -41,21 +52,27 @@ export declare class AparteChatComponent implements AfterViewInit, OnDestroy, Ap
|
|
|
41
52
|
* Off by default — additive (adds the `--auto-center` modifier + a
|
|
42
53
|
* `data-aparte-empty` attribute the shipped `aparte.css` recipe keys off).
|
|
43
54
|
*/
|
|
44
|
-
|
|
45
|
-
readonly centerWhenEmpty: import("@angular/core").WritableSignal<boolean>;
|
|
55
|
+
readonly centerWhenEmpty: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
46
56
|
/**
|
|
47
57
|
* The conversation is on its way: the viewport draws two skeleton turns, the empty
|
|
48
58
|
* state stays off and the composer is disabled until it lands. The conversation
|
|
49
59
|
* controller sets this itself while it fetches through your adapter's `loadFull()`;
|
|
50
60
|
* the input is for a wait of your own. Off by default.
|
|
51
61
|
*/
|
|
52
|
-
|
|
53
|
-
readonly loading: import("@angular/core").WritableSignal<boolean>;
|
|
62
|
+
readonly loading: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
54
63
|
/** The controller's wait (a conversation fetched through the adapter). */
|
|
55
64
|
readonly hostLoading: import("@angular/core").WritableSignal<boolean>;
|
|
56
65
|
readonly waiting: import("@angular/core").Signal<boolean>;
|
|
57
66
|
/** Bumped on every config change, so the two locale strings below follow a language switch under OnPush. */
|
|
58
67
|
private readonly _localeTick;
|
|
68
|
+
/**
|
|
69
|
+
* True until the host is built — on the server always, and in the browser only while Angular
|
|
70
|
+
* hydrates the server's HTML: the host element is then the one the server sent, still carrying
|
|
71
|
+
* the attribute. A client-only render holds nothing, so a component projected into the empty
|
|
72
|
+
* state (built in an @if, after the host binding) talks to live elements in its own
|
|
73
|
+
* ngAfterViewInit, which runs before this component's.
|
|
74
|
+
*/
|
|
75
|
+
protected readonly hydrating: import("@angular/core").WritableSignal<boolean>;
|
|
59
76
|
private _unsubscribeLocale?;
|
|
60
77
|
get loadingText(): string;
|
|
61
78
|
/**
|
|
@@ -70,11 +87,9 @@ export declare class AparteChatComponent implements AfterViewInit, OnDestroy, Ap
|
|
|
70
87
|
* selector on Angular alone. This input is that parity. Additive: the recipe's
|
|
71
88
|
* own classes stay.
|
|
72
89
|
*/
|
|
73
|
-
|
|
74
|
-
readonly containerClass: import("@angular/core").WritableSignal<string>;
|
|
90
|
+
readonly containerClass: import("@angular/core").InputSignalWithTransform<string, string>;
|
|
75
91
|
/** Inline style for the same div — a string or a `{ prop: value }` map. */
|
|
76
|
-
|
|
77
|
-
readonly containerStyle: import("@angular/core").WritableSignal<string | Record<string, string>>;
|
|
92
|
+
readonly containerStyle: import("@angular/core").InputSignalWithTransform<string | Record<string, string>, string | Record<string, string>>;
|
|
78
93
|
/**
|
|
79
94
|
* Overlay the composer on the transcript (the ChatGPT anatomy): the scroll
|
|
80
95
|
* surface spans the whole column, the scrollbar runs edge to edge, and the
|
|
@@ -83,8 +98,7 @@ export declare class AparteChatComponent implements AfterViewInit, OnDestroy, Ap
|
|
|
83
98
|
* core's recipe and the viewport's measurement both key on the attribute
|
|
84
99
|
* there. Read when the viewport mounts.
|
|
85
100
|
*/
|
|
86
|
-
|
|
87
|
-
readonly overlayComposer: import("@angular/core").WritableSignal<boolean>;
|
|
101
|
+
readonly overlayComposer: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
88
102
|
/**
|
|
89
103
|
* Add the file picker + chips strip to the default composer shell. **Off by
|
|
90
104
|
* default**, because the capability needs a host that consumes the files: an
|
|
@@ -94,8 +108,7 @@ export declare class AparteChatComponent implements AfterViewInit, OnDestroy, Ap
|
|
|
94
108
|
* project a `[slot='composer']` (drop `<aparte-composer-add-attachment>` and
|
|
95
109
|
* `<aparte-composer-attachments>` in it yourself).
|
|
96
110
|
*/
|
|
97
|
-
|
|
98
|
-
readonly attachments: import("@angular/core").WritableSignal<boolean>;
|
|
111
|
+
readonly attachments: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
99
112
|
/**
|
|
100
113
|
* Render the `<aparte-elicitation>` presenter inside the host — on by default, as
|
|
101
114
|
* it is in `<aparte-chat>`: the built-in approval gate and `requestUserInput()`
|
|
@@ -103,46 +116,47 @@ export declare class AparteChatComponent implements AfterViewInit, OnDestroy, Ap
|
|
|
103
116
|
* when you mount a presenter of your own (`setElicitationPresenter`) or place the
|
|
104
117
|
* element yourself.
|
|
105
118
|
*/
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
set isTypingInput(val: boolean);
|
|
119
|
+
readonly elicitation: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
120
|
+
/** Whether the assistant is currently typing/streaming. The host turns it off on the first token. */
|
|
121
|
+
readonly isTypingInput: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
110
122
|
readonly isTyping: import("@angular/core").WritableSignal<boolean>;
|
|
111
123
|
/** Text to show in the typing status */
|
|
112
|
-
|
|
113
|
-
readonly typingText: import("@angular/core").WritableSignal<string>;
|
|
124
|
+
readonly typingText: import("@angular/core").InputSignal<string>;
|
|
114
125
|
/** The status line's word: the input, else the locale's, like the rest of the chat. */
|
|
115
126
|
get typingLabel(): string;
|
|
116
|
-
/** Duration in ms to freeze spacer recalculation after a conversation swap. */
|
|
117
|
-
layoutTransitionMs: number
|
|
127
|
+
/** Duration in ms to freeze spacer recalculation after a conversation swap. Read when the host is created. */
|
|
128
|
+
readonly layoutTransitionMs: import("@angular/core").InputSignalWithTransform<number, unknown>;
|
|
118
129
|
/**
|
|
119
130
|
* Active conversation id. When provided, the host attaches an
|
|
120
131
|
* `AparteConversationController` that loads/persists messages via the
|
|
121
132
|
* `AparteConversationManager` registered in `aparteGlobalConfig`. Setting a different id
|
|
122
133
|
* mid-stream aborts the previous request; `null` deselects.
|
|
123
134
|
*/
|
|
124
|
-
|
|
135
|
+
readonly conversationIdInput: import("@angular/core").InputSignal<string>;
|
|
125
136
|
private _conversationId;
|
|
126
137
|
/**
|
|
127
138
|
* Instance {@link AparteConfig} for this chat. When set, aparté components
|
|
128
139
|
* inside resolve THIS config instead of `aparteGlobalConfig`, so
|
|
129
140
|
* several independently-configured chats can coexist on one page. Omit for the
|
|
130
|
-
* global config. Read once
|
|
141
|
+
* global config. Read once, when the host is created after the first render.
|
|
131
142
|
*/
|
|
132
|
-
config
|
|
143
|
+
readonly config: import("@angular/core").InputSignal<AparteConfig>;
|
|
133
144
|
/**
|
|
134
145
|
* Render your OWN element per message in place of `<aparte-chat-bubble>`.
|
|
135
|
-
* Opt-in — provide a `<ng-template let-message>` and pass its ref
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
146
|
+
* Opt-in — provide a `<ng-template let-message>` and pass its ref, or write the
|
|
147
|
+
* template as content with {@link AparteBubbleDirective} (`<ng-template aparteBubble
|
|
148
|
+
* let-message>`); this input wins when both are given. Driven by the reactive
|
|
149
|
+
* `messages()` signal, so it updates live during streaming. The built-in action bar
|
|
150
|
+
* (retry/edit/branch) belongs to the native bubble; a custom bubble owns whatever it wires.
|
|
139
151
|
* @example
|
|
140
152
|
* <aparte-chat [bubbleTemplate]="tpl" />
|
|
141
153
|
* <ng-template #tpl let-message>{{ message.content }}</ng-template>
|
|
142
154
|
*/
|
|
143
|
-
bubbleTemplate
|
|
155
|
+
readonly bubbleTemplate: import("@angular/core").InputSignal<TemplateRef<{
|
|
144
156
|
$implicit: AparteMessage;
|
|
145
|
-
}
|
|
157
|
+
}>>;
|
|
158
|
+
/** The `<ng-template aparteBubble>` written as content, if any. */
|
|
159
|
+
readonly bubbleDirective: import("@angular/core").Signal<AparteBubbleDirective>;
|
|
146
160
|
/**
|
|
147
161
|
* User submitted a message from the composer. It is **appended to the thread
|
|
148
162
|
* automatically** (optimistic UI) before this fires — do NOT add it again in
|
|
@@ -173,13 +187,15 @@ export declare class AparteChatComponent implements AfterViewInit, OnDestroy, Ap
|
|
|
173
187
|
readonly isStreaming: import("@angular/core").Signal<boolean>;
|
|
174
188
|
/** rAF id used to coalesce rapid signal updates during streaming */
|
|
175
189
|
private _syncRafId;
|
|
176
|
-
/** The framework-agnostic chat-host orchestrator (created in
|
|
190
|
+
/** The framework-agnostic chat-host orchestrator (created after the first render, in the browser). */
|
|
177
191
|
private _host?;
|
|
178
192
|
private _unbindHost?;
|
|
179
193
|
/** QueryList.changes subscription — released in ngOnDestroy so SPA route
|
|
180
194
|
* churn doesn't leak a live subscription per mount. */
|
|
181
195
|
private _bubbleRefsSub?;
|
|
182
|
-
|
|
196
|
+
/** Set by ngOnDestroy: an afterNextRender that lands after a destroy must not build a host. */
|
|
197
|
+
private _destroyed;
|
|
198
|
+
private _createHost;
|
|
183
199
|
private readonly _onAction;
|
|
184
200
|
ngOnDestroy(): void;
|
|
185
201
|
/** Append a message optimistically — `{ historical: true }` for one restored from your own store. */
|
|
@@ -248,14 +264,5 @@ export declare class AparteChatComponent implements AfterViewInit, OnDestroy, Ap
|
|
|
248
264
|
/** Handle aparte-send event from the composer Web Component. */
|
|
249
265
|
onAparteSend(event: Event): void;
|
|
250
266
|
static ɵfac: i0.ɵɵFactoryDeclaration<AparteChatComponent, never>;
|
|
251
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<AparteChatComponent, "aparte-chat", never, { "messagesInput": { "alias": "messages"; "required": false; }; "
|
|
252
|
-
static ngAcceptInputType_disabledInput: unknown;
|
|
253
|
-
static ngAcceptInputType_submitOnEnterInput: unknown;
|
|
254
|
-
static ngAcceptInputType_centerWhenEmptyInput: unknown;
|
|
255
|
-
static ngAcceptInputType_loadingInput: unknown;
|
|
256
|
-
static ngAcceptInputType_overlayComposerInput: unknown;
|
|
257
|
-
static ngAcceptInputType_attachmentsInput: unknown;
|
|
258
|
-
static ngAcceptInputType_elicitationInput: unknown;
|
|
259
|
-
static ngAcceptInputType_isTypingInput: unknown;
|
|
260
|
-
static ngAcceptInputType_layoutTransitionMs: unknown;
|
|
267
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<AparteChatComponent, "aparte-chat", never, { "messagesInput": { "alias": "messages"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "submitOnEnter": { "alias": "submitOnEnter"; "required": false; "isSignal": true; }; "centerWhenEmpty": { "alias": "centerWhenEmpty"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "containerClass": { "alias": "containerClass"; "required": false; "isSignal": true; }; "containerStyle": { "alias": "containerStyle"; "required": false; "isSignal": true; }; "overlayComposer": { "alias": "overlayComposer"; "required": false; "isSignal": true; }; "attachments": { "alias": "attachments"; "required": false; "isSignal": true; }; "elicitation": { "alias": "elicitation"; "required": false; "isSignal": true; }; "isTypingInput": { "alias": "isTyping"; "required": false; "isSignal": true; }; "typingText": { "alias": "typingText"; "required": false; "isSignal": true; }; "layoutTransitionMs": { "alias": "layoutTransitionMs"; "required": false; "isSignal": true; }; "conversationIdInput": { "alias": "conversationId"; "required": false; "isSignal": true; }; "config": { "alias": "config"; "required": false; "isSignal": true; }; "bubbleTemplate": { "alias": "bubbleTemplate"; "required": false; "isSignal": true; }; }, { "messageSent": "messageSent"; "action": "action"; "messagesChange": "messagesChange"; "messageAppended": "messageAppended"; "typingChange": "typingChange"; "conversationCreated": "conversationCreated"; }, ["bubbleDirective"], ["[slot='empty-state']", "[slot='above-composer']", "[slot='toolbar']", "[slot='composer']"], true, never>;
|
|
261
268
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { type AparteConfig, type AparteSegmentBase, type AparteToolCallView, type AparteToolMatcher } from '@aparte/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
/**
|
|
4
|
+
* Draws a tool call with your own template, for as long as the template is in the page.
|
|
5
|
+
*
|
|
6
|
+
* ```html
|
|
7
|
+
* <ng-template aparteToolUI="get_weather" let-tool>
|
|
8
|
+
* <app-weather-card [tool]="tool" />
|
|
9
|
+
* </ng-template>
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
12
|
+
* `let-tool` is an `AparteToolCallView`; its `input` is the model's arguments, `unknown` until
|
|
13
|
+
* the card narrows it — give the card the view (`input.required<AparteToolCallView>()`) and type
|
|
14
|
+
* its arguments there.
|
|
15
|
+
*
|
|
16
|
+
* Every `get_weather` call is drawn with the template, the call's view as `$implicit`, and
|
|
17
|
+
* given back to core's row when the template leaves. The view is created where you declare
|
|
18
|
+
* the template, so the components in it inject what your app provides there. Underneath it is
|
|
19
|
+
* core's `overrideToolRenderer` + `defineMountedToolRenderer`; nothing is declared in a server
|
|
20
|
+
* render, and the cards are drawn in the browser.
|
|
21
|
+
*/
|
|
22
|
+
export declare class AparteToolUIDirective {
|
|
23
|
+
/** The tool this draws: a name, a `RegExp`, or `'*'` for every tool. */
|
|
24
|
+
readonly name: import("@angular/core").InputSignal<AparteToolMatcher>;
|
|
25
|
+
/** The config to declare it on. Defaults to the global one. */
|
|
26
|
+
readonly config: import("@angular/core").InputSignal<AparteConfig>;
|
|
27
|
+
private readonly template;
|
|
28
|
+
private readonly container;
|
|
29
|
+
constructor();
|
|
30
|
+
/** Types `let-tool` in a strict template. */
|
|
31
|
+
static ngTemplateContextGuard(_dir: AparteToolUIDirective, _ctx: unknown): _ctx is {
|
|
32
|
+
$implicit: AparteToolCallView;
|
|
33
|
+
};
|
|
34
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AparteToolUIDirective, never>;
|
|
35
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<AparteToolUIDirective, "ng-template[aparteToolUI]", never, { "name": { "alias": "aparteToolUI"; "required": true; "isSignal": true; }; "config": { "alias": "aparteToolUIConfig"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Draws a segment type with your own template — one your stream emits, or a built-in such as
|
|
39
|
+
* `code` — the segment as `$implicit`. Taking the last declaration off a built-in type gives it
|
|
40
|
+
* back to core's renderer.
|
|
41
|
+
*
|
|
42
|
+
* ```html
|
|
43
|
+
* <ng-template aparteSegmentUI="chart" let-segment>
|
|
44
|
+
* <app-chart [segment]="segment" />
|
|
45
|
+
* </ng-template>
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* `let-segment` is the base segment with its own fields: the component it is handed to types it.
|
|
49
|
+
*/
|
|
50
|
+
export declare class AparteSegmentUIDirective {
|
|
51
|
+
/** The segment `type` this draws. */
|
|
52
|
+
readonly type: import("@angular/core").InputSignal<string>;
|
|
53
|
+
/** The config to declare it on. Defaults to the global one. */
|
|
54
|
+
readonly config: import("@angular/core").InputSignal<AparteConfig>;
|
|
55
|
+
private readonly template;
|
|
56
|
+
private readonly container;
|
|
57
|
+
constructor();
|
|
58
|
+
static ngTemplateContextGuard(_dir: AparteSegmentUIDirective, _ctx: unknown): _ctx is {
|
|
59
|
+
$implicit: AparteSegmentBase & Record<string, unknown>;
|
|
60
|
+
};
|
|
61
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AparteSegmentUIDirective, never>;
|
|
62
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<AparteSegmentUIDirective, "ng-template[aparteSegmentUI]", never, { "type": { "alias": "aparteSegmentUI"; "required": true; "isSignal": true; }; "config": { "alias": "aparteSegmentUIConfig"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
63
|
+
}
|
|
@@ -76,6 +76,13 @@ export declare class AparteUiComponent implements AfterViewInit, OnChanges, OnDe
|
|
|
76
76
|
readonly elementEvent: import("@angular/core").OutputEmitterRef<CustomEvent<any>>;
|
|
77
77
|
/** The dynamically created Web Component element */
|
|
78
78
|
private element;
|
|
79
|
+
/**
|
|
80
|
+
* On a server the element is not built: it would be serialized into the HTML without its
|
|
81
|
+
* props or listeners, hydration would keep it, and the browser would append its own beside
|
|
82
|
+
* it — two counters, two pickers. React, Vue and Svelte build theirs in an effect or onMount,
|
|
83
|
+
* which a server never runs.
|
|
84
|
+
*/
|
|
85
|
+
private readonly isBrowser;
|
|
79
86
|
/** Cleanup functions for event listeners */
|
|
80
87
|
private eventCleanups;
|
|
81
88
|
/** Joined key of the bound event set, so a fresh inline `[events]` array
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aparte/angular",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.25.0",
|
|
4
4
|
"homepage": "https://apartejs.dev/frameworks/angular/",
|
|
5
|
-
"description": "Angular
|
|
5
|
+
"description": "Angular wrapper for aparté (Angular 19.2 to 21, zone or zoneless) — an ergonomic <aparte-chat> component plus services over the framework-agnostic web components.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"sideEffects": false,
|
|
8
8
|
"main": "./dist/fesm2022/aparte-angular.mjs",
|
|
@@ -28,25 +28,26 @@
|
|
|
28
28
|
"node": ">=18"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
|
-
"@angular/common": "^19.2.0",
|
|
32
|
-
"@angular/core": "^19.2.0",
|
|
33
|
-
"@aparte/core": ">=0.
|
|
31
|
+
"@angular/common": "^19.2.0 || ^20.0.0 || ^21.0.0",
|
|
32
|
+
"@angular/core": "^19.2.0 || ^20.0.0 || ^21.0.0",
|
|
33
|
+
"@aparte/core": ">=0.25.0 <1.0.0",
|
|
34
34
|
"rxjs": "^7.8.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@analogjs/vitest-angular": "^2.2.2",
|
|
38
37
|
"@angular/common": "^19.2.0",
|
|
39
38
|
"@angular/compiler": "^19.2.0",
|
|
40
39
|
"@angular/compiler-cli": "^19.2.0",
|
|
41
40
|
"@angular/core": "^19.2.0",
|
|
42
41
|
"@angular/platform-browser": "^19.2.0",
|
|
42
|
+
"@angular/platform-server": "^19.2.0",
|
|
43
43
|
"jsdom": "^22.1.0",
|
|
44
44
|
"ng-packagr": "^19.2.0",
|
|
45
45
|
"rxjs": "^7.8.2",
|
|
46
46
|
"typescript": "^5.4.0",
|
|
47
47
|
"vite": "^6.0.0",
|
|
48
48
|
"zone.js": "~0.15.0",
|
|
49
|
-
"@aparte/core": "0.
|
|
49
|
+
"@aparte/core": "0.25.0",
|
|
50
|
+
"@aparte/provider-scenario": "0.25.0"
|
|
50
51
|
},
|
|
51
52
|
"keywords": [
|
|
52
53
|
"angular",
|