@truefoundry/assistant-ui-runtime 0.1.13 → 0.1.15
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 +23 -0
- package/dist/{chunk-XYGEKRA2.js → chunk-S4SH2KT2.js} +1 -1
- package/dist/chunk-S4SH2KT2.js.map +1 -0
- package/dist/index.d.ts +23 -3
- package/dist/index.js +138 -11
- package/dist/index.js.map +1 -1
- package/dist/plugins/truefoundry-agent-server-adapter/index.d.ts +2 -3
- package/dist/plugins/truefoundry-agent-server-adapter/index.js +1 -1
- package/dist/server/index.d.ts +2 -2
- package/dist/{types-BE-F3vCD.d.ts → types-VU3Fc17W.d.ts} +23 -5
- package/package.json +1 -1
- package/src/convertTurnMessages.test.ts +295 -1
- package/src/convertTurnMessages.ts +116 -13
- package/src/draft/useDraftAgentSpec.test.tsx +107 -0
- package/src/draft/useDraftAgentSpec.ts +38 -0
- package/src/hooks.ts +22 -0
- package/src/index.ts +6 -0
- package/src/plugins/truefoundry-agent-server-adapter/cp.ts +2 -1
- package/src/plugins/truefoundry-agent-server-adapter/types.ts +2 -2
- package/src/server/index.ts +3 -0
- package/src/server/types.ts +25 -3
- package/src/streamTurn.test.ts +18 -0
- package/src/streamTurn.ts +3 -3
- package/src/truefoundryExtras.ts +12 -0
- package/src/useTrueFoundryAgentMessages.test.tsx +115 -0
- package/src/useTrueFoundryAgentMessages.ts +38 -1
- package/src/useTrueFoundryAgentRuntime.ts +4 -0
- package/dist/chunk-XYGEKRA2.js.map +0 -1
package/README.md
CHANGED
|
@@ -249,6 +249,28 @@ const server: AgentChatServer = {
|
|
|
249
249
|
|
|
250
250
|
`ListResult<T>` is `{ data: T[]; nextPageToken?: string }` — flat token-based pagination. Optional methods: `deleteSession`, `listTurnEvents`, `subscribeToTurn`, `downloadSandboxFile`.
|
|
251
251
|
|
|
252
|
+
### Without `subscribeToTurn`
|
|
253
|
+
|
|
254
|
+
`subscribeToTurn` is what lets the runtime re-attach to a turn that is still running after a refresh. When a server omits it and a session loads with a running turn, the runtime does **not** throw. It renders the loaded history, reports the thread as running (so your UI shows a pending indicator rather than an endless skeleton), and calls `onError` with a `TurnResumeUnsupportedError`. The turn keeps running on the backend — reload the session to pick up the result.
|
|
255
|
+
|
|
256
|
+
```tsx
|
|
257
|
+
import { TurnResumeUnsupportedError } from "@truefoundry/assistant-ui-runtime";
|
|
258
|
+
|
|
259
|
+
const runtime = useTrueFoundryAgentRuntime({
|
|
260
|
+
server,
|
|
261
|
+
agentName,
|
|
262
|
+
onError: (error) => {
|
|
263
|
+
if (error instanceof TurnResumeUnsupportedError) {
|
|
264
|
+
showResumeUnavailableDialog();
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
showToast(error);
|
|
268
|
+
},
|
|
269
|
+
});
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Match on `error.name === "TurnResumeUnsupportedError"` (exported as `TURN_RESUME_UNSUPPORTED_ERROR_NAME`) when you cannot import the class.
|
|
273
|
+
|
|
252
274
|
---
|
|
253
275
|
|
|
254
276
|
## TrueFoundry agent UI server plugin
|
|
@@ -281,6 +303,7 @@ See the [plugin README](./src/plugins/truefoundry-agent-server-adapter/README.md
|
|
|
281
303
|
| `createTrueFoundryChatServer` | Function | Chat-only gateway → `AgentChatServer` |
|
|
282
304
|
| `trueFoundryAttachmentAdapter` | Adapter | Opt-in composer attachments |
|
|
283
305
|
| `trueFoundryExtras` | Namespace | Low-level extras access |
|
|
306
|
+
| `TurnResumeUnsupportedError` | Class | Reported when a running turn cannot be streamed (no `subscribeToTurn`) |
|
|
284
307
|
| `useTrueFoundryApprovals` / `ToolResponses` / `McpAuth` / … | Hooks | Pending state + actions |
|
|
285
308
|
| `AgentChatServer`, `AgentBuilderServer`, `CatalogServer`, `Session`, `Turn`, … | Types | Server ports + DTOs |
|
|
286
309
|
| `TfyAgentSpec`, `TfySession`, `isTfyToolInfo`, … | Types / guards | Gateway-concrete types from the plugin |
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/plugins/truefoundry-agent-server-adapter/chatServer.ts","../src/plugins/truefoundry-agent-server-adapter/normalizeAgentSpec.ts","../src/plugins/truefoundry-agent-server-adapter/cp.ts","../src/plugins/truefoundry-agent-server-adapter/createTrueFoundryAgentUIServer.ts","../src/plugins/truefoundry-agent-server-adapter/guards.ts"],"sourcesContent":["import { AgentSessionClient } from \"truefoundry-gateway-sdk/agents\";\nimport type { AgentSession } from \"truefoundry-gateway-sdk/agents\";\nimport { PrivateAgentSessionClient } from \"truefoundry-gateway-sdk/agents/private\";\nimport type { AgentDraftSession } from \"truefoundry-gateway-sdk/agents/private\";\nimport type {\n AgentChatServer,\n ListResult,\n TurnInputItem,\n PreviousTurnIdInput,\n UpdateSessionRequest,\n} from \"../../server/types.js\";\nimport type {\n SessionEventItem,\n TurnEvent,\n TurnStreamData,\n} from \"../../server/events.js\";\nimport { normalizeAgentSpecForGateway } from \"./normalizeAgentSpec.js\";\nimport type {\n TfyAgentSpec,\n TfyCreateSessionRequest,\n TfyListSessionsParams,\n TfySession,\n TfyTurn,\n TfyTurnState,\n} from \"./types.js\";\n\ntype GwSession = AgentSession | AgentDraftSession;\n\nexport type CreateTrueFoundryChatServerOptions = {\n apiKey: string;\n baseUrl: string;\n /** Optional override — otherwise constructed from apiKey/baseUrl. */\n client?: AgentSessionClient;\n privateClient?: PrivateAgentSessionClient;\n deleteSession?: (req: { sessionId: string }) => Promise<void>;\n};\n\n/**\n * Only the spec is generic. Session/Turn/list-params are the concrete Tfy*\n * types because the adapter builds them as fixed object literals — a generic\n * there would type fields that nothing ever populates. The spec is safe: the\n * gateway SDK serializes with `unrecognizedObjectKeys: \"passthrough\"`, so\n * host-added spec fields survive the round trip.\n */\nexport type TrueFoundryChatServer<TSpec extends TfyAgentSpec = TfyAgentSpec> =\n AgentChatServer<\n TSpec,\n TfySession<TSpec>,\n TfyCreateSessionRequest<TSpec>,\n TfyListSessionsParams,\n UpdateSessionRequest<TSpec>,\n TfyTurn\n > & {\n /** Escape hatch for hosts that still need raw gateway clients. */\n getGatewayClients(): {\n client: AgentSessionClient;\n privateClient: PrivateAgentSessionClient;\n };\n };\n\n/** Gateway SDK errors carry the HTTP status as `statusCode`. */\nfunction isNotFound(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n (error as { statusCode?: unknown }).statusCode === 404\n );\n}\n\nfunction isDraft(session: GwSession): session is AgentDraftSession {\n return (session as AgentDraftSession).type === \"session/draft\";\n}\n\nfunction toSession<TSpec extends TfyAgentSpec>(raw: GwSession): TfySession<TSpec> {\n const mutable = isDraft(raw);\n return {\n id: raw.id,\n title: raw.title,\n agentName: raw.agentName,\n ...(mutable ? { agentSpec: raw.agentSpec as TSpec } : {}),\n isMutable: mutable,\n createdBySubject: raw.createdBySubject,\n createdAt: raw.createdAt,\n updatedAt: raw.updatedAt,\n };\n}\n\nfunction toTurn(raw: {\n id: string;\n sessionId: string;\n previousTurnId?: string | null;\n input?: TurnInputItem[];\n state: unknown;\n createdBySubject: TfyTurn[\"createdBySubject\"];\n createdAt: string;\n}): TfyTurn {\n return {\n id: raw.id,\n sessionId: raw.sessionId,\n previousTurnId: raw.previousTurnId,\n input: raw.input,\n state: raw.state as TfyTurnState,\n createdBySubject: raw.createdBySubject,\n createdAt: raw.createdAt,\n };\n}\n\nasync function toListResult<TIn, TOut>(\n page: {\n data: TIn[];\n response?: { pagination?: { nextPageToken?: string } };\n hasNextPage?: () => boolean;\n },\n map: (item: TIn) => TOut,\n): Promise<ListResult<TOut>> {\n const nextPageToken = page.response?.pagination?.nextPageToken;\n return {\n data: page.data.map(map),\n ...(nextPageToken != null && nextPageToken !== \"\"\n ? { nextPageToken }\n : {}),\n };\n}\n\n/**\n * Wraps TrueFoundry gateway clients into a flat `AgentChatServer`.\n * Named vs draft routing is fully internal — an in-memory session-type cache\n * (populated by createSession/listSessions) determines which gateway client\n * to call, falling back to a one-time probe for ids seen only in a URL.\n */\nexport function createTrueFoundryChatServer<\n TSpec extends TfyAgentSpec = TfyAgentSpec,\n>(\n opts: CreateTrueFoundryChatServerOptions,\n): TrueFoundryChatServer<TSpec> {\n const gatewayOpts = { apiKey: opts.apiKey, baseUrl: opts.baseUrl };\n const client = opts.client ?? new AgentSessionClient(gatewayOpts);\n const privateClient =\n opts.privateClient ?? new PrivateAgentSessionClient(gatewayOpts);\n\n const sessionTypeCache = new Map<string, boolean>();\n const sessionTypeProbes = new Map<string, Promise<boolean>>();\n\n function cacheSessionType(session: {\n id: string;\n isMutable: boolean;\n }): void {\n sessionTypeCache.set(session.id, session.isMutable);\n }\n\n /**\n * Resolving a session id straight from a URL (page reload / shared link)\n * reaches the gateway before createSession or listSessions has cached the\n * type, so discover it by probing the draft endpoint and falling back to\n * the conversation endpoint. Concurrent callers share one probe.\n */\n async function probeSessionType(sessionId: string): Promise<boolean> {\n const inflight = sessionTypeProbes.get(sessionId);\n if (inflight != null) {\n return inflight;\n }\n const probe = (async () => {\n try {\n await privateClient.getDraftSession({ draftSessionId: sessionId });\n return true;\n } catch (error) {\n // Only a miss proves the id isn't a draft. Auth or transient\n // failures would otherwise be retried as a conversation session\n // and mislabel a real draft as named.\n if (!isNotFound(error)) {\n throw error;\n }\n await client.getSession({ sessionId });\n return false;\n }\n })();\n sessionTypeProbes.set(sessionId, probe);\n try {\n const isMutable = await probe;\n sessionTypeCache.set(sessionId, isMutable);\n return isMutable;\n } finally {\n sessionTypeProbes.delete(sessionId);\n }\n }\n\n async function getSessionObj(sessionId: string): Promise<GwSession> {\n const isMutable =\n sessionTypeCache.get(sessionId) ?? (await probeSessionType(sessionId));\n return isMutable\n ? privateClient.getDraftSession({ draftSessionId: sessionId })\n : client.getSession({ sessionId });\n }\n\n const server: TrueFoundryChatServer<TSpec> = {\n async createSession(req) {\n if (req.agentSpec != null) {\n const draft = await privateClient.createDraftSession({\n agentSpec: normalizeAgentSpecForGateway(req.agentSpec),\n ...(req.agentName != null ? { agentName: req.agentName } : {}),\n ...(req.tfyMetadata != null\n ? { tfyMetadata: req.tfyMetadata }\n : {}),\n });\n const session = toSession<TSpec>(draft);\n cacheSessionType(session);\n return session;\n }\n if (req.agentName != null) {\n const named = await client.createSession({\n agentName: req.agentName,\n ...(req.tfyMetadata != null\n ? { tfyMetadata: req.tfyMetadata }\n : {}),\n });\n const session = toSession<TSpec>(named);\n cacheSessionType(session);\n return session;\n }\n throw new Error(\"createSession requires agentName and/or agentSpec\");\n },\n\n async listSessions(req) {\n const page = await privateClient.listOwnedSessions({\n limit: req?.limit,\n order: req?.order,\n pageToken: req?.pageToken,\n startTimestamp: req?.startTimestamp,\n endTimestamp: req?.endTimestamp,\n ...(req?.agentId != null ? { agentName: req.agentId } : {}),\n });\n const result = await toListResult(page, (s) => toSession<TSpec>(s));\n for (const session of result.data) {\n cacheSessionType(session);\n }\n return result;\n },\n\n async getSession({ sessionId }) {\n const raw = await getSessionObj(sessionId);\n const session = toSession<TSpec>(raw);\n cacheSessionType(session);\n return session;\n },\n\n async updateSession(req) {\n const raw = await getSessionObj(req.sessionId);\n if (!isDraft(raw)) {\n throw new Error(\n \"updateSession: session is not mutable (isMutable=false)\",\n );\n }\n if (req.agentSpec != null) {\n await raw.update({\n agentSpec: normalizeAgentSpecForGateway(req.agentSpec),\n });\n }\n return toSession<TSpec>(raw);\n },\n\n createTurn(req: {\n sessionId: string;\n input?: TurnInputItem[];\n previousTurnId?: PreviousTurnIdInput;\n abortSignal?: AbortSignal;\n headers?: Record<string, string>;\n }): AsyncIterable<TurnStreamData> {\n return (async function* () {\n const session = await getSessionObj(req.sessionId);\n const prepared = session.prepareTurn({\n input: req.input,\n previousTurnId: req.previousTurnId ?? \"auto\",\n });\n yield* prepared.execute(\n { stream: true },\n {\n ...(req.abortSignal != null\n ? { abortSignal: req.abortSignal }\n : {}),\n ...(req.headers != null ? { headers: req.headers } : {}),\n },\n ) as AsyncIterable<TurnStreamData>;\n })();\n },\n\n async cancelSession({ sessionId }) {\n await (await getSessionObj(sessionId)).cancel();\n },\n\n async deleteSession({ sessionId }) {\n if (opts.deleteSession == null) {\n throw new Error(\n \"deleteSession is not on the gateway SDK. Pass deleteSession to createTrueFoundryChatServer.\",\n );\n }\n await opts.deleteSession({ sessionId });\n },\n\n // The runtime's signature offers `order`, but the gateway's listTurns\n // takes no such param — forwarding it silently did nothing.\n async listTurns({ sessionId, limit, pageToken }) {\n const raw = await getSessionObj(sessionId);\n const page = await raw.listTurns({\n ...(limit != null ? { limit } : {}),\n ...(pageToken != null ? { pageToken } : {}),\n });\n return toListResult(page, (turn) => toTurn(turn));\n },\n\n async getTurn({ sessionId, turnId }) {\n const raw = await getSessionObj(sessionId);\n return toTurn(await raw.getTurn({ turnId }));\n },\n\n async listEvents({ sessionId, pageToken, lastTurnId, limit }) {\n const raw = await getSessionObj(sessionId);\n const page = await raw.listEvents({\n ...(limit != null ? { limit } : {}),\n ...(pageToken != null ? { pageToken } : {}),\n ...(lastTurnId != null ? { lastTurnId } : {}),\n });\n return toListResult(\n page,\n (item) => item as SessionEventItem,\n );\n },\n\n async listTurnEvents({ sessionId, turnId, limit, pageToken, order }) {\n const raw = await getSessionObj(sessionId);\n const turn = await raw.getTurn({ turnId });\n const page = await turn.listEvents({\n ...(limit != null ? { limit } : {}),\n ...(pageToken != null ? { pageToken } : {}),\n ...(order != null ? { order } : {}),\n });\n return toListResult(page, (event) => event as TurnEvent);\n },\n\n async *subscribeToTurn({\n sessionId,\n turnId,\n afterSequenceNumber,\n abortSignal,\n }) {\n const raw = await getSessionObj(sessionId);\n const turn = await raw.getTurn({ turnId });\n yield* turn.stream(\n afterSequenceNumber != null ? { afterSequenceNumber } : {},\n abortSignal != null ? { abortSignal } : {},\n ) as AsyncIterable<TurnStreamData>;\n },\n\n // The gateway addresses sandboxes directly, so the turn is carried for hosts that need it\n // but is not part of this route.\n async downloadSandboxFile({ sandboxId, path }) {\n const response = await privateClient.downloadSandboxFile(sandboxId, {\n path,\n });\n return await response.blob();\n },\n\n getGatewayClients: () => ({ client, privateClient }),\n };\n\n return server;\n}\n","import type { TruefoundryGatewayApi } from \"truefoundry-gateway-sdk\";\n\nimport type { TfyAgentSpec } from \"./types.js\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value != null && typeof value === \"object\" && !Array.isArray(value);\n}\n\n/**\n * agent-ui-sdk DraftCompositeSelector writes catalog rows as `{ id, name }`.\n * Gateway AgentSpec mounts need discriminated registry shapes — without\n * `type` (and skill `fqn`), Fern serialization throws JsonError before PATCH.\n *\n * Our CP catalog sets skill `id` = version fqn and MCP `id` = server name.\n */\nexport function normalizeMcpMount(\n raw: unknown,\n): TruefoundryGatewayApi.McpServer {\n if (!isRecord(raw)) {\n throw new Error(\"mcpServers entry must be an object\");\n }\n if (raw.type === \"truefoundry-mcp-registry\" || raw.type === \"inline\") {\n return raw as unknown as TruefoundryGatewayApi.McpServer;\n }\n const name =\n (typeof raw.name === \"string\" && raw.name !== \"\" ? raw.name : null) ??\n (typeof raw.mcpName === \"string\" && raw.mcpName !== \"\"\n ? raw.mcpName\n : null) ??\n (typeof raw.id === \"string\" && raw.id !== \"\" ? raw.id : null);\n if (name == null) {\n throw new Error(\n \"mcpServers entry needs name, mcpName, or id to mount as registry MCP\",\n );\n }\n return {\n type: \"truefoundry-mcp-registry\",\n name,\n ...(Array.isArray(raw.enableTools) ? { enableTools: raw.enableTools } : {}),\n ...(typeof raw.preload === \"boolean\" ? { preload: raw.preload } : {}),\n ...(raw.config != null ? { config: raw.config } : {}),\n } as unknown as TruefoundryGatewayApi.McpServer;\n}\n\nexport function normalizeSkillMount(\n raw: unknown,\n): TruefoundryGatewayApi.SkillMount {\n if (!isRecord(raw)) {\n throw new Error(\"skills entry must be an object\");\n }\n if (raw.type === \"truefoundry-skills-registry\" || raw.type === \"git\") {\n return raw as unknown as TruefoundryGatewayApi.SkillMount;\n }\n const fqn =\n (typeof raw.fqn === \"string\" && raw.fqn !== \"\" ? raw.fqn : null) ??\n (typeof raw.id === \"string\" && raw.id !== \"\" ? raw.id : null);\n if (fqn == null) {\n throw new Error(\n \"skills entry needs fqn or id to mount as registry skill\",\n );\n }\n return {\n type: \"truefoundry-skills-registry\",\n fqn,\n ...(typeof raw.preload === \"boolean\" ? { preload: raw.preload } : {}),\n ...(raw.config != null ? { config: raw.config } : {}),\n } as unknown as TruefoundryGatewayApi.SkillMount;\n}\n\n/** Rewrite UI `{id,name}` mounts so create/update draft session can serialize. */\nexport function normalizeAgentSpecForGateway<TSpec extends TfyAgentSpec>(\n spec: TSpec,\n): TSpec {\n return {\n ...spec,\n ...(spec.mcpServers != null\n ? {\n mcpServers: spec.mcpServers.map(\n normalizeMcpMount,\n ) as TSpec[\"mcpServers\"],\n }\n : {}),\n ...(spec.skills != null\n ? {\n skills: spec.skills.map(\n normalizeSkillMount,\n ) as TSpec[\"skills\"],\n }\n : {}),\n };\n}\n","/**\n * Control Plane HTTP for builder catalog lists + gateway URL resolution.\n *\n * Wire shapes are host/CP contracts (not Fern / gateway SDK). Paths match\n * ai.tf cpApi usage — expect drift; keep normalizers defensive.\n */\n\nimport type {\n AgentSelectorEntry,\n ConnectorSelectorEntry,\n ModelSelectorEntry,\n SaveAgentRequest,\n SearchAgentSelectorParams,\n SkillSelectorEntry,\n} from \"../../server/types.js\";\nimport { normalizeAgentSpecForGateway } from \"./normalizeAgentSpec.js\";\nimport type { TfyAgentSpec } from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Selector rows — FE base + TFY mount fields\n// ---------------------------------------------------------------------------\n\nexport interface TfyModelSelectorEntry extends ModelSelectorEntry {\n /** Write into AgentSpec.model.name (model_fqn). */\n apiModel: string;\n modelId: string;\n providerAccount?: string;\n}\n\nexport interface TfySkillSelectorEntry extends SkillSelectorEntry {\n /** Version FQN — mount as RegisteredSkillMount.fqn. */\n fqn: string;\n}\n\nexport interface TfyConnectorSelectorEntry extends ConnectorSelectorEntry {\n /** Mount as RegisteredMcpServer.name. */\n mcpName: string;\n serverId?: string | null;\n authenticated?: boolean;\n}\n\nexport type TfyAgentSelectorEntry = AgentSelectorEntry;\n\nexport type CpCredentials = {\n apiKey: string;\n cpURL: string;\n};\n\n// ---------------------------------------------------------------------------\n// HTTP\n// ---------------------------------------------------------------------------\n\nfunction trimSlash(url: string): string {\n return url.replace(/\\/+$/, \"\");\n}\n\nexport async function cpFetch<T>(\n opts: CpCredentials,\n path: string,\n init?: RequestInit,\n): Promise<T> {\n const url = `${trimSlash(opts.cpURL)}${path.startsWith(\"/\") ? path : `/${path}`}`;\n const res = await fetch(url, {\n ...init,\n headers: {\n Authorization: `Bearer ${opts.apiKey}`,\n Accept: \"application/json\",\n ...(init?.headers ?? {}),\n },\n });\n if (!res.ok) {\n throw new Error(`CP ${res.status} ${res.statusText}: ${path}`);\n }\n return (await res.json()) as T;\n}\n\n// ---------------------------------------------------------------------------\n// Gateway URL resolve\n// ---------------------------------------------------------------------------\n\n/**\n * Real CP `/api/svc/v1/session` is flat `{ user, env, ... }` (no `data` wrapper).\n * `env.LLM_GATEWAY_URL` is a prefix like `/api/llm`; tenant is appended:\n * `{cpURL}{LLM_GATEWAY_URL}/{tenantName}` → e.g. `…/api/llm/truefoundry`.\n */\ntype SessionResponse = {\n user?: {\n tenantName?: string;\n };\n env?: {\n TENANT_NAME?: string;\n LLM_GATEWAY_URL?: string;\n };\n /** Legacy / alternate wrap — keep for safety. */\n data?: {\n user?: {\n tenantName?: string;\n };\n };\n};\n\nfunction joinCpPath(cpURL: string, path: string): string {\n const base = trimSlash(cpURL);\n const p = path.startsWith(\"/\") ? path : `/${path}`;\n return `${base}${p}`;\n}\n\n/**\n * Resolve gateway base URL.\n * - `gatewayURL` set → use it (no /session).\n * - else GET /api/svc/v1/session →\n * `{cpURL}{env.LLM_GATEWAY_URL ?? \"/api/llm\"}/{tenantName}`.\n * - session HTTP failure or missing tenantName → throw (no silent public fallback).\n */\nexport async function resolveGatewayURL(opts: {\n apiKey: string;\n cpURL: string;\n gatewayURL?: string;\n}): Promise<string> {\n if (opts.gatewayURL != null && opts.gatewayURL !== \"\") {\n return opts.gatewayURL;\n }\n\n const session = await cpFetch<SessionResponse>(opts, \"/api/svc/v1/session\");\n const tenantName =\n session.user?.tenantName ??\n session.env?.TENANT_NAME ??\n session.data?.user?.tenantName;\n if (tenantName == null || tenantName === \"\") {\n throw new Error(\n \"resolveGatewayURL: /api/svc/v1/session did not return user.tenantName\",\n );\n }\n\n const llmPrefix = trimSlash(session.env?.LLM_GATEWAY_URL ?? \"/api/llm\");\n return joinCpPath(opts.cpURL, `${llmPrefix}/${tenantName}`);\n}\n\n// ---------------------------------------------------------------------------\n// Models\n// ---------------------------------------------------------------------------\n\ntype RawEnabledModel = {\n id?: string;\n name?: string;\n provider?: string;\n provider_account_name?: string;\n model_id?: string;\n model_fqn?: string;\n types?: string[];\n};\n\nfunction isChatModel(row: RawEnabledModel): boolean {\n const types = row.types;\n if (types == null || types.length === 0) return true;\n return types.includes(\"chat\");\n}\n\nfunction toModelEntry(row: RawEnabledModel): TfyModelSelectorEntry | null {\n if (!isChatModel(row)) return null;\n const apiModel = row.model_fqn ?? row.id;\n const name = row.name;\n if (apiModel == null || apiModel === \"\" || name == null || name === \"\") {\n return null;\n }\n const modelId = row.model_id ?? name;\n return {\n id: apiModel,\n name,\n provider: { name: row.provider ?? \"unknown\" },\n properties: {},\n apiModel,\n modelId,\n ...(row.provider_account_name != null\n ? { providerAccount: row.provider_account_name }\n : {}),\n };\n}\n\n/**\n * Flatten enabled-models payload.\n * Nested: provider → account → models[].\n * Virtual: top-level account → models[] (array values that look like model rows).\n */\nexport function normalizeEnabledModels(raw: unknown): TfyModelSelectorEntry[] {\n if (raw == null || typeof raw !== \"object\" || Array.isArray(raw)) {\n return [];\n }\n const out: TfyModelSelectorEntry[] = [];\n const seen = new Set<string>();\n\n function pushRow(row: RawEnabledModel): void {\n const entry = toModelEntry(row);\n if (entry == null || seen.has(entry.apiModel)) return;\n seen.add(entry.apiModel);\n out.push(entry);\n }\n\n for (const level1 of Object.values(raw as Record<string, unknown>)) {\n if (Array.isArray(level1)) {\n // virtual-model style: account → models[]\n for (const row of level1) {\n if (row != null && typeof row === \"object\") {\n pushRow(row as RawEnabledModel);\n }\n }\n continue;\n }\n if (level1 == null || typeof level1 !== \"object\") continue;\n for (const level2 of Object.values(level1 as Record<string, unknown>)) {\n if (!Array.isArray(level2)) continue;\n for (const row of level2) {\n if (row != null && typeof row === \"object\") {\n pushRow(row as RawEnabledModel);\n }\n }\n }\n }\n return out;\n}\n\nexport async function listEnabledModels(\n opts: CpCredentials,\n): Promise<TfyModelSelectorEntry[]> {\n const raw = await cpFetch<unknown>(\n opts,\n \"/api/svc/v1/llm-gateway/model/enabled\",\n );\n return normalizeEnabledModels(raw);\n}\n\n// ---------------------------------------------------------------------------\n// Skills\n// ---------------------------------------------------------------------------\n\ntype RawAgentSkill = {\n id?: string;\n name?: string;\n fqn?: string;\n latest_version?: {\n id?: string;\n fqn?: string;\n manifest?: {\n ml_repo?: string;\n source?: { description?: string };\n };\n };\n};\n\nexport function normalizeAgentSkills(raw: unknown): TfySkillSelectorEntry[] {\n const data =\n raw != null &&\n typeof raw === \"object\" &&\n Array.isArray((raw as { data?: unknown }).data)\n ? ((raw as { data: RawAgentSkill[] }).data)\n : [];\n const out: TfySkillSelectorEntry[] = [];\n for (const row of data) {\n const fqn = row.latest_version?.fqn;\n const name = row.name;\n if (fqn == null || fqn === \"\" || name == null || name === \"\") continue;\n const description = row.latest_version?.manifest?.source?.description;\n out.push({\n id: fqn,\n name,\n fqn,\n ...(description != null ? { description } : {}),\n });\n }\n return out;\n}\n\nexport async function listAgentSkills(\n opts: CpCredentials,\n): Promise<TfySkillSelectorEntry[]> {\n const raw = await cpFetch<unknown>(\n opts,\n \"/api/ml/v1/agent-skills?include_empty_agent_skills=false\",\n );\n return normalizeAgentSkills(raw);\n}\n\n// ---------------------------------------------------------------------------\n// MCP\n// ---------------------------------------------------------------------------\n\ntype RawMcpServer = {\n id?: string;\n name?: string;\n fqn?: string;\n manifest?: {\n description?: string;\n url?: string;\n auth_data?: { type?: string; auth_level?: string };\n };\n authStatus?: { status?: string };\n};\n\nexport function normalizeMcpServers(raw: unknown): TfyConnectorSelectorEntry[] {\n const data =\n raw != null &&\n typeof raw === \"object\" &&\n Array.isArray((raw as { data?: unknown }).data)\n ? ((raw as { data: RawMcpServer[] }).data)\n : [];\n const out: TfyConnectorSelectorEntry[] = [];\n const seen = new Set<string>();\n for (const row of data) {\n const mcpName = row.name;\n if (mcpName == null || mcpName === \"\" || seen.has(mcpName)) continue;\n seen.add(mcpName);\n const description = row.manifest?.description;\n const authenticated = row.authStatus?.status === \"authenticated\";\n out.push({\n id: mcpName,\n name: mcpName,\n mcpName,\n ...(description != null ? { description } : {}),\n ...(row.id != null ? { serverId: row.id } : { serverId: null }),\n authenticated,\n });\n }\n return out;\n}\n\nexport async function listMcpServers(\n opts: CpCredentials,\n): Promise<TfyConnectorSelectorEntry[]> {\n const raw = await cpFetch<unknown>(opts, \"/api/svc/v1/mcp-servers\");\n return normalizeMcpServers(raw);\n}\n\n// ---------------------------------------------------------------------------\n// Agents\n// ---------------------------------------------------------------------------\n\ntype RawAgent = {\n id?: string;\n name?: string;\n latestVersionDetails?: {\n manifest?: unknown;\n };\n /** Defensive: some payloads nest manifest at the top level. */\n manifest?: unknown;\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value != null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction snakeToCamelKey(key: string): string {\n return key.replace(/_([a-z])/g, (_, letter: string) => letter.toUpperCase());\n}\n\n/** Deep snake_case → camelCase (inverse of {@link toSnakeCaseDeep}). */\nexport function toCamelCaseDeep(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(toCamelCaseDeep);\n }\n if (isRecord(value)) {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n out[snakeToCamelKey(k)] = toCamelCaseDeep(v);\n }\n return out;\n }\n return value;\n}\n\n/**\n * Map a CP AgentManifest (snake_case wire) → FE AgentSpec for Edit seeding.\n * Skills/MCP keep `{ id, name }` for draft pickers plus runtime fields\n * (`enableTools`, `preload`, `config`) so Edit → Save does not widen tool\n * access or wipe settings. Gateway registry shapes are restored on save via\n * normalizeAgentSpecForGateway.\n */\nexport function agentSpecFromCpManifest(manifest: unknown): TfyAgentSpec | undefined {\n if (!isRecord(manifest)) return undefined;\n const modelRaw = manifest.model;\n if (!isRecord(modelRaw) || typeof modelRaw.name !== \"string\" || modelRaw.name === \"\") {\n return undefined;\n }\n const model = toCamelCaseDeep(modelRaw) as TfyAgentSpec[\"model\"];\n\n // Catalog-shaped mounts (`id`/`name` + runtime fields). Not yet gateway\n // registry unions — normalizeAgentSpecForGateway restores those on save.\n const skills: Array<Record<string, unknown>> = [];\n if (Array.isArray(manifest.skills)) {\n for (const row of manifest.skills) {\n if (!isRecord(row)) continue;\n const fqn =\n typeof row.fqn === \"string\" && row.fqn !== \"\"\n ? row.fqn\n : typeof row.id === \"string\" && row.id !== \"\"\n ? row.id\n : null;\n if (fqn == null) continue;\n const camel = toCamelCaseDeep(row) as Record<string, unknown>;\n const name =\n typeof camel.name === \"string\" && camel.name !== \"\"\n ? camel.name\n : fqn;\n skills.push({\n id: fqn,\n name,\n ...(typeof camel.preload === \"boolean\"\n ? { preload: camel.preload }\n : {}),\n ...(camel.config != null ? { config: camel.config } : {}),\n });\n }\n }\n\n const mcpServers: Array<Record<string, unknown>> = [];\n const mcpRaw = Array.isArray(manifest.mcp_servers)\n ? manifest.mcp_servers\n : Array.isArray(manifest.mcpServers)\n ? manifest.mcpServers\n : [];\n for (const row of mcpRaw) {\n if (!isRecord(row)) continue;\n const camel = toCamelCaseDeep(row) as Record<string, unknown>;\n const name =\n typeof camel.name === \"string\" && camel.name !== \"\"\n ? camel.name\n : typeof camel.id === \"string\" && camel.id !== \"\"\n ? camel.id\n : null;\n if (name == null) continue;\n mcpServers.push({\n id: name,\n name,\n ...(Array.isArray(camel.enableTools)\n ? { enableTools: camel.enableTools }\n : {}),\n ...(typeof camel.preload === \"boolean\"\n ? { preload: camel.preload }\n : {}),\n ...(camel.config != null ? { config: camel.config } : {}),\n });\n }\n\n const configRaw = manifest.config;\n const config =\n configRaw != null ? (toCamelCaseDeep(configRaw) as TfyAgentSpec[\"config\"]) : undefined;\n\n return {\n model,\n ...(typeof manifest.instructions === \"string\"\n ? { instructions: manifest.instructions }\n : {}),\n ...(config != null ? { config } : {}),\n ...(skills.length > 0 ? { skills } : {}),\n ...(mcpServers.length > 0 ? { mcpServers } : {}),\n } as TfyAgentSpec;\n}\n\nexport function normalizeAgents(raw: unknown): TfyAgentSelectorEntry[] {\n const data =\n raw != null &&\n typeof raw === \"object\" &&\n Array.isArray((raw as { data?: unknown }).data)\n ? ((raw as { data: RawAgent[] }).data)\n : [];\n const out: TfyAgentSelectorEntry[] = [];\n for (const row of data) {\n if (row.name == null || row.name === \"\") continue;\n const manifest = row.latestVersionDetails?.manifest ?? row.manifest;\n const agentSpec = agentSpecFromCpManifest(manifest);\n const agentId =\n typeof row.id === \"string\" && row.id !== \"\" ? row.id : row.name;\n out.push({\n name: row.name,\n agentId,\n ...(agentSpec != null ? { agentSpec } : {}),\n });\n }\n return out;\n}\n\nexport async function listAgents(\n opts: CpCredentials,\n req?: SearchAgentSelectorParams,\n): Promise<TfyAgentSelectorEntry[]> {\n const limit = req?.limit ?? 50;\n const offset = req?.offset ?? 0;\n const namePrefix = req?.query ?? \"\";\n const qs = new URLSearchParams({\n type: \"truefoundry-agent\",\n limit: String(limit),\n offset: String(offset),\n namePrefix,\n });\n const raw = await cpFetch<unknown>(\n opts,\n `/api/svc/v1/agents?${qs.toString()}`,\n );\n return normalizeAgents(raw);\n}\n\n// ---------------------------------------------------------------------------\n// Save agent (PUT upsert by name)\n// ---------------------------------------------------------------------------\n\n/** Platform feature flags baked into every saved agent manifest. */\nexport const SAVE_AGENT_METADATA_TAGS = {\n agent: \"tfy-ai-gateway-agent\",\n TFY_ALPHA_ENABLE_OPENUI: \"true\",\n TFY_ALPHA_ENABLE_ASK_USER: \"true\",\n TFY_ALPHA_ENABLE_ASK_SECRET: \"true\",\n TFY_ALPHA_CONTEXT_MANAGEMENT:\n '{\"large_tool_response\":{\"individual_tool_response_token_threshold\":8000}}',\n TFY_ALPHA_ENABLE_FILE_DOWNLOAD: \"true\",\n} as const;\n\n/** Default ACL on create/update — everyone on the tenant gets agent-access. */\nexport const SAVE_AGENT_COLLABORATORS = [\n { subject: \"team:everyone\", role_id: \"agent-access\" },\n] as const;\n\nfunction camelToSnakeKey(key: string): string {\n return key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n/** Deep camelCase → snake_case for CP wire (model.params, config, mounts). */\nexport function toSnakeCaseDeep(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(toSnakeCaseDeep);\n }\n if (value != null && typeof value === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n out[camelToSnakeKey(k)] = toSnakeCaseDeep(v);\n }\n return out;\n }\n return value;\n}\n\nfunction mcpMountForCp(mount: unknown): Record<string, unknown> {\n const snake = toSnakeCaseDeep(mount) as Record<string, unknown>;\n if (snake.type === \"truefoundry-mcp-registry\") {\n return {\n ...snake,\n enable_tools: snake.enable_tools ?? [\"@all\"],\n preload: snake.preload ?? false,\n };\n }\n return snake;\n}\n\nfunction skillMountForCp(mount: unknown): Record<string, unknown> {\n const snake = toSnakeCaseDeep(mount) as Record<string, unknown>;\n if (snake.type === \"truefoundry-skills-registry\") {\n return {\n ...snake,\n preload: snake.preload ?? false,\n };\n }\n return snake;\n}\n\n/**\n * Build CP `manifest` for `PUT /api/svc/v1/agents`.\n * Normalizes UI catalog mounts, snake_cases gateway fields, hardcodes type /\n * metadata_tags / collaborators.\n */\nexport function buildSaveAgentManifest(\n agentName: string,\n agentSpec: TfyAgentSpec,\n): Record<string, unknown> {\n const spec = normalizeAgentSpecForGateway(agentSpec);\n const mcpServers = (spec.mcpServers ?? []).map(mcpMountForCp);\n const skills = (spec.skills ?? []).map(skillMountForCp);\n // CP AgentManifest requires description; not on FE AgentSpec yet.\n const rawDescription = (agentSpec as { description?: unknown }).description;\n const description = typeof rawDescription === \"string\" ? rawDescription : \"\";\n\n return {\n type: \"truefoundry-agent\",\n name: agentName,\n description,\n model: toSnakeCaseDeep(spec.model),\n metadata_tags: { ...SAVE_AGENT_METADATA_TAGS },\n collaborators: [...SAVE_AGENT_COLLABORATORS],\n ...(spec.instructions != null ? { instructions: spec.instructions } : {}),\n ...(spec.config != null ? { config: toSnakeCaseDeep(spec.config) } : {}),\n ...(mcpServers.length > 0 ? { mcp_servers: mcpServers } : {}),\n ...(skills.length > 0 ? { skills } : {}),\n };\n}\n\n/**\n * Upsert a named agent on the Control Plane.\n * `PUT /api/svc/v1/agents` with `{ manifest }` — name is the upsert key.\n */\nexport async function saveAgent(\n opts: CpCredentials,\n req: SaveAgentRequest<TfyAgentSpec>,\n): Promise<unknown> {\n const manifest = buildSaveAgentManifest(req.agentName, req.agentSpec);\n return cpFetch(opts, \"/api/svc/v1/agents\", {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ manifest }),\n });\n}\n","import type { AgentBuilderServer } from \"../../server/types.js\";\nimport {\n listAgents,\n listAgentSkills,\n listEnabledModels,\n listMcpServers,\n resolveGatewayURL,\n saveAgent,\n type TfyAgentSelectorEntry,\n type TfyConnectorSelectorEntry,\n type TfyModelSelectorEntry,\n type TfySkillSelectorEntry,\n} from \"./cp.js\";\nimport {\n createTrueFoundryChatServer,\n type TrueFoundryChatServer,\n} from \"./chatServer.js\";\nimport type { TfyAgentSpec } from \"./types.js\";\n\nexport type CreateTrueFoundryAgentUIServerOptions = {\n apiKey: string;\n /** Control Plane base URL (builder lists + optional /session for gateway resolve). */\n cpURL: string;\n /**\n * Gateway base URL. When omitted, resolved via\n * `GET {cpURL}/api/svc/v1/session` → `{cpURL}{env.LLM_GATEWAY_URL ?? \"/api/llm\"}/{tenantName}`.\n * Session failure throws (no silent public-gateway fallback).\n */\n gatewayURL?: string;\n};\n\nexport type TrueFoundryAgentUIServer<TSpec extends TfyAgentSpec = TfyAgentSpec> =\n TrueFoundryChatServer<TSpec> &\n AgentBuilderServer<\n TSpec,\n TfyModelSelectorEntry,\n TfySkillSelectorEntry,\n TfyConnectorSelectorEntry,\n TfyAgentSelectorEntry,\n unknown\n >;\n\nfunction credentialsKey(opts: CreateTrueFoundryAgentUIServerOptions): string {\n return `${opts.apiKey}\\0${opts.cpURL}\\0${opts.gatewayURL ?? \"\"}`;\n}\n\nconst inflight = new Map<\n string,\n Promise<TrueFoundryAgentUIServer<TfyAgentSpec>>\n>();\n\n/**\n * Full pack: gateway chat + Control Plane builder lists.\n *\n * Same `apiKey` bearer is used for CP and gateway. Concurrent calls with the\n * same credentials share one in-flight promise (React Strict Mode safe).\n */\nexport async function createTrueFoundryAgentUIServer<\n TSpec extends TfyAgentSpec = TfyAgentSpec,\n>(\n opts: CreateTrueFoundryAgentUIServerOptions,\n): Promise<TrueFoundryAgentUIServer<TSpec>> {\n const key = credentialsKey(opts);\n const existing = inflight.get(key);\n if (existing != null) {\n return existing as Promise<TrueFoundryAgentUIServer<TSpec>>;\n }\n\n const promise = (async () => {\n const baseUrl = await resolveGatewayURL(opts);\n const chat = createTrueFoundryChatServer<TSpec>({\n apiKey: opts.apiKey,\n baseUrl,\n });\n const cp = { apiKey: opts.apiKey, cpURL: opts.cpURL };\n\n const server: TrueFoundryAgentUIServer<TSpec> = {\n ...chat,\n getCapabilities: async () => ({\n data: {\n sandbox: { enabled: true },\n skill: { enabled: true },\n settings: { enabled: true },\n },\n }),\n getModels: () => listEnabledModels(cp),\n getSkills: () => listAgentSkills(cp),\n getMcp: () => listMcpServers(cp),\n searchAgents: (req) => listAgents(cp, req),\n saveAgent: (req) => saveAgent(cp, req),\n };\n return server as TrueFoundryAgentUIServer<TfyAgentSpec>;\n })();\n\n inflight.set(key, promise);\n try {\n return (await promise) as TrueFoundryAgentUIServer<TSpec>;\n } finally {\n inflight.delete(key);\n }\n}\n","/**\n * Point-of-use narrowing for the event half of the gateway protocol.\n *\n * `AgentChatServer` hardcodes the runtime's event types on listEvents,\n * listTurnEvents, subscribeToTurn and createTurn — there is no\n * generic to override them from here. So instead of typing those channels,\n * hosts call these guards on the values they receive.\n *\n * They validate rather than cast: this data comes off the network, and the\n * runtime types the relevant fields as `unknown` precisely because nothing\n * has checked them yet.\n */\n\nimport type {\n TfyMcpServerInitInfo,\n TfyMcpToolInfo,\n TfyModelMessageUsage,\n TfySystemToolInfo,\n TfyThreadState,\n TfyToolInfo,\n} from \"./types.js\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction hasNumbers<K extends string>(\n value: unknown,\n keys: readonly K[],\n): value is Record<string, unknown> & Record<K, number> {\n return isRecord(value) && keys.every((key) => typeof value[key] === \"number\");\n}\n\n/**\n * Identifies built-in tools such as `ask_user_question` and `create_sub_agent`.\n * Note `toolInfo` is legitimately absent on streamed deltas, so callers must\n * keep their `function.name` fallback rather than treating absence as an error.\n */\nexport function isTfySystemToolInfo(\n toolInfo: unknown,\n): toolInfo is TfySystemToolInfo {\n return (\n isRecord(toolInfo) &&\n toolInfo.type === \"truefoundry-system\" &&\n typeof toolInfo.name === \"string\"\n );\n}\n\n/** Carries `serverId` / `serverName`, so the UI can attribute a call to its MCP server. */\nexport function isTfyMcpToolInfo(toolInfo: unknown): toolInfo is TfyMcpToolInfo {\n return (\n isRecord(toolInfo) &&\n toolInfo.type === \"mcp\" &&\n typeof toolInfo.name === \"string\" &&\n typeof toolInfo.serverId === \"string\" &&\n typeof toolInfo.serverName === \"string\"\n );\n}\n\nexport function isTfyToolInfo(toolInfo: unknown): toolInfo is TfyToolInfo {\n return isTfySystemToolInfo(toolInfo) || isTfyMcpToolInfo(toolInfo);\n}\n\nconst USAGE_BREAKDOWN_KEYS = [\n \"harness\",\n \"skills\",\n \"instructions\",\n \"toolDefinitions\",\n \"messages\",\n] as const;\n\n/**\n * Token usage including the TrueFoundry-specific `inputTokensBreakdown`, which\n * attributes input tokens across harness, skills, instructions, tool\n * definitions and messages.\n */\nexport function getTfyUsage(\n source: { usage?: unknown } | null | undefined,\n): TfyModelMessageUsage | undefined {\n const usage = source?.usage;\n if (!hasNumbers(usage, [\"inputTokens\", \"outputTokens\"])) {\n return undefined;\n }\n if (!hasNumbers(usage.inputTokensBreakdown, USAGE_BREAKDOWN_KEYS)) {\n return undefined;\n }\n return usage as unknown as TfyModelMessageUsage;\n}\n\n/**\n * Completion state of a sub-agent thread. The runtime types `thread.done`'s\n * `state` as `unknown`, so a sub-agent that errored is otherwise\n * indistinguishable from one that succeeded.\n */\nexport function getTfyThreadState(\n event: { state?: unknown } | null | undefined,\n): TfyThreadState | undefined {\n const state = event?.state;\n if (!isRecord(state)) {\n return undefined;\n }\n if (state.status === \"done\" && isRecord(state.output)) {\n return state as unknown as TfyThreadState;\n }\n if (state.status === \"error\" && typeof state.error === \"string\") {\n return state as unknown as TfyThreadState;\n }\n return undefined;\n}\n\n/**\n * Servers from an `mcp.initialize` event, including each one's `transportType`.\n * The runtime models this event with an index signature, so the array is\n * `unknown` until checked.\n */\nexport function getTfyMcpInitServers(\n event: { mcpServers?: unknown } | null | undefined,\n): TfyMcpServerInitInfo[] | undefined {\n const servers = event?.mcpServers;\n if (!Array.isArray(servers)) {\n return undefined;\n }\n const valid = servers.every(\n (server) =>\n isRecord(server) &&\n typeof server.id === \"string\" &&\n typeof server.name === \"string\",\n );\n return valid ? (servers as TfyMcpServerInitInfo[]) : undefined;\n}\n"],"mappings":"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","names":["inflight","isRecord","isRecord"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as _assistant_ui_core from '@assistant-ui/core';
|
|
2
2
|
import { ExternalStoreSharedOptions, AttachmentAdapter, SpeechSynthesisAdapter, DictationAdapter, RealtimeVoiceAdapter, FeedbackAdapter, ThreadAssistantMessagePart, ThreadMessage, AppendMessage, ExportedMessageRepositoryItem, RemoteThreadListAdapter } from '@assistant-ui/core';
|
|
3
|
-
import { A as AgentSpec, a as AgentChatServer, T as TurnEvent, b as ThreadCreatedEvent, U as UserToolResponseEvent, M as McpAuthRequiredEvent, c as UserToolApprovalEvent, d as Turn, e as TurnInputItem, S as Session } from './types-
|
|
4
|
-
export { f as AgentBuilderCapabilitiesResponse, g as AgentBuilderServer, h as
|
|
3
|
+
import { A as AgentSpec, a as AgentChatServer, T as TurnEvent, b as ThreadCreatedEvent, U as UserToolResponseEvent, M as McpAuthRequiredEvent, c as UserToolApprovalEvent, d as Turn, e as TurnInputItem, S as Session } from './types-VU3Fc17W.js';
|
|
4
|
+
export { f as AgentBuilderCapabilitiesResponse, g as AgentBuilderServer, h as AgentCapabilityConfig, i as AgentLibraryEntry, j as AgentRuntimeConfig, k as AgentSelectorEntry, l as AgentSkill, m as AgentUIServer, n as AgentUIServerPort, o as ApprovalDecision, p as AuthenticateConnectorRequest, C as CatalogServer, q as ConnectorAuth, r as ConnectorAuthApiKey, s as ConnectorAuthNone, t as ConnectorAuthOAuth, u as ConnectorAuthPublic, v as ConnectorAuthPublicApiKey, w as ConnectorAuthPublicNone, x as ConnectorAuthPublicOAuth, y as ConnectorAuthType, z as ConnectorAuthenticationResult, B as ConnectorBase, D as ConnectorCatalogEntry, E as ConnectorCatalogServer, F as ConnectorConfigBase, G as ConnectorSelectorEntry, H as ConnectorState, I as CreateConnectorRequest, J as CreateModelProviderRequest, K as CreateSandboxProviderRequest, L as CreateSandboxRequest, N as CreateSessionRequest, O as CreateSkillRequest, P as CreateSkillRequestBase, Q as DefinedSkill, R as GithubSkill, V as ImportGithubSkillRequest, W as ListResult, X as ListSessionsOrder, Y as ListSessionsParams, Z as McpServerMount, _ as Model, $ as ModelCatalogServer, a0 as ModelEntry, a1 as ModelMessageEvent, a2 as ModelParams, a3 as ModelProperties, a4 as ModelProviderBase, a5 as ModelProviderCatalogEntry, a6 as ModelProviderConfigBase, a7 as ModelSelection, a8 as ModelSelectorEntry, a9 as PageParams, aa as PreviousTurnIdInput, ab as ProviderEntry, ac as ProviderType, ad as RegistrySkill, ae as SandboxBase, af as SandboxCatalogEntry, ag as SandboxCatalogServer, ah as SandboxConfig, ai as SandboxCreatedEvent, aj as SandboxProviderBase, ak as SandboxProviderCatalogEntry, al as SandboxProviderConfig, am as SaveAgentRequest, an as SaveAgentResult, ao as SearchAgentSelectorParams, ap as SearchAgentsParams, aq as SelectRegistrySkillRequest, ar as SessionEventItem, as as SkillBase, at as SkillCatalogEntry, au as SkillCatalogServer, av as SkillConfigBase, aw as SkillMount, ax as SkillSelectorEntry, ay as ToolApprovalRequiredEvent, az as ToolBase, aA as ToolCall, aB as ToolResponseRequiredEvent, aC as TurnState, aD as TurnStateDone, aE as TurnStreamData, aF as TurnStreamingEvent, aG as UpdateConnectorRequest, aH as UpdateModelProviderRequest, aI as UpdateSandboxProviderRequest, aJ as UpdateSandboxRequest, aK as UpdateSessionRequest, aL as UserMessage } from './types-VU3Fc17W.js';
|
|
5
5
|
import * as _assistant_ui_core_internal from '@assistant-ui/core/internal';
|
|
6
6
|
export { isEventDelta, mergeEventDelta } from './server/index.js';
|
|
7
7
|
export { CreateTrueFoundryAgentUIServerOptions, CreateTrueFoundryChatServerOptions, RequireApprovalToolSelectorItem, RequireApprovalToolsSelectorTag, TfyAgentSelectorEntry, TfyAgentSpec, TfyConnectorSelectorEntry, TfyCreateSessionRequest, TfyFinishReason, TfyListSessionsParams, TfyMcpServerInitInfo, TfyMcpServerMount, TfyMcpToolInfo, TfyModelMessageUsage, TfyModelParams, TfyModelSelectorEntry, TfyResponseFormat, TfyRuntimeConfig, TfySession, TfySkillMount, TfySkillSelectorEntry, TfySubject, TfySystemToolInfo, TfyThreadState, TfyToolInfo, TfyTurn, TfyTurnCancelledReason, TfyTurnState, TfyTurnStateDoneOutput, ToolsSelectorItem, ToolsSelectorTag, TrueFoundryAgentUIServer, TrueFoundryChatServer, createTrueFoundryAgentUIServer, createTrueFoundryChatServer, getTfyMcpInitServers, getTfyThreadState, getTfyUsage, isTfyMcpToolInfo, isTfySystemToolInfo, isTfyToolInfo } from './plugins/truefoundry-agent-server-adapter/index.js';
|
|
@@ -230,6 +230,11 @@ type TrueFoundryDraftRuntimeExtras = {
|
|
|
230
230
|
isSpecSyncing: boolean;
|
|
231
231
|
specError: unknown | null;
|
|
232
232
|
updateAgentSpec: (update: AgentSpecUpdate) => void;
|
|
233
|
+
flushAgentSpec: () => Promise<void>;
|
|
234
|
+
adoptAgentSpec: (request: {
|
|
235
|
+
agentSpec: AgentSpec;
|
|
236
|
+
updatedAt?: string;
|
|
237
|
+
}) => void;
|
|
233
238
|
};
|
|
234
239
|
type TrueFoundryRuntimeExtras = {
|
|
235
240
|
pendingApprovals: PendingApproval[];
|
|
@@ -237,6 +242,7 @@ type TrueFoundryRuntimeExtras = {
|
|
|
237
242
|
pendingMcpAuth: {
|
|
238
243
|
mcpServers: McpAuthRequiredEvent["mcpServers"];
|
|
239
244
|
} | null;
|
|
245
|
+
resumeUnavailable: boolean;
|
|
240
246
|
sandboxId: string | undefined;
|
|
241
247
|
respondToToolApproval: (response: RespondToToolApprovalOptions) => void;
|
|
242
248
|
respondToToolResponse: (response: RespondToToolResponseOptions) => void;
|
|
@@ -297,6 +303,11 @@ declare const useTrueFoundryHistoryPagination: () => {
|
|
|
297
303
|
isLoadingOlderHistory: boolean;
|
|
298
304
|
loadOlderHistory: () => Promise<void>;
|
|
299
305
|
};
|
|
306
|
+
/**
|
|
307
|
+
* True while a turn runs that this server cannot stream, so its result will not
|
|
308
|
+
* arrive in this client. Falls back to `false` on runtimes that predate the flag.
|
|
309
|
+
*/
|
|
310
|
+
declare const useTrueFoundryResumeUnavailable: () => boolean;
|
|
300
311
|
/** Returns a function to reset (re-submit) a user turn from any render context. */
|
|
301
312
|
declare const useTrueFoundryResetFromTurn: () => (turnId: string) => Promise<void>;
|
|
302
313
|
/** Current draft agent spec and sync state (draft mode only). */
|
|
@@ -307,9 +318,18 @@ declare const useTrueFoundryAgentSpec: () => {
|
|
|
307
318
|
isSpecSyncing: boolean;
|
|
308
319
|
specError: unknown | null;
|
|
309
320
|
updateAgentSpec: (update: AgentSpecUpdate) => void;
|
|
321
|
+
flushAgentSpec: () => Promise<void>;
|
|
322
|
+
adoptAgentSpec: (request: {
|
|
323
|
+
agentSpec: AgentSpec;
|
|
324
|
+
updatedAt?: string;
|
|
325
|
+
}) => void;
|
|
310
326
|
};
|
|
311
327
|
/** Returns a draft spec updater from any render context. */
|
|
312
328
|
declare const useTrueFoundryUpdateAgentSpec: () => (update: Parameters<TrueFoundryDraftRuntimeExtras["updateAgentSpec"]>[0]) => void | undefined;
|
|
329
|
+
/** Flushes any pending draft-spec synchronization before a coordinated write. */
|
|
330
|
+
declare const useTrueFoundryFlushAgentSpec: () => () => Promise<void>;
|
|
331
|
+
/** Adopts a spec already persisted by another server operation without syncing again. */
|
|
332
|
+
declare const useTrueFoundryAdoptAgentSpec: () => (request: Parameters<TrueFoundryDraftRuntimeExtras["adoptAgentSpec"]>[0]) => void | undefined;
|
|
313
333
|
|
|
314
334
|
type RequiredActionInput = Extract<TurnInputItem, UserToolApprovalEvent | UserToolResponseEvent>;
|
|
315
335
|
declare function messageHasPendingRequiredActions(message: ThreadMessage | undefined): boolean;
|
|
@@ -334,4 +354,4 @@ declare function getSession(server: AgentChatServer, sessionId: string): Promise
|
|
|
334
354
|
*/
|
|
335
355
|
declare const trueFoundryAttachmentAdapter: AttachmentAdapter;
|
|
336
356
|
|
|
337
|
-
export { AgentChatServer, AgentSpec, type AgentSpecUpdate, type ConvertTurnsResult, type DraftAgentConfig, type DraftSession, type DraftSessionBridge, type McpAuthMessageCustomMetadata, McpAuthRequiredEvent, type NamedAgentConfig, type PendingApproval, type PendingToolResponse, ROOT_THREAD_ID, type SandboxMessageCustomMetadata, Session, type SubAgentArtifact, type SubAgentCustomMetadata, type SubAgentMessageCustomMetadata, TOOL_RESPONSE_THREAD_ID_CUSTOM_KEY, ThreadCreatedEvent, type ToolApprovalMessageCustomMetadata, type ToolResponseMessageCustomMetadata, type TrueFoundryAgentConfig, type TrueFoundryDraftRuntimeExtras, type TrueFoundryMessageCustomMetadata, type TrueFoundryRuntimeExtras, Turn, TurnEvent, TurnInputItem, type UseTrueFoundryAgentRuntimeOptions, type UserMessageContent, UserToolApprovalEvent, UserToolResponseEvent, buildEditedUserMessageContent, buildTurnAssistantContent, buildUserMessageContent, collectApprovalInputs, collectRequiredActionInputs, collectResponseInputs, convertTurnsToThreadMessages, createDraftSessionBridge, createTrueFoundryDraftThreadListAdapter, createTrueFoundryOwnedSessionsThreadListAdapter, createTrueFoundryThreadListAdapter, draftSessionTitle, findPausedAssistantMessage, getSession, getTurnMessageContent, mergeAgentSpec, messageHasPendingApprovals, messageHasPendingRequiredActions, messageHasPendingResponses, parseTurnIdFromMessageId, repositoryItemsFromMessages, toTrueFoundryApprovalInputs, trueFoundryAttachmentAdapter, trueFoundryExtras, useTrueFoundryAgentRuntime, useTrueFoundryAgentSpec, useTrueFoundryApprovals, useTrueFoundryCancel, useTrueFoundryDownloadSandboxFile, useTrueFoundryHistoryPagination, useTrueFoundryMcpAuth, useTrueFoundryReload, useTrueFoundryResetFromTurn, useTrueFoundryRespondToToolApproval, useTrueFoundryRespondToToolResponse, useTrueFoundryResumeMcpAuth, useTrueFoundrySandboxId, useTrueFoundryToolResponses, useTrueFoundryTurnId, useTrueFoundryUpdateAgentSpec };
|
|
357
|
+
export { AgentChatServer, AgentSpec, type AgentSpecUpdate, type ConvertTurnsResult, type DraftAgentConfig, type DraftSession, type DraftSessionBridge, type McpAuthMessageCustomMetadata, McpAuthRequiredEvent, type NamedAgentConfig, type PendingApproval, type PendingToolResponse, ROOT_THREAD_ID, type SandboxMessageCustomMetadata, Session, type SubAgentArtifact, type SubAgentCustomMetadata, type SubAgentMessageCustomMetadata, TOOL_RESPONSE_THREAD_ID_CUSTOM_KEY, ThreadCreatedEvent, type ToolApprovalMessageCustomMetadata, type ToolResponseMessageCustomMetadata, type TrueFoundryAgentConfig, type TrueFoundryDraftRuntimeExtras, type TrueFoundryMessageCustomMetadata, type TrueFoundryRuntimeExtras, Turn, TurnEvent, TurnInputItem, type UseTrueFoundryAgentRuntimeOptions, type UserMessageContent, UserToolApprovalEvent, UserToolResponseEvent, buildEditedUserMessageContent, buildTurnAssistantContent, buildUserMessageContent, collectApprovalInputs, collectRequiredActionInputs, collectResponseInputs, convertTurnsToThreadMessages, createDraftSessionBridge, createTrueFoundryDraftThreadListAdapter, createTrueFoundryOwnedSessionsThreadListAdapter, createTrueFoundryThreadListAdapter, draftSessionTitle, findPausedAssistantMessage, getSession, getTurnMessageContent, mergeAgentSpec, messageHasPendingApprovals, messageHasPendingRequiredActions, messageHasPendingResponses, parseTurnIdFromMessageId, repositoryItemsFromMessages, toTrueFoundryApprovalInputs, trueFoundryAttachmentAdapter, trueFoundryExtras, useTrueFoundryAdoptAgentSpec, useTrueFoundryAgentRuntime, useTrueFoundryAgentSpec, useTrueFoundryApprovals, useTrueFoundryCancel, useTrueFoundryDownloadSandboxFile, useTrueFoundryFlushAgentSpec, useTrueFoundryHistoryPagination, useTrueFoundryMcpAuth, useTrueFoundryReload, useTrueFoundryResetFromTurn, useTrueFoundryRespondToToolApproval, useTrueFoundryRespondToToolResponse, useTrueFoundryResumeMcpAuth, useTrueFoundryResumeUnavailable, useTrueFoundrySandboxId, useTrueFoundryToolResponses, useTrueFoundryTurnId, useTrueFoundryUpdateAgentSpec };
|
package/dist/index.js
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
isTfyMcpToolInfo,
|
|
12
12
|
isTfySystemToolInfo,
|
|
13
13
|
isTfyToolInfo
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-S4SH2KT2.js";
|
|
15
15
|
|
|
16
16
|
// src/useTrueFoundryAgentRuntime.ts
|
|
17
17
|
import {
|
|
@@ -1534,7 +1534,6 @@ function attachRunningTurn(snapshot, runningTurn) {
|
|
|
1534
1534
|
if (runningTurn == null) {
|
|
1535
1535
|
return snapshot;
|
|
1536
1536
|
}
|
|
1537
|
-
applyUserToolResponsesToFold(snapshot.fold, runningTurn.input ?? []);
|
|
1538
1537
|
const pendingUserText = extractTurnUserText(runningTurn.input);
|
|
1539
1538
|
return replaceSessionSnapshot(snapshot, {
|
|
1540
1539
|
runningTurn,
|
|
@@ -1549,10 +1548,63 @@ function attachRunningTurn(snapshot, runningTurn) {
|
|
|
1549
1548
|
} : {}
|
|
1550
1549
|
});
|
|
1551
1550
|
}
|
|
1552
|
-
|
|
1551
|
+
function findOpenTurnCreated(itemsAsc) {
|
|
1552
|
+
let open;
|
|
1553
|
+
for (const item of itemsAsc) {
|
|
1554
|
+
if (item.event.type === "turn.created") {
|
|
1555
|
+
open = { turnId: item.turnId, event: item.event };
|
|
1556
|
+
} else if (item.event.type === "turn.done") {
|
|
1557
|
+
open = void 0;
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
return open;
|
|
1561
|
+
}
|
|
1562
|
+
function turnFromCreatedEvent(options) {
|
|
1563
|
+
const { sessionId, turnId, event } = options;
|
|
1564
|
+
return {
|
|
1565
|
+
id: turnId,
|
|
1566
|
+
sessionId,
|
|
1567
|
+
state: { status: "running" },
|
|
1568
|
+
createdAt: event.createdAt,
|
|
1569
|
+
...event.input != null ? { input: event.input } : {},
|
|
1570
|
+
...event.previousTurnId === void 0 ? {} : { previousTurnId: event.previousTurnId }
|
|
1571
|
+
};
|
|
1572
|
+
}
|
|
1573
|
+
async function resolveSessionTip(options) {
|
|
1574
|
+
const { server, sessionId, itemsAsc } = options;
|
|
1575
|
+
const open = findOpenTurnCreated(itemsAsc);
|
|
1576
|
+
if (open != null) {
|
|
1577
|
+
const continuationInput = open.event.input ?? [];
|
|
1578
|
+
if (typeof server.getTurn === "function") {
|
|
1579
|
+
try {
|
|
1580
|
+
const turn = await server.getTurn({
|
|
1581
|
+
sessionId,
|
|
1582
|
+
turnId: open.turnId
|
|
1583
|
+
});
|
|
1584
|
+
if (turn.state.status === "running") {
|
|
1585
|
+
return {
|
|
1586
|
+
runningTurn: turn,
|
|
1587
|
+
continuationInput: turn.input ?? continuationInput
|
|
1588
|
+
};
|
|
1589
|
+
}
|
|
1590
|
+
return { continuationInput: turn.input ?? continuationInput };
|
|
1591
|
+
} catch {
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
return {
|
|
1595
|
+
runningTurn: turnFromCreatedEvent({
|
|
1596
|
+
sessionId,
|
|
1597
|
+
turnId: open.turnId,
|
|
1598
|
+
event: open.event
|
|
1599
|
+
}),
|
|
1600
|
+
continuationInput
|
|
1601
|
+
};
|
|
1602
|
+
}
|
|
1553
1603
|
const turnsPage = await server.listTurns({ sessionId, limit: 1 });
|
|
1554
|
-
const
|
|
1555
|
-
|
|
1604
|
+
const tip = turnsPage.data[0];
|
|
1605
|
+
return tip?.state?.status === "running" ? { runningTurn: tip, continuationInput: tip.input ?? [] } : { continuationInput: [] };
|
|
1606
|
+
}
|
|
1607
|
+
async function buildSnapshotFromSessionEvents(server, sessionId, onProgress) {
|
|
1556
1608
|
const window = await fetchSessionEventsWindow(server, sessionId);
|
|
1557
1609
|
const historyPagination = {
|
|
1558
1610
|
hasOlder: window.hasOlder,
|
|
@@ -1564,7 +1616,13 @@ async function buildSnapshotFromSessionEvents(server, sessionId, onProgress) {
|
|
|
1564
1616
|
historyEvents: window.itemsAsc,
|
|
1565
1617
|
historyPagination
|
|
1566
1618
|
});
|
|
1567
|
-
|
|
1619
|
+
const tip = await resolveSessionTip({
|
|
1620
|
+
server,
|
|
1621
|
+
sessionId,
|
|
1622
|
+
itemsAsc: window.itemsAsc
|
|
1623
|
+
});
|
|
1624
|
+
applyUserToolResponsesToFold(withHistory.fold, tip.continuationInput);
|
|
1625
|
+
return attachRunningTurn(withHistory, tip.runningTurn);
|
|
1568
1626
|
}
|
|
1569
1627
|
async function prependOlderSessionHistory(server, sessionId, snapshot) {
|
|
1570
1628
|
const pagination = snapshot.historyPagination;
|
|
@@ -2540,6 +2598,12 @@ var EMPTY_DRAFT_EXTRAS = {
|
|
|
2540
2598
|
specError: null,
|
|
2541
2599
|
updateAgentSpec: () => {
|
|
2542
2600
|
throw new Error("Draft agent extras are only available in draft mode.");
|
|
2601
|
+
},
|
|
2602
|
+
flushAgentSpec: async () => {
|
|
2603
|
+
throw new Error("Draft agent extras are only available in draft mode.");
|
|
2604
|
+
},
|
|
2605
|
+
adoptAgentSpec: () => {
|
|
2606
|
+
throw new Error("Draft agent extras are only available in draft mode.");
|
|
2543
2607
|
}
|
|
2544
2608
|
};
|
|
2545
2609
|
|
|
@@ -2784,6 +2848,29 @@ function useDraftAgentSpec({
|
|
|
2784
2848
|
await inFlightFlushRef.current;
|
|
2785
2849
|
}
|
|
2786
2850
|
}, []);
|
|
2851
|
+
const adoptAgentSpec = useCallback(
|
|
2852
|
+
({
|
|
2853
|
+
agentSpec: persistedSpec,
|
|
2854
|
+
updatedAt
|
|
2855
|
+
}) => {
|
|
2856
|
+
if (syncTimeoutRef.current != null) {
|
|
2857
|
+
clearTimeout(syncTimeoutRef.current);
|
|
2858
|
+
syncTimeoutRef.current = void 0;
|
|
2859
|
+
}
|
|
2860
|
+
syncGenerationRef.current++;
|
|
2861
|
+
pendingFlushRef.current = void 0;
|
|
2862
|
+
inFlightFlushRef.current = void 0;
|
|
2863
|
+
localDirtyRef.current = false;
|
|
2864
|
+
if (updatedAt !== void 0) {
|
|
2865
|
+
lastUpdatedAtRef.current = updatedAt;
|
|
2866
|
+
}
|
|
2867
|
+
agentSpecRef.current = persistedSpec;
|
|
2868
|
+
setAgentSpec(persistedSpec);
|
|
2869
|
+
setSpecError(null);
|
|
2870
|
+
setIsSpecSyncing(false);
|
|
2871
|
+
},
|
|
2872
|
+
[]
|
|
2873
|
+
);
|
|
2787
2874
|
const takeTurnHeaderTimestamp = useCallback(async () => {
|
|
2788
2875
|
await flushPendingSpecSyncNow();
|
|
2789
2876
|
const updatedAt = lastUpdatedAtRef.current;
|
|
@@ -2820,6 +2907,8 @@ function useDraftAgentSpec({
|
|
|
2820
2907
|
isSpecSyncing: enabled ? isSpecSyncing : false,
|
|
2821
2908
|
specError: enabled ? specError : null,
|
|
2822
2909
|
updateAgentSpec,
|
|
2910
|
+
flushAgentSpec: flushPendingSpecSyncNow,
|
|
2911
|
+
adoptAgentSpec,
|
|
2823
2912
|
takeTurnHeaderTimestamp
|
|
2824
2913
|
}),
|
|
2825
2914
|
[
|
|
@@ -2829,6 +2918,8 @@ function useDraftAgentSpec({
|
|
|
2829
2918
|
isSpecLoading,
|
|
2830
2919
|
isSpecSyncing,
|
|
2831
2920
|
specError,
|
|
2921
|
+
flushPendingSpecSyncNow,
|
|
2922
|
+
adoptAgentSpec,
|
|
2832
2923
|
takeTurnHeaderTimestamp,
|
|
2833
2924
|
updateAgentSpec
|
|
2834
2925
|
]
|
|
@@ -2937,9 +3028,7 @@ async function* streamTurnContent(server, sessionId, foldState, options, abortSi
|
|
|
2937
3028
|
}
|
|
2938
3029
|
async function* resumeTurnStream(server, sessionId, turnId, foldState, abortSignal, afterSequenceNumber, groupRootBaseline) {
|
|
2939
3030
|
if (server.subscribeToTurn == null) {
|
|
2940
|
-
|
|
2941
|
-
"resumeTurnStream requires AgentChatServer.subscribeToTurn"
|
|
2942
|
-
);
|
|
3031
|
+
return;
|
|
2943
3032
|
}
|
|
2944
3033
|
const onAbort = () => {
|
|
2945
3034
|
void server.cancelSession({ sessionId }).catch(() => void 0);
|
|
@@ -3109,6 +3198,7 @@ function useTrueFoundryAgentMessages({
|
|
|
3109
3198
|
);
|
|
3110
3199
|
const [isLoadingOlderHistory, setIsLoadingOlderHistory] = useState2(false);
|
|
3111
3200
|
const [loadRetryTrigger, setLoadRetryTrigger] = useState2(0);
|
|
3201
|
+
const [resumeUnavailable, setResumeUnavailable] = useState2(false);
|
|
3112
3202
|
const snapshotRef = useRef2(snapshot);
|
|
3113
3203
|
snapshotRef.current = snapshot;
|
|
3114
3204
|
const loadOlderInflightRef = useRef2(null);
|
|
@@ -3123,12 +3213,17 @@ function useTrueFoundryAgentMessages({
|
|
|
3123
3213
|
const createdAtByMessageIdRef = useRef2(/* @__PURE__ */ new Map());
|
|
3124
3214
|
const abortControllerRef = useRef2(null);
|
|
3125
3215
|
const activeRunRef = useRef2(null);
|
|
3216
|
+
const resumeUnavailableRef = useRef2(false);
|
|
3126
3217
|
const runningTurnRef = useRef2(void 0);
|
|
3127
3218
|
const loadGenerationRef = useRef2(0);
|
|
3128
3219
|
const streamGenerationRef = useRef2(0);
|
|
3129
3220
|
const lazilyCreatedSessionIdRef = useRef2(void 0);
|
|
3130
3221
|
const initialLoadStartedForRef = useRef2(void 0);
|
|
3131
3222
|
const skipInitialPromotionLoadForRef = useRef2(void 0);
|
|
3223
|
+
const markResumeUnavailable = useCallback2((value) => {
|
|
3224
|
+
resumeUnavailableRef.current = value;
|
|
3225
|
+
setResumeUnavailable(value);
|
|
3226
|
+
}, []);
|
|
3132
3227
|
const projectOptions = useMemo2(
|
|
3133
3228
|
() => ({
|
|
3134
3229
|
getCreatedAt: (messageId, fallback) => {
|
|
@@ -3154,6 +3249,7 @@ function useTrueFoundryAgentMessages({
|
|
|
3154
3249
|
const abortController = new AbortController();
|
|
3155
3250
|
abortControllerRef.current = abortController;
|
|
3156
3251
|
setIsRunning(true);
|
|
3252
|
+
markResumeUnavailable(false);
|
|
3157
3253
|
const run = (async () => {
|
|
3158
3254
|
let pendingStreamUpdate = null;
|
|
3159
3255
|
let streamUpdateRaf = null;
|
|
@@ -3266,6 +3362,7 @@ function useTrueFoundryAgentMessages({
|
|
|
3266
3362
|
const generation = ++loadGenerationRef.current;
|
|
3267
3363
|
++streamGenerationRef.current;
|
|
3268
3364
|
setIsRunning(false);
|
|
3365
|
+
markResumeUnavailable(false);
|
|
3269
3366
|
abortControllerRef.current?.abort();
|
|
3270
3367
|
loadOlderInflightRef.current = null;
|
|
3271
3368
|
createdAtByMessageIdRef.current = /* @__PURE__ */ new Map();
|
|
@@ -3295,6 +3392,11 @@ function useTrueFoundryAgentMessages({
|
|
|
3295
3392
|
setIsLoading(false);
|
|
3296
3393
|
if (loadedSnapshot.runningTurn != null) {
|
|
3297
3394
|
const turn = loadedSnapshot.runningTurn;
|
|
3395
|
+
if (server.subscribeToTurn == null) {
|
|
3396
|
+
setIsRunning(true);
|
|
3397
|
+
markResumeUnavailable(true);
|
|
3398
|
+
return;
|
|
3399
|
+
}
|
|
3298
3400
|
const isContinuation = !extractTurnUserText(turn.input);
|
|
3299
3401
|
void runStream(
|
|
3300
3402
|
(signal) => resumeTurnStream(
|
|
@@ -3510,7 +3612,11 @@ function useTrueFoundryAgentMessages({
|
|
|
3510
3612
|
);
|
|
3511
3613
|
await server.cancelSession({ sessionId: conversationSessionId }).catch(() => void 0);
|
|
3512
3614
|
await activeRunRef.current?.catch(() => void 0);
|
|
3513
|
-
|
|
3615
|
+
if (resumeUnavailableRef.current) {
|
|
3616
|
+
markResumeUnavailable(false);
|
|
3617
|
+
setIsRunning(false);
|
|
3618
|
+
}
|
|
3619
|
+
}, [server, sessionId, markResumeUnavailable]);
|
|
3514
3620
|
const isRunningRef = useRef2(isRunning);
|
|
3515
3621
|
isRunningRef.current = isRunning;
|
|
3516
3622
|
const trySendCollectedRequiredActions = useCallback2(
|
|
@@ -3570,6 +3676,10 @@ function useTrueFoundryAgentMessages({
|
|
|
3570
3676
|
if (turn == null) {
|
|
3571
3677
|
return;
|
|
3572
3678
|
}
|
|
3679
|
+
if (server.subscribeToTurn == null) {
|
|
3680
|
+
markResumeUnavailable(true);
|
|
3681
|
+
return;
|
|
3682
|
+
}
|
|
3573
3683
|
await runStream(
|
|
3574
3684
|
(signal) => resumeTurnStream(
|
|
3575
3685
|
server,
|
|
@@ -3718,6 +3828,7 @@ function useTrueFoundryAgentMessages({
|
|
|
3718
3828
|
return {
|
|
3719
3829
|
messages,
|
|
3720
3830
|
isRunning,
|
|
3831
|
+
resumeUnavailable,
|
|
3721
3832
|
isLoading,
|
|
3722
3833
|
isLoadingOlderHistory,
|
|
3723
3834
|
hasOlderHistory,
|
|
@@ -3784,6 +3895,7 @@ function useTrueFoundryAgentRuntimeImpl(options, pendingAgentSpecRef) {
|
|
|
3784
3895
|
const {
|
|
3785
3896
|
messages,
|
|
3786
3897
|
isRunning,
|
|
3898
|
+
resumeUnavailable,
|
|
3787
3899
|
isLoading,
|
|
3788
3900
|
isLoadingOlderHistory,
|
|
3789
3901
|
hasOlderHistory,
|
|
@@ -3857,7 +3969,9 @@ function useTrueFoundryAgentRuntimeImpl(options, pendingAgentSpecRef) {
|
|
|
3857
3969
|
isSpecLoading: draftSpec.isSpecLoading,
|
|
3858
3970
|
isSpecSyncing: draftSpec.isSpecSyncing,
|
|
3859
3971
|
specError: draftSpec.specError,
|
|
3860
|
-
updateAgentSpec: draftSpec.updateAgentSpec
|
|
3972
|
+
updateAgentSpec: draftSpec.updateAgentSpec,
|
|
3973
|
+
flushAgentSpec: draftSpec.flushAgentSpec,
|
|
3974
|
+
adoptAgentSpec: draftSpec.adoptAgentSpec
|
|
3861
3975
|
};
|
|
3862
3976
|
}, [agent.mode, draftSpec]);
|
|
3863
3977
|
return useExternalStoreRuntime({
|
|
@@ -3869,6 +3983,7 @@ function useTrueFoundryAgentRuntimeImpl(options, pendingAgentSpecRef) {
|
|
|
3869
3983
|
pendingApprovals,
|
|
3870
3984
|
pendingToolResponses,
|
|
3871
3985
|
pendingMcpAuth,
|
|
3986
|
+
resumeUnavailable,
|
|
3872
3987
|
sandboxId,
|
|
3873
3988
|
respondToToolApproval,
|
|
3874
3989
|
respondToToolResponse,
|
|
@@ -4103,6 +4218,7 @@ var useTrueFoundryHistoryPagination = () => {
|
|
|
4103
4218
|
[extras]
|
|
4104
4219
|
);
|
|
4105
4220
|
};
|
|
4221
|
+
var useTrueFoundryResumeUnavailable = () => trueFoundryExtras.use((e) => e.resumeUnavailable, false) ?? false;
|
|
4106
4222
|
var useTrueFoundryResetFromTurn = () => {
|
|
4107
4223
|
const aui = useAui2();
|
|
4108
4224
|
return (turnId) => trueFoundryExtras.get(aui).resetFromTurn(turnId);
|
|
@@ -4118,6 +4234,14 @@ var useTrueFoundryUpdateAgentSpec = () => {
|
|
|
4118
4234
|
const aui = useAui2();
|
|
4119
4235
|
return (update) => trueFoundryExtras.get(aui).draft?.updateAgentSpec(update);
|
|
4120
4236
|
};
|
|
4237
|
+
var useTrueFoundryFlushAgentSpec = () => {
|
|
4238
|
+
const aui = useAui2();
|
|
4239
|
+
return () => trueFoundryExtras.get(aui).draft?.flushAgentSpec() ?? Promise.resolve();
|
|
4240
|
+
};
|
|
4241
|
+
var useTrueFoundryAdoptAgentSpec = () => {
|
|
4242
|
+
const aui = useAui2();
|
|
4243
|
+
return (request) => trueFoundryExtras.get(aui).draft?.adoptAgentSpec(request);
|
|
4244
|
+
};
|
|
4121
4245
|
|
|
4122
4246
|
// src/attachmentAdapter.ts
|
|
4123
4247
|
import {
|
|
@@ -4206,11 +4330,13 @@ export {
|
|
|
4206
4330
|
toTrueFoundryApprovalInputs,
|
|
4207
4331
|
trueFoundryAttachmentAdapter,
|
|
4208
4332
|
trueFoundryExtras,
|
|
4333
|
+
useTrueFoundryAdoptAgentSpec,
|
|
4209
4334
|
useTrueFoundryAgentRuntime,
|
|
4210
4335
|
useTrueFoundryAgentSpec,
|
|
4211
4336
|
useTrueFoundryApprovals,
|
|
4212
4337
|
useTrueFoundryCancel,
|
|
4213
4338
|
useTrueFoundryDownloadSandboxFile,
|
|
4339
|
+
useTrueFoundryFlushAgentSpec,
|
|
4214
4340
|
useTrueFoundryHistoryPagination,
|
|
4215
4341
|
useTrueFoundryMcpAuth,
|
|
4216
4342
|
useTrueFoundryReload,
|
|
@@ -4218,6 +4344,7 @@ export {
|
|
|
4218
4344
|
useTrueFoundryRespondToToolApproval,
|
|
4219
4345
|
useTrueFoundryRespondToToolResponse,
|
|
4220
4346
|
useTrueFoundryResumeMcpAuth,
|
|
4347
|
+
useTrueFoundryResumeUnavailable,
|
|
4221
4348
|
useTrueFoundrySandboxId,
|
|
4222
4349
|
useTrueFoundryToolResponses,
|
|
4223
4350
|
useTrueFoundryTurnId,
|