@truefoundry/assistant-ui-runtime 0.1.5 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +198 -401
- package/dist/chunk-3A2EPLQG.js +93 -0
- package/dist/chunk-3A2EPLQG.js.map +1 -0
- package/dist/chunk-Q2SHKMLM.js +270 -0
- package/dist/chunk-Q2SHKMLM.js.map +1 -0
- package/dist/index.d.ts +24 -29
- package/dist/index.js +264 -237
- package/dist/index.js.map +1 -1
- package/dist/plugins/truefoundry-agent-server-adapter/index.d.ts +162 -0
- package/dist/plugins/truefoundry-agent-server-adapter/index.js +19 -0
- package/dist/plugins/truefoundry-agent-server-adapter/index.js.map +1 -0
- package/dist/server/index.d.ts +17 -0
- package/dist/server/index.js +9 -0
- package/dist/server/index.js.map +1 -0
- package/dist/types-BfiFf8O1.d.ts +468 -0
- package/package.json +19 -6
- package/src/askUserQuestion.ts +3 -3
- package/src/buildEditedUserMessageContent.test.ts +2 -2
- package/src/collectPending.ts +1 -1
- package/src/convertTurnMessages.test.ts +141 -196
- package/src/convertTurnMessages.ts +130 -76
- package/src/createSubAgent.ts +1 -1
- package/src/draftAgentConfig.test.ts +26 -29
- package/src/extractTurnUserText.ts +1 -1
- package/src/foldPeerThreads.test.ts +1 -1
- package/src/foldPeerThreads.ts +3 -2
- package/src/index.ts +80 -4
- package/src/listPages.ts +21 -0
- package/src/loadSessionSnapshot.test.ts +9 -8
- package/src/loadSessionSnapshot.ts +9 -14
- package/src/mcpAuth.ts +6 -3
- package/src/messageCustomMetadata.ts +1 -1
- package/src/modelMessageContent.ts +1 -1
- package/src/modelMessageImageContent.test.ts +1 -1
- package/src/modelMessageImageContent.ts +7 -6
- package/src/plugins/truefoundry-agent-server-adapter/README.md +178 -0
- package/src/plugins/truefoundry-agent-server-adapter/guards.test.ts +113 -0
- package/src/plugins/truefoundry-agent-server-adapter/guards.ts +130 -0
- package/src/plugins/truefoundry-agent-server-adapter/index.ts +359 -0
- package/src/plugins/truefoundry-agent-server-adapter/types.ts +135 -0
- package/src/plugins/truefoundry-agent-server-adapter/types.typecheck.ts +164 -0
- package/src/private/agentSpec.ts +8 -3
- package/src/private/draftSessionBridge.ts +14 -13
- package/src/private/truefoundryDraftThreadListAdapter.test.ts +44 -49
- package/src/private/truefoundryDraftThreadListAdapter.ts +22 -16
- package/src/requiredActionInputs.ts +1 -1
- package/src/requiredActionsFromActiveUpdate.test.ts +1 -1
- package/src/server/eventUtils.ts +120 -0
- package/src/server/events.ts +246 -0
- package/src/server/index.ts +66 -0
- package/src/server/types.ts +319 -0
- package/src/sessionSnapshot.ts +1 -1
- package/src/sessions.ts +5 -21
- package/src/streamTurn.test.ts +172 -155
- package/src/streamTurn.ts +51 -48
- package/src/toolApproval.ts +4 -4
- package/src/toolResponse.ts +4 -4
- package/src/truefoundryExtras.ts +1 -1
- package/src/truefoundryOwnedSessionsThreadListAdapter.test.ts +26 -29
- package/src/truefoundryOwnedSessionsThreadListAdapter.ts +18 -23
- package/src/truefoundryThreadListAdapter.test.ts +16 -18
- package/src/truefoundryThreadListAdapter.ts +7 -7
- package/src/turnEventHelpers.ts +1 -1
- package/src/types.ts +2 -16
- package/src/useTrueFoundryAgentMessages.test.tsx +38 -70
- package/src/useTrueFoundryAgentMessages.ts +32 -44
- package/src/useTrueFoundryAgentRuntime.ts +11 -28
- package/src/private/bindDraftAgentSession.test.ts +0 -54
- package/src/private/bindDraftAgentSession.ts +0 -28
- package/src/private/getGatewayFromPrivateClient.ts +0 -13
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime-owned turn/stream event protocol.
|
|
3
|
+
*
|
|
4
|
+
* Hosts must emit events matching these shapes. The TFY adapter maps
|
|
5
|
+
* truefoundry-gateway-sdk events 1:1 onto these types.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { TurnInputItem, TurnState } from "./types.js";
|
|
9
|
+
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// Tool call shapes
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
|
|
14
|
+
export interface ToolCallFunction {
|
|
15
|
+
name: string;
|
|
16
|
+
arguments: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type ToolInfo =
|
|
20
|
+
| { type: "truefoundry-system"; name: string }
|
|
21
|
+
| { type: "mcp"; serverId: string; serverName: string; name: string }
|
|
22
|
+
| { type: string; name?: string; [key: string]: unknown };
|
|
23
|
+
|
|
24
|
+
export interface ToolCall {
|
|
25
|
+
id: string;
|
|
26
|
+
type: "function";
|
|
27
|
+
function: ToolCallFunction;
|
|
28
|
+
toolInfo?: ToolInfo;
|
|
29
|
+
providerSpecificFields?: Record<string, unknown>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Ref used by approval/response-required events. */
|
|
33
|
+
export interface ToolCallRef {
|
|
34
|
+
id: string;
|
|
35
|
+
sourceEventId: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface ChunkDeltaToolCall {
|
|
39
|
+
index: number;
|
|
40
|
+
id?: string;
|
|
41
|
+
type?: "function";
|
|
42
|
+
function?: { name?: string; arguments?: string };
|
|
43
|
+
toolInfo?: ToolInfo;
|
|
44
|
+
providerSpecificFields?: Record<string, unknown>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
// Content events
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
|
|
51
|
+
export type ModelMessageContentPart =
|
|
52
|
+
| { type: "text"; text: string }
|
|
53
|
+
| { type: "refusal"; refusal: string }
|
|
54
|
+
| { type: "image_url"; image_url: { url: string } };
|
|
55
|
+
|
|
56
|
+
export interface ModelMessageEvent {
|
|
57
|
+
type: "model.message";
|
|
58
|
+
id: string;
|
|
59
|
+
threadId: string;
|
|
60
|
+
content?: string | ModelMessageContentPart[] | null;
|
|
61
|
+
name?: string;
|
|
62
|
+
refusal?: string | null;
|
|
63
|
+
reasoningContent?: string;
|
|
64
|
+
toolCalls?: ToolCall[];
|
|
65
|
+
finishReason?: string | null;
|
|
66
|
+
createdAt: string;
|
|
67
|
+
usage?: unknown;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface ModelMessageDeltaEvent {
|
|
71
|
+
type: "model.message.delta";
|
|
72
|
+
id: string;
|
|
73
|
+
threadId: string;
|
|
74
|
+
content?: string | null;
|
|
75
|
+
refusal?: string | null;
|
|
76
|
+
reasoningContent?: string;
|
|
77
|
+
toolCalls?: ChunkDeltaToolCall[];
|
|
78
|
+
finishReason?: string | null;
|
|
79
|
+
createdAt?: string;
|
|
80
|
+
usage?: unknown;
|
|
81
|
+
/** Extended content-block deltas (image streaming). */
|
|
82
|
+
contentBlocks?: Array<{
|
|
83
|
+
index: number;
|
|
84
|
+
delta:
|
|
85
|
+
| { type: "text"; text?: string }
|
|
86
|
+
| { type: "image_url"; image_url?: { url?: string } };
|
|
87
|
+
}>;
|
|
88
|
+
content_blocks?: Array<{
|
|
89
|
+
index: number;
|
|
90
|
+
delta:
|
|
91
|
+
| { type: "text"; text?: string }
|
|
92
|
+
| { type: "image_url"; image_url?: { url?: string } };
|
|
93
|
+
}>;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export interface ToolResponseEvent {
|
|
97
|
+
type: "tool.response";
|
|
98
|
+
id: string;
|
|
99
|
+
threadId: string;
|
|
100
|
+
toolCallId: string;
|
|
101
|
+
content: string;
|
|
102
|
+
createdAt: string;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export interface ToolApprovalRequiredEvent {
|
|
106
|
+
type: "tool.approval_required";
|
|
107
|
+
id: string;
|
|
108
|
+
createdAt: string;
|
|
109
|
+
threadId: string;
|
|
110
|
+
toolCalls: ToolCallRef[];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export interface ToolResponseRequiredEvent {
|
|
114
|
+
type: "tool.response_required";
|
|
115
|
+
id: string;
|
|
116
|
+
createdAt: string;
|
|
117
|
+
threadId: string;
|
|
118
|
+
toolCalls: ToolCallRef[];
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface AgentInfo {
|
|
122
|
+
type?: string;
|
|
123
|
+
name: string;
|
|
124
|
+
input: string;
|
|
125
|
+
model?: string;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface AgentParent {
|
|
129
|
+
threadId: string;
|
|
130
|
+
toolCallId: string;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export interface ThreadCreatedEvent {
|
|
134
|
+
type: "thread.created";
|
|
135
|
+
id: string;
|
|
136
|
+
threadId: string;
|
|
137
|
+
title: string;
|
|
138
|
+
agentInfo: AgentInfo;
|
|
139
|
+
parent: AgentParent;
|
|
140
|
+
createdAt: string;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export interface ThreadDoneEvent {
|
|
144
|
+
type: "thread.done";
|
|
145
|
+
id: string;
|
|
146
|
+
threadId: string;
|
|
147
|
+
title?: string;
|
|
148
|
+
createdAt: string;
|
|
149
|
+
state?: unknown;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export interface McpServerAuthInfo {
|
|
153
|
+
id: string;
|
|
154
|
+
name: string;
|
|
155
|
+
authUrl: string;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export interface McpAuthRequiredEvent {
|
|
159
|
+
type: "mcp.auth_required";
|
|
160
|
+
id: string;
|
|
161
|
+
createdAt: string;
|
|
162
|
+
threadId?: string | null;
|
|
163
|
+
mcpServers: McpServerAuthInfo[];
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export interface SandboxCreatedEvent {
|
|
167
|
+
type: "sandbox.created";
|
|
168
|
+
id: string;
|
|
169
|
+
createdAt: string;
|
|
170
|
+
sandboxId: string;
|
|
171
|
+
threadId: string | null;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export interface McpInitializeEvent {
|
|
175
|
+
type: "mcp.initialize";
|
|
176
|
+
id: string;
|
|
177
|
+
createdAt: string;
|
|
178
|
+
threadId: string | null;
|
|
179
|
+
[key: string]: unknown;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// ---------------------------------------------------------------------------
|
|
183
|
+
// Turn lifecycle events
|
|
184
|
+
// ---------------------------------------------------------------------------
|
|
185
|
+
|
|
186
|
+
export interface TurnCreatedEvent {
|
|
187
|
+
type: "turn.created";
|
|
188
|
+
id: string;
|
|
189
|
+
turnId: string;
|
|
190
|
+
previousTurnId?: string | null;
|
|
191
|
+
input?: TurnInputItem[];
|
|
192
|
+
state?: { status: "running" };
|
|
193
|
+
createdAt: string;
|
|
194
|
+
threadId?: string | null;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export interface TurnDoneEvent {
|
|
198
|
+
type: "turn.done";
|
|
199
|
+
id: string;
|
|
200
|
+
state: Exclude<TurnState, { status: "running" }>;
|
|
201
|
+
createdAt: string;
|
|
202
|
+
threadId?: string | null;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// ---------------------------------------------------------------------------
|
|
206
|
+
// Unions
|
|
207
|
+
// ---------------------------------------------------------------------------
|
|
208
|
+
|
|
209
|
+
/** Events stored in fold buckets (non-delta, non-turn-lifecycle). */
|
|
210
|
+
export type TurnEvent =
|
|
211
|
+
| ModelMessageEvent
|
|
212
|
+
| ToolResponseEvent
|
|
213
|
+
| ThreadCreatedEvent
|
|
214
|
+
| ThreadDoneEvent
|
|
215
|
+
| McpAuthRequiredEvent
|
|
216
|
+
| McpInitializeEvent
|
|
217
|
+
| SandboxCreatedEvent
|
|
218
|
+
| ToolApprovalRequiredEvent
|
|
219
|
+
| ToolResponseRequiredEvent;
|
|
220
|
+
|
|
221
|
+
/** Full streaming event union (includes deltas + turn lifecycle). */
|
|
222
|
+
export type TurnStreamingEvent =
|
|
223
|
+
| TurnEvent
|
|
224
|
+
| ModelMessageDeltaEvent
|
|
225
|
+
| TurnCreatedEvent
|
|
226
|
+
| TurnDoneEvent;
|
|
227
|
+
|
|
228
|
+
export type ActionRequiredEvent =
|
|
229
|
+
| ToolApprovalRequiredEvent
|
|
230
|
+
| ToolResponseRequiredEvent
|
|
231
|
+
| McpAuthRequiredEvent;
|
|
232
|
+
|
|
233
|
+
export interface TurnStreamData<
|
|
234
|
+
TStreamEvent extends TurnStreamingEvent = TurnStreamingEvent,
|
|
235
|
+
> {
|
|
236
|
+
sequenceNumber: number;
|
|
237
|
+
event: TStreamEvent;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/** Session-level event item from `listEvents`. */
|
|
241
|
+
export interface SessionEventItem {
|
|
242
|
+
turnId: string;
|
|
243
|
+
event: TurnCreatedEvent | TurnDoneEvent | TurnEvent;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export type DeltaEvents = ModelMessageDeltaEvent;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export type {
|
|
2
|
+
ModelSelectorEntry,
|
|
3
|
+
SkillSelectorEntry,
|
|
4
|
+
ConnectorSelectorEntry,
|
|
5
|
+
AgentSelectorEntry,
|
|
6
|
+
SearchAgentSelectorParams,
|
|
7
|
+
SkillMount,
|
|
8
|
+
McpServerMount,
|
|
9
|
+
ModelParams,
|
|
10
|
+
Model,
|
|
11
|
+
AgentSpec,
|
|
12
|
+
Session,
|
|
13
|
+
CreateSessionRequest,
|
|
14
|
+
UpdateSessionRequest,
|
|
15
|
+
ListResult,
|
|
16
|
+
ListSessionsOrder,
|
|
17
|
+
PageParams,
|
|
18
|
+
ListSessionsParams,
|
|
19
|
+
PreviousTurnIdInput,
|
|
20
|
+
UserMessageContent,
|
|
21
|
+
UserMessage,
|
|
22
|
+
ApprovalDecision,
|
|
23
|
+
UserToolApprovalEvent,
|
|
24
|
+
UserToolResponseEvent,
|
|
25
|
+
TurnInputItem,
|
|
26
|
+
TurnStateRunning,
|
|
27
|
+
TurnStateDone,
|
|
28
|
+
TurnStateCancelled,
|
|
29
|
+
TurnStateError,
|
|
30
|
+
TurnState,
|
|
31
|
+
Turn,
|
|
32
|
+
AgentChatServer,
|
|
33
|
+
AgentBuilderServer,
|
|
34
|
+
} from "./types.js";
|
|
35
|
+
|
|
36
|
+
export type {
|
|
37
|
+
ToolCallFunction,
|
|
38
|
+
ToolInfo,
|
|
39
|
+
ToolCall,
|
|
40
|
+
ToolCallRef,
|
|
41
|
+
ChunkDeltaToolCall,
|
|
42
|
+
ModelMessageContentPart,
|
|
43
|
+
ModelMessageEvent,
|
|
44
|
+
ModelMessageDeltaEvent,
|
|
45
|
+
ToolResponseEvent,
|
|
46
|
+
ToolApprovalRequiredEvent,
|
|
47
|
+
ToolResponseRequiredEvent,
|
|
48
|
+
AgentInfo,
|
|
49
|
+
AgentParent,
|
|
50
|
+
ThreadCreatedEvent,
|
|
51
|
+
ThreadDoneEvent,
|
|
52
|
+
McpServerAuthInfo,
|
|
53
|
+
McpAuthRequiredEvent,
|
|
54
|
+
SandboxCreatedEvent,
|
|
55
|
+
McpInitializeEvent,
|
|
56
|
+
TurnCreatedEvent,
|
|
57
|
+
TurnDoneEvent,
|
|
58
|
+
TurnEvent,
|
|
59
|
+
TurnStreamingEvent,
|
|
60
|
+
ActionRequiredEvent,
|
|
61
|
+
TurnStreamData,
|
|
62
|
+
SessionEventItem,
|
|
63
|
+
DeltaEvents,
|
|
64
|
+
} from "./events.js";
|
|
65
|
+
|
|
66
|
+
export { isEventDelta, mergeEventDelta } from "./eventUtils.js";
|
|
@@ -0,0 +1,319 @@
|
|
|
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 truefoundry-gateway-sdk.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type {
|
|
10
|
+
ActionRequiredEvent,
|
|
11
|
+
SessionEventItem,
|
|
12
|
+
TurnEvent,
|
|
13
|
+
TurnStreamData,
|
|
14
|
+
TurnStreamingEvent,
|
|
15
|
+
} from "./events.js";
|
|
16
|
+
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// Catalog — selector rows (SDK-minimal; host extends via generics)
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
/** Model selector row. Host extends for apiModel, modelId, pricing, etc. */
|
|
22
|
+
export interface ModelSelectorEntry {
|
|
23
|
+
name: string;
|
|
24
|
+
provider: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Skill selector row. Host extends for fqn, preload, etc. */
|
|
28
|
+
export interface SkillSelectorEntry {
|
|
29
|
+
id: string;
|
|
30
|
+
name: string;
|
|
31
|
+
description?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** MCP connector selector row. Host extends for type, enableTools, url, etc. */
|
|
35
|
+
export interface ConnectorSelectorEntry {
|
|
36
|
+
id: string;
|
|
37
|
+
name: string;
|
|
38
|
+
description?: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Agent selector row — UI shows name only. Host extends for metadata. */
|
|
42
|
+
export interface AgentSelectorEntry {
|
|
43
|
+
name: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type SearchAgentSelectorParams = {
|
|
47
|
+
query?: string;
|
|
48
|
+
limit?: number;
|
|
49
|
+
offset?: number;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
// Mounts — neutral SDK base (host extends with backend-specific fields)
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Mounts written to AgentSpec.skills[] / AgentSpec.mcpServers[].
|
|
58
|
+
*
|
|
59
|
+
* These are opaque to the runtime — it stores and forwards them but never reads
|
|
60
|
+
* a field, and the backend owns the shape (the gateway identifies a skill by
|
|
61
|
+
* `fqn`, with no `id` or `name` anywhere). So the base constrains only that a
|
|
62
|
+
* mount is an object; hosts intersect their concrete mount type over it, as
|
|
63
|
+
* `TfySkillMount` / `TfyMcpServerMount` do in the gateway adapter.
|
|
64
|
+
*
|
|
65
|
+
* Naming a field here would not just be unread, it would be wrong: a base with
|
|
66
|
+
* required fields rejects the backend's own payloads, and one with only optional
|
|
67
|
+
* fields is a weak type, which TypeScript rejects for a source that shares no
|
|
68
|
+
* property with it — the gateway's registry skill shares none.
|
|
69
|
+
*/
|
|
70
|
+
export type SkillMount = object;
|
|
71
|
+
|
|
72
|
+
export type McpServerMount = object;
|
|
73
|
+
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
// AgentSpec — model + skills + mcpServers on base; host widens the rest
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
|
|
78
|
+
export interface ModelParams {
|
|
79
|
+
maxTokens?: number;
|
|
80
|
+
reasoningEffort?: string;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface Model {
|
|
84
|
+
name: string;
|
|
85
|
+
params?: ModelParams;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* SDK-owned agent definition — fields the FE reads/writes.
|
|
90
|
+
* Host adds additional fields via `TSpec extends AgentSpec`.
|
|
91
|
+
*/
|
|
92
|
+
export interface AgentSpec {
|
|
93
|
+
model: Model;
|
|
94
|
+
skills?: SkillMount[];
|
|
95
|
+
mcpServers?: McpServerMount[];
|
|
96
|
+
instructions?: string;
|
|
97
|
+
messages?: unknown[];
|
|
98
|
+
variables?: Record<string, string>;
|
|
99
|
+
responseFormat?: unknown;
|
|
100
|
+
config?: unknown;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// ---------------------------------------------------------------------------
|
|
104
|
+
// Session — plain DTO, generic in TSpec so host's spec type flows through
|
|
105
|
+
// ---------------------------------------------------------------------------
|
|
106
|
+
|
|
107
|
+
export interface Session<TSpec extends AgentSpec = AgentSpec> {
|
|
108
|
+
id: string;
|
|
109
|
+
title?: string | null;
|
|
110
|
+
agentName?: string | null;
|
|
111
|
+
agentSpec?: TSpec;
|
|
112
|
+
/** true → mutable builder + updateSession(spec) allowed. */
|
|
113
|
+
isMutable: boolean;
|
|
114
|
+
createdAt: string;
|
|
115
|
+
updatedAt: string;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface CreateSessionRequest<TSpec extends AgentSpec = AgentSpec> {
|
|
119
|
+
agentName?: string;
|
|
120
|
+
agentSpec?: TSpec;
|
|
121
|
+
title?: string;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface UpdateSessionRequest<TSpec extends AgentSpec = AgentSpec> {
|
|
125
|
+
sessionId: string;
|
|
126
|
+
agentSpec?: TSpec;
|
|
127
|
+
title?: string;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// ---------------------------------------------------------------------------
|
|
131
|
+
// Pagination — flat token-based (no Page objects with methods)
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
|
|
134
|
+
export interface ListResult<T> {
|
|
135
|
+
data: T[];
|
|
136
|
+
nextPageToken?: string;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export type ListSessionsOrder = "asc" | "desc";
|
|
140
|
+
|
|
141
|
+
export type PageParams = {
|
|
142
|
+
limit?: number;
|
|
143
|
+
order?: ListSessionsOrder;
|
|
144
|
+
pageToken?: string;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
export interface ListSessionsParams extends PageParams {
|
|
148
|
+
agentName?: string;
|
|
149
|
+
/** Host-specific filter (e.g. TFY startTimestamp). */
|
|
150
|
+
startTimestamp?: string;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export type PreviousTurnIdInput = "auto" | string;
|
|
154
|
+
|
|
155
|
+
// ---------------------------------------------------------------------------
|
|
156
|
+
// Turn input / state — what runtime sends and reads
|
|
157
|
+
// ---------------------------------------------------------------------------
|
|
158
|
+
|
|
159
|
+
export type UserMessageContent =
|
|
160
|
+
| string
|
|
161
|
+
| Array<{ type: "text"; text: string } | { type: "file"; name: string; data: string }>;
|
|
162
|
+
|
|
163
|
+
export interface UserMessage {
|
|
164
|
+
type: "user.message";
|
|
165
|
+
content: UserMessageContent;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export type ApprovalDecision =
|
|
169
|
+
| { status: "allow" }
|
|
170
|
+
| { status: "deny"; reason?: string };
|
|
171
|
+
|
|
172
|
+
export interface UserToolApprovalEvent {
|
|
173
|
+
type: "user.tool_approval";
|
|
174
|
+
threadId: string;
|
|
175
|
+
toolCallId: string;
|
|
176
|
+
approval: ApprovalDecision;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export interface UserToolResponseEvent {
|
|
180
|
+
type: "user.tool_response";
|
|
181
|
+
threadId: string;
|
|
182
|
+
toolCallId: string;
|
|
183
|
+
content: string;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export type TurnInputItem =
|
|
187
|
+
| UserMessage
|
|
188
|
+
| UserToolApprovalEvent
|
|
189
|
+
| UserToolResponseEvent;
|
|
190
|
+
|
|
191
|
+
export type TurnStateRunning = { status: "running" };
|
|
192
|
+
|
|
193
|
+
export type TurnStateDone = {
|
|
194
|
+
status: "done";
|
|
195
|
+
output?: unknown;
|
|
196
|
+
requiredActions?: ActionRequiredEvent[];
|
|
197
|
+
completedAt: string;
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
export type TurnStateCancelled = {
|
|
201
|
+
status: "cancelled";
|
|
202
|
+
reason: string;
|
|
203
|
+
completedAt: string;
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
export type TurnStateError = {
|
|
207
|
+
status: "error";
|
|
208
|
+
message: string;
|
|
209
|
+
completedAt: string;
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
export type TurnState =
|
|
213
|
+
| TurnStateRunning
|
|
214
|
+
| TurnStateDone
|
|
215
|
+
| TurnStateCancelled
|
|
216
|
+
| TurnStateError;
|
|
217
|
+
|
|
218
|
+
/** Plain turn DTO — no methods. */
|
|
219
|
+
export interface Turn {
|
|
220
|
+
id: string;
|
|
221
|
+
sessionId: string;
|
|
222
|
+
previousTurnId?: string | null;
|
|
223
|
+
input?: TurnInputItem[];
|
|
224
|
+
state: TurnState;
|
|
225
|
+
createdAt: string;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// ---------------------------------------------------------------------------
|
|
229
|
+
// Server ports — flat methods, no session-with-methods objects
|
|
230
|
+
// ---------------------------------------------------------------------------
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Chat / session port — the runtime calls these.
|
|
234
|
+
*
|
|
235
|
+
* All session ops are flat (sessionId param). No gateway client dependency.
|
|
236
|
+
* `createTrueFoundryServer` is one possible implementation (TFY adapter).
|
|
237
|
+
*/
|
|
238
|
+
export interface AgentChatServer<
|
|
239
|
+
TSpec extends AgentSpec = AgentSpec,
|
|
240
|
+
TSession extends Session<TSpec> = Session<TSpec>,
|
|
241
|
+
TCreate extends CreateSessionRequest<TSpec> = CreateSessionRequest<TSpec>,
|
|
242
|
+
TList extends ListSessionsParams = ListSessionsParams,
|
|
243
|
+
TUpdate extends UpdateSessionRequest<TSpec> = UpdateSessionRequest<TSpec>,
|
|
244
|
+
TTurn extends Turn = Turn,
|
|
245
|
+
> {
|
|
246
|
+
createSession(req: TCreate): Promise<TSession>;
|
|
247
|
+
listSessions(req?: TList): Promise<ListResult<TSession>>;
|
|
248
|
+
getSession(req: { sessionId: string }): Promise<TSession>;
|
|
249
|
+
updateSession(req: TUpdate): Promise<TSession>;
|
|
250
|
+
|
|
251
|
+
prepareAndExecuteTurn(req: {
|
|
252
|
+
sessionId: string;
|
|
253
|
+
input?: TurnInputItem[];
|
|
254
|
+
previousTurnId?: PreviousTurnIdInput;
|
|
255
|
+
abortSignal?: AbortSignal;
|
|
256
|
+
headers?: Record<string, string>;
|
|
257
|
+
}): AsyncIterable<TurnStreamData>;
|
|
258
|
+
|
|
259
|
+
cancelSession(req: { sessionId: string }): Promise<void>;
|
|
260
|
+
deleteSession?(req: { sessionId: string }): Promise<void>;
|
|
261
|
+
|
|
262
|
+
listTurns(req: {
|
|
263
|
+
sessionId: string;
|
|
264
|
+
limit?: number;
|
|
265
|
+
pageToken?: string;
|
|
266
|
+
order?: ListSessionsOrder;
|
|
267
|
+
}): Promise<ListResult<TTurn>>;
|
|
268
|
+
getTurn(req: { sessionId: string; turnId: string }): Promise<TTurn>;
|
|
269
|
+
listEvents(req: {
|
|
270
|
+
sessionId: string;
|
|
271
|
+
pageToken?: string;
|
|
272
|
+
lastTurnId?: string;
|
|
273
|
+
limit?: number;
|
|
274
|
+
}): Promise<ListResult<SessionEventItem>>;
|
|
275
|
+
|
|
276
|
+
/** Optional per-turn event listing (hydrate in-flight turn content). */
|
|
277
|
+
listTurnEvents?(req: {
|
|
278
|
+
sessionId: string;
|
|
279
|
+
turnId: string;
|
|
280
|
+
limit?: number;
|
|
281
|
+
pageToken?: string;
|
|
282
|
+
order?: ListSessionsOrder;
|
|
283
|
+
}): Promise<ListResult<TurnEvent>>;
|
|
284
|
+
|
|
285
|
+
subscribeToTurn?(req: {
|
|
286
|
+
sessionId: string;
|
|
287
|
+
turnId: string;
|
|
288
|
+
afterSequenceNumber?: number;
|
|
289
|
+
abortSignal?: AbortSignal;
|
|
290
|
+
}): AsyncIterable<TurnStreamData>;
|
|
291
|
+
|
|
292
|
+
downloadSandboxFile?(
|
|
293
|
+
sandboxId: string,
|
|
294
|
+
req: { path: string },
|
|
295
|
+
): Promise<Blob>;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Builder catalog + persist port — atoms call these.
|
|
300
|
+
* Passed separately from the runtime's chat server.
|
|
301
|
+
*/
|
|
302
|
+
export interface AgentBuilderServer<
|
|
303
|
+
TSpec extends AgentSpec = AgentSpec,
|
|
304
|
+
TModel extends ModelSelectorEntry = ModelSelectorEntry,
|
|
305
|
+
TSkill extends SkillSelectorEntry = SkillSelectorEntry,
|
|
306
|
+
TMcp extends ConnectorSelectorEntry = ConnectorSelectorEntry,
|
|
307
|
+
TAgent extends AgentSelectorEntry = AgentSelectorEntry,
|
|
308
|
+
TSave = unknown,
|
|
309
|
+
> {
|
|
310
|
+
getModels(): Promise<TModel[]>;
|
|
311
|
+
getSkills(): Promise<TSkill[]>;
|
|
312
|
+
getMcp(): Promise<TMcp[]>;
|
|
313
|
+
searchAgents(req?: SearchAgentSelectorParams): Promise<TAgent[]>;
|
|
314
|
+
saveAgent(req: {
|
|
315
|
+
agentName: string;
|
|
316
|
+
agentSpec: TSpec;
|
|
317
|
+
}): Promise<TSave>;
|
|
318
|
+
deleteAgent?(req: { agentName: string }): Promise<void>;
|
|
319
|
+
}
|
package/src/sessionSnapshot.ts
CHANGED
package/src/sessions.ts
CHANGED
|
@@ -1,31 +1,15 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
AgentSession,
|
|
3
|
-
AgentSessionClient,
|
|
4
|
-
} from "truefoundry-gateway-sdk/agents";
|
|
5
|
-
import type { PrivateAgentSessionClient } from "truefoundry-gateway-sdk/agents/private";
|
|
1
|
+
import type { AgentChatServer, Session } from "./server/types.js";
|
|
6
2
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const inflightBySessionId = new Map<string, Promise<AgentSession>>();
|
|
10
|
-
|
|
11
|
-
export type GetSessionOptions = {
|
|
12
|
-
/** When set, validates the draft and binds turns via PrivateAgentSessionClient. */
|
|
13
|
-
privateClient?: PrivateAgentSessionClient;
|
|
14
|
-
};
|
|
3
|
+
const inflightBySessionId = new Map<string, Promise<Session>>();
|
|
15
4
|
|
|
16
5
|
/** `sessionId` is the assistant-ui thread `remoteId` from `RemoteThreadListAdapter.initialize`. */
|
|
17
6
|
export function getSession(
|
|
18
|
-
|
|
7
|
+
server: AgentChatServer,
|
|
19
8
|
sessionId: string,
|
|
20
|
-
|
|
21
|
-
): Promise<AgentSession> {
|
|
22
|
-
if (options?.privateClient != null) {
|
|
23
|
-
return bindDraftAgentSession(options.privateClient, sessionId);
|
|
24
|
-
}
|
|
25
|
-
|
|
9
|
+
): Promise<Session> {
|
|
26
10
|
let inflight = inflightBySessionId.get(sessionId);
|
|
27
11
|
if (inflight == null) {
|
|
28
|
-
inflight =
|
|
12
|
+
inflight = server.getSession({ sessionId }).finally(() => {
|
|
29
13
|
if (inflightBySessionId.get(sessionId) === inflight) {
|
|
30
14
|
inflightBySessionId.delete(sessionId);
|
|
31
15
|
}
|