@agent-native/toolkit 0.225.2-nightly-20261106152255 → 0.226.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/agent-native.eject.json +1 -0
- package/dist/app/agentkit/react/components.d.ts.map +1 -1
- package/dist/app/agentkit/react/components.js +124 -9
- package/dist/app/agentkit/react/components.js.map +1 -1
- package/dist/app/agentkit/react/context.d.ts +1 -1
- package/dist/app/agentkit/react/core-file-storage.d.ts +21 -0
- package/dist/app/agentkit/react/core-file-storage.d.ts.map +1 -0
- package/dist/app/agentkit/react/core-file-storage.js +3 -0
- package/dist/app/agentkit/react/core-file-storage.js.map +1 -0
- package/dist/app/auth/AuthPage.d.ts.map +1 -1
- package/dist/app/auth/AuthPage.js +89 -10
- package/dist/app/auth/AuthPage.js.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.js +39 -58
- package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
- package/dist/app/chat/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/MultiTabAssistantChat.js +3 -1
- package/dist/app/chat/MultiTabAssistantChat.js.map +1 -1
- package/dist/app/chat/agentkit-chat/root.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/root.js +66 -2
- package/dist/app/chat/agentkit-chat/root.js.map +1 -1
- package/dist/app/chat/chat/surface-types.d.ts +1 -0
- package/dist/app/chat/chat/surface-types.d.ts.map +1 -1
- package/dist/app/chat/chat/surface-types.js.map +1 -1
- package/dist/app/chat/composer/runtime-adapters.d.ts.map +1 -1
- package/dist/app/chat/composer/runtime-adapters.js +2 -0
- package/dist/app/chat/composer/runtime-adapters.js.map +1 -1
- package/dist/app/chat/composer/use-agentkit-capabilities.d.ts +3 -1
- package/dist/app/chat/composer/use-agentkit-capabilities.d.ts.map +1 -1
- package/dist/app/chat/composer/use-agentkit-capabilities.js +11 -11
- package/dist/app/chat/composer/use-agentkit-capabilities.js.map +1 -1
- package/dist/app/chat/composer/use-workspace-composer-menu.d.ts +3 -0
- package/dist/app/chat/composer/use-workspace-composer-menu.d.ts.map +1 -0
- package/dist/app/chat/composer/use-workspace-composer-menu.js +80 -0
- package/dist/app/chat/composer/use-workspace-composer-menu.js.map +1 -0
- package/dist/app/chat/index.d.ts +1 -0
- package/dist/app/chat/index.d.ts.map +1 -1
- package/dist/app/chat/index.js +1 -0
- package/dist/app/chat/index.js.map +1 -1
- package/dist/app/chat/prepare-prompt-composer-agent-handoff.d.ts +5 -0
- package/dist/app/chat/prepare-prompt-composer-agent-handoff.d.ts.map +1 -0
- package/dist/app/chat/prepare-prompt-composer-agent-handoff.js +108 -0
- package/dist/app/chat/prepare-prompt-composer-agent-handoff.js.map +1 -0
- package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.js +6 -1
- package/dist/app/i18n/catalogs/ar-SA.js.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.js +6 -1
- package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
- package/dist/app/i18n/catalogs/en-US.d.ts +6 -1
- package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/en-US.js +6 -1
- package/dist/app/i18n/catalogs/en-US.js.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.js +6 -1
- package/dist/app/i18n/catalogs/es-ES.js.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.js +6 -1
- package/dist/app/i18n/catalogs/fr-FR.js.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.js +6 -1
- package/dist/app/i18n/catalogs/hi-IN.js.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.js +6 -1
- package/dist/app/i18n/catalogs/ja-JP.js.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.js +6 -1
- package/dist/app/i18n/catalogs/ko-KR.js.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.js +6 -1
- package/dist/app/i18n/catalogs/pt-BR.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.js +6 -1
- package/dist/app/i18n/catalogs/zh-CN.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.js +6 -1
- package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
- package/dist/app/resources/McpIntegrationDialog.d.ts +3 -1
- package/dist/app/resources/McpIntegrationDialog.d.ts.map +1 -1
- package/dist/app/resources/McpIntegrationDialog.js +2 -2
- package/dist/app/resources/McpIntegrationDialog.js.map +1 -1
- package/dist/app/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/app/settings/useBuilderStatus.js +119 -40
- package/dist/app/settings/useBuilderStatus.js.map +1 -1
- package/dist/composer/ComposerContextMenu.d.ts +36 -2
- package/dist/composer/ComposerContextMenu.d.ts.map +1 -1
- package/dist/composer/ComposerContextMenu.js +108 -40
- package/dist/composer/ComposerContextMenu.js.map +1 -1
- package/dist/composer/ComposerContextPickerDialog.d.ts.map +1 -1
- package/dist/composer/ComposerContextPickerDialog.js +63 -26
- package/dist/composer/ComposerContextPickerDialog.js.map +1 -1
- package/dist/composer/ComposerPlusMenu.d.ts +5 -3
- package/dist/composer/ComposerPlusMenu.d.ts.map +1 -1
- package/dist/composer/ComposerPlusMenu.js +166 -121
- package/dist/composer/ComposerPlusMenu.js.map +1 -1
- package/dist/composer/MentionItemMedia.d.ts.map +1 -1
- package/dist/composer/MentionItemMedia.js +3 -1
- package/dist/composer/MentionItemMedia.js.map +1 -1
- package/dist/composer/PromptComposer.d.ts +1 -0
- package/dist/composer/PromptComposer.d.ts.map +1 -1
- package/dist/composer/PromptComposer.js +1 -0
- package/dist/composer/PromptComposer.js.map +1 -1
- package/dist/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/composer/TiptapComposer.js +117 -50
- package/dist/composer/TiptapComposer.js.map +1 -1
- package/dist/composer/index.d.ts +1 -0
- package/dist/composer/index.d.ts.map +1 -1
- package/dist/composer/runtime-adapters.d.ts +15 -0
- package/dist/composer/runtime-adapters.d.ts.map +1 -1
- package/dist/composer/runtime-adapters.js.map +1 -1
- package/dist/composer/use-composer-panel-placement.d.ts.map +1 -1
- package/dist/composer/use-composer-panel-placement.js +2 -4
- package/dist/composer/use-composer-panel-placement.js.map +1 -1
- package/dist/composer/use-mention-search.d.ts +7 -0
- package/dist/composer/use-mention-search.d.ts.map +1 -1
- package/dist/composer/use-mention-search.js +86 -19
- package/dist/composer/use-mention-search.js.map +1 -1
- package/dist/composer/useComposerContextPicker.d.ts +5 -1
- package/dist/composer/useComposerContextPicker.d.ts.map +1 -1
- package/dist/composer/useComposerContextPicker.js +18 -4
- package/dist/composer/useComposerContextPicker.js.map +1 -1
- package/package.json +4 -4
- package/src/app/agentkit/react/components.tsx +158 -11
- package/src/app/agentkit/react/composer-context.spec.tsx +180 -0
- package/src/app/agentkit/react/core-file-storage.tsx +14 -0
- package/src/app/auth/AuthPage.interaction.spec.tsx +143 -0
- package/src/app/auth/AuthPage.tsx +159 -13
- package/src/app/chat/AgentKitAssistantChat.spec.tsx +65 -3
- package/src/app/chat/AgentKitAssistantChat.tsx +57 -65
- package/src/app/chat/MultiTabAssistantChat.spec.tsx +21 -0
- package/src/app/chat/MultiTabAssistantChat.tsx +4 -0
- package/src/app/chat/agentkit-chat/root.tsx +91 -8
- package/src/app/chat/chat/surface-types.ts +1 -0
- package/src/app/chat/composer/runtime-adapters.tsx +2 -0
- package/src/app/chat/composer/use-agentkit-capabilities.hardening.spec.tsx +26 -1
- package/src/app/chat/composer/use-agentkit-capabilities.ts +11 -11
- package/src/app/chat/composer/use-agentkit-integration-menu.spec.tsx +2 -4
- package/src/app/chat/composer/use-workspace-composer-menu.spec.tsx +174 -0
- package/src/app/chat/composer/use-workspace-composer-menu.tsx +122 -0
- package/src/app/chat/index.ts +1 -0
- package/src/app/chat/prepare-prompt-composer-agent-handoff.spec.ts +162 -0
- package/src/app/chat/prepare-prompt-composer-agent-handoff.ts +134 -0
- package/src/app/i18n/catalogs/ar-SA.ts +6 -1
- package/src/app/i18n/catalogs/de-DE.ts +6 -1
- package/src/app/i18n/catalogs/en-US.ts +6 -1
- package/src/app/i18n/catalogs/es-ES.ts +6 -1
- package/src/app/i18n/catalogs/fr-FR.ts +6 -1
- package/src/app/i18n/catalogs/hi-IN.ts +6 -1
- package/src/app/i18n/catalogs/ja-JP.ts +6 -1
- package/src/app/i18n/catalogs/ko-KR.ts +6 -1
- package/src/app/i18n/catalogs/pt-BR.ts +6 -1
- package/src/app/i18n/catalogs/zh-CN.ts +6 -1
- package/src/app/i18n/catalogs/zh-TW.ts +6 -1
- package/src/app/resources/McpIntegrationDialog.tsx +5 -0
- package/src/app/settings/useBuilderStatus.spec.tsx +229 -13
- package/src/app/settings/useBuilderStatus.ts +145 -47
- package/src/composer/ComposerContextMenu.spec.tsx +95 -32
- package/src/composer/ComposerContextMenu.tsx +284 -73
- package/src/composer/ComposerContextPicker.spec.tsx +13 -14
- package/src/composer/ComposerContextPickerDialog.spec.tsx +40 -3
- package/src/composer/ComposerContextPickerDialog.tsx +158 -24
- package/src/composer/ComposerPlusMenu.parity.spec.tsx +442 -62
- package/src/composer/ComposerPlusMenu.tsx +322 -237
- package/src/composer/MentionItemMedia.tsx +3 -0
- package/src/composer/PromptComposer.context.spec.tsx +253 -82
- package/src/composer/PromptComposer.tsx +2 -0
- package/src/composer/TiptapComposer.spec.ts +6 -8
- package/src/composer/TiptapComposer.tsx +148 -55
- package/src/composer/index.ts +5 -0
- package/src/composer/runtime-adapters.tsx +18 -0
- package/src/composer/use-composer-panel-placement.ts +2 -4
- package/src/composer/use-mention-search.spec.tsx +99 -1
- package/src/composer/use-mention-search.ts +101 -24
- package/src/composer/useComposerContextPicker.ts +25 -5
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
// @vitest-environment happy-dom
|
|
2
|
+
import { describe, expect, it, vi } from "vitest";
|
|
3
|
+
|
|
4
|
+
import { preparePromptComposerAgentHandoff } from "./prepare-prompt-composer-agent-handoff.js";
|
|
5
|
+
|
|
6
|
+
describe("prompt composer agent handoff", () => {
|
|
7
|
+
it("counts serialized metadata only once near the body budget", async () => {
|
|
8
|
+
const name = '"\\é'.repeat(450_000);
|
|
9
|
+
const result = await preparePromptComposerAgentHandoff(
|
|
10
|
+
[],
|
|
11
|
+
{
|
|
12
|
+
attachments: [
|
|
13
|
+
{
|
|
14
|
+
name,
|
|
15
|
+
content: [{ type: "file", url: "https://example.test/file" }],
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
},
|
|
19
|
+
"Upload failed",
|
|
20
|
+
);
|
|
21
|
+
expect(result.attachments?.[0]?.name).toBe(name);
|
|
22
|
+
});
|
|
23
|
+
it.each([[3 * 1024 * 1024], [2 * 1024 * 1024, 2 * 1024 * 1024]])(
|
|
24
|
+
"rejects oversized raw files before reading any",
|
|
25
|
+
async (...sizes) => {
|
|
26
|
+
const files = sizes.map((size, index) => {
|
|
27
|
+
const file = new File(["small"], `${index}.txt`);
|
|
28
|
+
Object.defineProperty(file, "size", { value: size });
|
|
29
|
+
return file;
|
|
30
|
+
});
|
|
31
|
+
const read = vi.spyOn(FileReader.prototype, "readAsDataURL");
|
|
32
|
+
try {
|
|
33
|
+
await expect(
|
|
34
|
+
preparePromptComposerAgentHandoff(files, {}, "Upload failed"),
|
|
35
|
+
).rejects.toMatchObject({
|
|
36
|
+
code: "upload_too_large",
|
|
37
|
+
cause: { code: "upload_too_large" },
|
|
38
|
+
});
|
|
39
|
+
expect(read).not.toHaveBeenCalled();
|
|
40
|
+
} finally {
|
|
41
|
+
read.mockRestore();
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
);
|
|
45
|
+
it("preserves raw file bytes once and durable attachment URLs", async () => {
|
|
46
|
+
const file = new File(["review content"], "review.txt", {
|
|
47
|
+
type: "text/plain",
|
|
48
|
+
});
|
|
49
|
+
const result = await preparePromptComposerAgentHandoff(
|
|
50
|
+
[file],
|
|
51
|
+
{
|
|
52
|
+
attachments: [
|
|
53
|
+
{ file, name: file.name },
|
|
54
|
+
{
|
|
55
|
+
name: "saved.pdf",
|
|
56
|
+
content: [
|
|
57
|
+
{
|
|
58
|
+
type: "file",
|
|
59
|
+
url: "https://example.test/saved.pdf",
|
|
60
|
+
mimeType: "application/pdf",
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
"Localized upload failure",
|
|
67
|
+
);
|
|
68
|
+
expect(result.attachments).toEqual([
|
|
69
|
+
{
|
|
70
|
+
type: "file",
|
|
71
|
+
name: "saved.pdf",
|
|
72
|
+
url: "https://example.test/saved.pdf",
|
|
73
|
+
contentType: "application/pdf",
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
type: "file",
|
|
77
|
+
name: "review.txt",
|
|
78
|
+
contentType: "text/plain",
|
|
79
|
+
data: "data:text/plain;base64,cmV2aWV3IGNvbnRlbnQ=",
|
|
80
|
+
},
|
|
81
|
+
]);
|
|
82
|
+
});
|
|
83
|
+
it("preserves orphan files and prefers uploaded content over retained raw files", async () => {
|
|
84
|
+
const file = new File(["context"], "context.txt", { type: "text/plain" });
|
|
85
|
+
const orphan = await preparePromptComposerAgentHandoff(
|
|
86
|
+
[],
|
|
87
|
+
{ attachments: [{ file, name: file.name }] },
|
|
88
|
+
"Upload failed",
|
|
89
|
+
);
|
|
90
|
+
expect(orphan.attachments?.[0]).toMatchObject({
|
|
91
|
+
name: "context.txt",
|
|
92
|
+
data: "data:text/plain;base64,Y29udGV4dA==",
|
|
93
|
+
});
|
|
94
|
+
const uploaded = await preparePromptComposerAgentHandoff(
|
|
95
|
+
[file],
|
|
96
|
+
{
|
|
97
|
+
attachments: [
|
|
98
|
+
{
|
|
99
|
+
file,
|
|
100
|
+
name: file.name,
|
|
101
|
+
content: [
|
|
102
|
+
{ type: "file", url: "https://example.test/context.txt" },
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
"Upload failed",
|
|
108
|
+
);
|
|
109
|
+
expect(uploaded.attachments).toEqual([
|
|
110
|
+
{
|
|
111
|
+
type: "file",
|
|
112
|
+
name: "context.txt",
|
|
113
|
+
url: "https://example.test/context.txt",
|
|
114
|
+
contentType: undefined,
|
|
115
|
+
},
|
|
116
|
+
]);
|
|
117
|
+
});
|
|
118
|
+
it("preserves trusted HTTP storage references without reading the raw file", async () => {
|
|
119
|
+
const file = new File(["small"], "large.txt");
|
|
120
|
+
Object.defineProperty(file, "size", { value: 100 * 1024 * 1024 });
|
|
121
|
+
const read = vi.spyOn(FileReader.prototype, "readAsDataURL");
|
|
122
|
+
try {
|
|
123
|
+
const result = await preparePromptComposerAgentHandoff(
|
|
124
|
+
[file],
|
|
125
|
+
{
|
|
126
|
+
attachments: [
|
|
127
|
+
{
|
|
128
|
+
file,
|
|
129
|
+
name: file.name,
|
|
130
|
+
content: [
|
|
131
|
+
{ type: "file", url: "http://127.0.0.1:5203/bucket/file.txt" },
|
|
132
|
+
],
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
},
|
|
136
|
+
"Upload failed",
|
|
137
|
+
);
|
|
138
|
+
expect(result.attachments?.[0]?.url).toBe(
|
|
139
|
+
"http://127.0.0.1:5203/bucket/file.txt",
|
|
140
|
+
);
|
|
141
|
+
expect(read).not.toHaveBeenCalled();
|
|
142
|
+
} finally {
|
|
143
|
+
read.mockRestore();
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
it("rejects unreadable descriptors rather than submitting without selected context", async () => {
|
|
147
|
+
await expect(
|
|
148
|
+
preparePromptComposerAgentHandoff(
|
|
149
|
+
[],
|
|
150
|
+
{
|
|
151
|
+
attachments: [
|
|
152
|
+
{
|
|
153
|
+
name: "missing",
|
|
154
|
+
content: [{ type: "file", url: "blob:unavailable" }],
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
},
|
|
158
|
+
"Localized upload failure",
|
|
159
|
+
),
|
|
160
|
+
).rejects.toThrow("Localized upload failure");
|
|
161
|
+
});
|
|
162
|
+
});
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { isPersistableAttachmentReferenceUrl } from "@agent-native/agentkit/protocol";
|
|
2
|
+
import type { AgentChatMessage } from "@agent-native/core/client/agent-chat";
|
|
3
|
+
|
|
4
|
+
import { MAX_ESTIMATED_BODY_BYTES } from "../../composer/attachment-accept.js";
|
|
5
|
+
import { isPastedTextAttachmentName } from "../../composer/pasted-text.js";
|
|
6
|
+
|
|
7
|
+
function readFile(file: File): Promise<string> {
|
|
8
|
+
return new Promise((resolve, reject) => {
|
|
9
|
+
const reader = new FileReader();
|
|
10
|
+
reader.onload = () =>
|
|
11
|
+
typeof reader.result === "string"
|
|
12
|
+
? resolve(reader.result)
|
|
13
|
+
: reject(new TypeError("Invalid file reader result"));
|
|
14
|
+
reader.onerror = () =>
|
|
15
|
+
reject(reader.error ?? new TypeError("File read failed"));
|
|
16
|
+
reader.readAsDataURL(file);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function prepareHandoff(
|
|
21
|
+
files: readonly File[],
|
|
22
|
+
options: { attachments?: readonly unknown[] },
|
|
23
|
+
): Promise<Pick<AgentChatMessage, "attachments">> {
|
|
24
|
+
const attachments: NonNullable<AgentChatMessage["attachments"]> = [];
|
|
25
|
+
const pending = new Set(files);
|
|
26
|
+
for (const value of options.attachments ?? []) {
|
|
27
|
+
if (!value || typeof value !== "object")
|
|
28
|
+
throw new TypeError("Invalid composer attachment");
|
|
29
|
+
if ("file" in value && value.file instanceof File) {
|
|
30
|
+
const hasDurableContent =
|
|
31
|
+
"content" in value &&
|
|
32
|
+
Array.isArray(value.content) &&
|
|
33
|
+
value.content.some(
|
|
34
|
+
(part: unknown) =>
|
|
35
|
+
part &&
|
|
36
|
+
typeof part === "object" &&
|
|
37
|
+
(("url" in part && isPersistableAttachmentReferenceUrl(part.url)) ||
|
|
38
|
+
("image" in part &&
|
|
39
|
+
isPersistableAttachmentReferenceUrl(part.image))),
|
|
40
|
+
);
|
|
41
|
+
if (hasDurableContent) pending.delete(value.file);
|
|
42
|
+
else {
|
|
43
|
+
if (
|
|
44
|
+
!isPastedTextAttachmentName(value.file.name) ||
|
|
45
|
+
pending.has(value.file)
|
|
46
|
+
)
|
|
47
|
+
pending.add(value.file);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (
|
|
52
|
+
!("name" in value) ||
|
|
53
|
+
typeof value.name !== "string" ||
|
|
54
|
+
!("content" in value) ||
|
|
55
|
+
!Array.isArray(value.content)
|
|
56
|
+
) {
|
|
57
|
+
throw new TypeError("Invalid composer attachment");
|
|
58
|
+
}
|
|
59
|
+
for (const part of value.content) {
|
|
60
|
+
if (!part || typeof part !== "object" || !("type" in part))
|
|
61
|
+
throw new TypeError("Invalid attachment content");
|
|
62
|
+
if (
|
|
63
|
+
part.type === "text" &&
|
|
64
|
+
"text" in part &&
|
|
65
|
+
typeof part.text === "string"
|
|
66
|
+
) {
|
|
67
|
+
attachments.push({ type: "file", name: value.name, text: part.text });
|
|
68
|
+
} else if (
|
|
69
|
+
part.type === "file" &&
|
|
70
|
+
"url" in part &&
|
|
71
|
+
isPersistableAttachmentReferenceUrl(part.url)
|
|
72
|
+
) {
|
|
73
|
+
attachments.push({
|
|
74
|
+
type: "file",
|
|
75
|
+
name: value.name,
|
|
76
|
+
url: part.url,
|
|
77
|
+
contentType:
|
|
78
|
+
"mimeType" in part && typeof part.mimeType === "string"
|
|
79
|
+
? part.mimeType
|
|
80
|
+
: undefined,
|
|
81
|
+
});
|
|
82
|
+
} else if (
|
|
83
|
+
part.type === "image" &&
|
|
84
|
+
"image" in part &&
|
|
85
|
+
typeof part.image === "string" &&
|
|
86
|
+
isPersistableAttachmentReferenceUrl(part.image)
|
|
87
|
+
) {
|
|
88
|
+
attachments.push({ type: "image", name: value.name, url: part.image });
|
|
89
|
+
} else throw new TypeError("Unsupported attachment content");
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const metadata = [
|
|
93
|
+
...attachments,
|
|
94
|
+
...Array.from(pending, (file) => ({ name: file.name, type: file.type })),
|
|
95
|
+
];
|
|
96
|
+
const estimatedBytes =
|
|
97
|
+
new TextEncoder().encode(JSON.stringify(metadata)).byteLength * 1.15 +
|
|
98
|
+
Array.from(pending).reduce(
|
|
99
|
+
(sum, file) => sum + (4 * Math.ceil(file.size / 3) + 64) * 1.15,
|
|
100
|
+
0,
|
|
101
|
+
);
|
|
102
|
+
if (estimatedBytes > MAX_ESTIMATED_BODY_BYTES)
|
|
103
|
+
throw Object.assign(new Error("upload_too_large"), {
|
|
104
|
+
code: "upload_too_large",
|
|
105
|
+
});
|
|
106
|
+
for (const file of pending)
|
|
107
|
+
attachments.push({
|
|
108
|
+
type: file.type.startsWith("image/") ? "image" : "file",
|
|
109
|
+
name: file.name,
|
|
110
|
+
contentType: file.type || "application/octet-stream",
|
|
111
|
+
data: await readFile(file),
|
|
112
|
+
});
|
|
113
|
+
return attachments.length ? { attachments } : {};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export async function preparePromptComposerAgentHandoff(
|
|
117
|
+
files: readonly File[],
|
|
118
|
+
options: { attachments?: readonly unknown[] },
|
|
119
|
+
failureMessage: string,
|
|
120
|
+
): Promise<Pick<AgentChatMessage, "attachments">> {
|
|
121
|
+
try {
|
|
122
|
+
return await prepareHandoff(files, options);
|
|
123
|
+
} catch (cause) {
|
|
124
|
+
throw Object.assign(new Error(failureMessage), {
|
|
125
|
+
cause,
|
|
126
|
+
...(cause &&
|
|
127
|
+
typeof cause === "object" &&
|
|
128
|
+
"code" in cause &&
|
|
129
|
+
typeof cause.code === "string"
|
|
130
|
+
? { code: cause.code }
|
|
131
|
+
: {}),
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -497,7 +497,12 @@ const messages: ToolkitAgentChatTranslation = {
|
|
|
497
497
|
"composer.useIntegrationTools": "استخدم أدوات {{integration}}",
|
|
498
498
|
"composer.menu.scheduleTask": "جدولة مهمة",
|
|
499
499
|
"composer.menu.scheduleTaskDescription": "تشغيل مهمة وفق جدول زمني",
|
|
500
|
-
"composer.menu.uploadFile": "
|
|
500
|
+
"composer.menu.uploadFile": "الملفات والصور",
|
|
501
|
+
"composer.menu.searchWorkspace": "البحث في مساحة العمل…",
|
|
502
|
+
"composer.menu.references": "المراجع",
|
|
503
|
+
"composer.menu.referenceFile": "الإشارة إلى ملف",
|
|
504
|
+
"composer.menu.attachToMessage": "إضافة سياق",
|
|
505
|
+
"composer.menu.commands": "الأوامر",
|
|
501
506
|
"composer.menu.uploadFileDescription":
|
|
502
507
|
"صور وPDFs ونصوص/تعليمات برمجية وJSON وCSV",
|
|
503
508
|
"composer.messageAgent": "مراسلة الوكيل...",
|
|
@@ -1217,7 +1217,12 @@ const messages: ToolkitAgentChatTranslation = {
|
|
|
1217
1217
|
"composer.menu.scheduleTask": "Aufgabe planen",
|
|
1218
1218
|
"composer.menu.scheduleTaskDescription":
|
|
1219
1219
|
"Etwas nach einem Zeitplan ausführen",
|
|
1220
|
-
"composer.menu.uploadFile": "
|
|
1220
|
+
"composer.menu.uploadFile": "Dateien und Bilder",
|
|
1221
|
+
"composer.menu.searchWorkspace": "Arbeitsbereich durchsuchen…",
|
|
1222
|
+
"composer.menu.references": "Referenzen",
|
|
1223
|
+
"composer.menu.referenceFile": "Datei referenzieren",
|
|
1224
|
+
"composer.menu.attachToMessage": "Kontext hinzufügen",
|
|
1225
|
+
"composer.menu.commands": "Befehle",
|
|
1221
1226
|
"composer.menu.uploadFileDescription": "Bilder, PDFs, Text/Code, JSON, CSV",
|
|
1222
1227
|
"composer.messageAgent": "Nachricht an den Agenten...",
|
|
1223
1228
|
"composer.model": "Modell",
|
|
@@ -506,7 +506,12 @@ const messages = {
|
|
|
506
506
|
"composer.useIntegrationTools": "Use {{integration}} tools",
|
|
507
507
|
"composer.menu.scheduleTask": "Schedule Task",
|
|
508
508
|
"composer.menu.scheduleTaskDescription": "Run something on a schedule",
|
|
509
|
-
"composer.menu.uploadFile": "
|
|
509
|
+
"composer.menu.uploadFile": "Files and images",
|
|
510
|
+
"composer.menu.searchWorkspace": "Search workspace…",
|
|
511
|
+
"composer.menu.references": "References",
|
|
512
|
+
"composer.menu.referenceFile": "Reference a file",
|
|
513
|
+
"composer.menu.attachToMessage": "Add context",
|
|
514
|
+
"composer.menu.commands": "Commands",
|
|
510
515
|
"composer.menu.uploadFileDescription": "Images, PDFs, text/code, JSON, CSV",
|
|
511
516
|
"composer.messageAgent": "Message agent...",
|
|
512
517
|
"composer.model": "Model",
|
|
@@ -1211,7 +1211,12 @@ const messages: ToolkitAgentChatTranslation = {
|
|
|
1211
1211
|
"composer.useIntegrationTools": "Usar las herramientas de {{integration}}",
|
|
1212
1212
|
"composer.menu.scheduleTask": "Programar tarea",
|
|
1213
1213
|
"composer.menu.scheduleTaskDescription": "Ejecutar algo según un horario",
|
|
1214
|
-
"composer.menu.uploadFile": "
|
|
1214
|
+
"composer.menu.uploadFile": "Archivos e imágenes",
|
|
1215
|
+
"composer.menu.searchWorkspace": "Buscar en el espacio de trabajo…",
|
|
1216
|
+
"composer.menu.references": "Referencias",
|
|
1217
|
+
"composer.menu.referenceFile": "Referenciar un archivo",
|
|
1218
|
+
"composer.menu.attachToMessage": "Añadir contexto",
|
|
1219
|
+
"composer.menu.commands": "Comandos",
|
|
1215
1220
|
"composer.menu.uploadFileDescription":
|
|
1216
1221
|
"Imágenes, PDFs, texto/código, JSON, CSV",
|
|
1217
1222
|
"composer.messageAgent": "Escribe al agente...",
|
|
@@ -1219,7 +1219,12 @@ const messages: ToolkitAgentChatTranslation = {
|
|
|
1219
1219
|
"composer.menu.scheduleTask": "Planifier une tâche",
|
|
1220
1220
|
"composer.menu.scheduleTaskDescription":
|
|
1221
1221
|
"Exécuter quelque chose selon un calendrier",
|
|
1222
|
-
"composer.menu.uploadFile": "
|
|
1222
|
+
"composer.menu.uploadFile": "Fichiers et images",
|
|
1223
|
+
"composer.menu.searchWorkspace": "Rechercher dans l’espace de travail…",
|
|
1224
|
+
"composer.menu.references": "Références",
|
|
1225
|
+
"composer.menu.referenceFile": "Référencer un fichier",
|
|
1226
|
+
"composer.menu.attachToMessage": "Ajouter du contexte",
|
|
1227
|
+
"composer.menu.commands": "Commandes",
|
|
1223
1228
|
"composer.menu.uploadFileDescription": "Images, PDFs, texte/code, JSON, CSV",
|
|
1224
1229
|
"composer.messageAgent": "Écrire à l’agent...",
|
|
1225
1230
|
"composer.model": "Modèle",
|
|
@@ -498,7 +498,12 @@ const messages: ToolkitAgentChatTranslation = {
|
|
|
498
498
|
"composer.useIntegrationTools": "{{integration}} टूल का उपयोग करें",
|
|
499
499
|
"composer.menu.scheduleTask": "कार्य शेड्यूल करें",
|
|
500
500
|
"composer.menu.scheduleTaskDescription": "किसी कार्य को शेड्यूल के अनुसार चलाएँ",
|
|
501
|
-
"composer.menu.uploadFile": "
|
|
501
|
+
"composer.menu.uploadFile": "फ़ाइलें और छवियाँ",
|
|
502
|
+
"composer.menu.searchWorkspace": "वर्कस्पेस में खोजें…",
|
|
503
|
+
"composer.menu.references": "संदर्भ",
|
|
504
|
+
"composer.menu.referenceFile": "फ़ाइल का संदर्भ दें",
|
|
505
|
+
"composer.menu.attachToMessage": "संदर्भ जोड़ें",
|
|
506
|
+
"composer.menu.commands": "कमांड",
|
|
502
507
|
"composer.menu.uploadFileDescription": "इमेज, PDFs, टेक्स्ट/कोड, JSON, CSV",
|
|
503
508
|
"composer.messageAgent": "एजेंट को संदेश भेजें...",
|
|
504
509
|
"composer.model": "मॉडल",
|
|
@@ -518,7 +518,12 @@ const messages: ToolkitAgentChatTranslation = {
|
|
|
518
518
|
"composer.useIntegrationTools": "{{integration}}のツールを使用",
|
|
519
519
|
"composer.menu.scheduleTask": "タスクをスケジュール",
|
|
520
520
|
"composer.menu.scheduleTaskDescription": "スケジュールに沿って実行",
|
|
521
|
-
"composer.menu.uploadFile": "
|
|
521
|
+
"composer.menu.uploadFile": "ファイルと画像",
|
|
522
|
+
"composer.menu.searchWorkspace": "ワークスペースを検索…",
|
|
523
|
+
"composer.menu.references": "参照",
|
|
524
|
+
"composer.menu.referenceFile": "ファイルを参照",
|
|
525
|
+
"composer.menu.attachToMessage": "コンテキストを追加",
|
|
526
|
+
"composer.menu.commands": "コマンド",
|
|
522
527
|
"composer.menu.uploadFileDescription":
|
|
523
528
|
"画像、PDF、テキスト/コード、JSON、CSV",
|
|
524
529
|
"composer.messageAgent": "エージェントにメッセージを送信...",
|
|
@@ -502,7 +502,12 @@ const messages: ToolkitAgentChatTranslation = {
|
|
|
502
502
|
"composer.useIntegrationTools": "{{integration}} 도구 사용",
|
|
503
503
|
"composer.menu.scheduleTask": "작업 예약",
|
|
504
504
|
"composer.menu.scheduleTaskDescription": "일정에 따라 실행",
|
|
505
|
-
"composer.menu.uploadFile": "파일
|
|
505
|
+
"composer.menu.uploadFile": "파일 및 이미지",
|
|
506
|
+
"composer.menu.searchWorkspace": "워크스페이스 검색…",
|
|
507
|
+
"composer.menu.references": "참조",
|
|
508
|
+
"composer.menu.referenceFile": "파일 참조",
|
|
509
|
+
"composer.menu.attachToMessage": "컨텍스트 추가",
|
|
510
|
+
"composer.menu.commands": "명령",
|
|
506
511
|
"composer.menu.uploadFileDescription": "이미지, PDF, 텍스트/코드, JSON, CSV",
|
|
507
512
|
"composer.messageAgent": "에이전트에게 메시지 보내기...",
|
|
508
513
|
"composer.model": "모델",
|
|
@@ -1202,7 +1202,12 @@ const messages: ToolkitAgentChatTranslation = {
|
|
|
1202
1202
|
"composer.menu.scheduleTask": "Agendar tarefa",
|
|
1203
1203
|
"composer.menu.scheduleTaskDescription":
|
|
1204
1204
|
"Executar algo conforme uma programação",
|
|
1205
|
-
"composer.menu.uploadFile": "
|
|
1205
|
+
"composer.menu.uploadFile": "Arquivos e imagens",
|
|
1206
|
+
"composer.menu.searchWorkspace": "Pesquisar no espaço de trabalho…",
|
|
1207
|
+
"composer.menu.references": "Referências",
|
|
1208
|
+
"composer.menu.referenceFile": "Referenciar um arquivo",
|
|
1209
|
+
"composer.menu.attachToMessage": "Adicionar contexto",
|
|
1210
|
+
"composer.menu.commands": "Comandos",
|
|
1206
1211
|
"composer.menu.uploadFileDescription":
|
|
1207
1212
|
"Imagens, PDFs, texto/código, JSON, CSV",
|
|
1208
1213
|
"composer.messageAgent": "Enviar mensagem ao agente...",
|
|
@@ -483,7 +483,12 @@ const messages: ToolkitAgentChatTranslation = {
|
|
|
483
483
|
"composer.useIntegrationTools": "使用 {{integration}} 工具",
|
|
484
484
|
"composer.menu.scheduleTask": "安排任务",
|
|
485
485
|
"composer.menu.scheduleTaskDescription": "按计划运行任务",
|
|
486
|
-
"composer.menu.uploadFile": "
|
|
486
|
+
"composer.menu.uploadFile": "文件和图片",
|
|
487
|
+
"composer.menu.searchWorkspace": "搜索工作区…",
|
|
488
|
+
"composer.menu.references": "引用",
|
|
489
|
+
"composer.menu.referenceFile": "引用文件",
|
|
490
|
+
"composer.menu.attachToMessage": "添加上下文",
|
|
491
|
+
"composer.menu.commands": "命令",
|
|
487
492
|
"composer.menu.uploadFileDescription": "图片、PDF、文本/代码、JSON、CSV",
|
|
488
493
|
"composer.messageAgent": "向智能体发送消息...",
|
|
489
494
|
"composer.model": "模型",
|
|
@@ -484,7 +484,12 @@ const messages: ToolkitAgentChatTranslation = {
|
|
|
484
484
|
"composer.useIntegrationTools": "使用 {{integration}} 工具",
|
|
485
485
|
"composer.menu.scheduleTask": "排程工作",
|
|
486
486
|
"composer.menu.scheduleTaskDescription": "依排程執行工作",
|
|
487
|
-
"composer.menu.uploadFile": "
|
|
487
|
+
"composer.menu.uploadFile": "檔案和圖片",
|
|
488
|
+
"composer.menu.searchWorkspace": "搜尋工作區…",
|
|
489
|
+
"composer.menu.references": "參照",
|
|
490
|
+
"composer.menu.referenceFile": "引用檔案",
|
|
491
|
+
"composer.menu.attachToMessage": "新增內容脈絡",
|
|
492
|
+
"composer.menu.commands": "命令",
|
|
488
493
|
"composer.menu.uploadFileDescription": "圖片、PDF、文字/程式碼、JSON、CSV",
|
|
489
494
|
"composer.messageAgent": "傳送訊息給代理...",
|
|
490
495
|
"composer.model": "模型",
|
|
@@ -80,6 +80,9 @@ type DialogMode = "catalog" | "choice" | "form";
|
|
|
80
80
|
export interface McpIntegrationDialogProps {
|
|
81
81
|
open: boolean;
|
|
82
82
|
onOpenChange: (open: boolean) => void;
|
|
83
|
+
onCloseAutoFocus?: React.ComponentProps<
|
|
84
|
+
typeof DialogContent
|
|
85
|
+
>["onCloseAutoFocus"];
|
|
83
86
|
initialIntegrationId?: string | null;
|
|
84
87
|
connectIntegrationId?: string | null;
|
|
85
88
|
quickConnectIntegrationId?: string | null;
|
|
@@ -157,6 +160,7 @@ function resolveIntegrationScope(
|
|
|
157
160
|
export function McpIntegrationDialog({
|
|
158
161
|
open,
|
|
159
162
|
onOpenChange,
|
|
163
|
+
onCloseAutoFocus,
|
|
160
164
|
initialIntegrationId = null,
|
|
161
165
|
connectIntegrationId = null,
|
|
162
166
|
quickConnectIntegrationId = null,
|
|
@@ -889,6 +893,7 @@ export function McpIntegrationDialog({
|
|
|
889
893
|
return (
|
|
890
894
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
891
895
|
<DialogContent
|
|
896
|
+
onCloseAutoFocus={onCloseAutoFocus}
|
|
892
897
|
aria-describedby={undefined}
|
|
893
898
|
className={cn(
|
|
894
899
|
"flex flex-col gap-0 overflow-hidden p-0",
|