@agent-native/core 0.78.0 → 0.78.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.
Files changed (92) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +9 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/agent/types.ts +22 -0
  5. package/corpus/core/src/client/AgentPanel.tsx +8 -0
  6. package/corpus/core/src/client/AssistantChat.tsx +40 -0
  7. package/corpus/core/src/client/agent-chat.ts +173 -0
  8. package/corpus/core/src/client/composer/TiptapComposer.tsx +316 -60
  9. package/corpus/core/src/client/composer/extensions/MentionReference.tsx +3 -0
  10. package/corpus/core/src/client/composer/types.ts +22 -0
  11. package/corpus/core/src/client/index.ts +5 -0
  12. package/corpus/core/src/server/agent-chat-plugin.ts +10 -0
  13. package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +10 -2
  14. package/corpus/templates/assets/.agents/skills/image-generation/SKILL.md +14 -7
  15. package/corpus/templates/assets/.agents/skills/library-management/SKILL.md +12 -0
  16. package/corpus/templates/assets/AGENTS.md +18 -3
  17. package/corpus/templates/assets/actions/_image-model-default.ts +24 -0
  18. package/corpus/templates/assets/actions/dismiss-variant-slots.ts +15 -22
  19. package/corpus/templates/assets/actions/generate-asset.ts +30 -23
  20. package/corpus/templates/assets/actions/generate-image-batch.ts +76 -29
  21. package/corpus/templates/assets/actions/generate-image.ts +46 -30
  22. package/corpus/templates/assets/actions/generate-video.ts +18 -3
  23. package/corpus/templates/assets/actions/list-assets.ts +39 -8
  24. package/corpus/templates/assets/actions/list-libraries.ts +24 -2
  25. package/corpus/templates/assets/actions/navigate.ts +1 -1
  26. package/corpus/templates/assets/actions/open-asset-picker.ts +38 -1
  27. package/corpus/templates/assets/actions/refresh-generation-run.ts +10 -0
  28. package/corpus/templates/assets/actions/save-generated-image.ts +21 -19
  29. package/corpus/templates/assets/actions/variant-slots.ts +131 -28
  30. package/corpus/templates/assets/actions/view-screen.ts +9 -0
  31. package/corpus/templates/assets/app/components/generation/GenerationResults.tsx +425 -0
  32. package/corpus/templates/assets/app/components/layout/Header.tsx +3 -1
  33. package/corpus/templates/assets/app/components/layout/Layout.tsx +5 -0
  34. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +4 -6
  35. package/corpus/templates/assets/app/hooks/use-navigation-state.ts +47 -21
  36. package/corpus/templates/assets/app/i18n-data.ts +1815 -0
  37. package/corpus/templates/assets/app/lib/libraries.ts +6 -0
  38. package/corpus/templates/assets/app/lib/picker-chat-handoff.ts +71 -0
  39. package/corpus/templates/assets/app/routes/_index.tsx +4 -0
  40. package/corpus/templates/assets/app/routes/asset.$id.tsx +2 -2
  41. package/corpus/templates/assets/app/routes/audit.tsx +1 -1
  42. package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +1557 -2164
  43. package/corpus/templates/assets/app/routes/brand-kits._index.tsx +7 -191
  44. package/corpus/templates/assets/app/routes/brand-kits.tsx +1 -5
  45. package/corpus/templates/assets/app/routes/libraries.tsx +4 -4
  46. package/corpus/templates/assets/app/routes/library.$id.tsx +9 -7
  47. package/corpus/templates/assets/app/routes/library.tsx +1454 -175
  48. package/corpus/templates/assets/server/db/index.ts +1 -1
  49. package/corpus/templates/assets/server/lib/generation.ts +86 -15
  50. package/corpus/templates/assets/server/plugins/agent-chat.ts +196 -0
  51. package/corpus/templates/assets/server/plugins/db.ts +5 -0
  52. package/corpus/templates/assets/shared/api.ts +6 -3
  53. package/dist/agent/types.d.ts +21 -0
  54. package/dist/agent/types.d.ts.map +1 -1
  55. package/dist/agent/types.js.map +1 -1
  56. package/dist/client/AgentPanel.d.ts +5 -1
  57. package/dist/client/AgentPanel.d.ts.map +1 -1
  58. package/dist/client/AgentPanel.js +2 -2
  59. package/dist/client/AgentPanel.js.map +1 -1
  60. package/dist/client/AssistantChat.d.ts +6 -0
  61. package/dist/client/AssistantChat.d.ts.map +1 -1
  62. package/dist/client/AssistantChat.js +15 -3
  63. package/dist/client/AssistantChat.js.map +1 -1
  64. package/dist/client/agent-chat.d.ts +32 -0
  65. package/dist/client/agent-chat.d.ts.map +1 -1
  66. package/dist/client/agent-chat.js +113 -0
  67. package/dist/client/agent-chat.js.map +1 -1
  68. package/dist/client/composer/TiptapComposer.d.ts +2 -1
  69. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  70. package/dist/client/composer/TiptapComposer.js +228 -56
  71. package/dist/client/composer/TiptapComposer.js.map +1 -1
  72. package/dist/client/composer/extensions/MentionReference.d.ts.map +1 -1
  73. package/dist/client/composer/extensions/MentionReference.js +3 -0
  74. package/dist/client/composer/extensions/MentionReference.js.map +1 -1
  75. package/dist/client/composer/types.d.ts +21 -0
  76. package/dist/client/composer/types.d.ts.map +1 -1
  77. package/dist/client/composer/types.js.map +1 -1
  78. package/dist/client/index.d.ts +1 -1
  79. package/dist/client/index.d.ts.map +1 -1
  80. package/dist/client/index.js +1 -1
  81. package/dist/client/index.js.map +1 -1
  82. package/dist/collab/routes.d.ts +2 -2
  83. package/dist/notifications/routes.d.ts +3 -3
  84. package/dist/observability/routes.d.ts +6 -6
  85. package/dist/progress/routes.d.ts +1 -1
  86. package/dist/resources/handlers.d.ts +3 -3
  87. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  88. package/dist/server/agent-chat-plugin.js +5 -0
  89. package/dist/server/agent-chat-plugin.js.map +1 -1
  90. package/dist/server/agent-engine-api-key-route.d.ts +2 -2
  91. package/dist/server/transcribe-voice.d.ts +1 -1
  92. package/package.json +1 -1
