@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.
Files changed (175) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +53 -0
  3. package/dist/client/aparte-client.d.ts +326 -0
  4. package/dist/client/aparte-client.d.ts.map +1 -0
  5. package/dist/client/stream-adapter.d.ts +197 -0
  6. package/dist/client/stream-adapter.d.ts.map +1 -0
  7. package/dist/components/bubble/aparte-chat-bubble.d.ts +153 -0
  8. package/dist/components/bubble/aparte-chat-bubble.d.ts.map +1 -0
  9. package/dist/components/bubble/bubble-sync.d.ts +44 -0
  10. package/dist/components/bubble/bubble-sync.d.ts.map +1 -0
  11. package/dist/components/bubble/index.d.ts +4 -0
  12. package/dist/components/bubble/index.d.ts.map +1 -0
  13. package/dist/components/chat/aparte-chat.d.ts +49 -0
  14. package/dist/components/chat/aparte-chat.d.ts.map +1 -0
  15. package/dist/components/chat/index.d.ts +2 -0
  16. package/dist/components/chat/index.d.ts.map +1 -0
  17. package/dist/components/composer/aparte-composer-action.d.ts +37 -0
  18. package/dist/components/composer/aparte-composer-action.d.ts.map +1 -0
  19. package/dist/components/composer/aparte-composer-add-attachment.d.ts +27 -0
  20. package/dist/components/composer/aparte-composer-add-attachment.d.ts.map +1 -0
  21. package/dist/components/composer/aparte-composer-attachments.d.ts +26 -0
  22. package/dist/components/composer/aparte-composer-attachments.d.ts.map +1 -0
  23. package/dist/components/composer/aparte-composer-cancel.d.ts +21 -0
  24. package/dist/components/composer/aparte-composer-cancel.d.ts.map +1 -0
  25. package/dist/components/composer/aparte-composer-input.d.ts +63 -0
  26. package/dist/components/composer/aparte-composer-input.d.ts.map +1 -0
  27. package/dist/components/composer/aparte-composer-send.d.ts +25 -0
  28. package/dist/components/composer/aparte-composer-send.d.ts.map +1 -0
  29. package/dist/components/composer/aparte-composer.d.ts +150 -0
  30. package/dist/components/composer/aparte-composer.d.ts.map +1 -0
  31. package/dist/components/composer/index.d.ts +9 -0
  32. package/dist/components/composer/index.d.ts.map +1 -0
  33. package/dist/components/conversation-list/aparte-conversation-list.d.ts +50 -0
  34. package/dist/components/conversation-list/aparte-conversation-list.d.ts.map +1 -0
  35. package/dist/components/conversation-list/index.d.ts +2 -0
  36. package/dist/components/conversation-list/index.d.ts.map +1 -0
  37. package/dist/components/elicitation/aparte-elicitation.d.ts +29 -0
  38. package/dist/components/elicitation/aparte-elicitation.d.ts.map +1 -0
  39. package/dist/components/index.d.ts +10 -0
  40. package/dist/components/index.d.ts.map +1 -0
  41. package/dist/components/status/aparte-chat-status.d.ts +34 -0
  42. package/dist/components/status/aparte-chat-status.d.ts.map +1 -0
  43. package/dist/components/status/index.d.ts +2 -0
  44. package/dist/components/status/index.d.ts.map +1 -0
  45. package/dist/components/viewport/aparte-chat-viewport.d.ts +358 -0
  46. package/dist/components/viewport/aparte-chat-viewport.d.ts.map +1 -0
  47. package/dist/components/viewport/index.d.ts +2 -0
  48. package/dist/components/viewport/index.d.ts.map +1 -0
  49. package/dist/config/action-provider.d.ts +59 -0
  50. package/dist/config/action-provider.d.ts.map +1 -0
  51. package/dist/config/aparte-config.d.ts +490 -0
  52. package/dist/config/aparte-config.d.ts.map +1 -0
  53. package/dist/config/attachment-renderer.d.ts +28 -0
  54. package/dist/config/attachment-renderer.d.ts.map +1 -0
  55. package/dist/config/avatar-provider.d.ts +35 -0
  56. package/dist/config/avatar-provider.d.ts.map +1 -0
  57. package/dist/config/bubble-shell-renderer.d.ts +41 -0
  58. package/dist/config/bubble-shell-renderer.d.ts.map +1 -0
  59. package/dist/config/config-context.d.ts +47 -0
  60. package/dist/config/config-context.d.ts.map +1 -0
  61. package/dist/config/error-renderer.d.ts +26 -0
  62. package/dist/config/error-renderer.d.ts.map +1 -0
  63. package/dist/config/icon-provider.d.ts +63 -0
  64. package/dist/config/icon-provider.d.ts.map +1 -0
  65. package/dist/config/index.d.ts +19 -0
  66. package/dist/config/index.d.ts.map +1 -0
  67. package/dist/config/locale.d.ts +60 -0
  68. package/dist/config/locale.d.ts.map +1 -0
  69. package/dist/config/sanitize.d.ts +31 -0
  70. package/dist/config/sanitize.d.ts.map +1 -0
  71. package/dist/config/sibling-nav-renderer.d.ts +27 -0
  72. package/dist/config/sibling-nav-renderer.d.ts.map +1 -0
  73. package/dist/config/skeleton-provider.d.ts +26 -0
  74. package/dist/config/skeleton-provider.d.ts.map +1 -0
  75. package/dist/config/status-renderer.d.ts +23 -0
  76. package/dist/config/status-renderer.d.ts.map +1 -0
  77. package/dist/conversations/conversation-controller.d.ts +126 -0
  78. package/dist/conversations/conversation-controller.d.ts.map +1 -0
  79. package/dist/conversations/conversation-manager.d.ts +98 -0
  80. package/dist/conversations/conversation-manager.d.ts.map +1 -0
  81. package/dist/conversations/index.d.ts +5 -0
  82. package/dist/conversations/index.d.ts.map +1 -0
  83. package/dist/conversations/types.d.ts +172 -0
  84. package/dist/conversations/types.d.ts.map +1 -0
  85. package/dist/custom-elements.json +15833 -0
  86. package/dist/elicitation/index.d.ts +20 -0
  87. package/dist/elicitation/index.d.ts.map +1 -0
  88. package/dist/elicitation/panel.d.ts +18 -0
  89. package/dist/elicitation/panel.d.ts.map +1 -0
  90. package/dist/elicitation/types.d.ts +98 -0
  91. package/dist/elicitation/types.d.ts.map +1 -0
  92. package/dist/host/aparte-chat-host.d.ts +176 -0
  93. package/dist/host/aparte-chat-host.d.ts.map +1 -0
  94. package/dist/host/index.d.ts +2 -0
  95. package/dist/host/index.d.ts.map +1 -0
  96. package/dist/index-D89k-n2Q.js +6294 -0
  97. package/dist/index-D89k-n2Q.js.map +1 -0
  98. package/dist/index.css +2554 -0
  99. package/dist/index.d.ts +62 -0
  100. package/dist/index.d.ts.map +1 -0
  101. package/dist/index.js +3763 -0
  102. package/dist/index.js.map +1 -0
  103. package/dist/index.node.d.ts +53 -0
  104. package/dist/index.node.d.ts.map +1 -0
  105. package/dist/index.node.js +49 -0
  106. package/dist/index.node.js.map +1 -0
  107. package/dist/interop/element-props.d.ts +23 -0
  108. package/dist/interop/element-props.d.ts.map +1 -0
  109. package/dist/parsers/aparte-event-stream.d.ts +13 -0
  110. package/dist/parsers/aparte-event-stream.d.ts.map +1 -0
  111. package/dist/parsers/aparte-stream-parser.d.ts +137 -0
  112. package/dist/parsers/aparte-stream-parser.d.ts.map +1 -0
  113. package/dist/parsers/index.d.ts +4 -0
  114. package/dist/parsers/index.d.ts.map +1 -0
  115. package/dist/primitives/index.d.ts +8 -0
  116. package/dist/primitives/index.d.ts.map +1 -0
  117. package/dist/primitives/progress-spinner/aparte-progress-spinner.d.ts +25 -0
  118. package/dist/primitives/progress-spinner/aparte-progress-spinner.d.ts.map +1 -0
  119. package/dist/primitives/progress-spinner/index.d.ts +2 -0
  120. package/dist/primitives/progress-spinner/index.d.ts.map +1 -0
  121. package/dist/primitives/select/aparte-optgroup.d.ts +32 -0
  122. package/dist/primitives/select/aparte-optgroup.d.ts.map +1 -0
  123. package/dist/primitives/select/aparte-option.d.ts +30 -0
  124. package/dist/primitives/select/aparte-option.d.ts.map +1 -0
  125. package/dist/primitives/select/aparte-select.d.ts +74 -0
  126. package/dist/primitives/select/aparte-select.d.ts.map +1 -0
  127. package/dist/primitives/select/index.d.ts +9 -0
  128. package/dist/primitives/select/index.d.ts.map +1 -0
  129. package/dist/renderers/index.d.ts +5 -0
  130. package/dist/renderers/index.d.ts.map +1 -0
  131. package/dist/renderers/segment-renderers.d.ts +31 -0
  132. package/dist/renderers/segment-renderers.d.ts.map +1 -0
  133. package/dist/runtime/message-repository.d.ts +111 -0
  134. package/dist/runtime/message-repository.d.ts.map +1 -0
  135. package/dist/transport/backend-handler.d.ts +50 -0
  136. package/dist/transport/backend-handler.d.ts.map +1 -0
  137. package/dist/transport/backend-transport.d.ts +39 -0
  138. package/dist/transport/backend-transport.d.ts.map +1 -0
  139. package/dist/transport/direct-transport.d.ts +36 -0
  140. package/dist/transport/direct-transport.d.ts.map +1 -0
  141. package/dist/transport/index.d.ts +6 -0
  142. package/dist/transport/index.d.ts.map +1 -0
  143. package/dist/transport/types.d.ts +73 -0
  144. package/dist/transport/types.d.ts.map +1 -0
  145. package/dist/types/chat.d.ts +223 -0
  146. package/dist/types/chat.d.ts.map +1 -0
  147. package/dist/types/errors.d.ts +25 -0
  148. package/dist/types/errors.d.ts.map +1 -0
  149. package/dist/types/event-map.d.ts +41 -0
  150. package/dist/types/event-map.d.ts.map +1 -0
  151. package/dist/types/events.d.ts +290 -0
  152. package/dist/types/events.d.ts.map +1 -0
  153. package/dist/types/imperative-api.d.ts +38 -0
  154. package/dist/types/imperative-api.d.ts.map +1 -0
  155. package/dist/types/index.d.ts +22 -0
  156. package/dist/types/index.d.ts.map +1 -0
  157. package/dist/types/model-provider.d.ts +229 -0
  158. package/dist/types/model-provider.d.ts.map +1 -0
  159. package/dist/types/models.d.ts +173 -0
  160. package/dist/types/models.d.ts.map +1 -0
  161. package/dist/types/parsers.d.ts +42 -0
  162. package/dist/types/parsers.d.ts.map +1 -0
  163. package/dist/types/providers.d.ts +93 -0
  164. package/dist/types/providers.d.ts.map +1 -0
  165. package/dist/types/segments.d.ts +221 -0
  166. package/dist/types/segments.d.ts.map +1 -0
  167. package/dist/types/theming.d.ts +44 -0
  168. package/dist/types/theming.d.ts.map +1 -0
  169. package/dist/types/tools.d.ts +98 -0
  170. package/dist/types/tools.d.ts.map +1 -0
  171. package/dist/utils/assert-never.d.ts +9 -0
  172. package/dist/utils/assert-never.d.ts.map +1 -0
  173. package/dist/utils/css-escape.d.ts +15 -0
  174. package/dist/utils/css-escape.d.ts.map +1 -0
  175. package/package.json +68 -0
