@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
|
@@ -5,8 +5,9 @@
|
|
|
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 { frameworkGroupEnabled, } from "../../framework-tools.js";
|
|
8
9
|
import { hasDatabaseReadTools, hasDatabaseWriteTools, } from "../../scripts/db/tool-mode.js";
|
|
9
|
-
import { sharedRule8, SHARED_RULE_9,
|
|
10
|
+
import { sharedRule8, SHARED_RULE_9, sharedRule14, SHARED_RULE_15, SHARED_RULE_AGENT_WARNINGS, } from "./shared-rules.js";
|
|
10
11
|
/**
|
|
11
12
|
* Build the full FRAMEWORK_CORE prompt string.
|
|
12
13
|
*
|
|
@@ -40,6 +41,33 @@ export function buildFrameworkCore(examples, options) {
|
|
|
40
41
|
const actionSurface = options?.extensionTools === true
|
|
41
42
|
? "this app's registered actions, extensions, and connected MCP tools"
|
|
42
43
|
: "this app's registered actions and connected MCP tools";
|
|
44
|
+
const groupOn = (group) => frameworkGroupEnabled(options?.disabledFrameworkGroups, group);
|
|
45
|
+
const resourcesSection = groupOn("resources")
|
|
46
|
+
? `### Resources
|
|
47
|
+
|
|
48
|
+
You have access to a Resources system for persistent notes and context files.
|
|
49
|
+
Use the \`resources\` tool to manage resources: \`action: "list"\`, \`"read"\`, \`"effective"\`, \`"write"\`, \`"promote"\`, or \`"delete"\`.
|
|
50
|
+
Resources can be workspace defaults inherited from Dispatch, shared organization/app overrides, or personal overrides. By default, resources are personal. Workspace-scope resources are read-only from app agents; create shared or personal resources to override or narrow them.
|
|
51
|
+
|
|
52
|
+
When the user gives instructions that should apply to all users/sessions, update the shared "AGENTS.md" resource.
|
|
53
|
+
|
|
54
|
+
Workspace resources are user-facing by default. If you need temporary working files, use the \`resources\` tool with \`visibility: "agent_scratch"\`; scratch resources are hidden from the Workspace view by default and expire automatically. Use \`visibility: "workspace"\` only when the user explicitly asked to save/create/manage that file, or for durable control files such as \`AGENTS.md\`, \`LEARNINGS.md\`, \`memory/\`, \`skills/\`, \`jobs/\`, or \`agents/\`. If a scratch result becomes useful to the user, call \`resources\` with \`action: "promote"\` or rewrite it with \`visibility: "workspace"\`.
|
|
55
|
+
`
|
|
56
|
+
: "";
|
|
57
|
+
const extendedCapabilityClauses = [
|
|
58
|
+
"inline embeds (`embed` fenced code block)",
|
|
59
|
+
groupOn("chat") ? "chat history search (`chat-history`)" : "",
|
|
60
|
+
groupOn("automation") ? "recurring jobs (`manage-jobs`)" : "",
|
|
61
|
+
"connecting Builder.io (`connect-builder`)",
|
|
62
|
+
"browser automation (`set-browser-control`/`activate-browser`)",
|
|
63
|
+
"structured memory (`save-memory`/`delete-memory`)",
|
|
64
|
+
].filter(Boolean);
|
|
65
|
+
const extendedCapabilitiesList = `${extendedCapabilityClauses.slice(0, -1).join(", ")}, and ${extendedCapabilityClauses.at(-1)}`;
|
|
66
|
+
const callAgentSection = groupOn("workspaceApps")
|
|
67
|
+
? `
|
|
68
|
+
**call-agent** messages a DIFFERENT deployed app's agent over A2A — never use it for your own actions or to call yourself. For brand-consistent generated media when this app has no native generation action, call agent "assets".
|
|
69
|
+
`
|
|
70
|
+
: "";
|
|
43
71
|
return `
|
|
44
72
|
### How You Work
|
|
45
73
|
|
|
@@ -78,7 +106,7 @@ ${SHARED_RULE_9}
|
|
|
78
106
|
**Downloadable files** — When the user asks you to create or export a file, deliver it in the same chat turn. For compact tabular results, prefer \`render-data-widget\` so the user gets the native Download CSV action without a second stored copy. For a complete or durable file written through \`workspaceWrite\`, use a normal non-\`scratch/\` path and then call \`show-workspace-file\` with that path so chat renders a direct download card. Never finish by giving filesystem paths or telling the user to navigate elsewhere to find the file.
|
|
79
107
|
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.
|
|
80
108
|
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. When answering factual questions, include the exact date or date range you used.
|
|
81
|
-
${
|
|
109
|
+
${sharedRule14(options)}
|
|
82
110
|
${SHARED_RULE_15}
|
|
83
111
|
${SHARED_RULE_AGENT_WARNINGS}
|
|
84
112
|
|
|
@@ -86,22 +114,11 @@ ${SHARED_RULE_AGENT_WARNINGS}
|
|
|
86
114
|
|
|
87
115
|
Gather context efficiently: when you need several independent read-only lookups (reading state, querying different tables, searching, fetching unrelated records), issue those tool calls together in one batch rather than one at a time. Keep mutating actions ordered and sequential — anything that creates, updates, deletes, sends, or publishes runs one at a time so each can be confirmed before the next, and so writes that depend on each other stay consistent.
|
|
88
116
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
You have access to a Resources system for persistent notes and context files.
|
|
92
|
-
Use the \`resources\` tool to manage resources: \`action: "list"\`, \`"read"\`, \`"effective"\`, \`"write"\`, \`"promote"\`, or \`"delete"\`.
|
|
93
|
-
Resources can be workspace defaults inherited from Dispatch, shared organization/app overrides, or personal overrides. By default, resources are personal. Workspace-scope resources are read-only from app agents; create shared or personal resources to override or narrow them.
|
|
94
|
-
|
|
95
|
-
When the user gives instructions that should apply to all users/sessions, update the shared "AGENTS.md" resource.
|
|
96
|
-
|
|
97
|
-
Workspace resources are user-facing by default. If you need temporary working files, use the \`resources\` tool with \`visibility: "agent_scratch"\`; scratch resources are hidden from the Workspace view by default and expire automatically. Use \`visibility: "workspace"\` only when the user explicitly asked to save/create/manage that file, or for durable control files such as \`AGENTS.md\`, \`LEARNINGS.md\`, \`memory/\`, \`skills/\`, \`jobs/\`, or \`agents/\`. If a scratch result becomes useful to the user, call \`resources\` with \`action: "promote"\` or rewrite it with \`visibility: "workspace"\`.
|
|
98
|
-
|
|
117
|
+
${resourcesSection}
|
|
99
118
|
### Extended Capabilities
|
|
100
119
|
|
|
101
|
-
You also have tools for
|
|
120
|
+
You also have tools for ${extendedCapabilitiesList}. Call \`get-framework-context\` with the matching key — it lists its own topics — for full instructions before non-trivial work in any of these areas.
|
|
102
121
|
|
|
103
122
|
**Agent teams:** default to doing the work yourself in this thread, but 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. Delegate ONE sub-agent for self-contained heavy work (deep research, long multi-step generation, noisy scans); fan out to MULTIPLE only for genuinely independent units; never parallelize tightly-coupled work; cap fan-out around 3. After \`spawn\`, say the task started/running, not completed; use \`status\`/\`read-result\` before claiming delegated work is done. Give every sub-agent a self-contained brief (objective, the specific context/IDs it needs, output format, boundaries), then read all results and synthesize one integrated answer. Full details: \`get-framework-context\` key \`agent-teams\`.
|
|
104
|
-
|
|
105
|
-
**call-agent** messages a DIFFERENT deployed app's agent over A2A — never use it for your own actions or to call yourself. For brand-consistent generated media when this app has no native generation action, call agent "assets".
|
|
106
|
-
`;
|
|
123
|
+
${callAgentSection}`;
|
|
107
124
|
}
|
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export { buildFrameworkCore } from "./framework-core.js";
|
|
6
6
|
export { buildFrameworkCoreCompact } from "./framework-core-compact.js";
|
|
7
|
-
export { sharedRule8, SHARED_RULE_9,
|
|
7
|
+
export { sharedRule8, SHARED_RULE_9, sharedRule14, SHARED_RULE_15, type PromptExamples, type SharedRuleOptions, } from "./shared-rules.js";
|
|
8
8
|
export { getModelFamilyOverlay } from "./model-overlays.js";
|
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export { buildFrameworkCore } from "./framework-core.js";
|
|
6
6
|
export { buildFrameworkCoreCompact } from "./framework-core-compact.js";
|
|
7
|
-
export { sharedRule8, SHARED_RULE_9,
|
|
7
|
+
export { sharedRule8, SHARED_RULE_9, sharedRule14, SHARED_RULE_15, } from "./shared-rules.js";
|
|
8
8
|
export { getModelFamilyOverlay } from "./model-overlays.js";
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* rule) and 12–13 (planning discipline; collaborate through uncertainty) are
|
|
8
8
|
* reproduced verbatim in both prompts — keep them here.
|
|
9
9
|
*/
|
|
10
|
+
import { type FrameworkToolGroup } from "../../framework-tools.js";
|
|
10
11
|
import { type DatabaseToolsOption } from "../../scripts/db/tool-mode.js";
|
|
11
12
|
/**
|
|
12
13
|
* Injectable provider/action examples. Defaults are generic; templates that
|
|
@@ -21,6 +22,9 @@ export interface PromptExamples {
|
|
|
21
22
|
export interface SharedRuleOptions {
|
|
22
23
|
databaseTools?: DatabaseToolsOption;
|
|
23
24
|
extensionTools?: boolean;
|
|
25
|
+
/** Framework tool groups this app switched off. Any rule naming a group's
|
|
26
|
+
* tool must drop that reference — see `frameworkGroupEnabled`. */
|
|
27
|
+
disabledFrameworkGroups?: ReadonlySet<FrameworkToolGroup>;
|
|
24
28
|
}
|
|
25
29
|
/** Rule 8 — db-* tools are internal only (shared between full and compact). */
|
|
26
30
|
export declare function sharedRule8(examples?: PromptExamples, options?: SharedRuleOptions): string;
|
|
@@ -34,14 +38,18 @@ export declare function sharedRule8(examples?: PromptExamples, options?: SharedR
|
|
|
34
38
|
*/
|
|
35
39
|
export declare const SHARED_RULE_9 = "9. **Never fabricate \u2014 verify results, report failures honestly, and recover instead of giving up.**\n - **Never fabricate factual claims or records** \u2014 do not invent numbers, metrics, records, query results, URLs, citations, source attributions, customer names, dates, or success rates. This applies inside generated artifacts too: decks, documents, reports, dashboards, Slack/email replies, and charts. Only state factual numbers/claims the user provided or you retrieved with an action/tool. If a data source is unavailable, returns no rows, is missing credentials, or has a connection error, say so clearly; do not create placeholder rows or fetch unrelated providers to look complete unless the user explicitly asked you to import/sync/backfill. Prefer qualitative wording, placeholders like `[metric TBD]`, or clearly labeled draft assumptions over plausible-looking facts \u2014 presenting made-up data as real is worse than admitting the limitation.\n - **Never fabricate success from tool errors** \u2014 when a tool call returns an error (marked `isError: true`, contains \"Command failed\", \"Error:\", or non-zero exit output), the operation FAILED; do not synthesize a success narrative or describe what it \"would have\" produced. Report the failure verbatim (this applies especially to `bash(command=\"pnpm action ...\")` calls). Before telling the user a mutating action (create/update/delete/send/publish) is done, confirm it actually landed \u2014 check the tool result, or read the refreshed `<current-screen>` / re-query the data; having *called* an action is not proof it worked. If a result is ambiguous, check rather than assume.\n - **Recover instead of giving up** \u2014 treat a failure or ambiguous result as a signal to retry the obvious fix, try an alternate tool or approach, or clearly hand the blocker back with what you tried; never silently give up, and never paper over a failure by claiming success.";
|
|
36
40
|
/**
|
|
37
|
-
* Rule 12 (
|
|
38
|
-
*
|
|
39
|
-
*
|
|
41
|
+
* Rule 12 (name retained as `sharedRule14` for import stability) — Planning and
|
|
42
|
+
* progress. Deliberately states only when to open a progress run; the
|
|
43
|
+
* start/update/complete discipline lives in `manage-progress`'s own tool
|
|
40
44
|
* description (packages/core/src/progress/actions.ts). Re-adding the mechanics
|
|
41
45
|
* here means every turn pays for guidance the model only needs once it has the
|
|
42
46
|
* tool loaded.
|
|
47
|
+
*
|
|
48
|
+
* Drops the `manage-progress` reference when the `automation` group is off, so
|
|
49
|
+
* the rule never names a tool the request does not carry. The planning
|
|
50
|
+
* discipline itself still applies — only the tool call goes away.
|
|
43
51
|
*/
|
|
44
|
-
export declare
|
|
52
|
+
export declare function sharedRule14(options?: SharedRuleOptions): string;
|
|
45
53
|
/**
|
|
46
54
|
* Rule 14 — Relay agent warnings. Named for what it is rather than its number,
|
|
47
55
|
* since the `SHARED_RULE_14`/`15` names above no longer match theirs.
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* rule) and 12–13 (planning discipline; collaborate through uncertainty) are
|
|
8
8
|
* reproduced verbatim in both prompts — keep them here.
|
|
9
9
|
*/
|
|
10
|
+
import { frameworkGroupEnabled, } from "../../framework-tools.js";
|
|
10
11
|
import { normalizeDatabaseToolsMode, } from "../../scripts/db/tool-mode.js";
|
|
11
12
|
const DEFAULT_PROVIDER_ACTIONS = [
|
|
12
13
|
"provider-search",
|
|
@@ -64,14 +65,23 @@ export const SHARED_RULE_9 = `9. **Never fabricate — verify results, report fa
|
|
|
64
65
|
- **Never fabricate success from tool errors** — when a tool call returns an error (marked \`isError: true\`, contains "Command failed", "Error:", or non-zero exit output), the operation FAILED; do not synthesize a success narrative or describe what it "would have" produced. Report the failure verbatim (this applies especially to \`bash(command="pnpm action ...")\` calls). Before telling the user a mutating action (create/update/delete/send/publish) is done, confirm it actually landed — check the tool result, or read the refreshed \`<current-screen>\` / re-query the data; having *called* an action is not proof it worked. If a result is ambiguous, check rather than assume.
|
|
65
66
|
- **Recover instead of giving up** — treat a failure or ambiguous result as a signal to retry the obvious fix, try an alternate tool or approach, or clearly hand the blocker back with what you tried; never silently give up, and never paper over a failure by claiming success.`;
|
|
66
67
|
/**
|
|
67
|
-
* Rule 12 (
|
|
68
|
-
*
|
|
69
|
-
*
|
|
68
|
+
* Rule 12 (name retained as `sharedRule14` for import stability) — Planning and
|
|
69
|
+
* progress. Deliberately states only when to open a progress run; the
|
|
70
|
+
* start/update/complete discipline lives in `manage-progress`'s own tool
|
|
70
71
|
* description (packages/core/src/progress/actions.ts). Re-adding the mechanics
|
|
71
72
|
* here means every turn pays for guidance the model only needs once it has the
|
|
72
73
|
* tool loaded.
|
|
74
|
+
*
|
|
75
|
+
* Drops the `manage-progress` reference when the `automation` group is off, so
|
|
76
|
+
* the rule never names a tool the request does not carry. The planning
|
|
77
|
+
* discipline itself still applies — only the tool call goes away.
|
|
73
78
|
*/
|
|
74
|
-
export
|
|
79
|
+
export function sharedRule14(options) {
|
|
80
|
+
if (!frameworkGroupEnabled(options?.disabledFrameworkGroups, "automation")) {
|
|
81
|
+
return `12. **Plan and track multi-step work** — When a task spans several real steps, work through them in order and tell the user where you are as you go rather than only at the end. Skip ceremony for single-action lookups, simple reads, and anything that finishes in one tool call.`;
|
|
82
|
+
}
|
|
83
|
+
return `12. **Plan and track multi-step work** — When a task spans several real steps the user would want to watch, open a \`manage-progress\` run so the work is visible while it's still in flight, and keep it updated as you go rather than after the fact; the tool's own description carries the full discipline. Skip it for single-action lookups, simple reads, and anything that finishes in one tool call — never create single-step plans.`;
|
|
84
|
+
}
|
|
75
85
|
/**
|
|
76
86
|
* Rule 14 — Relay agent warnings. Named for what it is rather than its number,
|
|
77
87
|
* since the `SHARED_RULE_14`/`15` names above no longer match theirs.
|
|
@@ -26,8 +26,8 @@ export declare function createRealtimeTokenHandler(): import("h3").EventHandlerW
|
|
|
26
26
|
expiresAt?: undefined;
|
|
27
27
|
ttlSeconds?: undefined;
|
|
28
28
|
} | {
|
|
29
|
+
error?: undefined;
|
|
29
30
|
token: string;
|
|
30
31
|
expiresAt: string;
|
|
31
32
|
ttlSeconds: number;
|
|
32
|
-
error?: undefined;
|
|
33
33
|
}>>;
|
package/dist/shared/index.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export { llmConnectionTrackingProperties, normalizeLlmConnection, type LlmConnec
|
|
|
9
9
|
export { DISPATCH_WORKSPACE_ROOT_REDIRECTS, RESERVED_WORKSPACE_APP_IDS, assertValidWorkspaceAppId, getWorkspaceAppIdValidationError, isValidWorkspaceAppIdFormat, } from "./workspace-app-id.js";
|
|
10
10
|
export { DEFAULT_WORKSPACE_APP_AUDIENCE, WORKSPACE_APP_AUDIENCES, normalizeWorkspaceAppAudience, normalizeWorkspaceAppPathList, workspaceAppAudienceFromEnv, workspaceAppAudienceFromPackageJson, workspaceAppRouteAccessFromEnv, workspaceAppRouteAccessFromPackageJson, type WorkspaceAppRouteAccess, type WorkspaceAppRouteAccessFromConfig, type WorkspaceAppAudience, } from "./workspace-app-audience.js";
|
|
11
11
|
export { AGENT_NATIVE_OPEN_PATH, AGENT_SIDEBAR_QUERY_PARAM, AGENT_SIDEBAR_QUERY_VALUE_CLOSED, isAgentNativeOpenDeepLink, withCollapsedAgentSidebarParam, } from "./agent-sidebar-url.js";
|
|
12
|
+
export { createPollEngine, type PollEngineOptions, type PollEngineHandle, } from "./poll-engine.js";
|
|
12
13
|
export { AGENT_NATIVE_DEFAULT_SOCIAL_IMAGE, AGENT_NATIVE_SOCIAL_IMAGE_CACHE_BUSTER, AGENT_NATIVE_SOCIAL_IMAGE_ALT, AGENT_NATIVE_SOCIAL_IMAGE_HEIGHT, AGENT_NATIVE_SOCIAL_IMAGE_PATH, AGENT_NATIVE_SOCIAL_IMAGE_TYPE, AGENT_NATIVE_SOCIAL_IMAGE_WIDTH, defaultSocialImageMeta, withAgentNativeSocialImageCacheBuster, withDefaultSocialImage, type SocialMetaDescriptor, } from "./social-meta.js";
|
|
13
14
|
export { EMBED_MODE_QUERY_PARAM, EMBED_SESSION_COOKIE, EMBED_START_PATH, EMBED_TOKEN_QUERY_PARAM, } from "./embed-auth.js";
|
|
14
15
|
export { AGENT_ACCESS_PARAM, DEFAULT_AGENT_ACCESS_TTL_SECONDS, appendAgentAccessParam, buildAgentAccessApiUrl, buildAgentAccessUrl, normalizeAgentAccessBasePath, normalizeAgentAccessOrigin, scopedAgentAccessResourceId, toAgentAccessUrl, type AgentAccessApiUrlOptions, type AgentAccessResourceScope, type AgentAccessUrlOptions, } from "./agent-access.js";
|
package/dist/shared/index.js
CHANGED
|
@@ -9,6 +9,7 @@ export { llmConnectionTrackingProperties, normalizeLlmConnection, } from "./llm-
|
|
|
9
9
|
export { DISPATCH_WORKSPACE_ROOT_REDIRECTS, RESERVED_WORKSPACE_APP_IDS, assertValidWorkspaceAppId, getWorkspaceAppIdValidationError, isValidWorkspaceAppIdFormat, } from "./workspace-app-id.js";
|
|
10
10
|
export { DEFAULT_WORKSPACE_APP_AUDIENCE, WORKSPACE_APP_AUDIENCES, normalizeWorkspaceAppAudience, normalizeWorkspaceAppPathList, workspaceAppAudienceFromEnv, workspaceAppAudienceFromPackageJson, workspaceAppRouteAccessFromEnv, workspaceAppRouteAccessFromPackageJson, } from "./workspace-app-audience.js";
|
|
11
11
|
export { AGENT_NATIVE_OPEN_PATH, AGENT_SIDEBAR_QUERY_PARAM, AGENT_SIDEBAR_QUERY_VALUE_CLOSED, isAgentNativeOpenDeepLink, withCollapsedAgentSidebarParam, } from "./agent-sidebar-url.js";
|
|
12
|
+
export { createPollEngine, } from "./poll-engine.js";
|
|
12
13
|
export { AGENT_NATIVE_DEFAULT_SOCIAL_IMAGE, AGENT_NATIVE_SOCIAL_IMAGE_CACHE_BUSTER, AGENT_NATIVE_SOCIAL_IMAGE_ALT, AGENT_NATIVE_SOCIAL_IMAGE_HEIGHT, AGENT_NATIVE_SOCIAL_IMAGE_PATH, AGENT_NATIVE_SOCIAL_IMAGE_TYPE, AGENT_NATIVE_SOCIAL_IMAGE_WIDTH, defaultSocialImageMeta, withAgentNativeSocialImageCacheBuster, withDefaultSocialImage, } from "./social-meta.js";
|
|
13
14
|
export { EMBED_MODE_QUERY_PARAM, EMBED_SESSION_COOKIE, EMBED_START_PATH, EMBED_TOKEN_QUERY_PARAM, } from "./embed-auth.js";
|
|
14
15
|
export { AGENT_ACCESS_PARAM, DEFAULT_AGENT_ACCESS_TTL_SECONDS, appendAgentAccessParam, buildAgentAccessApiUrl, buildAgentAccessUrl, normalizeAgentAccessBasePath, normalizeAgentAccessOrigin, scopedAgentAccessResourceId, toAgentAccessUrl, } from "./agent-access.js";
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared recurring-poll engine used by both `usePollLoop` (client) and
|
|
3
|
+
* `startIntervalJob` (server) so every polling loop in the codebase gets the
|
|
4
|
+
* same three properties for free instead of hand-rolling them per call site:
|
|
5
|
+
*
|
|
6
|
+
* 1. Never overlaps: the next attempt is scheduled via `setTimeout` only
|
|
7
|
+
* after the current one settles, not on a fixed `setInterval` cadence.
|
|
8
|
+
* This also avoids the latency `setInterval` + skip-if-busy introduces —
|
|
9
|
+
* a skipped tick there means waiting a full extra cadence before the next
|
|
10
|
+
* retry; here the gap after completion is always exactly `intervalMs`.
|
|
11
|
+
* 2. Never stalls silently: every attempt is bounded by a timeout (paired
|
|
12
|
+
* with an `AbortController` so a `fetch` can actually cancel, not just be
|
|
13
|
+
* abandoned), and that timeout reports through `onError` the moment it
|
|
14
|
+
* fires. An attempt that ignores its `signal` keeps holding the loop —
|
|
15
|
+
* reported, not hidden — because releasing the slot to the next attempt
|
|
16
|
+
* would trade a visible stall for a silent overlap.
|
|
17
|
+
* 3. Never double-fires: a single internal in-flight flag, owned by this
|
|
18
|
+
* engine rather than duplicated in every caller.
|
|
19
|
+
*/
|
|
20
|
+
export interface PollEngineOptions {
|
|
21
|
+
/** Delay in ms before the next attempt. Evaluated fresh before each schedule. */
|
|
22
|
+
intervalMs: number | (() => number);
|
|
23
|
+
/** Per-attempt timeout. Default: `Math.max(timeoutFloorMs, intervalMs * 4)`. */
|
|
24
|
+
timeoutMs?: number | (() => number);
|
|
25
|
+
/** Floor used by the default `timeoutMs`. Default: 10_000. */
|
|
26
|
+
timeoutFloorMs?: number;
|
|
27
|
+
/** Called when an attempt throws or times out. Default: swallow. */
|
|
28
|
+
onError?: (err: unknown) => void;
|
|
29
|
+
/** Run the first attempt immediately on `start()`. Default: true. */
|
|
30
|
+
leading?: boolean;
|
|
31
|
+
}
|
|
32
|
+
export interface PollEngineHandle {
|
|
33
|
+
/** Arm the loop. No-op if already running. */
|
|
34
|
+
start(): void;
|
|
35
|
+
/** Halt the loop and abort any in-flight attempt; its eventual settlement is a no-op. */
|
|
36
|
+
stop(): void;
|
|
37
|
+
/** Cancel the pending wait and run now. No-op if not running or an attempt is already in flight. */
|
|
38
|
+
pollNow(): void;
|
|
39
|
+
/**
|
|
40
|
+
* Re-arm the pending wait using a freshly resolved `intervalMs`, without
|
|
41
|
+
* running an attempt. Use this when `intervalMs` is a function whose
|
|
42
|
+
* result can change externally (e.g. tab visibility) — otherwise a
|
|
43
|
+
* change only takes effect the next time an attempt completes. No-op if
|
|
44
|
+
* there's no pending wait (not running, or an attempt is in flight).
|
|
45
|
+
*/
|
|
46
|
+
reschedule(): void;
|
|
47
|
+
readonly isRunning: boolean;
|
|
48
|
+
}
|
|
49
|
+
export declare function createPollEngine(attempt: (signal: AbortSignal) => Promise<void>, options: PollEngineOptions): PollEngineHandle;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared recurring-poll engine used by both `usePollLoop` (client) and
|
|
3
|
+
* `startIntervalJob` (server) so every polling loop in the codebase gets the
|
|
4
|
+
* same three properties for free instead of hand-rolling them per call site:
|
|
5
|
+
*
|
|
6
|
+
* 1. Never overlaps: the next attempt is scheduled via `setTimeout` only
|
|
7
|
+
* after the current one settles, not on a fixed `setInterval` cadence.
|
|
8
|
+
* This also avoids the latency `setInterval` + skip-if-busy introduces —
|
|
9
|
+
* a skipped tick there means waiting a full extra cadence before the next
|
|
10
|
+
* retry; here the gap after completion is always exactly `intervalMs`.
|
|
11
|
+
* 2. Never stalls silently: every attempt is bounded by a timeout (paired
|
|
12
|
+
* with an `AbortController` so a `fetch` can actually cancel, not just be
|
|
13
|
+
* abandoned), and that timeout reports through `onError` the moment it
|
|
14
|
+
* fires. An attempt that ignores its `signal` keeps holding the loop —
|
|
15
|
+
* reported, not hidden — because releasing the slot to the next attempt
|
|
16
|
+
* would trade a visible stall for a silent overlap.
|
|
17
|
+
* 3. Never double-fires: a single internal in-flight flag, owned by this
|
|
18
|
+
* engine rather than duplicated in every caller.
|
|
19
|
+
*/
|
|
20
|
+
const DEFAULT_TIMEOUT_FLOOR_MS = 10_000;
|
|
21
|
+
function resolve(value) {
|
|
22
|
+
return typeof value === "function" ? value() : value;
|
|
23
|
+
}
|
|
24
|
+
function maybeUnref(timer) {
|
|
25
|
+
if (timer &&
|
|
26
|
+
typeof timer === "object" &&
|
|
27
|
+
"unref" in timer &&
|
|
28
|
+
typeof timer.unref === "function") {
|
|
29
|
+
timer.unref();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export function createPollEngine(attempt, options) {
|
|
33
|
+
const timeoutFloorMs = options.timeoutFloorMs ?? DEFAULT_TIMEOUT_FLOOR_MS;
|
|
34
|
+
const getTimeoutMs = () => options.timeoutMs != null
|
|
35
|
+
? resolve(options.timeoutMs)
|
|
36
|
+
: Math.max(timeoutFloorMs, resolve(options.intervalMs) * 4);
|
|
37
|
+
const onError = options.onError ?? (() => { });
|
|
38
|
+
const leading = options.leading ?? true;
|
|
39
|
+
let generation = 0;
|
|
40
|
+
let running = false;
|
|
41
|
+
let inFlight = false;
|
|
42
|
+
let timer = null;
|
|
43
|
+
let activeController = null;
|
|
44
|
+
function clearTimer() {
|
|
45
|
+
if (timer != null) {
|
|
46
|
+
clearTimeout(timer);
|
|
47
|
+
timer = null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function schedule(gen) {
|
|
51
|
+
clearTimer();
|
|
52
|
+
timer = setTimeout(() => {
|
|
53
|
+
timer = null;
|
|
54
|
+
void tick(gen);
|
|
55
|
+
}, resolve(options.intervalMs));
|
|
56
|
+
maybeUnref(timer);
|
|
57
|
+
}
|
|
58
|
+
async function tick(gen) {
|
|
59
|
+
if (gen !== generation || !running)
|
|
60
|
+
return;
|
|
61
|
+
if (inFlight) {
|
|
62
|
+
// An attempt from a superseded generation is still settling — stop()
|
|
63
|
+
// aborted it but the caller has not returned yet. Its own `finally`
|
|
64
|
+
// sees a stale generation and will not reschedule, so re-arming here
|
|
65
|
+
// is what keeps a stop()/start() cycle (tab hidden then visible) from
|
|
66
|
+
// leaving the engine alive-but-timerless, i.e. permanently dead.
|
|
67
|
+
schedule(gen);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
inFlight = true;
|
|
71
|
+
const controller = new AbortController();
|
|
72
|
+
activeController = controller;
|
|
73
|
+
const timeoutMs = getTimeoutMs();
|
|
74
|
+
const abortTimer = setTimeout(() => controller.abort(), timeoutMs);
|
|
75
|
+
maybeUnref(abortTimer);
|
|
76
|
+
let reported = false;
|
|
77
|
+
const report = (err) => {
|
|
78
|
+
if (reported)
|
|
79
|
+
return;
|
|
80
|
+
reported = true;
|
|
81
|
+
onError(err);
|
|
82
|
+
};
|
|
83
|
+
// The attempt is retained separately from the timeout race below. The
|
|
84
|
+
// timeout reports a slow attempt immediately, but the in-flight slot is
|
|
85
|
+
// only released once the attempt itself settles: releasing on the
|
|
86
|
+
// timeout would let the next tick start while an attempt that ignores
|
|
87
|
+
// `signal` is still doing work, which is the overlap (duplicate external
|
|
88
|
+
// requests, racing writes) this engine exists to prevent. An attempt that
|
|
89
|
+
// never settles blocks further attempts by design — `onError` has already
|
|
90
|
+
// fired, so it is loud rather than silent.
|
|
91
|
+
const settled = Promise.resolve()
|
|
92
|
+
.then(() => attempt(controller.signal))
|
|
93
|
+
.then(() => { }, (err) => report(err));
|
|
94
|
+
try {
|
|
95
|
+
await Promise.race([
|
|
96
|
+
settled,
|
|
97
|
+
new Promise((_, reject) => {
|
|
98
|
+
controller.signal.addEventListener("abort", () => reject(new Error(`poll attempt timed out after ${timeoutMs}ms`)), { once: true });
|
|
99
|
+
}),
|
|
100
|
+
]);
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
report(err);
|
|
104
|
+
}
|
|
105
|
+
finally {
|
|
106
|
+
await settled;
|
|
107
|
+
clearTimeout(abortTimer);
|
|
108
|
+
if (activeController === controller)
|
|
109
|
+
activeController = null;
|
|
110
|
+
inFlight = false;
|
|
111
|
+
if (gen === generation && running)
|
|
112
|
+
schedule(gen);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
start() {
|
|
117
|
+
if (running)
|
|
118
|
+
return;
|
|
119
|
+
running = true;
|
|
120
|
+
generation++;
|
|
121
|
+
const gen = generation;
|
|
122
|
+
if (leading)
|
|
123
|
+
void tick(gen);
|
|
124
|
+
else
|
|
125
|
+
schedule(gen);
|
|
126
|
+
},
|
|
127
|
+
stop() {
|
|
128
|
+
running = false;
|
|
129
|
+
generation++;
|
|
130
|
+
clearTimer();
|
|
131
|
+
activeController?.abort();
|
|
132
|
+
},
|
|
133
|
+
pollNow() {
|
|
134
|
+
if (!running || inFlight)
|
|
135
|
+
return;
|
|
136
|
+
clearTimer();
|
|
137
|
+
void tick(generation);
|
|
138
|
+
},
|
|
139
|
+
reschedule() {
|
|
140
|
+
if (!running || inFlight || timer == null)
|
|
141
|
+
return;
|
|
142
|
+
schedule(generation);
|
|
143
|
+
},
|
|
144
|
+
get isRunning() {
|
|
145
|
+
return running;
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
}
|
|
@@ -29,6 +29,11 @@ Templates use `app/i18n/`:
|
|
|
29
29
|
Use BCP-47 filenames from the supported set: `en-US`, `zh-CN`, `es-ES`,
|
|
30
30
|
`fr-FR`, `de-DE`, `ja-JP`, `ko-KR`, `pt-BR`, `hi-IN`, `ar-SA`.
|
|
31
31
|
|
|
32
|
+
If an app only ships translations for a subset of that set, set
|
|
33
|
+
`supportedLocales` on the `AgentNativeI18nCatalog` to that subset. Without it,
|
|
34
|
+
`<LanguagePicker />` lists every framework-supported locale regardless of
|
|
35
|
+
whether `loadMessages` can actually resolve it.
|
|
36
|
+
|
|
32
37
|
## UI Pattern
|
|
33
38
|
|
|
34
39
|
- Wrap apps with `AppProviders i18n={{ catalog: i18nCatalog }}`.
|
|
@@ -217,9 +217,12 @@ POST /_agent-native/extensions
|
|
|
217
217
|
|
|
218
218
|
HTTP creation is disabled by default. The host app must set
|
|
219
219
|
`extensionTools: true` on `createCoreRoutesPlugin()` as well as
|
|
220
|
-
`
|
|
221
|
-
return `403` while existing extension
|
|
222
|
-
remain available for compatibility.
|
|
220
|
+
`frameworkTools: { extensions: true }` on `createAgentChatPlugin()`; otherwise
|
|
221
|
+
authenticated collection `POST` requests return `403` while existing extension
|
|
222
|
+
runtime, read, edit, and deep-link routes remain available for compatibility.
|
|
223
|
+
(`extensionTools` on the agent-chat plugin is the deprecated spelling of
|
|
224
|
+
`frameworkTools.extensions`; the core-routes option keeps its own name because
|
|
225
|
+
it gates route mounting rather than agent tools.)
|
|
223
226
|
|
|
224
227
|
The action accepts:
|
|
225
228
|
|
|
@@ -29,6 +29,11 @@ Templates use `app/i18n/`:
|
|
|
29
29
|
Use BCP-47 filenames from the supported set: `en-US`, `zh-CN`, `es-ES`,
|
|
30
30
|
`fr-FR`, `de-DE`, `ja-JP`, `ko-KR`, `pt-BR`, `hi-IN`, `ar-SA`.
|
|
31
31
|
|
|
32
|
+
If an app only ships translations for a subset of that set, set
|
|
33
|
+
`supportedLocales` on the `AgentNativeI18nCatalog` to that subset. Without it,
|
|
34
|
+
`<LanguagePicker />` lists every framework-supported locale regardless of
|
|
35
|
+
whether `loadMessages` can actually resolve it.
|
|
36
|
+
|
|
32
37
|
## UI Pattern
|
|
33
38
|
|
|
34
39
|
- Wrap apps with `AppProviders i18n={{ catalog: i18nCatalog }}`.
|
|
@@ -38,7 +38,16 @@ function setTimer(t) {
|
|
|
38
38
|
function enqueue(url, body, headers, options) {
|
|
39
39
|
const queue = getQueue();
|
|
40
40
|
queue.push({ url, body, headers });
|
|
41
|
-
|
|
41
|
+
// The batch timer is unref'd so it never keeps a long-lived server alive —
|
|
42
|
+
// but on Netlify/Vercel/Lambda the execution environment can freeze the
|
|
43
|
+
// moment the event loop looks empty, which is exactly when an unref'd timer
|
|
44
|
+
// doesn't count. Without a signal, a warm container freezing between
|
|
45
|
+
// invocations never fires that timer, silently dropping every provider's
|
|
46
|
+
// queued events for a request that ends in a crash. Default to flushing
|
|
47
|
+
// synchronously with the response in that environment; a caller (e.g.
|
|
48
|
+
// Agent Native Analytics' flush-mode override) can still force either way.
|
|
49
|
+
const flushImmediately = options?.flushImmediately ?? isServerlessRuntime();
|
|
50
|
+
if (flushImmediately || queue.length >= MAX_BATCH_SIZE) {
|
|
42
51
|
void drainQueue();
|
|
43
52
|
}
|
|
44
53
|
else if (!getTimer()) {
|
|
@@ -580,16 +580,19 @@ Rotate signing/session keys by replacing the env var on every instance and redep
|
|
|
580
580
|
|
|
581
581
|
## Production Agent Tools {#production-agent-tools}
|
|
582
582
|
|
|
583
|
-
Production agents get the app's registered actions plus framework
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
583
|
+
Production agents get the app's registered actions plus the framework's own
|
|
584
|
+
tools. `frameworkTools` selects which of those framework tools this app exposes.
|
|
585
|
+
Every group defaults to today's behavior, so omitting the option changes
|
|
586
|
+
nothing:
|
|
587
587
|
|
|
588
588
|
```ts filename="server/plugins/agent-chat.ts"
|
|
589
589
|
export default createAgentChatPlugin({
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
590
|
+
frameworkTools: {
|
|
591
|
+
database: "read", // "write" | "read" | "off" — default "read"
|
|
592
|
+
extensions: true, // default false
|
|
593
|
+
sharing: false, // this app has no share surface
|
|
594
|
+
review: false,
|
|
595
|
+
},
|
|
593
596
|
});
|
|
594
597
|
```
|
|
595
598
|
|
|
@@ -599,17 +602,48 @@ export default createCoreRoutesPlugin({
|
|
|
599
602
|
});
|
|
600
603
|
```
|
|
601
604
|
|
|
602
|
-
|
|
605
|
+
`database` and `extensions` accept the values the old top-level flags did:
|
|
606
|
+
|
|
607
|
+
- `database: "read"` — default. Registers only `db-schema` and `db-query`;
|
|
603
608
|
agents inspect data with SQL but must use typed app actions for writes.
|
|
604
|
-
- `
|
|
609
|
+
- `database: "write"` or `true` — additionally registers `db-exec` and
|
|
605
610
|
`db-patch` for deliberate raw SQL maintenance. Writes are scoped to the
|
|
606
611
|
current user/org and schema changes are blocked.
|
|
607
|
-
- `
|
|
612
|
+
- `database: "off"` or `false` — removes raw database tools from the
|
|
608
613
|
agent surface so the app's actions are the only data access path.
|
|
609
|
-
- `
|
|
614
|
+
- `extensions: true` — opts the app into framework extension-management
|
|
610
615
|
actions and prompt guidance (`create-extension`, `update-extension`, etc.).
|
|
611
|
-
Set
|
|
612
|
-
are disabled by default.
|
|
616
|
+
Set `extensionTools: true` on the core-routes plugin as well to allow
|
|
617
|
+
authenticated REST creation. Extensions are disabled by default.
|
|
618
|
+
|
|
619
|
+
The remaining groups are booleans, all on by default: `sharing`, `review`,
|
|
620
|
+
`history`, `featureFlags`, `localization`, `audit`, `contextXray`,
|
|
621
|
+
`userProfile`, `automation`, `docs`, `resources`, `web`, `workspaceApps`,
|
|
622
|
+
`chat`, and `email`. Use `frameworkTools: "minimal"` to turn every group off at
|
|
623
|
+
once for a voice-first or single-purpose app, or
|
|
624
|
+
`frameworkTools: { preset: "minimal", resources: true }` to keep just one — an
|
|
625
|
+
explicit group key always wins over the preset.
|
|
626
|
+
|
|
627
|
+
Switching a group off removes it from the **agent** surfaces only: interactive
|
|
628
|
+
chat, MCP, A2A, and background runs. The matching HTTP action routes stay
|
|
629
|
+
mounted, because the UI reaches them through client hooks — disabling `sharing`
|
|
630
|
+
must not 404 a share dialog that is still on screen. Weigh that parity cost
|
|
631
|
+
before using it: the framework's contract is that anything the UI can do the
|
|
632
|
+
agent can do, so `sharing: false` alongside a visible share button is a
|
|
633
|
+
deliberate break, and only makes sense when the app has no such surface at all.
|
|
634
|
+
|
|
635
|
+
Framework tools are no longer promoted into the first model request by default,
|
|
636
|
+
independent of this option. They stay in the searchable registry and load
|
|
637
|
+
through `tool-search`, or immediately if the app names them in
|
|
638
|
+
`initialToolNames`.
|
|
639
|
+
|
|
640
|
+
<Callout tone="warning">
|
|
641
|
+
The top-level `databaseTools` and `extensionTools` options are deprecated in
|
|
642
|
+
favor of `frameworkTools.database` and `frameworkTools.extensions`. They are
|
|
643
|
+
still honored, but setting a top-level flag and its `frameworkTools`
|
|
644
|
+
equivalent to conflicting values throws at plugin startup rather than booting
|
|
645
|
+
with a tool surface nobody chose.
|
|
646
|
+
</Callout>
|
|
613
647
|
|
|
614
648
|
## Production Code Execution {#production-code-execution}
|
|
615
649
|
|
|
@@ -254,12 +254,19 @@ pnpm action db-query --sql "SELECT * FROM forms"
|
|
|
254
254
|
```
|
|
255
255
|
|
|
256
256
|
The production agent chat plugin defaults raw SQL tools to read-only
|
|
257
|
-
(`
|
|
258
|
-
`db-query` and perform writes through typed app actions. Set
|
|
259
|
-
`
|
|
260
|
-
|
|
261
|
-
`
|
|
262
|
-
|
|
257
|
+
(`frameworkTools: { database: "read" }`), so agents inspect app-owned data with
|
|
258
|
+
`db-schema` / `db-query` and perform writes through typed app actions. Set
|
|
259
|
+
`database: "write"` (or `true`) only for deliberate maintenance surfaces that
|
|
260
|
+
should also expose scoped `db-exec` / `db-patch`; set `database: "off"` /
|
|
261
|
+
`false` to require typed app actions for all data access.
|
|
262
|
+
|
|
263
|
+
`frameworkTools` governs the rest of the framework's own tools the same way —
|
|
264
|
+
sharing, review comments, version history, feature flags, localization, audit,
|
|
265
|
+
context X-Ray, profile, automations, docs, resources, web, cross-app delegation,
|
|
266
|
+
chat, and email. See
|
|
267
|
+
[Production Agent Tools](/docs/deployment#production-agent-tools) for the full
|
|
268
|
+
list, the `"minimal"` preset, and why disabling a group leaves its HTTP routes
|
|
269
|
+
mounted.
|
|
263
270
|
|
|
264
271
|
## Agent chat bridge {#agent-chat-bridge}
|
|
265
272
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.145.0",
|
|
4
4
|
"description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -72,6 +72,7 @@
|
|
|
72
72
|
"./server/request-context": "./dist/server/request-context.js",
|
|
73
73
|
"./server/design-token-utils": "./dist/server/design-token-utils.js",
|
|
74
74
|
"./server/poll": "./dist/server/poll.js",
|
|
75
|
+
"./server/interval-job": "./dist/server/interval-job.js",
|
|
75
76
|
"./server/sse": "./dist/server/sse.js",
|
|
76
77
|
"./server/short-lived-token": "./dist/server/short-lived-token.js",
|
|
77
78
|
"./integrations": "./dist/integrations/index.js",
|
|
@@ -29,6 +29,11 @@ Templates use `app/i18n/`:
|
|
|
29
29
|
Use BCP-47 filenames from the supported set: `en-US`, `zh-CN`, `es-ES`,
|
|
30
30
|
`fr-FR`, `de-DE`, `ja-JP`, `ko-KR`, `pt-BR`, `hi-IN`, `ar-SA`.
|
|
31
31
|
|
|
32
|
+
If an app only ships translations for a subset of that set, set
|
|
33
|
+
`supportedLocales` on the `AgentNativeI18nCatalog` to that subset. Without it,
|
|
34
|
+
`<LanguagePicker />` lists every framework-supported locale regardless of
|
|
35
|
+
whether `loadMessages` can actually resolve it.
|
|
36
|
+
|
|
32
37
|
## UI Pattern
|
|
33
38
|
|
|
34
39
|
- Wrap apps with `AppProviders i18n={{ catalog: i18nCatalog }}`.
|
|
@@ -217,9 +217,12 @@ POST /_agent-native/extensions
|
|
|
217
217
|
|
|
218
218
|
HTTP creation is disabled by default. The host app must set
|
|
219
219
|
`extensionTools: true` on `createCoreRoutesPlugin()` as well as
|
|
220
|
-
`
|
|
221
|
-
return `403` while existing extension
|
|
222
|
-
remain available for compatibility.
|
|
220
|
+
`frameworkTools: { extensions: true }` on `createAgentChatPlugin()`; otherwise
|
|
221
|
+
authenticated collection `POST` requests return `403` while existing extension
|
|
222
|
+
runtime, read, edit, and deep-link routes remain available for compatibility.
|
|
223
|
+
(`extensionTools` on the agent-chat plugin is the deprecated spelling of
|
|
224
|
+
`frameworkTools.extensions`; the core-routes option keeps its own name because
|
|
225
|
+
it gates route mounting rather than agent tools.)
|
|
223
226
|
|
|
224
227
|
The action accepts:
|
|
225
228
|
|