package/corpus/README.md CHANGED
@@ -28,4 +28,4 @@ rg -n "defineAction|useActionQuery" node_modules/@agent-native/core/corpus
28
28
  ## Generated Counts
29
29
 
30
30
  - core files: 1937
31
- - template files: 4348
31
+ - template files: 4351
@@ -1,5 +1,14 @@
1
1
  # @agent-native/core
2
2
 
3
+ ## 0.78.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 71849f1: Add structured composer reference chips that can be inserted programmatically
8
+ and constrained to one visible value per app-defined slot.
9
+ - 71849f1: Forward chat thread footer slots through AgentSidebar so apps can keep live run
10
+ results attached to chat threads.
11
+
3
12
  ## 0.78.0
4
13
 
5
14
  ### Minor Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.78.0",
3
+ "version": "0.78.1",
4
4
  "description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {
@@ -74,6 +74,9 @@ export interface AgentChatReference {
74
74
  source: string;
75
75
  refType?: string;
76
76
  refId?: string;
77
+ slotKey?: string;
78
+ slotLabel?: string;
79
+ metadata?: Record<string, unknown>;
77
80
  }
78
81
 
79
82
  export interface MentionProviderItem {
@@ -84,6 +87,25 @@ export interface MentionProviderItem {
84
87
  refType: string;
85
88
  refId?: string;
86
89
  refPath?: string;
90
+ slotKey?: string;
91
+ slotLabel?: string;
92
+ metadata?: Record<string, unknown>;
93
+ clearsSlots?: string[];
94
+ relatedReferences?: MentionProviderReference[];
95
+ }
96
+
97
+ export interface MentionProviderReference {
98
+ label: string;
99
+ icon?: string;
100
+ source?: string;
101
+ refType: string;
102
+ refId?: string | null;
103
+ refPath?: string | null;
104
+ slotKey?: string;
105
+ slotLabel?: string;
106
+ metadata?: Record<string, unknown>;
107
+ clearsSlots?: string[];
108
+ relatedReferences?: MentionProviderReference[];
87
109
  }
88
110
 
89
111
  export interface MentionProvider {
@@ -2338,6 +2338,10 @@ export interface AgentSidebarProps {
2338
2338
  suggestions?: string[];
2339
2339
  /** Context-aware suggestions merged with `suggestions`. Enabled by default. */
2340
2340
  dynamicSuggestions?: AssistantChatProps["dynamicSuggestions"];
2341
+ /** Optional controls rendered in the chat composer toolbar. */
2342
+ composerToolbarSlot?: AssistantChatProps["composerToolbarSlot"];
2343
+ /** Optional content rendered at the bottom of the chat thread. */
2344
+ threadFooterSlot?: AssistantChatProps["threadFooterSlot"];
2341
2345
  /** Initial sidebar width in pixels. Mount-only; user resize and a saved
2342
2346
  * localStorage value override this. Default: 380 */
2343
2347
  defaultSidebarWidth?: number;
@@ -2384,6 +2388,8 @@ export function AgentSidebar({
2384
2388
  emptyStateText = "How can I help you?",
2385
2389
  suggestions,
2386
2390
  dynamicSuggestions,
2391
+ composerToolbarSlot,
2392
+ threadFooterSlot,
2387
2393
  defaultSidebarWidth,
2388
2394
  sidebarWidth,
2389
2395
  position = "right",
@@ -2905,6 +2911,8 @@ export function AgentSidebar({
2905
2911
  emptyStateText={emptyStateText}
2906
2912
  suggestions={suggestions}
2907
2913
  dynamicSuggestions={dynamicSuggestions}
2914
+ composerToolbarSlot={composerToolbarSlot}
2915
+ threadFooterSlot={threadFooterSlot}
2908
2916
  missingApiKeySetupLayout="sidebar"
2909
2917
  onCollapse={() => setOpenPersisted(false)}
2910
2918
  isFullscreen={effectiveFullscreen}
@@ -601,6 +601,13 @@ export interface AssistantChatHandle {
601
601
  exportThreadSnapshot(): ChatThreadSnapshot | null;
602
602
  }
603
603
 
604
+ export type AssistantChatThreadFooterSlot =
605
+ | React.ReactNode
606
+ | ((context: {
607
+ threadId: string | null;
608
+ tabId: string | null;
609
+ }) => React.ReactNode);
610
+
604
611
  export interface AssistantChatAdapterContext {
605
612
  apiUrl: string;
606
613
  tabId?: string;
@@ -638,6 +645,8 @@ export interface AssistantChatProps {
638
645
  suggestions?: string[];
639
646
  /** Context-aware suggestions merged with `suggestions`. Enabled by default. */
640
647
  dynamicSuggestions?: AgentDynamicSuggestionsOption;
648
+ /** Optional content rendered at the bottom of the scrollable thread, after messages. */
649
+ threadFooterSlot?: AssistantChatThreadFooterSlot;
641
650
  /** Optional content rendered in the empty state, above the suggestion buttons. */
642
651
  emptyStateAddon?: React.ReactNode;
643
652
  /** Whether to show the header bar. Default: true */
@@ -952,6 +961,7 @@ const AssistantChatInner = forwardRef<
952
961
  emptyStateText,
953
962
  suggestions,
954
963
  dynamicSuggestions,
964
+ threadFooterSlot,
955
965
  emptyStateAddon,
956
966
  showHeader = true,
957
967
  onSwitchToCli,
@@ -2870,6 +2880,14 @@ const AssistantChatInner = forwardRef<
2870
2880
  isAutoResuming ||
2871
2881
  queuedMessages.length > 0 ||
2872
2882
  reconnectContent.length > 0;
2883
+ const resolvedThreadFooterSlot =
2884
+ typeof threadFooterSlot === "function"
2885
+ ? threadFooterSlot({
2886
+ threadId: threadId ?? null,
2887
+ tabId: tabId ?? null,
2888
+ })
2889
+ : threadFooterSlot;
2890
+ const hasThreadFooterSlot = Boolean(resolvedThreadFooterSlot);
2873
2891
  const isFreshEmptyChat =
2874
2892
  messages.length === 0 &&
2875
2893
  !hasActiveChatWork &&
@@ -2887,6 +2905,13 @@ const AssistantChatInner = forwardRef<
2887
2905
  centerComposerWhenEmpty && (isFreshEmptyChat || centeredRestoringState);
2888
2906
  const showEmptyState =
2889
2907
  messages.length === 0 && !isReconnecting && !hasActiveChatWork;
2908
+ const showInlineEmptyThreadFooterSlot =
2909
+ showEmptyState &&
2910
+ !centeredEmptyState &&
2911
+ !isRestoring &&
2912
+ hasThreadFooterSlot;
2913
+ const showCenteredEmptyThreadFooterSlot =
2914
+ centeredEmptyState && !isRestoring && hasThreadFooterSlot;
2890
2915
  const showComposerSlot =
2891
2916
  Boolean(composerSlot) && (!centerComposerWhenEmpty || centeredEmptyState);
2892
2917
 
@@ -3139,6 +3164,11 @@ const AssistantChatInner = forwardRef<
3139
3164
  ))}
3140
3165
  </div>
3141
3166
  ) : null}
3167
+ {showInlineEmptyThreadFooterSlot ? (
3168
+ <div className="agent-thread-footer-slot agent-thread-footer-slot--empty">
3169
+ {resolvedThreadFooterSlot}
3170
+ </div>
3171
+ ) : null}
3142
3172
  </div>
3143
3173
  ) : (
3144
3174
  <div className="agent-thread-content flex flex-col gap-4 px-4 py-4">
@@ -3266,6 +3296,11 @@ const AssistantChatInner = forwardRef<
3266
3296
  </div>
3267
3297
  );
3268
3298
  })}
