@agent-native/core 0.58.1 → 0.58.3
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/dist/agent/engine/translate-ai-sdk.d.ts.map +1 -1
- package/dist/agent/engine/translate-ai-sdk.js +1 -0
- package/dist/agent/engine/translate-ai-sdk.js.map +1 -1
- package/dist/agent/production-agent.d.ts +2 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +114 -19
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +10 -2
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/agent/tool-error-redaction.d.ts +4 -0
- package/dist/agent/tool-error-redaction.d.ts.map +1 -0
- package/dist/agent/tool-error-redaction.js +43 -0
- package/dist/agent/tool-error-redaction.js.map +1 -0
- package/dist/agent/types.d.ts +23 -6
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +29 -5
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/chat/attachment-adapters.d.ts.map +1 -1
- package/dist/client/chat/attachment-adapters.js +29 -4
- package/dist/client/chat/attachment-adapters.js.map +1 -1
- package/dist/client/composer/PromptComposer.d.ts.map +1 -1
- package/dist/client/composer/PromptComposer.js +5 -1
- package/dist/client/composer/PromptComposer.js.map +1 -1
- package/dist/client/composer/attachment-accept.d.ts +2 -0
- package/dist/client/composer/attachment-accept.d.ts.map +1 -1
- package/dist/client/composer/attachment-accept.js +30 -1
- package/dist/client/composer/attachment-accept.js.map +1 -1
- package/dist/data-widgets/index.d.ts +5 -5
- package/dist/file-upload/pre-upload-attachments.d.ts +2 -0
- package/dist/file-upload/pre-upload-attachments.d.ts.map +1 -1
- package/dist/file-upload/pre-upload-attachments.js +66 -9
- package/dist/file-upload/pre-upload-attachments.js.map +1 -1
- package/dist/scripts/db/tool-schemas.d.ts +3 -0
- package/dist/scripts/db/tool-schemas.d.ts.map +1 -0
- package/dist/scripts/db/tool-schemas.js +27 -0
- package/dist/scripts/db/tool-schemas.js.map +1 -0
- package/dist/scripts/dev/index.d.ts.map +1 -1
- package/dist/scripts/dev/index.js +2 -22
- package/dist/scripts/dev/index.js.map +1 -1
- package/dist/scripts/parse-args.js +1 -1
- package/dist/scripts/parse-args.js.map +1 -1
- package/dist/scripts/runner.js +1 -1
- package/dist/scripts/runner.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +16 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +69 -27
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/cli-capture.d.ts.map +1 -1
- package/dist/server/cli-capture.js +2 -1
- package/dist/server/cli-capture.js.map +1 -1
- package/dist/server/prompts/framework-core-compact.d.ts.map +1 -1
- package/dist/server/prompts/framework-core-compact.js +2 -1
- package/dist/server/prompts/framework-core-compact.js.map +1 -1
- package/dist/server/prompts/framework-core.d.ts.map +1 -1
- package/dist/server/prompts/framework-core.js +1 -0
- package/dist/server/prompts/framework-core.js.map +1 -1
- package/docs/content/native-chat-ui.md +12 -0
- package/package.json +2 -1
|
@@ -1,6 +1,29 @@
|
|
|
1
1
|
import { getActiveFileUploadProvider, uploadFile } from "./registry.js";
|
|
2
|
-
const IMAGE_DATA_URL_RE = /^data:(image\/[^;]+);base64,(.+)$/;
|
|
3
2
|
const FILE_DATA_URL_RE = /^data:([^;]+);base64,(.+)$/;
|
|
3
|
+
const SVG_REFERENCE_SECURITY_NOTE = "SVG content may contain active markup; use this URL as a file reference unless the target app sanitizes it.";
|
|
4
|
+
function normalizeContentType(value) {
|
|
5
|
+
return value?.split(";")[0]?.trim().toLowerCase() || undefined;
|
|
6
|
+
}
|
|
7
|
+
function hasSvgFilename(name) {
|
|
8
|
+
return /\.svg$/i.test(name ?? "");
|
|
9
|
+
}
|
|
10
|
+
function isSvgAttachment(args) {
|
|
11
|
+
return (normalizeContentType(args.contentType) === "image/svg+xml" ||
|
|
12
|
+
hasSvgFilename(args.name));
|
|
13
|
+
}
|
|
14
|
+
function isSvgPayload(args) {
|
|
15
|
+
const contentType = normalizeContentType(args.contentType);
|
|
16
|
+
return (contentType === "image/svg+xml" ||
|
|
17
|
+
((contentType === undefined ||
|
|
18
|
+
contentType === "application/octet-stream") &&
|
|
19
|
+
hasSvgFilename(args.name)));
|
|
20
|
+
}
|
|
21
|
+
function markReferenceOnlySvgAttachment(att, contentType) {
|
|
22
|
+
att.type = "file";
|
|
23
|
+
att.contentType = normalizeContentType(contentType) ?? "image/svg+xml";
|
|
24
|
+
att.referenceOnly = true;
|
|
25
|
+
att.securityNote = SVG_REFERENCE_SECURITY_NOTE;
|
|
26
|
+
}
|
|
4
27
|
function escapeXmlAttr(value) {
|
|
5
28
|
return value
|
|
6
29
|
.replace(/&/g, "&")
|
|
@@ -63,13 +86,23 @@ export async function preUploadAttachments(opts) {
|
|
|
63
86
|
continue;
|
|
64
87
|
if (att.url) {
|
|
65
88
|
// Already pre-uploaded earlier in the pipeline — reuse it.
|
|
89
|
+
const isReferenceOnlySvg = isSvgAttachment(att);
|
|
90
|
+
if (isReferenceOnlySvg) {
|
|
91
|
+
markReferenceOnlySvgAttachment(att, att.contentType);
|
|
92
|
+
}
|
|
66
93
|
const entry = {
|
|
67
94
|
name: att.name,
|
|
68
95
|
url: att.url,
|
|
69
96
|
provider: att.uploadProvider || "unknown",
|
|
70
97
|
contentType: att.contentType,
|
|
98
|
+
...(isReferenceOnlySvg
|
|
99
|
+
? {
|
|
100
|
+
referenceOnly: true,
|
|
101
|
+
securityNote: SVG_REFERENCE_SECURITY_NOTE,
|
|
102
|
+
}
|
|
103
|
+
: {}),
|
|
71
104
|
};
|
|
72
|
-
if (isImage) {
|
|
105
|
+
if (isImage && !isReferenceOnlySvg) {
|
|
73
106
|
uploaded.push(entry);
|
|
74
107
|
}
|
|
75
108
|
else {
|
|
@@ -77,11 +110,15 @@ export async function preUploadAttachments(opts) {
|
|
|
77
110
|
}
|
|
78
111
|
continue;
|
|
79
112
|
}
|
|
80
|
-
const
|
|
81
|
-
const match = att.data.match(re);
|
|
113
|
+
const match = att.data.match(FILE_DATA_URL_RE);
|
|
82
114
|
if (!match)
|
|
83
115
|
continue;
|
|
84
|
-
const
|
|
116
|
+
const dataUrlMimeType = normalizeContentType(match[1]);
|
|
117
|
+
const mimeType = dataUrlMimeType || normalizeContentType(att.contentType) || match[1];
|
|
118
|
+
const uploadAsImage = isImage && !isSvgPayload({ name: att.name, contentType: mimeType });
|
|
119
|
+
const uploadAsFile = !uploadAsImage && (isImage || (includeFiles && isFile));
|
|
120
|
+
if (!uploadAsImage && !uploadAsFile)
|
|
121
|
+
continue;
|
|
85
122
|
let bytes;
|
|
86
123
|
try {
|
|
87
124
|
bytes = new Uint8Array(Buffer.from(match[2], "base64"));
|
|
@@ -97,20 +134,33 @@ export async function preUploadAttachments(opts) {
|
|
|
97
134
|
ownerEmail: opts.ownerEmail || undefined,
|
|
98
135
|
});
|
|
99
136
|
if (!result) {
|
|
100
|
-
if (
|
|
137
|
+
if (uploadAsImage)
|
|
101
138
|
providerMissing = true;
|
|
102
139
|
continue;
|
|
103
140
|
}
|
|
104
141
|
att.url = result.url;
|
|
105
142
|
att.uploadProvider = result.provider;
|
|
143
|
+
const isReferenceOnlySvg = isSvgPayload({
|
|
144
|
+
name: att.name,
|
|
145
|
+
contentType: mimeType,
|
|
146
|
+
});
|
|
147
|
+
if (isReferenceOnlySvg) {
|
|
148
|
+
markReferenceOnlySvgAttachment(att, mimeType);
|
|
149
|
+
}
|
|
106
150
|
const entry = {
|
|
107
151
|
name: att.name,
|
|
108
152
|
url: result.url,
|
|
109
153
|
provider: result.provider,
|
|
110
|
-
contentType: att.contentType,
|
|
154
|
+
contentType: isReferenceOnlySvg ? att.contentType : mimeType,
|
|
111
155
|
sizeBytes: bytes.byteLength,
|
|
156
|
+
...(isReferenceOnlySvg
|
|
157
|
+
? {
|
|
158
|
+
referenceOnly: true,
|
|
159
|
+
securityNote: SVG_REFERENCE_SECURITY_NOTE,
|
|
160
|
+
}
|
|
161
|
+
: {}),
|
|
112
162
|
};
|
|
113
|
-
if (
|
|
163
|
+
if (uploadAsImage) {
|
|
114
164
|
uploaded.push(entry);
|
|
115
165
|
}
|
|
116
166
|
else {
|
|
@@ -141,11 +191,18 @@ export async function preUploadAttachments(opts) {
|
|
|
141
191
|
`url="${escapeXmlAttr(f.url)}"`,
|
|
142
192
|
f.contentType ? `contentType="${escapeXmlAttr(f.contentType)}"` : null,
|
|
143
193
|
`provider="${escapeXmlAttr(f.provider)}"`,
|
|
194
|
+
f.referenceOnly ? `referenceOnly="true"` : null,
|
|
195
|
+
f.securityNote
|
|
196
|
+
? `securityNote="${escapeXmlAttr(f.securityNote)}"`
|
|
197
|
+
: null,
|
|
144
198
|
].filter(Boolean);
|
|
145
199
|
lines.push(`<chat-file-attachment ${attrs.join(" ")} />`);
|
|
146
200
|
}
|
|
201
|
+
const hasReferenceOnlySvg = uploadedFiles.some((file) => file.referenceOnly && isSvgAttachment(file));
|
|
147
202
|
injectedText = [
|
|
148
|
-
|
|
203
|
+
hasReferenceOnlySvg
|
|
204
|
+
? '<chat-attachments note="The user attached these files. Image attachment URLs may be used for embedding. File attachment URLs are references; SVG files are unsanitized vector source and must not be inlined as HTML or embedded in outbound content unless the target app sanitizes or stores them safely.">'
|
|
205
|
+
: '<chat-attachments note="The user attached these files. Image attachment URLs may be used for embedding in HTML, slide content, or outbound messages. File attachment URLs are references for reading or attaching in target apps.">',
|
|
149
206
|
...lines,
|
|
150
207
|
"</chat-attachments>",
|
|
151
208
|
].join("\n");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pre-upload-attachments.js","sourceRoot":"","sources":["../../src/file-upload/pre-upload-attachments.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentChatAttachment } from \"../agent/types.js\";\nimport { getActiveFileUploadProvider, uploadFile } from \"./registry.js\";\n\nexport interface PreUploadedImageAttachment {\n name?: string;\n url: string;\n provider: string;\n contentType?: string;\n}\n\n/**\n * A file/non-image attachment that was successfully uploaded to a hosted URL.\n * Consumers can use the URL in place of the base64 data to avoid persisting\n * large blobs in the thread repo and SQL.\n */\nexport interface PreUploadedFileAttachment {\n name?: string;\n url: string;\n provider: string;\n contentType?: string;\n sizeBytes?: number;\n}\n\nexport interface PreUploadAttachmentsResult {\n /** Same array reference. Each image attachment that was uploaded also gets a\n * `url` property attached (non-breaking; consumers that don't read it are\n * unaffected). */\n attachments: AgentChatAttachment[];\n /** Set when at least one image was uploaded. List of hosted URLs the agent\n * can embed in HTML, slide content, documents, etc. */\n uploaded: PreUploadedImageAttachment[];\n /** Uploaded non-image files (PDF, generic binary). Parallel to `uploaded`\n * but for the file/document attachment type. */\n uploadedFiles: PreUploadedFileAttachment[];\n /** True if at least one image attachment failed to upload because no\n * file-upload provider is configured. Templates use this to render a\n * \"Connect Builder.io\" suggestion. */\n providerMissing: boolean;\n /** A pre-formatted block to inject into the user message text so the agent\n * has each hosted URL inline. Null when nothing was uploaded or no provider\n * is configured. */\n injectedText: string | null;\n}\n\nconst IMAGE_DATA_URL_RE = /^data:(image\\/[^;]+);base64,(.+)$/;\nconst FILE_DATA_URL_RE = /^data:([^;]+);base64,(.+)$/;\n\nfunction escapeXmlAttr(value: string): string {\n return value\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\");\n}\n\n/**\n * Returns true when a file-upload provider is currently configured.\n * Used to decide whether to attempt upload-first or fall back to base64.\n */\nexport function isFileUploadProviderConfigured(): boolean {\n return getActiveFileUploadProvider() !== null;\n}\n\n/**\n * Pre-upload chat image attachments through the active file-upload provider\n * (Builder.io by default) so the agent can embed hosted URLs in HTML, slide\n * content, and outbound messages. Keeps the original base64 data URL on the\n * attachment so multimodal vision still works — only adds a hosted `url`.\n *\n * Safe to call when no provider is configured: it returns the attachments\n * untouched with `providerMissing: true` so callers can surface a connect-\n * Builder.io hint to the agent.\n */\nexport async function preUploadImageAttachments(opts: {\n attachments: AgentChatAttachment[] | undefined;\n ownerEmail: string | null | undefined;\n}): Promise<PreUploadAttachmentsResult> {\n return preUploadAttachments({ ...opts, includeFiles: false });\n}\n\n/**\n * Pre-upload ALL chat attachments (images AND files/PDFs) through the active\n * file-upload provider. When a provider is configured, each attachment gets a\n * `url` property injected so downstream code can store/send URLs instead of\n * base64. The base64 data is kept in-memory for the current turn so vision and\n * file-reading still work; callers that persist the attachment can drop the\n * data when a URL exists.\n *\n * Falls back gracefully when no provider is configured: returns untouched\n * attachments with `providerMissing: true` for image-type failures.\n */\nexport async function preUploadAttachments(opts: {\n attachments: AgentChatAttachment[] | undefined;\n ownerEmail: string | null | undefined;\n /** When false, only images are uploaded (legacy behaviour). Default: true */\n includeFiles?: boolean;\n}): Promise<PreUploadAttachmentsResult> {\n const list = Array.isArray(opts.attachments) ? opts.attachments : [];\n const includeFiles = opts.includeFiles !== false;\n const uploaded: PreUploadedImageAttachment[] = [];\n const uploadedFiles: PreUploadedFileAttachment[] = [];\n let providerMissing = false;\n\n if (list.length === 0) {\n return {\n attachments: list,\n uploaded,\n uploadedFiles,\n providerMissing: false,\n injectedText: null,\n };\n }\n\n for (const att of list) {\n const isImage = att.type === \"image\";\n const isFile = att.type === \"file\" || att.type === \"document\";\n if (!isImage && !(includeFiles && isFile)) continue;\n if (typeof att.data !== \"string\") continue;\n\n if ((att as any).url) {\n // Already pre-uploaded earlier in the pipeline — reuse it.\n const entry = {\n name: att.name,\n url: (att as any).url as string,\n provider: ((att as any).uploadProvider as string) || \"unknown\",\n contentType: att.contentType,\n };\n if (isImage) {\n uploaded.push(entry);\n } else {\n uploadedFiles.push(entry);\n }\n continue;\n }\n\n const re = isImage ? IMAGE_DATA_URL_RE : FILE_DATA_URL_RE;\n const match = att.data.match(re);\n if (!match) continue;\n const mimeType = att.contentType || match[1];\n let bytes: Uint8Array;\n try {\n bytes = new Uint8Array(Buffer.from(match[2], \"base64\"));\n } catch {\n continue;\n }\n\n try {\n const result = await uploadFile({\n data: bytes,\n filename: att.name,\n mimeType,\n ownerEmail: opts.ownerEmail || undefined,\n });\n if (!result) {\n if (isImage) providerMissing = true;\n continue;\n }\n (att as any).url = result.url;\n (att as any).uploadProvider = result.provider;\n const entry = {\n name: att.name,\n url: result.url,\n provider: result.provider,\n contentType: att.contentType,\n sizeBytes: bytes.byteLength,\n };\n if (isImage) {\n uploaded.push(entry);\n } else {\n uploadedFiles.push(entry);\n }\n } catch (err) {\n // Real upload failure (network, API). Keep the base64 so the model\n // can still see the image/file, but don't crash the turn.\n console.warn(\n \"[agent-native] pre-upload of chat attachment failed:\",\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n\n let injectedText: string | null = null;\n if (uploaded.length > 0 || uploadedFiles.length > 0) {\n const lines: string[] = [];\n for (const u of uploaded) {\n const attrs = [\n u.name ? `name=\"${escapeXmlAttr(u.name)}\"` : null,\n `url=\"${escapeXmlAttr(u.url)}\"`,\n u.contentType ? `contentType=\"${escapeXmlAttr(u.contentType)}\"` : null,\n `provider=\"${escapeXmlAttr(u.provider)}\"`,\n ].filter(Boolean);\n lines.push(`<chat-image-attachment ${attrs.join(\" \")} />`);\n }\n for (const f of uploadedFiles) {\n const attrs = [\n f.name ? `name=\"${escapeXmlAttr(f.name)}\"` : null,\n `url=\"${escapeXmlAttr(f.url)}\"`,\n f.contentType ? `contentType=\"${escapeXmlAttr(f.contentType)}\"` : null,\n `provider=\"${escapeXmlAttr(f.provider)}\"`,\n ].filter(Boolean);\n lines.push(`<chat-file-attachment ${attrs.join(\" \")} />`);\n }\n injectedText = [\n '<chat-attachments note=\"The user attached these files. They have been uploaded — use the url attribute when embedding in HTML, slide content, or any outbound message.\">',\n ...lines,\n \"</chat-attachments>\",\n ].join(\"\\n\");\n } else if (providerMissing) {\n injectedText = [\n \"<chat-image-attachment-upload-error>\",\n \"The user attached one or more images, but no file-upload provider is configured for this app.\",\n \"Tell the user to connect or reconnect Builder.io from Settings → File uploads. If `connect-builder` is available, use it to render the inline connection card. Workspaces with a custom storage provider can also use one registered via registerFileUploadProvider().\",\n \"Until that's done, you can still SEE the image, but you do NOT have a URL to embed it in HTML or share with other apps.\",\n \"</chat-image-attachment-upload-error>\",\n ].join(\"\\n\");\n }\n\n return {\n attachments: list,\n uploaded,\n uploadedFiles,\n providerMissing,\n injectedText,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"pre-upload-attachments.js","sourceRoot":"","sources":["../../src/file-upload/pre-upload-attachments.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentChatAttachment } from \"../agent/types.js\";\nimport { getActiveFileUploadProvider, uploadFile } from \"./registry.js\";\n\nexport interface PreUploadedImageAttachment {\n name?: string;\n url: string;\n provider: string;\n contentType?: string;\n}\n\n/**\n * A file/non-image attachment that was successfully uploaded to a hosted URL.\n * Consumers can use the URL in place of the base64 data to avoid persisting\n * large blobs in the thread repo and SQL.\n */\nexport interface PreUploadedFileAttachment {\n name?: string;\n url: string;\n provider: string;\n contentType?: string;\n sizeBytes?: number;\n referenceOnly?: boolean;\n securityNote?: string;\n}\n\nexport interface PreUploadAttachmentsResult {\n /** Same array reference. Each image attachment that was uploaded also gets a\n * `url` property attached (non-breaking; consumers that don't read it are\n * unaffected). */\n attachments: AgentChatAttachment[];\n /** Set when at least one image was uploaded. List of hosted URLs the agent\n * can embed in HTML, slide content, documents, etc. */\n uploaded: PreUploadedImageAttachment[];\n /** Uploaded non-image files (PDF, generic binary). Parallel to `uploaded`\n * but for the file/document attachment type. */\n uploadedFiles: PreUploadedFileAttachment[];\n /** True if at least one image attachment failed to upload because no\n * file-upload provider is configured. Templates use this to render a\n * \"Connect Builder.io\" suggestion. */\n providerMissing: boolean;\n /** A pre-formatted block to inject into the user message text so the agent\n * has each hosted URL inline. Null when nothing was uploaded or no provider\n * is configured. */\n injectedText: string | null;\n}\n\nconst FILE_DATA_URL_RE = /^data:([^;]+);base64,(.+)$/;\nconst SVG_REFERENCE_SECURITY_NOTE =\n \"SVG content may contain active markup; use this URL as a file reference unless the target app sanitizes it.\";\n\nfunction normalizeContentType(value: string | undefined): string | undefined {\n return value?.split(\";\")[0]?.trim().toLowerCase() || undefined;\n}\n\nfunction hasSvgFilename(name: string | undefined): boolean {\n return /\\.svg$/i.test(name ?? \"\");\n}\n\nfunction isSvgAttachment(args: {\n name?: string;\n contentType?: string;\n}): boolean {\n return (\n normalizeContentType(args.contentType) === \"image/svg+xml\" ||\n hasSvgFilename(args.name)\n );\n}\n\nfunction isSvgPayload(args: { name?: string; contentType?: string }): boolean {\n const contentType = normalizeContentType(args.contentType);\n return (\n contentType === \"image/svg+xml\" ||\n ((contentType === undefined ||\n contentType === \"application/octet-stream\") &&\n hasSvgFilename(args.name))\n );\n}\n\nfunction markReferenceOnlySvgAttachment(\n att: AgentChatAttachment,\n contentType: string | undefined,\n) {\n att.type = \"file\";\n att.contentType = normalizeContentType(contentType) ?? \"image/svg+xml\";\n (att as any).referenceOnly = true;\n (att as any).securityNote = SVG_REFERENCE_SECURITY_NOTE;\n}\n\nfunction escapeXmlAttr(value: string): string {\n return value\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\");\n}\n\n/**\n * Returns true when a file-upload provider is currently configured.\n * Used to decide whether to attempt upload-first or fall back to base64.\n */\nexport function isFileUploadProviderConfigured(): boolean {\n return getActiveFileUploadProvider() !== null;\n}\n\n/**\n * Pre-upload chat image attachments through the active file-upload provider\n * (Builder.io by default) so the agent can embed hosted URLs in HTML, slide\n * content, and outbound messages. Keeps the original base64 data URL on the\n * attachment so multimodal vision still works — only adds a hosted `url`.\n *\n * Safe to call when no provider is configured: it returns the attachments\n * untouched with `providerMissing: true` so callers can surface a connect-\n * Builder.io hint to the agent.\n */\nexport async function preUploadImageAttachments(opts: {\n attachments: AgentChatAttachment[] | undefined;\n ownerEmail: string | null | undefined;\n}): Promise<PreUploadAttachmentsResult> {\n return preUploadAttachments({ ...opts, includeFiles: false });\n}\n\n/**\n * Pre-upload ALL chat attachments (images AND files/PDFs) through the active\n * file-upload provider. When a provider is configured, each attachment gets a\n * `url` property injected so downstream code can store/send URLs instead of\n * base64. The base64 data is kept in-memory for the current turn so vision and\n * file-reading still work; callers that persist the attachment can drop the\n * data when a URL exists.\n *\n * Falls back gracefully when no provider is configured: returns untouched\n * attachments with `providerMissing: true` for image-type failures.\n */\nexport async function preUploadAttachments(opts: {\n attachments: AgentChatAttachment[] | undefined;\n ownerEmail: string | null | undefined;\n /** When false, only images are uploaded (legacy behaviour). Default: true */\n includeFiles?: boolean;\n}): Promise<PreUploadAttachmentsResult> {\n const list = Array.isArray(opts.attachments) ? opts.attachments : [];\n const includeFiles = opts.includeFiles !== false;\n const uploaded: PreUploadedImageAttachment[] = [];\n const uploadedFiles: PreUploadedFileAttachment[] = [];\n let providerMissing = false;\n\n if (list.length === 0) {\n return {\n attachments: list,\n uploaded,\n uploadedFiles,\n providerMissing: false,\n injectedText: null,\n };\n }\n\n for (const att of list) {\n const isImage = att.type === \"image\";\n const isFile = att.type === \"file\" || att.type === \"document\";\n if (!isImage && !(includeFiles && isFile)) continue;\n if (typeof att.data !== \"string\") continue;\n\n if ((att as any).url) {\n // Already pre-uploaded earlier in the pipeline — reuse it.\n const isReferenceOnlySvg = isSvgAttachment(att);\n if (isReferenceOnlySvg) {\n markReferenceOnlySvgAttachment(att, att.contentType);\n }\n const entry = {\n name: att.name,\n url: (att as any).url as string,\n provider: ((att as any).uploadProvider as string) || \"unknown\",\n contentType: att.contentType,\n ...(isReferenceOnlySvg\n ? {\n referenceOnly: true,\n securityNote: SVG_REFERENCE_SECURITY_NOTE,\n }\n : {}),\n };\n if (isImage && !isReferenceOnlySvg) {\n uploaded.push(entry);\n } else {\n uploadedFiles.push(entry);\n }\n continue;\n }\n\n const match = att.data.match(FILE_DATA_URL_RE);\n if (!match) continue;\n const dataUrlMimeType = normalizeContentType(match[1]);\n const mimeType =\n dataUrlMimeType || normalizeContentType(att.contentType) || match[1];\n const uploadAsImage =\n isImage && !isSvgPayload({ name: att.name, contentType: mimeType });\n const uploadAsFile =\n !uploadAsImage && (isImage || (includeFiles && isFile));\n if (!uploadAsImage && !uploadAsFile) continue;\n\n let bytes: Uint8Array;\n try {\n bytes = new Uint8Array(Buffer.from(match[2], \"base64\"));\n } catch {\n continue;\n }\n\n try {\n const result = await uploadFile({\n data: bytes,\n filename: att.name,\n mimeType,\n ownerEmail: opts.ownerEmail || undefined,\n });\n if (!result) {\n if (uploadAsImage) providerMissing = true;\n continue;\n }\n (att as any).url = result.url;\n (att as any).uploadProvider = result.provider;\n const isReferenceOnlySvg = isSvgPayload({\n name: att.name,\n contentType: mimeType,\n });\n if (isReferenceOnlySvg) {\n markReferenceOnlySvgAttachment(att, mimeType);\n }\n const entry = {\n name: att.name,\n url: result.url,\n provider: result.provider,\n contentType: isReferenceOnlySvg ? att.contentType : mimeType,\n sizeBytes: bytes.byteLength,\n ...(isReferenceOnlySvg\n ? {\n referenceOnly: true,\n securityNote: SVG_REFERENCE_SECURITY_NOTE,\n }\n : {}),\n };\n if (uploadAsImage) {\n uploaded.push(entry);\n } else {\n uploadedFiles.push(entry);\n }\n } catch (err) {\n // Real upload failure (network, API). Keep the base64 so the model\n // can still see the image/file, but don't crash the turn.\n console.warn(\n \"[agent-native] pre-upload of chat attachment failed:\",\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n\n let injectedText: string | null = null;\n if (uploaded.length > 0 || uploadedFiles.length > 0) {\n const lines: string[] = [];\n for (const u of uploaded) {\n const attrs = [\n u.name ? `name=\"${escapeXmlAttr(u.name)}\"` : null,\n `url=\"${escapeXmlAttr(u.url)}\"`,\n u.contentType ? `contentType=\"${escapeXmlAttr(u.contentType)}\"` : null,\n `provider=\"${escapeXmlAttr(u.provider)}\"`,\n ].filter(Boolean);\n lines.push(`<chat-image-attachment ${attrs.join(\" \")} />`);\n }\n for (const f of uploadedFiles) {\n const attrs = [\n f.name ? `name=\"${escapeXmlAttr(f.name)}\"` : null,\n `url=\"${escapeXmlAttr(f.url)}\"`,\n f.contentType ? `contentType=\"${escapeXmlAttr(f.contentType)}\"` : null,\n `provider=\"${escapeXmlAttr(f.provider)}\"`,\n f.referenceOnly ? `referenceOnly=\"true\"` : null,\n f.securityNote\n ? `securityNote=\"${escapeXmlAttr(f.securityNote)}\"`\n : null,\n ].filter(Boolean);\n lines.push(`<chat-file-attachment ${attrs.join(\" \")} />`);\n }\n const hasReferenceOnlySvg = uploadedFiles.some(\n (file) => file.referenceOnly && isSvgAttachment(file),\n );\n injectedText = [\n hasReferenceOnlySvg\n ? '<chat-attachments note=\"The user attached these files. Image attachment URLs may be used for embedding. File attachment URLs are references; SVG files are unsanitized vector source and must not be inlined as HTML or embedded in outbound content unless the target app sanitizes or stores them safely.\">'\n : '<chat-attachments note=\"The user attached these files. Image attachment URLs may be used for embedding in HTML, slide content, or outbound messages. File attachment URLs are references for reading or attaching in target apps.\">',\n ...lines,\n \"</chat-attachments>\",\n ].join(\"\\n\");\n } else if (providerMissing) {\n injectedText = [\n \"<chat-image-attachment-upload-error>\",\n \"The user attached one or more images, but no file-upload provider is configured for this app.\",\n \"Tell the user to connect or reconnect Builder.io from Settings → File uploads. If `connect-builder` is available, use it to render the inline connection card. Workspaces with a custom storage provider can also use one registered via registerFileUploadProvider().\",\n \"Until that's done, you can still SEE the image, but you do NOT have a URL to embed it in HTML or share with other apps.\",\n \"</chat-image-attachment-upload-error>\",\n ].join(\"\\n\");\n }\n\n return {\n attachments: list,\n uploaded,\n uploadedFiles,\n providerMissing,\n injectedText,\n };\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-schemas.d.ts","sourceRoot":"","sources":["../../../src/scripts/db/tool-schemas.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,wBAAgB,oBAAoB,IAAI,WAAW,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CA4B5E"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export function dbExecToolParameters() {
|
|
2
|
+
return {
|
|
3
|
+
type: "object",
|
|
4
|
+
properties: {
|
|
5
|
+
sql: {
|
|
6
|
+
type: "string",
|
|
7
|
+
description: "Single INSERT / UPDATE / DELETE / REPLACE statement. Use parameterized placeholders (?) where possible.",
|
|
8
|
+
},
|
|
9
|
+
args: {
|
|
10
|
+
type: "string",
|
|
11
|
+
description: 'Optional JSON array of positional bind args for `sql`. Example: \'["published","form-123"]\'',
|
|
12
|
+
},
|
|
13
|
+
statements: {
|
|
14
|
+
type: "string",
|
|
15
|
+
description: 'Optional JSON array of write statements to execute in one transaction. Prefer this over multiple db-exec calls. Example: \'[{"sql":"INSERT INTO notes (id,title) VALUES (?,?)","args":["n1","One"]},{"sql":"UPDATE counters SET value = value + 1 WHERE key = ?","args":["notes"]}]\'',
|
|
16
|
+
},
|
|
17
|
+
format: {
|
|
18
|
+
type: "string",
|
|
19
|
+
description: 'Output format: "json" or "text" (default: text)',
|
|
20
|
+
enum: ["json", "text"],
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
additionalProperties: false,
|
|
24
|
+
oneOf: [{ required: ["sql"] }, { required: ["statements"] }],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=tool-schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-schemas.js","sourceRoot":"","sources":["../../../src/scripts/db/tool-schemas.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,oBAAoB;IAClC,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,GAAG,EAAE;gBACH,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,yGAAyG;aAC5G;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,8FAA8F;aACjG;YACD,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,uRAAuR;aAC1R;YACD,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,iDAAiD;gBAC9D,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;aACvB;SACF;QACD,oBAAoB,EAAE,KAAK;QAC3B,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC;KAC7D,CAAC;AACJ,CAAC","sourcesContent":["import type { ActionTool } from \"../../agent/types.js\";\n\nexport function dbExecToolParameters(): NonNullable<ActionTool[\"parameters\"]> {\n return {\n type: \"object\",\n properties: {\n sql: {\n type: \"string\",\n description:\n \"Single INSERT / UPDATE / DELETE / REPLACE statement. Use parameterized placeholders (?) where possible.\",\n },\n args: {\n type: \"string\",\n description:\n 'Optional JSON array of positional bind args for `sql`. Example: \\'[\"published\",\"form-123\"]\\'',\n },\n statements: {\n type: \"string\",\n description:\n 'Optional JSON array of write statements to execute in one transaction. Prefer this over multiple db-exec calls. Example: \\'[{\"sql\":\"INSERT INTO notes (id,title) VALUES (?,?)\",\"args\":[\"n1\",\"One\"]},{\"sql\":\"UPDATE counters SET value = value + 1 WHERE key = ?\",\"args\":[\"notes\"]}]\\'',\n },\n format: {\n type: \"string\",\n description: 'Output format: \"json\" or \"text\" (default: text)',\n enum: [\"json\", \"text\"],\n },\n },\n additionalProperties: false,\n oneOf: [{ required: [\"sql\"] }, { required: [\"statements\"] }],\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/scripts/dev/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/scripts/dev/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAuDnE;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,GAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAO,GACjE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAyLtC"}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* registered in production.
|
|
7
7
|
*/
|
|
8
8
|
import { createCodingToolRegistry } from "../../coding-tools/index.js";
|
|
9
|
+
import { dbExecToolParameters } from "../db/tool-schemas.js";
|
|
9
10
|
import { tool as readFileTool, run as readFileRun } from "./read-file.js";
|
|
10
11
|
import { tool as writeFileTool, run as writeFileRun } from "./write-file.js";
|
|
11
12
|
import { tool as listFilesTool, run as listFilesRun } from "./list-files.js";
|
|
@@ -103,28 +104,7 @@ export async function createDevScriptRegistry(options = {}) {
|
|
|
103
104
|
}, dbQuery.default, { readOnly: true }),
|
|
104
105
|
"db-exec": wrapCliScript({
|
|
105
106
|
description: "Execute app-database write SQL (INSERT, UPDATE, DELETE, REPLACE). For multiple related writes, pass `statements` so they run sequentially in one transaction instead of issuing several db-exec calls. Schema changes (CREATE/ALTER/DROP) are blocked. Never use this to backfill missing data for a read/analysis request or to create/modify users, members, roles, permissions, admin flags, or ownership; use a dedicated app action or reviewed code.",
|
|
106
|
-
parameters:
|
|
107
|
-
type: "object",
|
|
108
|
-
properties: {
|
|
109
|
-
sql: {
|
|
110
|
-
type: "string",
|
|
111
|
-
description: "Single INSERT / UPDATE / DELETE / REPLACE statement. Use parameterized placeholders (?) where possible.",
|
|
112
|
-
},
|
|
113
|
-
args: {
|
|
114
|
-
type: "string",
|
|
115
|
-
description: 'Optional JSON array of positional bind args for `sql`. Example: \'["published","form-123"]\'',
|
|
116
|
-
},
|
|
117
|
-
statements: {
|
|
118
|
-
type: "string",
|
|
119
|
-
description: 'Optional JSON array of write statements to execute in one transaction. Prefer this over multiple db-exec calls. Example: \'[{"sql":"INSERT INTO notes (id,title) VALUES (?,?)","args":["n1","One"]},{"sql":"UPDATE counters SET value = value + 1 WHERE key = ?","args":["notes"]}]\'',
|
|
120
|
-
},
|
|
121
|
-
format: {
|
|
122
|
-
type: "string",
|
|
123
|
-
description: 'Output format: "json" or "text" (default: text)',
|
|
124
|
-
enum: ["json", "text"],
|
|
125
|
-
},
|
|
126
|
-
},
|
|
127
|
-
},
|
|
107
|
+
parameters: dbExecToolParameters(),
|
|
128
108
|
}, dbExec.default),
|
|
129
109
|
"db-patch": wrapCliScript({
|
|
130
110
|
description: "Surgical search-and-replace on a text column in a SQL table. Prefer over `db-exec UPDATE` for large text fields (documents, slides, dashboards, JSON blobs) where you only need to change a small slice — avoids re-sending the full column value. Targets exactly one row at a time (narrow --where by primary key). If a template-specific action exists for the table (e.g. `edit-document`, `update-slide`), use that instead — it will also push live updates to open collaborative editors.",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/scripts/dev/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,EAAE,IAAI,IAAI,YAAY,EAAE,GAAG,IAAI,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EAAE,IAAI,IAAI,aAAa,EAAE,GAAG,IAAI,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EAAE,IAAI,IAAI,aAAa,EAAE,GAAG,IAAI,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EACL,IAAI,IAAI,eAAe,EACvB,GAAG,IAAI,cAAc,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,IAAI,IAAI,SAAS,EAAE,GAAG,IAAI,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEhE;;;GAGG;AACH,SAAS,aAAa,CACpB,IAAgB,EAChB,UAA6C,EAC7C,IAA6B;IAE7B,OAAO;QACL,IAAI;QACJ,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtD,GAAG,EAAE,KAAK,EAAE,IAA4B,EAAmB,EAAE;YAC3D,MAAM,OAAO,GAAa,EAAE,CAAC;YAC7B,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC1C,MAAM,GAAG,GAAG,CAAY,CAAC;gBACzB,MAAM,KAAK,GACT,GAAG,IAAI,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ;oBACpC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;oBACrB,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAClB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;YAChC,CAAC;YAED,6BAA6B;YAC7B,MAAM,IAAI,GAAa,EAAE,CAAC;YAC1B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC;YAC5B,OAAO,CAAC,GAAG,GAAG,CAAC,GAAG,CAAY,EAAE,EAAE;gBAChC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YACrC,CAAC,CAAC;YAEF,IAAI,CAAC;gBACH,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;YAC5B,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,EAAE,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACrD,CAAC;oBAAS,CAAC;gBACT,OAAO,CAAC,GAAG,GAAG,OAAO,CAAC;YACxB,CAAC;YAED,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC;QAC1C,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,UAAgE,EAAE;IAElE,kEAAkE;IAClE,IAAI,SAAS,GAAgC,EAAE,CAAC;IAChD,IAAI,OAAO,CAAC,aAAa,KAAK,KAAK,EAAE,CAAC;QACpC,IAAI,CAAC;YACH,yDAAyD;YACzD,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,CAAC,GACxD,MAAM,OAAO,CAAC,GAAG,CAAC;gBAChB,MAAM,CAAC,iBAAiB,CAAC;gBACzB,MAAM,CAAC,gBAAgB,CAAC;gBACxB,MAAM,CAAC,eAAe,CAAC;gBACvB,MAAM,CAAC,gBAAgB,CAAC;gBACxB,MAAM,CAAC,wBAAwB,CAAC;aACjC,CAAC,CAAC;YAEL,SAAS,GAAG;gBACV,WAAW,EAAE,aAAa,CACxB;oBACE,WAAW,EACT,4DAA4D;oBAC9D,UAAU,EAAE;wBACV,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE;4BACV,MAAM,EAAE;gCACN,IAAI,EAAE,QAAQ;gCACd,WAAW,EACT,iDAAiD;gCACnD,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;6BACvB;yBACF;qBACF;iBACF,EACD,QAAQ,CAAC,OAAO,EAChB,EAAE,QAAQ,EAAE,IAAI,EAAE,CACnB;gBACD,UAAU,EAAE,aAAa,CACvB;oBACE,WAAW,EACT,oFAAoF;oBACtF,UAAU,EAAE;wBACV,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE;4BACV,GAAG,EAAE;gCACH,IAAI,EAAE,QAAQ;gCACd,WAAW,EAAE,iCAAiC;6BAC/C;4BACD,IAAI,EAAE;gCACJ,IAAI,EAAE,QAAQ;gCACd,WAAW,EACT,+GAA+G;6BAClH;4BACD,MAAM,EAAE;gCACN,IAAI,EAAE,QAAQ;gCACd,WAAW,EACT,mDAAmD;gCACrD,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;6BACxB;yBACF;wBACD,QAAQ,EAAE,CAAC,KAAK,CAAC;qBAClB;iBACF,EACD,OAAO,CAAC,OAAO,EACf,EAAE,QAAQ,EAAE,IAAI,EAAE,CACnB;gBACD,SAAS,EAAE,aAAa,CACtB;oBACE,WAAW,EACT,4bAA4b;oBAC9b,UAAU,EAAE;wBACV,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE;4BACV,GAAG,EAAE;gCACH,IAAI,EAAE,QAAQ;gCACd,WAAW,EACT,yGAAyG;6BAC5G;4BACD,IAAI,EAAE;gCACJ,IAAI,EAAE,QAAQ;gCACd,WAAW,EACT,8FAA8F;6BACjG;4BACD,UAAU,EAAE;gCACV,IAAI,EAAE,QAAQ;gCACd,WAAW,EACT,uRAAuR;6BAC1R;4BACD,MAAM,EAAE;gCACN,IAAI,EAAE,QAAQ;gCACd,WAAW,EACT,iDAAiD;gCACnD,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;6BACvB;yBACF;qBACF;iBACF,EACD,MAAM,CAAC,OAAO,CACf;gBACD,UAAU,EAAE,aAAa,CACvB;oBACE,WAAW,EACT,meAAme;oBACre,UAAU,EAAE;wBACV,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE;4BACV,KAAK,EAAE;gCACL,IAAI,EAAE,QAAQ;gCACd,WAAW,EACT,kDAAkD;6BACrD;4BACD,MAAM,EAAE;gCACN,IAAI,EAAE,QAAQ;gCACd,WAAW,EACT,wDAAwD;6BAC3D;4BACD,KAAK,EAAE;gCACL,IAAI,EAAE,QAAQ;gCACd,WAAW,EACT,qHAAqH;6BACxH;4BACD,IAAI,EAAE;gCACJ,IAAI,EAAE,QAAQ;gCACd,WAAW,EACT,uDAAuD;6BAC1D;4BACD,OAAO,EAAE;gCACP,IAAI,EAAE,QAAQ;gCACd,WAAW,EACT,yEAAyE;6BAC5E;4BACD,KAAK,EAAE;gCACL,IAAI,EAAE,QAAQ;gCACd,WAAW,EACT,iIAAiI;6BACpI;4BACD,GAAG,EAAE;gCACH,IAAI,EAAE,QAAQ;gCACd,WAAW,EACT,0FAA0F;gCAC5F,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;6BACxB;4BACD,MAAM,EAAE;gCACN,IAAI,EAAE,QAAQ;gCACd,WAAW,EACT,iDAAiD;gCACnD,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;6BACvB;yBACF;wBACD,QAAQ,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC;qBACvC;iBACF,EACD,OAAO,CAAC,OAAO,CAChB;gBACD,kBAAkB,EAAE,aAAa,CAC/B;oBACE,WAAW,EACT,wFAAwF;oBAC1F,UAAU,EAAE;wBACV,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE;4BACV,aAAa,EAAE;gCACb,IAAI,EAAE,QAAQ;gCACd,WAAW,EACT,mEAAmE;gCACrE,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;6BACxB;4BACD,MAAM,EAAE;gCACN,IAAI,EAAE,QAAQ;gCACd,WAAW,EACT,iDAAiD;gCACnD,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;6BACvB;yBACF;qBACF;iBACF,EACD,cAAc,CAAC,OAAO,EACtB,EAAE,QAAQ,EAAE,IAAI,EAAE,CACnB;aACF,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,uDAAuD;QACzD,CAAC;IACH,CAAC;IAED,MAAM,aAAa,GAAG,wBAAwB,CAAC;QAC7C,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;QAClB,mBAAmB,EAAE,IAAI;KAC1B,CAAC,CAAC;IACH,MAAM,aAAa,GAAgC,OAAO,CAAC,aAAa;QACtE,CAAC,CAAC;YACE,WAAW,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE;YACrE,YAAY,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,YAAY,EAAE;YACxD,YAAY,EAAE;gBACZ,IAAI,EAAE,aAAa;gBACnB,GAAG,EAAE,YAAY;gBACjB,QAAQ,EAAE,IAAI;aACf;YACD,cAAc,EAAE;gBACd,IAAI,EAAE,eAAe;gBACrB,GAAG,EAAE,cAAc;gBACnB,QAAQ,EAAE,IAAI;aACf;YACD,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,QAAQ,EAAE;SAC1C;QACH,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO;QACL,GAAG,aAAa;QAChB,GAAG,aAAa;QAChB,GAAG,SAAS;KACb,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Dev-mode script registry.\n *\n * Provides shared coding and database tools for the agent\n * when running in development mode. These tools should NEVER be\n * registered in production.\n */\n\nimport type { ActionTool } from \"../../agent/types.js\";\nimport type { ActionEntry } from \"../../agent/production-agent.js\";\nimport { createCodingToolRegistry } from \"../../coding-tools/index.js\";\nimport { tool as readFileTool, run as readFileRun } from \"./read-file.js\";\nimport { tool as writeFileTool, run as writeFileRun } from \"./write-file.js\";\nimport { tool as listFilesTool, run as listFilesRun } from \"./list-files.js\";\nimport {\n tool as searchFilesTool,\n run as searchFilesRun,\n} from \"./search-files.js\";\nimport { tool as shellTool, run as shellRun } from \"./shell.js\";\n\n/**\n * Wraps a core CLI script (that writes to console.log) as a ActionEntry\n * by capturing stdout.\n */\nfunction wrapCliScript(\n tool: ActionTool,\n cliDefault: (args: string[]) => Promise<void>,\n opts?: { readOnly?: boolean },\n): ActionEntry {\n return {\n tool,\n ...(opts?.readOnly ? { readOnly: true as const } : {}),\n run: async (args: Record<string, string>): Promise<string> => {\n const cliArgs: string[] = [];\n for (const [k, v] of Object.entries(args)) {\n const raw = v as unknown;\n const value =\n raw != null && typeof raw === \"object\"\n ? JSON.stringify(raw)\n : String(raw);\n cliArgs.push(`--${k}`, value);\n }\n\n // Capture console.log output\n const logs: string[] = [];\n const origLog = console.log;\n console.log = (...a: unknown[]) => {\n logs.push(a.map(String).join(\" \"));\n };\n\n try {\n await cliDefault(cliArgs);\n } catch (err: any) {\n logs.push(`Error: ${err?.message ?? String(err)}`);\n } finally {\n console.log = origLog;\n }\n\n return logs.join(\"\\n\") || \"(no output)\";\n },\n };\n}\n\n/**\n * Creates the dev-mode script registry with shared bash/read/edit/write\n * coding tools and database tools. Call this and merge with your app's registry\n * when NODE_ENV !== \"production\".\n */\nexport async function createDevScriptRegistry(\n options: { legacyAliases?: boolean; databaseTools?: boolean } = {},\n): Promise<Record<string, ActionEntry>> {\n // Lazy-import DB scripts to avoid requiring libsql in non-DB apps\n let dbEntries: Record<string, ActionEntry> = {};\n if (options.databaseTools !== false) {\n try {\n // Dynamic imports — these are part of @agent-native/core\n const [dbSchema, dbQuery, dbExec, dbPatch, dbCheckScoping] =\n await Promise.all([\n import(\"../db/schema.js\"),\n import(\"../db/query.js\"),\n import(\"../db/exec.js\"),\n import(\"../db/patch.js\"),\n import(\"../db/check-scoping.js\"),\n ]);\n\n dbEntries = {\n \"db-schema\": wrapCliScript(\n {\n description:\n \"Show all database tables, columns, types, and foreign keys\",\n parameters: {\n type: \"object\",\n properties: {\n format: {\n type: \"string\",\n description:\n 'Output format: \"json\" or \"text\" (default: text)',\n enum: [\"json\", \"text\"],\n },\n },\n },\n },\n dbSchema.default,\n { readOnly: true },\n ),\n \"db-query\": wrapCliScript(\n {\n description:\n \"Run a read-only SQL query (SELECT, WITH, EXPLAIN, PRAGMA) against the app database\",\n parameters: {\n type: \"object\",\n properties: {\n sql: {\n type: \"string\",\n description: \"The SQL SELECT query to execute\",\n },\n args: {\n type: \"string\",\n description:\n 'Optional JSON array of positional bind args for parameterized placeholders. Example: \\'[\"draft\",\"form-123\"]\\'',\n },\n format: {\n type: \"string\",\n description:\n 'Output format: \"json\" or \"table\" (default: table)',\n enum: [\"json\", \"table\"],\n },\n },\n required: [\"sql\"],\n },\n },\n dbQuery.default,\n { readOnly: true },\n ),\n \"db-exec\": wrapCliScript(\n {\n description:\n \"Execute app-database write SQL (INSERT, UPDATE, DELETE, REPLACE). For multiple related writes, pass `statements` so they run sequentially in one transaction instead of issuing several db-exec calls. Schema changes (CREATE/ALTER/DROP) are blocked. Never use this to backfill missing data for a read/analysis request or to create/modify users, members, roles, permissions, admin flags, or ownership; use a dedicated app action or reviewed code.\",\n parameters: {\n type: \"object\",\n properties: {\n sql: {\n type: \"string\",\n description:\n \"Single INSERT / UPDATE / DELETE / REPLACE statement. Use parameterized placeholders (?) where possible.\",\n },\n args: {\n type: \"string\",\n description:\n 'Optional JSON array of positional bind args for `sql`. Example: \\'[\"published\",\"form-123\"]\\'',\n },\n statements: {\n type: \"string\",\n description:\n 'Optional JSON array of write statements to execute in one transaction. Prefer this over multiple db-exec calls. Example: \\'[{\"sql\":\"INSERT INTO notes (id,title) VALUES (?,?)\",\"args\":[\"n1\",\"One\"]},{\"sql\":\"UPDATE counters SET value = value + 1 WHERE key = ?\",\"args\":[\"notes\"]}]\\'',\n },\n format: {\n type: \"string\",\n description:\n 'Output format: \"json\" or \"text\" (default: text)',\n enum: [\"json\", \"text\"],\n },\n },\n },\n },\n dbExec.default,\n ),\n \"db-patch\": wrapCliScript(\n {\n description:\n \"Surgical search-and-replace on a text column in a SQL table. Prefer over `db-exec UPDATE` for large text fields (documents, slides, dashboards, JSON blobs) where you only need to change a small slice — avoids re-sending the full column value. Targets exactly one row at a time (narrow --where by primary key). If a template-specific action exists for the table (e.g. `edit-document`, `update-slide`), use that instead — it will also push live updates to open collaborative editors.\",\n parameters: {\n type: \"object\",\n properties: {\n table: {\n type: \"string\",\n description:\n \"Target table name (plain identifier, no quoting)\",\n },\n column: {\n type: \"string\",\n description:\n \"Target text column name (plain identifier, no quoting)\",\n },\n where: {\n type: \"string\",\n description:\n \"SQL WHERE clause that matches exactly one row, e.g. \\\"id = 'abc123'\\\". Must not contain semicolons or DDL keywords.\",\n },\n find: {\n type: \"string\",\n description:\n \"Text to find (single-edit mode). Pair with --replace.\",\n },\n replace: {\n type: \"string\",\n description:\n 'Replacement text (single-edit mode). Defaults to \"\" (delete the match).',\n },\n edits: {\n type: \"string\",\n description:\n 'Batch mode: JSON array of {find, replace} objects. Example: \\'[{\"find\":\"Q3\",\"replace\":\"Q4\"},{\"find\":\"$1M\",\"replace\":\"$1.2M\"}]\\'',\n },\n all: {\n type: \"string\",\n description:\n 'Set to \"true\" to replace every occurrence of each find (default: first occurrence only).',\n enum: [\"true\", \"false\"],\n },\n format: {\n type: \"string\",\n description:\n 'Output format: \"json\" or \"text\" (default: text)',\n enum: [\"json\", \"text\"],\n },\n },\n required: [\"table\", \"column\", \"where\"],\n },\n },\n dbPatch.default,\n ),\n \"db-check-scoping\": wrapCliScript(\n {\n description:\n \"Validate that all template tables have owner_email and org_id columns for data scoping\",\n parameters: {\n type: \"object\",\n properties: {\n \"require-org\": {\n type: \"string\",\n description:\n 'Set to \"true\" to also require org_id columns (for multi-org apps)',\n enum: [\"true\", \"false\"],\n },\n format: {\n type: \"string\",\n description:\n 'Output format: \"json\" or \"text\" (default: text)',\n enum: [\"json\", \"text\"],\n },\n },\n },\n },\n dbCheckScoping.default,\n { readOnly: true },\n ),\n };\n } catch {\n // DB scripts not available (no libsql) — skip silently\n }\n }\n\n const codingEntries = createCodingToolRegistry({\n cwd: process.cwd(),\n bashThrowsOnNonZero: true,\n });\n const legacyEntries: Record<string, ActionEntry> = options.legacyAliases\n ? {\n \"read-file\": { tool: readFileTool, run: readFileRun, readOnly: true },\n \"write-file\": { tool: writeFileTool, run: writeFileRun },\n \"list-files\": {\n tool: listFilesTool,\n run: listFilesRun,\n readOnly: true,\n },\n \"search-files\": {\n tool: searchFilesTool,\n run: searchFilesRun,\n readOnly: true,\n },\n shell: { tool: shellTool, run: shellRun },\n }\n : {};\n\n return {\n ...codingEntries,\n ...legacyEntries,\n ...dbEntries,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/scripts/dev/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Dev-mode script registry.\n *\n * Provides shared coding and database tools for the agent\n * when running in development mode. These tools should NEVER be\n * registered in production.\n */\n\nimport type { ActionTool } from \"../../agent/types.js\";\nimport type { ActionEntry } from \"../../agent/production-agent.js\";\nimport { createCodingToolRegistry } from \"../../coding-tools/index.js\";\nimport { dbExecToolParameters } from \"../db/tool-schemas.js\";\nimport { tool as readFileTool, run as readFileRun } from \"./read-file.js\";\nimport { tool as writeFileTool, run as writeFileRun } from \"./write-file.js\";\nimport { tool as listFilesTool, run as listFilesRun } from \"./list-files.js\";\nimport {\n tool as searchFilesTool,\n run as searchFilesRun,\n} from \"./search-files.js\";\nimport { tool as shellTool, run as shellRun } from \"./shell.js\";\n\n/**\n * Wraps a core CLI script (that writes to console.log) as a ActionEntry\n * by capturing stdout.\n */\nfunction wrapCliScript(\n tool: ActionTool,\n cliDefault: (args: string[]) => Promise<void>,\n opts?: { readOnly?: boolean },\n): ActionEntry {\n return {\n tool,\n ...(opts?.readOnly ? { readOnly: true as const } : {}),\n run: async (args: Record<string, string>): Promise<string> => {\n const cliArgs: string[] = [];\n for (const [k, v] of Object.entries(args)) {\n const raw = v as unknown;\n const value =\n raw != null && typeof raw === \"object\"\n ? JSON.stringify(raw)\n : String(raw);\n cliArgs.push(`--${k}`, value);\n }\n\n // Capture console.log output\n const logs: string[] = [];\n const origLog = console.log;\n console.log = (...a: unknown[]) => {\n logs.push(a.map(String).join(\" \"));\n };\n\n try {\n await cliDefault(cliArgs);\n } catch (err: any) {\n logs.push(`Error: ${err?.message ?? String(err)}`);\n } finally {\n console.log = origLog;\n }\n\n return logs.join(\"\\n\") || \"(no output)\";\n },\n };\n}\n\n/**\n * Creates the dev-mode script registry with shared bash/read/edit/write\n * coding tools and database tools. Call this and merge with your app's registry\n * when NODE_ENV !== \"production\".\n */\nexport async function createDevScriptRegistry(\n options: { legacyAliases?: boolean; databaseTools?: boolean } = {},\n): Promise<Record<string, ActionEntry>> {\n // Lazy-import DB scripts to avoid requiring libsql in non-DB apps\n let dbEntries: Record<string, ActionEntry> = {};\n if (options.databaseTools !== false) {\n try {\n // Dynamic imports — these are part of @agent-native/core\n const [dbSchema, dbQuery, dbExec, dbPatch, dbCheckScoping] =\n await Promise.all([\n import(\"../db/schema.js\"),\n import(\"../db/query.js\"),\n import(\"../db/exec.js\"),\n import(\"../db/patch.js\"),\n import(\"../db/check-scoping.js\"),\n ]);\n\n dbEntries = {\n \"db-schema\": wrapCliScript(\n {\n description:\n \"Show all database tables, columns, types, and foreign keys\",\n parameters: {\n type: \"object\",\n properties: {\n format: {\n type: \"string\",\n description:\n 'Output format: \"json\" or \"text\" (default: text)',\n enum: [\"json\", \"text\"],\n },\n },\n },\n },\n dbSchema.default,\n { readOnly: true },\n ),\n \"db-query\": wrapCliScript(\n {\n description:\n \"Run a read-only SQL query (SELECT, WITH, EXPLAIN, PRAGMA) against the app database\",\n parameters: {\n type: \"object\",\n properties: {\n sql: {\n type: \"string\",\n description: \"The SQL SELECT query to execute\",\n },\n args: {\n type: \"string\",\n description:\n 'Optional JSON array of positional bind args for parameterized placeholders. Example: \\'[\"draft\",\"form-123\"]\\'',\n },\n format: {\n type: \"string\",\n description:\n 'Output format: \"json\" or \"table\" (default: table)',\n enum: [\"json\", \"table\"],\n },\n },\n required: [\"sql\"],\n },\n },\n dbQuery.default,\n { readOnly: true },\n ),\n \"db-exec\": wrapCliScript(\n {\n description:\n \"Execute app-database write SQL (INSERT, UPDATE, DELETE, REPLACE). For multiple related writes, pass `statements` so they run sequentially in one transaction instead of issuing several db-exec calls. Schema changes (CREATE/ALTER/DROP) are blocked. Never use this to backfill missing data for a read/analysis request or to create/modify users, members, roles, permissions, admin flags, or ownership; use a dedicated app action or reviewed code.\",\n parameters: dbExecToolParameters(),\n },\n dbExec.default,\n ),\n \"db-patch\": wrapCliScript(\n {\n description:\n \"Surgical search-and-replace on a text column in a SQL table. Prefer over `db-exec UPDATE` for large text fields (documents, slides, dashboards, JSON blobs) where you only need to change a small slice — avoids re-sending the full column value. Targets exactly one row at a time (narrow --where by primary key). If a template-specific action exists for the table (e.g. `edit-document`, `update-slide`), use that instead — it will also push live updates to open collaborative editors.\",\n parameters: {\n type: \"object\",\n properties: {\n table: {\n type: \"string\",\n description:\n \"Target table name (plain identifier, no quoting)\",\n },\n column: {\n type: \"string\",\n description:\n \"Target text column name (plain identifier, no quoting)\",\n },\n where: {\n type: \"string\",\n description:\n \"SQL WHERE clause that matches exactly one row, e.g. \\\"id = 'abc123'\\\". Must not contain semicolons or DDL keywords.\",\n },\n find: {\n type: \"string\",\n description:\n \"Text to find (single-edit mode). Pair with --replace.\",\n },\n replace: {\n type: \"string\",\n description:\n 'Replacement text (single-edit mode). Defaults to \"\" (delete the match).',\n },\n edits: {\n type: \"string\",\n description:\n 'Batch mode: JSON array of {find, replace} objects. Example: \\'[{\"find\":\"Q3\",\"replace\":\"Q4\"},{\"find\":\"$1M\",\"replace\":\"$1.2M\"}]\\'',\n },\n all: {\n type: \"string\",\n description:\n 'Set to \"true\" to replace every occurrence of each find (default: first occurrence only).',\n enum: [\"true\", \"false\"],\n },\n format: {\n type: \"string\",\n description:\n 'Output format: \"json\" or \"text\" (default: text)',\n enum: [\"json\", \"text\"],\n },\n },\n required: [\"table\", \"column\", \"where\"],\n },\n },\n dbPatch.default,\n ),\n \"db-check-scoping\": wrapCliScript(\n {\n description:\n \"Validate that all template tables have owner_email and org_id columns for data scoping\",\n parameters: {\n type: \"object\",\n properties: {\n \"require-org\": {\n type: \"string\",\n description:\n 'Set to \"true\" to also require org_id columns (for multi-org apps)',\n enum: [\"true\", \"false\"],\n },\n format: {\n type: \"string\",\n description:\n 'Output format: \"json\" or \"text\" (default: text)',\n enum: [\"json\", \"text\"],\n },\n },\n },\n },\n dbCheckScoping.default,\n { readOnly: true },\n ),\n };\n } catch {\n // DB scripts not available (no libsql) — skip silently\n }\n }\n\n const codingEntries = createCodingToolRegistry({\n cwd: process.cwd(),\n bashThrowsOnNonZero: true,\n });\n const legacyEntries: Record<string, ActionEntry> = options.legacyAliases\n ? {\n \"read-file\": { tool: readFileTool, run: readFileRun, readOnly: true },\n \"write-file\": { tool: writeFileTool, run: writeFileRun },\n \"list-files\": {\n tool: listFilesTool,\n run: listFilesRun,\n readOnly: true,\n },\n \"search-files\": {\n tool: searchFilesTool,\n run: searchFilesRun,\n readOnly: true,\n },\n shell: { tool: shellTool, run: shellRun },\n }\n : {};\n\n return {\n ...codingEntries,\n ...legacyEntries,\n ...dbEntries,\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-args.js","sourceRoot":"","sources":["../../src/scripts/parse-args.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAS;QAEpC,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC;YACnB,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YAClC,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACzB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACzB,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"parse-args.js","sourceRoot":"","sources":["../../src/scripts/parse-args.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAS;QAEpC,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC;YACnB,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YAClC,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACzB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACzB,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACjD,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;gBACnB,CAAC,EAAE,CAAC;YACN,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAC3B,IAA4B;IAE5B,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QAClE,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC;IACxB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["/**\n * Pure script utilities — no Node.js dependencies.\n * Safe to import from browser bundles and Vite SSR.\n */\n\n/**\n * Parse CLI args in --key value format.\n * Supports: --key value, --key=value, --flag (boolean true)\n */\nexport function parseArgs(args: string[]): Record<string, string> {\n const result: Record<string, string> = {};\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (!arg.startsWith(\"--\")) continue;\n\n const eqIndex = arg.indexOf(\"=\");\n if (eqIndex !== -1) {\n const key = arg.slice(2, eqIndex);\n result[key] = arg.slice(eqIndex + 1);\n } else {\n const key = arg.slice(2);\n const next = args[i + 1];\n if (next !== undefined && !next.startsWith(\"--\")) {\n result[key] = next;\n i++;\n } else {\n result[key] = \"true\";\n }\n }\n }\n return result;\n}\n\n/**\n * Convert kebab-case keys to camelCase.\n */\nexport function camelCaseArgs(\n args: Record<string, string>,\n): Record<string, string> {\n const result: Record<string, string> = {};\n for (const [key, value] of Object.entries(args)) {\n const camel = key.replace(/-([a-z])/g, (_, c) => c.toUpperCase());\n result[camel] = value;\n }\n return result;\n}\n"]}
|
package/dist/scripts/runner.js
CHANGED
|
@@ -131,7 +131,7 @@ function parseActionArgs(args, options = {}) {
|
|
|
131
131
|
else {
|
|
132
132
|
const key = arg.slice(2);
|
|
133
133
|
const next = args[i + 1];
|
|
134
|
-
if (next && !next.startsWith("--")) {
|
|
134
|
+
if (next !== undefined && !next.startsWith("--")) {
|
|
135
135
|
setParsedArg(parsed, key, coerceCliValue(next, coerceBooleans));
|
|
136
136
|
i++;
|
|
137
137
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/scripts/runner.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Generic action dispatcher for @agent-native/core apps.\n *\n * Dynamically imports and runs actions from the app's actions/ directory.\n * Falls back to scripts/ directory for backwards compatibility, then to\n * core scripts (db-schema, db-query, db-exec, etc.) when no local action is found.\n *\n * Actions must export a default function: (args: string[]) => Promise<void>\n *\n * Usage: pnpm action <action-name> [--args]\n */\n\nimport path from \"path\";\nimport fs from \"fs\";\nimport { pathToFileURL } from \"url\";\nimport { coreScripts, getCoreScriptNames } from \"./core-scripts.js\";\nimport { closeDbExec } from \"../db/client.js\";\nimport { loadEnv } from \"./utils.js\";\nimport {\n runWithRequestContext,\n getRequestOrgId,\n getRequestUserEmail,\n} from \"../server/request-context.js\";\nimport { resolveDevUserEmail } from \"./dev-session.js\";\nimport { notifyActionChange } from \"../server/action-change.js\";\nimport type { ActionEntry } from \"../agent/production-agent.js\";\n\n// Load .env from cwd so DATABASE_URL and other vars are available to all actions.\nloadEnv();\n\nexport interface RunScriptOptions {\n /**\n * Actions contributed by packages rather than the app's local `actions/`\n * directory. Local app actions still win on name collision.\n */\n packageActions?: Record<string, ActionEntry>;\n /** Help-section label for package actions. */\n packageActionLabel?: string;\n}\n\nasync function runAppDbPluginIfPresent(): Promise<void> {\n const dbPluginPath = path.resolve(process.cwd(), \"server/plugins/db.ts\");\n if (!fs.existsSync(dbPluginPath)) return;\n\n const mod = await import(/* @vite-ignore */ pathToFileURL(dbPluginPath).href);\n const plugin = mod.default;\n if (typeof plugin === \"function\") {\n await plugin({});\n }\n}\n\n/**\n * Run the action dispatcher. Call this from your app's actions/run.ts (or scripts/run.ts):\n *\n * import { runScript } from \"@agent-native/core\";\n * runScript();\n */\nexport async function runScript(options: RunScriptOptions = {}): Promise<void> {\n const actionName = process.argv[2];\n\n if (!actionName || actionName === \"--help\") {\n console.log(`Usage: pnpm action <action-name> [--arg value ...]`);\n console.log(`\\nRun any action with --help for usage details.`);\n\n // List local actions (try actions/ first, then scripts/)\n const actionsDir = path.resolve(process.cwd(), \"actions\");\n const scriptsDir = path.resolve(process.cwd(), \"scripts\");\n const localDir = fs.existsSync(actionsDir) ? actionsDir : scriptsDir;\n if (fs.existsSync(localDir)) {\n const locals = fs\n .readdirSync(localDir)\n .filter((f) => f.endsWith(\".ts\") && f !== \"run.ts\")\n .map((f) => f.replace(/\\.ts$/, \"\"));\n if (locals.length > 0) {\n console.log(`\\nApp actions:`);\n for (const name of locals) {\n console.log(` ${name}`);\n }\n }\n }\n\n const packageActionNames = Object.keys(options.packageActions ?? {}).sort();\n if (packageActionNames.length > 0) {\n console.log(`\\n${options.packageActionLabel ?? \"Package actions\"}:`);\n for (const name of packageActionNames) {\n console.log(` ${name}`);\n }\n }\n\n // List core scripts\n const coreNames = getCoreScriptNames();\n if (coreNames.length > 0) {\n console.log(`\\nCore actions (built-in):`);\n for (const name of coreNames) {\n console.log(` ${name}`);\n }\n }\n\n process.exit(0);\n }\n\n // Validate action name (only allow alphanumeric + hyphens)\n if (!/^[a-z][a-z0-9-]*$/.test(actionName)) {\n console.error(`Error: Invalid action name \"${actionName}\"`);\n process.exit(1);\n }\n\n const args = process.argv.slice(3);\n\n // Establish a request context for the duration of this CLI run. Without\n // it, db-exec / db-query / db-patch and any action that calls\n // `getRequestUserEmail()` see no identity and refuse to run. The\n // resolver picks up `AGENT_USER_EMAIL` if explicitly set, otherwise\n // reads the DB session owner only when it is unambiguous (dev-only,\n // narrowly gated — see dev-session.ts).\n //\n // This wrap is intentionally a single point of injection: it covers\n // both the local-action branch and the fall-through to core scripts\n // (db-query, db-exec, …) so every CLI entrypoint runs scoped to a real\n // user. It uses `runWithRequestContext` rather than mutating\n // `process.env.AGENT_USER_EMAIL` because env mutation leaks across\n // boundaries — see the cautionary comment in\n // `server/request-context.ts` about exactly that pattern.\n const userEmail = await resolveDevUserEmail();\n const orgId = process.env.AGENT_ORG_ID || undefined;\n\n return runWithRequestContext({ userEmail, orgId }, () =>\n dispatchAction(actionName, args, options),\n );\n}\n\nfunction coerceCliValue(\n value: string,\n coerceBooleans: boolean,\n): string | boolean {\n if (!coerceBooleans) return value;\n if (value === \"true\") return true;\n if (value === \"false\") return false;\n return value;\n}\n\nfunction setParsedArg(\n parsed: Record<string, unknown>,\n key: string,\n value: unknown,\n) {\n const existing = parsed[key];\n if (existing === undefined) {\n parsed[key] = value;\n return;\n }\n parsed[key] = Array.isArray(existing)\n ? [...existing, value]\n : [existing, value];\n}\n\nfunction parseActionArgs(\n args: string[],\n options: { coerceBooleans?: boolean } = {},\n): Record<string, unknown> {\n const parsed: Record<string, unknown> = {};\n const coerceBooleans = options.coerceBooleans ?? false;\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (!arg.startsWith(\"--\")) continue;\n const eqIdx = arg.indexOf(\"=\");\n if (eqIdx > 0) {\n setParsedArg(\n parsed,\n arg.slice(2, eqIdx),\n coerceCliValue(arg.slice(eqIdx + 1), coerceBooleans),\n );\n } else {\n const key = arg.slice(2);\n const next = args[i + 1];\n if (next && !next.startsWith(\"--\")) {\n setParsedArg(parsed, key, coerceCliValue(next, coerceBooleans));\n i++;\n } else {\n setParsedArg(parsed, key, coerceBooleans ? true : \"true\");\n }\n }\n }\n return parsed;\n}\n\n/**\n * Build the `ctx` passed as the action's second arg for CLI dispatch. The\n * identity comes from the `runWithRequestContext` wrap in `runScript` (which\n * resolves `AGENT_USER_EMAIL` / the dev session); we never inject a dev\n * identity here beyond what that wrap already established.\n */\nfunction cliActionCtx(): import(\"../action.js\").ActionRunContext {\n return {\n userEmail: getRequestUserEmail(),\n orgId: getRequestOrgId() ?? null,\n caller: \"cli\",\n };\n}\n\nasync function dispatchAction(\n actionName: string,\n args: string[],\n options: RunScriptOptions,\n): Promise<void> {\n // 1. Try local app action first (actions/ then scripts/ for backwards compat)\n const actionsPath = path.resolve(\n process.cwd(),\n \"actions\",\n `${actionName}.ts`,\n );\n const scriptsPath = path.resolve(\n process.cwd(),\n \"scripts\",\n `${actionName}.ts`,\n );\n const localPath = fs.existsSync(actionsPath) ? actionsPath : scriptsPath;\n\n if (fs.existsSync(localPath)) {\n try {\n await runAppDbPluginIfPresent();\n const mod = await import(\n /* @vite-ignore */ pathToFileURL(localPath).href\n );\n const handler = mod.default;\n // Support defineAction-style default exports (object with run method)\n if (\n handler &&\n typeof handler === \"object\" &&\n typeof handler.run === \"function\"\n ) {\n const parsed = parseActionArgs(args, { coerceBooleans: true });\n const result = await handler.run(parsed, cliActionCtx());\n if (handler.readOnly !== true) {\n await notifyActionChange({ actionName }).catch(() => {});\n }\n if (result) console.log(result);\n } else if (typeof handler === \"function\") {\n await handler(args);\n } else {\n console.error(\n `Action \"${actionName}\" does not export a default function or defineAction.`,\n );\n process.exit(1);\n }\n await closeDbExec().catch(() => {});\n process.exit(0);\n } catch (err: any) {\n await closeDbExec().catch(() => {});\n console.error(`Action \"${actionName}\" failed:`, err.message || err);\n process.exit(1);\n }\n }\n\n // 2. Try package-contributed actions (e.g. @agent-native/dispatch)\n const packageAction = options.packageActions?.[actionName];\n if (packageAction) {\n try {\n await runAppDbPluginIfPresent();\n const parsed = parseActionArgs(args, { coerceBooleans: true });\n const result = await packageAction.run(\n parsed as Record<string, string>,\n cliActionCtx(),\n );\n if (packageAction.readOnly !== true) {\n await notifyActionChange({ actionName }).catch(() => {});\n }\n if (result) console.log(result);\n await closeDbExec().catch(() => {});\n process.exit(0);\n } catch (err: any) {\n await closeDbExec().catch(() => {});\n console.error(`Action \"${actionName}\" failed:`, err.message || err);\n process.exit(1);\n }\n }\n\n // 3. Fall back to core scripts\n const coreScript = coreScripts[actionName];\n if (coreScript) {\n try {\n await coreScript(args);\n await closeDbExec().catch(() => {});\n process.exit(0);\n } catch (err: any) {\n await closeDbExec().catch(() => {});\n console.error(`Core action \"${actionName}\" failed:`, err.message || err);\n process.exit(1);\n }\n }\n\n // 4. Not found anywhere\n console.error(\n `Error: Action \"${actionName}\" not found. Run \"pnpm action --help\" for available actions.`,\n );\n process.exit(1);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/scripts/runner.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Generic action dispatcher for @agent-native/core apps.\n *\n * Dynamically imports and runs actions from the app's actions/ directory.\n * Falls back to scripts/ directory for backwards compatibility, then to\n * core scripts (db-schema, db-query, db-exec, etc.) when no local action is found.\n *\n * Actions must export a default function: (args: string[]) => Promise<void>\n *\n * Usage: pnpm action <action-name> [--args]\n */\n\nimport path from \"path\";\nimport fs from \"fs\";\nimport { pathToFileURL } from \"url\";\nimport { coreScripts, getCoreScriptNames } from \"./core-scripts.js\";\nimport { closeDbExec } from \"../db/client.js\";\nimport { loadEnv } from \"./utils.js\";\nimport {\n runWithRequestContext,\n getRequestOrgId,\n getRequestUserEmail,\n} from \"../server/request-context.js\";\nimport { resolveDevUserEmail } from \"./dev-session.js\";\nimport { notifyActionChange } from \"../server/action-change.js\";\nimport type { ActionEntry } from \"../agent/production-agent.js\";\n\n// Load .env from cwd so DATABASE_URL and other vars are available to all actions.\nloadEnv();\n\nexport interface RunScriptOptions {\n /**\n * Actions contributed by packages rather than the app's local `actions/`\n * directory. Local app actions still win on name collision.\n */\n packageActions?: Record<string, ActionEntry>;\n /** Help-section label for package actions. */\n packageActionLabel?: string;\n}\n\nasync function runAppDbPluginIfPresent(): Promise<void> {\n const dbPluginPath = path.resolve(process.cwd(), \"server/plugins/db.ts\");\n if (!fs.existsSync(dbPluginPath)) return;\n\n const mod = await import(/* @vite-ignore */ pathToFileURL(dbPluginPath).href);\n const plugin = mod.default;\n if (typeof plugin === \"function\") {\n await plugin({});\n }\n}\n\n/**\n * Run the action dispatcher. Call this from your app's actions/run.ts (or scripts/run.ts):\n *\n * import { runScript } from \"@agent-native/core\";\n * runScript();\n */\nexport async function runScript(options: RunScriptOptions = {}): Promise<void> {\n const actionName = process.argv[2];\n\n if (!actionName || actionName === \"--help\") {\n console.log(`Usage: pnpm action <action-name> [--arg value ...]`);\n console.log(`\\nRun any action with --help for usage details.`);\n\n // List local actions (try actions/ first, then scripts/)\n const actionsDir = path.resolve(process.cwd(), \"actions\");\n const scriptsDir = path.resolve(process.cwd(), \"scripts\");\n const localDir = fs.existsSync(actionsDir) ? actionsDir : scriptsDir;\n if (fs.existsSync(localDir)) {\n const locals = fs\n .readdirSync(localDir)\n .filter((f) => f.endsWith(\".ts\") && f !== \"run.ts\")\n .map((f) => f.replace(/\\.ts$/, \"\"));\n if (locals.length > 0) {\n console.log(`\\nApp actions:`);\n for (const name of locals) {\n console.log(` ${name}`);\n }\n }\n }\n\n const packageActionNames = Object.keys(options.packageActions ?? {}).sort();\n if (packageActionNames.length > 0) {\n console.log(`\\n${options.packageActionLabel ?? \"Package actions\"}:`);\n for (const name of packageActionNames) {\n console.log(` ${name}`);\n }\n }\n\n // List core scripts\n const coreNames = getCoreScriptNames();\n if (coreNames.length > 0) {\n console.log(`\\nCore actions (built-in):`);\n for (const name of coreNames) {\n console.log(` ${name}`);\n }\n }\n\n process.exit(0);\n }\n\n // Validate action name (only allow alphanumeric + hyphens)\n if (!/^[a-z][a-z0-9-]*$/.test(actionName)) {\n console.error(`Error: Invalid action name \"${actionName}\"`);\n process.exit(1);\n }\n\n const args = process.argv.slice(3);\n\n // Establish a request context for the duration of this CLI run. Without\n // it, db-exec / db-query / db-patch and any action that calls\n // `getRequestUserEmail()` see no identity and refuse to run. The\n // resolver picks up `AGENT_USER_EMAIL` if explicitly set, otherwise\n // reads the DB session owner only when it is unambiguous (dev-only,\n // narrowly gated — see dev-session.ts).\n //\n // This wrap is intentionally a single point of injection: it covers\n // both the local-action branch and the fall-through to core scripts\n // (db-query, db-exec, …) so every CLI entrypoint runs scoped to a real\n // user. It uses `runWithRequestContext` rather than mutating\n // `process.env.AGENT_USER_EMAIL` because env mutation leaks across\n // boundaries — see the cautionary comment in\n // `server/request-context.ts` about exactly that pattern.\n const userEmail = await resolveDevUserEmail();\n const orgId = process.env.AGENT_ORG_ID || undefined;\n\n return runWithRequestContext({ userEmail, orgId }, () =>\n dispatchAction(actionName, args, options),\n );\n}\n\nfunction coerceCliValue(\n value: string,\n coerceBooleans: boolean,\n): string | boolean {\n if (!coerceBooleans) return value;\n if (value === \"true\") return true;\n if (value === \"false\") return false;\n return value;\n}\n\nfunction setParsedArg(\n parsed: Record<string, unknown>,\n key: string,\n value: unknown,\n) {\n const existing = parsed[key];\n if (existing === undefined) {\n parsed[key] = value;\n return;\n }\n parsed[key] = Array.isArray(existing)\n ? [...existing, value]\n : [existing, value];\n}\n\nfunction parseActionArgs(\n args: string[],\n options: { coerceBooleans?: boolean } = {},\n): Record<string, unknown> {\n const parsed: Record<string, unknown> = {};\n const coerceBooleans = options.coerceBooleans ?? false;\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (!arg.startsWith(\"--\")) continue;\n const eqIdx = arg.indexOf(\"=\");\n if (eqIdx > 0) {\n setParsedArg(\n parsed,\n arg.slice(2, eqIdx),\n coerceCliValue(arg.slice(eqIdx + 1), coerceBooleans),\n );\n } else {\n const key = arg.slice(2);\n const next = args[i + 1];\n if (next !== undefined && !next.startsWith(\"--\")) {\n setParsedArg(parsed, key, coerceCliValue(next, coerceBooleans));\n i++;\n } else {\n setParsedArg(parsed, key, coerceBooleans ? true : \"true\");\n }\n }\n }\n return parsed;\n}\n\n/**\n * Build the `ctx` passed as the action's second arg for CLI dispatch. The\n * identity comes from the `runWithRequestContext` wrap in `runScript` (which\n * resolves `AGENT_USER_EMAIL` / the dev session); we never inject a dev\n * identity here beyond what that wrap already established.\n */\nfunction cliActionCtx(): import(\"../action.js\").ActionRunContext {\n return {\n userEmail: getRequestUserEmail(),\n orgId: getRequestOrgId() ?? null,\n caller: \"cli\",\n };\n}\n\nasync function dispatchAction(\n actionName: string,\n args: string[],\n options: RunScriptOptions,\n): Promise<void> {\n // 1. Try local app action first (actions/ then scripts/ for backwards compat)\n const actionsPath = path.resolve(\n process.cwd(),\n \"actions\",\n `${actionName}.ts`,\n );\n const scriptsPath = path.resolve(\n process.cwd(),\n \"scripts\",\n `${actionName}.ts`,\n );\n const localPath = fs.existsSync(actionsPath) ? actionsPath : scriptsPath;\n\n if (fs.existsSync(localPath)) {\n try {\n await runAppDbPluginIfPresent();\n const mod = await import(\n /* @vite-ignore */ pathToFileURL(localPath).href\n );\n const handler = mod.default;\n // Support defineAction-style default exports (object with run method)\n if (\n handler &&\n typeof handler === \"object\" &&\n typeof handler.run === \"function\"\n ) {\n const parsed = parseActionArgs(args, { coerceBooleans: true });\n const result = await handler.run(parsed, cliActionCtx());\n if (handler.readOnly !== true) {\n await notifyActionChange({ actionName }).catch(() => {});\n }\n if (result) console.log(result);\n } else if (typeof handler === \"function\") {\n await handler(args);\n } else {\n console.error(\n `Action \"${actionName}\" does not export a default function or defineAction.`,\n );\n process.exit(1);\n }\n await closeDbExec().catch(() => {});\n process.exit(0);\n } catch (err: any) {\n await closeDbExec().catch(() => {});\n console.error(`Action \"${actionName}\" failed:`, err.message || err);\n process.exit(1);\n }\n }\n\n // 2. Try package-contributed actions (e.g. @agent-native/dispatch)\n const packageAction = options.packageActions?.[actionName];\n if (packageAction) {\n try {\n await runAppDbPluginIfPresent();\n const parsed = parseActionArgs(args, { coerceBooleans: true });\n const result = await packageAction.run(\n parsed as Record<string, string>,\n cliActionCtx(),\n );\n if (packageAction.readOnly !== true) {\n await notifyActionChange({ actionName }).catch(() => {});\n }\n if (result) console.log(result);\n await closeDbExec().catch(() => {});\n process.exit(0);\n } catch (err: any) {\n await closeDbExec().catch(() => {});\n console.error(`Action \"${actionName}\" failed:`, err.message || err);\n process.exit(1);\n }\n }\n\n // 3. Fall back to core scripts\n const coreScript = coreScripts[actionName];\n if (coreScript) {\n try {\n await coreScript(args);\n await closeDbExec().catch(() => {});\n process.exit(0);\n } catch (err: any) {\n await closeDbExec().catch(() => {});\n console.error(`Core action \"${actionName}\" failed:`, err.message || err);\n process.exit(1);\n }\n }\n\n // 4. Not found anywhere\n console.error(\n `Error: Action \"${actionName}\" not found. Run \"pnpm action --help\" for available actions.`,\n );\n process.exit(1);\n}\n"]}
|
|
@@ -15,6 +15,7 @@ export declare function assembleA2AFinalResponse(events: readonly AgentChatEvent
|
|
|
15
15
|
responseText: string;
|
|
16
16
|
finalText: string;
|
|
17
17
|
};
|
|
18
|
+
declare function createDataWidgetActionEntries(): Record<string, ActionEntry>;
|
|
18
19
|
type NitroPluginDef = (nitroApp: any) => void | Promise<void>;
|
|
19
20
|
export interface AgentChatPluginOptions {
|
|
20
21
|
/** Template-specific actions (email ops, booking ops, etc.) */
|
|
@@ -292,6 +293,8 @@ export declare const _agentChatPromptSectionsForTests: {
|
|
|
292
293
|
frameworkCore: string;
|
|
293
294
|
frameworkCoreCompact: string;
|
|
294
295
|
frameworkContextSections: Record<string, string>;
|
|
296
|
+
generateActionsPrompt: typeof generateActionsPrompt;
|
|
297
|
+
createDataWidgetActionEntries: typeof createDataWidgetActionEntries;
|
|
295
298
|
};
|
|
296
299
|
/**
|
|
297
300
|
* Pre-load the agent's context: AGENTS.md (workspace/template/runtime
|
|
@@ -317,6 +320,19 @@ export declare const _agentChatPromptSectionsForTests: {
|
|
|
317
320
|
* the bundle in dev so changes land instantly.
|
|
318
321
|
*/
|
|
319
322
|
export declare function loadResourcesForPrompt(owner: string, compact?: boolean, selfAppId?: string): Promise<string>;
|
|
323
|
+
/**
|
|
324
|
+
* Generates a system prompt section describing registered template actions.
|
|
325
|
+
* This helps the agent prefer template-specific actions over raw db-query/db-exec.
|
|
326
|
+
*
|
|
327
|
+
* Two output modes:
|
|
328
|
+
*
|
|
329
|
+
* - `"tool"` — used in production, where template actions are registered
|
|
330
|
+
* as native Anthropic tools. Output reads `name(arg*: type; ...) — desc`.
|
|
331
|
+
* - `"cli"` — used in dev, where template actions are NOT registered as
|
|
332
|
+
* native tools and must be invoked via `bash(command="pnpm action ...")`.
|
|
333
|
+
* Output reads `pnpm action name --arg <type> [--opt <type>] — desc`.
|
|
334
|
+
*/
|
|
335
|
+
declare function generateActionsPrompt(registry: Record<string, ActionEntry>, mode?: "cli" | "tool"): string;
|
|
320
336
|
export declare function shouldBlockInProductCodeEditingSurface(input: {
|
|
321
337
|
surface?: string | null;
|
|
322
338
|
userAgent?: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-chat-plugin.d.ts","sourceRoot":"","sources":["../../src/server/agent-chat-plugin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"agent-chat-plugin.d.ts","sourceRoot":"","sources":["../../src/server/agent-chat-plugin.ts"],"names":[],"mappings":"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"}
|