@to11ai/sdk 2.0.0-rc.3 → 2.0.0-rc.4
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 +16 -41
- package/dist/client.d.ts +17 -37
- package/dist/client.js +14 -50
- package/dist/errors.cjs +19 -24
- package/dist/errors.d.ts +18 -46
- package/dist/errors.js +19 -24
- package/dist/gateway.cjs +18 -12
- package/dist/gateway.d.ts +19 -20
- package/dist/gateway.js +18 -12
- package/dist/generated/index.d.ts +1 -1
- package/dist/generated/types.gen.d.ts +103 -0
- package/dist/generated/zod.gen.d.ts +55 -12
- package/dist/prompts/resource.cjs +13 -28
- package/dist/prompts/resource.d.ts +8 -14
- package/dist/prompts/resource.js +17 -28
- package/dist/prompts/shape.d.ts +1 -1
- package/dist/prompts/types.d.ts +17 -13
- package/dist/transport.d.ts +2 -6
- package/package.json +3 -11
- package/src/client.ts +31 -118
- package/src/context.ts +3 -5
- package/src/errors.ts +34 -78
- package/src/gateway.ts +44 -39
- package/src/generated/index.ts +1 -1
- package/src/generated/types.gen.ts +108 -0
- package/src/generated/zod.gen.ts +46 -0
- package/src/prompts/resource.ts +36 -74
- package/src/prompts/shape.ts +1 -1
- package/src/prompts/types.ts +17 -14
- package/src/transport.ts +53 -40
- package/dist/prompts/cache.d.ts +0 -58
- package/dist/routingRules/resource.cjs +0 -138
- package/dist/routingRules/resource.js +0 -98
- package/src/prompts/cache.ts +0 -153
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
// src/routingRules/resource.ts
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
import { zRuleRelease, zRuleVersion } from "../generated/zod.gen";
|
|
4
|
-
function unwrap(envelope) {
|
|
5
|
-
if (envelope.data === null || envelope.data === undefined) {
|
|
6
|
-
throw new Error("API returned success but data is null");
|
|
7
|
-
}
|
|
8
|
-
return envelope.data;
|
|
9
|
-
}
|
|
10
|
-
function rulePath(projectId, ruleId) {
|
|
11
|
-
return `/v1/projects/${encodeURIComponent(projectId)}/routing/rules/${encodeURIComponent(ruleId)}`;
|
|
12
|
-
}
|
|
13
|
-
function versionsPath(projectId, ruleId) {
|
|
14
|
-
return `${rulePath(projectId, ruleId)}/versions`;
|
|
15
|
-
}
|
|
16
|
-
function versionPath(projectId, ruleId, versionId) {
|
|
17
|
-
return `${versionsPath(projectId, ruleId)}/${encodeURIComponent(versionId)}`;
|
|
18
|
-
}
|
|
19
|
-
function releasesPath(projectId, ruleId) {
|
|
20
|
-
return `${rulePath(projectId, ruleId)}/releases`;
|
|
21
|
-
}
|
|
22
|
-
function releasePath(projectId, ruleId, envSlug) {
|
|
23
|
-
return `${releasesPath(projectId, ruleId)}/${encodeURIComponent(envSlug)}`;
|
|
24
|
-
}
|
|
25
|
-
function releaseRollbackPath(projectId, ruleId, envSlug) {
|
|
26
|
-
return `${releasePath(projectId, ruleId, envSlug)}/rollback`;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
class RoutingRuleVersionResource {
|
|
30
|
-
transport;
|
|
31
|
-
constructor(transport) {
|
|
32
|
-
this.transport = transport;
|
|
33
|
-
}
|
|
34
|
-
async create(input) {
|
|
35
|
-
const { projectId, ruleId, ...body } = input;
|
|
36
|
-
const envelope = await this.transport.request("POST", versionsPath(projectId, ruleId), { body });
|
|
37
|
-
return unwrap(envelope);
|
|
38
|
-
}
|
|
39
|
-
async list(input) {
|
|
40
|
-
const query = {};
|
|
41
|
-
if (input.cursor !== undefined)
|
|
42
|
-
query.cursor = input.cursor;
|
|
43
|
-
if (input.limit !== undefined)
|
|
44
|
-
query.limit = input.limit;
|
|
45
|
-
const envelope = await this.transport.request("GET", versionsPath(input.projectId, input.ruleId), { query });
|
|
46
|
-
return unwrap(envelope);
|
|
47
|
-
}
|
|
48
|
-
async get(input) {
|
|
49
|
-
const envelope = await this.transport.request("GET", versionPath(input.projectId, input.ruleId, input.versionId), {
|
|
50
|
-
decode: (data) => zRuleVersion.parse(data)
|
|
51
|
-
});
|
|
52
|
-
return unwrap(envelope);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
class RoutingRuleReleaseResource {
|
|
57
|
-
transport;
|
|
58
|
-
constructor(transport) {
|
|
59
|
-
this.transport = transport;
|
|
60
|
-
}
|
|
61
|
-
async set(input) {
|
|
62
|
-
const { projectId, ruleId, envSlug, ...body } = input;
|
|
63
|
-
const envelope = await this.transport.request("PUT", releasePath(projectId, ruleId, envSlug), { body });
|
|
64
|
-
return unwrap(envelope);
|
|
65
|
-
}
|
|
66
|
-
async rollback(input) {
|
|
67
|
-
const { projectId, ruleId, envSlug, ...body } = input;
|
|
68
|
-
const envelope = await this.transport.request("POST", releaseRollbackPath(projectId, ruleId, envSlug), { body });
|
|
69
|
-
return unwrap(envelope);
|
|
70
|
-
}
|
|
71
|
-
async list(input) {
|
|
72
|
-
const query = {};
|
|
73
|
-
if (input.cursor !== undefined)
|
|
74
|
-
query.cursor = input.cursor;
|
|
75
|
-
if (input.limit !== undefined)
|
|
76
|
-
query.limit = input.limit;
|
|
77
|
-
const path = input.envSlug !== undefined ? releasePath(input.projectId, input.ruleId, input.envSlug) : releasesPath(input.projectId, input.ruleId);
|
|
78
|
-
const envelope = await this.transport.request("GET", path, {
|
|
79
|
-
query,
|
|
80
|
-
decode: (data) => z.array(zRuleRelease).parse(data)
|
|
81
|
-
});
|
|
82
|
-
return unwrap(envelope);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
class RoutingRulesResource {
|
|
87
|
-
versions;
|
|
88
|
-
releases;
|
|
89
|
-
constructor(transport) {
|
|
90
|
-
this.versions = new RoutingRuleVersionResource(transport);
|
|
91
|
-
this.releases = new RoutingRuleReleaseResource(transport);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
export {
|
|
95
|
-
RoutingRulesResource,
|
|
96
|
-
RoutingRuleVersionResource,
|
|
97
|
-
RoutingRuleReleaseResource
|
|
98
|
-
};
|
package/src/prompts/cache.ts
DELETED
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import type { RenderedPrompt } from "./types";
|
|
2
|
-
|
|
3
|
-
export interface CacheConfig {
|
|
4
|
-
/** Time-to-live in seconds. Default: 300 (5 minutes) */
|
|
5
|
-
ttlSeconds?: number;
|
|
6
|
-
/** Maximum number of entries. Default: 100 */
|
|
7
|
-
maxEntries?: number;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* The cache stores enriched `render()` results, which are JSON-cloneable.
|
|
12
|
-
*/
|
|
13
|
-
export type CacheableRendered = RenderedPrompt;
|
|
14
|
-
|
|
15
|
-
interface CacheEntry {
|
|
16
|
-
value: CacheableRendered;
|
|
17
|
-
expiresAt: number;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Build a canonical base cache key from project/slug/labels/variables.
|
|
22
|
-
*
|
|
23
|
-
* - projectId is included to prevent cross-project cache collisions: a single
|
|
24
|
-
* PromptResource can serve multiple projects, so the same slug+labels must
|
|
25
|
-
* not share a cache entry across different projects.
|
|
26
|
-
* - Labels are sorted alphabetically so ["production", "en"] and ["en", "production"]
|
|
27
|
-
* map to the same key.
|
|
28
|
-
* - Variables are canonicalized with deterministic sorted-keys JSON before hashing.
|
|
29
|
-
* - Each segment is JSON-encoded so that separator characters in slug or label
|
|
30
|
-
* values cannot cause key collisions (e.g. a slug containing "|" or ",").
|
|
31
|
-
*/
|
|
32
|
-
export function buildCacheKey(
|
|
33
|
-
projectId: string,
|
|
34
|
-
slug: string,
|
|
35
|
-
labels: string[],
|
|
36
|
-
variables?: Record<string, unknown>,
|
|
37
|
-
): string {
|
|
38
|
-
const sortedLabels = [...labels].sort();
|
|
39
|
-
const varsPart =
|
|
40
|
-
variables !== undefined ? JSON.stringify(sortObjectKeys(variables)) : null;
|
|
41
|
-
// JSON.stringify each segment to prevent separator-character collisions
|
|
42
|
-
return `${JSON.stringify(projectId)}|${JSON.stringify(slug)}|${JSON.stringify(sortedLabels)}|${JSON.stringify(varsPart)}`;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Build a cache key for an env-aware `render()` call.
|
|
47
|
-
*
|
|
48
|
-
* Folds in `env` and `subject` ON TOP of the base
|
|
49
|
-
* project/slug/labels/variables key so two calls that differ only by
|
|
50
|
-
* env/subject do not return a stale cross-env / cross-cohort hit
|
|
51
|
-
* (spec §3 "Caching key changes"). The env slug is also forwarded as the
|
|
52
|
-
* single resolution label (env→label mapping, correction #3), so it appears
|
|
53
|
-
* in the `labels` segment too; including it explicitly here keeps the key
|
|
54
|
-
* unambiguous and self-documenting.
|
|
55
|
-
*
|
|
56
|
-
* `subject` participates in the key so a `subject`-keyed weighted assignment
|
|
57
|
-
* caches as the same deterministic variant on repeat (D8); the
|
|
58
|
-
* weighted-no-subject bypass is handled in the resource, not here.
|
|
59
|
-
*/
|
|
60
|
-
export function buildRenderCacheKey(
|
|
61
|
-
projectId: string,
|
|
62
|
-
slug: string,
|
|
63
|
-
env: string,
|
|
64
|
-
subject?: string,
|
|
65
|
-
variables?: Record<string, unknown>,
|
|
66
|
-
): string {
|
|
67
|
-
const base = buildCacheKey(projectId, slug, [env], variables);
|
|
68
|
-
return `render|${base}|${JSON.stringify(env)}|${JSON.stringify(subject ?? null)}`;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function sortObjectKeys(obj: unknown): unknown {
|
|
72
|
-
if (obj === null || typeof obj !== "object") return obj;
|
|
73
|
-
if (Array.isArray(obj)) return obj.map(sortObjectKeys);
|
|
74
|
-
const sorted: Record<string, unknown> = {};
|
|
75
|
-
for (const key of Object.keys(obj as Record<string, unknown>).sort()) {
|
|
76
|
-
sorted[key] = sortObjectKeys((obj as Record<string, unknown>)[key]);
|
|
77
|
-
}
|
|
78
|
-
return sorted;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* In-memory LRU cache for RenderedPrompt objects.
|
|
83
|
-
*
|
|
84
|
-
* Uses a Map (insertion-ordered) as the backing store. On every access, the
|
|
85
|
-
* entry is deleted and re-inserted to maintain LRU order — oldest entries sit
|
|
86
|
-
* at the front of the Map.
|
|
87
|
-
*/
|
|
88
|
-
export class PromptCache {
|
|
89
|
-
private readonly ttlMs: number;
|
|
90
|
-
private readonly maxEntries: number;
|
|
91
|
-
private readonly store: Map<string, CacheEntry>;
|
|
92
|
-
|
|
93
|
-
constructor(config?: CacheConfig) {
|
|
94
|
-
this.ttlMs = (config?.ttlSeconds ?? 300) * 1000;
|
|
95
|
-
this.maxEntries = config?.maxEntries ?? 100;
|
|
96
|
-
this.store = new Map();
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
get(key: string): CacheableRendered | undefined {
|
|
100
|
-
const entry = this.store.get(key);
|
|
101
|
-
if (!entry) return undefined;
|
|
102
|
-
|
|
103
|
-
if (Date.now() > entry.expiresAt) {
|
|
104
|
-
this.store.delete(key);
|
|
105
|
-
return undefined;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// Refresh LRU order — move to end
|
|
109
|
-
this.store.delete(key);
|
|
110
|
-
this.store.set(key, entry);
|
|
111
|
-
|
|
112
|
-
return entry.value;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
set(key: string, value: CacheableRendered): void {
|
|
116
|
-
// maxEntries: 0 (or negative) means caching is disabled — drop the entry.
|
|
117
|
-
if (this.maxEntries <= 0) {
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// Remove existing entry so re-insertion moves it to the end
|
|
122
|
-
if (this.store.has(key)) {
|
|
123
|
-
this.store.delete(key);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// Evict least-recently-used entry if at capacity
|
|
127
|
-
while (this.store.size >= this.maxEntries) {
|
|
128
|
-
const lruKey = this.store.keys().next().value;
|
|
129
|
-
if (lruKey !== undefined) {
|
|
130
|
-
this.store.delete(lruKey);
|
|
131
|
-
} else {
|
|
132
|
-
break;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
this.store.set(key, {
|
|
137
|
-
value,
|
|
138
|
-
expiresAt: Date.now() + this.ttlMs,
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
delete(key: string): void {
|
|
143
|
-
this.store.delete(key);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
clear(): void {
|
|
147
|
-
this.store.clear();
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
get size(): number {
|
|
151
|
-
return this.store.size;
|
|
152
|
-
}
|
|
153
|
-
}
|