@truefoundry/assistant-ui-runtime 0.1.20 → 0.1.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-O7OIV5IZ.js → chunk-G4TO3HAP.js} +99 -20
- package/dist/chunk-G4TO3HAP.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -8
- package/dist/index.js.map +1 -1
- package/dist/plugins/truefoundry-agent-server-adapter/index.d.ts +10 -3
- package/dist/plugins/truefoundry-agent-server-adapter/index.js +1 -1
- package/dist/server/index.d.ts +2 -2
- package/dist/{types-CQnbe6Qh.d.ts → types-CUUft1YT.d.ts} +116 -5
- package/package.json +1 -1
- package/src/convertTurnMessages.test.ts +2 -2
- package/src/index.ts +10 -0
- package/src/mcpAuth.ts +3 -8
- package/src/plugins/truefoundry-agent-server-adapter/cp.test.ts +235 -6
- package/src/plugins/truefoundry-agent-server-adapter/cp.ts +163 -15
- package/src/plugins/truefoundry-agent-server-adapter/createTrueFoundryAgentUIServer.ts +2 -2
- package/src/plugins/truefoundry-agent-server-adapter/index.ts +26 -3
- package/src/plugins/truefoundry-agent-server-adapter/types.ts +10 -0
- package/src/plugins/truefoundry-agent-server-adapter/types.typecheck.ts +14 -0
- package/src/server/index.ts +8 -0
- package/src/server/types.ts +133 -4
- package/dist/chunk-O7OIV5IZ.js.map +0 -1
|
@@ -587,6 +587,43 @@ function toCamelCaseDeep(value) {
|
|
|
587
587
|
}
|
|
588
588
|
return value;
|
|
589
589
|
}
|
|
590
|
+
function stringRecordFromCp(raw) {
|
|
591
|
+
if (!isRecord2(raw)) return void 0;
|
|
592
|
+
const out = {};
|
|
593
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
594
|
+
if (typeof value === "string") out[key] = value;
|
|
595
|
+
}
|
|
596
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
597
|
+
}
|
|
598
|
+
function variablesFromCp(raw) {
|
|
599
|
+
if (!isRecord2(raw)) return void 0;
|
|
600
|
+
const out = {};
|
|
601
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
602
|
+
if (typeof value === "string") {
|
|
603
|
+
out[key] = value;
|
|
604
|
+
} else if (isRecord2(value) && typeof value.default_value === "string") {
|
|
605
|
+
out[key] = value.default_value;
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
609
|
+
}
|
|
610
|
+
function responseFormatFromCp(raw) {
|
|
611
|
+
if (!isRecord2(raw)) return void 0;
|
|
612
|
+
if (raw.type === "text") return { type: "text" };
|
|
613
|
+
if (raw.type === "json_object") return { type: "json_object" };
|
|
614
|
+
if (raw.type !== "json_schema") return void 0;
|
|
615
|
+
const wireSchema = isRecord2(raw.json_schema) ? raw.json_schema : void 0;
|
|
616
|
+
if (wireSchema == null || typeof wireSchema.name !== "string") return void 0;
|
|
617
|
+
return {
|
|
618
|
+
type: "json_schema",
|
|
619
|
+
jsonSchema: {
|
|
620
|
+
name: wireSchema.name,
|
|
621
|
+
...typeof wireSchema.description === "string" ? { description: wireSchema.description } : {},
|
|
622
|
+
...isRecord2(wireSchema.schema) ? { schema: wireSchema.schema } : {},
|
|
623
|
+
...typeof wireSchema.strict === "boolean" || wireSchema.strict === null ? { strict: wireSchema.strict } : {}
|
|
624
|
+
}
|
|
625
|
+
};
|
|
626
|
+
}
|
|
590
627
|
function agentSpecFromCpManifest(manifest) {
|
|
591
628
|
if (!isRecord2(manifest)) return void 0;
|
|
592
629
|
const modelRaw = manifest.model;
|
|
@@ -600,13 +637,13 @@ function agentSpecFromCpManifest(manifest) {
|
|
|
600
637
|
if (!isRecord2(row)) continue;
|
|
601
638
|
const fqn = typeof row.fqn === "string" && row.fqn !== "" ? row.fqn : typeof row.id === "string" && row.id !== "" ? row.id : null;
|
|
602
639
|
if (fqn == null) continue;
|
|
603
|
-
const
|
|
604
|
-
const name = typeof
|
|
640
|
+
const camel2 = toCamelCaseDeep(row);
|
|
641
|
+
const name = typeof camel2.name === "string" && camel2.name !== "" ? camel2.name : fqn;
|
|
605
642
|
skills.push({
|
|
606
643
|
id: fqn,
|
|
607
644
|
name,
|
|
608
|
-
...typeof
|
|
609
|
-
...
|
|
645
|
+
...typeof camel2.preload === "boolean" ? { preload: camel2.preload } : {},
|
|
646
|
+
...camel2.config != null ? { config: camel2.config } : {}
|
|
610
647
|
});
|
|
611
648
|
}
|
|
612
649
|
}
|
|
@@ -614,22 +651,35 @@ function agentSpecFromCpManifest(manifest) {
|
|
|
614
651
|
const mcpRaw = Array.isArray(manifest.mcp_servers) ? manifest.mcp_servers : Array.isArray(manifest.mcpServers) ? manifest.mcpServers : [];
|
|
615
652
|
for (const row of mcpRaw) {
|
|
616
653
|
if (!isRecord2(row)) continue;
|
|
617
|
-
const
|
|
618
|
-
const name = typeof
|
|
654
|
+
const camel2 = toCamelCaseDeep(row);
|
|
655
|
+
const name = typeof camel2.name === "string" && camel2.name !== "" ? camel2.name : typeof camel2.id === "string" && camel2.id !== "" ? camel2.id : null;
|
|
619
656
|
if (name == null) continue;
|
|
620
657
|
mcpServers.push({
|
|
621
658
|
id: name,
|
|
622
659
|
name,
|
|
623
|
-
...Array.isArray(
|
|
624
|
-
...typeof
|
|
625
|
-
...
|
|
660
|
+
...Array.isArray(camel2.enableTools) ? { enableTools: camel2.enableTools } : {},
|
|
661
|
+
...typeof camel2.preload === "boolean" ? { preload: camel2.preload } : {},
|
|
662
|
+
...camel2.config != null ? { config: camel2.config } : {}
|
|
626
663
|
});
|
|
627
664
|
}
|
|
628
665
|
const configRaw = manifest.config;
|
|
629
666
|
const config = configRaw != null ? toCamelCaseDeep(configRaw) : void 0;
|
|
667
|
+
const camel = toCamelCaseDeep(manifest);
|
|
668
|
+
const description = typeof camel.description === "string" ? camel.description : void 0;
|
|
669
|
+
const messages = Array.isArray(camel.messages) ? camel.messages : void 0;
|
|
670
|
+
const collaborators = Array.isArray(camel.collaborators) ? camel.collaborators : void 0;
|
|
671
|
+
const variables = variablesFromCp(manifest.variables);
|
|
672
|
+
const tags = stringRecordFromCp(manifest.tags);
|
|
673
|
+
const responseFormat = responseFormatFromCp(manifest.response_format);
|
|
630
674
|
return {
|
|
631
675
|
model,
|
|
632
676
|
...typeof manifest.instructions === "string" ? { instructions: manifest.instructions } : {},
|
|
677
|
+
...description != null ? { description } : {},
|
|
678
|
+
...variables != null ? { variables } : {},
|
|
679
|
+
...messages != null ? { messages } : {},
|
|
680
|
+
...responseFormat != null ? { responseFormat } : {},
|
|
681
|
+
...tags != null ? { tags } : {},
|
|
682
|
+
...collaborators != null ? { collaborators } : {},
|
|
633
683
|
...config != null ? { config } : {},
|
|
634
684
|
...skills.length > 0 ? { skills } : {},
|
|
635
685
|
...mcpServers.length > 0 ? { mcpServers } : {}
|
|
@@ -667,7 +717,7 @@ async function listAgents(opts, req) {
|
|
|
667
717
|
);
|
|
668
718
|
return normalizeAgents(raw);
|
|
669
719
|
}
|
|
670
|
-
var
|
|
720
|
+
var SAVE_AGENT_TAGS = {
|
|
671
721
|
agent: "tfy-ai-gateway-agent",
|
|
672
722
|
TFY_ALPHA_ENABLE_OPENUI: "true",
|
|
673
723
|
TFY_ALPHA_ENABLE_ASK_USER: "true",
|
|
@@ -715,32 +765,61 @@ function skillMountForCp(mount) {
|
|
|
715
765
|
}
|
|
716
766
|
return snake;
|
|
717
767
|
}
|
|
768
|
+
function responseFormatForCp(responseFormat) {
|
|
769
|
+
const out = {};
|
|
770
|
+
for (const [key, value] of Object.entries(responseFormat)) {
|
|
771
|
+
if (key === "jsonSchema" && isRecord2(value)) {
|
|
772
|
+
const inner = {};
|
|
773
|
+
for (const [innerKey, innerValue] of Object.entries(value)) {
|
|
774
|
+
inner[camelToSnakeKey(innerKey)] = innerKey === "schema" ? innerValue : toSnakeCaseDeep(innerValue);
|
|
775
|
+
}
|
|
776
|
+
out.json_schema = inner;
|
|
777
|
+
continue;
|
|
778
|
+
}
|
|
779
|
+
out[camelToSnakeKey(key)] = toSnakeCaseDeep(value);
|
|
780
|
+
}
|
|
781
|
+
return out;
|
|
782
|
+
}
|
|
718
783
|
function buildSaveAgentManifest(agentName, agentSpec) {
|
|
719
784
|
const spec = normalizeAgentSpecForGateway(agentSpec);
|
|
720
785
|
const mcpServers = (spec.mcpServers ?? []).map(mcpMountForCp);
|
|
721
786
|
const skills = (spec.skills ?? []).map(skillMountForCp);
|
|
722
|
-
const
|
|
723
|
-
const
|
|
787
|
+
const { tags, variables, responseFormat, ...wireFields } = spec;
|
|
788
|
+
const snake = toSnakeCaseDeep(wireFields);
|
|
724
789
|
return {
|
|
725
790
|
type: "truefoundry-agent",
|
|
726
791
|
name: agentName,
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
collaborators: [...SAVE_AGENT_COLLABORATORS],
|
|
731
|
-
...
|
|
732
|
-
...
|
|
792
|
+
...snake,
|
|
793
|
+
description: typeof snake.description === "string" ? snake.description : "",
|
|
794
|
+
tags: tags ?? { ...SAVE_AGENT_TAGS },
|
|
795
|
+
collaborators: Array.isArray(snake.collaborators) ? snake.collaborators : [...SAVE_AGENT_COLLABORATORS],
|
|
796
|
+
...variables != null ? { variables } : {},
|
|
797
|
+
...responseFormat != null ? { response_format: responseFormatForCp(responseFormat) } : {},
|
|
733
798
|
...mcpServers.length > 0 ? { mcp_servers: mcpServers } : {},
|
|
734
799
|
...skills.length > 0 ? { skills } : {}
|
|
735
800
|
};
|
|
736
801
|
}
|
|
802
|
+
function nonEmptyString2(value) {
|
|
803
|
+
return typeof value === "string" && value !== "" ? value : void 0;
|
|
804
|
+
}
|
|
805
|
+
function saveAgentResultFromCp(raw) {
|
|
806
|
+
const root = isRecord2(raw) ? raw : {};
|
|
807
|
+
const data = isRecord2(root.data) ? root.data : {};
|
|
808
|
+
const agentId = nonEmptyString2(data.agentId) ?? nonEmptyString2(data.id);
|
|
809
|
+
const versionId = nonEmptyString2(data.agentId) != null ? nonEmptyString2(data.id) : void 0;
|
|
810
|
+
return {
|
|
811
|
+
...agentId != null ? { agentId } : {},
|
|
812
|
+
...versionId != null ? { versionId } : {}
|
|
813
|
+
};
|
|
814
|
+
}
|
|
737
815
|
async function saveAgent(opts, req) {
|
|
738
816
|
const manifest = buildSaveAgentManifest(req.agentName, req.agentSpec);
|
|
739
|
-
|
|
817
|
+
const raw = await cpFetch(opts, "/api/svc/v1/agents", {
|
|
740
818
|
method: "PUT",
|
|
741
819
|
headers: { "Content-Type": "application/json" },
|
|
742
820
|
body: JSON.stringify({ manifest })
|
|
743
821
|
});
|
|
822
|
+
return saveAgentResultFromCp(raw);
|
|
744
823
|
}
|
|
745
824
|
|
|
746
825
|
// src/plugins/truefoundry-agent-server-adapter/createTrueFoundryAgentUIServer.ts
|
|
@@ -853,4 +932,4 @@ export {
|
|
|
853
932
|
getTfyThreadState,
|
|
854
933
|
getTfyMcpInitServers
|
|
855
934
|
};
|
|
856
|
-
//# sourceMappingURL=chunk-
|
|
935
|
+
//# sourceMappingURL=chunk-G4TO3HAP.js.map
|
|
@@ -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/modelReasoningEffort.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};\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 // 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\nfunction nonEmptyString(value: unknown): string | null {\n return typeof value === \"string\" && value !== \"\" ? value : null;\n}\n\n/** Optional BaseMcpServer fields shared by registry + inline mounts. */\nfunction mcpOptionalFields(raw: Record<string, unknown>): Record<string, unknown> {\n return {\n ...(Array.isArray(raw.enableTools) ? { enableTools: raw.enableTools } : {}),\n ...(Array.isArray(raw.disableTools) ? { disableTools: raw.disableTools } : {}),\n ...(Array.isArray(raw.preloadTools) ? { preloadTools: raw.preloadTools } : {}),\n ...(Array.isArray(raw.requireApprovalForTools)\n ? { requireApprovalForTools: raw.requireApprovalForTools }\n : {}),\n ...(typeof raw.preload === \"boolean\" ? { preload: raw.preload } : {}),\n ...(raw.config != null ? { config: raw.config } : {}),\n };\n}\n\nfunction skillOptionalFields(raw: Record<string, unknown>): Record<string, unknown> {\n return {\n ...(typeof raw.preload === \"boolean\" ? { preload: raw.preload } : {}),\n ...(raw.config != null ? { config: raw.config } : {}),\n };\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 * Always rebuild allowlisted fields so FE `id` / display `name` / registry\n * `url` never leak onto the wire.\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\n if (raw.type === \"inline\") {\n const name = nonEmptyString(raw.name);\n const url = nonEmptyString(raw.url);\n if (name == null || url == null) {\n throw new Error(\"inline mcpServers entry needs name and url\");\n }\n return {\n type: \"inline\",\n name,\n url,\n ...mcpOptionalFields(raw),\n } as unknown as TruefoundryGatewayApi.McpServer;\n }\n\n const name =\n nonEmptyString(raw.name) ??\n nonEmptyString(raw.mcpName) ??\n nonEmptyString(raw.id);\n if (name == null) {\n throw new Error(\n \"mcpServers entry needs name, mcpName, or id to mount as registry MCP\",\n );\n }\n\n return {\n type: \"truefoundry-mcp-registry\",\n name,\n ...mcpOptionalFields(raw),\n // Always set after the spread so missing enableTools defaults to [@all].\n enableTools: Array.isArray(raw.enableTools) ? raw.enableTools : [\"@all\"],\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\n if (raw.type === \"git\") {\n const url = nonEmptyString(raw.url);\n const name = nonEmptyString(raw.name);\n const ref = nonEmptyString(raw.ref);\n if (url == null || name == null || ref == null) {\n throw new Error(\"git skills entry needs url, name, and ref\");\n }\n return {\n type: \"git\",\n url,\n name,\n ref,\n ...(nonEmptyString(raw.path) != null ? { path: raw.path } : {}),\n ...skillOptionalFields(raw),\n } as unknown as TruefoundryGatewayApi.SkillMount;\n }\n\n const fqn = nonEmptyString(raw.fqn) ?? nonEmptyString(raw.id);\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 ...skillOptionalFields(raw),\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 * CP provider-account metadata → ModelSelectorEntry.properties.reasoningEfforts.\n *\n * Source: GET /api/svc/v1/provider-accounts/providers\n * Join key: `${providerSlug}/${modelId}` (NOT model_fqn).\n * Host (ai.tf) uses the same rules for the draft reasoning-effort picker.\n */\n\nexport type ModelParamDef = {\n key: string;\n type?: string;\n defaultValue?: string | number | boolean | null;\n maxValue?: number;\n minValue?: number;\n /** Legacy — prefer `supportedValues` from the real API. */\n options?: string[];\n supportedValues?: string[];\n};\n\nexport type ModelMetadata = {\n thinking?: boolean;\n removeParams?: string[];\n params?: ModelParamDef[];\n features?: string[];\n limits?: {\n context_window?: number;\n max_output_tokens?: number;\n max_tokens?: number;\n };\n /** Provider-wide defaults; reasoning_effort often lives only here. */\n defaultProviderParams?: {\n params?: ModelParamDef[];\n };\n};\n\nconst DEFAULT_EFFORT_LEVELS: readonly string[] = [\n \"minimal\",\n \"low\",\n \"medium\",\n \"high\",\n] as const;\n\nconst EFFORT_SET = new Set([\n \"minimal\",\n \"low\",\n \"medium\",\n \"high\",\n \"xhigh\",\n \"max\",\n]);\n\n/** Canonical metadata key: `<providerSlug>/<modelId>` (NOT model_fqn). */\nexport function metadataKey(providerSlug: string, modelId: string): string {\n return `${providerSlug}/${modelId}`;\n}\n\nfunction providerSlugFromType(type: string | undefined): string | null {\n if (type == null) return null;\n const prefix = \"provider-account/\";\n if (!type.startsWith(prefix)) return null;\n const slug = type.slice(prefix.length).trim();\n return slug.length > 0 ? slug : null;\n}\n\nfunction findReasoningEffortParam(\n meta: ModelMetadata | undefined,\n): ModelParamDef | undefined {\n const fromModel = meta?.params?.find((p) => p.key === \"reasoning_effort\");\n if (fromModel != null) return fromModel;\n return meta?.defaultProviderParams?.params?.find(\n (p) => p.key === \"reasoning_effort\",\n );\n}\n\n/**\n * Show efforts when thinking is on, reasoning_effort is not removed, and the\n * provider slug is not exact `\"openai\"` (azure-openai / openai-main still show).\n */\nexport function showsReasoningEffort(\n meta: ModelMetadata | undefined,\n providerSlug: string,\n): boolean {\n if (providerSlug === \"openai\") return false;\n if (meta == null) return false;\n if (meta.thinking !== true) return false;\n if (meta.removeParams?.includes(\"reasoning_effort\")) return false;\n return true;\n}\n\nexport function getEffortOptions(meta: ModelMetadata | undefined): string[] {\n const param = findReasoningEffortParam(meta);\n const raw = param?.supportedValues ?? param?.options;\n if (raw == null || raw.length === 0) return [...DEFAULT_EFFORT_LEVELS];\n const filtered = raw.filter((v) => EFFORT_SET.has(v));\n return filtered.length > 0 ? filtered : [...DEFAULT_EFFORT_LEVELS];\n}\n\n/** Options for the selector, or undefined when the picker should stay hidden. */\nexport function reasoningEffortsForModel(\n meta: ModelMetadata | undefined,\n providerSlug: string,\n): string[] | undefined {\n if (!showsReasoningEffort(meta, providerSlug)) return undefined;\n return getEffortOptions(meta);\n}\n\ntype RawIntegration = {\n type?: string;\n metadata?: Record<string, ModelMetadata>;\n};\n\ntype RawProvider = {\n type?: string;\n integrations?: RawIntegration[];\n};\n\nfunction providersFromJson(json: unknown): RawProvider[] {\n if (Array.isArray(json)) return json as RawProvider[];\n if (json != null && typeof json === \"object\") {\n const obj = json as Record<string, unknown>;\n for (const key of [\"data\", \"providers\", \"result\"] as const) {\n const value = obj[key];\n if (Array.isArray(value)) return value as RawProvider[];\n }\n }\n return [];\n}\n\n/** Build a map keyed by `<providerSlug>/<modelId>` from the providers API. */\nexport function buildMetadataMap(raw: unknown): Map<string, ModelMetadata> {\n const map = new Map<string, ModelMetadata>();\n for (const provider of providersFromJson(raw)) {\n const slug = providerSlugFromType(provider.type);\n if (slug == null) continue;\n for (const integration of provider.integrations ?? []) {\n const metadata = integration.metadata;\n if (metadata == null) continue;\n for (const [modelId, meta] of Object.entries(metadata)) {\n if (!modelId.trim()) continue;\n map.set(metadataKey(slug, modelId), meta);\n }\n }\n }\n return map;\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 {\n buildMetadataMap,\n metadataKey,\n reasoningEffortsForModel,\n} from \"./modelReasoningEffort.js\";\nimport { normalizeAgentSpecForGateway } from \"./normalizeAgentSpec.js\";\nimport type { TfyAgentSpec, TfySaveAgentResult } from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Selector rows — FE base + TFY mount fields\n// ---------------------------------------------------------------------------\n\nexport interface TfyModelSelectorEntry extends ModelSelectorEntry {\n /**\n * model_fqn for AgentSpec.model.name.\n * Same value as {@link ModelSelectorEntry.name} / `id` — trueforge-ui writes\n * `name` into the spec; keep this alias for hosts that still read `apiModel`.\n */\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 // Gateway AgentSpec.model.name must be model_fqn (e.g. account/model-id).\n // trueforge-ui DraftModelSelector writes ModelSelectorEntry.name into that\n // field, so `name` is the FQN — not the CP short display label.\n const apiModel = row.model_fqn ?? row.id;\n if (apiModel == null || apiModel === \"\") {\n return null;\n }\n const modelId = row.model_id ?? row.name ?? apiModel;\n return {\n id: apiModel,\n name: apiModel,\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\n/**\n * Attach `properties.reasoningEfforts` from provider-account metadata when the\n * model supports thinking. Pure — used by {@link listEnabledModels} and tests.\n */\nexport function enrichModelsWithReasoningEfforts(\n models: TfyModelSelectorEntry[],\n providerMetadataRaw: unknown,\n): TfyModelSelectorEntry[] {\n const map = buildMetadataMap(providerMetadataRaw);\n if (map.size === 0) return models;\n return models.map((model) => {\n const meta = map.get(metadataKey(model.provider.name, model.modelId));\n const reasoningEfforts = reasoningEffortsForModel(\n meta,\n model.provider.name,\n );\n if (reasoningEfforts == null) return model;\n return {\n ...model,\n properties: { ...model.properties, reasoningEfforts },\n };\n });\n}\n\nexport async function listEnabledModels(\n opts: CpCredentials,\n): Promise<TfyModelSelectorEntry[]> {\n // Parallel: providers is enrichment-only; soft-fail keeps models usable.\n const [raw, providers] = await Promise.all([\n cpFetch<unknown>(opts, \"/api/svc/v1/llm-gateway/model/enabled\"),\n cpFetch<unknown>(\n opts,\n \"/api/svc/v1/provider-accounts/providers\",\n ).catch(() => null),\n ]);\n const models = normalizeEnabledModels(raw);\n if (providers == null) return models;\n return enrichModelsWithReasoningEfforts(models, providers);\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/** Keys are user data (e.g. metadata tag names) — copied verbatim, never case-converted. */\nfunction stringRecordFromCp(raw: unknown): Record<string, string> | undefined {\n if (!isRecord(raw)) return undefined;\n const out: Record<string, string> = {};\n for (const [key, value] of Object.entries(raw)) {\n if (typeof value === \"string\") out[key] = value;\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\n/**\n * Variable names are user keys and must survive verbatim. Values appear as\n * plain strings in new manifests and `{ default_value }` records in older\n * ones; both collapse to the resolved string.\n */\nfunction variablesFromCp(raw: unknown): Record<string, string> | undefined {\n if (!isRecord(raw)) return undefined;\n const out: Record<string, string> = {};\n for (const [key, value] of Object.entries(raw)) {\n if (typeof value === \"string\") {\n out[key] = value;\n } else if (isRecord(value) && typeof value.default_value === \"string\") {\n out[key] = value.default_value;\n }\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\n/**\n * Rebuild the gateway ResponseFormat from the wire shape. Only the envelope\n * key changes case (`json_schema` → `jsonSchema`); the `schema` body is a\n * user-authored JSON schema whose property names must not be rewritten.\n */\nfunction responseFormatFromCp(raw: unknown): TfyAgentSpec[\"responseFormat\"] {\n if (!isRecord(raw)) return undefined;\n if (raw.type === \"text\") return { type: \"text\" };\n if (raw.type === \"json_object\") return { type: \"json_object\" };\n if (raw.type !== \"json_schema\") return undefined;\n const wireSchema = isRecord(raw.json_schema) ? raw.json_schema : undefined;\n if (wireSchema == null || typeof wireSchema.name !== \"string\") return undefined;\n return {\n type: \"json_schema\",\n jsonSchema: {\n name: wireSchema.name,\n ...(typeof wireSchema.description === \"string\"\n ? { description: wireSchema.description }\n : {}),\n ...(isRecord(wireSchema.schema) ? { schema: wireSchema.schema } : {}),\n ...(typeof wireSchema.strict === \"boolean\" || wireSchema.strict === null\n ? { strict: wireSchema.strict }\n : {}),\n },\n };\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 // Wire-named pass-through fields (description, messages, collaborators)\n // need no mount remapping — one camelCase pass and a shape guard each.\n // Guards drop malformed values instead of seeding the editor with garbage.\n const camel = toCamelCaseDeep(manifest) as Record<string, unknown>;\n const description =\n typeof camel.description === \"string\" ? camel.description : undefined;\n const messages = Array.isArray(camel.messages)\n ? (camel.messages as TfyAgentSpec[\"messages\"])\n : undefined;\n const collaborators = Array.isArray(camel.collaborators)\n ? (camel.collaborators as TfyAgentSpec[\"collaborators\"])\n : undefined;\n\n // User-keyed fields are read from the RAW manifest: their keys are data\n // (tag names like \"TFY_ALPHA_ENABLE_OPENUI\", variable names like\n // \"my_city\", JSON-schema property names), and case-converting them\n // corrupts saved agents (e.g. \"TFY_ALPHA…\" → \"tfyAlpha…\" → on the next\n // save \"_t_f_y__a_l_p_h_a__…\").\n const variables = variablesFromCp(manifest.variables);\n const tags = stringRecordFromCp(manifest.tags);\n const responseFormat = responseFormatFromCp(manifest.response_format);\n\n return {\n model,\n ...(typeof manifest.instructions === \"string\"\n ? { instructions: manifest.instructions }\n : {}),\n ...(description != null ? { description } : {}),\n ...(variables != null ? { variables } : {}),\n ...(messages != null ? { messages } : {}),\n ...(responseFormat != null ? { responseFormat } : {}),\n ...(tags != null ? { tags } : {}),\n ...(collaborators != null ? { collaborators } : {}),\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_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 * Snake-case only the response_format envelope (`jsonSchema` → `json_schema`);\n * the `schema` body is a user-authored JSON schema whose property names must\n * not be rewritten. Inverse of {@link responseFormatFromCp}.\n */\nfunction responseFormatForCp(\n responseFormat: NonNullable<TfyAgentSpec[\"responseFormat\"]>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(responseFormat)) {\n if (key === \"jsonSchema\" && isRecord(value)) {\n const inner: Record<string, unknown> = {};\n for (const [innerKey, innerValue] of Object.entries(value)) {\n inner[camelToSnakeKey(innerKey)] =\n innerKey === \"schema\" ? innerValue : toSnakeCaseDeep(innerValue);\n }\n out.json_schema = inner;\n continue;\n }\n out[camelToSnakeKey(key)] = toSnakeCaseDeep(value);\n }\n return out;\n}\n\n/**\n * Build CP `manifest` for `PUT /api/svc/v1/agents`.\n *\n * Wire-named spec fields are snake-cased and spread so any field the host\n * puts on the spec reaches the wire without this adapter enumerating it.\n * tags / variables / responseFormat are pulled out FIRST because\n * their keys are user data — snake-casing a tag named\n * \"TFY_ALPHA_ENABLE_OPENUI\" would corrupt it to \"_t_f_y__a_l_p_h_a__…\" —\n * and re-attached verbatim after the spread.\n *\n * Field order matters:\n * 1. `...snake` — everything wire-named the host provided.\n * 2. description / tags / collaborators — CP requires these, so\n * platform defaults fill in only when the host omitted them.\n * 3. mcp_servers / skills — overwrite the spread values because catalog\n * mounts need remapping to gateway registry shapes (mcpMountForCp /\n * skillMountForCp), which plain snake-casing cannot do.\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 const { tags, variables, responseFormat, ...wireFields } = spec;\n const snake = toSnakeCaseDeep(wireFields) as Record<string, unknown>;\n\n return {\n type: \"truefoundry-agent\",\n name: agentName,\n ...snake,\n description: typeof snake.description === \"string\" ? snake.description : \"\",\n tags: tags ?? { ...SAVE_AGENT_TAGS },\n collaborators: Array.isArray(snake.collaborators)\n ? snake.collaborators\n : [...SAVE_AGENT_COLLABORATORS],\n ...(variables != null ? { variables } : {}),\n ...(responseFormat != null\n ? { response_format: responseFormatForCp(responseFormat) }\n : {}),\n ...(mcpServers.length > 0 ? { mcp_servers: mcpServers } : {}),\n ...(skills.length > 0 ? { skills } : {}),\n };\n}\n\nfunction nonEmptyString(value: unknown): string | undefined {\n return typeof value === \"string\" && value !== \"\" ? value : undefined;\n}\n\n/**\n * Normalize CP save responses into\n * `{ agentId, versionId }`. Observed live shapes (both camelCase, wrapped):\n * { data: { id: \"<versionId>\", agentId: \"<agentId>\", fqn, version, … } } //agent-playground\n * { data: { id: \"<agentId>\", name, manifest } } — no separate version //trueforge\n * `id` is a version id only when a distinct `agentId` accompanies it;\n * otherwise `id` is the agent itself and no version id is known.\n */\nexport function saveAgentResultFromCp(raw: unknown): TfySaveAgentResult {\n const root = isRecord(raw) ? raw : {};\n const data = isRecord(root.data) ? root.data : {};\n const agentId = nonEmptyString(data.agentId) ?? nonEmptyString(data.id);\n const versionId =\n nonEmptyString(data.agentId) != null ? nonEmptyString(data.id) : undefined;\n return {\n ...(agentId != null ? { agentId } : {}),\n ...(versionId != null ? { versionId } : {}),\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<TfySaveAgentResult> {\n const manifest = buildSaveAgentManifest(req.agentName, req.agentSpec);\n const raw = await cpFetch<unknown>(opts, \"/api/svc/v1/agents\", {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ manifest }),\n });\n return saveAgentResultFromCp(raw);\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, TfySaveAgentResult } 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 TfySaveAgentResult\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":["name","inflight","isRecord","camel","nonEmptyString","isRecord"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
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 AgentCapabilityConfig, i 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-CUUft1YT.js';
|
|
4
|
+
export { f as AgentBuilderCapabilitiesResponse, g as AgentBuilderServer, h as AgentCapabilityConfig, i as AgentDetail, j as AgentLibraryEntry, k as AgentRuntimeConfig, l as AgentSelectorEntry, m as AgentSessionsServer, n as AgentSkill, o as AgentUIServer, p as AgentUIServerPort, q as ApprovalDecision, r as AuthenticateConnectorRequest, C as CatalogServer, s as CodeSnippet, t as CodeSnippetSampleCode, u as ConnectorAuth, v as ConnectorAuthApiKey, w as ConnectorAuthNone, x as ConnectorAuthOAuth, y as ConnectorAuthPublic, z as ConnectorAuthPublicApiKey, B as ConnectorAuthPublicNone, D as ConnectorAuthPublicOAuth, E as ConnectorAuthType, F as ConnectorAuthenticationResult, G as ConnectorBase, H as ConnectorCatalogEntry, I as ConnectorCatalogServer, J as ConnectorConfigBase, K as ConnectorSelectorEntry, L as ConnectorState, N as CreateConnectorRequest, O as CreateModelProviderRequest, P as CreateSandboxProviderRequest, Q as CreateSandboxRequest, R as CreateSessionRequest, V as CreateSkillRequest, W as CreateSkillRequestBase, X as DefinedSkill, Y as GithubSkill, Z as ImportGithubSkillRequest, _ as ListResult, $ as ListSessionEventsParams, a0 as ListSessionsOrder, a1 as ListSessionsParams, a2 as McpServerMount, a3 as Model, a4 as ModelCatalogServer, a5 as ModelEntry, a6 as ModelMessageEvent, a7 as ModelParams, a8 as ModelProperties, a9 as ModelProviderBase, aa as ModelProviderCatalogEntry, ab as ModelProviderConfigBase, ac as ModelSelection, ad as ModelSelectorEntry, ae as PageParams, af as PreviousTurnIdInput, ag as ProviderEntry, ah as ProviderType, ai as RegistrySkill, aj as SandboxBase, ak as SandboxCatalogEntry, al as SandboxCatalogServer, am as SandboxConfig, an as SandboxCreatedEvent, ao as SandboxProviderBase, ap as SandboxProviderCatalogEntry, aq as SandboxProviderConfig, ar as SandboxProviderListEntry, as as SandboxSnapshotSyncStatus, at as SaveAgentRequest, au as SaveAgentResult, av as SearchAgentSelectorParams, aw as SearchAgentsParams, ax as SelectRegistrySkillRequest, ay as SessionEventItem, az as SessionListEntry, aA as SessionListMetrics, aB as SkillBase, aC as SkillCatalogEntry, aD as SkillCatalogServer, aE as SkillConfigBase, aF as SkillMount, aG as SkillSelectorEntry, aH as ToolApprovalRequiredEvent, aI as ToolBase, aJ as ToolCall, aK as ToolResponseRequiredEvent, aL as TurnDoneMetrics, aM as TurnState, aN as TurnStateDone, aO as TurnStreamData, aP as TurnStreamingEvent, aQ as UpdateConnectorRequest, aR as UpdateModelProviderRequest, aS as UpdateSandboxProviderRequest, aT as UpdateSandboxRequest, aU as UpdateSessionRequest, aV as UserMessage } from './types-CUUft1YT.js';
|
|
5
5
|
import { AssistantClient } from '@assistant-ui/store';
|
|
6
6
|
export { isEventDelta, mergeEventDelta } from './server/index.js';
|
|
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';
|
|
7
|
+
export { CreateTrueFoundryAgentUIServerOptions, CreateTrueFoundryChatServerOptions, RequireApprovalToolSelectorItem, RequireApprovalToolsSelectorTag, TfyAgentSelectorEntry, TfyAgentSpec, TfyCollaborator, TfyConnectorSelectorEntry, TfyCreateSessionRequest, TfyFinishReason, TfyListSessionsParams, TfyMcpServerInitInfo, TfyMcpServerMount, TfyMcpToolInfo, TfyModelMessageUsage, TfyModelParams, TfyModelSelectorEntry, TfyResponseFormat, TfyRuntimeConfig, TfySaveAgentResult, 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';
|
|
8
8
|
import 'truefoundry-gateway-sdk/agents';
|
|
9
9
|
import 'truefoundry-gateway-sdk/agents/private';
|
|
10
10
|
import 'truefoundry-gateway-sdk';
|
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-G4TO3HAP.js";
|
|
15
15
|
|
|
16
16
|
// src/useTrueFoundryAgentRuntime.ts
|
|
17
17
|
import {
|
|
@@ -1199,16 +1199,11 @@ function extractTurnUserText(input) {
|
|
|
1199
1199
|
|
|
1200
1200
|
// src/mcpAuth.ts
|
|
1201
1201
|
var MCP_AUTH_RESUME_RUN_CUSTOM_KEY = "resumeMcpAuth";
|
|
1202
|
-
function buildMcpAuthTextParts(
|
|
1203
|
-
const linkLines = servers.map(
|
|
1204
|
-
(server) => `- [Authorize ${server.name}](${server.authUrl})`
|
|
1205
|
-
);
|
|
1202
|
+
function buildMcpAuthTextParts(_servers) {
|
|
1206
1203
|
const text = [
|
|
1207
1204
|
"This agent needs access to external services before it can continue.",
|
|
1208
1205
|
"",
|
|
1209
|
-
|
|
1210
|
-
"",
|
|
1211
|
-
"Open each link to sign in, then press **Continue** below."
|
|
1206
|
+
"Click the **Connect** button(s) to authorize the Connectors, then press **Continue**."
|
|
1212
1207
|
].join("\n");
|
|
1213
1208
|
return [{ type: "text", text }];
|
|
1214
1209
|
}
|