@ziggs-ai/api-client 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -7
- package/dist/ConnectionManager.d.ts +46 -0
- package/dist/ConnectionManager.js +132 -0
- package/dist/http/AgentSearchClient.d.ts +36 -0
- package/dist/http/AgentSearchClient.js +72 -0
- package/dist/http/AgreementClient.d.ts +153 -0
- package/dist/http/AgreementClient.js +477 -0
- package/dist/http/ArtifactsClient.d.ts +48 -0
- package/dist/http/ArtifactsClient.js +90 -0
- package/dist/http/ChatClient.d.ts +34 -0
- package/dist/http/ChatClient.js +104 -0
- package/dist/http/ContextDiscoveryClient.d.ts +23 -0
- package/dist/http/ContextDiscoveryClient.js +35 -0
- package/dist/http/ContextReadClient.d.ts +33 -0
- package/dist/http/ContextReadClient.js +54 -0
- package/dist/http/MarketplaceClient.d.ts +19 -0
- package/dist/http/MarketplaceClient.js +72 -0
- package/dist/http/MessagesClient.d.ts +26 -0
- package/dist/http/MessagesClient.js +49 -0
- package/dist/http/ScopeClient.d.ts +33 -0
- package/dist/http/ScopeClient.js +39 -0
- package/dist/http/TaskClient.d.ts +75 -0
- package/dist/http/TaskClient.js +352 -0
- package/dist/http/TelemetryClient.d.ts +11 -0
- package/dist/http/TelemetryClient.js +53 -0
- package/dist/http/index.d.ts +16 -0
- package/dist/http/index.js +11 -0
- package/dist/index.d.ts +9 -0
- package/{src → dist}/index.js +2 -12
- package/dist/shared/runtimeLog.d.ts +14 -0
- package/dist/shared/runtimeLog.js +64 -0
- package/dist/types.d.ts +130 -0
- package/dist/types.js +50 -0
- package/dist/utils/urlUtils.d.ts +2 -0
- package/dist/utils/urlUtils.js +8 -0
- package/dist/websocket/ControlSocket.d.ts +13 -0
- package/dist/websocket/ControlSocket.js +37 -0
- package/dist/websocket/WebSocketClient.d.ts +71 -0
- package/dist/websocket/WebSocketClient.js +233 -0
- package/dist/websocket/index.js +1 -0
- package/package.json +20 -7
- package/src/ConnectionManager.ts +172 -0
- package/src/http/AgentSearchClient.ts +115 -0
- package/src/http/AgreementClient.ts +721 -0
- package/src/http/ArtifactsClient.ts +133 -0
- package/src/http/ChatClient.ts +147 -0
- package/src/http/ContextDiscoveryClient.ts +52 -0
- package/src/http/ContextReadClient.ts +83 -0
- package/src/http/MarketplaceClient.ts +94 -0
- package/src/http/MessagesClient.ts +71 -0
- package/src/http/ScopeClient.ts +64 -0
- package/src/http/TaskClient.ts +450 -0
- package/src/http/{TelemetryClient.js → TelemetryClient.ts} +21 -7
- package/src/http/index.ts +26 -0
- package/src/index.ts +27 -0
- package/src/shared/runtimeLog.ts +68 -0
- package/src/types.ts +158 -0
- package/src/utils/urlUtils.ts +9 -0
- package/src/websocket/ControlSocket.ts +51 -0
- package/src/websocket/WebSocketClient.ts +315 -0
- package/src/websocket/index.ts +1 -0
- package/src/ConnectionManager.js +0 -179
- package/src/http/AgentSearchClient.js +0 -113
- package/src/http/ContextReader.js +0 -99
- package/src/http/ContextWriter.js +0 -98
- package/src/http/TaskClient.js +0 -612
- package/src/http/index.js +0 -6
- package/src/types.js +0 -28
- package/src/utils/urlUtils.js +0 -17
- package/src/websocket/ControlSocket.js +0 -55
- package/src/websocket/WebSocketClient.js +0 -318
- /package/{src/websocket/index.js → dist/websocket/index.d.ts} +0 -0
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
import { getBackendUrl } from '../utils/urlUtils.js';
|
|
3
|
+
import { ApiError } from '../types.js';
|
|
4
|
+
function getTaskBaseUrl() { return `${getBackendUrl()}/tasks`; }
|
|
5
|
+
function getMarketplaceBaseUrl() { return `${getBackendUrl()}/marketplace`; }
|
|
6
|
+
function buildHeaders(creds) {
|
|
7
|
+
return {
|
|
8
|
+
'content-type': 'application/json',
|
|
9
|
+
Authorization: `Bearer ${creds.operatorKey}`,
|
|
10
|
+
'X-Agent-Id': creds.agentId,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function assertCreds(creds, op) {
|
|
14
|
+
if (!creds?.operatorKey)
|
|
15
|
+
throw new Error(`operatorKey is required for ${op}`);
|
|
16
|
+
if (!creds?.agentId)
|
|
17
|
+
throw new Error(`agentId is required for ${op}`);
|
|
18
|
+
}
|
|
19
|
+
function parseErrorMessage(responseBody, defaultMessage) {
|
|
20
|
+
if (!responseBody)
|
|
21
|
+
return defaultMessage;
|
|
22
|
+
try {
|
|
23
|
+
const d = JSON.parse(responseBody);
|
|
24
|
+
return d['details'] || d['error'] || d['message'] || defaultMessage;
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return responseBody || defaultMessage;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function throwApiError(response, responseBody, defaultMessage) {
|
|
31
|
+
throw new ApiError(parseErrorMessage(responseBody, defaultMessage), response.status, responseBody);
|
|
32
|
+
}
|
|
33
|
+
function extractTask(data) {
|
|
34
|
+
if (!data || typeof data !== 'object')
|
|
35
|
+
return null;
|
|
36
|
+
const d = data;
|
|
37
|
+
if (d['task'] && typeof d['task'] === 'object' && d['task']['taskId']) {
|
|
38
|
+
return d['task'];
|
|
39
|
+
}
|
|
40
|
+
if (d['taskId'])
|
|
41
|
+
return d;
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
export async function createTask(taskData, creds) {
|
|
45
|
+
if (!taskData)
|
|
46
|
+
throw new Error('Task data is required for task creation');
|
|
47
|
+
assertCreds(creds, 'task creation');
|
|
48
|
+
const { idempotencyKey, ...bodyData } = taskData;
|
|
49
|
+
const headers = buildHeaders(creds);
|
|
50
|
+
if (idempotencyKey)
|
|
51
|
+
headers['Idempotency-Key'] = idempotencyKey;
|
|
52
|
+
const res = await fetch(getTaskBaseUrl(), {
|
|
53
|
+
method: 'POST',
|
|
54
|
+
headers,
|
|
55
|
+
body: JSON.stringify(bodyData),
|
|
56
|
+
});
|
|
57
|
+
if (!res.ok) {
|
|
58
|
+
const body = await res.text().catch(() => '');
|
|
59
|
+
throwApiError(res, body, `Task creation failed: ${res.status} ${res.statusText}`);
|
|
60
|
+
}
|
|
61
|
+
const data = await res.json().catch(() => null);
|
|
62
|
+
const task = extractTask(data);
|
|
63
|
+
if (!task)
|
|
64
|
+
throw new Error('Invalid response: task data not found');
|
|
65
|
+
return task;
|
|
66
|
+
}
|
|
67
|
+
export async function getTask(taskId, creds) {
|
|
68
|
+
if (!taskId)
|
|
69
|
+
throw new Error('getTask: taskId is required');
|
|
70
|
+
assertCreds(creds, 'task retrieval');
|
|
71
|
+
const res = await fetch(`${getTaskBaseUrl()}/${taskId}`, {
|
|
72
|
+
method: 'GET',
|
|
73
|
+
headers: buildHeaders(creds),
|
|
74
|
+
});
|
|
75
|
+
if (!res.ok) {
|
|
76
|
+
const body = await res.text().catch(() => '');
|
|
77
|
+
throwApiError(res, body, `Task get failed: ${res.status} ${res.statusText}`);
|
|
78
|
+
}
|
|
79
|
+
const data = await res.json().catch(() => null);
|
|
80
|
+
const task = extractTask(data);
|
|
81
|
+
if (!task)
|
|
82
|
+
throw new Error('Invalid response: task data not found');
|
|
83
|
+
return task;
|
|
84
|
+
}
|
|
85
|
+
export async function updateTaskState(taskId, state, data = {}, creds) {
|
|
86
|
+
if (!taskId)
|
|
87
|
+
throw new Error('updateTaskState: taskId is required');
|
|
88
|
+
if (!state)
|
|
89
|
+
throw new Error('updateTaskState: state is required');
|
|
90
|
+
assertCreds(creds, 'task state update');
|
|
91
|
+
const res = await fetch(`${getTaskBaseUrl()}/${taskId}/state`, {
|
|
92
|
+
method: 'PATCH',
|
|
93
|
+
headers: buildHeaders(creds),
|
|
94
|
+
body: JSON.stringify({ state, ...data }),
|
|
95
|
+
});
|
|
96
|
+
if (!res.ok) {
|
|
97
|
+
const body = await res.text().catch(() => '');
|
|
98
|
+
throwApiError(res, body, `Task state update failed: ${res.status} ${res.statusText}`);
|
|
99
|
+
}
|
|
100
|
+
const result = await res.json().catch(() => null);
|
|
101
|
+
const task = extractTask(result);
|
|
102
|
+
if (!task)
|
|
103
|
+
throw new Error('Invalid response: task data not found');
|
|
104
|
+
return task;
|
|
105
|
+
}
|
|
106
|
+
export async function getActiveTasksForAgent(agentId, creds) {
|
|
107
|
+
if (!agentId)
|
|
108
|
+
throw new Error('getActiveTasksForAgent: agentId is required');
|
|
109
|
+
assertCreds(creds, 'getting active tasks for agent');
|
|
110
|
+
const url = new URL(`${getBackendUrl()}/agents/${encodeURIComponent(agentId)}/tasks`);
|
|
111
|
+
url.searchParams.set('state', 'active');
|
|
112
|
+
const res = await fetch(url.toString(), {
|
|
113
|
+
method: 'GET',
|
|
114
|
+
headers: buildHeaders(creds),
|
|
115
|
+
});
|
|
116
|
+
if (!res.ok) {
|
|
117
|
+
const body = await res.text().catch(() => '');
|
|
118
|
+
throwApiError(res, body, `Get active tasks for agent failed: ${res.status} ${res.statusText}`);
|
|
119
|
+
}
|
|
120
|
+
const data = await res.json().catch(() => null);
|
|
121
|
+
return Array.isArray(data?.['tasks']) ? data['tasks'] : [];
|
|
122
|
+
}
|
|
123
|
+
// Backend deliberately has no `/chats/:id/tasks` route — it's composable
|
|
124
|
+
// from links → per-agreement tasks. We do the composition here so callers
|
|
125
|
+
// don't have to.
|
|
126
|
+
export async function getActiveTasksForChat(chatId, creds) {
|
|
127
|
+
if (!chatId)
|
|
128
|
+
throw new Error('getActiveTasksForChat: chatId is required');
|
|
129
|
+
assertCreds(creds, 'getting active tasks for chat');
|
|
130
|
+
const linksRes = await fetch(`${getBackendUrl()}/agreements/by-chat/${encodeURIComponent(chatId)}`, { method: 'GET', headers: buildHeaders(creds) });
|
|
131
|
+
if (!linksRes.ok) {
|
|
132
|
+
const body = await linksRes.text().catch(() => '');
|
|
133
|
+
throwApiError(linksRes, body, `Get agreements for chat failed: ${linksRes.status} ${linksRes.statusText}`);
|
|
134
|
+
}
|
|
135
|
+
const linksData = await linksRes.json().catch(() => null);
|
|
136
|
+
const rawLinks = linksData?.['links'] ?? linksData?.['agreements'];
|
|
137
|
+
const agreements = Array.isArray(rawLinks) ? rawLinks : [];
|
|
138
|
+
const agreementIds = Array.from(new Set(agreements.map((a) => a['agreementId']).filter(Boolean)));
|
|
139
|
+
if (agreementIds.length === 0)
|
|
140
|
+
return [];
|
|
141
|
+
const lists = await Promise.all(agreementIds.map(async (aid) => {
|
|
142
|
+
const url = new URL(`${getBackendUrl()}/agreements/${encodeURIComponent(aid)}/tasks`);
|
|
143
|
+
url.searchParams.set('state', 'active');
|
|
144
|
+
const res = await fetch(url.toString(), { method: 'GET', headers: buildHeaders(creds) });
|
|
145
|
+
if (!res.ok) {
|
|
146
|
+
const body = await res.text().catch(() => '');
|
|
147
|
+
throwApiError(res, body, `Get tasks for agreement ${aid} failed: ${res.status}`);
|
|
148
|
+
}
|
|
149
|
+
const data = await res.json().catch(() => null);
|
|
150
|
+
return Array.isArray(data?.['tasks']) ? data['tasks'] : [];
|
|
151
|
+
}));
|
|
152
|
+
return lists.flat();
|
|
153
|
+
}
|
|
154
|
+
export async function cancelTask(taskId, creds) {
|
|
155
|
+
if (!taskId)
|
|
156
|
+
throw new Error('cancelTask: taskId is required');
|
|
157
|
+
assertCreds(creds, 'task cancellation');
|
|
158
|
+
const res = await fetch(`${getTaskBaseUrl()}/${taskId}/cancel`, {
|
|
159
|
+
method: 'PATCH',
|
|
160
|
+
headers: buildHeaders(creds),
|
|
161
|
+
});
|
|
162
|
+
if (!res.ok) {
|
|
163
|
+
const body = await res.text().catch(() => '');
|
|
164
|
+
throwApiError(res, body, `Task cancel failed: ${res.status} ${res.statusText}`);
|
|
165
|
+
}
|
|
166
|
+
const result = await res.json().catch(() => null);
|
|
167
|
+
const task = extractTask(result);
|
|
168
|
+
if (!task)
|
|
169
|
+
throw new Error('Invalid response: task data not found');
|
|
170
|
+
return task;
|
|
171
|
+
}
|
|
172
|
+
export async function getSubtasks(parentTaskId, creds) {
|
|
173
|
+
if (!parentTaskId)
|
|
174
|
+
throw new Error('getSubtasks: parentTaskId is required');
|
|
175
|
+
assertCreds(creds, 'getting subtasks');
|
|
176
|
+
const url = new URL(`${getTaskBaseUrl()}/${encodeURIComponent(parentTaskId)}/subtasks`);
|
|
177
|
+
const res = await fetch(url.toString(), {
|
|
178
|
+
method: 'GET',
|
|
179
|
+
headers: buildHeaders(creds),
|
|
180
|
+
});
|
|
181
|
+
if (!res.ok) {
|
|
182
|
+
const body = await res.text().catch(() => '');
|
|
183
|
+
throwApiError(res, body, `Get subtasks failed: ${res.status} ${res.statusText}`);
|
|
184
|
+
}
|
|
185
|
+
const data = await res.json().catch(() => null);
|
|
186
|
+
return Array.isArray(data?.['tasks']) ? data['tasks'] : [];
|
|
187
|
+
}
|
|
188
|
+
export async function replaceTaskPlan(taskId, steps, creds) {
|
|
189
|
+
if (!taskId)
|
|
190
|
+
throw new Error('replaceTaskPlan: taskId is required');
|
|
191
|
+
if (!steps || !Array.isArray(steps))
|
|
192
|
+
throw new Error('replaceTaskPlan: steps must be an array');
|
|
193
|
+
assertCreds(creds, 'plan replace');
|
|
194
|
+
const res = await fetch(`${getTaskBaseUrl()}/${taskId}/plan`, {
|
|
195
|
+
method: 'PATCH',
|
|
196
|
+
headers: buildHeaders(creds),
|
|
197
|
+
body: JSON.stringify({ steps }),
|
|
198
|
+
});
|
|
199
|
+
if (!res.ok) {
|
|
200
|
+
const responseBody = await res.text().catch(() => '');
|
|
201
|
+
throwApiError(res, responseBody, `Plan replace failed: ${res.status} ${res.statusText}`);
|
|
202
|
+
}
|
|
203
|
+
const data = await res.json().catch(() => null);
|
|
204
|
+
const task = extractTask(data);
|
|
205
|
+
if (!task)
|
|
206
|
+
throw new Error('Invalid response: task data not found');
|
|
207
|
+
return task;
|
|
208
|
+
}
|
|
209
|
+
export async function publishToLedger(payload, creds) {
|
|
210
|
+
assertCreds(creds, 'quest publish');
|
|
211
|
+
const res = await fetch(`${getMarketplaceBaseUrl()}/quests/publish`, {
|
|
212
|
+
method: 'POST',
|
|
213
|
+
headers: buildHeaders(creds),
|
|
214
|
+
body: JSON.stringify(payload || {}),
|
|
215
|
+
});
|
|
216
|
+
if (!res.ok) {
|
|
217
|
+
const body = await res.text().catch(() => '');
|
|
218
|
+
throwApiError(res, body, `Quest publish failed: ${res.status}`);
|
|
219
|
+
}
|
|
220
|
+
const data = await res.json().catch(() => null);
|
|
221
|
+
if (!data?.['agreement'])
|
|
222
|
+
throw new Error('Quest publish returned no agreement');
|
|
223
|
+
return data['agreement'];
|
|
224
|
+
}
|
|
225
|
+
export async function pullFromLedger(options, creds) {
|
|
226
|
+
assertCreds(creds, 'quest pull');
|
|
227
|
+
const res = await fetch(`${getMarketplaceBaseUrl()}/quests/pull`, {
|
|
228
|
+
method: 'POST',
|
|
229
|
+
headers: buildHeaders(creds),
|
|
230
|
+
body: JSON.stringify(options || {}),
|
|
231
|
+
});
|
|
232
|
+
if (!res.ok) {
|
|
233
|
+
const body = await res.text().catch(() => '');
|
|
234
|
+
throwApiError(res, body, `Quest pull failed: ${res.status}`);
|
|
235
|
+
}
|
|
236
|
+
const data = await res.json().catch(() => null);
|
|
237
|
+
return data?.['agreements'] ?? [];
|
|
238
|
+
}
|
|
239
|
+
export async function claimLedgerTask(agreementId, creds, options) {
|
|
240
|
+
if (!agreementId)
|
|
241
|
+
throw new Error('agreementId is required');
|
|
242
|
+
assertCreds(creds, 'quest claim');
|
|
243
|
+
const headers = buildHeaders(creds);
|
|
244
|
+
if (options?.idempotencyKey)
|
|
245
|
+
headers['Idempotency-Key'] = options.idempotencyKey;
|
|
246
|
+
const res = await fetch(`${getMarketplaceBaseUrl()}/quests/claim`, {
|
|
247
|
+
method: 'POST',
|
|
248
|
+
headers,
|
|
249
|
+
body: JSON.stringify({ agreementId }),
|
|
250
|
+
});
|
|
251
|
+
if (!res.ok) {
|
|
252
|
+
const body = await res.text().catch(() => '');
|
|
253
|
+
throwApiError(res, body, `Quest claim failed: ${res.status}`);
|
|
254
|
+
}
|
|
255
|
+
const data = await res.json().catch(() => null);
|
|
256
|
+
if (!data?.['ok'])
|
|
257
|
+
throw new Error(data?.['error'] || 'Claim failed');
|
|
258
|
+
return data['agreement'];
|
|
259
|
+
}
|
|
260
|
+
// ---------------------------------------------------------------------------
|
|
261
|
+
// Reporting & satisfaction
|
|
262
|
+
// ---------------------------------------------------------------------------
|
|
263
|
+
export async function reportTask(taskId, message = '', creds) {
|
|
264
|
+
if (!taskId)
|
|
265
|
+
throw new Error('reportTask: taskId is required');
|
|
266
|
+
assertCreds(creds, 'task report');
|
|
267
|
+
const res = await fetch(`${getTaskBaseUrl()}/${taskId}/report`, {
|
|
268
|
+
method: 'POST',
|
|
269
|
+
headers: buildHeaders(creds),
|
|
270
|
+
body: JSON.stringify({ message }),
|
|
271
|
+
});
|
|
272
|
+
if (!res.ok) {
|
|
273
|
+
const body = await res.text().catch(() => '');
|
|
274
|
+
throwApiError(res, body, `Task report failed: ${res.status} ${res.statusText}`);
|
|
275
|
+
}
|
|
276
|
+
const data = await res.json().catch(() => null);
|
|
277
|
+
const task = extractTask(data);
|
|
278
|
+
if (!task)
|
|
279
|
+
throw new Error('Invalid response: task data not found');
|
|
280
|
+
return task;
|
|
281
|
+
}
|
|
282
|
+
export async function setTaskSatisfaction(taskId, satisfaction, creds) {
|
|
283
|
+
if (!taskId)
|
|
284
|
+
throw new Error('setTaskSatisfaction: taskId is required');
|
|
285
|
+
if (!satisfaction)
|
|
286
|
+
throw new Error('setTaskSatisfaction: satisfaction is required');
|
|
287
|
+
assertCreds(creds, 'task satisfaction');
|
|
288
|
+
const res = await fetch(`${getTaskBaseUrl()}/${taskId}/satisfaction`, {
|
|
289
|
+
method: 'PATCH',
|
|
290
|
+
headers: buildHeaders(creds),
|
|
291
|
+
body: JSON.stringify({ satisfaction }),
|
|
292
|
+
});
|
|
293
|
+
if (!res.ok) {
|
|
294
|
+
const body = await res.text().catch(() => '');
|
|
295
|
+
throwApiError(res, body, `Task satisfaction failed: ${res.status} ${res.statusText}`);
|
|
296
|
+
}
|
|
297
|
+
const data = await res.json().catch(() => null);
|
|
298
|
+
const task = extractTask(data);
|
|
299
|
+
if (!task)
|
|
300
|
+
throw new Error('Invalid response: task data not found');
|
|
301
|
+
return task;
|
|
302
|
+
}
|
|
303
|
+
export async function countTasks(filters = {}, creds) {
|
|
304
|
+
assertCreds(creds, 'count tasks');
|
|
305
|
+
// Canonical REST: GET /tasks/count.
|
|
306
|
+
const url = new URL(`${getTaskBaseUrl()}/count`);
|
|
307
|
+
if (filters.chatId)
|
|
308
|
+
url.searchParams.set('chatId', filters.chatId);
|
|
309
|
+
if (filters.state)
|
|
310
|
+
url.searchParams.set('state', filters.state);
|
|
311
|
+
if (filters.userId)
|
|
312
|
+
url.searchParams.set('userId', filters.userId);
|
|
313
|
+
if (filters.agentId)
|
|
314
|
+
url.searchParams.set('agentId', filters.agentId);
|
|
315
|
+
const res = await fetch(url.toString(), {
|
|
316
|
+
method: 'GET',
|
|
317
|
+
headers: buildHeaders(creds),
|
|
318
|
+
});
|
|
319
|
+
if (!res.ok) {
|
|
320
|
+
const body = await res.text().catch(() => '');
|
|
321
|
+
throwApiError(res, body, `Count tasks failed: ${res.status} ${res.statusText}`);
|
|
322
|
+
}
|
|
323
|
+
const data = await res.json().catch(() => null);
|
|
324
|
+
return typeof data?.['count'] === 'number' ? data['count'] : 0;
|
|
325
|
+
}
|
|
326
|
+
// ---------------------------------------------------------------------------
|
|
327
|
+
// TaskClient class — bind creds once
|
|
328
|
+
// ---------------------------------------------------------------------------
|
|
329
|
+
export class TaskClient {
|
|
330
|
+
creds;
|
|
331
|
+
constructor(operatorKey, agentId) {
|
|
332
|
+
if (!operatorKey)
|
|
333
|
+
throw new Error('TaskClient: operatorKey is required');
|
|
334
|
+
if (!agentId)
|
|
335
|
+
throw new Error('TaskClient: agentId is required');
|
|
336
|
+
this.creds = { operatorKey, agentId };
|
|
337
|
+
}
|
|
338
|
+
createTask(data) { return createTask(data, this.creds); }
|
|
339
|
+
getTask(taskId) { return getTask(taskId, this.creds); }
|
|
340
|
+
updateTaskState(taskId, state, data) { return updateTaskState(taskId, state, data ?? {}, this.creds); }
|
|
341
|
+
getActiveTasksForAgent(agentId) { return getActiveTasksForAgent(agentId, this.creds); }
|
|
342
|
+
getActiveTasksForChat(chatId) { return getActiveTasksForChat(chatId, this.creds); }
|
|
343
|
+
cancelTask(taskId) { return cancelTask(taskId, this.creds); }
|
|
344
|
+
getSubtasks(parentTaskId) { return getSubtasks(parentTaskId, this.creds); }
|
|
345
|
+
replaceTaskPlan(taskId, steps) { return replaceTaskPlan(taskId, steps, this.creds); }
|
|
346
|
+
publishToLedger(payload) { return publishToLedger(payload, this.creds); }
|
|
347
|
+
pullFromLedger(options) { return pullFromLedger(options, this.creds); }
|
|
348
|
+
claimLedgerTask(taskId, options) { return claimLedgerTask(taskId, this.creds, options); }
|
|
349
|
+
reportTask(taskId, message) { return reportTask(taskId, message, this.creds); }
|
|
350
|
+
setTaskSatisfaction(taskId, satisfaction) { return setTaskSatisfaction(taskId, satisfaction, this.creds); }
|
|
351
|
+
countTasks(filters) { return countTasks(filters, this.creds); }
|
|
352
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
export declare class TelemetryClient {
|
|
3
|
+
private readonly operatorKey;
|
|
4
|
+
private readonly agentId;
|
|
5
|
+
private _queue;
|
|
6
|
+
private _flushing;
|
|
7
|
+
constructor(operatorKey: string, agentId: string);
|
|
8
|
+
send(payload: unknown): Promise<void>;
|
|
9
|
+
private _flush;
|
|
10
|
+
private _post;
|
|
11
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
import { runtimeLog } from '../shared/runtimeLog.js';
|
|
3
|
+
import { getBackendUrl } from '../utils/urlUtils.js';
|
|
4
|
+
export class TelemetryClient {
|
|
5
|
+
operatorKey;
|
|
6
|
+
agentId;
|
|
7
|
+
_queue;
|
|
8
|
+
_flushing;
|
|
9
|
+
constructor(operatorKey, agentId) {
|
|
10
|
+
if (!operatorKey)
|
|
11
|
+
throw new Error('TelemetryClient: operatorKey is required');
|
|
12
|
+
if (!agentId)
|
|
13
|
+
throw new Error('TelemetryClient: agentId is required (operator-token impersonation)');
|
|
14
|
+
this.operatorKey = operatorKey;
|
|
15
|
+
this.agentId = agentId;
|
|
16
|
+
this._queue = [];
|
|
17
|
+
this._flushing = false;
|
|
18
|
+
}
|
|
19
|
+
async send(payload) {
|
|
20
|
+
this._queue.push(payload);
|
|
21
|
+
if (!this._flushing)
|
|
22
|
+
this._flush();
|
|
23
|
+
}
|
|
24
|
+
async _flush() {
|
|
25
|
+
this._flushing = true;
|
|
26
|
+
while (this._queue.length > 0) {
|
|
27
|
+
const batch = this._queue.splice(0, 10);
|
|
28
|
+
await Promise.allSettled(batch.map((p) => this._post(p)));
|
|
29
|
+
}
|
|
30
|
+
this._flushing = false;
|
|
31
|
+
}
|
|
32
|
+
async _post(payload) {
|
|
33
|
+
const url = `${getBackendUrl()}/agents/monitoring/ingest`;
|
|
34
|
+
try {
|
|
35
|
+
const res = await fetch(url, {
|
|
36
|
+
method: 'POST',
|
|
37
|
+
headers: {
|
|
38
|
+
'content-type': 'application/json',
|
|
39
|
+
Authorization: `Bearer ${this.operatorKey}`,
|
|
40
|
+
'X-Agent-Id': this.agentId,
|
|
41
|
+
},
|
|
42
|
+
body: JSON.stringify({ payload }),
|
|
43
|
+
});
|
|
44
|
+
if (!res.ok) {
|
|
45
|
+
const body = await res.text().catch(() => '');
|
|
46
|
+
runtimeLog.warn('TelemetryClient', `⚠️ ingest failed agent=${this.agentId} ${res.status} ${res.statusText} body=${body.slice(0, 200)}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
runtimeLog.warn('TelemetryClient', `⚠️ ingest error agent=${this.agentId} message=${err.message}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export * from './TaskClient.js';
|
|
2
|
+
export * from './AgreementClient.js';
|
|
3
|
+
export * from './MarketplaceClient.js';
|
|
4
|
+
export * from './ChatClient.js';
|
|
5
|
+
export { MessagesClient } from './MessagesClient.js';
|
|
6
|
+
export type { ListMessagesOptions, ListMessagesResult } from './MessagesClient.js';
|
|
7
|
+
export { ArtifactsClient } from './ArtifactsClient.js';
|
|
8
|
+
export type { ArtifactVisibility, ListArtifactsOptions, ListArtifactsQuery, ListArtifactsResult, WriteArtifactInput, } from './ArtifactsClient.js';
|
|
9
|
+
export { ScopeClient } from './ScopeClient.js';
|
|
10
|
+
export type { ScopeKind, ScopeResult, PartyRef } from './ScopeClient.js';
|
|
11
|
+
export { ContextReadClient } from './ContextReadClient.js';
|
|
12
|
+
export type { ContextReadType, ContextReadQuery, ContextReadEnvelope, } from './ContextReadClient.js';
|
|
13
|
+
export { ContextDiscoveryClient } from './ContextDiscoveryClient.js';
|
|
14
|
+
export type { ContextReachDescriptor } from './ContextDiscoveryClient.js';
|
|
15
|
+
export { AgentSearchClient } from './AgentSearchClient.js';
|
|
16
|
+
export { TelemetryClient } from './TelemetryClient.js';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from './TaskClient.js';
|
|
2
|
+
export * from './AgreementClient.js';
|
|
3
|
+
export * from './MarketplaceClient.js';
|
|
4
|
+
export * from './ChatClient.js';
|
|
5
|
+
export { MessagesClient } from './MessagesClient.js';
|
|
6
|
+
export { ArtifactsClient } from './ArtifactsClient.js';
|
|
7
|
+
export { ScopeClient } from './ScopeClient.js';
|
|
8
|
+
export { ContextReadClient } from './ContextReadClient.js';
|
|
9
|
+
export { ContextDiscoveryClient } from './ContextDiscoveryClient.js';
|
|
10
|
+
export { AgentSearchClient } from './AgentSearchClient.js';
|
|
11
|
+
export { TelemetryClient } from './TelemetryClient.js';
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './http/index.js';
|
|
2
|
+
export { WebSocketClient } from './websocket/index.js';
|
|
3
|
+
export { createControlSocket } from './websocket/ControlSocket.js';
|
|
4
|
+
export { ConnectionManager } from './ConnectionManager.js';
|
|
5
|
+
export { EntryTypes, ContentTypes, OPEN_AGREEMENT_TARGET, AGREEMENT_ENGAGEMENT_KIND, isValidContentType } from './types.js';
|
|
6
|
+
export { getBackendUrl, getWebSocketUrl } from './utils/urlUtils.js';
|
|
7
|
+
export { runtimeLog, resetRuntimeLogLevelCache } from './shared/runtimeLog.js';
|
|
8
|
+
export type { Creds, Task, TaskState, PlanStep, PlanStepStatus, Agreement, EngagementKind, EntryType, ContentType, MessageMetadata, MessageHandler, ApiError, } from './types.js';
|
|
9
|
+
export type { ProposeTerms, ProposeDirectInput, ProposeBroadcastInput, ProposeAgreementData, } from './http/AgreementClient.js';
|
package/{src → dist}/index.js
RENAMED
|
@@ -1,17 +1,7 @@
|
|
|
1
|
-
// Main entry point for @ziggs-ai/api-client
|
|
2
|
-
|
|
3
|
-
// HTTP Clients
|
|
4
1
|
export * from './http/index.js';
|
|
5
|
-
|
|
6
|
-
// WebSocket Client
|
|
7
2
|
export { WebSocketClient } from './websocket/index.js';
|
|
8
3
|
export { createControlSocket } from './websocket/ControlSocket.js';
|
|
9
|
-
|
|
10
|
-
// Connection management (optional — generic pool + control socket)
|
|
11
4
|
export { ConnectionManager } from './ConnectionManager.js';
|
|
12
|
-
|
|
13
|
-
// Types
|
|
14
|
-
export { EntryTypes, ContentTypes } from './types.js';
|
|
15
|
-
|
|
16
|
-
// Utilities
|
|
5
|
+
export { EntryTypes, ContentTypes, OPEN_AGREEMENT_TARGET, AGREEMENT_ENGAGEMENT_KIND, isValidContentType } from './types.js';
|
|
17
6
|
export { getBackendUrl, getWebSocketUrl } from './utils/urlUtils.js';
|
|
7
|
+
export { runtimeLog, resetRuntimeLogLevelCache } from './shared/runtimeLog.js';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Same semantics as `@ziggs-ai/agent-sdk` `shared/runtimeLog.ts` (duplicated
|
|
3
|
+
* here so this package stays dependency-free).
|
|
4
|
+
*
|
|
5
|
+
* @see agent-sdk/src/shared/runtimeLog.ts
|
|
6
|
+
*/
|
|
7
|
+
export type RuntimeLogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
8
|
+
export declare function resetRuntimeLogLevelCache(): void;
|
|
9
|
+
export declare const runtimeLog: {
|
|
10
|
+
debug(scope: string, msg: string, ...rest: unknown[]): void;
|
|
11
|
+
info(scope: string, msg: string, ...rest: unknown[]): void;
|
|
12
|
+
warn(scope: string, msg: string, ...rest: unknown[]): void;
|
|
13
|
+
error(scope: string, msg: string, ...rest: unknown[]): void;
|
|
14
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Same semantics as `@ziggs-ai/agent-sdk` `shared/runtimeLog.ts` (duplicated
|
|
3
|
+
* here so this package stays dependency-free).
|
|
4
|
+
*
|
|
5
|
+
* @see agent-sdk/src/shared/runtimeLog.ts
|
|
6
|
+
*/
|
|
7
|
+
const SEVERITY = {
|
|
8
|
+
debug: 0,
|
|
9
|
+
info: 1,
|
|
10
|
+
warn: 2,
|
|
11
|
+
error: 3,
|
|
12
|
+
};
|
|
13
|
+
function parseThreshold() {
|
|
14
|
+
if (process.env.DEBUG_AGENTPLUS === '1' || process.env.AGENTPLUS_DEBUG === '1') {
|
|
15
|
+
return SEVERITY.debug;
|
|
16
|
+
}
|
|
17
|
+
const raw = (process.env.LOG_LEVEL ||
|
|
18
|
+
process.env.AGENTPLUS_LOG_LEVEL ||
|
|
19
|
+
'info').toLowerCase();
|
|
20
|
+
if (raw === 'silent' || raw === 'none')
|
|
21
|
+
return SEVERITY.error;
|
|
22
|
+
if (raw === 'debug' || raw === 'trace')
|
|
23
|
+
return SEVERITY.debug;
|
|
24
|
+
if (raw === 'warn')
|
|
25
|
+
return SEVERITY.warn;
|
|
26
|
+
if (raw === 'error')
|
|
27
|
+
return SEVERITY.error;
|
|
28
|
+
return SEVERITY.info;
|
|
29
|
+
}
|
|
30
|
+
let cachedThreshold = null;
|
|
31
|
+
function threshold() {
|
|
32
|
+
if (cachedThreshold === null)
|
|
33
|
+
cachedThreshold = parseThreshold();
|
|
34
|
+
return cachedThreshold;
|
|
35
|
+
}
|
|
36
|
+
export function resetRuntimeLogLevelCache() {
|
|
37
|
+
cachedThreshold = null;
|
|
38
|
+
}
|
|
39
|
+
function shouldEmit(level) {
|
|
40
|
+
return SEVERITY[level] >= threshold();
|
|
41
|
+
}
|
|
42
|
+
function fmt(scope, msg) {
|
|
43
|
+
return `[${scope}] ${msg}`;
|
|
44
|
+
}
|
|
45
|
+
export const runtimeLog = {
|
|
46
|
+
debug(scope, msg, ...rest) {
|
|
47
|
+
if (!shouldEmit('debug'))
|
|
48
|
+
return;
|
|
49
|
+
console.log(fmt(scope, msg), ...rest);
|
|
50
|
+
},
|
|
51
|
+
info(scope, msg, ...rest) {
|
|
52
|
+
if (!shouldEmit('info'))
|
|
53
|
+
return;
|
|
54
|
+
console.log(fmt(scope, msg), ...rest);
|
|
55
|
+
},
|
|
56
|
+
warn(scope, msg, ...rest) {
|
|
57
|
+
if (!shouldEmit('warn'))
|
|
58
|
+
return;
|
|
59
|
+
console.warn(fmt(scope, msg), ...rest);
|
|
60
|
+
},
|
|
61
|
+
error(scope, msg, ...rest) {
|
|
62
|
+
console.error(fmt(scope, msg), ...rest);
|
|
63
|
+
},
|
|
64
|
+
};
|