@truefoundry/assistant-ui-runtime 0.1.8 → 0.1.10-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -5
- package/dist/{chunk-CXBZ6WLZ.js → chunk-BRPTG6VA.js} +7 -6
- package/dist/chunk-BRPTG6VA.js.map +1 -0
- package/dist/index.d.ts +15 -5
- package/dist/index.js +34 -8
- package/dist/index.js.map +1 -1
- package/dist/plugins/truefoundry-agent-server-adapter/index.d.ts +1 -1
- package/dist/plugins/truefoundry-agent-server-adapter/index.js +1 -1
- package/dist/server/index.d.ts +2 -2
- package/dist/{types-B_z-FsDS.d.ts → types-CgZUnILu.d.ts} +92 -14
- package/package.json +1 -1
- package/src/convertTurnMessages.test.ts +23 -1
- package/src/convertTurnMessages.ts +9 -3
- package/src/hooks.ts +23 -3
- package/src/index.ts +15 -0
- package/src/messageCustomMetadata.ts +2 -0
- package/src/plugins/truefoundry-agent-server-adapter/chatServer.ts +6 -5
- package/src/server/index.ts +14 -0
- package/src/server/types.ts +112 -15
- package/src/truefoundryExtras.ts +1 -1
- package/src/useTrueFoundryAgentRuntime.ts +13 -3
- package/dist/chunk-CXBZ6WLZ.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AgentSessionClient } from 'truefoundry-gateway-sdk/agents';
|
|
2
2
|
import { PrivateAgentSessionClient } from 'truefoundry-gateway-sdk/agents/private';
|
|
3
|
-
import { A as AgentSpec,
|
|
3
|
+
import { A as AgentSpec, x as CreateSessionRequest, B as ListSessionsParams, S as Session, d as Turn, a7 as TurnState, a as AgentChatServer, ae as UpdateSessionRequest, ag as AgentSelectorEntry, ah as ConnectorSelectorEntry, ai as ModelSelectorEntry, aj as SkillSelectorEntry, f as AgentBuilderServer } from '../../types-CgZUnILu.js';
|
|
4
4
|
import { TruefoundryGatewayApi } from 'truefoundry-gateway-sdk';
|
|
5
5
|
|
|
6
6
|
/**
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { aa as TurnStreamingEvent, ak as DeltaEvents, T as TurnEvent } from '../types-CgZUnILu.js';
|
|
2
|
+
export { al as ActionRequiredEvent, f as AgentBuilderServer, a as AgentChatServer, am as AgentInfo, an as AgentParent, ag as AgentSelectorEntry, A as AgentSpec, g as AgentUIServerPort, ao as ApprovalDecision, C as CatalogServer, ap as ChunkDeltaToolCall, h as ConnectorAuth, i as ConnectorAuthApiKey, j as ConnectorAuthNone, k as ConnectorAuthOAuth, l as ConnectorAuthPublic, m as ConnectorAuthPublicApiKey, n as ConnectorAuthPublicNone, o as ConnectorAuthPublicOAuth, p as ConnectorAuthType, q as ConnectorBase, r as ConnectorCatalogEntry, s as ConnectorCatalogServer, t as ConnectorConfigBase, ah as ConnectorSelectorEntry, u as CreateConnectorRequest, v as CreateModelProviderRequest, w as CreateSandboxRequest, x as CreateSessionRequest, y as CreateSkillRequest, z as CreateSkillRequestBase, D as DefinedSkill, G as GithubSkill, I as ImportGithubSkillRequest, L as ListResult, aq as ListSessionsOrder, B as ListSessionsParams, M as McpAuthRequiredEvent, ar as McpInitializeEvent, as as McpServerAuthInfo, at as McpServerMount, au as Model, E as ModelCatalogServer, F as ModelEntry, av as ModelMessageContentPart, aw as ModelMessageDeltaEvent, H as ModelMessageEvent, ax as ModelParams, J as ModelProviderBase, K as ModelProviderCatalogEntry, N as ModelProviderConfigBase, ai as ModelSelectorEntry, ay as PageParams, P as PreviousTurnIdInput, O as ProviderType, R as RegistrySkill, Q as SandboxBase, V as SandboxCatalogEntry, W as SandboxCatalogServer, X as SandboxConfig, Y as SandboxCreatedEvent, az as SearchAgentSelectorParams, Z as SelectRegistrySkillRequest, S as Session, _ as SessionEventItem, $ as SkillBase, a0 as SkillCatalogEntry, a1 as SkillCatalogServer, a2 as SkillConfigBase, aA as SkillMount, aj as SkillSelectorEntry, b as ThreadCreatedEvent, aB as ThreadDoneEvent, a3 as ToolApprovalRequiredEvent, a4 as ToolBase, a5 as ToolCall, aC as ToolCallFunction, aD as ToolCallRef, aE as ToolInfo, aF as ToolResponseEvent, a6 as ToolResponseRequiredEvent, d as Turn, aG as TurnCreatedEvent, aH as TurnDoneEvent, e as TurnInputItem, a7 as TurnState, aI as TurnStateCancelled, a8 as TurnStateDone, aJ as TurnStateError, aK as TurnStateRunning, a9 as TurnStreamData, ab as UpdateConnectorRequest, ac as UpdateModelProviderRequest, ad as UpdateSandboxRequest, ae as UpdateSessionRequest, af as UserMessage, aL as UserMessageContent, c as UserToolApprovalEvent, U as UserToolResponseEvent } from '../types-CgZUnILu.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Local implementations of streaming delta helpers.
|
|
@@ -231,6 +231,7 @@ type DeltaEvents = ModelMessageDeltaEvent;
|
|
|
231
231
|
interface ModelSelectorEntry {
|
|
232
232
|
name: string;
|
|
233
233
|
provider: string;
|
|
234
|
+
reasoningEfforts?: string[];
|
|
234
235
|
}
|
|
235
236
|
/** Skill selector row. Host extends for fqn, preload, etc. */
|
|
236
237
|
interface SkillSelectorEntry {
|
|
@@ -441,7 +442,15 @@ interface AgentChatServer<TSpec extends AgentSpec = AgentSpec, TSession extends
|
|
|
441
442
|
afterSequenceNumber?: number;
|
|
442
443
|
abortSignal?: AbortSignal;
|
|
443
444
|
}): AsyncIterable<TurnStreamData>;
|
|
444
|
-
|
|
445
|
+
/**
|
|
446
|
+
* Reads a file the agent wrote inside its sandbox. Hosts whose download route is scoped to a
|
|
447
|
+
* turn resolve the sandbox from `turnId` and ignore `sandboxId`; hosts addressing sandboxes
|
|
448
|
+
* directly use `sandboxId`.
|
|
449
|
+
*/
|
|
450
|
+
downloadSandboxFile?(req: {
|
|
451
|
+
sessionId: string;
|
|
452
|
+
turnId: string;
|
|
453
|
+
sandboxId: string;
|
|
445
454
|
path: string;
|
|
446
455
|
}): Promise<Blob>;
|
|
447
456
|
}
|
|
@@ -532,15 +541,16 @@ interface ModelCatalogServer<TModel extends ModelEntry = ModelEntry, TProvider e
|
|
|
532
541
|
interface ToolBase {
|
|
533
542
|
id: string;
|
|
534
543
|
name: string;
|
|
544
|
+
description: string;
|
|
535
545
|
}
|
|
536
546
|
/** Strict auth type id. Hosts widen branches via intersection + re-union. */
|
|
537
|
-
type ConnectorAuthType = "
|
|
547
|
+
type ConnectorAuthType = "dcr" | "header" | "none";
|
|
538
548
|
type ConnectorAuthOAuth = {
|
|
539
|
-
type: "
|
|
549
|
+
type: "dcr";
|
|
540
550
|
authUrl?: string;
|
|
541
551
|
};
|
|
542
552
|
type ConnectorAuthApiKey = {
|
|
543
|
-
type: "
|
|
553
|
+
type: "header";
|
|
544
554
|
apiKey?: string;
|
|
545
555
|
headerName?: string;
|
|
546
556
|
};
|
|
@@ -549,11 +559,11 @@ type ConnectorAuthNone = {
|
|
|
549
559
|
};
|
|
550
560
|
type ConnectorAuth = ConnectorAuthOAuth | ConnectorAuthApiKey | ConnectorAuthNone;
|
|
551
561
|
type ConnectorAuthPublicOAuth = {
|
|
552
|
-
type: "
|
|
562
|
+
type: "dcr";
|
|
553
563
|
authUrl: string;
|
|
554
564
|
};
|
|
555
565
|
type ConnectorAuthPublicApiKey = {
|
|
556
|
-
type: "
|
|
566
|
+
type: "header";
|
|
557
567
|
headerName?: string;
|
|
558
568
|
};
|
|
559
569
|
type ConnectorAuthPublicNone = {
|
|
@@ -626,12 +636,36 @@ interface SkillBase {
|
|
|
626
636
|
name: string;
|
|
627
637
|
description: string;
|
|
628
638
|
}
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
639
|
+
interface RegistrySkill extends SkillBase {
|
|
640
|
+
/** `SkillCatalogEntry.id` this skill was created from. */
|
|
641
|
+
catalogId: string;
|
|
642
|
+
}
|
|
643
|
+
interface GithubSkill extends SkillBase {
|
|
644
|
+
}
|
|
645
|
+
type DefinedSkill = RegistrySkill | GithubSkill;
|
|
646
|
+
/** Git source fields shared by catalog entries and create requests. */
|
|
647
|
+
interface SkillConfigBase {
|
|
648
|
+
name: string;
|
|
649
|
+
description: string;
|
|
650
|
+
repoURL: string;
|
|
651
|
+
path: string;
|
|
652
|
+
ref: string;
|
|
633
653
|
}
|
|
634
|
-
interface
|
|
654
|
+
interface SkillCatalogEntry extends SkillConfigBase {
|
|
655
|
+
id: string;
|
|
656
|
+
}
|
|
657
|
+
/** Create-skill base. Hosts may intersect extra fields and re-union. */
|
|
658
|
+
interface CreateSkillRequestBase extends SkillConfigBase {
|
|
659
|
+
}
|
|
660
|
+
interface SelectRegistrySkillRequest extends CreateSkillRequestBase {
|
|
661
|
+
/** `SkillCatalogEntry.id`, persisted so the created skill links back to it. */
|
|
662
|
+
catalogId: string;
|
|
663
|
+
}
|
|
664
|
+
interface ImportGithubSkillRequest extends CreateSkillRequestBase {
|
|
665
|
+
}
|
|
666
|
+
type CreateSkillRequest = SelectRegistrySkillRequest | ImportGithubSkillRequest;
|
|
667
|
+
interface SkillCatalogServer<TSkill extends SkillBase = SkillBase, TCatalogEntry extends SkillCatalogEntry = SkillCatalogEntry, TCreate extends CreateSkillRequest = CreateSkillRequest> {
|
|
668
|
+
getSkillCatalog(): Promise<TCatalogEntry[]>;
|
|
635
669
|
listSkills(req?: {
|
|
636
670
|
query?: string;
|
|
637
671
|
}): Promise<TSkill[]>;
|
|
@@ -640,15 +674,59 @@ interface SkillCatalogServer<TSkill extends SkillBase = SkillBase, TCreate exten
|
|
|
640
674
|
id: string;
|
|
641
675
|
}): Promise<void>;
|
|
642
676
|
}
|
|
677
|
+
/** Mutable sandbox settings shared by catalog rows, create, and update. */
|
|
678
|
+
interface SandboxConfig {
|
|
679
|
+
snapshotName: string;
|
|
680
|
+
execTimeoutMs: number;
|
|
681
|
+
autoStopIntervalInMinutes: number;
|
|
682
|
+
autoArchiveIntervalInMinutes: number;
|
|
683
|
+
autoDeleteIntervalInMinutes: number;
|
|
684
|
+
}
|
|
685
|
+
interface SandboxCatalogEntry extends SandboxConfig {
|
|
686
|
+
id: string;
|
|
687
|
+
name: string;
|
|
688
|
+
type: string;
|
|
689
|
+
}
|
|
690
|
+
interface SandboxBase {
|
|
691
|
+
id: string;
|
|
692
|
+
name: string;
|
|
693
|
+
catalogId: string;
|
|
694
|
+
isConnected: boolean;
|
|
695
|
+
}
|
|
696
|
+
interface CreateSandboxRequest extends SandboxConfig {
|
|
697
|
+
/** `SandboxCatalogEntry.id` used to create this sandbox. */
|
|
698
|
+
catalogId: string;
|
|
699
|
+
name: string;
|
|
700
|
+
type: string;
|
|
701
|
+
apiKey: string;
|
|
702
|
+
}
|
|
703
|
+
interface UpdateSandboxRequest extends SandboxConfig {
|
|
704
|
+
id: string;
|
|
705
|
+
apiKey: string;
|
|
706
|
+
}
|
|
707
|
+
interface SandboxCatalogServer<TSandbox extends SandboxBase = SandboxBase, TCatalogEntry extends SandboxCatalogEntry = SandboxCatalogEntry, TCreate extends CreateSandboxRequest = CreateSandboxRequest, TUpdate extends UpdateSandboxRequest = UpdateSandboxRequest> {
|
|
708
|
+
getSandboxCatalog(): Promise<TCatalogEntry[]>;
|
|
709
|
+
listSandboxes(req?: {
|
|
710
|
+
query?: string;
|
|
711
|
+
}): Promise<TSandbox[]>;
|
|
712
|
+
createSandbox(req: TCreate): Promise<TSandbox>;
|
|
713
|
+
updateSandbox(req: TUpdate): Promise<TSandbox>;
|
|
714
|
+
deleteSandbox(req: {
|
|
715
|
+
id: string;
|
|
716
|
+
}): Promise<void>;
|
|
717
|
+
}
|
|
643
718
|
/**
|
|
644
|
-
* Settings management aggregate — modelCatalog + connectorCatalog + optional
|
|
719
|
+
* Settings management aggregate — modelCatalog + connectorCatalog + optional
|
|
720
|
+
* skill and sandbox catalogs.
|
|
645
721
|
* Hosts may pass the whole object to an app shell, or a focused sub-port to a page.
|
|
646
722
|
*/
|
|
647
|
-
interface CatalogServer<TModelCatalog extends ModelCatalogServer = ModelCatalogServer, TConnectorCatalog extends ConnectorCatalogServer = ConnectorCatalogServer, TSkillCatalog extends SkillCatalogServer = SkillCatalogServer> {
|
|
723
|
+
interface CatalogServer<TModelCatalog extends ModelCatalogServer = ModelCatalogServer, TConnectorCatalog extends ConnectorCatalogServer = ConnectorCatalogServer, TSkillCatalog extends SkillCatalogServer = SkillCatalogServer, TSandboxCatalog extends SandboxCatalogServer = SandboxCatalogServer> {
|
|
648
724
|
modelCatalog: TModelCatalog;
|
|
649
725
|
connectorCatalog: TConnectorCatalog;
|
|
650
726
|
/** Optional — omit when the host has no skills settings surface. */
|
|
651
727
|
skillCatalog?: TSkillCatalog;
|
|
728
|
+
/** Optional — omit when the host has no sandboxes settings surface. */
|
|
729
|
+
sandboxCatalog?: TSandboxCatalog;
|
|
652
730
|
}
|
|
653
731
|
/**
|
|
654
732
|
* Composed host port: chat + builder + optional settings catalog.
|
|
@@ -663,4 +741,4 @@ type AgentUIServerPort<TChat extends AgentChatServer = AgentChatServer, TBuilder
|
|
|
663
741
|
catalog?: TCatalog;
|
|
664
742
|
};
|
|
665
743
|
|
|
666
|
-
export type {
|
|
744
|
+
export type { SkillBase as $, AgentSpec as A, ListSessionsParams as B, CatalogServer as C, DefinedSkill as D, ModelCatalogServer as E, ModelEntry as F, GithubSkill as G, ModelMessageEvent as H, ImportGithubSkillRequest as I, ModelProviderBase as J, ModelProviderCatalogEntry as K, ListResult as L, McpAuthRequiredEvent as M, ModelProviderConfigBase as N, ProviderType as O, PreviousTurnIdInput as P, SandboxBase as Q, RegistrySkill as R, Session as S, TurnEvent as T, UserToolResponseEvent as U, SandboxCatalogEntry as V, SandboxCatalogServer as W, SandboxConfig as X, SandboxCreatedEvent as Y, SelectRegistrySkillRequest as Z, SessionEventItem as _, AgentChatServer as a, SkillCatalogEntry as a0, SkillCatalogServer as a1, SkillConfigBase as a2, ToolApprovalRequiredEvent as a3, ToolBase as a4, ToolCall as a5, ToolResponseRequiredEvent as a6, TurnState as a7, TurnStateDone as a8, TurnStreamData as a9, SkillMount as aA, ThreadDoneEvent as aB, ToolCallFunction as aC, ToolCallRef as aD, ToolInfo as aE, ToolResponseEvent as aF, TurnCreatedEvent as aG, TurnDoneEvent as aH, TurnStateCancelled as aI, TurnStateError as aJ, TurnStateRunning as aK, UserMessageContent as aL, TurnStreamingEvent as aa, UpdateConnectorRequest as ab, UpdateModelProviderRequest as ac, UpdateSandboxRequest as ad, UpdateSessionRequest as ae, UserMessage as af, AgentSelectorEntry as ag, ConnectorSelectorEntry as ah, ModelSelectorEntry as ai, SkillSelectorEntry as aj, DeltaEvents as ak, ActionRequiredEvent as al, AgentInfo as am, AgentParent as an, ApprovalDecision as ao, ChunkDeltaToolCall as ap, ListSessionsOrder as aq, McpInitializeEvent as ar, McpServerAuthInfo as as, McpServerMount as at, Model as au, ModelMessageContentPart as av, ModelMessageDeltaEvent as aw, ModelParams as ax, PageParams as ay, SearchAgentSelectorParams as az, ThreadCreatedEvent as b, UserToolApprovalEvent as c, Turn as d, TurnInputItem as e, AgentBuilderServer as f, AgentUIServerPort as g, ConnectorAuth as h, ConnectorAuthApiKey as i, ConnectorAuthNone as j, ConnectorAuthOAuth as k, ConnectorAuthPublic as l, ConnectorAuthPublicApiKey as m, ConnectorAuthPublicNone as n, ConnectorAuthPublicOAuth as o, ConnectorAuthType as p, ConnectorBase as q, ConnectorCatalogEntry as r, ConnectorCatalogServer as s, ConnectorConfigBase as t, CreateConnectorRequest as u, CreateModelProviderRequest as v, CreateSandboxRequest as w, CreateSessionRequest as x, CreateSkillRequest as y, CreateSkillRequestBase as z };
|
package/package.json
CHANGED
|
@@ -461,6 +461,26 @@ describe("convertTurnMessages", () => {
|
|
|
461
461
|
expect(updated.id).toBe(existing.id);
|
|
462
462
|
expect(updated.content).toEqual([{ type: "text", text: "second" }]);
|
|
463
463
|
});
|
|
464
|
+
|
|
465
|
+
it("stamps the streaming turn id onto the message metadata", () => {
|
|
466
|
+
const message = turnStreamUpdateToAssistantMessage("turn-1", {
|
|
467
|
+
content: [{ type: "text", text: "hi" }],
|
|
468
|
+
});
|
|
469
|
+
expect(message.metadata.custom.turnId).toBe("turn-1");
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
it("advances the turn id when a continuation reuses the existing message", () => {
|
|
473
|
+
const existing = turnStreamUpdateToAssistantMessage("turn-1", {
|
|
474
|
+
content: [{ type: "text", text: "first" }],
|
|
475
|
+
});
|
|
476
|
+
const updated = turnStreamUpdateToAssistantMessage(
|
|
477
|
+
"turn-2",
|
|
478
|
+
{ content: [{ type: "text", text: "second" }] },
|
|
479
|
+
existing,
|
|
480
|
+
);
|
|
481
|
+
expect(updated.id).toBe("turn-1-assistant");
|
|
482
|
+
expect(updated.metadata.custom.turnId).toBe("turn-2");
|
|
483
|
+
});
|
|
464
484
|
});
|
|
465
485
|
|
|
466
486
|
describe("repositoryItemsFromMessages", () => {
|
|
@@ -546,7 +566,7 @@ describe("convertTurnMessages", () => {
|
|
|
546
566
|
|
|
547
567
|
expect(result.messages[1]).toMatchObject({
|
|
548
568
|
role: "assistant",
|
|
549
|
-
metadata: { custom: { sandboxId: "sbx-123" } },
|
|
569
|
+
metadata: { custom: { sandboxId: "sbx-123", turnId: "turn-1" } },
|
|
550
570
|
});
|
|
551
571
|
});
|
|
552
572
|
|
|
@@ -601,6 +621,8 @@ describe("convertTurnMessages", () => {
|
|
|
601
621
|
{ type: "text", text: "first chunk" },
|
|
602
622
|
{ type: "text", text: " after approval" },
|
|
603
623
|
]);
|
|
624
|
+
// Artifacts on a merged message belong to the turn that wrote them last.
|
|
625
|
+
expect(assistant.metadata.custom.turnId).toBe("turn-2");
|
|
604
626
|
});
|
|
605
627
|
|
|
606
628
|
it("preserves requires-action on reload when a turn ends awaiting tool approval", async () => {
|
|
@@ -1074,8 +1074,14 @@ function projectHistoryTurns(
|
|
|
1074
1074
|
content,
|
|
1075
1075
|
record,
|
|
1076
1076
|
);
|
|
1077
|
-
|
|
1078
|
-
|
|
1077
|
+
// Continuation turns fold into the previous assistant message and overwrite this custom,
|
|
1078
|
+
// so a folded message reports the latest turn that contributed to it — the one whose
|
|
1079
|
+
// sandbox wrote the newest artifacts.
|
|
1080
|
+
const custom = {
|
|
1081
|
+
...baseCustom,
|
|
1082
|
+
turnId: record.id,
|
|
1083
|
+
...(record.sandboxId != null ? { sandboxId: record.sandboxId } : {}),
|
|
1084
|
+
};
|
|
1079
1085
|
|
|
1080
1086
|
if (record.userText) {
|
|
1081
1087
|
messages.push(
|
|
@@ -1732,7 +1738,7 @@ export function turnStreamUpdateToAssistantMessage(
|
|
|
1732
1738
|
unstable_annotations: [],
|
|
1733
1739
|
unstable_data: [],
|
|
1734
1740
|
steps: [],
|
|
1735
|
-
custom: update.metadata?.custom
|
|
1741
|
+
custom: { ...update.metadata?.custom, turnId },
|
|
1736
1742
|
},
|
|
1737
1743
|
};
|
|
1738
1744
|
}
|
package/src/hooks.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { useMemo } from "react";
|
|
4
|
-
import { useAui } from "@assistant-ui/store";
|
|
4
|
+
import { useAui, useAuiState } from "@assistant-ui/store";
|
|
5
5
|
|
|
6
|
+
import type { TrueFoundryMessageCustomMetadata } from "./messageCustomMetadata.js";
|
|
6
7
|
import {
|
|
7
8
|
EMPTY_DRAFT_EXTRAS,
|
|
8
9
|
trueFoundryExtras,
|
|
@@ -86,10 +87,29 @@ export const useTrueFoundryResumeMcpAuth = () => {
|
|
|
86
87
|
export const useTrueFoundrySandboxId = (): string | undefined =>
|
|
87
88
|
trueFoundryExtras.use((e) => e.sandboxId, undefined);
|
|
88
89
|
|
|
89
|
-
/**
|
|
90
|
+
/** Turn that produced the message being rendered. Only defined inside a message scope. */
|
|
91
|
+
export const useTrueFoundryTurnId = (): string | undefined =>
|
|
92
|
+
useAuiState(
|
|
93
|
+
(state) =>
|
|
94
|
+
(state.message.metadata?.custom as TrueFoundryMessageCustomMetadata | undefined)
|
|
95
|
+
?.turnId,
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Returns a function to download a file the current turn wrote to its sandbox. Must be called
|
|
100
|
+
* from a message scope, since the artifact belongs to the turn that rendered it.
|
|
101
|
+
*/
|
|
90
102
|
export const useTrueFoundryDownloadSandboxFile = () => {
|
|
91
103
|
const aui = useAui();
|
|
92
|
-
|
|
104
|
+
const turnId = useTrueFoundryTurnId();
|
|
105
|
+
return (path: string) => {
|
|
106
|
+
if (turnId == null) {
|
|
107
|
+
throw new Error(
|
|
108
|
+
"Downloading a sandbox file requires a message scope to resolve its turn.",
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
return trueFoundryExtras.get(aui).downloadSandboxFile({ turnId, path });
|
|
112
|
+
};
|
|
93
113
|
};
|
|
94
114
|
|
|
95
115
|
/** Returns a function to cancel the current run from any render context. */
|
package/src/index.ts
CHANGED
|
@@ -49,6 +49,7 @@ export {
|
|
|
49
49
|
useTrueFoundryRespondToToolResponse,
|
|
50
50
|
useTrueFoundryResumeMcpAuth,
|
|
51
51
|
useTrueFoundrySandboxId,
|
|
52
|
+
useTrueFoundryTurnId,
|
|
52
53
|
useTrueFoundryDownloadSandboxFile,
|
|
53
54
|
useTrueFoundryCancel,
|
|
54
55
|
useTrueFoundryResetFromTurn,
|
|
@@ -116,8 +117,22 @@ export type {
|
|
|
116
117
|
UpdateConnectorRequest,
|
|
117
118
|
ConnectorCatalogServer,
|
|
118
119
|
SkillBase,
|
|
120
|
+
RegistrySkill,
|
|
121
|
+
GithubSkill,
|
|
122
|
+
DefinedSkill,
|
|
123
|
+
SkillConfigBase,
|
|
124
|
+
SkillCatalogEntry,
|
|
125
|
+
CreateSkillRequestBase,
|
|
126
|
+
SelectRegistrySkillRequest,
|
|
127
|
+
ImportGithubSkillRequest,
|
|
119
128
|
CreateSkillRequest,
|
|
120
129
|
SkillCatalogServer,
|
|
130
|
+
SandboxConfig,
|
|
131
|
+
SandboxCatalogEntry,
|
|
132
|
+
SandboxBase,
|
|
133
|
+
CreateSandboxRequest,
|
|
134
|
+
UpdateSandboxRequest,
|
|
135
|
+
SandboxCatalogServer,
|
|
121
136
|
CatalogServer,
|
|
122
137
|
AgentUIServerPort,
|
|
123
138
|
} from "./server/index.js";
|
|
@@ -10,6 +10,8 @@ export type TrueFoundryMessageCustomMetadata = {
|
|
|
10
10
|
pendingMcpAuth?: true;
|
|
11
11
|
mcpServers?: McpAuthRequiredEvent["mcpServers"];
|
|
12
12
|
sandboxId?: string;
|
|
13
|
+
/** Turn that produced this message. Scopes artifact downloads to their own turn. */
|
|
14
|
+
turnId?: string;
|
|
13
15
|
[TOOL_APPROVAL_THREAD_ID_CUSTOM_KEY]?: string;
|
|
14
16
|
[TOOL_RESPONSE_THREAD_ID_CUSTOM_KEY]?: string;
|
|
15
17
|
};
|
|
@@ -350,11 +350,12 @@ export function createTrueFoundryChatServer<
|
|
|
350
350
|
) as AsyncIterable<TurnStreamData>;
|
|
351
351
|
},
|
|
352
352
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
353
|
+
// The gateway addresses sandboxes directly, so the turn is carried for hosts that need it
|
|
354
|
+
// but is not part of this route.
|
|
355
|
+
async downloadSandboxFile({ sandboxId, path }) {
|
|
356
|
+
const response = await privateClient.downloadSandboxFile(sandboxId, {
|
|
357
|
+
path,
|
|
358
|
+
});
|
|
358
359
|
return await response.blob();
|
|
359
360
|
},
|
|
360
361
|
|
package/src/server/index.ts
CHANGED
|
@@ -56,8 +56,22 @@ export type {
|
|
|
56
56
|
UpdateConnectorRequest,
|
|
57
57
|
ConnectorCatalogServer,
|
|
58
58
|
SkillBase,
|
|
59
|
+
RegistrySkill,
|
|
60
|
+
GithubSkill,
|
|
61
|
+
DefinedSkill,
|
|
62
|
+
SkillConfigBase,
|
|
63
|
+
SkillCatalogEntry,
|
|
64
|
+
CreateSkillRequestBase,
|
|
65
|
+
SelectRegistrySkillRequest,
|
|
66
|
+
ImportGithubSkillRequest,
|
|
59
67
|
CreateSkillRequest,
|
|
60
68
|
SkillCatalogServer,
|
|
69
|
+
SandboxConfig,
|
|
70
|
+
SandboxCatalogEntry,
|
|
71
|
+
SandboxBase,
|
|
72
|
+
CreateSandboxRequest,
|
|
73
|
+
UpdateSandboxRequest,
|
|
74
|
+
SandboxCatalogServer,
|
|
61
75
|
CatalogServer,
|
|
62
76
|
AgentUIServerPort,
|
|
63
77
|
} from "./types.js";
|
package/src/server/types.ts
CHANGED
|
@@ -21,6 +21,7 @@ import type {
|
|
|
21
21
|
export interface ModelSelectorEntry {
|
|
22
22
|
name: string;
|
|
23
23
|
provider: string;
|
|
24
|
+
reasoningEfforts?: string[];
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
/** Skill selector row. Host extends for fqn, preload, etc. */
|
|
@@ -290,10 +291,17 @@ export interface AgentChatServer<
|
|
|
290
291
|
abortSignal?: AbortSignal;
|
|
291
292
|
}): AsyncIterable<TurnStreamData>;
|
|
292
293
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
294
|
+
/**
|
|
295
|
+
* Reads a file the agent wrote inside its sandbox. Hosts whose download route is scoped to a
|
|
296
|
+
* turn resolve the sandbox from `turnId` and ignore `sandboxId`; hosts addressing sandboxes
|
|
297
|
+
* directly use `sandboxId`.
|
|
298
|
+
*/
|
|
299
|
+
downloadSandboxFile?(req: {
|
|
300
|
+
sessionId: string;
|
|
301
|
+
turnId: string;
|
|
302
|
+
sandboxId: string;
|
|
303
|
+
path: string;
|
|
304
|
+
}): Promise<Blob>;
|
|
297
305
|
}
|
|
298
306
|
|
|
299
307
|
/**
|
|
@@ -405,15 +413,16 @@ export interface ModelCatalogServer<
|
|
|
405
413
|
export interface ToolBase {
|
|
406
414
|
id: string;
|
|
407
415
|
name: string;
|
|
416
|
+
description: string;
|
|
408
417
|
}
|
|
409
418
|
|
|
410
419
|
/** Strict auth type id. Hosts widen branches via intersection + re-union. */
|
|
411
|
-
export type ConnectorAuthType = "
|
|
420
|
+
export type ConnectorAuthType = "dcr" | "header" | "none";
|
|
412
421
|
|
|
413
422
|
// Write (create/update) — export branches so hosts can intersect extras
|
|
414
|
-
export type ConnectorAuthOAuth = { type: "
|
|
423
|
+
export type ConnectorAuthOAuth = { type: "dcr"; authUrl?: string };
|
|
415
424
|
export type ConnectorAuthApiKey = {
|
|
416
|
-
type: "
|
|
425
|
+
type: "header";
|
|
417
426
|
apiKey?: string;
|
|
418
427
|
headerName?: string;
|
|
419
428
|
};
|
|
@@ -423,10 +432,10 @@ export type ConnectorAuth =
|
|
|
423
432
|
| ConnectorAuthApiKey
|
|
424
433
|
| ConnectorAuthNone;
|
|
425
434
|
|
|
426
|
-
// Public (list/detail) — no secrets;
|
|
427
|
-
export type ConnectorAuthPublicOAuth = { type: "
|
|
435
|
+
// Public (list/detail) — no secrets; dcr requires authUrl
|
|
436
|
+
export type ConnectorAuthPublicOAuth = { type: "dcr"; authUrl: string };
|
|
428
437
|
export type ConnectorAuthPublicApiKey = {
|
|
429
|
-
type: "
|
|
438
|
+
type: "header";
|
|
430
439
|
headerName?: string;
|
|
431
440
|
};
|
|
432
441
|
export type ConnectorAuthPublicNone = { type: "none" };
|
|
@@ -525,34 +534,122 @@ export interface SkillBase {
|
|
|
525
534
|
description: string;
|
|
526
535
|
}
|
|
527
536
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
537
|
+
export interface RegistrySkill extends SkillBase {
|
|
538
|
+
/** `SkillCatalogEntry.id` this skill was created from. */
|
|
539
|
+
catalogId: string;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
export interface GithubSkill extends SkillBase {}
|
|
543
|
+
|
|
544
|
+
export type DefinedSkill = RegistrySkill | GithubSkill;
|
|
545
|
+
|
|
546
|
+
/** Git source fields shared by catalog entries and create requests. */
|
|
547
|
+
export interface SkillConfigBase {
|
|
548
|
+
name: string;
|
|
549
|
+
description: string;
|
|
550
|
+
repoURL: string;
|
|
551
|
+
path: string;
|
|
552
|
+
ref: string;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
export interface SkillCatalogEntry extends SkillConfigBase {
|
|
556
|
+
id: string;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
/** Create-skill base. Hosts may intersect extra fields and re-union. */
|
|
560
|
+
export interface CreateSkillRequestBase extends SkillConfigBase {}
|
|
561
|
+
|
|
562
|
+
export interface SelectRegistrySkillRequest extends CreateSkillRequestBase {
|
|
563
|
+
/** `SkillCatalogEntry.id`, persisted so the created skill links back to it. */
|
|
564
|
+
catalogId: string;
|
|
532
565
|
}
|
|
533
566
|
|
|
567
|
+
export interface ImportGithubSkillRequest extends CreateSkillRequestBase {}
|
|
568
|
+
|
|
569
|
+
export type CreateSkillRequest =
|
|
570
|
+
| SelectRegistrySkillRequest
|
|
571
|
+
| ImportGithubSkillRequest;
|
|
572
|
+
|
|
534
573
|
export interface SkillCatalogServer<
|
|
535
574
|
TSkill extends SkillBase = SkillBase,
|
|
575
|
+
TCatalogEntry extends SkillCatalogEntry = SkillCatalogEntry,
|
|
536
576
|
TCreate extends CreateSkillRequest = CreateSkillRequest,
|
|
537
577
|
> {
|
|
578
|
+
getSkillCatalog(): Promise<TCatalogEntry[]>;
|
|
538
579
|
listSkills(req?: { query?: string }): Promise<TSkill[]>;
|
|
539
580
|
createSkill(req: TCreate): Promise<TSkill>;
|
|
540
581
|
deleteSkill?(req: { id: string }): Promise<void>;
|
|
541
582
|
}
|
|
542
583
|
|
|
584
|
+
// ---------------------------------------------------------------------------
|
|
585
|
+
// Sandboxes catalog — public rows omit credentials; writes accept them
|
|
586
|
+
// ---------------------------------------------------------------------------
|
|
587
|
+
|
|
588
|
+
/** Mutable sandbox settings shared by catalog rows, create, and update. */
|
|
589
|
+
export interface SandboxConfig {
|
|
590
|
+
snapshotName: string;
|
|
591
|
+
execTimeoutMs: number;
|
|
592
|
+
autoStopIntervalInMinutes: number;
|
|
593
|
+
autoArchiveIntervalInMinutes: number;
|
|
594
|
+
autoDeleteIntervalInMinutes: number;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
export interface SandboxCatalogEntry extends SandboxConfig {
|
|
598
|
+
id: string;
|
|
599
|
+
name: string;
|
|
600
|
+
type: string;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
export interface SandboxBase {
|
|
604
|
+
id: string;
|
|
605
|
+
name: string;
|
|
606
|
+
catalogId: string;
|
|
607
|
+
isConnected: boolean;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
export interface CreateSandboxRequest extends SandboxConfig {
|
|
611
|
+
/** `SandboxCatalogEntry.id` used to create this sandbox. */
|
|
612
|
+
catalogId: string;
|
|
613
|
+
name: string;
|
|
614
|
+
type: string;
|
|
615
|
+
apiKey: string;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
export interface UpdateSandboxRequest extends SandboxConfig {
|
|
619
|
+
id: string;
|
|
620
|
+
apiKey: string;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
export interface SandboxCatalogServer<
|
|
624
|
+
TSandbox extends SandboxBase = SandboxBase,
|
|
625
|
+
TCatalogEntry extends SandboxCatalogEntry = SandboxCatalogEntry,
|
|
626
|
+
TCreate extends CreateSandboxRequest = CreateSandboxRequest,
|
|
627
|
+
TUpdate extends UpdateSandboxRequest = UpdateSandboxRequest,
|
|
628
|
+
> {
|
|
629
|
+
getSandboxCatalog(): Promise<TCatalogEntry[]>;
|
|
630
|
+
listSandboxes(req?: { query?: string }): Promise<TSandbox[]>;
|
|
631
|
+
createSandbox(req: TCreate): Promise<TSandbox>;
|
|
632
|
+
updateSandbox(req: TUpdate): Promise<TSandbox>;
|
|
633
|
+
deleteSandbox(req: { id: string }): Promise<void>;
|
|
634
|
+
}
|
|
635
|
+
|
|
543
636
|
/**
|
|
544
|
-
* Settings management aggregate — modelCatalog + connectorCatalog + optional
|
|
637
|
+
* Settings management aggregate — modelCatalog + connectorCatalog + optional
|
|
638
|
+
* skill and sandbox catalogs.
|
|
545
639
|
* Hosts may pass the whole object to an app shell, or a focused sub-port to a page.
|
|
546
640
|
*/
|
|
547
641
|
export interface CatalogServer<
|
|
548
642
|
TModelCatalog extends ModelCatalogServer = ModelCatalogServer,
|
|
549
643
|
TConnectorCatalog extends ConnectorCatalogServer = ConnectorCatalogServer,
|
|
550
644
|
TSkillCatalog extends SkillCatalogServer = SkillCatalogServer,
|
|
645
|
+
TSandboxCatalog extends SandboxCatalogServer = SandboxCatalogServer,
|
|
551
646
|
> {
|
|
552
647
|
modelCatalog: TModelCatalog;
|
|
553
648
|
connectorCatalog: TConnectorCatalog;
|
|
554
649
|
/** Optional — omit when the host has no skills settings surface. */
|
|
555
650
|
skillCatalog?: TSkillCatalog;
|
|
651
|
+
/** Optional — omit when the host has no sandboxes settings surface. */
|
|
652
|
+
sandboxCatalog?: TSandboxCatalog;
|
|
556
653
|
}
|
|
557
654
|
|
|
558
655
|
/**
|
package/src/truefoundryExtras.ts
CHANGED
|
@@ -26,7 +26,7 @@ export type TrueFoundryRuntimeExtras = {
|
|
|
26
26
|
respondToToolApproval: (response: RespondToToolApprovalOptions) => void;
|
|
27
27
|
respondToToolResponse: (response: RespondToToolResponseOptions) => void;
|
|
28
28
|
resumeMcpAuth: () => Promise<void>;
|
|
29
|
-
downloadSandboxFile: (path: string) => Promise<Blob>;
|
|
29
|
+
downloadSandboxFile: (req: { turnId: string; path: string }) => Promise<Blob>;
|
|
30
30
|
cancel: () => Promise<void>;
|
|
31
31
|
resetFromTurn: (turnId: string) => Promise<void>;
|
|
32
32
|
reload: () => void;
|
|
@@ -152,18 +152,28 @@ function useTrueFoundryAgentRuntimeImpl(
|
|
|
152
152
|
);
|
|
153
153
|
|
|
154
154
|
const downloadSandboxFile = useCallback(
|
|
155
|
-
async (path: string) => {
|
|
155
|
+
async ({ turnId, path }: { turnId: string; path: string }) => {
|
|
156
156
|
if (server.downloadSandboxFile == null) {
|
|
157
157
|
throw new Error(
|
|
158
158
|
"Downloading a sandbox file requires AgentChatServer.downloadSandboxFile.",
|
|
159
159
|
);
|
|
160
160
|
}
|
|
161
|
+
if (sessionId == null) {
|
|
162
|
+
throw new Error(
|
|
163
|
+
"This session has not been saved yet, so its files cannot be downloaded.",
|
|
164
|
+
);
|
|
165
|
+
}
|
|
161
166
|
if (sandboxId == null) {
|
|
162
167
|
throw new Error("No sandbox is available yet for this session.");
|
|
163
168
|
}
|
|
164
|
-
return await server.downloadSandboxFile(
|
|
169
|
+
return await server.downloadSandboxFile({
|
|
170
|
+
sessionId,
|
|
171
|
+
turnId,
|
|
172
|
+
sandboxId,
|
|
173
|
+
path,
|
|
174
|
+
});
|
|
165
175
|
},
|
|
166
|
-
[server, sandboxId],
|
|
176
|
+
[server, sessionId, sandboxId],
|
|
167
177
|
);
|
|
168
178
|
|
|
169
179
|
const draftExtras = useMemo(() => {
|