@agent-native/core 0.144.2 → 0.145.0
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/app/pages/DataSources.tsx +28 -4
- package/corpus/templates/analytics/server/jobs/dashboard-report.ts +7 -3
- package/corpus/templates/analytics/server/plugins/dashboard-report-jobs.ts +13 -3
- package/corpus/templates/calendar/app/components/calendar/GoogleConnectBanner.tsx +64 -23
- package/corpus/templates/calendar/app/hooks/use-google-auth.ts +69 -46
- package/corpus/templates/calendar/app/hooks/use-view-preferences.ts +35 -6
- package/corpus/templates/calendar/app/hooks/use-zoom-auth.ts +24 -3
- package/corpus/templates/clips/app/components/player/transcript-panel.tsx +45 -6
- package/corpus/templates/clips/app/components/recorder/storage-setup-card.tsx +38 -5
- package/corpus/templates/clips/changelog/2026-08-06-desktop-full-screen-recordings-now-normalize-microphone-leve.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +146 -45
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +185 -69
- package/corpus/templates/clips/server/jobs/brain-export.ts +13 -6
- package/corpus/templates/clips/server/jobs/builder-media-compression.ts +10 -3
- package/corpus/templates/clips/server/jobs/meeting-reminders.ts +10 -3
- package/corpus/templates/clips/server/jobs/poll-calendars.ts +23 -21
- package/corpus/templates/clips/server/jobs/stale-meeting-sweeper.ts +10 -3
- package/corpus/templates/clips/server/jobs/transactional-emails.ts +10 -3
- package/corpus/templates/content/app/components/sidebar/NotionButton.tsx +1 -0
- package/corpus/templates/design/app/components/design/FusionAppBanner.tsx +15 -2
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +47 -4
- package/corpus/templates/forms/server/plugins/agent-chat.ts +1 -1
- package/corpus/templates/mail/app/components/GoogleConnectBanner.tsx +82 -39
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +31 -9
- package/corpus/templates/mail/server/plugins/mail-jobs.ts +36 -17
- package/corpus/templates/slides/server/plugins/agent-chat.ts +1 -1
- package/dist/agent/production-agent.d.ts +6 -0
- package/dist/client/AssistantChat.js +73 -43
- package/dist/client/MultiTabAssistantChat.d.ts +3 -1
- package/dist/client/MultiTabAssistantChat.js +79 -92
- package/dist/client/browser-session-bridge.js +97 -54
- package/dist/client/db-admin/useAgentSync.js +34 -43
- package/dist/client/dynamic-suggestions.d.ts +3 -0
- package/dist/client/dynamic-suggestions.js +54 -52
- package/dist/client/hooks/index.d.ts +1 -0
- package/dist/client/hooks/index.js +1 -0
- package/dist/client/i18n.d.ts +7 -0
- package/dist/client/i18n.js +12 -3
- package/dist/client/integrations/useIntegrationStatus.d.ts +1 -1
- package/dist/client/integrations/useIntegrationStatus.js +9 -22
- package/dist/client/notifications/NotificationsBell.js +14 -9
- package/dist/client/progress/RunsTray.js +6 -5
- package/dist/client/settings/useBuilderStatus.js +95 -73
- package/dist/client/transcription/BuilderTranscriptionCta.js +27 -31
- package/dist/client/use-agent-engine-configured.js +21 -3
- package/dist/client/use-pausing-interval.d.ts +6 -0
- package/dist/client/use-pausing-interval.js +6 -0
- package/dist/client/use-poll-loop.d.ts +39 -0
- package/dist/client/use-poll-loop.js +73 -0
- package/dist/client/use-run-stuck-detection.js +41 -13
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/framework-tools.d.ts +126 -0
- package/dist/framework-tools.js +114 -0
- package/dist/integrations/google-docs-poller.js +26 -7
- package/dist/integrations/pending-tasks-retry-job.js +17 -23
- package/dist/integrations/plugin.js +16 -15
- package/dist/integrations/remote-push-delivery-job.js +16 -25
- package/dist/integrations/remote-retry-job.js +19 -23
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/oauth-tokens/google-refresh.js +12 -19
- package/dist/observability/routes.d.ts +3 -3
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +9 -9
- package/dist/provider-api/actions/provider-api.d.ts +11 -11
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +3 -3
- package/dist/server/action-discovery.d.ts +27 -0
- package/dist/server/action-discovery.js +89 -0
- package/dist/server/agent-chat/action-filters-a2a.d.ts +11 -0
- package/dist/server/agent-chat/action-filters-a2a.js +17 -1
- package/dist/server/agent-chat/framework-prompts.d.ts +2 -0
- package/dist/server/agent-chat/plugin-options.d.ts +30 -0
- package/dist/server/agent-chat/prompt-resources.d.ts +4 -1
- package/dist/server/agent-chat/prompt-resources.js +8 -2
- package/dist/server/agent-chat-plugin.js +148 -100
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +1 -0
- package/dist/server/interval-job.d.ts +25 -0
- package/dist/server/interval-job.js +19 -0
- package/dist/server/prompts/framework-core-compact.d.ts +5 -0
- package/dist/server/prompts/framework-core-compact.js +28 -12
- package/dist/server/prompts/framework-core.d.ts +5 -0
- package/dist/server/prompts/framework-core.js +33 -16
- package/dist/server/prompts/index.d.ts +1 -1
- package/dist/server/prompts/index.js +1 -1
- package/dist/server/prompts/shared-rules.d.ts +12 -4
- package/dist/server/prompts/shared-rules.js +14 -4
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.js +1 -0
- package/dist/shared/poll-engine.d.ts +49 -0
- package/dist/shared/poll-engine.js +148 -0
- package/dist/templates/default/.agents/skills/internationalization/SKILL.md +5 -0
- package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +6 -3
- package/dist/templates/workspace-core/.agents/skills/internationalization/SKILL.md +5 -0
- package/dist/tracking/providers.js +10 -1
- package/docs/content/deployment.mdx +47 -13
- package/docs/content/key-concepts.mdx +13 -6
- package/package.json +2 -1
- package/src/templates/default/.agents/skills/internationalization/SKILL.md +5 -0
- package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +6 -3
- package/src/templates/workspace-core/.agents/skills/internationalization/SKILL.md +5 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type FrameworkToolGroup } from "../../framework-tools.js";
|
|
1
2
|
import type { ContextGovernanceTier, ContextManifestSourceRef, ContextSystemProvenance } from "../../shared/context-xray.js";
|
|
2
3
|
export declare const COMPACT_PROMPT_RESOURCE_MAX_CHARS = 6000;
|
|
3
4
|
export interface PromptContextProviderContext {
|
|
@@ -89,4 +90,6 @@ export declare function resourceScopeForOwner(owner: string, currentOwner?: stri
|
|
|
89
90
|
* AGENTS.md and restarting the server is all it takes; Vite HMR invalidates
|
|
90
91
|
* the bundle in dev so changes land instantly.
|
|
91
92
|
*/
|
|
92
|
-
export declare function loadResourcesForPrompt(owner: string, compact?: boolean, selfAppId?: string, orgId?: string | null
|
|
93
|
+
export declare function loadResourcesForPrompt(owner: string, compact?: boolean, selfAppId?: string, orgId?: string | null, opts?: {
|
|
94
|
+
disabledFrameworkGroups?: ReadonlySet<FrameworkToolGroup>;
|
|
95
|
+
}): Promise<string>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { frameworkGroupEnabled, } from "../../framework-tools.js";
|
|
1
2
|
import { getFrontmatterValue, getSkillNameFromPath, parseFrontmatter, } from "../../resources/metadata.js";
|
|
2
3
|
import { ensurePersonalDefaults, organizationIdFromResourceOwner, resourceGet, resourceGetByPath, resourceList, resourceListAccessible, SHARED_OWNER, sharedResourceOwner, WORKSPACE_OWNER, } from "../../resources/store.js";
|
|
3
4
|
import { discoverAgents } from "../agent-discovery.js";
|
|
@@ -600,7 +601,7 @@ async function loadResourceIndexForPrompt(owner, scope) {
|
|
|
600
601
|
* AGENTS.md and restarting the server is all it takes; Vite HMR invalidates
|
|
601
602
|
* the bundle in dev so changes land instantly.
|
|
602
603
|
*/
|
|
603
|
-
export async function loadResourcesForPrompt(owner, compact = false, selfAppId, orgId = getRequestOrgId() ?? null) {
|
|
604
|
+
export async function loadResourcesForPrompt(owner, compact = false, selfAppId, orgId = getRequestOrgId() ?? null, opts) {
|
|
604
605
|
await ensurePersonalDefaults(owner);
|
|
605
606
|
const sections = [];
|
|
606
607
|
const addSection = (content, governance = "inherited") => {
|
|
@@ -774,7 +775,12 @@ export async function loadResourcesForPrompt(owner, compact = false, selfAppId,
|
|
|
774
775
|
orgId,
|
|
775
776
|
}));
|
|
776
777
|
try {
|
|
777
|
-
|
|
778
|
+
// Both tools this block names by name come from the `workspaceApps` group.
|
|
779
|
+
// With that group off there is no `call-agent` to delegate through, so the
|
|
780
|
+
// block would only teach a capability the request cannot carry.
|
|
781
|
+
const agents = frameworkGroupEnabled(opts?.disabledFrameworkGroups, "workspaceApps")
|
|
782
|
+
? (await discoverAgents(selfAppId)).slice(0, 30)
|
|
783
|
+
: [];
|
|
778
784
|
if (agents.length > 0) {
|
|
779
785
|
const lines = agents.map((agent) => `- ${agent.name} (${agent.id}) — ${agent.description || "Connected A2A app"}`);
|
|
780
786
|
// Nothing else in the prompt or the initial tool surface tells the agent
|
|
@@ -24,6 +24,7 @@ import { adoptThreadScopeIfUnscoped, createThread, forkThread, getThread, regist
|
|
|
24
24
|
import { isCheckpointRestorePath } from "../checkpoints/route-match.js";
|
|
25
25
|
import { createDbAdminAgentTools } from "../db-admin/agent-tools.js";
|
|
26
26
|
import { isTransientDatabaseError } from "../db/client.js";
|
|
27
|
+
import { filterFrameworkToolGroups, resolveFrameworkTools, } from "../framework-tools.js";
|
|
27
28
|
import { verifyInternalToken, extractBearerToken, } from "../integrations/internal-token.js";
|
|
28
29
|
import { RECURRING_JOBS_SWEEP_PATH, RECURRING_JOBS_SWEEP_TOKEN_SUBJECT, } from "../jobs/scheduler-dispatch.js";
|
|
29
30
|
import { McpClientManager, loadMcpConfig, autoDetectMcpConfig, mcpToolsToActionEntries, syncMcpActionEntries, mountMcpServersRoutes, mountMcpHubRoutes, buildMergedConfig, startMcpConfigRefresh, getHubStatus, isHubServeEnabled, } from "../mcp-client/index.js";
|
|
@@ -41,6 +42,7 @@ import { captureError } from "./capture-error.js";
|
|
|
41
42
|
import { getH3App, markDefaultPluginProvided, trackPluginInit, } from "./framework-request-handler.js";
|
|
42
43
|
import { getOrigin } from "./google-oauth.js";
|
|
43
44
|
import { readBody } from "./h3-helpers.js";
|
|
45
|
+
import { startIntervalJob } from "./interval-job.js";
|
|
44
46
|
import { getModelFamilyOverlay } from "./prompts/index.js";
|
|
45
47
|
import { mountRealtimeVoiceRoutes } from "./realtime-voice.js";
|
|
46
48
|
import { runWithRequestContext, getRequestContext, getRequestOrgId, getRequestUserEmail, getRequestRunContext, ensureRequestRunContext, } from "./request-context.js";
|
|
@@ -276,12 +278,19 @@ export function createAgentChatPlugin(options) {
|
|
|
276
278
|
// `canToggle` means "this environment allows toggling" (static); this
|
|
277
279
|
// function means "the user currently has dev mode ON" (live).
|
|
278
280
|
const isDevMode = () => currentDevMode;
|
|
281
|
+
// Resolve the framework's own tool surface once, folding the deprecated
|
|
282
|
+
// `databaseTools` / `extensionTools` into `frameworkTools` so every
|
|
283
|
+
// consumer below reads a single shape. Conflicting old/new values throw
|
|
284
|
+
// here rather than booting with a surface nobody chose.
|
|
285
|
+
const frameworkTools = resolveFrameworkTools(options);
|
|
286
|
+
const disabledFrameworkGroups = frameworkTools.disabledGroups;
|
|
279
287
|
// Build the four assembled system prompt strings. These are static for the
|
|
280
288
|
// lifetime of this plugin instance — examples come from options once at
|
|
281
289
|
// startup, not per-request.
|
|
282
290
|
const { PROD_FRAMEWORK_PROMPT, DEV_FRAMEWORK_PROMPT, PROD_FRAMEWORK_PROMPT_COMPACT, DEV_FRAMEWORK_PROMPT_COMPACT, } = buildFrameworkPrompts(options?.promptExamples, {
|
|
283
|
-
databaseTools:
|
|
284
|
-
extensionTools:
|
|
291
|
+
databaseTools: frameworkTools.database,
|
|
292
|
+
extensionTools: frameworkTools.extensions,
|
|
293
|
+
disabledFrameworkGroups,
|
|
285
294
|
});
|
|
286
295
|
// Route readiness must not wait on settings scans, remote hub fetches, or
|
|
287
296
|
// third-party MCP handshakes. Build the action surface against an empty
|
|
@@ -396,13 +405,23 @@ export function createAgentChatPlugin(options) {
|
|
|
396
405
|
catch {
|
|
397
406
|
// Package action registration is optional.
|
|
398
407
|
}
|
|
399
|
-
// Resource, chat, docs, db, and cross-agent scripts are available in both
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
408
|
+
// Resource, chat, docs, db, and cross-agent scripts are available in both
|
|
409
|
+
// prod and dev modes, unless the app switched the group off through
|
|
410
|
+
// `frameworkTools`. Gating at construction is deliberate: an empty map
|
|
411
|
+
// flows through all thirteen registry composition sites below, whereas a
|
|
412
|
+
// condition at each spread site is the same omission waiting to happen
|
|
413
|
+
// thirteen times. Matching HTTP routes are mounted from `httpActions`,
|
|
414
|
+
// which is built from the ungated sets so the UI keeps working.
|
|
415
|
+
const resourceScripts = frameworkTools.isEnabled("resources")
|
|
416
|
+
? await createResourceScriptEntries()
|
|
417
|
+
: {};
|
|
418
|
+
const docsScripts = frameworkTools.isEnabled("docs")
|
|
419
|
+
? await createDocsScriptEntries()
|
|
420
|
+
: {};
|
|
421
|
+
const databaseToolsMode = normalizeDatabaseToolsMode(frameworkTools.database);
|
|
403
422
|
const databaseToolsEnabled = databaseToolsMode !== "off";
|
|
404
423
|
const databaseWriteToolsEnabled = databaseToolsMode === "write";
|
|
405
|
-
const extensionToolsEnabled =
|
|
424
|
+
const extensionToolsEnabled = frameworkTools.extensions;
|
|
406
425
|
const dbScripts = databaseToolsEnabled
|
|
407
426
|
? await createDbScriptEntries(databaseToolsMode, {
|
|
408
427
|
extensionTools: extensionToolsEnabled,
|
|
@@ -416,12 +435,20 @@ export function createAgentChatPlugin(options) {
|
|
|
416
435
|
const urlTools = createUrlTools();
|
|
417
436
|
const engineScripts = await createAgentEngineScriptEntries(options?.appId);
|
|
418
437
|
const loopSettingsScripts = await createAgentLoopSettingsScriptEntries();
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
438
|
+
// `httpActions` spreads engineScripts/loopSettingsScripts directly, so
|
|
439
|
+
// gating here removes them from the agent's tools without unmounting the
|
|
440
|
+
// routes the settings UI calls.
|
|
441
|
+
const chatScripts = frameworkTools.isEnabled("chat")
|
|
442
|
+
? {
|
|
443
|
+
...(await createChatScriptEntries()),
|
|
444
|
+
...engineScripts,
|
|
445
|
+
...loopSettingsScripts,
|
|
446
|
+
}
|
|
447
|
+
: {};
|
|
448
|
+
// Both `call-agent` and `describe-workspace-apps` come from this factory.
|
|
449
|
+
const callAgentScript = frameworkTools.isEnabled("workspaceApps")
|
|
450
|
+
? await createCallAgentScriptEntry(options?.appId)
|
|
451
|
+
: {};
|
|
425
452
|
let runNowSchedulerDeps = null;
|
|
426
453
|
const browserTools = createBuilderBrowserTool({
|
|
427
454
|
getOrigin: () => getRequestRunContext()?.requestOrigin ?? "http://localhost:3000",
|
|
@@ -581,7 +608,13 @@ export function createAgentChatPlugin(options) {
|
|
|
581
608
|
// surface, prompt, MCP/A2A list, and job/trigger runner below. The full
|
|
582
609
|
// `*All` sets are reserved for `httpActions`, which keeps agent-hidden
|
|
583
610
|
// actions reachable from the frontend / HTTP.
|
|
584
|
-
|
|
611
|
+
//
|
|
612
|
+
// The framework's own action kits (sharing, review, history, flags, …)
|
|
613
|
+
// arrive in this same registry through `autoDiscoverActions`, tagged with
|
|
614
|
+
// `frameworkGroup`. Subtracting disabled groups HERE is what removes them
|
|
615
|
+
// from every downstream agent surface at once; `httpActions` re-merges
|
|
616
|
+
// them ungated, so the share dialog and review threads keep their routes.
|
|
617
|
+
const templateScripts = filterFrameworkToolGroups(filterAgentTools(templateScriptsAll), disabledFrameworkGroups);
|
|
585
618
|
// Compact is the safe default for every app, including generated and
|
|
586
619
|
// third-party apps that have not curated a starter list yet. Keep the
|
|
587
620
|
// app's own action surface immediately callable; framework, provider,
|
|
@@ -591,7 +624,7 @@ export function createAgentChatPlugin(options) {
|
|
|
591
624
|
// (below, after the run-code tools are built) additionally folds in
|
|
592
625
|
// whatever `generateCorpusToolsPrompt` teaches by name for this request.
|
|
593
626
|
const templateInitialToolNames = resolveInitialToolNames(templateScripts, options?.initialToolNames);
|
|
594
|
-
const discoveredActions = filterAgentTools(discoveredActionsAll);
|
|
627
|
+
const discoveredActions = filterFrameworkToolGroups(filterAgentTools(discoveredActionsAll), disabledFrameworkGroups);
|
|
595
628
|
// Per-request owner is read from the AsyncLocalStorage run context
|
|
596
629
|
// (populated by prepareRun). Module-scope `let` would race across
|
|
597
630
|
// concurrent requests on a long-lived Node process — overlapping
|
|
@@ -627,22 +660,29 @@ export function createAgentChatPlugin(options) {
|
|
|
627
660
|
// Automation tools + fetch tool — depend on owner via callback.
|
|
628
661
|
// Each callback short-circuits with a clear error when the run context
|
|
629
662
|
// has no authenticated owner (see SECURITY note on getCurrentRunOwner).
|
|
663
|
+
const automationGroupEnabled = frameworkTools.isEnabled("automation");
|
|
630
664
|
let automationTools = {};
|
|
631
665
|
try {
|
|
632
|
-
|
|
633
|
-
|
|
666
|
+
if (automationGroupEnabled) {
|
|
667
|
+
const { createAutomationToolEntries } = await import("../triggers/actions.js");
|
|
668
|
+
automationTools = createAutomationToolEntries(() => requireCurrentRunOwner("manage automations"));
|
|
669
|
+
}
|
|
634
670
|
}
|
|
635
671
|
catch { }
|
|
636
672
|
let notificationTools = {};
|
|
637
673
|
try {
|
|
638
|
-
|
|
639
|
-
|
|
674
|
+
if (automationGroupEnabled) {
|
|
675
|
+
const { createNotificationToolEntries } = await import("../notifications/actions.js");
|
|
676
|
+
notificationTools = createNotificationToolEntries(() => requireCurrentRunOwner("manage notifications"));
|
|
677
|
+
}
|
|
640
678
|
}
|
|
641
679
|
catch { }
|
|
642
680
|
let progressTools = {};
|
|
643
681
|
try {
|
|
644
|
-
|
|
645
|
-
|
|
682
|
+
if (automationGroupEnabled) {
|
|
683
|
+
const { createProgressToolEntries } = await import("../progress/actions.js");
|
|
684
|
+
progressTools = createProgressToolEntries(() => requireCurrentRunOwner("manage progress"));
|
|
685
|
+
}
|
|
646
686
|
}
|
|
647
687
|
catch { }
|
|
648
688
|
let githubRepoTools = {};
|
|
@@ -660,48 +700,53 @@ export function createAgentChatPlugin(options) {
|
|
|
660
700
|
});
|
|
661
701
|
}
|
|
662
702
|
catch { }
|
|
703
|
+
const webGroupEnabled = frameworkTools.isEnabled("web");
|
|
663
704
|
let fetchTool = {};
|
|
664
705
|
try {
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
const
|
|
685
|
-
|
|
686
|
-
|
|
706
|
+
if (webGroupEnabled) {
|
|
707
|
+
const { createFetchToolEntry } = await import("../extensions/fetch-tool.js");
|
|
708
|
+
// Resolve `${keys.NAME}` through the same request-scope cascade
|
|
709
|
+
// already used by extension fetches (extensions/routes.ts) and
|
|
710
|
+
// automation connector headers (automation/index.ts): user scope
|
|
711
|
+
// first (personal overrides win), then the active org scope (the
|
|
712
|
+
// Dispatch vault syncs workspace secrets here), then workspace
|
|
713
|
+
// scope. Org/workspace vault rows are write-gated (org-admin +
|
|
714
|
+
// Dispatch vault UI), so this is safe to read by default — unlike
|
|
715
|
+
// the opt-in-only user→workspace fallback in resolveKeyReferences
|
|
716
|
+
// (see audit 05 H2 in secrets/substitution.ts), which stays off.
|
|
717
|
+
// Previously this tool only looked at scope "user", so a
|
|
718
|
+
// ${keys.NAME} reference to a key synced into the org/workspace
|
|
719
|
+
// vault could never resolve here even though the same key already
|
|
720
|
+
// worked for extension fetches and automations.
|
|
721
|
+
const { resolveKeyReferencesWithRequestScopes, validateUrlAllowlist, getKeyAllowlist, getResolvedKeyAllowlist, } = await import("../secrets/substitution.js");
|
|
722
|
+
fetchTool = createFetchToolEntry({
|
|
723
|
+
resolveKeys: async (text) => resolveKeyReferencesWithRequestScopes(text, requireCurrentRunOwner("resolve key references")),
|
|
724
|
+
validateUrl: async (url, usedKeys, resolvedKeys) => {
|
|
725
|
+
for (const keyName of usedKeys) {
|
|
726
|
+
const allowlist = await resolveFetchToolKeyAllowlist(keyName, resolvedKeys, requireCurrentRunOwner("validate URL allowlist"), { getKeyAllowlist, getResolvedKeyAllowlist });
|
|
727
|
+
if (allowlist && !validateUrlAllowlist(url, allowlist)) {
|
|
728
|
+
return false;
|
|
729
|
+
}
|
|
687
730
|
}
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
}
|
|
691
|
-
}
|
|
731
|
+
return true;
|
|
732
|
+
},
|
|
733
|
+
});
|
|
734
|
+
}
|
|
692
735
|
}
|
|
693
736
|
catch { }
|
|
694
737
|
let webSearchTool = {};
|
|
695
738
|
try {
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
739
|
+
if (webGroupEnabled) {
|
|
740
|
+
const { createWebSearchToolEntry } = await import("../extensions/web-search-tool.js");
|
|
741
|
+
const { getBuilderWebSearchBaseUrl, resolveBuilderCredentials, resolveSecret, } = await import("./credential-provider.js");
|
|
742
|
+
const { getBuilderGatewayRequestHeaders } = await import("../agent/engine/builder-gateway-headers.js");
|
|
743
|
+
webSearchTool = createWebSearchToolEntry({
|
|
744
|
+
resolveSecret,
|
|
745
|
+
resolveBuilderCredentials,
|
|
746
|
+
getBuilderWebSearchBaseUrl,
|
|
747
|
+
getBuilderRequestHeaders: getBuilderGatewayRequestHeaders,
|
|
748
|
+
});
|
|
749
|
+
}
|
|
705
750
|
}
|
|
706
751
|
catch { }
|
|
707
752
|
let workspaceFilesTool = {};
|
|
@@ -751,11 +796,13 @@ export function createAgentChatPlugin(options) {
|
|
|
751
796
|
let coreEmailTools = {};
|
|
752
797
|
let backgroundCoreEmailTools = {};
|
|
753
798
|
try {
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
799
|
+
if (frameworkTools.isEnabled("email")) {
|
|
800
|
+
const { createCoreEmailActionEntries } = await import("./email-actions.js");
|
|
801
|
+
coreEmailTools = createCoreEmailActionEntries();
|
|
802
|
+
backgroundCoreEmailTools = createCoreEmailActionEntries({
|
|
803
|
+
unattended: true,
|
|
804
|
+
});
|
|
805
|
+
}
|
|
759
806
|
}
|
|
760
807
|
catch { }
|
|
761
808
|
// Core read-attachment tool — always registered so the agent can page
|
|
@@ -1232,7 +1279,7 @@ export function createAgentChatPlugin(options) {
|
|
|
1232
1279
|
const devActive = isDevMode();
|
|
1233
1280
|
// Build the same system prompt the interactive agent uses
|
|
1234
1281
|
const owner = userEmail;
|
|
1235
|
-
const resources = await loadResourcesForPrompt(owner, lazyContext, options?.appId);
|
|
1282
|
+
const resources = await loadResourcesForPrompt(owner, lazyContext, options?.appId, undefined, { disabledFrameworkGroups });
|
|
1236
1283
|
const schemaBlock = lazyContext
|
|
1237
1284
|
? ""
|
|
1238
1285
|
: await buildSchemaBlock(owner, databaseToolsMode);
|
|
@@ -1700,7 +1747,7 @@ export function createAgentChatPlugin(options) {
|
|
|
1700
1747
|
// catalog on its very first request, undermining the compact MCP
|
|
1701
1748
|
// catalog this surface is supposed to keep external callers on.
|
|
1702
1749
|
const mcpToolSurface = createA2AEngineToolSurface(actionsToEngineTools(mcpActions), effectiveInitialToolNames);
|
|
1703
|
-
const resources = await loadResourcesForPrompt(SHARED_OWNER, lazyContext, options?.appId);
|
|
1750
|
+
const resources = await loadResourcesForPrompt(SHARED_OWNER, lazyContext, options?.appId, undefined, { disabledFrameworkGroups });
|
|
1704
1751
|
const schemaBlock = lazyContext
|
|
1705
1752
|
? ""
|
|
1706
1753
|
: await buildSchemaBlock(SHARED_OWNER, databaseToolsMode);
|
|
@@ -2155,8 +2202,10 @@ export function createAgentChatPlugin(options) {
|
|
|
2155
2202
|
// Job management tool (manage-jobs)
|
|
2156
2203
|
let jobTools = {};
|
|
2157
2204
|
try {
|
|
2158
|
-
|
|
2159
|
-
|
|
2205
|
+
if (automationGroupEnabled) {
|
|
2206
|
+
const { createJobTools } = await import("../jobs/tools.js");
|
|
2207
|
+
jobTools = createJobTools();
|
|
2208
|
+
}
|
|
2160
2209
|
}
|
|
2161
2210
|
catch { }
|
|
2162
2211
|
// Lean mode: only template actions + essential framework tools. Drop
|
|
@@ -2486,7 +2535,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
2486
2535
|
modelOverlay +
|
|
2487
2536
|
runtimeContext);
|
|
2488
2537
|
}
|
|
2489
|
-
const resources = await loadResourcesForPrompt(owner, lazyContext, options?.appId);
|
|
2538
|
+
const resources = await loadResourcesForPrompt(owner, lazyContext, options?.appId, undefined, { disabledFrameworkGroups });
|
|
2490
2539
|
// In lazy context mode, skip embedding the full schema. When database
|
|
2491
2540
|
// tools are enabled the agent can call `db-schema` on demand.
|
|
2492
2541
|
const schemaBlock = lazyContext
|
|
@@ -2719,7 +2768,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
2719
2768
|
});
|
|
2720
2769
|
return setSystemPromptOnContext(leanBasePrompt + extra + modelOverlay + runtimeContext);
|
|
2721
2770
|
}
|
|
2722
|
-
const resources = await loadResourcesForPrompt(owner, lazyContext, options?.appId);
|
|
2771
|
+
const resources = await loadResourcesForPrompt(owner, lazyContext, options?.appId, undefined, { disabledFrameworkGroups });
|
|
2723
2772
|
const schemaBlock = lazyContext || !databaseToolsEnabled
|
|
2724
2773
|
? ""
|
|
2725
2774
|
: await buildSchemaBlock(owner, databaseToolsMode);
|
|
@@ -4695,7 +4744,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
4695
4744
|
const schedulerDeps = {
|
|
4696
4745
|
getActions: getBackgroundActionEntries,
|
|
4697
4746
|
getSystemPrompt: async (owner) => {
|
|
4698
|
-
const resources = await loadResourcesForPrompt(owner, lazyContext, options?.appId);
|
|
4747
|
+
const resources = await loadResourcesForPrompt(owner, lazyContext, options?.appId, undefined, { disabledFrameworkGroups });
|
|
4699
4748
|
const schemaBlock = lazyContext
|
|
4700
4749
|
? ""
|
|
4701
4750
|
: await buildSchemaBlock(owner, databaseToolsMode);
|
|
@@ -4711,8 +4760,11 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
4711
4760
|
// fetchTool/webSearchTool/toolActions catalog every tick.
|
|
4712
4761
|
getInitialToolNames: (job) => [
|
|
4713
4762
|
...effectiveInitialToolNames,
|
|
4714
|
-
|
|
4715
|
-
|
|
4763
|
+
// Only promotable while the group that supplies them is on; with
|
|
4764
|
+
// `automation` off the prompt no longer names them either.
|
|
4765
|
+
...(automationGroupEnabled
|
|
4766
|
+
? ["manage-jobs", "manage-progress"]
|
|
4767
|
+
: []),
|
|
4716
4768
|
...(job?.meta.mcpTools ?? []),
|
|
4717
4769
|
],
|
|
4718
4770
|
apiKey: options?.apiKey,
|
|
@@ -4966,35 +5018,31 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
4966
5018
|
setTimeout(() => {
|
|
4967
5019
|
(async () => {
|
|
4968
5020
|
const { UNCLAIMED_BACKGROUND_RUN_FAST_SWEEP_MS } = await import("../agent/run-store.js");
|
|
4969
|
-
|
|
4970
|
-
|
|
4971
|
-
|
|
4972
|
-
|
|
4973
|
-
|
|
4974
|
-
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
|
|
4982
|
-
|
|
4983
|
-
|
|
4984
|
-
|
|
4985
|
-
|
|
4986
|
-
|
|
4987
|
-
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
|
|
4991
|
-
|
|
4992
|
-
|
|
4993
|
-
|
|
4994
|
-
})().catch(() => {
|
|
4995
|
-
// best-effort — never break the server
|
|
4996
|
-
});
|
|
4997
|
-
}, UNCLAIMED_BACKGROUND_RUN_FAST_SWEEP_MS);
|
|
5021
|
+
startIntervalJob(async () => {
|
|
5022
|
+
const { listUnclaimedBackgroundRunRows, shouldRedispatchUnclaimedBackgroundRun, reapAllStaleRuns, } = await import("../agent/run-store.js");
|
|
5023
|
+
// The unclaimed-background sweep below only matches
|
|
5024
|
+
// dispatch_mode='background' — handoffs a worker never
|
|
5025
|
+
// claimed. Once a worker CLAIMS a row nothing periodic looked
|
|
5026
|
+
// at it again, so a dead producer was only reaped when some
|
|
5027
|
+
// client request path or an unrelated run's cleanup happened
|
|
5028
|
+
// to notice (prod: 24 minutes after the last heartbeat,
|
|
5029
|
+
// against a 45s window). `reapAllStaleRuns` is per-row,
|
|
5030
|
+
// idempotent, re-checks staleness at UPDATE time and honours
|
|
5031
|
+
// the in-flight grace, so it is safe on this cadence.
|
|
5032
|
+
await reapAllStaleRuns().catch(() => { });
|
|
5033
|
+
let rows;
|
|
5034
|
+
try {
|
|
5035
|
+
rows = await listUnclaimedBackgroundRunRows();
|
|
5036
|
+
}
|
|
5037
|
+
catch {
|
|
5038
|
+
return; // Table may not exist yet on first boot
|
|
5039
|
+
}
|
|
5040
|
+
for (const row of rows) {
|
|
5041
|
+
if (!shouldRedispatchUnclaimedBackgroundRun(row))
|
|
5042
|
+
continue;
|
|
5043
|
+
await attemptUnclaimedBackgroundRunRedispatch(row).catch(() => { });
|
|
5044
|
+
}
|
|
5045
|
+
}, { intervalMs: UNCLAIMED_BACKGROUND_RUN_FAST_SWEEP_MS });
|
|
4998
5046
|
})().catch(() => {
|
|
4999
5047
|
// best-effort — if run-store fails to load, the slow sweep below
|
|
5000
5048
|
// still provides eventual (loud) recovery.
|
|
@@ -5076,7 +5124,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
5076
5124
|
await initTriggerDispatcher({
|
|
5077
5125
|
getActions: getBackgroundActionEntries,
|
|
5078
5126
|
getSystemPrompt: async (owner) => {
|
|
5079
|
-
const resources = await loadResourcesForPrompt(owner, lazyContext, options?.appId);
|
|
5127
|
+
const resources = await loadResourcesForPrompt(owner, lazyContext, options?.appId, undefined, { disabledFrameworkGroups });
|
|
5080
5128
|
const schemaBlock = lazyContext
|
|
5081
5129
|
? ""
|
|
5082
5130
|
: await buildSchemaBlock(owner, databaseToolsMode);
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { createServer, type CreateServerOptions, type EnvKeyConfig, } from "./create-server.js";
|
|
2
|
+
export { startIntervalJob, type IntervalJobOptions, type IntervalJobHandle, } from "./interval-job.js";
|
|
2
3
|
export { AGENT_BACKGROUND_PROCESSOR_FIELD, AGENT_BACKGROUND_PROCESSOR_ROUTE, AGENT_BACKGROUND_PROCESSOR_ROUTE_FIELD, dispatchPathTargetsNetlifyBackgroundFunction, isInBackgroundFunctionRuntime, resolveDurableBackgroundDispatchPath, } from "../agent/durable-background.js";
|
|
3
4
|
export { readBody, readBodyWithSizeLimit, streamFile, DEFAULT_CHAT_MAX_BODY_BYTES, DEFAULT_UPLOAD_MAX_FILE_BYTES, MAX_CHAT_ATTACHMENTS_PER_MESSAGE, isAllowedUploadMimeType, } from "./h3-helpers.js";
|
|
4
5
|
export { buildDeepLink, toAbsoluteOpenUrl, toDesktopOpenUrl, toVsCodeOpenUrl, OPEN_ROUTE_SUBPATH, DESKTOP_OPEN_URL, VSCODE_OPEN_URL, type DeepLinkInput, } from "./deep-link.js";
|
package/dist/server/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { createServer, } from "./create-server.js";
|
|
2
|
+
export { startIntervalJob, } from "./interval-job.js";
|
|
2
3
|
export { AGENT_BACKGROUND_PROCESSOR_FIELD, AGENT_BACKGROUND_PROCESSOR_ROUTE, AGENT_BACKGROUND_PROCESSOR_ROUTE_FIELD, dispatchPathTargetsNetlifyBackgroundFunction, isInBackgroundFunctionRuntime, resolveDurableBackgroundDispatchPath, } from "../agent/durable-background.js";
|
|
3
4
|
export { readBody, readBodyWithSizeLimit, streamFile, DEFAULT_CHAT_MAX_BODY_BYTES, DEFAULT_UPLOAD_MAX_FILE_BYTES, MAX_CHAT_ATTACHMENTS_PER_MESSAGE, isAllowedUploadMimeType, } from "./h3-helpers.js";
|
|
4
5
|
export { buildDeepLink, toAbsoluteOpenUrl, toDesktopOpenUrl, toVsCodeOpenUrl, OPEN_ROUTE_SUBPATH, DESKTOP_OPEN_URL, VSCODE_OPEN_URL, } from "./deep-link.js";
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface IntervalJobOptions {
|
|
2
|
+
/** Delay in ms between runs. */
|
|
3
|
+
intervalMs: number;
|
|
4
|
+
/** Per-run timeout. Default: `Math.max(timeoutFloorMs, intervalMs * 4)`. */
|
|
5
|
+
timeoutMs?: number;
|
|
6
|
+
/** Floor used by the default `timeoutMs`. Default: 10_000. */
|
|
7
|
+
timeoutFloorMs?: number;
|
|
8
|
+
/** Called when a run throws or times out. Default: swallow (a background job shouldn't crash the host process). */
|
|
9
|
+
onError?: (err: unknown) => void;
|
|
10
|
+
/** Run immediately on start. Default: true. */
|
|
11
|
+
leading?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface IntervalJobHandle {
|
|
14
|
+
stop(): void;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Run a background job on a recurring interval without hand-rolling a
|
|
18
|
+
* `running` overlap guard or a request timeout — see `createPollEngine` for
|
|
19
|
+
* the underlying guarantees. `runOnce` keeps its normal exported signature
|
|
20
|
+
* (serverless schedulers can still call it directly, bypassing the loop);
|
|
21
|
+
* this only replaces the `setInterval` + module-level flag wiring around it.
|
|
22
|
+
* The internal timer is `.unref()`'d so it never keeps the process alive on
|
|
23
|
+
* its own.
|
|
24
|
+
*/
|
|
25
|
+
export declare function startIntervalJob(runOnce: (signal: AbortSignal) => Promise<void>, options: IntervalJobOptions): IntervalJobHandle;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { createPollEngine } from "../shared/poll-engine.js";
|
|
2
|
+
/**
|
|
3
|
+
* Run a background job on a recurring interval without hand-rolling a
|
|
4
|
+
* `running` overlap guard or a request timeout — see `createPollEngine` for
|
|
5
|
+
* the underlying guarantees. `runOnce` keeps its normal exported signature
|
|
6
|
+
* (serverless schedulers can still call it directly, bypassing the loop);
|
|
7
|
+
* this only replaces the `setInterval` + module-level flag wiring around it.
|
|
8
|
+
* The internal timer is `.unref()`'d so it never keeps the process alive on
|
|
9
|
+
* its own.
|
|
10
|
+
*/
|
|
11
|
+
export function startIntervalJob(runOnce, options) {
|
|
12
|
+
const engine = createPollEngine(runOnce, options);
|
|
13
|
+
engine.start();
|
|
14
|
+
return {
|
|
15
|
+
stop() {
|
|
16
|
+
engine.stop();
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
}
|
|
@@ -8,11 +8,16 @@
|
|
|
8
8
|
* - Detailed "Parallel Tool Calls" prose (replaced with one-liner)
|
|
9
9
|
* - Detailed "Resources" section (agent uses resources tool)
|
|
10
10
|
*/
|
|
11
|
+
import { type FrameworkToolGroup } from "../../framework-tools.js";
|
|
11
12
|
import { type DatabaseToolsOption } from "../../scripts/db/tool-mode.js";
|
|
12
13
|
import { type PromptExamples } from "./shared-rules.js";
|
|
13
14
|
export interface FrameworkCoreCompactPromptOptions {
|
|
14
15
|
databaseTools?: DatabaseToolsOption;
|
|
15
16
|
extensionTools?: boolean;
|
|
17
|
+
/** Framework tool groups this app switched off. Every block below that names
|
|
18
|
+
* a group's tool by name is gated on this — a prompt naming an absent tool
|
|
19
|
+
* makes the model call it, fail, and often report the capability as missing. */
|
|
20
|
+
disabledFrameworkGroups?: ReadonlySet<FrameworkToolGroup>;
|
|
16
21
|
}
|
|
17
22
|
/**
|
|
18
23
|
* Build the compact FRAMEWORK_CORE prompt string.
|
|
@@ -8,14 +8,37 @@
|
|
|
8
8
|
* - Detailed "Parallel Tool Calls" prose (replaced with one-liner)
|
|
9
9
|
* - Detailed "Resources" section (agent uses resources tool)
|
|
10
10
|
*/
|
|
11
|
+
import { frameworkGroupEnabled, } from "../../framework-tools.js";
|
|
11
12
|
import { hasDatabaseReadTools, hasDatabaseWriteTools, } from "../../scripts/db/tool-mode.js";
|
|
12
|
-
import { sharedRule8, SHARED_RULE_9,
|
|
13
|
+
import { sharedRule8, SHARED_RULE_9, sharedRule14, SHARED_RULE_15, SHARED_RULE_AGENT_WARNINGS, } from "./shared-rules.js";
|
|
13
14
|
/**
|
|
14
15
|
* Build the compact FRAMEWORK_CORE prompt string.
|
|
15
16
|
*
|
|
16
17
|
* @param examples Optional injectable provider/action examples for rule 8.
|
|
17
18
|
*/
|
|
18
19
|
export function buildFrameworkCoreCompact(examples, options) {
|
|
20
|
+
const groupOn = (group) => frameworkGroupEnabled(options?.disabledFrameworkGroups, group);
|
|
21
|
+
const resourcesSection = groupOn("resources")
|
|
22
|
+
? `### Resources
|
|
23
|
+
|
|
24
|
+
Use the \`resources\` tool for persistent notes and context files: \`action: "list"\`, \`"read"\`, \`"effective"\`, \`"write"\`, \`"promote"\`, or \`"delete"\`.
|
|
25
|
+
Resources have three levels: workspace defaults inherited from Dispatch, shared organization/app overrides, and personal overrides. Use \`resources\` with \`action: "effective"\` before editing when you need to explain or inspect which level is active for a path.
|
|
26
|
+
Workspace resources are user-facing by default. If you need temporary working files, write them as agent scratch (\`visibility: "agent_scratch"\`); scratch is hidden from the Workspace view by default and expires. Use \`visibility: "workspace"\` only when the user explicitly asked to save/manage that file, or for durable AGENTS.md, LEARNINGS.md, memory, skills, jobs, or custom agents.
|
|
27
|
+
`
|
|
28
|
+
: "";
|
|
29
|
+
const extendedCapabilityClauses = [
|
|
30
|
+
"inline embeds",
|
|
31
|
+
groupOn("chat") ? "chat history search (`chat-history`)" : "",
|
|
32
|
+
groupOn("automation") ? "recurring jobs (`manage-jobs`)" : "",
|
|
33
|
+
"structured memory (`save-memory`/`delete-memory`)",
|
|
34
|
+
"browser automation (`activate-browser` in production, `set-browser-control` locally)",
|
|
35
|
+
].filter(Boolean);
|
|
36
|
+
const extendedCapabilitiesList = `${extendedCapabilityClauses.slice(0, -1).join(", ")}, and ${extendedCapabilityClauses.at(-1)}`;
|
|
37
|
+
const callAgentSection = groupOn("workspaceApps")
|
|
38
|
+
? `
|
|
39
|
+
For generated media, prefer this app's native generation action; otherwise use \`call-agent\` with agent "assets".
|
|
40
|
+
`
|
|
41
|
+
: "";
|
|
19
42
|
const hasDatabaseTools = hasDatabaseReadTools(options?.databaseTools);
|
|
20
43
|
const hasDatabaseWrites = hasDatabaseWriteTools(options?.databaseTools);
|
|
21
44
|
const dataRule = hasDatabaseWrites
|
|
@@ -56,22 +79,15 @@ ${SHARED_RULE_9}
|
|
|
56
79
|
**Native widgets** — For table/chart/graph/report requests, prefer actions labeled \`Native chat widget\`; use \`render-data-widget\` for already-summarized data (≤50 rows) instead of markdown tables. Above that, give the total plus the top rows — never retype a full result set as widget arguments. Deliver files in chat, never just a path.
|
|
57
80
|
10. **Your tool list is not the whole surface** — Most app actions and connected MCP tools load on demand, so search the live registry with \`tool-search\` before concluding a capability doesn't exist.
|
|
58
81
|
11. **Relative dates use runtime context** — The \`<runtime-context>\` block gives the authoritative current date/time. Resolve "today", "yesterday", "last week", and similar phrases to explicit calendar dates before querying data or creating artifacts.
|
|
59
|
-
${
|
|
82
|
+
${sharedRule14(options)}
|
|
60
83
|
${SHARED_RULE_15}
|
|
61
84
|
${SHARED_RULE_AGENT_WARNINGS}
|
|
62
85
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
Use the \`resources\` tool for persistent notes and context files: \`action: "list"\`, \`"read"\`, \`"effective"\`, \`"write"\`, \`"promote"\`, or \`"delete"\`.
|
|
66
|
-
Resources have three levels: workspace defaults inherited from Dispatch, shared organization/app overrides, and personal overrides. Use \`resources\` with \`action: "effective"\` before editing when you need to explain or inspect which level is active for a path.
|
|
67
|
-
Workspace resources are user-facing by default. If you need temporary working files, write them as agent scratch (\`visibility: "agent_scratch"\`); scratch is hidden from the Workspace view by default and expires. Use \`visibility: "workspace"\` only when the user explicitly asked to save/manage that file, or for durable AGENTS.md, LEARNINGS.md, memory, skills, jobs, or custom agents.
|
|
68
|
-
|
|
86
|
+
${resourcesSection}
|
|
69
87
|
### Extended Capabilities
|
|
70
88
|
|
|
71
|
-
You also have tools for
|
|
89
|
+
You also have tools for ${extendedCapabilitiesList}. Call \`get-framework-context\` with the matching key — it lists its own topics — for full instructions when needed.
|
|
72
90
|
|
|
73
91
|
**Agent teams:** default to doing the work yourself. Delegate ONE sub-agent (\`agent-teams\` action "spawn") for self-contained heavy work; fan out to several only for genuinely independent units; never parallelize tightly-coupled work; cap fan-out around 3. Treat "background agent", "sub-agent", "parallel", "batch", "kick off", "run the rest", and "queued items" as delegation intent when the user is asking you to start or continue independent work items. After \`spawn\`, say the task started/running, not completed; use \`status\`/\`read-result\` before claiming the delegated work is done. Give each sub-agent a self-contained brief (objective, the specific context/IDs it needs, output format, boundaries) — it can't see this thread — then read all results and synthesize one integrated answer. Full details: \`get-framework-context\` key \`agent-teams\`.
|
|
74
|
-
|
|
75
|
-
For generated media, prefer this app's native generation action; otherwise use \`call-agent\` with agent "assets".
|
|
76
|
-
`;
|
|
92
|
+
${callAgentSection}`;
|
|
77
93
|
}
|
|
@@ -5,11 +5,16 @@
|
|
|
5
5
|
* Shared rules (8-9, 12-13) are imported from shared-rules.ts so the
|
|
6
6
|
* compact variant uses the same text and the two can never drift.
|
|
7
7
|
*/
|
|
8
|
+
import { type FrameworkToolGroup } from "../../framework-tools.js";
|
|
8
9
|
import { type DatabaseToolsOption } from "../../scripts/db/tool-mode.js";
|
|
9
10
|
import { type PromptExamples } from "./shared-rules.js";
|
|
10
11
|
export interface FrameworkCorePromptOptions {
|
|
11
12
|
databaseTools?: DatabaseToolsOption;
|
|
12
13
|
extensionTools?: boolean;
|
|
14
|
+
/** Framework tool groups this app switched off. Every block below that names
|
|
15
|
+
* a group's tool by name is gated on this — a prompt naming an absent tool
|
|
16
|
+
* makes the model call it, fail, and often report the capability as missing. */
|
|
17
|
+
disabledFrameworkGroups?: ReadonlySet<FrameworkToolGroup>;
|
|
13
18
|
}
|
|
14
19
|
/**
|
|
15
20
|
* Build the full FRAMEWORK_CORE prompt string.
|