@openwop/openwop 1.9.0 → 2.0.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 +64 -117
- package/dist/client.d.ts +131 -245
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +233 -440
- package/dist/client.js.map +1 -1
- package/dist/cost-attribution.d.ts +2 -2
- package/dist/cost-attribution.js +2 -2
- package/dist/envelope-directive.d.ts +1 -1
- package/dist/envelope-directive.js +1 -1
- package/dist/event-helpers.js +1 -1
- package/dist/event-helpers.js.map +1 -1
- package/dist/generated.d.ts +17 -0
- package/dist/generated.d.ts.map +1 -0
- package/dist/generated.js +311 -0
- package/dist/generated.js.map +1 -0
- package/dist/index.d.ts +16 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -56
- package/dist/index.js.map +1 -1
- package/dist/run-helpers.d.ts +20 -21
- package/dist/run-helpers.d.ts.map +1 -1
- package/dist/run-helpers.js +23 -72
- package/dist/run-helpers.js.map +1 -1
- package/dist/sse.d.ts +33 -15
- package/dist/sse.d.ts.map +1 -1
- package/dist/sse.js +28 -30
- package/dist/sse.js.map +1 -1
- package/dist/types.d.ts +253 -559
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/webhook-header-families.d.ts +22 -13
- package/dist/webhook-header-families.d.ts.map +1 -1
- package/dist/webhook-header-families.js +30 -27
- package/dist/webhook-header-families.js.map +1 -1
- package/dist/webhook-helpers.browser.d.ts +15 -29
- package/dist/webhook-helpers.browser.d.ts.map +1 -1
- package/dist/webhook-helpers.browser.js +16 -31
- package/dist/webhook-helpers.browser.js.map +1 -1
- package/dist/webhook-helpers.d.ts +41 -41
- package/dist/webhook-helpers.d.ts.map +1 -1
- package/dist/webhook-helpers.js +40 -47
- package/dist/webhook-helpers.js.map +1 -1
- package/package.json +6 -4
- package/src/client.ts +255 -454
- package/src/cost-attribution.ts +2 -2
- package/src/envelope-directive.ts +1 -1
- package/src/event-helpers.ts +1 -1
- package/src/generated.ts +322 -0
- package/src/index.ts +78 -110
- package/src/run-helpers.ts +27 -85
- package/src/sse.ts +63 -42
- package/src/types.ts +268 -603
- package/src/webhook-header-families.ts +41 -29
- package/src/webhook-helpers.browser.ts +23 -32
- package/src/webhook-helpers.ts +67 -53
- package/dist/registry-helpers.d.ts +0 -118
- package/dist/registry-helpers.d.ts.map +0 -1
- package/dist/registry-helpers.js +0 -82
- package/dist/registry-helpers.js.map +0 -1
- package/src/registry-helpers.ts +0 -173
package/README.md
CHANGED
|
@@ -1,155 +1,102 @@
|
|
|
1
|
-
# `@openwop/openwop` — TypeScript SDK for
|
|
1
|
+
# `@openwop/openwop` 2.x — TypeScript SDK for OpenWOP v2 hosts
|
|
2
2
|
|
|
3
|
-
**openwop is an open, wire-level protocol for multi-agent workflow orchestration
|
|
3
|
+
**openwop is an open, wire-level protocol for multi-agent workflow orchestration.** This package is the reference TypeScript client for the **v2 major** (`spec/v2/`, RFC 0168 §D): one typed method per operation in `spec/v2/path-manifest.json` (51 operations), an async-iterable SSE consumer for the run and host event channels, and zero runtime dependencies.
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
npm install @openwop/openwop
|
|
6
|
+
npm install @openwop/openwop@2 # 2.0.0 — v2-only; the 1.x client stays on `@openwop/openwop@1`
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
> **Spec:** [github.com/openwop/openwop](https://github.com/openwop/openwop) · **
|
|
9
|
+
> **Spec:** [github.com/openwop/openwop](https://github.com/openwop/openwop) · **Corpus tag:** see [`CORPUS_TAG`](../../CORPUS_TAG) · **Mirrors:** [`api/v2/openapi.yaml`](../../api/v2/openapi.yaml), [`api/v2/asyncapi.yaml`](../../api/v2/asyncapi.yaml), [`schemas/v2/`](../../schemas/v2/), [`spec/v2/errors.json`](../../spec/v2/errors.json)
|
|
10
|
+
>
|
|
11
|
+
> The 1.x package (`sdk/typescript/`) is untouched and keeps publishing for v1 hosts. This is a v2-ONLY client: it never sends a `/v1/…` path.
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
## What is different from 1.x (RFC 0172 / 0171 / 0173)
|
|
12
14
|
|
|
13
|
-
1.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
| 1.x | 2.x |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| `/v1/runs`, `/v1/agents`, … | Bare origin, unversioned path keys: `/runs`, `/agents`, … There is no `/v2/` path space. |
|
|
18
|
+
| Negotiation by `protocolVersion` | `OpenWOP-Version: <major>.0` on **every** request (ctor option `major`, default `2`); the host answers `406 protocol_version_unsupported` with `details.protocolVersions[]` when it does not list the major. |
|
|
19
|
+
| `X-Dedup` | `OpenWOP-Dedup` (`MutationOptions.dedup`). Every non-standard header is `OpenWOP-<Name>` (headers.md). |
|
|
20
|
+
| `pollEvents({ lastSequence })` | `pollEvents({ afterSequence })`; the response is the closed `{ runId, events, lastSequence, status, isTerminal }`. |
|
|
21
|
+
| Open discovery root, `supported: boolean` | The closed v2 root: `protocolVersions[]` + `preferredVersion` REQUIRED, every family a `CapabilityRecord` `{ status, since, until?, witness, …facets }` (presence is the claim). Family and metadata keys are generated from `schemas/v2/capabilities.schema.json`. |
|
|
22
|
+
| `ErrorEnvelope.error: string` | `ErrorCode \| VendorErrorCode` — the 94-member union is generated from `spec/v2/errors.json` (`ERROR_CODES`, `ERROR_CODE_HTTP_STATUS`, `RETRIABLE_ERROR_CODES`). |
|
|
23
|
+
| `workspace.*` (4), `runs.debugBundle`, `userAgents.*` (host-sample seams), `RegistryClient` | Removed — not v2 operations. The pack registry is a separate wire surface a client resolves through `.well-known/openwop-registry.json` `endpoints` (packs.md). |
|
|
24
|
+
| — | `runs.compensation`, `runs.effects`, `host.effectSeams` (RFC 0173), `host.events` (the `hostEvents` SSE channel). |
|
|
25
|
+
| Webhook `openwop-Webhook-*` legacy names, `v1=<hex>` | `OpenWOP-*` only (`X-openwop-*` accepted through the overlap); `sha256=<hex>`; an unrecognized `OpenWOP-Signature-Algorithm` is rejected. Import from `@openwop/openwop/webhooks` — the barrel no longer carries `node:crypto`. |
|
|
17
26
|
|
|
18
27
|
## Quickstart
|
|
19
28
|
|
|
20
29
|
```typescript
|
|
21
|
-
import { OpenwopClient } from '@openwop/openwop';
|
|
30
|
+
import { OpenwopClient, WopError, isTerminalRunStatus } from '@openwop/openwop';
|
|
22
31
|
|
|
23
32
|
const client = new OpenwopClient({
|
|
24
33
|
baseUrl: 'https://api.example.com',
|
|
25
34
|
apiKey: 'hk_test_abc123',
|
|
35
|
+
// major: 2 — the default; every request carries `OpenWOP-Version: 2.0`.
|
|
26
36
|
});
|
|
27
37
|
|
|
28
|
-
// Discovery
|
|
38
|
+
// Discovery — the closed v2 root; `webhooks` is a record or absent, never `supported: false`.
|
|
29
39
|
const caps = await client.discovery.capabilities();
|
|
30
|
-
console.log(caps.
|
|
31
|
-
|
|
32
|
-
// Workflows
|
|
33
|
-
const wf = await client.workflows.get('my-workflow-id');
|
|
40
|
+
console.log(caps.preferredVersion, caps.protocolVersions, caps.webhooks?.status);
|
|
34
41
|
|
|
35
|
-
//
|
|
36
|
-
const { runId } = await client.runs.create(
|
|
37
|
-
workflowId: 'my-workflow
|
|
38
|
-
|
|
39
|
-
|
|
42
|
+
// Runs
|
|
43
|
+
const { runId } = await client.runs.create(
|
|
44
|
+
{ workflowId: 'my-workflow', inputs: { q: 'hello' }, configurable: { version: 1, run: { runTimeoutMs: 60_000 } } },
|
|
45
|
+
{ idempotencyKey: crypto.randomUUID(), dedup: 'enforce' },
|
|
46
|
+
);
|
|
40
47
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
while (snap.status !== 'completed' && snap.status !== 'failed') {
|
|
44
|
-
await new Promise((r) => setTimeout(r, 500));
|
|
45
|
-
snap = await client.runs.get(runId);
|
|
48
|
+
for await (const event of client.runs.events(runId, { streamMode: ['updates', 'messages'] })) {
|
|
49
|
+
console.log(event.sequence, event.type);
|
|
46
50
|
}
|
|
47
51
|
|
|
48
|
-
//
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
// Replay / fork
|
|
55
|
-
const fork = await client.runs.fork(runId, { fromSeq: 5, mode: 'branch' });
|
|
56
|
-
|
|
57
|
-
// SSE stream
|
|
58
|
-
for await (const event of client.runs.events(runId, { streamMode: 'updates' })) {
|
|
59
|
-
console.log(event.type, event.payload);
|
|
52
|
+
// Long-poll fallback: feed `lastSequence` back as `afterSequence`.
|
|
53
|
+
let cursor: number | undefined;
|
|
54
|
+
for (;;) {
|
|
55
|
+
const page = await client.runs.pollEvents(runId, cursor === undefined ? {} : { afterSequence: cursor });
|
|
56
|
+
cursor = page.lastSequence;
|
|
57
|
+
if (page.isTerminal) break;
|
|
60
58
|
}
|
|
61
|
-
```
|
|
62
59
|
|
|
63
|
-
|
|
60
|
+
// RFC 0173 read projections
|
|
61
|
+
const compensation = await client.runs.compensation(runId); // null when `compensation` is unadvertised
|
|
62
|
+
const effects = await client.runs.effects(runId);
|
|
64
63
|
|
|
65
|
-
|
|
64
|
+
// Errors route on the registered code, never on `message`.
|
|
65
|
+
try {
|
|
66
|
+
await client.runs.get('tenant/does-not-exist');
|
|
67
|
+
} catch (err) {
|
|
68
|
+
if (err instanceof WopError && err.envelope?.error === 'not_found') { /* … */ }
|
|
69
|
+
}
|
|
66
70
|
|
|
67
|
-
|
|
68
|
-
cd sdk/typescript
|
|
69
|
-
npm install # installs @openwop/openwop deps locally (NOT in parent monorepo)
|
|
70
|
-
npx tsc --noEmit # typecheck the SDK source
|
|
71
|
+
void isTerminalRunStatus;
|
|
71
72
|
```
|
|
72
73
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
## What's Covered In v1.0
|
|
76
|
-
|
|
77
|
-
| Endpoint | SDK method |
|
|
78
|
-
|---|---|
|
|
79
|
-
| `GET /.well-known/openwop` | `client.discovery.capabilities()` |
|
|
80
|
-
| `GET /v1/openapi.json` | `client.discovery.openapi()` |
|
|
81
|
-
| `GET /v1/workflows/{id}` | `client.workflows.get(id)` |
|
|
82
|
-
| `POST /v1/runs` | `client.runs.create(body, opts?)` |
|
|
83
|
-
| `GET /v1/runs/{id}` | `client.runs.get(id)` |
|
|
84
|
-
| `GET /v1/runs/{id}/events` (SSE) | `client.runs.events(id, opts?)` (async iterable) |
|
|
85
|
-
| `GET /v1/runs/{id}/events/poll` | `client.runs.pollEvents(id, opts?)` |
|
|
86
|
-
| `POST /v1/runs/{id}/cancel` | `client.runs.cancel(id, body?)` |
|
|
87
|
-
| `POST /v1/runs:bulk-cancel` | `client.runs.bulkCancel(body, opts?)` |
|
|
88
|
-
| `POST /v1/runs/{id}:pause` | `client.runs.pause(id, body?, opts?)` |
|
|
89
|
-
| `POST /v1/runs/{id}:resume` | `client.runs.resume(id, body?, opts?)` |
|
|
90
|
-
| `POST /v1/runs/{id}:fork` | `client.runs.fork(id, body)` |
|
|
91
|
-
| `POST /v1/runs/{id}/interrupts/{nodeId}` | `client.interrupts.resolveByRun(id, nodeId, body)` |
|
|
92
|
-
| `GET /v1/interrupts/{token}` | `client.interrupts.inspectByToken(token)` |
|
|
93
|
-
| `POST /v1/interrupts/{token}` | `client.interrupts.resolveByToken(token, body)` |
|
|
94
|
-
| `GET /v1/audit/verify` | `client.audit.verify(fromSeq, toSeq)` |
|
|
95
|
-
|
|
96
|
-
**Idempotency-Key** is supported via the `idempotencyKey` option on every mutation method.
|
|
97
|
-
|
|
98
|
-
**Typed `RunConfigurable`** — `client.runs.create(...).configurable` is now a typed surface with reserved keys (`recursionLimit`, `model`, `temperature`, `maxTokens`, `promptOverrides`) plus pass-through for impl extensions.
|
|
99
|
-
|
|
100
|
-
## Error Handling
|
|
74
|
+
Webhook receivers (server-only):
|
|
101
75
|
|
|
102
76
|
```typescript
|
|
103
|
-
import {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
}
|
|
77
|
+
import { readWebhookHeaders, verifyWebhookSignature } from '@openwop/openwop/webhooks';
|
|
78
|
+
|
|
79
|
+
const read = readWebhookHeaders(req.headers);
|
|
80
|
+
const outcome = read
|
|
81
|
+
? verifyWebhookSignature(secret, read.signatureHeader, read.timestampHeader, rawBody, {
|
|
82
|
+
...(read.algorithmHeader === undefined ? {} : { algorithmHeader: read.algorithmHeader }),
|
|
83
|
+
})
|
|
84
|
+
: { valid: false as const, reason: 'malformed_signature_header' as const };
|
|
112
85
|
```
|
|
113
86
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
---
|
|
87
|
+
## Generated surface
|
|
117
88
|
|
|
118
|
-
|
|
89
|
+
`src/generated.ts` is produced by `scripts/generate.mjs` from the vendored `spec/v2/errors.json` and `schemas/v2/capabilities.schema.json`. `npm run generate` rewrites it; `npm run generate:check` (run by `scripts/sdks-check.sh`) fails when it drifts from the corpus at `CORPUS_TAG`.
|
|
119
90
|
|
|
120
|
-
|
|
121
|
-
|---|---|
|
|
122
|
-
| Webhook subscription helpers | v1 specifies webhook delivery, but the SDK keeps endpoint coverage focused on the run lifecycle and conformance-critical surfaces. |
|
|
123
|
-
| Hosted registry publishing helpers | Node-pack registry publishing needs operator-specific credentials and policy; use direct HTTP until a dedicated package workflow is warranted. |
|
|
124
|
-
| Auto-retry with exponential backoff | Retry policy is application-specific. The SDK exposes structured errors so callers can implement their own retry envelope. |
|
|
125
|
-
| Separate browser entrypoint (`@openwop/openwop/browser`) | The default ESM build uses standard `fetch`/`ReadableStream` primitives and can be bundled by modern tools; a dedicated browser subpath can ship later without changing the v1 surface. |
|
|
91
|
+
## Method ↔ operation map
|
|
126
92
|
|
|
127
|
-
|
|
93
|
+
Every one of the 51 `spec/v2/path-manifest.json` operations has exactly one method; `scripts/check-sdk-parity.mjs --manifest spec/v2/path-manifest.json --expectations sdk/parity-expectations-v2.json` enforces it. See [`sdk/PARITY.md`](../PARITY.md) §v2.
|
|
128
94
|
|
|
129
|
-
##
|
|
95
|
+
## Development
|
|
130
96
|
|
|
97
|
+
```bash
|
|
98
|
+
npm install
|
|
99
|
+
npm run typecheck # strict + exactOptionalPropertyTypes
|
|
100
|
+
npm test
|
|
101
|
+
npm run generate:check
|
|
131
102
|
```
|
|
132
|
-
sdk/typescript/
|
|
133
|
-
README.md — this file
|
|
134
|
-
package.json — @openwop/openwop package manifest
|
|
135
|
-
tsconfig.json — strict TS, ESM
|
|
136
|
-
src/
|
|
137
|
-
index.ts — public surface (OpenwopClient + types)
|
|
138
|
-
client.ts — OpenwopClient class (auth, request helper)
|
|
139
|
-
types.ts — request/response types mirrored from the OpenAPI spec
|
|
140
|
-
sse.ts — async-iterable SSE consumer
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
---
|
|
144
|
-
|
|
145
|
-
## Versioning
|
|
146
|
-
|
|
147
|
-
This SDK tracks OpenWOP v1. SDK majors match the protocol major; v1.x SDK releases remain forward-compatible with the v1 wire contract. Mismatch behavior is forward-compat tolerant — see `../../version-negotiation.md`. Breaking spec changes will increment the SDK major.
|
|
148
|
-
|
|
149
|
-
## References
|
|
150
|
-
|
|
151
|
-
- Spec corpus: `../../README.md`
|
|
152
|
-
- OpenAPI: `../../api/openapi.yaml` (the SDK mirrors this surface)
|
|
153
|
-
- AsyncAPI: `../../api/asyncapi.yaml` (the SSE consumer follows these channels)
|
|
154
|
-
- **[`../PARITY.md`](../PARITY.md)** — cross-SDK feature-parity matrix (TS/Python/Go).
|
|
155
|
-
- **[`../smoke/`](../smoke/)** — runnable wire-smoke scripts against a reference host.
|