@openwop/openwop 1.1.3 → 1.1.6
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/dist/client.d.ts +133 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +368 -1
- package/dist/client.js.map +1 -1
- package/dist/event-helpers.d.ts +4 -1
- package/dist/event-helpers.d.ts.map +1 -1
- package/dist/event-helpers.js +7 -0
- package/dist/event-helpers.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +378 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +393 -1
- package/src/event-helpers.ts +13 -0
- package/src/index.ts +34 -0
- package/src/types.ts +415 -1
package/src/client.ts
CHANGED
|
@@ -22,6 +22,10 @@ import {
|
|
|
22
22
|
type ErrorEnvelope,
|
|
23
23
|
type ForkRunRequest,
|
|
24
24
|
type ForkRunResponse,
|
|
25
|
+
type Annotation,
|
|
26
|
+
type CreateAnnotationRequest,
|
|
27
|
+
type WorkspaceFile,
|
|
28
|
+
type PutWorkspaceFileRequest,
|
|
25
29
|
type GetPromptRequest,
|
|
26
30
|
type InterruptByTokenInspection,
|
|
27
31
|
type DebugBundle,
|
|
@@ -41,8 +45,24 @@ import {
|
|
|
41
45
|
type ResolveInterruptResponse,
|
|
42
46
|
type ResumeRunRequest,
|
|
43
47
|
type ResumeRunResponse,
|
|
48
|
+
type RunAncestryResponse,
|
|
49
|
+
type RunDiffResponse,
|
|
44
50
|
type RunEventDoc,
|
|
45
51
|
type RunSnapshot,
|
|
52
|
+
type AgentInventoryEntry,
|
|
53
|
+
type AgentInventoryResponse,
|
|
54
|
+
type AgentRosterEntry,
|
|
55
|
+
type AgentRosterResponse,
|
|
56
|
+
type AgentOrgChart,
|
|
57
|
+
type OrgChartResponsibilityView,
|
|
58
|
+
type EvalSummary,
|
|
59
|
+
type AgentDeployment,
|
|
60
|
+
type AgentDeploymentTransition,
|
|
61
|
+
type CreateUserAgentRequest,
|
|
62
|
+
type UserAgentRecord,
|
|
63
|
+
type AgentPackRegistryResponse,
|
|
64
|
+
type InstallAgentPackRequest,
|
|
65
|
+
type InstallAgentPackResponse,
|
|
46
66
|
} from './types.js';
|
|
47
67
|
|
|
48
68
|
export interface OpenwopClientOptions {
|
|
@@ -142,7 +162,7 @@ export class OpenwopClient {
|
|
|
142
162
|
} catch (err) {
|
|
143
163
|
// Host doesn't advertise the capability → 404. Surface as null so callers
|
|
144
164
|
// can branch on capability discovery without try/catch.
|
|
145
|
-
if (err instanceof
|
|
165
|
+
if (err instanceof WopError && err.status === 404) return null;
|
|
146
166
|
throw err;
|
|
147
167
|
}
|
|
148
168
|
},
|
|
@@ -215,6 +235,105 @@ export class OpenwopClient {
|
|
|
215
235
|
headers: this.#mutationHeaders(opts),
|
|
216
236
|
}),
|
|
217
237
|
|
|
238
|
+
/**
|
|
239
|
+
* RFC 0056 — record a non-blocking quality annotation (rating / correction
|
|
240
|
+
* / label / flag) on a run/event/node. Returns the persisted `Annotation`.
|
|
241
|
+
* Throws on non-2xx (`501` when the host doesn't advertise
|
|
242
|
+
* `capabilities.feedback.supported`).
|
|
243
|
+
*/
|
|
244
|
+
createAnnotation: (
|
|
245
|
+
runId: string,
|
|
246
|
+
body: CreateAnnotationRequest,
|
|
247
|
+
opts: MutationOptions = {},
|
|
248
|
+
): Promise<Annotation> =>
|
|
249
|
+
this.#request<Annotation>({
|
|
250
|
+
method: 'POST',
|
|
251
|
+
path: `/v1/runs/${encodeURIComponent(runId)}/annotations`,
|
|
252
|
+
body,
|
|
253
|
+
headers: this.#mutationHeaders(opts),
|
|
254
|
+
}),
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* RFC 0056 — list a run's annotations (tenant-scoped). Returns `null` when
|
|
258
|
+
* the host doesn't advertise `capabilities.feedback` (404/501), so callers
|
|
259
|
+
* can branch on capability discovery without try/catch.
|
|
260
|
+
*/
|
|
261
|
+
listAnnotations: async (runId: string): Promise<readonly Annotation[] | null> => {
|
|
262
|
+
try {
|
|
263
|
+
const res = await this.#request<{ annotations: Annotation[] }>({
|
|
264
|
+
method: 'GET',
|
|
265
|
+
path: `/v1/runs/${encodeURIComponent(runId)}/annotations`,
|
|
266
|
+
});
|
|
267
|
+
return res.annotations;
|
|
268
|
+
} catch (err) {
|
|
269
|
+
if (err instanceof WopError && (err.status === 404 || err.status === 501)) return null;
|
|
270
|
+
throw err;
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* RFC 0040 §C — fetch the run's immediate parent in the cross-host
|
|
276
|
+
* composition chain. Returns `parent: null` for top-level runs;
|
|
277
|
+
* `parent.wellKnownUrl` is set when the parent is on a different
|
|
278
|
+
* host, so callers walk the chain one hop at a time.
|
|
279
|
+
*
|
|
280
|
+
* Returns `null` when the host doesn't advertise
|
|
281
|
+
* `capabilities.multiAgent.executionModel.crossHostCausation.ancestryEndpointSupported: true`
|
|
282
|
+
* (the endpoint returns 404 in that case per
|
|
283
|
+
* `spec/v1/multi-agent-execution.md` §"GET /v1/runs/{runId}/ancestry").
|
|
284
|
+
*/
|
|
285
|
+
ancestry: async (runId: string): Promise<RunAncestryResponse | null> => {
|
|
286
|
+
try {
|
|
287
|
+
return await this.#request<RunAncestryResponse>({
|
|
288
|
+
method: 'GET',
|
|
289
|
+
path: `/v1/runs/${encodeURIComponent(runId)}/ancestry`,
|
|
290
|
+
});
|
|
291
|
+
} catch (err) {
|
|
292
|
+
if (err instanceof WopError && err.status === 404) return null;
|
|
293
|
+
throw err;
|
|
294
|
+
}
|
|
295
|
+
},
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* RFC 0054 — deterministic, replay-aware structured diff of two runs
|
|
299
|
+
* (typically a run and its `:fork`). Requires `runs:read` on BOTH
|
|
300
|
+
* `runId` and `against`. Returns `null` when the host doesn't
|
|
301
|
+
* implement the endpoint (404 per `spec/v1/rest-endpoints.md`
|
|
302
|
+
* §`GET /v1/runs/{runId}:diff`). `divergedAtSeq` is null + `eventDiffs`
|
|
303
|
+
* empty when the two logs are identical.
|
|
304
|
+
*/
|
|
305
|
+
diff: async (runId: string, against: string): Promise<RunDiffResponse | null> => {
|
|
306
|
+
try {
|
|
307
|
+
return await this.#request<RunDiffResponse>({
|
|
308
|
+
method: 'GET',
|
|
309
|
+
path: `/v1/runs/${encodeURIComponent(runId)}:diff?against=${encodeURIComponent(against)}`,
|
|
310
|
+
});
|
|
311
|
+
} catch (err) {
|
|
312
|
+
if (err instanceof WopError && err.status === 404) return null;
|
|
313
|
+
throw err;
|
|
314
|
+
}
|
|
315
|
+
},
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* RFC 0081 §C — the `EvalSummary` scorecard for a terminal eval run (one
|
|
319
|
+
* started via `runs.create({ mode: 'eval', evalSuiteRef, agentId })`):
|
|
320
|
+
* aggregate + per-task scores, cost, latency, schema-validity, and
|
|
321
|
+
* redaction-safe safety findings. Returns `null` when the host doesn't
|
|
322
|
+
* advertise `capabilities.agents.evalSuite` or the run isn't an eval run
|
|
323
|
+
* (404). Throws `409` while the run is still in progress.
|
|
324
|
+
*/
|
|
325
|
+
evalSummary: async (runId: string): Promise<EvalSummary | null> => {
|
|
326
|
+
try {
|
|
327
|
+
return await this.#request<EvalSummary>({
|
|
328
|
+
method: 'GET',
|
|
329
|
+
path: `/v1/runs/${encodeURIComponent(runId)}/eval-summary`,
|
|
330
|
+
});
|
|
331
|
+
} catch (err) {
|
|
332
|
+
if (err instanceof WopError && err.status === 404) return null;
|
|
333
|
+
throw err;
|
|
334
|
+
}
|
|
335
|
+
},
|
|
336
|
+
|
|
218
337
|
pollEvents: (
|
|
219
338
|
runId: string,
|
|
220
339
|
params: { lastSequence?: number; timeoutSeconds?: number } = {},
|
|
@@ -242,6 +361,191 @@ export class OpenwopClient {
|
|
|
242
361
|
streamEvents({ baseUrl: this.#baseUrl, apiKey: this.#apiKey }, runId, opts),
|
|
243
362
|
};
|
|
244
363
|
|
|
364
|
+
// ── Manifest-agent inventory (RFC 0072 §A) ───────────────────────────
|
|
365
|
+
// Read-only. Gated on `capabilities.agents.manifestRuntime`; both methods
|
|
366
|
+
// return `null` when the host doesn't advertise it (the endpoints 404).
|
|
367
|
+
// Dispatch is not here: a manifest agent runs as a `runs.create` whose
|
|
368
|
+
// workflow node pins it via `WorkflowNode.agent` (RFC 0072 §B).
|
|
369
|
+
readonly agents = {
|
|
370
|
+
list: async (): Promise<AgentInventoryResponse | null> => {
|
|
371
|
+
try {
|
|
372
|
+
return await this.#request<AgentInventoryResponse>({ method: 'GET', path: '/v1/agents' });
|
|
373
|
+
} catch (err) {
|
|
374
|
+
if (err instanceof WopError && err.status === 404) return null;
|
|
375
|
+
throw err;
|
|
376
|
+
}
|
|
377
|
+
},
|
|
378
|
+
|
|
379
|
+
get: async (agentId: string): Promise<AgentInventoryEntry | null> => {
|
|
380
|
+
try {
|
|
381
|
+
return await this.#request<AgentInventoryEntry>({
|
|
382
|
+
method: 'GET',
|
|
383
|
+
path: `/v1/agents/${encodeURIComponent(agentId)}`,
|
|
384
|
+
});
|
|
385
|
+
} catch (err) {
|
|
386
|
+
if (err instanceof WopError && err.status === 404) return null;
|
|
387
|
+
throw err;
|
|
388
|
+
}
|
|
389
|
+
},
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* RFC 0082 §C/§E — list a manifest agent's deployment records (per-(agentId,
|
|
393
|
+
* version) lifecycle state + channels + canary + rollback pointer). Returns
|
|
394
|
+
* `null` when the host doesn't advertise `capabilities.agents.deployment`
|
|
395
|
+
* (the endpoint 404s).
|
|
396
|
+
*/
|
|
397
|
+
listDeployments: async (agentId: string): Promise<readonly AgentDeployment[] | null> => {
|
|
398
|
+
try {
|
|
399
|
+
return await this.#request<AgentDeployment[]>({
|
|
400
|
+
method: 'GET',
|
|
401
|
+
path: `/v1/agents/${encodeURIComponent(agentId)}/deployments`,
|
|
402
|
+
});
|
|
403
|
+
} catch (err) {
|
|
404
|
+
if (err instanceof WopError && err.status === 404) return null;
|
|
405
|
+
throw err;
|
|
406
|
+
}
|
|
407
|
+
},
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* RFC 0082 §E — request a deployment state transition (promote / pause /
|
|
411
|
+
* deprecate / rollback / adjust-canary). The host authorizes fail-closed
|
|
412
|
+
* against the RFC 0049 `deploy:*` scope, runs any RFC 0051 approvalGate, and
|
|
413
|
+
* enforces RFC 0081 `requiredEval` before emitting `deployment.promoted`.
|
|
414
|
+
* Returns the updated deployment record. Throws on non-2xx (`403` fail-closed
|
|
415
|
+
* / `eval_gate_unmet`; `400` `no_active_deployment` / unsupported state).
|
|
416
|
+
*/
|
|
417
|
+
transitionDeployment: (
|
|
418
|
+
agentId: string,
|
|
419
|
+
body: AgentDeploymentTransition,
|
|
420
|
+
opts: MutationOptions = {},
|
|
421
|
+
): Promise<AgentDeployment> =>
|
|
422
|
+
this.#request<AgentDeployment>({
|
|
423
|
+
method: 'POST',
|
|
424
|
+
path: `/v1/agents/${encodeURIComponent(agentId)}/deployments`,
|
|
425
|
+
body,
|
|
426
|
+
headers: this.#mutationHeaders(opts),
|
|
427
|
+
}),
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* RFC 0086 §B — list the standing agent roster (named instances + their
|
|
431
|
+
* workflow portfolios) visible to the caller. Returns `null` when the host
|
|
432
|
+
* doesn't advertise `capabilities.agents.roster` (the endpoint 404s).
|
|
433
|
+
*/
|
|
434
|
+
listRoster: async (): Promise<AgentRosterResponse | null> => {
|
|
435
|
+
try {
|
|
436
|
+
return await this.#request<AgentRosterResponse>({ method: 'GET', path: '/v1/agents/roster' });
|
|
437
|
+
} catch (err) {
|
|
438
|
+
if (err instanceof WopError && err.status === 404) return null;
|
|
439
|
+
throw err;
|
|
440
|
+
}
|
|
441
|
+
},
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* RFC 0086 §B — return one standing roster entry. Returns `null` on 404
|
|
445
|
+
* (no such entry, cross-tenant, or the capability is unadvertised).
|
|
446
|
+
*/
|
|
447
|
+
getRosterEntry: async (rosterId: string): Promise<AgentRosterEntry | null> => {
|
|
448
|
+
try {
|
|
449
|
+
return await this.#request<AgentRosterEntry>({
|
|
450
|
+
method: 'GET',
|
|
451
|
+
path: `/v1/agents/roster/${encodeURIComponent(rosterId)}`,
|
|
452
|
+
});
|
|
453
|
+
} catch (err) {
|
|
454
|
+
if (err instanceof WopError && err.status === 404) return null;
|
|
455
|
+
throw err;
|
|
456
|
+
}
|
|
457
|
+
},
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* RFC 0087 §C — return the caller's agent org-chart (departments + roles +
|
|
461
|
+
* `reportsTo` over roster members; descriptive — confers no authority).
|
|
462
|
+
* Returns `null` when the host doesn't advertise `capabilities.agents.orgChart`.
|
|
463
|
+
*/
|
|
464
|
+
getOrgChart: async (): Promise<AgentOrgChart | null> => {
|
|
465
|
+
try {
|
|
466
|
+
return await this.#request<AgentOrgChart>({ method: 'GET', path: '/v1/agents/org-chart' });
|
|
467
|
+
} catch (err) {
|
|
468
|
+
if (err instanceof WopError && err.status === 404) return null;
|
|
469
|
+
throw err;
|
|
470
|
+
}
|
|
471
|
+
},
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* RFC 0087 §D — one department's subtree + responsibility roll-up (the
|
|
475
|
+
* union of its members' RFC 0086 portfolios). `recursive: false` scopes the
|
|
476
|
+
* roll-up to direct members. Returns `null` on 404 (unknown/cross-tenant
|
|
477
|
+
* department, or the capability is unadvertised).
|
|
478
|
+
*/
|
|
479
|
+
getOrgChartDepartment: async (
|
|
480
|
+
departmentId: string,
|
|
481
|
+
opts: { recursive?: boolean } = {},
|
|
482
|
+
): Promise<OrgChartResponsibilityView | null> => {
|
|
483
|
+
const qs = opts.recursive === false ? '?recursive=false' : '';
|
|
484
|
+
try {
|
|
485
|
+
return await this.#request<OrgChartResponsibilityView>({
|
|
486
|
+
method: 'GET',
|
|
487
|
+
path: `/v1/agents/org-chart/${encodeURIComponent(departmentId)}${qs}`,
|
|
488
|
+
});
|
|
489
|
+
} catch (err) {
|
|
490
|
+
if (err instanceof WopError && err.status === 404) return null;
|
|
491
|
+
throw err;
|
|
492
|
+
}
|
|
493
|
+
},
|
|
494
|
+
};
|
|
495
|
+
|
|
496
|
+
// ── User-authored agents (sample-extension; non-normative) ───────────
|
|
497
|
+
// Backs the workflow-engine sample app's Agents tab. Pack-installed
|
|
498
|
+
// agents come through the `.agents` inventory above (RFC 0072 §A).
|
|
499
|
+
// These methods wrap the `POST/DELETE /v1/host/sample/agents` +
|
|
500
|
+
// `GET/POST /v1/host/sample/registry/agent-packs` host extensions.
|
|
501
|
+
// Returns `null` on 404 (capability absent — matches the `.agents`
|
|
502
|
+
// surface pattern); throws on other failures.
|
|
503
|
+
readonly userAgents = {
|
|
504
|
+
create: async (body: CreateUserAgentRequest, opts: MutationOptions = {}): Promise<UserAgentRecord> => {
|
|
505
|
+
return await this.#request<UserAgentRecord>({
|
|
506
|
+
method: 'POST',
|
|
507
|
+
path: '/v1/host/sample/agents',
|
|
508
|
+
body,
|
|
509
|
+
...(opts.idempotencyKey ? { idempotencyKey: opts.idempotencyKey } : {}),
|
|
510
|
+
});
|
|
511
|
+
},
|
|
512
|
+
|
|
513
|
+
delete: async (agentId: string): Promise<boolean> => {
|
|
514
|
+
try {
|
|
515
|
+
await this.#request<void>({
|
|
516
|
+
method: 'DELETE',
|
|
517
|
+
path: `/v1/host/sample/agents/${encodeURIComponent(agentId)}`,
|
|
518
|
+
});
|
|
519
|
+
return true;
|
|
520
|
+
} catch (err) {
|
|
521
|
+
if (err instanceof WopError && err.status === 404) return false;
|
|
522
|
+
throw err;
|
|
523
|
+
}
|
|
524
|
+
},
|
|
525
|
+
|
|
526
|
+
listAvailablePacks: async (): Promise<AgentPackRegistryResponse | null> => {
|
|
527
|
+
try {
|
|
528
|
+
return await this.#request<AgentPackRegistryResponse>({
|
|
529
|
+
method: 'GET',
|
|
530
|
+
path: '/v1/host/sample/registry/agent-packs',
|
|
531
|
+
});
|
|
532
|
+
} catch (err) {
|
|
533
|
+
if (err instanceof WopError && err.status === 404) return null;
|
|
534
|
+
throw err;
|
|
535
|
+
}
|
|
536
|
+
},
|
|
537
|
+
|
|
538
|
+
installPack: async (
|
|
539
|
+
body: InstallAgentPackRequest,
|
|
540
|
+
): Promise<InstallAgentPackResponse> => {
|
|
541
|
+
return await this.#request<InstallAgentPackResponse>({
|
|
542
|
+
method: 'POST',
|
|
543
|
+
path: '/v1/host/sample/registry/agent-packs/install',
|
|
544
|
+
body,
|
|
545
|
+
});
|
|
546
|
+
},
|
|
547
|
+
};
|
|
548
|
+
|
|
245
549
|
// ── HITL interrupts (run-scoped + signed-token) ──────────────────────
|
|
246
550
|
readonly interrupts = {
|
|
247
551
|
resolveByRun: (
|
|
@@ -471,6 +775,94 @@ export class OpenwopClient {
|
|
|
471
775
|
},
|
|
472
776
|
};
|
|
473
777
|
|
|
778
|
+
// ── Agent workspace files (RFC 0059; gated on capabilities.workspace) ──
|
|
779
|
+
readonly workspace = {
|
|
780
|
+
/**
|
|
781
|
+
* RFC 0059 — list workspace file metadata (no bodies) for the caller's
|
|
782
|
+
* `{tenant, workspace}`. Optional `prefix` filters the flat `path`
|
|
783
|
+
* namespace. Returns `null` when the host doesn't advertise
|
|
784
|
+
* `capabilities.workspace.supported` (501), so callers can branch on
|
|
785
|
+
* capability discovery without try/catch.
|
|
786
|
+
*/
|
|
787
|
+
listFiles: async (opts: { prefix?: string } = {}): Promise<readonly WorkspaceFile[] | null> => {
|
|
788
|
+
const search = new URLSearchParams();
|
|
789
|
+
if (opts.prefix !== undefined) search.set('prefix', opts.prefix);
|
|
790
|
+
const qs = search.toString();
|
|
791
|
+
try {
|
|
792
|
+
const res = await this.#request<{ files: WorkspaceFile[] }>({
|
|
793
|
+
method: 'GET',
|
|
794
|
+
path: `/v1/host/workspace/files${qs ? `?${qs}` : ''}`,
|
|
795
|
+
});
|
|
796
|
+
return res.files;
|
|
797
|
+
} catch (err) {
|
|
798
|
+
if (err instanceof WopError && err.status === 501) return null;
|
|
799
|
+
throw err;
|
|
800
|
+
}
|
|
801
|
+
},
|
|
802
|
+
|
|
803
|
+
/**
|
|
804
|
+
* RFC 0059 — read one workspace file. Pass `version` for a historical
|
|
805
|
+
* snapshot when `capabilities.workspace.versioned`. Returns `null` when
|
|
806
|
+
* the file is absent (404) or the host doesn't advertise the capability
|
|
807
|
+
* (501).
|
|
808
|
+
*/
|
|
809
|
+
getFile: async (path: string, opts: { version?: number } = {}): Promise<WorkspaceFile | null> => {
|
|
810
|
+
const search = new URLSearchParams();
|
|
811
|
+
if (opts.version !== undefined) search.set('version', String(opts.version));
|
|
812
|
+
const qs = search.toString();
|
|
813
|
+
try {
|
|
814
|
+
return await this.#request<WorkspaceFile>({
|
|
815
|
+
method: 'GET',
|
|
816
|
+
path: `/v1/host/workspace/files/${encodeURIComponent(path)}${qs ? `?${qs}` : ''}`,
|
|
817
|
+
});
|
|
818
|
+
} catch (err) {
|
|
819
|
+
if (err instanceof WopError && (err.status === 404 || err.status === 501)) return null;
|
|
820
|
+
throw err;
|
|
821
|
+
}
|
|
822
|
+
},
|
|
823
|
+
|
|
824
|
+
/**
|
|
825
|
+
* RFC 0059 — atomic create/replace of a workspace file. Pass `ifMatch`
|
|
826
|
+
* (the file's current `etag`) for optimistic concurrency; a stale token
|
|
827
|
+
* throws a `WopError` with status `409` (`workspace_conflict`). Content
|
|
828
|
+
* beyond `capabilities.workspace.maxFileBytes` throws `413`
|
|
829
|
+
* (`workspace_too_large`). Returns the persisted `WorkspaceFile`.
|
|
830
|
+
*/
|
|
831
|
+
putFile: (
|
|
832
|
+
path: string,
|
|
833
|
+
body: PutWorkspaceFileRequest,
|
|
834
|
+
opts: MutationOptions & { ifMatch?: string } = {},
|
|
835
|
+
): Promise<WorkspaceFile> => {
|
|
836
|
+
const headers = this.#mutationHeaders(opts);
|
|
837
|
+
if (opts.ifMatch !== undefined) headers['If-Match'] = opts.ifMatch;
|
|
838
|
+
return this.#request<WorkspaceFile>({
|
|
839
|
+
method: 'PUT',
|
|
840
|
+
path: `/v1/host/workspace/files/${encodeURIComponent(path)}`,
|
|
841
|
+
body,
|
|
842
|
+
headers,
|
|
843
|
+
});
|
|
844
|
+
},
|
|
845
|
+
|
|
846
|
+
/**
|
|
847
|
+
* RFC 0059 — delete a workspace file. Returns `true` on success (`204`),
|
|
848
|
+
* `false` when the file is absent (404) or the host doesn't advertise the
|
|
849
|
+
* capability (501).
|
|
850
|
+
*/
|
|
851
|
+
deleteFile: async (path: string, opts: MutationOptions = {}): Promise<boolean> => {
|
|
852
|
+
try {
|
|
853
|
+
await this.#request<void>({
|
|
854
|
+
method: 'DELETE',
|
|
855
|
+
path: `/v1/host/workspace/files/${encodeURIComponent(path)}`,
|
|
856
|
+
headers: this.#mutationHeaders(opts),
|
|
857
|
+
});
|
|
858
|
+
return true;
|
|
859
|
+
} catch (err) {
|
|
860
|
+
if (err instanceof WopError && (err.status === 404 || err.status === 501)) return false;
|
|
861
|
+
throw err;
|
|
862
|
+
}
|
|
863
|
+
},
|
|
864
|
+
};
|
|
865
|
+
|
|
474
866
|
// ── Internals ────────────────────────────────────────────────────────
|
|
475
867
|
#mutationHeaders(opts: MutationOptions): Record<string, string> {
|
|
476
868
|
const h: Record<string, string> = {};
|
package/src/event-helpers.ts
CHANGED
|
@@ -35,6 +35,7 @@ import type {
|
|
|
35
35
|
AgentReasoningDeltaPayload,
|
|
36
36
|
AgentToolCalledPayload,
|
|
37
37
|
AgentToolReturnedPayload,
|
|
38
|
+
MemoryWrittenPayload,
|
|
38
39
|
RunEventDoc,
|
|
39
40
|
TypedRunEvent,
|
|
40
41
|
} from './types.js';
|
|
@@ -130,6 +131,18 @@ export function isAgentDecided(
|
|
|
130
131
|
);
|
|
131
132
|
}
|
|
132
133
|
|
|
134
|
+
/** `memory.written` (RFC 0057). Narrows when `type` matches AND the payload
|
|
135
|
+
* carries the required `memoryRef` + `memoryId` identifier strings. */
|
|
136
|
+
export function isMemoryWritten(
|
|
137
|
+
ev: RunEventDoc,
|
|
138
|
+
): ev is TypedRunEvent<MemoryWrittenPayload> {
|
|
139
|
+
return (
|
|
140
|
+
ev.type === 'memory.written' &&
|
|
141
|
+
hasStringField(ev.payload, 'memoryRef') &&
|
|
142
|
+
hasStringField(ev.payload, 'memoryId')
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
133
146
|
// ─── High-level subscription helper ─────────────────────────────────────
|
|
134
147
|
|
|
135
148
|
/** Returned by {@link subscribeToAgentReasoning}. Call to cancel the
|
package/src/index.ts
CHANGED
|
@@ -42,17 +42,23 @@ export type {
|
|
|
42
42
|
ResumeRunRequest,
|
|
43
43
|
ResumeRunResponse,
|
|
44
44
|
RunConfigurable,
|
|
45
|
+
RunDiffEventDiff,
|
|
46
|
+
RunDiffResponse,
|
|
45
47
|
RunEventDoc,
|
|
46
48
|
RunSnapshot,
|
|
47
49
|
RunStatus,
|
|
48
50
|
StreamMode,
|
|
49
51
|
TypedRunEvent,
|
|
52
|
+
// RFC 0059 — agent workspace (spec/v1/agent-workspace.md)
|
|
53
|
+
WorkspaceFile,
|
|
54
|
+
PutWorkspaceFileRequest,
|
|
50
55
|
AgentReasonedPayload,
|
|
51
56
|
AgentReasoningDeltaPayload,
|
|
52
57
|
AgentToolCalledPayload,
|
|
53
58
|
AgentToolReturnedPayload,
|
|
54
59
|
AgentHandoffPayload,
|
|
55
60
|
AgentDecidedPayload,
|
|
61
|
+
MemoryWrittenPayload,
|
|
56
62
|
// RFC 0027 + RFC 0028 — Prompt library (spec/v1/prompts.md)
|
|
57
63
|
GetPromptRequest,
|
|
58
64
|
ListPromptsRequest,
|
|
@@ -63,6 +69,33 @@ export type {
|
|
|
63
69
|
PromptVariable,
|
|
64
70
|
RenderPromptRequest,
|
|
65
71
|
RenderPromptResponse,
|
|
72
|
+
// RFC 0072 §A — Manifest-agent inventory (GET /v1/agents).
|
|
73
|
+
// Consumed by the workflow-engine sample app's Agents tab + chat
|
|
74
|
+
// `@` mention picker (2026-05-28 mention-symbol swap).
|
|
75
|
+
AgentInventoryEntry,
|
|
76
|
+
AgentInventoryResponse,
|
|
77
|
+
// RFC 0081 — Agent evaluation (spec/v1/agent-evaluation.md). EvalSummary
|
|
78
|
+
// scorecard read via `client.runs.evalSummary(runId)` for a `mode:'eval'` run.
|
|
79
|
+
AgentModelClass,
|
|
80
|
+
EvalSafetyFinding,
|
|
81
|
+
EvalTaskResult,
|
|
82
|
+
EvalRegression,
|
|
83
|
+
EvalSummary,
|
|
84
|
+
// RFC 0082 — Agent deployment lifecycle (spec/v1/agent-deployment.md).
|
|
85
|
+
// `client.agents.listDeployments` / `transitionDeployment`.
|
|
86
|
+
DeploymentState,
|
|
87
|
+
AgentDeployment,
|
|
88
|
+
AgentDeploymentTransition,
|
|
89
|
+
// Sample-extension surface — user-authored agents
|
|
90
|
+
// (`POST /v1/host/sample/agents`) + agent-pack registry browser
|
|
91
|
+
// (`GET/POST /v1/host/sample/registry/agent-packs`). Non-normative;
|
|
92
|
+
// wraps host-extension routes the sample app authors against.
|
|
93
|
+
CreateUserAgentRequest,
|
|
94
|
+
UserAgentRecord,
|
|
95
|
+
AgentPackSummary,
|
|
96
|
+
AgentPackRegistryResponse,
|
|
97
|
+
InstallAgentPackRequest,
|
|
98
|
+
InstallAgentPackResponse,
|
|
66
99
|
} from './types.js';
|
|
67
100
|
export { streamEvents } from './sse.js';
|
|
68
101
|
export type { EventsStreamContext, EventsStreamOptions } from './sse.js';
|
|
@@ -76,6 +109,7 @@ export {
|
|
|
76
109
|
isAgentToolReturned,
|
|
77
110
|
isAgentHandoff,
|
|
78
111
|
isAgentDecided,
|
|
112
|
+
isMemoryWritten,
|
|
79
113
|
subscribeToAgentReasoning,
|
|
80
114
|
} from './event-helpers.js';
|
|
81
115
|
export type {
|