@agrentingai/paperclip-adapter 0.2.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/README.md +306 -0
- package/dist/server/index.cjs +1406 -0
- package/dist/server/index.cjs.map +1 -0
- package/dist/server/index.d.cts +895 -0
- package/dist/server/index.d.ts +895 -0
- package/dist/server/index.js +1336 -0
- package/dist/server/index.js.map +1 -0
- package/dist/ui/index.cjs +125 -0
- package/dist/ui/index.cjs.map +1 -0
- package/dist/ui/index.d.cts +36 -0
- package/dist/ui/index.d.ts +36 -0
- package/dist/ui/index.js +98 -0
- package/dist/ui/index.js.map +1 -0
- package/package.json +65 -0
- package/server/src/adapter.test.ts +497 -0
- package/server/src/adapter.ts +1044 -0
- package/server/src/balance-monitor.test.ts +147 -0
- package/server/src/balance-monitor.ts +118 -0
- package/server/src/client.test.ts +949 -0
- package/server/src/client.ts +550 -0
- package/server/src/comment-sync.test.ts +25 -0
- package/server/src/comment-sync.ts +71 -0
- package/server/src/crypto.test.ts +62 -0
- package/server/src/crypto.ts +25 -0
- package/server/src/index.ts +67 -0
- package/server/src/polling.test.ts +208 -0
- package/server/src/polling.ts +183 -0
- package/server/src/types.ts +244 -0
- package/server/src/webhook-handler.test.ts +379 -0
- package/server/src/webhook-handler.ts +292 -0
- package/ui/src/adapter.ts +131 -0
- package/ui/src/index.ts +2 -0
|
@@ -0,0 +1,497 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
createServerAdapter,
|
|
4
|
+
getConfigSchema,
|
|
5
|
+
testEnvironment,
|
|
6
|
+
execute,
|
|
7
|
+
cancelTask,
|
|
8
|
+
discoverAgents,
|
|
9
|
+
getBalance,
|
|
10
|
+
getTransactions,
|
|
11
|
+
getTaskPayment,
|
|
12
|
+
getTaskProgress,
|
|
13
|
+
} from "./adapter.js";
|
|
14
|
+
import { unregisterTaskMapping, getActiveTaskMappings, stopRegistryCleanup } from "./webhook-handler.js";
|
|
15
|
+
import type { AgrentingAdapterConfig } from "./types.js";
|
|
16
|
+
|
|
17
|
+
// Mock the client so we don't hit the real API
|
|
18
|
+
vi.mock("./client.js", () => {
|
|
19
|
+
return {
|
|
20
|
+
AgrentingClient: vi.fn().mockImplementation(function() {
|
|
21
|
+
return {
|
|
22
|
+
testConnection: vi.fn().mockResolvedValue({ ok: true, message: "Connected" }),
|
|
23
|
+
createTask: vi.fn().mockResolvedValue({
|
|
24
|
+
id: "mock-task-id",
|
|
25
|
+
status: "pending",
|
|
26
|
+
client_agent_id: "c1",
|
|
27
|
+
provider_agent_id: "did:agrenting:test",
|
|
28
|
+
capability: "test",
|
|
29
|
+
input: "hello",
|
|
30
|
+
created_at: new Date().toISOString(),
|
|
31
|
+
updated_at: new Date().toISOString(),
|
|
32
|
+
}),
|
|
33
|
+
getTask: vi.fn().mockResolvedValue({
|
|
34
|
+
id: "mock-task-id",
|
|
35
|
+
status: "completed",
|
|
36
|
+
client_agent_id: "c1",
|
|
37
|
+
provider_agent_id: "did:agrenting:test",
|
|
38
|
+
capability: "test",
|
|
39
|
+
input: "hello",
|
|
40
|
+
output: "task output",
|
|
41
|
+
created_at: new Date().toISOString(),
|
|
42
|
+
updated_at: new Date().toISOString(),
|
|
43
|
+
}),
|
|
44
|
+
getTaskProgress: vi.fn().mockResolvedValue({
|
|
45
|
+
status: "completed",
|
|
46
|
+
progress_percent: 100,
|
|
47
|
+
progress_message: "Done",
|
|
48
|
+
updated_at: new Date().toISOString(),
|
|
49
|
+
}),
|
|
50
|
+
getTaskTimeline: vi.fn().mockResolvedValue({ events: [] }),
|
|
51
|
+
cancelTask: vi.fn().mockResolvedValue({ id: "mock-task-id", status: "cancelled" }),
|
|
52
|
+
discoverAgents: vi.fn().mockResolvedValue([{ id: "agent-1", name: "Agent" }]),
|
|
53
|
+
getBalance: vi.fn().mockResolvedValue({ available: "100", escrow: "0", total: "100" }),
|
|
54
|
+
getTransactions: vi.fn().mockResolvedValue([]),
|
|
55
|
+
getTaskPayment: vi.fn().mockResolvedValue({
|
|
56
|
+
id: "pay-1", task_id: "mock-task-id", amount: "10", currency: "USD",
|
|
57
|
+
status: "escrowed", created_at: new Date().toISOString(),
|
|
58
|
+
}),
|
|
59
|
+
createTaskPayment: vi.fn().mockResolvedValue({
|
|
60
|
+
id: "pay-1", task_id: "mock-task-id", amount: "10", currency: "USD",
|
|
61
|
+
status: "escrowed", created_at: new Date().toISOString(),
|
|
62
|
+
}),
|
|
63
|
+
deleteWebhook: vi.fn().mockResolvedValue(undefined),
|
|
64
|
+
uploadDocument: vi.fn().mockResolvedValue({
|
|
65
|
+
id: "doc-1", name: "instructions", file_url: "https://cdn/doc",
|
|
66
|
+
content_type: "text/plain", file_hash: "hash", document_type: "instructions",
|
|
67
|
+
}),
|
|
68
|
+
};
|
|
69
|
+
}),
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Mock balance-monitor to avoid API calls
|
|
74
|
+
vi.mock("./balance-monitor.js", () => ({
|
|
75
|
+
canSubmitTask: vi.fn().mockResolvedValue({ ok: true }),
|
|
76
|
+
checkBalance: vi.fn().mockResolvedValue({
|
|
77
|
+
available: 100, escrow: 0, total: 100,
|
|
78
|
+
currency: "USD", isLow: false, isInsufficient: false,
|
|
79
|
+
}),
|
|
80
|
+
formatLowBalanceComment: vi.fn().mockReturnValue("Low balance"),
|
|
81
|
+
formatInsufficientBalanceComment: vi.fn().mockReturnValue("Insufficient"),
|
|
82
|
+
}));
|
|
83
|
+
|
|
84
|
+
// Mock webhook listener
|
|
85
|
+
vi.mock("./webhook-handler.js", async (importOriginal) => {
|
|
86
|
+
const actual = await importOriginal<typeof import("./webhook-handler.js")>();
|
|
87
|
+
return {
|
|
88
|
+
...actual,
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
const mockConfig: AgrentingAdapterConfig = {
|
|
93
|
+
agrentingUrl: "https://api.agrenting.com",
|
|
94
|
+
apiKey: "test-key",
|
|
95
|
+
agentDid: "did:agrenting:test",
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
beforeEach(() => {
|
|
99
|
+
vi.clearAllMocks();
|
|
100
|
+
// Clear task registry
|
|
101
|
+
const mappings = getActiveTaskMappings();
|
|
102
|
+
for (const key of mappings.keys()) {
|
|
103
|
+
unregisterTaskMapping(key);
|
|
104
|
+
}
|
|
105
|
+
stopRegistryCleanup();
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// ---------------------------------------------------------------------------
|
|
109
|
+
// createServerAdapter
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
|
|
112
|
+
describe("createServerAdapter", () => {
|
|
113
|
+
it("returns adapter with name 'agrenting'", () => {
|
|
114
|
+
const adapter = createServerAdapter();
|
|
115
|
+
expect(adapter.name).toBe("agrenting");
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("exposes all required methods", () => {
|
|
119
|
+
const adapter = createServerAdapter();
|
|
120
|
+
const methods = [
|
|
121
|
+
"execute",
|
|
122
|
+
"testEnvironment",
|
|
123
|
+
"getConfigSchema",
|
|
124
|
+
"startWebhookListener",
|
|
125
|
+
"stopWebhookListener",
|
|
126
|
+
"registerWebhook",
|
|
127
|
+
"deregisterWebhook",
|
|
128
|
+
"getTaskProgress",
|
|
129
|
+
"getTaskPayment",
|
|
130
|
+
"cancelTask",
|
|
131
|
+
"discoverAgents",
|
|
132
|
+
"getBalance",
|
|
133
|
+
"getTransactions",
|
|
134
|
+
"deposit",
|
|
135
|
+
"withdraw",
|
|
136
|
+
];
|
|
137
|
+
for (const method of methods) {
|
|
138
|
+
expect(typeof (adapter as Record<string, unknown>)[method]).toBe("function");
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
// ---------------------------------------------------------------------------
|
|
144
|
+
// getConfigSchema
|
|
145
|
+
// ---------------------------------------------------------------------------
|
|
146
|
+
|
|
147
|
+
describe("getConfigSchema", () => {
|
|
148
|
+
it("returns a valid JSON schema with required fields", () => {
|
|
149
|
+
const schema = getConfigSchema();
|
|
150
|
+
expect(schema.type).toBe("object");
|
|
151
|
+
expect(schema.required).toEqual(["agrentingUrl", "apiKey", "agentDid"]);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it("includes all config properties", () => {
|
|
155
|
+
const schema = getConfigSchema();
|
|
156
|
+
const props = schema.properties as Record<string, unknown>;
|
|
157
|
+
expect(props).toHaveProperty("agrentingUrl");
|
|
158
|
+
expect(props).toHaveProperty("apiKey");
|
|
159
|
+
expect(props).toHaveProperty("agentDid");
|
|
160
|
+
expect(props).toHaveProperty("webhookSecret");
|
|
161
|
+
expect(props).toHaveProperty("webhookCallbackUrl");
|
|
162
|
+
expect(props).toHaveProperty("pricingModel");
|
|
163
|
+
expect(props).toHaveProperty("timeoutSec");
|
|
164
|
+
expect(props).toHaveProperty("instructionsBundleMode");
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it("marks apiKey and webhookSecret as sensitive", () => {
|
|
168
|
+
const schema = getConfigSchema();
|
|
169
|
+
const props = schema.properties as Record<string, Record<string, unknown>>;
|
|
170
|
+
expect(props.apiKey.sensitive).toBe(true);
|
|
171
|
+
expect(props.webhookSecret.sensitive).toBe(true);
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// ---------------------------------------------------------------------------
|
|
176
|
+
// testEnvironment
|
|
177
|
+
// ---------------------------------------------------------------------------
|
|
178
|
+
|
|
179
|
+
describe("testEnvironment", () => {
|
|
180
|
+
it("returns ok when connection succeeds", async () => {
|
|
181
|
+
const result = await testEnvironment(mockConfig);
|
|
182
|
+
expect(result.ok).toBe(true);
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
// ---------------------------------------------------------------------------
|
|
187
|
+
// execute (polling mode — no webhook config)
|
|
188
|
+
// ---------------------------------------------------------------------------
|
|
189
|
+
|
|
190
|
+
describe("execute", () => {
|
|
191
|
+
it("executes a task in polling mode and returns success", async () => {
|
|
192
|
+
const result = await execute(mockConfig, {
|
|
193
|
+
input: "test input",
|
|
194
|
+
capability: "test-capability",
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
expect(result.success).toBe(true);
|
|
198
|
+
expect(result.taskId).toBe("mock-task-id");
|
|
199
|
+
expect(result.output).toBe("task output");
|
|
200
|
+
expect(result.durationMs).toBeGreaterThanOrEqual(0);
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
it("returns error when task fails", async () => {
|
|
204
|
+
const { AgrentingClient } = await import("./client.js");
|
|
205
|
+
const MockClient = vi.mocked(AgrentingClient);
|
|
206
|
+
// Both execute() and pollTaskUntilDone() create an AgrentingClient,
|
|
207
|
+
// so mock twice (once for each construction).
|
|
208
|
+
MockClient.mockImplementationOnce(function() {
|
|
209
|
+
return {
|
|
210
|
+
testConnection: vi.fn(),
|
|
211
|
+
createTask: vi.fn().mockResolvedValue({
|
|
212
|
+
id: "fail-task",
|
|
213
|
+
status: "pending",
|
|
214
|
+
client_agent_id: "c1",
|
|
215
|
+
provider_agent_id: "p1",
|
|
216
|
+
capability: "test",
|
|
217
|
+
input: "hello",
|
|
218
|
+
created_at: new Date().toISOString(),
|
|
219
|
+
updated_at: new Date().toISOString(),
|
|
220
|
+
}),
|
|
221
|
+
getTask: vi.fn(),
|
|
222
|
+
getTaskProgress: vi.fn(),
|
|
223
|
+
getTaskTimeline: vi.fn(),
|
|
224
|
+
cancelTask: vi.fn(),
|
|
225
|
+
discoverAgents: vi.fn(),
|
|
226
|
+
getBalance: vi.fn(),
|
|
227
|
+
getTransactions: vi.fn(),
|
|
228
|
+
getTaskPayment: vi.fn(),
|
|
229
|
+
createTaskPayment: vi.fn(),
|
|
230
|
+
deleteWebhook: vi.fn(),
|
|
231
|
+
uploadDocument: vi.fn(),
|
|
232
|
+
};
|
|
233
|
+
});
|
|
234
|
+
MockClient.mockImplementationOnce(function() {
|
|
235
|
+
return {
|
|
236
|
+
testConnection: vi.fn(),
|
|
237
|
+
createTask: vi.fn(),
|
|
238
|
+
getTask: vi.fn().mockResolvedValue({
|
|
239
|
+
id: "fail-task",
|
|
240
|
+
status: "failed",
|
|
241
|
+
error_reason: "Something went wrong",
|
|
242
|
+
client_agent_id: "c1",
|
|
243
|
+
provider_agent_id: "p1",
|
|
244
|
+
capability: "test",
|
|
245
|
+
input: "hello",
|
|
246
|
+
created_at: new Date().toISOString(),
|
|
247
|
+
updated_at: new Date().toISOString(),
|
|
248
|
+
}),
|
|
249
|
+
getTaskProgress: vi.fn(),
|
|
250
|
+
getTaskTimeline: vi.fn(),
|
|
251
|
+
cancelTask: vi.fn(),
|
|
252
|
+
discoverAgents: vi.fn(),
|
|
253
|
+
getBalance: vi.fn(),
|
|
254
|
+
getTransactions: vi.fn(),
|
|
255
|
+
getTaskPayment: vi.fn(),
|
|
256
|
+
createTaskPayment: vi.fn(),
|
|
257
|
+
deleteWebhook: vi.fn(),
|
|
258
|
+
uploadDocument: vi.fn(),
|
|
259
|
+
};
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
const result = await execute(mockConfig, {
|
|
263
|
+
input: "test",
|
|
264
|
+
capability: "test",
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
expect(result.success).toBe(false);
|
|
268
|
+
expect(result.error).toBe("Something went wrong");
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
it("returns error when task is cancelled", async () => {
|
|
272
|
+
const { AgrentingClient } = await import("./client.js");
|
|
273
|
+
const MockClient = vi.mocked(AgrentingClient);
|
|
274
|
+
MockClient.mockImplementationOnce(function() {
|
|
275
|
+
return {
|
|
276
|
+
testConnection: vi.fn(),
|
|
277
|
+
createTask: vi.fn().mockResolvedValue({
|
|
278
|
+
id: "cancel-task",
|
|
279
|
+
status: "pending",
|
|
280
|
+
client_agent_id: "c1",
|
|
281
|
+
provider_agent_id: "p1",
|
|
282
|
+
capability: "test",
|
|
283
|
+
input: "hello",
|
|
284
|
+
created_at: new Date().toISOString(),
|
|
285
|
+
updated_at: new Date().toISOString(),
|
|
286
|
+
}),
|
|
287
|
+
getTask: vi.fn(),
|
|
288
|
+
getTaskProgress: vi.fn(),
|
|
289
|
+
getTaskTimeline: vi.fn(),
|
|
290
|
+
cancelTask: vi.fn(),
|
|
291
|
+
discoverAgents: vi.fn(),
|
|
292
|
+
getBalance: vi.fn(),
|
|
293
|
+
getTransactions: vi.fn(),
|
|
294
|
+
getTaskPayment: vi.fn(),
|
|
295
|
+
createTaskPayment: vi.fn(),
|
|
296
|
+
deleteWebhook: vi.fn(),
|
|
297
|
+
uploadDocument: vi.fn(),
|
|
298
|
+
};
|
|
299
|
+
});
|
|
300
|
+
MockClient.mockImplementationOnce(function() {
|
|
301
|
+
return {
|
|
302
|
+
testConnection: vi.fn(),
|
|
303
|
+
createTask: vi.fn(),
|
|
304
|
+
getTask: vi.fn().mockResolvedValue({
|
|
305
|
+
id: "cancel-task",
|
|
306
|
+
status: "cancelled",
|
|
307
|
+
client_agent_id: "c1",
|
|
308
|
+
provider_agent_id: "p1",
|
|
309
|
+
capability: "test",
|
|
310
|
+
input: "hello",
|
|
311
|
+
created_at: new Date().toISOString(),
|
|
312
|
+
updated_at: new Date().toISOString(),
|
|
313
|
+
}),
|
|
314
|
+
getTaskProgress: vi.fn(),
|
|
315
|
+
getTaskTimeline: vi.fn(),
|
|
316
|
+
cancelTask: vi.fn(),
|
|
317
|
+
discoverAgents: vi.fn(),
|
|
318
|
+
getBalance: vi.fn(),
|
|
319
|
+
getTransactions: vi.fn(),
|
|
320
|
+
getTaskPayment: vi.fn(),
|
|
321
|
+
createTaskPayment: vi.fn(),
|
|
322
|
+
deleteWebhook: vi.fn(),
|
|
323
|
+
uploadDocument: vi.fn(),
|
|
324
|
+
};
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
const result = await execute(mockConfig, {
|
|
328
|
+
input: "test",
|
|
329
|
+
capability: "test",
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
expect(result.success).toBe(false);
|
|
333
|
+
expect(result.error).toBe("Task was cancelled");
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
it("handles escrow payment failure by cancelling the task", async () => {
|
|
337
|
+
const { AgrentingClient } = await import("./client.js");
|
|
338
|
+
const mockCancel = vi.fn().mockResolvedValue({ id: "pay-fail-task", status: "cancelled" });
|
|
339
|
+
const MockClient = vi.mocked(AgrentingClient);
|
|
340
|
+
MockClient.mockImplementationOnce(function() {
|
|
341
|
+
return {
|
|
342
|
+
testConnection: vi.fn(),
|
|
343
|
+
createTask: vi.fn().mockResolvedValue({
|
|
344
|
+
id: "pay-fail-task",
|
|
345
|
+
status: "pending",
|
|
346
|
+
client_agent_id: "c1",
|
|
347
|
+
provider_agent_id: "p1",
|
|
348
|
+
capability: "test",
|
|
349
|
+
input: "hello",
|
|
350
|
+
created_at: new Date().toISOString(),
|
|
351
|
+
updated_at: new Date().toISOString(),
|
|
352
|
+
}),
|
|
353
|
+
getTask: vi.fn(),
|
|
354
|
+
getTaskProgress: vi.fn(),
|
|
355
|
+
getTaskTimeline: vi.fn(),
|
|
356
|
+
cancelTask: mockCancel,
|
|
357
|
+
discoverAgents: vi.fn(),
|
|
358
|
+
getBalance: vi.fn(),
|
|
359
|
+
getTransactions: vi.fn(),
|
|
360
|
+
getTaskPayment: vi.fn(),
|
|
361
|
+
createTaskPayment: vi.fn().mockRejectedValue(new Error("Insufficient funds")),
|
|
362
|
+
deleteWebhook: vi.fn(),
|
|
363
|
+
uploadDocument: vi.fn(),
|
|
364
|
+
};
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
const result = await execute(mockConfig, {
|
|
368
|
+
input: "test",
|
|
369
|
+
capability: "test",
|
|
370
|
+
maxPrice: "50.00",
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
expect(result.success).toBe(false);
|
|
374
|
+
expect(result.error).toContain("Escrow payment failed");
|
|
375
|
+
expect(mockCancel).toHaveBeenCalledWith("pay-fail-task");
|
|
376
|
+
});
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
// ---------------------------------------------------------------------------
|
|
380
|
+
// cancelTask
|
|
381
|
+
// ---------------------------------------------------------------------------
|
|
382
|
+
|
|
383
|
+
describe("cancelTask", () => {
|
|
384
|
+
it("returns success when cancellation works", async () => {
|
|
385
|
+
const result = await cancelTask(mockConfig, "task-1");
|
|
386
|
+
expect(result.success).toBe(true);
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
it("returns error when cancellation fails", async () => {
|
|
390
|
+
const { AgrentingClient } = await import("./client.js");
|
|
391
|
+
const MockClient = vi.mocked(AgrentingClient);
|
|
392
|
+
MockClient.mockImplementationOnce(function() {
|
|
393
|
+
return {
|
|
394
|
+
testConnection: vi.fn(),
|
|
395
|
+
createTask: vi.fn(),
|
|
396
|
+
getTask: vi.fn(),
|
|
397
|
+
getTaskProgress: vi.fn(),
|
|
398
|
+
getTaskTimeline: vi.fn(),
|
|
399
|
+
cancelTask: vi.fn().mockRejectedValue(new Error("Cannot cancel")),
|
|
400
|
+
discoverAgents: vi.fn(),
|
|
401
|
+
getBalance: vi.fn(),
|
|
402
|
+
getTransactions: vi.fn(),
|
|
403
|
+
getTaskPayment: vi.fn(),
|
|
404
|
+
createTaskPayment: vi.fn(),
|
|
405
|
+
deleteWebhook: vi.fn(),
|
|
406
|
+
uploadDocument: vi.fn(),
|
|
407
|
+
};
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
const result = await cancelTask(mockConfig, "task-1");
|
|
411
|
+
expect(result.success).toBe(false);
|
|
412
|
+
expect(result.error).toBe("Cannot cancel");
|
|
413
|
+
});
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
// ---------------------------------------------------------------------------
|
|
417
|
+
// discoverAgents
|
|
418
|
+
// ---------------------------------------------------------------------------
|
|
419
|
+
|
|
420
|
+
describe("discoverAgents", () => {
|
|
421
|
+
it("returns agents from the API", async () => {
|
|
422
|
+
const result = await discoverAgents(mockConfig, { capability: "code-review" });
|
|
423
|
+
expect(result).toEqual([{ id: "agent-1", name: "Agent" }]);
|
|
424
|
+
});
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
// ---------------------------------------------------------------------------
|
|
428
|
+
// getBalance
|
|
429
|
+
// ---------------------------------------------------------------------------
|
|
430
|
+
|
|
431
|
+
describe("getBalance", () => {
|
|
432
|
+
it("returns balance from the API", async () => {
|
|
433
|
+
const result = await getBalance(mockConfig);
|
|
434
|
+
expect(result.available).toBe("100");
|
|
435
|
+
});
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
// ---------------------------------------------------------------------------
|
|
439
|
+
// getTransactions
|
|
440
|
+
// ---------------------------------------------------------------------------
|
|
441
|
+
|
|
442
|
+
describe("getTransactions", () => {
|
|
443
|
+
it("returns transactions from the API", async () => {
|
|
444
|
+
const result = await getTransactions(mockConfig);
|
|
445
|
+
expect(result).toEqual([]);
|
|
446
|
+
});
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
// ---------------------------------------------------------------------------
|
|
450
|
+
// getTaskPayment
|
|
451
|
+
// ---------------------------------------------------------------------------
|
|
452
|
+
|
|
453
|
+
describe("getTaskPayment", () => {
|
|
454
|
+
it("returns payment info when found", async () => {
|
|
455
|
+
const result = await getTaskPayment(mockConfig, "task-1");
|
|
456
|
+
expect(result).toBeDefined();
|
|
457
|
+
expect(result!.id).toBe("pay-1");
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
it("returns undefined when API throws", async () => {
|
|
461
|
+
const { AgrentingClient } = await import("./client.js");
|
|
462
|
+
const MockClient = vi.mocked(AgrentingClient);
|
|
463
|
+
MockClient.mockImplementationOnce(function() {
|
|
464
|
+
return {
|
|
465
|
+
testConnection: vi.fn(),
|
|
466
|
+
createTask: vi.fn(),
|
|
467
|
+
getTask: vi.fn(),
|
|
468
|
+
getTaskProgress: vi.fn(),
|
|
469
|
+
getTaskTimeline: vi.fn(),
|
|
470
|
+
cancelTask: vi.fn(),
|
|
471
|
+
discoverAgents: vi.fn(),
|
|
472
|
+
getBalance: vi.fn(),
|
|
473
|
+
getTransactions: vi.fn(),
|
|
474
|
+
getTaskPayment: vi.fn().mockRejectedValue(new Error("Not found")),
|
|
475
|
+
createTaskPayment: vi.fn(),
|
|
476
|
+
deleteWebhook: vi.fn(),
|
|
477
|
+
uploadDocument: vi.fn(),
|
|
478
|
+
};
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
const result = await getTaskPayment(mockConfig, "nonexistent");
|
|
482
|
+
expect(result).toBeUndefined();
|
|
483
|
+
});
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
// ---------------------------------------------------------------------------
|
|
487
|
+
// getTaskProgress
|
|
488
|
+
// ---------------------------------------------------------------------------
|
|
489
|
+
|
|
490
|
+
describe("getTaskProgress", () => {
|
|
491
|
+
it("returns progress and timeline", async () => {
|
|
492
|
+
const result = await getTaskProgress(mockConfig, "task-1");
|
|
493
|
+
expect(result.status).toBe("completed");
|
|
494
|
+
expect(result.progressPercent).toBe(100);
|
|
495
|
+
expect(result.timeline).toEqual([]);
|
|
496
|
+
});
|
|
497
|
+
});
|