@agent-native/core 0.155.0 → 0.157.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.
- package/corpus/README.md +1 -1
- package/corpus/templates/analytics/server/jobs/analytics-bigquery-backfill.ts +19 -4
- package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +7 -2
- package/corpus/templates/assets/app/components/asset/AssetPreviewDialog.tsx +3 -1
- package/corpus/templates/assets/app/global.css +4 -0
- package/corpus/templates/assets/app/i18n-data.ts +21 -1
- package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +18 -15
- package/corpus/templates/brain/app/routes/sources.tsx +1 -2
- package/corpus/templates/calendar/app/hooks/use-bookings.ts +12 -2
- package/corpus/templates/calendar/app/pages/BookingLinksPage.tsx +64 -2
- package/corpus/templates/calendar/server/handlers/bookings.ts +219 -93
- package/corpus/templates/calendar/server/plugins/auth.ts +0 -2
- package/corpus/templates/clips/actions/create-folder.ts +7 -1
- package/corpus/templates/clips/actions/create-meeting.ts +6 -2
- package/corpus/templates/clips/actions/create-recording.ts +5 -3
- package/corpus/templates/clips/actions/finalize-recording.ts +97 -65
- package/corpus/templates/clips/actions/import-loom-recording.ts +5 -3
- package/corpus/templates/clips/actions/request-recording-access.ts +272 -0
- package/corpus/templates/clips/actions/stitch-recordings.ts +5 -3
- package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +38 -63
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +177 -134
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +3 -21
- package/corpus/templates/clips/app/components/sharing/share-ui.tsx +13 -30
- package/corpus/templates/clips/app/i18n/en-US.ts +10 -0
- package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +5 -5
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +24 -17
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +151 -20
- package/corpus/templates/clips/changelog/2026-08-14-long-resumable-uploads-now-abort-cleanly-and-show-errors.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-14-standardized-share-popovers.md +6 -0
- package/corpus/templates/clips/chrome-extension/public/manifest.json +11 -3
- package/corpus/templates/clips/chrome-extension/src/github-preview-content.ts +37 -8
- package/corpus/templates/clips/chrome-extension/src/github-preview.ts +3 -3
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +8 -25
- package/corpus/templates/clips/desktop/src/app.tsx +24 -0
- package/corpus/templates/clips/desktop/src/lib/media-capture-constraints.ts +42 -13
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +11 -18
- package/corpus/templates/clips/desktop/src/overlays/onboarding.tsx +1 -0
- package/corpus/templates/clips/desktop/src/shared/config.ts +1 -0
- package/corpus/templates/clips/desktop/src/styles.css +24 -9
- package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +3 -0
- package/corpus/templates/clips/desktop/src-tauri/src/config.rs +8 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +154 -176
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +115 -31
- package/corpus/templates/clips/desktop/src-tauri/src/rewind_clip.rs +7 -0
- package/corpus/templates/clips/server/db/index.ts +1 -0
- package/corpus/templates/clips/server/db/schema.ts +1 -0
- package/corpus/templates/clips/server/lib/calendar-event-meetings.ts +6 -1
- package/corpus/templates/clips/server/lib/emails.ts +23 -0
- package/corpus/templates/clips/server/lib/public-agent-context.ts +55 -0
- package/corpus/templates/clips/server/lib/recordings.ts +2 -1
- package/corpus/templates/clips/server/lib/resumable-upload-cleanup.ts +49 -0
- package/corpus/templates/clips/server/lib/s3-upload-provider.ts +34 -7
- package/corpus/templates/clips/server/lib/upload-interruption.ts +15 -1
- package/corpus/templates/clips/server/lib/upload-lease.ts +94 -9
- package/corpus/templates/clips/server/routes/api/agent-context.json.get.ts +82 -7
- package/corpus/templates/clips/server/routes/api/public-recording.get.ts +1 -0
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +71 -12
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/interrupt.post.ts +4 -3
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/reset-chunks.post.ts +19 -0
- package/corpus/templates/clips/server/routes/api/uploads/reap.post.ts +8 -1
- package/corpus/templates/clips/shared/recording-link.ts +4 -0
- package/corpus/templates/clips/shared/share-loader-response.ts +2 -1
- package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +7 -16
- package/corpus/templates/factory/AGENTS.md +5 -1
- package/corpus/templates/factory/README.md +6 -2
- package/corpus/templates/factory/actions/view-screen.ts +15 -0
- package/corpus/templates/factory/app/components/factory/FactoryAgentsView.tsx +58 -189
- package/corpus/templates/factory/app/components/layout/Header.tsx +1 -0
- package/corpus/templates/factory/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/factory/app/components/layout/Sidebar.tsx +7 -0
- package/corpus/templates/factory/app/hooks/use-navigation-state.ts +3 -0
- package/corpus/templates/factory/app/i18n/en-US.ts +3 -1
- package/corpus/templates/factory/app/routes/agents.tsx +9 -0
- package/corpus/templates/mail/server/plugins/auth.ts +0 -2
- package/corpus/templates/plan/app/components/plan/LocalCodebasePicker.tsx +50 -14
- package/corpus/templates/plan/app/pages/PlansPage.tsx +9 -19
- package/corpus/templates/slides/app/components/editor/AddSlidePopover.tsx +98 -29
- package/corpus/templates/slides/app/components/editor/EditorActionCluster.tsx +45 -91
- package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +94 -2
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +17 -29
- package/corpus/templates/slides/app/components/editor/HistoryPanel.tsx +7 -1
- package/corpus/templates/slides/app/components/editor/SlideContextToolbar.tsx +1 -1
- package/corpus/templates/slides/app/context/DeckContext.tsx +108 -19
- package/corpus/templates/slides/app/global.css +7 -40
- package/corpus/templates/slides/app/i18n/en-US.ts +4 -0
- package/corpus/templates/slides/app/lib/editor-shortcuts.ts +46 -0
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +143 -45
- package/dist/agent/index.d.ts +1 -1
- package/dist/agent/production-agent.d.ts +30 -0
- package/dist/agent/production-agent.js +100 -8
- package/dist/agent/types.d.ts +9 -0
- package/dist/client/AgentPanel.d.ts +13 -1
- package/dist/client/AgentPanel.js +22 -17
- package/dist/client/AssistantChat.d.ts +15 -1
- package/dist/client/AssistantChat.js +135 -48
- package/dist/client/HighlightedCodeBlock.js +12 -2
- package/dist/client/MultiTabAssistantChat.js +44 -27
- package/dist/client/agent-chat/index.d.ts +1 -0
- package/dist/client/agent-chat/index.js +1 -0
- package/dist/client/chat/markdown-renderer.js +20 -5
- package/dist/client/chat/message-components.d.ts +2 -2
- package/dist/client/chat/message-components.js +69 -35
- package/dist/client/chat/run-recovery.d.ts +4 -1
- package/dist/client/chat/run-recovery.js +62 -30
- package/dist/client/chat/tool-call-display.d.ts +12 -3
- package/dist/client/chat/tool-call-display.js +79 -40
- package/dist/client/chat/widgets/DataChartRenderer.js +3 -1
- package/dist/client/chat/widgets/DataChartWidget.js +8 -2
- package/dist/client/chat/widgets/DataInsightsWidget.js +3 -1
- package/dist/client/chat/widgets/DataTableWidget.js +23 -9
- package/dist/client/chat/widgets/builtin-tool-renderers.js +3 -1
- package/dist/client/chat-first/apps-rail.js +1 -1
- package/dist/client/components/ui/message-scroller.d.ts +1 -1
- package/dist/client/components/ui/message-scroller.js +7 -3
- package/dist/client/composer/runtime-adapters.js +3 -2
- package/dist/client/context-xray/ContextMeter.js +5 -1
- package/dist/client/context-xray/ContextXRayPanel.js +5 -5
- package/dist/client/error-format.d.ts +4 -0
- package/dist/client/error-format.js +93 -5
- package/dist/client/i18n.js +83 -17
- package/dist/client/observability/ThumbsFeedback.js +10 -8
- package/dist/client/settings/AccountSettingsCard.js +48 -19
- package/dist/client/sharing/ShareButton.d.ts +1 -2
- package/dist/client/sharing/ShareButton.js +151 -81
- package/dist/client/sharing/ShareDialog.js +5 -4
- package/dist/client/use-chat-threads.js +10 -14
- package/dist/coding-tools/run-code.js +2 -1
- package/dist/coding-tools/sandbox/background.d.ts +1 -0
- package/dist/coding-tools/sandbox/background.js +8 -1
- package/dist/coding-tools/sandbox/executions-store.d.ts +2 -0
- package/dist/coding-tools/sandbox/executions-store.js +41 -3
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/localization/core-messages/ar-SA.d.ts +3 -0
- package/dist/localization/core-messages/ar-SA.js +541 -0
- package/dist/localization/core-messages/de-DE.d.ts +3 -0
- package/dist/localization/core-messages/de-DE.js +513 -0
- package/dist/localization/core-messages/en-US.d.ts +513 -0
- package/dist/localization/core-messages/en-US.js +513 -0
- package/dist/localization/core-messages/es-ES.d.ts +3 -0
- package/dist/localization/core-messages/es-ES.js +520 -0
- package/dist/localization/core-messages/fr-FR.d.ts +3 -0
- package/dist/localization/core-messages/fr-FR.js +520 -0
- package/dist/localization/core-messages/hi-IN.d.ts +3 -0
- package/dist/localization/core-messages/hi-IN.js +513 -0
- package/dist/localization/core-messages/ja-JP.d.ts +3 -0
- package/dist/localization/core-messages/ja-JP.js +506 -0
- package/dist/localization/core-messages/ko-KR.d.ts +3 -0
- package/dist/localization/core-messages/ko-KR.js +506 -0
- package/dist/localization/core-messages/pt-BR.d.ts +3 -0
- package/dist/localization/core-messages/pt-BR.js +520 -0
- package/dist/localization/core-messages/zh-CN.d.ts +3 -0
- package/dist/localization/core-messages/zh-CN.js +506 -0
- package/dist/localization/core-messages/zh-TW.d.ts +3 -0
- package/dist/localization/core-messages/zh-TW.js +506 -0
- package/dist/localization/core-messages.d.ts +524 -0
- package/dist/localization/core-messages.js +124 -0
- package/dist/localization/default-messages.d.ts +3 -0
- package/dist/localization/default-messages.js +3 -0
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +5 -5
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
- package/dist/provider-api/actions/provider-api.d.ts +15 -15
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-chat/plugin-options.d.ts +7 -2
- package/dist/server/agent-chat-plugin.d.ts +10 -0
- package/dist/server/agent-chat-plugin.js +144 -41
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agent-run-context.d.ts +7 -1
- package/dist/server/agent-run-context.js +9 -2
- package/dist/server/agent-teams-run-queue.d.ts +3 -0
- package/dist/server/agent-teams.js +38 -9
- package/dist/server/auth-marketing.d.ts +1 -0
- package/dist/server/auth-marketing.js +0 -2
- package/dist/server/auth.d.ts +1 -0
- package/dist/server/auth.js +18 -0
- package/dist/server/index.d.ts +1 -1
- package/dist/server/onboarding-html.d.ts +1 -0
- package/dist/server/onboarding-html.js +2 -88
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/request-context.d.ts +7 -0
- package/dist/server/request-context.js +15 -0
- package/dist/shared/markdown-block-split.d.ts +16 -0
- package/dist/shared/markdown-block-split.js +81 -5
- package/dist/styles/agent-native.css +13 -0
- package/dist/voice/voice-cleanup-prompt.js +1 -0
- package/docs/content/agent-surfaces.mdx +30 -0
- package/package.json +2 -2
- package/corpus/templates/clips/shared/mic-audio-cleanup.ts +0 -350
|
@@ -12,7 +12,7 @@ import { AGENT_CHAT_BACKGROUND_RUN_FIELD, AGENT_CHAT_PROCESS_RUN_PATH, backgroun
|
|
|
12
12
|
import { resolveEngine, createAnthropicEngine, getStoredModelForEngine, normalizeModelForEngine, resolveDelegatedRunModel, getAgentEngineEntry, isAgentEnginePackageInstalled, isStoredEngineUsableForRequest, listAgentEngines, registerBuiltinEngines, } from "../agent/engine/index.js";
|
|
13
13
|
import { SYSTEM_PROMPT_CACHE_SPLIT } from "../agent/engine/prompt-cache.js";
|
|
14
14
|
import { PROVIDER_TO_ENV } from "../agent/engine/provider-env-vars.js";
|
|
15
|
-
import { createProductionAgentHandler, actionsToEngineTools, executeAgentToolCall, toolCallCacheKey, getActiveRunForThreadAsync, abortRunDurably, abortTurnDurably, subscribeToRun, } from "../agent/production-agent.js";
|
|
15
|
+
import { createProductionAgentHandler, actionsToEngineTools, executeAgentToolCall, filterActionsByAllowedNames, readPersistedActionSurface, toolCallCacheKey, getActiveRunForThreadAsync, abortRunDurably, abortTurnDurably, subscribeToRun, } from "../agent/production-agent.js";
|
|
16
16
|
import { callerHasRunAccess, callerHasThreadAccess, } from "../agent/run-ownership.js";
|
|
17
17
|
import { markTurnAborted, readBackgroundRunClaim } from "../agent/run-store.js";
|
|
18
18
|
import { buildCurrentTimeUserContext, buildRuntimeContextPrompt, } from "../agent/runtime-context.js";
|
|
@@ -208,6 +208,46 @@ export async function resolveA2ARecoverableArtifactSecret(orgId = getRequestOrgI
|
|
|
208
208
|
export function buildLeanRunPolicyPrompt(codeEditingSurfaceRestriction, prodCodeExecPromptNote) {
|
|
209
209
|
return codeEditingSurfaceRestriction + prodCodeExecPromptNote;
|
|
210
210
|
}
|
|
211
|
+
export function filterPromptActionsToSurface(actions, allowedActionNames) {
|
|
212
|
+
if (!allowedActionNames)
|
|
213
|
+
return actions;
|
|
214
|
+
return filterActionsByAllowedNames(actions, allowedActionNames.filter((name) => actions[name]));
|
|
215
|
+
}
|
|
216
|
+
/** Keep late-bound sandbox and data-program bridges on the current request's
|
|
217
|
+
* authorized registry instead of the plugin's process-wide action catalog. */
|
|
218
|
+
export function filterRuntimeActionsToSurface(actions) {
|
|
219
|
+
return filterPromptActionsToSurface(actions, getRequestRunContext()?.allowedActionNames);
|
|
220
|
+
}
|
|
221
|
+
/** Remove framework guidance for tools that the request surface does not
|
|
222
|
+
* expose. The default framework prompt is line-oriented, so dropping the
|
|
223
|
+
* affected instruction keeps unrelated behavioral guidance intact without
|
|
224
|
+
* teaching the model names it cannot call. */
|
|
225
|
+
export function filterFrameworkPromptToSurface(prompt, actions, allowedActionNames) {
|
|
226
|
+
if (!allowedActionNames)
|
|
227
|
+
return prompt;
|
|
228
|
+
const allowedNames = new Set(allowedActionNames);
|
|
229
|
+
const deniedPatterns = Object.keys(actions)
|
|
230
|
+
.filter((name) => !allowedNames.has(name))
|
|
231
|
+
.sort((a, b) => b.length - a.length)
|
|
232
|
+
.map((name) => {
|
|
233
|
+
const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
234
|
+
return new RegExp(`(^|[^a-z0-9-])${escaped}(?=$|[^a-z0-9-])`);
|
|
235
|
+
});
|
|
236
|
+
if (deniedPatterns.length === 0)
|
|
237
|
+
return prompt;
|
|
238
|
+
return prompt
|
|
239
|
+
.split("\n")
|
|
240
|
+
.filter((line) => !deniedPatterns.some((pattern) => pattern.test(line)))
|
|
241
|
+
.join("\n")
|
|
242
|
+
.replace(/\n{3,}/g, "\n\n")
|
|
243
|
+
.trimEnd();
|
|
244
|
+
}
|
|
245
|
+
export function resolveProductionCodeExecutionForActionSurface(mode, hasRequestScopedSurface) {
|
|
246
|
+
// A trusted shell can reach action routes outside the native registry, so it
|
|
247
|
+
// cannot uphold a hard per-request allowlist. Keep sandboxed run-code, whose
|
|
248
|
+
// bridge is filtered against the current request, as the safe equivalent.
|
|
249
|
+
return hasRequestScopedSurface && mode === "trusted" ? "sandboxed" : mode;
|
|
250
|
+
}
|
|
211
251
|
/**
|
|
212
252
|
* In-memory rate-limit tracker for `/generate-title`. Keyed by user email,
|
|
213
253
|
* value is recent invocation timestamps within the rolling window. Stale
|
|
@@ -892,6 +932,11 @@ export function createAgentChatPlugin(options) {
|
|
|
892
932
|
: rawEnvCodeExec === "off"
|
|
893
933
|
? "off"
|
|
894
934
|
: (options?.codeExecution?.production ?? "off");
|
|
935
|
+
const effectiveProdCodeExec = resolveProductionCodeExecutionForActionSurface(resolvedProdCodeExec, Boolean(options?.resolveActionSurface));
|
|
936
|
+
if (resolvedProdCodeExec === "trusted" &&
|
|
937
|
+
effectiveProdCodeExec !== "trusted") {
|
|
938
|
+
console.warn("[agent-native] Request-scoped action surfaces disable trusted shell tools; using sandboxed code execution instead.");
|
|
939
|
+
}
|
|
895
940
|
// Forward-declaration for the production code-execution bridge supplier.
|
|
896
941
|
// Must come before the code entries are created so their closures can capture it.
|
|
897
942
|
let prodRunCodeToolActions = {};
|
|
@@ -902,11 +947,11 @@ export function createAgentChatPlugin(options) {
|
|
|
902
947
|
const runCodeTool = await loadRunCodeToolEntries(
|
|
903
948
|
// Supplier is evaluated at invocation time so runtime additions to
|
|
904
949
|
// prodActions (e.g. MCP sync) are visible to the bridge.
|
|
905
|
-
() => prodRunCodeToolActions, { bridgeTools: options?.codeExecution?.bridgeTools });
|
|
950
|
+
() => filterRuntimeActionsToSurface(prodRunCodeToolActions), { bridgeTools: options?.codeExecution?.bridgeTools });
|
|
906
951
|
const leanRunCodeTool = await loadRunCodeToolEntries(
|
|
907
952
|
// Lean prompt mode intentionally exposes a much smaller action
|
|
908
953
|
// surface; keep sandbox appAction() calls scoped to that same surface.
|
|
909
|
-
() => leanRunCodeToolActions, { bridgeTools: options?.codeExecution?.bridgeTools });
|
|
954
|
+
() => filterRuntimeActionsToSurface(leanRunCodeToolActions), { bridgeTools: options?.codeExecution?.bridgeTools });
|
|
910
955
|
// Full coding tool registry (bash/read/edit/write) for "trusted" prod.
|
|
911
956
|
// In dev mode this is handled separately via devHandler below.
|
|
912
957
|
const prodCodingTools = {};
|
|
@@ -935,7 +980,7 @@ export function createAgentChatPlugin(options) {
|
|
|
935
980
|
// use a late-binding supplier so devRunCodeTool can reference the
|
|
936
981
|
// devActions registry once it is built below (see devHandler block).
|
|
937
982
|
const devRunCodeTool = canToggle
|
|
938
|
-
? await loadRunCodeToolEntries(() => devRunCodeToolActions, {
|
|
983
|
+
? await loadRunCodeToolEntries(() => filterRuntimeActionsToSurface(devRunCodeToolActions), {
|
|
939
984
|
bridgeTools: options?.codeExecution?.bridgeTools,
|
|
940
985
|
})
|
|
941
986
|
: {};
|
|
@@ -946,7 +991,7 @@ export function createAgentChatPlugin(options) {
|
|
|
946
991
|
...templateScripts,
|
|
947
992
|
...(canToggle
|
|
948
993
|
? devRunCodeTool
|
|
949
|
-
:
|
|
994
|
+
: effectiveProdCodeExec !== "off"
|
|
950
995
|
? runCodeTool
|
|
951
996
|
: {}),
|
|
952
997
|
};
|
|
@@ -1684,6 +1729,36 @@ export function createAgentChatPlugin(options) {
|
|
|
1684
1729
|
: "";
|
|
1685
1730
|
const prodActionsPrompt = generateActionsPrompt(templateScripts, "tool", lazyContext ? effectiveInitialToolNames : undefined) + corpusToolsPrompt;
|
|
1686
1731
|
const devActionsPrompt = generateActionsPrompt({ ...discoveredActions, ...templateScripts }, "cli") + corpusToolsPrompt;
|
|
1732
|
+
const filterPromptActionsForRequest = (actions) => {
|
|
1733
|
+
return filterPromptActionsToSurface(actions, getRequestRunContext()?.allowedActionNames);
|
|
1734
|
+
};
|
|
1735
|
+
const resolveRequestActionsPrompt = (mode) => {
|
|
1736
|
+
const allowedNames = getRequestRunContext()?.allowedActionNames;
|
|
1737
|
+
if (!allowedNames) {
|
|
1738
|
+
return mode === "tool" ? prodActionsPrompt : devActionsPrompt;
|
|
1739
|
+
}
|
|
1740
|
+
const promptActions = filterPromptActionsForRequest(mode === "tool"
|
|
1741
|
+
? templateScripts
|
|
1742
|
+
: { ...discoveredActions, ...templateScripts });
|
|
1743
|
+
const promptCorpus = filterPromptActionsForRequest(corpusPromptRegistry);
|
|
1744
|
+
return (generateActionsPrompt(promptActions, mode) +
|
|
1745
|
+
(loadCorpusToolsInitially
|
|
1746
|
+
? generateCorpusToolsPrompt(promptCorpus)
|
|
1747
|
+
: ""));
|
|
1748
|
+
};
|
|
1749
|
+
const leanActionsPrompt = prodActionsPrompt +
|
|
1750
|
+
(a2aAgentDelegationEnabled
|
|
1751
|
+
? generateActionsPrompt(callAgentScript, "tool")
|
|
1752
|
+
: "");
|
|
1753
|
+
const resolveRequestLeanActionsPrompt = () => {
|
|
1754
|
+
const allowedNames = getRequestRunContext()?.allowedActionNames;
|
|
1755
|
+
if (!allowedNames)
|
|
1756
|
+
return leanActionsPrompt;
|
|
1757
|
+
return generateActionsPrompt(filterPromptActionsForRequest({
|
|
1758
|
+
...templateScripts,
|
|
1759
|
+
...(a2aAgentDelegationEnabled ? callAgentScript : {}),
|
|
1760
|
+
}), "tool");
|
|
1761
|
+
};
|
|
1687
1762
|
// Build system prompts — dynamic functions that pre-load resources per-request.
|
|
1688
1763
|
// Production gets PROD_FRAMEWORK_PROMPT, dev gets DEV_FRAMEWORK_PROMPT.
|
|
1689
1764
|
// Custom systemPrompt from options overrides the framework default entirely.
|
|
@@ -1695,10 +1770,19 @@ export function createAgentChatPlugin(options) {
|
|
|
1695
1770
|
// `nativeActionsInDev` or `leanPrompt`), the dev prompt's "invoke
|
|
1696
1771
|
// template actions via bash" guidance is wrong — use the prod prompt
|
|
1697
1772
|
// + tool-format action list instead, same as production.
|
|
1698
|
-
const devNative = options?.nativeActionsInDev === true ||
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1773
|
+
const devNative = options?.nativeActionsInDev === true ||
|
|
1774
|
+
leanPrompt ||
|
|
1775
|
+
Boolean(options?.resolveActionSurface);
|
|
1776
|
+
// Keep legacy names for the composition below
|
|
1777
|
+
const basePrompt = prodPrompt;
|
|
1778
|
+
const getFrameworkPromptActions = () => Object.fromEntries(Object.entries(prodActions).filter(([name]) => !templateScripts[name] && !mcpActionEntries[name]));
|
|
1779
|
+
const resolveRequestBasePrompt = () => (options?.systemPrompt ??
|
|
1780
|
+
filterFrameworkPromptToSurface(lazyContext ? PROD_FRAMEWORK_PROMPT_COMPACT : PROD_FRAMEWORK_PROMPT, getFrameworkPromptActions(), getRequestRunContext()?.allowedActionNames)) + resolveRequestActionsPrompt("tool");
|
|
1781
|
+
const resolveRequestLeanPrompt = () => (options?.systemPrompt ?? "") + resolveRequestLeanActionsPrompt();
|
|
1782
|
+
const resolveRequestDevPrompt = () => {
|
|
1783
|
+
if (devNative)
|
|
1784
|
+
return resolveRequestBasePrompt();
|
|
1785
|
+
const frameworkPrompt = options?.devSystemPrompt
|
|
1702
1786
|
? options.devSystemPrompt +
|
|
1703
1787
|
(options?.systemPrompt ??
|
|
1704
1788
|
(lazyContext
|
|
@@ -1706,9 +1790,9 @@ export function createAgentChatPlugin(options) {
|
|
|
1706
1790
|
: PROD_FRAMEWORK_PROMPT))
|
|
1707
1791
|
: lazyContext
|
|
1708
1792
|
? DEV_FRAMEWORK_PROMPT_COMPACT
|
|
1709
|
-
: DEV_FRAMEWORK_PROMPT
|
|
1710
|
-
|
|
1711
|
-
|
|
1793
|
+
: DEV_FRAMEWORK_PROMPT;
|
|
1794
|
+
return frameworkPrompt + resolveRequestActionsPrompt("cli");
|
|
1795
|
+
};
|
|
1712
1796
|
if (mcpOptions.enabled) {
|
|
1713
1797
|
// Mount MCP remote server — same action registry as A2A + agent chat
|
|
1714
1798
|
const { mountMCP } = await import("../mcp/server.js");
|
|
@@ -2245,7 +2329,7 @@ export function createAgentChatPlugin(options) {
|
|
|
2245
2329
|
const teamTools = createTeamTools({
|
|
2246
2330
|
getOwner: () => requireCurrentRunOwner("spawn or manage sub-agents"),
|
|
2247
2331
|
getSystemPrompt: () => getRequestRunContext()?.systemPrompt ?? basePrompt,
|
|
2248
|
-
getActions: buildSubAgentActions,
|
|
2332
|
+
getActions: () => filterRuntimeActionsToSurface(buildSubAgentActions()),
|
|
2249
2333
|
getEngine: () => {
|
|
2250
2334
|
const runCtx = getRequestRunContext();
|
|
2251
2335
|
// Sub-agents must inherit the parent run's resolved key so
|
|
@@ -2343,9 +2427,11 @@ export function createAgentChatPlugin(options) {
|
|
|
2343
2427
|
...mcpActionEntries,
|
|
2344
2428
|
// Sandboxed run-code for hosted production when enabled, and for the
|
|
2345
2429
|
// app-rendered production-style handler in local dev.
|
|
2346
|
-
...(canToggle ||
|
|
2430
|
+
...(canToggle || effectiveProdCodeExec !== "off" ? runCodeTool : {}),
|
|
2347
2431
|
// Full coding tools in production when mode is "trusted".
|
|
2348
|
-
...(!canToggle
|
|
2432
|
+
...(!canToggle && effectiveProdCodeExec === "trusted"
|
|
2433
|
+
? prodCodingTools
|
|
2434
|
+
: {}),
|
|
2349
2435
|
});
|
|
2350
2436
|
mountRealtimeVoiceRoutes(nitroApp, prodActions, {
|
|
2351
2437
|
resolveOrgId: options?.resolveOrgId,
|
|
@@ -2393,7 +2479,9 @@ export function createAgentChatPlugin(options) {
|
|
|
2393
2479
|
// Otherwise templates with a minimal prompt can advertise sandboxed
|
|
2394
2480
|
// execution in the system prompt while the actual tool registry omits
|
|
2395
2481
|
// it.
|
|
2396
|
-
...(canToggle ||
|
|
2482
|
+
...(canToggle || effectiveProdCodeExec !== "off"
|
|
2483
|
+
? leanRunCodeTool
|
|
2484
|
+
: {}),
|
|
2397
2485
|
});
|
|
2398
2486
|
leanRunCodeToolActions = leanActions;
|
|
2399
2487
|
// Keep the prod action dict's MCP entries in sync when the manager's
|
|
@@ -2410,14 +2498,18 @@ export function createAgentChatPlugin(options) {
|
|
|
2410
2498
|
// Lean mode: use only the template's systemPrompt + actions list.
|
|
2411
2499
|
// Skip resource loading and schema block — those add DB round-trips
|
|
2412
2500
|
// and tokens that minimal/voice apps don't need.
|
|
2413
|
-
const leanActionsPrompt = prodActionsPrompt +
|
|
2414
|
-
(a2aAgentDelegationEnabled
|
|
2415
|
-
? generateActionsPrompt(callAgentScript, "tool")
|
|
2416
|
-
: "");
|
|
2417
|
-
const leanBasePrompt = (options?.systemPrompt ?? "") + leanActionsPrompt;
|
|
2418
2501
|
const anonymousReadOnlyPrompt = (options?.systemPrompt ?? PROD_FRAMEWORK_PROMPT_COMPACT) +
|
|
2419
2502
|
generateActionsPrompt(filterReadOnlyActions(templateScripts), "tool", lazyContext ? effectiveInitialToolNames : undefined) +
|
|
2420
2503
|
"\n\nYou are answering from a public shared page. Treat the visible resource as read-only: do not create, edit, delete, comment on, share, or otherwise mutate app data. If the user asks for a change, describe what you would change or suggest signing in to edit.";
|
|
2504
|
+
const resolveAnonymousReadOnlyPrompt = () => {
|
|
2505
|
+
if (!getRequestRunContext()?.allowedActionNames) {
|
|
2506
|
+
return anonymousReadOnlyPrompt;
|
|
2507
|
+
}
|
|
2508
|
+
return ((options?.systemPrompt ??
|
|
2509
|
+
filterFrameworkPromptToSurface(PROD_FRAMEWORK_PROMPT_COMPACT, getFrameworkPromptActions(), getRequestRunContext()?.allowedActionNames)) +
|
|
2510
|
+
generateActionsPrompt(filterPromptActionsForRequest(filterReadOnlyActions(templateScripts)), "tool") +
|
|
2511
|
+
"\n\nYou are answering from a public shared page. Treat the visible resource as read-only: do not create, edit, delete, comment on, share, or otherwise mutate app data. If the user asks for a change, describe what you would change or suggest signing in to edit.");
|
|
2512
|
+
};
|
|
2421
2513
|
// Per-request preamble shared by both prod and dev handlers. Resolves
|
|
2422
2514
|
// owner + user API key onto the AsyncLocalStorage run context so
|
|
2423
2515
|
// downstream tool closures (automation, fetch, team) read the
|
|
@@ -2585,8 +2677,8 @@ When the user asks to add a feature, edit a component, fix a bug in the app itse
|
|
|
2585
2677
|
Non-code requests are still fine on this surface: read data, navigate the UI, summarize, search, create/update extensions (sandboxed Alpine.js mini-apps stored in SQL), and call template actions. The restriction is specifically about direct edits to the host app's own source files.
|
|
2586
2678
|
</app-rendered-chat-no-direct-code-edits>`;
|
|
2587
2679
|
// System-prompt note appended when production code execution is enabled.
|
|
2588
|
-
const prodCodeExecPromptNote = !canToggle &&
|
|
2589
|
-
?
|
|
2680
|
+
const prodCodeExecPromptNote = !canToggle && effectiveProdCodeExec !== "off"
|
|
2681
|
+
? effectiveProdCodeExec === "trusted"
|
|
2590
2682
|
? "\n\n<code-execution-mode>Full shell access is enabled (trusted mode). You have bash, read, edit, write, and run-code tools available. Use bash for file discovery, running tests and builds, and project CLIs. Use run-code for sandboxed JavaScript data processing: provider/API pagination, joins, classification, aggregation, and large-response reduction. Use tool-orchestration for short bounded fan-out or reduction over read-only tools. Use `pnpm action <name>` in bash to invoke registered app actions from the shell.</code-execution-mode>"
|
|
2591
2683
|
: "\n\n<code-execution-mode>Sandboxed code execution is enabled. Use tool-orchestration for short bounded fan-out, joins, and reduction over read-only tools. Use run-code when you need its broader provider/web helpers, workspace staging, or durable background execution. In either tool, authenticated calls go through the provided host globals and results should be reduced before printing.</code-execution-mode>"
|
|
2592
2684
|
: "";
|
|
@@ -2594,6 +2686,10 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
2594
2686
|
actions: leanPrompt ? leanActions : prodActions,
|
|
2595
2687
|
systemPrompt: async (event) => {
|
|
2596
2688
|
const { owner, extra } = await prepareRun(event);
|
|
2689
|
+
const requestActionsPrompt = resolveRequestActionsPrompt("tool");
|
|
2690
|
+
const requestLeanActionsPrompt = resolveRequestLeanActionsPrompt();
|
|
2691
|
+
const requestBasePrompt = resolveRequestBasePrompt();
|
|
2692
|
+
const requestLeanPrompt = resolveRequestLeanPrompt();
|
|
2597
2693
|
const runtimeContext = runtimeContextForEvent(event);
|
|
2598
2694
|
const codeEditingSurfaceRestriction = shouldBlockInProductCodeEditing(event)
|
|
2599
2695
|
? APP_RENDERED_CHAT_NO_DIRECT_CODE_PROMPT
|
|
@@ -2612,8 +2708,8 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
2612
2708
|
const leanRunPolicyPrompt = buildLeanRunPolicyPrompt(codeEditingSurfaceRestriction, prodCodeExecPromptNote);
|
|
2613
2709
|
const resources = await loadResourcesForPrompt(owner, true, options?.appId, undefined, { disabledFrameworkGroups });
|
|
2614
2710
|
await emitContextXraySystemSections(event, {
|
|
2615
|
-
frameworkPrompt:
|
|
2616
|
-
actionsPrompt:
|
|
2711
|
+
frameworkPrompt: requestLeanPrompt.slice(0, Math.max(0, requestLeanPrompt.length - requestLeanActionsPrompt.length)),
|
|
2712
|
+
actionsPrompt: requestLeanActionsPrompt,
|
|
2617
2713
|
additionalFramework: leanRunPolicyPrompt,
|
|
2618
2714
|
resources,
|
|
2619
2715
|
extra,
|
|
@@ -2621,7 +2717,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
2621
2717
|
runtimeContext,
|
|
2622
2718
|
});
|
|
2623
2719
|
return setSystemPromptOnContext(buildLeanSystemPrompt({
|
|
2624
|
-
basePrompt:
|
|
2720
|
+
basePrompt: requestLeanPrompt,
|
|
2625
2721
|
additionalFramework: leanRunPolicyPrompt,
|
|
2626
2722
|
cacheSplit: SYSTEM_PROMPT_CACHE_SPLIT,
|
|
2627
2723
|
resources,
|
|
@@ -2637,8 +2733,8 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
2637
2733
|
? ""
|
|
2638
2734
|
: await buildSchemaBlock(owner, databaseToolsMode);
|
|
2639
2735
|
await emitContextXraySystemSections(event, {
|
|
2640
|
-
frameworkPrompt:
|
|
2641
|
-
actionsPrompt:
|
|
2736
|
+
frameworkPrompt: requestBasePrompt.slice(0, Math.max(0, requestBasePrompt.length - requestActionsPrompt.length)),
|
|
2737
|
+
actionsPrompt: requestActionsPrompt,
|
|
2642
2738
|
resources,
|
|
2643
2739
|
schemaBlock,
|
|
2644
2740
|
extra,
|
|
@@ -2646,7 +2742,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
2646
2742
|
runtimeContext,
|
|
2647
2743
|
additionalFramework: codeEditingSurfaceRestriction + prodCodeExecPromptNote,
|
|
2648
2744
|
});
|
|
2649
|
-
return setSystemPromptOnContext(
|
|
2745
|
+
return setSystemPromptOnContext(requestBasePrompt +
|
|
2650
2746
|
SYSTEM_PROMPT_CACHE_SPLIT +
|
|
2651
2747
|
resources +
|
|
2652
2748
|
schemaBlock +
|
|
@@ -2708,6 +2804,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
2708
2804
|
message,
|
|
2709
2805
|
};
|
|
2710
2806
|
},
|
|
2807
|
+
resolveActionSurface: options?.resolveActionSurface,
|
|
2711
2808
|
skipFilesContext,
|
|
2712
2809
|
initialToolNames: effectiveInitialToolNames,
|
|
2713
2810
|
...(options?.toolLimits ? { toolLimits: options.toolLimits } : {}),
|
|
@@ -2741,12 +2838,13 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
2741
2838
|
actions: anonymousReadOnlyActions,
|
|
2742
2839
|
systemPrompt: async (event) => {
|
|
2743
2840
|
const { extra } = await prepareRun(event);
|
|
2841
|
+
const requestAnonymousPrompt = resolveAnonymousReadOnlyPrompt();
|
|
2744
2842
|
await emitContextXraySystemSections(event, {
|
|
2745
|
-
frameworkPrompt:
|
|
2843
|
+
frameworkPrompt: requestAnonymousPrompt,
|
|
2746
2844
|
extra,
|
|
2747
2845
|
runtimeContext: runtimeContextForEvent(event),
|
|
2748
2846
|
});
|
|
2749
|
-
return setSystemPromptOnContext(
|
|
2847
|
+
return setSystemPromptOnContext(requestAnonymousPrompt +
|
|
2750
2848
|
extra +
|
|
2751
2849
|
runtimeContextForEvent(event));
|
|
2752
2850
|
},
|
|
@@ -2756,6 +2854,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
2756
2854
|
...resolveInteractiveAgentRunOptions(options),
|
|
2757
2855
|
finalResponseGuard: options?.finalResponseGuard,
|
|
2758
2856
|
prepareRequest: options?.prepareRequest,
|
|
2857
|
+
resolveActionSurface: options?.resolveActionSurface,
|
|
2759
2858
|
skipFilesContext: true,
|
|
2760
2859
|
initialToolNames: effectiveInitialToolNames,
|
|
2761
2860
|
onEngineResolved: (engine, model) => {
|
|
@@ -2847,6 +2946,10 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
2847
2946
|
actions: devActions,
|
|
2848
2947
|
systemPrompt: async (event) => {
|
|
2849
2948
|
const { owner, extra } = await prepareRun(event);
|
|
2949
|
+
const requestActionsPrompt = resolveRequestActionsPrompt(devNative ? "tool" : "cli");
|
|
2950
|
+
const requestLeanActionsPrompt = resolveRequestLeanActionsPrompt();
|
|
2951
|
+
const requestLeanPrompt = resolveRequestLeanPrompt();
|
|
2952
|
+
const requestDevPrompt = resolveRequestDevPrompt();
|
|
2850
2953
|
const runtimeContext = runtimeContextForEvent(event);
|
|
2851
2954
|
const modelOverlay = resolveModelOverlay();
|
|
2852
2955
|
// Stable-first ordering: runtimeContext (day-granular) is
|
|
@@ -2856,15 +2959,15 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
2856
2959
|
if (leanPrompt) {
|
|
2857
2960
|
const resources = await loadResourcesForPrompt(owner, true, options?.appId, undefined, { disabledFrameworkGroups });
|
|
2858
2961
|
await emitContextXraySystemSections(event, {
|
|
2859
|
-
frameworkPrompt:
|
|
2860
|
-
actionsPrompt:
|
|
2962
|
+
frameworkPrompt: requestLeanPrompt.slice(0, Math.max(0, requestLeanPrompt.length - requestLeanActionsPrompt.length)),
|
|
2963
|
+
actionsPrompt: requestLeanActionsPrompt,
|
|
2861
2964
|
resources,
|
|
2862
2965
|
extra,
|
|
2863
2966
|
modelOverlay,
|
|
2864
2967
|
runtimeContext,
|
|
2865
2968
|
});
|
|
2866
2969
|
return setSystemPromptOnContext(buildLeanSystemPrompt({
|
|
2867
|
-
basePrompt:
|
|
2970
|
+
basePrompt: requestLeanPrompt,
|
|
2868
2971
|
resources,
|
|
2869
2972
|
extra,
|
|
2870
2973
|
modelOverlay,
|
|
@@ -2876,17 +2979,15 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
2876
2979
|
? ""
|
|
2877
2980
|
: await buildSchemaBlock(owner, databaseToolsMode);
|
|
2878
2981
|
await emitContextXraySystemSections(event, {
|
|
2879
|
-
frameworkPrompt:
|
|
2880
|
-
|
|
2881
|
-
: devPrompt.slice(0, Math.max(0, devPrompt.length - devActionsPrompt.length)),
|
|
2882
|
-
actionsPrompt: devNative ? prodActionsPrompt : devActionsPrompt,
|
|
2982
|
+
frameworkPrompt: requestDevPrompt.slice(0, Math.max(0, requestDevPrompt.length - requestActionsPrompt.length)),
|
|
2983
|
+
actionsPrompt: requestActionsPrompt,
|
|
2883
2984
|
resources,
|
|
2884
2985
|
schemaBlock,
|
|
2885
2986
|
extra,
|
|
2886
2987
|
modelOverlay,
|
|
2887
2988
|
runtimeContext,
|
|
2888
2989
|
});
|
|
2889
|
-
return setSystemPromptOnContext(
|
|
2990
|
+
return setSystemPromptOnContext(requestDevPrompt +
|
|
2890
2991
|
resources +
|
|
2891
2992
|
schemaBlock +
|
|
2892
2993
|
extra +
|
|
@@ -2913,6 +3014,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
2913
3014
|
}
|
|
2914
3015
|
return options?.prepareRequest?.(details);
|
|
2915
3016
|
},
|
|
3017
|
+
resolveActionSurface: options?.resolveActionSurface,
|
|
2916
3018
|
skipFilesContext,
|
|
2917
3019
|
initialToolNames: effectiveInitialToolNames,
|
|
2918
3020
|
...(options?.toolLimits ? { toolLimits: options.toolLimits } : {}),
|
|
@@ -3085,7 +3187,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
3085
3187
|
// just told, and filtering to the full set would only add a
|
|
3086
3188
|
// tool-search schema with nothing new for it to find.
|
|
3087
3189
|
return {
|
|
3088
|
-
baseSystemPrompt: basePrompt,
|
|
3190
|
+
baseSystemPrompt: filterFrameworkPromptToSurface(basePrompt, prodActions, payload.allowedActionNames),
|
|
3089
3191
|
actions: buildSubAgentActions(),
|
|
3090
3192
|
engine,
|
|
3091
3193
|
model,
|
|
@@ -4793,7 +4895,8 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
4793
4895
|
// helper expands that owner into the same user/org AsyncLocalStorage
|
|
4794
4896
|
// context the foreground request uses, so credential and data scoping
|
|
4795
4897
|
// stay aligned.
|
|
4796
|
-
|
|
4898
|
+
const persistedSurface = readPersistedActionSurface(workerBody, "__resolvedActionSurface");
|
|
4899
|
+
await seedBackgroundAgentRunOwnerContext(event, prepared.runId, persistedSurface?.orgId);
|
|
4797
4900
|
return await invokeAgentChatHandler(event);
|
|
4798
4901
|
}
|
|
4799
4902
|
catch (err) {
|
|
@@ -27,10 +27,10 @@ export declare function resolveAgentEngineApiKeyWriteTarget(event: H3Event, scop
|
|
|
27
27
|
export declare function createAgentEngineApiKeyHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
28
28
|
error: any;
|
|
29
29
|
} | {
|
|
30
|
+
error?: undefined;
|
|
30
31
|
ok: boolean;
|
|
31
32
|
key: string;
|
|
32
33
|
baseUrlKey?: string;
|
|
33
34
|
scope: AgentEngineApiKeyScope;
|
|
34
|
-
error?: undefined;
|
|
35
35
|
}>>;
|
|
36
36
|
export {};
|
|
@@ -4,6 +4,12 @@ export type AgentRunOwnerContext = {
|
|
|
4
4
|
owner: string;
|
|
5
5
|
anonymous: boolean;
|
|
6
6
|
name?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Trusted org binding for a cookieless durable worker. Presence matters:
|
|
9
|
+
* `null` means the authenticated foreground request had no org and must not
|
|
10
|
+
* fall back to another membership during worker re-entry.
|
|
11
|
+
*/
|
|
12
|
+
orgId?: string | null;
|
|
7
13
|
};
|
|
8
14
|
export declare const AGENT_RUN_OWNER_CONTEXT_KEY = "__agentNativeOwnerContext";
|
|
9
15
|
type AnonymousOwnerResolver = (event: H3Event) => string | null | Promise<string | null>;
|
|
@@ -20,7 +26,7 @@ export declare function readAgentRunTimezone(event: H3Event): string | undefined
|
|
|
20
26
|
*/
|
|
21
27
|
export declare function readBrowserSessionIdHeader(event: H3Event): string | undefined;
|
|
22
28
|
export declare function seedAgentRunOwnerContext(event: H3Event, ownerContext: AgentRunOwnerContext): AgentRunOwnerContext;
|
|
23
|
-
export declare function seedBackgroundAgentRunOwnerContext(event: H3Event, runId: string): Promise<AgentRunOwnerContext | null>;
|
|
29
|
+
export declare function seedBackgroundAgentRunOwnerContext(event: H3Event, runId: string, orgId?: string | null): Promise<AgentRunOwnerContext | null>;
|
|
24
30
|
export declare function resolveAgentRunOwnerContext(event: H3Event, options?: {
|
|
25
31
|
anonymousOwner?: AnonymousOwnerResolver;
|
|
26
32
|
}): Promise<AgentRunOwnerContext>;
|
|
@@ -67,13 +67,17 @@ export function seedAgentRunOwnerContext(event, ownerContext) {
|
|
|
67
67
|
ownerContext;
|
|
68
68
|
return ownerContext;
|
|
69
69
|
}
|
|
70
|
-
export async function seedBackgroundAgentRunOwnerContext(event, runId) {
|
|
70
|
+
export async function seedBackgroundAgentRunOwnerContext(event, runId, orgId) {
|
|
71
71
|
try {
|
|
72
72
|
const { getRunOwnerEmail } = await import("../agent/run-store.js");
|
|
73
73
|
const owner = await getRunOwnerEmail(runId);
|
|
74
74
|
if (!owner)
|
|
75
75
|
return null;
|
|
76
|
-
return seedAgentRunOwnerContext(event, {
|
|
76
|
+
return seedAgentRunOwnerContext(event, {
|
|
77
|
+
owner,
|
|
78
|
+
anonymous: false,
|
|
79
|
+
...(orgId !== undefined ? { orgId } : {}),
|
|
80
|
+
});
|
|
77
81
|
}
|
|
78
82
|
catch {
|
|
79
83
|
return null;
|
|
@@ -105,6 +109,9 @@ export async function resolveAgentRunOwnerContext(event, options = {}) {
|
|
|
105
109
|
});
|
|
106
110
|
}
|
|
107
111
|
export async function resolveAgentRunOrgId(options) {
|
|
112
|
+
if (Object.prototype.hasOwnProperty.call(options.ownerContext, "orgId")) {
|
|
113
|
+
return normalizeId(options.ownerContext.orgId);
|
|
114
|
+
}
|
|
108
115
|
let resolvedOrgId;
|
|
109
116
|
if (options.resolveOrgId) {
|
|
110
117
|
resolvedOrgId = normalizeId(await options.resolveOrgId(options.event));
|
|
@@ -31,6 +31,9 @@ export interface AgentTeamRunPayload {
|
|
|
31
31
|
parentRunId?: string;
|
|
32
32
|
/** Display name for the sub-agent tab. */
|
|
33
33
|
name?: string;
|
|
34
|
+
/** Exact action registry captured when the parent spawned this task. Older
|
|
35
|
+
* queue rows omit it and retain their original unscoped behavior. */
|
|
36
|
+
allowedActionNames?: string[];
|
|
34
37
|
/** Logical-turn id, stable across continuation chunks so durable assistant
|
|
35
38
|
* messages fold into one. */
|
|
36
39
|
turnId: string;
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
18
18
|
import { applyAgentTextEventToBuffer } from "../a2a/response-text.js";
|
|
19
19
|
import { resolveMainChatMaxOutputTokens } from "../agent/engine/output-tokens.js";
|
|
20
|
-
import { actionsToEngineTools, filterInitialEngineTools, resolveAgentRequestReasoningEffort, } from "../agent/production-agent.js";
|
|
20
|
+
import { actionsToEngineTools, filterActionsByAllowedNames, filterInitialEngineTools, readPersistedAllowedActionNames, resolveAgentRequestReasoningEffort, } from "../agent/production-agent.js";
|
|
21
21
|
import { runAgentLoop, appendAgentLoopContinuation, } from "../agent/production-agent.js";
|
|
22
22
|
import { abortRun, getActiveRunForThreadAsync, getRun, startRun, subscribeToRun, } from "../agent/run-manager.js";
|
|
23
23
|
import { getRunEventsSince } from "../agent/run-store.js";
|
|
@@ -31,7 +31,7 @@ import { describeDbError } from "../db/client.js";
|
|
|
31
31
|
import { resolveOrgIdForEmail } from "../org/context.js";
|
|
32
32
|
import { completeRun as completeProgressRun, startRun as startProgressRun, updateRunProgress, } from "../progress/registry.js";
|
|
33
33
|
import { enqueueAgentTeamRun, claimAgentTeamRun, touchAgentTeamRun, bumpAgentTeamContinuation, completeAgentTeamRun, getAgentTeamRunDispatchState, listActiveAgentTeamTaskIdsForOwner, MAX_AGENT_TEAM_CONTINUATIONS, MAX_AGENT_TEAM_NO_PROGRESS_CONTINUATIONS, RUN_DISPATCH_STUCK_AFTER_MS, RUN_PROCESSING_STUCK_AFTER_MS, } from "./agent-teams-run-queue.js";
|
|
34
|
-
import { getRequestUserEmail, runWithRequestContext, } from "./request-context.js";
|
|
34
|
+
import { getRequestOrgId, getRequestRunContext, getRequestUserEmail, hasRequestContext, runWithRequestContext, } from "./request-context.js";
|
|
35
35
|
import { fireInternalDispatch } from "./self-dispatch.js";
|
|
36
36
|
/**
|
|
37
37
|
* Ambient delegation depth for the agent whose run is currently executing.
|
|
@@ -972,12 +972,17 @@ export async function spawnTask(opts) {
|
|
|
972
972
|
// (integrations/webhook-handler.ts). Execution happens in `processAgentTeamRun`,
|
|
973
973
|
// invoked by the `/_agent-native/agent-teams/_process-run` route mounted
|
|
974
974
|
// inside the agent-chat plugin (where the action/prompt/engine closures live).
|
|
975
|
-
let orgId
|
|
976
|
-
|
|
977
|
-
orgId = (
|
|
975
|
+
let orgId;
|
|
976
|
+
if (hasRequestContext()) {
|
|
977
|
+
orgId = getRequestOrgId() ?? null;
|
|
978
978
|
}
|
|
979
|
-
|
|
980
|
-
|
|
979
|
+
else {
|
|
980
|
+
try {
|
|
981
|
+
orgId = await resolveOrgIdForEmail(opts.ownerEmail);
|
|
982
|
+
}
|
|
983
|
+
catch {
|
|
984
|
+
orgId = null;
|
|
985
|
+
}
|
|
981
986
|
}
|
|
982
987
|
const payload = {
|
|
983
988
|
description: opts.description,
|
|
@@ -986,6 +991,9 @@ export async function spawnTask(opts) {
|
|
|
986
991
|
...(opts.parentThreadId ? { parentThreadId: opts.parentThreadId } : {}),
|
|
987
992
|
...(opts.parentRunId ? { parentRunId: opts.parentRunId } : {}),
|
|
988
993
|
...(opts.name ? { name: opts.name } : {}),
|
|
994
|
+
...(getRequestRunContext()?.allowedActionNames !== undefined
|
|
995
|
+
? { allowedActionNames: Object.keys(opts.actions) }
|
|
996
|
+
: {}),
|
|
989
997
|
// Stable across continuation chunks so the durable assistant message folds.
|
|
990
998
|
turnId: runId,
|
|
991
999
|
};
|
|
@@ -1171,9 +1179,19 @@ export async function processAgentTeamRun(opts) {
|
|
|
1171
1179
|
const claimed = await claimAgentTeamRun(opts.taskId);
|
|
1172
1180
|
if (!claimed)
|
|
1173
1181
|
return { ok: true, skipped: "already-claimed-or-missing" };
|
|
1182
|
+
const persistedAllowedActionNames = readPersistedAllowedActionNames(claimed.payload);
|
|
1183
|
+
const payload = persistedAllowedActionNames === undefined
|
|
1184
|
+
? claimed.payload
|
|
1185
|
+
: {
|
|
1186
|
+
...claimed.payload,
|
|
1187
|
+
allowedActionNames: persistedAllowedActionNames,
|
|
1188
|
+
};
|
|
1174
1189
|
return await runWithRequestContext({
|
|
1175
1190
|
userEmail: claimed.ownerEmail ?? undefined,
|
|
1176
1191
|
orgId: claimed.orgId ?? undefined,
|
|
1192
|
+
run: persistedAllowedActionNames === undefined
|
|
1193
|
+
? undefined
|
|
1194
|
+
: { allowedActionNames: persistedAllowedActionNames },
|
|
1177
1195
|
}, async () => {
|
|
1178
1196
|
const task = await loadTask(opts.taskId);
|
|
1179
1197
|
if (!task) {
|
|
@@ -1184,13 +1202,18 @@ export async function processAgentTeamRun(opts) {
|
|
|
1184
1202
|
await completeAgentTeamRun(opts.taskId, task.status === "completed" ? "done" : "failed");
|
|
1185
1203
|
return { ok: true, skipped: "task-terminal" };
|
|
1186
1204
|
}
|
|
1187
|
-
const payload = claimed.payload;
|
|
1188
1205
|
const ownerEmail = claimed.ownerEmail ?? getRequestUserEmail() ?? "";
|
|
1189
1206
|
const orgId = claimed.orgId;
|
|
1190
1207
|
const turnId = payload.turnId || taskRunId(opts.taskId);
|
|
1191
1208
|
let config;
|
|
1192
1209
|
try {
|
|
1193
1210
|
config = await opts.resolveConfig({ payload, ownerEmail, orgId });
|
|
1211
|
+
if (persistedAllowedActionNames !== undefined) {
|
|
1212
|
+
config = {
|
|
1213
|
+
...config,
|
|
1214
|
+
actions: filterActionsByAllowedNames(config.actions, persistedAllowedActionNames),
|
|
1215
|
+
};
|
|
1216
|
+
}
|
|
1194
1217
|
}
|
|
1195
1218
|
catch (err) {
|
|
1196
1219
|
const message = err instanceof Error
|
|
@@ -1304,7 +1327,13 @@ export async function processAgentTeamRun(opts) {
|
|
|
1304
1327
|
task.currentStep = "";
|
|
1305
1328
|
}
|
|
1306
1329
|
};
|
|
1307
|
-
await runWithRequestContext({
|
|
1330
|
+
await runWithRequestContext({
|
|
1331
|
+
userEmail: ownerEmail || undefined,
|
|
1332
|
+
orgId: orgId ?? undefined,
|
|
1333
|
+
run: persistedAllowedActionNames === undefined
|
|
1334
|
+
? undefined
|
|
1335
|
+
: { allowedActionNames: persistedAllowedActionNames },
|
|
1336
|
+
},
|
|
1308
1337
|
// Record THIS sub-agent's own delegation depth as the ambient
|
|
1309
1338
|
// depth for the duration of its agent loop. If a tool call from
|
|
1310
1339
|
// within the loop reaches `spawnTask` (even with the team tool not
|
|
@@ -53,7 +53,6 @@ export const BUILT_IN_AUTH_MARKETING = {
|
|
|
53
53
|
"Review PR recaps with diagrams, file maps, and annotated code",
|
|
54
54
|
"Share links for async comments and product review",
|
|
55
55
|
],
|
|
56
|
-
runLocalCommand: PLAN_LOCAL_FILES_COMMAND,
|
|
57
56
|
signupLocalModeNote: {
|
|
58
57
|
text: "Prefer no account or self-hosting? Switch /visual-plan to local files only:",
|
|
59
58
|
command: PLAN_LOCAL_FILES_COMMAND,
|
|
@@ -103,7 +102,6 @@ export const BUILT_IN_AUTH_MARKETING = {
|
|
|
103
102
|
"Multi-account Gmail in a single unified inbox",
|
|
104
103
|
"Autonomous triage, archiving, and follow-ups",
|
|
105
104
|
],
|
|
106
|
-
runLocalCommand: "npx @agent-native/core@latest create my-mail-app --template mail",
|
|
107
105
|
},
|
|
108
106
|
slides: {
|
|
109
107
|
appName: "Agent-Native Slides",
|
package/dist/server/auth.d.ts
CHANGED
package/dist/server/auth.js
CHANGED
|
@@ -3309,6 +3309,24 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
3309
3309
|
}));
|
|
3310
3310
|
// Passwordless login via Better Auth's rate-limited magic-link plugin.
|
|
3311
3311
|
app.use("/_agent-native/auth/magic-link", defineEventHandler(async (event) => {
|
|
3312
|
+
if (getMethod(event) === "GET") {
|
|
3313
|
+
const query = getQuery(event);
|
|
3314
|
+
if (typeof query.token === "string") {
|
|
3315
|
+
const verificationUrl = new URL(`${getAppBasePath()}/_agent-native/auth/ba/magic-link/verify`, getOrigin(event));
|
|
3316
|
+
for (const key of [
|
|
3317
|
+
"token",
|
|
3318
|
+
"callbackURL",
|
|
3319
|
+
"newUserCallbackURL",
|
|
3320
|
+
"errorCallbackURL",
|
|
3321
|
+
]) {
|
|
3322
|
+
const value = query[key];
|
|
3323
|
+
if (typeof value === "string") {
|
|
3324
|
+
verificationUrl.searchParams.set(key, value);
|
|
3325
|
+
}
|
|
3326
|
+
}
|
|
3327
|
+
return redirectWithStagedCookies(event, verificationUrl.toString());
|
|
3328
|
+
}
|
|
3329
|
+
}
|
|
3312
3330
|
if (getMethod(event) !== "POST") {
|
|
3313
3331
|
setResponseStatus(event, 405);
|
|
3314
3332
|
return { error: "Method not allowed" };
|