@truefoundry/trueforge-assistant-ui-runtime 0.0.0 → 0.2.0-rc.0

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.
Files changed (55) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/LICENSE +201 -0
  3. package/README.md +146 -4
  4. package/dist/chunk-2SQK6TIO.js +104 -0
  5. package/dist/chunk-2SQK6TIO.js.map +1 -0
  6. package/dist/index.d.ts +378 -0
  7. package/dist/index.js +4391 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/server/index.d.ts +1210 -0
  10. package/dist/server/index.js +9 -0
  11. package/dist/server/index.js.map +1 -0
  12. package/package.json +79 -16
  13. package/src/askUserQuestion.ts +38 -0
  14. package/src/attachmentAdapter.ts +63 -0
  15. package/src/collectPending.ts +167 -0
  16. package/src/constants.ts +2 -0
  17. package/src/convertTurnMessages.ts +1679 -0
  18. package/src/createSubAgent.ts +11 -0
  19. package/src/draft/agentSpec.ts +34 -0
  20. package/src/draft/draftSessionBridge.ts +28 -0
  21. package/src/draft/trueforgeDraftThreadListAdapter.ts +73 -0
  22. package/src/draft/useDraftAgentSpec.ts +289 -0
  23. package/src/extractTurnUserText.ts +23 -0
  24. package/src/foldPeerThreads.ts +553 -0
  25. package/src/hooks.ts +176 -0
  26. package/src/index.ts +227 -0
  27. package/src/lastUserMessageText.ts +19 -0
  28. package/src/listPages.ts +19 -0
  29. package/src/loadSessionSnapshot.ts +34 -0
  30. package/src/mcpAuth.ts +35 -0
  31. package/src/messageCustomMetadata.ts +50 -0
  32. package/src/modelMessageContent.ts +149 -0
  33. package/src/modelMessageImageContent.ts +154 -0
  34. package/src/requiredActionInputs.ts +38 -0
  35. package/src/sandboxDownload.ts +33 -0
  36. package/src/server/eventUtils.ts +125 -0
  37. package/src/server/events.ts +232 -0
  38. package/src/server/index.ts +178 -0
  39. package/src/server/types.ts +1191 -0
  40. package/src/sessionListStartTimestamp.ts +6 -0
  41. package/src/sessionSnapshot.ts +146 -0
  42. package/src/sessionThreadMetadata.ts +36 -0
  43. package/src/sessions.ts +17 -0
  44. package/src/streamTurn.ts +118 -0
  45. package/src/toolApproval.ts +413 -0
  46. package/src/toolResponse.ts +346 -0
  47. package/src/trueforgeExtras.ts +223 -0
  48. package/src/trueforgeOwnedSessionsThreadListAdapter.ts +71 -0
  49. package/src/trueforgeThreadListAdapter.ts +69 -0
  50. package/src/turnEventHelpers.ts +71 -0
  51. package/src/turnStreamUpdate.ts +11 -0
  52. package/src/types.ts +84 -0
  53. package/src/useTrueForgeAgentMessages.ts +1138 -0
  54. package/src/useTrueForgeAgentRuntime.ts +308 -0
  55. package/index.js +0 -6
