@agent-native/core 0.84.53 → 0.84.55
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/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +13 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/cli/skills.ts +34 -16
- package/corpus/core/src/client/AssistantChat.tsx +198 -146
- package/corpus/core/src/client/agent-chat-adapter.ts +14 -4
- package/corpus/core/src/client/blocks/library/diagram.config.ts +13 -2
- package/corpus/core/src/client/blocks/library/diagram.tsx +27 -3
- package/corpus/core/src/client/blocks/library/server-specs.ts +2 -2
- package/corpus/core/src/client/blocks/library/wireframe.config.ts +7 -1
- package/corpus/core/src/client/blocks/library/wireframe.tsx +42 -3
- package/corpus/core/src/client/blocks/types.ts +9 -0
- package/corpus/core/src/client/chat/message-components.tsx +6 -2
- package/corpus/core/src/client/sse-event-processor.ts +11 -4
- package/corpus/core/src/client/use-agent-engine-configured.ts +54 -12
- package/corpus/core/src/server/agent-chat-plugin.ts +9 -5
- package/corpus/core/src/styles/agent-native.css +44 -0
- package/corpus/core/src/styles/blocks.css +18 -0
- package/corpus/templates/plan/.agents/skills/visual-plan/references/document-quality.md +10 -6
- package/corpus/templates/plan/.agents/skills/visual-plan/references/wireframe.md +20 -9
- package/corpus/templates/plan/.agents/skills/visual-recap/SKILL.md +4 -1
- package/corpus/templates/plan/.agents/skills/visual-recap/references/wireframe.md +20 -9
- package/corpus/templates/plan/actions/create-ui-plan.ts +1 -1
- package/corpus/templates/plan/actions/create-visual-plan.ts +1 -1
- package/corpus/templates/plan/actions/create-visual-recap.ts +1 -1
- package/corpus/templates/plan/actions/get-plan-blocks.ts +2 -0
- package/corpus/templates/plan/app/components/plan/planBlocks.tsx +2 -0
- package/corpus/templates/plan/app/components/plan/wireframe/Wireframe.tsx +38 -4
- package/corpus/templates/plan/app/components/plan/wireframe/html-artboard.css +18 -0
- package/corpus/templates/plan/app/global.css +1 -2
- package/corpus/templates/plan/changelog/2026-07-02-plan-chat-keeps-the-composer-anchored-when-connect-ai-appears.md +6 -0
- package/corpus/templates/plan/changelog/2026-07-02-wireframe-and-diagram-blocks-can-now-show-or-hide-their-outer-frame.md +6 -0
- package/corpus/templates/plan/server/plan-mdx.ts +3 -0
- package/corpus/templates/plan/shared/plan-content.ts +8 -0
- package/dist/cli/skills.d.ts +3 -3
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +34 -16
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +65 -45
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +12 -2
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/blocks/library/diagram.config.d.ts +3 -1
- package/dist/client/blocks/library/diagram.config.d.ts.map +1 -1
- package/dist/client/blocks/library/diagram.config.js +10 -1
- package/dist/client/blocks/library/diagram.config.js.map +1 -1
- package/dist/client/blocks/library/diagram.d.ts.map +1 -1
- package/dist/client/blocks/library/diagram.js +13 -7
- package/dist/client/blocks/library/diagram.js.map +1 -1
- package/dist/client/blocks/library/server-specs.js +2 -2
- package/dist/client/blocks/library/server-specs.js.map +1 -1
- package/dist/client/blocks/library/wireframe.config.d.ts +3 -1
- package/dist/client/blocks/library/wireframe.config.d.ts.map +1 -1
- package/dist/client/blocks/library/wireframe.config.js +4 -0
- package/dist/client/blocks/library/wireframe.config.js.map +1 -1
- package/dist/client/blocks/library/wireframe.d.ts.map +1 -1
- package/dist/client/blocks/library/wireframe.js +20 -9
- package/dist/client/blocks/library/wireframe.js.map +1 -1
- package/dist/client/blocks/types.d.ts +8 -0
- package/dist/client/blocks/types.d.ts.map +1 -1
- package/dist/client/blocks/types.js.map +1 -1
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +6 -2
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +9 -4
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/client/use-agent-engine-configured.d.ts +10 -1
- package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
- package/dist/client/use-agent-engine-configured.js +35 -10
- package/dist/client/use-agent-engine-configured.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +4 -4
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +9 -2
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/styles/agent-native.css +44 -0
- package/dist/styles/blocks.css +18 -0
- package/package.json +1 -1
package/corpus/README.md
CHANGED
package/corpus/core/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @agent-native/core
|
|
2
2
|
|
|
3
|
+
## 0.84.55
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- ea97dc1: Make agent chat setup, auth, and title state resilient to transient status checks and hidden context payloads.
|
|
8
|
+
|
|
9
|
+
## 0.84.54
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- a259f96: Keep centered chat composers stable when the Connect AI setup card appears.
|
|
14
|
+
- df3fcfd: Allow wireframe and diagram blocks to opt in or out of their outer visual frame.
|
|
15
|
+
|
|
3
16
|
## 0.84.53
|
|
4
17
|
|
|
5
18
|
### Patch Changes
|
package/corpus/core/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.84.
|
|
3
|
+
"version": "0.84.55",
|
|
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": {
|
|
@@ -858,15 +858,26 @@ occurrence. The result is re-sanitized. In local-files privacy mode, do not call
|
|
|
858
858
|
hosted Plan tools; edit the local MDX source directly and rerun the local
|
|
859
859
|
check/serve or verify command for \`<plan-dir>\`.
|
|
860
860
|
|
|
861
|
-
**
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
\`
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
861
|
+
**Choose the outer frame deliberately.** Wireframe and diagram data accept
|
|
862
|
+
\`frame: "auto" | "show" | "hide"\` in block data (\`<Screen frame="hide">\` in
|
|
863
|
+
MDX wireframes, \`<Diagram frame="hide">\` for MDX diagrams). Leave it unset or
|
|
864
|
+
\`auto\` when the host context should decide: Plan and recap surfaces default to a
|
|
865
|
+
drawn outer frame; docs surfaces default to no outer frame. Use \`show\` for
|
|
866
|
+
standalone product screens, before/after recap comparisons, screenshot-like
|
|
867
|
+
artifacts, and visuals that need containment from surrounding prose. Use \`hide\`
|
|
868
|
+
when a docs page, tab, column, card, canvas artboard, or the visual's own
|
|
869
|
+
internal chrome already supplies the boundary. Do not use \`hide\` to compensate
|
|
870
|
+
for cramped content; fix the layout instead.
|
|
871
|
+
|
|
872
|
+
**Inner padding and borders still matter.** Always wrap HTML wireframe content
|
|
873
|
+
in a root container with real inner padding before drawing cards, fields, pills,
|
|
874
|
+
labels, or controls. Use at least 14-16px of padding, \`box-sizing: border-box\`,
|
|
875
|
+
\`height: 100%\`, and \`gap\` between child rows on the root node itself so the
|
|
876
|
+
first row never sits flush against the screen edge. Do not rely on padding on a
|
|
877
|
+
nested page section as the first visible inset; the outermost element must
|
|
878
|
+
create the breathing room. Keep text away from borders: every container, field,
|
|
879
|
+
button, menu item, and annotation needs enough padding and line-height to read
|
|
880
|
+
cleanly in the rendered Plan view.
|
|
870
881
|
|
|
871
882
|
**For feature-cloud or abundance visuals, optimize the composition over line-by-line
|
|
872
883
|
reading.** Some marketing/product sections need to feel like a large surface area
|
|
@@ -1244,12 +1255,16 @@ so you never emit a block the editor cannot render or round-trip:
|
|
|
1244
1255
|
\`--wf-paper\`, \`--wf-card\`, \`--wf-accent\`, \`--wf-accent-soft\`, \`--wf-warn\`, and
|
|
1245
1256
|
\`--wf-ok\`, and switch to Excalifont plus rough.js outlines in sketchy mode. Do not
|
|
1246
1257
|
set \`font-family\` and do not hard-code hex, rgb, or hsl colors in diagram HTML
|
|
1247
|
-
or CSS.
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1258
|
+
or CSS. Choose the outer \`frame\` intentionally: use \`show\` when the diagram
|
|
1259
|
+
stands alone in a recap, comparison, or prose section; use \`hide\` when the
|
|
1260
|
+
diagram sits inside docs chrome, columns, tabs, cards, a canvas surface, or
|
|
1261
|
+
already has visible \`.diagram-panel\` / \`.diagram-box\` structure. Leave room
|
|
1262
|
+
for the sketch font: keep labels short, give nodes generous width, and place
|
|
1263
|
+
boundary/annotation labels in unused space instead of over nodes; labels must
|
|
1264
|
+
not overlap nodes, connectors, or each other. For small text/SVG changes to an
|
|
1265
|
+
existing HTML diagram, use \`patch-diagram-html\` with a unique
|
|
1266
|
+
\`find\`/\`replace\` snippet instead of resending the whole \`data.html\` string.
|
|
1267
|
+
Use legacy \`nodes\` / \`edges\` only for small previews or truly
|
|
1253
1268
|
sequential flows. In architecture/code plans, prefer a repeated section rhythm:
|
|
1254
1269
|
recommendation title, confidence and category badges, code-path evidence, a
|
|
1255
1270
|
local before/after or current/target spatial diagram, then concise
|
|
@@ -2426,7 +2441,10 @@ tags — resolve every conceptual name to its exact tag + prop schema with the
|
|
|
2426
2441
|
Author diagram HTML/CSS with the renderer-owned \`.diagram-*\` primitives
|
|
2427
2442
|
(\`.diagram-panel\`, \`.diagram-node\`, \`.diagram-pill\`, \`[data-rough]\`, …) and
|
|
2428
2443
|
the same \`--wf-*\` theme tokens \`references/wireframe.md\` defines — never
|
|
2429
|
-
\`font-family\`, hex, rgb/hsl literals, or one-off dark/light palettes.
|
|
2444
|
+
\`font-family\`, hex, rgb/hsl literals, or one-off dark/light palettes. Choose
|
|
2445
|
+
the outer \`frame\` intentionally: recap diagrams usually benefit from
|
|
2446
|
+
\`frame: "show"\` when they stand alone, but use \`frame: "hide"\` when columns,
|
|
2447
|
+
tabs, a card, or the diagram's own panels already provide the boundary.
|
|
2430
2448
|
- **Outcome-first narrative** → \`rich-text\` for the "what changed and why" prose:
|
|
2431
2449
|
the objective the diff served, the key decisions visible in it, and the risks a
|
|
2432
2450
|
reviewer should weigh. This is the only place the model writes freely.
|
|
@@ -89,6 +89,7 @@ import {
|
|
|
89
89
|
AssistantMessage,
|
|
90
90
|
SelectionAttachedPill,
|
|
91
91
|
RunningActivityStatus,
|
|
92
|
+
displayableUserMessageText,
|
|
92
93
|
} from "./chat/message-components.js";
|
|
93
94
|
import {
|
|
94
95
|
repoHasAssistantMessage,
|
|
@@ -178,6 +179,8 @@ export {
|
|
|
178
179
|
|
|
179
180
|
export { displayableUserMessageText } from "./chat/message-components.js";
|
|
180
181
|
|
|
182
|
+
type AuthSessionCheckResult = "available" | "missing" | "unknown";
|
|
183
|
+
|
|
181
184
|
const useBrowserLayoutEffect =
|
|
182
185
|
typeof window === "undefined" ? useEffect : useLayoutEffect;
|
|
183
186
|
|
|
@@ -492,13 +495,14 @@ function getMessageText(message: unknown): string {
|
|
|
492
495
|
const msg = (message as { message?: unknown })?.message ?? message;
|
|
493
496
|
const content = (msg as { content?: unknown })?.content;
|
|
494
497
|
if (Array.isArray(content)) {
|
|
495
|
-
return
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
498
|
+
return displayableUserMessageText(
|
|
499
|
+
content
|
|
500
|
+
.filter((p: any) => p?.type === "text" && typeof p.text === "string")
|
|
501
|
+
.map((p: any) => p.text)
|
|
502
|
+
.join("\n"),
|
|
503
|
+
);
|
|
500
504
|
}
|
|
501
|
-
return typeof content === "string" ? content
|
|
505
|
+
return typeof content === "string" ? displayableUserMessageText(content) : "";
|
|
502
506
|
}
|
|
503
507
|
|
|
504
508
|
function contentPartFollowKey(part: any): string {
|
|
@@ -1263,6 +1267,7 @@ const AssistantChatInner = forwardRef<
|
|
|
1263
1267
|
}, [threadRuntime]);
|
|
1264
1268
|
const agentEngineConfigured = useAgentEngineConfigured(
|
|
1265
1269
|
providerStatusChecksEnabled,
|
|
1270
|
+
{ tabId, threadId },
|
|
1266
1271
|
);
|
|
1267
1272
|
const missingApiKey = agentEngineConfigured.missing;
|
|
1268
1273
|
const isComposerDisabled = missingApiKey || composerDisabled;
|
|
@@ -1294,10 +1299,19 @@ const AssistantChatInner = forwardRef<
|
|
|
1294
1299
|
setComposerError(LLM_MISSING_CREDENTIALS_MESSAGE);
|
|
1295
1300
|
setMissingKeyBouncePulse((p) => p + 1);
|
|
1296
1301
|
if (typeof window !== "undefined") {
|
|
1297
|
-
window.dispatchEvent(
|
|
1302
|
+
window.dispatchEvent(
|
|
1303
|
+
new CustomEvent("agent-chat:missing-api-key", {
|
|
1304
|
+
detail: { tabId, threadId },
|
|
1305
|
+
}),
|
|
1306
|
+
);
|
|
1298
1307
|
}
|
|
1299
1308
|
return false;
|
|
1300
|
-
}, [
|
|
1309
|
+
}, [
|
|
1310
|
+
agentEngineConfigured.state,
|
|
1311
|
+
providerStatusChecksEnabled,
|
|
1312
|
+
tabId,
|
|
1313
|
+
threadId,
|
|
1314
|
+
]);
|
|
1301
1315
|
const [authError, setAuthError] = useState<{
|
|
1302
1316
|
sessionExpired?: boolean;
|
|
1303
1317
|
} | null>(null);
|
|
@@ -2443,23 +2457,31 @@ const AssistantChatInner = forwardRef<
|
|
|
2443
2457
|
}, []);
|
|
2444
2458
|
|
|
2445
2459
|
// Listen for auth error events from the adapter
|
|
2446
|
-
const checkAuthSession =
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2460
|
+
const checkAuthSession =
|
|
2461
|
+
useCallback(async (): Promise<AuthSessionCheckResult> => {
|
|
2462
|
+
try {
|
|
2463
|
+
const res = await fetch(
|
|
2464
|
+
agentNativePath("/_agent-native/auth/session"),
|
|
2465
|
+
{
|
|
2466
|
+
cache: "no-store",
|
|
2467
|
+
},
|
|
2468
|
+
);
|
|
2469
|
+
if (!res.ok) {
|
|
2470
|
+
return res.status === 401 || res.status === 403
|
|
2471
|
+
? "missing"
|
|
2472
|
+
: "unknown";
|
|
2473
|
+
}
|
|
2474
|
+
const data = await res.json().catch(() => null);
|
|
2475
|
+
const hasSession = !!data && !data.error;
|
|
2476
|
+
setAuthSessionAvailable(hasSession);
|
|
2477
|
+
if (hasSession) {
|
|
2478
|
+
setAuthError(null);
|
|
2479
|
+
}
|
|
2480
|
+
return hasSession ? "available" : "missing";
|
|
2481
|
+
} catch {
|
|
2482
|
+
return "unknown";
|
|
2457
2483
|
}
|
|
2458
|
-
|
|
2459
|
-
} catch {
|
|
2460
|
-
return false;
|
|
2461
|
-
}
|
|
2462
|
-
}, []);
|
|
2484
|
+
}, []);
|
|
2463
2485
|
|
|
2464
2486
|
useEffect(() => {
|
|
2465
2487
|
const handler = (e: Event) => {
|
|
@@ -2481,9 +2503,12 @@ const AssistantChatInner = forwardRef<
|
|
|
2481
2503
|
) {
|
|
2482
2504
|
return;
|
|
2483
2505
|
}
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2506
|
+
void (async () => {
|
|
2507
|
+
const sessionState = await checkAuthSession();
|
|
2508
|
+
if (sessionState !== "missing") return;
|
|
2509
|
+
setAuthSessionAvailable(false);
|
|
2510
|
+
setAuthError({ sessionExpired: detail?.reason === "session-expired" });
|
|
2511
|
+
})();
|
|
2487
2512
|
};
|
|
2488
2513
|
window.addEventListener("agent-chat:auth-error", handler);
|
|
2489
2514
|
return () => window.removeEventListener("agent-chat:auth-error", handler);
|
|
@@ -2499,8 +2524,9 @@ const AssistantChatInner = forwardRef<
|
|
|
2499
2524
|
// symptom we want signal on.
|
|
2500
2525
|
const stuckCapture = window.setTimeout(() => {
|
|
2501
2526
|
void (async () => {
|
|
2502
|
-
const
|
|
2503
|
-
if (
|
|
2527
|
+
const sessionState = await checkAuthSession();
|
|
2528
|
+
if (sessionState === "available") return;
|
|
2529
|
+
if (sessionState !== "missing") return;
|
|
2504
2530
|
if (!shouldCaptureStuckAuthCard) return;
|
|
2505
2531
|
captureError(new Error("agent-chat:auth_error_card_stuck"), {
|
|
2506
2532
|
tags: {
|
|
@@ -3452,6 +3478,15 @@ const AssistantChatInner = forwardRef<
|
|
|
3452
3478
|
queryKey: ["guided-questions"],
|
|
3453
3479
|
...(browserTabId ? { browserTabId } : {}),
|
|
3454
3480
|
});
|
|
3481
|
+
const hasComposerAccessoryAboveStack = Boolean(
|
|
3482
|
+
composerError ||
|
|
3483
|
+
showComposerSlot ||
|
|
3484
|
+
showCenteredEmptyThreadFooterSlot ||
|
|
3485
|
+
(guidedQuestions && guidedQuestions.length > 0) ||
|
|
3486
|
+
showScrollToBottom ||
|
|
3487
|
+
composerContextItems.length > 0 ||
|
|
3488
|
+
showPlanModeCallout,
|
|
3489
|
+
);
|
|
3455
3490
|
|
|
3456
3491
|
// Human-in-the-loop approvals: when the user approves a paused `needsApproval`
|
|
3457
3492
|
// tool call, re-issue the turn carrying the call's approval key so the server
|
|
@@ -3781,9 +3816,9 @@ const AssistantChatInner = forwardRef<
|
|
|
3781
3816
|
<RunningActivityStatus label={runningStatusLabel} />
|
|
3782
3817
|
)}
|
|
3783
3818
|
{queuedMessages.map((msg) => {
|
|
3784
|
-
const displayText =
|
|
3785
|
-
.
|
|
3786
|
-
|
|
3819
|
+
const displayText = displayableUserMessageText(
|
|
3820
|
+
msg.text,
|
|
3821
|
+
);
|
|
3787
3822
|
return (
|
|
3788
3823
|
<div
|
|
3789
3824
|
key={msg.id}
|
|
@@ -3877,7 +3912,6 @@ const AssistantChatInner = forwardRef<
|
|
|
3877
3912
|
onSwitchToAct={handleSwitchToAct}
|
|
3878
3913
|
/>
|
|
3879
3914
|
)}
|
|
3880
|
-
<SelectionAttachedPill />
|
|
3881
3915
|
{/* Inline attachment / body-size error */}
|
|
3882
3916
|
{composerError && (
|
|
3883
3917
|
<div
|
|
@@ -3896,124 +3930,142 @@ const AssistantChatInner = forwardRef<
|
|
|
3896
3930
|
</button>
|
|
3897
3931
|
</div>
|
|
3898
3932
|
)}
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
onConnected={handleBuilderConnected}
|
|
3904
|
-
bouncePulse={missingKeyBouncePulse}
|
|
3905
|
-
layout={missingApiKeySetupLayout}
|
|
3906
|
-
/>
|
|
3907
|
-
) : null}
|
|
3908
|
-
{/* Input area */}
|
|
3909
|
-
<AgentComposerFrame
|
|
3910
|
-
layoutVariant={composerLayoutVariant}
|
|
3911
|
-
className={cn(
|
|
3912
|
-
composerAreaClassName,
|
|
3913
|
-
missingApiKey && "cursor-pointer",
|
|
3914
|
-
isComposerDisabled && "opacity-70",
|
|
3915
|
-
)}
|
|
3916
|
-
onClick={
|
|
3917
|
-
missingApiKey
|
|
3918
|
-
? () => setMissingKeyBouncePulse((p) => p + 1)
|
|
3919
|
-
: undefined
|
|
3933
|
+
<div
|
|
3934
|
+
className="agent-composer-stack"
|
|
3935
|
+
data-agent-composer-adjacent-ui={
|
|
3936
|
+
hasComposerAccessoryAboveStack ? "true" : undefined
|
|
3920
3937
|
}
|
|
3921
3938
|
>
|
|
3922
|
-
<
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3939
|
+
<SelectionAttachedPill />
|
|
3940
|
+
{missingApiKey &&
|
|
3941
|
+
!authError &&
|
|
3942
|
+
missingApiKeySetupAboveComposer ? (
|
|
3943
|
+
<div
|
|
3944
|
+
className="agent-composer-setup-card"
|
|
3945
|
+
data-agent-composer-setup-position="above"
|
|
3946
|
+
>
|
|
3947
|
+
<BuilderSetupCard
|
|
3948
|
+
onConnected={handleBuilderConnected}
|
|
3949
|
+
bouncePulse={missingKeyBouncePulse}
|
|
3950
|
+
layout={missingApiKeySetupLayout}
|
|
3951
|
+
/>
|
|
3952
|
+
</div>
|
|
3953
|
+
) : null}
|
|
3954
|
+
{/* Input area */}
|
|
3955
|
+
<AgentComposerFrame
|
|
3956
|
+
layoutVariant={composerLayoutVariant}
|
|
3957
|
+
className={cn(
|
|
3958
|
+
composerAreaClassName,
|
|
3959
|
+
missingApiKey && "cursor-pointer",
|
|
3960
|
+
isComposerDisabled && "opacity-70",
|
|
3961
|
+
)}
|
|
3962
|
+
onClick={
|
|
3927
3963
|
missingApiKey
|
|
3928
|
-
?
|
|
3929
|
-
? "Connect AI above to start chatting..."
|
|
3930
|
-
: "Connect AI below to start chatting..."
|
|
3931
|
-
: composerDisabled
|
|
3932
|
-
? (composerDisabledPlaceholder ??
|
|
3933
|
-
"Open Desktop to use this chat.")
|
|
3934
|
-
: isRunning
|
|
3935
|
-
? queuedMessages.length > 0
|
|
3936
|
-
? `${queuedMessages.length} queued — send a follow-up...`
|
|
3937
|
-
: "Send a follow-up..."
|
|
3938
|
-
: composerPlaceholder
|
|
3939
|
-
}
|
|
3940
|
-
onSubmit={
|
|
3941
|
-
isRunning || composerContextItems.length > 0
|
|
3942
|
-
? (text, references, attachments, options) =>
|
|
3943
|
-
void addToQueue(
|
|
3944
|
-
text,
|
|
3945
|
-
undefined,
|
|
3946
|
-
references.length > 0 ? references : undefined,
|
|
3947
|
-
attachments,
|
|
3948
|
-
undefined,
|
|
3949
|
-
resolveAssistantChatSubmitIntent({
|
|
3950
|
-
isRunning,
|
|
3951
|
-
requestedIntent: options?.intent,
|
|
3952
|
-
}),
|
|
3953
|
-
undefined,
|
|
3954
|
-
true,
|
|
3955
|
-
)
|
|
3964
|
+
? () => setMissingKeyBouncePulse((p) => p + 1)
|
|
3956
3965
|
: undefined
|
|
3957
3966
|
}
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
3967
|
+
>
|
|
3968
|
+
<ComposerAttachmentPreviewStrip />
|
|
3969
|
+
<TiptapComposer
|
|
3970
|
+
focusRef={tiptapRef}
|
|
3971
|
+
disabled={isComposerDisabled}
|
|
3972
|
+
placeholder={
|
|
3973
|
+
missingApiKey
|
|
3974
|
+
? missingApiKeySetupAboveComposer
|
|
3975
|
+
? "Connect AI above to start chatting..."
|
|
3976
|
+
: "Connect AI below to start chatting..."
|
|
3977
|
+
: composerDisabled
|
|
3978
|
+
? (composerDisabledPlaceholder ??
|
|
3979
|
+
"Open Desktop to use this chat.")
|
|
3980
|
+
: isRunning
|
|
3981
|
+
? queuedMessages.length > 0
|
|
3982
|
+
? `${queuedMessages.length} queued — send a follow-up...`
|
|
3983
|
+
: "Send a follow-up..."
|
|
3984
|
+
: composerPlaceholder
|
|
3985
|
+
}
|
|
3986
|
+
onSubmit={
|
|
3987
|
+
isRunning || composerContextItems.length > 0
|
|
3988
|
+
? (text, references, attachments, options) =>
|
|
3989
|
+
void addToQueue(
|
|
3990
|
+
text,
|
|
3991
|
+
undefined,
|
|
3992
|
+
references.length > 0 ? references : undefined,
|
|
3993
|
+
attachments,
|
|
3994
|
+
undefined,
|
|
3995
|
+
resolveAssistantChatSubmitIntent({
|
|
3996
|
+
isRunning,
|
|
3997
|
+
requestedIntent: options?.intent,
|
|
3998
|
+
}),
|
|
3999
|
+
undefined,
|
|
4000
|
+
true,
|
|
4001
|
+
)
|
|
4002
|
+
: undefined
|
|
4003
|
+
}
|
|
4004
|
+
onSlashCommand={onSlashCommand}
|
|
4005
|
+
onBeforeSubmit={ensureAgentEngineReadyForSubmit}
|
|
4006
|
+
execMode={execMode}
|
|
4007
|
+
onExecModeChange={onExecModeChange}
|
|
4008
|
+
planModeDisabled={planModeDisabled}
|
|
4009
|
+
planModeDisabledReason={planModeDisabledReason}
|
|
4010
|
+
selectedModel={selectedModel ?? defaultModel}
|
|
4011
|
+
selectedEffort={selectedEffort}
|
|
4012
|
+
availableModels={availableModels}
|
|
4013
|
+
onModelChange={onModelChange}
|
|
4014
|
+
onEffortChange={onEffortChange}
|
|
4015
|
+
imageModelMenu={imageModelMenu}
|
|
4016
|
+
onConnectProvider={onConnectProvider}
|
|
4017
|
+
toolbarSlot={composerToolbarSlot}
|
|
4018
|
+
contextItems={composerContextItems}
|
|
4019
|
+
onRemoveContextItem={removeComposerContextItem}
|
|
4020
|
+
plusMenuMode={plusMenuMode}
|
|
4021
|
+
layoutVariant={composerLayoutVariant}
|
|
4022
|
+
providerConnectStatusEnabled={providerStatusChecksEnabled}
|
|
4023
|
+
draftScope={threadId || tabId}
|
|
4024
|
+
interceptBuildRequestsForBuilder
|
|
4025
|
+
onAttachmentError={setComposerError}
|
|
4026
|
+
extraActionButton={
|
|
4027
|
+
contextXRayEnabled ||
|
|
4028
|
+
composerExtraActionButton ||
|
|
4029
|
+
showRunningInUI ? (
|
|
4030
|
+
<>
|
|
4031
|
+
{contextXRayEnabled && (
|
|
4032
|
+
<ContextMeter threadId={threadId} />
|
|
4033
|
+
)}
|
|
4034
|
+
{composerExtraActionButton}
|
|
4035
|
+
{showRunningInUI && (
|
|
4036
|
+
<Tooltip>
|
|
4037
|
+
<TooltipTrigger asChild>
|
|
4038
|
+
<button
|
|
4039
|
+
type="button"
|
|
4040
|
+
onClick={stopActiveRun}
|
|
4041
|
+
className="shrink-0 flex h-7 w-7 items-center justify-center rounded-md bg-muted text-foreground hover:bg-muted/80"
|
|
4042
|
+
>
|
|
4043
|
+
<IconPlayerStop className="h-3.5 w-3.5" />
|
|
4044
|
+
</button>
|
|
4045
|
+
</TooltipTrigger>
|
|
4046
|
+
<TooltipContent>Stop generating</TooltipContent>
|
|
4047
|
+
</Tooltip>
|
|
4048
|
+
)}
|
|
4049
|
+
</>
|
|
4050
|
+
) : undefined
|
|
4051
|
+
}
|
|
4052
|
+
/>
|
|
4053
|
+
</AgentComposerFrame>
|
|
4054
|
+
{missingApiKey &&
|
|
4055
|
+
!authError &&
|
|
4056
|
+
!missingApiKeySetupAboveComposer ? (
|
|
4057
|
+
<div
|
|
4058
|
+
className="agent-composer-setup-card"
|
|
4059
|
+
data-agent-composer-setup-position="below"
|
|
4060
|
+
>
|
|
4061
|
+
<BuilderSetupCard
|
|
4062
|
+
onConnected={handleBuilderConnected}
|
|
4063
|
+
bouncePulse={missingKeyBouncePulse}
|
|
4064
|
+
layout={missingApiKeySetupLayout}
|
|
4065
|
+
/>
|
|
4066
|
+
</div>
|
|
4067
|
+
) : null}
|
|
4068
|
+
</div>
|
|
4017
4069
|
</div>
|
|
4018
4070
|
</TextStreamingContext.Provider>
|
|
4019
4071
|
</ChatRunningContext.Provider>
|
|
@@ -1526,6 +1526,18 @@ export function createAgentChatAdapter(
|
|
|
1526
1526
|
);
|
|
1527
1527
|
};
|
|
1528
1528
|
|
|
1529
|
+
const dispatchMissingApiKey = () => {
|
|
1530
|
+
if (typeof window === "undefined") return;
|
|
1531
|
+
window.dispatchEvent(
|
|
1532
|
+
new CustomEvent("agent-chat:missing-api-key", {
|
|
1533
|
+
detail: {
|
|
1534
|
+
...(tabId ? { tabId } : {}),
|
|
1535
|
+
...(threadId ? { threadId } : {}),
|
|
1536
|
+
},
|
|
1537
|
+
}),
|
|
1538
|
+
);
|
|
1539
|
+
};
|
|
1540
|
+
|
|
1529
1541
|
const tryRecoverAuthOnce = async (): Promise<boolean> => {
|
|
1530
1542
|
if (authRecoveryAttempted || abortSignal.aborted) return false;
|
|
1531
1543
|
authRecoveryAttempted = true;
|
|
@@ -2418,9 +2430,7 @@ export function createAgentChatAdapter(
|
|
|
2418
2430
|
if (isMissingCredentialMessage(body)) {
|
|
2419
2431
|
const failure = missingCredentialFailure(body);
|
|
2420
2432
|
if (typeof window !== "undefined") {
|
|
2421
|
-
|
|
2422
|
-
new Event("agent-chat:missing-api-key"),
|
|
2423
|
-
);
|
|
2433
|
+
dispatchMissingApiKey();
|
|
2424
2434
|
window.dispatchEvent(
|
|
2425
2435
|
new CustomEvent("agent-chat:run-error", {
|
|
2426
2436
|
detail: { ...failure.runError, tabId },
|
|
@@ -2633,7 +2643,7 @@ export function createAgentChatAdapter(
|
|
|
2633
2643
|
if (isMissingCredentialMessage(errMsg)) {
|
|
2634
2644
|
const failure = missingCredentialFailure(errMsg);
|
|
2635
2645
|
if (typeof window !== "undefined") {
|
|
2636
|
-
|
|
2646
|
+
dispatchMissingApiKey();
|
|
2637
2647
|
window.dispatchEvent(
|
|
2638
2648
|
new CustomEvent("agent-chat:run-error", {
|
|
2639
2649
|
detail: { ...failure.runError, tabId },
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
|
|
3
3
|
import { childCodeFenceFields, serializeChildCodeFenceFields } from "../mdx.js";
|
|
4
|
-
import type { BlockMdxConfig } from "../types.js";
|
|
4
|
+
import type { BlockMdxConfig, BlockVisualFrame } from "../types.js";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Pure (React-free) part of the shared `diagram` block: its data schema and MDX
|
|
@@ -45,6 +45,8 @@ export interface DiagramData {
|
|
|
45
45
|
html?: string;
|
|
46
46
|
css?: string;
|
|
47
47
|
caption?: string;
|
|
48
|
+
/** Outer surface frame. `auto` lets the host choose the right default. */
|
|
49
|
+
frame?: BlockVisualFrame;
|
|
48
50
|
/**
|
|
49
51
|
* Legacy compatibility path for older/simple node graphs. New plans should use
|
|
50
52
|
* `html`/`css` when layout quality matters.
|
|
@@ -120,6 +122,8 @@ const diagramNoteSchema = z.object({
|
|
|
120
122
|
y: z.number().min(0).max(100).optional(),
|
|
121
123
|
}) as z.ZodType<DiagramNote>;
|
|
122
124
|
|
|
125
|
+
const visualFrameSchema = z.enum(["auto", "show", "hide"]);
|
|
126
|
+
|
|
123
127
|
/**
|
|
124
128
|
* The block can be a flexible HTML/SVG fragment or a legacy positional
|
|
125
129
|
* node/edge/note graph, so it ships a custom `Edit` rather than relying on the
|
|
@@ -144,6 +148,7 @@ export const diagramSchema = z
|
|
|
144
148
|
})
|
|
145
149
|
.optional(),
|
|
146
150
|
caption: z.string().trim().max(600).optional(),
|
|
151
|
+
frame: visualFrameSchema.optional(),
|
|
147
152
|
nodes: z.array(diagramNodeSchema).max(80).optional(),
|
|
148
153
|
edges: z.array(diagramEdgeSchema).max(120).optional(),
|
|
149
154
|
notes: z.array(diagramNoteSchema).max(40).optional(),
|
|
@@ -167,7 +172,9 @@ function graphDataForAttr(data: DiagramData): DiagramData | undefined {
|
|
|
167
172
|
if (data.edges?.length) graph.edges = data.edges;
|
|
168
173
|
if (data.notes?.length) graph.notes = data.notes;
|
|
169
174
|
if (Object.keys(graph).length > 0) return graph;
|
|
170
|
-
|
|
175
|
+
if (hasChildFenceData(data)) return undefined;
|
|
176
|
+
const { frame: _frame, ...dataForAttr } = data;
|
|
177
|
+
return Object.keys(dataForAttr).length > 0 ? dataForAttr : undefined;
|
|
171
178
|
}
|
|
172
179
|
|
|
173
180
|
/**
|
|
@@ -185,12 +192,16 @@ export const diagramMdx: BlockMdxConfig<DiagramData> = {
|
|
|
185
192
|
| Record<string, unknown>
|
|
186
193
|
| undefined,
|
|
187
194
|
caption: data.caption,
|
|
195
|
+
frame: data.frame,
|
|
188
196
|
}),
|
|
189
197
|
fromAttrs: (attrs) => ({
|
|
190
198
|
...(attrs.object<DiagramData>("data") ?? {}),
|
|
191
199
|
...(attrs.string("caption") !== undefined
|
|
192
200
|
? { caption: attrs.string("caption") }
|
|
193
201
|
: {}),
|
|
202
|
+
...(attrs.string("frame") !== undefined
|
|
203
|
+
? { frame: attrs.string("frame") as BlockVisualFrame }
|
|
204
|
+
: {}),
|
|
194
205
|
}),
|
|
195
206
|
serializeChildren: (data) =>
|
|
196
207
|
serializeChildCodeFenceFields(data, { html: "html", css: "css" }),
|