@kedataindo/docflow-core 0.0.32 → 0.0.33

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/dist/index.d.cts CHANGED
@@ -4,6 +4,8 @@ import { IndexeddbPersistence } from 'y-indexeddb';
4
4
  import { WebrtcProvider } from 'y-webrtc';
5
5
  import { WebsocketProvider } from 'y-websocket';
6
6
  import * as Y from 'yjs';
7
+ import { I as ImageUploadHandler, C as CitationPort, A as AIStreamFn, a as AIDraftFn } from './index-BsIFJXPk.cjs';
8
+ export { b as AIAction, c as AIActionRequest, d as AICompleteRequest, e as AIConfig, f as AIDraftCitation, g as AIDraftEvent, h as AIProvider, i as AIProviderFactory, j as Auth, k as CONTEXT_CHAR_CAP, l as CslDate, m as CslItemData, n as CslName, H as HttpKeyStorageUrls, o as ImageUploadResult, K as KeyStorage, L as LOCAL_STORAGE_KEY, O as OpenAICompatibleConfig, S as StreamEvent, p as buildAIPrompt, q as httpKeyStorage, r as localStorageKeyStorage, s as memoryKeyStorage, t as openaiCompatibleProvider, u as toAIStreamFn, v as trimContextAfter, w as trimContextBefore } from './index-BsIFJXPk.cjs';
7
9
  import { PaginationPlusOptions } from 'tiptap-pagination-plus';
8
10
  export { PAGE_SIZES, PageSize, PaginationPlus, PaginationPlusOptions } from 'tiptap-pagination-plus';
9
11
  import { PluginKey } from '@tiptap/pm/state';
