@truefoundry/trueforge-assistant-ui-runtime 0.0.0 → 0.2.0-rc.0
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/CHANGELOG.md +9 -0
- package/LICENSE +201 -0
- package/README.md +146 -4
- package/dist/chunk-2SQK6TIO.js +104 -0
- package/dist/chunk-2SQK6TIO.js.map +1 -0
- package/dist/index.d.ts +378 -0
- package/dist/index.js +4391 -0
- package/dist/index.js.map +1 -0
- package/dist/server/index.d.ts +1210 -0
- package/dist/server/index.js +9 -0
- package/dist/server/index.js.map +1 -0
- package/package.json +79 -16
- package/src/askUserQuestion.ts +38 -0
- package/src/attachmentAdapter.ts +63 -0
- package/src/collectPending.ts +167 -0
- package/src/constants.ts +2 -0
- package/src/convertTurnMessages.ts +1679 -0
- package/src/createSubAgent.ts +11 -0
- package/src/draft/agentSpec.ts +34 -0
- package/src/draft/draftSessionBridge.ts +28 -0
- package/src/draft/trueforgeDraftThreadListAdapter.ts +73 -0
- package/src/draft/useDraftAgentSpec.ts +289 -0
- package/src/extractTurnUserText.ts +23 -0
- package/src/foldPeerThreads.ts +553 -0
- package/src/hooks.ts +176 -0
- package/src/index.ts +227 -0
- package/src/lastUserMessageText.ts +19 -0
- package/src/listPages.ts +19 -0
- package/src/loadSessionSnapshot.ts +34 -0
- package/src/mcpAuth.ts +35 -0
- package/src/messageCustomMetadata.ts +50 -0
- package/src/modelMessageContent.ts +149 -0
- package/src/modelMessageImageContent.ts +154 -0
- package/src/requiredActionInputs.ts +38 -0
- package/src/sandboxDownload.ts +33 -0
- package/src/server/eventUtils.ts +125 -0
- package/src/server/events.ts +232 -0
- package/src/server/index.ts +178 -0
- package/src/server/types.ts +1191 -0
- package/src/sessionListStartTimestamp.ts +6 -0
- package/src/sessionSnapshot.ts +146 -0
- package/src/sessionThreadMetadata.ts +36 -0
- package/src/sessions.ts +17 -0
- package/src/streamTurn.ts +118 -0
- package/src/toolApproval.ts +413 -0
- package/src/toolResponse.ts +346 -0
- package/src/trueforgeExtras.ts +223 -0
- package/src/trueforgeOwnedSessionsThreadListAdapter.ts +71 -0
- package/src/trueforgeThreadListAdapter.ts +69 -0
- package/src/turnEventHelpers.ts +71 -0
- package/src/turnStreamUpdate.ts +11 -0
- package/src/types.ts +84 -0
- package/src/useTrueForgeAgentMessages.ts +1138 -0
- package/src/useTrueForgeAgentRuntime.ts +308 -0
- package/index.js +0 -6
|
@@ -0,0 +1,1191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FE-owned AgentUIServer contract.
|
|
3
|
+
*
|
|
4
|
+
* Rule: only methods/fields the runtime or UI invokes.
|
|
5
|
+
* Hosts extend via `T extends Base` for system-specific extras.
|
|
6
|
+
* No dependency on trueforge-gateway-sdk.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { ActionRequiredEvent, SessionEventItem, TurnEvent, TurnStreamData } from './events.js';
|
|
10
|
+
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Catalog — selector rows (SDK-minimal; host extends via generics)
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
export interface ProviderEntry {
|
|
15
|
+
name: string;
|
|
16
|
+
logo?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface ModelProperties {
|
|
20
|
+
reasoningEfforts?: string[];
|
|
21
|
+
contextLength?: number;
|
|
22
|
+
maxOutputTokens?: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Model selector row. Host extends for apiModel, modelId, etc. */
|
|
26
|
+
export interface ModelSelectorEntry<
|
|
27
|
+
TProvider extends ProviderEntry = ProviderEntry,
|
|
28
|
+
TProperties extends ModelProperties = ModelProperties,
|
|
29
|
+
> {
|
|
30
|
+
name: string;
|
|
31
|
+
id: string;
|
|
32
|
+
provider: TProvider;
|
|
33
|
+
properties: TProperties;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Skill selector row. Host extends for fqn, preload, etc. */
|
|
37
|
+
export interface SkillSelectorEntry {
|
|
38
|
+
id: string;
|
|
39
|
+
name: string;
|
|
40
|
+
description?: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** MCP connector selector row. Host extends for type, enableTools, url, etc. */
|
|
44
|
+
export interface ConnectorSelectorEntry {
|
|
45
|
+
id: string;
|
|
46
|
+
name: string;
|
|
47
|
+
description?: string;
|
|
48
|
+
/** When true, the connector must be authenticated before use. Omitted when the host does not report auth. */
|
|
49
|
+
requiresAuth?: boolean;
|
|
50
|
+
/** When true, the connector is already authenticated. Omitted when the host does not report auth. */
|
|
51
|
+
authenticated?: boolean;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Who created a resource. Optional on list DTOs when the host does not track creators. */
|
|
55
|
+
export interface CreatedBySubject {
|
|
56
|
+
subjectId: string;
|
|
57
|
+
subjectType: string;
|
|
58
|
+
subjectDisplayName: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Agent selector row. Host extends for metadata; `agentSpec` enables Edit. */
|
|
62
|
+
export interface AgentSelectorEntry {
|
|
63
|
+
name: string;
|
|
64
|
+
/** Stable id when distinct from display `name`. Falls back to `name` when omitted. */
|
|
65
|
+
agentId?: string;
|
|
66
|
+
/** Published-agent description; not part of the executable agent spec. */
|
|
67
|
+
description?: string;
|
|
68
|
+
/** Published agent spec — required for Edit; optional for Try-only hosts. */
|
|
69
|
+
agentSpec?: AgentSpec;
|
|
70
|
+
/** Creator when the host persists one; omit to hide Created-by UI. */
|
|
71
|
+
createdBySubject?: CreatedBySubject;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface SearchAgentSelectorParams {
|
|
75
|
+
query?: string;
|
|
76
|
+
limit?: number;
|
|
77
|
+
offset?: number;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
// Mounts — neutral SDK base (host extends with backend-specific fields)
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Mounts written to AgentSpec.skills[] / AgentSpec.mcpServers[].
|
|
86
|
+
*
|
|
87
|
+
* These are opaque to the runtime — it stores and forwards them but never reads
|
|
88
|
+
* a field, and the backend owns the shape (the gateway identifies a skill by
|
|
89
|
+
* `fqn`, with no `id` or `name` anywhere). So the base constrains only that a
|
|
90
|
+
* mount is an object; hosts intersect their concrete mount type over it, as
|
|
91
|
+
* `TfySkillMount` / `TfyMcpServerMount` do in the gateway adapter.
|
|
92
|
+
*
|
|
93
|
+
* Naming a field here would not just be unread, it would be wrong: a base with
|
|
94
|
+
* required fields rejects the backend's own payloads, and one with only optional
|
|
95
|
+
* fields is a weak type, which TypeScript rejects for a source that shares no
|
|
96
|
+
* property with it — the gateway's registry skill shares none.
|
|
97
|
+
*/
|
|
98
|
+
export type SkillMount = object;
|
|
99
|
+
|
|
100
|
+
export type McpServerMount = object;
|
|
101
|
+
|
|
102
|
+
// ---------------------------------------------------------------------------
|
|
103
|
+
// AgentSpec — model / skills / mcpServers are type params; host widens the rest
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
|
|
106
|
+
export interface ModelParams {
|
|
107
|
+
maxTokens?: number;
|
|
108
|
+
reasoningEffort?: string;
|
|
109
|
+
temperature?: number;
|
|
110
|
+
topP?: number;
|
|
111
|
+
topK?: number;
|
|
112
|
+
parallelToolCalls?: boolean;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export interface Model {
|
|
116
|
+
name: string;
|
|
117
|
+
params?: ModelParams;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface AgentCapabilityConfig {
|
|
121
|
+
enabled?: boolean;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface AgentSandboxConfig extends AgentCapabilityConfig {
|
|
125
|
+
fileDownloads?: boolean;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface AgentInputTokensCompactionTrigger {
|
|
129
|
+
type: 'input_tokens';
|
|
130
|
+
value: number;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export interface AgentCompactionConfig extends AgentCapabilityConfig {
|
|
134
|
+
trigger?: AgentInputTokensCompactionTrigger;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export interface AgentContextManagementConfig {
|
|
138
|
+
compaction?: AgentCompactionConfig;
|
|
139
|
+
largeToolResponse?: AgentCapabilityConfig;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface AgentRuntimeConfig {
|
|
143
|
+
iterationLimit?: number;
|
|
144
|
+
sandbox?: AgentSandboxConfig;
|
|
145
|
+
contextManagement?: AgentContextManagementConfig;
|
|
146
|
+
generativeUi?: AgentCapabilityConfig;
|
|
147
|
+
dynamicSubAgents?: AgentCapabilityConfig;
|
|
148
|
+
askUserQuestions?: AgentCapabilityConfig;
|
|
149
|
+
webSearch?: AgentCapabilityConfig;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* SDK-owned agent definition — fields the FE reads/writes.
|
|
154
|
+
* Host widens `model` / `skills` / `mcpServers` / `config` via type params,
|
|
155
|
+
* and adds extra fields via `TSpec extends AgentSpec<...>`.
|
|
156
|
+
*/
|
|
157
|
+
export interface AgentSpec<
|
|
158
|
+
TModel extends Model = Model,
|
|
159
|
+
TSkill extends SkillMount = SkillMount,
|
|
160
|
+
TMcp extends McpServerMount = McpServerMount,
|
|
161
|
+
TConfig extends AgentRuntimeConfig = AgentRuntimeConfig,
|
|
162
|
+
> {
|
|
163
|
+
model: TModel;
|
|
164
|
+
skills?: TSkill[];
|
|
165
|
+
mcpServers?: TMcp[];
|
|
166
|
+
config?: TConfig;
|
|
167
|
+
instructions?: string;
|
|
168
|
+
variables?: Record<string, string>;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// ---------------------------------------------------------------------------
|
|
172
|
+
// Session — plain DTO, generic in TSpec so host's spec type flows through
|
|
173
|
+
// ---------------------------------------------------------------------------
|
|
174
|
+
|
|
175
|
+
export interface Session<TSpec extends AgentSpec = AgentSpec> {
|
|
176
|
+
id: string;
|
|
177
|
+
title?: string | null;
|
|
178
|
+
agentName?: string | null;
|
|
179
|
+
agentSpec?: TSpec;
|
|
180
|
+
/** true → mutable builder + updateSession(spec) allowed. */
|
|
181
|
+
isMutable: boolean;
|
|
182
|
+
createdAt: string;
|
|
183
|
+
updatedAt: string;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export interface CreateSessionRequest<TSpec extends AgentSpec = AgentSpec> {
|
|
187
|
+
agentName?: string;
|
|
188
|
+
agentSpec?: TSpec;
|
|
189
|
+
title?: string;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export interface UpdateSessionRequest<TSpec extends AgentSpec = AgentSpec> {
|
|
193
|
+
sessionId: string;
|
|
194
|
+
agentSpec?: TSpec;
|
|
195
|
+
title?: string;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// ---------------------------------------------------------------------------
|
|
199
|
+
// Pagination — flat token-based (no Page objects with methods)
|
|
200
|
+
// ---------------------------------------------------------------------------
|
|
201
|
+
|
|
202
|
+
export interface ListResult<T> {
|
|
203
|
+
data: T[];
|
|
204
|
+
nextPageToken?: string;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export type ListSessionsOrder = 'asc' | 'desc';
|
|
208
|
+
|
|
209
|
+
export interface PageParams {
|
|
210
|
+
limit?: number;
|
|
211
|
+
order?: ListSessionsOrder;
|
|
212
|
+
pageToken?: string;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export interface ListSessionsParams extends PageParams {
|
|
216
|
+
/** Host-owned agent identity filter. Omit for all sessions (current user). */
|
|
217
|
+
agentId?: string;
|
|
218
|
+
/**
|
|
219
|
+
* When true, only sessions created by the authenticated subject.
|
|
220
|
+
* Omit to include managed-agent visibility where the host supports it.
|
|
221
|
+
*/
|
|
222
|
+
createdByMe?: boolean;
|
|
223
|
+
/** Inclusive lower bound on session activity (ISO-8601). */
|
|
224
|
+
startTimestamp?: string;
|
|
225
|
+
/** Inclusive upper bound on session activity (ISO-8601). */
|
|
226
|
+
endTimestamp?: string;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export type PreviousTurnIdInput = string;
|
|
230
|
+
|
|
231
|
+
// ---------------------------------------------------------------------------
|
|
232
|
+
// Turn input / state — what runtime sends and reads
|
|
233
|
+
// ---------------------------------------------------------------------------
|
|
234
|
+
|
|
235
|
+
export type UserMessageContent =
|
|
236
|
+
string | ({ type: 'text'; text: string } | { type: 'file'; name: string; data: string })[];
|
|
237
|
+
|
|
238
|
+
export interface UserMessage {
|
|
239
|
+
type: 'user.message';
|
|
240
|
+
content: UserMessageContent;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export type ApprovalDecision = { status: 'allow' } | { status: 'deny'; reason?: string };
|
|
244
|
+
|
|
245
|
+
export interface UserToolApprovalEvent {
|
|
246
|
+
type: 'user.tool_approval';
|
|
247
|
+
threadId: string;
|
|
248
|
+
toolCallId: string;
|
|
249
|
+
approval: ApprovalDecision;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export interface UserToolResponseEvent {
|
|
253
|
+
type: 'user.tool_response';
|
|
254
|
+
threadId: string;
|
|
255
|
+
toolCallId: string;
|
|
256
|
+
content: string;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export type TurnInputItem = UserMessage | UserToolApprovalEvent | UserToolResponseEvent;
|
|
260
|
+
|
|
261
|
+
export interface TurnStateRunning {
|
|
262
|
+
status: 'running';
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Aggregated token metrics on a finished turn (`turn.done.state.metrics`).
|
|
267
|
+
* Host maps wire snake_case (`total_input_tokens`, …) → camelCase here.
|
|
268
|
+
*/
|
|
269
|
+
export interface TurnDoneMetrics {
|
|
270
|
+
totalInputTokens: number;
|
|
271
|
+
totalOutputTokens: number;
|
|
272
|
+
totalTokens: number;
|
|
273
|
+
totalCacheReadTokens: number;
|
|
274
|
+
totalCacheWriteTokens: number;
|
|
275
|
+
totalReasoningTokens: number;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export interface TurnStateDone {
|
|
279
|
+
status: 'done';
|
|
280
|
+
output?: unknown;
|
|
281
|
+
requiredActions?: ActionRequiredEvent[];
|
|
282
|
+
completedAt: string;
|
|
283
|
+
/** Present when the host reports per-turn token totals. */
|
|
284
|
+
metrics?: TurnDoneMetrics;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
export interface TurnStateCancelled {
|
|
288
|
+
status: 'cancelled';
|
|
289
|
+
reason: string;
|
|
290
|
+
completedAt: string;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export interface TurnStateError {
|
|
294
|
+
status: 'error';
|
|
295
|
+
message: string;
|
|
296
|
+
completedAt: string;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
export type TurnState = TurnStateRunning | TurnStateDone | TurnStateCancelled | TurnStateError;
|
|
300
|
+
|
|
301
|
+
/** Plain turn DTO — no methods. */
|
|
302
|
+
export interface Turn {
|
|
303
|
+
id: string;
|
|
304
|
+
sessionId: string;
|
|
305
|
+
previousTurnId?: string | null;
|
|
306
|
+
input?: TurnInputItem[];
|
|
307
|
+
state: TurnState;
|
|
308
|
+
createdAt: string;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// ---------------------------------------------------------------------------
|
|
312
|
+
// Server ports — flat methods, no session-with-methods objects
|
|
313
|
+
// ---------------------------------------------------------------------------
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Chat / session port — the runtime calls these.
|
|
317
|
+
*
|
|
318
|
+
* All session ops are flat (sessionId param). No gateway client dependency.
|
|
319
|
+
* `createTrueForgeServer` is one possible implementation (TFY adapter).
|
|
320
|
+
*/
|
|
321
|
+
export interface AgentChatServer<
|
|
322
|
+
TSpec extends AgentSpec = AgentSpec,
|
|
323
|
+
TSession extends Session<TSpec> = Session<TSpec>,
|
|
324
|
+
TCreate extends CreateSessionRequest<TSpec> = CreateSessionRequest<TSpec>,
|
|
325
|
+
TList extends ListSessionsParams = ListSessionsParams,
|
|
326
|
+
TUpdate extends UpdateSessionRequest<TSpec> = UpdateSessionRequest<TSpec>,
|
|
327
|
+
TTurn extends Turn = Turn,
|
|
328
|
+
> {
|
|
329
|
+
createSession(req: TCreate): Promise<TSession>;
|
|
330
|
+
listSessions(req?: TList): Promise<ListResult<TSession>>;
|
|
331
|
+
getSession(req: { sessionId: string }): Promise<TSession>;
|
|
332
|
+
updateSession(req: TUpdate): Promise<TSession>;
|
|
333
|
+
|
|
334
|
+
createTurn(req: {
|
|
335
|
+
sessionId: string;
|
|
336
|
+
input?: TurnInputItem[];
|
|
337
|
+
previousTurnId?: PreviousTurnIdInput;
|
|
338
|
+
abortSignal?: AbortSignal;
|
|
339
|
+
headers?: Record<string, string>;
|
|
340
|
+
}): AsyncIterable<TurnStreamData>;
|
|
341
|
+
|
|
342
|
+
cancelSession(req: { sessionId: string }): Promise<void>;
|
|
343
|
+
deleteSession?(req: { sessionId: string }): Promise<void>;
|
|
344
|
+
/**
|
|
345
|
+
* When present, thread-list `rename` persists via this method.
|
|
346
|
+
* Omitted: rename is a no-op (TrueForge Gateway does not persist titles).
|
|
347
|
+
*/
|
|
348
|
+
renameSession?(req: { sessionId: string; title: string }): Promise<void>;
|
|
349
|
+
|
|
350
|
+
listTurns(req: {
|
|
351
|
+
sessionId: string;
|
|
352
|
+
limit?: number;
|
|
353
|
+
pageToken?: string;
|
|
354
|
+
order?: ListSessionsOrder;
|
|
355
|
+
}): Promise<ListResult<TTurn>>;
|
|
356
|
+
getTurn(req: { sessionId: string; turnId: string }): Promise<TTurn>;
|
|
357
|
+
listEvents(req: {
|
|
358
|
+
sessionId: string;
|
|
359
|
+
pageToken?: string;
|
|
360
|
+
lastTurnId?: string;
|
|
361
|
+
limit?: number;
|
|
362
|
+
}): Promise<ListResult<SessionEventItem>>;
|
|
363
|
+
|
|
364
|
+
/** Optional per-turn event listing (hydrate in-flight turn content). */
|
|
365
|
+
listTurnEvents?(req: {
|
|
366
|
+
sessionId: string;
|
|
367
|
+
turnId: string;
|
|
368
|
+
limit?: number;
|
|
369
|
+
pageToken?: string;
|
|
370
|
+
order?: ListSessionsOrder;
|
|
371
|
+
}): Promise<ListResult<TurnEvent>>;
|
|
372
|
+
|
|
373
|
+
subscribeToTurn?(req: {
|
|
374
|
+
sessionId: string;
|
|
375
|
+
turnId: string;
|
|
376
|
+
afterSequenceNumber?: number;
|
|
377
|
+
abortSignal?: AbortSignal;
|
|
378
|
+
}): AsyncIterable<TurnStreamData>;
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Reads a file the agent wrote inside its sandbox. Hosts whose download route is scoped to a
|
|
382
|
+
* turn resolve the sandbox from `turnId` and ignore `sandboxId`; hosts addressing sandboxes
|
|
383
|
+
* directly use `sandboxId` when the runtime was able to recover it (optional after resume when
|
|
384
|
+
* `sandbox.created` is outside the loaded history window).
|
|
385
|
+
*/
|
|
386
|
+
downloadSandboxFile?(req: {
|
|
387
|
+
sessionId: string;
|
|
388
|
+
turnId: string;
|
|
389
|
+
/** Present when a `sandbox.created` event was observed in session history or the live stream. */
|
|
390
|
+
sandboxId?: string;
|
|
391
|
+
path: string;
|
|
392
|
+
}): Promise<Blob>;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/** Request body for `AgentBuilderServer.saveAgent`. */
|
|
396
|
+
export interface SaveAgentRequest<TSpec extends AgentSpec = AgentSpec> {
|
|
397
|
+
agentName: string;
|
|
398
|
+
/** Published-agent description; hosts may require it when creating an agent. */
|
|
399
|
+
description?: string;
|
|
400
|
+
agentSpec: TSpec;
|
|
401
|
+
intent: 'create' | 'update';
|
|
402
|
+
/** Current mutable session to update atomically with the named agent. */
|
|
403
|
+
sessionId?: string;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
export interface SaveAgentResult {
|
|
407
|
+
/** Immutable id allocated by the host registry. */
|
|
408
|
+
agentId?: string;
|
|
409
|
+
/** Version id allocated by the host registry for this save. */
|
|
410
|
+
versionId?: string;
|
|
411
|
+
/** Timestamp returned when the active mutable session was updated. */
|
|
412
|
+
sessionUpdatedAt?: string;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/** MCP tool row used by the per-agent connector tool selector. */
|
|
416
|
+
export interface McpToolSelection {
|
|
417
|
+
id: string;
|
|
418
|
+
name: string;
|
|
419
|
+
description?: string;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Builder feature flags — atoms gate sandbox / skill / settings surfaces on these.
|
|
424
|
+
*/
|
|
425
|
+
export interface AgentBuilderCapabilitiesResponse {
|
|
426
|
+
data: {
|
|
427
|
+
sandbox: { enabled: boolean };
|
|
428
|
+
skill: { enabled: boolean; reason?: string };
|
|
429
|
+
settings?: { enabled: boolean };
|
|
430
|
+
webSearch?: { enabled: boolean };
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Builder catalog + persist port — atoms call these.
|
|
436
|
+
* Passed separately from the runtime's chat server.
|
|
437
|
+
*/
|
|
438
|
+
export interface AgentBuilderServer<
|
|
439
|
+
TSpec extends AgentSpec = AgentSpec,
|
|
440
|
+
TModel extends ModelSelectorEntry = ModelSelectorEntry,
|
|
441
|
+
TSkill extends SkillSelectorEntry = SkillSelectorEntry,
|
|
442
|
+
TMcp extends ConnectorSelectorEntry = ConnectorSelectorEntry,
|
|
443
|
+
TAgent extends AgentSelectorEntry = AgentSelectorEntry,
|
|
444
|
+
TSave = SaveAgentResult,
|
|
445
|
+
TCapabilities extends AgentBuilderCapabilitiesResponse = AgentBuilderCapabilitiesResponse,
|
|
446
|
+
TMcpTool extends McpToolSelection = McpToolSelection,
|
|
447
|
+
> {
|
|
448
|
+
getCapabilities(): Promise<TCapabilities>;
|
|
449
|
+
getModels(): Promise<TModel[]>;
|
|
450
|
+
getSkills(): Promise<TSkill[]>;
|
|
451
|
+
getMcp(): Promise<TMcp[]>;
|
|
452
|
+
getMcpConnector?(req: { connectorId: string }): Promise<TMcp>;
|
|
453
|
+
getMcpTools?(req: { connectorId: string }): Promise<TMcpTool[]>;
|
|
454
|
+
searchAgents(req?: SearchAgentSelectorParams): Promise<TAgent[]>;
|
|
455
|
+
saveAgent(req: SaveAgentRequest<TSpec>): Promise<TSave>;
|
|
456
|
+
deleteAgent?(req: { agentName: string }): Promise<void>;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// ---------------------------------------------------------------------------
|
|
460
|
+
// Catalog management — FE-minimal settings DTOs (host extends via generics)
|
|
461
|
+
// ---------------------------------------------------------------------------
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Provider type id. Reserved literal: `"custom"` for user-defined providers;
|
|
465
|
+
* any other string is a builtin (e.g. `"openai"`, `"anthropic"`).
|
|
466
|
+
*
|
|
467
|
+
* Note: `string | "custom"` is useless in TypeScript (`"custom"` ⊆ `string`),
|
|
468
|
+
* so this stays `string` and `"custom"` is a documented convention.
|
|
469
|
+
*/
|
|
470
|
+
export type ProviderType = string;
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Model row — form "Model ID" + "Display name".
|
|
474
|
+
* Host extends for properties, etc.
|
|
475
|
+
*/
|
|
476
|
+
export interface ModelEntry {
|
|
477
|
+
id: string;
|
|
478
|
+
name: string;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* Write config for create/update (custom form + catalog "Save key").
|
|
483
|
+
* Host extends. `baseUrl` present iff `type === "custom"`.
|
|
484
|
+
*/
|
|
485
|
+
export interface ModelProviderConfigBase<TModel extends ModelEntry = ModelEntry> {
|
|
486
|
+
type: ProviderType;
|
|
487
|
+
name: string;
|
|
488
|
+
/** Present iff `type === "custom"`. */
|
|
489
|
+
baseUrl?: string;
|
|
490
|
+
apiKey: string;
|
|
491
|
+
models: TModel[];
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* Configured provider card (list/read). No raw `apiKey`.
|
|
496
|
+
* Host extends for apiKeySet, timestamps, etc.
|
|
497
|
+
*/
|
|
498
|
+
export interface ModelProviderBase<TModel extends ModelEntry = ModelEntry> {
|
|
499
|
+
id: string;
|
|
500
|
+
type: ProviderType;
|
|
501
|
+
name: string;
|
|
502
|
+
/** Present iff `type === "custom"`. */
|
|
503
|
+
baseUrl?: string;
|
|
504
|
+
models: TModel[];
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* Discovery-only catalog provider (AVAILABLE list).
|
|
509
|
+
* `type` must not be `"custom"` — custom providers use the custom form.
|
|
510
|
+
* Host extends for richer model rows.
|
|
511
|
+
*/
|
|
512
|
+
export interface ModelProviderCatalogEntry<TModel extends ModelEntry = ModelEntry> {
|
|
513
|
+
type: ProviderType;
|
|
514
|
+
name: string;
|
|
515
|
+
models: TModel[];
|
|
516
|
+
supportedReasoningEfforts?: string[];
|
|
517
|
+
logo?: string;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/** Create — no `id`; server assigns it. Catalog path = entry + apiKey. */
|
|
521
|
+
export type CreateModelProviderRequest<TModel extends ModelEntry = ModelEntry> = ModelProviderConfigBase<TModel>;
|
|
522
|
+
|
|
523
|
+
/** Update — `id` required. */
|
|
524
|
+
export type UpdateModelProviderRequest<TModel extends ModelEntry = ModelEntry> = ModelProviderConfigBase<TModel> & {
|
|
525
|
+
id: string;
|
|
526
|
+
};
|
|
527
|
+
|
|
528
|
+
export interface ModelCatalogServer<
|
|
529
|
+
TModel extends ModelEntry = ModelEntry,
|
|
530
|
+
TProvider extends ModelProviderBase<TModel> = ModelProviderBase<TModel>,
|
|
531
|
+
TCatalogProvider extends ModelProviderCatalogEntry<TModel> = ModelProviderCatalogEntry<TModel>,
|
|
532
|
+
TCreate extends CreateModelProviderRequest<TModel> = CreateModelProviderRequest<TModel>,
|
|
533
|
+
TUpdate extends UpdateModelProviderRequest<TModel> = UpdateModelProviderRequest<TModel>,
|
|
534
|
+
> {
|
|
535
|
+
getModelProviderCatalog(): Promise<TCatalogProvider[]>;
|
|
536
|
+
listModelProviders(): Promise<TProvider[]>;
|
|
537
|
+
createModelProvider(req: TCreate): Promise<TProvider>;
|
|
538
|
+
/** Full replace update keyed by provider `id`. */
|
|
539
|
+
updateModelProvider(req: TUpdate): Promise<TProvider>;
|
|
540
|
+
deleteModelProvider?(req: { id: string }): Promise<void>;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/** Tool row on a connector detail. Host extends for schemas, etc. */
|
|
544
|
+
export interface ToolBase {
|
|
545
|
+
id: string;
|
|
546
|
+
name: string;
|
|
547
|
+
description: string;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/** Strict auth type id. Hosts widen branches via intersection + re-union. */
|
|
551
|
+
export type ConnectorAuthType = 'dcr' | 'header' | 'none';
|
|
552
|
+
|
|
553
|
+
// Write (create/update) — export branches so hosts can intersect extras
|
|
554
|
+
export interface ConnectorAuthOAuth {
|
|
555
|
+
type: 'dcr';
|
|
556
|
+
authUrl?: string;
|
|
557
|
+
}
|
|
558
|
+
export interface ConnectorAuthApiKey {
|
|
559
|
+
type: 'header';
|
|
560
|
+
apiKey?: string;
|
|
561
|
+
headerName?: string;
|
|
562
|
+
}
|
|
563
|
+
export interface ConnectorAuthNone {
|
|
564
|
+
type: 'none';
|
|
565
|
+
}
|
|
566
|
+
export type ConnectorAuth = ConnectorAuthOAuth | ConnectorAuthApiKey | ConnectorAuthNone;
|
|
567
|
+
|
|
568
|
+
// Public (list/detail) — no secrets
|
|
569
|
+
export interface ConnectorAuthPublicOAuth {
|
|
570
|
+
type: 'dcr';
|
|
571
|
+
authUrl?: string;
|
|
572
|
+
}
|
|
573
|
+
export interface ConnectorAuthPublicApiKey {
|
|
574
|
+
type: 'header';
|
|
575
|
+
headerName?: string;
|
|
576
|
+
}
|
|
577
|
+
export interface ConnectorAuthPublicNone {
|
|
578
|
+
type: 'none';
|
|
579
|
+
}
|
|
580
|
+
export type ConnectorAuthPublic = ConnectorAuthPublicOAuth | ConnectorAuthPublicApiKey | ConnectorAuthPublicNone;
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* MCP / connector create-edit config. Host extends for extra fields, etc.
|
|
584
|
+
*/
|
|
585
|
+
export interface ConnectorConfigBase<TAuth extends ConnectorAuth = ConnectorAuth> {
|
|
586
|
+
name: string;
|
|
587
|
+
description: string;
|
|
588
|
+
url: string;
|
|
589
|
+
auth: TAuth;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* Connected connector row (settings/connectors). No raw `apiKey` or tools.
|
|
594
|
+
* Tools are fetched separately with `getToolsByConnectorId`.
|
|
595
|
+
* Host extends.
|
|
596
|
+
*/
|
|
597
|
+
export interface ConnectorBase<TAuth extends ConnectorAuthPublic = ConnectorAuthPublic> {
|
|
598
|
+
id: string;
|
|
599
|
+
name: string;
|
|
600
|
+
description: string;
|
|
601
|
+
url: string;
|
|
602
|
+
auth: TAuth;
|
|
603
|
+
/** When true, UI should not show Disconnect. */
|
|
604
|
+
requiresAuth: boolean;
|
|
605
|
+
authenticated: boolean;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
/** Discovery catalog entry for "+ Add MCP server". Host extends. */
|
|
609
|
+
export interface ConnectorCatalogEntry<TAuth extends ConnectorAuthPublic = ConnectorAuthPublic> {
|
|
610
|
+
id: string;
|
|
611
|
+
name: string;
|
|
612
|
+
description?: string;
|
|
613
|
+
url: string;
|
|
614
|
+
auth: TAuth;
|
|
615
|
+
logo?: string;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
/** Create connector — no `id`; server assigns it. Host extends. */
|
|
619
|
+
export type CreateConnectorRequest<TAuth extends ConnectorAuth = ConnectorAuth> = ConnectorConfigBase<TAuth>;
|
|
620
|
+
|
|
621
|
+
/** Update connector — `id` required. Host extends. */
|
|
622
|
+
export type UpdateConnectorRequest<TAuth extends ConnectorAuth = ConnectorAuth> = ConnectorConfigBase<TAuth> & {
|
|
623
|
+
id: string;
|
|
624
|
+
};
|
|
625
|
+
|
|
626
|
+
export interface AuthenticateConnectorRequest {
|
|
627
|
+
id: string;
|
|
628
|
+
/** OAuth callback page owned by the host application. */
|
|
629
|
+
returnTo?: string;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
export interface ConnectorAuthenticationResult<TConnector extends ConnectorBase = ConnectorBase> {
|
|
633
|
+
connector?: TConnector;
|
|
634
|
+
status?: string;
|
|
635
|
+
authorization_endpoint?: string | undefined;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
export interface ConnectorCatalogServer<
|
|
639
|
+
TTool extends ToolBase = ToolBase,
|
|
640
|
+
TAuthWrite extends ConnectorAuth = ConnectorAuth,
|
|
641
|
+
TAuthPublic extends ConnectorAuthPublic = ConnectorAuthPublic,
|
|
642
|
+
TConnector extends ConnectorBase<TAuthPublic> = ConnectorBase<TAuthPublic>,
|
|
643
|
+
TCatalogEntry extends ConnectorCatalogEntry<TAuthPublic> = ConnectorCatalogEntry<TAuthPublic>,
|
|
644
|
+
TCreate extends CreateConnectorRequest<TAuthWrite> = CreateConnectorRequest<TAuthWrite>,
|
|
645
|
+
TUpdate extends UpdateConnectorRequest<TAuthWrite> = UpdateConnectorRequest<TAuthWrite>,
|
|
646
|
+
> {
|
|
647
|
+
getConnectorCatalog(): Promise<TCatalogEntry[]>;
|
|
648
|
+
getConnector(req: { id: string }): Promise<TConnector>;
|
|
649
|
+
listConnectors(req?: { query?: string }): Promise<TConnector[]>;
|
|
650
|
+
getToolsByConnectorId(req: { id: string }): Promise<TTool[]>;
|
|
651
|
+
createConnector(req: TCreate): Promise<TConnector>;
|
|
652
|
+
/** Full replace update keyed by connector `id`. */
|
|
653
|
+
updateConnector(req: TUpdate): Promise<TConnector>;
|
|
654
|
+
/**
|
|
655
|
+
* Start connector auth (e.g. OAuth).
|
|
656
|
+
* May return a connector (already authenticated / with `auth.authUrl`) or a
|
|
657
|
+
* result carrying `authorization_endpoint` for the popup flow.
|
|
658
|
+
*/
|
|
659
|
+
authenticateConnector(
|
|
660
|
+
req: AuthenticateConnectorRequest,
|
|
661
|
+
): Promise<TConnector | ConnectorAuthenticationResult<TConnector>>;
|
|
662
|
+
/** Clear connector auth. */
|
|
663
|
+
disconnectConnector(req: { id: string }): Promise<TConnector>;
|
|
664
|
+
deleteConnector?(req: { id: string }): Promise<void>;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
// ---------------------------------------------------------------------------
|
|
668
|
+
// Skills catalog — FE-minimal settings DTOs (host extends via generics)
|
|
669
|
+
// ---------------------------------------------------------------------------
|
|
670
|
+
|
|
671
|
+
/** Skill row shown in settings/skills (list + delete). Host extends for fqn, etc. */
|
|
672
|
+
export interface SkillBase {
|
|
673
|
+
id: string;
|
|
674
|
+
name: string;
|
|
675
|
+
description: string;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
export interface RegistrySkill extends SkillBase {
|
|
679
|
+
/** `SkillCatalogEntry.id` this skill was created from. */
|
|
680
|
+
catalogId: string;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
export type GithubSkill = SkillBase;
|
|
684
|
+
|
|
685
|
+
export type DefinedSkill = RegistrySkill | GithubSkill;
|
|
686
|
+
|
|
687
|
+
/** Git source fields shared by catalog entries and create requests. */
|
|
688
|
+
export interface SkillConfigBase {
|
|
689
|
+
name: string;
|
|
690
|
+
description: string;
|
|
691
|
+
repoURL: string;
|
|
692
|
+
path: string;
|
|
693
|
+
ref: string;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
export interface SkillCatalogEntry extends SkillConfigBase {
|
|
697
|
+
id: string;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
/** Create-skill base. Hosts may intersect extra fields and re-union. */
|
|
701
|
+
export type CreateSkillRequestBase = SkillConfigBase;
|
|
702
|
+
|
|
703
|
+
export interface SelectRegistrySkillRequest extends CreateSkillRequestBase {
|
|
704
|
+
/** `SkillCatalogEntry.id`, persisted so the created skill links back to it. */
|
|
705
|
+
catalogId: string;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
export type ImportGithubSkillRequest = CreateSkillRequestBase;
|
|
709
|
+
|
|
710
|
+
export type CreateSkillRequest = SelectRegistrySkillRequest | ImportGithubSkillRequest;
|
|
711
|
+
|
|
712
|
+
export interface SkillCatalogServer<
|
|
713
|
+
TSkill extends SkillBase = SkillBase,
|
|
714
|
+
TCatalogEntry extends SkillCatalogEntry = SkillCatalogEntry,
|
|
715
|
+
TCreate extends CreateSkillRequest = CreateSkillRequest,
|
|
716
|
+
> {
|
|
717
|
+
getSkillCatalog(): Promise<TCatalogEntry[]>;
|
|
718
|
+
listSkills(req?: { query?: string }): Promise<TSkill[]>;
|
|
719
|
+
createSkill(req: TCreate): Promise<TSkill>;
|
|
720
|
+
deleteSkill?(req: { id: string }): Promise<void>;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
// ---------------------------------------------------------------------------
|
|
724
|
+
// Sandbox providers catalog — public rows omit credentials; writes accept them
|
|
725
|
+
// ---------------------------------------------------------------------------
|
|
726
|
+
|
|
727
|
+
/** Mutable sandbox provider settings shared by catalog rows, create, and update. */
|
|
728
|
+
export interface SandboxConfig {
|
|
729
|
+
execTimeoutMs: number;
|
|
730
|
+
autoStopIntervalInMinutes: number;
|
|
731
|
+
autoArchiveIntervalInMinutes: number;
|
|
732
|
+
autoDeleteIntervalInMinutes: number;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
export interface SandboxCatalogEntry extends SandboxConfig {
|
|
736
|
+
id: string;
|
|
737
|
+
name: string;
|
|
738
|
+
type: string;
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
/**
|
|
742
|
+
* Connected sandbox provider row (settings/sandboxes). No raw `apiKey`.
|
|
743
|
+
* Includes last-saved config so update forms can show previous values.
|
|
744
|
+
*/
|
|
745
|
+
export interface SandboxBase extends SandboxConfig {
|
|
746
|
+
id: string;
|
|
747
|
+
name: string;
|
|
748
|
+
catalogId: string;
|
|
749
|
+
isConnected: boolean;
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
export interface SandboxSnapshotSyncStatus {
|
|
753
|
+
status: 'pending' | 'ready' | 'failed';
|
|
754
|
+
statusReason?: string | null;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
export interface SandboxProviderListEntry<TSandbox extends SandboxBase = SandboxBase> {
|
|
758
|
+
data: TSandbox;
|
|
759
|
+
snapshotSyncStatus: SandboxSnapshotSyncStatus;
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
export interface CreateSandboxRequest extends SandboxConfig {
|
|
763
|
+
/** `SandboxCatalogEntry.id` used to create this sandbox provider. */
|
|
764
|
+
catalogId: string;
|
|
765
|
+
name: string;
|
|
766
|
+
type: string;
|
|
767
|
+
apiKey: string;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
export interface UpdateSandboxRequest extends SandboxConfig {
|
|
771
|
+
id: string;
|
|
772
|
+
/** Omit to keep the existing key; send a value to rotate. */
|
|
773
|
+
apiKey?: string;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
/** Host-facing aliases (trueforge-ui public names). */
|
|
777
|
+
export type SandboxProviderConfig = SandboxConfig;
|
|
778
|
+
export type SandboxProviderCatalogEntry = SandboxCatalogEntry;
|
|
779
|
+
export type SandboxProviderBase = SandboxBase;
|
|
780
|
+
export type CreateSandboxProviderRequest = CreateSandboxRequest;
|
|
781
|
+
export type UpdateSandboxProviderRequest = UpdateSandboxRequest;
|
|
782
|
+
|
|
783
|
+
export interface SandboxCatalogServer<
|
|
784
|
+
TProvider extends SandboxBase = SandboxBase,
|
|
785
|
+
TCatalogEntry extends SandboxCatalogEntry = SandboxCatalogEntry,
|
|
786
|
+
TCreate extends CreateSandboxRequest = CreateSandboxRequest,
|
|
787
|
+
TUpdate extends UpdateSandboxRequest = UpdateSandboxRequest,
|
|
788
|
+
TListEntry extends SandboxProviderListEntry<TProvider> = SandboxProviderListEntry<TProvider>,
|
|
789
|
+
> {
|
|
790
|
+
getSandboxProviderCatalog(): Promise<TCatalogEntry[]>;
|
|
791
|
+
listSandboxProviders(req?: { query?: string }): Promise<TListEntry[]>;
|
|
792
|
+
createSandboxProvider(req: TCreate): Promise<TProvider>;
|
|
793
|
+
updateSandboxProvider(req: TUpdate): Promise<TProvider>;
|
|
794
|
+
deleteSandboxProvider?(req: { id: string }): Promise<void>;
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
// ---------------------------------------------------------------------------
|
|
798
|
+
// Web-search providers catalog — public rows omit credentials; writes accept them
|
|
799
|
+
// ---------------------------------------------------------------------------
|
|
800
|
+
|
|
801
|
+
export interface WebSearchCatalogEntry {
|
|
802
|
+
id: string;
|
|
803
|
+
name: string;
|
|
804
|
+
type: string;
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
/**
|
|
808
|
+
* Connected web-search provider row (settings/web-search). No raw `apiKey`.
|
|
809
|
+
*/
|
|
810
|
+
export interface WebSearchBase {
|
|
811
|
+
id: string;
|
|
812
|
+
name: string;
|
|
813
|
+
catalogId: string;
|
|
814
|
+
isConnected: boolean;
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
export interface CreateWebSearchRequest {
|
|
818
|
+
/** `WebSearchCatalogEntry.id` used to create this web-search provider. */
|
|
819
|
+
catalogId: string;
|
|
820
|
+
name: string;
|
|
821
|
+
type: string;
|
|
822
|
+
apiKey: string;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
export interface UpdateWebSearchRequest {
|
|
826
|
+
id: string;
|
|
827
|
+
/** Omit to keep the existing key; send a value to set/rotate. */
|
|
828
|
+
apiKey?: string;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
/** Host-facing aliases (trueforge-ui public names). */
|
|
832
|
+
export type WebSearchProviderCatalogEntry = WebSearchCatalogEntry;
|
|
833
|
+
export type WebSearchProviderBase = WebSearchBase;
|
|
834
|
+
export type CreateWebSearchProviderRequest = CreateWebSearchRequest;
|
|
835
|
+
export type UpdateWebSearchProviderRequest = UpdateWebSearchRequest;
|
|
836
|
+
|
|
837
|
+
export interface WebSearchCatalogServer<
|
|
838
|
+
TProvider extends WebSearchBase = WebSearchBase,
|
|
839
|
+
TCatalogEntry extends WebSearchCatalogEntry = WebSearchCatalogEntry,
|
|
840
|
+
TCreate extends CreateWebSearchRequest = CreateWebSearchRequest,
|
|
841
|
+
TUpdate extends UpdateWebSearchRequest = UpdateWebSearchRequest,
|
|
842
|
+
> {
|
|
843
|
+
getWebSearchProviderCatalog(): Promise<TCatalogEntry[]>;
|
|
844
|
+
listWebSearchProviders(req?: { query?: string }): Promise<TProvider[]>;
|
|
845
|
+
createWebSearchProvider(req: TCreate): Promise<TProvider>;
|
|
846
|
+
updateWebSearchProvider(req: TUpdate): Promise<TProvider>;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
/** Host-facing selector / compose aliases (trueforge-ui public names). */
|
|
850
|
+
export type ModelSelection = ModelSelectorEntry;
|
|
851
|
+
export type AgentSkill = SkillSelectorEntry;
|
|
852
|
+
export type ConnectorState = ConnectorSelectorEntry;
|
|
853
|
+
export type AgentLibraryEntry = AgentSelectorEntry;
|
|
854
|
+
export type SearchAgentsParams = SearchAgentSelectorParams;
|
|
855
|
+
|
|
856
|
+
/**
|
|
857
|
+
* Settings management aggregate — modelCatalog + connectorCatalog + optional
|
|
858
|
+
* skill, sandbox, and web-search catalogs.
|
|
859
|
+
* Hosts may pass the whole object to an app shell, or a focused sub-port to a page.
|
|
860
|
+
*/
|
|
861
|
+
export interface CatalogServer<
|
|
862
|
+
TModelCatalog extends ModelCatalogServer = ModelCatalogServer,
|
|
863
|
+
TConnectorCatalog extends ConnectorCatalogServer = ConnectorCatalogServer,
|
|
864
|
+
TSkillCatalog extends SkillCatalogServer = SkillCatalogServer,
|
|
865
|
+
TSandboxCatalog extends SandboxCatalogServer = SandboxCatalogServer,
|
|
866
|
+
TWebSearchCatalog extends WebSearchCatalogServer = WebSearchCatalogServer,
|
|
867
|
+
> {
|
|
868
|
+
modelCatalog: TModelCatalog;
|
|
869
|
+
connectorCatalog: TConnectorCatalog;
|
|
870
|
+
/** Optional — omit when the host has no skills settings surface. */
|
|
871
|
+
skillCatalog?: TSkillCatalog;
|
|
872
|
+
/** Optional — omit when the host has no sandboxes settings surface. */
|
|
873
|
+
sandboxCatalog?: TSandboxCatalog;
|
|
874
|
+
/** Optional — omit when the host has no web-search settings surface. */
|
|
875
|
+
webSearchCatalog?: TWebSearchCatalog;
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
// ---------------------------------------------------------------------------
|
|
879
|
+
// AgentSessions — optional agent-detail shell (Overview + sessions under agent)
|
|
880
|
+
// ---------------------------------------------------------------------------
|
|
881
|
+
|
|
882
|
+
/**
|
|
883
|
+
* Published agent identity + spec for the agent-detail Overview (read-only).
|
|
884
|
+
* Host widens `TSpec` (and may extend this DTO) for mounts / config / extras.
|
|
885
|
+
*/
|
|
886
|
+
export interface AgentDetail<TSpec extends AgentSpec = AgentSpec> {
|
|
887
|
+
agentId: string;
|
|
888
|
+
/** Display name (e.g. "release-notes-writer"). */
|
|
889
|
+
name: string;
|
|
890
|
+
/** Published-agent description; not part of the executable agent spec. */
|
|
891
|
+
description?: string;
|
|
892
|
+
agentSpec: TSpec;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
/** Stream vs non-stream bodies for one language on the Use In Code tab. */
|
|
896
|
+
export interface CodeSnippetSampleCode {
|
|
897
|
+
stream: string;
|
|
898
|
+
nonStream: string;
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
/**
|
|
902
|
+
* One language row for Use In Code.
|
|
903
|
+
* Host maps wire `sample_code` / `non_stream` → camelCase here.
|
|
904
|
+
*/
|
|
905
|
+
export interface CodeSnippet<TSample extends CodeSnippetSampleCode = CodeSnippetSampleCode> {
|
|
906
|
+
/** Sidebar label (e.g. "TypeScript"). */
|
|
907
|
+
labelName: string;
|
|
908
|
+
/** Highlighter / tab id (e.g. "typescript"). */
|
|
909
|
+
language: string;
|
|
910
|
+
icon?: string;
|
|
911
|
+
sampleCode: TSample;
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
/**
|
|
915
|
+
* Aggregated session metrics for the sessions list sidebar.
|
|
916
|
+
* Host maps wire snake_case (`total_turns`, `total_cost_in_usd`, …) → camelCase.
|
|
917
|
+
*/
|
|
918
|
+
export interface SessionListMetrics {
|
|
919
|
+
totalTurns: number;
|
|
920
|
+
totalCostInUsd?: number;
|
|
921
|
+
totalDurationMs: number;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
/**
|
|
925
|
+
* One row in the Agent Sessions list (left pane).
|
|
926
|
+
*
|
|
927
|
+
* Binding: `agentName` → named / immutable agent; `agentSpec` → mutable / draft.
|
|
928
|
+
* Host may send one, both, or neither depending on how the session was created.
|
|
929
|
+
*/
|
|
930
|
+
export interface SessionListEntry<TSpec extends AgentSpec = AgentSpec> {
|
|
931
|
+
id: string;
|
|
932
|
+
title?: string | null;
|
|
933
|
+
createdAt: string;
|
|
934
|
+
updatedAt: string;
|
|
935
|
+
lastActivityAt: string;
|
|
936
|
+
metrics: SessionListMetrics;
|
|
937
|
+
/** Present when bound to a published (immutable) agent. */
|
|
938
|
+
agentName?: string | null;
|
|
939
|
+
/** Present when bound to a mutable / draft agent spec. */
|
|
940
|
+
agentSpec?: TSpec;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
/** Params for `AgentSessionsServer.listSessionEvents` (session event timeline). */
|
|
944
|
+
export interface ListSessionEventsParams extends Pick<PageParams, 'limit' | 'pageToken'> {
|
|
945
|
+
sessionId: string;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
/**
|
|
949
|
+
* Optional plug-in for agent-detail UI: Overview, Use In Code, sessions list,
|
|
950
|
+
* and per-session event timeline. Omit `sessions` on `AgentUIServerPort` when
|
|
951
|
+
* the host has no agent-detail surface.
|
|
952
|
+
*
|
|
953
|
+
* Read-only — create/update/delete stay on `AgentChatServer` / `AgentBuilderServer`.
|
|
954
|
+
*/
|
|
955
|
+
export interface AgentSessionsServer<
|
|
956
|
+
TSpec extends AgentSpec = AgentSpec,
|
|
957
|
+
TDetail extends AgentDetail<TSpec> = AgentDetail<TSpec>,
|
|
958
|
+
TSnippet extends CodeSnippet = CodeSnippet,
|
|
959
|
+
TListEntry extends SessionListEntry<TSpec> = SessionListEntry<TSpec>,
|
|
960
|
+
TList extends ListSessionsParams = ListSessionsParams,
|
|
961
|
+
> {
|
|
962
|
+
/** Fetch published agent details by id for the Overview tab. */
|
|
963
|
+
getAgent(req: { agentId: string }): Promise<TDetail>;
|
|
964
|
+
/** Fetch Use In Code snippets for the agent (one row per language). */
|
|
965
|
+
getCodeSnippets(req: { agentId: string }): Promise<TSnippet[]>;
|
|
966
|
+
/**
|
|
967
|
+
* List sessions visible to the current user. Pass `agentId` to scope to one
|
|
968
|
+
* agent; `createdByMe: true` for only sessions they created. Use
|
|
969
|
+
* `startTimestamp` / `endTimestamp` for date filters.
|
|
970
|
+
*/
|
|
971
|
+
listSessions(req?: TList): Promise<ListResult<TListEntry>>;
|
|
972
|
+
/**
|
|
973
|
+
* Fetch the session event timeline (right pane). Paginate with `pageToken`
|
|
974
|
+
* until exhausted; rebuild turns from `turn.created` / `turn.done` +
|
|
975
|
+
* nested `TurnEvent`s. Per-turn token metrics live on `turn.done.state.metrics`.
|
|
976
|
+
*/
|
|
977
|
+
listSessionEvents(req: ListSessionEventsParams): Promise<ListResult<SessionEventItem>>;
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
// ---------------------------------------------------------------------------
|
|
981
|
+
// Schedules — optional schedules listing + CRUD + manual runs (host extends)
|
|
982
|
+
// ---------------------------------------------------------------------------
|
|
983
|
+
|
|
984
|
+
export type ScheduleStatus = 'active' | 'paused';
|
|
985
|
+
|
|
986
|
+
export type ScheduleRunStatus = 'scheduled' | 'triggered' | 'failed';
|
|
987
|
+
|
|
988
|
+
export interface Schedule {
|
|
989
|
+
id: string;
|
|
990
|
+
name: string;
|
|
991
|
+
/** Stable agent id (`AgentSelectorEntry.agentId`). */
|
|
992
|
+
agentId: string;
|
|
993
|
+
/** Display name; omit when the host only has `agentId`. */
|
|
994
|
+
agentName?: string;
|
|
995
|
+
task: string;
|
|
996
|
+
cron: string;
|
|
997
|
+
timezone: string;
|
|
998
|
+
status: ScheduleStatus;
|
|
999
|
+
lastRunAt: string | null;
|
|
1000
|
+
/** Creator when the host persists one; omit to hide Created-by UI. */
|
|
1001
|
+
createdBySubject?: CreatedBySubject;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
/** Flat schedule-run DTO (ISO-8601 timestamps; host maps from wire Dates). */
|
|
1005
|
+
export interface ScheduleRun {
|
|
1006
|
+
id: string;
|
|
1007
|
+
scheduleId: string;
|
|
1008
|
+
name: string;
|
|
1009
|
+
scheduledFor: string;
|
|
1010
|
+
status: ScheduleRunStatus;
|
|
1011
|
+
triggeredAt: string | null;
|
|
1012
|
+
triggeredBy: string;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
export interface ListSchedulesParams extends Pick<PageParams, 'limit' | 'pageToken'> {
|
|
1016
|
+
agentId?: string;
|
|
1017
|
+
/** Multi-agent filter; combined with `agentId` when both are set. */
|
|
1018
|
+
agentIds?: string[];
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
export interface CreateScheduleRequest {
|
|
1022
|
+
agentId: string;
|
|
1023
|
+
name: string;
|
|
1024
|
+
task: string;
|
|
1025
|
+
cron: string;
|
|
1026
|
+
timezone?: string;
|
|
1027
|
+
status?: ScheduleStatus;
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
/** `agentId` is not on the base update body; hosts that allow rebinding can extend `TUpdate`. */
|
|
1031
|
+
export interface UpdateScheduleRequest {
|
|
1032
|
+
id: string;
|
|
1033
|
+
name: string;
|
|
1034
|
+
task: string;
|
|
1035
|
+
cron: string;
|
|
1036
|
+
timezone?: string;
|
|
1037
|
+
status?: ScheduleStatus;
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
export interface CreateScheduleRunRequest {
|
|
1041
|
+
scheduleId: string;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
export interface ScheduleServer<
|
|
1045
|
+
TSchedule extends Schedule = Schedule,
|
|
1046
|
+
TCreate extends CreateScheduleRequest = CreateScheduleRequest,
|
|
1047
|
+
TUpdate extends UpdateScheduleRequest = UpdateScheduleRequest,
|
|
1048
|
+
TRun extends ScheduleRun = ScheduleRun,
|
|
1049
|
+
> {
|
|
1050
|
+
listSchedules(req?: ListSchedulesParams): Promise<ListResult<TSchedule>>;
|
|
1051
|
+
getSchedule(req: { id: string }): Promise<TSchedule>;
|
|
1052
|
+
createSchedule(req: TCreate): Promise<TSchedule>;
|
|
1053
|
+
updateSchedule(req: TUpdate): Promise<TSchedule>;
|
|
1054
|
+
deleteSchedule(req: { id: string }): Promise<void>;
|
|
1055
|
+
listScheduleRuns(req: { scheduleId: string }): Promise<TRun[]>;
|
|
1056
|
+
createScheduleRun(req: CreateScheduleRunRequest): Promise<TRun>;
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
// ---------------------------------------------------------------------------
|
|
1060
|
+
// Permissions — optional resource mutation grants
|
|
1061
|
+
// ---------------------------------------------------------------------------
|
|
1062
|
+
|
|
1063
|
+
export type PermissionResourceType = 'agent' | 'schedule' | 'session' | 'tenant';
|
|
1064
|
+
|
|
1065
|
+
export type ResourcePermission = 'USE' | 'MANAGE' | 'DELETE' | 'CREATE';
|
|
1066
|
+
|
|
1067
|
+
export interface ListPermissionsRequest {
|
|
1068
|
+
resourceType: PermissionResourceType;
|
|
1069
|
+
resourceIds: string[];
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
export interface ListPermissionsResponse {
|
|
1073
|
+
data: {
|
|
1074
|
+
type: PermissionResourceType;
|
|
1075
|
+
permissions: Record<string, ResourcePermission[]>;
|
|
1076
|
+
};
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
export interface PermissionsServer<
|
|
1080
|
+
TRequest extends ListPermissionsRequest = ListPermissionsRequest,
|
|
1081
|
+
TResponse extends ListPermissionsResponse = ListPermissionsResponse,
|
|
1082
|
+
> {
|
|
1083
|
+
listPermissions(req: TRequest): Promise<TResponse>;
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
// ---------------------------------------------------------------------------
|
|
1087
|
+
// AgentMetrics — optional aggregate metrics + time-series charts
|
|
1088
|
+
// ---------------------------------------------------------------------------
|
|
1089
|
+
|
|
1090
|
+
export type AgentMetricChartType = 'line';
|
|
1091
|
+
|
|
1092
|
+
export interface AgentMetricChartDefinition {
|
|
1093
|
+
name: string;
|
|
1094
|
+
displayName: string;
|
|
1095
|
+
description: string;
|
|
1096
|
+
chartType: AgentMetricChartType;
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
export interface AgentMetricMeter {
|
|
1100
|
+
name: string;
|
|
1101
|
+
aggregateValue: number;
|
|
1102
|
+
description: string;
|
|
1103
|
+
unit: string;
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
export interface AgentMetricPoint {
|
|
1107
|
+
timestamp: string;
|
|
1108
|
+
value: number;
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
export interface AgentMetricGraphLine<TPoint extends AgentMetricPoint = AgentMetricPoint> {
|
|
1112
|
+
name: string;
|
|
1113
|
+
values: TPoint[];
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
export interface AgentMetricGraph<TLine extends AgentMetricGraphLine = AgentMetricGraphLine> {
|
|
1117
|
+
name: string;
|
|
1118
|
+
displayName: string;
|
|
1119
|
+
description: string;
|
|
1120
|
+
unit: string;
|
|
1121
|
+
chartType: AgentMetricChartType;
|
|
1122
|
+
graphLines: TLine[];
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
export interface AgentMetricChartData<TGraph extends AgentMetricGraph = AgentMetricGraph> {
|
|
1126
|
+
step: string;
|
|
1127
|
+
graphs: TGraph[];
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
export interface AgentMetricRangeRequest {
|
|
1131
|
+
agentId: string;
|
|
1132
|
+
startTimestamp: string;
|
|
1133
|
+
endTimestamp: string;
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
export interface AgentMetricChartDataRequest extends AgentMetricRangeRequest {
|
|
1137
|
+
chartName: string;
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
export interface AgentMetricsServer<
|
|
1141
|
+
TChart extends AgentMetricChartDefinition = AgentMetricChartDefinition,
|
|
1142
|
+
TMeter extends AgentMetricMeter = AgentMetricMeter,
|
|
1143
|
+
TChartData extends AgentMetricChartData = AgentMetricChartData,
|
|
1144
|
+
TRangeRequest extends AgentMetricRangeRequest = AgentMetricRangeRequest,
|
|
1145
|
+
TChartDataRequest extends AgentMetricChartDataRequest = AgentMetricChartDataRequest,
|
|
1146
|
+
> {
|
|
1147
|
+
getCharts(): Promise<TChart[]>;
|
|
1148
|
+
getMeters(req: TRangeRequest): Promise<TMeter[]>;
|
|
1149
|
+
getChartData(req: TChartDataRequest): Promise<TChartData>;
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
/**
|
|
1153
|
+
* Composed host port: chat + builder + optional settings catalog + optional
|
|
1154
|
+
* agent-detail / sessions shell + optional schedules surface + optional metrics.
|
|
1155
|
+
*
|
|
1156
|
+
* `catalog` is optional — if the host passes it, settings UI can call
|
|
1157
|
+
* `useCatalogServer()` / show modelCatalog, connectorCatalog, and skillCatalog;
|
|
1158
|
+
* if omitted, those surfaces stay hidden.
|
|
1159
|
+
*
|
|
1160
|
+
* `sessions` is optional — if the host passes it, agent-detail UI can call
|
|
1161
|
+
* `useAgentSessionsServer()` / Overview + sessions under an agent; if omitted,
|
|
1162
|
+
* that surface stays hidden.
|
|
1163
|
+
*
|
|
1164
|
+
* `schedules` is optional — if the host passes it, schedules UI can call
|
|
1165
|
+
* `useScheduleServer()` / list and manage schedules; if omitted, that surface
|
|
1166
|
+
* stays hidden.
|
|
1167
|
+
*
|
|
1168
|
+
* `metrics` is optional — if the host passes it, agent-detail UI can render
|
|
1169
|
+
* aggregate meter cards and time-series charts.
|
|
1170
|
+
*
|
|
1171
|
+
* trueforge-ui re-exports this as `AgentUIServer`.
|
|
1172
|
+
*/
|
|
1173
|
+
export type AgentUIServerPort<
|
|
1174
|
+
TChat extends AgentChatServer = AgentChatServer,
|
|
1175
|
+
TBuilder extends AgentBuilderServer = AgentBuilderServer,
|
|
1176
|
+
TCatalog extends CatalogServer = CatalogServer,
|
|
1177
|
+
TSessions extends AgentSessionsServer = AgentSessionsServer,
|
|
1178
|
+
TSchedules extends ScheduleServer = ScheduleServer,
|
|
1179
|
+
TMetrics extends AgentMetricsServer = AgentMetricsServer,
|
|
1180
|
+
TPermissions extends PermissionsServer = PermissionsServer,
|
|
1181
|
+
> = TChat &
|
|
1182
|
+
TBuilder & {
|
|
1183
|
+
catalog?: TCatalog;
|
|
1184
|
+
sessions?: TSessions;
|
|
1185
|
+
schedules?: TSchedules;
|
|
1186
|
+
metrics?: TMetrics;
|
|
1187
|
+
permissions?: TPermissions;
|
|
1188
|
+
};
|
|
1189
|
+
|
|
1190
|
+
/** Host-facing alias used by trueforge-ui. */
|
|
1191
|
+
export type AgentUIServer = AgentUIServerPort;
|