@swarmdock/sdk 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/.turbo/turbo-type-check.log +4 -0
- package/dist/client.d.ts +140 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +330 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +8 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +25 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/package.json +27 -0
- package/src/client.ts +464 -0
- package/src/errors.ts +26 -0
- package/src/index.ts +31 -0
- package/tsconfig.json +8 -0
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import type { Agent, Task, TaskBid, EscrowTransaction, AgentRating, AgentSkill, SSEEvent, AgentUpdateInput, TaskCreateInput, TaskListQuery, TaskSubmitInput, BidCreateInput, RatingCreateInput } from '@swarmdock/shared';
|
|
2
|
+
export interface SwarmDockClientOptions {
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
privateKey: string;
|
|
5
|
+
}
|
|
6
|
+
export interface RegisterParams {
|
|
7
|
+
displayName: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
framework?: string;
|
|
10
|
+
frameworkVersion?: string;
|
|
11
|
+
modelProvider?: string;
|
|
12
|
+
modelName?: string;
|
|
13
|
+
walletAddress: string;
|
|
14
|
+
skills?: Array<{
|
|
15
|
+
skillId: string;
|
|
16
|
+
skillName: string;
|
|
17
|
+
description: string;
|
|
18
|
+
category: string;
|
|
19
|
+
tags?: string[];
|
|
20
|
+
pricingModel?: string;
|
|
21
|
+
basePrice: string;
|
|
22
|
+
examplePrompts?: string[];
|
|
23
|
+
}>;
|
|
24
|
+
agentCardUrl?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface RegisterResult {
|
|
27
|
+
token: string;
|
|
28
|
+
agent: {
|
|
29
|
+
id: string;
|
|
30
|
+
did: string;
|
|
31
|
+
displayName: string;
|
|
32
|
+
trustLevel: number;
|
|
33
|
+
status: string;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export interface BalanceResult {
|
|
37
|
+
agentId: string;
|
|
38
|
+
earned: string;
|
|
39
|
+
spent: string;
|
|
40
|
+
currency: string;
|
|
41
|
+
network: string;
|
|
42
|
+
}
|
|
43
|
+
export interface TransactionsResult {
|
|
44
|
+
transactions: EscrowTransaction[];
|
|
45
|
+
limit: number;
|
|
46
|
+
offset: number;
|
|
47
|
+
}
|
|
48
|
+
export interface TaskListResult {
|
|
49
|
+
tasks: Task[];
|
|
50
|
+
limit: number;
|
|
51
|
+
offset: number;
|
|
52
|
+
}
|
|
53
|
+
export interface TaskDetailResult extends Task {
|
|
54
|
+
bids: TaskBid[];
|
|
55
|
+
bidCount: number;
|
|
56
|
+
}
|
|
57
|
+
type SSECallback = (event: SSEEvent) => void;
|
|
58
|
+
export declare class SwarmDockClient {
|
|
59
|
+
private readonly baseUrl;
|
|
60
|
+
private readonly secretKey;
|
|
61
|
+
private readonly publicKeyBase64;
|
|
62
|
+
private token;
|
|
63
|
+
private agentId;
|
|
64
|
+
private sseAbortController;
|
|
65
|
+
readonly profile: ProfileOperations;
|
|
66
|
+
readonly tasks: TaskOperations;
|
|
67
|
+
readonly events: EventOperations;
|
|
68
|
+
readonly payments: PaymentOperations;
|
|
69
|
+
constructor(options: SwarmDockClientOptions);
|
|
70
|
+
register(params: RegisterParams): Promise<RegisterResult>;
|
|
71
|
+
heartbeat(): Promise<{
|
|
72
|
+
token: string;
|
|
73
|
+
}>;
|
|
74
|
+
rate(input: RatingCreateInput): Promise<AgentRating>;
|
|
75
|
+
/** @internal */
|
|
76
|
+
fetch<T>(path: string, options?: FetchOptions): Promise<T>;
|
|
77
|
+
/** @internal */
|
|
78
|
+
getAgentId(): string;
|
|
79
|
+
/** @internal */
|
|
80
|
+
getToken(): string;
|
|
81
|
+
/** @internal */
|
|
82
|
+
getBaseUrl(): string;
|
|
83
|
+
/** @internal */
|
|
84
|
+
setToken(token: string): void;
|
|
85
|
+
/** @internal */
|
|
86
|
+
getSseAbortController(): AbortController | null;
|
|
87
|
+
/** @internal */
|
|
88
|
+
setSseAbortController(controller: AbortController | null): void;
|
|
89
|
+
private requireAuth;
|
|
90
|
+
private sign;
|
|
91
|
+
}
|
|
92
|
+
interface FetchOptions {
|
|
93
|
+
method?: string;
|
|
94
|
+
body?: unknown;
|
|
95
|
+
query?: Record<string, string | number | undefined | null>;
|
|
96
|
+
auth?: boolean;
|
|
97
|
+
}
|
|
98
|
+
declare class ProfileOperations {
|
|
99
|
+
private readonly client;
|
|
100
|
+
constructor(client: SwarmDockClient);
|
|
101
|
+
get(agentId?: string): Promise<Agent & {
|
|
102
|
+
skills: AgentSkill[];
|
|
103
|
+
}>;
|
|
104
|
+
update(fields: AgentUpdateInput): Promise<Agent>;
|
|
105
|
+
match(params: {
|
|
106
|
+
description: string;
|
|
107
|
+
skills?: string[];
|
|
108
|
+
limit?: number;
|
|
109
|
+
}): Promise<{
|
|
110
|
+
matches: Agent[];
|
|
111
|
+
}>;
|
|
112
|
+
}
|
|
113
|
+
declare class TaskOperations {
|
|
114
|
+
private readonly client;
|
|
115
|
+
constructor(client: SwarmDockClient);
|
|
116
|
+
list(filters?: Partial<TaskListQuery>): Promise<TaskListResult>;
|
|
117
|
+
create(input: TaskCreateInput): Promise<Task>;
|
|
118
|
+
get(taskId: string): Promise<TaskDetailResult>;
|
|
119
|
+
bid(taskId: string, input: BidCreateInput): Promise<TaskBid>;
|
|
120
|
+
start(taskId: string): Promise<Task>;
|
|
121
|
+
submit(taskId: string, input: TaskSubmitInput): Promise<Task>;
|
|
122
|
+
approve(taskId: string): Promise<Task>;
|
|
123
|
+
reject(taskId: string, reason?: string): Promise<Task>;
|
|
124
|
+
}
|
|
125
|
+
declare class EventOperations {
|
|
126
|
+
private readonly client;
|
|
127
|
+
private callback;
|
|
128
|
+
constructor(client: SwarmDockClient);
|
|
129
|
+
subscribe(callback: SSECallback): void;
|
|
130
|
+
unsubscribe(): void;
|
|
131
|
+
private connectSSE;
|
|
132
|
+
}
|
|
133
|
+
declare class PaymentOperations {
|
|
134
|
+
private readonly client;
|
|
135
|
+
constructor(client: SwarmDockClient);
|
|
136
|
+
balance(): Promise<BalanceResult>;
|
|
137
|
+
transactions(limit?: number, offset?: number): Promise<TransactionsResult>;
|
|
138
|
+
}
|
|
139
|
+
export {};
|
|
140
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import nacl from 'tweetnacl';
|
|
2
|
+
import { encodeBase64, decodeBase64 } from 'tweetnacl-util';
|
|
3
|
+
import { SwarmDockError } from './errors.js';
|
|
4
|
+
export class SwarmDockClient {
|
|
5
|
+
baseUrl;
|
|
6
|
+
secretKey;
|
|
7
|
+
publicKeyBase64;
|
|
8
|
+
token = null;
|
|
9
|
+
agentId = null;
|
|
10
|
+
sseAbortController = null;
|
|
11
|
+
profile;
|
|
12
|
+
tasks;
|
|
13
|
+
events;
|
|
14
|
+
payments;
|
|
15
|
+
constructor(options) {
|
|
16
|
+
this.baseUrl = options.baseUrl.replace(/\/+$/, '');
|
|
17
|
+
this.secretKey = decodeBase64(options.privateKey);
|
|
18
|
+
const keyPair = nacl.sign.keyPair.fromSecretKey(this.secretKey);
|
|
19
|
+
this.publicKeyBase64 = encodeBase64(keyPair.publicKey);
|
|
20
|
+
this.profile = new ProfileOperations(this);
|
|
21
|
+
this.tasks = new TaskOperations(this);
|
|
22
|
+
this.events = new EventOperations(this);
|
|
23
|
+
this.payments = new PaymentOperations(this);
|
|
24
|
+
}
|
|
25
|
+
async register(params) {
|
|
26
|
+
const registerBody = {
|
|
27
|
+
publicKey: this.publicKeyBase64,
|
|
28
|
+
displayName: params.displayName,
|
|
29
|
+
description: params.description,
|
|
30
|
+
framework: params.framework,
|
|
31
|
+
frameworkVersion: params.frameworkVersion,
|
|
32
|
+
modelProvider: params.modelProvider,
|
|
33
|
+
modelName: params.modelName,
|
|
34
|
+
walletAddress: params.walletAddress,
|
|
35
|
+
agentCardUrl: params.agentCardUrl,
|
|
36
|
+
skills: params.skills ?? [],
|
|
37
|
+
};
|
|
38
|
+
const registerRes = await this.fetch('/api/v1/agents/register', { method: 'POST', body: registerBody, auth: false });
|
|
39
|
+
const signature = this.sign(registerRes.challenge);
|
|
40
|
+
const verifyRes = await this.fetch('/api/v1/agents/verify', {
|
|
41
|
+
method: 'POST',
|
|
42
|
+
body: {
|
|
43
|
+
publicKey: this.publicKeyBase64,
|
|
44
|
+
challenge: registerRes.challenge,
|
|
45
|
+
signature,
|
|
46
|
+
},
|
|
47
|
+
auth: false,
|
|
48
|
+
});
|
|
49
|
+
this.token = verifyRes.token;
|
|
50
|
+
this.agentId = verifyRes.agent.id;
|
|
51
|
+
return verifyRes;
|
|
52
|
+
}
|
|
53
|
+
async heartbeat() {
|
|
54
|
+
this.requireAuth();
|
|
55
|
+
const res = await this.fetch(`/api/v1/agents/${this.agentId}/heartbeat`, { method: 'POST' });
|
|
56
|
+
this.token = res.token;
|
|
57
|
+
return { token: res.token };
|
|
58
|
+
}
|
|
59
|
+
async rate(input) {
|
|
60
|
+
return this.fetch('/api/v1/ratings', {
|
|
61
|
+
method: 'POST',
|
|
62
|
+
body: input,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
// -- Internal helpers exposed to sub-operation classes --
|
|
66
|
+
/** @internal */
|
|
67
|
+
async fetch(path, options = {}) {
|
|
68
|
+
const { method = 'GET', body, query, auth = true } = options;
|
|
69
|
+
let url = `${this.baseUrl}${path}`;
|
|
70
|
+
if (query) {
|
|
71
|
+
const params = new URLSearchParams();
|
|
72
|
+
for (const [key, value] of Object.entries(query)) {
|
|
73
|
+
if (value !== undefined && value !== null) {
|
|
74
|
+
params.set(key, String(value));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const qs = params.toString();
|
|
78
|
+
if (qs)
|
|
79
|
+
url += `?${qs}`;
|
|
80
|
+
}
|
|
81
|
+
const headers = {
|
|
82
|
+
'Content-Type': 'application/json',
|
|
83
|
+
'Accept': 'application/json',
|
|
84
|
+
};
|
|
85
|
+
if (auth) {
|
|
86
|
+
this.requireAuth();
|
|
87
|
+
headers['Authorization'] = `Bearer ${this.token}`;
|
|
88
|
+
}
|
|
89
|
+
const res = await globalThis.fetch(url, {
|
|
90
|
+
method,
|
|
91
|
+
headers,
|
|
92
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
93
|
+
});
|
|
94
|
+
if (!res.ok) {
|
|
95
|
+
let errorData;
|
|
96
|
+
try {
|
|
97
|
+
errorData = await res.json();
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// Response may not be JSON
|
|
101
|
+
}
|
|
102
|
+
throw new SwarmDockError(res.status, errorData?.error ?? `Request failed: ${method} ${path}`, errorData?.details);
|
|
103
|
+
}
|
|
104
|
+
return res.json();
|
|
105
|
+
}
|
|
106
|
+
/** @internal */
|
|
107
|
+
getAgentId() {
|
|
108
|
+
this.requireAuth();
|
|
109
|
+
return this.agentId;
|
|
110
|
+
}
|
|
111
|
+
/** @internal */
|
|
112
|
+
getToken() {
|
|
113
|
+
this.requireAuth();
|
|
114
|
+
return this.token;
|
|
115
|
+
}
|
|
116
|
+
/** @internal */
|
|
117
|
+
getBaseUrl() {
|
|
118
|
+
return this.baseUrl;
|
|
119
|
+
}
|
|
120
|
+
/** @internal */
|
|
121
|
+
setToken(token) {
|
|
122
|
+
this.token = token;
|
|
123
|
+
}
|
|
124
|
+
/** @internal */
|
|
125
|
+
getSseAbortController() {
|
|
126
|
+
return this.sseAbortController;
|
|
127
|
+
}
|
|
128
|
+
/** @internal */
|
|
129
|
+
setSseAbortController(controller) {
|
|
130
|
+
this.sseAbortController = controller;
|
|
131
|
+
}
|
|
132
|
+
requireAuth() {
|
|
133
|
+
if (!this.token || !this.agentId) {
|
|
134
|
+
throw new SwarmDockError(401, 'Not authenticated. Call register() first.');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
sign(message) {
|
|
138
|
+
const messageBytes = new TextEncoder().encode(message);
|
|
139
|
+
const signature = nacl.sign.detached(messageBytes, this.secretKey);
|
|
140
|
+
return encodeBase64(signature);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// -- Sub-operation classes --
|
|
144
|
+
class ProfileOperations {
|
|
145
|
+
client;
|
|
146
|
+
constructor(client) {
|
|
147
|
+
this.client = client;
|
|
148
|
+
}
|
|
149
|
+
async get(agentId) {
|
|
150
|
+
const id = agentId ?? this.client.getAgentId();
|
|
151
|
+
return this.client.fetch(`/api/v1/agents/${id}`, { auth: false });
|
|
152
|
+
}
|
|
153
|
+
async update(fields) {
|
|
154
|
+
const id = this.client.getAgentId();
|
|
155
|
+
return this.client.fetch(`/api/v1/agents/${id}`, {
|
|
156
|
+
method: 'PATCH',
|
|
157
|
+
body: fields,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
async match(params) {
|
|
161
|
+
return this.client.fetch('/api/v1/agents/match', { method: 'POST', body: params, auth: false });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
class TaskOperations {
|
|
165
|
+
client;
|
|
166
|
+
constructor(client) {
|
|
167
|
+
this.client = client;
|
|
168
|
+
}
|
|
169
|
+
async list(filters) {
|
|
170
|
+
const query = {};
|
|
171
|
+
if (filters) {
|
|
172
|
+
if (filters.status)
|
|
173
|
+
query.status = filters.status;
|
|
174
|
+
if (filters.skills)
|
|
175
|
+
query.skills = filters.skills;
|
|
176
|
+
if (filters.budgetMin)
|
|
177
|
+
query.budgetMin = filters.budgetMin;
|
|
178
|
+
if (filters.budgetMax)
|
|
179
|
+
query.budgetMax = filters.budgetMax;
|
|
180
|
+
if (filters.requesterId)
|
|
181
|
+
query.requesterId = filters.requesterId;
|
|
182
|
+
if (filters.assigneeId)
|
|
183
|
+
query.assigneeId = filters.assigneeId;
|
|
184
|
+
if (filters.limit !== undefined)
|
|
185
|
+
query.limit = filters.limit;
|
|
186
|
+
if (filters.offset !== undefined)
|
|
187
|
+
query.offset = filters.offset;
|
|
188
|
+
}
|
|
189
|
+
return this.client.fetch('/api/v1/tasks', { query, auth: false });
|
|
190
|
+
}
|
|
191
|
+
async create(input) {
|
|
192
|
+
return this.client.fetch('/api/v1/tasks', {
|
|
193
|
+
method: 'POST',
|
|
194
|
+
body: input,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
async get(taskId) {
|
|
198
|
+
return this.client.fetch(`/api/v1/tasks/${taskId}`, { auth: false });
|
|
199
|
+
}
|
|
200
|
+
async bid(taskId, input) {
|
|
201
|
+
return this.client.fetch(`/api/v1/tasks/${taskId}/bids`, {
|
|
202
|
+
method: 'POST',
|
|
203
|
+
body: input,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
async start(taskId) {
|
|
207
|
+
return this.client.fetch(`/api/v1/tasks/${taskId}/start`, {
|
|
208
|
+
method: 'POST',
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
async submit(taskId, input) {
|
|
212
|
+
return this.client.fetch(`/api/v1/tasks/${taskId}/submit`, {
|
|
213
|
+
method: 'POST',
|
|
214
|
+
body: input,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
async approve(taskId) {
|
|
218
|
+
return this.client.fetch(`/api/v1/tasks/${taskId}/approve`, {
|
|
219
|
+
method: 'POST',
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
async reject(taskId, reason) {
|
|
223
|
+
return this.client.fetch(`/api/v1/tasks/${taskId}/reject`, {
|
|
224
|
+
method: 'POST',
|
|
225
|
+
body: reason ? { reason } : undefined,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
class EventOperations {
|
|
230
|
+
client;
|
|
231
|
+
callback = null;
|
|
232
|
+
constructor(client) {
|
|
233
|
+
this.client = client;
|
|
234
|
+
}
|
|
235
|
+
subscribe(callback) {
|
|
236
|
+
this.unsubscribe();
|
|
237
|
+
this.callback = callback;
|
|
238
|
+
const controller = new AbortController();
|
|
239
|
+
this.client.setSseAbortController(controller);
|
|
240
|
+
const url = `${this.client.getBaseUrl()}/api/v1/events`;
|
|
241
|
+
const token = this.client.getToken();
|
|
242
|
+
this.connectSSE(url, token, controller.signal);
|
|
243
|
+
}
|
|
244
|
+
unsubscribe() {
|
|
245
|
+
const controller = this.client.getSseAbortController();
|
|
246
|
+
if (controller) {
|
|
247
|
+
controller.abort();
|
|
248
|
+
this.client.setSseAbortController(null);
|
|
249
|
+
}
|
|
250
|
+
this.callback = null;
|
|
251
|
+
}
|
|
252
|
+
async connectSSE(url, token, signal) {
|
|
253
|
+
try {
|
|
254
|
+
const response = await globalThis.fetch(url, {
|
|
255
|
+
headers: {
|
|
256
|
+
'Authorization': `Bearer ${token}`,
|
|
257
|
+
'Accept': 'text/event-stream',
|
|
258
|
+
'Cache-Control': 'no-cache',
|
|
259
|
+
},
|
|
260
|
+
signal,
|
|
261
|
+
});
|
|
262
|
+
if (!response.ok) {
|
|
263
|
+
throw new SwarmDockError(response.status, 'Failed to connect to SSE stream');
|
|
264
|
+
}
|
|
265
|
+
const reader = response.body?.getReader();
|
|
266
|
+
if (!reader) {
|
|
267
|
+
throw new SwarmDockError(500, 'Response body is not readable');
|
|
268
|
+
}
|
|
269
|
+
const decoder = new TextDecoder();
|
|
270
|
+
let buffer = '';
|
|
271
|
+
while (!signal.aborted) {
|
|
272
|
+
const { done, value } = await reader.read();
|
|
273
|
+
if (done)
|
|
274
|
+
break;
|
|
275
|
+
buffer += decoder.decode(value, { stream: true });
|
|
276
|
+
const lines = buffer.split('\n');
|
|
277
|
+
buffer = lines.pop() ?? '';
|
|
278
|
+
let currentEvent = null;
|
|
279
|
+
let currentData = null;
|
|
280
|
+
for (const line of lines) {
|
|
281
|
+
if (line.startsWith('event: ')) {
|
|
282
|
+
currentEvent = line.slice(7).trim();
|
|
283
|
+
}
|
|
284
|
+
else if (line.startsWith('data: ')) {
|
|
285
|
+
currentData = line.slice(6).trim();
|
|
286
|
+
}
|
|
287
|
+
else if (line === '' && currentEvent && currentData) {
|
|
288
|
+
if (this.callback) {
|
|
289
|
+
try {
|
|
290
|
+
const parsed = JSON.parse(currentData);
|
|
291
|
+
this.callback({
|
|
292
|
+
type: currentEvent,
|
|
293
|
+
data: parsed,
|
|
294
|
+
timestamp: parsed.timestamp ?? new Date().toISOString(),
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
catch {
|
|
298
|
+
// Skip malformed events
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
currentEvent = null;
|
|
302
|
+
currentData = null;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
catch (err) {
|
|
308
|
+
if (signal.aborted)
|
|
309
|
+
return;
|
|
310
|
+
throw err;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
class PaymentOperations {
|
|
315
|
+
client;
|
|
316
|
+
constructor(client) {
|
|
317
|
+
this.client = client;
|
|
318
|
+
}
|
|
319
|
+
async balance() {
|
|
320
|
+
const id = this.client.getAgentId();
|
|
321
|
+
return this.client.fetch(`/api/v1/payments/agents/${id}/balance`);
|
|
322
|
+
}
|
|
323
|
+
async transactions(limit, offset) {
|
|
324
|
+
const id = this.client.getAgentId();
|
|
325
|
+
return this.client.fetch(`/api/v1/payments/agents/${id}/transactions`, {
|
|
326
|
+
query: { limit: limit ?? undefined, offset: offset ?? undefined },
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare class SwarmDockError extends Error {
|
|
2
|
+
readonly status: number;
|
|
3
|
+
readonly code: string;
|
|
4
|
+
readonly details?: unknown;
|
|
5
|
+
constructor(status: number, message: string, details?: unknown);
|
|
6
|
+
private static statusToCode;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;gBAEf,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO;IAQ9D,OAAO,CAAC,MAAM,CAAC,YAAY;CAY5B"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export class SwarmDockError extends Error {
|
|
2
|
+
status;
|
|
3
|
+
code;
|
|
4
|
+
details;
|
|
5
|
+
constructor(status, message, details) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = 'SwarmDockError';
|
|
8
|
+
this.status = status;
|
|
9
|
+
this.code = SwarmDockError.statusToCode(status);
|
|
10
|
+
this.details = details;
|
|
11
|
+
}
|
|
12
|
+
static statusToCode(status) {
|
|
13
|
+
switch (status) {
|
|
14
|
+
case 400: return 'BAD_REQUEST';
|
|
15
|
+
case 401: return 'UNAUTHORIZED';
|
|
16
|
+
case 403: return 'FORBIDDEN';
|
|
17
|
+
case 404: return 'NOT_FOUND';
|
|
18
|
+
case 409: return 'CONFLICT';
|
|
19
|
+
case 429: return 'RATE_LIMITED';
|
|
20
|
+
case 500: return 'INTERNAL_ERROR';
|
|
21
|
+
default: return 'UNKNOWN_ERROR';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,cAAe,SAAQ,KAAK;IAC9B,MAAM,CAAS;IACf,IAAI,CAAS;IACb,OAAO,CAAW;IAE3B,YAAY,MAAc,EAAE,OAAe,EAAE,OAAiB;QAC5D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAChD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAEO,MAAM,CAAC,YAAY,CAAC,MAAc;QACxC,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,GAAG,CAAC,CAAC,OAAO,aAAa,CAAC;YAC/B,KAAK,GAAG,CAAC,CAAC,OAAO,cAAc,CAAC;YAChC,KAAK,GAAG,CAAC,CAAC,OAAO,WAAW,CAAC;YAC7B,KAAK,GAAG,CAAC,CAAC,OAAO,WAAW,CAAC;YAC7B,KAAK,GAAG,CAAC,CAAC,OAAO,UAAU,CAAC;YAC5B,KAAK,GAAG,CAAC,CAAC,OAAO,cAAc,CAAC;YAChC,KAAK,GAAG,CAAC,CAAC,OAAO,gBAAgB,CAAC;YAClC,OAAO,CAAC,CAAC,OAAO,eAAe,CAAC;QAClC,CAAC;IACH,CAAC;CACF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { SwarmDockClient } from './client.js';
|
|
2
|
+
export type { SwarmDockClientOptions, RegisterParams, RegisterResult, BalanceResult, TransactionsResult, TaskListResult, TaskDetailResult, } from './client.js';
|
|
3
|
+
export { SwarmDockError } from './errors.js';
|
|
4
|
+
export type { Agent, AgentSkill, Task, TaskBid, EscrowTransaction, AgentRating, AATPayload, AgentCard, AgentCardSkill, SSEEvent, AgentUpdateInput, TaskCreateInput, TaskUpdateInput, TaskSubmitInput, TaskListQuery, BidCreateInput, RatingCreateInput, } from '@swarmdock/shared';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EACV,sBAAsB,EACtB,cAAc,EACd,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,YAAY,EACV,KAAK,EACL,UAAU,EACV,IAAI,EACJ,OAAO,EACP,iBAAiB,EACjB,WAAW,EACX,UAAU,EACV,SAAS,EACT,cAAc,EACd,QAAQ,EACR,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,eAAe,EACf,aAAa,EACb,cAAc,EACd,iBAAiB,GAClB,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAU9C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@swarmdock/sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"dev": "tsc --watch",
|
|
16
|
+
"type-check": "tsc --noEmit"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@swarmdock/shared": "^0.1.0",
|
|
20
|
+
"jose": "^6.0.0",
|
|
21
|
+
"tweetnacl": "^1.0.3",
|
|
22
|
+
"tweetnacl-util": "^0.15.1"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"typescript": "^5.8.0"
|
|
26
|
+
}
|
|
27
|
+
}
|
package/src/client.ts
ADDED
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
import nacl from 'tweetnacl';
|
|
2
|
+
import { encodeBase64, decodeBase64 } from 'tweetnacl-util';
|
|
3
|
+
import type {
|
|
4
|
+
Agent,
|
|
5
|
+
Task,
|
|
6
|
+
TaskBid,
|
|
7
|
+
EscrowTransaction,
|
|
8
|
+
AgentRating,
|
|
9
|
+
AgentSkill,
|
|
10
|
+
SSEEvent,
|
|
11
|
+
AgentUpdateInput,
|
|
12
|
+
TaskCreateInput,
|
|
13
|
+
TaskListQuery,
|
|
14
|
+
TaskSubmitInput,
|
|
15
|
+
BidCreateInput,
|
|
16
|
+
RatingCreateInput,
|
|
17
|
+
} from '@swarmdock/shared';
|
|
18
|
+
import { SwarmDockError } from './errors.js';
|
|
19
|
+
|
|
20
|
+
export interface SwarmDockClientOptions {
|
|
21
|
+
baseUrl: string;
|
|
22
|
+
privateKey: string; // Ed25519 secret key, base64
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface RegisterParams {
|
|
26
|
+
displayName: string;
|
|
27
|
+
description?: string;
|
|
28
|
+
framework?: string;
|
|
29
|
+
frameworkVersion?: string;
|
|
30
|
+
modelProvider?: string;
|
|
31
|
+
modelName?: string;
|
|
32
|
+
walletAddress: string;
|
|
33
|
+
skills?: Array<{
|
|
34
|
+
skillId: string;
|
|
35
|
+
skillName: string;
|
|
36
|
+
description: string;
|
|
37
|
+
category: string;
|
|
38
|
+
tags?: string[];
|
|
39
|
+
pricingModel?: string;
|
|
40
|
+
basePrice: string;
|
|
41
|
+
examplePrompts?: string[];
|
|
42
|
+
}>;
|
|
43
|
+
agentCardUrl?: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface RegisterResult {
|
|
47
|
+
token: string;
|
|
48
|
+
agent: {
|
|
49
|
+
id: string;
|
|
50
|
+
did: string;
|
|
51
|
+
displayName: string;
|
|
52
|
+
trustLevel: number;
|
|
53
|
+
status: string;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface BalanceResult {
|
|
58
|
+
agentId: string;
|
|
59
|
+
earned: string;
|
|
60
|
+
spent: string;
|
|
61
|
+
currency: string;
|
|
62
|
+
network: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface TransactionsResult {
|
|
66
|
+
transactions: EscrowTransaction[];
|
|
67
|
+
limit: number;
|
|
68
|
+
offset: number;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface TaskListResult {
|
|
72
|
+
tasks: Task[];
|
|
73
|
+
limit: number;
|
|
74
|
+
offset: number;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface TaskDetailResult extends Task {
|
|
78
|
+
bids: TaskBid[];
|
|
79
|
+
bidCount: number;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
type SSECallback = (event: SSEEvent) => void;
|
|
83
|
+
|
|
84
|
+
export class SwarmDockClient {
|
|
85
|
+
private readonly baseUrl: string;
|
|
86
|
+
private readonly secretKey: Uint8Array;
|
|
87
|
+
private readonly publicKeyBase64: string;
|
|
88
|
+
private token: string | null = null;
|
|
89
|
+
private agentId: string | null = null;
|
|
90
|
+
|
|
91
|
+
private sseAbortController: AbortController | null = null;
|
|
92
|
+
|
|
93
|
+
readonly profile: ProfileOperations;
|
|
94
|
+
readonly tasks: TaskOperations;
|
|
95
|
+
readonly events: EventOperations;
|
|
96
|
+
readonly payments: PaymentOperations;
|
|
97
|
+
|
|
98
|
+
constructor(options: SwarmDockClientOptions) {
|
|
99
|
+
this.baseUrl = options.baseUrl.replace(/\/+$/, '');
|
|
100
|
+
this.secretKey = decodeBase64(options.privateKey);
|
|
101
|
+
|
|
102
|
+
const keyPair = nacl.sign.keyPair.fromSecretKey(this.secretKey);
|
|
103
|
+
this.publicKeyBase64 = encodeBase64(keyPair.publicKey);
|
|
104
|
+
|
|
105
|
+
this.profile = new ProfileOperations(this);
|
|
106
|
+
this.tasks = new TaskOperations(this);
|
|
107
|
+
this.events = new EventOperations(this);
|
|
108
|
+
this.payments = new PaymentOperations(this);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async register(params: RegisterParams): Promise<RegisterResult> {
|
|
112
|
+
const registerBody = {
|
|
113
|
+
publicKey: this.publicKeyBase64,
|
|
114
|
+
displayName: params.displayName,
|
|
115
|
+
description: params.description,
|
|
116
|
+
framework: params.framework,
|
|
117
|
+
frameworkVersion: params.frameworkVersion,
|
|
118
|
+
modelProvider: params.modelProvider,
|
|
119
|
+
modelName: params.modelName,
|
|
120
|
+
walletAddress: params.walletAddress,
|
|
121
|
+
agentCardUrl: params.agentCardUrl,
|
|
122
|
+
skills: params.skills ?? [],
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const registerRes = await this.fetch<{ agentId: string; challenge: string; expiresAt: string }>(
|
|
126
|
+
'/api/v1/agents/register',
|
|
127
|
+
{ method: 'POST', body: registerBody, auth: false },
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
const signature = this.sign(registerRes.challenge);
|
|
131
|
+
|
|
132
|
+
const verifyRes = await this.fetch<RegisterResult>(
|
|
133
|
+
'/api/v1/agents/verify',
|
|
134
|
+
{
|
|
135
|
+
method: 'POST',
|
|
136
|
+
body: {
|
|
137
|
+
publicKey: this.publicKeyBase64,
|
|
138
|
+
challenge: registerRes.challenge,
|
|
139
|
+
signature,
|
|
140
|
+
},
|
|
141
|
+
auth: false,
|
|
142
|
+
},
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
this.token = verifyRes.token;
|
|
146
|
+
this.agentId = verifyRes.agent.id;
|
|
147
|
+
|
|
148
|
+
return verifyRes;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async heartbeat(): Promise<{ token: string }> {
|
|
152
|
+
this.requireAuth();
|
|
153
|
+
|
|
154
|
+
const res = await this.fetch<{ token: string; lastHeartbeat: string }>(
|
|
155
|
+
`/api/v1/agents/${this.agentId}/heartbeat`,
|
|
156
|
+
{ method: 'POST' },
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
this.token = res.token;
|
|
160
|
+
return { token: res.token };
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
async rate(input: RatingCreateInput): Promise<AgentRating> {
|
|
164
|
+
return this.fetch<AgentRating>('/api/v1/ratings', {
|
|
165
|
+
method: 'POST',
|
|
166
|
+
body: input,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// -- Internal helpers exposed to sub-operation classes --
|
|
171
|
+
|
|
172
|
+
/** @internal */
|
|
173
|
+
async fetch<T>(path: string, options: FetchOptions = {}): Promise<T> {
|
|
174
|
+
const { method = 'GET', body, query, auth = true } = options;
|
|
175
|
+
|
|
176
|
+
let url = `${this.baseUrl}${path}`;
|
|
177
|
+
if (query) {
|
|
178
|
+
const params = new URLSearchParams();
|
|
179
|
+
for (const [key, value] of Object.entries(query)) {
|
|
180
|
+
if (value !== undefined && value !== null) {
|
|
181
|
+
params.set(key, String(value));
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
const qs = params.toString();
|
|
185
|
+
if (qs) url += `?${qs}`;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const headers: Record<string, string> = {
|
|
189
|
+
'Content-Type': 'application/json',
|
|
190
|
+
'Accept': 'application/json',
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
if (auth) {
|
|
194
|
+
this.requireAuth();
|
|
195
|
+
headers['Authorization'] = `Bearer ${this.token}`;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const res = await globalThis.fetch(url, {
|
|
199
|
+
method,
|
|
200
|
+
headers,
|
|
201
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
if (!res.ok) {
|
|
205
|
+
let errorData: { error?: string; details?: unknown } | undefined;
|
|
206
|
+
try {
|
|
207
|
+
errorData = await res.json() as { error?: string; details?: unknown };
|
|
208
|
+
} catch {
|
|
209
|
+
// Response may not be JSON
|
|
210
|
+
}
|
|
211
|
+
throw new SwarmDockError(
|
|
212
|
+
res.status,
|
|
213
|
+
errorData?.error ?? `Request failed: ${method} ${path}`,
|
|
214
|
+
errorData?.details,
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return res.json() as Promise<T>;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/** @internal */
|
|
222
|
+
getAgentId(): string {
|
|
223
|
+
this.requireAuth();
|
|
224
|
+
return this.agentId!;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** @internal */
|
|
228
|
+
getToken(): string {
|
|
229
|
+
this.requireAuth();
|
|
230
|
+
return this.token!;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/** @internal */
|
|
234
|
+
getBaseUrl(): string {
|
|
235
|
+
return this.baseUrl;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/** @internal */
|
|
239
|
+
setToken(token: string): void {
|
|
240
|
+
this.token = token;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/** @internal */
|
|
244
|
+
getSseAbortController(): AbortController | null {
|
|
245
|
+
return this.sseAbortController;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/** @internal */
|
|
249
|
+
setSseAbortController(controller: AbortController | null): void {
|
|
250
|
+
this.sseAbortController = controller;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
private requireAuth(): void {
|
|
254
|
+
if (!this.token || !this.agentId) {
|
|
255
|
+
throw new SwarmDockError(401, 'Not authenticated. Call register() first.');
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
private sign(message: string): string {
|
|
260
|
+
const messageBytes = new TextEncoder().encode(message);
|
|
261
|
+
const signature = nacl.sign.detached(messageBytes, this.secretKey);
|
|
262
|
+
return encodeBase64(signature);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
interface FetchOptions {
|
|
267
|
+
method?: string;
|
|
268
|
+
body?: unknown;
|
|
269
|
+
query?: Record<string, string | number | undefined | null>;
|
|
270
|
+
auth?: boolean;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// -- Sub-operation classes --
|
|
274
|
+
|
|
275
|
+
class ProfileOperations {
|
|
276
|
+
constructor(private readonly client: SwarmDockClient) {}
|
|
277
|
+
|
|
278
|
+
async get(agentId?: string): Promise<Agent & { skills: AgentSkill[] }> {
|
|
279
|
+
const id = agentId ?? this.client.getAgentId();
|
|
280
|
+
return this.client.fetch(`/api/v1/agents/${id}`, { auth: false });
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
async update(fields: AgentUpdateInput): Promise<Agent> {
|
|
284
|
+
const id = this.client.getAgentId();
|
|
285
|
+
return this.client.fetch(`/api/v1/agents/${id}`, {
|
|
286
|
+
method: 'PATCH',
|
|
287
|
+
body: fields,
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
async match(params: { description: string; skills?: string[]; limit?: number }): Promise<{ matches: Agent[] }> {
|
|
292
|
+
return this.client.fetch('/api/v1/agents/match', { method: 'POST', body: params, auth: false });
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
class TaskOperations {
|
|
297
|
+
constructor(private readonly client: SwarmDockClient) {}
|
|
298
|
+
|
|
299
|
+
async list(filters?: Partial<TaskListQuery>): Promise<TaskListResult> {
|
|
300
|
+
const query: Record<string, string | number | undefined | null> = {};
|
|
301
|
+
if (filters) {
|
|
302
|
+
if (filters.status) query.status = filters.status;
|
|
303
|
+
if (filters.skills) query.skills = filters.skills;
|
|
304
|
+
if (filters.budgetMin) query.budgetMin = filters.budgetMin;
|
|
305
|
+
if (filters.budgetMax) query.budgetMax = filters.budgetMax;
|
|
306
|
+
if (filters.requesterId) query.requesterId = filters.requesterId;
|
|
307
|
+
if (filters.assigneeId) query.assigneeId = filters.assigneeId;
|
|
308
|
+
if (filters.limit !== undefined) query.limit = filters.limit;
|
|
309
|
+
if (filters.offset !== undefined) query.offset = filters.offset;
|
|
310
|
+
}
|
|
311
|
+
return this.client.fetch('/api/v1/tasks', { query, auth: false });
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
async create(input: TaskCreateInput): Promise<Task> {
|
|
315
|
+
return this.client.fetch('/api/v1/tasks', {
|
|
316
|
+
method: 'POST',
|
|
317
|
+
body: input,
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
async get(taskId: string): Promise<TaskDetailResult> {
|
|
322
|
+
return this.client.fetch(`/api/v1/tasks/${taskId}`, { auth: false });
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
async bid(taskId: string, input: BidCreateInput): Promise<TaskBid> {
|
|
326
|
+
return this.client.fetch(`/api/v1/tasks/${taskId}/bids`, {
|
|
327
|
+
method: 'POST',
|
|
328
|
+
body: input,
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
async start(taskId: string): Promise<Task> {
|
|
333
|
+
return this.client.fetch(`/api/v1/tasks/${taskId}/start`, {
|
|
334
|
+
method: 'POST',
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
async submit(taskId: string, input: TaskSubmitInput): Promise<Task> {
|
|
339
|
+
return this.client.fetch(`/api/v1/tasks/${taskId}/submit`, {
|
|
340
|
+
method: 'POST',
|
|
341
|
+
body: input,
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
async approve(taskId: string): Promise<Task> {
|
|
346
|
+
return this.client.fetch(`/api/v1/tasks/${taskId}/approve`, {
|
|
347
|
+
method: 'POST',
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
async reject(taskId: string, reason?: string): Promise<Task> {
|
|
352
|
+
return this.client.fetch(`/api/v1/tasks/${taskId}/reject`, {
|
|
353
|
+
method: 'POST',
|
|
354
|
+
body: reason ? { reason } : undefined,
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
class EventOperations {
|
|
360
|
+
private callback: SSECallback | null = null;
|
|
361
|
+
|
|
362
|
+
constructor(private readonly client: SwarmDockClient) {}
|
|
363
|
+
|
|
364
|
+
subscribe(callback: SSECallback): void {
|
|
365
|
+
this.unsubscribe();
|
|
366
|
+
this.callback = callback;
|
|
367
|
+
|
|
368
|
+
const controller = new AbortController();
|
|
369
|
+
this.client.setSseAbortController(controller);
|
|
370
|
+
|
|
371
|
+
const url = `${this.client.getBaseUrl()}/api/v1/events`;
|
|
372
|
+
const token = this.client.getToken();
|
|
373
|
+
|
|
374
|
+
this.connectSSE(url, token, controller.signal);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
unsubscribe(): void {
|
|
378
|
+
const controller = this.client.getSseAbortController();
|
|
379
|
+
if (controller) {
|
|
380
|
+
controller.abort();
|
|
381
|
+
this.client.setSseAbortController(null);
|
|
382
|
+
}
|
|
383
|
+
this.callback = null;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
private async connectSSE(url: string, token: string, signal: AbortSignal): Promise<void> {
|
|
387
|
+
try {
|
|
388
|
+
const response = await globalThis.fetch(url, {
|
|
389
|
+
headers: {
|
|
390
|
+
'Authorization': `Bearer ${token}`,
|
|
391
|
+
'Accept': 'text/event-stream',
|
|
392
|
+
'Cache-Control': 'no-cache',
|
|
393
|
+
},
|
|
394
|
+
signal,
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
if (!response.ok) {
|
|
398
|
+
throw new SwarmDockError(response.status, 'Failed to connect to SSE stream');
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
const reader = response.body?.getReader();
|
|
402
|
+
if (!reader) {
|
|
403
|
+
throw new SwarmDockError(500, 'Response body is not readable');
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
const decoder = new TextDecoder();
|
|
407
|
+
let buffer = '';
|
|
408
|
+
|
|
409
|
+
while (!signal.aborted) {
|
|
410
|
+
const { done, value } = await reader.read();
|
|
411
|
+
if (done) break;
|
|
412
|
+
|
|
413
|
+
buffer += decoder.decode(value, { stream: true });
|
|
414
|
+
const lines = buffer.split('\n');
|
|
415
|
+
buffer = lines.pop() ?? '';
|
|
416
|
+
|
|
417
|
+
let currentEvent: string | null = null;
|
|
418
|
+
let currentData: string | null = null;
|
|
419
|
+
|
|
420
|
+
for (const line of lines) {
|
|
421
|
+
if (line.startsWith('event: ')) {
|
|
422
|
+
currentEvent = line.slice(7).trim();
|
|
423
|
+
} else if (line.startsWith('data: ')) {
|
|
424
|
+
currentData = line.slice(6).trim();
|
|
425
|
+
} else if (line === '' && currentEvent && currentData) {
|
|
426
|
+
if (this.callback) {
|
|
427
|
+
try {
|
|
428
|
+
const parsed = JSON.parse(currentData);
|
|
429
|
+
this.callback({
|
|
430
|
+
type: currentEvent,
|
|
431
|
+
data: parsed,
|
|
432
|
+
timestamp: (parsed as Record<string, unknown>).timestamp as string ?? new Date().toISOString(),
|
|
433
|
+
});
|
|
434
|
+
} catch {
|
|
435
|
+
// Skip malformed events
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
currentEvent = null;
|
|
439
|
+
currentData = null;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
} catch (err) {
|
|
444
|
+
if (signal.aborted) return;
|
|
445
|
+
throw err;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
class PaymentOperations {
|
|
451
|
+
constructor(private readonly client: SwarmDockClient) {}
|
|
452
|
+
|
|
453
|
+
async balance(): Promise<BalanceResult> {
|
|
454
|
+
const id = this.client.getAgentId();
|
|
455
|
+
return this.client.fetch(`/api/v1/payments/agents/${id}/balance`);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
async transactions(limit?: number, offset?: number): Promise<TransactionsResult> {
|
|
459
|
+
const id = this.client.getAgentId();
|
|
460
|
+
return this.client.fetch(`/api/v1/payments/agents/${id}/transactions`, {
|
|
461
|
+
query: { limit: limit ?? undefined, offset: offset ?? undefined },
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
}
|
package/src/errors.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export class SwarmDockError extends Error {
|
|
2
|
+
readonly status: number;
|
|
3
|
+
readonly code: string;
|
|
4
|
+
readonly details?: unknown;
|
|
5
|
+
|
|
6
|
+
constructor(status: number, message: string, details?: unknown) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = 'SwarmDockError';
|
|
9
|
+
this.status = status;
|
|
10
|
+
this.code = SwarmDockError.statusToCode(status);
|
|
11
|
+
this.details = details;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
private static statusToCode(status: number): string {
|
|
15
|
+
switch (status) {
|
|
16
|
+
case 400: return 'BAD_REQUEST';
|
|
17
|
+
case 401: return 'UNAUTHORIZED';
|
|
18
|
+
case 403: return 'FORBIDDEN';
|
|
19
|
+
case 404: return 'NOT_FOUND';
|
|
20
|
+
case 409: return 'CONFLICT';
|
|
21
|
+
case 429: return 'RATE_LIMITED';
|
|
22
|
+
case 500: return 'INTERNAL_ERROR';
|
|
23
|
+
default: return 'UNKNOWN_ERROR';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export { SwarmDockClient } from './client.js';
|
|
2
|
+
export type {
|
|
3
|
+
SwarmDockClientOptions,
|
|
4
|
+
RegisterParams,
|
|
5
|
+
RegisterResult,
|
|
6
|
+
BalanceResult,
|
|
7
|
+
TransactionsResult,
|
|
8
|
+
TaskListResult,
|
|
9
|
+
TaskDetailResult,
|
|
10
|
+
} from './client.js';
|
|
11
|
+
export { SwarmDockError } from './errors.js';
|
|
12
|
+
|
|
13
|
+
export type {
|
|
14
|
+
Agent,
|
|
15
|
+
AgentSkill,
|
|
16
|
+
Task,
|
|
17
|
+
TaskBid,
|
|
18
|
+
EscrowTransaction,
|
|
19
|
+
AgentRating,
|
|
20
|
+
AATPayload,
|
|
21
|
+
AgentCard,
|
|
22
|
+
AgentCardSkill,
|
|
23
|
+
SSEEvent,
|
|
24
|
+
AgentUpdateInput,
|
|
25
|
+
TaskCreateInput,
|
|
26
|
+
TaskUpdateInput,
|
|
27
|
+
TaskSubmitInput,
|
|
28
|
+
TaskListQuery,
|
|
29
|
+
BidCreateInput,
|
|
30
|
+
RatingCreateInput,
|
|
31
|
+
} from '@swarmdock/shared';
|