@@ -109,204 +111,6 @@ interface CollaborationSetup {
109
111
  declare function createCollaboration(options: CollaborationOptions): CollaborationSetup;
110
112
  declare function collaborationExtensions(options: CollaborationOptions | CollaborationSetup): AnyExtension[];
111
113
 
112
- /**
113
- * Injectable ports — the narrow interfaces through which the library reaches
114
- * host-provided backend capabilities (storage, persistence, …). The library
115
- * declares them; the host app implements them. See docs/LIBRARY_CONTRACT.md.
116
- */
117
- interface ImageUploadResult {
118
- /** Resolved URL/href the host stored the file at. */
119
- src: string;
120
- alt?: string;
121
- title?: string;
122
- }
123
- /**
124
- * Host-supplied image upload handler. Called with the file picked by the user;
125
- * resolves to the stored location to insert into the document. Reject to abort
126
- * the insert (the failure is logged, nothing is inserted).
127
- */
128
- type ImageUploadHandler = (file: File) => Promise<ImageUploadResult>;
129
- /** CSL-JSON name (see https://citeproc-js.readthedocs.io/csl-json/). */
130
- interface CslName {
131
- family?: string;
132
- given?: string;
133
- literal?: string;
134
- }
135
- /** CSL-JSON date. */
136
- interface CslDate {
137
- 'date-parts'?: number[][];
138
- raw?: string;
139
- literal?: string;
140
- }
141
- /**
142
- * A CSL-JSON item — the structured source metadata citeproc-js consumes.
143
- * Nodes store only `{ sourceId, locator }`; all rendered text is derived from
144
- * this data by the citation engine (never persisted in the document).
145
- */
146
- interface CslItemData {
147
- id: string;
148
- type: string;
149
- title?: string;
150
- author?: CslName[];
151
- editor?: CslName[];
152
- issued?: CslDate;
153
- 'container-title'?: string;
154
- publisher?: string;
155
- 'publisher-place'?: string;
156
- page?: string;
157
- volume?: string;
158
- issue?: string;
159
- DOI?: string;
160
- URL?: string;
161
- ISBN?: string;
162
- abstract?: string;
163
- [k: string]: unknown;
164
- }
165
- /**
166
- * Host-supplied citation port. The library never fetches sources itself — the
167
- * host owns the reference library and injects CSL-JSON through this port,
168
- * mirroring the `onImageUpload` injection pattern.
169
- */
170
- interface CitationPort {
171
- /** CSL-JSON provider — a snapshot array or a getter for live data. */
172
- sources: CslItemData[] | (() => CslItemData[]);
173
- /** Active CSL style id (e.g. 'chicago-notes-bibliography'). */
174
- style?: string;
175
- /**
176
- * Called when the user inserts a citation: the host opens its source
177
- * picker and resolves with the chosen source id (null = cancelled).
178
- */
179
- onSourceRequest?: () => Promise<string | null>;
180
- /**
181
- * Called when the set of cited source ids changes, so the host can update
182
- * its embedded per-document source snapshot.
183
- */
184
- onSourcesChange?: (ids: string[]) => void;
185
- /**
186
- * Optional importer (Phase 6C-2): resolve a DOI/URL into a new persisted
187
- * source via the host's backend (CrossRef lookup). Returns the created
188
- * (or deduplicated) source, null on failure.
189
- */
190
- onImportDoi?: (doi: string) => Promise<CslItemData | null>;
191
- /**
192
- * Optional importer (Phase 6C-3): parse + persist a BibTeX/RIS document
193
- * via the host's backend. Returns the imported sources and how many
194
- * entries failed.
195
- */
196
- onImportBibliography?: (payload: {
197
- format: 'bibtex' | 'ris';
198
- text: string;
199
- }) => Promise<{
200
- imported: CslItemData[];
201
- failed: number;
202
- }>;
203
- }
204
-
205
- /**
206
- * The library's only knowledge of LLMs (pluggable AI provider — issue #119).
207
- *
208
- * `AIProvider` is a thin transport: one prompt in, a stream of events out.
209
- * The library imports only this type — never an implementation. Hosts plug in
210
- * `openaiCompatibleProvider` (the default we ship) or their own class wrapping
211
- * an agent SDK, a proxy, or an in-process model. Agent orchestration, tool
212
- * calling, RAG, and multi-turn memory live behind the host's endpoint, not in
213
- * the library. See docs/plans/PLUGGABLE_AI_PROVIDER.md §4.1.
214
- */
215
- type StreamEvent = {
216
- type: 'delta';
217
- text: string;
218
- } | {
219
- type: 'done';
220
- stopReason?: string;
221
- } | {
222
- type: 'error';
223
- error: Error;
224
- };
225
- interface AICompleteRequest {
226
- system?: string;
227
- prompt: string;
228
- signal?: AbortSignal;
229
- }
230
- interface AIProvider {
231
- complete(req: AICompleteRequest): AsyncIterable<StreamEvent>;
232
- }
233
-
234
- /**
235
- * Shared AI action types (Phase 7; pluggable AI provider — issue #119).
236
- *
237
- * The library (aiPlugin) is provider-agnostic: it never names a URL or holds a
238
- * key. The host injects `aiStream` / `aiDraft` via `EditorOptions` — either a
239
- * hand-written function or `toAIStreamFn(openaiCompatibleProvider({...}))`
240
- * (see ./provider.ts, ./openaiCompatibleProvider.ts).
241
- */
242
-
243
- /**
244
- * Factory shape for hosts that hand the library a provider object rather than
245
- * a plain function (plan §4.2). `toAIStreamFn` adapts an `AIProvider` to the
246
- * `AIStreamFn` port, so both shapes are accepted at the boundary.
247
- */
248
- type AIProviderFactory = (config: {
249
- signal?: AbortSignal;
250
- }) => AIProvider;
251
- type AIAction = 'rewrite' | 'summarize' | 'grammar' | 'tone' | 'translate' | 'expand' | 'shorten' | 'generate' | 'chat' | 'draft';
252
- interface AIActionRequest {
253
- action: AIAction;
254
- /** Selected text (7B). */
255
- selection?: string;
256
- /** Bounded surrounding text — never the whole document. */
257
- context?: {
258
- before: string;
259
- after: string;
260
- };
261
- /** User instruction (/ai prompt, chat message, tone target, target language). */
262
- prompt?: string;
263
- /** For doc-aware chat / RAG scoping. */
264
- documentId?: string;
265
- options?: Record<string, unknown>;
266
- }
267
- /**
268
- * The app implements this and injects it; the library never knows the URL.
269
- * Yields streamed text chunks in order; stops at end of stream, throws on error.
270
- */
271
- type AIStreamFn = (req: AIActionRequest, signal: AbortSignal) => AsyncIterable<string>;
272
- /** One entry in the citation table carried by the SSE `done` event (§3.4). */
273
- interface AIDraftCitation {
274
- /** 1-based index matching a `[n]` marker in the streamed text. */
275
- ref: number;
276
- /** `Source._id` string — the library maps markers through this table. */
277
- sourceId: string;
278
- /** "first author family + year" tag, e.g. "Doe (2024)". */
279
- label: string;
280
- }
281
- /**
282
- * Events yielded by `aiDraft` (§3.5). The `done` event carries the citation
283
- * table; the `error` event does NOT (the bug-hunter carry-forward — the client
284
- * treats BOTH `done` and `error` as terminal; Insert is enabled only on `done`).
285
- */
286
- type AIDraftEvent = {
287
- type: 'delta';
288
- text: string;
289
- } | {
290
- type: 'done';
291
- citations: AIDraftCitation[];
292
- } | {
293
- type: 'error';
294
- message: string;
295
- };
296
- /**
297
- * The app implements this and injects it; the library never knows the URL.
298
- * Mirrors `AIStreamFn` but yields richer `AIDraftEvent`s (carries the citation
299
- * table on the terminal `done` event). Injected exactly like `aiStream`.
300
- */
301
- type AIDraftFn = (req: {
302
- prompt: string;
303
- context?: {
304
- before: string;
305
- after: string;
306
- };
307
- k?: number;
308
- }, signal: AbortSignal) => AsyncIterable<AIDraftEvent>;
309
-
310
114
  /**
311
115
  * Lightweight client-side performance monitor (debug overlay).
312
116
  *
@@ -566,118 +370,4 @@ declare class SubdocumentProvider {
566
370
  destroy(): void;
567
371
  }
568
372
 
569
- declare function toAIStreamFn(provider: AIProvider): AIStreamFn;
570
-
571
- /**
572
- * Per-action prompt assembly (pluggable AI provider — issue #119).
573
- *
574
- * Ported from the Phase 7 server proxy (`apps/server/src/ai/context.ts`) so
575
- * the browser can call the LLM directly: the selection + BOUNDED surrounding
576
- * text is sent — never the whole document (cost + privacy). Untrusted document
577
- * text stays in the user prompt; instructions live in the system prompt
578
- * (prompt-injection hygiene).
579
- */
580
-
581
- /** Max characters of surrounding context sent on each side of the selection. */
582
- declare const CONTEXT_CHAR_CAP = 1500;
583
- /** Last `CONTEXT_CHAR_CAP` chars of the preceding text (nearest context wins). */
584
- declare function trimContextBefore(text: string): string;
585
- /** First `CONTEXT_CHAR_CAP` chars of the following text. */
586
- declare function trimContextAfter(text: string): string;
587
- /**
588
- * Assemble the per-action system prompt + user prompt from a bounded request.
589
- * `draft` is rejected: RAG-cited drafting goes through the `aiDraft` port,
590
- * which owns its grounded-prompt assembly (Phase 7E).
591
- */
592
- declare function buildAIPrompt(req: AIActionRequest): {
593
- system: string;
594
- prompt: string;
595
- };
596
-
597
- /**
598
- * Where the AI provider's config (base URL + credentials + model) lives —
599
- * the host decides (pluggable AI provider — issue #119, plan §4.4).
600
- *
601
- * The URL and the key are a pair and travel together. The library ships three
602
- * reference implementations; hosts may write their own (e.g. keyed per-tenant
603
- * in their own backend). No URL is hardcoded anywhere — `httpKeyStorage`
604
- * receives its endpoints from the host, keeping the library backend-agnostic
605
- * (docs/LIBRARY_CONTRACT.md rule 3).
606
- */
607
- type Auth = {
608
- type: 'bearer';
609
- apiKey: string;
610
- } | {
611
- type: 'header';
612
- name: string;
613
- value: string;
614
- } | {
615
- type: 'none';
616
- };
617
- interface AIConfig {
618
- baseUrl: string;
619
- auth: Auth;
620
- model: string;
621
- /**
622
- * Who may receive this config in their browser (issue #126).
623
- * - `shared` (default): any authenticated user gets it via GET and calls
624
- * the LLM browser-direct — the #119 model.
625
- * - `admin-only`: only tenant admins get it; everyone else must complete
626
- * through the server's `/api/ai/complete` proxy so the key never leaves
627
- * the server.
628
- */
629
- visibility?: 'shared' | 'admin-only';
630
- }
631
- interface KeyStorage {
632
- get(): Promise<AIConfig | null>;
633
- set(value: AIConfig): Promise<void>;
634
- clear(): Promise<void>;
635
- }
636
- /** In-memory storage — for tests and SSR (no persistence). */
637
- declare function memoryKeyStorage(initial?: AIConfig | null): KeyStorage;
638
- declare const LOCAL_STORAGE_KEY = "docflow:ai-config";
639
- /**
640
- * Browser `localStorage` persistence — for embedded apps that want the config
641
- * kept client-side. Note: this stores AI *credentials*, not document data, so
642
- * it is the host's deliberate choice, not a library persistence leak.
643
- */
644
- declare function localStorageKeyStorage(key?: string, storage?: Storage): KeyStorage;
645
- interface HttpKeyStorageUrls {
646
- /** GET → 200 with the AIConfig JSON body, or 404 when unset. */
647
- getUrl: string;
648
- /** POST with the AIConfig JSON body. */
649
- setUrl: string;
650
- /** DELETE to clear. */
651
- deleteUrl: string;
652
- /** Optional fetch override (tests, custom credentials mode). Defaults to global fetch. */
653
- fetchImpl?: typeof fetch;
654
- }
655
- /**
656
- * Server-backed storage — for our SaaS web app (`/api/ai/config`) and any
657
- * embedded app that wants credentials kept on its own backend. Endpoints are
658
- * host-supplied; the library never names a path.
659
- */
660
- declare function httpKeyStorage(urls: HttpKeyStorageUrls): KeyStorage;
661
-
662
- /**
663
- * Default `AIProvider` implementation (pluggable AI provider — issue #119,
664
- * plan §4.3): OpenAI-shaped `POST {baseUrl}/chat/completions` with SSE
665
- * streaming. Covers OpenAI, Azure-style gateways, Ollama, vLLM, and most
666
- * OpenAI-compatible proxies.
667
- *
668
- * Cancellation-safe: closing the async iterator early (e.g. the user accepts
669
- * or cancels mid-stream) aborts the in-flight `fetch`; an aborted `req.signal`
670
- * ends the stream silently rather than yielding an error event.
671
- */
672
-
673
- interface OpenAICompatibleConfig {
674
- /** Base URL of the OpenAI-compatible endpoint, e.g. `https://api.openai.com/v1`. */
675
- baseUrl: string;
676
- auth: Auth;
677
- model: string;
678
- /** Prepended to every call's system prompt so hosts don't repeat it. */
679
- systemPrompt?: string;
680
- }
681
- declare function openaiCompatibleProvider(config: OpenAICompatibleConfig): AIProvider;
682
-
683
- export { type AIAction, type AIActionRequest, type AICompleteRequest, type AIConfig, type AIDraftCitation, type AIDraftEvent, type AIDraftFn, type AIProvider, type AIProviderFactory, type AIStreamFn, type Auth, type AwarenessState, BlockAttributesExtension, CONTEXT_CHAR_CAP, type CitationPort, type CollaborationOptions, type CollaborationSetup, type CslDate, type CslItemData, type CslName, type DocsEditor, type DocsEditorPlugin, EditorContextExtension, type EditorContextOptions, type EditorOptions, FontSizeExtension, type HttpKeyStorageUrls, type ImageUploadHandler, type ImageUploadResult, type KeyStorage, LOCAL_STORAGE_KEY, type MonitorMetric, type OpenAICompatibleConfig, PerformanceMonitor, type PerformanceMonitorOptions, SearchAndReplaceExtension, type SearchMatch, type SearchState, type SlashCommand, type StreamEvent, type SubdocState, SubdocumentProvider, type SubdocumentProviderOptions, type ToolbarItem, buildAIPrompt, clearSearch, collaborationExtensions, collectExtensions, createActionMap, createCollaboration, createEditor, createPerformanceMonitor, definePlugin, findMatches, getSearchState, httpKeyStorage, localStorageKeyStorage, memoryKeyStorage, openaiCompatibleProvider, replaceAll, replaceCurrent, resolveAction, sanitizePastedHTML, searchAndReplaceKey, searchNext, searchPrev, setSearchQuery, toAIStreamFn, trimContextAfter, trimContextBefore };
373
+ export { AIDraftFn, AIStreamFn, type AwarenessState, BlockAttributesExtension, CitationPort, type CollaborationOptions, type CollaborationSetup, type DocsEditor, type DocsEditorPlugin, EditorContextExtension, type EditorContextOptions, type EditorOptions, FontSizeExtension, ImageUploadHandler, type MonitorMetric, PerformanceMonitor, type PerformanceMonitorOptions, SearchAndReplaceExtension, type SearchMatch, type SearchState, type SlashCommand, type SubdocState, SubdocumentProvider, type SubdocumentProviderOptions, type ToolbarItem, clearSearch, collaborationExtensions, collectExtensions, createActionMap, createCollaboration, createEditor, createPerformanceMonitor, definePlugin, findMatches, getSearchState, replaceAll, replaceCurrent, resolveAction, sanitizePastedHTML, searchAndReplaceKey, searchNext, searchPrev, setSearchQuery };
package/dist/index.d.ts CHANGED
@@ -4,6 +4,8 @@ import { IndexeddbPersistence } from 'y-indexeddb';
4
4
  import { WebrtcProvider } from 'y-webrtc';
5
5
  import { WebsocketProvider } from 'y-websocket';
6
6
  import * as Y from 'yjs';
7
+ import { I as ImageUploadHandler, C as CitationPort, A as AIStreamFn, a as AIDraftFn } from './index-BsIFJXPk.js';
8
+ export { b as AIAction, c as AIActionRequest, d as AICompleteRequest, e as AIConfig, f as AIDraftCitation, g as AIDraftEvent, h as AIProvider, i as AIProviderFactory, j as Auth, k as CONTEXT_CHAR_CAP, l as CslDate, m as CslItemData, n as CslName, H as HttpKeyStorageUrls, o as ImageUploadResult, K as KeyStorage, L as LOCAL_STORAGE_KEY, O as OpenAICompatibleConfig, S as StreamEvent, p as buildAIPrompt, q as httpKeyStorage, r as localStorageKeyStorage, s as memoryKeyStorage, t as openaiCompatibleProvider, u as toAIStreamFn, v as trimContextAfter, w as trimContextBefore } from './index-BsIFJXPk.js';
7
9
  import { PaginationPlusOptions } from 'tiptap-pagination-plus';
8
10
  export { PAGE_SIZES, PageSize, PaginationPlus, PaginationPlusOptions } from 'tiptap-pagination-plus';
9
11
  import { PluginKey } from '@tiptap/pm/state';
@@ -109,204 +111,6 @@ interface CollaborationSetup {
109
111
  declare function createCollaboration(options: CollaborationOptions): CollaborationSetup;
110
112
  declare function collaborationExtensions(options: CollaborationOptions | CollaborationSetup): AnyExtension[];
111
113
 
112
- /**
113
- * Injectable ports — the narrow interfaces through which the library reaches
114
- * host-provided backend capabilities (storage, persistence, …). The library
115
- * declares them; the host app implements them. See docs/LIBRARY_CONTRACT.md.
116
- */
117
- interface ImageUploadResult {
118
- /** Resolved URL/href the host stored the file at. */
119
- src: string;
120
- alt?: string;
121
- title?: string;
122
- }
123
- /**
124
- * Host-supplied image upload handler. Called with the file picked by the user;
125
- * resolves to the stored location to insert into the document. Reject to abort
126
- * the insert (the failure is logged, nothing is inserted).
127
- */
128
- type ImageUploadHandler = (file: File) => Promise<ImageUploadResult>;
129
- /** CSL-JSON name (see https://citeproc-js.readthedocs.io/csl-json/). */
130
- interface CslName {
131
- family?: string;
132
- given?: string;
133
- literal?: string;
134
- }
135
- /** CSL-JSON date. */
136
- interface CslDate {
137
- 'date-parts'?: number[][];
138
- raw?: string;
139
- literal?: string;
140
- }
141
- /**
142
- * A CSL-JSON item — the structured source metadata citeproc-js consumes.
143
- * Nodes store only `{ sourceId, locator }`; all rendered text is derived from
144
- * this data by the citation engine (never persisted in the document).
145
- */
146
- interface CslItemData {
147
- id: string;
148
- type: string;
149
- title?: string;
150
- author?: CslName[];
151
- editor?: CslName[];
152
- issued?: CslDate;
153
- 'container-title'?: string;
154
- publisher?: string;
155
- 'publisher-place'?: string;
156
- page?: string;
157
- volume?: string;
158
- issue?: string;
159
- DOI?: string;
160
- URL?: string;
161
- ISBN?: string;
162
- abstract?: string;
163
- [k: string]: unknown;
164
- }
165
- /**
166
- * Host-supplied citation port. The library never fetches sources itself — the
167
- * host owns the reference library and injects CSL-JSON through this port,
168
- * mirroring the `onImageUpload` injection pattern.
169
- */
170
- interface CitationPort {
171
- /** CSL-JSON provider — a snapshot array or a getter for live data. */
172
- sources: CslItemData[] | (() => CslItemData[]);
173
- /** Active CSL style id (e.g. 'chicago-notes-bibliography'). */
174
- style?: string;
175
- /**
176
- * Called when the user inserts a citation: the host opens its source
177
- * picker and resolves with the chosen source id (null = cancelled).
178
- */
179
- onSourceRequest?: () => Promise<string | null>;
180
- /**
181
- * Called when the set of cited source ids changes, so the host can update
182
- * its embedded per-document source snapshot.
183
- */
184
- onSourcesChange?: (ids: string[]) => void;
185
- /**
186
- * Optional importer (Phase 6C-2): resolve a DOI/URL into a new persisted
187
- * source via the host's backend (CrossRef lookup). Returns the created
188
- * (or deduplicated) source, null on failure.
189
- */
190
- onImportDoi?: (doi: string) => Promise<CslItemData | null>;
191
- /**
192
- * Optional importer (Phase 6C-3): parse + persist a BibTeX/RIS document
193
- * via the host's backend. Returns the imported sources and how many
194
- * entries failed.
195
- */
196
- onImportBibliography?: (payload: {
197
- format: 'bibtex' | 'ris';
198
- text: string;
199
- }) => Promise<{
200
- imported: CslItemData[];
201
- failed: number;
202
- }>;
203
- }
204
-
205
- /**
206
- * The library's only knowledge of LLMs (pluggable AI provider — issue #119).
207
- *
208
- * `AIProvider` is a thin transport: one prompt in, a stream of events out.
209
- * The library imports only this type — never an implementation. Hosts plug in
210
- * `openaiCompatibleProvider` (the default we ship) or their own class wrapping
211
- * an agent SDK, a proxy, or an in-process model. Agent orchestration, tool
212
- * calling, RAG, and multi-turn memory live behind the host's endpoint, not in
213
- * the library. See docs/plans/PLUGGABLE_AI_PROVIDER.md §4.1.
214
- */
215
- type StreamEvent = {
216
- type: 'delta';
217
- text: string;
218
- } | {
219
- type: 'done';
220
- stopReason?: string;
221
- } | {
222
- type: 'error';
223
- error: Error;
224
- };
225
- interface AICompleteRequest {
226
- system?: string;
227
- prompt: string;
228
- signal?: AbortSignal;
229
- }
230
- interface AIProvider {
231
- complete(req: AICompleteRequest): AsyncIterable<StreamEvent>;
232
- }
233
-
234
- /**
235
- * Shared AI action types (Phase 7; pluggable AI provider — issue #119).
236
- *
237
- * The library (aiPlugin) is provider-agnostic: it never names a URL or holds a
238
- * key. The host injects `aiStream` / `aiDraft` via `EditorOptions` — either a
239
- * hand-written function or `toAIStreamFn(openaiCompatibleProvider({...}))`
240
- * (see ./provider.ts, ./openaiCompatibleProvider.ts).
241
- */
242
-
243
- /**
244
- * Factory shape for hosts that hand the library a provider object rather than
245
- * a plain function (plan §4.2). `toAIStreamFn` adapts an `AIProvider` to the
246
- * `AIStreamFn` port, so both shapes are accepted at the boundary.
247
- */
248
- type AIProviderFactory = (config: {
249
- signal?: AbortSignal;
250
- }) => AIProvider;
251
- type AIAction = 'rewrite' | 'summarize' | 'grammar' | 'tone' | 'translate' | 'expand' | 'shorten' | 'generate' | 'chat' | 'draft';
252
- interface AIActionRequest {
253
- action: AIAction;
254
- /** Selected text (7B). */
255
- selection?: string;
256
- /** Bounded surrounding text — never the whole document. */
257
- context?: {
258
- before: string;
259
- after: string;
260
- };
261
- /** User instruction (/ai prompt, chat message, tone target, target language). */
262
- prompt?: string;
263
- /** For doc-aware chat / RAG scoping. */
264
- documentId?: string;
265
- options?: Record<string, unknown>;
266
- }
267
- /**
268
- * The app implements this and injects it; the library never knows the URL.
269
- * Yields streamed text chunks in order; stops at end of stream, throws on error.
270
- */
271
- type AIStreamFn = (req: AIActionRequest, signal: AbortSignal) => AsyncIterable<string>;
272
- /** One entry in the citation table carried by the SSE `done` event (§3.4). */
273
- interface AIDraftCitation {
274
- /** 1-based index matching a `[n]` marker in the streamed text. */
275
- ref: number;
276
- /** `Source._id` string — the library maps markers through this table. */
277
- sourceId: string;
278
- /** "first author family + year" tag, e.g. "Doe (2024)". */
279
- label: string;
280
- }
281
- /**
282
- * Events yielded by `aiDraft` (§3.5). The `done` event carries the citation
283
- * table; the `error` event does NOT (the bug-hunter carry-forward — the client
284
- * treats BOTH `done` and `error` as terminal; Insert is enabled only on `done`).
285
- */
286
- type AIDraftEvent = {
287
- type: 'delta';
288
- text: string;
289
- } | {
290
- type: 'done';
291
- citations: AIDraftCitation[];
292
- } | {
293
- type: 'error';
294
- message: string;
295
- };
296
- /**
297
- * The app implements this and injects it; the library never knows the URL.
298
- * Mirrors `AIStreamFn` but yields richer `AIDraftEvent`s (carries the citation
299
- * table on the terminal `done` event). Injected exactly like `aiStream`.
300
- */
301
- type AIDraftFn = (req: {
302
- prompt: string;
303
- context?: {
304
- before: string;
305
- after: string;
306
- };
307
- k?: number;
308
- }, signal: AbortSignal) => AsyncIterable<AIDraftEvent>;
309
-
310
114
  /**
311
115
  * Lightweight client-side performance monitor (debug overlay).
312
116
  *
@@ -566,118 +370,4 @@ declare class SubdocumentProvider {
566
370
  destroy(): void;
567
371
  }
568
372
 
569
- declare function toAIStreamFn(provider: AIProvider): AIStreamFn;
570
-
571
- /**
572
- * Per-action prompt assembly (pluggable AI provider — issue #119).
573
- *
574
- * Ported from the Phase 7 server proxy (`apps/server/src/ai/context.ts`) so
575
- * the browser can call the LLM directly: the selection + BOUNDED surrounding
576
- * text is sent — never the whole document (cost + privacy). Untrusted document
577
- * text stays in the user prompt; instructions live in the system prompt
578
- * (prompt-injection hygiene).
579
- */
580
-
581
- /** Max characters of surrounding context sent on each side of the selection. */
582
- declare const CONTEXT_CHAR_CAP = 1500;
583
- /** Last `CONTEXT_CHAR_CAP` chars of the preceding text (nearest context wins). */
584
- declare function trimContextBefore(text: string): string;
585
- /** First `CONTEXT_CHAR_CAP` chars of the following text. */
586
- declare function trimContextAfter(text: string): string;
587
- /**
588
- * Assemble the per-action system prompt + user prompt from a bounded request.
589
- * `draft` is rejected: RAG-cited drafting goes through the `aiDraft` port,
590
- * which owns its grounded-prompt assembly (Phase 7E).
591
- */
592
- declare function buildAIPrompt(req: AIActionRequest): {
593
- system: string;
594
- prompt: string;
595
- };
596
-
597
- /**
598
- * Where the AI provider's config (base URL + credentials + model) lives —
599
- * the host decides (pluggable AI provider — issue #119, plan §4.4).
600
- *
601
- * The URL and the key are a pair and travel together. The library ships three
602
- * reference implementations; hosts may write their own (e.g. keyed per-tenant
603
- * in their own backend). No URL is hardcoded anywhere — `httpKeyStorage`
604
- * receives its endpoints from the host, keeping the library backend-agnostic
605
- * (docs/LIBRARY_CONTRACT.md rule 3).
606
- */
607
- type Auth = {
608
- type: 'bearer';
609
- apiKey: string;
610
- } | {
611
- type: 'header';
612
- name: string;
613
- value: string;
614
- } | {
615
- type: 'none';
616
- };
617
- interface AIConfig {
618
- baseUrl: string;
619
- auth: Auth;
620
- model: string;
621
- /**
622
- * Who may receive this config in their browser (issue #126).
623
- * - `shared` (default): any authenticated user gets it via GET and calls
624
- * the LLM browser-direct — the #119 model.
625
- * - `admin-only`: only tenant admins get it; everyone else must complete
626
- * through the server's `/api/ai/complete` proxy so the key never leaves
627
- * the server.
628
- */
629
- visibility?: 'shared' | 'admin-only';
630
- }
631
- interface KeyStorage {
632
- get(): Promise<AIConfig | null>;
633
- set(value: AIConfig): Promise<void>;
634
- clear(): Promise<void>;
635
- }
636
- /** In-memory storage — for tests and SSR (no persistence). */
637
- declare function memoryKeyStorage(initial?: AIConfig | null): KeyStorage;
638
- declare const LOCAL_STORAGE_KEY = "docflow:ai-config";
639
- /**
640
- * Browser `localStorage` persistence — for embedded apps that want the config
641
- * kept client-side. Note: this stores AI *credentials*, not document data, so
642
- * it is the host's deliberate choice, not a library persistence leak.
643
- */
644
- declare function localStorageKeyStorage(key?: string, storage?: Storage): KeyStorage;
645
- interface HttpKeyStorageUrls {
646
- /** GET → 200 with the AIConfig JSON body, or 404 when unset. */
647
- getUrl: string;
648
- /** POST with the AIConfig JSON body. */
649
- setUrl: string;
650
- /** DELETE to clear. */
651
- deleteUrl: string;
652
- /** Optional fetch override (tests, custom credentials mode). Defaults to global fetch. */
653
- fetchImpl?: typeof fetch;
654
- }
655
- /**
656
- * Server-backed storage — for our SaaS web app (`/api/ai/config`) and any
657
- * embedded app that wants credentials kept on its own backend. Endpoints are
658
- * host-supplied; the library never names a path.
659
- */
660
- declare function httpKeyStorage(urls: HttpKeyStorageUrls): KeyStorage;
661
-
662
- /**
663
- * Default `AIProvider` implementation (pluggable AI provider — issue #119,
664
- * plan §4.3): OpenAI-shaped `POST {baseUrl}/chat/completions` with SSE
665
- * streaming. Covers OpenAI, Azure-style gateways, Ollama, vLLM, and most
666
- * OpenAI-compatible proxies.
667
- *
668
- * Cancellation-safe: closing the async iterator early (e.g. the user accepts
669
- * or cancels mid-stream) aborts the in-flight `fetch`; an aborted `req.signal`
670
- * ends the stream silently rather than yielding an error event.
671
- */
672
-
673
- interface OpenAICompatibleConfig {
674
- /** Base URL of the OpenAI-compatible endpoint, e.g. `https://api.openai.com/v1`. */
675
- baseUrl: string;
676
- auth: Auth;
677
- model: string;
678
- /** Prepended to every call's system prompt so hosts don't repeat it. */
679
- systemPrompt?: string;
680
- }
681
- declare function openaiCompatibleProvider(config: OpenAICompatibleConfig): AIProvider;
682
-
683
- export { type AIAction, type AIActionRequest, type AICompleteRequest, type AIConfig, type AIDraftCitation, type AIDraftEvent, type AIDraftFn, type AIProvider, type AIProviderFactory, type AIStreamFn, type Auth, type AwarenessState, BlockAttributesExtension, CONTEXT_CHAR_CAP, type CitationPort, type CollaborationOptions, type CollaborationSetup, type CslDate, type CslItemData, type CslName, type DocsEditor, type DocsEditorPlugin, EditorContextExtension, type EditorContextOptions, type EditorOptions, FontSizeExtension, type HttpKeyStorageUrls, type ImageUploadHandler, type ImageUploadResult, type KeyStorage, LOCAL_STORAGE_KEY, type MonitorMetric, type OpenAICompatibleConfig, PerformanceMonitor, type PerformanceMonitorOptions, SearchAndReplaceExtension, type SearchMatch, type SearchState, type SlashCommand, type StreamEvent, type SubdocState, SubdocumentProvider, type SubdocumentProviderOptions, type ToolbarItem, buildAIPrompt, clearSearch, collaborationExtensions, collectExtensions, createActionMap, createCollaboration, createEditor, createPerformanceMonitor, definePlugin, findMatches, getSearchState, httpKeyStorage, localStorageKeyStorage, memoryKeyStorage, openaiCompatibleProvider, replaceAll, replaceCurrent, resolveAction, sanitizePastedHTML, searchAndReplaceKey, searchNext, searchPrev, setSearchQuery, toAIStreamFn, trimContextAfter, trimContextBefore };
373
+ export { AIDraftFn, AIStreamFn, type AwarenessState, BlockAttributesExtension, CitationPort, type CollaborationOptions, type CollaborationSetup, type DocsEditor, type DocsEditorPlugin, EditorContextExtension, type EditorContextOptions, type EditorOptions, FontSizeExtension, ImageUploadHandler, type MonitorMetric, PerformanceMonitor, type PerformanceMonitorOptions, SearchAndReplaceExtension, type SearchMatch, type SearchState, type SlashCommand, type SubdocState, SubdocumentProvider, type SubdocumentProviderOptions, type ToolbarItem, clearSearch, collaborationExtensions, collectExtensions, createActionMap, createCollaboration, createEditor, createPerformanceMonitor, definePlugin, findMatches, getSearchState, replaceAll, replaceCurrent, resolveAction, sanitizePastedHTML, searchAndReplaceKey, searchNext, searchPrev, setSearchQuery };