@agent-native/core 0.78.8 → 0.79.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 +2 -2
- package/corpus/core/CHANGELOG.md +25 -0
- package/corpus/core/docs/content/actions.md +4 -2
- package/corpus/core/docs/content/agent-surfaces.md +9 -0
- package/corpus/core/docs/content/extensions.md +10 -0
- package/corpus/core/docs/content/generative-ui.md +217 -0
- package/corpus/core/docs/content/key-concepts.md +2 -2
- package/corpus/core/docs/content/mcp-apps.md +3 -5
- package/corpus/core/docs/content/native-chat-ui.md +9 -5
- package/corpus/core/docs/content/tracking.md +9 -3
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/action-ui.ts +1 -0
- package/corpus/core/src/client/analytics.ts +195 -12
- package/corpus/core/src/client/chat/index.ts +1 -0
- package/corpus/core/src/client/chat/tool-call-display.tsx +5 -2
- package/corpus/core/src/client/chat/widgets/InlineExtensionWidget.tsx +139 -0
- package/corpus/core/src/client/chat/widgets/builtin-tool-renderers.tsx +27 -1
- package/corpus/core/src/client/conversation/AgentConversation.tsx +38 -0
- package/corpus/core/src/client/conversation/code-agent-transcript.ts +9 -0
- package/corpus/core/src/client/conversation/types.ts +4 -0
- package/corpus/core/src/client/extensions/EmbeddedExtension.tsx +27 -5
- package/corpus/core/src/client/extensions/ExtensionViewer.tsx +26 -5
- package/corpus/core/src/client/extensions/InlineExtensionFrame.tsx +654 -0
- package/corpus/core/src/client/extensions/iframe-bridge.ts +30 -0
- package/corpus/core/src/client/extensions/index.ts +5 -0
- package/corpus/core/src/client/index.ts +1 -0
- package/corpus/core/src/client/session-replay.ts +89 -14
- package/corpus/core/src/code-agents/transcript-normalizer.ts +14 -0
- package/corpus/core/src/extensions/actions.ts +218 -1
- package/corpus/core/src/extensions/html-shell.ts +70 -3
- package/corpus/core/src/extensions/routes.ts +12 -4
- package/corpus/core/src/index.browser.ts +1 -0
- package/corpus/core/src/index.ts +1 -0
- package/corpus/core/src/mcp/build-server.ts +1 -1
- package/corpus/core/src/mcp/embed-app.ts +11 -1
- package/corpus/core/src/server/agent-chat-plugin.ts +21 -9
- package/corpus/core/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +13 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/extensions/references/api.md +2 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/generative-ui/SKILL.md +115 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +198 -59
- package/corpus/templates/analytics/AGENTS.md +12 -0
- package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +1105 -0
- package/corpus/templates/analytics/actions/dashboard-panel-order.ts +169 -0
- package/corpus/templates/analytics/actions/get-sql-dashboard.ts +89 -6
- package/corpus/templates/analytics/actions/mutate-dashboard.ts +333 -0
- package/corpus/templates/analytics/actions/reorder-dashboard-panels.ts +214 -0
- package/corpus/templates/analytics/actions/send-dashboard-report-now.ts +48 -21
- package/corpus/templates/analytics/actions/update-dashboard.ts +193 -100
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +11 -0
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +1 -1
- package/corpus/templates/analytics/app/global.css +81 -10
- package/corpus/templates/analytics/app/i18n-data.ts +249 -4
- package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/ChartCard.tsx +3 -3
- package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +41 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/EmailReportDialog.tsx +1 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +4 -4
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +48 -18
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/dashboard-layout.ts +32 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +204 -70
- package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +1101 -227
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +160 -133
- package/corpus/templates/analytics/changelog/2026-06-26-agents-can-now-edit-dashboards-through-a-typed-mutation-scri.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-26-dashboard-bar-chart-hovers-stay-subtle-in-dark-mode.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-26-dashboard-chart-moves-are-now-handled-by-panel-id-making-sim.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-26-dashboard-charts-drag-smoothly-with-stable-cards-inactive-ch.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-26-dashboard-charts-show-a-refresh-spinner-while-keeping-existi.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-26-dashboard-edits-stay-stable-while-chart-order-and-deletions-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-26-dashboard-email-reports-queue-immediate-sends.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-26-explorer-dashboards-now-drag-charts-with-a-stable-preview-an.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-26-session-replay-playback-can-now-be-toggled-by-clicking-the-r.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-26-session-replays-now-open-from-the-full-row-and-play-with-tim.md +6 -0
- package/corpus/templates/analytics/server/lib/dashboard-report-subscriptions.ts +21 -0
- package/corpus/templates/analytics/server/lib/dashboard-report.ts +41 -17
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +5 -0
- package/dist/action-ui.d.ts +1 -0
- package/dist/action-ui.d.ts.map +1 -1
- package/dist/action-ui.js +1 -0
- package/dist/action-ui.js.map +1 -1
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +173 -12
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/chat/index.d.ts +1 -1
- package/dist/client/chat/index.d.ts.map +1 -1
- package/dist/client/chat/index.js +1 -1
- package/dist/client/chat/index.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +3 -1
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/chat/widgets/InlineExtensionWidget.d.ts +17 -0
- package/dist/client/chat/widgets/InlineExtensionWidget.d.ts.map +1 -0
- package/dist/client/chat/widgets/InlineExtensionWidget.js +85 -0
- package/dist/client/chat/widgets/InlineExtensionWidget.js.map +1 -0
- package/dist/client/chat/widgets/builtin-tool-renderers.d.ts.map +1 -1
- package/dist/client/chat/widgets/builtin-tool-renderers.js +15 -2
- package/dist/client/chat/widgets/builtin-tool-renderers.js.map +1 -1
- package/dist/client/conversation/AgentConversation.d.ts.map +1 -1
- package/dist/client/conversation/AgentConversation.js +33 -0
- package/dist/client/conversation/AgentConversation.js.map +1 -1
- package/dist/client/conversation/code-agent-transcript.js +8 -0
- package/dist/client/conversation/code-agent-transcript.js.map +1 -1
- package/dist/client/conversation/types.d.ts +4 -0
- package/dist/client/conversation/types.d.ts.map +1 -1
- package/dist/client/conversation/types.js.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.d.ts.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.js +29 -1
- package/dist/client/extensions/EmbeddedExtension.js.map +1 -1
- package/dist/client/extensions/ExtensionViewer.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionViewer.js +28 -1
- package/dist/client/extensions/ExtensionViewer.js.map +1 -1
- package/dist/client/extensions/InlineExtensionFrame.d.ts +25 -0
- package/dist/client/extensions/InlineExtensionFrame.d.ts.map +1 -0
- package/dist/client/extensions/InlineExtensionFrame.js +488 -0
- package/dist/client/extensions/InlineExtensionFrame.js.map +1 -0
- package/dist/client/extensions/iframe-bridge.d.ts +2 -0
- package/dist/client/extensions/iframe-bridge.d.ts.map +1 -1
- package/dist/client/extensions/iframe-bridge.js +23 -0
- package/dist/client/extensions/iframe-bridge.js.map +1 -1
- package/dist/client/extensions/index.d.ts +1 -0
- package/dist/client/extensions/index.d.ts.map +1 -1
- package/dist/client/extensions/index.js +1 -0
- package/dist/client/extensions/index.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/session-replay.d.ts +11 -1
- package/dist/client/session-replay.d.ts.map +1 -1
- package/dist/client/session-replay.js +74 -14
- package/dist/client/session-replay.js.map +1 -1
- package/dist/code-agents/transcript-normalizer.d.ts +2 -0
- package/dist/code-agents/transcript-normalizer.d.ts.map +1 -1
- package/dist/code-agents/transcript-normalizer.js +8 -0
- package/dist/code-agents/transcript-normalizer.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/routes.d.ts +2 -2
- package/dist/extensions/actions.d.ts.map +1 -1
- package/dist/extensions/actions.js +200 -1
- package/dist/extensions/actions.js.map +1 -1
- package/dist/extensions/html-shell.d.ts.map +1 -1
- package/dist/extensions/html-shell.js +70 -3
- package/dist/extensions/html-shell.js.map +1 -1
- package/dist/extensions/routes.d.ts.map +1 -1
- package/dist/extensions/routes.js +11 -4
- package/dist/extensions/routes.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/index.browser.d.ts +1 -1
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.js +1 -1
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/build-server.js +1 -1
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/mcp/embed-app.d.ts.map +1 -1
- package/dist/mcp/embed-app.js +11 -1
- package/dist/mcp/embed-app.js.map +1 -1
- package/dist/observability/routes.d.ts +7 -7
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/resources/handlers.d.ts +2 -2
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +21 -9
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +2 -2
- package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +13 -0
- package/dist/templates/workspace-core/.agents/skills/extensions/references/api.md +2 -0
- package/dist/templates/workspace-core/.agents/skills/generative-ui/SKILL.md +115 -0
- package/docs/content/actions.md +4 -2
- package/docs/content/agent-surfaces.md +9 -0
- package/docs/content/extensions.md +10 -0
- package/docs/content/generative-ui.md +217 -0
- package/docs/content/key-concepts.md +2 -2
- package/docs/content/mcp-apps.md +3 -5
- package/docs/content/native-chat-ui.md +9 -5
- package/docs/content/tracking.md +9 -3
- package/package.json +1 -1
- package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +13 -0
- package/src/templates/workspace-core/.agents/skills/extensions/references/api.md +2 -0
- package/src/templates/workspace-core/.agents/skills/generative-ui/SKILL.md +115 -0
|
@@ -49,11 +49,11 @@ export declare const postAwareness: import("h3").EventHandlerWithFetch<import("h
|
|
|
49
49
|
error: string;
|
|
50
50
|
states?: undefined;
|
|
51
51
|
} | {
|
|
52
|
+
error?: undefined;
|
|
52
53
|
states: {
|
|
53
54
|
clientId: number;
|
|
54
55
|
state: string;
|
|
55
56
|
}[];
|
|
56
|
-
error?: undefined;
|
|
57
57
|
}>>;
|
|
58
58
|
/**
|
|
59
59
|
* GET /_agent-native/collab/:docId/users
|
|
@@ -64,10 +64,10 @@ export declare const getActiveUsers: import("h3").EventHandlerWithFetch<import("
|
|
|
64
64
|
error: string;
|
|
65
65
|
users?: undefined;
|
|
66
66
|
} | {
|
|
67
|
+
error?: undefined;
|
|
67
68
|
users: {
|
|
68
69
|
clientId: number;
|
|
69
70
|
lastSeen: number;
|
|
70
71
|
}[];
|
|
71
|
-
error?: undefined;
|
|
72
72
|
}>>;
|
|
73
73
|
//# sourceMappingURL=awareness.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"awareness.d.ts","sourceRoot":"","sources":["../../src/collab/awareness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAS3C,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAOD,eAAO,MAAM,sBAAsB,EAAG,kBAA2B,CAAC;AAElE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,kBAAkB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,MAAM,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,wBAAgB,mBAAmB,IAAI,YAAY,CAElD;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,EAClD,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,IAAI,CAUN;AAKD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAO1E;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,IAAI,CAOnE;AAUD;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa
|
|
1
|
+
{"version":3,"file":"awareness.d.ts","sourceRoot":"","sources":["../../src/collab/awareness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAS3C,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAOD,eAAO,MAAM,sBAAsB,EAAG,kBAA2B,CAAC;AAElE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,kBAAkB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,MAAM,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,wBAAgB,mBAAmB,IAAI,YAAY,CAElD;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,EAClD,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,IAAI,CAUN;AAKD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAO1E;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,IAAI,CAOnE;AAUD;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa;;;;;;kBAuCa,MAAM;eAAS,MAAM;;GAa1D,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,cAAc;;;;;;kBAWM,MAAM;kBAAY,MAAM;;GAMvD,CAAC"}
|
package/dist/collab/routes.d.ts
CHANGED
|
@@ -26,8 +26,8 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
|
|
|
26
26
|
* Body: { update: string (base64), requestSource?: string }
|
|
27
27
|
*/
|
|
28
28
|
export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
29
|
-
ok?: undefined;
|
|
30
29
|
error: string;
|
|
30
|
+
ok?: undefined;
|
|
31
31
|
} | {
|
|
32
32
|
error?: undefined;
|
|
33
33
|
ok: boolean;
|
|
@@ -41,9 +41,9 @@ export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import
|
|
|
41
41
|
* Body: { text: string, fieldName?: string, requestSource?: string }
|
|
42
42
|
*/
|
|
43
43
|
export declare const postCollabText: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
44
|
-
text?: undefined;
|
|
45
44
|
ok?: undefined;
|
|
46
45
|
error: string;
|
|
46
|
+
text?: undefined;
|
|
47
47
|
} | {
|
|
48
48
|
error?: undefined;
|
|
49
49
|
ok: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/extensions/actions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/extensions/actions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAyChE,wBAAgB,4BAA4B,IAAI,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CA49B1E"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ACTION_CHAT_UI_INLINE_EXTENSION_RENDERER } from "../action-ui.js";
|
|
1
2
|
import { writeAppState } from "../application-state/script-helpers.js";
|
|
2
3
|
import { resolveAccess } from "../sharing/access.js";
|
|
3
4
|
import { getLocalExtension, isLocalExtensionRow, listLocalExtensions, } from "./local.js";
|
|
@@ -193,9 +194,178 @@ export function createExtensionActionEntries() {
|
|
|
193
194
|
},
|
|
194
195
|
readOnly: true,
|
|
195
196
|
},
|
|
197
|
+
"render-inline-extension": {
|
|
198
|
+
tool: {
|
|
199
|
+
description: "Render a one-time, transient sandboxed Alpine.js mini-app directly inside the chat. Use this for generated UI that should answer the current turn inline without saving anything to the Extensions view: calculators, adjustable controls, knobs, pickers, visualizers, temporary dashboards, and interactive results. The content must be a self-contained Alpine.js HTML body snippet that can use appAction(), appFetch(), dbQuery(), dbExec(), extensionFetch(), extensionData, agentNative.ui.output(value, opts?), and agentNative.chat.send()/sendToAgentChat(). Use agentNative.ui.output for passive current values from knobs, sliders, and selections; it writes application state at inline-ui:<inline extension id>:output, which the agent can read later with readAppState when the user says to use that value. Use agentNative.chat.send for visible submit/apply actions. For transient UIs, extensionData is browser-local throwaway state; use application_state/appFetch, appAction, ui.output, or chat.send for anything the agent or app must observe. Use semantic Tailwind colors (bg-background, text-foreground, bg-primary, etc.) so it inherits the parent app theme. Use create-extension instead when the user wants the UI saved or reusable.",
|
|
200
|
+
parameters: {
|
|
201
|
+
type: "object",
|
|
202
|
+
properties: {
|
|
203
|
+
name: {
|
|
204
|
+
type: "string",
|
|
205
|
+
description: "Short display name for the inline UI.",
|
|
206
|
+
},
|
|
207
|
+
description: {
|
|
208
|
+
type: "string",
|
|
209
|
+
description: "One-sentence summary of what the inline UI does.",
|
|
210
|
+
},
|
|
211
|
+
content: {
|
|
212
|
+
type: "string",
|
|
213
|
+
description: "Self-contained Alpine.js HTML body snippet. Do not include a full app build, React code, or source files. Required unless contentFromAttachment is set.",
|
|
214
|
+
},
|
|
215
|
+
contentFromAttachment: {
|
|
216
|
+
type: "string",
|
|
217
|
+
description: 'Render a pasted/attached HTML file verbatim without re-typing it. Set to an attachment name or "latest".',
|
|
218
|
+
},
|
|
219
|
+
context: {
|
|
220
|
+
type: "string",
|
|
221
|
+
description: "Optional JSON object passed to the iframe as slotContext for initial inputs from chat.",
|
|
222
|
+
},
|
|
223
|
+
initialHeight: {
|
|
224
|
+
type: "number",
|
|
225
|
+
description: "Optional initial iframe height in pixels before auto-resize reports. Defaults to 260.",
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
required: ["name"],
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
chatUI: {
|
|
232
|
+
renderer: ACTION_CHAT_UI_INLINE_EXTENSION_RENDERER,
|
|
233
|
+
title: "Inline extension",
|
|
234
|
+
},
|
|
235
|
+
maxResultChars: 220_000,
|
|
236
|
+
readOnly: true,
|
|
237
|
+
run: async (args, ctx) => {
|
|
238
|
+
const name = String(args?.name ?? "").trim();
|
|
239
|
+
if (!name)
|
|
240
|
+
return "Error: name is required.";
|
|
241
|
+
const resolved = resolveExtensionContent(args, ctx);
|
|
242
|
+
if ("error" in resolved)
|
|
243
|
+
return resolved.error;
|
|
244
|
+
const content = resolved.content.trim();
|
|
245
|
+
if (!content)
|
|
246
|
+
return "Error: content is required.";
|
|
247
|
+
const description = String(args?.description ?? "").trim();
|
|
248
|
+
const id = `inline-${Date.now().toString(36)}-${Math.random()
|
|
249
|
+
.toString(36)
|
|
250
|
+
.slice(2, 8)}`;
|
|
251
|
+
return {
|
|
252
|
+
ok: true,
|
|
253
|
+
inlineExtension: {
|
|
254
|
+
mode: "transient",
|
|
255
|
+
id,
|
|
256
|
+
name,
|
|
257
|
+
description,
|
|
258
|
+
content,
|
|
259
|
+
context: parseInlineContext(args?.context),
|
|
260
|
+
initialHeight: coerceInlineHeight(args?.initialHeight),
|
|
261
|
+
},
|
|
262
|
+
next: "Rendered inline in chat only. It is not saved in the Extensions view.",
|
|
263
|
+
};
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
"show-extension-inline": {
|
|
267
|
+
tool: {
|
|
268
|
+
description: "Render an existing saved extension inline in the chat. Use this when the user asks to load, reopen, reuse, or show a saved extension/widget/dashboard/calculator/mini-app in the conversation. Inline extensions can expose passive current values through agentNative.ui.output(value, opts?), which writes application state at inline-ui:<extension id>:output for the agent to read later with readAppState. Pass id when known; otherwise pass a search string and the action will use the best visible extension match.",
|
|
269
|
+
parameters: {
|
|
270
|
+
type: "object",
|
|
271
|
+
properties: {
|
|
272
|
+
id: {
|
|
273
|
+
type: "string",
|
|
274
|
+
description: "Extension id to render inline.",
|
|
275
|
+
},
|
|
276
|
+
search: {
|
|
277
|
+
type: "string",
|
|
278
|
+
description: "Fallback search matched against id, name, description, and owner email when id is unknown.",
|
|
279
|
+
},
|
|
280
|
+
context: {
|
|
281
|
+
type: "string",
|
|
282
|
+
description: "Optional JSON object passed to the iframe as slotContext for chat-provided inputs.",
|
|
283
|
+
},
|
|
284
|
+
initialHeight: {
|
|
285
|
+
type: "number",
|
|
286
|
+
description: "Optional initial iframe height in pixels before auto-resize reports. Defaults to 260.",
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
chatUI: {
|
|
292
|
+
renderer: ACTION_CHAT_UI_INLINE_EXTENSION_RENDERER,
|
|
293
|
+
title: "Inline extension",
|
|
294
|
+
},
|
|
295
|
+
readOnly: true,
|
|
296
|
+
run: async (args) => {
|
|
297
|
+
let id = String(args?.id ?? "").trim();
|
|
298
|
+
const search = String(args?.search ?? "")
|
|
299
|
+
.trim()
|
|
300
|
+
.toLowerCase();
|
|
301
|
+
if (!id && search) {
|
|
302
|
+
const hiddenIds = await getHiddenExtensionIdsForCurrentUser();
|
|
303
|
+
const rows = [
|
|
304
|
+
...(await listExtensions({
|
|
305
|
+
includeHidden: false,
|
|
306
|
+
includeGloballyHidden: false,
|
|
307
|
+
})),
|
|
308
|
+
...(await listLocalExtensions()),
|
|
309
|
+
];
|
|
310
|
+
const match = rows.find((row) => [row.id, row.name, row.description, row.ownerEmail]
|
|
311
|
+
.join("\n")
|
|
312
|
+
.toLowerCase()
|
|
313
|
+
.includes(search));
|
|
314
|
+
if (match) {
|
|
315
|
+
id = match.id;
|
|
316
|
+
}
|
|
317
|
+
else {
|
|
318
|
+
return {
|
|
319
|
+
ok: false,
|
|
320
|
+
error: `No extension matched "${args?.search}".`,
|
|
321
|
+
available: await Promise.all(rows
|
|
322
|
+
.slice(0, 10)
|
|
323
|
+
.map((row) => summarizeExtension(row, hiddenIds, false))),
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
if (!id)
|
|
328
|
+
return "Error: provide id or search.";
|
|
329
|
+
const localExtension = await getLocalExtension(id);
|
|
330
|
+
const hiddenIds = await getHiddenExtensionIdsForCurrentUser();
|
|
331
|
+
if (localExtension) {
|
|
332
|
+
const summary = await summarizeExtension(localExtension, hiddenIds, false);
|
|
333
|
+
return {
|
|
334
|
+
ok: true,
|
|
335
|
+
inlineExtension: {
|
|
336
|
+
mode: "persisted",
|
|
337
|
+
id: summary.id,
|
|
338
|
+
name: summary.name,
|
|
339
|
+
description: summary.description,
|
|
340
|
+
path: summary.path,
|
|
341
|
+
updatedAt: summary.updatedAt,
|
|
342
|
+
context: parseInlineContext(args?.context),
|
|
343
|
+
initialHeight: coerceInlineHeight(args?.initialHeight),
|
|
344
|
+
},
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
const extension = await getExtension(id);
|
|
348
|
+
if (!extension)
|
|
349
|
+
return `Error: extension not found: ${id}`;
|
|
350
|
+
const summary = await summarizeExtension(extension, hiddenIds, false);
|
|
351
|
+
return {
|
|
352
|
+
ok: true,
|
|
353
|
+
inlineExtension: {
|
|
354
|
+
mode: "persisted",
|
|
355
|
+
id: summary.id,
|
|
356
|
+
name: summary.name,
|
|
357
|
+
description: summary.description,
|
|
358
|
+
path: summary.path,
|
|
359
|
+
updatedAt: summary.updatedAt,
|
|
360
|
+
context: parseInlineContext(args?.context),
|
|
361
|
+
initialHeight: coerceInlineHeight(args?.initialHeight),
|
|
362
|
+
},
|
|
363
|
+
};
|
|
364
|
+
},
|
|
365
|
+
},
|
|
196
366
|
"create-extension": {
|
|
197
367
|
tool: {
|
|
198
|
-
description: 'Create a sandboxed Alpine.js mini-app extension. Use this when the user
|
|
368
|
+
description: 'Create a persisted sandboxed Alpine.js mini-app extension and render it inline in the chat. Use this when the user wants generated UI that should be saved, reusable, or visible in the Extensions view: extensions, widgets, dashboards, calculators, mini-apps, and reusable interactive utilities. For one-time chat-only UI, use render-inline-extension instead. The content must be a self-contained Alpine.js HTML body snippet that can use appAction(), appFetch(), dbQuery(), dbExec(), extensionFetch(), extensionData, agentNative.ui.output(value, opts?), and agentNative.chat.send()/sendToAgentChat(). Use agentNative.ui.output for passive current values from knobs, sliders, and selections; it writes application state at inline-ui:<extension id>:output, which the agent can read later with readAppState when the user says to use that value. Use agentNative.chat.send for visible submit/apply actions. Persist reusable user-edited state with extensionData: if the extension has checkboxes, todos, notes, filters, preferences, or any control whose value should survive reload/reopen, load that state on init and save changes with extensionData, usually at user scope, instead of keeping it only in Alpine state. IMPORTANT — hosting a pasted file: if the user pasted a large HTML/Alpine file (it appears in your context as an <attachment name="pasted-text-…"> block) and asked you to host it as-is, do NOT copy that file into `content`. Instead leave `content` empty and pass `contentFromAttachment` set to that attachment\'s name (or the literal "latest" for the most recent pasted block) — the server reads the file verbatim. Re-emitting a large pasted file as `content` regularly gets cut off mid-stream and stalls the turn. Prefer appAction(name, params) for app data and actions, including read actions mounted as GET; do not call template /api/* routes from appFetch because the extension bridge only allows framework /_agent-native/* paths. Parse JSON string action results before aggregating; use dbQuery()/dbExec() only for known existing SQL tables. Keep the initial create-extension payload compact and working; for complex extensions, create a useful v1 first, then use focused update-extension edits for refinements rather than assembling one enormous initial tool input. For any non-trivial component (more than a couple of state fields, any methods, any string formatting, any branching) put the component in a <script> block via Alpine.data(\'name\', () => ({...})) and reference it with x-data="name" — do NOT cram methods, template literals, or branching logic into an inline x-data="{...}" attribute (HTML parser pitfalls cause ReferenceError failures). Define every variable referenced from x-text/x-show/x-if/x-for on the data object\'s initial state. If the extension\'s value depends on an LLM call, require a real key via \\${keys.OPENAI_API_KEY}/\\${keys.ANTHROPIC_API_KEY} (and tell the user to add it in the Dispatch Vault, or in app Settings → API Keys & Connections for standalone apps, if missing) or route the AI work to the agent chat — never ship a stubbed analysis step that renders a placeholder/boolean as the result.',
|
|
199
369
|
parameters: {
|
|
200
370
|
type: "object",
|
|
201
371
|
properties: {
|
|
@@ -223,6 +393,10 @@ export function createExtensionActionEntries() {
|
|
|
223
393
|
required: ["name"],
|
|
224
394
|
},
|
|
225
395
|
},
|
|
396
|
+
chatUI: {
|
|
397
|
+
renderer: ACTION_CHAT_UI_INLINE_EXTENSION_RENDERER,
|
|
398
|
+
title: "Extension",
|
|
399
|
+
},
|
|
226
400
|
run: async (args, ctx) => {
|
|
227
401
|
const name = String(args?.name ?? "").trim();
|
|
228
402
|
if (!name)
|
|
@@ -889,6 +1063,31 @@ function resolveExtensionContent(args, ctx) {
|
|
|
889
1063
|
function coerceBoolean(value) {
|
|
890
1064
|
return value === true || value === "true";
|
|
891
1065
|
}
|
|
1066
|
+
function parseInlineContext(value) {
|
|
1067
|
+
if (value === undefined || value === null || value === "")
|
|
1068
|
+
return undefined;
|
|
1069
|
+
const parsed = typeof value === "string"
|
|
1070
|
+
? (() => {
|
|
1071
|
+
try {
|
|
1072
|
+
return JSON.parse(value);
|
|
1073
|
+
}
|
|
1074
|
+
catch {
|
|
1075
|
+
return undefined;
|
|
1076
|
+
}
|
|
1077
|
+
})()
|
|
1078
|
+
: value;
|
|
1079
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
1080
|
+
? parsed
|
|
1081
|
+
: undefined;
|
|
1082
|
+
}
|
|
1083
|
+
function coerceInlineHeight(value) {
|
|
1084
|
+
if (value === undefined || value === null || value === "")
|
|
1085
|
+
return undefined;
|
|
1086
|
+
const height = Number(value);
|
|
1087
|
+
if (!Number.isFinite(height) || height <= 0)
|
|
1088
|
+
return undefined;
|
|
1089
|
+
return Math.min(Math.max(Math.round(height), 120), 1000);
|
|
1090
|
+
}
|
|
892
1091
|
function coerceLimit(value) {
|
|
893
1092
|
const limit = Number(value ?? 100);
|
|
894
1093
|
if (!Number.isFinite(limit))
|