@agent-native/core 0.12.22 → 0.12.24

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 (118) hide show
  1. package/dist/agent/engine/ai-sdk-engine.d.ts +2 -0
  2. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  3. package/dist/agent/engine/ai-sdk-engine.js +4 -2
  4. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  5. package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
  6. package/dist/agent/engine/anthropic-engine.js +2 -1
  7. package/dist/agent/engine/anthropic-engine.js.map +1 -1
  8. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  9. package/dist/agent/engine/builder-engine.js +117 -8
  10. package/dist/agent/engine/builder-engine.js.map +1 -1
  11. package/dist/agent/engine/registry.d.ts.map +1 -1
  12. package/dist/agent/engine/registry.js +24 -13
  13. package/dist/agent/engine/registry.js.map +1 -1
  14. package/dist/agent/production-agent.d.ts +1 -0
  15. package/dist/agent/production-agent.d.ts.map +1 -1
  16. package/dist/agent/production-agent.js +20 -10
  17. package/dist/agent/production-agent.js.map +1 -1
  18. package/dist/agent/thread-data-builder.d.ts +10 -0
  19. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  20. package/dist/agent/thread-data-builder.js +80 -0
  21. package/dist/agent/thread-data-builder.js.map +1 -1
  22. package/dist/agent/types.d.ts +7 -0
  23. package/dist/agent/types.d.ts.map +1 -1
  24. package/dist/agent/types.js.map +1 -1
  25. package/dist/cli/create.d.ts.map +1 -1
  26. package/dist/cli/create.js +3 -3
  27. package/dist/cli/create.js.map +1 -1
  28. package/dist/client/AgentPanel.d.ts.map +1 -1
  29. package/dist/client/AgentPanel.js +10 -2
  30. package/dist/client/AgentPanel.js.map +1 -1
  31. package/dist/client/AssistantChat.d.ts.map +1 -1
  32. package/dist/client/AssistantChat.js +169 -15
  33. package/dist/client/AssistantChat.js.map +1 -1
  34. package/dist/client/ErrorBoundary.d.ts.map +1 -1
  35. package/dist/client/ErrorBoundary.js +3 -2
  36. package/dist/client/ErrorBoundary.js.map +1 -1
  37. package/dist/client/FeedbackButton.js +1 -1
  38. package/dist/client/FeedbackButton.js.map +1 -1
  39. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  40. package/dist/client/agent-chat-adapter.js +93 -45
  41. package/dist/client/agent-chat-adapter.js.map +1 -1
  42. package/dist/client/analytics.d.ts.map +1 -1
  43. package/dist/client/analytics.js +26 -0
  44. package/dist/client/analytics.js.map +1 -1
  45. package/dist/client/components/ui/tooltip.js +1 -1
  46. package/dist/client/components/ui/tooltip.js.map +1 -1
  47. package/dist/client/composer/PromptComposer.js +1 -1
  48. package/dist/client/composer/PromptComposer.js.map +1 -1
  49. package/dist/client/composer/TiptapComposer.d.ts +5 -0
  50. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  51. package/dist/client/composer/TiptapComposer.js +12 -7
  52. package/dist/client/composer/TiptapComposer.js.map +1 -1
  53. package/dist/client/onboarding/OnboardingPanel.js +2 -1
  54. package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
  55. package/dist/client/progress/RunsTray.d.ts.map +1 -1
  56. package/dist/client/progress/RunsTray.js +18 -3
  57. package/dist/client/progress/RunsTray.js.map +1 -1
  58. package/dist/client/resources/ResourceTree.d.ts.map +1 -1
  59. package/dist/client/resources/ResourceTree.js +5 -4
  60. package/dist/client/resources/ResourceTree.js.map +1 -1
  61. package/dist/client/resources/ResourcesPanel.js +1 -1
  62. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  63. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  64. package/dist/client/settings/useBuilderStatus.js +5 -3
  65. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  66. package/dist/client/sse-event-processor.d.ts.map +1 -1
  67. package/dist/client/sse-event-processor.js +3 -0
  68. package/dist/client/sse-event-processor.js.map +1 -1
  69. package/dist/collab/client.d.ts +9 -0
  70. package/dist/collab/client.d.ts.map +1 -1
  71. package/dist/collab/client.js +36 -10
  72. package/dist/collab/client.js.map +1 -1
  73. package/dist/extensions/html-shell.d.ts.map +1 -1
  74. package/dist/extensions/html-shell.js +12 -0
  75. package/dist/extensions/html-shell.js.map +1 -1
  76. package/dist/mcp-client/errors.d.ts +2 -0
  77. package/dist/mcp-client/errors.d.ts.map +1 -0
  78. package/dist/mcp-client/errors.js +47 -0
  79. package/dist/mcp-client/errors.js.map +1 -0
  80. package/dist/mcp-client/manager.d.ts.map +1 -1
  81. package/dist/mcp-client/manager.js +44 -15
  82. package/dist/mcp-client/manager.js.map +1 -1
  83. package/dist/mcp-client/routes.d.ts +1 -2
  84. package/dist/mcp-client/routes.d.ts.map +1 -1
  85. package/dist/mcp-client/routes.js +2 -27
  86. package/dist/mcp-client/routes.js.map +1 -1
  87. package/dist/onboarding/default-steps.js +1 -1
  88. package/dist/onboarding/default-steps.js.map +1 -1
  89. package/dist/progress/store.d.ts +2 -0
  90. package/dist/progress/store.d.ts.map +1 -1
  91. package/dist/progress/store.js +44 -0
  92. package/dist/progress/store.js.map +1 -1
  93. package/dist/server/action-routes.d.ts +2 -0
  94. package/dist/server/action-routes.d.ts.map +1 -1
  95. package/dist/server/action-routes.js +4 -1
  96. package/dist/server/action-routes.js.map +1 -1
  97. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  98. package/dist/server/agent-chat-plugin.js +27 -15
  99. package/dist/server/agent-chat-plugin.js.map +1 -1
  100. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  101. package/dist/server/core-routes-plugin.js +31 -9
  102. package/dist/server/core-routes-plugin.js.map +1 -1
  103. package/dist/server/credential-provider.d.ts +8 -0
  104. package/dist/server/credential-provider.d.ts.map +1 -1
  105. package/dist/server/credential-provider.js +29 -3
  106. package/dist/server/credential-provider.js.map +1 -1
  107. package/dist/server/index.d.ts +1 -1
  108. package/dist/server/index.d.ts.map +1 -1
  109. package/dist/server/index.js +1 -1
  110. package/dist/server/index.js.map +1 -1
  111. package/dist/server/request-context.d.ts +9 -0
  112. package/dist/server/request-context.d.ts.map +1 -1
  113. package/dist/server/request-context.js +13 -0
  114. package/dist/server/request-context.js.map +1 -1
  115. package/dist/terminal/terminal-plugin.d.ts.map +1 -1
  116. package/dist/terminal/terminal-plugin.js +4 -3
  117. package/dist/terminal/terminal-plugin.js.map +1 -1
  118. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantChat.d.ts","sourceRoot":"","sources":["../../src/client/AssistantChat.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AssistantChat.d.ts","sourceRoot":"","sources":["../../src/client/AssistantChat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAQN,MAAM,OAAO,CAAC;AA6Bf,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AA8rErE,MAAM,WAAW,mBAAmB;IAClC,qDAAqD;IACrD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,6DAA6D;IAC7D,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,4CAA4C;IAC5C,SAAS,IAAI,OAAO,CAAC;IACrB,+BAA+B;IAC/B,aAAa,IAAI,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wGAAwG;IACxG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,oDAAoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iDAAiD;IACjD,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,0CAA0C;IAC1C,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,8EAA8E;IAC9E,YAAY,CAAC,EAAE,CACb,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE;QACJ,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,MAAM,CAAC;KACtB,KACE,IAAI,CAAC;IACV,+DAA+D;IAC/D,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9D,8DAA8D;IAC9D,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,sFAAsF;IACtF,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,8EAA8E;IAC9E,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,+FAA+F;IAC/F,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,mEAAmE;IACnE,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,wCAAwC;IACxC,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC;IACpD,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,0DAA0D;IAC1D,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,qFAAqF;IACrF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iFAAiF;IACjF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,+DAA+D;IAC/D,cAAc,CAAC,EAAE,eAAe,CAAC;IACjC,uDAAuD;IACvD,eAAe,CAAC,EAAE,KAAK,CAAC;QACtB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,UAAU,EAAE,OAAO,CAAC;KACrB,CAAC,CAAC;IACH,uDAAuD;IACvD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,kEAAkE;IAClE,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IACnD,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB;AAED,eAAO,MAAM,mBAAmB,gBAAgB,CAAC;AAEjD,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAAC,KAAK,CAAC,EAAE,MAAM,QAI9C;AAqCD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,CAAC;AA25C7B,eAAO,MAAM,aAAa,gGA4DxB,CAAC"}
