pilotswarm-sdk 0.3.2 → 0.4.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 +21 -4
- package/api/README.md +44 -0
- package/api/index.d.ts +86 -0
- package/api/index.js +16 -0
- package/api/src/api-client.js +363 -0
- package/api/src/http-api-transport.js +342 -0
- package/api/src/protocol.js +230 -0
- package/dist/client.d.ts +2 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +9 -0
- package/dist/client.js.map +1 -1
- package/dist/cms-migrations.d.ts.map +1 -1
- package/dist/cms-migrations.js +250 -0
- package/dist/cms-migrations.js.map +1 -1
- package/dist/cms.d.ts +10 -0
- package/dist/cms.d.ts.map +1 -1
- package/dist/cms.js +5 -0
- package/dist/cms.js.map +1 -1
- package/dist/index.d.ts +25 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -7
- package/dist/index.js.map +1 -1
- package/dist/managed-session.d.ts +35 -0
- package/dist/managed-session.d.ts.map +1 -1
- package/dist/managed-session.js +74 -0
- package/dist/managed-session.js.map +1 -1
- package/dist/management-client.d.ts +88 -3
- package/dist/management-client.d.ts.map +1 -1
- package/dist/management-client.js +259 -2
- package/dist/management-client.js.map +1 -1
- package/dist/orchestration/index.d.ts +2 -2
- package/dist/orchestration/index.js +1 -1
- package/dist/orchestration/runtime.d.ts +1 -1
- package/dist/orchestration/turn.d.ts +13 -0
- package/dist/orchestration/turn.d.ts.map +1 -1
- package/dist/orchestration/turn.js +317 -163
- package/dist/orchestration/turn.js.map +1 -1
- package/dist/orchestration-registry.d.ts.map +1 -1
- package/dist/orchestration-registry.js +4 -2
- package/dist/orchestration-registry.js.map +1 -1
- package/dist/orchestration-version.d.ts +1 -1
- package/dist/orchestration-version.js +1 -1
- package/dist/orchestration.d.ts +2 -2
- package/dist/orchestration.js +1 -1
- package/dist/orchestration_1_0_46.d.ts +1 -1
- package/dist/orchestration_1_0_47.d.ts +1 -1
- package/dist/orchestration_1_0_48.d.ts +1 -1
- package/dist/orchestration_1_0_49.d.ts +1 -1
- package/dist/orchestration_1_0_50.d.ts +1 -1
- package/dist/orchestration_1_0_55/agents.d.ts +41 -0
- package/dist/orchestration_1_0_55/agents.d.ts.map +1 -0
- package/dist/orchestration_1_0_55/agents.js +758 -0
- package/dist/orchestration_1_0_55/agents.js.map +1 -0
- package/dist/orchestration_1_0_55/index.d.ts +24 -0
- package/dist/orchestration_1_0_55/index.d.ts.map +1 -0
- package/dist/orchestration_1_0_55/index.js +13 -0
- package/dist/orchestration_1_0_55/index.js.map +1 -0
- package/dist/orchestration_1_0_55/lifecycle.d.ts +41 -0
- package/dist/orchestration_1_0_55/lifecycle.d.ts.map +1 -0
- package/dist/orchestration_1_0_55/lifecycle.js +580 -0
- package/dist/orchestration_1_0_55/lifecycle.js.map +1 -0
- package/dist/orchestration_1_0_55/queue.d.ts +7 -0
- package/dist/orchestration_1_0_55/queue.d.ts.map +1 -0
- package/dist/orchestration_1_0_55/queue.js +644 -0
- package/dist/orchestration_1_0_55/queue.js.map +1 -0
- package/dist/orchestration_1_0_55/runtime.d.ts +29 -0
- package/dist/orchestration_1_0_55/runtime.d.ts.map +1 -0
- package/dist/orchestration_1_0_55/runtime.js +194 -0
- package/dist/orchestration_1_0_55/runtime.js.map +1 -0
- package/dist/orchestration_1_0_55/state.d.ts +126 -0
- package/dist/orchestration_1_0_55/state.d.ts.map +1 -0
- package/dist/orchestration_1_0_55/state.js +106 -0
- package/dist/orchestration_1_0_55/state.js.map +1 -0
- package/dist/orchestration_1_0_55/turn.d.ts +17 -0
- package/dist/orchestration_1_0_55/turn.d.ts.map +1 -0
- package/dist/orchestration_1_0_55/turn.js +921 -0
- package/dist/orchestration_1_0_55/turn.js.map +1 -0
- package/dist/orchestration_1_0_55/utils.d.ts +22 -0
- package/dist/orchestration_1_0_55/utils.d.ts.map +1 -0
- package/dist/orchestration_1_0_55/utils.js +226 -0
- package/dist/orchestration_1_0_55/utils.js.map +1 -0
- package/dist/session-manager.d.ts +20 -1
- package/dist/session-manager.d.ts.map +1 -1
- package/dist/session-manager.js +62 -0
- package/dist/session-manager.js.map +1 -1
- package/dist/session-proxy.d.ts +7 -0
- package/dist/session-proxy.d.ts.map +1 -1
- package/dist/session-proxy.js +35 -1
- package/dist/session-proxy.js.map +1 -1
- package/dist/session-store.d.ts.map +1 -1
- package/dist/session-store.js +13 -3
- package/dist/session-store.js.map +1 -1
- package/dist/types.d.ts +39 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -1
- package/dist/web/api-connection.d.ts +20 -0
- package/dist/web/api-connection.d.ts.map +1 -0
- package/dist/web/api-connection.js +23 -0
- package/dist/web/api-connection.js.map +1 -0
- package/dist/web/web-client.d.ts +91 -0
- package/dist/web/web-client.d.ts.map +1 -0
- package/dist/web/web-client.js +378 -0
- package/dist/web/web-client.js.map +1 -0
- package/dist/web/web-fact-store.d.ts +78 -0
- package/dist/web/web-fact-store.d.ts.map +1 -0
- package/dist/web/web-fact-store.js +112 -0
- package/dist/web/web-fact-store.js.map +1 -0
- package/dist/web/web-graph-store.d.ts +38 -0
- package/dist/web/web-graph-store.d.ts.map +1 -0
- package/dist/web/web-graph-store.js +68 -0
- package/dist/web/web-graph-store.js.map +1 -0
- package/dist/web/web-management-client.d.ts +125 -0
- package/dist/web/web-management-client.d.ts.map +1 -0
- package/dist/web/web-management-client.js +256 -0
- package/dist/web/web-management-client.js.map +1 -0
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +10 -0
- package/dist/worker.js.map +1 -1
- package/package.json +16 -6
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import { ApiClient } from "./api-client.js";
|
|
2
|
+
|
|
3
|
+
function toIso(value) {
|
|
4
|
+
return value instanceof Date ? value.toISOString() : value;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function unsupported(name, hint) {
|
|
8
|
+
return () => {
|
|
9
|
+
throw new Error(`${name} is not available on this client${hint ? ` (${hint})` : ""}`);
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The shared-UI transport surface (what `pilotswarm/ui-core` consumes) over
|
|
15
|
+
* the PilotSwarm Web API. Used by the browser portal and by the TUI's API
|
|
16
|
+
* mode; both inject their environment-specific conveniences (artifact
|
|
17
|
+
* save-to-disk / browser download, open-in-app) via `options.host`.
|
|
18
|
+
*/
|
|
19
|
+
export class HttpApiTransport {
|
|
20
|
+
constructor(options = {}) {
|
|
21
|
+
this.api = options.api instanceof ApiClient ? options.api : new ApiClient(options);
|
|
22
|
+
this.bootstrap = null;
|
|
23
|
+
const host = options.host || {};
|
|
24
|
+
if (host.saveArtifactDownload) this.saveArtifactDownload = host.saveArtifactDownload.bind(null, this);
|
|
25
|
+
else this.saveArtifactDownload = unsupported("saveArtifactDownload", "no host download handler");
|
|
26
|
+
if (host.uploadArtifactFromPath) this.uploadArtifactFromPath = host.uploadArtifactFromPath.bind(null, this);
|
|
27
|
+
if (host.openPathInDefaultApp) this.openPathInDefaultApp = host.openPathInDefaultApp;
|
|
28
|
+
if (host.openUrlInDefaultBrowser) this.openUrlInDefaultBrowser = host.openUrlInDefaultBrowser;
|
|
29
|
+
this.artifactExportDirectory = host.artifactExportDirectory || null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async start() {
|
|
33
|
+
await this.api.start();
|
|
34
|
+
this.bootstrap = await this.api.getBootstrap();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async stop() {
|
|
38
|
+
await this.api.stop();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// ── Bootstrap-backed getters ────────────────────────────────────────
|
|
42
|
+
|
|
43
|
+
getWorkerCount() {
|
|
44
|
+
return this.bootstrap?.workerCount ?? null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
getLogConfig() {
|
|
48
|
+
return this.bootstrap?.logConfig || null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
getModelsByProvider() {
|
|
52
|
+
return this.bootstrap?.modelsByProvider || [];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
getDefaultModel() {
|
|
56
|
+
return this.bootstrap?.defaultModel || null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
getAuthContext() {
|
|
60
|
+
return this.bootstrap?.auth || {
|
|
61
|
+
principal: null,
|
|
62
|
+
authorization: { allowed: false, role: null, reason: "Auth context unavailable", matchedGroups: [] },
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async listCreatableAgents() {
|
|
67
|
+
return this.bootstrap?.creatableAgents || this.api.call("listCreatableAgents");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
getSessionCreationPolicy() {
|
|
71
|
+
return this.bootstrap?.sessionCreationPolicy || null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// ── Sessions ────────────────────────────────────────────────────────
|
|
75
|
+
|
|
76
|
+
async listSessions() {
|
|
77
|
+
return this.api.call("listSessions");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async listSessionsPage(opts = {}) {
|
|
81
|
+
return this.api.call("listSessionsPage", {
|
|
82
|
+
limit: opts?.limit,
|
|
83
|
+
cursor: opts?.cursor ?? undefined,
|
|
84
|
+
includeDeleted: opts?.includeDeleted,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async getSession(sessionId) {
|
|
89
|
+
return this.api.call("getSession", { sessionId });
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async createSession(options = {}) {
|
|
93
|
+
return this.api.call("createSession", options);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async createSessionForAgent(agentName, options = {}) {
|
|
97
|
+
return this.api.call("createSessionForAgent", { agentName, ...options });
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async deleteSession(sessionId) {
|
|
101
|
+
return this.api.call("deleteSession", { sessionId });
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async renameSession(sessionId, title) {
|
|
105
|
+
return this.api.call("renameSession", { sessionId, title });
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async cancelSession(sessionId) {
|
|
109
|
+
return this.api.call("cancelSession", { sessionId });
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async completeSession(sessionId, reason) {
|
|
113
|
+
return this.api.call("completeSession", { sessionId, reason });
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async restartSystemSession(agentIdOrSessionId, options = {}) {
|
|
117
|
+
return this.api.call("restartSystemSession", { agentIdOrSessionId, options });
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async setSessionModel(sessionId, options = {}) {
|
|
121
|
+
return this.api.call("setSessionModel", { sessionId, options });
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async stopSessionTurn(sessionId, options = {}) {
|
|
125
|
+
return this.api.call("stopSessionTurn", { sessionId, options });
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// ── Messaging ───────────────────────────────────────────────────────
|
|
129
|
+
|
|
130
|
+
async sendMessage(sessionId, prompt, options = {}) {
|
|
131
|
+
return this.api.call("sendMessage", { sessionId, prompt, options });
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async sendAnswer(sessionId, answer) {
|
|
135
|
+
return this.api.call("sendAnswer", { sessionId, answer });
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async cancelPendingMessage(sessionId, clientMessageIds) {
|
|
139
|
+
return this.api.call("cancelPendingMessage", { sessionId, clientMessageIds });
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// ── Session groups ──────────────────────────────────────────────────
|
|
143
|
+
|
|
144
|
+
async listSessionGroups() {
|
|
145
|
+
return this.api.call("listSessionGroups");
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
async createSessionGroup(input) {
|
|
149
|
+
return this.api.call("createSessionGroup", { input });
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async updateSessionGroup(groupId, patch) {
|
|
153
|
+
return this.api.call("updateSessionGroup", { groupId, patch });
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async assignSessionsToGroup(groupId, sessionIds) {
|
|
157
|
+
return this.api.call("assignSessionsToGroup", { groupId, sessionIds });
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async moveSessionsToGroup(groupId, sessionIds) {
|
|
161
|
+
return this.api.call("moveSessionsToGroup", { groupId: groupId ?? null, sessionIds });
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
async deleteSessionGroup(groupId) {
|
|
165
|
+
return this.api.call("deleteSessionGroup", { groupId });
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
async cancelSessionGroup(groupId, reason) {
|
|
169
|
+
return this.api.call("cancelSessionGroup", { groupId, reason });
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
async completeSessionGroup(groupId, options = {}) {
|
|
173
|
+
return this.api.call("completeSessionGroup", { groupId, options });
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
async getChildOutcome(childSessionId) {
|
|
177
|
+
return this.api.call("getChildOutcome", { childSessionId });
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async listChildOutcomes(parentSessionId) {
|
|
181
|
+
return this.api.call("listChildOutcomes", { parentSessionId });
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// ── Stats / telemetry ───────────────────────────────────────────────
|
|
185
|
+
|
|
186
|
+
async getOrchestrationStats(sessionId) {
|
|
187
|
+
return this.api.call("getOrchestrationStats", { sessionId });
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
async getSessionMetricSummary(sessionId) {
|
|
191
|
+
return this.api.call("getSessionMetricSummary", { sessionId });
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
async getSessionTokensByModel(sessionId) {
|
|
195
|
+
return this.api.call("getSessionTokensByModel", { sessionId });
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
async getSessionTreeStats(sessionId) {
|
|
199
|
+
return this.api.call("getSessionTreeStats", { sessionId });
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
async getFleetStats(opts) {
|
|
203
|
+
return this.api.call("getFleetStats", {
|
|
204
|
+
includeDeleted: opts?.includeDeleted,
|
|
205
|
+
since: toIso(opts?.since),
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
async getUserStats(opts) {
|
|
210
|
+
return this.api.call("getUserStats", {
|
|
211
|
+
includeDeleted: opts?.includeDeleted,
|
|
212
|
+
since: toIso(opts?.since),
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
async getTopEventEmitters(opts = {}) {
|
|
217
|
+
return this.api.call("getTopEventEmitters", {
|
|
218
|
+
since: toIso(opts?.since),
|
|
219
|
+
limit: opts?.limit,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
async getSessionSkillUsage(sessionId, opts) {
|
|
224
|
+
return this.api.call("getSessionSkillUsage", { sessionId, since: toIso(opts?.since) });
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
async getSessionTreeSkillUsage(sessionId, opts) {
|
|
228
|
+
return this.api.call("getSessionTreeSkillUsage", { sessionId, since: toIso(opts?.since) });
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
async getFleetSkillUsage(opts) {
|
|
232
|
+
return this.api.call("getFleetSkillUsage", {
|
|
233
|
+
includeDeleted: opts?.includeDeleted,
|
|
234
|
+
since: toIso(opts?.since),
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
async getFleetRetrievalUsage(opts) {
|
|
239
|
+
return this.api.call("getFleetRetrievalUsage", {
|
|
240
|
+
includeDeleted: opts?.includeDeleted,
|
|
241
|
+
since: toIso(opts?.since),
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
async getSessionFactsStats(sessionId) {
|
|
246
|
+
return this.api.call("getSessionFactsStats", { sessionId });
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
async getSessionTreeFactsStats(sessionId) {
|
|
250
|
+
return this.api.call("getSessionTreeFactsStats", { sessionId });
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
async getSharedFactsStats() {
|
|
254
|
+
return this.api.call("getSharedFactsStats");
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
async getFactsTombstoneStats(opts = {}) {
|
|
258
|
+
return this.api.call("getFactsTombstoneStats", { ttlSeconds: opts.ttlSeconds });
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
async pruneDeletedSummaries(olderThan) {
|
|
262
|
+
return this.api.call("pruneDeletedSummaries", { olderThan: toIso(olderThan) });
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// ── User profile ────────────────────────────────────────────────────
|
|
266
|
+
|
|
267
|
+
async getCurrentUserProfile() {
|
|
268
|
+
return this.api.call("getCurrentUserProfile");
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
async setCurrentUserProfileSettings({ settings } = {}) {
|
|
272
|
+
return this.api.call("setCurrentUserProfileSettings", {
|
|
273
|
+
settings: settings && typeof settings === "object" && !Array.isArray(settings) ? settings : {},
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
async setCurrentUserGitHubCopilotKey({ key } = {}) {
|
|
278
|
+
return this.api.call("setCurrentUserGitHubCopilotKey", {
|
|
279
|
+
key: typeof key === "string" ? key : null,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// ── Models ──────────────────────────────────────────────────────────
|
|
284
|
+
|
|
285
|
+
async listModels() {
|
|
286
|
+
return this.api.call("listModels");
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// ── Events / history ────────────────────────────────────────────────
|
|
290
|
+
|
|
291
|
+
async getSessionEvents(sessionId, afterSeq, limit) {
|
|
292
|
+
return this.api.call("getSessionEvents", { sessionId, afterSeq, limit });
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
async getSessionEventsBefore(sessionId, beforeSeq, limit) {
|
|
296
|
+
return this.api.call("getSessionEventsBefore", { sessionId, beforeSeq, limit });
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
async getExecutionHistory(sessionId, executionId) {
|
|
300
|
+
return this.api.call("getExecutionHistory", { sessionId, executionId });
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
async exportExecutionHistory(sessionId) {
|
|
304
|
+
return this.api.call("exportExecutionHistory", { sessionId });
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// ── Artifacts ───────────────────────────────────────────────────────
|
|
308
|
+
|
|
309
|
+
async listArtifacts(sessionId) {
|
|
310
|
+
return this.api.call("listArtifacts", { sessionId });
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
async getArtifactMetadata(sessionId, filename) {
|
|
314
|
+
return this.api.call("getArtifactMetadata", { sessionId, filename });
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
async deleteArtifact(sessionId, filename) {
|
|
318
|
+
return this.api.call("deleteArtifact", { sessionId, filename });
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
async downloadArtifact(sessionId, filename) {
|
|
322
|
+
return this.api.call("downloadArtifact", { sessionId, filename });
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
async uploadArtifactContent(sessionId, filename, content, contentType, contentEncoding) {
|
|
326
|
+
return this.api.call("uploadArtifact", { sessionId, filename, content, contentType, contentEncoding });
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
getArtifactExportDirectory() {
|
|
330
|
+
return this.artifactExportDirectory || "Downloads";
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// ── Streaming ───────────────────────────────────────────────────────
|
|
334
|
+
|
|
335
|
+
subscribeSession(sessionId, handler) {
|
|
336
|
+
return this.api.subscribeSession(sessionId, handler);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
startLogTail(handler) {
|
|
340
|
+
return this.api.subscribeLogs(handler);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The PilotSwarm Web API protocol: one table describing every JSON operation
|
|
3
|
+
* under `/api/v1`, plus the WebSocket vocabulary and the error envelope.
|
|
4
|
+
*
|
|
5
|
+
* This table is the single source of truth for the contract. The portal
|
|
6
|
+
* server generates its Express routes from it, `ApiClient` builds requests
|
|
7
|
+
* from it, and `docs/api/reference.md` documents it. Operation names are
|
|
8
|
+
* exactly the method names of the portal runtime dispatcher
|
|
9
|
+
* (`packages/app/web/runtime.js`), which stays the single behavior point.
|
|
10
|
+
*
|
|
11
|
+
* Param placement (`in`):
|
|
12
|
+
* - "path" — URL path segment (`:name` in the template)
|
|
13
|
+
* - "query" — query string; `type` drives server-side coercion
|
|
14
|
+
* - "body" — JSON request body field
|
|
15
|
+
* Param types: "string" (default) | "number" | "boolean" | "json".
|
|
16
|
+
* "json" query params carry JSON-encoded values (e.g. the paging cursor).
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export const API_PREFIX = "/api/v1";
|
|
20
|
+
export const API_VERSION = 1;
|
|
21
|
+
|
|
22
|
+
/** WebSocket endpoint path (auth: Bearer header or ["access_token", <token>] subprotocol). */
|
|
23
|
+
export const WS_PATH = "/api/v1/ws";
|
|
24
|
+
|
|
25
|
+
/** WebSocket message vocabulary (same as the legacy /portal-ws, minus theme). */
|
|
26
|
+
export const WS_CLIENT_MESSAGES = ["subscribeSession", "unsubscribeSession", "subscribeLogs", "unsubscribeLogs"];
|
|
27
|
+
export const WS_SERVER_MESSAGES = ["ready", "subscribedSession", "sessionEvent", "subscribedLogs", "logEntry", "error"];
|
|
28
|
+
|
|
29
|
+
/** Error code used when an SDK web-mode method has no API equivalent. */
|
|
30
|
+
export const WEB_MODE_UNSUPPORTED = "WEB_MODE_UNSUPPORTED";
|
|
31
|
+
|
|
32
|
+
const path = (name) => ({ in: "path", name });
|
|
33
|
+
const query = (type = "string") => ({ in: "query", type });
|
|
34
|
+
const body = () => ({ in: "body" });
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @type {Array<{
|
|
38
|
+
* name: string,
|
|
39
|
+
* method: "GET"|"POST"|"PUT"|"PATCH"|"DELETE",
|
|
40
|
+
* path: string,
|
|
41
|
+
* params?: Record<string, { in: "path"|"query"|"body", name?: string, type?: string }>,
|
|
42
|
+
* summary: string,
|
|
43
|
+
* }>}
|
|
44
|
+
*/
|
|
45
|
+
export const OPERATIONS = [
|
|
46
|
+
// ── Sessions (client surface) ───────────────────────────────────────
|
|
47
|
+
{ name: "listSessions", method: "GET", path: "/sessions", summary: "List session summaries." },
|
|
48
|
+
{ name: "createSession", method: "POST", path: "/sessions", params: { model: body(), reasoningEffort: body(), groupId: body() }, summary: "Create a session. Owner is the authenticated principal." },
|
|
49
|
+
{ name: "createSessionForAgent", method: "POST", path: "/sessions/for-agent", params: { agentName: body(), model: body(), reasoningEffort: body(), title: body(), splash: body(), initialPrompt: body(), groupId: body() }, summary: "Create a session bound to a named agent." },
|
|
50
|
+
{ name: "getSession", method: "GET", path: "/sessions/:sessionId", params: { sessionId: path("sessionId") }, summary: "Get one session view (live orchestration status)." },
|
|
51
|
+
{ name: "deleteSession", method: "DELETE", path: "/sessions/:sessionId", params: { sessionId: path("sessionId") }, summary: "Cancel and soft-delete a session." },
|
|
52
|
+
{ name: "sendMessage", method: "POST", path: "/sessions/:sessionId/messages", params: { sessionId: path("sessionId"), prompt: body(), options: body() }, summary: "Send a prompt (options: { enqueueOnly?, clientMessageIds? })." },
|
|
53
|
+
{ name: "sendAnswer", method: "POST", path: "/sessions/:sessionId/answers", params: { sessionId: path("sessionId"), answer: body() }, summary: "Answer a pending input-required question." },
|
|
54
|
+
{ name: "sendSessionEvent", method: "POST", path: "/sessions/:sessionId/events", params: { sessionId: path("sessionId"), eventName: body(), data: body() }, summary: "Send a custom event into the session." },
|
|
55
|
+
{ name: "cancelPendingMessage", method: "POST", path: "/sessions/:sessionId/cancel-pending", params: { sessionId: path("sessionId"), clientMessageIds: body() }, summary: "Cancel queued messages by client message ids." },
|
|
56
|
+
|
|
57
|
+
// ── Session artifacts (JSON surface; binary download is a bespoke route) ──
|
|
58
|
+
{ name: "listArtifacts", method: "GET", path: "/sessions/:sessionId/artifacts", params: { sessionId: path("sessionId") }, summary: "List artifacts for a session." },
|
|
59
|
+
{ name: "getArtifactMetadata", method: "GET", path: "/sessions/:sessionId/artifacts/:filename/meta", params: { sessionId: path("sessionId"), filename: path("filename") }, summary: "Artifact metadata." },
|
|
60
|
+
{ name: "downloadArtifact", method: "GET", path: "/sessions/:sessionId/artifacts/:filename/text", params: { sessionId: path("sessionId"), filename: path("filename") }, summary: "Artifact content as text (JSON envelope). Binary: GET …/download." },
|
|
61
|
+
{ name: "uploadArtifact", method: "PUT", path: "/sessions/:sessionId/artifacts/:filename", params: { sessionId: path("sessionId"), filename: path("filename"), content: body(), contentType: body(), contentEncoding: body() }, summary: "Upload artifact content (base64 for binary; 2 MB JSON limit)." },
|
|
62
|
+
{ name: "deleteArtifact", method: "DELETE", path: "/sessions/:sessionId/artifacts/:filename", params: { sessionId: path("sessionId"), filename: path("filename") }, summary: "Delete an artifact." },
|
|
63
|
+
|
|
64
|
+
// ── Management: sessions ────────────────────────────────────────────
|
|
65
|
+
{ name: "listSessionsPage", method: "GET", path: "/management/sessions", params: { limit: query("number"), cursor: query("json"), includeDeleted: query("boolean") }, summary: "Keyset-paginated session listing." },
|
|
66
|
+
{ name: "renameSession", method: "PATCH", path: "/management/sessions/:sessionId", params: { sessionId: path("sessionId"), title: body() }, summary: "Rename a session." },
|
|
67
|
+
{ name: "cancelSession", method: "POST", path: "/management/sessions/:sessionId/cancel", params: { sessionId: path("sessionId") }, summary: "Cancel a session." },
|
|
68
|
+
{ name: "completeSession", method: "POST", path: "/management/sessions/:sessionId/complete", params: { sessionId: path("sessionId"), reason: body() }, summary: "Mark a session completed." },
|
|
69
|
+
{ name: "stopSessionTurn", method: "POST", path: "/management/sessions/:sessionId/stop-turn", params: { sessionId: path("sessionId"), options: body() }, summary: "Abort the in-flight turn." },
|
|
70
|
+
{ name: "setSessionModel", method: "POST", path: "/management/sessions/:sessionId/model", params: { sessionId: path("sessionId"), options: body() }, summary: "Switch the session model ({ model, reasoningEffort? })." },
|
|
71
|
+
{ name: "restartSystemSession", method: "POST", path: "/management/sessions/:agentIdOrSessionId/restart-system", params: { agentIdOrSessionId: path("agentIdOrSessionId"), options: body() }, summary: "Restart a system session (complete | terminate | hard_delete)." },
|
|
72
|
+
{ name: "exportExecutionHistory", method: "POST", path: "/management/sessions/:sessionId/export-execution-history", params: { sessionId: path("sessionId") }, summary: "Export execution history to an artifact; returns artifact meta." },
|
|
73
|
+
{ name: "getSessionStatus", method: "GET", path: "/management/sessions/:sessionId/status", params: { sessionId: path("sessionId") }, summary: "Live custom status + orchestration status." },
|
|
74
|
+
{ name: "waitForStatusChange", method: "GET", path: "/management/sessions/:sessionId/status/wait", params: { sessionId: path("sessionId"), afterVersion: query("number"), timeoutMs: query("number") }, summary: "Long-poll for a status version change (server-capped timeout)." },
|
|
75
|
+
{ name: "getLatestResponse", method: "GET", path: "/management/sessions/:sessionId/latest-response", params: { sessionId: path("sessionId") }, summary: "Latest turn response payload, if any." },
|
|
76
|
+
{ name: "getOrchestrationStats", method: "GET", path: "/management/sessions/:sessionId/orchestration-stats", params: { sessionId: path("sessionId") }, summary: "Orchestration runtime stats." },
|
|
77
|
+
{ name: "getExecutionHistory", method: "GET", path: "/management/sessions/:sessionId/execution-history", params: { sessionId: path("sessionId"), executionId: query("number") }, summary: "Raw execution history events." },
|
|
78
|
+
{ name: "getSessionEvents", method: "GET", path: "/management/sessions/:sessionId/events", params: { sessionId: path("sessionId"), afterSeq: query("number"), limit: query("number") }, summary: "Session events after a sequence number (reconnect catch-up)." },
|
|
79
|
+
{ name: "getSessionEventsBefore", method: "GET", path: "/management/sessions/:sessionId/events-before", params: { sessionId: path("sessionId"), beforeSeq: query("number"), limit: query("number") }, summary: "Older session events for history paging." },
|
|
80
|
+
{ name: "getSessionMetricSummary", method: "GET", path: "/management/sessions/:sessionId/metric-summary", params: { sessionId: path("sessionId") }, summary: "Per-session metric summary." },
|
|
81
|
+
{ name: "getSessionTokensByModel", method: "GET", path: "/management/sessions/:sessionId/tokens-by-model", params: { sessionId: path("sessionId") }, summary: "Token totals grouped by model." },
|
|
82
|
+
{ name: "getSessionTreeStats", method: "GET", path: "/management/sessions/:sessionId/tree-stats", params: { sessionId: path("sessionId") }, summary: "Stats rolled up across the spawn tree." },
|
|
83
|
+
{ name: "getSessionSkillUsage", method: "GET", path: "/management/sessions/:sessionId/skill-usage", params: { sessionId: path("sessionId"), since: query("string") }, summary: "Skill usage for one session." },
|
|
84
|
+
{ name: "getSessionTreeSkillUsage", method: "GET", path: "/management/sessions/:sessionId/tree-skill-usage", params: { sessionId: path("sessionId"), since: query("string") }, summary: "Skill usage across the spawn tree." },
|
|
85
|
+
{ name: "getSessionFactsStats", method: "GET", path: "/management/sessions/:sessionId/facts-stats", params: { sessionId: path("sessionId") }, summary: "Facts stats for one session." },
|
|
86
|
+
{ name: "getSessionTreeFactsStats", method: "GET", path: "/management/sessions/:sessionId/tree-facts-stats", params: { sessionId: path("sessionId") }, summary: "Facts stats across the spawn tree." },
|
|
87
|
+
{ name: "listChildOutcomes", method: "GET", path: "/management/sessions/:parentSessionId/child-outcomes", params: { parentSessionId: path("parentSessionId") }, summary: "Child outcomes recorded under a parent session." },
|
|
88
|
+
{ name: "getChildOutcome", method: "GET", path: "/management/child-outcomes/:childSessionId", params: { childSessionId: path("childSessionId") }, summary: "One child outcome." },
|
|
89
|
+
|
|
90
|
+
// ── Management: session groups ──────────────────────────────────────
|
|
91
|
+
{ name: "listSessionGroups", method: "GET", path: "/management/session-groups", summary: "List session groups." },
|
|
92
|
+
{ name: "createSessionGroup", method: "POST", path: "/management/session-groups", params: { input: body() }, summary: "Create a session group." },
|
|
93
|
+
{ name: "updateSessionGroup", method: "PATCH", path: "/management/session-groups/:groupId", params: { groupId: path("groupId"), patch: body() }, summary: "Update group title/description." },
|
|
94
|
+
{ name: "deleteSessionGroup", method: "DELETE", path: "/management/session-groups/:groupId", params: { groupId: path("groupId") }, summary: "Delete an empty session group." },
|
|
95
|
+
{ name: "assignSessionsToGroup", method: "POST", path: "/management/session-groups/:groupId/assign", params: { groupId: path("groupId"), sessionIds: body() }, summary: "Assign sessions to a group." },
|
|
96
|
+
{ name: "cancelSessionGroup", method: "POST", path: "/management/session-groups/:groupId/cancel", params: { groupId: path("groupId"), reason: body() }, summary: "Cancel all sessions in a group." },
|
|
97
|
+
{ name: "completeSessionGroup", method: "POST", path: "/management/session-groups/:groupId/complete", params: { groupId: path("groupId"), options: body() }, summary: "Complete all sessions in a group." },
|
|
98
|
+
{ name: "moveSessionsToGroup", method: "POST", path: "/management/session-groups/move", params: { groupId: body(), sessionIds: body() }, summary: "Move sessions between groups (groupId null = ungroup)." },
|
|
99
|
+
|
|
100
|
+
// ── Management: fleet / users / facts / events ──────────────────────
|
|
101
|
+
{ name: "getFleetStats", method: "GET", path: "/management/fleet/stats", params: { since: query("string"), includeDeleted: query("boolean") }, summary: "Fleet-wide stats." },
|
|
102
|
+
{ name: "getFleetSkillUsage", method: "GET", path: "/management/fleet/skill-usage", params: { since: query("string"), includeDeleted: query("boolean") }, summary: "Fleet-wide skill usage." },
|
|
103
|
+
{ name: "getFleetRetrievalUsage", method: "GET", path: "/management/fleet/retrieval-usage", params: { since: query("string"), includeDeleted: query("boolean") }, summary: "Fleet-wide retrieval usage." },
|
|
104
|
+
{ name: "getUserStats", method: "GET", path: "/management/users/stats", params: { since: query("string"), includeDeleted: query("boolean") }, summary: "Per-user stats." },
|
|
105
|
+
{ name: "getSharedFactsStats", method: "GET", path: "/management/facts/shared-stats", summary: "Shared facts stats." },
|
|
106
|
+
{ name: "getFactsTombstoneStats", method: "GET", path: "/management/facts/tombstone-stats", params: { ttlSeconds: query("number") }, summary: "Soft-deleted facts awaiting reconciliation." },
|
|
107
|
+
{ name: "getTopEventEmitters", method: "GET", path: "/management/events/top-emitters", params: { since: query("string"), limit: query("number") }, summary: "Noisiest event emitters since a date." },
|
|
108
|
+
{ name: "pruneDeletedSummaries", method: "POST", path: "/management/summaries/prune-deleted", params: { olderThan: body() }, summary: "Prune summaries of deleted sessions." },
|
|
109
|
+
|
|
110
|
+
// ── Facts data-plane (Tier 1: any admitted caller) ──────────────────
|
|
111
|
+
{ name: "factsCapabilities", method: "GET", path: "/facts/capabilities", summary: "Store capabilities: { search, embedder, graph } — the remote isEnhancedFactStore/isGraphStore." },
|
|
112
|
+
{ name: "readFacts", method: "GET", path: "/facts", params: { keyPattern: query("string"), scopeKeys: query("json"), tags: query("json"), sessionId: query("string"), agentId: query("string"), limit: query("number"), scope: query("string") }, summary: "Read facts (ReadFactsQuery params)." },
|
|
113
|
+
{ name: "storeFact", method: "POST", path: "/facts", params: { input: body() }, summary: "Store a fact or facts (StoreFactInput | StoreFactInput[])." },
|
|
114
|
+
{ name: "deleteFact", method: "POST", path: "/facts/delete", params: { input: body() }, summary: "Delete a fact / pattern (DeleteFactInput). POST because DELETE bodies are unreliable." },
|
|
115
|
+
{ name: "searchFacts", method: "POST", path: "/facts/search", params: { query: body(), opts: body() }, summary: "Retrieval over facts (lexical | semantic | hybrid). [enhanced]" },
|
|
116
|
+
{ name: "similarFacts", method: "POST", path: "/facts/similar", params: { scopeKey: body(), opts: body() }, summary: "Semantic nearest-neighbours of a known fact. [enhanced]" },
|
|
117
|
+
|
|
118
|
+
// ── Facts operational (Tier 2: admin) ───────────────────────────────
|
|
119
|
+
{ name: "getEmbedderStatus", method: "GET", path: "/facts/embedder", summary: "Durable embedder status. [enhanced]" },
|
|
120
|
+
{ name: "startFactsEmbedder", method: "POST", path: "/facts/embedder/start", params: { intervalSeconds: body(), batch: body() }, admin: true, summary: "Start the durable embedder loop. [enhanced, admin]" },
|
|
121
|
+
{ name: "stopFactsEmbedder", method: "POST", path: "/facts/embedder/stop", params: { reason: body() }, admin: true, summary: "Stop the durable embedder loop. [enhanced, admin]" },
|
|
122
|
+
{ name: "forcePurgeFacts", method: "POST", path: "/facts/purge", params: { input: body() }, admin: true, summary: "Force-purge soft-deleted facts (ForcePurgeFactsInput). [admin]" },
|
|
123
|
+
|
|
124
|
+
// ── Graph data-plane (Tier 1: any admitted caller) ──────────────────
|
|
125
|
+
{ name: "searchGraphNodes", method: "POST", path: "/graph/nodes/search", params: { query: body() }, summary: "Search graph nodes (GraphNodeQuery)." },
|
|
126
|
+
{ name: "searchGraphEdges", method: "POST", path: "/graph/edges/search", params: { query: body() }, summary: "Search graph edges (GraphEdgeQuery)." },
|
|
127
|
+
{ name: "graphNeighbourhood", method: "POST", path: "/graph/neighbourhood", params: { nodeKey: body(), depth: body(), namespace: body() }, summary: "Expand a subgraph around a node." },
|
|
128
|
+
{ name: "upsertGraphNode", method: "POST", path: "/graph/nodes", params: { input: body() }, summary: "Upsert a graph node (GraphNodeInput)." },
|
|
129
|
+
{ name: "upsertGraphEdge", method: "POST", path: "/graph/edges", params: { input: body() }, summary: "Upsert a graph edge (GraphEdgeInput)." },
|
|
130
|
+
{ name: "deleteGraphNode", method: "POST", path: "/graph/nodes/delete", params: { nodeKey: body(), namespace: body() }, summary: "Delete a graph node." },
|
|
131
|
+
{ name: "deleteGraphEdge", method: "POST", path: "/graph/edges/delete", params: { fromKey: body(), toKey: body(), predicateKey: body(), namespace: body() }, summary: "Delete a graph edge." },
|
|
132
|
+
{ name: "graphStats", method: "GET", path: "/graph/stats", params: { namespace: query("string") }, summary: "Graph node/edge counts." },
|
|
133
|
+
{ name: "listGraphNamespaces", method: "GET", path: "/graph/namespaces", params: { prefix: query("string"), includeArchived: query("boolean"), includeDetails: query("boolean") }, summary: "List graph namespaces (corpora)." },
|
|
134
|
+
{ name: "getGraphNamespace", method: "GET", path: "/graph/namespaces/:namespace", params: { namespace: path("namespace") }, summary: "One graph namespace descriptor." },
|
|
135
|
+
|
|
136
|
+
// ── Graph operational (Tier 2: admin) ───────────────────────────────
|
|
137
|
+
{ name: "upsertGraphNamespace", method: "POST", path: "/graph/namespaces", params: { input: body() }, admin: true, summary: "Register/update a graph namespace. [admin]" },
|
|
138
|
+
{ name: "deleteGraphNamespace", method: "DELETE", path: "/graph/namespaces/:namespace", params: { namespace: path("namespace") }, admin: true, summary: "Delete a graph namespace and its data. [admin]" },
|
|
139
|
+
|
|
140
|
+
// ── Models / agents / policy ────────────────────────────────────────
|
|
141
|
+
{ name: "listModels", method: "GET", path: "/models", summary: "All available models." },
|
|
142
|
+
{ name: "getModelsByProvider", method: "GET", path: "/models/by-provider", summary: "Models grouped by provider." },
|
|
143
|
+
{ name: "getDefaultModel", method: "GET", path: "/models/default", summary: "The deployment default model." },
|
|
144
|
+
{ name: "listCreatableAgents", method: "GET", path: "/agents", summary: "Agents sessions can be created for." },
|
|
145
|
+
{ name: "getSessionCreationPolicy", method: "GET", path: "/session-creation-policy", summary: "Session creation policy." },
|
|
146
|
+
|
|
147
|
+
// ── Current user profile ────────────────────────────────────────────
|
|
148
|
+
{ name: "getCurrentUserProfile", method: "GET", path: "/me/profile", summary: "Profile of the authenticated principal." },
|
|
149
|
+
{ name: "setCurrentUserProfileSettings", method: "PATCH", path: "/me/profile/settings", params: { settings: body() }, summary: "Replace profile settings." },
|
|
150
|
+
{ name: "setCurrentUserGitHubCopilotKey", method: "PUT", path: "/me/github-copilot-key", params: { key: body() }, summary: "Set (or clear with null) the per-user GitHub Copilot key." },
|
|
151
|
+
|
|
152
|
+
// ── System ──────────────────────────────────────────────────────────
|
|
153
|
+
{ name: "getLogConfig", method: "GET", path: "/system/log-config", summary: "Log tail availability." },
|
|
154
|
+
{ name: "getWorkerCount", method: "GET", path: "/system/workers", summary: "Live worker count." },
|
|
155
|
+
];
|
|
156
|
+
|
|
157
|
+
const OPERATIONS_BY_NAME = new Map(OPERATIONS.map((op) => [op.name, op]));
|
|
158
|
+
|
|
159
|
+
export function getOperation(name) {
|
|
160
|
+
return OPERATIONS_BY_NAME.get(name) || null;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Build the HTTP request for an operation from an rpc-shaped params object
|
|
165
|
+
* (the exact shapes the legacy /api/rpc dispatcher accepts).
|
|
166
|
+
*
|
|
167
|
+
* @returns {{ method: string, path: string, query: URLSearchParams, body: object|null }}
|
|
168
|
+
*/
|
|
169
|
+
export function buildOperationRequest(name, params = {}) {
|
|
170
|
+
const op = getOperation(name);
|
|
171
|
+
if (!op) throw new Error(`Unknown API operation: ${name}`);
|
|
172
|
+
const safeParams = params && typeof params === "object" ? params : {};
|
|
173
|
+
|
|
174
|
+
let resolvedPath = op.path;
|
|
175
|
+
const queryParams = new URLSearchParams();
|
|
176
|
+
let bodyPayload = null;
|
|
177
|
+
|
|
178
|
+
for (const [key, spec] of Object.entries(op.params || {})) {
|
|
179
|
+
const value = safeParams[key];
|
|
180
|
+
if (spec.in === "path") {
|
|
181
|
+
const raw = value == null ? "" : String(value);
|
|
182
|
+
if (!raw) throw new Error(`API operation ${name} requires param '${key}'`);
|
|
183
|
+
resolvedPath = resolvedPath.replace(`:${spec.name || key}`, encodeURIComponent(raw));
|
|
184
|
+
} else if (spec.in === "query") {
|
|
185
|
+
if (value === undefined || value === null) continue;
|
|
186
|
+
queryParams.set(key, spec.type === "json" ? JSON.stringify(value) : String(value));
|
|
187
|
+
} else {
|
|
188
|
+
if (value === undefined) continue;
|
|
189
|
+
if (!bodyPayload) bodyPayload = {};
|
|
190
|
+
bodyPayload[key] = value;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (resolvedPath.includes("/:")) {
|
|
195
|
+
throw new Error(`API operation ${name} is missing required path params (${op.path})`);
|
|
196
|
+
}
|
|
197
|
+
return { method: op.method, path: `${API_PREFIX}${resolvedPath}`, query: queryParams, body: bodyPayload };
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/** Coerce a query-string value per the declared param type (server side). */
|
|
201
|
+
export function coerceQueryValue(value, type) {
|
|
202
|
+
if (value === undefined || value === null) return undefined;
|
|
203
|
+
if (type === "number") {
|
|
204
|
+
const numeric = Number(value);
|
|
205
|
+
return Number.isFinite(numeric) ? numeric : undefined;
|
|
206
|
+
}
|
|
207
|
+
if (type === "boolean") return value === "true" || value === true;
|
|
208
|
+
if (type === "json") {
|
|
209
|
+
try {
|
|
210
|
+
return JSON.parse(String(value));
|
|
211
|
+
} catch {
|
|
212
|
+
throw Object.assign(new Error("Malformed JSON query parameter"), { code: "INVALID_REQUEST" });
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return String(value);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/** Path for the raw (streaming) artifact download route. */
|
|
219
|
+
export function artifactDownloadPath(sessionId, filename) {
|
|
220
|
+
return `${API_PREFIX}/sessions/${encodeURIComponent(String(sessionId || ""))}/artifacts/${encodeURIComponent(String(filename || ""))}/download`;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export class ApiError extends Error {
|
|
224
|
+
constructor(message, { code = "INTERNAL_ERROR", status = 500 } = {}) {
|
|
225
|
+
super(message);
|
|
226
|
+
this.name = "ApiError";
|
|
227
|
+
this.code = code;
|
|
228
|
+
this.status = status;
|
|
229
|
+
}
|
|
230
|
+
}
|
package/dist/client.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { PilotSwarmClientOptions, ManagedSessionConfig, PilotSwarmSessionInfo, UserInputHandler, SessionOwnerInfo } from "./types.js";
|
|
2
2
|
import type { SessionCatalog, SessionEvent } from "./cms.js";
|
|
3
|
+
import { type PilotSwarmWebOptions } from "./web/api-connection.js";
|
|
3
4
|
/**
|
|
4
5
|
* PilotSwarmClient — pure client-side session handle.
|
|
5
6
|
*
|
|
@@ -35,7 +36,7 @@ export declare class PilotSwarmClient {
|
|
|
35
36
|
private get _sessionPolicy();
|
|
36
37
|
/** Allowed agent names (set via config from worker). */
|
|
37
38
|
private get _allowedAgentNames();
|
|
38
|
-
constructor(options: PilotSwarmClientOptions);
|
|
39
|
+
constructor(options: PilotSwarmClientOptions | PilotSwarmWebOptions);
|
|
39
40
|
createSession(config?: ManagedSessionConfig & {
|
|
40
41
|
sessionId?: string;
|
|
41
42
|
onUserInputRequest?: UserInputHandler;
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACR,uBAAuB,EACvB,oBAAoB,EAGpB,qBAAqB,EAErB,gBAAgB,EAIhB,gBAAgB,EACnB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
CHANGED
|
@@ -3,6 +3,8 @@ import { DURABLE_SESSION_LATEST_VERSION, DURABLE_SESSION_ORCHESTRATION_NAME, } f
|
|
|
3
3
|
import { resolveStorageConfig } from "./storage-config.js";
|
|
4
4
|
import { getDuroxideStorageProvider, getRuntimeStorageProvider } from "./storage-providers.js";
|
|
5
5
|
import { deriveStatusFromCmsAndRuntime, shouldSyncCompletedStatus, shouldSyncFailedStatus } from "./session-status.js";
|
|
6
|
+
import { assertUnambiguousProvider, isWebOptions } from "./web/api-connection.js";
|
|
7
|
+
import { WebPilotSwarmClient } from "./web/web-client.js";
|
|
6
8
|
// duroxide is CommonJS — use createRequire for ESM compatibility
|
|
7
9
|
import { createRequire } from "node:module";
|
|
8
10
|
const require = createRequire(import.meta.url);
|
|
@@ -60,6 +62,13 @@ export class PilotSwarmClient {
|
|
|
60
62
|
return this.config.allowedAgentNames ?? [];
|
|
61
63
|
}
|
|
62
64
|
constructor(options) {
|
|
65
|
+
assertUnambiguousProvider(options, "PilotSwarmClient");
|
|
66
|
+
if (isWebOptions(options)) {
|
|
67
|
+
// Web mode — the supported public mode: talk to a deployment's
|
|
68
|
+
// Web API instead of the datastore. The returned object carries
|
|
69
|
+
// the same session-handle programming model (WebPilotSwarmClient).
|
|
70
|
+
return new WebPilotSwarmClient(options);
|
|
71
|
+
}
|
|
63
72
|
this.config = {
|
|
64
73
|
...options,
|
|
65
74
|
waitThreshold: options.waitThreshold ?? 30,
|