@truefoundry/assistant-ui-runtime 0.1.6-rc.0 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +193 -579
- package/dist/chunk-3A2EPLQG.js +93 -0
- package/dist/chunk-3A2EPLQG.js.map +1 -0
- package/dist/chunk-SQDOTGP2.js +292 -0
- package/dist/chunk-SQDOTGP2.js.map +1 -0
- package/dist/index.d.ts +24 -36
- package/dist/index.js +276 -249
- package/dist/index.js.map +1 -1
- package/dist/plugins/truefoundry-agent-server-adapter/index.d.ts +134 -5
- package/dist/plugins/truefoundry-agent-server-adapter/index.js +16 -195
- package/dist/plugins/truefoundry-agent-server-adapter/index.js.map +1 -1
- package/dist/server/index.d.ts +17 -0
- package/dist/server/index.js +9 -0
- package/dist/server/index.js.map +1 -0
- package/dist/{types-VUBzoJT2.d.ts → types-DbNsU075.d.ts} +212 -19
- package/package.json +10 -5
- package/src/{private → draft}/agentSpec.ts +14 -17
- package/src/{private → draft}/draftSessionBridge.ts +1 -2
- package/src/{private → draft}/truefoundryDraftThreadListAdapter.test.ts +1 -1
- package/src/{private → draft}/truefoundryDraftThreadListAdapter.ts +2 -1
- package/src/{private → draft}/useDraftAgentSpec.ts +16 -5
- package/src/draftAgentConfig.test.ts +2 -1
- package/src/index.ts +71 -7
- package/src/plugins/truefoundry-agent-server-adapter/README.md +178 -0
- package/src/plugins/truefoundry-agent-server-adapter/guards.test.ts +113 -0
- package/src/plugins/truefoundry-agent-server-adapter/guards.ts +130 -0
- package/src/plugins/truefoundry-agent-server-adapter/index.ts +154 -40
- package/src/plugins/truefoundry-agent-server-adapter/types.ts +137 -0
- package/src/plugins/truefoundry-agent-server-adapter/types.typecheck.ts +164 -0
- package/src/server/index.ts +23 -0
- package/src/server/types.ts +272 -21
- package/src/truefoundryExtras.ts +4 -1
- package/src/truefoundryOwnedSessionsThreadListAdapter.ts +1 -1
- package/src/types.ts +1 -2
- package/src/useTrueFoundryAgentMessages.test.tsx +261 -1
- package/src/useTrueFoundryAgentMessages.ts +284 -176
- package/src/useTrueFoundryAgentRuntime.ts +31 -21
- /package/src/{private → draft}/useDraftAgentSpec.test.tsx +0 -0
|
@@ -253,16 +253,22 @@ type SearchAgentSelectorParams = {
|
|
|
253
253
|
limit?: number;
|
|
254
254
|
offset?: number;
|
|
255
255
|
};
|
|
256
|
-
/**
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
256
|
+
/**
|
|
257
|
+
* Mounts written to AgentSpec.skills[] / AgentSpec.mcpServers[].
|
|
258
|
+
*
|
|
259
|
+
* These are opaque to the runtime — it stores and forwards them but never reads
|
|
260
|
+
* a field, and the backend owns the shape (the gateway identifies a skill by
|
|
261
|
+
* `fqn`, with no `id` or `name` anywhere). So the base constrains only that a
|
|
262
|
+
* mount is an object; hosts intersect their concrete mount type over it, as
|
|
263
|
+
* `TfySkillMount` / `TfyMcpServerMount` do in the gateway adapter.
|
|
264
|
+
*
|
|
265
|
+
* Naming a field here would not just be unread, it would be wrong: a base with
|
|
266
|
+
* required fields rejects the backend's own payloads, and one with only optional
|
|
267
|
+
* fields is a weak type, which TypeScript rejects for a source that shares no
|
|
268
|
+
* property with it — the gateway's registry skill shares none.
|
|
269
|
+
*/
|
|
270
|
+
type SkillMount = object;
|
|
271
|
+
type McpServerMount = object;
|
|
266
272
|
interface ModelParams {
|
|
267
273
|
maxTokens?: number;
|
|
268
274
|
reasoningEffort?: string;
|
|
@@ -273,17 +279,15 @@ interface Model {
|
|
|
273
279
|
}
|
|
274
280
|
/**
|
|
275
281
|
* SDK-owned agent definition — fields the FE reads/writes.
|
|
276
|
-
* Host
|
|
282
|
+
* Host widens `model` / `skills` / `mcpServers` via type params, and adds
|
|
283
|
+
* extra fields via `TSpec extends AgentSpec<...>`.
|
|
277
284
|
*/
|
|
278
|
-
interface AgentSpec {
|
|
279
|
-
model:
|
|
280
|
-
skills?:
|
|
281
|
-
mcpServers?:
|
|
285
|
+
interface AgentSpec<TModel extends Model = Model, TSkill extends SkillMount = SkillMount, TMcp extends McpServerMount = McpServerMount> {
|
|
286
|
+
model: TModel;
|
|
287
|
+
skills?: TSkill[];
|
|
288
|
+
mcpServers?: TMcp[];
|
|
282
289
|
instructions?: string;
|
|
283
|
-
messages?: unknown[];
|
|
284
290
|
variables?: Record<string, string>;
|
|
285
|
-
responseFormat?: unknown;
|
|
286
|
-
config?: unknown;
|
|
287
291
|
}
|
|
288
292
|
interface Session<TSpec extends AgentSpec = AgentSpec> {
|
|
289
293
|
id: string;
|
|
@@ -458,5 +462,194 @@ interface AgentBuilderServer<TSpec extends AgentSpec = AgentSpec, TModel extends
|
|
|
458
462
|
agentName: string;
|
|
459
463
|
}): Promise<void>;
|
|
460
464
|
}
|
|
465
|
+
/**
|
|
466
|
+
* Provider type id. Reserved literal: `"custom"` for user-defined providers;
|
|
467
|
+
* any other string is a builtin (e.g. `"openai"`, `"anthropic"`).
|
|
468
|
+
*
|
|
469
|
+
* Note: `string | "custom"` is useless in TypeScript (`"custom"` ⊆ `string`),
|
|
470
|
+
* so this stays `string` and `"custom"` is a documented convention.
|
|
471
|
+
*/
|
|
472
|
+
type ProviderType = string;
|
|
473
|
+
/**
|
|
474
|
+
* Model row — form "Model ID" + "Display name".
|
|
475
|
+
* Host extends for properties, etc.
|
|
476
|
+
*/
|
|
477
|
+
interface ModelEntry {
|
|
478
|
+
id: string;
|
|
479
|
+
name: string;
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Write config for create/update (custom form + catalog "Save key").
|
|
483
|
+
* Host extends. `baseUrl` present iff `type === "custom"`.
|
|
484
|
+
*/
|
|
485
|
+
interface ModelProviderConfigBase<TModel extends ModelEntry = ModelEntry> {
|
|
486
|
+
type: ProviderType;
|
|
487
|
+
name: string;
|
|
488
|
+
/** Present iff `type === "custom"`. */
|
|
489
|
+
baseUrl?: string;
|
|
490
|
+
apiKey: string;
|
|
491
|
+
models: TModel[];
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Configured provider card (list/read). No raw `apiKey`.
|
|
495
|
+
* Host extends for apiKeySet, timestamps, etc.
|
|
496
|
+
*/
|
|
497
|
+
interface ModelProviderBase<TModel extends ModelEntry = ModelEntry> {
|
|
498
|
+
id: string;
|
|
499
|
+
type: ProviderType;
|
|
500
|
+
name: string;
|
|
501
|
+
/** Present iff `type === "custom"`. */
|
|
502
|
+
baseUrl?: string;
|
|
503
|
+
models: TModel[];
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Discovery-only catalog provider (AVAILABLE list).
|
|
507
|
+
* `type` must not be `"custom"` — custom providers use the custom form.
|
|
508
|
+
* Host extends for richer model rows.
|
|
509
|
+
*/
|
|
510
|
+
interface ModelProviderCatalogEntry<TModel extends ModelEntry = ModelEntry> {
|
|
511
|
+
type: ProviderType;
|
|
512
|
+
name: string;
|
|
513
|
+
models: TModel[];
|
|
514
|
+
}
|
|
515
|
+
/** Create — no `id`; server assigns it. Catalog path = entry + apiKey. */
|
|
516
|
+
type CreateModelProviderRequest<TModel extends ModelEntry = ModelEntry> = ModelProviderConfigBase<TModel>;
|
|
517
|
+
/** Update — `id` required. */
|
|
518
|
+
type UpdateModelProviderRequest<TModel extends ModelEntry = ModelEntry> = ModelProviderConfigBase<TModel> & {
|
|
519
|
+
id: string;
|
|
520
|
+
};
|
|
521
|
+
interface ModelCatalogServer<TModel extends ModelEntry = ModelEntry, TProvider extends ModelProviderBase<TModel> = ModelProviderBase<TModel>, TCatalogProvider extends ModelProviderCatalogEntry<TModel> = ModelProviderCatalogEntry<TModel>, TCreate extends CreateModelProviderRequest<TModel> = CreateModelProviderRequest<TModel>, TUpdate extends UpdateModelProviderRequest<TModel> = UpdateModelProviderRequest<TModel>> {
|
|
522
|
+
getModelProviderCatalog(): Promise<TCatalogProvider[]>;
|
|
523
|
+
listModelProviders(): Promise<TProvider[]>;
|
|
524
|
+
createModelProvider(req: TCreate): Promise<TProvider>;
|
|
525
|
+
/** Full replace update keyed by provider `id`. */
|
|
526
|
+
updateModelProvider(req: TUpdate): Promise<TProvider>;
|
|
527
|
+
deleteModelProvider?(req: {
|
|
528
|
+
id: string;
|
|
529
|
+
}): Promise<void>;
|
|
530
|
+
}
|
|
531
|
+
/** Tool row on a connector detail. Host extends for schemas, etc. */
|
|
532
|
+
interface ToolBase {
|
|
533
|
+
id: string;
|
|
534
|
+
name: string;
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* Auth type id. Reserved literals: `"None"`, `"OAuth"`, `"API Key"`.
|
|
538
|
+
* Stays `string` so hosts can widen (same pattern as `ProviderType`).
|
|
539
|
+
*/
|
|
540
|
+
type ConnectorAuthType = string;
|
|
541
|
+
/**
|
|
542
|
+
* Write-time connector auth. Host extends / narrows via `TType`.
|
|
543
|
+
* For `"API Key"`, pass `apiKey` (and optional `headerName`).
|
|
544
|
+
*/
|
|
545
|
+
interface ConnectorAuth<TType extends ConnectorAuthType = ConnectorAuthType> {
|
|
546
|
+
type: TType;
|
|
547
|
+
apiKey?: string;
|
|
548
|
+
headerName?: string;
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Catalog / list auth — no secrets. Host extends / narrows via `TType`.
|
|
552
|
+
*/
|
|
553
|
+
interface ConnectorAuthPublic<TType extends ConnectorAuthType = ConnectorAuthType> {
|
|
554
|
+
type: TType;
|
|
555
|
+
headerName?: string;
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* MCP / connector create-edit config. Host extends for extra fields, etc.
|
|
559
|
+
*/
|
|
560
|
+
interface ConnectorConfigBase<TAuth extends ConnectorAuth = ConnectorAuth> {
|
|
561
|
+
name: string;
|
|
562
|
+
url: string;
|
|
563
|
+
auth: TAuth;
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Connected connector row (settings/connectors). No raw `apiKey`.
|
|
567
|
+
* Host extends.
|
|
568
|
+
*/
|
|
569
|
+
interface ConnectorBase<TTool extends ToolBase = ToolBase, TAuth extends ConnectorAuthPublic = ConnectorAuthPublic> {
|
|
570
|
+
id: string;
|
|
571
|
+
name: string;
|
|
572
|
+
description: string;
|
|
573
|
+
url: string;
|
|
574
|
+
auth: TAuth;
|
|
575
|
+
authenticated: boolean;
|
|
576
|
+
tools: TTool[];
|
|
577
|
+
}
|
|
578
|
+
/** Discovery catalog entry for "+ Add MCP server". Host extends. */
|
|
579
|
+
interface ConnectorCatalogEntry<TAuth extends ConnectorAuthPublic = ConnectorAuthPublic> {
|
|
580
|
+
id: string;
|
|
581
|
+
name: string;
|
|
582
|
+
description?: string;
|
|
583
|
+
url: string;
|
|
584
|
+
auth: TAuth;
|
|
585
|
+
}
|
|
586
|
+
/** Create connector — no `id`; server assigns it. Host extends. */
|
|
587
|
+
type CreateConnectorRequest<TAuth extends ConnectorAuth = ConnectorAuth> = ConnectorConfigBase<TAuth>;
|
|
588
|
+
/** Update connector — `id` required. Host extends. */
|
|
589
|
+
type UpdateConnectorRequest<TAuth extends ConnectorAuth = ConnectorAuth> = ConnectorConfigBase<TAuth> & {
|
|
590
|
+
id: string;
|
|
591
|
+
};
|
|
592
|
+
interface ConnectorCatalogServer<TTool extends ToolBase = ToolBase, TAuthWrite extends ConnectorAuth = ConnectorAuth, TAuthPublic extends ConnectorAuthPublic = ConnectorAuthPublic, TConnector extends ConnectorBase<TTool, TAuthPublic> = ConnectorBase<TTool, TAuthPublic>, TCatalogEntry extends ConnectorCatalogEntry<TAuthPublic> = ConnectorCatalogEntry<TAuthPublic>, TCreate extends CreateConnectorRequest<TAuthWrite> = CreateConnectorRequest<TAuthWrite>, TUpdate extends UpdateConnectorRequest<TAuthWrite> = UpdateConnectorRequest<TAuthWrite>> {
|
|
593
|
+
getConnectorCatalog(): Promise<TCatalogEntry[]>;
|
|
594
|
+
listConnectors(req?: {
|
|
595
|
+
query?: string;
|
|
596
|
+
}): Promise<TConnector[]>;
|
|
597
|
+
createConnector(req: TCreate): Promise<TConnector>;
|
|
598
|
+
/** Full replace update keyed by connector `id`. */
|
|
599
|
+
updateConnector(req: TUpdate): Promise<TConnector>;
|
|
600
|
+
/** Start connector auth (e.g. OAuth). Host may widen return with `authUrl`. */
|
|
601
|
+
authenticateConnector(req: {
|
|
602
|
+
id: string;
|
|
603
|
+
}): Promise<TConnector>;
|
|
604
|
+
/** Clear connector auth. */
|
|
605
|
+
disconnectConnector(req: {
|
|
606
|
+
id: string;
|
|
607
|
+
}): Promise<TConnector>;
|
|
608
|
+
deleteConnector?(req: {
|
|
609
|
+
id: string;
|
|
610
|
+
}): Promise<void>;
|
|
611
|
+
}
|
|
612
|
+
/** Skill row shown in settings/skills (list + delete). Host extends for fqn, etc. */
|
|
613
|
+
interface SkillBase {
|
|
614
|
+
id: string;
|
|
615
|
+
name: string;
|
|
616
|
+
description: string;
|
|
617
|
+
}
|
|
618
|
+
/** Create-skill request. Host extends for branch, auth, etc. */
|
|
619
|
+
interface CreateSkillRequest {
|
|
620
|
+
repo: string;
|
|
621
|
+
directory: string;
|
|
622
|
+
}
|
|
623
|
+
interface SkillCatalogServer<TSkill extends SkillBase = SkillBase, TCreate extends CreateSkillRequest = CreateSkillRequest> {
|
|
624
|
+
listSkills(req?: {
|
|
625
|
+
query?: string;
|
|
626
|
+
}): Promise<TSkill[]>;
|
|
627
|
+
createSkill(req: TCreate): Promise<TSkill>;
|
|
628
|
+
deleteSkill?(req: {
|
|
629
|
+
id: string;
|
|
630
|
+
}): Promise<void>;
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
633
|
+
* Settings management aggregate — modelCatalog + connectorCatalog + optional skillCatalog.
|
|
634
|
+
* Hosts may pass the whole object to an app shell, or a focused sub-port to a page.
|
|
635
|
+
*/
|
|
636
|
+
interface CatalogServer<TModelCatalog extends ModelCatalogServer = ModelCatalogServer, TConnectorCatalog extends ConnectorCatalogServer = ConnectorCatalogServer, TSkillCatalog extends SkillCatalogServer = SkillCatalogServer> {
|
|
637
|
+
modelCatalog: TModelCatalog;
|
|
638
|
+
connectorCatalog: TConnectorCatalog;
|
|
639
|
+
/** Optional — omit when the host has no skills settings surface. */
|
|
640
|
+
skillCatalog?: TSkillCatalog;
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Composed host port: chat + builder + optional settings catalog.
|
|
644
|
+
* Agent-ui's `AgentUIServer` mirrors this shape; named differently here to
|
|
645
|
+
* avoid colliding with that package's local type name.
|
|
646
|
+
*
|
|
647
|
+
* `catalog` is optional — if the host passes it, settings UI can call
|
|
648
|
+
* `useCatalogServer()` / show modelCatalog, connectorCatalog, and skillCatalog;
|
|
649
|
+
* if omitted, those surfaces stay hidden.
|
|
650
|
+
*/
|
|
651
|
+
type AgentUIServerPort<TChat extends AgentChatServer = AgentChatServer, TBuilder extends AgentBuilderServer = AgentBuilderServer, TCatalog extends CatalogServer = CatalogServer> = TChat & TBuilder & {
|
|
652
|
+
catalog?: TCatalog;
|
|
653
|
+
};
|
|
461
654
|
|
|
462
|
-
export type { AgentSpec as A, CreateSessionRequest as C,
|
|
655
|
+
export type { AgentParent as $, AgentSpec as A, ModelProviderConfigBase as B, CreateSessionRequest as C, ProviderType as D, SandboxCreatedEvent as E, SessionEventItem as F, SkillBase as G, SkillCatalogServer as H, ToolApprovalRequiredEvent as I, ToolBase as J, ToolCall as K, ListSessionsParams as L, McpAuthRequiredEvent as M, ToolResponseRequiredEvent as N, TurnStateDone as O, PreviousTurnIdInput as P, TurnStreamData as Q, TurnStreamingEvent as R, Session as S, Turn as T, UpdateSessionRequest as U, UpdateConnectorRequest as V, UpdateModelProviderRequest as W, UserMessage as X, DeltaEvents as Y, ActionRequiredEvent as Z, AgentInfo as _, TurnState as a, AgentSelectorEntry as a0, ApprovalDecision as a1, ChunkDeltaToolCall as a2, ConnectorSelectorEntry as a3, ListSessionsOrder as a4, McpInitializeEvent as a5, McpServerAuthInfo as a6, McpServerMount as a7, Model as a8, ModelMessageContentPart as a9, ModelMessageDeltaEvent as aa, ModelParams as ab, ModelSelectorEntry as ac, PageParams as ad, SearchAgentSelectorParams as ae, SkillMount as af, SkillSelectorEntry as ag, ThreadDoneEvent as ah, ToolCallFunction as ai, ToolCallRef as aj, ToolInfo as ak, ToolResponseEvent as al, TurnCreatedEvent as am, TurnDoneEvent as an, TurnStateCancelled as ao, TurnStateError as ap, TurnStateRunning as aq, UserMessageContent as ar, AgentChatServer as b, TurnEvent as c, ThreadCreatedEvent as d, UserToolResponseEvent as e, UserToolApprovalEvent as f, TurnInputItem as g, AgentBuilderServer as h, AgentUIServerPort as i, CatalogServer as j, ConnectorAuth as k, ConnectorAuthPublic as l, ConnectorAuthType as m, ConnectorBase as n, ConnectorCatalogEntry as o, ConnectorCatalogServer as p, ConnectorConfigBase as q, CreateConnectorRequest as r, CreateModelProviderRequest as s, CreateSkillRequest as t, ListResult as u, ModelCatalogServer as v, ModelEntry as w, ModelMessageEvent as x, ModelProviderBase as y, ModelProviderCatalogEntry as z };
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truefoundry/assistant-ui-runtime",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "TrueFoundry Gateway agent runtime adapter for assistant-ui",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
|
-
"url": "https://github.com/truefoundry/truefoundry-agents-assistant-ui-runtime"
|
|
8
|
+
"url": "git+https://github.com/truefoundry/truefoundry-agents-assistant-ui-runtime.git"
|
|
9
9
|
},
|
|
10
10
|
"homepage": "https://github.com/truefoundry/truefoundry-agents-assistant-ui-runtime#readme",
|
|
11
11
|
"keywords": [
|
|
@@ -27,6 +27,11 @@
|
|
|
27
27
|
"import": "./dist/index.js",
|
|
28
28
|
"default": "./dist/index.js"
|
|
29
29
|
},
|
|
30
|
+
"./server": {
|
|
31
|
+
"types": "./dist/server/index.d.ts",
|
|
32
|
+
"import": "./dist/server/index.js",
|
|
33
|
+
"default": "./dist/server/index.js"
|
|
34
|
+
},
|
|
30
35
|
"./plugins/truefoundry-agent-server-adapter": {
|
|
31
36
|
"types": "./dist/plugins/truefoundry-agent-server-adapter/index.d.ts",
|
|
32
37
|
"import": "./dist/plugins/truefoundry-agent-server-adapter/index.js",
|
|
@@ -55,7 +60,7 @@
|
|
|
55
60
|
"peerDependencies": {
|
|
56
61
|
"@types/react": "*",
|
|
57
62
|
"react": "^18 || ^19",
|
|
58
|
-
"truefoundry-gateway-sdk": "^0.4.0-rc.
|
|
63
|
+
"truefoundry-gateway-sdk": "^0.4.0-rc.6"
|
|
59
64
|
},
|
|
60
65
|
"peerDependenciesMeta": {
|
|
61
66
|
"@types/react": {
|
|
@@ -71,9 +76,9 @@
|
|
|
71
76
|
"@types/react": "^19.2.17",
|
|
72
77
|
"jsdom": "^29.1.1",
|
|
73
78
|
"react": "^19.2.4",
|
|
74
|
-
"truefoundry-gateway-sdk": "0.4.0-rc.
|
|
79
|
+
"truefoundry-gateway-sdk": "0.4.0-rc.6",
|
|
75
80
|
"tsup": "^8.5.0",
|
|
76
81
|
"typescript": "^5.9.3",
|
|
77
82
|
"vitest": "4.1.9"
|
|
78
83
|
}
|
|
79
|
-
}
|
|
84
|
+
}
|
|
@@ -1,33 +1,30 @@
|
|
|
1
1
|
import type { AgentSpec } from "../server/types.js";
|
|
2
2
|
|
|
3
|
-
export type { AgentSpec } from "../server/types.js";
|
|
4
|
-
|
|
5
3
|
/** @deprecated Use Session with isMutable: true instead. Kept for title helper. */
|
|
6
4
|
export type DraftSession = {
|
|
7
5
|
title?: string | null;
|
|
8
6
|
agentSpec: AgentSpec;
|
|
9
7
|
};
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
messages?: AgentSpec["messages"];
|
|
19
|
-
variables?: AgentSpec["variables"];
|
|
20
|
-
responseFormat?: AgentSpec["responseFormat"];
|
|
21
|
-
config?: AgentSpec["config"];
|
|
9
|
+
/** Partial update — host fields flow through when `TSpec` is widened. */
|
|
10
|
+
export type AgentSpecUpdate<TSpec extends AgentSpec = AgentSpec> = {
|
|
11
|
+
[K in keyof TSpec]?: K extends "model"
|
|
12
|
+
? Omit<Partial<TSpec["model"]>, "params"> & {
|
|
13
|
+
params?: Partial<NonNullable<TSpec["model"]["params"]>>;
|
|
14
|
+
}
|
|
15
|
+
: TSpec[K];
|
|
22
16
|
};
|
|
23
17
|
|
|
24
|
-
export function mergeAgentSpec
|
|
18
|
+
export function mergeAgentSpec<TSpec extends AgentSpec>(
|
|
19
|
+
base: TSpec,
|
|
20
|
+
update: AgentSpecUpdate<TSpec>,
|
|
21
|
+
): TSpec {
|
|
25
22
|
const { model: modelUpdate, ...rest } = update;
|
|
26
23
|
|
|
27
|
-
const next
|
|
24
|
+
const next = {
|
|
28
25
|
...base,
|
|
29
26
|
...rest,
|
|
30
|
-
};
|
|
27
|
+
} as TSpec;
|
|
31
28
|
|
|
32
29
|
if (modelUpdate != null) {
|
|
33
30
|
next.model = {
|
|
@@ -38,7 +35,7 @@ export function mergeAgentSpec(base: AgentSpec, update: AgentSpecUpdate): AgentS
|
|
|
38
35
|
modelUpdate.params != null
|
|
39
36
|
? { ...base.model.params, ...modelUpdate.params }
|
|
40
37
|
: base.model.params,
|
|
41
|
-
};
|
|
38
|
+
} as TSpec["model"];
|
|
42
39
|
}
|
|
43
40
|
|
|
44
41
|
return next;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { AgentChatServer } from "../server/types.js";
|
|
2
|
-
import type { AgentSpec } from "./agentSpec.js";
|
|
1
|
+
import type { AgentChatServer, AgentSpec } from "../server/types.js";
|
|
3
2
|
|
|
4
3
|
export const DRAFT_SESSION_LAST_UPDATED_AT_HEADER = "x-tfy-session-last-updated-at";
|
|
5
4
|
|
|
@@ -3,7 +3,7 @@ import { describe, expect, it, vi } from "vitest";
|
|
|
3
3
|
import type { AgentChatServer, Session } from "../server/index.js";
|
|
4
4
|
|
|
5
5
|
import { createTrueFoundryDraftThreadListAdapter } from "./truefoundryDraftThreadListAdapter.js";
|
|
6
|
-
import type { AgentSpec } from "
|
|
6
|
+
import type { AgentSpec } from "../server/types.js";
|
|
7
7
|
|
|
8
8
|
const defaultAgentSpec: AgentSpec = {
|
|
9
9
|
model: { name: "anthropic/claude-sonnet-4-6" },
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { RemoteThreadListAdapter } from "@assistant-ui/core";
|
|
2
2
|
|
|
3
3
|
import type { AgentChatServer } from "../server/types.js";
|
|
4
|
-
import {
|
|
4
|
+
import type { AgentSpec } from "../server/types.js";
|
|
5
|
+
import { draftSessionTitle } from "./agentSpec.js";
|
|
5
6
|
import { sessionListStartTimestamp } from "../sessionListStartTimestamp.js";
|
|
6
7
|
|
|
7
8
|
const THREAD_LIST_PAGE_SIZE = 20;
|
|
@@ -2,11 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
type AgentSpec,
|
|
8
|
-
type AgentSpecUpdate,
|
|
9
|
-
} from "./agentSpec.js";
|
|
5
|
+
import type { AgentSpec } from "../server/types.js";
|
|
6
|
+
import { mergeAgentSpec, type AgentSpecUpdate } from "./agentSpec.js";
|
|
10
7
|
import type { DraftSessionBridge } from "./draftSessionBridge.js";
|
|
11
8
|
|
|
12
9
|
const SPEC_SYNC_DEBOUNCE_MS = 400;
|
|
@@ -22,6 +19,7 @@ export type UseDraftAgentSpecOptions = {
|
|
|
22
19
|
export type UseDraftAgentSpecResult = {
|
|
23
20
|
agentSpec: AgentSpec | null;
|
|
24
21
|
draftSessionId: string | undefined;
|
|
22
|
+
isSpecLoading: boolean;
|
|
25
23
|
isSpecSyncing: boolean;
|
|
26
24
|
specError: unknown | null;
|
|
27
25
|
updateAgentSpec: (update: AgentSpecUpdate) => void;
|
|
@@ -37,6 +35,7 @@ export function useDraftAgentSpec({
|
|
|
37
35
|
}: UseDraftAgentSpecOptions): UseDraftAgentSpecResult {
|
|
38
36
|
const enabled = draftBridge != null;
|
|
39
37
|
const [agentSpec, setAgentSpec] = useState<AgentSpec>(defaultAgentSpec);
|
|
38
|
+
const [isSpecLoading, setIsSpecLoading] = useState(false);
|
|
40
39
|
const [isSpecSyncing, setIsSpecSyncing] = useState(false);
|
|
41
40
|
const [specError, setSpecError] = useState<unknown | null>(null);
|
|
42
41
|
|
|
@@ -86,6 +85,7 @@ export function useDraftAgentSpec({
|
|
|
86
85
|
setAgentSpec(defaultAgentSpec);
|
|
87
86
|
localDirtyRef.current = false;
|
|
88
87
|
setSpecError(null);
|
|
88
|
+
setIsSpecLoading(false);
|
|
89
89
|
return;
|
|
90
90
|
}
|
|
91
91
|
|
|
@@ -94,6 +94,7 @@ export function useDraftAgentSpec({
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
let cancelled = false;
|
|
97
|
+
setIsSpecLoading(true);
|
|
97
98
|
void (async () => {
|
|
98
99
|
try {
|
|
99
100
|
const loaded = await draftBridge.getDraftAgentSpec(draftSessionId);
|
|
@@ -106,21 +107,29 @@ export function useDraftAgentSpec({
|
|
|
106
107
|
scheduleSpecSyncRef.current?.(draftSessionId, agentSpecRef.current);
|
|
107
108
|
localDirtyRef.current = false;
|
|
108
109
|
setSpecError(null);
|
|
110
|
+
setIsSpecLoading(false);
|
|
109
111
|
return;
|
|
110
112
|
}
|
|
111
113
|
|
|
112
114
|
setAgentSpec(loaded);
|
|
113
115
|
setSpecError(null);
|
|
116
|
+
setIsSpecLoading(false);
|
|
114
117
|
} catch (error) {
|
|
115
118
|
if (!cancelled) {
|
|
116
119
|
onError?.(error);
|
|
117
120
|
setSpecError(error);
|
|
121
|
+
setIsSpecLoading(false);
|
|
118
122
|
}
|
|
119
123
|
}
|
|
120
124
|
})();
|
|
121
125
|
|
|
122
126
|
return () => {
|
|
123
127
|
cancelled = true;
|
|
128
|
+
// The cancelled load can no longer clear the flag itself. Releasing it
|
|
129
|
+
// here keeps it from sticking when the next run early-returns on an
|
|
130
|
+
// already-loaded draft; a run that starts a fresh load re-raises it in
|
|
131
|
+
// the same commit.
|
|
132
|
+
setIsSpecLoading(false);
|
|
124
133
|
};
|
|
125
134
|
}, [defaultAgentSpec, draftBridge, draftSessionId, enabled, onError]);
|
|
126
135
|
|
|
@@ -232,6 +241,7 @@ export function useDraftAgentSpec({
|
|
|
232
241
|
() => ({
|
|
233
242
|
agentSpec: enabled ? agentSpec : null,
|
|
234
243
|
draftSessionId: enabled ? draftSessionId : undefined,
|
|
244
|
+
isSpecLoading: enabled ? isSpecLoading : false,
|
|
235
245
|
isSpecSyncing: enabled ? isSpecSyncing : false,
|
|
236
246
|
specError: enabled ? specError : null,
|
|
237
247
|
updateAgentSpec,
|
|
@@ -241,6 +251,7 @@ export function useDraftAgentSpec({
|
|
|
241
251
|
agentSpec,
|
|
242
252
|
draftSessionId,
|
|
243
253
|
enabled,
|
|
254
|
+
isSpecLoading,
|
|
244
255
|
isSpecSyncing,
|
|
245
256
|
specError,
|
|
246
257
|
takeTurnHeaderTimestamp,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
2
|
|
|
3
|
-
import { mergeAgentSpec
|
|
3
|
+
import { mergeAgentSpec } from "./draft/agentSpec.js";
|
|
4
|
+
import type { AgentSpec } from "./server/types.js";
|
|
4
5
|
import {
|
|
5
6
|
resolveTrueFoundryAgentConfig,
|
|
6
7
|
resolveTrueFoundryAgentRuntimeOptions,
|
package/src/index.ts
CHANGED
|
@@ -13,17 +13,17 @@ export {
|
|
|
13
13
|
export type { ConvertTurnsResult, UserMessageContent } from "./convertTurnMessages.js";
|
|
14
14
|
export { ROOT_THREAD_ID } from "./constants.js";
|
|
15
15
|
export type {
|
|
16
|
-
UseTrueFoundryAgentRuntimeOptions,
|
|
17
16
|
NamedAgentConfig,
|
|
18
17
|
DraftAgentConfig,
|
|
19
18
|
TrueFoundryAgentConfig,
|
|
19
|
+
UseTrueFoundryAgentRuntimeOptions,
|
|
20
20
|
} from "./types.js";
|
|
21
|
-
export type {
|
|
22
|
-
export { mergeAgentSpec, draftSessionTitle } from "./
|
|
23
|
-
export { createTrueFoundryDraftThreadListAdapter } from "./
|
|
21
|
+
export type { AgentSpecUpdate, DraftSession } from "./draft/agentSpec.js";
|
|
22
|
+
export { mergeAgentSpec, draftSessionTitle } from "./draft/agentSpec.js";
|
|
23
|
+
export { createTrueFoundryDraftThreadListAdapter } from "./draft/truefoundryDraftThreadListAdapter.js";
|
|
24
24
|
export { createTrueFoundryOwnedSessionsThreadListAdapter } from "./truefoundryOwnedSessionsThreadListAdapter.js";
|
|
25
|
-
export { createDraftSessionBridge } from "./
|
|
26
|
-
export type { DraftSessionBridge } from "./
|
|
25
|
+
export { createDraftSessionBridge } from "./draft/draftSessionBridge.js";
|
|
26
|
+
export type { DraftSessionBridge } from "./draft/draftSessionBridge.js";
|
|
27
27
|
export {
|
|
28
28
|
useTrueFoundryAgentSpec,
|
|
29
29
|
useTrueFoundryUpdateAgentSpec,
|
|
@@ -82,7 +82,7 @@ export type {
|
|
|
82
82
|
TurnState,
|
|
83
83
|
TurnStateDone,
|
|
84
84
|
TurnInputItem,
|
|
85
|
-
AgentSpec
|
|
85
|
+
AgentSpec,
|
|
86
86
|
ListResult,
|
|
87
87
|
CreateSessionRequest,
|
|
88
88
|
UpdateSessionRequest,
|
|
@@ -91,6 +91,29 @@ export type {
|
|
|
91
91
|
UserToolApprovalEvent,
|
|
92
92
|
UserToolResponseEvent,
|
|
93
93
|
PreviousTurnIdInput,
|
|
94
|
+
ProviderType,
|
|
95
|
+
ModelEntry,
|
|
96
|
+
ModelProviderConfigBase,
|
|
97
|
+
ModelProviderBase,
|
|
98
|
+
ModelProviderCatalogEntry,
|
|
99
|
+
CreateModelProviderRequest,
|
|
100
|
+
UpdateModelProviderRequest,
|
|
101
|
+
ModelCatalogServer,
|
|
102
|
+
ToolBase,
|
|
103
|
+
ConnectorAuthType,
|
|
104
|
+
ConnectorAuth,
|
|
105
|
+
ConnectorAuthPublic,
|
|
106
|
+
ConnectorConfigBase,
|
|
107
|
+
ConnectorBase,
|
|
108
|
+
ConnectorCatalogEntry,
|
|
109
|
+
CreateConnectorRequest,
|
|
110
|
+
UpdateConnectorRequest,
|
|
111
|
+
ConnectorCatalogServer,
|
|
112
|
+
SkillBase,
|
|
113
|
+
CreateSkillRequest,
|
|
114
|
+
SkillCatalogServer,
|
|
115
|
+
CatalogServer,
|
|
116
|
+
AgentUIServerPort,
|
|
94
117
|
} from "./server/index.js";
|
|
95
118
|
export type {
|
|
96
119
|
SandboxCreatedEvent,
|
|
@@ -106,3 +129,44 @@ export type {
|
|
|
106
129
|
ToolResponseRequiredEvent,
|
|
107
130
|
} from "./server/index.js";
|
|
108
131
|
export { isEventDelta, mergeEventDelta } from "./server/index.js";
|
|
132
|
+
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
// Plugin: truefoundry-agent-server-adapter
|
|
135
|
+
// ---------------------------------------------------------------------------
|
|
136
|
+
|
|
137
|
+
export {
|
|
138
|
+
createTrueFoundryChatServer,
|
|
139
|
+
type CreateTrueFoundryChatServerOptions,
|
|
140
|
+
type TrueFoundryChatServer,
|
|
141
|
+
type TfyAgentSpec,
|
|
142
|
+
type TfySkillMount,
|
|
143
|
+
type TfyMcpServerMount,
|
|
144
|
+
type TfyModelParams,
|
|
145
|
+
type TfyRuntimeConfig,
|
|
146
|
+
type TfyResponseFormat,
|
|
147
|
+
type TfySubject,
|
|
148
|
+
type ToolsSelectorItem,
|
|
149
|
+
type ToolsSelectorTag,
|
|
150
|
+
type RequireApprovalToolSelectorItem,
|
|
151
|
+
type RequireApprovalToolsSelectorTag,
|
|
152
|
+
type TfyTurn,
|
|
153
|
+
type TfyTurnState,
|
|
154
|
+
type TfyTurnCancelledReason,
|
|
155
|
+
type TfyTurnStateDoneOutput,
|
|
156
|
+
type TfySession,
|
|
157
|
+
type TfyCreateSessionRequest,
|
|
158
|
+
type TfyListSessionsParams,
|
|
159
|
+
type TfyToolInfo,
|
|
160
|
+
type TfySystemToolInfo,
|
|
161
|
+
type TfyMcpToolInfo,
|
|
162
|
+
type TfyModelMessageUsage,
|
|
163
|
+
type TfyFinishReason,
|
|
164
|
+
type TfyThreadState,
|
|
165
|
+
type TfyMcpServerInitInfo,
|
|
166
|
+
isTfyToolInfo,
|
|
167
|
+
isTfySystemToolInfo,
|
|
168
|
+
isTfyMcpToolInfo,
|
|
169
|
+
getTfyUsage,
|
|
170
|
+
getTfyThreadState,
|
|
171
|
+
getTfyMcpInitServers,
|
|
172
|
+
} from "./plugins/truefoundry-agent-server-adapter/index.js";
|