@@ -70,6 +70,111 @@ function getFileDataURL(file) {
70
70
  reader.readAsDataURL(file);
71
71
  });
72
72
  }
73
+ function escapeQueuedAttachmentAttribute(value) {
74
+ return value.replace(/&/g, "&").replace(/"/g, """);
75
+ }
76
+ function isTextLikeFile(file) {
77
+ if (file.type.startsWith("text/"))
78
+ return true;
79
+ if (file.type === "application/json")
80
+ return true;
81
+ return /\.(txt|md|markdown|csv|json|yaml|yml)$/i.test(file.name);
82
+ }
83
+ function textFileAttachmentEnvelope(file, text) {
84
+ const contentType = file.type || "text/plain";
85
+ return `<attachment name="${escapeQueuedAttachmentAttribute(file.name)}" contentType="${escapeQueuedAttachmentAttribute(contentType)}">\n${text}\n</attachment>`;
86
+ }
87
+ function serializeAttachmentContentPart(part) {
88
+ if (part.type === "image" && typeof part.image === "string") {
89
+ return { type: "image", image: part.image };
90
+ }
91
+ if (part.type === "text" && typeof part.text === "string") {
92
+ return { type: "text", text: part.text };
93
+ }
94
+ if (part.type === "file" && typeof part.data === "string") {
95
+ return {
96
+ type: "file",
97
+ data: part.data,
98
+ mimeType: typeof part.mimeType === "string"
99
+ ? part.mimeType
100
+ : "application/octet-stream",
101
+ ...(typeof part.filename === "string" ? { filename: part.filename } : {}),
102
+ };
103
+ }
104
+ return null;
105
+ }
106
+ async function serializeQueuedAttachments(attachments) {
107
+ const queued = [];
108
+ for (const raw of attachments ?? []) {
109
+ const attachment = raw;
110
+ const name = attachment.name || attachment.file?.name || "attachment";
111
+ const id = attachment.id || name;
112
+ const type = attachment.type || "file";
113
+ const contentType = attachment.contentType || attachment.file?.type;
114
+ if (Array.isArray(attachment.content) && attachment.content.length > 0) {
115
+ const content = attachment.content
116
+ .map((part) => serializeAttachmentContentPart(part))
117
+ .filter((part) => !!part);
118
+ if (content.length > 0) {
119
+ queued.push({
120
+ id,
121
+ type,
122
+ name,
123
+ contentType,
124
+ status: { type: "complete" },
125
+ content,
126
+ });
127
+ }
128
+ continue;
129
+ }
130
+ if (typeof File !== "undefined" && attachment.file instanceof File) {
131
+ const file = attachment.file;
132
+ if (file.type.startsWith("image/")) {
133
+ queued.push({
134
+ id,
135
+ type: "image",
136
+ name,
137
+ contentType: file.type,
138
+ status: { type: "complete" },
139
+ content: [{ type: "image", image: await getFileDataURL(file) }],
140
+ });
141
+ }
142
+ else if (isTextLikeFile(file)) {
143
+ queued.push({
144
+ id,
145
+ type: "file",
146
+ name,
147
+ contentType: file.type || "text/plain",
148
+ status: { type: "complete" },
149
+ content: [
150
+ {
151
+ type: "text",
152
+ text: textFileAttachmentEnvelope(file, await file.text()),
153
+ },
154
+ ],
155
+ });
156
+ }
157
+ else {
158
+ queued.push({
159
+ id,
160
+ type: "document",
161
+ name,
162
+ contentType: inferDocumentContentType(file),
163
+ status: { type: "complete" },
164
+ content: [
165
+ {
166
+ type: "file",
167
+ filename: file.name,
168
+ data: await getFileDataURL(file),
169
+ mimeType: inferDocumentContentType(file),
170
+ },
171
+ ],
172
+ });
173
+ }
174
+ }
175
+ }
176
+ return queued.length > 0 ? queued : undefined;
177
+ }
73
178
  // ─── Markdown Text ──────────────────────────────────────────────────────────
