@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.
Files changed (56) hide show
  1. package/dist/app-config/analytics.js +1 -1
  2. package/dist/automation/index.d.ts +1 -1
  3. package/dist/client/analytics-session.d.ts +7 -0
  4. package/dist/client/analytics-session.js +27 -1
  5. package/dist/client/analytics.js +110 -15
  6. package/dist/client/consent.d.ts +12 -0
  7. package/dist/client/consent.js +132 -2
  8. package/dist/client/onboarding/index.d.ts +1 -0
  9. package/dist/client/onboarding/index.js +1 -0
  10. package/dist/client/onboarding/use-onboarding-checklist.d.ts +23 -0
  11. package/dist/client/onboarding/use-onboarding-checklist.js +115 -0
  12. package/dist/client/session-replay.d.ts +1 -1
  13. package/dist/client/session-replay.js +142 -3
  14. package/dist/collab/routes.d.ts +2 -2
  15. package/dist/collab/struct-routes.d.ts +1 -1
  16. package/dist/jobs/actions/manage-recurring-job.d.ts +1 -1
  17. package/dist/localization/consent-banner-messages.d.ts +16 -0
  18. package/dist/localization/consent-banner-messages.js +149 -0
  19. package/dist/localization/core-messages.js +4 -0
  20. package/dist/localization/default-messages.d.ts +1 -0
  21. package/dist/localization/default-messages.js +2 -0
  22. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  23. package/dist/notifications/routes.d.ts +2 -2
  24. package/dist/observability/routes.d.ts +6 -6
  25. package/dist/onboarding/index.d.ts +2 -1
  26. package/dist/onboarding/index.js +1 -0
  27. package/dist/onboarding/plugin.js +55 -46
  28. package/dist/onboarding/status.d.ts +15 -0
  29. package/dist/onboarding/status.js +59 -0
  30. package/dist/onboarding/types.d.ts +12 -0
  31. package/dist/onboarding/types.js +2 -1
  32. package/dist/org/workspace-app-access.js +19 -9
  33. package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
  34. package/dist/provider-api/actions/provider-api.d.ts +11 -11
  35. package/dist/resources/handlers.d.ts +1 -1
  36. package/dist/server/agent-capabilities.js +13 -6
  37. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  38. package/dist/server/agent-engine-default-model-route.d.ts +1 -1
  39. package/dist/server/agent-engine-ollama-models-route.d.ts +2 -2
  40. package/dist/server/analytics.d.ts +0 -1
  41. package/dist/server/analytics.js +81 -20
  42. package/dist/server/builder-api-auth.d.ts +7 -0
  43. package/dist/server/builder-api-auth.js +24 -0
  44. package/dist/server/builder-oauth.d.ts +5 -1
  45. package/dist/server/builder-oauth.js +5 -0
  46. package/dist/server/core-routes-plugin.d.ts +1 -1
  47. package/dist/server/first-touch-route.d.ts +2 -2
  48. package/dist/server/index.d.ts +1 -1
  49. package/dist/server/index.js +1 -1
  50. package/dist/shared/consent.d.ts +2 -0
  51. package/dist/shared/consent.js +4 -0
  52. package/dist/triggers/actions/manage-automation.d.ts +5 -5
  53. package/dist/usage/actions/get-usage-metrics.js +3 -3
  54. package/docs/content/deployment-environment-variables.mdx +1 -1
  55. package/docs/content/environment-variables.mdx +1 -1
  56. package/package.json +5 -3
@@ -1,5 +1,6 @@
1
1
  export { registerOnboardingStep, listOnboardingSteps } from "./registry.js";
2
- export type { OnboardingStep, OnboardingMethod, OnboardingMethodBadge, OnboardingFormField, OnboardingStepStatus, OnboardingCapability, OnboardingAppProfile, WorkspaceBuilderIncludedServiceId, WorkspaceBuilderOnlyServiceId, WorkspaceProviderServiceId, WorkspaceServiceId, } from "./types.js";
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";
@@ -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
- async function hasOverride(sessionId, stepId) {
31
- const val = await appStateGet(sessionId, `${OVERRIDE_KEY_PREFIX}${stepId}`);
32
- return !!(val && val.complete);
33
- }
34
- async function serializeSteps(context, options = {}) {
35
- const steps = listOnboardingSteps();
36
- const serialized = await Promise.all(steps.map(async (step) => {
37
- if (!options.preview && step.isAvailable) {
38
- if (!(await step.isAvailable(context)))
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
- async function readDismissedFlag(sessionId) {
77
- const value = await appStateGet(sessionId, DISMISSED_KEY);
78
- return !!(value && value.dismissed);
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, () => serializeSteps(context, { preview }));
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, `${OVERRIDE_KEY_PREFIX}${id}`, { complete: true }, { requestSource: "agent" });
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, DISMISSED_KEY, { dismissed: true, at: new Date().toISOString() }, { requestSource: "agent" });
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, DISMISSED_KEY, { dismissed: false, at: new Date().toISOString() }, { requestSource: "agent" });
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, value] = await Promise.all([
154
- serializeSteps(context),
155
- appStateGet(context.sessionId, DISMISSED_KEY),
155
+ const [statuses, dismissed] = await Promise.all([
156
+ getOnboardingStepStatuses(context, { checklist }),
157
+ readOnboardingDismissed(context.sessionId, checklist),
156
158
  ]);
157
159
  return {
158
- dismissed: !!(value && value.dismissed),
159
- allComplete: allRequiredComplete(statuses),
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
- serializeSteps(context, { preview }),
181
- readDismissedFlag(context.sessionId),
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`). */
@@ -1 +1,2 @@
1
- export {};
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 = "org-a2a-secret-lookup-failed";
241
- const orgSecret = orgId
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
- const deploymentSecret = readDeployCredentialEnv("A2A_SECRET")?.trim();
245
- const signingSecret = orgSecret || deploymentSecret;
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 (requestContext?.a2aIdentityAssurance === "org-member") {
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
- token = await signA2AToken(email, normalizedOrgDomain, orgSecret, {
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: false,
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
- found?: undefined;
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
- deleted?: undefined;
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
- found?: undefined;
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
- found?: undefined;
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 manifest = peer.agent.description?.trim();
163
- if (manifest)
164
- return truncate(manifest, MAX_DESCRIPTION_CHARS);
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
  }>>;
@@ -1,5 +1,4 @@
1
1
  export declare function getAgentNativeAnalyticsConfigScript(): string | null;
2
- export declare function getHeadScriptTag(): string | null;
3
2
  export declare function getGaInlineConfigScriptBody(options?: {
4
3
  dataLayerName?: string;
5
4
  sendPageView?: boolean;