@agent-native/core 0.149.6 → 0.151.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +83 -45
- package/corpus/templates/analytics/changelog/2026-08-11-analytics-dashboards-keep-the-selected-tab-when-reopened.md +6 -0
- package/corpus/templates/assets/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/brain/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/calendar/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/clips/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/clips/changelog/2026-08-11-clips-recovers-from-transient-updates-and-avoids-macos-priva.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +32 -176
- package/corpus/templates/clips/desktop/src/lib/updater.ts +52 -37
- package/corpus/templates/clips/desktop/src/styles.css +1 -166
- package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +2 -0
- package/corpus/templates/clips/desktop/src-tauri/Info.plist +4 -0
- package/corpus/templates/clips/desktop/src-tauri/src/eventkit.rs +28 -1
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +2 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_speech.rs +48 -1
- package/corpus/templates/clips/desktop/src-tauri/src/permission_status.rs +3 -0
- package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +5 -0
- package/corpus/templates/clips/server/plugins/auth.ts +3 -0
- package/corpus/templates/content/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/content/app/components/editor/CommentsSidebar.tsx +2 -1
- package/corpus/templates/design/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +5 -1
- package/corpus/templates/design/changelog/2026-08-11-design-agent-prompts-copy-successfully-in-the-desktop-app.md +6 -0
- package/corpus/templates/dispatch/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/dispatch/app/global.css +2 -2
- package/corpus/templates/dispatch/changelog/2026-08-10-desktop-workspace-sign-in.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-08-11-dispatch-no-longer-shows-the-generic-chat-starter-among-defa.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-08-11-integrations-and-scheduled-work-open-as-first-class-electron-pages.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-08-11-sidebar-text-is-slightly-easier-to-read-in-light-and-dark-mo.md +6 -0
- package/corpus/templates/dispatch/server/lib/identity-sso.ts +57 -31
- package/corpus/templates/dispatch/server/plugins/feature-flags.ts +5 -0
- package/corpus/templates/dispatch/server/plugins/identity-sso.ts +82 -33
- package/corpus/templates/dispatch/server/plugins/org-apps-directory.ts +7 -15
- package/corpus/templates/dispatch/server/plugins/setup-dispatch.ts +9 -1
- package/corpus/templates/dispatch/shared/feature-flags.ts +15 -0
- package/corpus/templates/factory/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/forms/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/forms/.agents/skills/form-responses/SKILL.md +8 -7
- package/corpus/templates/forms/app/hooks/use-forms.ts +8 -1
- package/corpus/templates/forms/changelog/2026-08-11-fixed-public-forms-so-conditional-questions-stay-hidden-unti.md +6 -0
- package/corpus/templates/forms/server/handlers/submissions.ts +2 -1
- package/corpus/templates/forms/server/lib/public-form-ssr.ts +37 -2
- package/corpus/templates/forms/shared/page-url.ts +54 -0
- package/corpus/templates/forms/shared/types.ts +4 -4
- package/corpus/templates/mail/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/plan/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/slides/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/corpus/templates/slides/actions/add-slide.ts +0 -27
- package/corpus/templates/slides/actions/import-file.ts +28 -9
- package/corpus/templates/slides/actions/view-screen.ts +4 -4
- package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +8 -1
- package/corpus/templates/slides/app/components/editor/AiEditingMarker.tsx +25 -0
- package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +43 -48
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +9 -6
- package/corpus/templates/slides/app/components/editor/GeneratingSlidePreview.tsx +1 -9
- package/corpus/templates/slides/app/components/editor/ImageDropPromptPopover.tsx +2 -0
- package/corpus/templates/slides/app/components/editor/ImageOverlay.tsx +0 -26
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +904 -217
- package/corpus/templates/slides/app/components/editor/canvas-interactions/index.ts +1 -0
- package/corpus/templates/slides/app/components/editor/canvas-interactions/slides-canvas-adapter.ts +11 -0
- package/corpus/templates/slides/app/components/editor/inline-edit-session.ts +16 -0
- package/corpus/templates/slides/app/components/editor/slide-object-interactions.ts +22 -6
- package/corpus/templates/slides/app/components/editor/style-clipboard.ts +61 -0
- package/corpus/templates/slides/app/components/layout/Layout.tsx +26 -2
- package/corpus/templates/slides/app/components/ui/context-menu.tsx +1 -0
- package/corpus/templates/slides/app/context/DeckContext.tsx +75 -25
- package/corpus/templates/slides/app/global.css +1 -1
- package/corpus/templates/slides/app/i18n/en-US.ts +6 -1
- package/corpus/templates/slides/app/lib/create-deck-generation.ts +1 -1
- package/corpus/templates/slides/app/lib/image-drop-to-agent.ts +12 -12
- package/corpus/templates/slides/app/lib/slide-agent-context.ts +52 -0
- package/corpus/templates/slides/app/lib/slide-image-replacement.ts +61 -0
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +55 -116
- package/corpus/templates/slides/app/pages/Index.tsx +28 -3
- package/corpus/templates/slides/changelog/2026-08-11-agent-chat-now-follows-the-current-slide-and-selection.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-11-deck-titles-now-use-slide-content-instead-of-placeholder-filenames.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-11-history-now-opens-from-the-deck-overflow-menu.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-11-images-can-be-dropped-directly-onto-slides-and-resized-or-re.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-11-new-decks-now-transition-directly-to-a-full-page-editor-load.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-11-selected-slide-layers-can-be-nudged-precisely-with-arrow-key.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-11-slides-can-copy-and-paste-element-styles-with-cmd-option-c-v.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-11-slides-shows-one-compact-ai-marker-and-keeps-your-current-sl.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-11-text-edits-preserve-slide-layout-when-no-changes-are-made.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-11-the-style-toolbar-now-uses-the-full-available-width.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-11-undo-and-redo-now-move-one-visible-slide-state-at-a-time.md +6 -0
- package/corpus/templates/slides/server/lib/chat-attachments.ts +6 -2
- package/corpus/templates/slides/shared/deck-title.ts +56 -0
- package/corpus/templates/tasks/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/dist/agent/run-store.js +6 -1
- package/dist/agent/thread-data-builder.js +19 -44
- package/dist/agent/types.d.ts +13 -0
- package/dist/catalog.json +1 -0
- package/dist/cli/create.js +1 -1
- package/dist/client/AssistantChat.js +58 -10
- package/dist/client/FileStorageSetupCard.d.ts +6 -0
- package/dist/client/FileStorageSetupCard.js +18 -0
- package/dist/client/NewWorkspaceAppFlow.js +10 -0
- package/dist/client/agent-chat-adapter.js +87 -11
- package/dist/client/agent-chat.d.ts +1 -1
- package/dist/client/agent-chat.js +8 -3
- package/dist/client/chat/attachment-adapters.js +10 -0
- package/dist/client/chat/message-components.d.ts +4 -1
- package/dist/client/chat/message-components.js +37 -13
- package/dist/client/chat/tool-call-display.js +14 -0
- package/dist/client/chat-first/apps-rail.d.ts +1 -1
- package/dist/client/chat-first/apps-rail.js +6 -6
- package/dist/client/chat-first/copy.js +1 -0
- package/dist/client/chat-first/types.d.ts +1 -0
- package/dist/client/extensions/EmbeddedExtension.js +1 -1
- package/dist/client/extensions/ExtensionViewer.js +1 -1
- package/dist/client/extensions/InlineExtensionFrame.js +1 -1
- package/dist/client/onboarding/FirstRunOnboarding.js +17 -2
- package/dist/client/settings/FileStorageSettingsForm.d.ts +2 -0
- package/dist/client/settings/FileStorageSettingsForm.js +113 -0
- package/dist/client/settings/SettingsPanel.js +2 -1
- package/dist/client/sse-event-processor.js +21 -0
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/extensions/actions.js +2 -2
- package/dist/extensions/html-shell.js +3 -1
- package/dist/file-upload/pre-upload-attachments.d.ts +15 -10
- package/dist/file-upload/pre-upload-attachments.js +68 -24
- package/dist/file-upload/registry.d.ts +4 -5
- package/dist/file-upload/registry.js +7 -14
- package/dist/file-upload/s3.d.ts +9 -0
- package/dist/file-upload/s3.js +168 -0
- package/dist/file-upload/types.d.ts +3 -3
- package/dist/file-upload/types.js +2 -2
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/notifications/routes.d.ts +6 -6
- package/dist/observability/routes.d.ts +3 -3
- package/dist/onboarding/app-profile.js +23 -1
- package/dist/onboarding/default-steps.js +69 -0
- package/dist/onboarding/types.d.ts +2 -0
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
- package/dist/provider-api/actions/provider-api.d.ts +8 -8
- package/dist/secrets/routes.d.ts +3 -3
- package/dist/server/agent-chat/browser-team-tools.js +20 -0
- package/dist/server/agent-chat-plugin.js +12 -3
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/auth.js +45 -21
- package/dist/server/better-auth-instance.d.ts +2 -0
- package/dist/server/better-auth-instance.js +2 -2
- package/dist/server/core-routes-plugin.d.ts +1 -0
- package/dist/server/core-routes-plugin.js +26 -16
- package/dist/server/identity-sso-store.d.ts +3 -0
- package/dist/server/identity-sso-store.js +45 -0
- package/dist/server/identity-sso.d.ts +20 -10
- package/dist/server/identity-sso.js +79 -31
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/dist/templates/default/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +24 -1
- package/dist/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +6 -2
- package/dist/templates/workspace-core/.agents/skills/extensions/references/api.md +1 -1
- package/dist/templates/workspace-core/.agents/skills/generative-ui/SKILL.md +3 -1
- package/docs/content/authentication.mdx +27 -0
- package/docs/content/cross-app-sso.mdx +38 -8
- package/docs/content/extensions.mdx +15 -15
- package/docs/content/file-uploads.mdx +10 -12
- package/docs/content/generative-ui.mdx +6 -1
- package/package.json +2 -2
- package/src/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/src/templates/default/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +24 -1
- package/src/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +28 -0
- package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +6 -2
- package/src/templates/workspace-core/.agents/skills/extensions/references/api.md +1 -1
- package/src/templates/workspace-core/.agents/skills/generative-ui/SKILL.md +3 -1
|
@@ -393,7 +393,9 @@ export function buildExtensionHtml(content, themeVars, isDark, extensionId, bind
|
|
|
393
393
|
type: 'agent-native-send-to-chat',
|
|
394
394
|
message: text,
|
|
395
395
|
context: options.context,
|
|
396
|
-
|
|
396
|
+
// Extension code can run polling and error handlers without a user
|
|
397
|
+
// gesture; submitting is opt-in for an explicit user action.
|
|
398
|
+
submit: options.submit === true,
|
|
397
399
|
openSidebar: options.openSidebar !== false,
|
|
398
400
|
}, '*');
|
|
399
401
|
return { ok: true };
|
|
@@ -30,10 +30,14 @@ export interface PreUploadAttachmentsResult {
|
|
|
30
30
|
/** Uploaded non-image files (PDF, generic binary). Parallel to `uploaded`
|
|
31
31
|
* but for the file/document attachment type. */
|
|
32
32
|
uploadedFiles: PreUploadedFileAttachment[];
|
|
33
|
-
/** True if at least one image
|
|
34
|
-
* file-upload provider is configured.
|
|
35
|
-
*
|
|
33
|
+
/** True if at least one image or file could not be uploaded because no
|
|
34
|
+
* file-upload provider is configured. The agent uses this to render the
|
|
35
|
+
* storage setup card. */
|
|
36
36
|
providerMissing: boolean;
|
|
37
|
+
/** True if at least one configured provider failed while uploading. */
|
|
38
|
+
uploadFailed: boolean;
|
|
39
|
+
/** The first provider error, bounded for safe inclusion in the chat hint. */
|
|
40
|
+
uploadError?: string;
|
|
37
41
|
/** A pre-formatted block to inject into the user message text so the agent
|
|
38
42
|
* has each hosted URL inline. Null when nothing was uploaded or no provider
|
|
39
43
|
* is configured. */
|
|
@@ -41,18 +45,18 @@ export interface PreUploadAttachmentsResult {
|
|
|
41
45
|
}
|
|
42
46
|
/**
|
|
43
47
|
* Returns true when a file-upload provider is currently configured.
|
|
44
|
-
* Used to decide whether
|
|
48
|
+
* Used to decide whether an attachment can be uploaded before the agent turn.
|
|
45
49
|
*/
|
|
46
50
|
export declare function isFileUploadProviderConfigured(): boolean;
|
|
47
51
|
/**
|
|
48
52
|
* Pre-upload chat image attachments through the active file-upload provider
|
|
49
53
|
* (Builder.io by default) so the agent can embed hosted URLs in HTML, slide
|
|
50
|
-
* content, and outbound messages. Keeps the original
|
|
51
|
-
*
|
|
54
|
+
* content, and outbound messages. Keeps the original data URL in memory for
|
|
55
|
+
* the current multimodal turn and adds a hosted `url`.
|
|
52
56
|
*
|
|
53
57
|
* Safe to call when no provider is configured: it returns the attachments
|
|
54
|
-
* untouched with `providerMissing: true` so callers can surface
|
|
55
|
-
*
|
|
58
|
+
* untouched with `providerMissing: true` so callers can surface the storage
|
|
59
|
+
* setup card to the agent without persisting the binary payload.
|
|
56
60
|
*/
|
|
57
61
|
export declare function preUploadImageAttachments(opts: {
|
|
58
62
|
attachments: AgentChatAttachment[] | undefined;
|
|
@@ -66,8 +70,9 @@ export declare function preUploadImageAttachments(opts: {
|
|
|
66
70
|
* file-reading still work; callers that persist the attachment can drop the
|
|
67
71
|
* data when a URL exists.
|
|
68
72
|
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
73
|
+
* When no provider is configured, returns untouched in-memory attachments with
|
|
74
|
+
* `providerMissing: true`. The caller may still use the bytes for this turn,
|
|
75
|
+
* but must not persist them as SQL/base64 attachment data.
|
|
71
76
|
*/
|
|
72
77
|
export declare function preUploadAttachments(opts: {
|
|
73
78
|
attachments: AgentChatAttachment[] | undefined;
|
|
@@ -33,7 +33,7 @@ function escapeXmlAttr(value) {
|
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
35
|
* Returns true when a file-upload provider is currently configured.
|
|
36
|
-
* Used to decide whether
|
|
36
|
+
* Used to decide whether an attachment can be uploaded before the agent turn.
|
|
37
37
|
*/
|
|
38
38
|
export function isFileUploadProviderConfigured() {
|
|
39
39
|
return getActiveFileUploadProvider() !== null;
|
|
@@ -41,12 +41,12 @@ export function isFileUploadProviderConfigured() {
|
|
|
41
41
|
/**
|
|
42
42
|
* Pre-upload chat image attachments through the active file-upload provider
|
|
43
43
|
* (Builder.io by default) so the agent can embed hosted URLs in HTML, slide
|
|
44
|
-
* content, and outbound messages. Keeps the original
|
|
45
|
-
*
|
|
44
|
+
* content, and outbound messages. Keeps the original data URL in memory for
|
|
45
|
+
* the current multimodal turn and adds a hosted `url`.
|
|
46
46
|
*
|
|
47
47
|
* Safe to call when no provider is configured: it returns the attachments
|
|
48
|
-
* untouched with `providerMissing: true` so callers can surface
|
|
49
|
-
*
|
|
48
|
+
* untouched with `providerMissing: true` so callers can surface the storage
|
|
49
|
+
* setup card to the agent without persisting the binary payload.
|
|
50
50
|
*/
|
|
51
51
|
export async function preUploadImageAttachments(opts) {
|
|
52
52
|
return preUploadAttachments({ ...opts, includeFiles: false });
|
|
@@ -59,8 +59,9 @@ export async function preUploadImageAttachments(opts) {
|
|
|
59
59
|
* file-reading still work; callers that persist the attachment can drop the
|
|
60
60
|
* data when a URL exists.
|
|
61
61
|
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
62
|
+
* When no provider is configured, returns untouched in-memory attachments with
|
|
63
|
+
* `providerMissing: true`. The caller may still use the bytes for this turn,
|
|
64
|
+
* but must not persist them as SQL/base64 attachment data.
|
|
64
65
|
*/
|
|
65
66
|
export async function preUploadAttachments(opts) {
|
|
66
67
|
const list = Array.isArray(opts.attachments) ? opts.attachments : [];
|
|
@@ -68,12 +69,15 @@ export async function preUploadAttachments(opts) {
|
|
|
68
69
|
const uploaded = [];
|
|
69
70
|
const uploadedFiles = [];
|
|
70
71
|
let providerMissing = false;
|
|
72
|
+
let uploadFailed = false;
|
|
73
|
+
let uploadError;
|
|
71
74
|
if (list.length === 0) {
|
|
72
75
|
return {
|
|
73
76
|
attachments: list,
|
|
74
77
|
uploaded,
|
|
75
78
|
uploadedFiles,
|
|
76
79
|
providerMissing: false,
|
|
80
|
+
uploadFailed: false,
|
|
77
81
|
injectedText: null,
|
|
78
82
|
};
|
|
79
83
|
}
|
|
@@ -82,11 +86,9 @@ export async function preUploadAttachments(opts) {
|
|
|
82
86
|
const isFile = att.type === "file" || att.type === "document";
|
|
83
87
|
if (!isImage && !(includeFiles && isFile))
|
|
84
88
|
continue;
|
|
85
|
-
if (typeof att.
|
|
86
|
-
continue;
|
|
87
|
-
if (att.url) {
|
|
89
|
+
if (typeof att.url === "string" && att.url.trim()) {
|
|
88
90
|
// Already pre-uploaded earlier in the pipeline — reuse it.
|
|
89
|
-
const isReferenceOnlySvg = isSvgAttachment(att);
|
|
91
|
+
const isReferenceOnlySvg = att.referenceOnly === true || isSvgAttachment(att);
|
|
90
92
|
if (isReferenceOnlySvg) {
|
|
91
93
|
markReferenceOnlySvgAttachment(att, att.contentType);
|
|
92
94
|
}
|
|
@@ -110,7 +112,21 @@ export async function preUploadAttachments(opts) {
|
|
|
110
112
|
}
|
|
111
113
|
continue;
|
|
112
114
|
}
|
|
113
|
-
|
|
115
|
+
let data = att.data;
|
|
116
|
+
if (typeof data !== "string" &&
|
|
117
|
+
includeFiles &&
|
|
118
|
+
isFile &&
|
|
119
|
+
typeof att.text === "string" &&
|
|
120
|
+
att.text.length > 0) {
|
|
121
|
+
// Text attachments are already decoded by the client. Upload the text
|
|
122
|
+
// bytes too so a later turn has the same durable object URL as binary
|
|
123
|
+
// attachments instead of a SQL-only scratch copy.
|
|
124
|
+
const encoded = Buffer.from(att.text, "utf8").toString("base64");
|
|
125
|
+
data = `data:${normalizeContentType(att.contentType) || "text/plain"};base64,${encoded}`;
|
|
126
|
+
}
|
|
127
|
+
if (typeof data !== "string")
|
|
128
|
+
continue;
|
|
129
|
+
const match = data.match(FILE_DATA_URL_RE);
|
|
114
130
|
if (!match)
|
|
115
131
|
continue;
|
|
116
132
|
const dataUrlMimeType = normalizeContentType(match[1]);
|
|
@@ -134,8 +150,8 @@ export async function preUploadAttachments(opts) {
|
|
|
134
150
|
ownerEmail: opts.ownerEmail || undefined,
|
|
135
151
|
});
|
|
136
152
|
if (!result) {
|
|
137
|
-
|
|
138
|
-
|
|
153
|
+
providerMissing = true;
|
|
154
|
+
att.storageRequired = true;
|
|
139
155
|
continue;
|
|
140
156
|
}
|
|
141
157
|
att.url = result.url;
|
|
@@ -168,8 +184,12 @@ export async function preUploadAttachments(opts) {
|
|
|
168
184
|
}
|
|
169
185
|
}
|
|
170
186
|
catch (err) {
|
|
171
|
-
// Real upload failure (network, API). Keep the
|
|
172
|
-
//
|
|
187
|
+
// Real upload failure (network, API). Keep the bytes in memory for the
|
|
188
|
+
// current turn, but never treat the failure as a durable upload.
|
|
189
|
+
att.storageRequired = true;
|
|
190
|
+
att.storageUploadFailed = true;
|
|
191
|
+
uploadFailed = true;
|
|
192
|
+
uploadError ??= (err instanceof Error ? err.message : String(err)).slice(0, 500);
|
|
173
193
|
console.warn("[agent-native] pre-upload of chat attachment failed:", err instanceof Error ? err.message : String(err));
|
|
174
194
|
}
|
|
175
195
|
}
|
|
@@ -199,21 +219,43 @@ export async function preUploadAttachments(opts) {
|
|
|
199
219
|
lines.push(`<chat-file-attachment ${attrs.join(" ")} />`);
|
|
200
220
|
}
|
|
201
221
|
const hasReferenceOnlySvg = uploadedFiles.some((file) => file.referenceOnly && isSvgAttachment(file));
|
|
202
|
-
|
|
222
|
+
const linesWithMetadata = [
|
|
203
223
|
hasReferenceOnlySvg
|
|
204
224
|
? '<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
225
|
: '<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.">',
|
|
206
226
|
...lines,
|
|
207
227
|
"</chat-attachments>",
|
|
208
|
-
]
|
|
228
|
+
];
|
|
229
|
+
if (providerMissing || uploadFailed) {
|
|
230
|
+
const failureLines = [
|
|
231
|
+
providerMissing
|
|
232
|
+
? "One or more attachments could not be stored because no durable object-storage provider is configured."
|
|
233
|
+
: null,
|
|
234
|
+
uploadFailed
|
|
235
|
+
? `A configured object-storage provider failed to upload an attachment${uploadError ? `: ${escapeXmlAttr(uploadError)}` : "."}`
|
|
236
|
+
: null,
|
|
237
|
+
].filter((line) => Boolean(line));
|
|
238
|
+
linesWithMetadata.push("<chat-file-attachment-upload-error>", ...failureLines, ...(providerMissing
|
|
239
|
+
? [
|
|
240
|
+
"Call `connect-file-storage` now so the user can connect Builder or configure custom storage keys, then continue using the hosted references.",
|
|
241
|
+
]
|
|
242
|
+
: [
|
|
243
|
+
"Retry the upload or inspect the configured storage provider. Do not claim the attachment is durably available until it succeeds.",
|
|
244
|
+
]), "</chat-file-attachment-upload-error>");
|
|
245
|
+
}
|
|
246
|
+
injectedText = linesWithMetadata.join("\n");
|
|
209
247
|
}
|
|
210
|
-
else if (providerMissing) {
|
|
248
|
+
else if (providerMissing || uploadFailed) {
|
|
211
249
|
injectedText = [
|
|
212
|
-
"<chat-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
250
|
+
"<chat-file-attachment-upload-error>",
|
|
251
|
+
providerMissing
|
|
252
|
+
? "The user attached one or more images or files, but durable object storage is not configured for this app."
|
|
253
|
+
: `The user attached one or more images or files, but the configured storage provider failed to upload them${uploadError ? `: ${escapeXmlAttr(uploadError)}` : "."}`,
|
|
254
|
+
providerMissing
|
|
255
|
+
? "Call `connect-file-storage` now to render the inline storage setup card. The user can connect Builder for managed storage or open the same card's custom-key setup for S3-compatible object storage."
|
|
256
|
+
: "Retry the upload or inspect the configured storage provider. Do not claim the attachment is durably available until it succeeds.",
|
|
257
|
+
"Do not persist the base64 contents in SQL. Until storage succeeds, use the attachment only for this turn.",
|
|
258
|
+
"</chat-file-attachment-upload-error>",
|
|
217
259
|
].join("\n");
|
|
218
260
|
}
|
|
219
261
|
return {
|
|
@@ -221,6 +263,8 @@ export async function preUploadAttachments(opts) {
|
|
|
221
263
|
uploaded,
|
|
222
264
|
uploadedFiles,
|
|
223
265
|
providerMissing,
|
|
266
|
+
uploadFailed,
|
|
267
|
+
...(uploadError ? { uploadError } : {}),
|
|
224
268
|
injectedText,
|
|
225
269
|
};
|
|
226
270
|
}
|
|
@@ -9,15 +9,14 @@ export declare function listFileUploadProviders(): FileUploadProvider[];
|
|
|
9
9
|
/**
|
|
10
10
|
* Returns the first configured provider, checking user-registered ones first
|
|
11
11
|
* and falling back to the built-in Builder.io provider when its env is set.
|
|
12
|
-
* Returns `null` when nothing is configured
|
|
13
|
-
* SQL
|
|
12
|
+
* Returns `null` when nothing is configured. Callers must fail closed rather
|
|
13
|
+
* than persisting the original binary payload in SQL.
|
|
14
14
|
*/
|
|
15
15
|
export declare function getActiveFileUploadProvider(): FileUploadProvider | null;
|
|
16
16
|
export declare function getActiveFileUploadProviderForRequest(): Promise<FileUploadProvider | null>;
|
|
17
17
|
/**
|
|
18
18
|
* Upload a file via the active provider, or `null` if no provider is
|
|
19
|
-
* configured.
|
|
20
|
-
*
|
|
21
|
-
* storing files in SQL is not optimal for production.
|
|
19
|
+
* configured. `null` is an explicit storage-setup state: callers must not
|
|
20
|
+
* turn the input into a base64 SQL fallback.
|
|
22
21
|
*/
|
|
23
22
|
export declare function uploadFile(input: FileUploadInput): Promise<FileUploadResult | null>;
|
|
@@ -18,8 +18,8 @@ export function listFileUploadProviders() {
|
|
|
18
18
|
/**
|
|
19
19
|
* Returns the first configured provider, checking user-registered ones first
|
|
20
20
|
* and falling back to the built-in Builder.io provider when its env is set.
|
|
21
|
-
* Returns `null` when nothing is configured
|
|
22
|
-
* SQL
|
|
21
|
+
* Returns `null` when nothing is configured. Callers must fail closed rather
|
|
22
|
+
* than persisting the original binary payload in SQL.
|
|
23
23
|
*/
|
|
24
24
|
export function getActiveFileUploadProvider() {
|
|
25
25
|
for (const provider of providers.values()) {
|
|
@@ -36,14 +36,8 @@ export async function getActiveFileUploadProviderForRequest() {
|
|
|
36
36
|
if (provider.isConfigured())
|
|
37
37
|
return provider;
|
|
38
38
|
if (provider.isConfiguredForRequest) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
return provider;
|
|
42
|
-
}
|
|
43
|
-
catch {
|
|
44
|
-
// Treat failed scoped credential lookups as unavailable. The upload
|
|
45
|
-
// call will surface real provider errors after a provider is selected.
|
|
46
|
-
}
|
|
39
|
+
if (await provider.isConfiguredForRequest())
|
|
40
|
+
return provider;
|
|
47
41
|
}
|
|
48
42
|
}
|
|
49
43
|
if (builderFileUploadProvider.isConfigured()) {
|
|
@@ -62,9 +56,8 @@ export async function getActiveFileUploadProviderForRequest() {
|
|
|
62
56
|
}
|
|
63
57
|
/**
|
|
64
58
|
* Upload a file via the active provider, or `null` if no provider is
|
|
65
|
-
* configured.
|
|
66
|
-
*
|
|
67
|
-
* storing files in SQL is not optimal for production.
|
|
59
|
+
* configured. `null` is an explicit storage-setup state: callers must not
|
|
60
|
+
* turn the input into a base64 SQL fallback.
|
|
68
61
|
*/
|
|
69
62
|
export async function uploadFile(input) {
|
|
70
63
|
const provider = await getActiveFileUploadProviderForRequest();
|
|
@@ -85,7 +78,7 @@ export async function uploadFile(input) {
|
|
|
85
78
|
}
|
|
86
79
|
catch (err) {
|
|
87
80
|
// DB unavailable or credential store not ready — can't resolve key.
|
|
88
|
-
//
|
|
81
|
+
// Return an unavailable-provider state below; never fall back to SQL.
|
|
89
82
|
console.warn("[agent-native] Builder credential check failed:", err instanceof Error ? err.message : String(err));
|
|
90
83
|
}
|
|
91
84
|
if (builderKey) {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework-owned S3-compatible object storage provider.
|
|
3
|
+
*
|
|
4
|
+
* The onboarding form writes these keys to scoped secrets. A public base URL
|
|
5
|
+
* is required because chat attachments need stable URLs that remain usable
|
|
6
|
+
* after the request and across later turns in the thread.
|
|
7
|
+
*/
|
|
8
|
+
import type { FileUploadProvider } from "./types.js";
|
|
9
|
+
export declare const s3FileUploadProvider: FileUploadProvider;
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework-owned S3-compatible object storage provider.
|
|
3
|
+
*
|
|
4
|
+
* The onboarding form writes these keys to scoped secrets. A public base URL
|
|
5
|
+
* is required because chat attachments need stable URLs that remain usable
|
|
6
|
+
* after the request and across later turns in the thread.
|
|
7
|
+
*/
|
|
8
|
+
import { resolveSecret } from "../server/credential-provider.js";
|
|
9
|
+
function cleanValue(value) {
|
|
10
|
+
const cleaned = value?.trim();
|
|
11
|
+
return cleaned ? cleaned : undefined;
|
|
12
|
+
}
|
|
13
|
+
function buildConfig(values) {
|
|
14
|
+
const bucket = cleanValue(values.bucket);
|
|
15
|
+
const accessKeyId = cleanValue(values.accessKeyId);
|
|
16
|
+
const secretAccessKey = cleanValue(values.secretAccessKey);
|
|
17
|
+
const endpoint = cleanValue(values.endpoint)?.replace(/\/+$/, "");
|
|
18
|
+
const publicBaseUrl = cleanValue(values.publicBaseUrl)?.replace(/\/+$/, "");
|
|
19
|
+
if (!bucket ||
|
|
20
|
+
!accessKeyId ||
|
|
21
|
+
!secretAccessKey ||
|
|
22
|
+
!endpoint ||
|
|
23
|
+
!publicBaseUrl) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
if (!URL.canParse(endpoint) || !URL.canParse(publicBaseUrl)) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const endpointUrl = new URL(endpoint);
|
|
30
|
+
const publicUrl = new URL(publicBaseUrl);
|
|
31
|
+
if (!["http:", "https:"].includes(endpointUrl.protocol) ||
|
|
32
|
+
!["http:", "https:"].includes(publicUrl.protocol)) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
region: cleanValue(values.region) ?? "auto",
|
|
37
|
+
bucket,
|
|
38
|
+
accessKeyId,
|
|
39
|
+
secretAccessKey,
|
|
40
|
+
endpoint,
|
|
41
|
+
publicBaseUrl,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function readEnvConfig() {
|
|
45
|
+
const env = process.env;
|
|
46
|
+
return buildConfig({
|
|
47
|
+
bucket: env.S3_BUCKET || env.R2_BUCKET,
|
|
48
|
+
accessKeyId: env.S3_ACCESS_KEY_ID || env.R2_ACCESS_KEY_ID,
|
|
49
|
+
secretAccessKey: env.S3_SECRET_ACCESS_KEY || env.R2_SECRET_ACCESS_KEY,
|
|
50
|
+
endpoint: env.S3_ENDPOINT || env.R2_ENDPOINT,
|
|
51
|
+
region: env.S3_REGION || env.R2_REGION,
|
|
52
|
+
publicBaseUrl: env.S3_PUBLIC_BASE_URL || env.R2_PUBLIC_BASE_URL,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
async function resolveStorageSecret(primary, fallback) {
|
|
56
|
+
const primaryValue = cleanValue(await resolveSecret(primary));
|
|
57
|
+
return primaryValue ?? cleanValue(await resolveSecret(fallback));
|
|
58
|
+
}
|
|
59
|
+
async function readRequestConfig() {
|
|
60
|
+
const scopedConfig = buildConfig({
|
|
61
|
+
bucket: await resolveStorageSecret("S3_BUCKET", "R2_BUCKET"),
|
|
62
|
+
accessKeyId: await resolveStorageSecret("S3_ACCESS_KEY_ID", "R2_ACCESS_KEY_ID"),
|
|
63
|
+
secretAccessKey: await resolveStorageSecret("S3_SECRET_ACCESS_KEY", "R2_SECRET_ACCESS_KEY"),
|
|
64
|
+
endpoint: await resolveStorageSecret("S3_ENDPOINT", "R2_ENDPOINT"),
|
|
65
|
+
region: await resolveStorageSecret("S3_REGION", "R2_REGION"),
|
|
66
|
+
publicBaseUrl: await resolveStorageSecret("S3_PUBLIC_BASE_URL", "R2_PUBLIC_BASE_URL"),
|
|
67
|
+
});
|
|
68
|
+
return scopedConfig ?? readEnvConfig();
|
|
69
|
+
}
|
|
70
|
+
async function hmac(key, message) {
|
|
71
|
+
const cryptoKey = await crypto.subtle.importKey("raw", key, { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
|
|
72
|
+
return crypto.subtle.sign("HMAC", cryptoKey, new TextEncoder().encode(message));
|
|
73
|
+
}
|
|
74
|
+
async function sha256(data) {
|
|
75
|
+
const buffer = new ArrayBuffer(data.byteLength);
|
|
76
|
+
new Uint8Array(buffer).set(data);
|
|
77
|
+
return toHex(await crypto.subtle.digest("SHA-256", buffer));
|
|
78
|
+
}
|
|
79
|
+
function toHex(buffer) {
|
|
80
|
+
return Array.from(new Uint8Array(buffer), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
81
|
+
}
|
|
82
|
+
async function signingKey(secret, dateStamp, region) {
|
|
83
|
+
const dateKey = await hmac(new TextEncoder().encode(`AWS4${secret}`).buffer, dateStamp);
|
|
84
|
+
const regionKey = await hmac(dateKey, region);
|
|
85
|
+
const serviceKey = await hmac(regionKey, "s3");
|
|
86
|
+
return hmac(serviceKey, "aws4_request");
|
|
87
|
+
}
|
|
88
|
+
function encodePathSegment(value) {
|
|
89
|
+
return encodeURIComponent(value).replace(/[!'()*]/g, (char) => `%${char.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
90
|
+
}
|
|
91
|
+
function objectPath(config, key) {
|
|
92
|
+
return `/${config.bucket}/${key.split("/").map(encodePathSegment).join("/")}`;
|
|
93
|
+
}
|
|
94
|
+
async function putObject(config, key, data, contentType) {
|
|
95
|
+
const now = new Date();
|
|
96
|
+
const amzDate = now
|
|
97
|
+
.toISOString()
|
|
98
|
+
.replace(/[:-]|\.\d{3}/g, "")
|
|
99
|
+
.slice(0, 15) + "Z";
|
|
100
|
+
const dateStamp = amzDate.slice(0, 8);
|
|
101
|
+
const credentialScope = `${dateStamp}/${config.region}/s3/aws4_request`;
|
|
102
|
+
const host = new URL(config.endpoint).host;
|
|
103
|
+
const canonicalUri = objectPath(config, key);
|
|
104
|
+
const payloadHash = await sha256(data);
|
|
105
|
+
const headers = {
|
|
106
|
+
host,
|
|
107
|
+
"content-type": contentType,
|
|
108
|
+
"x-amz-content-sha256": payloadHash,
|
|
109
|
+
"x-amz-date": amzDate,
|
|
110
|
+
};
|
|
111
|
+
const signedHeaderKeys = Object.keys(headers).sort();
|
|
112
|
+
const signedHeaders = signedHeaderKeys.join(";");
|
|
113
|
+
const canonicalHeaders = signedHeaderKeys
|
|
114
|
+
.map((header) => `${header}:${headers[header]}`)
|
|
115
|
+
.join("\n") + "\n";
|
|
116
|
+
const canonicalRequest = [
|
|
117
|
+
"PUT",
|
|
118
|
+
canonicalUri,
|
|
119
|
+
"",
|
|
120
|
+
canonicalHeaders,
|
|
121
|
+
signedHeaders,
|
|
122
|
+
payloadHash,
|
|
123
|
+
].join("\n");
|
|
124
|
+
const requestHash = await sha256(new TextEncoder().encode(canonicalRequest));
|
|
125
|
+
const stringToSign = [
|
|
126
|
+
"AWS4-HMAC-SHA256",
|
|
127
|
+
amzDate,
|
|
128
|
+
credentialScope,
|
|
129
|
+
requestHash,
|
|
130
|
+
].join("\n");
|
|
131
|
+
const signature = toHex(await hmac(await signingKey(config.secretAccessKey, dateStamp, config.region), stringToSign));
|
|
132
|
+
const authorization = `AWS4-HMAC-SHA256 Credential=${config.accessKeyId}/${credentialScope}, ` +
|
|
133
|
+
`SignedHeaders=${signedHeaders}, Signature=${signature}`;
|
|
134
|
+
const response = await fetch(`${config.endpoint}${canonicalUri}`, {
|
|
135
|
+
method: "PUT",
|
|
136
|
+
headers: {
|
|
137
|
+
...headers,
|
|
138
|
+
Authorization: authorization,
|
|
139
|
+
"Content-Length": String(data.byteLength),
|
|
140
|
+
},
|
|
141
|
+
body: data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength),
|
|
142
|
+
});
|
|
143
|
+
if (!response.ok) {
|
|
144
|
+
const detail = await response.text();
|
|
145
|
+
throw new Error(`S3 PutObject failed (${response.status}): ${detail || response.statusText}`);
|
|
146
|
+
}
|
|
147
|
+
return `${config.publicBaseUrl}/${key.split("/").map(encodePathSegment).join("/")}`;
|
|
148
|
+
}
|
|
149
|
+
function safeFilename(filename) {
|
|
150
|
+
const basename = filename?.split(/[\\/]/).pop()?.trim() || "attachment";
|
|
151
|
+
return (basename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 160) || "attachment");
|
|
152
|
+
}
|
|
153
|
+
export const s3FileUploadProvider = {
|
|
154
|
+
id: "s3",
|
|
155
|
+
name: "S3-compatible object storage",
|
|
156
|
+
isConfigured: () => readEnvConfig() !== null,
|
|
157
|
+
isConfiguredForRequest: async () => (await readRequestConfig()) !== null,
|
|
158
|
+
upload: async ({ data, filename, mimeType }) => {
|
|
159
|
+
const config = await readRequestConfig();
|
|
160
|
+
if (!config) {
|
|
161
|
+
throw new Error("S3 object storage requires a bucket, endpoint, credentials, and public base URL");
|
|
162
|
+
}
|
|
163
|
+
const key = `uploads/${Date.now()}-${Math.random().toString(36).slice(2, 10)}-${safeFilename(filename)}`;
|
|
164
|
+
const bytes = data instanceof Uint8Array ? data : new Uint8Array(data);
|
|
165
|
+
const url = await putObject(config, key, bytes, mimeType || "application/octet-stream");
|
|
166
|
+
return { url, provider: "s3" };
|
|
167
|
+
},
|
|
168
|
+
};
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Templates call `uploadFile()` to upload a file and get back a URL.
|
|
5
5
|
* The framework dispatches to whichever provider is registered (Builder.io
|
|
6
|
-
* built-in, or a user-supplied one). If no provider is active,
|
|
7
|
-
*
|
|
6
|
+
* built-in, or a user-supplied one). If no provider is active, uploads fail
|
|
7
|
+
* closed so binary payloads never get persisted as base64 in SQL.
|
|
8
8
|
*/
|
|
9
9
|
export interface FileUploadInput {
|
|
10
10
|
/** File contents. */
|
|
@@ -13,7 +13,7 @@ export interface FileUploadInput {
|
|
|
13
13
|
filename?: string;
|
|
14
14
|
/** MIME type, e.g. "image/png". */
|
|
15
15
|
mimeType?: string;
|
|
16
|
-
/**
|
|
16
|
+
/** Owner email used for request-scoped provider credentials. */
|
|
17
17
|
ownerEmail?: string;
|
|
18
18
|
/** Builder.io upload hint: return one stable URL while compression finishes asynchronously. */
|
|
19
19
|
stableUrl?: boolean;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Templates call `uploadFile()` to upload a file and get back a URL.
|
|
5
5
|
* The framework dispatches to whichever provider is registered (Builder.io
|
|
6
|
-
* built-in, or a user-supplied one). If no provider is active,
|
|
7
|
-
*
|
|
6
|
+
* built-in, or a user-supplied one). If no provider is active, uploads fail
|
|
7
|
+
* closed so binary payloads never get persisted as base64 in SQL.
|
|
8
8
|
*/
|
|
9
9
|
export {};
|
|
@@ -137,13 +137,13 @@ export declare function screenMemoryMcpToolDefinitions(): ({
|
|
|
137
137
|
inputSchema: {
|
|
138
138
|
type: string;
|
|
139
139
|
properties: {
|
|
140
|
-
count?: undefined;
|
|
141
140
|
query?: undefined;
|
|
142
141
|
minutes?: undefined;
|
|
143
142
|
limit?: undefined;
|
|
144
143
|
clientHint?: undefined;
|
|
145
144
|
timestamp?: undefined;
|
|
146
145
|
chapterId?: undefined;
|
|
146
|
+
count?: undefined;
|
|
147
147
|
startAt?: undefined;
|
|
148
148
|
endAt?: undefined;
|
|
149
149
|
reason?: undefined;
|
|
@@ -159,7 +159,6 @@ export declare function screenMemoryMcpToolDefinitions(): ({
|
|
|
159
159
|
inputSchema: {
|
|
160
160
|
type: string;
|
|
161
161
|
properties: {
|
|
162
|
-
count?: undefined;
|
|
163
162
|
query: {
|
|
164
163
|
type: string;
|
|
165
164
|
description: string;
|
|
@@ -175,6 +174,7 @@ export declare function screenMemoryMcpToolDefinitions(): ({
|
|
|
175
174
|
clientHint?: undefined;
|
|
176
175
|
timestamp?: undefined;
|
|
177
176
|
chapterId?: undefined;
|
|
177
|
+
count?: undefined;
|
|
178
178
|
startAt?: undefined;
|
|
179
179
|
endAt?: undefined;
|
|
180
180
|
reason?: undefined;
|
|
@@ -190,7 +190,6 @@ export declare function screenMemoryMcpToolDefinitions(): ({
|
|
|
190
190
|
inputSchema: {
|
|
191
191
|
type: string;
|
|
192
192
|
properties: {
|
|
193
|
-
count?: undefined;
|
|
194
193
|
minutes: {
|
|
195
194
|
type: string;
|
|
196
195
|
description: string;
|
|
@@ -200,6 +199,7 @@ export declare function screenMemoryMcpToolDefinitions(): ({
|
|
|
200
199
|
clientHint?: undefined;
|
|
201
200
|
timestamp?: undefined;
|
|
202
201
|
chapterId?: undefined;
|
|
202
|
+
count?: undefined;
|
|
203
203
|
startAt?: undefined;
|
|
204
204
|
endAt?: undefined;
|
|
205
205
|
reason?: undefined;
|
|
@@ -216,7 +216,6 @@ export declare function screenMemoryMcpToolDefinitions(): ({
|
|
|
216
216
|
type: string;
|
|
217
217
|
required: string[];
|
|
218
218
|
properties: {
|
|
219
|
-
count?: undefined;
|
|
220
219
|
query: {
|
|
221
220
|
type: string;
|
|
222
221
|
description: string;
|
|
@@ -235,6 +234,7 @@ export declare function screenMemoryMcpToolDefinitions(): ({
|
|
|
235
234
|
};
|
|
236
235
|
timestamp?: undefined;
|
|
237
236
|
chapterId?: undefined;
|
|
237
|
+
count?: undefined;
|
|
238
238
|
startAt?: undefined;
|
|
239
239
|
endAt?: undefined;
|
|
240
240
|
reason?: undefined;
|
|
@@ -250,7 +250,6 @@ export declare function screenMemoryMcpToolDefinitions(): ({
|
|
|
250
250
|
type: string;
|
|
251
251
|
required: string[];
|
|
252
252
|
properties: {
|
|
253
|
-
count?: undefined;
|
|
254
253
|
query?: undefined;
|
|
255
254
|
minutes?: undefined;
|
|
256
255
|
limit?: undefined;
|
|
@@ -264,6 +263,7 @@ export declare function screenMemoryMcpToolDefinitions(): ({
|
|
|
264
263
|
description: string;
|
|
265
264
|
};
|
|
266
265
|
chapterId?: undefined;
|
|
266
|
+
count?: undefined;
|
|
267
267
|
startAt?: undefined;
|
|
268
268
|
endAt?: undefined;
|
|
269
269
|
includeMicrophone?: undefined;
|
|
@@ -314,13 +314,13 @@ export declare function screenMemoryMcpToolDefinitions(): ({
|
|
|
314
314
|
type: string;
|
|
315
315
|
required: string[];
|
|
316
316
|
properties: {
|
|
317
|
-
count?: undefined;
|
|
318
317
|
query?: undefined;
|
|
319
318
|
minutes?: undefined;
|
|
320
319
|
limit?: undefined;
|
|
321
320
|
clientHint?: undefined;
|
|
322
321
|
timestamp?: undefined;
|
|
323
322
|
chapterId?: undefined;
|
|
323
|
+
count?: undefined;
|
|
324
324
|
startAt: {
|
|
325
325
|
type: string;
|
|
326
326
|
description: string;
|
|
@@ -349,13 +349,13 @@ export declare function screenMemoryMcpToolDefinitions(): ({
|
|
|
349
349
|
type: string;
|
|
350
350
|
required: string[];
|
|
351
351
|
properties: {
|
|
352
|
-
count?: undefined;
|
|
353
352
|
query?: undefined;
|
|
354
353
|
minutes?: undefined;
|
|
355
354
|
limit?: undefined;
|
|
356
355
|
clientHint?: undefined;
|
|
357
356
|
timestamp?: undefined;
|
|
358
357
|
chapterId?: undefined;
|
|
358
|
+
count?: undefined;
|
|
359
359
|
startAt?: undefined;
|
|
360
360
|
endAt?: undefined;
|
|
361
361
|
reason?: undefined;
|
|
@@ -13,21 +13,21 @@
|
|
|
13
13
|
export declare function createNotificationsHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<"" | import("./types.js").Notification[] | {
|
|
14
14
|
count: number;
|
|
15
15
|
updated?: undefined;
|
|
16
|
-
error?: undefined;
|
|
17
16
|
ok?: undefined;
|
|
17
|
+
error?: undefined;
|
|
18
18
|
} | {
|
|
19
|
-
count?: undefined;
|
|
20
19
|
updated: number;
|
|
21
|
-
error?: undefined;
|
|
22
20
|
ok?: undefined;
|
|
23
|
-
|
|
21
|
+
error?: undefined;
|
|
24
22
|
count?: undefined;
|
|
23
|
+
} | {
|
|
25
24
|
updated?: undefined;
|
|
26
25
|
error: string;
|
|
27
26
|
ok?: undefined;
|
|
28
|
-
} | {
|
|
29
27
|
count?: undefined;
|
|
28
|
+
} | {
|
|
30
29
|
updated?: undefined;
|
|
31
|
-
error?: undefined;
|
|
32
30
|
ok: boolean;
|
|
31
|
+
error?: undefined;
|
|
32
|
+
count?: undefined;
|
|
33
33
|
}>>;
|