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