74
179
  const markdownStyles = `
75
180
  .agent-markdown > :first-child { margin-top: 0; }
@@ -1111,6 +1216,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1111
1216
  // is connected — `BuilderSetupCard` watches this to replay a one-shot bounce.
1112
1217
  const [missingKeyBouncePulse, setMissingKeyBouncePulse] = useState(0);
1113
1218
  const [authError, setAuthError] = useState(null);
1219
+ const [authSessionAvailable, setAuthSessionAvailable] = useState(false);
1114
1220
  const [queuedMessages, setQueuedMessages] = useState([]);
1115
1221
  // Tracks the JSON of the last queue we successfully persisted so the
1116
1222
  // debounced save effect can skip no-op writes (e.g. restore-from-server
@@ -1478,8 +1584,6 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1478
1584
  return;
1479
1585
  const repo = threadRuntime.export();
1480
1586
  const { title, preview } = extractThreadMeta(repo);
1481
- if (!title)
1482
- return;
1483
1587
  lastSaveTimeRef.current = now;
1484
1588
  savedTitleRef.current = title;
1485
1589
  onSaveThreadRef.current(threadId, {
@@ -1598,6 +1702,25 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1598
1702
  };
1599
1703
  }, []);
1600
1704
  // Listen for auth error events from the adapter
1705
+ const checkAuthSession = useCallback(async () => {
1706
+ try {
1707
+ const res = await fetch(agentNativePath("/_agent-native/auth/session"), {
1708
+ cache: "no-store",
1709
+ });
1710
+ if (!res.ok)
1711
+ return false;
1712
+ const data = await res.json().catch(() => null);
1713
+ const hasSession = !!data && !data.error;
1714
+ setAuthSessionAvailable(hasSession);
1715
+ if (hasSession) {
1716
+ setAuthError(null);
1717
+ }
1718
+ return hasSession;
1719
+ }
1720
+ catch {
1721
+ return false;
1722
+ }
1723
+ }, []);
1601
1724
  useEffect(() => {
1602
1725
  const handler = (e) => {
1603
1726
  const detail = e.detail;
@@ -1608,11 +1731,26 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1608
1731
  eventThreadId !== threadId) {
1609
1732
  return;
1610
1733
  }
1734
+ setAuthSessionAvailable(false);
1611
1735
  setAuthError({ sessionExpired: detail?.reason === "session-expired" });
1736
+ void checkAuthSession();
1612
1737
  };
1613
1738
  window.addEventListener("agent-chat:auth-error", handler);
1614
1739
  return () => window.removeEventListener("agent-chat:auth-error", handler);
1615
- }, [tabId, threadId]);
1740
+ }, [checkAuthSession, tabId, threadId]);
1741
+ useEffect(() => {
1742
+ if (!authError)
1743
+ return;
1744
+ const handler = () => void checkAuthSession();
1745
+ const timer = window.setTimeout(handler, 250);
1746
+ window.addEventListener("focus", handler);
1747
+ window.addEventListener("agent-engine:configured-changed", handler);
1748
+ return () => {
1749
+ window.clearTimeout(timer);
1750
+ window.removeEventListener("focus", handler);
1751
+ window.removeEventListener("agent-engine:configured-changed", handler);
1752
+ };
1753
+ }, [authError, checkAuthSession]);
1616
1754
  // Listen for loop-limit events from the adapter
1617
1755
  useEffect(() => {
1618
1756
  const handler = (e) => {
@@ -1709,6 +1847,9 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1709
1847
  threadRuntime.append({
1710
1848
  role: "user",
1711
1849
  content,
1850
+ ...(next.attachments && next.attachments.length > 0
1851
+ ? { attachments: next.attachments }
1852
+ : {}),
1712
1853
  ...(next.references && next.references.length > 0
1713
1854
  ? { runConfig: { custom: { references: next.references } } }
1714
1855
  : {}),
@@ -1747,7 +1888,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1747
1888
  setForceStopped(false);
1748
1889
  }
1749
1890
  }, [isReconnecting, forceStopped]);
1750
- const addToQueue = useCallback((text, images, references) => {
1891
+ const addToQueue = useCallback(async (text, images, references, attachments) => {
1751
1892
  setShowContinue(false);
1752
1893
  setLoopLimitInfo(null);
1753
1894
  setRunErrorInfo(null);
@@ -1758,6 +1899,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1758
1899
  // Selection context attached via Cmd+I is one-shot — clear it as soon
1759
1900
  // as the user actually sends a message so it can't be re-used.
1760
1901
  clearPendingSelection();
1902
+ const queuedAttachments = await serializeQueuedAttachments(attachments);
1761
1903
  if (isRunning) {
1762
1904
  setQueuedMessages((prev) => [
1763
1905
  ...prev,
@@ -1767,6 +1909,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1767
1909
  : `q-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
