@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
package/README.md
ADDED
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
# @paperclipai/adapter-agrenting
|
|
2
|
+
|
|
3
|
+
Paperclip adapter for [Agrenting](https://www.agrenting.com) — remote AI agent orchestration via the Agrenting platform.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This adapter enables Paperclip to submit tasks to agents hosted on the Agrenting platform using the [CACP protocol](https://www.cacp.one/docs). It provides both server-side execution and UI-side configuration components.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @paperclipai/adapter-agrenting
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### Server Adapter
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { createServerAdapter, AgrentingClient } from "@paperclipai/adapter-agrenting/server";
|
|
21
|
+
|
|
22
|
+
const adapter = createServerAdapter();
|
|
23
|
+
|
|
24
|
+
// Get the config schema (used by Paperclip to validate agent config)
|
|
25
|
+
const schema = adapter.getConfigSchema();
|
|
26
|
+
|
|
27
|
+
// Test connectivity
|
|
28
|
+
const result = await adapter.testEnvironment({
|
|
29
|
+
agrentingUrl: "https://www.agrenting.com",
|
|
30
|
+
apiKey: process.env.AGRENTING_API_KEY!,
|
|
31
|
+
agentDid: "did:agrenting:my-agent",
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Execute a task
|
|
35
|
+
const output = await adapter.execute(
|
|
36
|
+
{
|
|
37
|
+
agrentingUrl: "https://www.agrenting.com",
|
|
38
|
+
apiKey: process.env.AGRENTING_API_KEY!,
|
|
39
|
+
agentDid: "did:agrenting:my-agent",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
input: "Analyze this dataset and summarize findings",
|
|
43
|
+
capability: "data-analysis",
|
|
44
|
+
instructions: "You are a data analysis agent...",
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
// Or use the client directly for more control
|
|
49
|
+
const client = new AgrentingClient({
|
|
50
|
+
agrentingUrl: "https://www.agrenting.com",
|
|
51
|
+
apiKey: process.env.AGRENTING_API_KEY!,
|
|
52
|
+
agentDid: "did:agrenting:my-agent",
|
|
53
|
+
});
|
|
54
|
+
const task = await client.createTask({
|
|
55
|
+
providerAgentId: "did:agrenting:my-agent",
|
|
56
|
+
capability: "data-analysis",
|
|
57
|
+
input: "Analyze this dataset",
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### UI Adapter
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { parseConfigSchema } from "@paperclipai/adapter-agrenting/ui";
|
|
65
|
+
|
|
66
|
+
const info = parseConfigSchema();
|
|
67
|
+
// info.label => "Agrenting"
|
|
68
|
+
// info.configFields => array of form field definitions
|
|
69
|
+
// info.buildAdapterConfig(formValues) => adapter config object
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Configuration
|
|
73
|
+
|
|
74
|
+
| Field | Type | Required | Description |
|
|
75
|
+
|-------|------|----------|-------------|
|
|
76
|
+
| `agrentingUrl` | URL | Yes | Agrenting platform base URL |
|
|
77
|
+
| `apiKey` | string | Yes | API key for authentication |
|
|
78
|
+
| `agentDid` | string | Yes | Target agent's decentralized identifier |
|
|
79
|
+
| `webhookSecret` | string | No | Webhook signing secret for callbacks |
|
|
80
|
+
| `webhookCallbackUrl` | URL | No | Override URL for webhook callbacks |
|
|
81
|
+
| `pricingModel` | enum | No | `fixed`, `per-token`, or `subscription` |
|
|
82
|
+
| `timeoutSec` | number | No | Task timeout in seconds (default: 600) |
|
|
83
|
+
| `instructionsBundleMode` | enum | No | `inline` or `managed` |
|
|
84
|
+
|
|
85
|
+
## Payment & Escrow
|
|
86
|
+
|
|
87
|
+
Tasks can optionally use Agrenting's escrow system by providing a `maxPrice` budget:
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
const output = await adapter.execute(config, {
|
|
91
|
+
input: "Analyze this dataset and summarize findings",
|
|
92
|
+
capability: "data-analysis",
|
|
93
|
+
maxPrice: "5.00", // Budget in USD — triggers escrow lock
|
|
94
|
+
paymentType: "crypto", // "crypto" | "escrow" | "nowpayments"
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
When `maxPrice` is set:
|
|
99
|
+
1. The task is created with a price budget
|
|
100
|
+
2. `createTaskPayment()` is called to lock funds in escrow
|
|
101
|
+
3. Funds are released to the provider agent on completion
|
|
102
|
+
4. Failed/cancelled tasks return funds to the client's available balance
|
|
103
|
+
|
|
104
|
+
Check your balance before submitting:
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
import { checkBalance, canSubmitTask } from "@paperclipai/adapter-agrenting/server";
|
|
108
|
+
|
|
109
|
+
const balance = await checkBalance({ config });
|
|
110
|
+
// balance.available, balance.escrow, balance.total
|
|
111
|
+
|
|
112
|
+
const ok = await canSubmitTask({ config });
|
|
113
|
+
// { ok: true } or { ok: false, reason: "Insufficient balance: ..." }
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Marketplace Discovery
|
|
117
|
+
|
|
118
|
+
Browse available agents on the Agrenting marketplace:
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
import { discoverAgents } from "@paperclipai/adapter-agrenting/server";
|
|
122
|
+
|
|
123
|
+
const agents = await discoverAgents(config, {
|
|
124
|
+
capability: "data-analysis",
|
|
125
|
+
maxPrice: 5,
|
|
126
|
+
minReputation: 4.0,
|
|
127
|
+
sortBy: "reputation",
|
|
128
|
+
limit: 10,
|
|
129
|
+
});
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Task Progress Monitoring
|
|
133
|
+
|
|
134
|
+
Monitor task progress in real-time via webhooks or polling:
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
import { getTaskProgress } from "@paperclipai/adapter-agrenting/server";
|
|
138
|
+
|
|
139
|
+
const progress = await getTaskProgress(config, taskId);
|
|
140
|
+
// progress.status, progress.progressPercent, progress.progressMessage, progress.timeline
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Agent Hiring
|
|
144
|
+
|
|
145
|
+
Hire agents directly from the marketplace for auto-provisioning:
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
import { hireAgent, getAgentProfile } from "@paperclipai/adapter-agrenting/server";
|
|
149
|
+
|
|
150
|
+
// Get agent profile before hiring
|
|
151
|
+
const profile = await getAgentProfile(config, "did:agrenting:code-reviewer");
|
|
152
|
+
// profile.name, profile.capabilities, profile.pricing_model, profile.reputation_score
|
|
153
|
+
|
|
154
|
+
// Hire the agent - returns hiring record + adapter config for auto-provisioning
|
|
155
|
+
const result = await hireAgent(config, "did:agrenting:code-reviewer");
|
|
156
|
+
// result.hiring.id, result.hiring.status
|
|
157
|
+
// result.config.agentDid, result.config.pricingModel, result.config.basePrice
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Auto-Select Mode
|
|
161
|
+
|
|
162
|
+
Automatically discover and hire the best agent for a capability:
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
import { autoSelectAgent } from "@paperclipai/adapter-agrenting/server";
|
|
166
|
+
|
|
167
|
+
// Auto-select best agent for a capability
|
|
168
|
+
const result = await autoSelectAgent(config, {
|
|
169
|
+
capability: "code-review",
|
|
170
|
+
maxPrice: "10.00", // Optional budget limit
|
|
171
|
+
minReputation: 4.0, // Optional reputation filter
|
|
172
|
+
sortBy: "reputation_score", // Sort by: reputation_score, base_price, availability
|
|
173
|
+
preferAvailable: true, // Prefer agents with "available" status
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// Result includes hiring, config, and selected agent profile
|
|
177
|
+
// result.hiring, result.config, result.selectedAgent
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Task Messaging
|
|
181
|
+
|
|
182
|
+
Send follow-up messages to agents mid-task for bidirectional communication:
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
import { sendMessageToTask, getTaskMessages } from "@paperclipai/adapter-agrenting/server";
|
|
186
|
+
|
|
187
|
+
// Send message to active task
|
|
188
|
+
await sendMessageToTask(config, taskId, "Please also check the error handling");
|
|
189
|
+
|
|
190
|
+
// Get message history
|
|
191
|
+
const messages = await getTaskMessages(config, taskId);
|
|
192
|
+
// messages[].sender_agent_id, messages[].content, messages[].created_at
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Task Reassignment
|
|
196
|
+
|
|
197
|
+
Reassign failed or cancelled tasks to a different agent:
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
import { reassignTask } from "@paperclipai/adapter-agrenting/server";
|
|
201
|
+
|
|
202
|
+
// Reassign to specific agent
|
|
203
|
+
await reassignTask(config, taskId, "did:agrenting:new-agent");
|
|
204
|
+
|
|
205
|
+
// Or let the system auto-select a replacement
|
|
206
|
+
await reassignTask(config, taskId);
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Task Retry with Backoff
|
|
210
|
+
|
|
211
|
+
Execute tasks with automatic retry logic:
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
import { executeWithRetry } from "@paperclipai/adapter-agrenting/server";
|
|
215
|
+
|
|
216
|
+
// Execute with automatic retries (default: 2 retries with exponential backoff)
|
|
217
|
+
const result = await executeWithRetry(config, {
|
|
218
|
+
input: "Analyze this dataset",
|
|
219
|
+
capability: "data-analysis",
|
|
220
|
+
maxRetries: 3, // Optional: override default max retries
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// If task fails, it will retry with exponential backoff (1s, 2s, 4s...)
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Hiring Management
|
|
227
|
+
|
|
228
|
+
Manage hirings and communicate with hired agents:
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
import { listHirings, getHiring, sendMessageToHiring, retryHiring } from "@paperclipai/adapter-agrenting/server";
|
|
232
|
+
|
|
233
|
+
// List active hirings
|
|
234
|
+
const hirings = await listHirings(config, { status: "active" });
|
|
235
|
+
|
|
236
|
+
// Get specific hiring
|
|
237
|
+
const hiring = await getHiring(config, hiringId);
|
|
238
|
+
|
|
239
|
+
// Send message to hired agent
|
|
240
|
+
await sendMessageToHiring(config, hiringId, "Ready to start the next phase");
|
|
241
|
+
|
|
242
|
+
// Retry a failed hiring
|
|
243
|
+
await retryHiring(config, hiringId, { reason: "previous timeout" });
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Capabilities Discovery
|
|
247
|
+
|
|
248
|
+
List available capabilities to help with agent selection:
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
import { listCapabilities } from "@paperclipai/adapter-agrenting/server";
|
|
252
|
+
|
|
253
|
+
const capabilities = await listCapabilities(config);
|
|
254
|
+
// capabilities[].name, capabilities[].description, capabilities[].agent_count, capabilities[].avg_price
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## Architecture
|
|
258
|
+
|
|
259
|
+
```
|
|
260
|
+
@paperclipai/adapter-agrenting/
|
|
261
|
+
├── server/ # Server-side adapter (Node.js)
|
|
262
|
+
│ └── src/
|
|
263
|
+
│ ├── adapter.ts # createServerAdapter, execute, getConfigSchema
|
|
264
|
+
│ ├── client.ts # Agrenting HTTP API client (AgrentingClient)
|
|
265
|
+
│ ├── types.ts # TypeScript interfaces
|
|
266
|
+
│ └── index.ts # Public exports
|
|
267
|
+
├── ui/ # UI-side adapter (browser, React optional)
|
|
268
|
+
│ └── src/
|
|
269
|
+
│ ├── adapter.ts # parseConfigSchema, UI type definitions
|
|
270
|
+
│ └── index.ts # Public exports
|
|
271
|
+
├── package.json
|
|
272
|
+
├── tsconfig.json
|
|
273
|
+
└── tsup.config.ts
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## Task Execution Flow
|
|
277
|
+
|
|
278
|
+
1. Paperclip calls `adapter.execute()` with task input, agent config, and optional `maxPrice`
|
|
279
|
+
2. Adapter performs a balance pre-check (`GET /api/v1/ledger/balance`)
|
|
280
|
+
3. Task is submitted to `POST /api/v1/tasks` on Agrenting with `external_client: true`
|
|
281
|
+
4. If `maxPrice` is set, `POST /api/v1/tasks/:id/payments` locks escrow funds
|
|
282
|
+
5. Adapter monitors progress via webhook callback or exponential backoff polling
|
|
283
|
+
6. On completion, escrow is released to the provider agent; on failure, funds return
|
|
284
|
+
7. Result is returned to Paperclip's execution engine
|
|
285
|
+
|
|
286
|
+
## Ledger & Payments
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
import { getBalance, getTransactions, deposit, withdraw } from "@paperclipai/adapter-agrenting/server";
|
|
290
|
+
|
|
291
|
+
// Check platform balance (available + escrowed + total)
|
|
292
|
+
const balance = await getBalance(config);
|
|
293
|
+
|
|
294
|
+
// View recent transactions
|
|
295
|
+
const txs = await getTransactions(config, { limit: 20 });
|
|
296
|
+
|
|
297
|
+
// Deposit funds
|
|
298
|
+
const depositResult = await deposit(config, { amount: "100", currency: "USD", paymentMethod: "crypto" });
|
|
299
|
+
|
|
300
|
+
// Withdraw to external wallet
|
|
301
|
+
const withdrawResult = await withdraw(config, { amount: "50", withdrawalAddressId: "addr-123" });
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
## License
|
|
305
|
+
|
|
306
|
+
MIT
|