@to11ai/sdk 1.1.0 → 2.0.0-rc.10
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 +99 -258
- package/dist/client.cjs +91 -45
- package/dist/client.d.ts +149 -61
- package/dist/client.js +95 -55
- package/dist/config.d.ts +9 -0
- package/dist/context.d.ts +124 -0
- package/dist/errors.cjs +36 -24
- package/dist/errors.d.ts +35 -46
- package/dist/errors.js +36 -24
- package/dist/gateway.cjs +85 -31
- package/dist/gateway.d.ts +102 -27
- package/dist/gateway.js +85 -31
- package/dist/generated/index.d.ts +1 -1
- package/dist/generated/types.gen.d.ts +2802 -502
- package/dist/generated/zod.gen.d.ts +1018 -243
- package/dist/prompts/resource.cjs +80 -113
- package/dist/prompts/resource.d.ts +60 -39
- package/dist/prompts/resource.js +84 -113
- package/dist/prompts/shape.d.ts +56 -0
- package/dist/prompts/types.d.ts +76 -61
- package/dist/transport.d.ts +2 -6
- package/package.json +5 -11
- package/src/client.ts +332 -157
- package/src/config.ts +13 -0
- package/src/context.ts +196 -0
- package/src/errors.ts +65 -79
- package/src/gateway.ts +212 -67
- package/src/generated/index.ts +1 -1
- package/src/generated/types.gen.ts +2977 -611
- package/src/generated/zod.gen.ts +1029 -338
- package/src/prompts/resource.ts +211 -226
- package/src/prompts/shape.ts +152 -0
- package/src/prompts/types.ts +77 -65
- package/src/transport.ts +53 -40
- package/dist/prompts/cache.d.ts +0 -59
- package/dist/routingRules/resource.cjs +0 -138
- package/dist/routingRules/resource.js +0 -98
- package/src/prompts/cache.ts +0 -157
package/README.md
CHANGED
|
@@ -2,325 +2,166 @@
|
|
|
2
2
|
|
|
3
3
|
JavaScript/TypeScript SDK for [to11ai](https://to11ai.com) — the AI engineering platform for prompt management, tracing, and evals.
|
|
4
4
|
|
|
5
|
+
Use it to **render managed prompts** at runtime, **wire your own provider client** (OpenAI, Anthropic, …) to the to11 gateway with the right auth/trace headers, and group model calls into **sessions, conversations, and turns** for tracing.
|
|
6
|
+
|
|
5
7
|
Ships ESM, CommonJS, and raw TypeScript source in the same package. Runtimes and bundlers pick the right variant automatically.
|
|
6
8
|
|
|
7
9
|
## Installation
|
|
8
10
|
|
|
9
11
|
```bash
|
|
10
12
|
npm install @to11ai/sdk
|
|
11
|
-
# or
|
|
12
|
-
bun add @to11ai/sdk
|
|
13
|
-
# or
|
|
14
|
-
pnpm add @to11ai/sdk
|
|
15
|
-
# or
|
|
16
|
-
yarn add @to11ai/sdk
|
|
13
|
+
# or: bun add @to11ai/sdk · pnpm add @to11ai/sdk · yarn add @to11ai/sdk
|
|
17
14
|
```
|
|
18
15
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
| Runtime / loader | Resolves to | Notes |
|
|
22
|
-
| --------------------------- | -------------------- | --------------------------------------------- |
|
|
23
|
-
| Node.js (ESM: `import`) | `dist/*.js` | Bundled ESM, Node-targeted |
|
|
24
|
-
| Node.js (CJS: `require`) | `dist/*.cjs` | Bundled CommonJS |
|
|
25
|
-
| TypeScript (type resolution)| `dist/*.d.ts` | Declarations for editor + tsc |
|
|
26
|
-
| Bun | `src/*.ts` | Raw source — zero build overhead, full maps |
|
|
27
|
-
| Deno | `src/*.ts` | Raw source |
|
|
28
|
-
| Browsers (via bundler) | `dist/*.js` | Tree-shakeable ESM |
|
|
29
|
-
| Workers / edge runtimes | `dist/*.js` | ESM, Node-compatible |
|
|
16
|
+
Runs anywhere Node, Bun, Deno, or edge runs — servers, CLIs, and backend jobs. Not for browsers: a to11 API key carries gateway access and must never ship in client-side code.
|
|
30
17
|
|
|
31
|
-
|
|
18
|
+
## Quick start
|
|
32
19
|
|
|
33
|
-
|
|
20
|
+
Create a client, render a prompt for the current environment, and send it through the gateway with your normal provider client:
|
|
34
21
|
|
|
35
22
|
```typescript
|
|
36
23
|
import { createClient } from "@to11ai/sdk";
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
24
|
+
import OpenAI from "openai";
|
|
25
|
+
|
|
26
|
+
const to11 = createClient({
|
|
27
|
+
// `process.env` is the Node/Bun form; on Deno/edge use that runtime's env API —
|
|
28
|
+
// or omit these entirely, since the SDK reads the matching `TO11_*` vars itself.
|
|
29
|
+
baseUrl: process.env.TO11_API_URL, // → https://api.to11.ai
|
|
30
|
+
apiKey: process.env.TO11_API_KEY, // → TO11_API_KEY
|
|
31
|
+
projectId: process.env.TO11_PROJECT_ID, // → TO11_PROJECT_ID
|
|
32
|
+
env: process.env.TO11_ENV, // "prod", "staging", … → TO11_ENV
|
|
41
33
|
});
|
|
42
34
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
variables: { userName: "Alice" },
|
|
35
|
+
// Render a released prompt for the client's project + environment.
|
|
36
|
+
const prompt = await to11.prompts.render("welcome-message", {
|
|
37
|
+
variables: { name: "Ada" },
|
|
38
|
+
format: "openai", // omit for the provider-neutral result
|
|
48
39
|
});
|
|
49
40
|
|
|
50
|
-
|
|
41
|
+
// Point your provider client at the gateway and send it.
|
|
42
|
+
const openai = new OpenAI(to11.openaiOptions());
|
|
43
|
+
const completion = await openai.chat.completions.create(
|
|
44
|
+
{ ...prompt.config, messages: prompt.messages },
|
|
45
|
+
{ headers: to11.turn().headers(prompt) }, // auth + trace id + prompt provenance
|
|
46
|
+
);
|
|
51
47
|
```
|
|
52
48
|
|
|
53
|
-
|
|
49
|
+
`prompt.config` carries the model parameters, `prompt.messages` the rendered messages, and `turn().headers(prompt)` the headers that authenticate the gateway call and record which prompt produced the trace. You never assemble a `provider::model` string or merge auth headers by hand.
|
|
54
50
|
|
|
55
|
-
|
|
51
|
+
## Configuring the client
|
|
56
52
|
|
|
57
|
-
|
|
53
|
+
`createClient(options)` is a factory (call it directly, no `new`). Each URL/credential resolves **option → environment variable → built-in default**, so a server app can construct it from the environment alone.
|
|
58
54
|
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
| Option | Resolves from | Default |
|
|
56
|
+
| --- | --- | --- |
|
|
57
|
+
| `baseUrl` | option → `TO11_API_URL` | `https://api.to11.ai` |
|
|
58
|
+
| `gatewayUrl` | option → `TO11_GATEWAY_URL` | `https://gw.to11.ai` |
|
|
59
|
+
| `apiKey` | option → `TO11_API_KEY` | — (throws if constructed in a browser) |
|
|
60
|
+
| `projectId` | option → `TO11_PROJECT_ID` | — |
|
|
61
|
+
| `env` | option → `TO11_ENV` | — (must match `^[a-z0-9-]{1,63}$`) |
|
|
62
|
+
| `providerApiKey` | option | — (BYOK; carried by `openaiOptions()`/`anthropicOptions()`) |
|
|
63
|
+
| `format` | option | — (`"openai"` \| `"anthropic"`; omit for the neutral result) |
|
|
64
|
+
| `onUnknownRole` | option | `"drop"` |
|
|
65
|
+
| `timeoutMs` / `maxRetries` | option | `30000` / `3` |
|
|
61
66
|
|
|
62
|
-
|
|
63
|
-
baseUrl: "https://api.to11ai.com",
|
|
64
|
-
apiKey: process.env.TO11AI_API_KEY!,
|
|
65
|
-
});
|
|
66
|
-
```
|
|
67
|
+
> **Keep credentials server-side.** A to11 API key carries gateway access, so it must never ship in browser code — the SDK throws if you construct a client with `apiKey` in a browser context (like OpenAI's `dangerouslyAllowBrowser`). The same goes for a `providerApiKey` (BYOK). Use the SDK from a server, CLI, or backend job.
|
|
67
68
|
|
|
68
|
-
|
|
69
|
+
The client exposes read-only accessors for the resolved values — **`to11.baseUrl`**, **`to11.gatewayUrl`**, **`to11.apiKey`**, **`to11.projectId`**, and **`to11.env`**. Use the non-secret ones (`baseUrl`/`gatewayUrl`/`projectId`/`env`) for diagnostics; `apiKey` is exposed to build manual auth headers — treat it as a secret and never log it. `providerApiKey` (BYOK) is deliberately **not** exposed back off the client.
|
|
69
70
|
|
|
70
|
-
|
|
71
|
+
## Rendering prompts
|
|
71
72
|
|
|
72
|
-
|
|
73
|
-
import { createClient } from "@to11ai/sdk";
|
|
73
|
+
`prompts.render(slug, options?)` resolves the released prompt for the client's `projectId` + `env` in one request. Set `format` (on the client or per call) to get a result shaped for that provider; omit it for the provider-neutral result.
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
75
|
+
```typescript
|
|
76
|
+
const prompt = await to11.prompts.render("weather-concierge", {
|
|
77
|
+
variables: { city: "New York", units: "fahrenheit" },
|
|
78
|
+
// label?: label to resolve for this call (defaults to the client's env)
|
|
79
|
+
// subject?: a stable id so a weighted release pins the same caller to a variant
|
|
80
|
+
// fallback?: a previously-rendered RenderedPrompt served on a network error
|
|
81
|
+
// format?: "openai" | "anthropic"
|
|
82
82
|
});
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
## Prompt resolution
|
|
85
|
+
- **With `format`** the result is spread-ready: `{ messages, config, metadata }` (`config` = the version's model params; `metadata` = prompt/version/release provenance).
|
|
86
|
+
- **Without `format`** you get the neutral **`RenderedPrompt`**: `messages`, `tools`, `toolChoice`, `promptId`, `version`, `versionId`, `releaseId`, `variantName`, `contentHash`, `label`, `slug`, `blockRenderRecord`, and `modelConfig`. This is the path for providers the shaper doesn't cover (Vercel AI, LangChain) or for driving one prompt through more than one provider.
|
|
88
87
|
|
|
89
|
-
`
|
|
88
|
+
Authored `developer` blocks come back as-is; the SDK maps them per provider (OpenAI keeps `developer`; Anthropic folds `system`/`developer` into the top-level `system`). `onUnknownRole` (`"drop"` default, `"warn"`, `"error"`) controls how an unrecognized role is handled during provider conversion.
|
|
90
89
|
|
|
91
|
-
|
|
92
|
-
const result = await client.prompts.resolve({
|
|
93
|
-
projectId: "proj_abc123",
|
|
94
|
-
slug: "summarise-article",
|
|
95
|
-
labels: ["production", "en"],
|
|
96
|
-
variables: {
|
|
97
|
-
article: "OpenAI releases GPT-5...",
|
|
98
|
-
maxLength: 200,
|
|
99
|
-
},
|
|
100
|
-
});
|
|
90
|
+
> Prompts render as **chat blocks**. The pre-2.0 `resolve()` and the `text` render format have been removed — use `render()` with a `label` (the client's `env` is the default; env is just a label value).
|
|
101
91
|
|
|
102
|
-
|
|
103
|
-
console.log(result.rendered.text);
|
|
104
|
-
} else {
|
|
105
|
-
// chat format
|
|
106
|
-
for (const msg of result.rendered.messages) {
|
|
107
|
-
console.log(`[${msg.role}] ${msg.content}`);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
```
|
|
92
|
+
## Sending through the gateway
|
|
111
93
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
| Method | Description |
|
|
115
|
-
|---|---|
|
|
116
|
-
| `prompts.resolve(input)` | Fetch a prompt by slug + labels, render variables, return rendered output. Cached by default. |
|
|
117
|
-
| `prompts.create(input)` | Create a new prompt (name, slug, description, tags). |
|
|
118
|
-
| `prompts.list(input)` | List prompts in a project with optional pagination. |
|
|
119
|
-
| `prompts.get(input)` | Get a single prompt by ID. |
|
|
120
|
-
| `prompts.update(input)` | Update prompt metadata (name, description, tags). |
|
|
121
|
-
| `prompts.archive(input)` | Archive a prompt (soft delete). |
|
|
122
|
-
| `prompts.createVersion(input)` | Create a new version for an existing prompt. |
|
|
123
|
-
| `prompts.listVersions(input)` | List all versions of a prompt. |
|
|
124
|
-
| `prompts.getVersion(input)` | Get a specific version by version number. |
|
|
125
|
-
| `prompts.moveLabel(input)` | Point a label (e.g. `production`) at a specific version. |
|
|
126
|
-
| `prompts.listLabels(input)` | List all label pointers for a prompt. |
|
|
127
|
-
| `prompts.listProjectLabels(input)` | List the project-level label registry. Pass `includeArchived: true` for soft-deleted rows. |
|
|
128
|
-
| `prompts.createProjectLabel(input)` | Create a new project label (requires `project:manage_labels`). |
|
|
129
|
-
| `prompts.getProjectLabel(input)` | Get a single project label by name. |
|
|
130
|
-
| `prompts.updateProjectLabel(input)` | Update a project label's `isDefault`, `description`, or `displayColor`. |
|
|
131
|
-
| `prompts.deleteProjectLabel(input)` | Archive (soft-delete) a project label. Returns the archived row. |
|
|
132
|
-
| `prompts.listProjectLabelUsages(input)` | List every prompt currently pointed at by a given project label. |
|
|
133
|
-
| `prompts.listLabelEvents(input)` | List immutable label-movement events. Polymorphic by `scope`: `"label"`, `"prompt"`, or `"project"`. |
|
|
134
|
-
|
|
135
|
-
All methods require at minimum `projectId` and the relevant resource identifier(s).
|
|
136
|
-
|
|
137
|
-
## Project label registry
|
|
138
|
-
|
|
139
|
-
The project label registry stores the canonical list of labels available in a project (e.g. `production`, `staging`, `experiment`). When strict-mode is enabled on a project, `prompts.moveLabel()` only accepts labels that exist in the registry.
|
|
94
|
+
`openaiOptions()` / `anthropicOptions()` return spread-ready options (`{ baseURL, apiKey, defaultHeaders }`) for a provider client pointed at the gateway; `defaultHeaders` carries the static tenant auth. Add `turn().headers(prompt)` per call for the trace id and prompt provenance:
|
|
140
95
|
|
|
141
96
|
```typescript
|
|
142
|
-
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
label: "canary",
|
|
146
|
-
isDefault: false,
|
|
147
|
-
description: "5% traffic shadow",
|
|
148
|
-
displayColor: "amber",
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
// List the project's labels (excludes archived rows by default)
|
|
152
|
-
const labels = await client.prompts.listProjectLabels({
|
|
153
|
-
projectId: "proj_abc123",
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
// Reverse-lookup: which prompts currently point at this label?
|
|
157
|
-
const usages = await client.prompts.listProjectLabelUsages({
|
|
158
|
-
projectId: "proj_abc123",
|
|
159
|
-
label: "production",
|
|
160
|
-
});
|
|
97
|
+
import Anthropic from "@anthropic-ai/sdk";
|
|
98
|
+
const anthropic = new Anthropic(to11.anthropicOptions());
|
|
99
|
+
```
|
|
161
100
|
|
|
162
|
-
|
|
163
|
-
const allEvents = await client.prompts.listLabelEvents({
|
|
164
|
-
scope: "project",
|
|
165
|
-
projectId: "proj_abc123",
|
|
166
|
-
page: 1,
|
|
167
|
-
limit: 50,
|
|
168
|
-
since: "2024-01-01T00:00:00Z",
|
|
169
|
-
});
|
|
101
|
+
By default the gateway runs the call on the project's configured provider credential (managed). For **BYOK**, set `providerApiKey` on `createClient` (or pass `apiKey` to the helper per call). For Vercel AI / LangChain, build the base URL from `to11.gatewayUrl` and attach `turn().headers()` yourself.
|
|
170
102
|
|
|
171
|
-
|
|
172
|
-
scope: "prompt",
|
|
173
|
-
projectId: "proj_abc123",
|
|
174
|
-
promptId: "prompt_xyz789",
|
|
175
|
-
label: "production", // optional filter
|
|
176
|
-
});
|
|
103
|
+
## Sessions, conversations & turns
|
|
177
104
|
|
|
178
|
-
|
|
179
|
-
scope: "label",
|
|
180
|
-
projectId: "proj_abc123",
|
|
181
|
-
promptId: "prompt_xyz789",
|
|
182
|
-
label: "production",
|
|
183
|
-
});
|
|
184
|
-
```
|
|
105
|
+
Group model calls for tracing. `to11.turn()` uses the client's default session; create explicit ones with `to11.session(id?)` / `to11.conversation(id?)`. `turn().headers(prompt?)` emits the session/conversation/`traceparent` headers (plus prompt provenance when a rendered prompt is passed).
|
|
185
106
|
|
|
186
|
-
##
|
|
107
|
+
## Managing prompts, versions & labels
|
|
187
108
|
|
|
188
|
-
|
|
109
|
+
Beyond `render()`, the `prompts` namespace covers the control-plane lifecycle. **All of these default `projectId` from the client** — pass it per call only to override:
|
|
189
110
|
|
|
190
111
|
```typescript
|
|
191
|
-
|
|
192
|
-
To11aiError,
|
|
193
|
-
To11aiApiError,
|
|
194
|
-
To11aiAuthError,
|
|
195
|
-
To11aiRateLimitError,
|
|
196
|
-
To11aiValidationError,
|
|
197
|
-
To11aiNetworkError,
|
|
198
|
-
PromptLabelNotRegisteredError,
|
|
199
|
-
} from "@to11ai/sdk";
|
|
112
|
+
const to11 = createClient({ apiKey, projectId: "proj_abc123" });
|
|
200
113
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
const retryAfter = err.retryAfterSeconds ?? 60;
|
|
206
|
-
console.warn(`Rate limited — retry in ${retryAfter}s`);
|
|
207
|
-
} else if (err instanceof To11aiAuthError) {
|
|
208
|
-
console.error("Authentication failed:", err.statusCode, err.message);
|
|
209
|
-
} else if (err instanceof To11aiValidationError) {
|
|
210
|
-
console.error("Bad request:", err.message, err.details);
|
|
211
|
-
} else if (err instanceof To11aiNetworkError) {
|
|
212
|
-
console.error("Network failure:", err.message, err.cause);
|
|
213
|
-
} else if (err instanceof To11aiApiError) {
|
|
214
|
-
console.error(`API error ${err.statusCode} [${err.errorCode}]:`, err.message);
|
|
215
|
-
} else {
|
|
216
|
-
throw err;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
114
|
+
await to11.prompts.list(); // uses the bound projectId
|
|
115
|
+
await to11.prompts.get({ promptId: "prompt_1" });
|
|
116
|
+
await to11.prompts.getVersion({ promptId: "prompt_1", versionNumber: 3 });
|
|
117
|
+
await to11.prompts.moveLabel({ promptId: "prompt_1", label: "production", versionId: "ver_9", reason: "promote" });
|
|
219
118
|
```
|
|
220
119
|
|
|
221
|
-
|
|
120
|
+
Full set: `create`, `list`, `get`, `update`, `archive`, `createVersion`, `listVersions`, `getVersion`, `moveLabel`, `listLabels`, and the project-label registry (`listProjectLabels`, `createProjectLabel`, `getProjectLabel`, `updateProjectLabel`, `deleteProjectLabel`, `listProjectLabelUsages`, `listLabelEvents`). `client.projectEnvironments` and `client.routingRules` expose the environment and routing-rule surfaces.
|
|
222
121
|
|
|
223
|
-
|
|
122
|
+
## Error handling
|
|
123
|
+
|
|
124
|
+
`To11aiError` is the base; catch it broadly or match a subclass:
|
|
224
125
|
|
|
225
126
|
```typescript
|
|
226
|
-
import {
|
|
127
|
+
import { To11aiRateLimitError, PromptNotFoundError } from "@to11ai/sdk";
|
|
227
128
|
|
|
228
129
|
try {
|
|
229
|
-
await
|
|
230
|
-
projectId: "proj_abc123",
|
|
231
|
-
promptId: "prompt_xyz789",
|
|
232
|
-
label: "canary",
|
|
233
|
-
versionId: "ver_42",
|
|
234
|
-
reason: "promote to canary",
|
|
235
|
-
});
|
|
130
|
+
const prompt = await to11.prompts.render("welcome-message");
|
|
236
131
|
} catch (err) {
|
|
237
|
-
if (
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
);
|
|
241
|
-
// Offer to create it: client.prompts.createProjectLabel({ … })
|
|
242
|
-
} else {
|
|
243
|
-
throw err;
|
|
244
|
-
}
|
|
132
|
+
if (err instanceof To11aiRateLimitError) { /* err.retryAfterSeconds */ }
|
|
133
|
+
else if (err instanceof PromptNotFoundError) { /* … */ }
|
|
134
|
+
else throw err;
|
|
245
135
|
}
|
|
246
136
|
```
|
|
247
137
|
|
|
248
|
-
| Class | When
|
|
249
|
-
|
|
250
|
-
| `
|
|
251
|
-
| `
|
|
252
|
-
| `
|
|
253
|
-
| `
|
|
254
|
-
| `
|
|
255
|
-
| `
|
|
256
|
-
| `
|
|
257
|
-
|
|
258
|
-
## Caching
|
|
259
|
-
|
|
260
|
-
`prompts.resolve()` uses an in-memory LRU cache by default. Configure it at client construction time:
|
|
261
|
-
|
|
262
|
-
```typescript
|
|
263
|
-
const client = createClient({
|
|
264
|
-
baseUrl: "https://api.to11ai.com",
|
|
265
|
-
apiKey: process.env.TO11AI_API_KEY!,
|
|
266
|
-
cache: {
|
|
267
|
-
ttlSeconds: 600, // default: 300 (5 minutes)
|
|
268
|
-
maxEntries: 500, // default: 100
|
|
269
|
-
},
|
|
270
|
-
});
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
**Per-call bypass:** pass `cache: false` to skip the cache for a single call:
|
|
138
|
+
| Class | When |
|
|
139
|
+
| --- | --- |
|
|
140
|
+
| `To11aiApiError` | non-2xx API response (`statusCode`, `errorCode`, `details`) |
|
|
141
|
+
| `To11aiAuthError` | 401/403 |
|
|
142
|
+
| `To11aiRateLimitError` | 429 (`retryAfterSeconds`) |
|
|
143
|
+
| `To11aiValidationError` | 400 |
|
|
144
|
+
| `To11aiNetworkError` | network failure / timeout |
|
|
145
|
+
| `PromptNotFoundError` · `LabelNotFoundError` · `MissingLabelError` · `NoActiveReleaseError` · `PromptPolicyViolationError` · `PromptLabelNotRegisteredError` | typed prompt-resolution errors |
|
|
146
|
+
| `UnknownRoleError` | an unrecognized message role with `onUnknownRole: "error"` |
|
|
274
147
|
|
|
275
|
-
|
|
276
|
-
const fresh = await client.prompts.resolve({
|
|
277
|
-
projectId: "proj_abc123",
|
|
278
|
-
slug: "chat-system-prompt",
|
|
279
|
-
labels: ["production"],
|
|
280
|
-
cache: false, // bypass cache, always fetch from API
|
|
281
|
-
});
|
|
282
|
-
```
|
|
148
|
+
## TypeScript types
|
|
283
149
|
|
|
284
|
-
|
|
150
|
+
All inputs/outputs are typed; declarations ship as `dist/*.d.ts` (no separate `@types`). Import types from the entrypoint or the `@to11ai/sdk/prompts` subpath:
|
|
285
151
|
|
|
286
152
|
```typescript
|
|
287
|
-
|
|
288
|
-
projectId: "proj_abc123",
|
|
289
|
-
slug: "chat-system-prompt",
|
|
290
|
-
labels: ["production"],
|
|
291
|
-
fallback: {
|
|
292
|
-
promptId: "...",
|
|
293
|
-
versionId: "...",
|
|
294
|
-
version: 1,
|
|
295
|
-
rendered: { format: "text", text: "You are a helpful assistant." },
|
|
296
|
-
},
|
|
297
|
-
});
|
|
153
|
+
import type { ClientOptions, RenderOptions, RenderedPrompt } from "@to11ai/sdk";
|
|
298
154
|
```
|
|
299
155
|
|
|
300
|
-
##
|
|
156
|
+
## Runtime support
|
|
301
157
|
|
|
302
|
-
|
|
158
|
+
| Runtime / loader | Resolves to | Notes |
|
|
159
|
+
| --- | --- | --- |
|
|
160
|
+
| Node.js (ESM `import`) | `dist/*.js` | Bundled ESM |
|
|
161
|
+
| Node.js (CJS `require`) | `dist/*.cjs` | Bundled CommonJS |
|
|
162
|
+
| TypeScript | `dist/*.d.ts` | Declarations |
|
|
163
|
+
| Bun / Deno | `src/*.ts` | Raw source — zero build overhead |
|
|
303
164
|
|
|
304
|
-
|
|
305
|
-
import type {
|
|
306
|
-
ClientOptions,
|
|
307
|
-
CacheConfig,
|
|
308
|
-
To11aiClient,
|
|
309
|
-
} from "@to11ai/sdk";
|
|
310
|
-
|
|
311
|
-
import type {
|
|
312
|
-
ResolvePromptInput,
|
|
313
|
-
ResolvePromptResult,
|
|
314
|
-
ResolvedPrompt,
|
|
315
|
-
Prompt,
|
|
316
|
-
PromptVersion,
|
|
317
|
-
// Project label registry
|
|
318
|
-
ProjectPromptLabel,
|
|
319
|
-
ProjectPromptLabelUsage,
|
|
320
|
-
PromptLabelEvent,
|
|
321
|
-
PaletteToken,
|
|
322
|
-
ListLabelEventsInput,
|
|
323
|
-
} from "@to11ai/sdk/prompts";
|
|
324
|
-
```
|
|
165
|
+
## Documentation
|
|
325
166
|
|
|
326
|
-
|
|
167
|
+
Full reference: [TypeScript SDK docs](https://docs.to11.ai/reference/typescript-sdk) · [Rendering prompts](https://docs.to11.ai/platform/prompts/rendering). Licensed under MPL-2.0.
|
package/dist/client.cjs
CHANGED
|
@@ -39,55 +39,66 @@ var __export = (target, all) => {
|
|
|
39
39
|
// src/client.ts
|
|
40
40
|
var exports_client = {};
|
|
41
41
|
__export(exports_client, {
|
|
42
|
-
gatewayPromptHeaders: () =>
|
|
43
|
-
gatewayAuthHeaders: () =>
|
|
44
|
-
envVarNameForKey: () => import_store2.envVarNameForKey,
|
|
42
|
+
gatewayPromptHeaders: () => import_gateway2.gatewayPromptHeaders,
|
|
43
|
+
gatewayAuthHeaders: () => import_gateway2.gatewayAuthHeaders,
|
|
45
44
|
createClient: () => createClient,
|
|
45
|
+
UnknownRoleError: () => import_errors.UnknownRoleError,
|
|
46
|
+
Turn: () => import_context2.Turn,
|
|
46
47
|
To11aiValidationError: () => import_errors.To11aiValidationError,
|
|
47
48
|
To11aiRateLimitError: () => import_errors.To11aiRateLimitError,
|
|
48
49
|
To11aiNetworkError: () => import_errors.To11aiNetworkError,
|
|
49
50
|
To11aiError: () => import_errors.To11aiError,
|
|
50
51
|
To11aiAuthError: () => import_errors.To11aiAuthError,
|
|
51
52
|
To11aiApiError: () => import_errors.To11aiApiError,
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
RoutingRulesResource: () => import_resource6.RoutingRulesResource,
|
|
55
|
-
RoutingRuleVersionResource: () => import_resource6.RoutingRuleVersionResource,
|
|
56
|
-
RoutingRuleReleaseResource: () => import_resource6.RoutingRuleReleaseResource,
|
|
57
|
-
PromptResource: () => import_resource5.PromptResource,
|
|
53
|
+
Session: () => import_context2.Session,
|
|
54
|
+
PromptResource: () => import_resource4.PromptResource,
|
|
58
55
|
PromptPolicyViolationError: () => import_errors.PromptPolicyViolationError,
|
|
59
56
|
PromptNotFoundError: () => import_errors.PromptNotFoundError,
|
|
60
57
|
PromptLabelNotRegisteredError: () => import_errors.PromptLabelNotRegisteredError,
|
|
61
|
-
ProjectEnvironmentResource: () =>
|
|
62
|
-
NoApplicableRouteError: () => import_errors.NoApplicableRouteError,
|
|
58
|
+
ProjectEnvironmentResource: () => import_resource3.ProjectEnvironmentResource,
|
|
63
59
|
NoActiveReleaseError: () => import_errors.NoActiveReleaseError,
|
|
64
|
-
|
|
65
|
-
|
|
60
|
+
MissingLabelError: () => import_errors.MissingLabelError,
|
|
61
|
+
LabelNotFoundError: () => import_errors.LabelNotFoundError,
|
|
66
62
|
ENV_SLUG_REGEX: () => import_types2.ENV_SLUG_REGEX,
|
|
67
|
-
|
|
68
|
-
AmbiguousEnvLabelsError: () => import_errors.AmbiguousEnvLabelsError
|
|
63
|
+
Conversation: () => import_context2.Conversation
|
|
69
64
|
});
|
|
70
65
|
module.exports = __toCommonJS(exports_client);
|
|
71
66
|
var import_store = require("./behaviors/store");
|
|
67
|
+
var import_config = require("./config");
|
|
68
|
+
var import_context = require("./context");
|
|
69
|
+
var import_gateway = require("./gateway");
|
|
72
70
|
var import_resource = require("./projectEnvironments/resource");
|
|
73
71
|
var import_resource2 = require("./prompts/resource");
|
|
74
72
|
var import_types = require("./prompts/types");
|
|
75
|
-
var import_resource3 = require("./routingRules/resource");
|
|
76
73
|
var import_transport = require("./transport");
|
|
77
|
-
var
|
|
74
|
+
var import_context2 = require("./context");
|
|
78
75
|
var import_errors = require("./errors");
|
|
79
|
-
var
|
|
80
|
-
var
|
|
81
|
-
var
|
|
76
|
+
var import_gateway2 = require("./gateway");
|
|
77
|
+
var import_resource3 = require("./projectEnvironments/resource");
|
|
78
|
+
var import_resource4 = require("./prompts/resource");
|
|
82
79
|
var import_types2 = require("./prompts/types");
|
|
83
|
-
|
|
84
|
-
function createClient(options) {
|
|
80
|
+
function createClient(options = {}) {
|
|
85
81
|
const isDomBrowser = typeof globalThis === "object" && typeof globalThis.document !== "undefined";
|
|
86
82
|
const workerLikeGlobal = globalThis;
|
|
87
83
|
const isBunMainThread = workerLikeGlobal.Bun?.isMainThread === true;
|
|
88
84
|
const isWorkerBrowser = typeof globalThis === "object" && (typeof workerLikeGlobal.importScripts === "function" || !isBunMainThread && typeof workerLikeGlobal.postMessage === "function" && typeof workerLikeGlobal.onmessage !== "undefined");
|
|
89
|
-
|
|
90
|
-
|
|
85
|
+
const isBrowser = isDomBrowser || isWorkerBrowser;
|
|
86
|
+
const processEnv = !isBrowser && typeof process !== "undefined" && typeof process.env === "object" ? process.env : undefined;
|
|
87
|
+
const pick = (opt, envKey) => {
|
|
88
|
+
const fromOpt = opt?.trim();
|
|
89
|
+
if (fromOpt)
|
|
90
|
+
return fromOpt;
|
|
91
|
+
const fromEnv = processEnv?.[envKey]?.trim();
|
|
92
|
+
return fromEnv ? fromEnv : undefined;
|
|
93
|
+
};
|
|
94
|
+
const baseUrl = pick(options.baseUrl, "TO11_API_URL") ?? import_config.DEFAULT_API_URL;
|
|
95
|
+
const gatewayUrl = (pick(options.gatewayUrl, "TO11_GATEWAY_URL") ?? import_config.DEFAULT_GATEWAY_URL).replace(/\/+$/, "").replace(/\/v1$/, "");
|
|
96
|
+
const apiKey = pick(options.apiKey, "TO11_API_KEY");
|
|
97
|
+
const projectId = pick(options.projectId, "TO11_PROJECT_ID");
|
|
98
|
+
const env = pick(options.env, "TO11_ENV");
|
|
99
|
+
const providerApiKey = options.providerApiKey?.trim() || undefined;
|
|
100
|
+
if (isBrowser && options.apiKey !== undefined) {
|
|
101
|
+
throw new Error("[to11ai/sdk] Do not use `apiKey` in a browser — a to11 API key carries gateway access and must stay server-side (server, CLI, or backend job).");
|
|
91
102
|
}
|
|
92
103
|
if (options.apiKey !== undefined && options.apiKey.trim() === "") {
|
|
93
104
|
throw new Error("[to11ai/sdk] `apiKey` must not be an empty string.");
|
|
@@ -95,39 +106,74 @@ function createClient(options) {
|
|
|
95
106
|
if (options.projectId !== undefined && options.projectId.trim() === "") {
|
|
96
107
|
throw new Error("[to11ai/sdk] `projectId` must not be an empty string — omit it or pass a valid project id.");
|
|
97
108
|
}
|
|
98
|
-
if (options.env !== undefined &&
|
|
99
|
-
throw new Error(
|
|
109
|
+
if (options.env !== undefined && options.env.trim() === "") {
|
|
110
|
+
throw new Error("[to11ai/sdk] `env` must not be an empty string — omit it or pass a valid env slug.");
|
|
100
111
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const getAccessToken = options.getAccessToken;
|
|
104
|
-
if (hasApiKey === hasGetAccessToken) {
|
|
105
|
-
throw new Error("[to11ai/sdk] Provide exactly one of `apiKey` (server) or `getAccessToken` (browser).");
|
|
112
|
+
if (env !== undefined && !import_types.ENV_SLUG_REGEX.test(env)) {
|
|
113
|
+
throw new Error(`[to11ai/sdk] \`env\` must match ${import_types.ENV_SLUG_REGEX} (lowercase-kebab, 1-63 chars). Received: ${JSON.stringify(env)}`);
|
|
106
114
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
env: processEnv
|
|
113
|
-
});
|
|
115
|
+
if (apiKey === undefined) {
|
|
116
|
+
throw new Error("[to11ai/sdk] An `apiKey` (or `TO11_API_KEY`) is required.");
|
|
117
|
+
}
|
|
118
|
+
const auth = { apiKey };
|
|
119
|
+
const behaviorStore = new import_store.BehaviorStore({ env: processEnv });
|
|
114
120
|
const transport = new import_transport.Transport({
|
|
115
|
-
baseUrl
|
|
121
|
+
baseUrl,
|
|
116
122
|
auth,
|
|
117
123
|
timeoutMs: options.timeoutMs,
|
|
118
124
|
maxRetries: options.maxRetries,
|
|
119
125
|
behaviorStore
|
|
120
126
|
});
|
|
121
|
-
const prompts = new import_resource2.PromptResource(transport,
|
|
122
|
-
projectId
|
|
123
|
-
env
|
|
127
|
+
const prompts = new import_resource2.PromptResource(transport, {
|
|
128
|
+
projectId,
|
|
129
|
+
env,
|
|
130
|
+
format: options.format,
|
|
131
|
+
onUnknownRole: options.onUnknownRole
|
|
124
132
|
});
|
|
125
133
|
const projectEnvironments = new import_resource.ProjectEnvironmentResource(transport);
|
|
126
|
-
const
|
|
134
|
+
const gatewayAuthContext = () => {
|
|
135
|
+
if (projectId === undefined) {
|
|
136
|
+
throw new Error("[to11ai/sdk] session()/turn() need a `projectId` (or `TO11_PROJECT_ID`).");
|
|
137
|
+
}
|
|
138
|
+
return env !== undefined ? { apiKey, projectId, env } : { apiKey, projectId };
|
|
139
|
+
};
|
|
140
|
+
let defaultSession;
|
|
141
|
+
const clientDefaultSession = () => {
|
|
142
|
+
if (defaultSession === undefined) {
|
|
143
|
+
defaultSession = new import_context.Session(gatewayAuthContext());
|
|
144
|
+
}
|
|
145
|
+
return defaultSession;
|
|
146
|
+
};
|
|
147
|
+
const gatewayClientOptions = (defaultBaseURL, overrides) => {
|
|
148
|
+
if (projectId === undefined) {
|
|
149
|
+
throw new Error("[to11ai/sdk] openaiOptions()/anthropicOptions() need a `projectId` (or `TO11_PROJECT_ID`) — it authenticates the gateway call via `x-to11-project-id`.");
|
|
150
|
+
}
|
|
151
|
+
const authHeaders = import_gateway.gatewayAuthHeaders(env !== undefined ? { apiKey, projectId, env } : { apiKey, projectId });
|
|
152
|
+
const {
|
|
153
|
+
apiKey: overrideApiKey,
|
|
154
|
+
baseURL: overrideBaseURL,
|
|
155
|
+
defaultHeaders: overrideHeaders,
|
|
156
|
+
...passthrough
|
|
157
|
+
} = overrides ?? {};
|
|
158
|
+
return {
|
|
159
|
+
...passthrough,
|
|
160
|
+
baseURL: overrideBaseURL ?? defaultBaseURL,
|
|
161
|
+
apiKey: overrideApiKey ?? providerApiKey ?? apiKey,
|
|
162
|
+
defaultHeaders: { ...authHeaders, ...overrideHeaders }
|
|
163
|
+
};
|
|
164
|
+
};
|
|
127
165
|
return {
|
|
128
166
|
prompts,
|
|
129
167
|
projectEnvironments,
|
|
130
|
-
|
|
131
|
-
|
|
168
|
+
apiKey,
|
|
169
|
+
baseUrl,
|
|
170
|
+
gatewayUrl,
|
|
171
|
+
projectId,
|
|
172
|
+
env,
|
|
173
|
+
session: (id) => new import_context.Session(gatewayAuthContext(), id),
|
|
174
|
+
conversation: (id) => clientDefaultSession().conversation(id),
|
|
175
|
+
turn: () => clientDefaultSession().turn(),
|
|
176
|
+
openaiOptions: (overrides) => gatewayClientOptions(`${gatewayUrl}/v1`, overrides),
|
|
177
|
+
anthropicOptions: (overrides) => gatewayClientOptions(gatewayUrl, overrides)
|
|
132
178
|
};
|
|
133
179
|
}
|