@eigenpal/docx-editor-agents 0.5.1 → 1.0.1

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 (72) hide show
  1. package/LICENSE +204 -672
  2. package/README.md +74 -42
  3. package/dist/agent-types-C8RvQB7n.d.mts +36 -0
  4. package/dist/agent-types-C8RvQB7n.d.ts +36 -0
  5. package/dist/ai-sdk/react.d.mts +29 -39
  6. package/dist/ai-sdk/react.d.ts +29 -39
  7. package/dist/ai-sdk/react.js +1 -1
  8. package/dist/ai-sdk/react.mjs +1 -1
  9. package/dist/ai-sdk/server.d.mts +42 -4
  10. package/dist/ai-sdk/server.d.ts +42 -4
  11. package/dist/ai-sdk/vue.d.ts +32 -0
  12. package/dist/ai-sdk/vue.js +1 -0
  13. package/dist/ai-sdk/vue.mjs +31 -0
  14. package/dist/bridge.d.mts +18 -1
  15. package/dist/bridge.d.ts +18 -1
  16. package/dist/bridge.js +1 -1
  17. package/dist/bridge.mjs +1 -1
  18. package/dist/chunk-BJPVVT5W.mjs +1 -0
  19. package/dist/{chunk-CPJV53R6.mjs → chunk-DEDOV3KL.mjs} +1 -1
  20. package/dist/chunk-DQH7AV5E.js +71 -0
  21. package/dist/chunk-DZYPK4JQ.mjs +2 -0
  22. package/dist/chunk-JH5VOTEK.js +2 -0
  23. package/dist/chunk-LSPYEWWJ.js +1 -0
  24. package/dist/chunk-NISW2GF6.js +1 -0
  25. package/dist/chunk-NX2KNBB6.mjs +71 -0
  26. package/dist/{chunk-LVRKZUG4.js → chunk-TFIRB2ZB.js} +3 -3
  27. package/dist/chunk-X4YGLGUM.mjs +1 -0
  28. package/dist/docx-editor-agents.css +1 -0
  29. package/dist/executor-QBMOTUCJ.js +1 -0
  30. package/dist/executor-RSQI3VOF.mjs +1 -0
  31. package/dist/{headless-JRF2KBID.mjs → headless-J5TF46GZ.mjs} +1 -1
  32. package/dist/headless-ULW7Q5F4.js +1 -0
  33. package/dist/index.d.mts +32 -2
  34. package/dist/index.d.ts +32 -2
  35. package/dist/index.js +1 -1
  36. package/dist/index.mjs +1 -1
  37. package/dist/mcp.d.mts +20 -1
  38. package/dist/mcp.d.ts +20 -1
  39. package/dist/react.d.mts +175 -3
  40. package/dist/react.d.ts +175 -3
  41. package/dist/react.js +9 -1
  42. package/dist/react.mjs +9 -1
  43. package/dist/{server-DH5eszkm.d.mts → server-B7RHNVSu.d.mts} +970 -753
  44. package/dist/{server-DH5eszkm.d.ts → server-B7RHNVSu.d.ts} +970 -753
  45. package/dist/server.d.mts +34 -1
  46. package/dist/server.d.ts +34 -1
  47. package/dist/server.js +1 -1
  48. package/dist/server.mjs +1 -1
  49. package/dist/vue/components/AIContextMenu.d.ts +33 -0
  50. package/dist/vue/components/AIResponsePreview.d.ts +40 -0
  51. package/dist/vue/components/AgentChatLog.d.ts +37 -0
  52. package/dist/vue/components/AgentComposer.d.ts +30 -0
  53. package/dist/vue/components/AgentPanel.d.ts +49 -0
  54. package/dist/vue/components/AgentSuggestionChip.d.ts +10 -0
  55. package/dist/vue/components/AgentTimeline.d.ts +19 -0
  56. package/dist/vue/composables/useAgentBridge.d.ts +19 -0
  57. package/dist/vue/types.d.ts +5 -0
  58. package/dist/vue.d.ts +72 -0
  59. package/dist/vue.js +21 -0
  60. package/dist/vue.mjs +1857 -0
  61. package/package.json +52 -9
  62. package/dist/chunk-6NWAUIGY.js +0 -1
  63. package/dist/chunk-A6ANAWKH.js +0 -1
  64. package/dist/chunk-BDHS4WRJ.mjs +0 -1
  65. package/dist/chunk-G46D3GDJ.js +0 -71
  66. package/dist/chunk-N2TKFYHU.js +0 -2
  67. package/dist/chunk-QALBLABE.mjs +0 -2
  68. package/dist/chunk-U7BWZ7DG.mjs +0 -1
  69. package/dist/chunk-XZHZXQO5.mjs +0 -71
  70. package/dist/executor-OYRPTNBR.mjs +0 -1
  71. package/dist/executor-SJAFSXKL.js +0 -1
  72. package/dist/headless-FE3K7ABO.js +0 -1
