roe-typescript 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +189 -0
- package/dist/api/agents.d.ts +87 -0
- package/dist/api/agents.js +263 -0
- package/dist/auth.d.ts +6 -0
- package/dist/auth.js +11 -0
- package/dist/client.d.ts +13 -0
- package/dist/client.js +18 -0
- package/dist/config.d.ts +17 -0
- package/dist/config.js +43 -0
- package/dist/exceptions.d.ts +25 -0
- package/dist/exceptions.js +73 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +9 -0
- package/dist/integration_test.js +686 -0
- package/dist/models/agent.d.ts +78 -0
- package/dist/models/agent.js +40 -0
- package/dist/models/file.d.ts +30 -0
- package/dist/models/file.js +85 -0
- package/dist/models/job.d.ts +37 -0
- package/dist/models/job.js +133 -0
- package/dist/models/responses.d.ts +71 -0
- package/dist/models/responses.js +36 -0
- package/dist/models/user.d.ts +6 -0
- package/dist/models/user.js +1 -0
- package/dist/src/api/agents.js +269 -0
- package/dist/src/auth.js +15 -0
- package/dist/src/client.js +22 -0
- package/dist/src/config.js +47 -0
- package/dist/src/exceptions.js +86 -0
- package/dist/src/models/agent.js +45 -0
- package/dist/src/models/file.js +92 -0
- package/dist/src/models/job.js +138 -0
- package/dist/src/models/responses.js +42 -0
- package/dist/src/models/user.js +2 -0
- package/dist/src/utils/fileDetection.js +46 -0
- package/dist/src/utils/httpClient.js +236 -0
- package/dist/src/utils/pagination.js +18 -0
- package/dist/utils/fileDetection.d.ts +11 -0
- package/dist/utils/fileDetection.js +38 -0
- package/dist/utils/httpClient.d.ts +30 -0
- package/dist/utils/httpClient.js +229 -0
- package/dist/utils/pagination.d.ts +3 -0
- package/dist/utils/pagination.js +14 -0
- package/package.json +36 -0
|
@@ -0,0 +1,686 @@
|
|
|
1
|
+
#!/usr/bin/env npx ts-node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Comprehensive integration tests for the Roe TypeScript SDK.
|
|
5
|
+
* Tests identical scenarios to Go and Python SDKs for cross-SDK parity verification.
|
|
6
|
+
*
|
|
7
|
+
* Run with: npx ts-node integration_test.ts
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
const fs = __importStar(require("fs"));
|
|
44
|
+
const https = __importStar(require("https"));
|
|
45
|
+
const http = __importStar(require("http"));
|
|
46
|
+
const path = __importStar(require("path"));
|
|
47
|
+
const os = __importStar(require("os"));
|
|
48
|
+
const client_1 = require("./src/client");
|
|
49
|
+
const config_1 = require("./src/config");
|
|
50
|
+
const file_1 = require("./src/models/file");
|
|
51
|
+
// Helper to get timeout in seconds from config
|
|
52
|
+
const getTimeoutSeconds = (config) => config.timeoutMs / 1000;
|
|
53
|
+
// Test configuration
|
|
54
|
+
const TEST_CONFIG = {
|
|
55
|
+
apiKey: "7jmZWLJO.QvCXpF1v7IhXebQw4TLoW5YFtG89jDJo",
|
|
56
|
+
organizationId: "abfad6df-ee35-4ab0-81ab-89214e9ed900",
|
|
57
|
+
baseUrl: "https://api.test.roe-ai.com",
|
|
58
|
+
samplePdfs: [
|
|
59
|
+
"https://www.uscis.gov/sites/default/files/document/forms/i-9.pdf",
|
|
60
|
+
"https://arxiv.org/pdf/2512.09941",
|
|
61
|
+
"https://arxiv.org/pdf/2512.09933",
|
|
62
|
+
"https://arxiv.org/pdf/2512.09956",
|
|
63
|
+
],
|
|
64
|
+
sampleUrl: "https://www.roe-ai.com/",
|
|
65
|
+
};
|
|
66
|
+
class TestResults {
|
|
67
|
+
constructor() {
|
|
68
|
+
this.results = {};
|
|
69
|
+
this.errors = [];
|
|
70
|
+
}
|
|
71
|
+
record(testName, result) {
|
|
72
|
+
this.results[testName] = result;
|
|
73
|
+
console.log(` [PASS] ${testName}`);
|
|
74
|
+
}
|
|
75
|
+
recordError(testName, error) {
|
|
76
|
+
this.errors.push([testName, error.message]);
|
|
77
|
+
console.log(` [FAIL] ${testName}: ${error.message}`);
|
|
78
|
+
}
|
|
79
|
+
toJson() {
|
|
80
|
+
return JSON.stringify({
|
|
81
|
+
results: this.results,
|
|
82
|
+
errors: this.errors,
|
|
83
|
+
passed: Object.keys(this.results).length,
|
|
84
|
+
failed: this.errors.length,
|
|
85
|
+
}, null, 2);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Download a PDF from URL to a temp file.
|
|
90
|
+
*/
|
|
91
|
+
async function downloadPdf(url, filename) {
|
|
92
|
+
return new Promise((resolve, reject) => {
|
|
93
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "roe-test-"));
|
|
94
|
+
const filepath = path.join(tempDir, filename);
|
|
95
|
+
console.log(` Downloading ${url}...`);
|
|
96
|
+
const protocol = url.startsWith("https") ? https : http;
|
|
97
|
+
const file = fs.createWriteStream(filepath);
|
|
98
|
+
const request = protocol.get(url, (response) => {
|
|
99
|
+
// Handle redirects
|
|
100
|
+
if (response.statusCode === 301 || response.statusCode === 302) {
|
|
101
|
+
const redirectUrl = response.headers.location;
|
|
102
|
+
if (redirectUrl) {
|
|
103
|
+
file.close();
|
|
104
|
+
fs.unlinkSync(filepath);
|
|
105
|
+
fs.rmdirSync(tempDir);
|
|
106
|
+
downloadPdf(redirectUrl, filename).then(resolve).catch(reject);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
response.pipe(file);
|
|
111
|
+
file.on("finish", () => {
|
|
112
|
+
file.close();
|
|
113
|
+
resolve(filepath);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
request.on("error", (err) => {
|
|
117
|
+
fs.unlink(filepath, () => { });
|
|
118
|
+
reject(err);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Cleanup temp file and directory.
|
|
124
|
+
*/
|
|
125
|
+
function cleanupFile(filepath) {
|
|
126
|
+
try {
|
|
127
|
+
fs.unlinkSync(filepath);
|
|
128
|
+
fs.rmdirSync(path.dirname(filepath));
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
// Ignore cleanup errors
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Test configuration edge cases - falsy values like timeout=0.
|
|
136
|
+
*/
|
|
137
|
+
function testConfigEdgeCases() {
|
|
138
|
+
console.log("\n=== Testing Config Edge Cases ===");
|
|
139
|
+
const results = new TestResults();
|
|
140
|
+
// Test 1: timeout=0 should work (not fall back to default)
|
|
141
|
+
try {
|
|
142
|
+
const config = config_1.RoeConfig.fromEnv({
|
|
143
|
+
apiKey: TEST_CONFIG.apiKey,
|
|
144
|
+
organizationId: TEST_CONFIG.organizationId,
|
|
145
|
+
baseUrl: TEST_CONFIG.baseUrl,
|
|
146
|
+
timeoutSeconds: 0,
|
|
147
|
+
maxRetries: 0,
|
|
148
|
+
});
|
|
149
|
+
// Verify values are actually 0, not defaults
|
|
150
|
+
if (getTimeoutSeconds(config) !== 0) {
|
|
151
|
+
throw new Error(`Expected timeout=0, got ${getTimeoutSeconds(config)}`);
|
|
152
|
+
}
|
|
153
|
+
if (config.maxRetries !== 0) {
|
|
154
|
+
throw new Error(`Expected maxRetries=0, got ${config.maxRetries}`);
|
|
155
|
+
}
|
|
156
|
+
results.record("config_falsy_timeout", {
|
|
157
|
+
timeout: getTimeoutSeconds(config),
|
|
158
|
+
maxRetries: config.maxRetries,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
catch (e) {
|
|
162
|
+
results.recordError("config_falsy_timeout", e);
|
|
163
|
+
}
|
|
164
|
+
// Test 2: Normal config creation
|
|
165
|
+
try {
|
|
166
|
+
const config = config_1.RoeConfig.fromEnv({
|
|
167
|
+
apiKey: TEST_CONFIG.apiKey,
|
|
168
|
+
organizationId: TEST_CONFIG.organizationId,
|
|
169
|
+
baseUrl: TEST_CONFIG.baseUrl,
|
|
170
|
+
});
|
|
171
|
+
if (getTimeoutSeconds(config) !== 60) {
|
|
172
|
+
throw new Error(`Expected default timeout=60, got ${getTimeoutSeconds(config)}`);
|
|
173
|
+
}
|
|
174
|
+
if (config.maxRetries !== 3) {
|
|
175
|
+
throw new Error(`Expected default maxRetries=3, got ${config.maxRetries}`);
|
|
176
|
+
}
|
|
177
|
+
results.record("config_defaults", {
|
|
178
|
+
timeout: getTimeoutSeconds(config),
|
|
179
|
+
maxRetries: config.maxRetries,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
catch (e) {
|
|
183
|
+
results.recordError("config_defaults", e);
|
|
184
|
+
}
|
|
185
|
+
return results;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Test FileUpload from URL functionality.
|
|
189
|
+
*/
|
|
190
|
+
async function testFileUploadFromUrl() {
|
|
191
|
+
console.log("\n=== Testing FileUpload from URL ===");
|
|
192
|
+
const results = new TestResults();
|
|
193
|
+
try {
|
|
194
|
+
const pdfPath = await downloadPdf(TEST_CONFIG.samplePdfs[1], "test_upload.pdf");
|
|
195
|
+
// Test FileUpload with file path
|
|
196
|
+
const upload = new file_1.FileUpload({ path: pdfPath });
|
|
197
|
+
if (upload.effectiveFilename !== "test_upload.pdf") {
|
|
198
|
+
throw new Error(`Expected filename 'test_upload.pdf', got '${upload.effectiveFilename}'`);
|
|
199
|
+
}
|
|
200
|
+
if (upload.effectiveMimeType !== "application/pdf") {
|
|
201
|
+
throw new Error(`Expected mimeType 'application/pdf', got '${upload.effectiveMimeType}'`);
|
|
202
|
+
}
|
|
203
|
+
results.record("file_upload_from_path", {
|
|
204
|
+
filename: upload.effectiveFilename,
|
|
205
|
+
mimeType: upload.effectiveMimeType,
|
|
206
|
+
});
|
|
207
|
+
cleanupFile(pdfPath);
|
|
208
|
+
}
|
|
209
|
+
catch (e) {
|
|
210
|
+
results.recordError("file_upload_from_path", e);
|
|
211
|
+
}
|
|
212
|
+
return results;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Test Document Insights (PDF Extraction) agent.
|
|
216
|
+
*/
|
|
217
|
+
async function testDocInsightsAgent(client) {
|
|
218
|
+
console.log("\n=== Testing Doc Insights Agent ===");
|
|
219
|
+
const results = new TestResults();
|
|
220
|
+
try {
|
|
221
|
+
// Create a Doc Insights agent
|
|
222
|
+
const agent = await client.agents.create({
|
|
223
|
+
name: "TypeScript SDK Test - Doc Insights",
|
|
224
|
+
engineClassId: "PDFExtractionEngine",
|
|
225
|
+
inputDefinitions: [
|
|
226
|
+
{ key: "pdf_files", data_type: "application/pdf", description: "PDF document to analyze" },
|
|
227
|
+
],
|
|
228
|
+
engineConfig: {
|
|
229
|
+
model: "gpt-4.1-2025-04-14",
|
|
230
|
+
pdf_files: "${pdf_files}",
|
|
231
|
+
instructions: "Extract the document title and list the main sections.",
|
|
232
|
+
output_schema: {
|
|
233
|
+
type: "object",
|
|
234
|
+
properties: {
|
|
235
|
+
title: { type: "string", description: "Document title" },
|
|
236
|
+
sections: { type: "array", items: { type: "string" }, description: "Main sections" },
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
});
|
|
241
|
+
results.record("create_doc_insights_agent", { agent_id: agent.id, name: agent.name });
|
|
242
|
+
// Download and run with a PDF
|
|
243
|
+
const pdfPath = await downloadPdf(TEST_CONFIG.samplePdfs[0], "i9_form.pdf");
|
|
244
|
+
try {
|
|
245
|
+
// Run async job
|
|
246
|
+
const job = await client.agents.run({
|
|
247
|
+
agentId: agent.id,
|
|
248
|
+
inputs: { pdf_files: new file_1.FileUpload({ path: pdfPath }) },
|
|
249
|
+
});
|
|
250
|
+
results.record("submit_doc_insights_job", { job_id: job.id });
|
|
251
|
+
// Wait for result
|
|
252
|
+
const result = await job.wait({ timeoutSeconds: 300 });
|
|
253
|
+
results.record("doc_insights_result", {
|
|
254
|
+
agent_id: result.agent_id,
|
|
255
|
+
outputs_count: result.outputs.length,
|
|
256
|
+
has_output: result.outputs.length > 0,
|
|
257
|
+
});
|
|
258
|
+
// Parse and verify output
|
|
259
|
+
if (result.outputs.length > 0) {
|
|
260
|
+
const outputValue = result.outputs[0].value;
|
|
261
|
+
try {
|
|
262
|
+
const parsed = JSON.parse(outputValue);
|
|
263
|
+
results.record("doc_insights_parsed", {
|
|
264
|
+
has_title: "title" in parsed,
|
|
265
|
+
has_sections: "sections" in parsed,
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
catch {
|
|
269
|
+
results.record("doc_insights_parsed", { raw_output: outputValue.substring(0, 200) });
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
finally {
|
|
274
|
+
cleanupFile(pdfPath);
|
|
275
|
+
}
|
|
276
|
+
// Cleanup: delete the agent
|
|
277
|
+
await client.agents.delete(agent.id);
|
|
278
|
+
results.record("delete_doc_insights_agent", { deleted: true });
|
|
279
|
+
}
|
|
280
|
+
catch (e) {
|
|
281
|
+
results.recordError("doc_insights_agent", e);
|
|
282
|
+
}
|
|
283
|
+
return results;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Test Web Insights (URL Website Extraction) agent.
|
|
287
|
+
*/
|
|
288
|
+
async function testWebInsightsAgent(client) {
|
|
289
|
+
console.log("\n=== Testing Web Insights Agent ===");
|
|
290
|
+
const results = new TestResults();
|
|
291
|
+
try {
|
|
292
|
+
// Create a Web Insights agent
|
|
293
|
+
const agent = await client.agents.create({
|
|
294
|
+
name: "TypeScript SDK Test - Web Insights",
|
|
295
|
+
engineClassId: "URLWebsiteExtractionEngine",
|
|
296
|
+
inputDefinitions: [
|
|
297
|
+
{ key: "url", data_type: "text/plain", description: "Website URL to analyze" },
|
|
298
|
+
],
|
|
299
|
+
engineConfig: {
|
|
300
|
+
url: "${url}",
|
|
301
|
+
model: "gpt-4.1-2025-04-14",
|
|
302
|
+
instruction: "Extract the company name and a brief description from this website.",
|
|
303
|
+
vision_mode: false,
|
|
304
|
+
crawl_config: {
|
|
305
|
+
save_html: true,
|
|
306
|
+
save_markdown: true,
|
|
307
|
+
},
|
|
308
|
+
output_schema: {
|
|
309
|
+
type: "object",
|
|
310
|
+
properties: {
|
|
311
|
+
company_name: { type: "string", description: "Company name" },
|
|
312
|
+
description: { type: "string", description: "Brief company description" },
|
|
313
|
+
},
|
|
314
|
+
},
|
|
315
|
+
},
|
|
316
|
+
});
|
|
317
|
+
results.record("create_web_insights_agent", { agent_id: agent.id, name: agent.name });
|
|
318
|
+
// Run with URL
|
|
319
|
+
const job = await client.agents.run({
|
|
320
|
+
agentId: agent.id,
|
|
321
|
+
inputs: { url: TEST_CONFIG.sampleUrl },
|
|
322
|
+
});
|
|
323
|
+
results.record("submit_web_insights_job", { job_id: job.id });
|
|
324
|
+
// Wait for result
|
|
325
|
+
const result = await job.wait({ timeoutSeconds: 300 });
|
|
326
|
+
results.record("web_insights_result", {
|
|
327
|
+
agent_id: result.agent_id,
|
|
328
|
+
outputs_count: result.outputs.length,
|
|
329
|
+
has_output: result.outputs.length > 0,
|
|
330
|
+
});
|
|
331
|
+
// Parse and verify output
|
|
332
|
+
if (result.outputs.length > 0) {
|
|
333
|
+
const outputValue = result.outputs[0].value;
|
|
334
|
+
try {
|
|
335
|
+
const parsed = JSON.parse(outputValue);
|
|
336
|
+
results.record("web_insights_parsed", {
|
|
337
|
+
has_company_name: "company_name" in parsed,
|
|
338
|
+
has_description: "description" in parsed,
|
|
339
|
+
company_name: parsed.company_name ?? "N/A",
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
catch {
|
|
343
|
+
results.record("web_insights_parsed", { raw_output: outputValue.substring(0, 200) });
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
// Cleanup
|
|
347
|
+
await client.agents.delete(agent.id);
|
|
348
|
+
results.record("delete_web_insights_agent", { deleted: true });
|
|
349
|
+
}
|
|
350
|
+
catch (e) {
|
|
351
|
+
results.recordError("web_insights_agent", e);
|
|
352
|
+
}
|
|
353
|
+
return results;
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Test batch job operations with multiple inputs.
|
|
357
|
+
*/
|
|
358
|
+
async function testBatchOperations(client) {
|
|
359
|
+
console.log("\n=== Testing Batch Operations ===");
|
|
360
|
+
const results = new TestResults();
|
|
361
|
+
try {
|
|
362
|
+
// Create a simple text extraction agent for batch testing
|
|
363
|
+
const agent = await client.agents.create({
|
|
364
|
+
name: "TypeScript SDK Test - Batch",
|
|
365
|
+
engineClassId: "MultimodalExtractionEngine",
|
|
366
|
+
inputDefinitions: [
|
|
367
|
+
{ key: "text", data_type: "text/plain", description: "Text to analyze" },
|
|
368
|
+
],
|
|
369
|
+
engineConfig: {
|
|
370
|
+
model: "gpt-4.1-2025-04-14",
|
|
371
|
+
text: "${text}",
|
|
372
|
+
instruction: "Count the number of words in this text.",
|
|
373
|
+
output_schema: {
|
|
374
|
+
type: "object",
|
|
375
|
+
properties: {
|
|
376
|
+
word_count: { type: "integer", description: "Number of words" },
|
|
377
|
+
},
|
|
378
|
+
},
|
|
379
|
+
},
|
|
380
|
+
});
|
|
381
|
+
results.record("create_batch_agent", { agent_id: agent.id });
|
|
382
|
+
// Run batch with multiple inputs
|
|
383
|
+
const batchInputs = [
|
|
384
|
+
{ text: "Hello world" },
|
|
385
|
+
{ text: "This is a longer sentence with more words" },
|
|
386
|
+
{ text: "One" },
|
|
387
|
+
];
|
|
388
|
+
const batch = await client.agents.runMany({
|
|
389
|
+
agentId: agent.id,
|
|
390
|
+
batchInputs,
|
|
391
|
+
});
|
|
392
|
+
results.record("submit_batch_jobs", { job_count: batch.jobs.length });
|
|
393
|
+
// Wait for all results
|
|
394
|
+
const batchResults = await batch.wait({ timeoutSeconds: 300 });
|
|
395
|
+
results.record("batch_results", {
|
|
396
|
+
results_count: batchResults.length,
|
|
397
|
+
all_have_outputs: batchResults.every((r) => r.outputs.length > 0),
|
|
398
|
+
});
|
|
399
|
+
// Cleanup
|
|
400
|
+
await client.agents.delete(agent.id);
|
|
401
|
+
results.record("delete_batch_agent", { deleted: true });
|
|
402
|
+
}
|
|
403
|
+
catch (e) {
|
|
404
|
+
results.recordError("batch_operations", e);
|
|
405
|
+
}
|
|
406
|
+
return results;
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Test synchronous job execution.
|
|
410
|
+
*/
|
|
411
|
+
async function testSyncExecution(client) {
|
|
412
|
+
console.log("\n=== Testing Sync Execution ===");
|
|
413
|
+
const results = new TestResults();
|
|
414
|
+
try {
|
|
415
|
+
// Create agent
|
|
416
|
+
const agent = await client.agents.create({
|
|
417
|
+
name: "TypeScript SDK Test - Sync",
|
|
418
|
+
engineClassId: "MultimodalExtractionEngine",
|
|
419
|
+
inputDefinitions: [
|
|
420
|
+
{ key: "text", data_type: "text/plain", description: "Text input" },
|
|
421
|
+
],
|
|
422
|
+
engineConfig: {
|
|
423
|
+
model: "gpt-4.1-2025-04-14",
|
|
424
|
+
text: "${text}",
|
|
425
|
+
instruction: "Echo back the input text.",
|
|
426
|
+
output_schema: {
|
|
427
|
+
type: "object",
|
|
428
|
+
properties: {
|
|
429
|
+
echo: { type: "string" },
|
|
430
|
+
},
|
|
431
|
+
},
|
|
432
|
+
},
|
|
433
|
+
});
|
|
434
|
+
results.record("create_sync_agent", { agent_id: agent.id });
|
|
435
|
+
// Run synchronously
|
|
436
|
+
const outputs = await client.agents.runSync(agent.id, { text: "Test input for sync" });
|
|
437
|
+
results.record("sync_execution", {
|
|
438
|
+
outputs_count: outputs.length,
|
|
439
|
+
has_output: outputs.length > 0,
|
|
440
|
+
});
|
|
441
|
+
// Cleanup
|
|
442
|
+
await client.agents.delete(agent.id);
|
|
443
|
+
results.record("delete_sync_agent", { deleted: true });
|
|
444
|
+
}
|
|
445
|
+
catch (e) {
|
|
446
|
+
results.recordError("sync_execution", e);
|
|
447
|
+
}
|
|
448
|
+
return results;
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Test agent version management.
|
|
452
|
+
*/
|
|
453
|
+
async function testVersionManagement(client) {
|
|
454
|
+
console.log("\n=== Testing Version Management ===");
|
|
455
|
+
const results = new TestResults();
|
|
456
|
+
try {
|
|
457
|
+
// Create agent
|
|
458
|
+
const agent = await client.agents.create({
|
|
459
|
+
name: "TypeScript SDK Test - Versions",
|
|
460
|
+
engineClassId: "MultimodalExtractionEngine",
|
|
461
|
+
inputDefinitions: [
|
|
462
|
+
{ key: "text", data_type: "text/plain", description: "Text" },
|
|
463
|
+
],
|
|
464
|
+
engineConfig: {
|
|
465
|
+
model: "gpt-4.1-2025-04-14",
|
|
466
|
+
text: "${text}",
|
|
467
|
+
instruction: "Version 1 instruction",
|
|
468
|
+
output_schema: { type: "object", properties: { result: { type: "string" } } },
|
|
469
|
+
},
|
|
470
|
+
versionName: "v1",
|
|
471
|
+
});
|
|
472
|
+
results.record("create_versioned_agent", { agent_id: agent.id });
|
|
473
|
+
// List versions
|
|
474
|
+
const versions = await client.agents.versions.list(agent.id);
|
|
475
|
+
results.record("list_versions", { version_count: versions.length });
|
|
476
|
+
// Get current version
|
|
477
|
+
const current = await client.agents.versions.retrieveCurrent(agent.id);
|
|
478
|
+
results.record("current_version", { version_id: current.id, version_name: current.version_name });
|
|
479
|
+
// Create new version
|
|
480
|
+
const v2 = await client.agents.versions.create({
|
|
481
|
+
agentId: agent.id,
|
|
482
|
+
versionName: "v2",
|
|
483
|
+
engineConfig: {
|
|
484
|
+
model: "gpt-4.1-2025-04-14",
|
|
485
|
+
text: "${text}",
|
|
486
|
+
instruction: "Version 2 instruction - updated",
|
|
487
|
+
output_schema: { type: "object", properties: { result: { type: "string" } } },
|
|
488
|
+
},
|
|
489
|
+
});
|
|
490
|
+
results.record("create_version_v2", { version_id: v2.id, version_name: v2.version_name });
|
|
491
|
+
// Run specific version
|
|
492
|
+
const job = await client.agents.runVersion({
|
|
493
|
+
agentId: agent.id,
|
|
494
|
+
versionId: v2.id,
|
|
495
|
+
inputs: { text: "Test" },
|
|
496
|
+
});
|
|
497
|
+
const versionResult = await job.wait({ timeoutSeconds: 120 });
|
|
498
|
+
results.record("run_specific_version", {
|
|
499
|
+
job_id: job.id,
|
|
500
|
+
has_output: versionResult.outputs.length > 0,
|
|
501
|
+
});
|
|
502
|
+
// Cleanup
|
|
503
|
+
await client.agents.delete(agent.id);
|
|
504
|
+
results.record("delete_versioned_agent", { deleted: true });
|
|
505
|
+
}
|
|
506
|
+
catch (e) {
|
|
507
|
+
results.recordError("version_management", e);
|
|
508
|
+
}
|
|
509
|
+
return results;
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Test job status and result retrieval.
|
|
513
|
+
*/
|
|
514
|
+
async function testJobManagement(client) {
|
|
515
|
+
console.log("\n=== Testing Job Management ===");
|
|
516
|
+
const results = new TestResults();
|
|
517
|
+
try {
|
|
518
|
+
// Create agent
|
|
519
|
+
const agent = await client.agents.create({
|
|
520
|
+
name: "TypeScript SDK Test - Jobs",
|
|
521
|
+
engineClassId: "MultimodalExtractionEngine",
|
|
522
|
+
inputDefinitions: [
|
|
523
|
+
{ key: "text", data_type: "text/plain", description: "Text" },
|
|
524
|
+
],
|
|
525
|
+
engineConfig: {
|
|
526
|
+
model: "gpt-4.1-2025-04-14",
|
|
527
|
+
text: "${text}",
|
|
528
|
+
instruction: "Analyze this text.",
|
|
529
|
+
output_schema: { type: "object", properties: { analysis: { type: "string" } } },
|
|
530
|
+
},
|
|
531
|
+
});
|
|
532
|
+
// Submit job
|
|
533
|
+
const job = await client.agents.run({
|
|
534
|
+
agentId: agent.id,
|
|
535
|
+
inputs: { text: "Test for job management" },
|
|
536
|
+
});
|
|
537
|
+
results.record("submit_job", { job_id: job.id });
|
|
538
|
+
// Check status
|
|
539
|
+
const status = await client.agents.jobs.retrieveStatus(job.id);
|
|
540
|
+
results.record("job_status", { status: status.status });
|
|
541
|
+
// Wait and get result
|
|
542
|
+
const result = await job.wait({ timeoutSeconds: 120 });
|
|
543
|
+
results.record("job_result", {
|
|
544
|
+
agent_id: result.agent_id,
|
|
545
|
+
has_outputs: result.outputs.length > 0,
|
|
546
|
+
});
|
|
547
|
+
// Retrieve result separately
|
|
548
|
+
const retrievedResult = await client.agents.jobs.retrieveResult(job.id);
|
|
549
|
+
results.record("retrieved_result", {
|
|
550
|
+
matches: retrievedResult.agent_id === result.agent_id,
|
|
551
|
+
});
|
|
552
|
+
// Cleanup
|
|
553
|
+
await client.agents.delete(agent.id);
|
|
554
|
+
}
|
|
555
|
+
catch (e) {
|
|
556
|
+
results.recordError("job_management", e);
|
|
557
|
+
}
|
|
558
|
+
return results;
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Test uploading multiple different PDFs.
|
|
562
|
+
*/
|
|
563
|
+
async function testMultiplePdfUploads(client) {
|
|
564
|
+
console.log("\n=== Testing Multiple PDF Uploads ===");
|
|
565
|
+
const results = new TestResults();
|
|
566
|
+
try {
|
|
567
|
+
// Create agent
|
|
568
|
+
const agent = await client.agents.create({
|
|
569
|
+
name: "TypeScript SDK Test - Multi PDF",
|
|
570
|
+
engineClassId: "PDFExtractionEngine",
|
|
571
|
+
inputDefinitions: [
|
|
572
|
+
{ key: "pdf_files", data_type: "application/pdf", description: "PDF" },
|
|
573
|
+
],
|
|
574
|
+
engineConfig: {
|
|
575
|
+
model: "gpt-4.1-2025-04-14",
|
|
576
|
+
pdf_files: "${pdf_files}",
|
|
577
|
+
instructions: "What is the title or main topic of this document?",
|
|
578
|
+
output_schema: {
|
|
579
|
+
type: "object",
|
|
580
|
+
properties: {
|
|
581
|
+
title: { type: "string" },
|
|
582
|
+
},
|
|
583
|
+
},
|
|
584
|
+
},
|
|
585
|
+
});
|
|
586
|
+
results.record("create_multi_pdf_agent", { agent_id: agent.id });
|
|
587
|
+
// Test with multiple PDFs (arxiv papers)
|
|
588
|
+
const pdfUrls = TEST_CONFIG.samplePdfs.slice(1, 4);
|
|
589
|
+
for (let i = 0; i < pdfUrls.length; i++) {
|
|
590
|
+
const pdfUrl = pdfUrls[i];
|
|
591
|
+
const pdfPath = await downloadPdf(pdfUrl, `arxiv_${i}.pdf`);
|
|
592
|
+
try {
|
|
593
|
+
const job = await client.agents.run({
|
|
594
|
+
agentId: agent.id,
|
|
595
|
+
inputs: { pdf_files: new file_1.FileUpload({ path: pdfPath }) },
|
|
596
|
+
});
|
|
597
|
+
const pdfResult = await job.wait({ timeoutSeconds: 300 });
|
|
598
|
+
results.record(`pdf_upload_${i}`, {
|
|
599
|
+
url: pdfUrl,
|
|
600
|
+
job_id: job.id,
|
|
601
|
+
has_output: pdfResult.outputs.length > 0,
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
finally {
|
|
605
|
+
cleanupFile(pdfPath);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
// Cleanup
|
|
609
|
+
await client.agents.delete(agent.id);
|
|
610
|
+
results.record("delete_multi_pdf_agent", { deleted: true });
|
|
611
|
+
}
|
|
612
|
+
catch (e) {
|
|
613
|
+
results.recordError("multiple_pdf_uploads", e);
|
|
614
|
+
}
|
|
615
|
+
return results;
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* Main test runner.
|
|
619
|
+
*/
|
|
620
|
+
async function main() {
|
|
621
|
+
console.log("=".repeat(60));
|
|
622
|
+
console.log("ROE TYPESCRIPT SDK INTEGRATION TESTS");
|
|
623
|
+
console.log("=".repeat(60));
|
|
624
|
+
console.log(`Base URL: ${TEST_CONFIG.baseUrl}`);
|
|
625
|
+
console.log(`Organization ID: ${TEST_CONFIG.organizationId}`);
|
|
626
|
+
// Create client
|
|
627
|
+
const client = new client_1.RoeClient({
|
|
628
|
+
apiKey: TEST_CONFIG.apiKey,
|
|
629
|
+
organizationId: TEST_CONFIG.organizationId,
|
|
630
|
+
baseUrl: TEST_CONFIG.baseUrl,
|
|
631
|
+
});
|
|
632
|
+
const allResults = {};
|
|
633
|
+
// Run all test suites
|
|
634
|
+
const testSuites = [
|
|
635
|
+
["config_edge_cases", () => testConfigEdgeCases()],
|
|
636
|
+
["file_upload_from_url", () => testFileUploadFromUrl()],
|
|
637
|
+
["doc_insights_agent", () => testDocInsightsAgent(client)],
|
|
638
|
+
["web_insights_agent", () => testWebInsightsAgent(client)],
|
|
639
|
+
["batch_operations", () => testBatchOperations(client)],
|
|
640
|
+
["sync_execution", () => testSyncExecution(client)],
|
|
641
|
+
["version_management", () => testVersionManagement(client)],
|
|
642
|
+
["job_management", () => testJobManagement(client)],
|
|
643
|
+
["multiple_pdf_uploads", () => testMultiplePdfUploads(client)],
|
|
644
|
+
];
|
|
645
|
+
for (const [suiteName, testFunc] of testSuites) {
|
|
646
|
+
try {
|
|
647
|
+
const result = await testFunc();
|
|
648
|
+
allResults[suiteName] = result.results;
|
|
649
|
+
if (result.errors.length > 0) {
|
|
650
|
+
allResults[`${suiteName}_errors`] = result.errors;
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
catch (e) {
|
|
654
|
+
allResults[suiteName] = { error: e.message };
|
|
655
|
+
console.log(` [FATAL] ${suiteName}: ${e.message}`);
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
// Summary
|
|
659
|
+
console.log("\n" + "=".repeat(60));
|
|
660
|
+
console.log("TEST SUMMARY");
|
|
661
|
+
console.log("=".repeat(60));
|
|
662
|
+
let totalPassed = 0;
|
|
663
|
+
let totalFailed = 0;
|
|
664
|
+
for (const [key, value] of Object.entries(allResults)) {
|
|
665
|
+
if (!key.endsWith("_errors") && typeof value === "object" && value !== null) {
|
|
666
|
+
totalPassed += Object.keys(value).length;
|
|
667
|
+
}
|
|
668
|
+
if (key.endsWith("_errors") && Array.isArray(value)) {
|
|
669
|
+
totalFailed += value.length;
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
console.log(`Total passed: ${totalPassed}`);
|
|
673
|
+
console.log(`Total failed: ${totalFailed}`);
|
|
674
|
+
// Save results for comparison
|
|
675
|
+
const outputFile = "typescript_test_results.json";
|
|
676
|
+
fs.writeFileSync(outputFile, JSON.stringify(allResults, null, 2));
|
|
677
|
+
console.log(`\nResults saved to: ${outputFile}`);
|
|
678
|
+
return totalFailed === 0 ? 0 : 1;
|
|
679
|
+
}
|
|
680
|
+
// Run main
|
|
681
|
+
main()
|
|
682
|
+
.then((code) => process.exit(code))
|
|
683
|
+
.catch((err) => {
|
|
684
|
+
console.error("Fatal error:", err);
|
|
685
|
+
process.exit(1);
|
|
686
|
+
});
|