@to11ai/sdk 2.0.0-rc.1 → 2.0.0-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.cjs +5 -1
- package/dist/client.d.ts +10 -3
- package/dist/client.js +5 -1
- package/dist/context.d.ts +1 -1
- package/dist/gateway.cjs +3 -0
- package/dist/gateway.d.ts +8 -0
- package/dist/gateway.js +3 -0
- package/dist/prompts/cache.d.ts +8 -9
- package/dist/prompts/resource.cjs +57 -78
- package/dist/prompts/resource.d.ts +14 -18
- package/dist/prompts/resource.js +58 -79
- package/dist/prompts/shape.d.ts +8 -6
- package/dist/prompts/types.d.ts +34 -39
- package/package.json +1 -1
- package/src/client.ts +21 -5
- package/src/context.ts +1 -1
- package/src/gateway.ts +13 -0
- package/src/generated/zod.gen.ts +3 -3
- package/src/prompts/cache.ts +10 -11
- package/src/prompts/resource.ts +111 -137
- package/src/prompts/shape.ts +11 -8
- package/src/prompts/types.ts +33 -43
package/dist/client.cjs
CHANGED
|
@@ -108,7 +108,7 @@ function createClient(options = {}) {
|
|
|
108
108
|
const getAccessToken = options.getAccessToken;
|
|
109
109
|
const apiKey = getAccessToken !== undefined ? options.apiKey : pick(options.apiKey, "TO11_API_KEY");
|
|
110
110
|
const projectId = pick(options.projectId, "TO11_PROJECT_ID");
|
|
111
|
-
const env = options.env;
|
|
111
|
+
const env = pick(options.env, "TO11_ENV");
|
|
112
112
|
const providerApiKey = options.providerApiKey?.trim() || undefined;
|
|
113
113
|
if (isBrowser && options.apiKey !== undefined) {
|
|
114
114
|
throw new Error("[to11ai/sdk] Do not use `apiKey` in browser contexts — use `getAccessToken` instead.");
|
|
@@ -119,6 +119,9 @@ function createClient(options = {}) {
|
|
|
119
119
|
if (options.projectId !== undefined && options.projectId.trim() === "") {
|
|
120
120
|
throw new Error("[to11ai/sdk] `projectId` must not be an empty string — omit it or pass a valid project id.");
|
|
121
121
|
}
|
|
122
|
+
if (options.env !== undefined && options.env.trim() === "") {
|
|
123
|
+
throw new Error("[to11ai/sdk] `env` must not be an empty string — omit it or pass a valid env slug.");
|
|
124
|
+
}
|
|
122
125
|
if (env !== undefined && !import_types.ENV_SLUG_REGEX.test(env)) {
|
|
123
126
|
throw new Error(`[to11ai/sdk] \`env\` must match ${import_types.ENV_SLUG_REGEX} (lowercase-kebab, 1-63 chars). Received: ${JSON.stringify(env)}`);
|
|
124
127
|
}
|
|
@@ -191,6 +194,7 @@ function createClient(options = {}) {
|
|
|
191
194
|
resolveBehavior: (key, codedDefault) => behaviorStore.resolve(key, codedDefault),
|
|
192
195
|
apiKey,
|
|
193
196
|
gatewayUrl,
|
|
197
|
+
projectId,
|
|
194
198
|
session: (id) => new import_context.Session(gatewayAuthContext(), id),
|
|
195
199
|
conversation: (id) => clientDefaultSession().conversation(id),
|
|
196
200
|
turn: () => clientDefaultSession().turn(),
|
package/dist/client.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export type { CacheConfig } from "./prompts/cache";
|
|
|
17
17
|
export type { PromptResourceConfig } from "./prompts/resource";
|
|
18
18
|
export { PromptResource } from "./prompts/resource";
|
|
19
19
|
export type { AnthropicRenderedPrompt, OpenAiRenderedPrompt, PromptConfig, PromptMetadata, RenderResult, } from "./prompts/shape";
|
|
20
|
-
export type { BlockRenderRecord,
|
|
20
|
+
export type { BlockRenderRecord, RenderedChatMessage, RenderedPrompt, RenderFormat, RenderOptions, ResolvedPrompt, ResolvedPromptEnvelope, UnknownRoleMode, } from "./prompts/types";
|
|
21
21
|
export { ENV_SLUG_REGEX } from "./prompts/types";
|
|
22
22
|
export type { CreateRuleVersionInput, CreateRuleVersionResult, GetRuleVersionInput, GetRuleVersionResult, ListRuleReleasesInput, ListRuleReleasesResult, ListRuleVersionsInput, ListRuleVersionsResult, RollbackRuleReleaseInput, RollbackRuleReleaseResult, RuleModelBinding, RuleProviderRef, RuleRelease, RuleReleaseActorType, RuleReleaseApprovalStatus, RuleReleaseChangeKind, RuleReleaseStrategy, RuleReleaseWeight, RuleSnapshot, RuleStrategy, RuleVersion, SetRuleReleaseInput, SetRuleReleaseResult, } from "./routingRules/resource";
|
|
23
23
|
export { RoutingRuleReleaseResource, RoutingRulesResource, RoutingRuleVersionResource, } from "./routingRules/resource";
|
|
@@ -57,8 +57,9 @@ export interface ClientOptions {
|
|
|
57
57
|
projectId?: string;
|
|
58
58
|
/**
|
|
59
59
|
* Default serving environment for `prompts.render(slug)`, inherited by every
|
|
60
|
-
* render unless overridden per call.
|
|
61
|
-
* project-environments slug rule
|
|
60
|
+
* render unless overridden per call. Precedence: this option → `TO11_ENV`
|
|
61
|
+
* env. Validated eagerly against the project-environments slug rule
|
|
62
|
+
* (`^[a-z0-9-]{1,63}$`).
|
|
62
63
|
*/
|
|
63
64
|
env?: string;
|
|
64
65
|
/**
|
|
@@ -126,6 +127,12 @@ export interface To11aiClient<F extends RenderFormat | undefined = undefined> {
|
|
|
126
127
|
readonly apiKey: string | undefined;
|
|
127
128
|
/** Resolved data-plane gateway URL (option → `TO11_GATEWAY_URL` → default). */
|
|
128
129
|
readonly gatewayUrl: string;
|
|
130
|
+
/**
|
|
131
|
+
* Resolved project id (option → `TO11_PROJECT_ID`); `undefined` when none is
|
|
132
|
+
* configured. Read-only, for your own logging / manual headers — `prompts.*`
|
|
133
|
+
* already default to it, so you don't need to pass it back into calls.
|
|
134
|
+
*/
|
|
135
|
+
readonly projectId: string | undefined;
|
|
129
136
|
/** A new session (unit of work). Pass an id to group telemetry by your own id. */
|
|
130
137
|
session(id?: string): Session;
|
|
131
138
|
/**
|
package/dist/client.js
CHANGED
|
@@ -64,7 +64,7 @@ function createClient(options = {}) {
|
|
|
64
64
|
const getAccessToken = options.getAccessToken;
|
|
65
65
|
const apiKey = getAccessToken !== undefined ? options.apiKey : pick(options.apiKey, "TO11_API_KEY");
|
|
66
66
|
const projectId = pick(options.projectId, "TO11_PROJECT_ID");
|
|
67
|
-
const env = options.env;
|
|
67
|
+
const env = pick(options.env, "TO11_ENV");
|
|
68
68
|
const providerApiKey = options.providerApiKey?.trim() || undefined;
|
|
69
69
|
if (isBrowser && options.apiKey !== undefined) {
|
|
70
70
|
throw new Error("[to11ai/sdk] Do not use `apiKey` in browser contexts — use `getAccessToken` instead.");
|
|
@@ -75,6 +75,9 @@ function createClient(options = {}) {
|
|
|
75
75
|
if (options.projectId !== undefined && options.projectId.trim() === "") {
|
|
76
76
|
throw new Error("[to11ai/sdk] `projectId` must not be an empty string — omit it or pass a valid project id.");
|
|
77
77
|
}
|
|
78
|
+
if (options.env !== undefined && options.env.trim() === "") {
|
|
79
|
+
throw new Error("[to11ai/sdk] `env` must not be an empty string — omit it or pass a valid env slug.");
|
|
80
|
+
}
|
|
78
81
|
if (env !== undefined && !ENV_SLUG_REGEX.test(env)) {
|
|
79
82
|
throw new Error(`[to11ai/sdk] \`env\` must match ${ENV_SLUG_REGEX} (lowercase-kebab, 1-63 chars). Received: ${JSON.stringify(env)}`);
|
|
80
83
|
}
|
|
@@ -147,6 +150,7 @@ function createClient(options = {}) {
|
|
|
147
150
|
resolveBehavior: (key, codedDefault) => behaviorStore.resolve(key, codedDefault),
|
|
148
151
|
apiKey,
|
|
149
152
|
gatewayUrl,
|
|
153
|
+
projectId,
|
|
150
154
|
session: (id) => new Session(gatewayAuthContext(), id),
|
|
151
155
|
conversation: (id) => clientDefaultSession().conversation(id),
|
|
152
156
|
turn: () => clientDefaultSession().turn(),
|
package/dist/context.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export interface TurnAuthContext {
|
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
19
19
|
* A prompt argument accepted by `turn.headers()`. Either the flat provenance
|
|
20
|
-
* (a neutral `
|
|
20
|
+
* (a neutral `RenderedPrompt`) or a `format`-shaped result carrying it under
|
|
21
21
|
* `metadata` — both are accepted so the format and neutral render paths carry
|
|
22
22
|
* provenance identically.
|
|
23
23
|
*/
|
package/dist/gateway.cjs
CHANGED
|
@@ -88,6 +88,9 @@ function gatewayPromptHeaders(prompt) {
|
|
|
88
88
|
if (prompt.label.length > 0) {
|
|
89
89
|
headers["x-to11-prompt-label"] = prompt.label;
|
|
90
90
|
}
|
|
91
|
+
if (typeof prompt.slug === "string" && prompt.slug.length > 0) {
|
|
92
|
+
headers["x-to11-prompt-slug"] = prompt.slug;
|
|
93
|
+
}
|
|
91
94
|
return headers;
|
|
92
95
|
}
|
|
93
96
|
function toOpenAITools(tools) {
|
package/dist/gateway.d.ts
CHANGED
|
@@ -42,6 +42,9 @@ export declare function gatewayAuthHeaders(options: GatewayAuthOptions): Record<
|
|
|
42
42
|
* release was weighted); omitted for `single`-strategy releases.
|
|
43
43
|
* - `x-to11-prompt-label` — the single label the prompt resolved through (the
|
|
44
44
|
* env slug today); omitted when empty (the gateway rejects empty values).
|
|
45
|
+
* - `x-to11-prompt-slug` — the prompt's human-readable slug, so traces show a
|
|
46
|
+
* readable name alongside the opaque `x-to11-prompt-id`; omitted when empty
|
|
47
|
+
* or absent (a legacy `resolve()` result carries no slug).
|
|
45
48
|
*
|
|
46
49
|
* The parameter type is WIDENED to accept either the enriched `render()`
|
|
47
50
|
* result or the legacy `ResolvedPrompt`. The new fields are read when present
|
|
@@ -57,6 +60,11 @@ export interface GatewayPromptProvenance {
|
|
|
57
60
|
version: number;
|
|
58
61
|
/** The single label the prompt resolved through (env slug today). */
|
|
59
62
|
label: string;
|
|
63
|
+
/**
|
|
64
|
+
* The prompt's human-readable slug (the `render()`/`resolve()` input). Present
|
|
65
|
+
* on an enriched `render()` result; a legacy `ResolvedPrompt` omits it.
|
|
66
|
+
*/
|
|
67
|
+
slug?: string;
|
|
60
68
|
/** Present on an enriched result; a legacy `resolve()` result omits it. */
|
|
61
69
|
releaseId?: string | null;
|
|
62
70
|
/** Present IFF the resolved release was weighted. */
|
package/dist/gateway.js
CHANGED
|
@@ -39,6 +39,9 @@ function gatewayPromptHeaders(prompt) {
|
|
|
39
39
|
if (prompt.label.length > 0) {
|
|
40
40
|
headers["x-to11-prompt-label"] = prompt.label;
|
|
41
41
|
}
|
|
42
|
+
if (typeof prompt.slug === "string" && prompt.slug.length > 0) {
|
|
43
|
+
headers["x-to11-prompt-slug"] = prompt.slug;
|
|
44
|
+
}
|
|
42
45
|
return headers;
|
|
43
46
|
}
|
|
44
47
|
function toOpenAITools(tools) {
|
package/dist/prompts/cache.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RenderedPrompt } from "./types";
|
|
2
2
|
export interface CacheConfig {
|
|
3
3
|
/** Time-to-live in seconds. Default: 300 (5 minutes) */
|
|
4
4
|
ttlSeconds?: number;
|
|
@@ -6,12 +6,11 @@ export interface CacheConfig {
|
|
|
6
6
|
maxEntries?: number;
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
|
-
* The cache stores
|
|
10
|
-
* `render()` result. Both are JSON-cloneable; the cache is shape-agnostic.
|
|
9
|
+
* The cache stores enriched `render()` results, which are JSON-cloneable.
|
|
11
10
|
*/
|
|
12
|
-
export type
|
|
11
|
+
export type CacheableRendered = RenderedPrompt;
|
|
13
12
|
/**
|
|
14
|
-
* Build a canonical cache key
|
|
13
|
+
* Build a canonical base cache key from project/slug/labels/variables.
|
|
15
14
|
*
|
|
16
15
|
* - projectId is included to prevent cross-project cache collisions: a single
|
|
17
16
|
* PromptResource can serve multiple projects, so the same slug+labels must
|
|
@@ -38,9 +37,9 @@ export declare function buildCacheKey(projectId: string, slug: string, labels: s
|
|
|
38
37
|
* caches as the same deterministic variant on repeat (D8); the
|
|
39
38
|
* weighted-no-subject bypass is handled in the resource, not here.
|
|
40
39
|
*/
|
|
41
|
-
export declare function
|
|
40
|
+
export declare function buildRenderCacheKey(projectId: string, slug: string, env: string, subject?: string, variables?: Record<string, unknown>): string;
|
|
42
41
|
/**
|
|
43
|
-
* In-memory LRU cache for
|
|
42
|
+
* In-memory LRU cache for RenderedPrompt objects.
|
|
44
43
|
*
|
|
45
44
|
* Uses a Map (insertion-ordered) as the backing store. On every access, the
|
|
46
45
|
* entry is deleted and re-inserted to maintain LRU order — oldest entries sit
|
|
@@ -51,8 +50,8 @@ export declare class PromptCache {
|
|
|
51
50
|
private readonly maxEntries;
|
|
52
51
|
private readonly store;
|
|
53
52
|
constructor(config?: CacheConfig);
|
|
54
|
-
get(key: string):
|
|
55
|
-
set(key: string, value:
|
|
53
|
+
get(key: string): CacheableRendered | undefined;
|
|
54
|
+
set(key: string, value: CacheableRendered): void;
|
|
56
55
|
delete(key: string): void;
|
|
57
56
|
clear(): void;
|
|
58
57
|
get size(): number;
|
|
@@ -48,17 +48,6 @@ var import_zod2 = require("../generated/zod.gen");
|
|
|
48
48
|
var import_cache = require("./cache");
|
|
49
49
|
var import_shape = require("./shape");
|
|
50
50
|
var import_types = require("./types");
|
|
51
|
-
var zResolvedPromptLegacy = import_zod2.zResolvedPrompt.pick({
|
|
52
|
-
promptId: true,
|
|
53
|
-
versionId: true,
|
|
54
|
-
version: true,
|
|
55
|
-
label: true,
|
|
56
|
-
contentHash: true,
|
|
57
|
-
rendered: true,
|
|
58
|
-
tools: true,
|
|
59
|
-
toolChoice: true,
|
|
60
|
-
modelConfig: true
|
|
61
|
-
});
|
|
62
51
|
var zResolvedPromptEnvelope = import_zod2.zResolvedPrompt.partial({ releaseId: true }).extend({ strategy: import_zod.z.enum(["single", "weighted"]).optional() });
|
|
63
52
|
function unwrap(envelope) {
|
|
64
53
|
if (envelope.data === null || envelope.data === undefined) {
|
|
@@ -70,12 +59,12 @@ function getProjectPromptsPath(projectId) {
|
|
|
70
59
|
return `/v1/projects/${encodeURIComponent(projectId)}/prompts`;
|
|
71
60
|
}
|
|
72
61
|
function renderedToMessages(rendered) {
|
|
73
|
-
if (rendered.format
|
|
74
|
-
|
|
62
|
+
if (rendered.format !== "chat") {
|
|
63
|
+
throw new Error("[to11ai/sdk] Unsupported non-chat prompt format; author the prompt as chat blocks.");
|
|
75
64
|
}
|
|
76
|
-
return
|
|
65
|
+
return rendered.messages;
|
|
77
66
|
}
|
|
78
|
-
function normalizeResolvedEnvelope(raw) {
|
|
67
|
+
function normalizeResolvedEnvelope(raw, slug) {
|
|
79
68
|
const provenance = raw;
|
|
80
69
|
const result = {
|
|
81
70
|
messages: renderedToMessages(raw.rendered),
|
|
@@ -86,7 +75,7 @@ function normalizeResolvedEnvelope(raw) {
|
|
|
86
75
|
versionId: raw.versionId,
|
|
87
76
|
contentHash: raw.contentHash,
|
|
88
77
|
label: raw.label,
|
|
89
|
-
|
|
78
|
+
slug,
|
|
90
79
|
modelConfig: provenance.modelConfig
|
|
91
80
|
};
|
|
92
81
|
if (raw.tools != null && raw.tools.length > 0) {
|
|
@@ -100,11 +89,11 @@ function normalizeResolvedEnvelope(raw) {
|
|
|
100
89
|
}
|
|
101
90
|
return result;
|
|
102
91
|
}
|
|
103
|
-
function
|
|
104
|
-
if (
|
|
105
|
-
|
|
92
|
+
function liftFallbackToRendered(fallback, slug) {
|
|
93
|
+
if (!Array.isArray(fallback.messages)) {
|
|
94
|
+
throw new Error("[to11ai/sdk] `fallback` must be a RenderedPrompt (as returned by render()); the legacy resolve() shape is no longer supported.");
|
|
106
95
|
}
|
|
107
|
-
return
|
|
96
|
+
return { ...structuredClone(fallback), slug: fallback.slug || slug };
|
|
108
97
|
}
|
|
109
98
|
function getProjectPromptPath(projectId, promptId) {
|
|
110
99
|
return `${getProjectPromptsPath(projectId)}/${encodeURIComponent(promptId)}`;
|
|
@@ -152,13 +141,22 @@ class PromptResource {
|
|
|
152
141
|
this.format = config?.format;
|
|
153
142
|
this.onUnknownRole = config?.onUnknownRole;
|
|
154
143
|
}
|
|
144
|
+
resolveProjectId(perCall) {
|
|
145
|
+
const projectId = perCall ?? this.projectId;
|
|
146
|
+
if (projectId === undefined || projectId.trim() === "") {
|
|
147
|
+
throw new Error("[to11ai/sdk] this call needs a `projectId` — pass it on the call or bind one via createClient({ projectId, ... }).");
|
|
148
|
+
}
|
|
149
|
+
return projectId.trim();
|
|
150
|
+
}
|
|
155
151
|
async create(input) {
|
|
156
|
-
const { projectId, ...body } = input;
|
|
152
|
+
const { projectId: perCallProjectId, ...body } = input;
|
|
153
|
+
const projectId = this.resolveProjectId(perCallProjectId);
|
|
157
154
|
const envelope = await this.transport.request("POST", getProjectPromptsPath(projectId), { body });
|
|
158
155
|
return unwrap(envelope);
|
|
159
156
|
}
|
|
160
|
-
async list(input) {
|
|
161
|
-
const { projectId, ...queryRest } = input;
|
|
157
|
+
async list(input = {}) {
|
|
158
|
+
const { projectId: perCallProjectId, ...queryRest } = input;
|
|
159
|
+
const projectId = this.resolveProjectId(perCallProjectId);
|
|
162
160
|
const envelope = await this.transport.request("GET", getProjectPromptsPath(projectId), {
|
|
163
161
|
query: {
|
|
164
162
|
...queryRest
|
|
@@ -175,52 +173,60 @@ class PromptResource {
|
|
|
175
173
|
return { items, pagination };
|
|
176
174
|
}
|
|
177
175
|
async get(input) {
|
|
178
|
-
const { projectId, promptId } = input;
|
|
176
|
+
const { projectId: perCallProjectId, promptId } = input;
|
|
177
|
+
const projectId = this.resolveProjectId(perCallProjectId);
|
|
179
178
|
const envelope = await this.transport.request("GET", getProjectPromptPath(projectId, promptId));
|
|
180
179
|
return unwrap(envelope);
|
|
181
180
|
}
|
|
182
181
|
async update(input) {
|
|
183
|
-
const { projectId, promptId, ...body } = input;
|
|
182
|
+
const { projectId: perCallProjectId, promptId, ...body } = input;
|
|
183
|
+
const projectId = this.resolveProjectId(perCallProjectId);
|
|
184
184
|
const envelope = await this.transport.request("PATCH", getProjectPromptPath(projectId, promptId), { body });
|
|
185
185
|
return unwrap(envelope);
|
|
186
186
|
}
|
|
187
187
|
async archive(input) {
|
|
188
|
-
const { projectId, promptId } = input;
|
|
188
|
+
const { projectId: perCallProjectId, promptId } = input;
|
|
189
|
+
const projectId = this.resolveProjectId(perCallProjectId);
|
|
189
190
|
const envelope = await this.transport.request("DELETE", getProjectPromptPath(projectId, promptId));
|
|
190
191
|
return unwrap(envelope);
|
|
191
192
|
}
|
|
192
193
|
async createVersion(input) {
|
|
193
|
-
const { projectId, promptId, ...body } = input;
|
|
194
|
+
const { projectId: perCallProjectId, promptId, ...body } = input;
|
|
195
|
+
const projectId = this.resolveProjectId(perCallProjectId);
|
|
194
196
|
const envelope = await this.transport.request("POST", `${getProjectPromptPath(projectId, promptId)}/versions`, { body });
|
|
195
197
|
return unwrap(envelope);
|
|
196
198
|
}
|
|
197
199
|
async listVersions(input) {
|
|
198
|
-
const { projectId, promptId } = input;
|
|
200
|
+
const { projectId: perCallProjectId, promptId } = input;
|
|
201
|
+
const projectId = this.resolveProjectId(perCallProjectId);
|
|
199
202
|
const envelope = await this.transport.request("GET", `${getProjectPromptPath(projectId, promptId)}/versions`);
|
|
200
203
|
return unwrap(envelope);
|
|
201
204
|
}
|
|
202
205
|
async getVersion(input) {
|
|
203
|
-
const { projectId, promptId, versionNumber } = input;
|
|
206
|
+
const { projectId: perCallProjectId, promptId, versionNumber } = input;
|
|
207
|
+
const projectId = this.resolveProjectId(perCallProjectId);
|
|
204
208
|
const envelope = await this.transport.request("GET", `${getProjectPromptPath(projectId, promptId)}/versions/${encodeURIComponent(String(versionNumber))}`);
|
|
205
209
|
return unwrap(envelope);
|
|
206
210
|
}
|
|
207
211
|
async moveLabel(input) {
|
|
208
|
-
const { projectId, promptId, label, ...body } = input;
|
|
212
|
+
const { projectId: perCallProjectId, promptId, label, ...body } = input;
|
|
213
|
+
const projectId = this.resolveProjectId(perCallProjectId);
|
|
209
214
|
const envelope = await this.transport.request("PUT", `${getProjectPromptPath(projectId, promptId)}/labels/${encodeURIComponent(label)}`, { body });
|
|
210
215
|
return unwrap(envelope);
|
|
211
216
|
}
|
|
212
217
|
async listLabels(input) {
|
|
213
|
-
const { projectId, promptId } = input;
|
|
218
|
+
const { projectId: perCallProjectId, promptId } = input;
|
|
219
|
+
const projectId = this.resolveProjectId(perCallProjectId);
|
|
214
220
|
const envelope = await this.transport.request("GET", `${getProjectPromptPath(projectId, promptId)}/labels`);
|
|
215
221
|
return unwrap(envelope);
|
|
216
222
|
}
|
|
217
223
|
async render(slug, options = {}) {
|
|
218
|
-
const
|
|
219
|
-
return import_shape.shapePrompt(
|
|
224
|
+
const rendered = await this.resolveToRendered(slug, options);
|
|
225
|
+
return import_shape.shapePrompt(rendered, options.format ?? this.format, {
|
|
220
226
|
onUnknownRole: options.onUnknownRole ?? this.onUnknownRole
|
|
221
227
|
});
|
|
222
228
|
}
|
|
223
|
-
async
|
|
229
|
+
async resolveToRendered(slug, options = {}) {
|
|
224
230
|
if (this.projectId === undefined || this.projectId.trim() === "") {
|
|
225
231
|
throw new Error("[to11ai/sdk] `prompts.render()` requires a `projectId` on the client — pass it to createClient({ projectId, ... }).");
|
|
226
232
|
}
|
|
@@ -232,10 +238,10 @@ class PromptResource {
|
|
|
232
238
|
throw new Error(`[to11ai/sdk] \`env\` must match ${import_types.ENV_SLUG_REGEX} (lowercase-kebab, 1-63 chars). Received: ${JSON.stringify(env)}`);
|
|
233
239
|
}
|
|
234
240
|
const { subject, variables, cache: useCache = true, fallback } = options;
|
|
235
|
-
const cacheKey = import_cache.
|
|
241
|
+
const cacheKey = import_cache.buildRenderCacheKey(this.projectId, slug, env, subject, variables);
|
|
236
242
|
if (useCache) {
|
|
237
243
|
const cached = this.cache.get(cacheKey);
|
|
238
|
-
if (cached
|
|
244
|
+
if (cached)
|
|
239
245
|
return structuredClone(cached);
|
|
240
246
|
}
|
|
241
247
|
const body = { slug, labels: [env] };
|
|
@@ -249,7 +255,7 @@ class PromptResource {
|
|
|
249
255
|
decode: (data) => zResolvedPromptEnvelope.parse(data)
|
|
250
256
|
});
|
|
251
257
|
const raw = unwrap(envelope);
|
|
252
|
-
const result = normalizeResolvedEnvelope(raw);
|
|
258
|
+
const result = normalizeResolvedEnvelope(raw, slug);
|
|
253
259
|
const isWeighted = raw.strategy === "weighted" || result.variantName !== undefined;
|
|
254
260
|
const cacheable = !(isWeighted && subject === undefined);
|
|
255
261
|
if (useCache && cacheable) {
|
|
@@ -258,61 +264,33 @@ class PromptResource {
|
|
|
258
264
|
return result;
|
|
259
265
|
} catch (err) {
|
|
260
266
|
if (err instanceof import_errors.To11aiNetworkError && fallback !== undefined) {
|
|
261
|
-
return
|
|
262
|
-
}
|
|
263
|
-
throw err;
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
async resolve(input) {
|
|
267
|
-
const {
|
|
268
|
-
projectId,
|
|
269
|
-
slug,
|
|
270
|
-
labels,
|
|
271
|
-
variables,
|
|
272
|
-
cache: useCache = true,
|
|
273
|
-
fallback
|
|
274
|
-
} = input;
|
|
275
|
-
const cacheKey = import_cache.buildCacheKey(projectId, slug, labels, variables);
|
|
276
|
-
if (useCache) {
|
|
277
|
-
const cached = this.cache.get(cacheKey);
|
|
278
|
-
if (cached && !("messages" in cached))
|
|
279
|
-
return structuredClone(cached);
|
|
280
|
-
}
|
|
281
|
-
try {
|
|
282
|
-
const envelope = await this.transport.request("POST", `${getProjectPromptsPath(projectId)}:resolve`, {
|
|
283
|
-
body: { slug, labels, variables },
|
|
284
|
-
decode: (data) => zResolvedPromptLegacy.parse(data)
|
|
285
|
-
});
|
|
286
|
-
const result = unwrap(envelope);
|
|
287
|
-
if (useCache) {
|
|
288
|
-
this.cache.set(cacheKey, structuredClone(result));
|
|
289
|
-
}
|
|
290
|
-
return result;
|
|
291
|
-
} catch (err) {
|
|
292
|
-
if (err instanceof import_errors.To11aiNetworkError && fallback !== undefined) {
|
|
293
|
-
return fallback;
|
|
267
|
+
return liftFallbackToRendered(fallback, slug);
|
|
294
268
|
}
|
|
295
269
|
throw err;
|
|
296
270
|
}
|
|
297
271
|
}
|
|
298
|
-
async listProjectLabels(input) {
|
|
299
|
-
const { projectId, includeArchived } = input;
|
|
272
|
+
async listProjectLabels(input = {}) {
|
|
273
|
+
const { projectId: perCallProjectId, includeArchived } = input;
|
|
274
|
+
const projectId = this.resolveProjectId(perCallProjectId);
|
|
300
275
|
const envelope = await this.transport.request("GET", getProjectPromptLabelsPath(projectId), {
|
|
301
276
|
query: includeArchived ? { includeArchived: "true" } : undefined
|
|
302
277
|
});
|
|
303
278
|
return unwrap(envelope);
|
|
304
279
|
}
|
|
305
280
|
async createProjectLabel(input) {
|
|
306
|
-
const { projectId, ...body } = input;
|
|
281
|
+
const { projectId: perCallProjectId, ...body } = input;
|
|
282
|
+
const projectId = this.resolveProjectId(perCallProjectId);
|
|
307
283
|
const envelope = await this.transport.request("POST", getProjectPromptLabelsPath(projectId), { body });
|
|
308
284
|
return unwrap(envelope);
|
|
309
285
|
}
|
|
310
286
|
async getProjectLabel(input) {
|
|
311
|
-
const
|
|
287
|
+
const projectId = this.resolveProjectId(input.projectId);
|
|
288
|
+
const envelope = await this.transport.request("GET", getProjectPromptLabelPath(projectId, input.label));
|
|
312
289
|
return unwrap(envelope);
|
|
313
290
|
}
|
|
314
291
|
async updateProjectLabel(input) {
|
|
315
|
-
const { projectId, label, ...rest } = input;
|
|
292
|
+
const { projectId: perCallProjectId, label, ...rest } = input;
|
|
293
|
+
const projectId = this.resolveProjectId(perCallProjectId);
|
|
316
294
|
const body = {};
|
|
317
295
|
if (rest.isDefault !== undefined)
|
|
318
296
|
body.isDefault = rest.isDefault;
|
|
@@ -324,15 +302,16 @@ class PromptResource {
|
|
|
324
302
|
return unwrap(envelope);
|
|
325
303
|
}
|
|
326
304
|
async deleteProjectLabel(input) {
|
|
327
|
-
const
|
|
305
|
+
const projectId = this.resolveProjectId(input.projectId);
|
|
306
|
+
const envelope = await this.transport.request("DELETE", getProjectPromptLabelPath(projectId, input.label));
|
|
328
307
|
return unwrap(envelope);
|
|
329
308
|
}
|
|
330
309
|
async listProjectLabelUsages(input) {
|
|
331
|
-
const envelope = await this.transport.request("GET", `${getProjectPromptLabelPath(input.projectId, input.label)}/usages`);
|
|
310
|
+
const envelope = await this.transport.request("GET", `${getProjectPromptLabelPath(this.resolveProjectId(input.projectId), input.label)}/usages`);
|
|
332
311
|
return unwrap(envelope);
|
|
333
312
|
}
|
|
334
313
|
async listLabelEvents(input) {
|
|
335
|
-
const projectSeg = encodeURIComponent(input.projectId);
|
|
314
|
+
const projectSeg = encodeURIComponent(this.resolveProjectId(input.projectId));
|
|
336
315
|
let path;
|
|
337
316
|
switch (input.scope) {
|
|
338
317
|
case "label":
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { Transport } from "../transport";
|
|
2
2
|
import type { CacheConfig } from "./cache";
|
|
3
3
|
import type { AnthropicRenderedPrompt, OpenAiRenderedPrompt, RenderResult } from "./shape";
|
|
4
|
-
import type { ArchivePromptInput, ArchivePromptResult, CreateProjectPromptLabelInput, CreateProjectPromptLabelResult, CreatePromptInput, CreatePromptResult, CreatePromptVersionInput, CreatePromptVersionResult, DeleteProjectPromptLabelInput, DeleteProjectPromptLabelResult, GetProjectPromptLabelInput, GetProjectPromptLabelResult, GetPromptInput, GetPromptResult, GetPromptVersionInput, GetPromptVersionResult, ListLabelEventsInput, ListLabelEventsResult, ListProjectPromptLabelsInput, ListProjectPromptLabelsResult, ListProjectPromptLabelUsagesInput, ListProjectPromptLabelUsagesResult, ListPromptLabelsInput, ListPromptLabelsResult, ListPromptsInput, ListPromptsResult, ListPromptVersionsInput, ListPromptVersionsResult, MovePromptLabelInput, MovePromptLabelResult, PaginatedResult, RenderFormat, RenderOptions,
|
|
4
|
+
import type { ArchivePromptInput, ArchivePromptResult, CreateProjectPromptLabelInput, CreateProjectPromptLabelResult, CreatePromptInput, CreatePromptResult, CreatePromptVersionInput, CreatePromptVersionResult, DeleteProjectPromptLabelInput, DeleteProjectPromptLabelResult, GetProjectPromptLabelInput, GetProjectPromptLabelResult, GetPromptInput, GetPromptResult, GetPromptVersionInput, GetPromptVersionResult, ListLabelEventsInput, ListLabelEventsResult, ListProjectPromptLabelsInput, ListProjectPromptLabelsResult, ListProjectPromptLabelUsagesInput, ListProjectPromptLabelUsagesResult, ListPromptLabelsInput, ListPromptLabelsResult, ListPromptsInput, ListPromptsResult, ListPromptVersionsInput, ListPromptVersionsResult, MovePromptLabelInput, MovePromptLabelResult, PaginatedResult, RenderFormat, RenderOptions, UnknownRoleMode, UpdateProjectPromptLabelInput, UpdateProjectPromptLabelResult, UpdatePromptInput, UpdatePromptResult } from "./types";
|
|
5
5
|
export type { CacheConfig } from "./cache";
|
|
6
|
-
export type { ArchivePromptInput, ArchivePromptResult, BlockRenderRecord, ChatMessage, CreateProjectPromptLabelInput, CreateProjectPromptLabelResult, CreatePromptInput, CreatePromptResult, CreatePromptVersionInput, CreatePromptVersionResult, DeleteProjectPromptLabelInput, DeleteProjectPromptLabelResult,
|
|
6
|
+
export type { ArchivePromptInput, ArchivePromptResult, BlockRenderRecord, ChatMessage, CreateProjectPromptLabelInput, CreateProjectPromptLabelResult, CreatePromptInput, CreatePromptResult, CreatePromptVersionInput, CreatePromptVersionResult, DeleteProjectPromptLabelInput, DeleteProjectPromptLabelResult, GetProjectPromptLabelInput, GetProjectPromptLabelResult, GetPromptInput, GetPromptResult, GetPromptVersionInput, GetPromptVersionResult, ListLabelEventsInput, ListLabelEventsResult, ListProjectPromptLabelsInput, ListProjectPromptLabelsResult, ListProjectPromptLabelUsagesInput, ListProjectPromptLabelUsagesResult, ListPromptLabelsInput, ListPromptLabelsResult, ListPromptsInput, ListPromptsResult, ListPromptVersionsInput, ListPromptVersionsResult, MovePromptLabelInput, MovePromptLabelResult, PaginatedResult, PaginationInfo, PaletteToken, ProjectPromptLabel, ProjectPromptLabelUsage, Prompt, PromptFormat, PromptLabelEvent, PromptLabelPointer, PromptStatus, PromptVersion, RenderedChatMessage, RenderedPrompt, RenderFormat, RenderOptions, ResolvedPrompt, ResolvedPromptEnvelope, ResolvedToolCall, ResolvedToolDefinition, RowError, TextChatMessage, TextChatRole, UnknownRoleMode, UpdateProjectPromptLabelInput, UpdateProjectPromptLabelResult, UpdatePromptInput, UpdatePromptResult, } from "./types";
|
|
7
7
|
/**
|
|
8
8
|
* Init-time config for the env-aware `render()` surface (TO11-980 / S9).
|
|
9
9
|
*
|
|
@@ -34,8 +34,15 @@ export declare class PromptResource<F extends RenderFormat | undefined = undefin
|
|
|
34
34
|
constructor(transport: Transport, cacheConfig?: CacheConfig, config?: Omit<PromptResourceConfig, "format"> & {
|
|
35
35
|
format?: F;
|
|
36
36
|
});
|
|
37
|
+
/**
|
|
38
|
+
* Resolve the project for a control-plane call: the per-call `projectId`
|
|
39
|
+
* wins, else the client-bound one from `createClient({ projectId })`. Throws
|
|
40
|
+
* if neither is set. Mirrors how `render()` resolves its project, so every
|
|
41
|
+
* method honors the bound `projectId` and callers need not repeat it.
|
|
42
|
+
*/
|
|
43
|
+
private resolveProjectId;
|
|
37
44
|
create(input: CreatePromptInput): Promise<CreatePromptResult>;
|
|
38
|
-
list(input
|
|
45
|
+
list(input?: ListPromptsInput): Promise<PaginatedResult<ListPromptsResult>>;
|
|
39
46
|
get(input: GetPromptInput): Promise<GetPromptResult>;
|
|
40
47
|
update(input: UpdatePromptInput): Promise<UpdatePromptResult>;
|
|
41
48
|
archive(input: ArchivePromptInput): Promise<ArchivePromptResult>;
|
|
@@ -49,8 +56,7 @@ export declare class PromptResource<F extends RenderFormat | undefined = undefin
|
|
|
49
56
|
* `projectId` + `env`, in one control-plane request. With a `format` (per
|
|
50
57
|
* call or inherited from the client) the result is provider-shaped
|
|
51
58
|
* `{ messages, config, metadata }`; without one it is the neutral
|
|
52
|
-
* `
|
|
53
|
-
* resolution see {@link PromptResource.resolve | `resolve()`}.
|
|
59
|
+
* `RenderedPrompt`. Resolves by the client's configured `env`.
|
|
54
60
|
*
|
|
55
61
|
* @example Render an OpenAI-shaped prompt and send it through the gateway
|
|
56
62
|
* const prompt = await to11.prompts.render("weather-concierge", {
|
|
@@ -69,7 +75,7 @@ export declare class PromptResource<F extends RenderFormat | undefined = undefin
|
|
|
69
75
|
}): Promise<AnthropicRenderedPrompt>;
|
|
70
76
|
render(slug: string, options?: RenderOptions): Promise<RenderResult<F>>;
|
|
71
77
|
/**
|
|
72
|
-
* Env-aware resolution → neutral `
|
|
78
|
+
* Env-aware resolution → neutral `RenderedPrompt`. Carries the resolve /
|
|
73
79
|
* cache / offline-fallback logic; `render()` is the public shaping surface.
|
|
74
80
|
*
|
|
75
81
|
* - **env→label wire mapping:** the resolve route is label-based
|
|
@@ -82,17 +88,7 @@ export declare class PromptResource<F extends RenderFormat | undefined = undefin
|
|
|
82
88
|
* WITH a `subject`; BYPASSES the cache for weighted releases with NO
|
|
83
89
|
* `subject` (a uniform-random assignment must not be pinned for the TTL).
|
|
84
90
|
*/
|
|
85
|
-
private
|
|
86
|
-
/**
|
|
87
|
-
* Resolve a prompt by explicit `labels` for a given `projectId`, in one
|
|
88
|
-
* control-plane request. This is the label-addressed counterpart to
|
|
89
|
-
* {@link PromptResource.render | `render()`}, which resolves by the client's
|
|
90
|
-
* configured `env`. Reach for `resolve()` when you address prompts by label
|
|
91
|
-
* rather than by environment; it is env-agnostic, so it carries no `env` /
|
|
92
|
-
* `subject`, no enriched release/variant provenance, and no typed-env errors,
|
|
93
|
-
* and is not subject to the env-based no-silent-fallback gate.
|
|
94
|
-
*/
|
|
95
|
-
resolve(input: ResolvePromptInput): Promise<ResolvePromptResult>;
|
|
91
|
+
private resolveToRendered;
|
|
96
92
|
/**
|
|
97
93
|
* List the project-level label registry.
|
|
98
94
|
*
|
|
@@ -100,7 +96,7 @@ export declare class PromptResource<F extends RenderFormat | undefined = undefin
|
|
|
100
96
|
* include rows with a non-null `archivedAt` (useful for admin / history
|
|
101
97
|
* affordances). Gated on `prompt:read` server-side.
|
|
102
98
|
*/
|
|
103
|
-
listProjectLabels(input
|
|
99
|
+
listProjectLabels(input?: ListProjectPromptLabelsInput): Promise<ListProjectPromptLabelsResult>;
|
|
104
100
|
/**
|
|
105
101
|
* Create a new project label.
|
|
106
102
|
*
|