package/README.md CHANGED
@@ -1,94 +1,126 @@
1
+ <p align="center">
2
+ <a href="https://www.docx-editor.dev/">
3
+ <img src="https://raw.githubusercontent.com/eigenpal/docx-editor/main/assets/header.png" alt="DOCX Editor — .docx in, .docx out. Open source, agent ready, client-side." width="500" />
4
+ </a>
5
+ </p>
6
+
7
+ <p align="center">
8
+ <a href="https://www.npmjs.com/package/@eigenpal/docx-editor-agents"><img src="https://img.shields.io/npm/v/@eigenpal/docx-editor-agents.svg?style=flat-square&color=3B5BDB" alt="npm version" /></a>
9
+ <a href="https://www.npmjs.com/package/@eigenpal/docx-editor-agents"><img src="https://img.shields.io/npm/dm/@eigenpal/docx-editor-agents.svg?style=flat-square&color=3B5BDB" alt="npm downloads" /></a>
10
+ <a href="https://github.com/eigenpal/docx-editor/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache_2.0-blue.svg?style=flat-square&color=3B5BDB" alt="license" /></a>
11
+ <a href="https://docx-editor.dev/editor"><img src="https://img.shields.io/badge/Live_Demo-3B5BDB?style=flat-square&logo=vercel&logoColor=white" alt="Demo" /></a>
12
+ <a href="https://www.docx-editor.dev/docs"><img src="https://img.shields.io/badge/Docs-3B5BDB?style=flat-square&logo=readthedocs&logoColor=white" alt="Documentation" /></a>
13
+ </p>
14
+
1
15
  # @eigenpal/docx-editor-agents
2
16
 
