@agent-native/core 0.149.1 → 0.149.2
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/templates/analytics/.agents/skills/dashboard-management/SKILL.md +2 -0
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +150 -46
- package/corpus/templates/analytics/app/global.css +1 -1
- package/corpus/templates/analytics/app/i18n-data.ts +37 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +1 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +32 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +2 -0
- package/corpus/templates/analytics/changelog/2026-08-10-dashboard-tables-can-be-copied-and-sorted-by-multiple-column.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
- package/corpus/templates/assets/app/global.css +1 -1
- package/corpus/templates/assets/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
- package/corpus/templates/brain/app/global.css +1 -1
- package/corpus/templates/brain/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
- package/corpus/templates/chat/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-10-clips-desktop-sign-in-now-starts-with-magic-links-and-google.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/overlay.css +1 -0
- package/corpus/templates/clips/desktop/src/app.tsx +274 -137
- package/corpus/templates/clips/desktop/src/styles.css +35 -0
- package/corpus/templates/content/app/global.css +1 -0
- package/corpus/templates/crm/app/global.css +1 -1
- package/corpus/templates/crm/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
- package/corpus/templates/forms/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
- package/corpus/templates/plan/app/global.css +1 -0
- package/corpus/templates/plan/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
- package/corpus/templates/plan/server/ui-plan-html.ts +4 -1
- package/corpus/templates/slides/AGENTS.md +11 -10
- package/corpus/templates/slides/actions/add-deck.ts +2 -0
- package/corpus/templates/slides/actions/add-slide.ts +15 -1
- package/corpus/templates/slides/actions/create-deck.ts +18 -6
- package/corpus/templates/slides/actions/get-deck.ts +29 -1
- package/corpus/templates/slides/actions/patch-deck.ts +122 -9
- package/corpus/templates/slides/actions/save-deck.ts +24 -1
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +134 -618
- package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +69 -60
- package/corpus/templates/slides/app/components/editor/GeneratingSlidePreview.tsx +1 -1
- package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +13 -1
- package/corpus/templates/slides/app/components/editor/NewDeckReferenceStep.tsx +56 -174
- package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +239 -116
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +3 -3
- package/corpus/templates/slides/app/components/layout/AgentWorkIndicator.tsx +1 -1
- package/corpus/templates/slides/app/components/layout/Layout.tsx +34 -35
- package/corpus/templates/slides/app/components/layout/layout-route-policy.ts +2 -5
- package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +45 -40
- package/corpus/templates/slides/app/components/presentation/PresentationView.tsx +63 -16
- package/corpus/templates/slides/app/hooks/use-generating-slide-preview.ts +25 -3
- package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
- package/corpus/templates/slides/app/lib/create-deck-generation.ts +5 -4
- package/corpus/templates/slides/app/lib/recent-references.ts +23 -1
- package/corpus/templates/slides/app/lib/slide-animation-elements.ts +41 -3
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +4 -27
- package/corpus/templates/slides/app/pages/Index.tsx +240 -89
- package/corpus/templates/slides/changelog/2026-08-10-ai-editing-avatar-badge.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-10-generated-decks-keep-a-clear-human-readable-title.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-10-new-deck-creation-now-shows-progress-opens-the-editor-direct.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-10-presentation-reveals-now-follow-valid-targets.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-10-slides-editing-controls-are-consolidated-into-one-focused-me.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-10-slides-now-verify-and-restyle-every-imported-slide-in-one-pa.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-10-slides-only-suggests-a-google-connection-for-relevant-reques.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-10-the-google-slides-import-option-is-now-labeled-slides.md +6 -0
- package/corpus/templates/slides/server/lib/chat-attachments.ts +1 -1
- package/corpus/templates/slides/server/plugins/agent-chat.ts +5 -3
- package/corpus/templates/slides/shared/api.ts +2 -1
- package/corpus/templates/slides/shared/deck-title.ts +135 -0
- package/corpus/templates/tasks/app/components/tasks/TaskListRow.tsx +4 -1
- package/dist/agent/engine/ai-sdk-engine.js +1 -1
- package/dist/agent/production-agent.d.ts +21 -1
- package/dist/agent/production-agent.js +129 -10
- package/dist/agent/tool-approval-store.d.ts +18 -0
- package/dist/agent/tool-approval-store.js +122 -0
- package/dist/agent/types.d.ts +1 -1
- package/dist/cli/code-agent-executor.js +11 -2
- package/dist/client/AgentPanel.js +31 -6
- package/dist/client/AssistantChat.d.ts +3 -2
- package/dist/client/AssistantChat.js +7 -20
- package/dist/client/agent-chat/index.d.ts +1 -1
- package/dist/client/agent-chat-adapter.js +11 -0
- package/dist/client/agent-chat.d.ts +1 -1
- package/dist/client/chat/markdown-renderer.js +14 -2
- package/dist/client/chat/message-components.d.ts +6 -2
- package/dist/client/chat/message-components.js +25 -47
- package/dist/client/chat/tool-call-display.d.ts +3 -5
- package/dist/client/chat/tool-call-display.js +7 -212
- package/dist/client/chat-first/apps-rail.js +3 -3
- package/dist/client/chat-first/browser-pane.js +4 -1
- package/dist/client/chat-first/chat-history.d.ts +3 -1
- package/dist/client/chat-first/chat-history.js +2 -2
- package/dist/client/chat-first/surface-tabs.d.ts +1 -1
- package/dist/client/chat-first/surface-tabs.js +52 -41
- package/dist/client/chat-first/types.d.ts +3 -0
- package/dist/client/chat-first.d.ts +10 -0
- package/dist/client/chat-first.js +37 -2
- package/dist/client/components/ui/message-scroller.js +4 -1
- package/dist/client/i18n.js +3 -1
- package/dist/client/resources/McpConnectionSuggestion.js +9 -1
- package/dist/client/sse-event-processor.js +10 -0
- package/dist/client/use-chat-models.js +156 -80
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/integrations/webhook-handler.js +1 -1
- package/dist/observability/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/auth.js +262 -31
- package/dist/server/onboarding-html.js +56 -9
- package/dist/shared/reasoning-effort.d.ts +8 -8
- package/dist/shared/reasoning-effort.js +10 -10
- package/dist/shared/streaming-text-smoothing.js +41 -11
- package/dist/styles/agent-native.css +19 -32
- package/dist/templates/chat/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
- package/docs/content/template-chat.mdx +1 -1
- package/package.json +2 -2
- package/src/templates/chat/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
package/dist/client/i18n.js
CHANGED
|
@@ -549,7 +549,9 @@ export function LanguagePicker({ className, includeSystem = true, label, variant
|
|
|
549
549
|
? "flex h-8 w-8 items-center justify-center"
|
|
550
550
|
: variant === "select"
|
|
551
551
|
? "flex h-9 w-full items-center justify-between gap-2 px-3 text-start text-sm"
|
|
552
|
-
: null), children: [_jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [_jsx(IconLanguage, { className: "h-4 w-4 shrink-0 text-muted-foreground" }), variant === "select" ? (_jsx("span", { className: "truncate", children: selectedLabel })) : (_jsx("span", { className: "sr-only", children: triggerLabel }))] }), variant === "select" ? (_jsx(IconChevronDown, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground", "aria-hidden": "true" })) : null] }) }), _jsx(PopoverPrimitive.Portal, { children: _jsx(PopoverPrimitive.Content, { align: variant === "select" ? "start" : "end", sideOffset: 6, role: "menu", className: cn(
|
|
552
|
+
: null), children: [_jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [_jsx(IconLanguage, { className: "h-4 w-4 shrink-0 text-muted-foreground" }), variant === "select" ? (_jsx("span", { className: "truncate", children: selectedLabel })) : (_jsx("span", { className: "sr-only", children: triggerLabel }))] }), variant === "select" ? (_jsx(IconChevronDown, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground", "aria-hidden": "true" })) : null] }) }), _jsx(PopoverPrimitive.Portal, { children: _jsx(PopoverPrimitive.Content, { align: variant === "select" ? "start" : "end", sideOffset: 6, role: "menu", className: cn(
|
|
553
|
+
// compositing-ok: popover content unmounts on close.
|
|
554
|
+
"z-[9999] max-h-[min(20rem,var(--radix-popover-content-available-height))] overflow-y-auto rounded-lg border border-border bg-popover p-1 text-popover-foreground shadow-lg outline-none will-change-[transform,opacity] data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:duration-100 data-[state=open]:duration-150 data-[state=closed]:ease-in data-[state=open]:ease-out data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1", variant === "icon" || variant === "ghost-icon"
|
|
553
555
|
? "min-w-56"
|
|
554
556
|
: "w-[min(20rem,calc(100vw-2rem))] min-w-[var(--radix-popover-trigger-width)]"), children: options.map((option) => {
|
|
555
557
|
const optionSelected = option.value === preference;
|
|
@@ -9,8 +9,16 @@ import { buildMcpOAuthStartUrl, findMcpIntegrationForText, getMcpIntegrationApiF
|
|
|
9
9
|
import { McpIntegrationDialog } from "./McpIntegrationDialog.js";
|
|
10
10
|
import { McpIntegrationLogo } from "./McpIntegrationLogo.js";
|
|
11
11
|
import { useCreateMcpServer, useMcpServers, } from "./use-mcp-servers.js";
|
|
12
|
+
function visibleUserAuthoredText(text) {
|
|
13
|
+
return text
|
|
14
|
+
.replace(/<context\b[^>]*>[\s\S]*?<\/context>\n?/gi, "")
|
|
15
|
+
.replace(/<context\b[^>]*>[\s\S]*$/gi, "")
|
|
16
|
+
.replace(/<\/context>/gi, "")
|
|
17
|
+
.trim();
|
|
18
|
+
}
|
|
12
19
|
export function findMcpConnectionSuggestionIntegration({ text, contextText = "", variant = "composer", integrations = getDefaultMcpIntegrations(), }) {
|
|
13
|
-
|
|
20
|
+
const sourceText = variant === "response" ? contextText : text;
|
|
21
|
+
return findMcpIntegrationForText(visibleUserAuthoredText(sourceText), integrations);
|
|
14
22
|
}
|
|
15
23
|
export function shouldRenderMcpIntegrationFallback(logoUrl, logoLoadFailed) {
|
|
16
24
|
return !logoUrl || logoLoadFailed;
|
|
@@ -1291,6 +1291,9 @@ export function processEvent(ev, content, toolCallCounter, tabId, state) {
|
|
|
1291
1291
|
detail: { ...runError, tabId },
|
|
1292
1292
|
}));
|
|
1293
1293
|
}
|
|
1294
|
+
// This event is terminal. There may be no visible text or tool_done after
|
|
1295
|
+
// the last preparation activity, so do not leave its label mounted.
|
|
1296
|
+
dispatchActivityClear(tabId);
|
|
1294
1297
|
settleInterruptedToolCalls(content, undefined, { includeActivity: true });
|
|
1295
1298
|
content.push({
|
|
1296
1299
|
type: "text",
|
|
@@ -1386,6 +1389,9 @@ export function processEvent(ev, content, toolCallCounter, tabId, state) {
|
|
|
1386
1389
|
...(ev.errorCode ? { errorCode: ev.errorCode } : {}),
|
|
1387
1390
|
...(ev.recoverable ? { recoverable: ev.recoverable } : {}),
|
|
1388
1391
|
};
|
|
1392
|
+
// Non-recoverable errors end the turn. Recoverable errors return above as
|
|
1393
|
+
// auto-continue signals and must keep their activity state alive.
|
|
1394
|
+
dispatchActivityClear(tabId);
|
|
1389
1395
|
if (typeof window !== "undefined") {
|
|
1390
1396
|
window.dispatchEvent(new CustomEvent("agent-chat:run-error", {
|
|
1391
1397
|
detail: { ...runError, tabId },
|
|
@@ -1406,6 +1412,10 @@ export function processEvent(ev, content, toolCallCounter, tabId, state) {
|
|
|
1406
1412
|
};
|
|
1407
1413
|
}
|
|
1408
1414
|
if (ev.type === "done") {
|
|
1415
|
+
// `done` is authoritative even when the final model chunk contains only
|
|
1416
|
+
// a wrap-up marker. Clear any preparation label before inspecting pending
|
|
1417
|
+
// tools so both success and interrupted-terminal paths settle the UI.
|
|
1418
|
+
dispatchActivityClear(tabId);
|
|
1409
1419
|
const interruptedTools = pendingToolNames(content);
|
|
1410
1420
|
const allInterruptedTools = [
|
|
1411
1421
|
...interruptedTools.running,
|
|
@@ -6,6 +6,22 @@ import { fetchBuilderStatus, fetchEnvironmentStatus, } from "./client-status-req
|
|
|
6
6
|
import { callAction } from "./use-action.js";
|
|
7
7
|
const DEFAULT_STORAGE_KEY = "agent-native:chat-models:selection";
|
|
8
8
|
export const CHAT_MODEL_SELECTION_CHANGED_EVENT = "agent-native:chat-model-selection-changed";
|
|
9
|
+
const MODEL_DISCOVERY_RETRY_DELAYS_MS = [250, 1_000];
|
|
10
|
+
async function fetchEngineCatalog() {
|
|
11
|
+
try {
|
|
12
|
+
const result = (await callAction("manage-agent-engine", { action: "list" }));
|
|
13
|
+
if (!result ||
|
|
14
|
+
typeof result !== "object" ||
|
|
15
|
+
!("engines" in result) ||
|
|
16
|
+
!Array.isArray(result.engines)) {
|
|
17
|
+
return { state: "unavailable" };
|
|
18
|
+
}
|
|
19
|
+
return { state: "available", value: result };
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return { state: "unavailable" };
|
|
23
|
+
}
|
|
24
|
+
}
|
|
9
25
|
function readPersisted(key) {
|
|
10
26
|
if (!key || typeof window === "undefined")
|
|
11
27
|
return {};
|
|
@@ -50,6 +66,9 @@ export function useChatModels({ storageKey = DEFAULT_STORAGE_KEY, enabled = true
|
|
|
50
66
|
selectedEngine,
|
|
51
67
|
selectedEffort,
|
|
52
68
|
});
|
|
69
|
+
const mountedRef = useRef(true);
|
|
70
|
+
const refreshGenerationRef = useRef(0);
|
|
71
|
+
const retryTimerRef = useRef(null);
|
|
53
72
|
useEffect(() => {
|
|
54
73
|
selectionRef.current = {
|
|
55
74
|
selectedModel,
|
|
@@ -109,98 +128,155 @@ export function useChatModels({ storageKey = DEFAULT_STORAGE_KEY, enabled = true
|
|
|
109
128
|
const refreshEngines = useCallback(() => {
|
|
110
129
|
if (!enabled)
|
|
111
130
|
return;
|
|
131
|
+
refreshGenerationRef.current += 1;
|
|
132
|
+
const refreshGeneration = refreshGenerationRef.current;
|
|
133
|
+
if (retryTimerRef.current !== null) {
|
|
134
|
+
clearTimeout(retryTimerRef.current);
|
|
135
|
+
retryTimerRef.current = null;
|
|
136
|
+
}
|
|
112
137
|
setIsLoading(true);
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
138
|
+
const isCurrentRefresh = () => mountedRef.current && refreshGenerationRef.current === refreshGeneration;
|
|
139
|
+
const finish = () => {
|
|
140
|
+
if (isCurrentRefresh())
|
|
141
|
+
setIsLoading(false);
|
|
142
|
+
};
|
|
143
|
+
function scheduleRetry(attempt) {
|
|
144
|
+
const delay = MODEL_DISCOVERY_RETRY_DELAYS_MS[attempt];
|
|
145
|
+
if (delay === undefined || !isCurrentRefresh())
|
|
146
|
+
return false;
|
|
147
|
+
retryTimerRef.current = setTimeout(() => {
|
|
148
|
+
retryTimerRef.current = null;
|
|
149
|
+
load(attempt + 1);
|
|
150
|
+
}, delay);
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
function load(attempt) {
|
|
154
|
+
if (!isCurrentRefresh())
|
|
127
155
|
return;
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
156
|
+
Promise.all([
|
|
157
|
+
fetchEngineCatalog(),
|
|
158
|
+
fetchEnvironmentStatus(),
|
|
159
|
+
fetchBuilderStatus(),
|
|
160
|
+
])
|
|
161
|
+
.then(([engineResult, envResult, builderResult]) => {
|
|
162
|
+
if (!isCurrentRefresh())
|
|
163
|
+
return;
|
|
164
|
+
if (engineResult.state !== "available" ||
|
|
165
|
+
envResult.state !== "available" ||
|
|
166
|
+
builderResult.state !== "available") {
|
|
167
|
+
if (scheduleRetry(attempt))
|
|
168
|
+
return;
|
|
169
|
+
if (engineResult.state !== "available") {
|
|
170
|
+
// Without a catalog the picker keeps an unvalidated DEFAULT_MODEL,
|
|
171
|
+
// which is indistinguishable from a real selection unless we say so.
|
|
172
|
+
console.warn("[agent-chat] engine list unavailable; model picker is showing an unvalidated default");
|
|
173
|
+
}
|
|
174
|
+
finish();
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
const enginesData = engineResult.value;
|
|
178
|
+
const envKeys = envResult.value;
|
|
179
|
+
const builderStatus = builderResult.value;
|
|
180
|
+
const configuredKeys = new Set(envKeys.filter((k) => k.configured).map((k) => k.key));
|
|
181
|
+
const builderConnected = builderStatus?.configured === true;
|
|
182
|
+
const currentEngineName = enginesData.current?.engine;
|
|
183
|
+
const currentModel = enginesData.current?.model;
|
|
184
|
+
const groups = buildChatModelGroups({
|
|
185
|
+
engines: enginesData.engines,
|
|
186
|
+
configuredKeys,
|
|
187
|
+
builderConnected,
|
|
188
|
+
currentEngineName,
|
|
189
|
+
currentModel,
|
|
190
|
+
});
|
|
191
|
+
const nextDefaultModel = currentModel ?? DEFAULT_MODEL;
|
|
192
|
+
setAvailableModels(groups);
|
|
193
|
+
setDefaultModel(nextDefaultModel);
|
|
194
|
+
const selection = selectionRef.current;
|
|
195
|
+
// Default only to a CONFIGURED group, and to nothing when there is
|
|
196
|
+
// none. `DEFAULT_MODEL` is a builder-gateway id that no group carries
|
|
197
|
+
// unless Builder is connected, and unconfigured groups are kept in the
|
|
198
|
+
// list for their connect affordance — so both `?? DEFAULT_MODEL` and
|
|
199
|
+
// `?? groups[0]` yield a selection the app cannot route, which the
|
|
200
|
+
// server silently replaces with its own default. An empty selection
|
|
201
|
+
// hides the picker instead of showing a model that will not be used.
|
|
202
|
+
const configuredGroups = groups.filter((g) => g.configured);
|
|
203
|
+
const resolveRoutableSelection = () => {
|
|
204
|
+
const group = configuredGroups.find((g) => g.models.includes(nextDefaultModel)) ?? configuredGroups[0];
|
|
205
|
+
if (!group)
|
|
206
|
+
return null;
|
|
207
|
+
const model = group.models.find((m) => m === nextDefaultModel) ??
|
|
208
|
+
group.models[0];
|
|
209
|
+
if (!model)
|
|
210
|
+
return null;
|
|
211
|
+
return {
|
|
212
|
+
model,
|
|
213
|
+
engine: group.engine,
|
|
214
|
+
effort: resolveReasoningEffortSelection(model, selection.selectedEffort),
|
|
215
|
+
};
|
|
216
|
+
};
|
|
217
|
+
const applyFallback = (persist) => {
|
|
218
|
+
const next = resolveRoutableSelection();
|
|
219
|
+
setSelectedModel(next?.model ?? "");
|
|
220
|
+
setSelectedEngine(next?.engine ?? "");
|
|
221
|
+
if (next) {
|
|
222
|
+
setSelectedEffort(next.effort);
|
|
223
|
+
if (persist)
|
|
224
|
+
writePersisted(storageKey, next);
|
|
225
|
+
}
|
|
166
226
|
};
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
setSelectedEngine(next?.engine ?? "");
|
|
172
|
-
if (next) {
|
|
173
|
-
setSelectedEffort(next.effort);
|
|
174
|
-
if (persist)
|
|
175
|
-
writePersisted(storageKey, next);
|
|
227
|
+
if (!hasExplicitSelectionRef.current) {
|
|
228
|
+
applyFallback(false);
|
|
229
|
+
finish();
|
|
230
|
+
return;
|
|
176
231
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if (selection.selectedEngine !== selectedGroup.engine) {
|
|
189
|
-
setSelectedEngine(selectedGroup.engine);
|
|
232
|
+
const selectedGroup = groups.find((group) => group.models.includes(selection.selectedModel) &&
|
|
233
|
+
(!selection.selectedEngine ||
|
|
234
|
+
group.engine === selection.selectedEngine));
|
|
235
|
+
if (selectedGroup) {
|
|
236
|
+
// Heal a selection stored without an engine (or with a stale one) so
|
|
237
|
+
// later submits carry the pair the catalog resolved.
|
|
238
|
+
if (selection.selectedEngine !== selectedGroup.engine) {
|
|
239
|
+
setSelectedEngine(selectedGroup.engine);
|
|
240
|
+
}
|
|
241
|
+
finish();
|
|
242
|
+
return;
|
|
190
243
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
244
|
+
applyFallback(true);
|
|
245
|
+
finish();
|
|
246
|
+
})
|
|
247
|
+
.catch(() => {
|
|
248
|
+
if (!isCurrentRefresh())
|
|
249
|
+
return;
|
|
250
|
+
if (!scheduleRetry(attempt))
|
|
251
|
+
finish();
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
load(0);
|
|
197
255
|
}, [enabled, storageKey]);
|
|
256
|
+
useEffect(() => {
|
|
257
|
+
mountedRef.current = true;
|
|
258
|
+
return () => {
|
|
259
|
+
mountedRef.current = false;
|
|
260
|
+
refreshGenerationRef.current += 1;
|
|
261
|
+
if (retryTimerRef.current !== null) {
|
|
262
|
+
clearTimeout(retryTimerRef.current);
|
|
263
|
+
retryTimerRef.current = null;
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
}, []);
|
|
198
267
|
useEffect(() => {
|
|
199
268
|
if (!enabled) {
|
|
269
|
+
refreshGenerationRef.current += 1;
|
|
270
|
+
if (retryTimerRef.current !== null) {
|
|
271
|
+
clearTimeout(retryTimerRef.current);
|
|
272
|
+
retryTimerRef.current = null;
|
|
273
|
+
}
|
|
200
274
|
setIsLoading(false);
|
|
201
275
|
return;
|
|
202
276
|
}
|
|
203
277
|
refreshEngines();
|
|
278
|
+
window.addEventListener("agent-engine:configured-changed", refreshEngines);
|
|
279
|
+
return () => window.removeEventListener("agent-engine:configured-changed", refreshEngines);
|
|
204
280
|
}, [enabled, refreshEngines]);
|
|
205
281
|
return {
|
|
206
282
|
availableModels,
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
* Body: { json: any, fieldName?: string, type?: "map"|"array", requestSource?: string }
|
|
14
14
|
*/
|
|
15
15
|
export declare const postCollabJson: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
16
|
-
ok?: undefined;
|
|
17
16
|
error: string;
|
|
17
|
+
ok?: undefined;
|
|
18
18
|
} | {
|
|
19
19
|
error?: undefined;
|
|
20
20
|
ok: boolean;
|
|
@@ -928,7 +928,7 @@ async function processIncomingMessage(incoming, options, opts = {}) {
|
|
|
928
928
|
// leave a user-facing Slack reply empty.
|
|
929
929
|
maxOutputTokens: resolveMainChatMaxOutputTokens(resolvedModel),
|
|
930
930
|
// Explicitly resolve the normal chat default so an empty-final
|
|
931
|
-
// retry can step its
|
|
931
|
+
// retry can step its effort down rather than
|
|
932
932
|
// repeatedly letting the engine choose Medium.
|
|
933
933
|
reasoningEffort: normalizeReasoningEffortForRequest(resolvedModel, undefined),
|
|
934
934
|
}, undefined, {
|
|
@@ -93,8 +93,8 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
|
|
|
93
93
|
label?: undefined;
|
|
94
94
|
message?: undefined;
|
|
95
95
|
} | {
|
|
96
|
-
count?: undefined;
|
|
97
96
|
id?: undefined;
|
|
97
|
+
count?: undefined;
|
|
98
98
|
deleted?: undefined;
|
|
99
99
|
providers?: undefined;
|
|
100
100
|
found: boolean;
|
|
@@ -48,8 +48,8 @@ export declare function handleUpdateResource(event: any): Promise<import("./stor
|
|
|
48
48
|
}>;
|
|
49
49
|
/** DELETE /_agent-native/resources/:id — delete a resource */
|
|
50
50
|
export declare function handleDeleteResource(event: any): Promise<{
|
|
51
|
-
error: string;
|
|
52
51
|
ok?: undefined;
|
|
52
|
+
error: string;
|
|
53
53
|
} | {
|
|
54
54
|
error?: undefined;
|
|
55
55
|
ok: boolean;
|
package/dist/secrets/routes.d.ts
CHANGED
|
@@ -34,37 +34,37 @@ export declare function createListSecretsHandler(): import("h3").EventHandlerWit
|
|
|
34
34
|
/** POST /_agent-native/secrets/:key — write a secret. */
|
|
35
35
|
export declare function createWriteSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
36
36
|
error: string;
|
|
37
|
-
status?: undefined;
|
|
38
37
|
ok?: undefined;
|
|
38
|
+
status?: undefined;
|
|
39
39
|
} | {
|
|
40
|
+
error?: undefined;
|
|
40
41
|
ok: boolean;
|
|
41
42
|
status: string;
|
|
42
|
-
error?: undefined;
|
|
43
43
|
} | {
|
|
44
|
+
ok?: undefined;
|
|
44
45
|
error: string;
|
|
45
46
|
removed?: undefined;
|
|
46
|
-
ok?: undefined;
|
|
47
47
|
} | {
|
|
48
|
+
error?: undefined;
|
|
48
49
|
ok: boolean;
|
|
49
50
|
removed: boolean;
|
|
50
|
-
error?: undefined;
|
|
51
51
|
}>>;
|
|
52
52
|
/**
|
|
53
53
|
* POST /_agent-native/secrets/:key/test — validate an optional candidate value
|
|
54
54
|
* or the current stored value without changing anything.
|
|
55
55
|
*/
|
|
56
56
|
export declare function createTestSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
57
|
+
ok?: undefined;
|
|
57
58
|
error: string;
|
|
58
59
|
note?: undefined;
|
|
59
|
-
ok?: undefined;
|
|
60
60
|
} | {
|
|
61
|
+
error?: undefined;
|
|
61
62
|
ok: boolean;
|
|
62
63
|
note?: undefined;
|
|
63
|
-
error?: undefined;
|
|
64
64
|
} | {
|
|
65
|
+
error?: undefined;
|
|
65
66
|
ok: boolean;
|
|
66
67
|
note: string;
|
|
67
|
-
error?: undefined;
|
|
68
68
|
} | {
|
|
69
69
|
note?: undefined;
|
|
70
70
|
ok: boolean;
|
|
@@ -95,11 +95,11 @@ export interface AdHocSecretPayload {
|
|
|
95
95
|
export declare function createAdHocSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<AdHocSecretPayload[] | {
|
|
96
96
|
error: string;
|
|
97
97
|
} | {
|
|
98
|
+
error?: undefined;
|
|
98
99
|
ok: boolean;
|
|
99
100
|
key: string;
|
|
100
|
-
error?: undefined;
|
|
101
101
|
} | {
|
|
102
|
+
error?: undefined;
|
|
102
103
|
ok: boolean;
|
|
103
104
|
removed: boolean;
|
|
104
|
-
error?: undefined;
|
|
105
105
|
}>>;
|