@morphllm/subagents 0.1.3 → 0.1.5
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/README.md +15 -25
- package/dist/base-client-B7fgl_Wg.d.mts +30 -0
- package/dist/base-client-C6pbtqLX.d.ts +30 -0
- package/dist/core/index.d.mts +4 -30
- package/dist/core/index.d.ts +4 -30
- package/dist/docx/index.d.mts +193 -11
- package/dist/docx/index.d.ts +193 -11
- package/dist/docx/index.js +156 -402
- package/dist/docx/index.js.map +1 -1
- package/dist/docx/index.mjs +156 -402
- package/dist/docx/index.mjs.map +1 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +164 -263
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +164 -263
- package/dist/index.mjs.map +1 -1
- package/dist/pdf/index.d.mts +1 -1
- package/dist/pdf/index.d.ts +1 -1
- package/dist/pdf/index.js.map +1 -1
- package/dist/pdf/index.mjs.map +1 -1
- package/package.json +4 -3
- package/src/core/index.ts +1 -1
- package/src/docx/agent.ts +134 -274
- package/src/docx/client.ts +58 -1
- package/src/docx/index.ts +1 -1
- package/src/docx/types.ts +146 -2
- package/src/index.ts +3 -3
- package/src/pdf/index.ts +1 -1
package/src/docx/agent.ts
CHANGED
|
@@ -1,200 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* DocxAgent - AI agent for DOCX document editing
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* OpenAI Agents SDK compatible client for morph-docx.
|
|
5
|
+
* Talks to api.subagents.com/v1/chat/completions with model "morph-docx".
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
import type { Tool } from '../core/types';
|
|
10
|
-
import { DocxClient } from './client';
|
|
11
|
-
import type { DocxAgentOptions } from './types';
|
|
8
|
+
import type { DocxAgentOptions, Message, ChatCompletionResponse, StreamChunk } from './types';
|
|
12
9
|
|
|
13
|
-
const
|
|
10
|
+
const DEFAULT_BASE_URL = 'https://api.subagents.com/v1';
|
|
14
11
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
3. Add comments to flag issues or request clarification
|
|
19
|
-
4. Be precise with paragraph text matching - use unique text snippets
|
|
20
|
-
|
|
21
|
-
Available tools:
|
|
22
|
-
- read_document: Read the document content
|
|
23
|
-
- add_comment: Add a comment to a specific paragraph
|
|
24
|
-
- insert_text: Insert text within a paragraph (tracked change)
|
|
25
|
-
- propose_deletion: Mark text for deletion (tracked change)
|
|
26
|
-
- reply_comment: Reply to an existing comment
|
|
27
|
-
- resolve_comment: Mark a comment as resolved
|
|
28
|
-
- delete_comment: Delete a comment
|
|
29
|
-
- insert_paragraph: Insert a new paragraph
|
|
30
|
-
- validate_document: Validate DOCX structure`;
|
|
31
|
-
|
|
32
|
-
const TOOLS: Tool[] = [
|
|
33
|
-
{
|
|
34
|
-
type: 'function',
|
|
35
|
-
function: {
|
|
36
|
-
name: 'read_document',
|
|
37
|
-
description: 'Read the document content as plain text',
|
|
38
|
-
parameters: {
|
|
39
|
-
type: 'object',
|
|
40
|
-
properties: {
|
|
41
|
-
doc_id: { type: 'string', description: 'Document ID' },
|
|
42
|
-
},
|
|
43
|
-
required: ['doc_id'],
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
type: 'function',
|
|
49
|
-
function: {
|
|
50
|
-
name: 'add_comment',
|
|
51
|
-
description: 'Add a comment to a specific paragraph in the document',
|
|
52
|
-
parameters: {
|
|
53
|
-
type: 'object',
|
|
54
|
-
properties: {
|
|
55
|
-
doc_id: { type: 'string', description: 'Document ID' },
|
|
56
|
-
para_text: { type: 'string', description: 'Unique text from the target paragraph' },
|
|
57
|
-
comment: { type: 'string', description: 'Comment text to add' },
|
|
58
|
-
highlight: { type: 'string', description: 'Optional specific text to highlight' },
|
|
59
|
-
},
|
|
60
|
-
required: ['doc_id', 'para_text', 'comment'],
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
type: 'function',
|
|
66
|
-
function: {
|
|
67
|
-
name: 'insert_text',
|
|
68
|
-
description: 'Insert text within a paragraph (creates a tracked change)',
|
|
69
|
-
parameters: {
|
|
70
|
-
type: 'object',
|
|
71
|
-
properties: {
|
|
72
|
-
doc_id: { type: 'string', description: 'Document ID' },
|
|
73
|
-
para_text: { type: 'string', description: 'Unique text from the target paragraph' },
|
|
74
|
-
after: { type: 'string', description: 'Text after which to insert' },
|
|
75
|
-
new_text: { type: 'string', description: 'Text to insert' },
|
|
76
|
-
},
|
|
77
|
-
required: ['doc_id', 'para_text', 'after', 'new_text'],
|
|
78
|
-
},
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
type: 'function',
|
|
83
|
-
function: {
|
|
84
|
-
name: 'propose_deletion',
|
|
85
|
-
description: 'Mark text for deletion (creates a tracked change)',
|
|
86
|
-
parameters: {
|
|
87
|
-
type: 'object',
|
|
88
|
-
properties: {
|
|
89
|
-
doc_id: { type: 'string', description: 'Document ID' },
|
|
90
|
-
para_text: { type: 'string', description: 'Unique text from the target paragraph' },
|
|
91
|
-
target: { type: 'string', description: 'Specific text to delete (optional, defaults to whole paragraph)' },
|
|
92
|
-
},
|
|
93
|
-
required: ['doc_id', 'para_text'],
|
|
94
|
-
},
|
|
95
|
-
},
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
type: 'function',
|
|
99
|
-
function: {
|
|
100
|
-
name: 'reply_comment',
|
|
101
|
-
description: 'Reply to an existing comment',
|
|
102
|
-
parameters: {
|
|
103
|
-
type: 'object',
|
|
104
|
-
properties: {
|
|
105
|
-
doc_id: { type: 'string', description: 'Document ID' },
|
|
106
|
-
comment_id: { type: 'string', description: 'ID of the comment to reply to' },
|
|
107
|
-
reply: { type: 'string', description: 'Reply text' },
|
|
108
|
-
},
|
|
109
|
-
required: ['doc_id', 'comment_id', 'reply'],
|
|
110
|
-
},
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
type: 'function',
|
|
115
|
-
function: {
|
|
116
|
-
name: 'resolve_comment',
|
|
117
|
-
description: 'Mark a comment as resolved',
|
|
118
|
-
parameters: {
|
|
119
|
-
type: 'object',
|
|
120
|
-
properties: {
|
|
121
|
-
doc_id: { type: 'string', description: 'Document ID' },
|
|
122
|
-
comment_id: { type: 'string', description: 'ID of the comment to resolve' },
|
|
123
|
-
},
|
|
124
|
-
required: ['doc_id', 'comment_id'],
|
|
125
|
-
},
|
|
126
|
-
},
|
|
127
|
-
},
|
|
128
|
-
{
|
|
129
|
-
type: 'function',
|
|
130
|
-
function: {
|
|
131
|
-
name: 'delete_comment',
|
|
132
|
-
description: 'Delete a comment and its replies',
|
|
133
|
-
parameters: {
|
|
134
|
-
type: 'object',
|
|
135
|
-
properties: {
|
|
136
|
-
doc_id: { type: 'string', description: 'Document ID' },
|
|
137
|
-
comment_id: { type: 'string', description: 'ID of the comment to delete' },
|
|
138
|
-
},
|
|
139
|
-
required: ['doc_id', 'comment_id'],
|
|
140
|
-
},
|
|
141
|
-
},
|
|
142
|
-
},
|
|
143
|
-
{
|
|
144
|
-
type: 'function',
|
|
145
|
-
function: {
|
|
146
|
-
name: 'insert_paragraph',
|
|
147
|
-
description: 'Insert a new paragraph after existing text',
|
|
148
|
-
parameters: {
|
|
149
|
-
type: 'object',
|
|
150
|
-
properties: {
|
|
151
|
-
doc_id: { type: 'string', description: 'Document ID' },
|
|
152
|
-
after_text: { type: 'string', description: 'Text after which to insert the new paragraph' },
|
|
153
|
-
new_text: { type: 'string', description: 'Content of the new paragraph' },
|
|
154
|
-
},
|
|
155
|
-
required: ['doc_id', 'after_text', 'new_text'],
|
|
156
|
-
},
|
|
157
|
-
},
|
|
158
|
-
},
|
|
159
|
-
{
|
|
160
|
-
type: 'function',
|
|
161
|
-
function: {
|
|
162
|
-
name: 'validate_document',
|
|
163
|
-
description: 'Validate the document structure',
|
|
164
|
-
parameters: {
|
|
165
|
-
type: 'object',
|
|
166
|
-
properties: {
|
|
167
|
-
doc_id: { type: 'string', description: 'Document ID' },
|
|
168
|
-
},
|
|
169
|
-
required: ['doc_id'],
|
|
170
|
-
},
|
|
171
|
-
},
|
|
172
|
-
},
|
|
173
|
-
];
|
|
174
|
-
|
|
175
|
-
export class DocxAgent extends BaseAgent<DocxClient> {
|
|
12
|
+
export class DocxAgent {
|
|
13
|
+
private baseUrl: string;
|
|
14
|
+
private apiKey: string;
|
|
176
15
|
private documentId?: string;
|
|
177
16
|
|
|
178
17
|
constructor(options: DocxAgentOptions = {}) {
|
|
179
|
-
|
|
180
|
-
|
|
18
|
+
this.baseUrl = options.baseUrl || process.env.MORPH_API_URL || DEFAULT_BASE_URL;
|
|
19
|
+
this.apiKey = options.apiKey || process.env.MORPH_API_KEY || '';
|
|
181
20
|
this.documentId = options.documentId;
|
|
182
21
|
}
|
|
183
22
|
|
|
184
|
-
protected getDefaultModel(): string {
|
|
185
|
-
return 'moonshot-v1-32k';
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
protected getDefaultInstructions(): string {
|
|
189
|
-
return this.documentId
|
|
190
|
-
? `${DEFAULT_INSTRUCTIONS}\n\nCurrent document ID: ${this.documentId}`
|
|
191
|
-
: DEFAULT_INSTRUCTIONS;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
protected getTools(): Tool[] {
|
|
195
|
-
return TOOLS;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
23
|
/** Set the current document ID */
|
|
199
24
|
setDocument(docId: string) {
|
|
200
25
|
this.documentId = docId;
|
|
@@ -205,107 +30,142 @@ export class DocxAgent extends BaseAgent<DocxClient> {
|
|
|
205
30
|
return this.documentId;
|
|
206
31
|
}
|
|
207
32
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Send a chat completion request (non-streaming).
|
|
35
|
+
* This runs the full agent loop on the server and returns the final response.
|
|
36
|
+
*/
|
|
37
|
+
async chat(messages: Message[]): Promise<ChatCompletionResponse> {
|
|
38
|
+
// Add document context to user message if we have a document ID
|
|
39
|
+
const contextMessages = this.documentId
|
|
40
|
+
? messages.map((m, i) => {
|
|
41
|
+
if (i === messages.length - 1 && m.role === 'user') {
|
|
42
|
+
return {
|
|
43
|
+
...m,
|
|
44
|
+
content: `[Document ID: ${this.documentId}]\n\n${m.content}`,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
return m;
|
|
48
|
+
})
|
|
49
|
+
: messages;
|
|
50
|
+
|
|
51
|
+
const response = await fetch(`${this.baseUrl}/chat/completions`, {
|
|
52
|
+
method: 'POST',
|
|
53
|
+
headers: {
|
|
54
|
+
'Content-Type': 'application/json',
|
|
55
|
+
...(this.apiKey && { Authorization: `Bearer ${this.apiKey}` }),
|
|
56
|
+
},
|
|
57
|
+
body: JSON.stringify({
|
|
58
|
+
model: 'morph-docx',
|
|
59
|
+
messages: contextMessages,
|
|
60
|
+
stream: false,
|
|
61
|
+
}),
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
if (!response.ok) {
|
|
65
|
+
const error = await response.text();
|
|
66
|
+
throw new Error(`API error: ${error}`);
|
|
213
67
|
}
|
|
214
68
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
case 'read_document': {
|
|
218
|
-
const result = await this.client.read(docId);
|
|
219
|
-
return `Document content (${result.paragraphs} paragraphs):\n\n${result.content}`;
|
|
220
|
-
}
|
|
69
|
+
return response.json();
|
|
70
|
+
}
|
|
221
71
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
72
|
+
/**
|
|
73
|
+
* Send a streaming chat completion request.
|
|
74
|
+
* Returns an async generator that yields chunks as they arrive.
|
|
75
|
+
*/
|
|
76
|
+
async *chatStream(messages: Message[]): AsyncGenerator<StreamChunk> {
|
|
77
|
+
// Add document context to user message if we have a document ID
|
|
78
|
+
const contextMessages = this.documentId
|
|
79
|
+
? messages.map((m, i) => {
|
|
80
|
+
if (i === messages.length - 1 && m.role === 'user') {
|
|
81
|
+
return {
|
|
82
|
+
...m,
|
|
83
|
+
content: `[Document ID: ${this.documentId}]\n\n${m.content}`,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return m;
|
|
87
|
+
})
|
|
88
|
+
: messages;
|
|
89
|
+
|
|
90
|
+
const response = await fetch(`${this.baseUrl}/chat/completions`, {
|
|
91
|
+
method: 'POST',
|
|
92
|
+
headers: {
|
|
93
|
+
'Content-Type': 'application/json',
|
|
94
|
+
...(this.apiKey && { Authorization: `Bearer ${this.apiKey}` }),
|
|
95
|
+
},
|
|
96
|
+
body: JSON.stringify({
|
|
97
|
+
model: 'morph-docx',
|
|
98
|
+
messages: contextMessages,
|
|
99
|
+
stream: true,
|
|
100
|
+
}),
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
if (!response.ok) {
|
|
104
|
+
const error = await response.text();
|
|
105
|
+
throw new Error(`API error: ${error}`);
|
|
106
|
+
}
|
|
233
107
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
para_text: args.para_text as string,
|
|
239
|
-
after: args.after as string,
|
|
240
|
-
new_text: args.new_text as string,
|
|
241
|
-
},
|
|
242
|
-
]);
|
|
243
|
-
return result.results[0];
|
|
244
|
-
}
|
|
108
|
+
const reader = response.body?.getReader();
|
|
109
|
+
if (!reader) {
|
|
110
|
+
throw new Error('No response body');
|
|
111
|
+
}
|
|
245
112
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
{
|
|
249
|
-
type: 'propose_deletion',
|
|
250
|
-
para_text: args.para_text as string,
|
|
251
|
-
target: args.target as string | undefined,
|
|
252
|
-
},
|
|
253
|
-
]);
|
|
254
|
-
return result.results[0];
|
|
255
|
-
}
|
|
113
|
+
const decoder = new TextDecoder();
|
|
114
|
+
let buffer = '';
|
|
256
115
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
type: 'reply_comment',
|
|
261
|
-
comment_id: args.comment_id as string,
|
|
262
|
-
reply: args.reply as string,
|
|
263
|
-
},
|
|
264
|
-
]);
|
|
265
|
-
return result.results[0];
|
|
266
|
-
}
|
|
116
|
+
while (true) {
|
|
117
|
+
const { done, value } = await reader.read();
|
|
118
|
+
if (done) break;
|
|
267
119
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
type: 'resolve_comment',
|
|
272
|
-
comment_id: args.comment_id as string,
|
|
273
|
-
},
|
|
274
|
-
]);
|
|
275
|
-
return result.results[0];
|
|
276
|
-
}
|
|
120
|
+
buffer += decoder.decode(value, { stream: true });
|
|
121
|
+
const lines = buffer.split('\n');
|
|
122
|
+
buffer = lines.pop() || '';
|
|
277
123
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
comment_id: args.comment_id as string,
|
|
283
|
-
},
|
|
284
|
-
]);
|
|
285
|
-
return result.results[0];
|
|
286
|
-
}
|
|
124
|
+
for (const line of lines) {
|
|
125
|
+
if (!line.startsWith('data: ')) continue;
|
|
126
|
+
const data = line.slice(6).trim();
|
|
127
|
+
if (data === '[DONE]') return;
|
|
287
128
|
|
|
288
|
-
|
|
289
|
-
const
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
new_text: args.new_text as string,
|
|
294
|
-
},
|
|
295
|
-
]);
|
|
296
|
-
return result.results[0];
|
|
129
|
+
try {
|
|
130
|
+
const chunk = JSON.parse(data);
|
|
131
|
+
yield chunk;
|
|
132
|
+
} catch {
|
|
133
|
+
// Skip malformed JSON
|
|
297
134
|
}
|
|
298
|
-
|
|
299
|
-
case 'validate_document': {
|
|
300
|
-
const result = await this.client.validate(docId);
|
|
301
|
-
return `${result.result}: ${result.output}`;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
default:
|
|
305
|
-
return `Error: Unknown tool '${name}'`;
|
|
306
135
|
}
|
|
307
|
-
} catch (error) {
|
|
308
|
-
return `Error: ${error instanceof Error ? error.message : String(error)}`;
|
|
309
136
|
}
|
|
310
137
|
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Helper: Simple completion that returns just the content string.
|
|
141
|
+
*/
|
|
142
|
+
async complete(userMessage: string): Promise<string> {
|
|
143
|
+
const response = await this.chat([{ role: 'user', content: userMessage }]);
|
|
144
|
+
return response.choices[0]?.message?.content || '';
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Create an OpenAI-compatible client configuration.
|
|
149
|
+
* Use this with the OpenAI SDK or OpenAI Agents SDK.
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```typescript
|
|
153
|
+
* import OpenAI from 'openai';
|
|
154
|
+
* import { DocxAgent } from 'subagents/docx';
|
|
155
|
+
*
|
|
156
|
+
* const agent = new DocxAgent();
|
|
157
|
+
* const openai = new OpenAI(agent.getOpenAIConfig());
|
|
158
|
+
*
|
|
159
|
+
* const response = await openai.chat.completions.create({
|
|
160
|
+
* model: 'morph-docx',
|
|
161
|
+
* messages: [{ role: 'user', content: 'Hello!' }],
|
|
162
|
+
* });
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
getOpenAIConfig() {
|
|
166
|
+
return {
|
|
167
|
+
baseURL: this.baseUrl,
|
|
168
|
+
apiKey: this.apiKey || 'not-required',
|
|
169
|
+
};
|
|
170
|
+
}
|
|
311
171
|
}
|
package/src/docx/client.ts
CHANGED
|
@@ -10,9 +10,13 @@ import type {
|
|
|
10
10
|
EditOperation,
|
|
11
11
|
EditResponse,
|
|
12
12
|
ValidateResponse,
|
|
13
|
+
BuildOperation,
|
|
14
|
+
BuildResponse,
|
|
15
|
+
CreateResponse,
|
|
16
|
+
DocumentInfoResponse,
|
|
13
17
|
} from './types';
|
|
14
18
|
|
|
15
|
-
const DEFAULT_API_URL = 'https://
|
|
19
|
+
const DEFAULT_API_URL = 'https://api.subagents.com/v1/morph-docx';
|
|
16
20
|
|
|
17
21
|
export class DocxClient extends BaseClient {
|
|
18
22
|
constructor(options: DocxClientOptions = {}) {
|
|
@@ -66,4 +70,57 @@ export class DocxClient extends BaseClient {
|
|
|
66
70
|
async deleteDocument(docId: string): Promise<void> {
|
|
67
71
|
return this.delete(`/documents/${docId}`);
|
|
68
72
|
}
|
|
73
|
+
|
|
74
|
+
// --- Creation Operations ---
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Create a new empty DOCX document.
|
|
78
|
+
*/
|
|
79
|
+
async create(title?: string): Promise<CreateResponse> {
|
|
80
|
+
return this.post('/documents/create', { title });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Execute build operations on a document (add content).
|
|
85
|
+
*/
|
|
86
|
+
async build(docId: string, operations: BuildOperation[]): Promise<BuildResponse> {
|
|
87
|
+
return this.post(`/documents/${docId}/build`, { operations });
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Get document information.
|
|
92
|
+
*/
|
|
93
|
+
async getInfo(docId: string): Promise<DocumentInfoResponse> {
|
|
94
|
+
return this.get(`/documents/${docId}/info`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// --- Convenience Methods ---
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Add a heading to the document.
|
|
101
|
+
*/
|
|
102
|
+
async addHeading(docId: string, text: string, level = 1): Promise<BuildResponse> {
|
|
103
|
+
return this.build(docId, [{ type: 'add_heading', text, level }]);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Add a paragraph to the document.
|
|
108
|
+
*/
|
|
109
|
+
async addParagraph(docId: string, text: string, options?: Partial<BuildOperation>): Promise<BuildResponse> {
|
|
110
|
+
return this.build(docId, [{ type: 'add_paragraph', text, ...options }]);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Add a table to the document.
|
|
115
|
+
*/
|
|
116
|
+
async addTable(docId: string, headers: string[], rows: string[][]): Promise<BuildResponse> {
|
|
117
|
+
return this.build(docId, [{ type: 'add_table', headers, rows }]);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Add page numbers to the document.
|
|
122
|
+
*/
|
|
123
|
+
async addPageNumbers(docId: string, format = 'Page {PAGE} of {NUMPAGES}'): Promise<BuildResponse> {
|
|
124
|
+
return this.build(docId, [{ type: 'add_page_numbers', format_string: format }]);
|
|
125
|
+
}
|
|
69
126
|
}
|
package/src/docx/index.ts
CHANGED
package/src/docx/types.ts
CHANGED
|
@@ -24,7 +24,81 @@ export type EditOperationType =
|
|
|
24
24
|
| 'delete_comment'
|
|
25
25
|
| 'insert_text'
|
|
26
26
|
| 'insert_paragraph'
|
|
27
|
-
| 'propose_deletion'
|
|
27
|
+
| 'propose_deletion'
|
|
28
|
+
| 'reject_insertion'
|
|
29
|
+
| 'restore_deletion'
|
|
30
|
+
| 'enable_track_changes';
|
|
31
|
+
|
|
32
|
+
/** Build operation types (for document creation) */
|
|
33
|
+
export type BuildOperationType =
|
|
34
|
+
| 'add_heading'
|
|
35
|
+
| 'add_paragraph'
|
|
36
|
+
| 'add_table'
|
|
37
|
+
| 'add_image'
|
|
38
|
+
| 'add_list_item'
|
|
39
|
+
| 'add_hyperlink'
|
|
40
|
+
| 'add_page_break'
|
|
41
|
+
| 'add_section_break'
|
|
42
|
+
| 'add_header'
|
|
43
|
+
| 'add_footer'
|
|
44
|
+
| 'add_page_numbers'
|
|
45
|
+
| 'setup_styles';
|
|
46
|
+
|
|
47
|
+
/** Build operation payload */
|
|
48
|
+
export interface BuildOperation {
|
|
49
|
+
type: BuildOperationType;
|
|
50
|
+
text?: string;
|
|
51
|
+
level?: number;
|
|
52
|
+
style?: string;
|
|
53
|
+
alignment?: 'left' | 'center' | 'right' | 'justify';
|
|
54
|
+
bold?: boolean;
|
|
55
|
+
italic?: boolean;
|
|
56
|
+
font_size?: number;
|
|
57
|
+
font_name?: string;
|
|
58
|
+
color?: string;
|
|
59
|
+
space_before?: number;
|
|
60
|
+
space_after?: number;
|
|
61
|
+
headers?: string[];
|
|
62
|
+
rows?: string[][];
|
|
63
|
+
header_bg_color?: string;
|
|
64
|
+
image_url?: string;
|
|
65
|
+
image_data?: string;
|
|
66
|
+
width?: number;
|
|
67
|
+
height?: number;
|
|
68
|
+
list_type?: 'bullet' | 'number';
|
|
69
|
+
url?: string;
|
|
70
|
+
position?: 'header' | 'footer';
|
|
71
|
+
format_string?: string;
|
|
72
|
+
section_index?: number;
|
|
73
|
+
base_font?: string;
|
|
74
|
+
base_size?: number;
|
|
75
|
+
heading_font?: string;
|
|
76
|
+
primary_color?: string;
|
|
77
|
+
break_type?: 'next_page' | 'continuous' | 'even_page' | 'odd_page';
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Response from create operations */
|
|
81
|
+
export interface CreateResponse {
|
|
82
|
+
doc_id: string;
|
|
83
|
+
message: string;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Response from build operations */
|
|
87
|
+
export interface BuildResponse {
|
|
88
|
+
results: string[];
|
|
89
|
+
doc_id: string;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Document info response */
|
|
93
|
+
export interface DocumentInfoResponse {
|
|
94
|
+
paragraphs: number;
|
|
95
|
+
tables: number;
|
|
96
|
+
sections: number;
|
|
97
|
+
title: string;
|
|
98
|
+
author: string;
|
|
99
|
+
created: string;
|
|
100
|
+
modified: string;
|
|
101
|
+
}
|
|
28
102
|
|
|
29
103
|
/** Edit operation payload */
|
|
30
104
|
export interface EditOperation {
|
|
@@ -62,7 +136,77 @@ export interface DocxClientOptions extends BaseClientOptions {
|
|
|
62
136
|
}
|
|
63
137
|
|
|
64
138
|
/** DOCX agent options */
|
|
65
|
-
export interface DocxAgentOptions
|
|
139
|
+
export interface DocxAgentOptions {
|
|
140
|
+
/** Base URL for the API. Defaults to api.subagents.com/v1 */
|
|
141
|
+
baseUrl?: string;
|
|
142
|
+
/** API key (optional, not required for public endpoints) */
|
|
143
|
+
apiKey?: string;
|
|
66
144
|
/** Current document ID */
|
|
67
145
|
documentId?: string;
|
|
68
146
|
}
|
|
147
|
+
|
|
148
|
+
/** Chat message */
|
|
149
|
+
export interface Message {
|
|
150
|
+
role: 'system' | 'user' | 'assistant' | 'tool';
|
|
151
|
+
content: string;
|
|
152
|
+
tool_call_id?: string;
|
|
153
|
+
tool_calls?: ToolCall[];
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** Tool call in a message */
|
|
157
|
+
export interface ToolCall {
|
|
158
|
+
id: string;
|
|
159
|
+
type: 'function';
|
|
160
|
+
function: {
|
|
161
|
+
name: string;
|
|
162
|
+
arguments: string;
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** Chat completion response (non-streaming) */
|
|
167
|
+
export interface ChatCompletionResponse {
|
|
168
|
+
id: string;
|
|
169
|
+
object: 'chat.completion';
|
|
170
|
+
created: number;
|
|
171
|
+
model: string;
|
|
172
|
+
choices: {
|
|
173
|
+
index: number;
|
|
174
|
+
message: {
|
|
175
|
+
role: 'assistant';
|
|
176
|
+
content: string | null;
|
|
177
|
+
tool_calls?: ToolCall[];
|
|
178
|
+
};
|
|
179
|
+
finish_reason: string;
|
|
180
|
+
}[];
|
|
181
|
+
usage?: {
|
|
182
|
+
prompt_tokens: number;
|
|
183
|
+
completion_tokens: number;
|
|
184
|
+
total_tokens: number;
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** Stream chunk */
|
|
189
|
+
export interface StreamChunk {
|
|
190
|
+
id?: string;
|
|
191
|
+
object?: string;
|
|
192
|
+
created?: number;
|
|
193
|
+
model?: string;
|
|
194
|
+
choices?: {
|
|
195
|
+
index: number;
|
|
196
|
+
delta: {
|
|
197
|
+
role?: string;
|
|
198
|
+
content?: string;
|
|
199
|
+
tool_calls?: {
|
|
200
|
+
index: number;
|
|
201
|
+
id?: string;
|
|
202
|
+
type?: string;
|
|
203
|
+
function?: {
|
|
204
|
+
name?: string;
|
|
205
|
+
arguments?: string;
|
|
206
|
+
};
|
|
207
|
+
}[];
|
|
208
|
+
};
|
|
209
|
+
finish_reason?: string | null;
|
|
210
|
+
}[];
|
|
211
|
+
error?: string;
|
|
212
|
+
}
|