@agent-native/core 0.216.0 → 0.217.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/dist/app-config/analytics.js +1 -1
- package/dist/automation/index.d.ts +1 -1
- package/dist/client/analytics-session.d.ts +7 -0
- package/dist/client/analytics-session.js +27 -1
- package/dist/client/analytics.js +110 -15
- package/dist/client/consent.d.ts +12 -0
- package/dist/client/consent.js +132 -2
- package/dist/client/onboarding/index.d.ts +1 -0
- package/dist/client/onboarding/index.js +1 -0
- package/dist/client/onboarding/use-onboarding-checklist.d.ts +23 -0
- package/dist/client/onboarding/use-onboarding-checklist.js +115 -0
- package/dist/client/session-replay.d.ts +1 -1
- package/dist/client/session-replay.js +142 -3
- package/dist/collab/routes.d.ts +2 -2
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/jobs/actions/manage-recurring-job.d.ts +1 -1
- package/dist/localization/consent-banner-messages.d.ts +16 -0
- package/dist/localization/consent-banner-messages.js +149 -0
- package/dist/localization/core-messages.js +4 -0
- package/dist/localization/default-messages.d.ts +1 -0
- package/dist/localization/default-messages.js +2 -0
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +6 -6
- package/dist/onboarding/index.d.ts +2 -1
- package/dist/onboarding/index.js +1 -0
- package/dist/onboarding/plugin.js +55 -46
- package/dist/onboarding/status.d.ts +15 -0
- package/dist/onboarding/status.js +59 -0
- package/dist/onboarding/types.d.ts +12 -0
- package/dist/onboarding/types.js +2 -1
- package/dist/org/workspace-app-access.js +19 -9
- package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
- package/dist/provider-api/actions/provider-api.d.ts +11 -11
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/server/agent-capabilities.js +13 -6
- 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 +2 -2
- package/dist/server/analytics.d.ts +0 -1
- package/dist/server/analytics.js +81 -20
- package/dist/server/builder-api-auth.d.ts +7 -0
- package/dist/server/builder-api-auth.js +24 -0
- package/dist/server/builder-oauth.d.ts +5 -1
- package/dist/server/builder-oauth.js +5 -0
- package/dist/server/core-routes-plugin.d.ts +1 -1
- package/dist/server/first-touch-route.d.ts +2 -2
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +1 -1
- package/dist/shared/consent.d.ts +2 -0
- package/dist/shared/consent.js +4 -0
- package/dist/triggers/actions/manage-automation.d.ts +5 -5
- package/dist/usage/actions/get-usage-metrics.js +3 -3
- package/docs/content/deployment-environment-variables.mdx +1 -1
- package/docs/content/environment-variables.mdx +1 -1
- package/package.json +5 -3
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { registerOnboardingStep, listOnboardingSteps } from "./registry.js";
|
|
2
|
-
export
|
|
2
|
+
export { DEFAULT_ONBOARDING_CHECKLIST } from "./types.js";
|
|
3
|
+
export type { OnboardingStep, OnboardingMethod, OnboardingMethodBadge, OnboardingFormField, OnboardingStepStatus, OnboardingResolveContext, OnboardingCapability, OnboardingAppProfile, WorkspaceBuilderIncludedServiceId, WorkspaceBuilderOnlyServiceId, WorkspaceProviderServiceId, WorkspaceServiceId, } from "./types.js";
|
|
3
4
|
export { WORKSPACE_SERVICES, workspaceServiceForCapability, type WorkspaceService, type WorkspaceServiceKind, } from "./workspace-services.js";
|
|
4
5
|
export { getOnboardingAppProfile, resolveOnboardingAppId, } from "./app-profile.js";
|
|
5
6
|
export { getOnboardingAppProfileForId } from "./app-profile-data.js";
|
package/dist/onboarding/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { registerOnboardingStep, listOnboardingSteps } from "./registry.js";
|
|
2
|
+
export { DEFAULT_ONBOARDING_CHECKLIST } from "./types.js";
|
|
2
3
|
export { WORKSPACE_SERVICES, workspaceServiceForCapability, } from "./workspace-services.js";
|
|
3
4
|
export { getOnboardingAppProfile, resolveOnboardingAppId, } from "./app-profile.js";
|
|
4
5
|
export { getOnboardingAppProfileForId } from "./app-profile-data.js";
|
|
@@ -11,11 +11,10 @@ import { getOnboardingRoleCategory, getOnboardingRoleTextForAnalytics, onboardin
|
|
|
11
11
|
import { getUserProfile, updateUserOnboardingRole, } from "../user-profile/store.js";
|
|
12
12
|
import { getOnboardingAppProfile } from "./app-profile.js";
|
|
13
13
|
import { registerDefaultOnboardingSteps } from "./default-steps.js";
|
|
14
|
-
import { listOnboardingSteps } from "./registry.js";
|
|
15
14
|
import { SHARED_ONBOARDING_COOKIE, SHARED_ONBOARDING_COOKIE_MAX_AGE, decodeSharedOnboardingCookie, encodeSharedOnboardingCookie, hashOnboardingEmail, } from "./shared-cookie.js";
|
|
15
|
+
import { getOnboardingStepStatuses, isValidOnboardingChecklistName, onboardingDismissedKey, onboardingOverrideKey, readOnboardingDismissed, } from "./status.js";
|
|
16
|
+
import { DEFAULT_ONBOARDING_CHECKLIST, } from "./types.js";
|
|
16
17
|
const ONBOARDING_PREFIX = "/_agent-native/onboarding";
|
|
17
|
-
const OVERRIDE_KEY_PREFIX = "onboarding:override:";
|
|
18
|
-
const DISMISSED_KEY = "onboarding:dismissed";
|
|
19
18
|
async function resolveOnboardingContext(event) {
|
|
20
19
|
const { getSession } = await import("../server/auth.js");
|
|
21
20
|
const session = await getSession(event);
|
|
@@ -27,35 +26,15 @@ async function resolveOnboardingContext(event) {
|
|
|
27
26
|
orgId: session.orgId ?? null,
|
|
28
27
|
};
|
|
29
28
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
let complete = false;
|
|
42
|
-
if (!options.preview) {
|
|
43
|
-
complete = (await step.isComplete(context)) === true;
|
|
44
|
-
if (!complete) {
|
|
45
|
-
complete = await hasOverride(context.sessionId, step.id);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
return {
|
|
49
|
-
id: step.id,
|
|
50
|
-
title: step.title,
|
|
51
|
-
description: step.description,
|
|
52
|
-
order: step.order,
|
|
53
|
-
required: step.required ?? false,
|
|
54
|
-
complete,
|
|
55
|
-
methods: step.methods,
|
|
56
|
-
};
|
|
57
|
-
}));
|
|
58
|
-
return serialized.filter((step) => step !== null);
|
|
29
|
+
/** `undefined` when the request names no checklist; `null` when the name is invalid. */
|
|
30
|
+
function readChecklistParam(event) {
|
|
31
|
+
const raw = getQuery(event).checklist;
|
|
32
|
+
if (raw === undefined)
|
|
33
|
+
return undefined;
|
|
34
|
+
if (typeof raw !== "string" || !isValidOnboardingChecklistName(raw)) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
return raw;
|
|
59
38
|
}
|
|
60
39
|
function withOnboardingRequestContext(context, fn) {
|
|
61
40
|
return runWithRequestContext({
|
|
@@ -73,9 +52,10 @@ function roleTrackingProperties(role) {
|
|
|
73
52
|
function allRequiredComplete(statuses) {
|
|
74
53
|
return statuses.filter((s) => s.required).every((s) => s.complete);
|
|
75
54
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
55
|
+
// A progress checklist has no required steps, so "required complete" would be
|
|
56
|
+
// vacuously true while steps are still open.
|
|
57
|
+
function allStepsComplete(statuses) {
|
|
58
|
+
return statuses.length > 0 && statuses.every((s) => s.complete);
|
|
79
59
|
}
|
|
80
60
|
async function resolveSharedCompletionEnabled() {
|
|
81
61
|
if (!getAppConfig().onboarding.sharedCompletion.enabled)
|
|
@@ -104,10 +84,15 @@ export function createOnboardingPlugin(options = {}) {
|
|
|
104
84
|
setResponseStatus(event, 405);
|
|
105
85
|
return { error: "Method not allowed" };
|
|
106
86
|
}
|
|
87
|
+
const checklist = readChecklistParam(event);
|
|
88
|
+
if (checklist === null) {
|
|
89
|
+
setResponseStatus(event, 400);
|
|
90
|
+
return { error: "Invalid checklist" };
|
|
91
|
+
}
|
|
107
92
|
const context = await resolveOnboardingContext(event);
|
|
108
93
|
const query = getQuery(event);
|
|
109
94
|
const preview = query.preview === "1" || query.preview === 1;
|
|
110
|
-
return withOnboardingRequestContext(context, () =>
|
|
95
|
+
return withOnboardingRequestContext(context, () => getOnboardingStepStatuses(context, { preview, checklist }));
|
|
111
96
|
}
|
|
112
97
|
const [id, action] = trimmed.split("/");
|
|
113
98
|
if (action === "complete") {
|
|
@@ -120,7 +105,7 @@ export function createOnboardingPlugin(options = {}) {
|
|
|
120
105
|
return { error: "id required" };
|
|
121
106
|
}
|
|
122
107
|
const { sessionId } = await resolveOnboardingContext(event);
|
|
123
|
-
await appStatePut(sessionId,
|
|
108
|
+
await appStatePut(sessionId, onboardingOverrideKey(id), { complete: true }, { requestSource: "agent" });
|
|
124
109
|
return { ok: true, id };
|
|
125
110
|
}
|
|
126
111
|
return;
|
|
@@ -130,8 +115,14 @@ export function createOnboardingPlugin(options = {}) {
|
|
|
130
115
|
setResponseStatus(event, 405);
|
|
131
116
|
return { error: "Method not allowed" };
|
|
132
117
|
}
|
|
118
|
+
const requested = readChecklistParam(event);
|
|
119
|
+
if (requested === null) {
|
|
120
|
+
setResponseStatus(event, 400);
|
|
121
|
+
return { error: "Invalid checklist" };
|
|
122
|
+
}
|
|
123
|
+
const checklist = requested ?? DEFAULT_ONBOARDING_CHECKLIST;
|
|
133
124
|
const { sessionId } = await resolveOnboardingContext(event);
|
|
134
|
-
await appStatePut(sessionId,
|
|
125
|
+
await appStatePut(sessionId, onboardingDismissedKey(checklist), { dismissed: true, at: new Date().toISOString() }, { requestSource: "agent" });
|
|
135
126
|
return { ok: true };
|
|
136
127
|
}));
|
|
137
128
|
getH3App(nitroApp).use(`${ONBOARDING_PREFIX}/reopen`, defineEventHandler(async (event) => {
|
|
@@ -139,8 +130,14 @@ export function createOnboardingPlugin(options = {}) {
|
|
|
139
130
|
setResponseStatus(event, 405);
|
|
140
131
|
return { error: "Method not allowed" };
|
|
141
132
|
}
|
|
133
|
+
const requested = readChecklistParam(event);
|
|
134
|
+
if (requested === null) {
|
|
135
|
+
setResponseStatus(event, 400);
|
|
136
|
+
return { error: "Invalid checklist" };
|
|
137
|
+
}
|
|
138
|
+
const checklist = requested ?? DEFAULT_ONBOARDING_CHECKLIST;
|
|
142
139
|
const { sessionId } = await resolveOnboardingContext(event);
|
|
143
|
-
await appStatePut(sessionId,
|
|
140
|
+
await appStatePut(sessionId, onboardingDismissedKey(checklist), { dismissed: false, at: new Date().toISOString() }, { requestSource: "agent" });
|
|
144
141
|
return { ok: true };
|
|
145
142
|
}));
|
|
146
143
|
getH3App(nitroApp).use(`${ONBOARDING_PREFIX}/dismissed`, defineEventHandler(async (event) => {
|
|
@@ -148,15 +145,22 @@ export function createOnboardingPlugin(options = {}) {
|
|
|
148
145
|
setResponseStatus(event, 405);
|
|
149
146
|
return { error: "Method not allowed" };
|
|
150
147
|
}
|
|
148
|
+
const checklist = readChecklistParam(event);
|
|
149
|
+
if (checklist === null) {
|
|
150
|
+
setResponseStatus(event, 400);
|
|
151
|
+
return { error: "Invalid checklist" };
|
|
152
|
+
}
|
|
151
153
|
const context = await resolveOnboardingContext(event);
|
|
152
154
|
return withOnboardingRequestContext(context, async () => {
|
|
153
|
-
const [statuses,
|
|
154
|
-
|
|
155
|
-
|
|
155
|
+
const [statuses, dismissed] = await Promise.all([
|
|
156
|
+
getOnboardingStepStatuses(context, { checklist }),
|
|
157
|
+
readOnboardingDismissed(context.sessionId, checklist),
|
|
156
158
|
]);
|
|
157
159
|
return {
|
|
158
|
-
dismissed
|
|
159
|
-
allComplete:
|
|
160
|
+
dismissed,
|
|
161
|
+
allComplete: checklist === undefined
|
|
162
|
+
? allRequiredComplete(statuses)
|
|
163
|
+
: allStepsComplete(statuses),
|
|
160
164
|
};
|
|
161
165
|
});
|
|
162
166
|
}));
|
|
@@ -172,13 +176,18 @@ export function createOnboardingPlugin(options = {}) {
|
|
|
172
176
|
setResponseStatus(event, 405);
|
|
173
177
|
return { error: "Method not allowed" };
|
|
174
178
|
}
|
|
179
|
+
const checklist = readChecklistParam(event);
|
|
180
|
+
if (checklist === null) {
|
|
181
|
+
setResponseStatus(event, 400);
|
|
182
|
+
return { error: "Invalid checklist" };
|
|
183
|
+
}
|
|
175
184
|
const context = await resolveOnboardingContext(event);
|
|
176
185
|
const query = getQuery(event);
|
|
177
186
|
const preview = query.preview === "1" || query.preview === 1;
|
|
178
187
|
return withOnboardingRequestContext(context, async () => {
|
|
179
188
|
const [steps, dismissed] = await Promise.all([
|
|
180
|
-
|
|
181
|
-
|
|
189
|
+
getOnboardingStepStatuses(context, { preview, checklist }),
|
|
190
|
+
readOnboardingDismissed(context.sessionId, checklist ?? DEFAULT_ONBOARDING_CHECKLIST),
|
|
182
191
|
]);
|
|
183
192
|
return {
|
|
184
193
|
steps,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type OnboardingResolveContext, type OnboardingStepStatus } from "./types.js";
|
|
2
|
+
export declare function isValidOnboardingChecklistName(name: string): boolean;
|
|
3
|
+
/** The setup checklist keeps its original key so existing dismissals survive. */
|
|
4
|
+
export declare function onboardingDismissedKey(checklist: string): string;
|
|
5
|
+
export declare function onboardingOverrideKey(stepId: string): string;
|
|
6
|
+
export declare function readOnboardingDismissed(sessionId: string, checklist?: string): Promise<boolean>;
|
|
7
|
+
/**
|
|
8
|
+
* Resolves the steps of one checklist. A failing `isAvailable`, `isComplete`,
|
|
9
|
+
* or override read rejects instead of reporting a step as incomplete, so
|
|
10
|
+
* callers can tell "could not check" from "not done".
|
|
11
|
+
*/
|
|
12
|
+
export declare function getOnboardingStepStatuses(context: OnboardingResolveContext, options?: {
|
|
13
|
+
preview?: boolean;
|
|
14
|
+
checklist?: string;
|
|
15
|
+
}): Promise<OnboardingStepStatus[]>;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { appStateGet } from "../application-state/store.js";
|
|
2
|
+
import { listOnboardingSteps } from "./registry.js";
|
|
3
|
+
import { DEFAULT_ONBOARDING_CHECKLIST, } from "./types.js";
|
|
4
|
+
const OVERRIDE_KEY_PREFIX = "onboarding:override:";
|
|
5
|
+
const DISMISSED_KEY = "onboarding:dismissed";
|
|
6
|
+
const CHECKLIST_NAME_PATTERN = /^[a-z][a-z0-9-]{0,39}$/;
|
|
7
|
+
export function isValidOnboardingChecklistName(name) {
|
|
8
|
+
return CHECKLIST_NAME_PATTERN.test(name);
|
|
9
|
+
}
|
|
10
|
+
/** The setup checklist keeps its original key so existing dismissals survive. */
|
|
11
|
+
export function onboardingDismissedKey(checklist) {
|
|
12
|
+
return checklist === DEFAULT_ONBOARDING_CHECKLIST
|
|
13
|
+
? DISMISSED_KEY
|
|
14
|
+
: `${DISMISSED_KEY}:${checklist}`;
|
|
15
|
+
}
|
|
16
|
+
export function onboardingOverrideKey(stepId) {
|
|
17
|
+
return `${OVERRIDE_KEY_PREFIX}${stepId}`;
|
|
18
|
+
}
|
|
19
|
+
async function hasOverride(sessionId, stepId) {
|
|
20
|
+
const val = await appStateGet(sessionId, onboardingOverrideKey(stepId));
|
|
21
|
+
return !!(val && val.complete);
|
|
22
|
+
}
|
|
23
|
+
export async function readOnboardingDismissed(sessionId, checklist = DEFAULT_ONBOARDING_CHECKLIST) {
|
|
24
|
+
const value = await appStateGet(sessionId, onboardingDismissedKey(checklist));
|
|
25
|
+
return !!(value && value.dismissed);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Resolves the steps of one checklist. A failing `isAvailable`, `isComplete`,
|
|
29
|
+
* or override read rejects instead of reporting a step as incomplete, so
|
|
30
|
+
* callers can tell "could not check" from "not done".
|
|
31
|
+
*/
|
|
32
|
+
export async function getOnboardingStepStatuses(context, options = {}) {
|
|
33
|
+
const checklist = options.checklist ?? DEFAULT_ONBOARDING_CHECKLIST;
|
|
34
|
+
const steps = listOnboardingSteps().filter((step) => (step.checklist ?? DEFAULT_ONBOARDING_CHECKLIST) === checklist);
|
|
35
|
+
const serialized = await Promise.all(steps.map(async (step) => {
|
|
36
|
+
if (!options.preview && step.isAvailable) {
|
|
37
|
+
if (!(await step.isAvailable(context)))
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
let complete = false;
|
|
41
|
+
if (!options.preview) {
|
|
42
|
+
complete = (await step.isComplete(context)) === true;
|
|
43
|
+
if (!complete) {
|
|
44
|
+
complete = await hasOverride(context.sessionId, step.id);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
id: step.id,
|
|
49
|
+
title: step.title,
|
|
50
|
+
description: step.description,
|
|
51
|
+
order: step.order,
|
|
52
|
+
required: step.required ?? false,
|
|
53
|
+
complete,
|
|
54
|
+
...(step.href ? { href: step.href } : {}),
|
|
55
|
+
methods: step.methods,
|
|
56
|
+
};
|
|
57
|
+
}));
|
|
58
|
+
return serialized.filter((step) => step !== null);
|
|
59
|
+
}
|
|
@@ -45,12 +45,23 @@ export type OnboardingMethod = (OnboardingMethodBase & {
|
|
|
45
45
|
*/
|
|
46
46
|
kind: "file-storage";
|
|
47
47
|
});
|
|
48
|
+
/** The checklist a step belongs to when it does not name one: credential and connection setup. */
|
|
49
|
+
export declare const DEFAULT_ONBOARDING_CHECKLIST = "setup";
|
|
48
50
|
export interface OnboardingStep {
|
|
49
51
|
id: string;
|
|
50
52
|
title: string;
|
|
51
53
|
description: string;
|
|
52
54
|
order: number;
|
|
53
55
|
required?: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Named checklist the step belongs to. The setup checklist (the default)
|
|
58
|
+
* and a progress checklist such as `getting-started` never share rows:
|
|
59
|
+
* each is served only when asked for by name.
|
|
60
|
+
*/
|
|
61
|
+
checklist?: string;
|
|
62
|
+
/** In-app path a progress row opens so the user can complete the step. */
|
|
63
|
+
href?: string;
|
|
64
|
+
/** Progress steps that need no setup form pass an empty list. */
|
|
54
65
|
methods: OnboardingMethod[];
|
|
55
66
|
isAvailable?: (context?: OnboardingResolveContext) => boolean | Promise<boolean>;
|
|
56
67
|
isComplete: (context?: OnboardingResolveContext) => boolean | Promise<boolean>;
|
|
@@ -67,6 +78,7 @@ export interface OnboardingStepStatus {
|
|
|
67
78
|
order: number;
|
|
68
79
|
required: boolean;
|
|
69
80
|
complete: boolean;
|
|
81
|
+
href?: string;
|
|
70
82
|
methods: OnboardingMethod[];
|
|
71
83
|
}
|
|
72
84
|
/** Services whose provider is picked per service (`manage-service-providers`). */
|
package/dist/onboarding/types.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
/** The checklist a step belongs to when it does not name one: credential and connection setup. */
|
|
2
|
+
export const DEFAULT_ONBOARDING_CHECKLIST = "setup";
|
|
@@ -232,24 +232,28 @@ async function resolveHostedWorkspaceAppAuth(configuredDirectory, context, email
|
|
|
232
232
|
const audience = canonicalA2AAudience(configuredDirectory);
|
|
233
233
|
let stage = "org-domain-lookup-failed";
|
|
234
234
|
try {
|
|
235
|
+
const requestContext = getRequestContext();
|
|
236
|
+
const delegatedMember = requestContext?.a2aIdentityAssurance === "org-member";
|
|
235
237
|
const orgDomain = orgId ? await cachedOrgDomain(orgId) : null;
|
|
236
238
|
const normalizedOrgDomain = orgDomain?.trim() || undefined;
|
|
237
239
|
if (orgId && !normalizedOrgDomain) {
|
|
238
240
|
return workspaceAppAccessUnavailable("org-domain-missing", { audience });
|
|
239
241
|
}
|
|
240
|
-
stage = "
|
|
241
|
-
const
|
|
242
|
+
stage = "token-signing-failed";
|
|
243
|
+
const deploymentSecret = readDeployCredentialEnv("A2A_SECRET")?.trim();
|
|
244
|
+
if (orgId && (delegatedMember || deploymentSecret)) {
|
|
245
|
+
stage = "org-a2a-secret-lookup-failed";
|
|
246
|
+
}
|
|
247
|
+
const orgSecret = orgId && (delegatedMember || deploymentSecret)
|
|
242
248
|
? (await cachedOrgA2ASecret(orgId))?.trim() || undefined
|
|
243
249
|
: undefined;
|
|
244
|
-
|
|
245
|
-
const signingSecret = orgSecret
|
|
250
|
+
stage = "token-signing-failed";
|
|
251
|
+
const signingSecret = delegatedMember ? orgSecret : deploymentSecret;
|
|
246
252
|
if (!signingSecret) {
|
|
247
253
|
return workspaceAppAccessUnavailable("a2a-secret-missing", { audience });
|
|
248
254
|
}
|
|
249
|
-
stage = "token-signing-failed";
|
|
250
|
-
const requestContext = getRequestContext();
|
|
251
255
|
let token;
|
|
252
|
-
if (
|
|
256
|
+
if (delegatedMember) {
|
|
253
257
|
if (!orgId ||
|
|
254
258
|
!normalizedOrgDomain ||
|
|
255
259
|
requestContext.orgId?.trim() !== orgId ||
|
|
@@ -273,9 +277,15 @@ async function resolveHostedWorkspaceAppAuth(configuredDirectory, context, email
|
|
|
273
277
|
token = await signA2AOrgMemberDelegationToken(email, normalizedOrgDomain, orgSecret, audience);
|
|
274
278
|
}
|
|
275
279
|
else {
|
|
276
|
-
|
|
280
|
+
if (orgSecret && orgSecret === deploymentSecret) {
|
|
281
|
+
return workspaceAppAccessUnavailable("token-signing-failed", {
|
|
282
|
+
audience,
|
|
283
|
+
detail: "Organization and deployment A2A secrets must differ for user identity.",
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
token = await signA2AToken(email, normalizedOrgDomain, undefined, {
|
|
277
287
|
expiresIn: "1m",
|
|
278
|
-
preferGlobalSecret:
|
|
288
|
+
preferGlobalSecret: true,
|
|
279
289
|
audience,
|
|
280
290
|
extraClaims: {
|
|
281
291
|
jti: randomUUID(),
|
|
@@ -75,10 +75,10 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
|
|
|
75
75
|
user: "user";
|
|
76
76
|
}>>;
|
|
77
77
|
}, z.core.$strip>>, {
|
|
78
|
+
message?: undefined;
|
|
78
79
|
id?: undefined;
|
|
79
|
-
deleted?: undefined;
|
|
80
80
|
provider?: undefined;
|
|
81
|
-
|
|
81
|
+
deleted?: undefined;
|
|
82
82
|
providers: {
|
|
83
83
|
id: string;
|
|
84
84
|
label: string;
|
|
@@ -89,45 +89,45 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
|
|
|
89
89
|
updatedAt: number;
|
|
90
90
|
}[];
|
|
91
91
|
count: number;
|
|
92
|
+
found?: undefined;
|
|
92
93
|
registered?: undefined;
|
|
93
94
|
label?: undefined;
|
|
94
|
-
message?: undefined;
|
|
95
95
|
} | {
|
|
96
|
+
message?: undefined;
|
|
96
97
|
id?: undefined;
|
|
97
|
-
deleted?: undefined;
|
|
98
98
|
count?: undefined;
|
|
99
|
+
deleted?: undefined;
|
|
99
100
|
providers?: undefined;
|
|
100
101
|
found: boolean;
|
|
101
102
|
provider: import("../custom-registry.js").CustomProviderConfig;
|
|
102
103
|
registered?: undefined;
|
|
103
104
|
label?: undefined;
|
|
104
|
-
message?: undefined;
|
|
105
105
|
} | {
|
|
106
|
-
|
|
106
|
+
message?: undefined;
|
|
107
107
|
provider?: undefined;
|
|
108
108
|
count?: undefined;
|
|
109
|
+
deleted?: undefined;
|
|
109
110
|
providers?: undefined;
|
|
110
111
|
found: boolean;
|
|
111
112
|
id: string;
|
|
112
113
|
registered?: undefined;
|
|
113
114
|
label?: undefined;
|
|
114
|
-
message?: undefined;
|
|
115
115
|
} | {
|
|
116
|
+
message?: undefined;
|
|
116
117
|
provider?: undefined;
|
|
117
118
|
count?: undefined;
|
|
118
|
-
found?: undefined;
|
|
119
119
|
providers?: undefined;
|
|
120
|
+
found?: undefined;
|
|
120
121
|
deleted: boolean;
|
|
121
122
|
id: string;
|
|
122
123
|
registered?: undefined;
|
|
123
124
|
label?: undefined;
|
|
124
|
-
message?: undefined;
|
|
125
125
|
} | {
|
|
126
|
-
deleted?: undefined;
|
|
127
126
|
provider?: undefined;
|
|
128
127
|
count?: undefined;
|
|
129
|
-
|
|
128
|
+
deleted?: undefined;
|
|
130
129
|
providers?: undefined;
|
|
130
|
+
found?: undefined;
|
|
131
131
|
registered: boolean;
|
|
132
132
|
id: string;
|
|
133
133
|
label: string;
|
|
@@ -317,10 +317,8 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
317
317
|
scope?: "org" | "user" | undefined;
|
|
318
318
|
}, {
|
|
319
319
|
id?: undefined;
|
|
320
|
-
provider?: undefined;
|
|
321
|
-
message?: undefined;
|
|
322
320
|
deleted?: undefined;
|
|
323
|
-
|
|
321
|
+
provider?: undefined;
|
|
324
322
|
providers: {
|
|
325
323
|
id: string;
|
|
326
324
|
label: string;
|
|
@@ -331,44 +329,46 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
331
329
|
updatedAt: number;
|
|
332
330
|
}[];
|
|
333
331
|
count: number;
|
|
332
|
+
found?: undefined;
|
|
334
333
|
registered?: undefined;
|
|
335
334
|
label?: undefined;
|
|
335
|
+
message?: undefined;
|
|
336
336
|
} | {
|
|
337
337
|
id?: undefined;
|
|
338
|
-
count?: undefined;
|
|
339
|
-
message?: undefined;
|
|
340
338
|
deleted?: undefined;
|
|
339
|
+
count?: undefined;
|
|
341
340
|
providers?: undefined;
|
|
342
341
|
found: boolean;
|
|
343
342
|
provider: import("../custom-registry.js").CustomProviderConfig;
|
|
344
343
|
registered?: undefined;
|
|
345
344
|
label?: undefined;
|
|
345
|
+
message?: undefined;
|
|
346
346
|
} | {
|
|
347
|
+
deleted?: undefined;
|
|
347
348
|
provider?: undefined;
|
|
348
349
|
count?: undefined;
|
|
349
|
-
message?: undefined;
|
|
350
|
-
deleted?: undefined;
|
|
351
350
|
providers?: undefined;
|
|
352
351
|
found: boolean;
|
|
353
352
|
id: string;
|
|
354
353
|
registered?: undefined;
|
|
355
354
|
label?: undefined;
|
|
355
|
+
message?: undefined;
|
|
356
356
|
} | {
|
|
357
357
|
provider?: undefined;
|
|
358
358
|
count?: undefined;
|
|
359
|
-
message?: undefined;
|
|
360
|
-
found?: undefined;
|
|
361
359
|
providers?: undefined;
|
|
360
|
+
found?: undefined;
|
|
362
361
|
deleted: boolean;
|
|
363
362
|
id: string;
|
|
364
363
|
registered?: undefined;
|
|
365
364
|
label?: undefined;
|
|
365
|
+
message?: undefined;
|
|
366
366
|
} | {
|
|
367
|
+
deleted?: undefined;
|
|
367
368
|
provider?: undefined;
|
|
368
369
|
count?: undefined;
|
|
369
|
-
deleted?: undefined;
|
|
370
|
-
found?: undefined;
|
|
371
370
|
providers?: undefined;
|
|
371
|
+
found?: undefined;
|
|
372
372
|
registered: boolean;
|
|
373
373
|
id: string;
|
|
374
374
|
label: string;
|
|
@@ -39,8 +39,8 @@ export declare function handleUpdateResource(event: any): Promise<import("./stor
|
|
|
39
39
|
error: string;
|
|
40
40
|
}>;
|
|
41
41
|
export declare function handleDeleteResource(event: any): Promise<{
|
|
42
|
-
error: string;
|
|
43
42
|
ok?: undefined;
|
|
43
|
+
error: string;
|
|
44
44
|
} | {
|
|
45
45
|
error?: undefined;
|
|
46
46
|
ok: boolean;
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { canonicalA2AAudience } from "../a2a/audience.js";
|
|
2
2
|
import { A2AClient, A2ANoJsonRpcInterfaceError } from "../a2a/client.js";
|
|
3
3
|
import { resolveRemoteAgentToken } from "../a2a/remote-agent-auth.js";
|
|
4
|
+
import { AGENT_PROFILE_WHEN_TO_USE_MAX_ITEMS, AGENT_PROFILE_WHEN_TO_USE_MAX_LENGTH, } from "../shared/agent-profile.js";
|
|
4
5
|
import { getRequestOrgId, getRequestUserEmail } from "./request-context.js";
|
|
5
6
|
export const MAX_APPS = 30;
|
|
6
7
|
const MAX_SKILLS_IN_SUMMARY = 8;
|
|
7
8
|
const MAX_SKILLS_IN_DETAIL = 60;
|
|
8
9
|
const MAX_DESCRIPTION_CHARS = 240;
|
|
10
|
+
// Every valid profile fits; the cap only bounds unparsed sources.
|
|
11
|
+
const MAX_WHEN_TO_USE_CHARS = AGENT_PROFILE_WHEN_TO_USE_MAX_ITEMS *
|
|
12
|
+
(AGENT_PROFILE_WHEN_TO_USE_MAX_LENGTH + "; ".length);
|
|
9
13
|
const CARD_TIMEOUT_MS = 6_000;
|
|
10
14
|
const CARD_CONCURRENCY = 8;
|
|
11
15
|
const CARD_CACHE_TTL_MS = 30_000;
|
|
@@ -159,13 +163,16 @@ export async function loadAllCapabilities(agents) {
|
|
|
159
163
|
return results;
|
|
160
164
|
}
|
|
161
165
|
export function purposeOf(peer) {
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
const card = peer.cardDescription?.trim();
|
|
166
|
-
return card
|
|
167
|
-
? truncate(card, MAX_DESCRIPTION_CHARS)
|
|
166
|
+
const description = peer.agent.description?.trim() || peer.cardDescription?.trim();
|
|
167
|
+
const purpose = description
|
|
168
|
+
? truncate(description, MAX_DESCRIPTION_CHARS)
|
|
168
169
|
: "(no description published)";
|
|
170
|
+
// Ranking matches on whenToUse; without it here the model picks between
|
|
171
|
+
// ranked apps by name alone and can overrule the ranking.
|
|
172
|
+
const whenToUse = peer.agent.whenToUse?.join("; ").trim();
|
|
173
|
+
return whenToUse
|
|
174
|
+
? `${purpose}\nWhen to use: ${truncate(whenToUse, MAX_WHEN_TO_USE_CHARS)}`
|
|
175
|
+
: purpose;
|
|
169
176
|
}
|
|
170
177
|
export function formatCapabilitySummary(peers, truncated, detailHint) {
|
|
171
178
|
const lines = peers.map((peer) => {
|
|
@@ -67,12 +67,12 @@ export declare function createAgentEngineApiKeyHandler(): import("h3").EventHand
|
|
|
67
67
|
code: any;
|
|
68
68
|
} | {
|
|
69
69
|
errorCode?: undefined;
|
|
70
|
-
error?: undefined;
|
|
71
70
|
code?: undefined;
|
|
72
71
|
ok: boolean;
|
|
73
72
|
key: string;
|
|
74
73
|
baseUrlKey?: string;
|
|
75
74
|
scope: AgentEngineApiKeyScope;
|
|
76
75
|
defaultModel?: import("./agent-engine-default-model-route.js").SavedKeyDefaultModelOutcome;
|
|
76
|
+
error?: undefined;
|
|
77
77
|
}>>;
|
|
78
78
|
export {};
|
|
@@ -16,9 +16,9 @@ export declare function createAgentEngineDisconnectHandler(): import("h3").Event
|
|
|
16
16
|
error: any;
|
|
17
17
|
scope?: undefined;
|
|
18
18
|
} | {
|
|
19
|
+
error?: undefined;
|
|
19
20
|
ok: boolean;
|
|
20
21
|
scope: "org" | "user";
|
|
21
|
-
error?: undefined;
|
|
22
22
|
}>>;
|
|
23
23
|
export interface DefaultModelSelectionRequest {
|
|
24
24
|
engine: string;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export declare function createAgentEngineOllamaModelsHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
2
2
|
error: string;
|
|
3
|
-
ok?: undefined;
|
|
4
3
|
models?: undefined;
|
|
4
|
+
ok?: undefined;
|
|
5
5
|
} | {
|
|
6
|
-
error?: undefined;
|
|
7
6
|
ok: boolean;
|
|
8
7
|
models: string[];
|
|
8
|
+
error?: undefined;
|
|
9
9
|
}>>;
|