@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
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 aparté
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# @aparte/core
|
|
2
|
+
|
|
3
|
+
Framework-agnostic AI-chat UI as **vanilla Web Components** — zero runtime dependencies,
|
|
4
|
+
ESM-only, usable in any framework or none.
|
|
5
|
+
|
|
6
|
+
> 🚧 **Pre-alpha** — not yet published to npm. Part of the
|
|
7
|
+
> [aparté](https://github.com/apartejs/aparte) monorepo.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @aparte/core
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick start
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import '@aparte/core'; // registers the <aparte-*> custom elements
|
|
19
|
+
import '@aparte/core/styles.css'; // theme variables + component styles
|
|
20
|
+
import { registerDefaultRenderers, AparteClient } from '@aparte/core';
|
|
21
|
+
|
|
22
|
+
registerDefaultRenderers();
|
|
23
|
+
// Drop the shell in your HTML: <aparte-chat placeholder="Ask anything…"></aparte-chat>
|
|
24
|
+
|
|
25
|
+
// Give it a provider + transport (see the docs), then construct the client and call
|
|
26
|
+
// .start() — it listens for the composer's events and streams the reply into the
|
|
27
|
+
// conversation. (Without .start(), no listeners are attached and nothing streams.)
|
|
28
|
+
new AparteClient().start();
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## What's in it
|
|
32
|
+
|
|
33
|
+
- **`<aparte-chat>`** — a drop-in shell (viewport + composer), or compose the primitives
|
|
34
|
+
yourself (`<aparte-chat-viewport>`, `<aparte-composer>`, `<aparte-chat-bubble>`, …).
|
|
35
|
+
- **`AparteClient`** — an optional driver that turns composer events into a streamed reply.
|
|
36
|
+
Retry / edit fork the conversation into **branches** with a built-in `‹ 1/2 ›` picker.
|
|
37
|
+
- **Transports** — `DirectTransport` (browser → provider, BYOK / local model) or
|
|
38
|
+
`BackendTransport` (browser → your endpoint, API key stays server-side).
|
|
39
|
+
- **Theming** — restyle everything through `--aparte-*` CSS variables (Light DOM, no forking).
|
|
40
|
+
- **Customization** — icons, render hooks, and a zoned action registry via `AparteConfig`.
|
|
41
|
+
|
|
42
|
+
Zero runtime dependencies: Markdown, syntax highlighting, etc. are **opt-in** providers you inject.
|
|
43
|
+
ESM-only (CJS consumers use `await import()`).
|
|
44
|
+
|
|
45
|
+
## Docs
|
|
46
|
+
|
|
47
|
+
Guides + a generated API reference live in the monorepo under
|
|
48
|
+
[`apps/docs`](https://github.com/apartejs/aparte/tree/main/apps/docs): Getting started, Theming,
|
|
49
|
+
Customization, Conversations & branching, and The agent engine.
|
|
50
|
+
|
|
51
|
+
## License
|
|
52
|
+
|
|
53
|
+
MIT
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
import { AparteConfigClass } from '../config/aparte-config.js';
|
|
2
|
+
import type { AparteStreamRunner } from './stream-adapter.js';
|
|
3
|
+
import type { AparteMessage } from '../types/index.js';
|
|
4
|
+
import { AparteChatRequest, AparteChatMessage } from '../types/chat.js';
|
|
5
|
+
/**
|
|
6
|
+
* Resolves a human-in-the-loop tool approval for a `needsApproval` tool call.
|
|
7
|
+
* Resolves `{ approved, payload? }`; the `signal` aborts a pending decision.
|
|
8
|
+
*/
|
|
9
|
+
export type AparteToolApprovalResolver = (toolCallId: string, signal: AbortSignal) => Promise<{
|
|
10
|
+
approved: boolean;
|
|
11
|
+
payload?: unknown;
|
|
12
|
+
}>;
|
|
13
|
+
/**
|
|
14
|
+
* Decides how a conversation is compacted: which messages are summarized away
|
|
15
|
+
* (`drop`) and which are preserved verbatim (`keep`). Pure — no LLM call.
|
|
16
|
+
*
|
|
17
|
+
* The default selector drops the whole history (summarize everything, replace
|
|
18
|
+
* all), which is the built-in behaviour. Inject a budget-aware selector (e.g.
|
|
19
|
+
* wrapping `@aparte/engine`'s `compactConversation`) so the compaction badge and
|
|
20
|
+
* the `compact()` action share one selection and only the old turns are sent to
|
|
21
|
+
* the summarizer — the budget is closed over by the consumer, not core's to know.
|
|
22
|
+
*/
|
|
23
|
+
export type AparteCompactionSelector = (messages: AparteMessage[]) => {
|
|
24
|
+
keep: AparteMessage[];
|
|
25
|
+
drop: AparteMessage[];
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Configuration options for AparteClient
|
|
29
|
+
*/
|
|
30
|
+
export interface AparteClientOptions {
|
|
31
|
+
/**
|
|
32
|
+
* Function to resolve API keys for a given provider.
|
|
33
|
+
* Can return a string (key) or a full configuration object.
|
|
34
|
+
*/
|
|
35
|
+
keyResolver?: (providerId: string) => string | Record<string, string> | Promise<string | Record<string, string> | undefined | null> | undefined | null;
|
|
36
|
+
/**
|
|
37
|
+
* Custom human-in-the-loop approval resolver for tools marked
|
|
38
|
+
* `needsApproval`. Defaults to a global `document` `aparte-tool-decision`
|
|
39
|
+
* listener (the built-in Approve/Reject gate). Inject this to run multiple
|
|
40
|
+
* isolated clients on one page, or to drive approval from a headless source
|
|
41
|
+
* (CLI / webhook) with no DOM.
|
|
42
|
+
*/
|
|
43
|
+
approvalResolver?: AparteToolApprovalResolver;
|
|
44
|
+
/**
|
|
45
|
+
* Custom compaction selection strategy. Defaults to dropping the entire
|
|
46
|
+
* history (summarize all, replace all — the built-in behaviour). Inject a
|
|
47
|
+
* budget-aware selector so only old turns are summarized and recent ones are
|
|
48
|
+
* kept verbatim. See {@link AparteCompactionSelector}.
|
|
49
|
+
*/
|
|
50
|
+
compactionSelector?: AparteCompactionSelector;
|
|
51
|
+
/**
|
|
52
|
+
* Optional headless stream-loop runner. When set, `_streamLoop` delegates the
|
|
53
|
+
* agentic loop to it and renders via the core adapter
|
|
54
|
+
* ({@link createStreamAdapter}); when absent, the built-in inline loop runs.
|
|
55
|
+
* Inject `@aparte/engine`'s `runStreamAgent` here so a backend/cloud path
|
|
56
|
+
* shares one tested loop — core stays the zero-dep leaf and never imports
|
|
57
|
+
* engine. Same injection pattern as {@link approvalResolver} /
|
|
58
|
+
* {@link compactionSelector}. See {@link AparteStreamRunner}.
|
|
59
|
+
*/
|
|
60
|
+
streamRunner?: AparteStreamRunner;
|
|
61
|
+
/**
|
|
62
|
+
* Optional request interceptor to modify the chat request before sending.
|
|
63
|
+
*/
|
|
64
|
+
requestInterceptor?: (request: AparteChatRequest) => AparteChatRequest | Promise<AparteChatRequest>;
|
|
65
|
+
/**
|
|
66
|
+
* Whether to automatically register default segment renderers.
|
|
67
|
+
* @default true
|
|
68
|
+
*/
|
|
69
|
+
autoRegister?: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Conversation history strategy:
|
|
72
|
+
* - 'viewport' (default) — collects completed messages from the viewport
|
|
73
|
+
* - 'none' — sends only the current message (original behavior)
|
|
74
|
+
* - function — custom: receives viewport messages, returns AparteChatMessage[]
|
|
75
|
+
*/
|
|
76
|
+
history?: 'viewport' | 'none' | ((viewportMessages: AparteMessage[]) => AparteChatMessage[]);
|
|
77
|
+
/**
|
|
78
|
+
* Optional resolver that returns the host element exposing `appendMessage`.
|
|
79
|
+
* Use this when the default event-bubble walk cannot reach the host
|
|
80
|
+
* (e.g. Angular re-renders detach the input element mid-flight).
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* targetResolver: () => document.querySelector('aparte-chat')
|
|
84
|
+
*/
|
|
85
|
+
targetResolver?: () => HTMLElement | null;
|
|
86
|
+
/**
|
|
87
|
+
* Scope this client to a specific target element id.
|
|
88
|
+
* When set, the client will only handle `aparte-send`, `aparte-retry`, `aparte-edit`
|
|
89
|
+
* and `aparte-abort` events whose `detail.targetId` matches this id.
|
|
90
|
+
* This allows multiple AparteClient instances (one per conversation) to coexist
|
|
91
|
+
* on the same page without interfering with each other.
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* // Two independent conversations:
|
|
95
|
+
* new AparteClient({ scopeToTargetId: 'chat-left' }).start();
|
|
96
|
+
* new AparteClient({ scopeToTargetId: 'chat-right' }).start();
|
|
97
|
+
*/
|
|
98
|
+
scopeToTargetId?: string;
|
|
99
|
+
/**
|
|
100
|
+
* Maximum number of agentic tool-call loop turns before the loop is forcibly
|
|
101
|
+
* stopped and an error segment is shown. Prevents infinite loops.
|
|
102
|
+
* Individual tools can override this via `AparteTool.maxTurns`.
|
|
103
|
+
* @default 10
|
|
104
|
+
*/
|
|
105
|
+
maxTurns?: number;
|
|
106
|
+
/**
|
|
107
|
+
* Controls which files attached by the user are injected as raw content
|
|
108
|
+
* parts in the LLM request.
|
|
109
|
+
*
|
|
110
|
+
* - `'all'` (default) — images as base64, text files as code-fenced text
|
|
111
|
+
* - `'images-only'` — only images are injected; text/binary documents
|
|
112
|
+
* are left for the application layer (e.g. a RAG pipeline) to handle
|
|
113
|
+
* - `'none'` — no files are injected as content parts; ALL file
|
|
114
|
+
* types (including images) are routed to the application layer. Used
|
|
115
|
+
* when images go through a captioning pipeline before RAG ingest, so
|
|
116
|
+
* the chat context only ever sees retrieved text — never raw image
|
|
117
|
+
* bytes. Saves bytes on every turn and matches the offline-first
|
|
118
|
+
* intent (read file once at upload, retrieve text-only forever after).
|
|
119
|
+
*
|
|
120
|
+
* Set `'images-only'` when a `requestInterceptor` retrieves relevant
|
|
121
|
+
* document chunks and injects them as a system message instead, to avoid
|
|
122
|
+
* flooding the context window with full file contents.
|
|
123
|
+
*/
|
|
124
|
+
rawFileInject?: 'all' | 'images-only' | 'none';
|
|
125
|
+
/**
|
|
126
|
+
* Config this client reads (providers, model selection, tools, system
|
|
127
|
+
* prompt). Defaults to the global `AparteConfig` singleton. Pass a host's
|
|
128
|
+
* instance config when scoping a client to one chat among several
|
|
129
|
+
* (pairs with `scopeToTargetId`).
|
|
130
|
+
*/
|
|
131
|
+
config?: AparteConfigClass;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* AparteClient
|
|
135
|
+
*
|
|
136
|
+
* The "Automatic Transmission" for Aparte.
|
|
137
|
+
* Connects the UI events (aparte-send) to the AI Providers (chat).
|
|
138
|
+
* Handles:
|
|
139
|
+
* - Listening to send events
|
|
140
|
+
* - Resolving API keys
|
|
141
|
+
* - Calling the appropriate Provider
|
|
142
|
+
* - Streaming the response back to the UI
|
|
143
|
+
* - Tool use: awaiting handlers and re-calling the provider
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```typescript
|
|
147
|
+
* const client = new AparteClient({
|
|
148
|
+
* keyResolver: (providerId) => process.env[providerId.toUpperCase() + '_KEY']
|
|
149
|
+
* });
|
|
150
|
+
* client.start();
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
153
|
+
export declare class AparteClient {
|
|
154
|
+
private _boundHandler;
|
|
155
|
+
private _boundAbortHandler;
|
|
156
|
+
private _boundCompactHandler;
|
|
157
|
+
private _boundRetryHandler;
|
|
158
|
+
private _boundEditHandler;
|
|
159
|
+
private _activeToolControllers;
|
|
160
|
+
private _isAborted;
|
|
161
|
+
/** Aborts the in-flight vendor/transport fetch when the user stops a stream. */
|
|
162
|
+
private _streamController;
|
|
163
|
+
private options;
|
|
164
|
+
/** Config read by this client — an instance config, or the global default. */
|
|
165
|
+
private readonly _config;
|
|
166
|
+
constructor(options?: AparteClientOptions);
|
|
167
|
+
/**
|
|
168
|
+
* Sets up the event listeners.
|
|
169
|
+
* This is called once in the constructor.
|
|
170
|
+
*/
|
|
171
|
+
private _setupListeners;
|
|
172
|
+
/**
|
|
173
|
+
* Start listening for aparte-send events on the window.
|
|
174
|
+
*/
|
|
175
|
+
start(): void;
|
|
176
|
+
/**
|
|
177
|
+
* Stop listening.
|
|
178
|
+
*/
|
|
179
|
+
stop(): void;
|
|
180
|
+
/**
|
|
181
|
+
* Abort the current streaming response and all active tool calls.
|
|
182
|
+
* Dispatches `aparte-message-aborted` on the target element.
|
|
183
|
+
*/
|
|
184
|
+
abort(): void;
|
|
185
|
+
/**
|
|
186
|
+
* Human-in-the-loop: wait for an `aparte-tool-decision` event matching this
|
|
187
|
+
* tool call (dispatched by the built-in Approve/Reject UI or an app-level
|
|
188
|
+
* approval surface). Resolves `{ approved, payload }` — `approved` is `true`
|
|
189
|
+
* only on an explicit approve, and `payload` carries any arbitrary data a
|
|
190
|
+
* custom approval UI attached to the decision (the built-in gate sends
|
|
191
|
+
* none). The `signal` (an AbortController registered in
|
|
192
|
+
* `_activeToolControllers`) lets `abort()` cleanly resolve a pending
|
|
193
|
+
* approval to `{ approved: false }` — there is no timeout, since a human may
|
|
194
|
+
* take any amount of time to decide.
|
|
195
|
+
*/
|
|
196
|
+
private _awaitToolDecision;
|
|
197
|
+
/**
|
|
198
|
+
* Resolve the auth for a provider: `options.keyResolver` takes precedence,
|
|
199
|
+
* then the AparteConfig key channel (`setKeyProvider`) so a key registered
|
|
200
|
+
* there reaches the request. One key source on the happy path.
|
|
201
|
+
*/
|
|
202
|
+
private _resolveAuth;
|
|
203
|
+
/**
|
|
204
|
+
* The shared tail of send / retry / edit: attach the current tools, run the
|
|
205
|
+
* request interceptor, honour `toolChoice: 'none'`, reset the abort flag,
|
|
206
|
+
* dispatch `aparte-message-start`, run the agentic `_streamLoop`, then dispatch
|
|
207
|
+
* `aparte-message-done` or route the error to the lifecycle handler.
|
|
208
|
+
*
|
|
209
|
+
* Callers own only their turn-specific prep (target resolution, history
|
|
210
|
+
* building, appending the assistant placeholder) and hand the fully-built
|
|
211
|
+
* `messages` here — one place for the provider→interceptor→toolChoice→stream
|
|
212
|
+
* sequence, so it can't drift between the three entry points.
|
|
213
|
+
*/
|
|
214
|
+
private _streamTurn;
|
|
215
|
+
/**
|
|
216
|
+
* Compact the current conversation: summarize all messages via the AI,
|
|
217
|
+
* clear the viewport, then inject the summary as a single context message.
|
|
218
|
+
*
|
|
219
|
+
* Triggered programmatically or by dispatching `window.dispatchEvent(new CustomEvent('aparte-compact'))`.
|
|
220
|
+
* Dispatches `aparte-compact-done` on window when complete, or `aparte-compact-error` on failure.
|
|
221
|
+
*/
|
|
222
|
+
compact(): Promise<void>;
|
|
223
|
+
/**
|
|
224
|
+
* Handle aparte-retry — add a sibling branch to the assistant message and re-stream
|
|
225
|
+
* using the same conversation history minus the retried reply.
|
|
226
|
+
*/
|
|
227
|
+
/**
|
|
228
|
+
* Registered tools, gated by capability: only returned when the current model
|
|
229
|
+
* declares `function_calling` support (else `[]`). Single source for the gate so
|
|
230
|
+
* send / retry / edit can't drift — the drift is exactly what shipped `tools` on
|
|
231
|
+
* the initial send while retry/edit correctly omitted them.
|
|
232
|
+
*/
|
|
233
|
+
private _toolsForCurrentModel;
|
|
234
|
+
private _handleRetry;
|
|
235
|
+
/**
|
|
236
|
+
* Handle aparte-edit — update the user message in place, truncate all subsequent
|
|
237
|
+
* messages, then re-stream a fresh assistant response.
|
|
238
|
+
*/
|
|
239
|
+
private _handleEdit;
|
|
240
|
+
/**
|
|
241
|
+
* Resolve a target element by id (from event detail.targetId) or via targetResolver / DOM scan.
|
|
242
|
+
*/
|
|
243
|
+
private _resolveTarget;
|
|
244
|
+
/**
|
|
245
|
+
* Resolve an element to a usable render target: itself when it exposes
|
|
246
|
+
* `appendMessage`, else the viewport it delegates to. The `<aparte-chat>`
|
|
247
|
+
* shell matches the host selectors/id but owns no `appendMessage` (it forwards
|
|
248
|
+
* rendering to its `.viewport`), so returning the bare shell would make
|
|
249
|
+
* send / retry / edit silently no-op. Returns null when neither can render.
|
|
250
|
+
*/
|
|
251
|
+
private _asRenderTarget;
|
|
252
|
+
/**
|
|
253
|
+
* Convert AparteMessage[] to AparteChatMessage[] for re-submission.
|
|
254
|
+
*/
|
|
255
|
+
private _messagesToChatMessages;
|
|
256
|
+
private _handleSend;
|
|
257
|
+
/**
|
|
258
|
+
* Build the initial messages array, prepending system prompts and conversation history.
|
|
259
|
+
*/
|
|
260
|
+
private _buildMessages;
|
|
261
|
+
private _toHistoryMessages;
|
|
262
|
+
private _extractText;
|
|
263
|
+
/**
|
|
264
|
+
* Convert an array of File objects to AparteContentPart[].
|
|
265
|
+
* - Images → AparteImagePart (base64 data URL)
|
|
266
|
+
* - Text files (txt, md, json, csv, xml, html, css, js, ts, …) → AparteTextPart
|
|
267
|
+
* injected as a fenced block so all models (including local) can read them.
|
|
268
|
+
* - Other binary files → silently ignored.
|
|
269
|
+
*/
|
|
270
|
+
private _filesToContentParts;
|
|
271
|
+
/**
|
|
272
|
+
* Stream loop: runs one provider.chat() call and repeats if a tool was called.
|
|
273
|
+
* Maintains a running messages array to inject tool_call / tool_result turns.
|
|
274
|
+
*/
|
|
275
|
+
/**
|
|
276
|
+
* Feed one text delta to the Claude-style `<artifact>` XML streamer. Scans for
|
|
277
|
+
* `<artifact …>` / `</artifact>`, routing chat text through the text parser and
|
|
278
|
+
* artifact content into a dedicated artifact segment (handling tags split across
|
|
279
|
+
* deltas). Mutates `xml` in place. Extracted from _streamLoop.
|
|
280
|
+
*/
|
|
281
|
+
private _feedXmlArtifactDelta;
|
|
282
|
+
/**
|
|
283
|
+
* Turn-1 forced tool call. When `toolChoice = { name, input }`
|
|
284
|
+
* (orchestrator-driven), execute the handler directly instead of consulting
|
|
285
|
+
* the LLM, render the tool segment, inject the result as `tool_result`, and
|
|
286
|
+
* strip `toolChoice` for the follow-up turn. Returns the (possibly-updated)
|
|
287
|
+
* request and whether the loop should skip to the next turn (handler missing
|
|
288
|
+
* or aborted). Extracted from `_streamLoop`. `messages` is mutated in place.
|
|
289
|
+
*/
|
|
290
|
+
private _maybeRunSyntheticTool;
|
|
291
|
+
/**
|
|
292
|
+
* Handle one `tool_use` stream event from {@link _streamLoop}: the built-in
|
|
293
|
+
* `create_artifact`, per-tool renderer selection, the human-in-the-loop
|
|
294
|
+
* approval gate, and running the registered handler (timeout / abort).
|
|
295
|
+
* Mutates the shared `messages` / `toolCallsThisTurn` history in place and
|
|
296
|
+
* returns whether the agentic loop should keep going.
|
|
297
|
+
*/
|
|
298
|
+
private _handleToolUseEvent;
|
|
299
|
+
private _streamLoop;
|
|
300
|
+
/**
|
|
301
|
+
* Delegate `_streamLoop`'s agentic loop to an injected {@link AparteStreamRunner},
|
|
302
|
+
* rendering its DOM-free events through {@link createStreamAdapter}.
|
|
303
|
+
* Builds the runner's dependencies from this client's config / provider /
|
|
304
|
+
* transport; the adapter reproduces the inline loop's `targetElement.*` calls
|
|
305
|
+
* (validated by the engine `stream-parity` suite). Leading writes (status
|
|
306
|
+
* streaming, prefix segments) mirror the inline path; the runner's `run-start`
|
|
307
|
+
* re-asserts `streaming` idempotently.
|
|
308
|
+
*/
|
|
309
|
+
private _runViaStreamRunner;
|
|
310
|
+
/**
|
|
311
|
+
* Updates an existing message or appends a new error if ID lookup fails
|
|
312
|
+
*/
|
|
313
|
+
private _updateMessage;
|
|
314
|
+
/**
|
|
315
|
+
* Gracefully handles errors by updating the current message instead of duplicating it
|
|
316
|
+
*/
|
|
317
|
+
private _handleLifecycleError;
|
|
318
|
+
private _dispatchLifecycleEvent;
|
|
319
|
+
/**
|
|
320
|
+
* Dispatch the artifact lifecycle (`aparte-artifact-start` / `delta` / `ready`)
|
|
321
|
+
* on the host bubble element. Idempotent for `start` (fires once per segment id)
|
|
322
|
+
* and emits `delta` only when the body actually grew. `isFinal=true` fires `ready`.
|
|
323
|
+
*/
|
|
324
|
+
private _dispatchArtifactLifecycle;
|
|
325
|
+
}
|
|
326
|
+
//# sourceMappingURL=aparte-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aparte-client.d.ts","sourceRoot":"","sources":["../../src/client/aparte-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* stream-adapter.ts — the DOM half of the structured-stream agent loop.
|
|
3
|
+
*
|
|
4
|
+
* `@aparte/engine`'s `runStreamAgent` is the headless loop: it emits high-level,
|
|
5
|
+
* DOM-free run events. This adapter is the other half — it turns each event into
|
|
6
|
+
* the exact `targetElement.*` calls + CustomEvents that `AparteClient._streamLoop`
|
|
7
|
+
* performs today, using the **real** `AparteStreamParser` and tool renderers. So
|
|
8
|
+
* `runStreamAgent` (engine, pure Node) + this adapter (core, DOM) reproduce
|
|
9
|
+
* `_streamLoop` byte-for-byte.
|
|
10
|
+
*
|
|
11
|
+
* DEPENDENCY DIRECTION: `@aparte/core` is the zero-dep leaf — it must NEVER import
|
|
12
|
+
* `@aparte/engine` (engine peer-deps core; importing back would create a build
|
|
13
|
+
* cycle). So the run-event contract is **mirrored** here as
|
|
14
|
+
* {@link AparteStreamRunEvent}, structurally identical to engine's `StreamRunEvent`.
|
|
15
|
+
* `@aparte/engine`'s `runStreamAgent` emits objects that satisfy this type; a
|
|
16
|
+
* consumer wires the two together via the injectable
|
|
17
|
+
* `AparteClientOptions.streamRunner` seam — the same pattern as `approvalResolver`
|
|
18
|
+
* (HITL) and `compactionSelector`. Keep the two unions in sync by hand.
|
|
19
|
+
*/
|
|
20
|
+
import type { AparteConfigClass } from '../config/aparte-config.js';
|
|
21
|
+
import type { AparteSegment, AparteMessage, AparteStreamEvent } from '../types/index.js';
|
|
22
|
+
import type { AparteUsage, AparteChatRequest } from '../types/chat.js';
|
|
23
|
+
/**
|
|
24
|
+
* DOM-free run events emitted by `@aparte/engine`'s `runStreamAgent`, mirrored here
|
|
25
|
+
* so core need not import engine. **Structurally identical** to engine's
|
|
26
|
+
* `StreamRunEvent` — kept in sync manually (the boundary cost of the zero-dep
|
|
27
|
+
* leaf). See `packages/engine/src/agent/stream-events.ts` for the source of truth
|
|
28
|
+
* and the per-event `_streamLoop` mapping notes.
|
|
29
|
+
*/
|
|
30
|
+
export type AparteStreamRunEvent = {
|
|
31
|
+
type: 'run-start';
|
|
32
|
+
} | {
|
|
33
|
+
type: 'turn-start';
|
|
34
|
+
} | {
|
|
35
|
+
type: 'text-delta';
|
|
36
|
+
delta: string;
|
|
37
|
+
reduced?: boolean;
|
|
38
|
+
} | {
|
|
39
|
+
type: 'text-flush';
|
|
40
|
+
} | {
|
|
41
|
+
type: 'thinking-delta';
|
|
42
|
+
delta: string;
|
|
43
|
+
} | {
|
|
44
|
+
type: 'artifact-open';
|
|
45
|
+
id: string;
|
|
46
|
+
mimeType: string;
|
|
47
|
+
kind: string;
|
|
48
|
+
title: string;
|
|
49
|
+
} | {
|
|
50
|
+
type: 'artifact-chunk';
|
|
51
|
+
id: string;
|
|
52
|
+
content: string;
|
|
53
|
+
} | {
|
|
54
|
+
type: 'artifact-close';
|
|
55
|
+
id: string;
|
|
56
|
+
content: string;
|
|
57
|
+
inline: boolean;
|
|
58
|
+
} | {
|
|
59
|
+
type: 'artifact-ready';
|
|
60
|
+
id: string;
|
|
61
|
+
mimeType: string;
|
|
62
|
+
kind: string;
|
|
63
|
+
title: string;
|
|
64
|
+
content: string;
|
|
65
|
+
} | {
|
|
66
|
+
type: 'tool-start';
|
|
67
|
+
toolCallId: string;
|
|
68
|
+
name: string;
|
|
69
|
+
input: unknown;
|
|
70
|
+
} | {
|
|
71
|
+
type: 'tool-awaiting-approval';
|
|
72
|
+
toolCallId: string;
|
|
73
|
+
name: string;
|
|
74
|
+
input: unknown;
|
|
75
|
+
} | {
|
|
76
|
+
type: 'tool-approved';
|
|
77
|
+
toolCallId: string;
|
|
78
|
+
} | {
|
|
79
|
+
type: 'tool-rejected';
|
|
80
|
+
toolCallId: string;
|
|
81
|
+
reason: string;
|
|
82
|
+
} | {
|
|
83
|
+
type: 'tool-resolved';
|
|
84
|
+
toolCallId: string;
|
|
85
|
+
result: string;
|
|
86
|
+
} | {
|
|
87
|
+
type: 'tool-aborted';
|
|
88
|
+
toolCallId: string;
|
|
89
|
+
} | {
|
|
90
|
+
type: 'turn-limit-exceeded';
|
|
91
|
+
scope: 'global' | 'tool';
|
|
92
|
+
limit: number;
|
|
93
|
+
toolCallId?: string;
|
|
94
|
+
} | {
|
|
95
|
+
type: 'phase-advance';
|
|
96
|
+
index: number;
|
|
97
|
+
} | {
|
|
98
|
+
type: 'run-aborted';
|
|
99
|
+
} | {
|
|
100
|
+
type: 'run-done';
|
|
101
|
+
usage?: AparteUsage;
|
|
102
|
+
};
|
|
103
|
+
/** Synchronous, ordered event sink — mirrors engine's `StreamRunEmitter`. */
|
|
104
|
+
export type AparteStreamRunEmitter = (event: AparteStreamRunEvent) => void;
|
|
105
|
+
/**
|
|
106
|
+
* Options for an injected {@link AparteStreamRunner} — structurally identical to
|
|
107
|
+
* engine's `StreamRunOptions` (the mirror boundary again). `AparteClient` builds
|
|
108
|
+
* these from its config/provider/transport and hands them to the runner.
|
|
109
|
+
*/
|
|
110
|
+
export interface AparteStreamRunOptions {
|
|
111
|
+
messageId: string;
|
|
112
|
+
baseRequest: AparteChatRequest;
|
|
113
|
+
/** Calls the transport; returns the structured stream or a plain string. */
|
|
114
|
+
transportCall: (request: AparteChatRequest) => Promise<AsyncIterable<AparteStreamEvent> | string>;
|
|
115
|
+
/** Resolves a tool's handler by name (mirrors `AparteConfig.getToolHandler`). */
|
|
116
|
+
toolLookup: (name: string) => ((call: {
|
|
117
|
+
id: string;
|
|
118
|
+
name: string;
|
|
119
|
+
input: Record<string, unknown>;
|
|
120
|
+
}, signal: AbortSignal) => Promise<{
|
|
121
|
+
content: string;
|
|
122
|
+
}>) | undefined;
|
|
123
|
+
/** Resolves a tool's loop config by name (maxTurns / needsApproval). */
|
|
124
|
+
toolConfigLookup?: (name: string) => {
|
|
125
|
+
maxTurns?: number;
|
|
126
|
+
needsApproval?: boolean;
|
|
127
|
+
} | undefined;
|
|
128
|
+
/** HITL approval resolver for `needsApproval` tools. */
|
|
129
|
+
approvalResolver?: (toolCallId: string, signal: AbortSignal) => Promise<{
|
|
130
|
+
approved: boolean;
|
|
131
|
+
payload?: unknown;
|
|
132
|
+
}>;
|
|
133
|
+
/** The DOM adapter (from {@link createStreamAdapter}). */
|
|
134
|
+
emitter: AparteStreamRunEmitter;
|
|
135
|
+
/** Single abort signal (the client composes `_isAborted` + the controller). */
|
|
136
|
+
signal: AbortSignal;
|
|
137
|
+
maxTurns?: number;
|
|
138
|
+
toolTimeoutMs?: number;
|
|
139
|
+
idGen?: (prefix: string) => string;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* A headless structured-stream loop injected via `AparteClientOptions.streamRunner`
|
|
143
|
+
* — the seam by which a consumer swaps `_streamLoop`'s inline loop for
|
|
144
|
+
* `@aparte/engine`'s `runStreamAgent` (core stays the zero-dep leaf; it never
|
|
145
|
+
* imports engine). Structurally identical to `runStreamAgent`; wire it with a
|
|
146
|
+
* cast at the injection site if the duck-typed shapes don't line up exactly.
|
|
147
|
+
*/
|
|
148
|
+
export type AparteStreamRunner = (opts: AparteStreamRunOptions) => Promise<AparteUsage | undefined>;
|
|
149
|
+
/**
|
|
150
|
+
* The imperative surface the adapter drives (subset of `AparteChatTargetElement`).
|
|
151
|
+
* Every method is optional so a partial/mock target degrades gracefully.
|
|
152
|
+
*/
|
|
153
|
+
export interface StreamAdapterTarget {
|
|
154
|
+
updateMessage?(id: string, updates: Partial<AparteMessage>): void;
|
|
155
|
+
updateLastMessage?(content: string, options?: {
|
|
156
|
+
append?: boolean;
|
|
157
|
+
}): void;
|
|
158
|
+
addSegment?(segment: AparteSegment): void;
|
|
159
|
+
updateSegment?(segmentId: string, updates: Partial<AparteSegment>): void;
|
|
160
|
+
typeName?(text: string): void;
|
|
161
|
+
setUsage?(id: string, usage: AparteUsage): void;
|
|
162
|
+
dispatchEvent(event: Event): boolean;
|
|
163
|
+
}
|
|
164
|
+
export interface CreateStreamAdapterOptions {
|
|
165
|
+
/** The chat target element the events are rendered onto. */
|
|
166
|
+
target: StreamAdapterTarget;
|
|
167
|
+
/** Config for tool-renderer lookup + per-tool style injection. */
|
|
168
|
+
config: AparteConfigClass;
|
|
169
|
+
/** The streamed assistant message id (carried in run/artifact events). */
|
|
170
|
+
messageId: string;
|
|
171
|
+
/**
|
|
172
|
+
* Code-fence promotion hint (`baseRequest._meta.artifactHint`). When set, the
|
|
173
|
+
* first `code` segment produced by the text parser is promoted to an artifact
|
|
174
|
+
* — the one `_streamLoop` mechanism that stays adapter-side (it needs the
|
|
175
|
+
* parser). Absent for the raw / XML / create_artifact modes.
|
|
176
|
+
*/
|
|
177
|
+
artifactHint?: {
|
|
178
|
+
mimeType: string;
|
|
179
|
+
kind: string;
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Build the event → DOM adapter for one streamed message. Returns a synchronous
|
|
184
|
+
* {@link AparteStreamRunEmitter} to hand to `runStreamAgent` as its `emitter`.
|
|
185
|
+
* Reproduces `_streamLoop`'s `targetElement.*` call sequence exactly (validated
|
|
186
|
+
* by the engine parity test against the real loop).
|
|
187
|
+
*/
|
|
188
|
+
export declare function createStreamAdapter(opts: CreateStreamAdapterOptions): AparteStreamRunEmitter;
|
|
189
|
+
/**
|
|
190
|
+
* Bridge a `ReadableStream` (what the transport returns) to the
|
|
191
|
+
* `AsyncIterable<AparteStreamEvent>` `runStreamAgent` consumes, cancelling the
|
|
192
|
+
* reader **synchronously** on abort so a user "stop" cuts the in-flight read.
|
|
193
|
+
* Used by the `_streamLoop` seam when building `transportCall` for an injected
|
|
194
|
+
* runner. Mirrors `_streamLoop`'s `reader.read()` loop + `reader.cancel()`.
|
|
195
|
+
*/
|
|
196
|
+
export declare function readableToAsyncIterable(stream: ReadableStream<AparteStreamEvent>, signal: AbortSignal): AsyncIterable<AparteStreamEvent>;
|
|
197
|
+
//# sourceMappingURL=stream-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-adapter.d.ts","sourceRoot":"","sources":["../../src/client/stream-adapter.ts"],"names":[],"mappings":"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"}
|