@truefoundry/assistant-ui-runtime 0.1.10 → 0.1.12

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.
@@ -7,10 +7,10 @@
7
7
  */
8
8
 
9
9
  import type {
10
- ActionRequiredEvent,
11
- SessionEventItem,
12
- TurnEvent,
13
- TurnStreamData
10
+ ActionRequiredEvent,
11
+ SessionEventItem,
12
+ TurnEvent,
13
+ TurnStreamData
14
14
  } from "./events.js";
15
15
 
16
16
  // ---------------------------------------------------------------------------
@@ -19,38 +19,44 @@ import type {
19
19
 
20
20
  /** Model selector row. Host extends for apiModel, modelId, pricing, etc. */
21
21
  export interface ModelSelectorEntry {
22
- name: string;
23
- provider: string;
24
- reasoningEfforts?: string[];
22
+ name: string;
23
+ provider: string;
24
+ reasoningEfforts?: string[];
25
+ /** Provider logo URL from the model catalog; selector falls back to a monogram when omitted. */
26
+ providerLogo?: string;
25
27
  }
26
28
 
27
29
  /** Skill selector row. Host extends for fqn, preload, etc. */
28
30
  export interface SkillSelectorEntry {
29
- id: string;
30
- name: string;
31
- description?: string;
31
+ id: string;
32
+ name: string;
33
+ description?: string;
32
34
  }
33
35
 
34
36
  /** MCP connector selector row. Host extends for type, enableTools, url, etc. */
35
37
  export interface ConnectorSelectorEntry {
36
- id: string;
37
- name: string;
38
- description?: string;
38
+ id: string;
39
+ name: string;
40
+ description?: string;
41
+ /** When true, the connector must be authenticated before use. Omitted when the host does not report auth. */
42
+ requiresAuth?: boolean;
43
+ /** When true, the connector is already authenticated. Omitted when the host does not report auth. */
44
+ authenticated?: boolean;
39
45
  }
40
46
 
41
47
  /** Agent selector row. Host extends for metadata; `agentSpec` enables Edit. */
42
48
  export interface AgentSelectorEntry {
43
- name: string;
44
- /** Stable id when distinct from display `name`. Falls back to `name` when omitted. */
45
- agentId?: string;
46
- /** Published agent spec — required for Edit; optional for Try-only hosts. */
47
- agentSpec?: AgentSpec;
49
+ name: string;
50
+ /** Stable id when distinct from display `name`. Falls back to `name` when omitted. */
51
+ agentId?: string;
52
+ /** Published agent spec — required for Edit; optional for Try-only hosts. */
53
+ agentSpec?: AgentSpec;
48
54
  }
49
55
 
50
56
  export type SearchAgentSelectorParams = {
51
- query?: string;
52
- limit?: number;
53
- offset?: number;
57
+ query?: string;
58
+ limit?: number;
59
+ offset?: number;
54
60
  };
55
61
 
56
62
  // ---------------------------------------------------------------------------
@@ -58,19 +64,19 @@ export type SearchAgentSelectorParams = {
58
64
  // ---------------------------------------------------------------------------
59
65
 
60
66
  /**
61
- * Mounts written to AgentSpec.skills[] / AgentSpec.mcpServers[].
62
- *
63
- * These are opaque to the runtime — it stores and forwards them but never reads
64
- * a field, and the backend owns the shape (the gateway identifies a skill by
65
- * `fqn`, with no `id` or `name` anywhere). So the base constrains only that a
66
- * mount is an object; hosts intersect their concrete mount type over it, as
67
- * `TfySkillMount` / `TfyMcpServerMount` do in the gateway adapter.
68
- *
69
- * Naming a field here would not just be unread, it would be wrong: a base with
70
- * required fields rejects the backend's own payloads, and one with only optional
71
- * fields is a weak type, which TypeScript rejects for a source that shares no
72
- * property with it — the gateway's registry skill shares none.
73
- */
67
+ * Mounts written to AgentSpec.skills[] / AgentSpec.mcpServers[].
68
+ *
69
+ * These are opaque to the runtime — it stores and forwards them but never reads
70
+ * a field, and the backend owns the shape (the gateway identifies a skill by
71
+ * `fqn`, with no `id` or `name` anywhere). So the base constrains only that a
72
+ * mount is an object; hosts intersect their concrete mount type over it, as
73
+ * `TfySkillMount` / `TfyMcpServerMount` do in the gateway adapter.
74
+ *
75
+ * Naming a field here would not just be unread, it would be wrong: a base with
76
+ * required fields rejects the backend's own payloads, and one with only optional
77
+ * fields is a weak type, which TypeScript rejects for a source that shares no
78
+ * property with it — the gateway's registry skill shares none.
79
+ */
74
80
  export type SkillMount = object;
75
81
 
76
82
  export type McpServerMount = object;
@@ -80,30 +86,30 @@ export type McpServerMount = object;
80
86
  // ---------------------------------------------------------------------------
81
87
 
82
88
  export interface ModelParams {
83
- maxTokens?: number;
84
- reasoningEffort?: string;
89
+ maxTokens?: number;
90
+ reasoningEffort?: string;
85
91
  }
86
92
 
87
93
  export interface Model {
88
- name: string;
89
- params?: ModelParams;
94
+ name: string;
95
+ params?: ModelParams;
90
96
  }
91
97
 
92
98
  /**
93
- * SDK-owned agent definition — fields the FE reads/writes.
94
- * Host widens `model` / `skills` / `mcpServers` via type params, and adds
95
- * extra fields via `TSpec extends AgentSpec<...>`.
96
- */
99
+ * SDK-owned agent definition — fields the FE reads/writes.
100
+ * Host widens `model` / `skills` / `mcpServers` via type params, and adds
101
+ * extra fields via `TSpec extends AgentSpec<...>`.
102
+ */
97
103
  export interface AgentSpec<
98
- TModel extends Model = Model,
99
- TSkill extends SkillMount = SkillMount,
100
- TMcp extends McpServerMount = McpServerMount,
104
+ TModel extends Model = Model,
105
+ TSkill extends SkillMount = SkillMount,
106
+ TMcp extends McpServerMount = McpServerMount,
101
107
  > {
102
- model: TModel;
103
- skills?: TSkill[];
104
- mcpServers?: TMcp[];
105
- instructions?: string;
106
- variables?: Record<string, string>;
108
+ model: TModel;
109
+ skills?: TSkill[];
110
+ mcpServers?: TMcp[];
111
+ instructions?: string;
112
+ variables?: Record<string, string>;
107
113
  }
108
114
 
109
115
  // ---------------------------------------------------------------------------
@@ -111,26 +117,26 @@ export interface AgentSpec<
111
117
  // ---------------------------------------------------------------------------
112
118
 
113
119
  export interface Session<TSpec extends AgentSpec = AgentSpec> {
114
- id: string;
115
- title?: string | null;
116
- agentName?: string | null;
117
- agentSpec?: TSpec;
118
- /** true → mutable builder + updateSession(spec) allowed. */
119
- isMutable: boolean;
120
- createdAt: string;
121
- updatedAt: string;
120
+ id: string;
121
+ title?: string | null;
122
+ agentName?: string | null;
123
+ agentSpec?: TSpec;
124
+ /** true → mutable builder + updateSession(spec) allowed. */
125
+ isMutable: boolean;
126
+ createdAt: string;
127
+ updatedAt: string;
122
128
  }
123
129
 
124
130
  export interface CreateSessionRequest<TSpec extends AgentSpec = AgentSpec> {
125
- agentName?: string;
126
- agentSpec?: TSpec;
127
- title?: string;
131
+ agentName?: string;
132
+ agentSpec?: TSpec;
133
+ title?: string;
128
134
  }
129
135
 
130
136
  export interface UpdateSessionRequest<TSpec extends AgentSpec = AgentSpec> {
131
- sessionId: string;
132
- agentSpec?: TSpec;
133
- title?: string;
137
+ sessionId: string;
138
+ agentSpec?: TSpec;
139
+ title?: string;
134
140
  }
135
141
 
136
142
  // ---------------------------------------------------------------------------
@@ -138,98 +144,98 @@ export interface UpdateSessionRequest<TSpec extends AgentSpec = AgentSpec> {
138
144
  // ---------------------------------------------------------------------------
139
145
 
140
146
  export interface ListResult<T> {
141
- data: T[];
142
- nextPageToken?: string;
147
+ data: T[];
148
+ nextPageToken?: string;
143
149
  }
144
150
 
145
151
  export type ListSessionsOrder = "asc" | "desc";
146
152
 
147
153
  export type PageParams = {
148
- limit?: number;
149
- order?: ListSessionsOrder;
150
- pageToken?: string;
154
+ limit?: number;
155
+ order?: ListSessionsOrder;
156
+ pageToken?: string;
151
157
  };
152
158
 
153
159
  export interface ListSessionsParams extends PageParams {
154
- /** Host-owned agent identity filter. Hosts that key agents by name pass that name here. */
155
- agentId?: string;
156
- /** Host-specific filter (e.g. TFY startTimestamp). */
157
- startTimestamp?: string;
160
+ /** Host-owned agent identity filter. Hosts that key agents by name pass that name here. */
161
+ agentId?: string;
162
+ /** Host-specific filter (e.g. TFY startTimestamp). */
163
+ startTimestamp?: string;
158
164
  }
159
165
 
160
- export type PreviousTurnIdInput = "auto" | string;
166
+ export type PreviousTurnIdInput = "auto" | "none" | string;
161
167
 
162
168
  // ---------------------------------------------------------------------------
163
169
  // Turn input / state — what runtime sends and reads
164
170
  // ---------------------------------------------------------------------------
165
171
 
166
172
  export type UserMessageContent =
167
- | string
168
- | Array<{ type: "text"; text: string } | { type: "file"; name: string; data: string }>;
173
+ | string
174
+ | Array<{ type: "text"; text: string } | { type: "file"; name: string; data: string }>;
169
175
 
170
176
  export interface UserMessage {
171
- type: "user.message";
172
- content: UserMessageContent;
177
+ type: "user.message";
178
+ content: UserMessageContent;
173
179
  }
174
180
 
175
181
  export type ApprovalDecision =
176
- | { status: "allow" }
177
- | { status: "deny"; reason?: string };
182
+ | { status: "allow" }
183
+ | { status: "deny"; reason?: string };
178
184
 
179
185
  export interface UserToolApprovalEvent {
180
- type: "user.tool_approval";
181
- threadId: string;
182
- toolCallId: string;
183
- approval: ApprovalDecision;
186
+ type: "user.tool_approval";
187
+ threadId: string;
188
+ toolCallId: string;
189
+ approval: ApprovalDecision;
184
190
  }
185
191
 
186
192
  export interface UserToolResponseEvent {
187
- type: "user.tool_response";
188
- threadId: string;
189
- toolCallId: string;
190
- content: string;
193
+ type: "user.tool_response";
194
+ threadId: string;
195
+ toolCallId: string;
196
+ content: string;
191
197
  }
192
198
 
193
199
  export type TurnInputItem =
194
- | UserMessage
195
- | UserToolApprovalEvent
196
- | UserToolResponseEvent;
200
+ | UserMessage
201
+ | UserToolApprovalEvent
202
+ | UserToolResponseEvent;
197
203
 
198
204
  export type TurnStateRunning = { status: "running" };
199
205
 
200
206
  export type TurnStateDone = {
201
- status: "done";
202
- output?: unknown;
203
- requiredActions?: ActionRequiredEvent[];
204
- completedAt: string;
207
+ status: "done";
208
+ output?: unknown;
209
+ requiredActions?: ActionRequiredEvent[];
210
+ completedAt: string;
205
211
  };
206
212
 
207
213
  export type TurnStateCancelled = {
208
- status: "cancelled";
209
- reason: string;
210
- completedAt: string;
214
+ status: "cancelled";
215
+ reason: string;
216
+ completedAt: string;
211
217
  };
212
218
 
213
219
  export type TurnStateError = {
214
- status: "error";
215
- message: string;
216
- completedAt: string;
220
+ status: "error";
221
+ message: string;
222
+ completedAt: string;
217
223
  };
218
224
 
219
225
  export type TurnState =
220
- | TurnStateRunning
221
- | TurnStateDone
222
- | TurnStateCancelled
223
- | TurnStateError;
226
+ | TurnStateRunning
227
+ | TurnStateDone
228
+ | TurnStateCancelled
229
+ | TurnStateError;
224
230
 
225
231
  /** Plain turn DTO — no methods. */
226
232
  export interface Turn {
227
- id: string;
228
- sessionId: string;
229
- previousTurnId?: string | null;
230
- input?: TurnInputItem[];
231
- state: TurnState;
232
- createdAt: string;
233
+ id: string;
234
+ sessionId: string;
235
+ previousTurnId?: string | null;
236
+ input?: TurnInputItem[];
237
+ state: TurnState;
238
+ createdAt: string;
233
239
  }
234
240
 
235
241
  // ---------------------------------------------------------------------------
@@ -237,99 +243,115 @@ export interface Turn {
237
243
  // ---------------------------------------------------------------------------
238
244
 
239
245
  /**
240
- * Chat / session port — the runtime calls these.
241
- *
242
- * All session ops are flat (sessionId param). No gateway client dependency.
243
- * `createTrueFoundryServer` is one possible implementation (TFY adapter).
244
- */
246
+ * Chat / session port — the runtime calls these.
247
+ *
248
+ * All session ops are flat (sessionId param). No gateway client dependency.
249
+ * `createTrueFoundryServer` is one possible implementation (TFY adapter).
250
+ */
245
251
  export interface AgentChatServer<
246
- TSpec extends AgentSpec = AgentSpec,
247
- TSession extends Session<TSpec> = Session<TSpec>,
248
- TCreate extends CreateSessionRequest<TSpec> = CreateSessionRequest<TSpec>,
249
- TList extends ListSessionsParams = ListSessionsParams,
250
- TUpdate extends UpdateSessionRequest<TSpec> = UpdateSessionRequest<TSpec>,
251
- TTurn extends Turn = Turn,
252
+ TSpec extends AgentSpec = AgentSpec,
253
+ TSession extends Session<TSpec> = Session<TSpec>,
254
+ TCreate extends CreateSessionRequest<TSpec> = CreateSessionRequest<TSpec>,
255
+ TList extends ListSessionsParams = ListSessionsParams,
256
+ TUpdate extends UpdateSessionRequest<TSpec> = UpdateSessionRequest<TSpec>,
257
+ TTurn extends Turn = Turn,
252
258
  > {
253
- createSession(req: TCreate): Promise<TSession>;
254
- listSessions(req?: TList): Promise<ListResult<TSession>>;
255
- getSession(req: { sessionId: string }): Promise<TSession>;
256
- updateSession(req: TUpdate): Promise<TSession>;
257
-
258
- createTurn(req: {
259
- sessionId: string;
260
- input?: TurnInputItem[];
261
- previousTurnId?: PreviousTurnIdInput;
262
- abortSignal?: AbortSignal;
263
- headers?: Record<string, string>;
264
- }): AsyncIterable<TurnStreamData>;
265
-
266
- cancelSession(req: { sessionId: string }): Promise<void>;
267
- deleteSession?(req: { sessionId: string }): Promise<void>;
268
-
269
- listTurns(req: {
270
- sessionId: string;
271
- limit?: number;
272
- pageToken?: string;
273
- order?: ListSessionsOrder;
274
- }): Promise<ListResult<TTurn>>;
275
- getTurn(req: { sessionId: string; turnId: string }): Promise<TTurn>;
276
- listEvents(req: {
277
- sessionId: string;
278
- pageToken?: string;
279
- lastTurnId?: string;
280
- limit?: number;
281
- }): Promise<ListResult<SessionEventItem>>;
282
-
283
- /** Optional per-turn event listing (hydrate in-flight turn content). */
284
- listTurnEvents?(req: {
285
- sessionId: string;
286
- turnId: string;
287
- limit?: number;
288
- pageToken?: string;
289
- order?: ListSessionsOrder;
290
- }): Promise<ListResult<TurnEvent>>;
291
-
292
- subscribeToTurn?(req: {
293
- sessionId: string;
294
- turnId: string;
295
- afterSequenceNumber?: number;
296
- abortSignal?: AbortSignal;
297
- }): AsyncIterable<TurnStreamData>;
298
-
299
- /**
300
- * Reads a file the agent wrote inside its sandbox. Hosts whose download route is scoped to a
301
- * turn resolve the sandbox from `turnId` and ignore `sandboxId`; hosts addressing sandboxes
302
- * directly use `sandboxId`.
303
- */
304
- downloadSandboxFile?(req: {
305
- sessionId: string;
306
- turnId: string;
307
- sandboxId: string;
308
- path: string;
309
- }): Promise<Blob>;
259
+ createSession(req: TCreate): Promise<TSession>;
260
+ listSessions(req?: TList): Promise<ListResult<TSession>>;
261
+ getSession(req: { sessionId: string }): Promise<TSession>;
262
+ updateSession(req: TUpdate): Promise<TSession>;
263
+
264
+ createTurn(req: {
265
+ sessionId: string;
266
+ input?: TurnInputItem[];
267
+ previousTurnId?: PreviousTurnIdInput;
268
+ abortSignal?: AbortSignal;
269
+ headers?: Record<string, string>;
270
+ }): AsyncIterable<TurnStreamData>;
271
+
272
+ cancelSession(req: { sessionId: string }): Promise<void>;
273
+ deleteSession?(req: { sessionId: string }): Promise<void>;
274
+
275
+ listTurns(req: {
276
+ sessionId: string;
277
+ limit?: number;
278
+ pageToken?: string;
279
+ order?: ListSessionsOrder;
280
+ }): Promise<ListResult<TTurn>>;
281
+ getTurn(req: { sessionId: string; turnId: string }): Promise<TTurn>;
282
+ listEvents(req: {
283
+ sessionId: string;
284
+ pageToken?: string;
285
+ lastTurnId?: string;
286
+ limit?: number;
287
+ }): Promise<ListResult<SessionEventItem>>;
288
+
289
+ /** Optional per-turn event listing (hydrate in-flight turn content). */
290
+ listTurnEvents?(req: {
291
+ sessionId: string;
292
+ turnId: string;
293
+ limit?: number;
294
+ pageToken?: string;
295
+ order?: ListSessionsOrder;
296
+ }): Promise<ListResult<TurnEvent>>;
297
+
298
+ subscribeToTurn?(req: {
299
+ sessionId: string;
300
+ turnId: string;
301
+ afterSequenceNumber?: number;
302
+ abortSignal?: AbortSignal;
303
+ }): AsyncIterable<TurnStreamData>;
304
+
305
+ /**
306
+ * Reads a file the agent wrote inside its sandbox. Hosts whose download route is scoped to a
307
+ * turn resolve the sandbox from `turnId` and ignore `sandboxId`; hosts addressing sandboxes
308
+ * directly use `sandboxId`.
309
+ */
310
+ downloadSandboxFile?(req: {
311
+ sessionId: string;
312
+ turnId: string;
313
+ sandboxId: string;
314
+ path: string;
315
+ }): Promise<Blob>;
316
+ }
317
+
318
+ /** Request body for `AgentBuilderServer.saveAgent`. */
319
+ export interface SaveAgentRequest<TSpec extends AgentSpec = AgentSpec> {
320
+ agentName: string;
321
+ agentSpec: TSpec;
310
322
  }
311
323
 
312
324
  /**
313
- * Builder catalog + persist port — atoms call these.
314
- * Passed separately from the runtime's chat server.
325
+ * Builder feature flags — atoms gate sandbox / skill / settings surfaces on these.
315
326
  */
327
+ export interface AgentBuilderCapabilitiesResponse {
328
+ data: {
329
+ sandbox: { enabled: boolean };
330
+ skill: { enabled: boolean; reason?: string };
331
+ settings?: { enabled: boolean };
332
+ };
333
+ }
334
+
335
+ /**
336
+ * Builder catalog + persist port — atoms call these.
337
+ * Passed separately from the runtime's chat server.
338
+ */
316
339
  export interface AgentBuilderServer<
317
- TSpec extends AgentSpec = AgentSpec,
318
- TModel extends ModelSelectorEntry = ModelSelectorEntry,
319
- TSkill extends SkillSelectorEntry = SkillSelectorEntry,
320
- TMcp extends ConnectorSelectorEntry = ConnectorSelectorEntry,
321
- TAgent extends AgentSelectorEntry = AgentSelectorEntry,
322
- TSave = unknown,
340
+ TSpec extends AgentSpec = AgentSpec,
341
+ TModel extends ModelSelectorEntry = ModelSelectorEntry,
342
+ TSkill extends SkillSelectorEntry = SkillSelectorEntry,
343
+ TMcp extends ConnectorSelectorEntry = ConnectorSelectorEntry,
344
+ TAgent extends AgentSelectorEntry = AgentSelectorEntry,
345
+ TSave = unknown,
346
+ TCapabilities extends AgentBuilderCapabilitiesResponse = AgentBuilderCapabilitiesResponse,
323
347
  > {
324
- getModels(): Promise<TModel[]>;
325
- getSkills(): Promise<TSkill[]>;
326
- getMcp(): Promise<TMcp[]>;
327
- searchAgents(req?: SearchAgentSelectorParams): Promise<TAgent[]>;
328
- saveAgent(req: {
329
- agentName: string;
330
- agentSpec: TSpec;
331
- }): Promise<TSave>;
332
- deleteAgent?(req: { agentName: string }): Promise<void>;
348
+ getCapabilities(): Promise<TCapabilities>;
349
+ getModels(): Promise<TModel[]>;
350
+ getSkills(): Promise<TSkill[]>;
351
+ getMcp(): Promise<TMcp[]>;
352
+ searchAgents(req?: SearchAgentSelectorParams): Promise<TAgent[]>;
353
+ saveAgent(req: SaveAgentRequest<TSpec>): Promise<TSave>;
354
+ deleteAgent?(req: { agentName: string }): Promise<void>;
333
355
  }
334
356
 
335
357
  // ---------------------------------------------------------------------------
@@ -337,88 +359,90 @@ export interface AgentBuilderServer<
337
359
  // ---------------------------------------------------------------------------
338
360
 
339
361
  /**
340
- * Provider type id. Reserved literal: `"custom"` for user-defined providers;
341
- * any other string is a builtin (e.g. `"openai"`, `"anthropic"`).
342
- *
343
- * Note: `string | "custom"` is useless in TypeScript (`"custom"` ⊆ `string`),
344
- * so this stays `string` and `"custom"` is a documented convention.
345
- */
362
+ * Provider type id. Reserved literal: `"custom"` for user-defined providers;
363
+ * any other string is a builtin (e.g. `"openai"`, `"anthropic"`).
364
+ *
365
+ * Note: `string | "custom"` is useless in TypeScript (`"custom"` ⊆ `string`),
366
+ * so this stays `string` and `"custom"` is a documented convention.
367
+ */
346
368
  export type ProviderType = string;
347
369
 
348
370
  /**
349
- * Model row — form "Model ID" + "Display name".
350
- * Host extends for properties, etc.
351
- */
371
+ * Model row — form "Model ID" + "Display name".
372
+ * Host extends for properties, etc.
373
+ */
352
374
  export interface ModelEntry {
353
- id: string;
354
- name: string;
375
+ id: string;
376
+ name: string;
355
377
  }
356
378
 
357
379
  /**
358
- * Write config for create/update (custom form + catalog "Save key").
359
- * Host extends. `baseUrl` present iff `type === "custom"`.
360
- */
380
+ * Write config for create/update (custom form + catalog "Save key").
381
+ * Host extends. `baseUrl` present iff `type === "custom"`.
382
+ */
361
383
  export interface ModelProviderConfigBase<TModel extends ModelEntry = ModelEntry> {
362
- type: ProviderType;
363
- name: string;
364
- /** Present iff `type === "custom"`. */
365
- baseUrl?: string;
366
- apiKey: string;
367
- models: TModel[];
384
+ type: ProviderType;
385
+ name: string;
386
+ /** Present iff `type === "custom"`. */
387
+ baseUrl?: string;
388
+ apiKey: string;
389
+ models: TModel[];
368
390
  }
369
391
 
370
392
  /**
371
- * Configured provider card (list/read). No raw `apiKey`.
372
- * Host extends for apiKeySet, timestamps, etc.
373
- */
393
+ * Configured provider card (list/read). No raw `apiKey`.
394
+ * Host extends for apiKeySet, timestamps, etc.
395
+ */
374
396
  export interface ModelProviderBase<TModel extends ModelEntry = ModelEntry> {
375
- id: string;
376
- type: ProviderType;
377
- name: string;
378
- /** Present iff `type === "custom"`. */
379
- baseUrl?: string;
380
- models: TModel[];
397
+ id: string;
398
+ type: ProviderType;
399
+ name: string;
400
+ /** Present iff `type === "custom"`. */
401
+ baseUrl?: string;
402
+ models: TModel[];
381
403
  }
382
404
 
383
405
  /**
384
- * Discovery-only catalog provider (AVAILABLE list).
385
- * `type` must not be `"custom"` — custom providers use the custom form.
386
- * Host extends for richer model rows.
387
- */
406
+ * Discovery-only catalog provider (AVAILABLE list).
407
+ * `type` must not be `"custom"` — custom providers use the custom form.
408
+ * Host extends for richer model rows.
409
+ */
388
410
  export interface ModelProviderCatalogEntry<TModel extends ModelEntry = ModelEntry> {
389
- type: ProviderType;
390
- name: string;
391
- models: TModel[];
411
+ type: ProviderType;
412
+ name: string;
413
+ models: TModel[];
414
+ supportedReasoningEfforts?: string[];
415
+ logo?: string;
392
416
  }
393
417
 
394
418
  /** Create — no `id`; server assigns it. Catalog path = entry + apiKey. */
395
419
  export type CreateModelProviderRequest<TModel extends ModelEntry = ModelEntry> =
396
- ModelProviderConfigBase<TModel>;
420
+ ModelProviderConfigBase<TModel>;
397
421
 
398
422
  /** Update — `id` required. */
399
423
  export type UpdateModelProviderRequest<TModel extends ModelEntry = ModelEntry> =
400
- ModelProviderConfigBase<TModel> & { id: string };
424
+ ModelProviderConfigBase<TModel> & { id: string };
401
425
 
402
426
  export interface ModelCatalogServer<
403
- TModel extends ModelEntry = ModelEntry,
404
- TProvider extends ModelProviderBase<TModel> = ModelProviderBase<TModel>,
405
- TCatalogProvider extends ModelProviderCatalogEntry<TModel> = ModelProviderCatalogEntry<TModel>,
406
- TCreate extends CreateModelProviderRequest<TModel> = CreateModelProviderRequest<TModel>,
407
- TUpdate extends UpdateModelProviderRequest<TModel> = UpdateModelProviderRequest<TModel>,
427
+ TModel extends ModelEntry = ModelEntry,
428
+ TProvider extends ModelProviderBase<TModel> = ModelProviderBase<TModel>,
429
+ TCatalogProvider extends ModelProviderCatalogEntry<TModel> = ModelProviderCatalogEntry<TModel>,
430
+ TCreate extends CreateModelProviderRequest<TModel> = CreateModelProviderRequest<TModel>,
431
+ TUpdate extends UpdateModelProviderRequest<TModel> = UpdateModelProviderRequest<TModel>,
408
432
  > {
409
- getModelProviderCatalog(): Promise<TCatalogProvider[]>;
410
- listModelProviders(): Promise<TProvider[]>;
411
- createModelProvider(req: TCreate): Promise<TProvider>;
412
- /** Full replace update keyed by provider `id`. */
413
- updateModelProvider(req: TUpdate): Promise<TProvider>;
414
- deleteModelProvider?(req: { id: string }): Promise<void>;
433
+ getModelProviderCatalog(): Promise<TCatalogProvider[]>;
434
+ listModelProviders(): Promise<TProvider[]>;
435
+ createModelProvider(req: TCreate): Promise<TProvider>;
436
+ /** Full replace update keyed by provider `id`. */
437
+ updateModelProvider(req: TUpdate): Promise<TProvider>;
438
+ deleteModelProvider?(req: { id: string }): Promise<void>;
415
439
  }
416
440
 
417
441
  /** Tool row on a connector detail. Host extends for schemas, etc. */
418
442
  export interface ToolBase {
419
- id: string;
420
- name: string;
421
- description: string;
443
+ id: string;
444
+ name: string;
445
+ description: string;
422
446
  }
423
447
 
424
448
  /** Strict auth type id. Hosts widen branches via intersection + re-union. */
@@ -427,105 +451,121 @@ export type ConnectorAuthType = "dcr" | "header" | "none";
427
451
  // Write (create/update) — export branches so hosts can intersect extras
428
452
  export type ConnectorAuthOAuth = { type: "dcr"; authUrl?: string };
429
453
  export type ConnectorAuthApiKey = {
430
- type: "header";
431
- apiKey?: string;
432
- headerName?: string;
454
+ type: "header";
455
+ apiKey?: string;
456
+ headerName?: string;
433
457
  };
434
458
  export type ConnectorAuthNone = { type: "none" };
435
459
  export type ConnectorAuth =
436
- | ConnectorAuthOAuth
437
- | ConnectorAuthApiKey
438
- | ConnectorAuthNone;
460
+ | ConnectorAuthOAuth
461
+ | ConnectorAuthApiKey
462
+ | ConnectorAuthNone;
439
463
 
440
- // Public (list/detail) — no secrets; dcr requires authUrl
441
- export type ConnectorAuthPublicOAuth = { type: "dcr"; authUrl: string };
464
+ // Public (list/detail) — no secrets
465
+ export type ConnectorAuthPublicOAuth = { type: "dcr"; authUrl?: string };
442
466
  export type ConnectorAuthPublicApiKey = {
443
- type: "header";
444
- headerName?: string;
467
+ type: "header";
468
+ headerName?: string;
445
469
  };
446
470
  export type ConnectorAuthPublicNone = { type: "none" };
447
471
  export type ConnectorAuthPublic =
448
- | ConnectorAuthPublicOAuth
449
- | ConnectorAuthPublicApiKey
450
- | ConnectorAuthPublicNone;
472
+ | ConnectorAuthPublicOAuth
473
+ | ConnectorAuthPublicApiKey
474
+ | ConnectorAuthPublicNone;
451
475
 
452
476
  /**
453
- * MCP / connector create-edit config. Host extends for extra fields, etc.
454
- */
477
+ * MCP / connector create-edit config. Host extends for extra fields, etc.
478
+ */
455
479
  export interface ConnectorConfigBase<
456
- TAuth extends ConnectorAuth = ConnectorAuth,
480
+ TAuth extends ConnectorAuth = ConnectorAuth,
457
481
  > {
458
- name: string;
459
- url: string;
460
- auth: TAuth;
482
+ name: string;
483
+ url: string;
484
+ auth: TAuth;
461
485
  }
462
486
 
463
487
  /**
464
- * Connected connector row (settings/connectors). No raw `apiKey`.
488
+ * Connected connector row (settings/connectors). No raw `apiKey` or tools.
489
+ * Tools are fetched separately with `getToolsByConnectorId`.
465
490
  * Host extends.
466
491
  */
467
492
  export interface ConnectorBase<
468
- TTool extends ToolBase = ToolBase,
469
- TAuth extends ConnectorAuthPublic = ConnectorAuthPublic,
493
+ TAuth extends ConnectorAuthPublic = ConnectorAuthPublic,
470
494
  > {
471
- id: string;
472
- name: string;
473
- description: string;
474
- url: string;
475
- auth: TAuth;
476
- /** When true, UI should not show Disconnect. */
477
- requiresAuth: boolean;
478
- authenticated: boolean;
479
- tools: TTool[];
495
+ id: string;
496
+ name: string;
497
+ description: string;
498
+ url: string;
499
+ auth: TAuth;
500
+ /** When true, UI should not show Disconnect. */
501
+ requiresAuth: boolean;
502
+ authenticated: boolean;
480
503
  }
481
504
 
482
505
  /** Discovery catalog entry for "+ Add MCP server". Host extends. */
483
506
  export interface ConnectorCatalogEntry<
484
- TAuth extends ConnectorAuthPublic = ConnectorAuthPublic,
507
+ TAuth extends ConnectorAuthPublic = ConnectorAuthPublic,
485
508
  > {
486
- id: string;
487
- name: string;
488
- description?: string;
489
- url: string;
490
- auth: TAuth;
509
+ id: string;
510
+ name: string;
511
+ description?: string;
512
+ url: string;
513
+ auth: TAuth;
514
+ logo?: string;
491
515
  }
492
516
 
493
517
  /** Create connector — no `id`; server assigns it. Host extends. */
494
518
  export type CreateConnectorRequest<TAuth extends ConnectorAuth = ConnectorAuth> =
495
- ConnectorConfigBase<TAuth>;
519
+ ConnectorConfigBase<TAuth>;
496
520
 
497
521
  /** Update connector — `id` required. Host extends. */
498
522
  export type UpdateConnectorRequest<TAuth extends ConnectorAuth = ConnectorAuth> =
499
- ConnectorConfigBase<TAuth> & { id: string };
523
+ ConnectorConfigBase<TAuth> & { id: string };
524
+
525
+ export interface AuthenticateConnectorRequest {
526
+ id: string;
527
+ /** OAuth callback page owned by the host application. */
528
+ redirectURL?: string;
529
+ }
530
+
531
+ export interface ConnectorAuthenticationResult<
532
+ TConnector extends ConnectorBase = ConnectorBase,
533
+ > {
534
+ connector?: TConnector;
535
+ status?: string;
536
+ authorization_endpoint?: string | undefined;
537
+ }
500
538
 
501
539
  export interface ConnectorCatalogServer<
502
- TTool extends ToolBase = ToolBase,
503
- TAuthWrite extends ConnectorAuth = ConnectorAuth,
504
- TAuthPublic extends ConnectorAuthPublic = ConnectorAuthPublic,
505
- TConnector extends ConnectorBase<TTool, TAuthPublic> = ConnectorBase<
506
- TTool,
507
- TAuthPublic
508
- >,
509
- TCatalogEntry extends ConnectorCatalogEntry<TAuthPublic> =
510
- ConnectorCatalogEntry<TAuthPublic>,
511
- TCreate extends CreateConnectorRequest<TAuthWrite> =
512
- CreateConnectorRequest<TAuthWrite>,
513
- TUpdate extends UpdateConnectorRequest<TAuthWrite> =
514
- UpdateConnectorRequest<TAuthWrite>,
540
+ TTool extends ToolBase = ToolBase,
541
+ TAuthWrite extends ConnectorAuth = ConnectorAuth,
542
+ TAuthPublic extends ConnectorAuthPublic = ConnectorAuthPublic,
543
+ TConnector extends ConnectorBase<TAuthPublic> = ConnectorBase<TAuthPublic>,
544
+ TCatalogEntry extends ConnectorCatalogEntry<TAuthPublic> =
545
+ ConnectorCatalogEntry<TAuthPublic>,
546
+ TCreate extends CreateConnectorRequest<TAuthWrite> =
547
+ CreateConnectorRequest<TAuthWrite>,
548
+ TUpdate extends UpdateConnectorRequest<TAuthWrite> =
549
+ UpdateConnectorRequest<TAuthWrite>,
515
550
  > {
516
- getConnectorCatalog(): Promise<TCatalogEntry[]>;
517
- listConnectors(req?: { query?: string }): Promise<TConnector[]>;
518
- createConnector(req: TCreate): Promise<TConnector>;
519
- /** Full replace update keyed by connector `id`. */
520
- updateConnector(req: TUpdate): Promise<TConnector>;
521
- /**
522
- * Start connector auth (e.g. OAuth).
523
- * For oauth, the returned connector's `auth.authUrl` is the authorize URL.
524
- */
525
- authenticateConnector(req: { id: string }): Promise<TConnector>;
526
- /** Clear connector auth. */
527
- disconnectConnector(req: { id: string }): Promise<TConnector>;
528
- deleteConnector?(req: { id: string }): Promise<void>;
551
+ getConnectorCatalog(): Promise<TCatalogEntry[]>;
552
+ getConnector(req: { id: string }): Promise<TConnector>;
553
+ listConnectors(req?: { query?: string }): Promise<TConnector[]>;
554
+ getToolsByConnectorId(req: { id: string }): Promise<TTool[]>;
555
+ createConnector(req: TCreate): Promise<TConnector>;
556
+ /** Full replace update keyed by connector `id`. */
557
+ updateConnector(req: TUpdate): Promise<TConnector>;
558
+ /**
559
+ * Start connector auth (e.g. OAuth).
560
+ * May return a connector (already authenticated / with `auth.authUrl`) or a
561
+ * result carrying `authorization_endpoint` for the popup flow.
562
+ */
563
+ authenticateConnector(
564
+ req: AuthenticateConnectorRequest,
565
+ ): Promise<TConnector | ConnectorAuthenticationResult<TConnector>>;
566
+ /** Clear connector auth. */
567
+ disconnectConnector(req: { id: string }): Promise<TConnector>;
568
+ deleteConnector?(req: { id: string }): Promise<void>;
529
569
  }
530
570
 
531
571
  // ---------------------------------------------------------------------------
@@ -534,14 +574,14 @@ export interface ConnectorCatalogServer<
534
574
 
535
575
  /** Skill row shown in settings/skills (list + delete). Host extends for fqn, etc. */
536
576
  export interface SkillBase {
537
- id: string;
538
- name: string;
539
- description: string;
577
+ id: string;
578
+ name: string;
579
+ description: string;
540
580
  }
541
581
 
542
582
  export interface RegistrySkill extends SkillBase {
543
- /** `SkillCatalogEntry.id` this skill was created from. */
544
- catalogId: string;
583
+ /** `SkillCatalogEntry.id` this skill was created from. */
584
+ catalogId: string;
545
585
  }
546
586
 
547
587
  export interface GithubSkill extends SkillBase {}
@@ -550,124 +590,146 @@ export type DefinedSkill = RegistrySkill | GithubSkill;
550
590
 
551
591
  /** Git source fields shared by catalog entries and create requests. */
552
592
  export interface SkillConfigBase {
553
- name: string;
554
- description: string;
555
- repoURL: string;
556
- path: string;
557
- ref: string;
593
+ name: string;
594
+ description: string;
595
+ repoURL: string;
596
+ path: string;
597
+ ref: string;
558
598
  }
559
599
 
560
600
  export interface SkillCatalogEntry extends SkillConfigBase {
561
- id: string;
601
+ id: string;
562
602
  }
563
603
 
564
604
  /** Create-skill base. Hosts may intersect extra fields and re-union. */
565
605
  export interface CreateSkillRequestBase extends SkillConfigBase {}
566
606
 
567
607
  export interface SelectRegistrySkillRequest extends CreateSkillRequestBase {
568
- /** `SkillCatalogEntry.id`, persisted so the created skill links back to it. */
569
- catalogId: string;
608
+ /** `SkillCatalogEntry.id`, persisted so the created skill links back to it. */
609
+ catalogId: string;
570
610
  }
571
611
 
572
612
  export interface ImportGithubSkillRequest extends CreateSkillRequestBase {}
573
613
 
574
614
  export type CreateSkillRequest =
575
- | SelectRegistrySkillRequest
576
- | ImportGithubSkillRequest;
615
+ | SelectRegistrySkillRequest
616
+ | ImportGithubSkillRequest;
577
617
 
578
618
  export interface SkillCatalogServer<
579
- TSkill extends SkillBase = SkillBase,
580
- TCatalogEntry extends SkillCatalogEntry = SkillCatalogEntry,
581
- TCreate extends CreateSkillRequest = CreateSkillRequest,
619
+ TSkill extends SkillBase = SkillBase,
620
+ TCatalogEntry extends SkillCatalogEntry = SkillCatalogEntry,
621
+ TCreate extends CreateSkillRequest = CreateSkillRequest,
582
622
  > {
583
- getSkillCatalog(): Promise<TCatalogEntry[]>;
584
- listSkills(req?: { query?: string }): Promise<TSkill[]>;
585
- createSkill(req: TCreate): Promise<TSkill>;
586
- deleteSkill?(req: { id: string }): Promise<void>;
623
+ getSkillCatalog(): Promise<TCatalogEntry[]>;
624
+ listSkills(req?: { query?: string }): Promise<TSkill[]>;
625
+ createSkill(req: TCreate): Promise<TSkill>;
626
+ deleteSkill?(req: { id: string }): Promise<void>;
587
627
  }
588
628
 
589
629
  // ---------------------------------------------------------------------------
590
- // Sandboxes catalog — public rows omit credentials; writes accept them
630
+ // Sandbox providers catalog — public rows omit credentials; writes accept them
591
631
  // ---------------------------------------------------------------------------
592
632
 
593
- /** Mutable sandbox settings shared by catalog rows, create, and update. */
633
+ /** Mutable sandbox provider settings shared by catalog rows, create, and update. */
594
634
  export interface SandboxConfig {
595
- snapshotName: string;
596
- execTimeoutMs: number;
597
- autoStopIntervalInMinutes: number;
598
- autoArchiveIntervalInMinutes: number;
599
- autoDeleteIntervalInMinutes: number;
635
+ snapshotName: string;
636
+ execTimeoutMs: number;
637
+ autoStopIntervalInMinutes: number;
638
+ autoArchiveIntervalInMinutes: number;
639
+ autoDeleteIntervalInMinutes: number;
600
640
  }
601
641
 
602
642
  export interface SandboxCatalogEntry extends SandboxConfig {
603
- id: string;
604
- name: string;
605
- type: string;
643
+ id: string;
644
+ name: string;
645
+ type: string;
606
646
  }
607
647
 
608
- export interface SandboxBase {
609
- id: string;
610
- name: string;
611
- catalogId: string;
612
- isConnected: boolean;
648
+ /**
649
+ * Connected sandbox provider row (settings/sandboxes). No raw `apiKey`.
650
+ * Includes last-saved config so update forms can show previous values.
651
+ */
652
+ export interface SandboxBase extends SandboxConfig {
653
+ id: string;
654
+ name: string;
655
+ catalogId: string;
656
+ isConnected: boolean;
613
657
  }
614
658
 
615
659
  export interface CreateSandboxRequest extends SandboxConfig {
616
- /** `SandboxCatalogEntry.id` used to create this sandbox. */
617
- catalogId: string;
618
- name: string;
619
- type: string;
620
- apiKey: string;
660
+ /** `SandboxCatalogEntry.id` used to create this sandbox provider. */
661
+ catalogId: string;
662
+ name: string;
663
+ type: string;
664
+ apiKey: string;
621
665
  }
622
666
 
623
667
  export interface UpdateSandboxRequest extends SandboxConfig {
624
- id: string;
625
- apiKey: string;
668
+ id: string;
669
+ /** Omit to keep the existing key; send a value to rotate. */
670
+ apiKey?: string;
626
671
  }
627
672
 
673
+ /** Host-facing aliases (trueforge-ui public names). */
674
+ export type SandboxProviderConfig = SandboxConfig;
675
+ export type SandboxProviderCatalogEntry = SandboxCatalogEntry;
676
+ export type SandboxProviderBase = SandboxBase;
677
+ export type CreateSandboxProviderRequest = CreateSandboxRequest;
678
+ export type UpdateSandboxProviderRequest = UpdateSandboxRequest;
679
+
628
680
  export interface SandboxCatalogServer<
629
- TSandbox extends SandboxBase = SandboxBase,
630
- TCatalogEntry extends SandboxCatalogEntry = SandboxCatalogEntry,
631
- TCreate extends CreateSandboxRequest = CreateSandboxRequest,
632
- TUpdate extends UpdateSandboxRequest = UpdateSandboxRequest,
681
+ TProvider extends SandboxBase = SandboxBase,
682
+ TCatalogEntry extends SandboxCatalogEntry = SandboxCatalogEntry,
683
+ TCreate extends CreateSandboxRequest = CreateSandboxRequest,
684
+ TUpdate extends UpdateSandboxRequest = UpdateSandboxRequest,
633
685
  > {
634
- getSandboxCatalog(): Promise<TCatalogEntry[]>;
635
- listSandboxes(req?: { query?: string }): Promise<TSandbox[]>;
636
- createSandbox(req: TCreate): Promise<TSandbox>;
637
- updateSandbox(req: TUpdate): Promise<TSandbox>;
638
- deleteSandbox(req: { id: string }): Promise<void>;
686
+ getSandboxProviderCatalog(): Promise<TCatalogEntry[]>;
687
+ listSandboxProviders(req?: { query?: string }): Promise<TProvider[]>;
688
+ createSandboxProvider(req: TCreate): Promise<TProvider>;
689
+ updateSandboxProvider(req: TUpdate): Promise<TProvider>;
690
+ deleteSandboxProvider?(req: { id: string }): Promise<void>;
639
691
  }
640
692
 
693
+ /** Host-facing selector / compose aliases (trueforge-ui public names). */
694
+ export type ModelSelection = ModelSelectorEntry;
695
+ export type AgentSkill = SkillSelectorEntry;
696
+ export type ConnectorState = ConnectorSelectorEntry;
697
+ export type AgentLibraryEntry = AgentSelectorEntry;
698
+ export type SearchAgentsParams = SearchAgentSelectorParams;
699
+
641
700
  /**
642
- * Settings management aggregate — modelCatalog + connectorCatalog + optional
643
- * skill and sandbox catalogs.
644
- * Hosts may pass the whole object to an app shell, or a focused sub-port to a page.
645
- */
701
+ * Settings management aggregate — modelCatalog + connectorCatalog + optional
702
+ * skill and sandbox catalogs.
703
+ * Hosts may pass the whole object to an app shell, or a focused sub-port to a page.
704
+ */
646
705
  export interface CatalogServer<
647
- TModelCatalog extends ModelCatalogServer = ModelCatalogServer,
648
- TConnectorCatalog extends ConnectorCatalogServer = ConnectorCatalogServer,
649
- TSkillCatalog extends SkillCatalogServer = SkillCatalogServer,
650
- TSandboxCatalog extends SandboxCatalogServer = SandboxCatalogServer,
706
+ TModelCatalog extends ModelCatalogServer = ModelCatalogServer,
707
+ TConnectorCatalog extends ConnectorCatalogServer = ConnectorCatalogServer,
708
+ TSkillCatalog extends SkillCatalogServer = SkillCatalogServer,
709
+ TSandboxCatalog extends SandboxCatalogServer = SandboxCatalogServer,
651
710
  > {
652
- modelCatalog: TModelCatalog;
653
- connectorCatalog: TConnectorCatalog;
654
- /** Optional — omit when the host has no skills settings surface. */
655
- skillCatalog?: TSkillCatalog;
656
- /** Optional — omit when the host has no sandboxes settings surface. */
657
- sandboxCatalog?: TSandboxCatalog;
711
+ modelCatalog: TModelCatalog;
712
+ connectorCatalog: TConnectorCatalog;
713
+ /** Optional — omit when the host has no skills settings surface. */
714
+ skillCatalog?: TSkillCatalog;
715
+ /** Optional — omit when the host has no sandboxes settings surface. */
716
+ sandboxCatalog?: TSandboxCatalog;
658
717
  }
659
718
 
660
719
  /**
661
720
  * Composed host port: chat + builder + optional settings catalog.
662
- * Agent-ui's `AgentUIServer` mirrors this shape; named differently here to
663
- * avoid colliding with that package's local type name.
664
721
  *
665
722
  * `catalog` is optional — if the host passes it, settings UI can call
666
723
  * `useCatalogServer()` / show modelCatalog, connectorCatalog, and skillCatalog;
667
724
  * if omitted, those surfaces stay hidden.
725
+ *
726
+ * trueforge-ui re-exports this as `AgentUIServer`.
668
727
  */
669
728
  export type AgentUIServerPort<
670
- TChat extends AgentChatServer = AgentChatServer,
671
- TBuilder extends AgentBuilderServer = AgentBuilderServer,
672
- TCatalog extends CatalogServer = CatalogServer,
729
+ TChat extends AgentChatServer = AgentChatServer,
730
+ TBuilder extends AgentBuilderServer = AgentBuilderServer,
731
+ TCatalog extends CatalogServer = CatalogServer,
673
732
  > = TChat & TBuilder & { catalog?: TCatalog };
733
+
734
+ /** Host-facing alias used by trueforge-ui. */
735
+ export type AgentUIServer = AgentUIServerPort;