@agent-native/core 0.198.3 → 0.198.5
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/a2a/types.d.ts +5 -0
- package/dist/agent/production-agent.js +26 -1
- package/dist/catalog.json +1 -0
- package/dist/client/chat/agentkit-agent-native.js +15 -15
- package/dist/client/chat/runtime.js +5 -3
- package/dist/client/feature-flags/types.d.ts +2 -0
- package/dist/client/i18n.d.ts +2 -0
- package/dist/client/i18n.js +2 -0
- package/dist/client/integrations/index.d.ts +1 -0
- package/dist/client/integrations/index.js +1 -0
- package/dist/client/labs/index.d.ts +1 -1
- package/dist/client/labs/use-lab.d.ts +5 -0
- package/dist/client/labs/use-lab.js +7 -3
- package/dist/client/resources/mcp-connection-resume.d.ts +5 -3
- package/dist/client/resources/mcp-connection-resume.js +150 -13
- package/dist/client/sse-event-processor.d.ts +6 -0
- package/dist/client/uploads/index.d.ts +1 -0
- package/dist/client/uploads/index.js +1 -0
- package/dist/client/uploads/private-icon.d.ts +10 -0
- package/dist/client/uploads/private-icon.js +52 -0
- package/dist/collab/routes.d.ts +2 -2
- package/dist/feature-flags/actions/get-feature-flags.js +20 -0
- package/dist/feature-flags/actions/list-feature-flags.d.ts +2 -0
- package/dist/feature-flags/actions/list-feature-flags.js +5 -0
- package/dist/feature-flags/actions/set-feature-flag.js +5 -0
- package/dist/file-upload/actions/upload-image.d.ts +3 -3
- package/dist/framework-tools.js +2 -0
- package/dist/icon-assets/index.d.ts +3 -0
- package/dist/icon-assets/index.js +3 -0
- package/dist/icon-assets/multipart.d.ts +9 -0
- package/dist/icon-assets/multipart.js +60 -0
- package/dist/icon-assets/schema.d.ts +194 -0
- package/dist/icon-assets/schema.js +16 -0
- package/dist/icon-assets/store.d.ts +38 -0
- package/dist/icon-assets/store.js +187 -0
- package/dist/icon-assets/svg.d.ts +2 -0
- package/dist/icon-assets/svg.js +146 -0
- package/dist/icon-assets/workspace-transport.d.ts +20 -0
- package/dist/icon-assets/workspace-transport.js +122 -0
- package/dist/identity/rekey.js +1 -0
- package/dist/jobs/actions/manage-recurring-job.d.ts +1 -1
- package/dist/labs/actions/get-lab-states.d.ts +2 -0
- package/dist/labs/actions/get-lab-states.js +14 -0
- package/dist/labs/actions/get-labs.js +2 -2
- package/dist/labs/actions/set-lab.js +4 -2
- package/dist/labs/index.d.ts +1 -1
- package/dist/labs/index.js +1 -1
- package/dist/labs/registry.d.ts +3 -0
- package/dist/labs/registry.js +14 -0
- package/dist/labs/server.d.ts +1 -1
- package/dist/labs/server.js +1 -1
- package/dist/labs/store.d.ts +13 -2
- package/dist/labs/store.js +124 -7
- package/dist/localization/default-messages.d.ts +2 -0
- package/dist/localization/default-messages.js +1 -1
- package/dist/localization/icon-picker-messages.d.ts +44 -0
- package/dist/localization/icon-picker-messages.js +22 -0
- package/dist/mcp-client/oauth-client.d.ts +1 -0
- package/dist/mcp-client/oauth-client.js +42 -4
- package/dist/mcp-client/oauth-routes.js +15 -2
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +9 -9
- package/dist/org/actions/list-workspace-icons.d.ts +7 -0
- package/dist/org/actions/list-workspace-icons.js +41 -0
- package/dist/org/handlers.d.ts +1 -1
- package/dist/org/handlers.js +28 -1
- package/dist/org/index.d.ts +1 -1
- package/dist/org/migrations.js +21 -0
- package/dist/org/plugin.js +42 -0
- package/dist/org/private-icon-handlers.d.ts +6 -0
- package/dist/org/private-icon-handlers.js +212 -0
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +8 -8
- package/dist/provider-api/actions/provider-api.d.ts +5 -5
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/provider-api/index.d.ts +1 -1
- package/dist/provider-api/index.js +26 -6
- package/dist/secrets/routes.d.ts +4 -4
- package/dist/server/action-discovery.js +5 -0
- package/dist/server/agent-chat-plugin.js +14 -0
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agent-engine-default-model-route.d.ts +1 -1
- package/dist/server/agent-engine-ollama-models-route.d.ts +1 -1
- package/dist/server/core-routes-plugin.d.ts +1 -1
- package/dist/server/core-routes-plugin.js +18 -3
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/workspace-provider-oauth.d.ts +1 -0
- package/dist/server/workspace-provider-oauth.js +4 -2
- package/dist/templates/chat/app/components/chat/ChatRouteContent.tsx +9 -16
- package/dist/triggers/actions/manage-automation.d.ts +5 -5
- package/dist/vite/action-types-plugin.js +4 -0
- package/package.json +7 -9
- package/src/templates/chat/app/components/chat/ChatRouteContent.tsx +9 -16
package/dist/org/plugin.js
CHANGED
|
@@ -7,7 +7,31 @@ import { listSSOProvidersHandler, createSSOProviderHandler, verifySSOProviderHan
|
|
|
7
7
|
import { CROSS_APP_ORG_FEDERATION_FLAG } from "./feature-flags.js";
|
|
8
8
|
import { getMyOrgHandler, createOrgHandler, updateOrgHandler, deleteOrgHandler, switchOrgHandler, listMembersHandler, removeMemberHandler, retryPendingFederatedRemovalHandler, changeMemberRoleHandler, listInvitationsHandler, createInvitationHandler, acceptInvitationHandler, joinByDomainHandler, setDomainHandler, setWorkspaceUrlHandler, setRequiredAuthProviderHandler, revealA2ASecretHandler, setA2ASecretHandler, syncA2ASecretHandler, receiveA2ASecretHandler, setWorkspaceAppDefaultVisibilityHandler, setOrgVisualIdentityHandler, } from "./handlers.js";
|
|
9
9
|
import { ORG_MIGRATIONS } from "./migrations.js";
|
|
10
|
+
import { readWorkspacePrivateIconHandler, uploadWorkspacePrivateIconHandler, } from "./private-icon-handlers.js";
|
|
10
11
|
const ORG_PREFIX = `${FRAMEWORK_PREFIX}/org`;
|
|
12
|
+
async function workspaceIconUploadResponse(event) {
|
|
13
|
+
try {
|
|
14
|
+
return await uploadWorkspacePrivateIconHandler(event);
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
const statusCode = error &&
|
|
18
|
+
typeof error === "object" &&
|
|
19
|
+
"statusCode" in error &&
|
|
20
|
+
typeof error.statusCode === "number"
|
|
21
|
+
? error.statusCode
|
|
22
|
+
: 500;
|
|
23
|
+
setResponseStatus(event, statusCode);
|
|
24
|
+
return {
|
|
25
|
+
message: statusCode < 500 &&
|
|
26
|
+
error &&
|
|
27
|
+
typeof error === "object" &&
|
|
28
|
+
"message" in error &&
|
|
29
|
+
typeof error.message === "string"
|
|
30
|
+
? error.message
|
|
31
|
+
: "Workspace icon upload failed.",
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
11
35
|
/**
|
|
12
36
|
* Mounts the org REST routes under `/_agent-native/org/*` and runs the org
|
|
13
37
|
* module's migrations.
|
|
@@ -47,6 +71,24 @@ export function createOrgPlugin() {
|
|
|
47
71
|
await awaitBootstrap(nitroApp);
|
|
48
72
|
await migrate(nitroApp);
|
|
49
73
|
const app = getH3App(nitroApp);
|
|
74
|
+
app.use(`${ORG_PREFIX}/private-icons`, defineEventHandler(async (event) => {
|
|
75
|
+
const tail = getRequestURL(event).pathname || "/";
|
|
76
|
+
const method = getMethod(event);
|
|
77
|
+
if (tail === "/" ||
|
|
78
|
+
tail === "" ||
|
|
79
|
+
tail === `${ORG_PREFIX}/private-icons` ||
|
|
80
|
+
tail === `${ORG_PREFIX}/private-icons/`) {
|
|
81
|
+
if (method === "POST")
|
|
82
|
+
return workspaceIconUploadResponse(event);
|
|
83
|
+
setResponseStatus(event, 405);
|
|
84
|
+
return { error: "Method not allowed" };
|
|
85
|
+
}
|
|
86
|
+
if (method === "GET")
|
|
87
|
+
return readWorkspacePrivateIconHandler(event);
|
|
88
|
+
setResponseStatus(event, 405);
|
|
89
|
+
return { error: "Method not allowed" };
|
|
90
|
+
}));
|
|
91
|
+
// GET /me
|
|
50
92
|
app.use(`${ORG_PREFIX}/me`, defineEventHandler(async (event) => {
|
|
51
93
|
if (getMethod(event) !== "GET") {
|
|
52
94
|
setResponseStatus(event, 405);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const uploadWorkspacePrivateIconHandler: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
2
|
+
id: string;
|
|
3
|
+
}>>;
|
|
4
|
+
export declare const readWorkspacePrivateIconHandler: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<Buffer<ArrayBuffer>>>;
|
|
5
|
+
export declare function assertOwnedLocalWorkspaceIcon(assetId: string, email: string, orgId: string): Promise<void>;
|
|
6
|
+
export declare function requirePrivateWorkspaceIconId(assetId: string): void;
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { createError, defineEventHandler, getRequestURL, setResponseHeader, setResponseStatus, } from "h3";
|
|
2
|
+
import { getDbExec } from "../db/client.js";
|
|
3
|
+
import { getIconAsset, IconUploadBodyError, putIconAsset, readIconUploadFormData, readIconAssetForAuthorizedReference, } from "../icon-assets/index.js";
|
|
4
|
+
import { readFederatedWorkspaceIcon, uploadFederatedWorkspaceIcon, verifyFederatedWorkspaceIconOwner, } from "../icon-assets/workspace-transport.js";
|
|
5
|
+
import { getSession } from "../server/auth.js";
|
|
6
|
+
import { runWithRequestContext } from "../server/request-context.js";
|
|
7
|
+
import { getOrgContext } from "./context.js";
|
|
8
|
+
import { validateFederatedOrganizationMembership } from "./federation.js";
|
|
9
|
+
import { parseOrganizationIconJson } from "./visual-identity.js";
|
|
10
|
+
const ASSET_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
11
|
+
const ORG_ID = /^[A-Za-z0-9_-]{1,128}$/;
|
|
12
|
+
const MAX_ICON_BYTES = 5 * 1024 * 1024;
|
|
13
|
+
const IMAGE_TYPES = new Set([
|
|
14
|
+
"image/png",
|
|
15
|
+
"image/jpeg",
|
|
16
|
+
"image/webp",
|
|
17
|
+
"image/svg+xml",
|
|
18
|
+
]);
|
|
19
|
+
async function readOrg(orgId) {
|
|
20
|
+
const result = await getDbExec().execute({
|
|
21
|
+
sql: `SELECT identity_authority, identity_id, allowed_domain, icon_json
|
|
22
|
+
FROM organizations WHERE id = ? LIMIT 1`,
|
|
23
|
+
args: [orgId],
|
|
24
|
+
});
|
|
25
|
+
const row = result.rows[0];
|
|
26
|
+
if (!row)
|
|
27
|
+
return null;
|
|
28
|
+
return {
|
|
29
|
+
identityAuthority: typeof row.identity_authority === "string"
|
|
30
|
+
? row.identity_authority
|
|
31
|
+
: null,
|
|
32
|
+
identityId: typeof row.identity_id === "string" ? row.identity_id : null,
|
|
33
|
+
allowedDomain: typeof row.allowed_domain === "string" ? row.allowed_domain : null,
|
|
34
|
+
iconJson: row.icon_json,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function isFederated(org) {
|
|
38
|
+
if (Boolean(org.identityAuthority) !== Boolean(org.identityId)) {
|
|
39
|
+
throw new Error("Workspace identity mapping is incomplete.");
|
|
40
|
+
}
|
|
41
|
+
return Boolean(org.identityAuthority);
|
|
42
|
+
}
|
|
43
|
+
export const uploadWorkspacePrivateIconHandler = defineEventHandler(async (event) => {
|
|
44
|
+
const ctx = await getOrgContext(event);
|
|
45
|
+
if (!ctx.orgId || !ctx.email)
|
|
46
|
+
throw createError({
|
|
47
|
+
statusCode: 401,
|
|
48
|
+
message: "Organization access required",
|
|
49
|
+
});
|
|
50
|
+
if (ctx.role !== "owner" && ctx.role !== "admin") {
|
|
51
|
+
throw createError({
|
|
52
|
+
statusCode: 403,
|
|
53
|
+
message: "Only owners and admins can upload workspace icons",
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
const org = await readOrg(ctx.orgId);
|
|
57
|
+
if (!org)
|
|
58
|
+
throw createError({ statusCode: 404, message: "Organization not found" });
|
|
59
|
+
const form = await readIconUploadFormData(event.req).catch((error) => {
|
|
60
|
+
if (error instanceof IconUploadBodyError) {
|
|
61
|
+
throw createError({
|
|
62
|
+
statusCode: error.statusCode,
|
|
63
|
+
cause: error,
|
|
64
|
+
message: error.statusCode === 413
|
|
65
|
+
? "Workspace icon is too large"
|
|
66
|
+
: error.message,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
throw error;
|
|
70
|
+
});
|
|
71
|
+
const file = form.get("file");
|
|
72
|
+
if (!file || typeof file === "string" || !file.size)
|
|
73
|
+
throw createError({ statusCode: 400, message: "Image file required" });
|
|
74
|
+
if (file.size > MAX_ICON_BYTES)
|
|
75
|
+
throw createError({
|
|
76
|
+
statusCode: 413,
|
|
77
|
+
message: "Workspace icon is too large",
|
|
78
|
+
});
|
|
79
|
+
const mimeType = file.type?.toLowerCase();
|
|
80
|
+
if (!mimeType || !IMAGE_TYPES.has(mimeType)) {
|
|
81
|
+
throw createError({
|
|
82
|
+
statusCode: 415,
|
|
83
|
+
message: "Unsupported workspace icon image type",
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
const data = new Uint8Array(await file.arrayBuffer());
|
|
87
|
+
const id = await runWithRequestContext({ userEmail: ctx.email, orgId: ctx.orgId }, async () => isFederated(org)
|
|
88
|
+
? uploadFederatedWorkspaceIcon(event, org, ctx.email, {
|
|
89
|
+
data,
|
|
90
|
+
mimeType,
|
|
91
|
+
filename: file.name || "workspace-icon",
|
|
92
|
+
})
|
|
93
|
+
: (await putIconAsset({
|
|
94
|
+
data,
|
|
95
|
+
mimeType,
|
|
96
|
+
filename: file.name || undefined,
|
|
97
|
+
ownerEmail: ctx.email,
|
|
98
|
+
orgId: ctx.orgId,
|
|
99
|
+
})).id);
|
|
100
|
+
if (!ASSET_ID.test(id))
|
|
101
|
+
throw new Error("Workspace icon storage returned an invalid asset ID.");
|
|
102
|
+
setResponseStatus(event, 201);
|
|
103
|
+
return { id };
|
|
104
|
+
});
|
|
105
|
+
export const readWorkspacePrivateIconHandler = defineEventHandler(async (event) => {
|
|
106
|
+
const session = await getSession(event);
|
|
107
|
+
if (!session?.email)
|
|
108
|
+
throw createError({
|
|
109
|
+
statusCode: 401,
|
|
110
|
+
message: "Authentication required",
|
|
111
|
+
});
|
|
112
|
+
const path = getRequestURL(event).pathname;
|
|
113
|
+
const match = path.match(/^(?:\/_agent-native\/org\/private-icons)?\/(library\/)?([A-Za-z0-9_-]{1,128})\/([0-9a-f-]{36})\/?$/i);
|
|
114
|
+
if (!match || !ORG_ID.test(match[2]) || !ASSET_ID.test(match[3])) {
|
|
115
|
+
throw createError({
|
|
116
|
+
statusCode: 404,
|
|
117
|
+
message: "Workspace icon not found",
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
const [, library, orgId, assetId] = match;
|
|
121
|
+
const membership = await getDbExec().execute({
|
|
122
|
+
sql: `SELECT role FROM org_members
|
|
123
|
+
WHERE org_id = ? AND LOWER(email) = ?
|
|
124
|
+
AND federation_removal_pending_at IS NULL LIMIT 1`,
|
|
125
|
+
args: [orgId, session.email.toLowerCase()],
|
|
126
|
+
});
|
|
127
|
+
if (!membership.rows.length)
|
|
128
|
+
throw createError({
|
|
129
|
+
statusCode: 404,
|
|
130
|
+
message: "Workspace icon not found",
|
|
131
|
+
});
|
|
132
|
+
if (library &&
|
|
133
|
+
membership.rows[0]?.role !== "owner" &&
|
|
134
|
+
membership.rows[0]?.role !== "admin") {
|
|
135
|
+
throw createError({
|
|
136
|
+
statusCode: 404,
|
|
137
|
+
message: "Workspace icon not found",
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
const org = await readOrg(orgId);
|
|
141
|
+
if (!org)
|
|
142
|
+
throw createError({
|
|
143
|
+
statusCode: 404,
|
|
144
|
+
message: "Workspace icon not found",
|
|
145
|
+
});
|
|
146
|
+
if (library) {
|
|
147
|
+
const owned = isFederated(org)
|
|
148
|
+
? await verifyFederatedWorkspaceIconOwner(event, org, session.email, assetId)
|
|
149
|
+
: Boolean(await getIconAsset(assetId, { ownerEmail: session.email, orgId }));
|
|
150
|
+
if (!owned)
|
|
151
|
+
throw createError({
|
|
152
|
+
statusCode: 404,
|
|
153
|
+
message: "Workspace icon not found",
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
const icon = parseOrganizationIconJson(org.iconJson);
|
|
158
|
+
if (icon?.kind !== "image" ||
|
|
159
|
+
icon.authority !== "private-icon" ||
|
|
160
|
+
icon.assetId !== assetId) {
|
|
161
|
+
throw createError({
|
|
162
|
+
statusCode: 404,
|
|
163
|
+
message: "Workspace icon not found",
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (isFederated(org)) {
|
|
168
|
+
const verified = await validateFederatedOrganizationMembership(event, {
|
|
169
|
+
orgId,
|
|
170
|
+
email: session.email,
|
|
171
|
+
});
|
|
172
|
+
if (!verified.active)
|
|
173
|
+
throw createError({
|
|
174
|
+
statusCode: 404,
|
|
175
|
+
message: "Workspace icon not found",
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
const bytes = isFederated(org)
|
|
179
|
+
? await readFederatedWorkspaceIcon(event, org, session.email, assetId)
|
|
180
|
+
: await readIconAssetForAuthorizedReference(assetId, { orgId });
|
|
181
|
+
if (!bytes || !IMAGE_TYPES.has(bytes.mimeType)) {
|
|
182
|
+
throw createError({
|
|
183
|
+
statusCode: 404,
|
|
184
|
+
message: "Workspace icon not found",
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
setResponseHeader(event, "Content-Type", bytes.mimeType);
|
|
188
|
+
setResponseHeader(event, "Content-Length", String(bytes.data.length));
|
|
189
|
+
setResponseHeader(event, "Cache-Control", "private, no-store");
|
|
190
|
+
setResponseHeader(event, "X-Content-Type-Options", "nosniff");
|
|
191
|
+
if (bytes.mimeType === "image/svg+xml") {
|
|
192
|
+
setResponseHeader(event, "Content-Security-Policy", "sandbox; default-src 'none'; style-src 'unsafe-inline'; img-src data:");
|
|
193
|
+
}
|
|
194
|
+
return Buffer.from(bytes.data);
|
|
195
|
+
});
|
|
196
|
+
export async function assertOwnedLocalWorkspaceIcon(assetId, email, orgId) {
|
|
197
|
+
if (!ASSET_ID.test(assetId) ||
|
|
198
|
+
!(await getIconAsset(assetId, { ownerEmail: email, orgId }))) {
|
|
199
|
+
throw createError({
|
|
200
|
+
statusCode: 403,
|
|
201
|
+
message: "Workspace icon asset is not owned by this organization administrator",
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
export function requirePrivateWorkspaceIconId(assetId) {
|
|
206
|
+
if (!ASSET_ID.test(assetId)) {
|
|
207
|
+
throw createError({
|
|
208
|
+
statusCode: 400,
|
|
209
|
+
message: "Invalid workspace icon asset ID",
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}
|
|
@@ -75,10 +75,11 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
|
|
|
75
75
|
user: "user";
|
|
76
76
|
}>>;
|
|
77
77
|
}, z.core.$strip>>, {
|
|
78
|
-
id?: undefined;
|
|
79
78
|
message?: undefined;
|
|
80
|
-
found?: undefined;
|
|
81
79
|
deleted?: undefined;
|
|
80
|
+
id?: undefined;
|
|
81
|
+
provider?: undefined;
|
|
82
|
+
found?: undefined;
|
|
82
83
|
providers: {
|
|
83
84
|
id: string;
|
|
84
85
|
label: string;
|
|
@@ -89,13 +90,12 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
|
|
|
89
90
|
updatedAt: number;
|
|
90
91
|
}[];
|
|
91
92
|
count: number;
|
|
92
|
-
provider?: undefined;
|
|
93
93
|
registered?: undefined;
|
|
94
94
|
label?: undefined;
|
|
95
95
|
} | {
|
|
96
|
-
id?: undefined;
|
|
97
96
|
message?: undefined;
|
|
98
97
|
deleted?: undefined;
|
|
98
|
+
id?: undefined;
|
|
99
99
|
providers?: undefined;
|
|
100
100
|
count?: undefined;
|
|
101
101
|
found: boolean;
|
|
@@ -105,29 +105,29 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
|
|
|
105
105
|
} | {
|
|
106
106
|
message?: undefined;
|
|
107
107
|
deleted?: undefined;
|
|
108
|
+
provider?: undefined;
|
|
108
109
|
providers?: undefined;
|
|
109
110
|
count?: undefined;
|
|
110
|
-
provider?: undefined;
|
|
111
111
|
found: boolean;
|
|
112
112
|
id: string;
|
|
113
113
|
registered?: undefined;
|
|
114
114
|
label?: undefined;
|
|
115
115
|
} | {
|
|
116
116
|
message?: undefined;
|
|
117
|
+
provider?: undefined;
|
|
117
118
|
found?: undefined;
|
|
118
119
|
providers?: undefined;
|
|
119
120
|
count?: undefined;
|
|
120
|
-
provider?: undefined;
|
|
121
121
|
deleted: boolean;
|
|
122
122
|
id: string;
|
|
123
123
|
registered?: undefined;
|
|
124
124
|
label?: undefined;
|
|
125
125
|
} | {
|
|
126
|
-
found?: undefined;
|
|
127
126
|
deleted?: undefined;
|
|
127
|
+
provider?: undefined;
|
|
128
|
+
found?: undefined;
|
|
128
129
|
providers?: undefined;
|
|
129
130
|
count?: undefined;
|
|
130
|
-
provider?: undefined;
|
|
131
131
|
registered: boolean;
|
|
132
132
|
id: string;
|
|
133
133
|
label: string;
|
|
@@ -311,10 +311,10 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
311
311
|
notes?: string | undefined;
|
|
312
312
|
scope?: "org" | "user" | undefined;
|
|
313
313
|
}, {
|
|
314
|
-
id?: undefined;
|
|
315
314
|
provider?: undefined;
|
|
316
|
-
|
|
315
|
+
id?: undefined;
|
|
317
316
|
message?: undefined;
|
|
317
|
+
deleted?: undefined;
|
|
318
318
|
found?: undefined;
|
|
319
319
|
providers: {
|
|
320
320
|
id: string;
|
|
@@ -330,9 +330,9 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
330
330
|
label?: undefined;
|
|
331
331
|
} | {
|
|
332
332
|
id?: undefined;
|
|
333
|
-
deleted?: undefined;
|
|
334
333
|
count?: undefined;
|
|
335
334
|
message?: undefined;
|
|
335
|
+
deleted?: undefined;
|
|
336
336
|
providers?: undefined;
|
|
337
337
|
found: boolean;
|
|
338
338
|
provider: import("../custom-registry.js").CustomProviderConfig;
|
|
@@ -340,9 +340,9 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
340
340
|
label?: undefined;
|
|
341
341
|
} | {
|
|
342
342
|
provider?: undefined;
|
|
343
|
-
deleted?: undefined;
|
|
344
343
|
count?: undefined;
|
|
345
344
|
message?: undefined;
|
|
345
|
+
deleted?: undefined;
|
|
346
346
|
providers?: undefined;
|
|
347
347
|
found: boolean;
|
|
348
348
|
id: string;
|
|
@@ -360,8 +360,8 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
360
360
|
label?: undefined;
|
|
361
361
|
} | {
|
|
362
362
|
provider?: undefined;
|
|
363
|
-
deleted?: undefined;
|
|
364
363
|
count?: undefined;
|
|
364
|
+
deleted?: undefined;
|
|
365
365
|
found?: undefined;
|
|
366
366
|
providers?: undefined;
|
|
367
367
|
registered: boolean;
|
|
@@ -73,6 +73,7 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
|
|
|
73
73
|
offset?: unknown;
|
|
74
74
|
limit?: unknown;
|
|
75
75
|
}, {
|
|
76
|
+
deleted?: undefined;
|
|
76
77
|
jobs: {
|
|
77
78
|
id: string;
|
|
78
79
|
name: string;
|
|
@@ -83,7 +84,6 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
|
|
|
83
84
|
updatedAt: string;
|
|
84
85
|
}[];
|
|
85
86
|
total: number;
|
|
86
|
-
deleted?: undefined;
|
|
87
87
|
jobId?: undefined;
|
|
88
88
|
} | {
|
|
89
89
|
jobs?: undefined;
|
|
@@ -91,9 +91,9 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
|
|
|
91
91
|
deleted: boolean;
|
|
92
92
|
jobId: string;
|
|
93
93
|
} | {
|
|
94
|
+
deleted?: undefined;
|
|
94
95
|
jobs?: undefined;
|
|
95
96
|
total?: undefined;
|
|
96
|
-
deleted?: undefined;
|
|
97
97
|
jobId?: undefined;
|
|
98
98
|
hits: Record<string, unknown>[];
|
|
99
99
|
offset: number;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type WorkspaceConnectionTemplateUse } from "../connections/catalog.js";
|
|
2
2
|
import { type CredentialContext } from "../credentials/index.js";
|
|
3
3
|
import { type WebContentSearchOptions, type WebExtractMode, type WebResponseMode } from "../extensions/web-content.js";
|
|
4
4
|
import type { CustomProviderConfig } from "./custom-registry.js";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { AgentConnectionRequiredError } from "../action.js";
|
|
3
|
+
import { getWorkspaceConnectionProvider, } from "../connections/catalog.js";
|
|
3
4
|
import { assertCredentialCanReachEndpoint, describeCredentialScopeGap, resolveCredentialDetailed, } from "../credentials/index.js";
|
|
4
5
|
import { createSsrfSafeDispatcher, isBlockedExtensionUrlWithDns, } from "../extensions/url-safety.js";
|
|
5
6
|
import { processWebContent, } from "../extensions/web-content.js";
|
|
@@ -1452,6 +1453,7 @@ export async function resolveProviderApiOAuthAccessToken(args, runtime) {
|
|
|
1452
1453
|
})
|
|
1453
1454
|
: await resolveOAuthBearerToken({
|
|
1454
1455
|
auth: oauthAuth,
|
|
1456
|
+
runtime,
|
|
1455
1457
|
ctx,
|
|
1456
1458
|
accountId: args.accountId,
|
|
1457
1459
|
});
|
|
@@ -2756,8 +2758,10 @@ async function resolveAuth(config, runtime, ctx, args) {
|
|
|
2756
2758
|
})
|
|
2757
2759
|
: await resolveOAuthBearerToken({
|
|
2758
2760
|
auth: { ...auth, oauthProvider },
|
|
2761
|
+
runtime,
|
|
2759
2762
|
ctx,
|
|
2760
2763
|
accountId: args.accountId,
|
|
2764
|
+
connectionId: args.connectionId,
|
|
2761
2765
|
});
|
|
2762
2766
|
return {
|
|
2763
2767
|
headers: { Authorization: `Bearer ${credential.value}` },
|
|
@@ -3009,9 +3013,7 @@ async function resolveAnyCredential(options) {
|
|
|
3009
3013
|
return credential;
|
|
3010
3014
|
}
|
|
3011
3015
|
const scopeGap = await describeCredentialScopeGap(options.keys, options.ctx).catch(() => null);
|
|
3012
|
-
if (options.workspaceProvider &&
|
|
3013
|
-
!options.runtime.resolveCredential &&
|
|
3014
|
-
!scopeGap) {
|
|
3016
|
+
if (options.workspaceProvider && !scopeGap) {
|
|
3015
3017
|
return throwWorkspaceConnectionRequired({
|
|
3016
3018
|
runtime: options.runtime,
|
|
3017
3019
|
provider: options.workspaceProvider,
|
|
@@ -3029,9 +3031,7 @@ async function resolveRequiredCredential(options) {
|
|
|
3029
3031
|
// coercion-ok: only enriches an error we throw either way — losing the scope
|
|
3030
3032
|
// hint still surfaces the real "not configured" failure, never a success.
|
|
3031
3033
|
.catch(() => null);
|
|
3032
|
-
if (options.workspaceProvider &&
|
|
3033
|
-
!options.runtime.resolveCredential &&
|
|
3034
|
-
!scopeGap) {
|
|
3034
|
+
if (options.workspaceProvider && !scopeGap) {
|
|
3035
3035
|
return throwWorkspaceConnectionRequired({
|
|
3036
3036
|
runtime: options.runtime,
|
|
3037
3037
|
provider: options.workspaceProvider,
|
|
@@ -3152,6 +3152,14 @@ async function resolveOAuthBearerToken(options) {
|
|
|
3152
3152
|
const ownerEmail = options.ownerEmail?.trim() || options.ctx.userEmail;
|
|
3153
3153
|
const accounts = await listOAuthAccountsByOwner(options.auth.oauthProvider, ownerEmail);
|
|
3154
3154
|
if (accounts.length === 0) {
|
|
3155
|
+
if (options.auth.workspaceProvider) {
|
|
3156
|
+
return throwWorkspaceConnectionRequired({
|
|
3157
|
+
runtime: options.runtime,
|
|
3158
|
+
provider: options.auth.workspaceProvider,
|
|
3159
|
+
connectionId: options.connectionId,
|
|
3160
|
+
message: `${options.auth.tokenLabel} requires an available workspace connection.`,
|
|
3161
|
+
});
|
|
3162
|
+
}
|
|
3155
3163
|
throw new Error(`${options.auth.tokenLabel} is not connected for ${ownerEmail}.`);
|
|
3156
3164
|
}
|
|
3157
3165
|
const accountId = options.accountId?.trim();
|
|
@@ -3205,10 +3213,20 @@ async function throwWorkspaceConnectionRequired(options) {
|
|
|
3205
3213
|
resolved.connection.status !== "connected") {
|
|
3206
3214
|
reason = "reauthorize";
|
|
3207
3215
|
}
|
|
3216
|
+
const connectionProvider = getWorkspaceConnectionProvider(options.provider);
|
|
3208
3217
|
throw new AgentConnectionRequiredError(options.message, {
|
|
3209
3218
|
provider: options.provider,
|
|
3210
3219
|
reason,
|
|
3211
3220
|
appId: options.runtime.appId,
|
|
3221
|
+
...(connectionProvider
|
|
3222
|
+
? {
|
|
3223
|
+
source: {
|
|
3224
|
+
id: options.provider,
|
|
3225
|
+
kind: "workspace_connection",
|
|
3226
|
+
label: connectionProvider.label,
|
|
3227
|
+
},
|
|
3228
|
+
}
|
|
3229
|
+
: {}),
|
|
3212
3230
|
});
|
|
3213
3231
|
}
|
|
3214
3232
|
async function resolveOptionalConnectionBoundOAuthBearerToken(options) {
|
|
@@ -3252,9 +3270,11 @@ async function resolveOptionalConnectionBoundOAuthBearerToken(options) {
|
|
|
3252
3270
|
}
|
|
3253
3271
|
const credential = await resolveOAuthBearerToken({
|
|
3254
3272
|
auth: options.auth,
|
|
3273
|
+
runtime: options.runtime,
|
|
3255
3274
|
ctx: options.ctx,
|
|
3256
3275
|
accountId: connectionAccountId,
|
|
3257
3276
|
ownerEmail: resolved.connection.ownerEmail,
|
|
3277
|
+
connectionId: requestedConnectionId,
|
|
3258
3278
|
salesforceLoginUrl: options.auth.oauthProvider === "salesforce" &&
|
|
3259
3279
|
typeof resolved.connection.config?.salesforceLoginUrl === "string"
|
|
3260
3280
|
? resolved.connection.config.salesforceLoginUrl
|
package/dist/secrets/routes.d.ts
CHANGED
|
@@ -55,31 +55,31 @@ export declare function createWriteSecretHandler(): import("h3").EventHandlerWit
|
|
|
55
55
|
} | {
|
|
56
56
|
error: string;
|
|
57
57
|
errorCode?: undefined;
|
|
58
|
-
status?: undefined;
|
|
59
58
|
ok?: undefined;
|
|
59
|
+
status?: undefined;
|
|
60
60
|
} | {
|
|
61
61
|
error: string;
|
|
62
62
|
errorCode: string;
|
|
63
|
-
status?: undefined;
|
|
64
63
|
ok?: undefined;
|
|
64
|
+
status?: undefined;
|
|
65
65
|
} | {
|
|
66
66
|
errorCode?: undefined;
|
|
67
67
|
ok: boolean;
|
|
68
68
|
status: string;
|
|
69
69
|
error?: undefined;
|
|
70
70
|
} | {
|
|
71
|
+
ok?: undefined;
|
|
71
72
|
error: string;
|
|
72
73
|
removed?: undefined;
|
|
73
|
-
ok?: undefined;
|
|
74
74
|
} | {
|
|
75
75
|
ok: boolean;
|
|
76
76
|
removed: boolean;
|
|
77
77
|
error?: undefined;
|
|
78
78
|
}>>;
|
|
79
79
|
export declare function createTestSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
80
|
+
ok?: undefined;
|
|
80
81
|
error: string;
|
|
81
82
|
note?: undefined;
|
|
82
|
-
ok?: undefined;
|
|
83
83
|
} | {
|
|
84
84
|
ok: boolean;
|
|
85
85
|
note?: undefined;
|
|
@@ -437,6 +437,10 @@ export async function mergeCoreSharingActions(registry) {
|
|
|
437
437
|
"list-workspace-app-access",
|
|
438
438
|
() => import("../org/actions/list-workspace-app-access.js"),
|
|
439
439
|
],
|
|
440
|
+
[
|
|
441
|
+
"list-workspace-icons",
|
|
442
|
+
() => import("../org/actions/list-workspace-icons.js"),
|
|
443
|
+
],
|
|
440
444
|
[
|
|
441
445
|
"set-workspace-app-access",
|
|
442
446
|
() => import("../org/actions/set-workspace-app-access.js"),
|
|
@@ -545,6 +549,7 @@ export async function mergeCoreSharingActions(registry) {
|
|
|
545
549
|
() => import("../feature-flags/actions/set-feature-flag.js"),
|
|
546
550
|
],
|
|
547
551
|
["get-labs", () => import("../labs/actions/get-labs.js")],
|
|
552
|
+
["get-lab-states", () => import("../labs/actions/get-lab-states.js")],
|
|
548
553
|
["set-lab", () => import("../labs/actions/set-lab.js")],
|
|
549
554
|
[
|
|
550
555
|
"get-chatgpt-subscription-status",
|
|
@@ -2126,6 +2126,20 @@ export function createAgentChatPlugin(options) {
|
|
|
2126
2126
|
...(connectionRequest.detail
|
|
2127
2127
|
? { detail: connectionRequest.detail }
|
|
2128
2128
|
: {}),
|
|
2129
|
+
...(connectionRequest.source?.kind === "workspace_connection" &&
|
|
2130
|
+
connectionRequest.source.id === connectionRequest.provider
|
|
2131
|
+
? {
|
|
2132
|
+
source: {
|
|
2133
|
+
id: connectionRequest.provider,
|
|
2134
|
+
kind: "workspace_connection",
|
|
2135
|
+
...(connectionRequest.source.label
|
|
2136
|
+
? {
|
|
2137
|
+
label: connectionRequest.source.label.slice(0, 120),
|
|
2138
|
+
}
|
|
2139
|
+
: {}),
|
|
2140
|
+
},
|
|
2141
|
+
}
|
|
2142
|
+
: {}),
|
|
2129
2143
|
};
|
|
2130
2144
|
yield {
|
|
2131
2145
|
role: "agent",
|
|
@@ -65,6 +65,7 @@ export declare function createAgentEngineApiKeyHandler(): import("h3").EventHand
|
|
|
65
65
|
error: any;
|
|
66
66
|
code: any;
|
|
67
67
|
} | {
|
|
68
|
+
error?: undefined;
|
|
68
69
|
errorCode?: undefined;
|
|
69
70
|
code?: undefined;
|
|
70
71
|
ok: boolean;
|
|
@@ -72,6 +73,5 @@ export declare function createAgentEngineApiKeyHandler(): import("h3").EventHand
|
|
|
72
73
|
baseUrlKey?: string;
|
|
73
74
|
scope: AgentEngineApiKeyScope;
|
|
74
75
|
defaultModel?: import("./agent-engine-default-model-route.js").SavedKeyDefaultModelOutcome;
|
|
75
|
-
error?: undefined;
|
|
76
76
|
}>>;
|
|
77
77
|
export {};
|
|
@@ -8,8 +8,8 @@ export declare const AGENT_ENGINE_API_KEY_ACTION_NAME = "agent-engine-api-key";
|
|
|
8
8
|
* resolveEngine's credential detection.
|
|
9
9
|
*/
|
|
10
10
|
export declare function createAgentEngineDisconnectHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
11
|
-
error: string;
|
|
12
11
|
ok?: undefined;
|
|
12
|
+
error: string;
|
|
13
13
|
scope?: undefined;
|
|
14
14
|
} | {
|
|
15
15
|
ok: boolean;
|
|
@@ -616,7 +616,7 @@ export declare function resolveOAuthCustodyBuilderKeyStatus(dependencies?: {
|
|
|
616
616
|
lookupFailed: boolean;
|
|
617
617
|
}>;
|
|
618
618
|
}): Promise<OAuthCustodyBuilderKeyStatus>;
|
|
619
|
-
export declare function createOAuthPopupWaitingHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest,
|
|
619
|
+
export declare function createOAuthPopupWaitingHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, string | {
|
|
620
620
|
error: string;
|
|
621
621
|
}>;
|
|
622
622
|
export declare function mountApplicationStateRoutes(nitroApp: any, routePrefix?: string, app?: H3AppShim, options?: {
|