@aparte/core 0.2.0-alpha.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/LICENSE +21 -0
- package/README.md +53 -0
- package/dist/client/aparte-client.d.ts +326 -0
- package/dist/client/aparte-client.d.ts.map +1 -0
- package/dist/client/stream-adapter.d.ts +197 -0
- package/dist/client/stream-adapter.d.ts.map +1 -0
- package/dist/components/bubble/aparte-chat-bubble.d.ts +153 -0
- package/dist/components/bubble/aparte-chat-bubble.d.ts.map +1 -0
- package/dist/components/bubble/bubble-sync.d.ts +44 -0
- package/dist/components/bubble/bubble-sync.d.ts.map +1 -0
- package/dist/components/bubble/index.d.ts +4 -0
- package/dist/components/bubble/index.d.ts.map +1 -0
- package/dist/components/chat/aparte-chat.d.ts +49 -0
- package/dist/components/chat/aparte-chat.d.ts.map +1 -0
- package/dist/components/chat/index.d.ts +2 -0
- package/dist/components/chat/index.d.ts.map +1 -0
- package/dist/components/composer/aparte-composer-action.d.ts +37 -0
- package/dist/components/composer/aparte-composer-action.d.ts.map +1 -0
- package/dist/components/composer/aparte-composer-add-attachment.d.ts +27 -0
- package/dist/components/composer/aparte-composer-add-attachment.d.ts.map +1 -0
- package/dist/components/composer/aparte-composer-attachments.d.ts +26 -0
- package/dist/components/composer/aparte-composer-attachments.d.ts.map +1 -0
- package/dist/components/composer/aparte-composer-cancel.d.ts +21 -0
- package/dist/components/composer/aparte-composer-cancel.d.ts.map +1 -0
- package/dist/components/composer/aparte-composer-input.d.ts +63 -0
- package/dist/components/composer/aparte-composer-input.d.ts.map +1 -0
- package/dist/components/composer/aparte-composer-send.d.ts +25 -0
- package/dist/components/composer/aparte-composer-send.d.ts.map +1 -0
- package/dist/components/composer/aparte-composer.d.ts +150 -0
- package/dist/components/composer/aparte-composer.d.ts.map +1 -0
- package/dist/components/composer/index.d.ts +9 -0
- package/dist/components/composer/index.d.ts.map +1 -0
- package/dist/components/conversation-list/aparte-conversation-list.d.ts +50 -0
- package/dist/components/conversation-list/aparte-conversation-list.d.ts.map +1 -0
- package/dist/components/conversation-list/index.d.ts +2 -0
- package/dist/components/conversation-list/index.d.ts.map +1 -0
- package/dist/components/elicitation/aparte-elicitation.d.ts +29 -0
- package/dist/components/elicitation/aparte-elicitation.d.ts.map +1 -0
- package/dist/components/index.d.ts +10 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/status/aparte-chat-status.d.ts +34 -0
- package/dist/components/status/aparte-chat-status.d.ts.map +1 -0
- package/dist/components/status/index.d.ts +2 -0
- package/dist/components/status/index.d.ts.map +1 -0
- package/dist/components/viewport/aparte-chat-viewport.d.ts +358 -0
- package/dist/components/viewport/aparte-chat-viewport.d.ts.map +1 -0
- package/dist/components/viewport/index.d.ts +2 -0
- package/dist/components/viewport/index.d.ts.map +1 -0
- package/dist/config/action-provider.d.ts +59 -0
- package/dist/config/action-provider.d.ts.map +1 -0
- package/dist/config/aparte-config.d.ts +490 -0
- package/dist/config/aparte-config.d.ts.map +1 -0
- package/dist/config/attachment-renderer.d.ts +28 -0
- package/dist/config/attachment-renderer.d.ts.map +1 -0
- package/dist/config/avatar-provider.d.ts +35 -0
- package/dist/config/avatar-provider.d.ts.map +1 -0
- package/dist/config/bubble-shell-renderer.d.ts +41 -0
- package/dist/config/bubble-shell-renderer.d.ts.map +1 -0
- package/dist/config/config-context.d.ts +47 -0
- package/dist/config/config-context.d.ts.map +1 -0
- package/dist/config/error-renderer.d.ts +26 -0
- package/dist/config/error-renderer.d.ts.map +1 -0
- package/dist/config/icon-provider.d.ts +63 -0
- package/dist/config/icon-provider.d.ts.map +1 -0
- package/dist/config/index.d.ts +19 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/locale.d.ts +60 -0
- package/dist/config/locale.d.ts.map +1 -0
- package/dist/config/sanitize.d.ts +31 -0
- package/dist/config/sanitize.d.ts.map +1 -0
- package/dist/config/sibling-nav-renderer.d.ts +27 -0
- package/dist/config/sibling-nav-renderer.d.ts.map +1 -0
- package/dist/config/skeleton-provider.d.ts +26 -0
- package/dist/config/skeleton-provider.d.ts.map +1 -0
- package/dist/config/status-renderer.d.ts +23 -0
- package/dist/config/status-renderer.d.ts.map +1 -0
- package/dist/conversations/conversation-controller.d.ts +126 -0
- package/dist/conversations/conversation-controller.d.ts.map +1 -0
- package/dist/conversations/conversation-manager.d.ts +98 -0
- package/dist/conversations/conversation-manager.d.ts.map +1 -0
- package/dist/conversations/index.d.ts +5 -0
- package/dist/conversations/index.d.ts.map +1 -0
- package/dist/conversations/types.d.ts +172 -0
- package/dist/conversations/types.d.ts.map +1 -0
- package/dist/custom-elements.json +15833 -0
- package/dist/elicitation/index.d.ts +20 -0
- package/dist/elicitation/index.d.ts.map +1 -0
- package/dist/elicitation/panel.d.ts +18 -0
- package/dist/elicitation/panel.d.ts.map +1 -0
- package/dist/elicitation/types.d.ts +98 -0
- package/dist/elicitation/types.d.ts.map +1 -0
- package/dist/host/aparte-chat-host.d.ts +176 -0
- package/dist/host/aparte-chat-host.d.ts.map +1 -0
- package/dist/host/index.d.ts +2 -0
- package/dist/host/index.d.ts.map +1 -0
- package/dist/index-D89k-n2Q.js +6294 -0
- package/dist/index-D89k-n2Q.js.map +1 -0
- package/dist/index.css +2554 -0
- package/dist/index.d.ts +62 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3763 -0
- package/dist/index.js.map +1 -0
- package/dist/index.node.d.ts +53 -0
- package/dist/index.node.d.ts.map +1 -0
- package/dist/index.node.js +49 -0
- package/dist/index.node.js.map +1 -0
- package/dist/interop/element-props.d.ts +23 -0
- package/dist/interop/element-props.d.ts.map +1 -0
- package/dist/parsers/aparte-event-stream.d.ts +13 -0
- package/dist/parsers/aparte-event-stream.d.ts.map +1 -0
- package/dist/parsers/aparte-stream-parser.d.ts +137 -0
- package/dist/parsers/aparte-stream-parser.d.ts.map +1 -0
- package/dist/parsers/index.d.ts +4 -0
- package/dist/parsers/index.d.ts.map +1 -0
- package/dist/primitives/index.d.ts +8 -0
- package/dist/primitives/index.d.ts.map +1 -0
- package/dist/primitives/progress-spinner/aparte-progress-spinner.d.ts +25 -0
- package/dist/primitives/progress-spinner/aparte-progress-spinner.d.ts.map +1 -0
- package/dist/primitives/progress-spinner/index.d.ts +2 -0
- package/dist/primitives/progress-spinner/index.d.ts.map +1 -0
- package/dist/primitives/select/aparte-optgroup.d.ts +32 -0
- package/dist/primitives/select/aparte-optgroup.d.ts.map +1 -0
- package/dist/primitives/select/aparte-option.d.ts +30 -0
- package/dist/primitives/select/aparte-option.d.ts.map +1 -0
- package/dist/primitives/select/aparte-select.d.ts +74 -0
- package/dist/primitives/select/aparte-select.d.ts.map +1 -0
- package/dist/primitives/select/index.d.ts +9 -0
- package/dist/primitives/select/index.d.ts.map +1 -0
- package/dist/renderers/index.d.ts +5 -0
- package/dist/renderers/index.d.ts.map +1 -0
- package/dist/renderers/segment-renderers.d.ts +31 -0
- package/dist/renderers/segment-renderers.d.ts.map +1 -0
- package/dist/runtime/message-repository.d.ts +111 -0
- package/dist/runtime/message-repository.d.ts.map +1 -0
- package/dist/transport/backend-handler.d.ts +50 -0
- package/dist/transport/backend-handler.d.ts.map +1 -0
- package/dist/transport/backend-transport.d.ts +39 -0
- package/dist/transport/backend-transport.d.ts.map +1 -0
- package/dist/transport/direct-transport.d.ts +36 -0
- package/dist/transport/direct-transport.d.ts.map +1 -0
- package/dist/transport/index.d.ts +6 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/types.d.ts +73 -0
- package/dist/transport/types.d.ts.map +1 -0
- package/dist/types/chat.d.ts +223 -0
- package/dist/types/chat.d.ts.map +1 -0
- package/dist/types/errors.d.ts +25 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/event-map.d.ts +41 -0
- package/dist/types/event-map.d.ts.map +1 -0
- package/dist/types/events.d.ts +290 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/imperative-api.d.ts +38 -0
- package/dist/types/imperative-api.d.ts.map +1 -0
- package/dist/types/index.d.ts +22 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/model-provider.d.ts +229 -0
- package/dist/types/model-provider.d.ts.map +1 -0
- package/dist/types/models.d.ts +173 -0
- package/dist/types/models.d.ts.map +1 -0
- package/dist/types/parsers.d.ts +42 -0
- package/dist/types/parsers.d.ts.map +1 -0
- package/dist/types/providers.d.ts +93 -0
- package/dist/types/providers.d.ts.map +1 -0
- package/dist/types/segments.d.ts +221 -0
- package/dist/types/segments.d.ts.map +1 -0
- package/dist/types/theming.d.ts +44 -0
- package/dist/types/theming.d.ts.map +1 -0
- package/dist/types/tools.d.ts +98 -0
- package/dist/types/tools.d.ts.map +1 -0
- package/dist/utils/assert-never.d.ts +9 -0
- package/dist/utils/assert-never.d.ts.map +1 -0
- package/dist/utils/css-escape.d.ts +15 -0
- package/dist/utils/css-escape.d.ts.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-instance config resolution (Phase 2, step 1 — the seam only).
|
|
3
|
+
*
|
|
4
|
+
* `AparteConfig` is a global singleton: one config for the whole page. That makes
|
|
5
|
+
* two independent chats on one page impossible (changing the model of one
|
|
6
|
+
* changes the other) and couples every component to global state.
|
|
7
|
+
*
|
|
8
|
+
* This module adds an OPTIONAL instance boundary without touching behaviour:
|
|
9
|
+
* a host element can carry its own {@link AparteConfigClass} instance, and any
|
|
10
|
+
* component resolves "its" config by walking up to the nearest such host —
|
|
11
|
+
* falling back to the global singleton when there is none. Until a caller
|
|
12
|
+
* attaches an instance config, `resolveConfig` always returns the global, so
|
|
13
|
+
* single-chat apps are unaffected.
|
|
14
|
+
*
|
|
15
|
+
* Step 2 migrates the ~23 component read-sites from `AparteConfig.x()` to
|
|
16
|
+
* `resolveConfig(this).x()`. This step just ships the mechanism + tests.
|
|
17
|
+
*/
|
|
18
|
+
import { AparteConfigClass } from './aparte-config.js';
|
|
19
|
+
/** Marks an element as an instance-config boundary (used by `closest()`). */
|
|
20
|
+
export declare const APARTE_HOST_ATTR = "data-aparte-host";
|
|
21
|
+
/**
|
|
22
|
+
* Attach an instance config to `el`, making it a resolution boundary: every
|
|
23
|
+
* component inside `el` resolves to `config` instead of the global singleton.
|
|
24
|
+
* Idempotent; pass the same element to replace its config.
|
|
25
|
+
*/
|
|
26
|
+
export declare function attachConfig(el: HTMLElement, config: AparteConfigClass): void;
|
|
27
|
+
/**
|
|
28
|
+
* Remove the instance-config boundary from `el` (e.g. in `disconnectedCallback`).
|
|
29
|
+
* Components under `el` fall back to the next boundary up, or the global.
|
|
30
|
+
*/
|
|
31
|
+
export declare function detachConfig(el: HTMLElement): void;
|
|
32
|
+
/**
|
|
33
|
+
* Resolve the config governing `el`: the nearest ancestor boundary's instance
|
|
34
|
+
* config (including `el` itself), or the global {@link AparteConfig} when none is
|
|
35
|
+
* present. Cheap — a single `closest()` — but callers should cache the result at
|
|
36
|
+
* `connectedCallback` rather than call it per render.
|
|
37
|
+
*/
|
|
38
|
+
export declare function resolveConfig(el: Element | null | undefined): AparteConfigClass;
|
|
39
|
+
/** Run `fn` with `config` as the ambient render config (restored after). */
|
|
40
|
+
export declare function runWithConfig<T>(config: AparteConfigClass, fn: () => T): T;
|
|
41
|
+
/**
|
|
42
|
+
* The ambient render config set by {@link runWithConfig}, else the config
|
|
43
|
+
* resolved from `el` (when provided), else the global singleton. Capture it
|
|
44
|
+
* synchronously at the top of a renderer — never after an `await`.
|
|
45
|
+
*/
|
|
46
|
+
export declare function contextConfig(el?: Element | null): AparteConfigClass;
|
|
47
|
+
//# sourceMappingURL=config-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-context.d.ts","sourceRoot":"","sources":["../../src/config/config-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAgB,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAErE,6EAA6E;AAC7E,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AASnD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAG7E;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,WAAW,GAAG,IAAI,CAGlD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,iBAAiB,CAG/E;AAWD,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAQ1E;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAAE,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,iBAAiB,CAEpE"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Renderer
|
|
3
|
+
*
|
|
4
|
+
* Replace the content of an error bubble — the default is an icon + "Error" title
|
|
5
|
+
* + message (+ details). Return an HTML **string** or a ready **HTMLElement**
|
|
6
|
+
* (charter §6 render hooks: `string | HTMLElement`), e.g. a friendly message with
|
|
7
|
+
* your own "Try again" button. This drives the built-in `error` segment renderer,
|
|
8
|
+
* so it's the one place to customize error UI (rather than registering a segment
|
|
9
|
+
* renderer for the `error` type yourself). The bubble also reflects `data-error`
|
|
10
|
+
* on its `.aparte-message` while an error segment is present, for CSS theming.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* AparteConfig.setErrorRenderer(({ message }) => {
|
|
14
|
+
* const el = document.createElement('div');
|
|
15
|
+
* el.className = 'my-error';
|
|
16
|
+
* el.textContent = `Something went wrong: ${message}`;
|
|
17
|
+
* return el;
|
|
18
|
+
* });
|
|
19
|
+
*/
|
|
20
|
+
export type AparteErrorRenderer = (ctx: {
|
|
21
|
+
/** Human-readable error message (the error segment's content). */
|
|
22
|
+
message: string;
|
|
23
|
+
/** Optional error code/details (the error segment's `details`). */
|
|
24
|
+
details?: string;
|
|
25
|
+
}) => string | HTMLElement;
|
|
26
|
+
//# sourceMappingURL=error-renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-renderer.d.ts","sourceRoot":"","sources":["../../src/config/error-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,GAAG,EAAE;IACpC,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB,KAAK,MAAM,GAAG,WAAW,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Icon Provider Interface
|
|
3
|
+
*
|
|
4
|
+
* Defines the contract for icon plugins.
|
|
5
|
+
* Returns HTML strings: SVG, <i> tags, emojis, or any valid HTML.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* // Register an icon provider (e.g. a FontAwesome bridge)
|
|
9
|
+
* AparteConfig.setIconProvider({
|
|
10
|
+
* copy: () => '<i class="fas fa-copy"></i>',
|
|
11
|
+
* check: () => '<i class="fas fa-check"></i>',
|
|
12
|
+
* // ...
|
|
13
|
+
* });
|
|
14
|
+
*/
|
|
15
|
+
export interface AparteIconProvider {
|
|
16
|
+
/** Copy button icon */
|
|
17
|
+
copy: () => string;
|
|
18
|
+
/** Success/check icon */
|
|
19
|
+
check: () => string;
|
|
20
|
+
/** Send message icon */
|
|
21
|
+
send: () => string;
|
|
22
|
+
/** Loading/spinner indicator */
|
|
23
|
+
loading: () => string;
|
|
24
|
+
/** Error indicator */
|
|
25
|
+
error: () => string;
|
|
26
|
+
/** Expand/show more icon */
|
|
27
|
+
expand: () => string;
|
|
28
|
+
/** Collapse/show less icon */
|
|
29
|
+
collapse: () => string;
|
|
30
|
+
/** Terminal/command prompt icon */
|
|
31
|
+
terminal: () => string;
|
|
32
|
+
/** File attachment / paperclip icon (used by upload plugin) */
|
|
33
|
+
paperclip: () => string;
|
|
34
|
+
/** Image file icon (used by upload plugin) */
|
|
35
|
+
image: () => string;
|
|
36
|
+
/** Generic file icon (used by upload plugin) */
|
|
37
|
+
file: () => string;
|
|
38
|
+
/** Scroll to bottom button icon */
|
|
39
|
+
scrollDown: () => string;
|
|
40
|
+
/** Retry / regenerate icon */
|
|
41
|
+
retry: () => string;
|
|
42
|
+
/** Edit / pencil icon */
|
|
43
|
+
edit: () => string;
|
|
44
|
+
/** Thumbs up / positive feedback icon */
|
|
45
|
+
thumbUp: () => string;
|
|
46
|
+
/** Thumbs down / negative feedback icon */
|
|
47
|
+
thumbDown: () => string;
|
|
48
|
+
/** Previous branch arrow */
|
|
49
|
+
prevBranch: () => string;
|
|
50
|
+
/** Next branch arrow */
|
|
51
|
+
nextBranch: () => string;
|
|
52
|
+
/** Tool call indicator (wrench) — optional so existing providers stay valid */
|
|
53
|
+
tool?: () => string;
|
|
54
|
+
/** Close / failed / rejected (✕) — optional so existing providers stay valid */
|
|
55
|
+
close?: () => string;
|
|
56
|
+
/** Stop / halt streaming (■) — optional so existing providers stay valid */
|
|
57
|
+
stop?: () => string;
|
|
58
|
+
}
|
|
59
|
+
/** Icon names available in the provider */
|
|
60
|
+
export type AparteIconName = keyof AparteIconProvider;
|
|
61
|
+
/** Default textual fallbacks - zero dependency */
|
|
62
|
+
export declare const DEFAULT_ICON_FALLBACKS: Record<AparteIconName, string>;
|
|
63
|
+
//# sourceMappingURL=icon-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icon-provider.d.ts","sourceRoot":"","sources":["../../src/config/icon-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,kBAAkB;IAC/B,uBAAuB;IACvB,IAAI,EAAE,MAAM,MAAM,CAAC;IACnB,yBAAyB;IACzB,KAAK,EAAE,MAAM,MAAM,CAAC;IACpB,wBAAwB;IACxB,IAAI,EAAE,MAAM,MAAM,CAAC;IACnB,gCAAgC;IAChC,OAAO,EAAE,MAAM,MAAM,CAAC;IACtB,sBAAsB;IACtB,KAAK,EAAE,MAAM,MAAM,CAAC;IACpB,4BAA4B;IAC5B,MAAM,EAAE,MAAM,MAAM,CAAC;IACrB,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,MAAM,CAAC;IACvB,mCAAmC;IACnC,QAAQ,EAAE,MAAM,MAAM,CAAC;IACvB,+DAA+D;IAC/D,SAAS,EAAE,MAAM,MAAM,CAAC;IACxB,8CAA8C;IAC9C,KAAK,EAAE,MAAM,MAAM,CAAC;IACpB,gDAAgD;IAChD,IAAI,EAAE,MAAM,MAAM,CAAC;IACnB,mCAAmC;IACnC,UAAU,EAAE,MAAM,MAAM,CAAC;IACzB,8BAA8B;IAC9B,KAAK,EAAE,MAAM,MAAM,CAAC;IACpB,yBAAyB;IACzB,IAAI,EAAE,MAAM,MAAM,CAAC;IACnB,yCAAyC;IACzC,OAAO,EAAE,MAAM,MAAM,CAAC;IACtB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,MAAM,CAAC;IACxB,4BAA4B;IAC5B,UAAU,EAAE,MAAM,MAAM,CAAC;IACzB,wBAAwB;IACxB,UAAU,EAAE,MAAM,MAAM,CAAC;IACzB,+EAA+E;IAC/E,IAAI,CAAC,EAAE,MAAM,MAAM,CAAC;IACpB,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,MAAM,CAAC;IACrB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,MAAM,CAAC;CACvB;AAED,2CAA2C;AAC3C,MAAM,MAAM,cAAc,GAAG,MAAM,kBAAkB,CAAC;AAEtD,kDAAkD;AAClD,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAsBjE,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export { AparteConfig, AparteConfigClass } from './aparte-config.js';
|
|
2
|
+
export { resolveConfig, attachConfig, detachConfig, runWithConfig, contextConfig, APARTE_HOST_ATTR } from './config-context.js';
|
|
3
|
+
export type { AparteMarkdownProvider, AparteStreamingMarkdownProvider, AparteStreamingMarkdownRenderer, AparteHighlightProvider, AparteSystemPromptVarsProvider, AparteModelPreference, AparteModelPreferenceProvider, AparteArtifactPreviewBuilder } from './aparte-config.js';
|
|
4
|
+
export type { AparteSanitizer } from './sanitize.js';
|
|
5
|
+
export { defaultSanitizer, isSafeUrl } from './sanitize.js';
|
|
6
|
+
export type { AparteIconProvider, AparteIconName } from './icon-provider.js';
|
|
7
|
+
export { DEFAULT_ICON_FALLBACKS } from './icon-provider.js';
|
|
8
|
+
export type { AparteSkeletonType, AparteSkeletonProvider } from './skeleton-provider.js';
|
|
9
|
+
export { DEFAULT_SKELETON_FALLBACKS } from './skeleton-provider.js';
|
|
10
|
+
export type { AparteAvatarProvider } from './avatar-provider.js';
|
|
11
|
+
export type { AparteStatusRenderer } from './status-renderer.js';
|
|
12
|
+
export type { AparteErrorRenderer } from './error-renderer.js';
|
|
13
|
+
export type { AparteAttachmentRenderer } from './attachment-renderer.js';
|
|
14
|
+
export type { AparteSiblingNavRenderer } from './sibling-nav-renderer.js';
|
|
15
|
+
export type { AparteBubbleShellRenderer } from './bubble-shell-renderer.js';
|
|
16
|
+
export type { AparteLocale } from './locale.js';
|
|
17
|
+
export { DEFAULT_LOCALE } from './locale.js';
|
|
18
|
+
export type { AparteAction, AparteActionZone } from './action-provider.js';
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAChI,YAAY,EAAE,sBAAsB,EAAE,+BAA+B,EAAE,+BAA+B,EAAE,uBAAuB,EAAE,8BAA8B,EAAE,qBAAqB,EAAE,6BAA6B,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAC;AAChR,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC5D,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,YAAY,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACzF,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACpE,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,YAAY,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACzE,YAAY,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAC1E,YAAY,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAC5E,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Aparte Locale Interface
|
|
3
|
+
*
|
|
4
|
+
* Defines all translatable strings for the chat interface.
|
|
5
|
+
* The core keeps only the English default in memory.
|
|
6
|
+
* Other languages are injected via AparteConfig.setLocale().
|
|
7
|
+
*/
|
|
8
|
+
export interface AparteLocale {
|
|
9
|
+
inputPlaceholder: string;
|
|
10
|
+
sendButton: string;
|
|
11
|
+
copy: string;
|
|
12
|
+
copied: string;
|
|
13
|
+
retry: string;
|
|
14
|
+
thinking: string;
|
|
15
|
+
typing: string;
|
|
16
|
+
error: string;
|
|
17
|
+
running: string;
|
|
18
|
+
run: string;
|
|
19
|
+
file: string;
|
|
20
|
+
/** Display name shown above the user's messages (default: "You") */
|
|
21
|
+
roleNameUser: string;
|
|
22
|
+
/** Display name shown above the assistant's messages (default: "Assistant") */
|
|
23
|
+
roleNameAssistant: string;
|
|
24
|
+
yourMessage: string;
|
|
25
|
+
assistantResponse: string;
|
|
26
|
+
messageActions: string;
|
|
27
|
+
edit: string;
|
|
28
|
+
editConfirm: string;
|
|
29
|
+
editCancel: string;
|
|
30
|
+
feedbackPositive: string;
|
|
31
|
+
feedbackNegative: string;
|
|
32
|
+
previousResponse: string;
|
|
33
|
+
nextResponse: string;
|
|
34
|
+
/** Approve button on a tool awaiting human approval (default: "Approve") */
|
|
35
|
+
approveTool?: string;
|
|
36
|
+
/** Reject button on a tool awaiting human approval (default: "Reject") */
|
|
37
|
+
rejectTool?: string;
|
|
38
|
+
/** Short suffix for tokens-per-second perf chip (default: "tok/s") */
|
|
39
|
+
tokensPerSecondLabel?: string;
|
|
40
|
+
/** Aria-label / tooltip for the message info ("i") action button (default: "Details") */
|
|
41
|
+
messageInfo?: string;
|
|
42
|
+
/** Default title for a new conversation (default: "New Chat") */
|
|
43
|
+
newChat: string;
|
|
44
|
+
/** Aria-label for the delete conversation button (default: "Delete conversation") */
|
|
45
|
+
deleteConversation: string;
|
|
46
|
+
/** Aria-label for the archive conversation button (default: "Archive conversation") */
|
|
47
|
+
archiveConversation?: string;
|
|
48
|
+
/** Aria-label for the unarchive conversation button (default: "Unarchive conversation") */
|
|
49
|
+
unarchiveConversation?: string;
|
|
50
|
+
/** Direction of the text (ltr or rtl) - defaults to ltr */
|
|
51
|
+
direction?: 'ltr' | 'rtl';
|
|
52
|
+
/** Allow extensions for plugins */
|
|
53
|
+
[key: string]: string | undefined;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Default English Locale (Zero-dependency)
|
|
57
|
+
* Hardcoded to ensure the core works out-of-the-box.
|
|
58
|
+
*/
|
|
59
|
+
export declare const DEFAULT_LOCALE: AparteLocale;
|
|
60
|
+
//# sourceMappingURL=locale.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locale.d.ts","sourceRoot":"","sources":["../../src/config/locale.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,YAAY;IAEzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IAGnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IAGd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAGhB,GAAG,EAAE,MAAM,CAAC;IAGZ,IAAI,EAAE,MAAM,CAAC;IAGb,oEAAoE;IACpE,YAAY,EAAE,MAAM,CAAC;IACrB,+EAA+E;IAC/E,iBAAiB,EAAE,MAAM,CAAC;IAG1B,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IAGvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,yFAAyF;IACzF,WAAW,CAAC,EAAE,MAAM,CAAC;IAGrB,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAC;IAChB,qFAAqF;IACrF,kBAAkB,EAAE,MAAM,CAAC;IAC3B,uFAAuF;IACvF,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,2FAA2F;IAC3F,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAG/B,2DAA2D;IAC3D,SAAS,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAE1B,mCAAmC;IACnC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACrC;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,YAkC5B,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zero-dependency HTML sanitizer for provider output.
|
|
3
|
+
*
|
|
4
|
+
* Aparte renders LLM-authored content: a markdown or highlight provider turns the
|
|
5
|
+
* assistant's text into HTML that is then injected via `innerHTML`. Prompt
|
|
6
|
+
* injection can make a model emit arbitrary markup (`<img onerror=…>`,
|
|
7
|
+
* `<script>`, `javascript:` URLs), so that HTML is **untrusted** and must be
|
|
8
|
+
* scrubbed before it touches the DOM.
|
|
9
|
+
*
|
|
10
|
+
* This is an allowlist sanitizer built on the browser's own parser: the HTML is
|
|
11
|
+
* parsed into an inert document (scripts never execute during
|
|
12
|
+
* `DOMParser.parseFromString`), the tree is rebuilt keeping only known-safe tags
|
|
13
|
+
* and attributes, then re-serialized. It is deliberately conservative and covers
|
|
14
|
+
* the realistic threat model (LLM-emitted markup). For hardened, audited
|
|
15
|
+
* coverage, register DOMPurify via `AparteConfig.setHtmlSanitizer`.
|
|
16
|
+
*/
|
|
17
|
+
export type AparteSanitizer = (html: string) => string;
|
|
18
|
+
/**
|
|
19
|
+
* True when a URL is safe to place in a `href`/`src` attribute. Exported so a
|
|
20
|
+
* streaming renderer (which bypasses the one-shot `sanitizeHtml`) can apply the
|
|
21
|
+
* same URL policy live. `tag` is the host element ('a', 'img', …) — `data:image`
|
|
22
|
+
* URLs are only allowed on `img`.
|
|
23
|
+
*/
|
|
24
|
+
export declare function isSafeUrl(value: string, tag: string): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* The built-in sanitizer. Parses `html` with the platform DOMParser, rebuilds an
|
|
27
|
+
* allowlisted tree, and re-serializes it. Falls back to a regex scrub only when
|
|
28
|
+
* no DOMParser exists (non-browser runtime).
|
|
29
|
+
*/
|
|
30
|
+
export declare const defaultSanitizer: AparteSanitizer;
|
|
31
|
+
//# sourceMappingURL=sanitize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/config/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;AA0DvD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAQ7D;AAkGD;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,eAY9B,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sibling-Nav Renderer
|
|
3
|
+
*
|
|
4
|
+
* Replace the branch position indicator — the default `‹ N / M ›` counter between
|
|
5
|
+
* the prev/next arrows — e.g. with a row of dots. Return an HTML **string**
|
|
6
|
+
* (multiple roots allowed, set via innerHTML) or a single **HTMLElement**
|
|
7
|
+
* (charter §6 render hooks: `string | HTMLElement`). Called whenever the active
|
|
8
|
+
* sibling / count changes.
|
|
9
|
+
*
|
|
10
|
+
* The prev/next arrows and their behavior (dispatching `aparte-branch-navigate`) are
|
|
11
|
+
* kept — this hook customizes only the indicator. For click-to-jump navigation,
|
|
12
|
+
* dispatch your own events / use the imperative API from your rendered output.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* AparteConfig.setSiblingNavRenderer(({ count, index }) =>
|
|
16
|
+
* Array.from({ length: count }, (_, i) =>
|
|
17
|
+
* `<span class="dot${i === index ? ' active' : ''}"></span>`).join(''));
|
|
18
|
+
*
|
|
19
|
+
* @param ctx.count - Total number of siblings (> 1 when a picker shows).
|
|
20
|
+
* @param ctx.index - 0-based index of the active sibling.
|
|
21
|
+
* @returns HTML string or a DOM element for the indicator.
|
|
22
|
+
*/
|
|
23
|
+
export type AparteSiblingNavRenderer = (ctx: {
|
|
24
|
+
count: number;
|
|
25
|
+
index: number;
|
|
26
|
+
}) => string | HTMLElement;
|
|
27
|
+
//# sourceMappingURL=sibling-nav-renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sibling-nav-renderer.d.ts","sourceRoot":"","sources":["../../src/config/sibling-nav-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,GAAG,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,KAAK,MAAM,GAAG,WAAW,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skeleton Provider Interface
|
|
3
|
+
*
|
|
4
|
+
* Defines the contract for skeleton/loading state plugins.
|
|
5
|
+
* Returns HTML strings for various loading states.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* // Register a skeleton provider (e.g. an Angular ngx-skeleton-loader bridge)
|
|
9
|
+
* AparteConfig.setSkeletonProvider({
|
|
10
|
+
* message: () => '<ngx-skeleton-loader count="3"></ngx-skeleton-loader>',
|
|
11
|
+
* code: () => '<ngx-skeleton-loader appearance="line" count="5"></ngx-skeleton-loader>',
|
|
12
|
+
* // ...
|
|
13
|
+
* });
|
|
14
|
+
*/
|
|
15
|
+
/** Skeleton types available in the provider */
|
|
16
|
+
export type AparteSkeletonType = 'message' | 'code' | 'thinking' | 'input' | 'list' | 'text';
|
|
17
|
+
export interface AparteSkeletonProvider {
|
|
18
|
+
/** Get skeleton HTML for a specific type */
|
|
19
|
+
getSkeleton: (type: AparteSkeletonType) => string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Minimal fallback skeletons - zero CSS animations, just structure
|
|
23
|
+
* Used when no skeleton plugin is installed
|
|
24
|
+
*/
|
|
25
|
+
export declare const DEFAULT_SKELETON_FALLBACKS: Record<AparteSkeletonType, string>;
|
|
26
|
+
//# sourceMappingURL=skeleton-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skeleton-provider.d.ts","sourceRoot":"","sources":["../../src/config/skeleton-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,+CAA+C;AAC/C,MAAM,MAAM,kBAAkB,GACxB,SAAS,GACT,MAAM,GACN,UAAU,GACV,OAAO,GACP,MAAM,GACN,MAAM,CAAC;AAEb,MAAM,WAAW,sBAAsB;IACnC,4CAA4C;IAC5C,WAAW,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,MAAM,CAAC;CACrD;AAED;;;GAGG;AACH,eAAO,MAAM,0BAA0B,EAAE,MAAM,CAAC,kBAAkB,EAAE,MAAM,CAOzE,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Status Renderer
|
|
3
|
+
*
|
|
4
|
+
* Replace the typing indicator's inner markup — the default is an assistant
|
|
5
|
+
* avatar slot + animated dots + optional text. Return an HTML **string** or a
|
|
6
|
+
* ready **HTMLElement** (charter §6 render hooks: `string | HTMLElement`). The
|
|
7
|
+
* `<aparte-chat-status>` container keeps owning show/hide (via the `visible`
|
|
8
|
+
* attribute) and the accessible name, so you supply only the visual.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* // A custom spinner, driven by the typing text.
|
|
12
|
+
* AparteConfig.setStatusRenderer((text) => {
|
|
13
|
+
* const el = document.createElement('div');
|
|
14
|
+
* el.className = 'my-typing';
|
|
15
|
+
* el.textContent = text;
|
|
16
|
+
* return el;
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* @param text - The typing text (from the `text` attribute, default "Typing").
|
|
20
|
+
* @returns HTML string or a DOM element to place inside the status container.
|
|
21
|
+
*/
|
|
22
|
+
export type AparteStatusRenderer = (text: string) => string | HTMLElement;
|
|
23
|
+
//# sourceMappingURL=status-renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status-renderer.d.ts","sourceRoot":"","sources":["../../src/config/status-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,WAAW,CAAC"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import type { AparteMessage } from '../types/index.js';
|
|
2
|
+
import type { ConversationManager } from './conversation-manager.js';
|
|
3
|
+
import type { ExportedMessageRepository } from '../runtime/message-repository.js';
|
|
4
|
+
/**
|
|
5
|
+
* Abstract binding between a chat UI and the conversation lifecycle.
|
|
6
|
+
*
|
|
7
|
+
* Each framework wrapper (Angular, React, Vue, Svelte) provides an
|
|
8
|
+
* implementation that knows how to mutate its own message list. The
|
|
9
|
+
* controller orchestrates loading, persistence and abort using only this
|
|
10
|
+
* interface, keeping the conversation engine fully framework-agnostic.
|
|
11
|
+
*/
|
|
12
|
+
export interface AparteChatBinding {
|
|
13
|
+
/** Stable id of the host element (used as `targetId` for scoped events). */
|
|
14
|
+
readonly hostId: string;
|
|
15
|
+
/** The element that emits/receives `aparte-send` and `aparte-path-changed`. */
|
|
16
|
+
readonly host: HTMLElement;
|
|
17
|
+
/** Replace the entire message list (used when switching conversations). */
|
|
18
|
+
setMessages(messages: AparteMessage[]): void;
|
|
19
|
+
/** Append a single message (used for the optimistic user-msg on send). */
|
|
20
|
+
appendMessage(message: AparteMessage): void;
|
|
21
|
+
/** Read the current message list. */
|
|
22
|
+
getMessages(): AparteMessage[];
|
|
23
|
+
/** Clear all messages (e.g. when starting a new conversation). */
|
|
24
|
+
clearMessages(): void;
|
|
25
|
+
/**
|
|
26
|
+
* Export the full conversation tree for persistence.
|
|
27
|
+
* Optional: only available when the binding wraps a `MessageRepository`
|
|
28
|
+
* (e.g. the vanilla viewport). Returns `undefined` when not supported.
|
|
29
|
+
*/
|
|
30
|
+
exportTree?(): ExportedMessageRepository | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Import a previously-persisted tree snapshot, restoring full branch
|
|
33
|
+
* topology. Called by the controller after `setMessages` (which handles
|
|
34
|
+
* cleanup) when the loaded conversation carries a `tree` field.
|
|
35
|
+
* Optional: falls back to the flat `setMessages` load when absent.
|
|
36
|
+
*/
|
|
37
|
+
importTree?(tree: ExportedMessageRepository): void;
|
|
38
|
+
}
|
|
39
|
+
export interface AparteConversationControllerOptions {
|
|
40
|
+
/**
|
|
41
|
+
* Conversation manager. If omitted, the controller resolves it from
|
|
42
|
+
* `AparteConfig.getConversationManager()` when first needed.
|
|
43
|
+
*/
|
|
44
|
+
manager?: ConversationManager;
|
|
45
|
+
/**
|
|
46
|
+
* Called whenever a new conversation is created lazily (on first user
|
|
47
|
+
* message in an empty thread). Useful for the parent app to sync the URL.
|
|
48
|
+
*/
|
|
49
|
+
onConversationCreated?: (id: string) => void;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Connects an `AparteChatBinding` to a `ConversationManager`.
|
|
53
|
+
*
|
|
54
|
+
* Responsibilities:
|
|
55
|
+
* - Load messages when `setConversationId(id)` is called.
|
|
56
|
+
* - Lazily create a conversation on the first user `aparte-send` if none active.
|
|
57
|
+
* - Persist updates triggered by `aparte-path-changed` (branch nav, retry, edit).
|
|
58
|
+
* - Dispatch `aparte-abort` when the active conversation changes mid-stream.
|
|
59
|
+
*
|
|
60
|
+
* Usage:
|
|
61
|
+
* ```ts
|
|
62
|
+
* const controller = new AparteConversationController(binding);
|
|
63
|
+
* const stop = controller.bind();
|
|
64
|
+
* controller.setConversationId('abc-123');
|
|
65
|
+
* // …
|
|
66
|
+
* stop();
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export declare class AparteConversationController {
|
|
70
|
+
private _binding;
|
|
71
|
+
private _options;
|
|
72
|
+
private _activeId;
|
|
73
|
+
private _isStreaming;
|
|
74
|
+
private _isLoadingConversation;
|
|
75
|
+
private _ensureInFlight;
|
|
76
|
+
private _onSendCapture;
|
|
77
|
+
private _onPathChanged;
|
|
78
|
+
private _onMessageStart;
|
|
79
|
+
private _onMessageDone;
|
|
80
|
+
private _onMessageError;
|
|
81
|
+
private _onMessageAborted;
|
|
82
|
+
private _onSelectConversation;
|
|
83
|
+
private _unsubscribeManager;
|
|
84
|
+
constructor(binding: AparteChatBinding, options?: AparteConversationControllerOptions);
|
|
85
|
+
/** The current active conversation id (null when none selected). */
|
|
86
|
+
get activeId(): string | null;
|
|
87
|
+
/**
|
|
88
|
+
* Lazily resolve the conversation manager. Returns `undefined` if none is
|
|
89
|
+
* registered — the controller then runs in degraded mode: optimistic UI
|
|
90
|
+
* still works (user message is appended) but no persistence happens. This
|
|
91
|
+
* keeps backward compatibility with hosts that haven't opted into the
|
|
92
|
+
* conversation lifecycle yet.
|
|
93
|
+
*/
|
|
94
|
+
private _manager;
|
|
95
|
+
/**
|
|
96
|
+
* Attach event listeners to the binding host. Returns an unbind function.
|
|
97
|
+
*/
|
|
98
|
+
bind(): () => void;
|
|
99
|
+
/** Detach event listeners. */
|
|
100
|
+
unbind(): void;
|
|
101
|
+
/**
|
|
102
|
+
* Switch to (or clear) the active conversation.
|
|
103
|
+
* - `null`: clears the binding and deselects in the manager.
|
|
104
|
+
* - any id: loads the conversation's messages into the binding.
|
|
105
|
+
*
|
|
106
|
+
* Idempotent: calling with the current id forces a re-snapshot from the
|
|
107
|
+
* manager (handy when external mutations could have desynchronised the
|
|
108
|
+
* binding, or when a user re-selects the already-active conv from a
|
|
109
|
+
* sidebar). Streams are only aborted on an actual id change so a same-id
|
|
110
|
+
* reload never kills an in-flight response.
|
|
111
|
+
*/
|
|
112
|
+
setConversationId(id: string | null): Promise<void>;
|
|
113
|
+
/**
|
|
114
|
+
* Snapshot the binding's current messages and push them to the manager.
|
|
115
|
+
* No-op when there is no active conversation or no manager registered.
|
|
116
|
+
* Idempotent: safe to call multiple times in a row.
|
|
117
|
+
*
|
|
118
|
+
* Any message whose status is 'streaming' or 'pending' at persist-time is
|
|
119
|
+
* normalised to 'completed' so that reloading the conversation does not
|
|
120
|
+
* re-enter streaming UI (caret, spinner, no action buttons) for content
|
|
121
|
+
* that was partially written before a switch or component destruction.
|
|
122
|
+
*/
|
|
123
|
+
private _persistActive;
|
|
124
|
+
private _ensureConversationAndPersist;
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=conversation-controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-controller.d.ts","sourceRoot":"","sources":["../../src/conversations/conversation-controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAoB,MAAM,mBAAmB,CAAC;AACzE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAErE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAGlF;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAC9B,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,+EAA+E;IAC/E,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,2EAA2E;IAC3E,WAAW,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;IAC7C,0EAA0E;IAC1E,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC;IAC5C,qCAAqC;IACrC,WAAW,IAAI,aAAa,EAAE,CAAC;IAC/B,kEAAkE;IAClE,aAAa,IAAI,IAAI,CAAC;IACtB;;;;OAIG;IACH,UAAU,CAAC,IAAI,yBAAyB,GAAG,SAAS,CAAC;IACrD;;;;;OAKG;IACH,UAAU,CAAC,CAAC,IAAI,EAAE,yBAAyB,GAAG,IAAI,CAAC;CACtD;AAED,MAAM,WAAW,mCAAmC;IAChD;;;OAGG;IACH,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B;;;OAGG;IACH,qBAAqB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAChD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,4BAA4B;IACrC,OAAO,CAAC,QAAQ,CAAoB;IACpC,OAAO,CAAC,QAAQ,CAAsC;IACtD,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,sBAAsB,CAAS;IACvC,OAAO,CAAC,eAAe,CAAgC;IAEvD,OAAO,CAAC,cAAc,CAAqC;IAC3D,OAAO,CAAC,cAAc,CAAqC;IAC3D,OAAO,CAAC,eAAe,CAA6B;IACpD,OAAO,CAAC,cAAc,CAA6B;IACnD,OAAO,CAAC,eAAe,CAA6B;IACpD,OAAO,CAAC,iBAAiB,CAA6B;IACtD,OAAO,CAAC,qBAAqB,CAAqC;IAClE,OAAO,CAAC,mBAAmB,CAA6B;gBAE5C,OAAO,EAAE,iBAAiB,EAAE,OAAO,GAAE,mCAAwC;IAKzF,oEAAoE;IACpE,IAAI,QAAQ,IAAI,MAAM,GAAG,IAAI,CAE5B;IAED;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ;IAMhB;;OAEG;IACH,IAAI,IAAI,MAAM,IAAI;IAoIlB,8BAA8B;IAC9B,MAAM,IAAI,IAAI;IA2Cd;;;;;;;;;;OAUG;IACG,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAoHzD;;;;;;;;;OASG;IACH,OAAO,CAAC,cAAc;YA2BR,6BAA6B;CAiD9C"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { AparteMessage } from '../types/index.js';
|
|
2
|
+
import type { AparteConversation, AparteStorageAdapter } from './types.js';
|
|
3
|
+
import type { ExportedMessageRepository } from '../runtime/message-repository.js';
|
|
4
|
+
type Listener = (conversations: AparteConversation[]) => void;
|
|
5
|
+
export interface ConversationManagerOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Opt-in history retention. When set, `updateMessages()` trims a persisted
|
|
8
|
+
* conversation to at most `maxMessages` on the active path (dropping the
|
|
9
|
+
* oldest history and the branches hanging off it) before writing to storage.
|
|
10
|
+
* Omit for unbounded history (the default) — retention is a deliberate
|
|
11
|
+
* consumer choice, never silent.
|
|
12
|
+
*/
|
|
13
|
+
retention?: {
|
|
14
|
+
maxMessages: number;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Pure retention transform: keep at most `maxMessages` on the active path.
|
|
19
|
+
*
|
|
20
|
+
* Keeps the subtree rooted at the new-oldest kept message (so recent history AND
|
|
21
|
+
* recent branches survive) and drops everything before it. Exported for testing.
|
|
22
|
+
*/
|
|
23
|
+
export declare function applyRetention(messages: AparteMessage[], tree: ExportedMessageRepository | undefined, maxMessages: number): {
|
|
24
|
+
messages: AparteMessage[];
|
|
25
|
+
tree: ExportedMessageRepository | undefined;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Framework-agnostic conversation manager.
|
|
29
|
+
*
|
|
30
|
+
* Usage:
|
|
31
|
+
* ```ts
|
|
32
|
+
* const manager = new ConversationManager(myAdapter);
|
|
33
|
+
* await manager.init(); // load from storage
|
|
34
|
+
* const conv = await manager.createNew(); // returns new AparteConversation
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* The manager emits synchronous notifications to registered listeners on every
|
|
38
|
+
* mutation so framework wrappers (Angular signals, Vue reactive, etc.) can
|
|
39
|
+
* react without polling.
|
|
40
|
+
*/
|
|
41
|
+
export declare class ConversationManager {
|
|
42
|
+
private _adapter;
|
|
43
|
+
private _conversations;
|
|
44
|
+
private _activeId;
|
|
45
|
+
private _listeners;
|
|
46
|
+
private _initialized;
|
|
47
|
+
private _retention;
|
|
48
|
+
constructor(adapter: AparteStorageAdapter, options?: ConversationManagerOptions);
|
|
49
|
+
/** Load all conversations from the adapter. Call once at app startup. */
|
|
50
|
+
init(): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Whether `init()` has completed at least once. Consumers use this to
|
|
53
|
+
* distinguish "manager still hydrating from storage" from "manager
|
|
54
|
+
* hydrated, conversations is genuinely empty". The conversation-controller
|
|
55
|
+
* relies on this to defer clearing the binding during the IndexedDB
|
|
56
|
+
* hydration window (Angular APP_INITIALIZER race).
|
|
57
|
+
*/
|
|
58
|
+
get initialized(): boolean;
|
|
59
|
+
get conversations(): AparteConversation[];
|
|
60
|
+
get activeId(): string | null;
|
|
61
|
+
get active(): AparteConversation | null;
|
|
62
|
+
/** Active conversations (not archived), newest first. */
|
|
63
|
+
get activeConversations(): AparteConversation[];
|
|
64
|
+
/** Archived conversations, newest first. */
|
|
65
|
+
get archivedConversations(): AparteConversation[];
|
|
66
|
+
/** Create a new empty conversation, persist it, and make it active. */
|
|
67
|
+
createNew(title?: string): Promise<AparteConversation>;
|
|
68
|
+
/** Switch active conversation without touching storage. */
|
|
69
|
+
select(id: string): void;
|
|
70
|
+
/** Deselect the active conversation (no conv selected). */
|
|
71
|
+
clearActive(): void;
|
|
72
|
+
/** Append a message to a conversation. Auto-generates title from first user message. */
|
|
73
|
+
addMessage(convId: string, msg: AparteMessage): Promise<void>;
|
|
74
|
+
/**
|
|
75
|
+
* Replace the flat active-path messages and optionally the full branch tree.
|
|
76
|
+
* `messages` is always written (active path, for sidebar/title/compat).
|
|
77
|
+
* `tree` is written when provided — it carries the full branching topology.
|
|
78
|
+
*/
|
|
79
|
+
updateMessages(convId: string, messages: AparteMessage[], tree?: ExportedMessageRepository): Promise<void>;
|
|
80
|
+
/** Permanently delete a conversation. */
|
|
81
|
+
delete(id: string): Promise<void>;
|
|
82
|
+
/** Archive a conversation (soft-delete). */
|
|
83
|
+
archive(id: string): Promise<void>;
|
|
84
|
+
/** Restore an archived conversation. */
|
|
85
|
+
unarchive(id: string): Promise<void>;
|
|
86
|
+
/** Update the title manually. The full input is preserved — UI surfaces
|
|
87
|
+
* (sidebar list, topbar) are responsible for visual truncation via CSS
|
|
88
|
+
* (`min-w-0` + `truncate`). Auto-titles produced internally by
|
|
89
|
+
* `_autoTitle()` remain capped at a sensible length on input. */
|
|
90
|
+
updateTitle(id: string, title: string): Promise<void>;
|
|
91
|
+
subscribe(listener: Listener): () => void;
|
|
92
|
+
private _find;
|
|
93
|
+
private _replace;
|
|
94
|
+
private _notify;
|
|
95
|
+
private _autoTitle;
|
|
96
|
+
}
|
|
97
|
+
export {};
|
|
98
|
+
//# sourceMappingURL=conversation-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-manager.d.ts","sourceRoot":"","sources":["../../src/conversations/conversation-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAGlF,KAAK,QAAQ,GAAG,CAAC,aAAa,EAAE,kBAAkB,EAAE,KAAK,IAAI,CAAC;AAE9D,MAAM,WAAW,0BAA0B;IACvC;;;;;;OAMG;IACH,SAAS,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;CACvC;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC1B,QAAQ,EAAE,aAAa,EAAE,EACzB,IAAI,EAAE,yBAAyB,GAAG,SAAS,EAC3C,WAAW,EAAE,MAAM,GACpB;IAAE,QAAQ,EAAE,aAAa,EAAE,CAAC;IAAC,IAAI,EAAE,yBAAyB,GAAG,SAAS,CAAA;CAAE,CAgC5E;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,mBAAmB;IAC5B,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,UAAU,CAAwC;gBAE9C,OAAO,EAAE,oBAAoB,EAAE,OAAO,CAAC,EAAE,0BAA0B;IAO/E,yEAAyE;IACnE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B;;;;;;OAMG;IACH,IAAI,WAAW,IAAI,OAAO,CAEzB;IAID,IAAI,aAAa,IAAI,kBAAkB,EAAE,CAExC;IAED,IAAI,QAAQ,IAAI,MAAM,GAAG,IAAI,CAE5B;IAED,IAAI,MAAM,IAAI,kBAAkB,GAAG,IAAI,CAGtC;IAED,yDAAyD;IACzD,IAAI,mBAAmB,IAAI,kBAAkB,EAAE,CAI9C;IAED,4CAA4C;IAC5C,IAAI,qBAAqB,IAAI,kBAAkB,EAAE,CAIhD;IAID,uEAAuE;IACjE,SAAS,CAAC,KAAK,SAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAiBhE,2DAA2D;IAC3D,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAMxB,2DAA2D;IAC3D,WAAW,IAAI,IAAI;IAKnB,wFAAwF;IAClF,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBnE;;;;OAIG;IACG,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,EAAE,IAAI,CAAC,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BhH,yCAAyC;IACnC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOvC,4CAA4C;IACtC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBxC,wCAAwC;IAClC,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB1C;;;sEAGkE;IAC5D,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW3D,SAAS,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,IAAI;IAOzC,OAAO,CAAC,KAAK;IAIb,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,OAAO;IAcf,OAAO,CAAC,UAAU;CAQrB"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { AparteConversation, AparteConversationMeta, AparteStorageAdapter, AparteMemoryFact, AparteArtifactRow, AparteAttachmentRow, } from './types.js';
|
|
2
|
+
export { APARTE_CONVERSATION_SCHEMA_VERSION } from './types.js';
|
|
3
|
+
export { ConversationManager, applyRetention, type ConversationManagerOptions } from './conversation-manager.js';
|
|
4
|
+
export { AparteConversationController, type AparteChatBinding, type AparteConversationControllerOptions, } from './conversation-controller.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/conversations/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACR,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,GACtB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,kCAAkC,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,KAAK,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACjH,OAAO,EACH,4BAA4B,EAC5B,KAAK,iBAAiB,EACtB,KAAK,mCAAmC,GAC3C,MAAM,8BAA8B,CAAC"}
|