@@ -0,0 +1,71 @@
1
+ import type { Turn } from './server/index.js';
2
+
3
+ import { buildMcpAuthTextParts, findMcpAuthRequired, mcpAuthAssistantStatus, mcpAuthMessageCustom } from './mcpAuth.js';
4
+ import type { AssistantContentPart } from './modelMessageContent.js';
5
+ import { findApprovalRequiredInTurn, toolApprovalMessageCustom, toolApprovalStatus } from './toolApproval.js';
6
+ import { findResponseRequiredInTurn, toolResponseMessageCustom, toolResponseStatus } from './toolResponse.js';
7
+ import type { TurnStreamUpdate } from './turnStreamUpdate.js';
8
+
9
+ function buildToolApprovalUpdate(content: AssistantContentPart[], turn: Pick<Turn, 'state'>): TurnStreamUpdate {
10
+ const pendingApproval = findApprovalRequiredInTurn(turn);
11
+ if (pendingApproval == null) {
12
+ return { content };
13
+ }
14
+ return {
15
+ content,
16
+ status: toolApprovalStatus(),
17
+ metadata: { custom: toolApprovalMessageCustom(pendingApproval.threadId) },
18
+ };
19
+ }
20
+
21
+ function buildToolResponseUpdate(update: TurnStreamUpdate, turn: Pick<Turn, 'state'>): TurnStreamUpdate {
22
+ const pendingResponse = findResponseRequiredInTurn(turn);
23
+ if (pendingResponse == null) {
24
+ return update;
25
+ }
26
+ return {
27
+ ...update,
28
+ content: update.content,
29
+ status: toolResponseStatus(),
30
+ metadata: {
31
+ custom: {
32
+ ...update.metadata?.custom,
33
+ ...toolResponseMessageCustom(pendingResponse.threadId),
34
+ },
35
+ },
36
+ };
37
+ }
38
+
39
+ export function appendToolResponseToTurnContent(update: TurnStreamUpdate, turn: Pick<Turn, 'state'>): TurnStreamUpdate {
40
+ if (update.status?.type === 'requires-action') {
41
+ return update;
42
+ }
43
+ return buildToolResponseUpdate(update, turn);
44
+ }
45
+
46
+ export function appendToolApprovalToTurnContent(update: TurnStreamUpdate, turn: Pick<Turn, 'state'>): TurnStreamUpdate {
47
+ if (update.status?.type === 'requires-action') {
48
+ return update;
49
+ }
50
+ const approvalUpdate = buildToolApprovalUpdate(update.content, turn);
51
+ return appendToolResponseToTurnContent(approvalUpdate, turn);
52
+ }
53
+
54
+ export function appendMcpAuthToTurnContent(
55
+ content: AssistantContentPart[],
56
+ turn: Pick<Turn, 'state'>,
57
+ ): TurnStreamUpdate {
58
+ const pendingMcpAuth = findMcpAuthRequired(turn.state.status === 'done' ? turn.state.requiredActions : undefined);
59
+ if (pendingMcpAuth == null) {
60
+ return appendToolApprovalToTurnContent({ content }, turn);
61
+ }
62
+
63
+ return appendToolApprovalToTurnContent(
64
+ {
65
+ content: [...content, ...buildMcpAuthTextParts(pendingMcpAuth.mcpServers)],
66
+ status: mcpAuthAssistantStatus(),
67
+ metadata: { custom: mcpAuthMessageCustom(pendingMcpAuth.mcpServers) },
68
+ },
69
+ turn,
70
+ );
71
+ }
@@ -0,0 +1,11 @@
1
+ import type { MessageStatus } from '@assistant-ui/core';
2
+
3
+ import type { AssistantContentPart } from './modelMessageContent.js';
4
+
5
+ export interface TurnStreamUpdate {
6
+ content: AssistantContentPart[];
7
+ status?: MessageStatus;
8
+ metadata?: {
9
+ custom?: Record<string, unknown>;
10
+ };
11
+ }
package/src/types.ts ADDED
@@ -0,0 +1,84 @@
1
+ import type {
2
+ AttachmentAdapter,
3
+ DictationAdapter,
4
+ ExternalStoreSharedOptions,
5
+ FeedbackAdapter,
6
+ RealtimeVoiceAdapter,
7
+ SpeechSynthesisAdapter,
8
+ } from '@assistant-ui/core';
9
+
10
+ import type { AgentChatServer, AgentSpec } from './server/types.js';
11
+
12
+ export interface NamedAgentConfig {
13
+ mode: 'named';
14
+ agentName: string;
15
+ }
16
+
17
+ export interface DraftAgentConfig {
18
+ mode: 'draft';
19
+ defaultAgentSpec: AgentSpec;
20
+ onAgentSpecChange?: ((spec: AgentSpec) => void) | undefined;
21
+ }
22
+
23
+ export type TrueForgeAgentConfig = NamedAgentConfig | DraftAgentConfig;
24
+
25
+ type TrueForgeAgentRuntimeBaseOptions = ExternalStoreSharedOptions & {
26
+ server: AgentChatServer;
27
+ initialSessionId?: string | undefined;
28
+ threadId?: string | undefined;
29
+ onThreadIdChange?: ((threadId: string | undefined) => void) | undefined;
30
+ onError?: ((error: unknown) => void) | undefined;
31
+ /**
32
+ * Optional filter forwarded to `listSessions({ agentId })`.
33
+ * Omit for all chats; hosts that key agents by name pass that name as the id.
34
+ */
35
+ listSessionsAgentId?: string | undefined;
36
+ /** Restrict thread history to sessions created by the authenticated subject. */
37
+ listSessionsCreatedByMe?: boolean | undefined;
38
+ adapters?:
39
+ | {
40
+ attachments?: AttachmentAdapter | undefined;
41
+ speech?: SpeechSynthesisAdapter | undefined;
42
+ dictation?: DictationAdapter | undefined;
43
+ voice?: RealtimeVoiceAdapter | undefined;
44
+ feedback?: FeedbackAdapter | undefined;
45
+ }
46
+ | undefined;
47
+ };
48
+
49
+ export type UseTrueForgeAgentRuntimeOptions = TrueForgeAgentRuntimeBaseOptions & {
50
+ /** Discriminated agent source. Omit when using legacy `agentName`. */
51
+ agent?: TrueForgeAgentConfig | undefined;
52
+ /** Legacy named-agent shorthand. Prefer `agent: { mode: "named", agentName }`. */
53
+ agentName?: string | undefined;
54
+ };
55
+
56
+ export type ResolvedTrueForgeAgentRuntimeOptions = TrueForgeAgentRuntimeBaseOptions & {
57
+ agent: TrueForgeAgentConfig;
58
+ };
59
+
60
+ export function resolveTrueForgeAgentConfig(
61
+ options: Pick<UseTrueForgeAgentRuntimeOptions, 'agent' | 'agentName'>,
62
+ ): TrueForgeAgentConfig {
63
+ if (options.agent != null) {
64
+ if (options.agent.mode === 'named' && options.agentName != null) {
65
+ return { mode: 'named', agentName: options.agentName };
66
+ }
67
+ return options.agent;
68
+ }
69
+ if (options.agentName != null) {
70
+ return { mode: 'named', agentName: options.agentName };
71
+ }
72
+ throw new Error('useTrueForgeAgentRuntime requires `agent` or legacy `agentName`.');
73
+ }
74
+
75
+ export function resolveTrueForgeAgentRuntimeOptions(
76
+ options: UseTrueForgeAgentRuntimeOptions,
77
+ ): ResolvedTrueForgeAgentRuntimeOptions {
78
+ const agent = resolveTrueForgeAgentConfig(options);
79
+
80
+ return {
81
+ ...options,
82
+ agent,
83
+ };
84
+ }