@@ -0,0 +1,111 @@
1
+ /**
2
+ * MessageRepository — Conversation Tree Storage
3
+ *
4
+ * Manages the branching conversation tree while keeping AparteMessage pure
5
+ * (no topology fields on the message itself). Inspired by assistant-ui's
6
+ * MessageRepository but adapted for the Aparte vanilla-TS stack.
7
+ *
8
+ * Internal structure: a doubly-linked tree where each node holds a pointer
9
+ * to its parent (prev) and its active child (next). `children` stores all
10
+ * sibling IDs. `head` is always the active leaf.
11
+ *
12
+ * getMessages() walks head → root via `prev` — O(depth), not O(n).
13
+ */
14
+ import type { AparteMessage } from '../types/index.js';
15
+ /** Exported format — compatible with serialisation */
16
+ export type ExportedMessageRepository = {
17
+ headId: string | null;
18
+ messages: Array<{
19
+ message: AparteMessage;
20
+ parentId: string | null;
21
+ }>;
22
+ };
23
+ export declare class MessageRepository {
24
+ private _nodes;
25
+ private _head;
26
+ private _root;
27
+ /** ID of the currently active leaf message */
28
+ get headId(): string | null;
29
+ /**
30
+ * Returns the messages on the currently active path, root → head.
31
+ * O(depth).
32
+ */
33
+ getMessages(): AparteMessage[];
34
+ /**
35
+ * Returns metadata about a specific message, or `undefined` if not found.
36
+ *
37
+ * Read methods (`getMessage`, `getMessageById`, `getBranches`) all return
38
+ * `undefined` / `[]` for unknown ids — never throw — so callers can do a
39
+ * single existence check at the top of a flow rather than wrapping every
40
+ * call in try/catch.
41
+ */
42
+ getMessage(id: string): {
43
+ parentId: string | null;
44
+ message: AparteMessage;
45
+ index: number;
46
+ } | undefined;
47
+ /**
48
+ * Returns the mutable message reference, or `undefined` if not found.
49
+ * Mutations to the returned object are reflected in `getMessages()`.
50
+ */
51
+ getMessageById(id: string): AparteMessage | undefined;
52
+ /**
53
+ * Returns the IDs of all siblings of `messageId`
54
+ * (i.e. all children of its parent, including itself).
55
+ * Use this to build branch-picker UI.
56
+ */
57
+ getBranches(messageId: string): string[];
58
+ /**
59
+ * Add a new message as a child of `parentId` (null = root).
60
+ * If a message with the same id already exists, updates its data
61
+ * and re-links it under the correct parent.
62
+ */
63
+ addOrUpdateMessage(parentId: string | null, message: AparteMessage): void;
64
+ /**
65
+ * Switch the active branch to `messageId`.
66
+ * Updates `next` on the parent chain so getMessages() reflects the change.
67
+ * Advances `head` to the deepest active node in the new branch.
68
+ *
69
+ * Silent no-op for unknown ids — mutation methods (`switchToBranch`,
70
+ * `resetHead`, `updateMessage`, `clearChildren`) never throw.
71
+ */
72
+ switchToBranch(messageId: string): void;
73
+ /**
74
+ * Remove all descendants of `messageId` (inclusive) and set `head` to
75
+ * the parent of `messageId`. Used by edit/truncate flows.
76
+ *
77
+ * @param messageId The first message to remove
78
+ * @param newParentId Optional explicit parent to set head to
79
+ */
80
+ resetHead(messageId: string): void;
81
+ /**
82
+ * Update a message's data without changing its position in the tree.
83
+ */
84
+ updateMessage(messageId: string, updates: Partial<AparteMessage>): void;
85
+ /**
86
+ * Remove ALL children of `parentId` (and their descendants) and set head
87
+ * to `parentId`. Used by edit to discard every previous response before
88
+ * re-generating — ensures the new response starts with sibling count = 1.
89
+ */
90
+ clearChildren(parentId: string): void;
91
+ /** Remove all messages and reset to empty state. */
92
+ clear(): void;
93
+ /**
94
+ * Import a previously-exported snapshot, rebuilding the full tree and
95
+ * restoring the active head. Replaces any existing content (calls `clear()`
96
+ * first). Messages must be in topological order (parent before child) —
97
+ * this is guaranteed by `export()` since `_nodes` is an insertion-order
98
+ * Map and parents are always inserted before their children.
99
+ */
100
+ import(exported: ExportedMessageRepository): void;
101
+ /**
102
+ * Export the full tree for serialisation or debugging.
103
+ * Compatible with the assistant-ui ExportedMessageRepository format.
104
+ */
105
+ export(): ExportedMessageRepository;
106
+ private _link;
107
+ private _relink;
108
+ private _updateLevels;
109
+ private _deleteDescendants;
110
+ }
111
+ //# sourceMappingURL=message-repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-repository.d.ts","sourceRoot":"","sources":["../../src/runtime/message-repository.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAsBvD,sDAAsD;AACtD,MAAM,MAAM,yBAAyB,GAAG;IACpC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,aAAa,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;CACxE,CAAC;AAaF,qBAAa,iBAAiB;IAC1B,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,KAAK,CAA0C;IAIvD,8CAA8C;IAC9C,IAAI,MAAM,IAAI,MAAM,GAAG,IAAI,CAE1B;IAED;;;OAGG;IACH,WAAW,IAAI,aAAa,EAAE;IAU9B;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG;QAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,OAAO,EAAE,aAAa,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS;IAUtG;;;OAGG;IACH,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAIrD;;;;OAIG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE;IASxC;;;;OAIG;IACH,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI;IAkCzE;;;;;;;OAOG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAQvC;;;;;;OAMG;IACH,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAuBlC;;OAEG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI;IAMvE;;;;OAIG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAgBrC,oDAAoD;IACpD,KAAK,IAAI,IAAI;IAMb;;;;;;OAMG;IACH,MAAM,CAAC,QAAQ,EAAE,yBAAyB,GAAG,IAAI;IAUjD;;;OAGG;IACH,MAAM,IAAI,yBAAyB;IAanC,OAAO,CAAC,KAAK;IAUb,OAAO,CAAC,OAAO;IA0Bf,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,kBAAkB;CAW7B"}
@@ -0,0 +1,50 @@
1
+ import type { AparteAIProvider } from '../types/model-provider.js';
2
+ export interface AparteChatHandlerOptions {
3
+ /**
4
+ * Your server-side format adapters, keyed by the `providerId` the client
5
+ * sends. The same adapters as the browser (`@aparte/provider-*`), running here
6
+ * so the vendor key never leaves the server.
7
+ */
8
+ providers: Record<string, AparteAIProvider>;
9
+ /**
10
+ * Optional gate run on EVERY request before any work — this endpoint spends
11
+ * your server-held vendor key, so put your own auth in front of it. Return
12
+ * `false` to reject with 401, a `Response` to reject with your own status/body
13
+ * (e.g. 403 + a message), or `true` to proceed. Reads cookies/headers via `req`.
14
+ */
15
+ authorize?: (req: Request) => boolean | Response | Promise<boolean | Response>;
16
+ /**
17
+ * Resolve the vendor API key for a providerId — from env / a secret store.
18
+ * Runs server-side only. Return `undefined` for keyless/local providers.
19
+ */
20
+ resolveKey?: (providerId: string) => string | undefined | Promise<string | undefined>;
21
+ /**
22
+ * The `fetch` used to call the vendor. Defaults to the global `fetch`
23
+ * (Node 18+, Deno, Bun, Workers). Override in tests or to add a proxy.
24
+ */
25
+ fetchImpl?: typeof fetch;
26
+ }
27
+ /**
28
+ * Build a framework-free `/api/chat` handler for {@link BackendTransport} — the
29
+ * server counterpart that keeps the key off the client.
30
+ *
31
+ * The returned handler speaks the Web `fetch` API (`Request` → `Response`), so
32
+ * it drops into a Next.js route handler, Deno, Bun, or a Cloudflare Worker
33
+ * unchanged. It reads `{ providerId, request }`, runs the matching format
34
+ * adapter **server-side** (buildRequest → auth → vendor fetch → parseStream),
35
+ * and streams back normalized `AparteStreamEvent`s as NDJSON — the exact wire
36
+ * format `BackendTransport` expects. The vendor key is injected here and never
37
+ * travels to the browser.
38
+ *
39
+ * ```ts
40
+ * // app/api/chat/route.ts (Next.js)
41
+ * import { createAparteChatHandler } from '@aparte/core';
42
+ * import { createOpenAICompatProvider, presets } from '@aparte/provider-openai-compat';
43
+ * export const POST = createAparteChatHandler({
44
+ * providers: { openai: createOpenAICompatProvider(presets.OPENAI) },
45
+ * resolveKey: (id) => process.env[`${id.toUpperCase()}_KEY`],
46
+ * });
47
+ * ```
48
+ */
49
+ export declare function createAparteChatHandler(options: AparteChatHandlerOptions): (req: Request) => Promise<Response>;
50
+ //# sourceMappingURL=backend-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend-handler.d.ts","sourceRoot":"","sources":["../../src/transport/backend-handler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAGnE,MAAM,WAAW,wBAAwB;IACrC;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC5C;;;;;OAKG;IACH,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC,OAAO,GAAG,QAAQ,CAAC,CAAC;IAC/E;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACtF;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,uBAAuB,CACnC,OAAO,EAAE,wBAAwB,GAClC,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CA4GrC"}
@@ -0,0 +1,39 @@
1
+ import type { AparteChatRequest, AparteChatResponse } from '../types/chat.js';
2
+ import type { AparteAIProvider } from '../types/model-provider.js';
3
+ import type { AparteTransport, AparteTransportContext } from './types.js';
4
+ export interface BackendTransportOptions {
5
+ /** Your backend chat endpoint, e.g. `/api/chat`. */
6
+ endpoint: string;
7
+ /** Extra headers to send with each request (session cookie is automatic). */
8
+ headers?: Record<string, string>;
9
+ /**
10
+ * Override how the request is serialised to your backend. Default body is
11
+ * `{ providerId, request }`. Return any JSON-serialisable value.
12
+ */
13
+ buildBody?: (request: AparteChatRequest, providerId: string) => unknown;
14
+ }
15
+ /**
16
+ * Backend-proxied transport — RECOMMENDED for production.
17
+ *
18
+ * POSTs `{ providerId, request }` to YOUR endpoint. The backend resolves the API
19
+ * key server-side, calls the vendor, runs the vendor parser **server-side**, and
20
+ * streams back already-normalized `AparteStreamEvent`s as NDJSON (one JSON object
21
+ * per line). The key never reaches the browser and — unlike a raw proxy — the
22
+ * client stays fully vendor-agnostic (it never runs the vendor's `parseStream`,
23
+ * so switching the server-side provider needs no client change). Non-streaming
24
+ * requests get a JSON `{ text }` reply.
25
+ *
26
+ * This is NOT the Vercel AI SDK Data Stream Protocol; the wire format is a plain
27
+ * NDJSON of `AparteStreamEvent` (see `parseAparteEventStream`).
28
+ *
29
+ * The matching `/api/chat` handler ships as a real, framework-free function —
30
+ * {@link createAparteChatHandler} (Web `fetch` API, same @aparte adapters run
31
+ * server-side, key held server-side). Drop it into a Next.js route handler,
32
+ * Deno, Bun, or a Worker rather than hand-rolling one.
33
+ */
34
+ export declare class BackendTransport implements AparteTransport {
35
+ private readonly options;
36
+ constructor(options: BackendTransportOptions);
37
+ chat(_provider: AparteAIProvider, request: AparteChatRequest, _auth: string | Record<string, string> | undefined, ctx: AparteTransportContext): Promise<AparteChatResponse>;
38
+ }
39
+ //# sourceMappingURL=backend-transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend-transport.d.ts","sourceRoot":"","sources":["../../src/transport/backend-transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAI1E,MAAM,WAAW,uBAAuB;IACpC,oDAAoD;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;CAC3E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,gBAAiB,YAAW,eAAe;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,uBAAuB;IAEvD,IAAI,CACN,SAAS,EAAE,gBAAgB,EAC3B,OAAO,EAAE,iBAAiB,EAC1B,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAClD,GAAG,EAAE,sBAAsB,GAC5B,OAAO,CAAC,kBAAkB,CAAC;CA4BjC"}
@@ -0,0 +1,36 @@
1
+ import type { AparteChatRequest, AparteChatResponse } from '../types/chat.js';
2
+ import type { AparteAIProvider } from '../types/model-provider.js';
3
+ import type { AparteTransport, AparteTransportContext } from './types.js';
4
+ /** Options for {@link DirectTransport}. */
5
+ export interface DirectTransportOptions {
6
+ /**
7
+ * Set when the key is the end-user's own (BYOK) or the model runs locally —
8
+ * i.e. you *intend* the credential to live in the browser. This silences the
9
+ * one-time insecure-key warning. Leave it unset for keys that must stay
10
+ * server-side, and use `BackendTransport` for those instead.
11
+ */
12
+ byok?: boolean;
13
+ }
14
+ /**
15
+ * Browser-direct transport (BYOK / local / prototyping) — the DEFAULT.
16
+ *
17
+ * Calls the vendor endpoint straight from the browser, injecting the resolved
18
+ * key via the adapter's `authHeaders`. This is the pre-refactor behaviour and
19
+ * is only safe when the user brings their own key or the model runs locally.
20
+ * Production apps that must keep a key server-side should use `BackendTransport`.
21
+ *
22
+ * When a real key is sent straight from the browser and the transport was not
23
+ * flagged `{ byok: true }`, a one-time `console.warn` names the exposure — the
24
+ * default should be loud, not silent. Local providers (no key) never warn.
25
+ *
26
+ * Legacy providers (still exposing `chat()` rather than the adapter surface) are
27
+ * delegated to untouched, so the migration can proceed provider-by-provider.
28
+ */
29
+ export declare class DirectTransport implements AparteTransport {
30
+ private readonly byok;
31
+ private warnedBrowserKey;
32
+ constructor(options?: DirectTransportOptions);
33
+ chat(provider: AparteAIProvider, request: AparteChatRequest, auth: string | Record<string, string> | undefined, ctx: AparteTransportContext): Promise<AparteChatResponse>;
34
+ private warnBrowserKeyOnce;
35
+ }
36
+ //# sourceMappingURL=direct-transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"direct-transport.d.ts","sourceRoot":"","sources":["../../src/transport/direct-transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAG1E,2CAA2C;AAC3C,MAAM,WAAW,sBAAsB;IACnC;;;;;OAKG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,eAAgB,YAAW,eAAe;IACnD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAU;IAC/B,OAAO,CAAC,gBAAgB,CAAS;gBAErB,OAAO,GAAE,sBAA2B;IAI1C,IAAI,CACN,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,iBAAiB,EAC1B,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EACjD,GAAG,EAAE,sBAAsB,GAC5B,OAAO,CAAC,kBAAkB,CAAC;IAoD9B,OAAO,CAAC,kBAAkB;CAU7B"}
@@ -0,0 +1,6 @@
1
+ export type { AparteTransport, AparteTransportContext, AparteFormatAdapter, AparteVendorRequest, } from './types.js';
2
+ export { isFormatAdapter, readAuth } from './types.js';
3
+ export { DirectTransport, type DirectTransportOptions } from './direct-transport.js';
4
+ export { BackendTransport, type BackendTransportOptions } from './backend-transport.js';
5
+ export { createAparteChatHandler, type AparteChatHandlerOptions } from './backend-handler.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/transport/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACR,eAAe,EACf,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,GACtB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACxF,OAAO,EAAE,uBAAuB,EAAE,KAAK,wBAAwB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Transport seam — separates the two concerns that providers used to bundle:
3
+ *
4
+ * • **Format adapter** (`AparteFormatAdapter`): the vendor-specific concern —
5
+ * how to shape the HTTP request and how to parse the response stream into
6
+ * unified `AparteStreamEvent`s. No network, no auth, no key.
7
+ * • **Transport** (`AparteTransport`): WHERE the call goes and how auth is
8
+ * handled — straight to the vendor from the browser (`DirectTransport`,
9
+ * BYOK/local) or via your own backend that holds the key
10
+ * (`BackendTransport`, recommended for production).
11
+ *
12
+ * A "provider" is migrating from a monolithic `chat()` (fetch + key + parse) to
13
+ * a pure format adapter. During the migration a provider may expose EITHER the
14
+ * adapter surface OR a legacy `chat()`; the transports handle both.
15
+ */
16
+ import type { AparteChatRequest, AparteChatResponse, AparteStreamEvent } from '../types/chat.js';
17
+ import type { AparteAIProvider } from '../types/model-provider.js';
18
+ /** A vendor HTTP request built from an Aparte request — auth is injected separately. */
19
+ export interface AparteVendorRequest {
20
+ /** Appended to the transport's endpoint, e.g. `/chat/completions`. */
21
+ path: string;
22
+ /** Vendor-shaped JSON body. */
23
+ body: unknown;
24
+ /** Content headers (NOT auth — the transport adds auth). */
25
+ headers?: Record<string, string>;
26
+ }
27
+ /** The vendor-format concern, with no transport/auth coupling. */
28
+ export interface AparteFormatAdapter {
29
+ id: string;
30
+ /** Base URL for browser-direct calls (overridable per request via config). */
31
+ defaultEndpoint: string;
32
+ /** Map an Aparte request to the vendor HTTP request (without auth). */
33
+ buildRequest(request: AparteChatRequest): AparteVendorRequest;
34
+ /** Vendor auth headers for a resolved key (browser-direct only). Most vendors. */
35
+ authHeaders?(key: string): Record<string, string>;
36
+ /** Vendor auth as URL query params for a resolved key (e.g. Gemini `?key=`). */
37
+ authQuery?(key: string): Record<string, string>;
38
+ /** Parse a streaming vendor response body into unified events. */
39
+ parseStream(body: ReadableStream<Uint8Array>): ReadableStream<AparteStreamEvent>;
40
+ /** Extract text from a non-streaming vendor JSON response. */
41
+ parseText?(json: unknown): string;
42
+ }
43
+ export interface AparteTransportContext {
44
+ providerId: string;
45
+ signal?: AbortSignal;
46
+ }
47
+ /**
48
+ * Decides where a chat request goes and how auth is handled. Given a provider
49
+ * (adapter or legacy), the request, and the already-resolved auth, it returns
50
+ * unified events (streaming) or a string (non-streaming).
51
+ */
52
+ export interface AparteTransport {
53
+ chat(provider: AparteAIProvider, request: AparteChatRequest, auth: string | Record<string, string> | undefined, ctx: AparteTransportContext): Promise<AparteChatResponse>;
54
+ }
55
+ /** True once a provider has been refactored to the format-adapter surface. */
56
+ export declare function isFormatAdapter(p: AparteAIProvider): p is AparteAIProvider & Required<Pick<AparteFormatAdapter, 'buildRequest' | 'parseStream' | 'defaultEndpoint'>>;
57
+ /** Read an api key / endpoint out of the legacy `string | Record` auth shape. */
58
+ export declare function readAuth(auth: string | Record<string, string> | undefined): {
59
+ key?: string;
60
+ endpoint?: string;
61
+ };
62
+ /** Best-effort human message from a non-ok vendor/backend JSON error response. */
63
+ export declare function vendorErrorMessage(response: Response, label?: string): Promise<string>;
64
+ /**
65
+ * Resolve a non-streaming response to text via the adapter's `parseText`.
66
+ * Both transports use this so `stream: false` behaves identically (previously
67
+ * DirectTransport returned '' and BackendTransport returned raw JSON when
68
+ * `parseText` was missing — now both fail loud).
69
+ */
70
+ export declare function parseNonStreamText(provider: {
71
+ parseText?: (json: unknown) => string;
72
+ }, response: Response, providerId: string): Promise<string>;
73
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/transport/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACjG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,wFAAwF;AACxF,MAAM,WAAW,mBAAmB;IAChC,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,IAAI,EAAE,OAAO,CAAC;IACd,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED,kEAAkE;AAClE,MAAM,WAAW,mBAAmB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,8EAA8E;IAC9E,eAAe,EAAE,MAAM,CAAC;IACxB,uEAAuE;IACvE,YAAY,CAAC,OAAO,EAAE,iBAAiB,GAAG,mBAAmB,CAAC;IAC9D,kFAAkF;IAClF,WAAW,CAAC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClD,gFAAgF;IAChF,SAAS,CAAC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChD,kEAAkE;IAClE,WAAW,CAAC,IAAI,EAAE,cAAc,CAAC,UAAU,CAAC,GAAG,cAAc,CAAC,iBAAiB,CAAC,CAAC;IACjF,8DAA8D;IAC9D,SAAS,CAAC,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;CACrC;AAED,MAAM,WAAW,sBAAsB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC5B,IAAI,CACA,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,iBAAiB,EAC1B,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EACjD,GAAG,EAAE,sBAAsB,GAC5B,OAAO,CAAC,kBAAkB,CAAC,CAAC;CAClC;AAED,8EAA8E;AAC9E,wBAAgB,eAAe,CAC3B,CAAC,EAAE,gBAAgB,GACpB,CAAC,IAAI,gBAAgB,GAAG,QAAQ,CAAC,IAAI,CAAC,mBAAmB,EAAE,cAAc,GAAG,aAAa,GAAG,iBAAiB,CAAC,CAAC,CAOjH;AAED,iFAAiF;AACjF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GAAG;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAI/G;AAED,kFAAkF;AAClF,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAK5F;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACpC,QAAQ,EAAE;IAAE,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM,CAAA;CAAE,EACnD,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CAMjB"}
@@ -0,0 +1,223 @@
1
+ /**
2
+ * Aparte Chat Request & Stream Types
3
+ */
4
+ import type { AparteTool, AparteToolCall } from './tools.js';
5
+ import type { AparteSegment } from './segments.js';
6
+ /** Plain text content part */
7
+ export interface AparteTextPart {
8
+ type: 'text';
9
+ text: string;
10
+ }
11
+ /**
12
+ * Image content part.
13
+ * `image` must be a base64 data URL: `data:image/png;base64,...`
14
+ * The data URL encodes the MIME type, making it consumable by all providers.
15
+ */
16
+ export interface AparteImagePart {
17
+ type: 'image';
18
+ image: string;
19
+ mimeType?: string;
20
+ }
21
+ /**
22
+ * File content part — reserved for future PDF/audio support.
23
+ * `data` must be a base64 data URL.
24
+ */
25
+ export interface AparteFilePart {
26
+ type: 'file';
27
+ data: string;
28
+ mimeType: string;
29
+ name?: string;
30
+ }
31
+ /** Discriminated union of all content part types */
32
+ export type AparteContentPart = AparteTextPart | AparteImagePart | AparteFilePart;
33
+ /**
34
+ * Extract plain text from a `string | AparteContentPart[]` content value.
35
+ * Use this in providers and app-layer code whenever you need the text-only representation.
36
+ */
37
+ export declare function contentToText(content: string | AparteContentPart[]): string;
38
+ export interface AparteChatMessage {
39
+ role: 'user' | 'assistant' | 'system' | 'tool_call' | 'tool_result';
40
+ /**
41
+ * Message content — either a plain string (backward compatible) or an array
42
+ * of typed content parts for multimodal messages (text + images + files).
43
+ *
44
+ * Use `contentToText(content)` to extract the text-only representation.
45
+ */
46
+ content: string | AparteContentPart[];
47
+ /** For role='tool_call': tool calls made by the assistant in this turn */
48
+ toolCalls?: AparteToolCall[];
49
+ /** For role='tool_result': id of the tool call this responds to */
50
+ toolCallId?: string;
51
+ /** For role='tool_call': text streamed before the tool call in the same turn */
52
+ precedingText?: string;
53
+ }
54
+ export interface AparteChatRequest {
55
+ messages: AparteChatMessage[];
56
+ modelId: string;
57
+ temperature?: number;
58
+ maxTokens?: number;
59
+ stream?: boolean;
60
+ /** Tools the AI is allowed to call */
61
+ tools?: AparteTool[];
62
+ /**
63
+ * Random seed for reproducibility / diversity.
64
+ * Automatically set to a random integer on every `aparte-retry` so the
65
+ * provider generates a different response even with the same history.
66
+ * Supported by OpenAI, OpenRouter, LM Studio, Mistral, Ollama, and Gemini.
67
+ * Anthropic does not expose a seed parameter — ignored silently there.
68
+ */
69
+ seed?: number;
70
+ /**
71
+ * Controls which tool the model must call — mirrors OpenAI tool_choice / Anthropic tool_choice.
72
+ * - 'auto' : model decides (default when tools are present)
73
+ * - 'none' : no tools injected this turn — model answers directly
74
+ * - { name } : model MUST call this tool (provider injects a strong directive)
75
+ * - { name, input }: synthetic call — the agent loop (inline `_streamLoop`
76
+ * or the injected `runStreamAgent`) bypasses the LLM
77
+ * entirely and runs the handler directly with the provided
78
+ * input, then re-calls the LLM with the tool_result in history.
79
+ */
80
+ toolChoice?: 'auto' | 'none' | {
81
+ name: string;
82
+ input?: Record<string, unknown>;
83
+ };
84
+ /**
85
+ * Optional prefill string applied after the chat template's generation
86
+ * prompt — the model continues from the end of this string. Provider- and
87
+ * model-specific; core prescribes no syntax (the consuming app/orchestrator
88
+ * decides what control tokens, if any, to inject). Providers that support a
89
+ * "continue final message" mode apply it; others MAY ignore this field.
90
+ */
91
+ prefill?: string;
92
+ /**
93
+ * Verbatim system message to use INSTEAD of the provider building its own
94
+ * (e.g. the transformers provider's tool-system-message). Generic transport
95
+ * field : when set, the provider uses this string as the system message
96
+ * as-is. `tools` may still be passed (for the tool-call parser/dispatch)
97
+ * but is NOT re-rendered into the system prompt. Used to feed a fine-tuned
98
+ * model its EXACT training system prompt (anti-OOD). Providers that build no
99
+ * system message MAY ignore it.
100
+ */
101
+ systemOverride?: string;
102
+ /**
103
+ * Hint : stream tokens AS THEY ARRIVE (bypass the provider's flush-throttle).
104
+ * Default throttling coalesces UI paints to protect WebGPU decode speed ;
105
+ * a short codegen turn that drives a live preview (e.g. xlsx_ops ops) opts
106
+ * in so the consumer can render progressively. Providers MAY ignore it.
107
+ */
108
+ fastStream?: boolean;
109
+ /**
110
+ * Opaque metadata bag threaded through the request pipeline (e.g. from a
111
+ * requestInterceptor to the `_streamLoop` post-processor). Never sent to the
112
+ * AI provider — stripped before the network call. The well-known keys are
113
+ * typed; see {@link AparteRequestMeta}.
114
+ */
115
+ _meta?: AparteRequestMeta;
116
+ }
117
+ /** One phase of a multi-turn `_meta.pipeline` run: each phase is a single LLM
118
+ * turn whose reply becomes context for the next. */
119
+ export type ApartePipelinePhase = {
120
+ mode: 'text';
121
+ system: string;
122
+ } | {
123
+ mode: 'thinking';
124
+ system: string;
125
+ label?: string;
126
+ } | {
127
+ mode: 'artifact';
128
+ system: string;
129
+ mimeType: string;
130
+ kind: string;
131
+ };
132
+ /** A `{ mimeType, kind }` artifact hint for the `_meta` artifact modes. */
133
+ export interface AparteArtifactHint {
134
+ mimeType: string;
135
+ kind: string;
136
+ }
137
+ /**
138
+ * Well-known keys of {@link AparteChatRequest._meta}, typed for discoverability.
139
+ * The index signature keeps it an open channel for consumer-specific context.
140
+ * None of these reach the provider — they're stripped before the network call.
141
+ */
142
+ export interface AparteRequestMeta {
143
+ /** Multi-phase run — each phase is one LLM turn; reply N is context for N+1. */
144
+ pipeline?: ApartePipelinePhase[];
145
+ /** Segments injected into the bubble before streaming (e.g. a plan thinking block). */
146
+ prefixSegments?: AparteSegment[];
147
+ /** Promote the first code fence in the reply to an artifact (for small models that ignore `<artifact>` XML). */
148
+ artifactHint?: AparteArtifactHint;
149
+ /** Treat the WHOLE reply as a raw artifact of this kind. */
150
+ artifactRaw?: AparteArtifactHint;
151
+ /** Parse an `<artifact>` XML block of this kind out of the stream. */
152
+ artifactXml?: AparteArtifactHint;
153
+ /** Consumer-specific context (open channel). */
154
+ [key: string]: unknown;
155
+ }
156
+ /**
157
+ * Token usage reported by the AI provider after a completed response.
158
+ */
159
+ export interface AparteUsage {
160
+ /** Tokens in the prompt / conversation history sent to the model */
161
+ inputTokens: number;
162
+ /** Tokens generated by the model */
163
+ outputTokens: number;
164
+ /** Total tokens (inputTokens + outputTokens). Populated when the provider reports it. */
165
+ totalTokens?: number;
166
+ /** Tokens read from the provider's prompt cache (Anthropic, OpenAI). */
167
+ cacheReadTokens?: number;
168
+ /** Wall-clock generation time in milliseconds (provider-measured). Used to compute tokens/sec. */
169
+ durationMs?: number;
170
+ /** Time to first token in ms — the prefill / TTFT phase. */
171
+ ttftMs?: number;
172
+ /** Decode-phase wall time in ms (≈ durationMs − ttftMs). */
173
+ decodeMs?: number;
174
+ /** Tokens emitted during the decode phase (outputTokens minus the first). */
175
+ decodeTokens?: number;
176
+ /** Total turn wall-clock time in ms, measured client-side across all phases. */
177
+ wallMs?: number;
178
+ /** Id of the model / aparteni that produced this response. */
179
+ modelId?: string;
180
+ /** Compute device used for this response ('webgpu' | 'wasm' | …). */
181
+ device?: string;
182
+ /**
183
+ * Per-call breakdown when a single turn used several provider calls
184
+ * (e.g. a tool-use round-trip or an aparteni hot-swap). Absent for a plain
185
+ * single-call turn. Each entry is the AparteUsage of one provider call.
186
+ */
187
+ phases?: AparteUsage[];
188
+ }
189
+ /**
190
+ * Normalized stream event map — extensible via declaration merging.
191
+ *
192
+ * @example
193
+ * // In a plugin or app:
194
+ * declare module '@aparte/core' {
195
+ * interface AparteStreamEventMap {
196
+ * tool_call: { name: string; arguments: string }
197
+ * }
198
+ * }
199
+ */
200
+ export interface AparteStreamEventMap {
201
+ text: {
202
+ delta: string;
203
+ };
204
+ thinking: {
205
+ delta: string;
206
+ };
207
+ /** Emitted when the stream ends. May carry token usage reported by the provider. */
208
+ done: {
209
+ usage?: AparteUsage;
210
+ };
211
+ error: {
212
+ message: string;
213
+ };
214
+ tool_use: AparteToolCall;
215
+ }
216
+ /** Discriminated union derived from AparteStreamEventMap — stays in sync automatically. */
217
+ export type AparteStreamEvent = {
218
+ [K in keyof AparteStreamEventMap]: {
219
+ type: K;
220
+ } & AparteStreamEventMap[K];
221
+ }[keyof AparteStreamEventMap];
222
+ export type AparteChatResponse = ReadableStream<AparteStreamEvent> | string;
223
+ //# sourceMappingURL=chat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/types/chat.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ export declare enum AparteErrorCode {
2
+ CONFIG_NO_PROVIDER = "CONFIG_NO_PROVIDER",
3
+ CONFIG_MISSING_KEY = "CONFIG_MISSING_KEY",
4
+ CONFIG_INVALID_MODEL = "CONFIG_INVALID_MODEL",
5
+ USAGE_RATE_LIMIT = "USAGE_RATE_LIMIT",// HTTP 429
6
+ USAGE_CONTEXT_EXCEEDED = "USAGE_CONTEXT_EXCEEDED",// HTTP 400
7
+ USAGE_BAD_REQUEST = "USAGE_BAD_REQUEST",// HTTP 400
8
+ NET_OFFLINE = "NET_OFFLINE",
9
+ NET_TIMEOUT = "NET_TIMEOUT",
10
+ NET_ERROR = "NET_ERROR",
11
+ PROVIDER_ERROR = "PROVIDER_ERROR",// HTTP 5xx
12
+ PROVIDER_UNAVAILABLE = "PROVIDER_UNAVAILABLE",// HTTP 503
13
+ PROVIDER_POLICY = "PROVIDER_POLICY",// Moderation / Policy
14
+ UNKNOWN_ERROR = "UNKNOWN_ERROR"
15
+ }
16
+ export declare class AparteError extends Error {
17
+ message: string;
18
+ code: AparteErrorCode;
19
+ data?: Record<string, unknown> | undefined;
20
+ originalError?: unknown | undefined;
21
+ httpStatus?: number | undefined;
22
+ constructor(message: string, code: AparteErrorCode, data?: Record<string, unknown> | undefined, originalError?: unknown | undefined, httpStatus?: number | undefined);
23
+ static from(error: unknown, defaultCode?: AparteErrorCode, defaultStatus?: number): AparteError;
24
+ }
25
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/types/errors.ts"],"names":[],"mappings":"AACA,oBAAY,eAAe;IAEvB,kBAAkB,uBAAuB;IACzC,kBAAkB,uBAAuB;IACzC,oBAAoB,yBAAyB;IAG7C,gBAAgB,qBAAqB,CAAQ,WAAW;IACxD,sBAAsB,2BAA2B,CAAE,WAAW;IAC9D,iBAAiB,sBAAsB,CAAM,WAAW;IAGxD,WAAW,gBAAgB;IAC3B,WAAW,gBAAgB;IAC3B,SAAS,cAAc;IAGvB,cAAc,mBAAmB,CAAY,WAAW;IACxD,oBAAoB,yBAAyB,CAAE,WAAW;IAC1D,eAAe,oBAAoB,CAAU,sBAAsB;IAGnE,aAAa,kBAAkB;CAClC;AAED,qBAAa,WAAY,SAAQ,KAAK;IAEd,OAAO,EAAE,MAAM;IACxB,IAAI,EAAE,eAAe;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC9B,aAAa,CAAC,EAAE,OAAO;IACvB,UAAU,CAAC,EAAE,MAAM;gBAJV,OAAO,EAAE,MAAM,EACxB,IAAI,EAAE,eAAe,EACrB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YAAA,EAC9B,aAAa,CAAC,EAAE,OAAO,YAAA,EACvB,UAAU,CAAC,EAAE,MAAM,YAAA;IAM9B,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,WAAW,kBAAgC,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,WAAW;CAUhH"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Global typing for aparté custom events. Once `@aparte/core` is in a consumer's
3
+ * TypeScript program, `element.addEventListener('aparte-retry', e => e.detail)`
4
+ * types `e` as `CustomEvent<AparteRetryEventDetail>` with a typed `e.detail` — no
5
+ * manual `(e as CustomEvent<…>).detail` cast.
6
+ *
7
+ * Covers the public bubble / lifecycle / artifact / tool events whose detail type
8
+ * lives in the types layer. Internal component/primitive events (composer-submit,
9
+ * select-change, optgroup-toggle, …) intentionally fall back to the DOM's default
10
+ * `Event` — they carry no cross-package detail contract.
11
+ *
12
+ * All names are kebab-case (`aparte-*`) so every framework can bind them in a
13
+ * template (Angular parses a `:` in an event name as a `target:event` selector,
14
+ * so a colon name could never be `(aparte:x)`-bound there).
15
+ */
16
+ import type { AparteSendEventDetail, AparteRetryEventDetail, AparteEditEventDetail, AparteActionEventDetail, ApartePathChangedEventDetail, AparteBranchNavigateEventDetail, AparteFeedbackEventDetail, AparteMessageInfoEventDetail, AparteMessageDoneEventDetail, AparteModelChangeEventDetail, AparteArtifactStartEventDetail, AparteArtifactDeltaEventDetail, AparteArtifactReadyEventDetail, AparteArtifactOpenEventDetail } from './events.js';
17
+ import type { AparteToolDecisionDetail, AparteToolApprovalRequestDetail } from './tools.js';
18
+ import type { AparteComposerChangeEventDetail } from '../components/composer/aparte-composer.js';
19
+ declare global {
20
+ interface HTMLElementEventMap {
21
+ 'aparte-send': CustomEvent<AparteSendEventDetail>;
22
+ 'aparte-retry': CustomEvent<AparteRetryEventDetail>;
23
+ 'aparte-edit': CustomEvent<AparteEditEventDetail>;
24
+ 'aparte-action': CustomEvent<AparteActionEventDetail>;
25
+ 'aparte-path-changed': CustomEvent<ApartePathChangedEventDetail>;
26
+ 'aparte-branch-navigate': CustomEvent<AparteBranchNavigateEventDetail>;
27
+ 'aparte-feedback': CustomEvent<AparteFeedbackEventDetail>;
28
+ 'aparte-message-info': CustomEvent<AparteMessageInfoEventDetail>;
29
+ 'aparte-message-done': CustomEvent<AparteMessageDoneEventDetail>;
30
+ 'aparte-model-change': CustomEvent<AparteModelChangeEventDetail>;
31
+ 'aparte-artifact-start': CustomEvent<AparteArtifactStartEventDetail>;
32
+ 'aparte-artifact-delta': CustomEvent<AparteArtifactDeltaEventDetail>;
33
+ 'aparte-artifact-ready': CustomEvent<AparteArtifactReadyEventDetail>;
34
+ 'aparte-artifact-open': CustomEvent<AparteArtifactOpenEventDetail>;
35
+ 'aparte-tool-decision': CustomEvent<AparteToolDecisionDetail>;
36
+ 'aparte-tool-approval-request': CustomEvent<AparteToolApprovalRequestDetail>;
37
+ 'aparte-composer-change': CustomEvent<AparteComposerChangeEventDetail>;
38
+ }
39
+ }
40
+ export {};
41
+ //# sourceMappingURL=event-map.d.ts.map