@zarel-ai/sdk 0.6.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/LICENSE +21 -0
- package/README.md +412 -0
- package/dist/_internal/auth-headers.d.ts +19 -0
- package/dist/_internal/auth-headers.d.ts.map +1 -0
- package/dist/_internal/auth-headers.js +30 -0
- package/dist/_internal/auth-headers.js.map +1 -0
- package/dist/_internal/confirmation.d.ts +24 -0
- package/dist/_internal/confirmation.d.ts.map +1 -0
- package/dist/_internal/confirmation.js +54 -0
- package/dist/_internal/confirmation.js.map +1 -0
- package/dist/_internal/event-iterator.d.ts +18 -0
- package/dist/_internal/event-iterator.d.ts.map +1 -0
- package/dist/_internal/event-iterator.js +151 -0
- package/dist/_internal/event-iterator.js.map +1 -0
- package/dist/_internal/fetch-client.d.ts +141 -0
- package/dist/_internal/fetch-client.d.ts.map +1 -0
- package/dist/_internal/fetch-client.js +471 -0
- package/dist/_internal/fetch-client.js.map +1 -0
- package/dist/_internal/interceptors.d.ts +40 -0
- package/dist/_internal/interceptors.d.ts.map +1 -0
- package/dist/_internal/interceptors.js +28 -0
- package/dist/_internal/interceptors.js.map +1 -0
- package/dist/_internal/mcp.d.ts +11 -0
- package/dist/_internal/mcp.d.ts.map +1 -0
- package/dist/_internal/mcp.js +79 -0
- package/dist/_internal/mcp.js.map +1 -0
- package/dist/_internal/pagination.d.ts +71 -0
- package/dist/_internal/pagination.d.ts.map +1 -0
- package/dist/_internal/pagination.js +130 -0
- package/dist/_internal/pagination.js.map +1 -0
- package/dist/_internal/require-token.d.ts +17 -0
- package/dist/_internal/require-token.d.ts.map +1 -0
- package/dist/_internal/require-token.js +25 -0
- package/dist/_internal/require-token.js.map +1 -0
- package/dist/_internal/retry-after.d.ts +2 -0
- package/dist/_internal/retry-after.d.ts.map +1 -0
- package/dist/_internal/retry-after.js +34 -0
- package/dist/_internal/retry-after.js.map +1 -0
- package/dist/_internal/sse-client.d.ts +43 -0
- package/dist/_internal/sse-client.d.ts.map +1 -0
- package/dist/_internal/sse-client.js +250 -0
- package/dist/_internal/sse-client.js.map +1 -0
- package/dist/_internal/version.d.ts +5 -0
- package/dist/_internal/version.d.ts.map +1 -0
- package/dist/_internal/version.js +12 -0
- package/dist/_internal/version.js.map +1 -0
- package/dist/client.d.ts +74 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +86 -0
- package/dist/client.js.map +1 -0
- package/dist/contract/_singleton.d.ts +18 -0
- package/dist/contract/_singleton.d.ts.map +1 -0
- package/dist/contract/_singleton.js +27 -0
- package/dist/contract/_singleton.js.map +1 -0
- package/dist/contract/actions.d.ts +18 -0
- package/dist/contract/actions.d.ts.map +1 -0
- package/dist/contract/actions.js +36 -0
- package/dist/contract/actions.js.map +1 -0
- package/dist/contract/assistant.d.ts +65 -0
- package/dist/contract/assistant.d.ts.map +1 -0
- package/dist/contract/assistant.js +44 -0
- package/dist/contract/assistant.js.map +1 -0
- package/dist/contract/batch.d.ts +27 -0
- package/dist/contract/batch.d.ts.map +1 -0
- package/dist/contract/batch.js +20 -0
- package/dist/contract/batch.js.map +1 -0
- package/dist/contract/capabilities.d.ts +21 -0
- package/dist/contract/capabilities.d.ts.map +1 -0
- package/dist/contract/capabilities.js +31 -0
- package/dist/contract/capabilities.js.map +1 -0
- package/dist/contract/constraints.d.ts +21 -0
- package/dist/contract/constraints.d.ts.map +1 -0
- package/dist/contract/constraints.js +31 -0
- package/dist/contract/constraints.js.map +1 -0
- package/dist/contract/events.d.ts +33 -0
- package/dist/contract/events.d.ts.map +1 -0
- package/dist/contract/events.js +56 -0
- package/dist/contract/events.js.map +1 -0
- package/dist/contract/flows.d.ts +44 -0
- package/dist/contract/flows.d.ts.map +1 -0
- package/dist/contract/flows.js +109 -0
- package/dist/contract/flows.js.map +1 -0
- package/dist/contract/governance.d.ts +6 -0
- package/dist/contract/governance.d.ts.map +1 -0
- package/dist/contract/governance.js +17 -0
- package/dist/contract/governance.js.map +1 -0
- package/dist/contract/index.d.ts +137 -0
- package/dist/contract/index.d.ts.map +1 -0
- package/dist/contract/index.js +177 -0
- package/dist/contract/index.js.map +1 -0
- package/dist/contract/metadata.d.ts +26 -0
- package/dist/contract/metadata.d.ts.map +1 -0
- package/dist/contract/metadata.js +25 -0
- package/dist/contract/metadata.js.map +1 -0
- package/dist/contract/process-model.d.ts +31 -0
- package/dist/contract/process-model.d.ts.map +1 -0
- package/dist/contract/process-model.js +51 -0
- package/dist/contract/process-model.js.map +1 -0
- package/dist/contract/roots/channels.d.ts +27 -0
- package/dist/contract/roots/channels.d.ts.map +1 -0
- package/dist/contract/roots/channels.js +53 -0
- package/dist/contract/roots/channels.js.map +1 -0
- package/dist/contract/roots/events.d.ts +7 -0
- package/dist/contract/roots/events.d.ts.map +1 -0
- package/dist/contract/roots/events.js +19 -0
- package/dist/contract/roots/events.js.map +1 -0
- package/dist/contract/roots/index.d.ts +15 -0
- package/dist/contract/roots/index.d.ts.map +1 -0
- package/dist/contract/roots/index.js +38 -0
- package/dist/contract/roots/index.js.map +1 -0
- package/dist/contract/roots/mcp-servers.d.ts +46 -0
- package/dist/contract/roots/mcp-servers.d.ts.map +1 -0
- package/dist/contract/roots/mcp-servers.js +68 -0
- package/dist/contract/roots/mcp-servers.js.map +1 -0
- package/dist/contract/roots/profiles.d.ts +18 -0
- package/dist/contract/roots/profiles.d.ts.map +1 -0
- package/dist/contract/roots/profiles.js +31 -0
- package/dist/contract/roots/profiles.js.map +1 -0
- package/dist/contract/roots/timezone.d.ts +10 -0
- package/dist/contract/roots/timezone.d.ts.map +1 -0
- package/dist/contract/roots/timezone.js +19 -0
- package/dist/contract/roots/timezone.js.map +1 -0
- package/dist/contract/roots/treatment.d.ts +11 -0
- package/dist/contract/roots/treatment.d.ts.map +1 -0
- package/dist/contract/roots/treatment.js +37 -0
- package/dist/contract/roots/treatment.js.map +1 -0
- package/dist/contract/roots/vocabulary.d.ts +18 -0
- package/dist/contract/roots/vocabulary.d.ts.map +1 -0
- package/dist/contract/roots/vocabulary.js +31 -0
- package/dist/contract/roots/vocabulary.js.map +1 -0
- package/dist/contract/schemas.d.ts +18 -0
- package/dist/contract/schemas.d.ts.map +1 -0
- package/dist/contract/schemas.js +31 -0
- package/dist/contract/schemas.js.map +1 -0
- package/dist/contract/skills.d.ts +20 -0
- package/dist/contract/skills.d.ts.map +1 -0
- package/dist/contract/skills.js +36 -0
- package/dist/contract/skills.js.map +1 -0
- package/dist/errors.d.ts +65 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +80 -0
- package/dist/errors.js.map +1 -0
- package/dist/generated/contract.d.ts +7688 -0
- package/dist/generated/contract.d.ts.map +1 -0
- package/dist/generated/contract.js +7 -0
- package/dist/generated/contract.js.map +1 -0
- package/dist/generated/index.d.ts +41 -0
- package/dist/generated/index.d.ts.map +1 -0
- package/dist/generated/index.js +3 -0
- package/dist/generated/index.js.map +1 -0
- package/dist/generated/runtime.d.ts +4020 -0
- package/dist/generated/runtime.d.ts.map +1 -0
- package/dist/generated/runtime.js +7 -0
- package/dist/generated/runtime.js.map +1 -0
- package/dist/generated/unwrap-map.d.ts +989 -0
- package/dist/generated/unwrap-map.d.ts.map +1 -0
- package/dist/generated/unwrap-map.js +344 -0
- package/dist/generated/unwrap-map.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/resources/actions.d.ts +33 -0
- package/dist/resources/actions.d.ts.map +1 -0
- package/dist/resources/actions.js +52 -0
- package/dist/resources/actions.js.map +1 -0
- package/dist/resources/audit.d.ts +52 -0
- package/dist/resources/audit.d.ts.map +1 -0
- package/dist/resources/audit.js +86 -0
- package/dist/resources/audit.js.map +1 -0
- package/dist/resources/authorization-ceiling.d.ts +25 -0
- package/dist/resources/authorization-ceiling.d.ts.map +1 -0
- package/dist/resources/authorization-ceiling.js +26 -0
- package/dist/resources/authorization-ceiling.js.map +1 -0
- package/dist/resources/authorization-operation-ids.d.ts +15 -0
- package/dist/resources/authorization-operation-ids.d.ts.map +1 -0
- package/dist/resources/authorization-operation-ids.js +31 -0
- package/dist/resources/authorization-operation-ids.js.map +1 -0
- package/dist/resources/authorization.d.ts +60 -0
- package/dist/resources/authorization.d.ts.map +1 -0
- package/dist/resources/authorization.js +51 -0
- package/dist/resources/authorization.js.map +1 -0
- package/dist/resources/authorizations.d.ts +38 -0
- package/dist/resources/authorizations.d.ts.map +1 -0
- package/dist/resources/authorizations.js +19 -0
- package/dist/resources/authorizations.js.map +1 -0
- package/dist/resources/channels.d.ts +36 -0
- package/dist/resources/channels.d.ts.map +1 -0
- package/dist/resources/channels.js +61 -0
- package/dist/resources/channels.js.map +1 -0
- package/dist/resources/contracts.d.ts +46 -0
- package/dist/resources/contracts.d.ts.map +1 -0
- package/dist/resources/contracts.js +86 -0
- package/dist/resources/contracts.js.map +1 -0
- package/dist/resources/conversation-sessions.d.ts +62 -0
- package/dist/resources/conversation-sessions.d.ts.map +1 -0
- package/dist/resources/conversation-sessions.js +48 -0
- package/dist/resources/conversation-sessions.js.map +1 -0
- package/dist/resources/conversation.d.ts +48 -0
- package/dist/resources/conversation.d.ts.map +1 -0
- package/dist/resources/conversation.js +104 -0
- package/dist/resources/conversation.js.map +1 -0
- package/dist/resources/embedding-credentials.d.ts +60 -0
- package/dist/resources/embedding-credentials.d.ts.map +1 -0
- package/dist/resources/embedding-credentials.js +53 -0
- package/dist/resources/embedding-credentials.js.map +1 -0
- package/dist/resources/entities.d.ts +66 -0
- package/dist/resources/entities.d.ts.map +1 -0
- package/dist/resources/entities.js +106 -0
- package/dist/resources/entities.js.map +1 -0
- package/dist/resources/events.d.ts +45 -0
- package/dist/resources/events.d.ts.map +1 -0
- package/dist/resources/events.js +71 -0
- package/dist/resources/events.js.map +1 -0
- package/dist/resources/flows.d.ts +45 -0
- package/dist/resources/flows.d.ts.map +1 -0
- package/dist/resources/flows.js +82 -0
- package/dist/resources/flows.js.map +1 -0
- package/dist/resources/imports.d.ts +8 -0
- package/dist/resources/imports.d.ts.map +1 -0
- package/dist/resources/imports.js +14 -0
- package/dist/resources/imports.js.map +1 -0
- package/dist/resources/index.d.ts +24 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +41 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/resources/llm-credentials.d.ts +47 -0
- package/dist/resources/llm-credentials.d.ts.map +1 -0
- package/dist/resources/llm-credentials.js +46 -0
- package/dist/resources/llm-credentials.js.map +1 -0
- package/dist/resources/llm-services.d.ts +46 -0
- package/dist/resources/llm-services.d.ts.map +1 -0
- package/dist/resources/llm-services.js +41 -0
- package/dist/resources/llm-services.js.map +1 -0
- package/dist/resources/mcp.d.ts +8 -0
- package/dist/resources/mcp.d.ts.map +1 -0
- package/dist/resources/mcp.js +25 -0
- package/dist/resources/mcp.js.map +1 -0
- package/dist/resources/receipts.d.ts +25 -0
- package/dist/resources/receipts.d.ts.map +1 -0
- package/dist/resources/receipts.js +54 -0
- package/dist/resources/receipts.js.map +1 -0
- package/dist/resources/records.d.ts +51 -0
- package/dist/resources/records.d.ts.map +1 -0
- package/dist/resources/records.js +103 -0
- package/dist/resources/records.js.map +1 -0
- package/dist/resources/role-assignments.d.ts +27 -0
- package/dist/resources/role-assignments.d.ts.map +1 -0
- package/dist/resources/role-assignments.js +40 -0
- package/dist/resources/role-assignments.js.map +1 -0
- package/dist/resources/roles.d.ts +39 -0
- package/dist/resources/roles.d.ts.map +1 -0
- package/dist/resources/roles.js +42 -0
- package/dist/resources/roles.js.map +1 -0
- package/dist/resources/runtime-entities.d.ts +23 -0
- package/dist/resources/runtime-entities.d.ts.map +1 -0
- package/dist/resources/runtime-entities.js +29 -0
- package/dist/resources/runtime-entities.js.map +1 -0
- package/dist/resources/state-machine.d.ts +45 -0
- package/dist/resources/state-machine.d.ts.map +1 -0
- package/dist/resources/state-machine.js +86 -0
- package/dist/resources/state-machine.js.map +1 -0
- package/dist/resources/system.d.ts +12 -0
- package/dist/resources/system.d.ts.map +1 -0
- package/dist/resources/system.js +26 -0
- package/dist/resources/system.js.map +1 -0
- package/dist/resources/tools.d.ts +22 -0
- package/dist/resources/tools.d.ts.map +1 -0
- package/dist/resources/tools.js +33 -0
- package/dist/resources/tools.js.map +1 -0
- package/dist/resources/traces.d.ts +65 -0
- package/dist/resources/traces.d.ts.map +1 -0
- package/dist/resources/traces.js +97 -0
- package/dist/resources/traces.js.map +1 -0
- package/dist/runtime/index.d.ts +128 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +210 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/types/actions.d.ts +32 -0
- package/dist/types/actions.d.ts.map +1 -0
- package/dist/types/actions.js +9 -0
- package/dist/types/actions.js.map +1 -0
- package/dist/types/audit.d.ts +65 -0
- package/dist/types/audit.d.ts.map +1 -0
- package/dist/types/audit.js +14 -0
- package/dist/types/audit.js.map +1 -0
- package/dist/types/channels.d.ts +37 -0
- package/dist/types/channels.d.ts.map +1 -0
- package/dist/types/channels.js +6 -0
- package/dist/types/channels.js.map +1 -0
- package/dist/types/confirmation.d.ts +53 -0
- package/dist/types/confirmation.d.ts.map +1 -0
- package/dist/types/confirmation.js +17 -0
- package/dist/types/confirmation.js.map +1 -0
- package/dist/types/contracts.d.ts +194 -0
- package/dist/types/contracts.d.ts.map +1 -0
- package/dist/types/contracts.js +10 -0
- package/dist/types/contracts.js.map +1 -0
- package/dist/types/conversation-sessions.d.ts +58 -0
- package/dist/types/conversation-sessions.d.ts.map +1 -0
- package/dist/types/conversation-sessions.js +6 -0
- package/dist/types/conversation-sessions.js.map +1 -0
- package/dist/types/conversation.d.ts +96 -0
- package/dist/types/conversation.d.ts.map +1 -0
- package/dist/types/conversation.js +3 -0
- package/dist/types/conversation.js.map +1 -0
- package/dist/types/entities.d.ts +22 -0
- package/dist/types/entities.d.ts.map +1 -0
- package/dist/types/entities.js +4 -0
- package/dist/types/entities.js.map +1 -0
- package/dist/types/events-stream.d.ts +82 -0
- package/dist/types/events-stream.d.ts.map +1 -0
- package/dist/types/events-stream.js +65 -0
- package/dist/types/events-stream.js.map +1 -0
- package/dist/types/flows-contract.d.ts +8 -0
- package/dist/types/flows-contract.d.ts.map +1 -0
- package/dist/types/flows-contract.js +7 -0
- package/dist/types/flows-contract.js.map +1 -0
- package/dist/types/flows.d.ts +66 -0
- package/dist/types/flows.d.ts.map +1 -0
- package/dist/types/flows.js +25 -0
- package/dist/types/flows.js.map +1 -0
- package/dist/types/imports.d.ts +57 -0
- package/dist/types/imports.d.ts.map +1 -0
- package/dist/types/imports.js +3 -0
- package/dist/types/imports.js.map +1 -0
- package/dist/types/index.d.ts +17 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/locale.d.ts +24 -0
- package/dist/types/locale.d.ts.map +1 -0
- package/dist/types/locale.js +17 -0
- package/dist/types/locale.js.map +1 -0
- package/dist/types/mcp.d.ts +28 -0
- package/dist/types/mcp.d.ts.map +1 -0
- package/dist/types/mcp.js +12 -0
- package/dist/types/mcp.js.map +1 -0
- package/dist/types/platform.d.ts +51 -0
- package/dist/types/platform.d.ts.map +1 -0
- package/dist/types/platform.js +4 -0
- package/dist/types/platform.js.map +1 -0
- package/dist/types/receipt.d.ts +79 -0
- package/dist/types/receipt.d.ts.map +1 -0
- package/dist/types/receipt.js +15 -0
- package/dist/types/receipt.js.map +1 -0
- package/dist/types/records.d.ts +45 -0
- package/dist/types/records.d.ts.map +1 -0
- package/dist/types/records.js +4 -0
- package/dist/types/records.js.map +1 -0
- package/dist/types/spec.d.ts +6 -0
- package/dist/types/spec.d.ts.map +1 -0
- package/dist/types/spec.js +3 -0
- package/dist/types/spec.js.map +1 -0
- package/dist/types/state-machine.d.ts +100 -0
- package/dist/types/state-machine.d.ts.map +1 -0
- package/dist/types/state-machine.js +9 -0
- package/dist/types/state-machine.js.map +1 -0
- package/dist/types/system.d.ts +28 -0
- package/dist/types/system.d.ts.map +1 -0
- package/dist/types/system.js +3 -0
- package/dist/types/system.js.map +1 -0
- package/dist/types/tools.d.ts +188 -0
- package/dist/types/tools.d.ts.map +1 -0
- package/dist/types/tools.js +22 -0
- package/dist/types/tools.js.map +1 -0
- package/dist/types/traces.d.ts +77 -0
- package/dist/types/traces.d.ts.map +1 -0
- package/dist/types/traces.js +11 -0
- package/dist/types/traces.js.map +1 -0
- package/dist/types/workflows.d.ts +42 -0
- package/dist/types/workflows.d.ts.map +1 -0
- package/dist/types/workflows.js +11 -0
- package/dist/types/workflows.js.map +1 -0
- package/package.json +103 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Zarel AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
# @zarel-ai/sdk
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for the [Zarel](https://zarel.ia) API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @zarel-ai/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
`@zarel-ai/sdk` exposes a single `Zarel` client with two explicit plane
|
|
14
|
+
namespaces — `client.runtime.*` (records, tools, conversation, flows, traces,
|
|
15
|
+
…) and `client.contract.*` (spec, entities, roles, authorization,
|
|
16
|
+
capabilities, schemas, processModel, runtime config, …). Each plane targets its own host and accepts an
|
|
17
|
+
independent JWT.
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { Zarel } from '@zarel-ai/sdk';
|
|
21
|
+
|
|
22
|
+
const zarel = new Zarel({
|
|
23
|
+
tenant: 'fintech_credit',
|
|
24
|
+
runtimeToken: process.env.ZAREL_RUNTIME_TOKEN!, // JWT class: tenant
|
|
25
|
+
contractToken: process.env.ZAREL_CONTRACT_TOKEN!, // JWT class: contract
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// ── runtime plane (https://fintech_credit.zarel.ia/v1) ────────────
|
|
29
|
+
const reply = await zarel.runtime.conversation.send({ message: 'List pending tickets' });
|
|
30
|
+
const tickets = await zarel.runtime.records.list('tickets');
|
|
31
|
+
await zarel.runtime.actions.dispatch('cancel_booking', { record_id: 42 });
|
|
32
|
+
|
|
33
|
+
// ── contract plane (https://fintech_credit.admin.zarel.ia/v1) ─────
|
|
34
|
+
const diff = await zarel.contract.spec.diff(yamlSource);
|
|
35
|
+
await zarel.contract.entities.create({ name: 'orders' /* ... */ });
|
|
36
|
+
await zarel.contract.actions.patch('replace_component', { enforcement: 'advisory' });
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Either token can be omitted if you only need one plane; touching the
|
|
40
|
+
other plane throws `ZarelAuthError` with a code identifying which token
|
|
41
|
+
is missing (`runtime_token_missing` / `contract_token_missing`). See
|
|
42
|
+
[Error Handling](#error-handling).
|
|
43
|
+
|
|
44
|
+
Tenant provisioning lives in `@zarel-ai/sdk-platform`; this SDK
|
|
45
|
+
operates against a tenant that already exists.
|
|
46
|
+
|
|
47
|
+
## Configuration
|
|
48
|
+
|
|
49
|
+
| Option | Type | Default | Description |
|
|
50
|
+
|--------|------|---------|-------------|
|
|
51
|
+
| `tenant` | `string` | — | Tenant slug; derives `runtimeBaseUrl` and `contractBaseUrl` when those are not set |
|
|
52
|
+
| `runtimeToken` | `string \| (() => string \| Promise<string>)` | — | Runtime-plane credential (`token_class: tenant`). A static JWT **or** a provider resolved before each request (auth-callback / refresh) |
|
|
53
|
+
| `contractToken` | `string \| (() => string \| Promise<string>)` | — | Contract-plane credential (`token_class: contract`); same string-or-provider shape |
|
|
54
|
+
| `transportManaged` | `boolean` | `false` | Transport-managed (no-token) mode for **both** planes: the SDK omits the `Authorization` header and skips the token-presence guard, leaving auth to a credential-injecting transport (e.g. a BFF proxy). Opt-in — direct consumers keep the token-required guard |
|
|
55
|
+
| `runtimeBaseUrl` | `string` | `https://{tenant}.zarel.ia/v1` | Override the runtime host |
|
|
56
|
+
| `contractBaseUrl` | `string` | `https://{tenant}.admin.zarel.ia/v1` | Override the contract host |
|
|
57
|
+
| `timeout` | `number` | `30000` | Request timeout (ms) — applied to both planes |
|
|
58
|
+
| `maxRetries` | `number` | `3` | Max retries on 5xx / network errors |
|
|
59
|
+
| `retryDelay` | `number` | `500` | Base retry delay (ms, exponential backoff) |
|
|
60
|
+
| `apiVersion` | `string` | — | When set, sends `X-Zarel-Api-Version: <value>` on every request (both planes). Forward-looking — no backend reads it yet |
|
|
61
|
+
| `interceptors` | `Interceptors` | — | Per-attempt request/response/error hooks (both planes). See [Interceptors](#interceptors) |
|
|
62
|
+
| `fetch` | `typeof fetch` | `globalThis.fetch` | Custom fetch implementation |
|
|
63
|
+
|
|
64
|
+
Every request also carries a built-in `User-Agent: @zarel-ai/sdk/<version>`
|
|
65
|
+
header (effective in Node; browsers drop it — `User-Agent` is a forbidden
|
|
66
|
+
`fetch` header).
|
|
67
|
+
|
|
68
|
+
When `tenant` is omitted and no explicit `runtimeBaseUrl` is given, the
|
|
69
|
+
runtime plane falls back to `https://api.zarel.ia/v1`.
|
|
70
|
+
|
|
71
|
+
## Plane Surface
|
|
72
|
+
|
|
73
|
+
### `client.runtime.*`
|
|
74
|
+
|
|
75
|
+
| Resource | Methods |
|
|
76
|
+
|----------|---------|
|
|
77
|
+
| `runtime.conversation` | `send`, `clearSession`; nested `sessions.{list, get, create, delete}`, `sessions.actions.{list}` |
|
|
78
|
+
| `runtime.tools` | `list`, `mcp.list`, `call`, `userCatalog` |
|
|
79
|
+
| `runtime.records` | `list`, `get`, `create`, `update`, `delete`, `bulk` |
|
|
80
|
+
| `runtime.actions` | `dispatch` (ADR-0085) |
|
|
81
|
+
| `runtime.stateMachine` | `listInstances`, `getInstance`, `listEvents`, `getEvent`, `listTransitionRequests`, `listPendingTransitions`, `getTransitionRequest`, `createTransitionRequest`, `resolveTransitionRequest`, `replay` |
|
|
82
|
+
| `runtime.flows` | `instances.{list, get}` (`list` accepts an optional `{flow}` filter), `callbacks.{resolve}` |
|
|
83
|
+
| `runtime.mcp` | `call(message)` — POST one MCP JSON-RPC message to `/runtime/mcp`, returns the typed `McpJsonRpcResponse` |
|
|
84
|
+
| `runtime.events` | `subscriptions.{list, create, delete}`, `deliveries.{list}` |
|
|
85
|
+
| `runtime.roles.assignments` | `list`, `create`, `delete` |
|
|
86
|
+
| `runtime.entities` | `recompute` (rewrites `runtime.records`; entity *authoring* is `contract.entities`) |
|
|
87
|
+
| `llm` | `services.{list, get}`, `credentials.{list, get, put, delete}` |
|
|
88
|
+
| `embeddings` | `credentials.{list, get, put, delete}` (per provider; write-only on the secret) |
|
|
89
|
+
| `runtime.imports` | `snapshot` |
|
|
90
|
+
| `runtime.traces` | `get`, `list`, `replay`, `bundle` |
|
|
91
|
+
| `runtime.audit` | `list(log, params?)` — paginated, filterable listing of a privacy-preserving audit row-table (`log` ∈ `binding_violations` \| `topic_refusals`); returns a `PagePromise` (`await` → one page, `for await` → auto-paginate). `evidence(log, { from?, to? })` — download a signed tamper-evidence bundle (`.tar.gz`) for an event hash-chain (`log` ∈ `state_machine` \| `flows`) for offline `zarel verify`; optional inclusive `seq` range bounds a large log (over-cap → HTTP 413) (ADR-0108) |
|
|
92
|
+
| `runtime.receipts` | `list(params?)` — the AUTHENTICATED caller's OWN governance receipts, normalized over the three audit signals (`refusal` \| `binding_violation` \| `validation_violation`); always scoped server-side to the token actor (no `view_traces`), returns a `PagePromise` (`await` → one page, `for await` → auto-paginate). Filter by `signal` / `trace_id` / `from` / `to`. Each receipt carries only a non-reversible proof (hash + masked value), never the raw value (Desk Spec 3) |
|
|
93
|
+
| `runtime.system` | `health`, `metrics`, `apiKeys.{list, create, delete}` |
|
|
94
|
+
| `runtime.authorizations` | `effective` — self-scoped effective-authorizations introspection (ADR-0102 §6, S3b) |
|
|
95
|
+
|
|
96
|
+
### `client.contract.*`
|
|
97
|
+
|
|
98
|
+
| Resource | Methods |
|
|
99
|
+
|----------|---------|
|
|
100
|
+
| `contract.spec` | `publish`, `diff`, `apply`, `snapshot.{get, localeCoverage, semanticDiff}`, `dryRun.{submit, get, cancel}` |
|
|
101
|
+
| `contract.entities` | `list`, `get`, `create`, `put`, `patch`, `delete`; `fields(name).{list, get, create, put, patch, delete}`; `fields(name).transitions(field).{list, get, create, put, patch, delete}` |
|
|
102
|
+
| `contract.roles` | `list`, `get`, `create`, `put`, `update`, `delete` (`put` = wholesale replace, `update` = partial patch) |
|
|
103
|
+
| `contract.flows` | `list`, `get`, `create`, `update`, `patch`, `delete`; `steps(name).{list, get, create, put, patch, delete}`; `onCompletion(name).{list, get, create, put, patch, delete}` — flow *definitions* (the `contract.flows` plane; runs live on `runtime.flows.instances`) |
|
|
104
|
+
| `contract.authorization` | `list(role)`, `get(role, onPath)`, `create(role, grant)`, `put(role, onPath, actions)`, `patch(role, onPath, actions)`, `del(role, onPath)` — the WHOLE authorization surface, addressed by `(role, on-path)` regardless of family. `ceiling.get()` — read-only owner/plan-envelope introspection (ADR-0102 §6) |
|
|
105
|
+
| `contract.skills` | `list`, `get`, `create`, `put`, `patch`, `delete` (some verbs may surface server-side `501 ENDPOINT_PLANNED`) |
|
|
106
|
+
| `contract.actions` | `list`, `get`, `create`, `put`, `patch`, `delete` (DELETE may surface 501) |
|
|
107
|
+
| `contract.assistant` | `createSession`, `conversationSend`, `getChangeset`, `applyChangeset`, `discardChangeset` — conversational authoring (conversation stages into one changeset; `applyChangeset({base_hash})` is the sole mutation, one version bump). On staleness `applyChangeset` throws `ZarelAPIError` with `code:'contract_hash_mismatch'` and `details.{reseeded_changeset_id, base_hash}` |
|
|
108
|
+
| `contract.batch` | `execute` (Microsoft Graph-style envelope) |
|
|
109
|
+
| `contract.capabilities` | `list`, `get`, `create`, `put`, `patch`, `delete` |
|
|
110
|
+
| `contract.constraints` | same |
|
|
111
|
+
| `contract.schemas` | same |
|
|
112
|
+
| `contract.metadata` | `get`, `put`, `patch` (composite singleton) |
|
|
113
|
+
| `contract.events.rules` | CRUD on `/contract/events/rules*` |
|
|
114
|
+
| `contract.processModel` | `get`/`put`/`patch` (the process-model document) + `phases.{list,get,create,put,patch,delete}` |
|
|
115
|
+
| `contract.quotas` | **no resource, by design.** The per-role bounds (`max_chained_actions_per_turn`, `composite_write.*`) have no admin route — they are declared by publishing the contract, so there is nothing for the SDK to call |
|
|
116
|
+
| `contract.{llm,embeddings,treatment,rails,channels,mcpServers,profiles,timezone}` | ADR-0138 contract roots (admin host). Distinct from the runtime-plane `client.runtime.*`. Singletons: `llm`, `rails`, `embeddings`, `timezone` (`get`/`put` only), `events.delivery`, `assistant` (`get`/`put`/`patch` + `vocabulary` collection). Collections: `mcpServers` (+ `allowedTools(ns)`), `profiles`, `channels` (+ `credentials`) |
|
|
117
|
+
|
|
118
|
+
_The namespace hierarchy is a structural bijection with the contract OpenAPI surface, enforced by `tests/contract-hierarchy-alignment.test.ts` (ADR-0066)._
|
|
119
|
+
|
|
120
|
+
### Working with authorization
|
|
121
|
+
|
|
122
|
+
A grant is `{ on, actions }` — the same shape the YAML contract declares, so what
|
|
123
|
+
you read here and what you author there are isomorphic. `on` is the **on-path**:
|
|
124
|
+
a config section (`entities`, `channels/credentials`) or an operational
|
|
125
|
+
root (`records/{entity}`, `flows/{flow}`, `llm/services/{name}`).
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
// Everything a role holds, canonically ordered
|
|
129
|
+
const { grants } = await client.contract.authorization.list('support');
|
|
130
|
+
|
|
131
|
+
// Create-or-replace one grant (idempotent). An action is a bare string or a
|
|
132
|
+
// single-key attenuation carrying `fields` / `scope` / `when`.
|
|
133
|
+
await client.contract.authorization.put('support', 'records/orders', [
|
|
134
|
+
'read',
|
|
135
|
+
'list',
|
|
136
|
+
{ update: { fields: ['status'] } },
|
|
137
|
+
]);
|
|
138
|
+
|
|
139
|
+
// Merge actions into an existing grant — adds or re-attenuates, never drops
|
|
140
|
+
await client.contract.authorization.patch('support', 'records/orders', ['create']);
|
|
141
|
+
|
|
142
|
+
await client.contract.authorization.del('support', 'records/orders');
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
`create(role, grant)` is the create-only verb: it returns **409** when a grant on
|
|
146
|
+
that on-path already exists, so it and the idempotent `put` never disagree about
|
|
147
|
+
duplicates.
|
|
148
|
+
|
|
149
|
+
Writes are bounded by the **plan ceiling** (ADR-0102 §6). Two `403`s are expected
|
|
150
|
+
and worth handling distinctly: `ceiling_exceeded` (the grant is outside the
|
|
151
|
+
tenant's plan envelope) and `owner_role_protected` (the role is platform-seeded
|
|
152
|
+
and immutable to the tenant — this applies to `del` too, not only writes). Read
|
|
153
|
+
the envelope those verdicts derive from with:
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
const { ownerRoleNames, grants } = await client.contract.authorization.ceiling.get();
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Grants are **exact-match, with no parent→child inheritance**: a grant on `runtime`
|
|
160
|
+
never covers `channels` (ADR-0136 §4.1). Address the child explicitly.
|
|
161
|
+
|
|
162
|
+
## Responses
|
|
163
|
+
|
|
164
|
+
Methods return the **response payload directly** — the SDK never surfaces the
|
|
165
|
+
wire-level `{ success, data }` envelope. The transport validates the envelope
|
|
166
|
+
and returns its `data`; a `success: false` envelope surfaces as a
|
|
167
|
+
`ZarelAPIError`. This is the single unwrap authority (ADR-0109).
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
const roles = await zarel.contract.roles.list(); // RoleRecord[] (not { success, data })
|
|
171
|
+
const order = await zarel.runtime.records.get('orders', 42); // RecordData
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
A handful of endpoints return a **bare body** (no envelope) or a **flat**
|
|
175
|
+
shape where `success` is a status field rather than a wrapper — e.g.
|
|
176
|
+
`contract.spec.snapshot.get` (the flat contract document), `runtime.conversation.send`
|
|
177
|
+
(`{ success, message, intent_type, … }`), `runtime.tools.*`, and
|
|
178
|
+
`runtime.flows.callbacks.resolve`. The SDK returns those **unchanged**.
|
|
179
|
+
|
|
180
|
+
The unwrap decision is **spec-derived, not guessed**: the OpenAPI is the single
|
|
181
|
+
source of truth. A codegen step (`gen:sdk-unwrap-map`) reads each operation's
|
|
182
|
+
success response and emits a checked-in per-plane map
|
|
183
|
+
(`src/generated/unwrap-map.ts`) of `{ [operationId]: { unwrap } }`; the transport
|
|
184
|
+
does an O(1) lookup by the `operationId` the resource passes. An operation whose
|
|
185
|
+
2xx response references the canonical envelope is unwrapped to `data`; a flat or
|
|
186
|
+
bare response is returned whole. There is **no runtime key-shape heuristic and no
|
|
187
|
+
manual opt-outs** — both were removed (ADR-0109 amendment). A build-time
|
|
188
|
+
completeness guard ensures every operation is classified, so the decision can
|
|
189
|
+
never silently fall through. Callers never think about this — the return type is
|
|
190
|
+
always the payload.
|
|
191
|
+
|
|
192
|
+
Response payload types are **generated from `docs/api/*-openapi-v1.yaml`** and
|
|
193
|
+
guarded against drift in CI (ADR-0109): `npm run gen:sdk` regenerates both the
|
|
194
|
+
types (`generated/{runtime,contract}.ts`) and the unwrap map from the same
|
|
195
|
+
response-schema signal, and jest drift-guards byte-diff the checked-in output.
|
|
196
|
+
|
|
197
|
+
## Pagination
|
|
198
|
+
|
|
199
|
+
The paginated list calls — `runtime.records.list`, `runtime.traces.list`,
|
|
200
|
+
`runtime.conversation.sessions.list`, and `runtime.audit.list` — return a value that is
|
|
201
|
+
**both awaitable and async-iterable** (the OpenAI/Stripe pattern):
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
// Await it for the first page — exactly the shape it has always returned:
|
|
205
|
+
const page = await zarel.runtime.records.list('orders', { limit: 50 });
|
|
206
|
+
console.log(page.records, page.total);
|
|
207
|
+
|
|
208
|
+
// …or iterate it to auto-paginate over every item across all pages:
|
|
209
|
+
for await (const order of zarel.runtime.records.list('orders', { filters: { status: 'open' } })) {
|
|
210
|
+
process(order);
|
|
211
|
+
}
|
|
212
|
+
for await (const trace of zarel.runtime.traces.list({ outcome: 'refused' })) { /* … */ }
|
|
213
|
+
for await (const session of zarel.runtime.conversation.sessions.list({ status: 'active' })) { /* … */ }
|
|
214
|
+
|
|
215
|
+
// Audit row-tables (gated by the `view_traces` runtime-system action):
|
|
216
|
+
const violations = await zarel.runtime.audit.list('binding_violations', { entity: 'Account' });
|
|
217
|
+
for await (const refusal of zarel.runtime.audit.list('topic_refusals', { category: 'investment_advice' })) { /* … */ }
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
`await` is fully backward-compatible — it resolves to the same single-page shape
|
|
221
|
+
as before (`{ records, total }`, `{ traces, next_cursor }`, or
|
|
222
|
+
`ConversationSessionSummary[]`). The first page is fetched lazily (nothing happens until
|
|
223
|
+
you `await` or iterate) and is shared if you do both.
|
|
224
|
+
|
|
225
|
+
**Page size.** Iteration uses your `limit` as the page size; if you omit it, the
|
|
226
|
+
server's natural page size is used (the SDK does not inject a default, so the
|
|
227
|
+
first request stays identical to a plain `list` call).
|
|
228
|
+
|
|
229
|
+
**Stopping early & cancellation.** `break` out of the loop and no further page is
|
|
230
|
+
requested. To cancel an in-flight request, pass an `AbortSignal`:
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
const ac = new AbortController();
|
|
234
|
+
for await (const order of zarel.runtime.records.list('orders', undefined, { signal: ac.signal })) {
|
|
235
|
+
if (done) { ac.abort(); break; }
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**Caveat — `conversation.sessions.list`.** That endpoint's wire shape carries neither a
|
|
240
|
+
`total` nor a cursor, so iteration stops when a page returns fewer items than the
|
|
241
|
+
page size. When the row count is an exact multiple of the page size, one extra
|
|
242
|
+
request returns an empty page and iteration then stops — no items are missed or
|
|
243
|
+
duplicated.
|
|
244
|
+
|
|
245
|
+
## Error Handling
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
import { ZarelAPIError, ZarelAuthError, ZarelTimeoutError } from '@zarel-ai/sdk';
|
|
249
|
+
|
|
250
|
+
try {
|
|
251
|
+
await zarel.runtime.records.list('tickets');
|
|
252
|
+
} catch (err) {
|
|
253
|
+
if (err instanceof ZarelAuthError) {
|
|
254
|
+
// Three discrete codes, distinguishable without parsing messages:
|
|
255
|
+
// 'runtime_token_missing' — runtime call without runtimeToken (pre-network)
|
|
256
|
+
// 'contract_token_missing' — contract call without contractToken (pre-network)
|
|
257
|
+
// 'unauthorized' — server returned 401
|
|
258
|
+
switch (err.code) {
|
|
259
|
+
case 'runtime_token_missing': /* configure runtimeToken */ break;
|
|
260
|
+
case 'contract_token_missing': /* configure contractToken */ break;
|
|
261
|
+
case 'unauthorized': /* refresh / re-mint */ break;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
if (err instanceof ZarelAPIError) {
|
|
265
|
+
console.error(`API Error ${err.status}: [${err.code}] ${err.message}`);
|
|
266
|
+
}
|
|
267
|
+
if (err instanceof ZarelTimeoutError) {
|
|
268
|
+
console.error('Request timed out');
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
## Retries
|
|
274
|
+
|
|
275
|
+
The SDK automatically retries on `408`, `429`, `500`, `502`, `503`, `504`
|
|
276
|
+
status codes and network errors using exponential backoff with jitter.
|
|
277
|
+
`401` immediately throws `ZarelAuthError` (no retry); `400` / `403` /
|
|
278
|
+
`404` / `501` surface as `ZarelAPIError` without retry.
|
|
279
|
+
|
|
280
|
+
**`Retry-After`** — when a retryable response (typically `429` / `503`) carries
|
|
281
|
+
a `Retry-After` header, the SDK honours it for that attempt's wait instead of the
|
|
282
|
+
exponential backoff. Both RFC 7231 forms are parsed (delta-seconds and an
|
|
283
|
+
HTTP-date); the wait is clamped to a 60-second ceiling so a huge value can't hang
|
|
284
|
+
the client (it still retries). When the header is absent or unparseable, the
|
|
285
|
+
exponential backoff is unchanged.
|
|
286
|
+
|
|
287
|
+
## Interceptors
|
|
288
|
+
|
|
289
|
+
Register per-attempt hooks at client construction (applied to both planes) to
|
|
290
|
+
observe and augment requests without replacing the transport:
|
|
291
|
+
|
|
292
|
+
```ts
|
|
293
|
+
const client = new Zarel({
|
|
294
|
+
tenant: 'acme',
|
|
295
|
+
runtimeToken: token,
|
|
296
|
+
interceptors: {
|
|
297
|
+
onRequest: (ctx) => { ctx.headers['X-Trace-Id'] = traceId(); }, // mutate in place
|
|
298
|
+
onResponse: (ctx) => log.debug(ctx.method, ctx.url, ctx.status, ctx.attempt),
|
|
299
|
+
onError: (ctx) => log.warn('transport failure', ctx.url, ctx.attempt, ctx.error),
|
|
300
|
+
},
|
|
301
|
+
});
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
- Hooks fire **once per network attempt** (retries included); `ctx.attempt` is
|
|
305
|
+
the 0-based attempt number.
|
|
306
|
+
- **`onRequest`** runs after the transport assembles the per-attempt headers
|
|
307
|
+
(`Authorization`, `Idempotency-Key`, `User-Agent`, `X-Zarel-Api-Version`), so it
|
|
308
|
+
sees and may override any of them by mutating `ctx.headers`. A **throw aborts**
|
|
309
|
+
the request (no network call, no retry) — useful as a pre-flight veto. (Avoid
|
|
310
|
+
changing `Idempotency-Key` across attempts — it breaks server-side dedup.)
|
|
311
|
+
Note: `ctx.headers` includes the `Authorization` bearer — don't log it.
|
|
312
|
+
- **`onResponse`** fires for **every** HTTP response (any status: 2xx/4xx/5xx),
|
|
313
|
+
read-only. **`onError`** fires only when an attempt produced **no** response (a
|
|
314
|
+
network error or timeout), read-only. The two are mutually exclusive per attempt
|
|
315
|
+
and a thrown observation hook is swallowed (it never masks the real outcome).
|
|
316
|
+
- Hooks may be `async`; the transport awaits them. Zero runtime dependencies.
|
|
317
|
+
|
|
318
|
+
## Streaming
|
|
319
|
+
|
|
320
|
+
`client.runtime.events.stream(...)` opens a typed Server-Sent-Events stream over
|
|
321
|
+
`GET /runtime/events/stream` (runtime plane). It is built on native `fetch` +
|
|
322
|
+
`ReadableStream` (so it carries the `Authorization` header for direct consumers
|
|
323
|
+
and credentials for proxy/cookie consumers — unlike a raw `EventSource`) and adds
|
|
324
|
+
**zero runtime dependencies**.
|
|
325
|
+
|
|
326
|
+
```ts
|
|
327
|
+
const handle = client.runtime.events.stream(
|
|
328
|
+
{
|
|
329
|
+
onEvent: (e) => {
|
|
330
|
+
if (e.event === 'conversation.turn_created') {
|
|
331
|
+
// typed via the exported `isConversationTurnCreatedEvent` guard
|
|
332
|
+
console.log(e.data.payload.session_key, e.data.payload.turn_number);
|
|
333
|
+
}
|
|
334
|
+
},
|
|
335
|
+
onError: (err) => console.error('stream ended', err), // terminal only
|
|
336
|
+
onOpen: () => console.log('connected'), // each (re)connect
|
|
337
|
+
},
|
|
338
|
+
{ reconnect: true /* default */ },
|
|
339
|
+
);
|
|
340
|
+
|
|
341
|
+
// later — tears down the request + stops reconnecting (idempotent):
|
|
342
|
+
handle.close();
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
Events are a typed union: a validated `conversation.turn_created` arm plus a generic
|
|
346
|
+
`{ event: string; data: unknown }` fallback for other named events. Narrow with the
|
|
347
|
+
exported `isConversationTurnCreatedEvent(e)` guard. Malformed or schema-failing frames are
|
|
348
|
+
dropped (never thrown into `onEvent`).
|
|
349
|
+
|
|
350
|
+
**Reconnection** is built in and default-on: a transient disconnect (network error,
|
|
351
|
+
server EOF, `5xx`, `408`, `429`) reconnects with bounded exponential backoff +
|
|
352
|
+
`Last-Event-ID`, indefinitely until `close()`/abort. A terminal status (`401`/`403`
|
|
353
|
+
and other `4xx`) calls `onError` once and stops. Pass `{ reconnect: false }` for a
|
|
354
|
+
single connection, `{ signal }` to abort via an `AbortSignal`, or `{ lastEventId }`
|
|
355
|
+
to resume from a known position.
|
|
356
|
+
|
|
357
|
+
### `events.iterate(...)` — async-iterable view
|
|
358
|
+
|
|
359
|
+
For a pull-style consumer, `client.runtime.events.iterate(...)` returns an
|
|
360
|
+
`AsyncIterableIterator<RuntimeStreamEvent>` over the **same** stream (same auth,
|
|
361
|
+
reconnect, and parsing — it adds no transport of its own):
|
|
362
|
+
|
|
363
|
+
```ts
|
|
364
|
+
const ac = new AbortController();
|
|
365
|
+
for await (const e of client.runtime.events.iterate({
|
|
366
|
+
signal: ac.signal,
|
|
367
|
+
bufferSize: 512, // default 1024; < 1 clamps to 1
|
|
368
|
+
onDropped: (n) => console.warn(`dropped ${n} (slow consumer)`),
|
|
369
|
+
})) {
|
|
370
|
+
if (isConversationTurnCreatedEvent(e)) console.log(e.data.payload.turn_number);
|
|
371
|
+
if (done(e)) break; // break tears the stream down
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
Events are buffered between the stream and your loop in a **bounded FIFO** ring of
|
|
376
|
+
`bufferSize`. If you consume slower than events arrive and the buffer fills, the
|
|
377
|
+
**oldest** event is dropped (loss-tolerant, like the callback stream) and `onDropped`
|
|
378
|
+
is called with the running total — so memory stays bounded regardless of consumer
|
|
379
|
+
speed. A **terminal** stream error (e.g. `401`) is thrown out of the `for await`
|
|
380
|
+
(buffered events drain first); a transient disconnect reconnects silently and never
|
|
381
|
+
ends the loop. `break`/`return`/`throw` and an aborted `signal` all tear the
|
|
382
|
+
underlying stream down. `iterate` does not take `onOpen` (use `stream` for per-connect
|
|
383
|
+
signals); `signal`/`reconnect`/`lastEventId` apply identically.
|
|
384
|
+
|
|
385
|
+
## MCP transport (`runtime.mcp.call`)
|
|
386
|
+
|
|
387
|
+
`client.runtime.mcp.call(message)` sends one MCP JSON-RPC message to the tenant's
|
|
388
|
+
stateless MCP "Streamable HTTP" transport (`POST /runtime/mcp`, runtime plane) and
|
|
389
|
+
returns the typed `McpJsonRpcResponse`. It accepts either an `application/json` body
|
|
390
|
+
or a single `text/event-stream` frame (the server chooses) and de-frames both —
|
|
391
|
+
bare JSON-RPC, never the `{success,data}` envelope. A **protocol-level** JSON-RPC
|
|
392
|
+
error is returned in the union (not thrown); **transport** failures throw
|
|
393
|
+
(`ZarelAuthError` on 401, `ZarelAPIError` otherwise). It makes a single attempt
|
|
394
|
+
(no retry — `tools/call` may be a non-idempotent mutation).
|
|
395
|
+
|
|
396
|
+
```ts
|
|
397
|
+
const res = await client.runtime.mcp.call({ jsonrpc: '2.0', id: 1, method: 'tools/list' });
|
|
398
|
+
if ('error' in res) console.error(res.error.code, res.error.message);
|
|
399
|
+
else console.log(res.result);
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
This is a thin, zero-dependency one-shot call — for a full MCP client (sessions,
|
|
403
|
+
server-push) use `@modelcontextprotocol/sdk`.
|
|
404
|
+
|
|
405
|
+
## Requirements
|
|
406
|
+
|
|
407
|
+
- Node.js 18+ (for native `fetch`)
|
|
408
|
+
- TypeScript 5.0+ (for type-safe usage)
|
|
409
|
+
|
|
410
|
+
## License
|
|
411
|
+
|
|
412
|
+
MIT
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { TokenInput } from './fetch-client';
|
|
2
|
+
export type RequireTokenCode = 'runtime_token_missing' | 'contract_token_missing';
|
|
3
|
+
/**
|
|
4
|
+
* The SINGLE auth authority (G3 QI-001) shared by BOTH request paths — the REST
|
|
5
|
+
* `FetchClient` and the SSE stream client. Given a token (string or provider)
|
|
6
|
+
* and the transport-managed flag, it resolves the token (honoring the optional
|
|
7
|
+
* presence guard) and returns the `Authorization` header decision:
|
|
8
|
+
*
|
|
9
|
+
* - transport-managed → `{}` (the credential-injecting transport sets the
|
|
10
|
+
* header server-side; the SDK omits it and skips the presence guard);
|
|
11
|
+
* - direct, empty token → `{}` (no bearer);
|
|
12
|
+
* - direct, present token → `{ Authorization: 'Bearer <token>' }`.
|
|
13
|
+
*
|
|
14
|
+
* Centralizing this here means there is exactly one place that builds a Bearer
|
|
15
|
+
* header — neither the SSE client nor any resource may build its own (the QI-001
|
|
16
|
+
* structural gate enforces a single `Bearer ` site).
|
|
17
|
+
*/
|
|
18
|
+
export declare function resolveAuthHeaders(token: TokenInput, transportManaged: boolean, requireTokenCode?: RequireTokenCode): Promise<Record<string, string>>;
|
|
19
|
+
//# sourceMappingURL=auth-headers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-headers.d.ts","sourceRoot":"","sources":["../../src/_internal/auth-headers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,MAAM,MAAM,gBAAgB,GAAG,uBAAuB,GAAG,wBAAwB,CAAC;AAElF;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,kBAAkB,CACpC,KAAK,EAAE,UAAU,EACjB,gBAAgB,EAAE,OAAO,EACzB,gBAAgB,CAAC,EAAE,gBAAgB,GACpC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CASjC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveAuthHeaders = resolveAuthHeaders;
|
|
4
|
+
const require_token_1 = require("./require-token");
|
|
5
|
+
/**
|
|
6
|
+
* The SINGLE auth authority (G3 QI-001) shared by BOTH request paths — the REST
|
|
7
|
+
* `FetchClient` and the SSE stream client. Given a token (string or provider)
|
|
8
|
+
* and the transport-managed flag, it resolves the token (honoring the optional
|
|
9
|
+
* presence guard) and returns the `Authorization` header decision:
|
|
10
|
+
*
|
|
11
|
+
* - transport-managed → `{}` (the credential-injecting transport sets the
|
|
12
|
+
* header server-side; the SDK omits it and skips the presence guard);
|
|
13
|
+
* - direct, empty token → `{}` (no bearer);
|
|
14
|
+
* - direct, present token → `{ Authorization: 'Bearer <token>' }`.
|
|
15
|
+
*
|
|
16
|
+
* Centralizing this here means there is exactly one place that builds a Bearer
|
|
17
|
+
* header — neither the SSE client nor any resource may build its own (the QI-001
|
|
18
|
+
* structural gate enforces a single `Bearer ` site).
|
|
19
|
+
*/
|
|
20
|
+
async function resolveAuthHeaders(token, transportManaged, requireTokenCode) {
|
|
21
|
+
if (transportManaged) {
|
|
22
|
+
return {};
|
|
23
|
+
}
|
|
24
|
+
const resolved = typeof token === 'function' ? await token() : token;
|
|
25
|
+
if (requireTokenCode) {
|
|
26
|
+
(0, require_token_1.requireToken)(resolved, requireTokenCode);
|
|
27
|
+
}
|
|
28
|
+
return resolved === '' ? {} : { 'Authorization': `Bearer ${resolved}` };
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=auth-headers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-headers.js","sourceRoot":"","sources":["../../src/_internal/auth-headers.ts"],"names":[],"mappings":";;AAoBA,gDAaC;AAjCD,mDAA+C;AAK/C;;;;;;;;;;;;;;GAcG;AACI,KAAK,UAAU,kBAAkB,CACpC,KAAiB,EACjB,gBAAyB,EACzB,gBAAmC;IAEnC,IAAI,gBAAgB,EAAE,CAAC;QACnB,OAAO,EAAE,CAAC;IACd,CAAC;IACD,MAAM,QAAQ,GAAG,OAAO,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IACrE,IAAI,gBAAgB,EAAE,CAAC;QACnB,IAAA,4BAAY,EAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,UAAU,QAAQ,EAAE,EAAE,CAAC;AAC5E,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Confirmation round-trip transport helpers (ADR-0127 US3) — the single place
|
|
3
|
+
* the SDK names the header and the single place it parses the challenge.
|
|
4
|
+
*/
|
|
5
|
+
import type { ConfirmationChallenge } from '../types/confirmation';
|
|
6
|
+
/** The retry header. Read server-side from the header only, never the body. */
|
|
7
|
+
export declare const CONFIRMATION_TOKEN_HEADER = "X-Zarel-Confirmation-Token";
|
|
8
|
+
/** `{}` when no token — so a caller can spread this unconditionally. */
|
|
9
|
+
export declare function confirmationHeaders(token?: string): Record<string, string>;
|
|
10
|
+
/**
|
|
11
|
+
* Parse `error.confirmation` off a 409 body, fail-closed.
|
|
12
|
+
*
|
|
13
|
+
* Returns undefined unless the challenge is COMPLETE — at least one named guard
|
|
14
|
+
* AND a token. A challenge with no token cannot be round-tripped, and one with
|
|
15
|
+
* no guard has no prompt to show, so surfacing either as a confirmable error
|
|
16
|
+
* would offer the operator a Confirm button that can only fail. Undefined
|
|
17
|
+
* degrades the 409 to an ordinary API error, which is the honest outcome.
|
|
18
|
+
*
|
|
19
|
+
* A guard missing its `prompt` is kept with a name-derived fallback (the name is
|
|
20
|
+
* what makes it auditable); a guard missing its `name` is dropped, mirroring
|
|
21
|
+
* `parseConfirmationGuards` in `@zarel-ai/contract/core`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function parseConfirmationChallenge(raw: unknown): ConfirmationChallenge | undefined;
|
|
24
|
+
//# sourceMappingURL=confirmation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confirmation.d.ts","sourceRoot":"","sources":["../../src/_internal/confirmation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAqB,MAAM,uBAAuB,CAAC;AAEtF,+EAA+E;AAC/E,eAAO,MAAM,yBAAyB,+BAA+B,CAAC;AAEtE,wEAAwE;AACxE,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAE1E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,OAAO,GAAG,qBAAqB,GAAG,SAAS,CAoB1F"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Confirmation round-trip transport helpers (ADR-0127 US3) — the single place
|
|
4
|
+
* the SDK names the header and the single place it parses the challenge.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.CONFIRMATION_TOKEN_HEADER = void 0;
|
|
8
|
+
exports.confirmationHeaders = confirmationHeaders;
|
|
9
|
+
exports.parseConfirmationChallenge = parseConfirmationChallenge;
|
|
10
|
+
/** The retry header. Read server-side from the header only, never the body. */
|
|
11
|
+
exports.CONFIRMATION_TOKEN_HEADER = 'X-Zarel-Confirmation-Token';
|
|
12
|
+
/** `{}` when no token — so a caller can spread this unconditionally. */
|
|
13
|
+
function confirmationHeaders(token) {
|
|
14
|
+
return token ? { [exports.CONFIRMATION_TOKEN_HEADER]: token } : {};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Parse `error.confirmation` off a 409 body, fail-closed.
|
|
18
|
+
*
|
|
19
|
+
* Returns undefined unless the challenge is COMPLETE — at least one named guard
|
|
20
|
+
* AND a token. A challenge with no token cannot be round-tripped, and one with
|
|
21
|
+
* no guard has no prompt to show, so surfacing either as a confirmable error
|
|
22
|
+
* would offer the operator a Confirm button that can only fail. Undefined
|
|
23
|
+
* degrades the 409 to an ordinary API error, which is the honest outcome.
|
|
24
|
+
*
|
|
25
|
+
* A guard missing its `prompt` is kept with a name-derived fallback (the name is
|
|
26
|
+
* what makes it auditable); a guard missing its `name` is dropped, mirroring
|
|
27
|
+
* `parseConfirmationGuards` in `@zarel-ai/contract/core`.
|
|
28
|
+
*/
|
|
29
|
+
function parseConfirmationChallenge(raw) {
|
|
30
|
+
if (typeof raw !== 'object' || raw === null)
|
|
31
|
+
return undefined;
|
|
32
|
+
const { guards, token, expires_at: expiresAt } = raw;
|
|
33
|
+
if (typeof token !== 'string' || token.length === 0)
|
|
34
|
+
return undefined;
|
|
35
|
+
if (!Array.isArray(guards))
|
|
36
|
+
return undefined;
|
|
37
|
+
const parsed = [];
|
|
38
|
+
for (const entry of guards) {
|
|
39
|
+
if (typeof entry !== 'object' || entry === null)
|
|
40
|
+
continue;
|
|
41
|
+
const { name, prompt } = entry;
|
|
42
|
+
if (typeof name !== 'string' || name.length === 0)
|
|
43
|
+
continue;
|
|
44
|
+
parsed.push({ name, prompt: typeof prompt === 'string' ? prompt : `Confirm "${name}"` });
|
|
45
|
+
}
|
|
46
|
+
if (parsed.length === 0)
|
|
47
|
+
return undefined;
|
|
48
|
+
return {
|
|
49
|
+
guards: parsed,
|
|
50
|
+
token,
|
|
51
|
+
expires_at: typeof expiresAt === 'string' ? expiresAt : '',
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=confirmation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confirmation.js","sourceRoot":"","sources":["../../src/_internal/confirmation.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAQH,kDAEC;AAeD,gEAoBC;AAzCD,+EAA+E;AAClE,QAAA,yBAAyB,GAAG,4BAA4B,CAAC;AAEtE,wEAAwE;AACxE,SAAgB,mBAAmB,CAAC,KAAc;IAC9C,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,iCAAyB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAC/D,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,0BAA0B,CAAC,GAAY;IACnD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAC9D,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,GAA8B,CAAC;IAChF,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACtE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,SAAS,CAAC;IAE7C,MAAM,MAAM,GAAwB,EAAE,CAAC;IACvC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QACzB,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;YAAE,SAAS;QAC1D,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,KAAgC,CAAC;QAC1D,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAC5D,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,IAAI,GAAG,EAAE,CAAC,CAAC;IAC7F,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAE1C,OAAO;QACH,MAAM,EAAE,MAAM;QACd,KAAK;QACL,UAAU,EAAE,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE;KAC7D,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { EventStreamHandle, EventStreamHandlers, EventStreamOptions, RuntimeStreamEvent } from '../types/events-stream';
|
|
2
|
+
/** Opens an underlying stream with the given handlers; returns its teardown handle. */
|
|
3
|
+
export type OpenStream = (handlers: EventStreamHandlers, options: EventStreamOptions) => EventStreamHandle;
|
|
4
|
+
export interface EventIteratorConfig {
|
|
5
|
+
/** Bounded buffer capacity; clamped to a minimum of 1. */
|
|
6
|
+
bufferSize?: number;
|
|
7
|
+
/** Reported with the running total on each overflow drop. */
|
|
8
|
+
onDropped?: (totalDropped: number) => void;
|
|
9
|
+
/** Stream options forwarded verbatim to `open` (signal/reconnect/lastEventId). */
|
|
10
|
+
streamOptions: EventStreamOptions;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Build an `AsyncIterableIterator<RuntimeStreamEvent>` over `open`. The first
|
|
14
|
+
* `next()` (or entry into a `for await`) lazily opens the stream; `return()` /
|
|
15
|
+
* `throw()` / consumer `break` tear it down via the handle's idempotent `close()`.
|
|
16
|
+
*/
|
|
17
|
+
export declare function createEventIterator(open: OpenStream, config: EventIteratorConfig): AsyncIterableIterator<RuntimeStreamEvent>;
|
|
18
|
+
//# sourceMappingURL=event-iterator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-iterator.d.ts","sourceRoot":"","sources":["../../src/_internal/event-iterator.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACR,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EACrB,MAAM,wBAAwB,CAAC;AAIhC,uFAAuF;AACvF,MAAM,MAAM,UAAU,GAAG,CAAC,QAAQ,EAAE,mBAAmB,EAAE,OAAO,EAAE,kBAAkB,KAAK,iBAAiB,CAAC;AAE3G,MAAM,WAAW,mBAAmB;IAChC,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,kFAAkF;IAClF,aAAa,EAAE,kBAAkB,CAAC;CACrC;AASD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAC/B,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,mBAAmB,GAC5B,qBAAqB,CAAC,kBAAkB,CAAC,CA4I3C"}
|