1768
1910
  text,
1769
1911
  images,
1912
+ attachments: queuedAttachments,
1770
1913
  references,
1771
1914
  },
1772
1915
  ]);
@@ -1778,7 +1921,13 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1778
1921
  content.push({ type: "image", image: img });
1779
1922
  }
1780
1923
  }
1781
- threadRuntime.append({ role: "user", content });
1924
+ threadRuntime.append({
1925
+ role: "user",
1926
+ content,
1927
+ ...(queuedAttachments && queuedAttachments.length > 0
1928
+ ? { attachments: queuedAttachments }
1929
+ : {}),
1930
+ });
1782
1931
  }
1783
1932
  }, [isRunning, threadRuntime]);
1784
1933
  // Expose imperative handle
@@ -1924,16 +2073,20 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1924
2073
  (!userStoppedRunRef.current.runId ||
1925
2074
  !visibleRunError.runId ||
1926
2075
  userStoppedRunRef.current.runId === visibleRunError.runId));
1927
- return (_jsx(CheckpointContext.Provider, { value: checkpointCtx, children: _jsx(MessageActionsContext.Provider, { value: messageActionsCtx, children: _jsx(ChatRunningContext.Provider, { value: isRunning, children: _jsxs("div", { className: cn("flex flex-1 flex-col h-full min-h-0 text-foreground", className), children: [showHeader && (_jsxs("div", { className: "flex h-11 shrink-0 items-center justify-between border-b border-border px-4", children: [_jsx("span", { className: "text-[13px] font-medium text-muted-foreground", children: "Agent" }), _jsx("div", { className: "flex items-center gap-1", children: onSwitchToCli && (_jsx(TooltipProvider, { delayDuration: 200, children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { onClick: onSwitchToCli, "aria-label": "Switch to CLI", className: "flex items-center gap-1 text-[12px] text-muted-foreground hover:text-foreground px-2 py-1 rounded-md hover:bg-accent", children: [_jsx(IconTerminal, { className: "h-3.5 w-3.5" }), "CLI"] }) }), _jsx(TooltipContent, { children: "Switch to CLI" })] }) })) })] })), _jsx("div", { ref: scrollRef, className: "flex-1 overflow-y-auto overflow-x-hidden min-h-0", children: authError ? (_jsxs("div", { className: "flex flex-col items-center justify-center h-full px-4 gap-3", children: [_jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full bg-destructive/10", children: _jsx(IconLock, { className: "h-5 w-5 text-destructive" }) }), _jsxs("div", { className: "text-center max-w-[280px]", children: [_jsx("p", { className: "text-sm font-medium text-foreground mb-1", children: authError.sessionExpired
1928
- ? "Session expired"
1929
- : "Authentication required" }), _jsx("p", { className: "text-xs text-muted-foreground leading-relaxed", children: authError.sessionExpired
1930
- ? "Your session may have expired. Log out and log back in to reconnect."
1931
- : "You need to log in to use the agent." })] }), _jsxs("div", { className: "flex gap-2", children: [!authError.sessionExpired && (_jsx("button", { onClick: () => {
2076
+ return (_jsx(CheckpointContext.Provider, { value: checkpointCtx, children: _jsx(MessageActionsContext.Provider, { value: messageActionsCtx, children: _jsx(ChatRunningContext.Provider, { value: isRunning, children: _jsxs("div", { className: cn("flex flex-1 flex-col h-full min-h-0 text-foreground", className), children: [showHeader && (_jsxs("div", { className: "flex h-11 shrink-0 items-center justify-between border-b border-border px-4", children: [_jsx("span", { className: "text-[13px] font-medium text-muted-foreground", children: "Agent" }), _jsx("div", { className: "flex items-center gap-1", children: onSwitchToCli && (_jsx(TooltipProvider, { delayDuration: 200, children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { onClick: onSwitchToCli, "aria-label": "Switch to CLI", className: "flex items-center gap-1 text-[12px] text-muted-foreground hover:text-foreground px-2 py-1 rounded-md hover:bg-accent", children: [_jsx(IconTerminal, { className: "h-3.5 w-3.5" }), "CLI"] }) }), _jsx(TooltipContent, { children: "Switch to CLI" })] }) })) })] })), _jsx("div", { ref: scrollRef, className: "flex-1 overflow-y-auto overflow-x-hidden min-h-0", children: authError ? (_jsxs("div", { className: "flex flex-col items-center justify-center h-full px-4 gap-3", children: [_jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full bg-destructive/10", children: _jsx(IconLock, { className: "h-5 w-5 text-destructive" }) }), _jsxs("div", { className: "text-center max-w-[280px]", children: [_jsx("p", { className: "text-sm font-medium text-foreground mb-1", children: authSessionAvailable
2077
+ ? "Chat session needs refresh"
2078
+ : authError.sessionExpired
2079
+ ? "Session expired"
2080
+ : "Authentication required" }), _jsx("p", { className: "text-xs text-muted-foreground leading-relaxed", children: authSessionAvailable
2081
+ ? "You're signed in, but this chat connection needs to reconnect."
2082
+ : authError.sessionExpired
2083
+ ? "Your session may have expired. Log out and log back in to reconnect."
2084
+ : "You need to log in to use the agent." })] }), _jsxs("div", { className: "flex gap-2", children: [!authError.sessionExpired && !authSessionAvailable && (_jsx("button", { onClick: () => {
1932
2085
  const ret = window.location.pathname + window.location.search;
1933
2086
  window.location.href =
1934
2087
  agentNativePath("/_agent-native/sign-in") +
1935
2088
  `?return=${encodeURIComponent(ret)}`;
1936
- }, className: "text-xs text-background bg-foreground hover:opacity-90 px-3 py-1.5 rounded-md", children: "Log in" })), authError.sessionExpired && (_jsx("button", { onClick: async () => {
2089
+ }, className: "text-xs text-background bg-foreground hover:opacity-90 px-3 py-1.5 rounded-md", children: "Log in" })), authError.sessionExpired && !authSessionAvailable && (_jsx("button", { onClick: async () => {
1937
2090
  try {
1938
2091
  await fetch(agentNativePath("/_agent-native/auth/logout"), {
1939
2092
  method: "POST",
@@ -1944,7 +2097,9 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1944
2097
  }, className: "text-xs text-destructive hover:text-destructive/80 px-3 py-1.5 rounded-md border border-destructive/30 hover:bg-destructive/10", children: "Log out" })), _jsx("button", { onClick: () => {
1945
2098
  setAuthError(null);
1946
2099
  window.location.reload();
1947
- }, className: "text-xs text-muted-foreground hover:text-foreground px-3 py-1.5 rounded-md border border-border hover:bg-accent", children: "Retry" })] })] })) : missingApiKey && messages.length === 0 ? (_jsx("div", { className: "flex flex-col items-center justify-center h-full px-2", children: _jsx(BuilderSetupCard, { onConnected: handleBuilderConnected, bouncePulse: missingKeyBouncePulse }) })) : isRestoring ? (_jsxs("div", { className: "flex flex-col gap-3 p-4", children: [_jsx("div", { className: "flex justify-end", children: _jsx("div", { className: "h-8 w-32 rounded-lg bg-muted animate-pulse" }) }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx("div", { className: "h-4 w-48 rounded bg-muted animate-pulse" }), _jsx("div", { className: "h-4 w-64 rounded bg-muted animate-pulse" }), _jsx("div", { className: "h-4 w-40 rounded bg-muted animate-pulse" })] })] })) : messages.length === 0 && !isReconnecting ? (_jsxs("div", { className: "flex flex-col items-center justify-center gap-4 py-16 px-4 h-full", children: [_jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full bg-muted", children: _jsx(IconMessage, { className: "h-5 w-5 text-muted-foreground" }) }), _jsx("p", { className: "text-sm text-muted-foreground text-center max-w-[240px]", children: emptyStateText ?? "How can I help you?" }), suggestions && suggestions.length > 0 && (_jsx("div", { className: "flex flex-col gap-1.5 w-full max-w-[280px]", children: suggestions.map((suggestion) => (_jsx("button", { onClick: () => {
2100
+ }, className: authSessionAvailable
2101
+ ? "text-xs text-background bg-foreground hover:opacity-90 px-3 py-1.5 rounded-md"
2102
+ : "text-xs text-muted-foreground hover:text-foreground px-3 py-1.5 rounded-md border border-border hover:bg-accent", children: "Refresh chat" })] })] })) : missingApiKey && messages.length === 0 ? (_jsx("div", { className: "flex flex-col items-center justify-center h-full px-2", children: _jsx(BuilderSetupCard, { onConnected: handleBuilderConnected, bouncePulse: missingKeyBouncePulse }) })) : isRestoring ? (_jsxs("div", { className: "flex flex-col gap-3 p-4", children: [_jsx("div", { className: "flex justify-end", children: _jsx("div", { className: "h-8 w-32 rounded-lg bg-muted animate-pulse" }) }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx("div", { className: "h-4 w-48 rounded bg-muted animate-pulse" }), _jsx("div", { className: "h-4 w-64 rounded bg-muted animate-pulse" }), _jsx("div", { className: "h-4 w-40 rounded bg-muted animate-pulse" })] })] })) : messages.length === 0 && !isReconnecting ? (_jsxs("div", { className: "flex flex-col items-center justify-center gap-4 py-16 px-4 h-full", children: [_jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full bg-muted", children: _jsx(IconMessage, { className: "h-5 w-5 text-muted-foreground" }) }), _jsx("p", { className: "text-sm text-muted-foreground text-center max-w-[240px]", children: emptyStateText ?? "How can I help you?" }), suggestions && suggestions.length > 0 && (_jsx("div", { className: "flex flex-col gap-1.5 w-full max-w-[280px]", children: suggestions.map((suggestion) => (_jsx("button", { onClick: () => {
1948
2103
  threadRuntime.append({
1949
2104
  role: "user",
1950
2105
  content: [{ type: "text", text: suggestion }],
@@ -1979,8 +2134,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1979
2134
  return (_jsx("div", { className: "flex justify-end group", children: _jsxs("div", { className: "relative max-w-[85%] rounded-lg bg-accent/50 text-foreground/60 px-3 py-2 text-sm leading-relaxed whitespace-pre-wrap break-words", children: [_jsxs("div", { className: "flex items-center gap-1.5 text-[10px] text-muted-foreground mb-1 font-medium uppercase tracking-wide", children: [_jsx(IconClock, { className: "h-3 w-3" }), "Queued"] }), displayText, msg.images && msg.images.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-1.5 mt-1.5", children: msg.images.map((img, j) => (_jsx("img", { src: img, alt: "", className: "h-12 w-12 rounded object-cover border border-border/50" }, j))) })), _jsx("button", { type: "button", onClick: () => setQueuedMessages((prev) => prev.filter((m) => m.id !== msg.id)), "aria-label": "Remove from queue", className: "absolute -top-2 -right-2 flex h-5 w-5 items-center justify-center rounded-full border border-border bg-background text-muted-foreground opacity-0 group-hover:opacity-100 focus-visible:opacity-100 hover:text-foreground hover:bg-accent shadow-sm", children: _jsx(IconX, { className: "h-3 w-3" }) })] }) }, msg.id));
1980
2135
  })] })) }), showScrollToBottom && (_jsx("div", { className: "shrink-0 flex justify-center -mb-1", children: _jsx("button", { type: "button", onClick: scrollToBottom, className: "flex h-7 w-7 items-center justify-center rounded-full border border-border bg-background shadow-sm hover:bg-accent", "aria-label": "Scroll to bottom", children: _jsx(IconChevronDown, { className: "h-3.5 w-3.5 text-muted-foreground" }) }) })), composerSlot, _jsx(SelectionAttachedPill, {}), _jsx("div", { className: cn("agent-composer-area shrink-0 px-3 py-2", missingApiKey && "cursor-pointer", isComposerDisabled && "opacity-70"), onClick: missingApiKey
1981
2136
  ? () => setMissingKeyBouncePulse((p) => p + 1)
1982
- : undefined, children: _jsxs(ComposerPrimitive.Root, { className: cn("flex flex-col rounded-lg border border-input bg-background focus-within:ring-1 focus-within:ring-ring", execMode === "plan" &&
1983
- "border-amber-500/50 bg-amber-500/[0.03] focus-within:ring-amber-500/30"), children: [_jsx(ComposerAttachmentPreviewStrip, {}), _jsx(TiptapComposer, { focusRef: tiptapRef, disabled: isComposerDisabled, placeholder: missingApiKey
2137
+ : undefined, children: _jsxs(ComposerPrimitive.Root, { className: "flex flex-col rounded-lg border border-input bg-background focus-within:ring-1 focus-within:ring-ring", children: [_jsx(ComposerAttachmentPreviewStrip, {}), _jsx(TiptapComposer, { focusRef: tiptapRef, disabled: isComposerDisabled, placeholder: missingApiKey
1984
2138
  ? "Connect an AI engine above to start chatting…"
1985
2139
  : composerDisabled
1986
2140
  ? (composerDisabledPlaceholder ??
@@ -1990,7 +2144,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1990
2144
  ? `${queuedMessages.length} queued — type another...`
1991
2145
  : "Queue a message..."
1992
2146
  : undefined, onSubmit: isRunning
1993
- ? (text, references) => addToQueue(text, undefined, references.length > 0 ? references : undefined)
2147
+ ? (text, references, attachments) => void addToQueue(text, undefined, references.length > 0 ? references : undefined, attachments)
1994
2148
  : undefined, onSlashCommand: onSlashCommand, execMode: execMode, onExecModeChange: onExecModeChange, planModeDisabled: planModeDisabled, planModeDisabledReason: planModeDisabledReason, selectedModel: selectedModel ?? defaultModel, selectedEffort: selectedEffort, availableModels: availableModels, onModelChange: onModelChange, onEffortChange: onEffortChange, draftScope: threadId || tabId, interceptBuildRequestsForBuilder: true, extraActionButton: showRunningInUI ? (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: () => {
1995
2149
  // Nuclear stop: flip forceStopped so isRunning is false
1996
2150
  // immediately. This unblocks submission even if the