3
- [![License: AGPL-3.0](https://img.shields.io/badge/License-AGPL--3.0-blue.svg)](./LICENSE)
17
+ Word-like API for AI agents to review DOCX documents. Read, comment, suggest tracked changes, accept/reject. Headless, server-friendly, browser-friendly. The library you build your AI document features on top of.
4
18
 
5
- Word-like API for AI agents to review DOCX documents. Read, comment, suggest tracked changes, accept/reject. Headless. Server-friendly. Browser-friendly. **The library you build your AI document features on top of.**
19
+ ## Quick Start
6
20
 
7
21
  ```bash
8
22
  npm install @eigenpal/docx-editor-agents
9
23
  ```
10
24
 
11
- ## Three ways to use this package
12
-
13
- ### 1. Static review (`DocxReviewer`) — single function call against a parsed DOCX
14
-
15
25
  ```ts
26
+ import { readFile, writeFile } from 'node:fs/promises';
16
27
  import { DocxReviewer } from '@eigenpal/docx-editor-agents';
17
28
 
29
+ const buffer = await readFile('contract.docx');
18
30
  const reviewer = await DocxReviewer.fromBuffer(buffer, 'AI Reviewer');
31
+
19
32
  reviewer.addComment(5, 'This cap seems too low.');
20
33
  reviewer.replace(5, '$50k', '$500k');
21
- const output = await reviewer.toBuffer();
34
+
35
+ await writeFile('contract.reviewed.docx', new Uint8Array(await reviewer.toBuffer()));
22
36
  ```
23
37
 
24
- Drop into a CI bot, a queue worker, a Lambda. No editor needed. ~50 KB.
38
+ That's the static-review path: drop into a CI bot, queue worker, or Lambda. No editor needed. ~50 KB.
25
39
 
26
- ### 2. Live editor bridge (`createEditorBridge`) — wire AI tools into a running `<DocxEditor>` instance
40
+ ## Packages
27
41
 
28
- ```ts
29
- import { useAgentChat } from '@eigenpal/docx-editor-agents/bridge';
42
+ | Package | Description |
43
+ | -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
44
+ | [`@eigenpal/docx-editor-react`](https://www.npmjs.com/package/@eigenpal/docx-editor-react) | <img src="https://cdn.simpleicons.org/react/61DAFB" width="20" align="middle" /> &nbsp; React adapter. Toolbar, paged editor, plugins. |
45
+ | [`@eigenpal/docx-editor-vue`](https://www.npmjs.com/package/@eigenpal/docx-editor-vue) | <img src="https://cdn.simpleicons.org/vuedotjs/4FC08D" width="20" align="middle" /> &nbsp; Vue 3 adapter. Toolbar, paged editor, plugins. |
46
+ | [`@eigenpal/docx-editor-core`](https://www.npmjs.com/package/@eigenpal/docx-editor-core) | Framework-agnostic core: OOXML parser, serializer, layout engine, ProseMirror schema. Depend on this if you fork the React or Vue adapter. |
47
+ | [`@eigenpal/docx-editor-i18n`](https://www.npmjs.com/package/@eigenpal/docx-editor-i18n) | Shared locale strings and types consumed by both adapters. |
48
+ | [`@eigenpal/docx-editor-agents`](https://www.npmjs.com/package/@eigenpal/docx-editor-agents) | Agent SDK and chat UI: framework-agnostic bridge, MCP server, AI SDK adapters, plus React UI. |
49
+
50
+ > **Forking the adapter?** Keep your fork thin. Depend on `@eigenpal/docx-editor-core` directly so parser, serializer, and rendering fixes land in your build automatically, without backporting each upstream change by hand.
51
+
52
+ ## Live editor bridge
30
53
 
54
+ Wire AI tools into a running `<DocxEditor>` so `add_comment`, `suggest_change`, `find_text` etc. show up live in the user's editor.
55
+
56
+ ```ts
57
+ // React
58
+ import { useAgentChat } from '@eigenpal/docx-editor-agents/react';
31
59
  const { executeToolCall, toolSchemas } = useAgentChat({ editorRef, author: 'Assistant' });
60
+
61
+ // Vue
62
+ import { useAgentBridge } from '@eigenpal/docx-editor-agents/vue';
63
+ const { executeToolCall, toolSchemas } = useAgentBridge({ editorRef, author: 'Assistant' });
32
64
  ```
33
65
 
34
- The agent's `add_comment`, `suggest_change`, `find_text` etc. show up live in the user's editor. Used by Eigenpal's chat panel; published for anyone building an AI document UX.
66
+ Both share the same `EditorRefLike` contract from `/bridge`, the same tool catalog, and the same `AgentMessage[]` chat shape. For other frameworks, build the bridge directly via `createEditorBridge` from `@eigenpal/docx-editor-agents/bridge`.
35
67
 
36
- ### 3. Build your own MCP server (`McpServer` + `createReviewerBridge`) — the SaaS path
68
+ ## MCP server
37
69
 
38
- This is the one most teams want. The published library exposes a transport-agnostic MCP server core. **You wrap it inside your own auth, storage, and transport layer.** Stdio, HTTP-SSE, WebSocket, queue-worker — your call.
70
+ Transport-agnostic core. Wrap it with your own auth, storage, and transport (HTTP-SSE, WebSocket, queue worker, anything).
39
71
 
40
72
  ```ts
41
- // Your /api/mcp/sse route — Express, Hono, Next.js, whatever
42
73
  import { McpServer, createReviewerBridge, DocxReviewer } from '@eigenpal/docx-editor-agents';
43
74
 
44
75
  app.post('/api/mcp', requireAuth, async (req, res) => {
45
- // 1. Pull the DOCX from your storage (S3, Postgres bytea, etc.)
46
76
  const buffer = await loadDocxForUser(req.user, req.params.docId);
47
-
48
- // 2. Wire it through the bridge
49
77
  const reviewer = await DocxReviewer.fromBuffer(buffer, req.user.name);
50
- const bridge = createReviewerBridge(reviewer);
51
- const server = new McpServer(bridge, {
52
- name: 'acme-contract-review',
78
+ const server = new McpServer(createReviewerBridge(reviewer), {
79
+ name: 'acme-review',
53
80
  version: '1.0.0',
54
81
  });
55
82
 
56
- // 3. Drive MCP messages over your transport. server.handle() is sync,
57
- // transport-free, and never throws.
58
- const reply = server.handle(JSON.parse(req.body));
59
- res.json(reply);
83
+ res.json(server.handle(JSON.parse(req.body))); // sync, transport-free, never throws
60
84
 
61
- // 4. After the agent's done, persist the modified DOCX back to your storage.
62
85
  await saveDocxForUser(req.user, req.params.docId, await reviewer.toBuffer());
63
86
  });
64
87
  ```
65
88
 
66
- That's the whole shape. Ten built-in agent tools (`read_document`, `find_text`, `add_comment`, `suggest_change`, `read_comments`, `read_changes`, `reply_comment`, `resolve_comment`, `read_selection`, `scroll`) are exposed automatically through MCP `tools/list` and `tools/call`. MCP spec version: `2025-06-18`.
89
+ Ten built-in agent tools (`read_document`, `find_text`, `add_comment`, `suggest_change`, `read_comments`, `read_changes`, `reply_comment`, `resolve_comment`, `read_selection`, `scroll`) are exposed automatically via MCP `tools/list` and `tools/call`. MCP spec version: `2025-06-18`.
67
90
 
68
- #### Why server-side, why not a local stdio bin?
91
+ > A local stdio MCP bin is one-document-per-config (Claude Desktop loads its list at startup), which doesn't fit a multi-doc product. Host the server yourself with your own auth and storage.
69
92
 
70
- A local-installed stdio MCP server only works for one document per config — Claude Desktop loads its MCP server list at startup. That's a useless shape for a contract-review product where users have many documents. The right deployment is **a hosted MCP server you operate**, with your own auth and storage. The library gives you the engine; you bring the chassis.
93
+ ## Subpaths
71
94
 
72
- ## Word JS API parity
95
+ | Subpath | Use when |
96
+ | -------------------------------------------- | -------------------------------------------------------------- |
97
+ | `@eigenpal/docx-editor-agents` | Server-side review, library glue |
98
+ | `@eigenpal/docx-editor-agents/bridge` | Wiring AI tools into a running editor adapter |
99
+ | `@eigenpal/docx-editor-agents/server` | Backend routes needing agent tooling without the MCP transport |
100
+ | `@eigenpal/docx-editor-agents/mcp` | Building an MCP server (any transport) |
101
+ | `@eigenpal/docx-editor-agents/ai-sdk/server` | Server-side streaming chat with the Vercel `ai` package |
102
+ | `@eigenpal/docx-editor-agents/react` | React apps wiring `<DocxEditor>` to an agent |
103
+ | `@eigenpal/docx-editor-agents/ai-sdk/react` | React chat UI over the bridge |
104
+ | `@eigenpal/docx-editor-agents/vue` | Vue apps wiring `<DocxEditor>` to an agent |
105
+ | `@eigenpal/docx-editor-agents/ai-sdk/vue` | Vue chat UI over the bridge |
73
106
 
74
- The bridge mirrors the Office.js Word API pattern locate a stable handle (`paraId`) first, then mutate. The parity contract is enforced at compile time:
107
+ Each subpath tree-shakes independently. Vue and AI SDK peers are optional via `peerDependenciesMeta`.
108
+
109
+ ## Word API parity
110
+
111
+ The bridge mirrors the Office.js Word API pattern: locate a stable handle (`paraId`) first, then mutate. The contract is type-enforced at compile time:
75
112
 
76
113
  ```ts
77
114
  import type { WordCompatBridge } from '@eigenpal/docx-editor-agents';
78
115
  ```
79
116
 
80
- `WordCompatBridge` is a TypeScript interface that `EditorBridge` is statically required to satisfy. If we ever drop a method that maps to a Word API call, typecheck breaks.
81
-
82
- ## What's in the package
117
+ `EditorBridge` is statically required to satisfy `WordCompatBridge`. Drop a method that maps to a Word API call and typecheck breaks.
83
118
 
84
- | Subpath | What | Use when |
85
- | ------------------------------------- | ----------------------------------------------------------------- | --------------------------------------------------------- |
86
- | `@eigenpal/docx-editor-agents` | `DocxReviewer`, `createReviewerBridge`, agent tool catalog, types | Server-side review, building your own MCP server |
87
- | `@eigenpal/docx-editor-agents/bridge` | `useAgentChat`, `createEditorBridge`, `EditorBridge` interface | Wiring AI tools into a live `<DocxEditor>` in the browser |
88
- | `@eigenpal/docx-editor-agents/mcp` | `McpServer`, JSON-RPC types, stdio adapter | Building an MCP server (any transport) |
119
+ ## Contributing
89
120
 
90
- Zero new runtime dependencies. Tree-shakes cleanly per subpath.
121
+ Contributions welcome. See [CONTRIBUTING.md](https://github.com/eigenpal/docx-editor/blob/main/CONTRIBUTING.md) for setup, tests, and the one-time CLA signature.
91
122
 
92
- ## License
123
+ ## Commercial Support
93
124
 
94
- [AGPL-3.0](./LICENSE) — free to use and modify, but you must open-source your code. For commercial licensing without AGPL obligations, contact [founders@eigenpal.com](mailto:founders@eigenpal.com).
125
+ > [!TIP]
126
+ > Questions or custom features? Email **[docx-editor@eigenpal.com](mailto:docx-editor@eigenpal.com)**.
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Shared agent UI types — framework-agnostic. Both React and Vue
3
+ * adapters (and the AI SDK adapters) consume this single declaration.
4
+ *
5
+ * Keeping the types here lets us tweak the chat schema without writing
6
+ * the same drift fix in four files.
7
+ */
8
+ interface AgentToolCall {
9
+ /** Stable id for keying. */
10
+ id: string;
11
+ /** Tool name (e.g. `read_document`, `add_comment`). */
12
+ name: string;
13
+ /** JSON-able input the agent passed. Rendered in the expanded view. */
14
+ input?: unknown;
15
+ /** Result text or summary. Set after the call completes. */
16
+ result?: string;
17
+ /** Set when the call errored — surfaces in the timeline as failed. */
18
+ error?: string;
19
+ /** `running` while in flight, `done` on success, `error` on failure. */
20
+ status: 'running' | 'done' | 'error';
21
+ }
22
+ interface AgentMessage {
23
+ id: string;
24
+ role: 'user' | 'assistant';
25
+ text: string;
26
+ /**
27
+ * Tool calls the assistant made for this turn, in order. The timeline
28
+ * stays expanded while `status === 'streaming'` and auto-collapses to
29
+ * an "N steps" summary when the message hits `status === 'done'`.
30
+ */
31
+ toolCalls?: AgentToolCall[];
32
+ /** `streaming` while the model is still calling tools / writing text; `done` once the turn is final. */
33
+ status?: 'streaming' | 'done';
34
+ }
35
+
36
+ export type { AgentMessage as A, AgentToolCall as a };
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Shared agent UI types — framework-agnostic. Both React and Vue
3
+ * adapters (and the AI SDK adapters) consume this single declaration.
4
+ *
5
+ * Keeping the types here lets us tweak the chat schema without writing
6
+ * the same drift fix in four files.
7
+ */
8
+ interface AgentToolCall {
9
+ /** Stable id for keying. */
10
+ id: string;
11
+ /** Tool name (e.g. `read_document`, `add_comment`). */
12
+ name: string;
13
+ /** JSON-able input the agent passed. Rendered in the expanded view. */
14
+ input?: unknown;
15
+ /** Result text or summary. Set after the call completes. */
16
+ result?: string;
17
+ /** Set when the call errored — surfaces in the timeline as failed. */
18
+ error?: string;
19
+ /** `running` while in flight, `done` on success, `error` on failure. */
20
+ status: 'running' | 'done' | 'error';
21
+ }
22
+ interface AgentMessage {
23
+ id: string;
24
+ role: 'user' | 'assistant';
25
+ text: string;
26
+ /**
27
+ * Tool calls the assistant made for this turn, in order. The timeline
28
+ * stays expanded while `status === 'streaming'` and auto-collapses to
29
+ * an "N steps" summary when the message hits `status === 'done'`.
30
+ */
31
+ toolCalls?: AgentToolCall[];
32
+ /** `streaming` while the model is still calling tools / writing text; `done` once the turn is final. */
33
+ status?: 'streaming' | 'done';
34
+ }
35
+
36
+ export type { AgentMessage as A, AgentToolCall as a };
@@ -1,36 +1,36 @@
1
1
  /**
2
- * Vercel AI SDK adapter (React side) — opt-in.
2
+ * @eigenpal/docx-editor-agents/ai-sdk/react
3
3
  *
4
- * Use this only if you're driving the chat with `useChat` from
5
- * `@ai-sdk/react`. The library's `<AgentChatLog>` consumes a flat
6
- * `AgentMessage[]` shape; AI SDK's `useChat` produces `UIMessage[]`
7
- * with structured `parts`. `toAgentMessages()` is the bridge.
8
- */
9
- /**
10
- * Local mirror of `AgentMessage` / `AgentToolCall` from
11
- * `@eigenpal/docx-js-editor`. Inlined here so this subpath has zero
12
- * runtime/type coupling to the editor package — the shapes are
13
- * structurally identical, so values flow either way without casting.
4
+ * Vercel AI SDK adapter (React side). Opt-in.
5
+ *
6
+ * Use this if you're driving the chat with `useChat` from `@ai-sdk/react`.
7
+ * The library's `<AgentChatLog>` consumes a flat `AgentMessage[]` shape;
8
+ * AI SDK's `useChat` produces `UIMessage[]` with structured `parts`.
9
+ * `toAgentMessages()` is the bridge.
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * const chat = useChat({ ... });
14
+ * const messages = useMemo(
15
+ * () => toAgentMessages(chat.messages, chat.status),
16
+ * [chat.messages, chat.status]
17
+ * );
18
+ * return <AgentChatLog messages={messages} />;
19
+ * ```
20
+ *
21
+ * @packageDocumentation
22
+ * @public
14
23
  */
15
- interface AgentToolCall {
16
- id: string;
17
- name: string;
18
- input?: unknown;
19
- result?: string;
20
- error?: string;
21
- status: 'running' | 'done' | 'error';
22
- }
23
- interface AgentMessage {
24
- id: string;
25
- role: 'user' | 'assistant';
26
- text: string;
27
- toolCalls?: AgentToolCall[];
28
- status?: 'streaming' | 'done';
29
- }
24
+ import { A as AgentMessage } from '../agent-types-C8RvQB7n.mjs';
25
+ export { a as AgentToolCall } from '../agent-types-C8RvQB7n.mjs';
26
+
30
27
  /**
31
- * Minimal structural shape of a Vercel AI SDK `UIMessage` keeps the
32
- * `ai` package as a peer dep, not a runtime dep.
28
+ * Framework-agnostic Vercel AI SDK adapter logic. The React and Vue
29
+ * subpaths re-export from here so consumers don't have to import a
30
+ * cross-framework path.
33
31
  */
32
+
33
+ /** Minimal structural shape of a Vercel AI SDK `UIMessage`. */
34
34
  interface AiSdkUIMessage {
35
35
  id: string;
36
36
  role: 'user' | 'assistant' | 'system';
@@ -51,17 +51,7 @@ interface AiSdkUIMessage {
51
51
  * @param uiMessages - the `messages` array from `useChat`
52
52
  * @param status - the `status` from `useChat`. The last assistant
53
53
  * message is marked `streaming` while the chat is still in flight.
54
- *
55
- * @example
56
- * ```tsx
57
- * const chat = useChat({ ... });
58
- * const messages = useMemo(
59
- * () => toAgentMessages(chat.messages, chat.status),
60
- * [chat.messages, chat.status]
61
- * );
62
- * return <AgentChatLog messages={messages} />;
63
- * ```
64
54
  */
65
55
  declare function toAgentMessages(uiMessages: ReadonlyArray<AiSdkUIMessage>, status: string): AgentMessage[];
66
56
 
67
- export { type AgentMessage, type AgentToolCall, toAgentMessages };
57
+ export { AgentMessage, type AiSdkUIMessage, toAgentMessages };
@@ -1,36 +1,36 @@
1
1
  /**
2
- * Vercel AI SDK adapter (React side) — opt-in.
2
+ * @eigenpal/docx-editor-agents/ai-sdk/react
3
3
  *
4
- * Use this only if you're driving the chat with `useChat` from
5
- * `@ai-sdk/react`. The library's `<AgentChatLog>` consumes a flat
6
- * `AgentMessage[]` shape; AI SDK's `useChat` produces `UIMessage[]`
7
- * with structured `parts`. `toAgentMessages()` is the bridge.
8
- */
9
- /**
10
- * Local mirror of `AgentMessage` / `AgentToolCall` from
11
- * `@eigenpal/docx-js-editor`. Inlined here so this subpath has zero
12
- * runtime/type coupling to the editor package — the shapes are
13
- * structurally identical, so values flow either way without casting.
4
+ * Vercel AI SDK adapter (React side). Opt-in.
5
+ *
6
+ * Use this if you're driving the chat with `useChat` from `@ai-sdk/react`.
7
+ * The library's `<AgentChatLog>` consumes a flat `AgentMessage[]` shape;
8
+ * AI SDK's `useChat` produces `UIMessage[]` with structured `parts`.
9
+ * `toAgentMessages()` is the bridge.
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * const chat = useChat({ ... });
14
+ * const messages = useMemo(
15
+ * () => toAgentMessages(chat.messages, chat.status),
16
+ * [chat.messages, chat.status]
17
+ * );
18
+ * return <AgentChatLog messages={messages} />;
19
+ * ```
20
+ *
21
+ * @packageDocumentation
22
+ * @public
14
23
  */
15
- interface AgentToolCall {
16
- id: string;
17
- name: string;
18
- input?: unknown;
19
- result?: string;
20
- error?: string;
21
- status: 'running' | 'done' | 'error';
22
- }
23
- interface AgentMessage {
24
- id: string;
25
- role: 'user' | 'assistant';
26
- text: string;
27
- toolCalls?: AgentToolCall[];
28
- status?: 'streaming' | 'done';
29
- }
24
+ import { A as AgentMessage } from '../agent-types-C8RvQB7n.js';
25
+ export { a as AgentToolCall } from '../agent-types-C8RvQB7n.js';
26
+
30
27
  /**
31
- * Minimal structural shape of a Vercel AI SDK `UIMessage` keeps the
32
- * `ai` package as a peer dep, not a runtime dep.
28
+ * Framework-agnostic Vercel AI SDK adapter logic. The React and Vue
29
+ * subpaths re-export from here so consumers don't have to import a
30
+ * cross-framework path.
33
31
  */
32
+
33
+ /** Minimal structural shape of a Vercel AI SDK `UIMessage`. */
34
34
  interface AiSdkUIMessage {
35
35
  id: string;
36
36
  role: 'user' | 'assistant' | 'system';
@@ -51,17 +51,7 @@ interface AiSdkUIMessage {
51
51
  * @param uiMessages - the `messages` array from `useChat`
52
52
  * @param status - the `status` from `useChat`. The last assistant
53
53
  * message is marked `streaming` while the chat is still in flight.
54
- *
55
- * @example
56
- * ```tsx
57
- * const chat = useChat({ ... });
58
- * const messages = useMemo(
59
- * () => toAgentMessages(chat.messages, chat.status),
60
- * [chat.messages, chat.status]
61
- * );
62
- * return <AgentChatLog messages={messages} />;
63
- * ```
64
54
  */
65
55
  declare function toAgentMessages(uiMessages: ReadonlyArray<AiSdkUIMessage>, status: string): AgentMessage[];
66
56
 
67
- export { type AgentMessage, type AgentToolCall, toAgentMessages };
57
+ export { AgentMessage, type AiSdkUIMessage, toAgentMessages };
@@ -1 +1 @@
1
- 'use strict';function g(s,r){return s.map((e,a)=>{let o="",n=[];for(let t of e.parts??[])if(t.type==="text")o+=t.text??"";else if(t.type.startsWith("tool-")){let u=t.state==="output-available"?"done":t.state==="output-error"?"error":"running";n.push({id:t.toolCallId??`${e.id}-tc-${n.length}`,name:t.type.slice(5),input:t.input,result:typeof t.output=="string"?t.output:void 0,error:t.errorText,status:u});}let i=a===s.length-1,l=e.role==="assistant"&&i&&(r==="streaming"||r==="submitted");return {id:e.id,role:e.role==="user"?"user":"assistant",text:o,toolCalls:n.length>0?n:void 0,status:l?"streaming":"done"}})}exports.toAgentMessages=g;
1
+ 'use strict';function u(n,o){return n.map((e,a)=>{let r="",s=[];for(let t of e.parts??[])if(t.type==="text")r+=t.text??"";else if(t.type.startsWith("tool-")){let g=t.state==="output-available"?"done":t.state==="output-error"?"error":"running";s.push({id:t.toolCallId??`${e.id}-tc-${s.length}`,name:t.type.slice(5),input:t.input,result:typeof t.output=="string"?t.output:void 0,error:t.errorText,status:g});}let l=a===n.length-1,i=e.role==="assistant"&&l&&(o==="streaming"||o==="submitted");return {id:e.id,role:e.role==="user"?"user":"assistant",text:r,toolCalls:s.length>0?s:void 0,status:i?"streaming":"done"}})}exports.toAgentMessages=u;
@@ -1 +1 @@
1
- function g(s,r){return s.map((e,a)=>{let o="",n=[];for(let t of e.parts??[])if(t.type==="text")o+=t.text??"";else if(t.type.startsWith("tool-")){let u=t.state==="output-available"?"done":t.state==="output-error"?"error":"running";n.push({id:t.toolCallId??`${e.id}-tc-${n.length}`,name:t.type.slice(5),input:t.input,result:typeof t.output=="string"?t.output:void 0,error:t.errorText,status:u});}let i=a===s.length-1,l=e.role==="assistant"&&i&&(r==="streaming"||r==="submitted");return {id:e.id,role:e.role==="user"?"user":"assistant",text:o,toolCalls:n.length>0?n:void 0,status:l?"streaming":"done"}})}export{g as toAgentMessages};
1
+ function u(n,o){return n.map((e,a)=>{let r="",s=[];for(let t of e.parts??[])if(t.type==="text")r+=t.text??"";else if(t.type.startsWith("tool-")){let g=t.state==="output-available"?"done":t.state==="output-error"?"error":"running";s.push({id:t.toolCallId??`${e.id}-tc-${s.length}`,name:t.type.slice(5),input:t.input,result:typeof t.output=="string"?t.output:void 0,error:t.errorText,status:g});}let l=a===n.length-1,i=e.role==="assistant"&&l&&(o==="streaming"||o==="submitted");return {id:e.id,role:e.role==="user"?"user":"assistant",text:r,toolCalls:s.length>0?s:void 0,status:i?"streaming":"done"}})}export{u as toAgentMessages};
@@ -1,13 +1,48 @@
1
+ /**
2
+ * @eigenpal/docx-editor-agents/ai-sdk/server
3
+ *
4
+ * Vercel AI SDK adapter (server side). Opt-in.
5
+ *
6
+ * The core toolkit is runtime-agnostic. Use this entry only if you're
7
+ * wiring `streamText` / `generateText` from `ai` in your route handler.
8
+ * For LangChain, the Anthropic SDK, or OpenAI direct, import
9
+ * `getToolSchemas` from `@eigenpal/docx-editor-agents/server` and shape it
10
+ * however your runtime expects.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * import { getAiSdkTools } from '@eigenpal/docx-editor-agents/ai-sdk/server';
15
+ * import { streamText, stepCountIs, convertToModelMessages } from 'ai';
16
+ *
17
+ * const tools = getAiSdkTools();
18
+ *
19
+ * export async function POST(req: Request) {
20
+ * const { messages } = await req.json();
21
+ * const result = streamText({
22
+ * model: 'openai/gpt-4o',
23
+ * messages: await convertToModelMessages(messages),
24
+ * tools,
25
+ * stopWhen: stepCountIs(12),
26
+ * });
27
+ * return result.toUIMessageStreamResponse();
28
+ * }
29
+ * ```
30
+ *
31
+ * @packageDocumentation
32
+ * @public
33
+ */
1
34
  import { Tool } from 'ai';
2
35
 
3
36
  /**
4
- * Vercel AI SDK adapter (server side) — opt-in.
37
+ * @eigenpal/docx-editor-agents/ai-sdk/server
38
+ *
39
+ * Vercel AI SDK adapter (server side). Opt-in.
5
40
  *
6
41
  * The core toolkit is runtime-agnostic. Use this entry only if you're
7
42
  * wiring `streamText` / `generateText` from `ai` in your route handler.
8
- * For LangChain / Anthropic SDK / OpenAI direct, import
9
- * `getToolSchemas` from `@eigenpal/docx-editor-agents/server` and
10
- * shape it however your runtime expects.
43
+ * For LangChain, the Anthropic SDK, or OpenAI direct, import
44
+ * `getToolSchemas` from `@eigenpal/docx-editor-agents/server` and shape it
45
+ * however your runtime expects.
11
46
  *
12
47
  * @example
13
48
  * ```ts
@@ -27,6 +62,9 @@ import { Tool } from 'ai';
27
62
  * return result.toUIMessageStreamResponse();
28
63
  * }
29
64
  * ```
65
+ *
66
+ * @packageDocumentation
67
+ * @public
30
68
  */
31
69
 
32
70
  /**
@@ -1,13 +1,48 @@
1
+ /**
2
+ * @eigenpal/docx-editor-agents/ai-sdk/server
3
+ *
4
+ * Vercel AI SDK adapter (server side). Opt-in.
5
+ *
6
+ * The core toolkit is runtime-agnostic. Use this entry only if you're
7
+ * wiring `streamText` / `generateText` from `ai` in your route handler.
8
+ * For LangChain, the Anthropic SDK, or OpenAI direct, import
9
+ * `getToolSchemas` from `@eigenpal/docx-editor-agents/server` and shape it
10
+ * however your runtime expects.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * import { getAiSdkTools } from '@eigenpal/docx-editor-agents/ai-sdk/server';
15
+ * import { streamText, stepCountIs, convertToModelMessages } from 'ai';
16
+ *
17
+ * const tools = getAiSdkTools();
18
+ *
19
+ * export async function POST(req: Request) {
20
+ * const { messages } = await req.json();
21
+ * const result = streamText({
22
+ * model: 'openai/gpt-4o',
23
+ * messages: await convertToModelMessages(messages),
24
+ * tools,
25
+ * stopWhen: stepCountIs(12),
26
+ * });
27
+ * return result.toUIMessageStreamResponse();
28
+ * }
29
+ * ```
30
+ *
31
+ * @packageDocumentation
32
+ * @public
33
+ */
1
34
  import { Tool } from 'ai';
2
35
 
3
36
  /**
4
- * Vercel AI SDK adapter (server side) — opt-in.
37
+ * @eigenpal/docx-editor-agents/ai-sdk/server
38
+ *
39
+ * Vercel AI SDK adapter (server side). Opt-in.
5
40
  *
6
41
  * The core toolkit is runtime-agnostic. Use this entry only if you're
7
42
  * wiring `streamText` / `generateText` from `ai` in your route handler.
8
- * For LangChain / Anthropic SDK / OpenAI direct, import
9
- * `getToolSchemas` from `@eigenpal/docx-editor-agents/server` and
10
- * shape it however your runtime expects.
43
+ * For LangChain, the Anthropic SDK, or OpenAI direct, import
44
+ * `getToolSchemas` from `@eigenpal/docx-editor-agents/server` and shape it
45
+ * however your runtime expects.
11
46
  *
12
47
  * @example
13
48
  * ```ts
@@ -27,6 +62,9 @@ import { Tool } from 'ai';
27
62
  * return result.toUIMessageStreamResponse();
28
63
  * }
29
64
  * ```
65
+ *
66
+ * @packageDocumentation
67
+ * @public
30
68
  */
31
69
 
32
70
  /**
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @eigenpal/docx-editor-agents/ai-sdk/vue
3
+ *
4
+ * Vercel AI SDK adapter (Vue side). Opt-in.
5
+ *
6
+ * Use this if you're driving the chat with `useChat` from `@ai-sdk/vue`.
7
+ * The Vue `<AgentChatLog>` consumes a flat `AgentMessage[]` shape;
8
+ * AI SDK's `useChat` produces `UIMessage[]` with structured `parts`.
9
+ * `toAgentMessages()` is the bridge.
10
+ *
11
+ * @example
12
+ * ```vue
13
+ * <script setup lang="ts">
14
+ * import { computed } from 'vue';
15
+ * import { useChat } from '@ai-sdk/vue';
16
+ * import { toAgentMessages } from '@eigenpal/docx-editor-agents/ai-sdk/vue';
17
+ * import { AgentChatLog } from '@eigenpal/docx-editor-agents/vue';
18
+ *
19
+ * const chat = useChat({ ... });
20
+ * const messages = computed(() => toAgentMessages(chat.messages.value, chat.status.value));
21
+ * </script>
22
+ *
23
+ * <template>
24
+ * <AgentChatLog :messages="messages" />
25
+ * </template>
26
+ * ```
27
+ *
28
+ * @packageDocumentation
29
+ * @public
30
+ */
31
+ export type { AgentMessage, AgentToolCall } from '../agent-types';
32
+ export { toAgentMessages, type AiSdkUIMessage } from './shared';
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function p(s,r){return s.map((e,l)=>{let n="";const o=[];for(const t of e.parts??[])if(t.type==="text")n+=t.text??"";else if(t.type.startsWith("tool-")){const u=t.state==="output-available"?"done":t.state==="output-error"?"error":"running";o.push({id:t.toolCallId??`${e.id}-tc-${o.length}`,name:t.type.slice(5),input:t.input,result:typeof t.output=="string"?t.output:void 0,error:t.errorText,status:u})}const a=l===s.length-1,i=e.role==="assistant"&&a&&(r==="streaming"||r==="submitted");return{id:e.id,role:e.role==="user"?"user":"assistant",text:n,toolCalls:o.length>0?o:void 0,status:i?"streaming":"done"}})}exports.toAgentMessages=p;
@@ -0,0 +1,31 @@
1
+ function p(s, r) {
2
+ return s.map((e, l) => {
3
+ let n = "";
4
+ const o = [];
5
+ for (const t of e.parts ?? [])
6
+ if (t.type === "text")
7
+ n += t.text ?? "";
8
+ else if (t.type.startsWith("tool-")) {
9
+ const u = t.state === "output-available" ? "done" : t.state === "output-error" ? "error" : "running";
10
+ o.push({
11
+ id: t.toolCallId ?? `${e.id}-tc-${o.length}`,
12
+ name: t.type.slice(5),
13
+ input: t.input,
14
+ result: typeof t.output == "string" ? t.output : void 0,
15
+ error: t.errorText,
16
+ status: u
17
+ });
18
+ }
19
+ const a = l === s.length - 1, i = e.role === "assistant" && a && (r === "streaming" || r === "submitted");
20
+ return {
21
+ id: e.id,
22
+ role: e.role === "user" ? "user" : "assistant",
23
+ text: n,
24
+ toolCalls: o.length > 0 ? o : void 0,
25
+ status: i ? "streaming" : "done"
26
+ };
27
+ });
28
+ }
29
+ export {
30
+ p as toAgentMessages
31
+ };
package/dist/bridge.d.mts CHANGED
@@ -1 +1,18 @@
1
- export { A as AgentToolDefinition, a as AgentToolResult, n as ContentChangeEvent, v as EditorBridge, E as EditorRefLike, o as SelectionChangeEvent, U as UseAgentChatOptions, c as UseAgentChatReturn, r as agentTools, w as createEditorBridge, s as createReviewerBridge, t as executeToolCall, g as getToolSchemas, u as useAgentChat } from './server-DH5eszkm.mjs';
1
+ /**
2
+ * @eigenpal/docx-editor-agents/bridge
3
+ *
4
+ * Editor bridge that connects agent tools to a live `DocxEditor` instance.
5
+ * Framework-agnostic. The React adapter lives in
6
+ * `@eigenpal/docx-editor-agents/react`.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { createEditorBridge } from '@eigenpal/docx-editor-agents/bridge';
11
+ * const bridge = createEditorBridge(editorRef, 'Assistant');
12
+ * bridge.addComment({ paragraphIndex: 3, text: 'Fix this.' });
13
+ * ```
14
+ *
15
+ * @packageDocumentation
16
+ * @public
17
+ */
18
+ export { j as AgentToolDefinition, k as AgentToolResult, h as ContentChangeEvent, E as EditorBridge, r as EditorRefLike, i as SelectionChangeEvent, n as agentTools, u as createEditorBridge, o as createReviewerBridge, p as executeToolCall, q as getToolSchemas } from './server-B7RHNVSu.mjs';