3299
+ {resolvedThreadFooterSlot ? (
3300
+ <div className="agent-thread-footer-slot">
3301
+ {resolvedThreadFooterSlot}
3302
+ </div>
3303
+ ) : null}
3269
3304
  </div>
3270
3305
  )}
3271
3306
  </div>
@@ -3285,6 +3320,11 @@ const AssistantChatInner = forwardRef<
3285
3320
  )}
3286
3321
 
3287
3322
  {showComposerSlot ? composerSlot : null}
3323
+ {showCenteredEmptyThreadFooterSlot ? (
3324
+ <div className="agent-thread-footer-slot agent-thread-footer-slot--centered-empty">
3325
+ {resolvedThreadFooterSlot}
3326
+ </div>
3327
+ ) : null}
3288
3328
  {guidedQuestions && guidedQuestions.length > 0 && (
3289
3329
  <div className="shrink-0 px-3 pb-2 pt-1">
3290
3330
  <div className="rounded-lg border border-border bg-card/60 shadow-sm">
@@ -117,6 +117,37 @@ export interface AgentChatContextState {
117
117
  updatedAt: number;
118
118
  }
119
119
 
120
+ export interface AgentComposerReference {
121
+ label: string;
122
+ icon?: string;
123
+ source?: string;
124
+ refType: string;
125
+ refId?: string | null;
126
+ refPath?: string | null;
127
+ /** Stable composer slot this reference occupies. Slot references replace older values. */
128
+ slotKey?: string;
129
+ /** Short label shown before the selected value in the composer chip. */
130
+ slotLabel?: string;
131
+ /** Additional app-defined data used by the client for filtering and grouping. */
132
+ metadata?: Record<string, unknown>;
133
+ /** Slots to remove when this reference is inserted or removed. */
134
+ clearsSlots?: string[];
135
+ /** Additional references to insert before this one. */
136
+ relatedReferences?: AgentComposerReference[];
137
+ }
138
+
139
+ export interface AgentComposerReferenceInsertOptions {
140
+ /**
141
+ * Whether to open the agent sidebar before inserting the reference.
142
+ * Defaults to false so contextual auto-tags can stay quiet.
143
+ */
144
+ openSidebar?: boolean;
145
+ }
146
+
147
+ export interface AgentComposerReferenceInsertPayload extends AgentComposerReference {
148
+ insertMessageId: string;
149
+ }
150
+
120
151
  export interface AgentChatContextMutationOptions {
121
152
  /**
122
153
  * Whether to open the agent sidebar if it's currently hidden.
@@ -140,6 +171,10 @@ export const AGENT_CHAT_REMOVE_CONTEXT_MESSAGE_TYPE =
140
171
  "agentNative.removeChatContext";
141
172
  export const AGENT_CHAT_CLEAR_CONTEXT_MESSAGE_TYPE =
142
173
  "agentNative.clearChatContext";
174
+ export const AGENT_CHAT_INSERT_REFERENCE_MESSAGE_TYPE =
175
+ "agentNative.insertComposerReference";
176
+ export const AGENT_CHAT_INSERT_REFERENCE_EVENT =
177
+ "agentNative:insert-composer-reference";
143
178
  const AGENT_PANEL_PREPARE_EVENT = "agent-panel:prepare";
144
179
 
145
180
  let agentChatContextState: AgentChatContextState = {
@@ -406,6 +441,82 @@ export function appendAgentChatContextToMessage(
406
441
  return `${message.trim()}\n\n<context>\n${trimmedContext}\n</context>`;
407
442
  }
408
443
 
444
+ function normalizeStringArray(value: unknown): string[] | undefined {
445
+ if (!Array.isArray(value)) return undefined;
446
+ const normalized = value
447
+ .filter((item): item is string => typeof item === "string")
448
+ .map((item) => item.trim())
449
+ .filter(Boolean);
450
+ return normalized.length > 0 ? normalized : undefined;
451
+ }
452
+
453
+ function normalizeMetadata(
454
+ value: unknown,
455
+ ): Record<string, unknown> | undefined {
456
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
457
+ return undefined;
458
+ }
459
+ return value as Record<string, unknown>;
460
+ }
461
+
462
+ function normalizeAgentComposerReferenceInternal(
463
+ value: unknown,
464
+ depth: number,
465
+ ): AgentComposerReference | null {
466
+ if (typeof value !== "object" || value === null) return null;
467
+ const candidate = value as Partial<AgentComposerReference>;
468
+ const label =
469
+ typeof candidate.label === "string" ? candidate.label.trim() : "";
470
+ const refType =
471
+ typeof candidate.refType === "string" ? candidate.refType.trim() : "";
472
+ if (!label || !refType) return null;
473
+ const normalized: AgentComposerReference = {
474
+ label,
475
+ icon:
476
+ typeof candidate.icon === "string" && candidate.icon.trim()
477
+ ? candidate.icon.trim()
478
+ : undefined,
479
+ source:
480
+ typeof candidate.source === "string" && candidate.source.trim()
481
+ ? candidate.source.trim()
482
+ : undefined,
483
+ refType,
484
+ refId:
485
+ typeof candidate.refId === "string" && candidate.refId.trim()
486
+ ? candidate.refId.trim()
487
+ : null,
488
+ refPath:
489
+ typeof candidate.refPath === "string" && candidate.refPath.trim()
490
+ ? candidate.refPath.trim()
491
+ : null,
492
+ };
493
+ const slotKey =
494
+ typeof candidate.slotKey === "string" ? candidate.slotKey.trim() : "";
495
+ if (slotKey) normalized.slotKey = slotKey;
496
+ const slotLabel =
497
+ typeof candidate.slotLabel === "string" ? candidate.slotLabel.trim() : "";
498
+ if (slotLabel) normalized.slotLabel = slotLabel;
499
+ const metadata = normalizeMetadata(candidate.metadata);
500
+ if (metadata) normalized.metadata = metadata;
501
+ const clearsSlots = normalizeStringArray(candidate.clearsSlots);
502
+ if (clearsSlots) normalized.clearsSlots = clearsSlots;
503
+ if (depth < 3 && Array.isArray(candidate.relatedReferences)) {
504
+ const relatedReferences = candidate.relatedReferences
505
+ .map((item) => normalizeAgentComposerReferenceInternal(item, depth + 1))
506
+ .filter((item): item is AgentComposerReference => item !== null);
507
+ if (relatedReferences.length > 0) {
508
+ normalized.relatedReferences = relatedReferences;
509
+ }
510
+ }
511
+ return normalized;
512
+ }
513
+
514
+ export function normalizeAgentComposerReference(
515
+ value: unknown,
516
+ ): AgentComposerReference | null {
517
+ return normalizeAgentComposerReferenceInternal(value, 0);
518
+ }
519
+
409
520
  function postAgentChatContextMessage(
410
521
  type:
411
522
  | typeof AGENT_CHAT_SET_CONTEXT_MESSAGE_TYPE
@@ -446,6 +557,51 @@ function postAgentChatContextMessage(
446
557
  }
447
558
  }
448
559
 
560
+ function postAgentChatReferenceMessage(
561
+ payload: AgentComposerReferenceInsertPayload,
562
+ options: { openSidebar: boolean },
563
+ ): void {
564
+ if (typeof window === "undefined") return;
565
+
566
+ const message = {
567
+ type: AGENT_CHAT_INSERT_REFERENCE_MESSAGE_TYPE,
568
+ data: payload,
569
+ };
570
+ const targetSelf = isInBuilderFrame() || isDirectMcpAppEmbedSession();
571
+ const target = targetSelf
572
+ ? window
573
+ : window.parent !== window
574
+ ? window.parent
575
+ : window;
576
+ const targetOrigin = targetSelf
577
+ ? window.location.origin
578
+ : getFramePostMessageTargetOrigin() || window.location.origin;
579
+
580
+ if (options.openSidebar) {
581
+ window.dispatchEvent(
582
+ new CustomEvent("agent-panel:set-mode", {
583
+ detail: { mode: "chat" },
584
+ }),
585
+ );
586
+ window.dispatchEvent(new CustomEvent("agent-panel:open"));
587
+ } else {
588
+ window.dispatchEvent(new CustomEvent(AGENT_PANEL_PREPARE_EVENT));
589
+ }
590
+
591
+ window.dispatchEvent(
592
+ new CustomEvent(AGENT_CHAT_INSERT_REFERENCE_EVENT, {
593
+ detail: payload,
594
+ }),
595
+ );
596
+
597
+ const postToTarget = () => target.postMessage(message, targetOrigin);
598
+ if (target === window) {
599
+ setTimeout(postToTarget, 0);
600
+ } else {
601
+ postToTarget();
602
+ }
603
+ }
604
+
449
605
  function isMcpAppChatBridgeEnabled(): boolean {
450
606
  if (typeof window === "undefined" || window.parent === window) return false;
451
607
  if (readEmbedMcpChatBridgeFlagFromUrl()) markEmbedMcpChatBridgeActive();
@@ -685,6 +841,23 @@ export const setContextToAgentChat = setAgentChatContextItem;
685
841
  /** @deprecated Use `setAgentChatContextItem` instead. */
686
842
  export const addContextToAgentChat = setAgentChatContextItem;
687
843
 
844
+ export function insertAgentComposerReference(
845
+ ref: AgentComposerReference,
846
+ options: AgentComposerReferenceInsertOptions = {},
847
+ ): void {
848
+ const normalized = normalizeAgentComposerReference(ref);
849
+ if (!normalized || typeof window === "undefined") return;
850
+ postAgentChatReferenceMessage(
851
+ {
852
+ ...normalized,
853
+ insertMessageId: `reference-${Date.now()}-${Math.random()
854
+ .toString(36)
855
+ .slice(2, 8)}`,
856
+ },
857
+ { openSidebar: options.openSidebar === true },
858
+ );
859
+ }
860
+
688
861
  export function removeAgentChatContextItem(
689
862
  keyOrOpts: string | AgentChatContextRemoveOptions,
690
863
  ): void {