@to11ai/sdk 2.0.0-rc.2 → 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 CHANGED
@@ -194,6 +194,7 @@ function createClient(options = {}) {
194
194
  resolveBehavior: (key, codedDefault) => behaviorStore.resolve(key, codedDefault),
195
195
  apiKey,
196
196
  gatewayUrl,
197
+ projectId,
197
198
  session: (id) => new import_context.Session(gatewayAuthContext(), id),
198
199
  conversation: (id) => clientDefaultSession().conversation(id),
199
200
  turn: () => clientDefaultSession().turn(),
package/dist/client.d.ts CHANGED
@@ -127,6 +127,12 @@ export interface To11aiClient<F extends RenderFormat | undefined = undefined> {
127
127
  readonly apiKey: string | undefined;
128
128
  /** Resolved data-plane gateway URL (option → `TO11_GATEWAY_URL` → default). */
129
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;
130
136
  /** A new session (unit of work). Pass an id to group telemetry by your own id. */
131
137
  session(id?: string): Session;
132
138
  /**
package/dist/client.js CHANGED
@@ -150,6 +150,7 @@ function createClient(options = {}) {
150
150
  resolveBehavior: (key, codedDefault) => behaviorStore.resolve(key, codedDefault),
151
151
  apiKey,
152
152
  gatewayUrl,
153
+ projectId,
153
154
  session: (id) => new Session(gatewayAuthContext(), id),
154
155
  conversation: (id) => clientDefaultSession().conversation(id),
155
156
  turn: () => clientDefaultSession().turn(),
@@ -141,13 +141,22 @@ class PromptResource {
141
141
  this.format = config?.format;
142
142
  this.onUnknownRole = config?.onUnknownRole;
143
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
+ }
144
151
  async create(input) {
145
- const { projectId, ...body } = input;
152
+ const { projectId: perCallProjectId, ...body } = input;
153
+ const projectId = this.resolveProjectId(perCallProjectId);
146
154
  const envelope = await this.transport.request("POST", getProjectPromptsPath(projectId), { body });
147
155
  return unwrap(envelope);
148
156
  }
149
- async list(input) {
150
- const { projectId, ...queryRest } = input;
157
+ async list(input = {}) {
158
+ const { projectId: perCallProjectId, ...queryRest } = input;
159
+ const projectId = this.resolveProjectId(perCallProjectId);
151
160
  const envelope = await this.transport.request("GET", getProjectPromptsPath(projectId), {
152
161
  query: {
153
162
  ...queryRest
@@ -164,42 +173,50 @@ class PromptResource {
164
173
  return { items, pagination };
165
174
  }
166
175
  async get(input) {
167
- const { projectId, promptId } = input;
176
+ const { projectId: perCallProjectId, promptId } = input;
177
+ const projectId = this.resolveProjectId(perCallProjectId);
168
178
  const envelope = await this.transport.request("GET", getProjectPromptPath(projectId, promptId));
169
179
  return unwrap(envelope);
170
180
  }
171
181
  async update(input) {
172
- const { projectId, promptId, ...body } = input;
182
+ const { projectId: perCallProjectId, promptId, ...body } = input;
183
+ const projectId = this.resolveProjectId(perCallProjectId);
173
184
  const envelope = await this.transport.request("PATCH", getProjectPromptPath(projectId, promptId), { body });
174
185
  return unwrap(envelope);
175
186
  }
176
187
  async archive(input) {
177
- const { projectId, promptId } = input;
188
+ const { projectId: perCallProjectId, promptId } = input;
189
+ const projectId = this.resolveProjectId(perCallProjectId);
178
190
  const envelope = await this.transport.request("DELETE", getProjectPromptPath(projectId, promptId));
179
191
  return unwrap(envelope);
180
192
  }
181
193
  async createVersion(input) {
182
- const { projectId, promptId, ...body } = input;
194
+ const { projectId: perCallProjectId, promptId, ...body } = input;
195
+ const projectId = this.resolveProjectId(perCallProjectId);
183
196
  const envelope = await this.transport.request("POST", `${getProjectPromptPath(projectId, promptId)}/versions`, { body });
184
197
  return unwrap(envelope);
185
198
  }
186
199
  async listVersions(input) {
187
- const { projectId, promptId } = input;
200
+ const { projectId: perCallProjectId, promptId } = input;
201
+ const projectId = this.resolveProjectId(perCallProjectId);
188
202
  const envelope = await this.transport.request("GET", `${getProjectPromptPath(projectId, promptId)}/versions`);
189
203
  return unwrap(envelope);
190
204
  }
191
205
  async getVersion(input) {
192
- const { projectId, promptId, versionNumber } = input;
206
+ const { projectId: perCallProjectId, promptId, versionNumber } = input;
207
+ const projectId = this.resolveProjectId(perCallProjectId);
193
208
  const envelope = await this.transport.request("GET", `${getProjectPromptPath(projectId, promptId)}/versions/${encodeURIComponent(String(versionNumber))}`);
194
209
  return unwrap(envelope);
195
210
  }
196
211
  async moveLabel(input) {
197
- const { projectId, promptId, label, ...body } = input;
212
+ const { projectId: perCallProjectId, promptId, label, ...body } = input;
213
+ const projectId = this.resolveProjectId(perCallProjectId);
198
214
  const envelope = await this.transport.request("PUT", `${getProjectPromptPath(projectId, promptId)}/labels/${encodeURIComponent(label)}`, { body });
199
215
  return unwrap(envelope);
200
216
  }
201
217
  async listLabels(input) {
202
- const { projectId, promptId } = input;
218
+ const { projectId: perCallProjectId, promptId } = input;
219
+ const projectId = this.resolveProjectId(perCallProjectId);
203
220
  const envelope = await this.transport.request("GET", `${getProjectPromptPath(projectId, promptId)}/labels`);
204
221
  return unwrap(envelope);
205
222
  }
@@ -252,24 +269,28 @@ class PromptResource {
252
269
  throw err;
253
270
  }
254
271
  }
255
- async listProjectLabels(input) {
256
- const { projectId, includeArchived } = input;
272
+ async listProjectLabels(input = {}) {
273
+ const { projectId: perCallProjectId, includeArchived } = input;
274
+ const projectId = this.resolveProjectId(perCallProjectId);
257
275
  const envelope = await this.transport.request("GET", getProjectPromptLabelsPath(projectId), {
258
276
  query: includeArchived ? { includeArchived: "true" } : undefined
259
277
  });
260
278
  return unwrap(envelope);
261
279
  }
262
280
  async createProjectLabel(input) {
263
- const { projectId, ...body } = input;
281
+ const { projectId: perCallProjectId, ...body } = input;
282
+ const projectId = this.resolveProjectId(perCallProjectId);
264
283
  const envelope = await this.transport.request("POST", getProjectPromptLabelsPath(projectId), { body });
265
284
  return unwrap(envelope);
266
285
  }
267
286
  async getProjectLabel(input) {
268
- const envelope = await this.transport.request("GET", getProjectPromptLabelPath(input.projectId, input.label));
287
+ const projectId = this.resolveProjectId(input.projectId);
288
+ const envelope = await this.transport.request("GET", getProjectPromptLabelPath(projectId, input.label));
269
289
  return unwrap(envelope);
270
290
  }
271
291
  async updateProjectLabel(input) {
272
- const { projectId, label, ...rest } = input;
292
+ const { projectId: perCallProjectId, label, ...rest } = input;
293
+ const projectId = this.resolveProjectId(perCallProjectId);
273
294
  const body = {};
274
295
  if (rest.isDefault !== undefined)
275
296
  body.isDefault = rest.isDefault;
@@ -281,15 +302,16 @@ class PromptResource {
281
302
  return unwrap(envelope);
282
303
  }
283
304
  async deleteProjectLabel(input) {
284
- const envelope = await this.transport.request("DELETE", getProjectPromptLabelPath(input.projectId, input.label));
305
+ const projectId = this.resolveProjectId(input.projectId);
306
+ const envelope = await this.transport.request("DELETE", getProjectPromptLabelPath(projectId, input.label));
285
307
  return unwrap(envelope);
286
308
  }
287
309
  async listProjectLabelUsages(input) {
288
- 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`);
289
311
  return unwrap(envelope);
290
312
  }
291
313
  async listLabelEvents(input) {
292
- const projectSeg = encodeURIComponent(input.projectId);
314
+ const projectSeg = encodeURIComponent(this.resolveProjectId(input.projectId));
293
315
  let path;
294
316
  switch (input.scope) {
295
317
  case "label":
@@ -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: ListPromptsInput): Promise<PaginatedResult<ListPromptsResult>>;
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>;
@@ -89,7 +96,7 @@ export declare class PromptResource<F extends RenderFormat | undefined = undefin
89
96
  * include rows with a non-null `archivedAt` (useful for admin / history
90
97
  * affordances). Gated on `prompt:read` server-side.
91
98
  */
92
- listProjectLabels(input: ListProjectPromptLabelsInput): Promise<ListProjectPromptLabelsResult>;
99
+ listProjectLabels(input?: ListProjectPromptLabelsInput): Promise<ListProjectPromptLabelsResult>;
93
100
  /**
94
101
  * Create a new project label.
95
102
  *
@@ -98,13 +98,22 @@ class PromptResource {
98
98
  this.format = config?.format;
99
99
  this.onUnknownRole = config?.onUnknownRole;
100
100
  }
101
+ resolveProjectId(perCall) {
102
+ const projectId = perCall ?? this.projectId;
103
+ if (projectId === undefined || projectId.trim() === "") {
104
+ throw new Error("[to11ai/sdk] this call needs a `projectId` — pass it on the call or bind one via createClient({ projectId, ... }).");
105
+ }
106
+ return projectId.trim();
107
+ }
101
108
  async create(input) {
102
- const { projectId, ...body } = input;
109
+ const { projectId: perCallProjectId, ...body } = input;
110
+ const projectId = this.resolveProjectId(perCallProjectId);
103
111
  const envelope = await this.transport.request("POST", getProjectPromptsPath(projectId), { body });
104
112
  return unwrap(envelope);
105
113
  }
106
- async list(input) {
107
- const { projectId, ...queryRest } = input;
114
+ async list(input = {}) {
115
+ const { projectId: perCallProjectId, ...queryRest } = input;
116
+ const projectId = this.resolveProjectId(perCallProjectId);
108
117
  const envelope = await this.transport.request("GET", getProjectPromptsPath(projectId), {
109
118
  query: {
110
119
  ...queryRest
@@ -121,42 +130,50 @@ class PromptResource {
121
130
  return { items, pagination };
122
131
  }
123
132
  async get(input) {
124
- const { projectId, promptId } = input;
133
+ const { projectId: perCallProjectId, promptId } = input;
134
+ const projectId = this.resolveProjectId(perCallProjectId);
125
135
  const envelope = await this.transport.request("GET", getProjectPromptPath(projectId, promptId));
126
136
  return unwrap(envelope);
127
137
  }
128
138
  async update(input) {
129
- const { projectId, promptId, ...body } = input;
139
+ const { projectId: perCallProjectId, promptId, ...body } = input;
140
+ const projectId = this.resolveProjectId(perCallProjectId);
130
141
  const envelope = await this.transport.request("PATCH", getProjectPromptPath(projectId, promptId), { body });
131
142
  return unwrap(envelope);
132
143
  }
133
144
  async archive(input) {
134
- const { projectId, promptId } = input;
145
+ const { projectId: perCallProjectId, promptId } = input;
146
+ const projectId = this.resolveProjectId(perCallProjectId);
135
147
  const envelope = await this.transport.request("DELETE", getProjectPromptPath(projectId, promptId));
136
148
  return unwrap(envelope);
137
149
  }
138
150
  async createVersion(input) {
139
- const { projectId, promptId, ...body } = input;
151
+ const { projectId: perCallProjectId, promptId, ...body } = input;
152
+ const projectId = this.resolveProjectId(perCallProjectId);
140
153
  const envelope = await this.transport.request("POST", `${getProjectPromptPath(projectId, promptId)}/versions`, { body });
141
154
  return unwrap(envelope);
142
155
  }
143
156
  async listVersions(input) {
144
- const { projectId, promptId } = input;
157
+ const { projectId: perCallProjectId, promptId } = input;
158
+ const projectId = this.resolveProjectId(perCallProjectId);
145
159
  const envelope = await this.transport.request("GET", `${getProjectPromptPath(projectId, promptId)}/versions`);
146
160
  return unwrap(envelope);
147
161
  }
148
162
  async getVersion(input) {
149
- const { projectId, promptId, versionNumber } = input;
163
+ const { projectId: perCallProjectId, promptId, versionNumber } = input;
164
+ const projectId = this.resolveProjectId(perCallProjectId);
150
165
  const envelope = await this.transport.request("GET", `${getProjectPromptPath(projectId, promptId)}/versions/${encodeURIComponent(String(versionNumber))}`);
151
166
  return unwrap(envelope);
152
167
  }
153
168
  async moveLabel(input) {
154
- const { projectId, promptId, label, ...body } = input;
169
+ const { projectId: perCallProjectId, promptId, label, ...body } = input;
170
+ const projectId = this.resolveProjectId(perCallProjectId);
155
171
  const envelope = await this.transport.request("PUT", `${getProjectPromptPath(projectId, promptId)}/labels/${encodeURIComponent(label)}`, { body });
156
172
  return unwrap(envelope);
157
173
  }
158
174
  async listLabels(input) {
159
- const { projectId, promptId } = input;
175
+ const { projectId: perCallProjectId, promptId } = input;
176
+ const projectId = this.resolveProjectId(perCallProjectId);
160
177
  const envelope = await this.transport.request("GET", `${getProjectPromptPath(projectId, promptId)}/labels`);
161
178
  return unwrap(envelope);
162
179
  }
@@ -209,24 +226,28 @@ class PromptResource {
209
226
  throw err;
210
227
  }
211
228
  }
212
- async listProjectLabels(input) {
213
- const { projectId, includeArchived } = input;
229
+ async listProjectLabels(input = {}) {
230
+ const { projectId: perCallProjectId, includeArchived } = input;
231
+ const projectId = this.resolveProjectId(perCallProjectId);
214
232
  const envelope = await this.transport.request("GET", getProjectPromptLabelsPath(projectId), {
215
233
  query: includeArchived ? { includeArchived: "true" } : undefined
216
234
  });
217
235
  return unwrap(envelope);
218
236
  }
219
237
  async createProjectLabel(input) {
220
- const { projectId, ...body } = input;
238
+ const { projectId: perCallProjectId, ...body } = input;
239
+ const projectId = this.resolveProjectId(perCallProjectId);
221
240
  const envelope = await this.transport.request("POST", getProjectPromptLabelsPath(projectId), { body });
222
241
  return unwrap(envelope);
223
242
  }
224
243
  async getProjectLabel(input) {
225
- const envelope = await this.transport.request("GET", getProjectPromptLabelPath(input.projectId, input.label));
244
+ const projectId = this.resolveProjectId(input.projectId);
245
+ const envelope = await this.transport.request("GET", getProjectPromptLabelPath(projectId, input.label));
226
246
  return unwrap(envelope);
227
247
  }
228
248
  async updateProjectLabel(input) {
229
- const { projectId, label, ...rest } = input;
249
+ const { projectId: perCallProjectId, label, ...rest } = input;
250
+ const projectId = this.resolveProjectId(perCallProjectId);
230
251
  const body = {};
231
252
  if (rest.isDefault !== undefined)
232
253
  body.isDefault = rest.isDefault;
@@ -238,15 +259,16 @@ class PromptResource {
238
259
  return unwrap(envelope);
239
260
  }
240
261
  async deleteProjectLabel(input) {
241
- const envelope = await this.transport.request("DELETE", getProjectPromptLabelPath(input.projectId, input.label));
262
+ const projectId = this.resolveProjectId(input.projectId);
263
+ const envelope = await this.transport.request("DELETE", getProjectPromptLabelPath(projectId, input.label));
242
264
  return unwrap(envelope);
243
265
  }
244
266
  async listProjectLabelUsages(input) {
245
- const envelope = await this.transport.request("GET", `${getProjectPromptLabelPath(input.projectId, input.label)}/usages`);
267
+ const envelope = await this.transport.request("GET", `${getProjectPromptLabelPath(this.resolveProjectId(input.projectId), input.label)}/usages`);
246
268
  return unwrap(envelope);
247
269
  }
248
270
  async listLabelEvents(input) {
249
- const projectSeg = encodeURIComponent(input.projectId);
271
+ const projectSeg = encodeURIComponent(this.resolveProjectId(input.projectId));
250
272
  let path;
251
273
  switch (input.scope) {
252
274
  case "label":
@@ -50,7 +50,7 @@ export interface PaginatedResult<T> {
50
50
  pagination: PaginationInfo;
51
51
  }
52
52
  export interface CreatePromptInput {
53
- projectId: string;
53
+ projectId?: string;
54
54
  name: string;
55
55
  slug: string;
56
56
  description?: string;
@@ -58,7 +58,7 @@ export interface CreatePromptInput {
58
58
  }
59
59
  export type CreatePromptResult = Prompt;
60
60
  export interface ListPromptsInput {
61
- projectId: string;
61
+ projectId?: string;
62
62
  status?: PromptStatus;
63
63
  sortBy?: "createdAt" | "updatedAt" | "name";
64
64
  tags?: string;
@@ -67,12 +67,12 @@ export interface ListPromptsInput {
67
67
  }
68
68
  export type ListPromptsResult = Prompt;
69
69
  export interface GetPromptInput {
70
- projectId: string;
70
+ projectId?: string;
71
71
  promptId: string;
72
72
  }
73
73
  export type GetPromptResult = Prompt;
74
74
  export interface UpdatePromptInput {
75
- projectId: string;
75
+ projectId?: string;
76
76
  promptId: string;
77
77
  name?: string;
78
78
  description?: string | null;
@@ -80,12 +80,12 @@ export interface UpdatePromptInput {
80
80
  }
81
81
  export type UpdatePromptResult = Prompt;
82
82
  export interface ArchivePromptInput {
83
- projectId: string;
83
+ projectId?: string;
84
84
  promptId: string;
85
85
  }
86
86
  export type ArchivePromptResult = Prompt;
87
87
  export interface CreatePromptVersionInput {
88
- projectId: string;
88
+ projectId?: string;
89
89
  promptId: string;
90
90
  format: PromptFormat;
91
91
  templateJson: unknown;
@@ -95,18 +95,18 @@ export interface CreatePromptVersionInput {
95
95
  }
96
96
  export type CreatePromptVersionResult = PromptVersion;
97
97
  export interface ListPromptVersionsInput {
98
- projectId: string;
98
+ projectId?: string;
99
99
  promptId: string;
100
100
  }
101
101
  export type ListPromptVersionsResult = PromptVersion[];
102
102
  export interface GetPromptVersionInput {
103
- projectId: string;
103
+ projectId?: string;
104
104
  promptId: string;
105
105
  versionNumber: number;
106
106
  }
107
107
  export type GetPromptVersionResult = PromptVersion;
108
108
  export interface MovePromptLabelInput {
109
- projectId: string;
109
+ projectId?: string;
110
110
  promptId: string;
111
111
  label: string;
112
112
  versionId: string;
@@ -114,7 +114,7 @@ export interface MovePromptLabelInput {
114
114
  }
115
115
  export type MovePromptLabelResult = PromptLabelPointer;
116
116
  export interface ListPromptLabelsInput {
117
- projectId: string;
117
+ projectId?: string;
118
118
  promptId: string;
119
119
  }
120
120
  export type ListPromptLabelsResult = PromptLabelPointer[];
@@ -192,13 +192,13 @@ export type ProjectPromptLabel = GenProjectPromptLabel;
192
192
  export type ProjectPromptLabelUsage = GenProjectPromptLabelUsage;
193
193
  export type PromptLabelEvent = GenPromptLabelEvent;
194
194
  export interface ListProjectPromptLabelsInput {
195
- projectId: string;
195
+ projectId?: string;
196
196
  /** Set true to include archived (soft-deleted) entries. Default: false. */
197
197
  includeArchived?: boolean;
198
198
  }
199
199
  export type ListProjectPromptLabelsResult = ProjectPromptLabel[];
200
200
  export interface CreateProjectPromptLabelInput {
201
- projectId: string;
201
+ projectId?: string;
202
202
  label: string;
203
203
  isDefault?: boolean;
204
204
  description?: string;
@@ -206,12 +206,12 @@ export interface CreateProjectPromptLabelInput {
206
206
  }
207
207
  export type CreateProjectPromptLabelResult = ProjectPromptLabel;
208
208
  export interface GetProjectPromptLabelInput {
209
- projectId: string;
209
+ projectId?: string;
210
210
  label: string;
211
211
  }
212
212
  export type GetProjectPromptLabelResult = ProjectPromptLabel;
213
213
  export interface UpdateProjectPromptLabelInput {
214
- projectId: string;
214
+ projectId?: string;
215
215
  label: string;
216
216
  isDefault?: boolean;
217
217
  description?: string | null;
@@ -219,18 +219,18 @@ export interface UpdateProjectPromptLabelInput {
219
219
  }
220
220
  export type UpdateProjectPromptLabelResult = ProjectPromptLabel;
221
221
  export interface DeleteProjectPromptLabelInput {
222
- projectId: string;
222
+ projectId?: string;
223
223
  label: string;
224
224
  }
225
225
  export type DeleteProjectPromptLabelResult = ProjectPromptLabel;
226
226
  export interface ListProjectPromptLabelUsagesInput {
227
- projectId: string;
227
+ projectId?: string;
228
228
  label: string;
229
229
  }
230
230
  export type ListProjectPromptLabelUsagesResult = ProjectPromptLabelUsage[];
231
231
  export type ListLabelEventsInput = {
232
232
  scope: "label";
233
- projectId: string;
233
+ projectId?: string;
234
234
  promptId: string;
235
235
  label: string;
236
236
  page?: number;
@@ -239,7 +239,7 @@ export type ListLabelEventsInput = {
239
239
  until?: string;
240
240
  } | {
241
241
  scope: "prompt";
242
- projectId: string;
242
+ projectId?: string;
243
243
  promptId: string;
244
244
  label?: string;
245
245
  page?: number;
@@ -248,7 +248,7 @@ export type ListLabelEventsInput = {
248
248
  until?: string;
249
249
  } | {
250
250
  scope: "project";
251
- projectId: string;
251
+ projectId?: string;
252
252
  promptId?: string;
253
253
  label?: string;
254
254
  page?: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@to11ai/sdk",
3
- "version": "2.0.0-rc.2",
3
+ "version": "2.0.0-rc.3",
4
4
  "license": "MPL-2.0",
5
5
  "repository": {
6
6
  "type": "git",
package/src/client.ts CHANGED
@@ -245,6 +245,12 @@ export interface To11aiClient<F extends RenderFormat | undefined = undefined> {
245
245
  readonly apiKey: string | undefined;
246
246
  /** Resolved data-plane gateway URL (option → `TO11_GATEWAY_URL` → default). */
247
247
  readonly gatewayUrl: string;
248
+ /**
249
+ * Resolved project id (option → `TO11_PROJECT_ID`); `undefined` when none is
250
+ * configured. Read-only, for your own logging / manual headers — `prompts.*`
251
+ * already default to it, so you don't need to pass it back into calls.
252
+ */
253
+ readonly projectId: string | undefined;
248
254
  /** A new session (unit of work). Pass an id to group telemetry by your own id. */
249
255
  session(id?: string): Session;
250
256
  /**
@@ -529,6 +535,7 @@ export function createClient<
529
535
  behaviorStore.resolve(key, codedDefault),
530
536
  apiKey,
531
537
  gatewayUrl,
538
+ projectId,
532
539
  session: (id) => new Session(gatewayAuthContext(), id),
533
540
  conversation: (id) => clientDefaultSession().conversation(id),
534
541
  turn: () => clientDefaultSession().turn(),
@@ -315,10 +315,29 @@ export class PromptResource<F extends RenderFormat | undefined = undefined> {
315
315
  this.onUnknownRole = config?.onUnknownRole;
316
316
  }
317
317
 
318
+ /**
319
+ * Resolve the project for a control-plane call: the per-call `projectId`
320
+ * wins, else the client-bound one from `createClient({ projectId })`. Throws
321
+ * if neither is set. Mirrors how `render()` resolves its project, so every
322
+ * method honors the bound `projectId` and callers need not repeat it.
323
+ */
324
+ private resolveProjectId(perCall?: string): string {
325
+ const projectId = perCall ?? this.projectId;
326
+ if (projectId === undefined || projectId.trim() === "") {
327
+ throw new Error(
328
+ "[to11ai/sdk] this call needs a `projectId` — pass it on the call or bind one via createClient({ projectId, ... }).",
329
+ );
330
+ }
331
+ // Trim so a whitespace-padded per-call id normalizes like the client-bound
332
+ // one (resolved via `pick()`), instead of reaching the wire untrimmed.
333
+ return projectId.trim();
334
+ }
335
+
318
336
  // ─── Create ──────────────────────────────────────────────────────────────
319
337
 
320
338
  async create(input: CreatePromptInput): Promise<CreatePromptResult> {
321
- const { projectId, ...body } = input;
339
+ const { projectId: perCallProjectId, ...body } = input;
340
+ const projectId = this.resolveProjectId(perCallProjectId);
322
341
  const envelope = await this.transport.request<CreatePromptResult>(
323
342
  "POST",
324
343
  getProjectPromptsPath(projectId),
@@ -330,9 +349,10 @@ export class PromptResource<F extends RenderFormat | undefined = undefined> {
330
349
  // ─── List ─────────────────────────────────────────────────────────────────
331
350
 
332
351
  async list(
333
- input: ListPromptsInput,
352
+ input: ListPromptsInput = {},
334
353
  ): Promise<PaginatedResult<ListPromptsResult>> {
335
- const { projectId, ...queryRest } = input;
354
+ const { projectId: perCallProjectId, ...queryRest } = input;
355
+ const projectId = this.resolveProjectId(perCallProjectId);
336
356
  const envelope = await this.transport.request<
337
357
  | ListPromptsResult[]
338
358
  | {
@@ -364,7 +384,8 @@ export class PromptResource<F extends RenderFormat | undefined = undefined> {
364
384
  // ─── Get ──────────────────────────────────────────────────────────────────
365
385
 
366
386
  async get(input: GetPromptInput): Promise<GetPromptResult> {
367
- const { projectId, promptId } = input;
387
+ const { projectId: perCallProjectId, promptId } = input;
388
+ const projectId = this.resolveProjectId(perCallProjectId);
368
389
  const envelope = await this.transport.request<GetPromptResult>(
369
390
  "GET",
370
391
  getProjectPromptPath(projectId, promptId),
@@ -375,7 +396,8 @@ export class PromptResource<F extends RenderFormat | undefined = undefined> {
375
396
  // ─── Update ───────────────────────────────────────────────────────────────
376
397
 
377
398
  async update(input: UpdatePromptInput): Promise<UpdatePromptResult> {
378
- const { projectId, promptId, ...body } = input;
399
+ const { projectId: perCallProjectId, promptId, ...body } = input;
400
+ const projectId = this.resolveProjectId(perCallProjectId);
379
401
  const envelope = await this.transport.request<UpdatePromptResult>(
380
402
  "PATCH",
381
403
  getProjectPromptPath(projectId, promptId),
@@ -387,7 +409,8 @@ export class PromptResource<F extends RenderFormat | undefined = undefined> {
387
409
  // ─── Archive ──────────────────────────────────────────────────────────────
388
410
 
389
411
  async archive(input: ArchivePromptInput): Promise<ArchivePromptResult> {
390
- const { projectId, promptId } = input;
412
+ const { projectId: perCallProjectId, promptId } = input;
413
+ const projectId = this.resolveProjectId(perCallProjectId);
391
414
  const envelope = await this.transport.request<ArchivePromptResult>(
392
415
  "DELETE",
393
416
  getProjectPromptPath(projectId, promptId),
@@ -400,7 +423,8 @@ export class PromptResource<F extends RenderFormat | undefined = undefined> {
400
423
  async createVersion(
401
424
  input: CreatePromptVersionInput,
402
425
  ): Promise<CreatePromptVersionResult> {
403
- const { projectId, promptId, ...body } = input;
426
+ const { projectId: perCallProjectId, promptId, ...body } = input;
427
+ const projectId = this.resolveProjectId(perCallProjectId);
404
428
  const envelope = await this.transport.request<CreatePromptVersionResult>(
405
429
  "POST",
406
430
  `${getProjectPromptPath(projectId, promptId)}/versions`,
@@ -414,7 +438,8 @@ export class PromptResource<F extends RenderFormat | undefined = undefined> {
414
438
  async listVersions(
415
439
  input: ListPromptVersionsInput,
416
440
  ): Promise<ListPromptVersionsResult> {
417
- const { projectId, promptId } = input;
441
+ const { projectId: perCallProjectId, promptId } = input;
442
+ const projectId = this.resolveProjectId(perCallProjectId);
418
443
  const envelope = await this.transport.request<ListPromptVersionsResult>(
419
444
  "GET",
420
445
  `${getProjectPromptPath(projectId, promptId)}/versions`,
@@ -427,7 +452,8 @@ export class PromptResource<F extends RenderFormat | undefined = undefined> {
427
452
  async getVersion(
428
453
  input: GetPromptVersionInput,
429
454
  ): Promise<GetPromptVersionResult> {
430
- const { projectId, promptId, versionNumber } = input;
455
+ const { projectId: perCallProjectId, promptId, versionNumber } = input;
456
+ const projectId = this.resolveProjectId(perCallProjectId);
431
457
  const envelope = await this.transport.request<GetPromptVersionResult>(
432
458
  "GET",
433
459
  `${getProjectPromptPath(projectId, promptId)}/versions/${encodeURIComponent(String(versionNumber))}`,
@@ -438,7 +464,8 @@ export class PromptResource<F extends RenderFormat | undefined = undefined> {
438
464
  // ─── Move Label ───────────────────────────────────────────────────────────
439
465
 
440
466
  async moveLabel(input: MovePromptLabelInput): Promise<MovePromptLabelResult> {
441
- const { projectId, promptId, label, ...body } = input;
467
+ const { projectId: perCallProjectId, promptId, label, ...body } = input;
468
+ const projectId = this.resolveProjectId(perCallProjectId);
442
469
  const envelope = await this.transport.request<MovePromptLabelResult>(
443
470
  "PUT",
444
471
  `${getProjectPromptPath(projectId, promptId)}/labels/${encodeURIComponent(label)}`,
@@ -452,7 +479,8 @@ export class PromptResource<F extends RenderFormat | undefined = undefined> {
452
479
  async listLabels(
453
480
  input: ListPromptLabelsInput,
454
481
  ): Promise<ListPromptLabelsResult> {
455
- const { projectId, promptId } = input;
482
+ const { projectId: perCallProjectId, promptId } = input;
483
+ const projectId = this.resolveProjectId(perCallProjectId);
456
484
  const envelope = await this.transport.request<ListPromptLabelsResult>(
457
485
  "GET",
458
486
  `${getProjectPromptPath(projectId, promptId)}/labels`,
@@ -611,9 +639,10 @@ export class PromptResource<F extends RenderFormat | undefined = undefined> {
611
639
  * affordances). Gated on `prompt:read` server-side.
612
640
  */
613
641
  async listProjectLabels(
614
- input: ListProjectPromptLabelsInput,
642
+ input: ListProjectPromptLabelsInput = {},
615
643
  ): Promise<ListProjectPromptLabelsResult> {
616
- const { projectId, includeArchived } = input;
644
+ const { projectId: perCallProjectId, includeArchived } = input;
645
+ const projectId = this.resolveProjectId(perCallProjectId);
617
646
  const envelope =
618
647
  await this.transport.request<ListProjectPromptLabelsResult>(
619
648
  "GET",
@@ -635,7 +664,8 @@ export class PromptResource<F extends RenderFormat | undefined = undefined> {
635
664
  async createProjectLabel(
636
665
  input: CreateProjectPromptLabelInput,
637
666
  ): Promise<CreateProjectPromptLabelResult> {
638
- const { projectId, ...body } = input;
667
+ const { projectId: perCallProjectId, ...body } = input;
668
+ const projectId = this.resolveProjectId(perCallProjectId);
639
669
  const envelope =
640
670
  await this.transport.request<CreateProjectPromptLabelResult>(
641
671
  "POST",
@@ -648,9 +678,10 @@ export class PromptResource<F extends RenderFormat | undefined = undefined> {
648
678
  async getProjectLabel(
649
679
  input: GetProjectPromptLabelInput,
650
680
  ): Promise<GetProjectPromptLabelResult> {
681
+ const projectId = this.resolveProjectId(input.projectId);
651
682
  const envelope = await this.transport.request<GetProjectPromptLabelResult>(
652
683
  "GET",
653
- getProjectPromptLabelPath(input.projectId, input.label),
684
+ getProjectPromptLabelPath(projectId, input.label),
654
685
  );
655
686
  return unwrap(envelope);
656
687
  }
@@ -666,7 +697,8 @@ export class PromptResource<F extends RenderFormat | undefined = undefined> {
666
697
  async updateProjectLabel(
667
698
  input: UpdateProjectPromptLabelInput,
668
699
  ): Promise<UpdateProjectPromptLabelResult> {
669
- const { projectId, label, ...rest } = input;
700
+ const { projectId: perCallProjectId, label, ...rest } = input;
701
+ const projectId = this.resolveProjectId(perCallProjectId);
670
702
  const body: Record<string, unknown> = {};
671
703
  if (rest.isDefault !== undefined) body.isDefault = rest.isDefault;
672
704
  if (rest.description !== undefined) body.description = rest.description;
@@ -692,10 +724,11 @@ export class PromptResource<F extends RenderFormat | undefined = undefined> {
692
724
  async deleteProjectLabel(
693
725
  input: DeleteProjectPromptLabelInput,
694
726
  ): Promise<DeleteProjectPromptLabelResult> {
727
+ const projectId = this.resolveProjectId(input.projectId);
695
728
  const envelope =
696
729
  await this.transport.request<DeleteProjectPromptLabelResult>(
697
730
  "DELETE",
698
- getProjectPromptLabelPath(input.projectId, input.label),
731
+ getProjectPromptLabelPath(projectId, input.label),
699
732
  );
700
733
  return unwrap(envelope);
701
734
  }
@@ -714,7 +747,7 @@ export class PromptResource<F extends RenderFormat | undefined = undefined> {
714
747
  const envelope =
715
748
  await this.transport.request<ListProjectPromptLabelUsagesResult>(
716
749
  "GET",
717
- `${getProjectPromptLabelPath(input.projectId, input.label)}/usages`,
750
+ `${getProjectPromptLabelPath(this.resolveProjectId(input.projectId), input.label)}/usages`,
718
751
  );
719
752
  return unwrap(envelope);
720
753
  }
@@ -739,7 +772,9 @@ export class PromptResource<F extends RenderFormat | undefined = undefined> {
739
772
  async listLabelEvents(
740
773
  input: ListLabelEventsInput,
741
774
  ): Promise<ListLabelEventsResult> {
742
- const projectSeg = encodeURIComponent(input.projectId);
775
+ const projectSeg = encodeURIComponent(
776
+ this.resolveProjectId(input.projectId),
777
+ );
743
778
  let path: string;
744
779
  switch (input.scope) {
745
780
  case "label":
@@ -86,7 +86,7 @@ export interface PaginatedResult<T> {
86
86
  }
87
87
 
88
88
  export interface CreatePromptInput {
89
- projectId: string;
89
+ projectId?: string;
90
90
  name: string;
91
91
  slug: string;
92
92
  description?: string;
@@ -96,7 +96,7 @@ export interface CreatePromptInput {
96
96
  export type CreatePromptResult = Prompt;
97
97
 
98
98
  export interface ListPromptsInput {
99
- projectId: string;
99
+ projectId?: string;
100
100
  status?: PromptStatus;
101
101
  sortBy?: "createdAt" | "updatedAt" | "name";
102
102
  tags?: string;
@@ -107,14 +107,14 @@ export interface ListPromptsInput {
107
107
  export type ListPromptsResult = Prompt;
108
108
 
109
109
  export interface GetPromptInput {
110
- projectId: string;
110
+ projectId?: string;
111
111
  promptId: string;
112
112
  }
113
113
 
114
114
  export type GetPromptResult = Prompt;
115
115
 
116
116
  export interface UpdatePromptInput {
117
- projectId: string;
117
+ projectId?: string;
118
118
  promptId: string;
119
119
  name?: string;
120
120
  description?: string | null;
@@ -124,14 +124,14 @@ export interface UpdatePromptInput {
124
124
  export type UpdatePromptResult = Prompt;
125
125
 
126
126
  export interface ArchivePromptInput {
127
- projectId: string;
127
+ projectId?: string;
128
128
  promptId: string;
129
129
  }
130
130
 
131
131
  export type ArchivePromptResult = Prompt;
132
132
 
133
133
  export interface CreatePromptVersionInput {
134
- projectId: string;
134
+ projectId?: string;
135
135
  promptId: string;
136
136
  format: PromptFormat;
137
137
  templateJson: unknown;
@@ -143,14 +143,14 @@ export interface CreatePromptVersionInput {
143
143
  export type CreatePromptVersionResult = PromptVersion;
144
144
 
145
145
  export interface ListPromptVersionsInput {
146
- projectId: string;
146
+ projectId?: string;
147
147
  promptId: string;
148
148
  }
149
149
 
150
150
  export type ListPromptVersionsResult = PromptVersion[];
151
151
 
152
152
  export interface GetPromptVersionInput {
153
- projectId: string;
153
+ projectId?: string;
154
154
  promptId: string;
155
155
  versionNumber: number;
156
156
  }
@@ -158,7 +158,7 @@ export interface GetPromptVersionInput {
158
158
  export type GetPromptVersionResult = PromptVersion;
159
159
 
160
160
  export interface MovePromptLabelInput {
161
- projectId: string;
161
+ projectId?: string;
162
162
  promptId: string;
163
163
  label: string;
164
164
  versionId: string;
@@ -168,7 +168,7 @@ export interface MovePromptLabelInput {
168
168
  export type MovePromptLabelResult = PromptLabelPointer;
169
169
 
170
170
  export interface ListPromptLabelsInput {
171
- projectId: string;
171
+ projectId?: string;
172
172
  promptId: string;
173
173
  }
174
174
 
@@ -257,7 +257,7 @@ export type ProjectPromptLabelUsage = GenProjectPromptLabelUsage;
257
257
  export type PromptLabelEvent = GenPromptLabelEvent;
258
258
 
259
259
  export interface ListProjectPromptLabelsInput {
260
- projectId: string;
260
+ projectId?: string;
261
261
  /** Set true to include archived (soft-deleted) entries. Default: false. */
262
262
  includeArchived?: boolean;
263
263
  }
@@ -265,7 +265,7 @@ export interface ListProjectPromptLabelsInput {
265
265
  export type ListProjectPromptLabelsResult = ProjectPromptLabel[];
266
266
 
267
267
  export interface CreateProjectPromptLabelInput {
268
- projectId: string;
268
+ projectId?: string;
269
269
  label: string;
270
270
  isDefault?: boolean;
271
271
  description?: string;
@@ -275,14 +275,14 @@ export interface CreateProjectPromptLabelInput {
275
275
  export type CreateProjectPromptLabelResult = ProjectPromptLabel;
276
276
 
277
277
  export interface GetProjectPromptLabelInput {
278
- projectId: string;
278
+ projectId?: string;
279
279
  label: string;
280
280
  }
281
281
 
282
282
  export type GetProjectPromptLabelResult = ProjectPromptLabel;
283
283
 
284
284
  export interface UpdateProjectPromptLabelInput {
285
- projectId: string;
285
+ projectId?: string;
286
286
  label: string;
287
287
  isDefault?: boolean;
288
288
  description?: string | null;
@@ -292,14 +292,14 @@ export interface UpdateProjectPromptLabelInput {
292
292
  export type UpdateProjectPromptLabelResult = ProjectPromptLabel;
293
293
 
294
294
  export interface DeleteProjectPromptLabelInput {
295
- projectId: string;
295
+ projectId?: string;
296
296
  label: string;
297
297
  }
298
298
 
299
299
  export type DeleteProjectPromptLabelResult = ProjectPromptLabel;
300
300
 
301
301
  export interface ListProjectPromptLabelUsagesInput {
302
- projectId: string;
302
+ projectId?: string;
303
303
  label: string;
304
304
  }
305
305
 
@@ -308,7 +308,7 @@ export type ListProjectPromptLabelUsagesResult = ProjectPromptLabelUsage[];
308
308
  export type ListLabelEventsInput =
309
309
  | {
310
310
  scope: "label";
311
- projectId: string;
311
+ projectId?: string;
312
312
  promptId: string;
313
313
  label: string;
314
314
  page?: number;
@@ -318,7 +318,7 @@ export type ListLabelEventsInput =
318
318
  }
319
319
  | {
320
320
  scope: "prompt";
321
- projectId: string;
321
+ projectId?: string;
322
322
  promptId: string;
323
323
  label?: string;
324
324
  page?: number;
@@ -328,7 +328,7 @@ export type ListLabelEventsInput =
328
328
  }
329
329
  | {
330
330
  scope: "project";
331
- projectId: string;
331
+ projectId?: string;
332
332
  promptId?: string;
333
333
  label?: string;
334
334
  page?: number;