@agent-native/core 0.207.0-nightly-20261011153008 → 0.207.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 (57) hide show
  1. package/dist/agent/production-agent.js +23 -6
  2. package/dist/agent/thread-data-builder.js +7 -4
  3. package/dist/automation/index.d.ts +1 -1
  4. package/dist/client/analytics/index.d.ts +1 -1
  5. package/dist/client/analytics.d.ts +12 -3
  6. package/dist/client/analytics.js +51 -17
  7. package/dist/client/onboarding/use-onboarding.d.ts +1 -0
  8. package/dist/client/onboarding/use-onboarding.js +19 -6
  9. package/dist/collab/routes.d.ts +1 -1
  10. package/dist/eval/agent-runner.js +18 -8
  11. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  12. package/dist/jobs/actions/manage-recurring-job.d.ts +1 -1
  13. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  14. package/dist/notifications/routes.d.ts +1 -1
  15. package/dist/observability/routes.d.ts +7 -7
  16. package/dist/onboarding/plugin.js +15 -45
  17. package/dist/resources/handlers.d.ts +1 -1
  18. package/dist/resources/store.js +25 -30
  19. package/dist/secrets/routes.d.ts +5 -5
  20. package/dist/server/agent-discovery.js +47 -53
  21. package/dist/server/agent-engine-default-model-route.d.ts +2 -2
  22. package/dist/server/agent-engine-ollama-models-route.d.ts +2 -2
  23. package/dist/server/builtin-agents.d.ts +2 -0
  24. package/dist/server/builtin-agents.js +50 -3
  25. package/dist/server/core-routes-plugin.d.ts +1 -1
  26. package/dist/sharing/actions/list-resource-shares.d.ts +1 -1
  27. package/dist/templates/chat/CHANGELOG.md +6 -0
  28. package/dist/templates/chat/app/components/home/HomePage.tsx +1 -1
  29. package/dist/templates/chat/app/i18n/ar-SA.ts +1 -1
  30. package/dist/templates/chat/app/i18n/de-DE.ts +1 -1
  31. package/dist/templates/chat/app/i18n/en-US.ts +1 -1
  32. package/dist/templates/chat/app/i18n/es-ES.ts +1 -1
  33. package/dist/templates/chat/app/i18n/fr-FR.ts +1 -1
  34. package/dist/templates/chat/app/i18n/hi-IN.ts +1 -1
  35. package/dist/templates/chat/app/i18n/ja-JP.ts +1 -1
  36. package/dist/templates/chat/app/i18n/ko-KR.ts +1 -1
  37. package/dist/templates/chat/app/i18n/pt-BR.ts +1 -1
  38. package/dist/templates/chat/app/i18n/zh-CN.ts +1 -1
  39. package/dist/templates/chat/app/i18n/zh-TW.ts +1 -1
  40. package/dist/triggers/actions/manage-automation.d.ts +7 -7
  41. package/docs/content/environment-variables.mdx +38 -13
  42. package/docs/content/getting-started.mdx +6 -28
  43. package/docs/content/multi-app-workspace.mdx +7 -3
  44. package/package.json +4 -4
  45. package/src/templates/chat/CHANGELOG.md +6 -0
  46. package/src/templates/chat/app/components/home/HomePage.tsx +1 -1
  47. package/src/templates/chat/app/i18n/ar-SA.ts +1 -1
  48. package/src/templates/chat/app/i18n/de-DE.ts +1 -1
  49. package/src/templates/chat/app/i18n/en-US.ts +1 -1
  50. package/src/templates/chat/app/i18n/es-ES.ts +1 -1
  51. package/src/templates/chat/app/i18n/fr-FR.ts +1 -1
  52. package/src/templates/chat/app/i18n/hi-IN.ts +1 -1
  53. package/src/templates/chat/app/i18n/ja-JP.ts +1 -1
  54. package/src/templates/chat/app/i18n/ko-KR.ts +1 -1
  55. package/src/templates/chat/app/i18n/pt-BR.ts +1 -1
  56. package/src/templates/chat/app/i18n/zh-CN.ts +1 -1
  57. package/src/templates/chat/app/i18n/zh-TW.ts +1 -1
@@ -3,7 +3,6 @@ import { getAppConfig } from "../app-config/index.js";
3
3
  import { appStateGet, appStatePut } from "../application-state/store.js";
4
4
  import { getOrgContext } from "../org/context.js";
5
5
  import { readBrowserSessionIdHeader } from "../server/agent-run-context.js";
6
- import { CredentialStoreUnavailableError } from "../server/credential-provider.js";
7
6
  import { awaitBootstrap, getH3App, markDefaultPluginProvided, } from "../server/framework-request-handler.js";
8
7
  import { runWithRequestContext } from "../server/request-context.js";
9
8
  import { FIRST_RUN_ONBOARDING_COMPLETED_KEY, FIRST_RUN_ONBOARDING_COOKIE, FIRST_RUN_ONBOARDING_ELIGIBLE_KEY, } from "../shared/first-run-onboarding.js";
@@ -29,13 +28,8 @@ async function resolveOnboardingContext(event) {
29
28
  };
30
29
  }
31
30
  async function hasOverride(sessionId, stepId) {
32
- try {
33
- const val = await appStateGet(sessionId, `${OVERRIDE_KEY_PREFIX}${stepId}`);
34
- return !!(val && val.complete);
35
- }
36
- catch {
37
- return false;
38
- }
31
+ const val = await appStateGet(sessionId, `${OVERRIDE_KEY_PREFIX}${stepId}`);
32
+ return !!(val && val.complete);
39
33
  }
40
34
  async function serializeSteps(context, options = {}) {
41
35
  const steps = listOnboardingSteps();
@@ -46,12 +40,7 @@ async function serializeSteps(context, options = {}) {
46
40
  }
47
41
  let complete = false;
48
42
  if (!options.preview) {
49
- try {
50
- complete = (await step.isComplete(context)) === true;
51
- }
52
- catch {
53
- complete = false;
54
- }
43
+ complete = (await step.isComplete(context)) === true;
55
44
  if (!complete) {
56
45
  complete = await hasOverride(context.sessionId, step.id);
57
46
  }
@@ -78,19 +67,8 @@ function allRequiredComplete(statuses) {
78
67
  return statuses.filter((s) => s.required).every((s) => s.complete);
79
68
  }
80
69
  async function readDismissedFlag(sessionId) {
81
- // The dismissed flag is optional UX state; a transient DB failure reading it
82
- // must not take down a read whose steps and profile are still usable (the
83
- // pre-summary client already assumed "not dismissed" when this read
84
- // failed). A credential-store outage is not transient, so it still throws.
85
- try {
86
- const value = await appStateGet(sessionId, DISMISSED_KEY);
87
- return !!(value && value.dismissed);
88
- }
89
- catch (error) {
90
- if (error instanceof CredentialStoreUnavailableError)
91
- throw error;
92
- return false;
93
- }
70
+ const value = await appStateGet(sessionId, DISMISSED_KEY);
71
+ return !!(value && value.dismissed);
94
72
  }
95
73
  async function resolveSharedCompletionEnabled() {
96
74
  if (!getAppConfig().onboarding.sharedCompletion.enabled)
@@ -164,24 +142,16 @@ export function createOnboardingPlugin(options = {}) {
164
142
  return { error: "Method not allowed" };
165
143
  }
166
144
  const context = await resolveOnboardingContext(event);
167
- try {
168
- return await withOnboardingRequestContext(context, async () => {
169
- const [value, statuses] = await Promise.all([
170
- appStateGet(context.sessionId, DISMISSED_KEY),
171
- serializeSteps(context),
172
- ]);
173
- const dismissed = !!(value && value.dismissed);
174
- return {
175
- dismissed,
176
- allComplete: allRequiredComplete(statuses),
177
- };
178
- });
179
- }
180
- catch (error) {
181
- if (error instanceof CredentialStoreUnavailableError)
182
- throw error;
183
- return { dismissed: false, allComplete: false };
184
- }
145
+ return withOnboardingRequestContext(context, async () => {
146
+ const [statuses, value] = await Promise.all([
147
+ serializeSteps(context),
148
+ appStateGet(context.sessionId, DISMISSED_KEY),
149
+ ]);
150
+ return {
151
+ dismissed: !!(value && value.dismissed),
152
+ allComplete: allRequiredComplete(statuses),
153
+ };
154
+ });
185
155
  }));
186
156
  getH3App(nitroApp).use(`${ONBOARDING_PREFIX}/profile`, defineEventHandler(async (event) => {
187
157
  if (getMethod(event) !== "GET") {
@@ -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;
@@ -982,36 +982,31 @@ async function _doEnsureTable() {
982
982
  now,
983
983
  ],
984
984
  });
985
- try {
986
- const { getBuiltinAgentsForSeeding } = await import("../server/agent-discovery.js");
987
- const builtins = getBuiltinAgentsForSeeding();
988
- for (const agent of builtins) {
989
- const agentJson = JSON.stringify({
990
- id: agent.id,
991
- name: agent.name,
992
- description: agent.description,
993
- url: agent.url, // always prod
994
- color: agent.color,
995
- }, null, 2);
996
- assertResourcePayloadIsSqlSafe(agentJson, "application/json");
997
- const agentSize = Buffer.byteLength(agentJson, "utf8");
998
- await client.execute({
999
- sql: seedSql,
1000
- args: [
1001
- crypto.randomUUID(),
1002
- `remote-agents/${agent.id}.json`,
1003
- SHARED_OWNER,
1004
- agentJson,
1005
- "application/json",
1006
- agentSize,
1007
- now,
1008
- now,
1009
- ],
1010
- });
1011
- }
1012
- }
1013
- catch {
1014
- // Agent discovery not available — skip seeding
985
+ const { getBuiltinAgentsForSeeding } = await import("../server/agent-discovery.js");
986
+ const builtins = getBuiltinAgentsForSeeding();
987
+ for (const agent of builtins) {
988
+ const agentJson = JSON.stringify({
989
+ id: agent.id,
990
+ name: agent.name,
991
+ description: agent.description,
992
+ url: agent.url, // always prod
993
+ color: agent.color,
994
+ }, null, 2);
995
+ assertResourcePayloadIsSqlSafe(agentJson, "application/json");
996
+ const agentSize = Buffer.byteLength(agentJson, "utf8");
997
+ await client.execute({
998
+ sql: seedSql,
999
+ args: [
1000
+ crypto.randomUUID(),
1001
+ `remote-agents/${agent.id}.json`,
1002
+ SHARED_OWNER,
1003
+ agentJson,
1004
+ "application/json",
1005
+ agentSize,
1006
+ now,
1007
+ now,
1008
+ ],
1009
+ });
1015
1010
  }
1016
1011
  try {
1017
1012
  const legacy = await client.execute({
@@ -58,20 +58,20 @@ export declare function createWriteSecretHandler(): import("h3").EventHandlerWit
58
58
  error: string;
59
59
  errorCode?: undefined;
60
60
  retryable?: undefined;
61
- status?: undefined;
62
61
  ok?: undefined;
62
+ status?: undefined;
63
63
  } | {
64
64
  error: string;
65
65
  errorCode: string;
66
66
  retryable?: undefined;
67
- status?: undefined;
68
67
  ok?: undefined;
68
+ status?: undefined;
69
69
  } | {
70
70
  error: string;
71
71
  errorCode: string;
72
72
  retryable: boolean;
73
- status?: undefined;
74
73
  ok?: undefined;
74
+ status?: undefined;
75
75
  } | {
76
76
  errorCode?: undefined;
77
77
  retryable?: undefined;
@@ -79,18 +79,18 @@ export declare function createWriteSecretHandler(): import("h3").EventHandlerWit
79
79
  status: string;
80
80
  error?: undefined;
81
81
  } | {
82
+ ok?: undefined;
82
83
  error: string;
83
84
  removed?: undefined;
84
- ok?: undefined;
85
85
  } | {
86
86
  ok: boolean;
87
87
  removed: boolean;
88
88
  error?: undefined;
89
89
  }>>;
90
90
  export declare function createTestSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
91
+ ok?: undefined;
91
92
  error: string;
92
93
  note?: undefined;
93
- ok?: undefined;
94
94
  } | {
95
95
  ok: boolean;
96
96
  note?: undefined;
@@ -6,7 +6,7 @@ import { HIDDEN_FIRST_PARTY_AGENT_IDS, isBuiltinAgentCatalogId, normalizeAgentId
6
6
  import { DEFAULT_WORKSPACE_APP_AUDIENCE, normalizeWorkspaceAppAudience, normalizeWorkspaceAppHomePath, normalizeWorkspaceAppPathList, workspaceAppAudienceFromPackageJson, workspaceAppRouteAccessFromPackageJson, } from "../shared/workspace-app-audience.js";
7
7
  import { inferWorkspaceAppRootHomePath, readConfiguredWorkspaceAppHomePath, } from "../workspace-app-config.js";
8
8
  import { resolveAppRuntimeUrl } from "./app-url.js";
9
- import { readBuiltinAgentsConfig } from "./builtin-agents.js";
9
+ import { readBuiltinAgentsConfig, } from "./builtin-agents.js";
10
10
  import { getRequestContext, getRequestOrgId, getRequestUserEmail, } from "./request-context.js";
11
11
  import { findWorkspaceRoot, readJson } from "./workspace-root.js";
12
12
  export { isBuiltinAgentCatalogId, normalizeAgentId };
@@ -199,23 +199,57 @@ export function shouldIncludeRemoteAgentManifest(manifest, selfAppId) {
199
199
  }
200
200
  return !HIDDEN_FIRST_PARTY_AGENT_IDS.has(normalizedId);
201
201
  }
202
- function builtinAgentsFor(ids, selfAppId, options) {
202
+ function builtinAgentsFor(config, selfAppId, options) {
203
203
  const normalizedSelfAppId = selfAppId ? normalizeAgentId(selfAppId) : "";
204
- return BUILTIN_AGENT_CATALOG.filter((app) => ids.includes(app.id) && app.id !== normalizedSelfAppId && app.url).map((app) => ({
204
+ const useLocalUrls = options?.preferLocalUrls === true || shouldUseLocalAgentUrls();
205
+ return BUILTIN_AGENT_CATALOG.filter((app) => config.include.includes(app.id) &&
206
+ app.id !== normalizedSelfAppId &&
207
+ app.url).map((app) => ({
205
208
  id: app.id,
206
209
  name: app.name,
207
210
  description: app.description,
208
- url: resolveAgentUrl(app, options?.preferLocalUrls),
211
+ url: !useLocalUrls && config.urls?.[app.id]
212
+ ? config.urls[app.id]
213
+ : resolveAgentUrl(app, options?.preferLocalUrls),
209
214
  color: app.color,
210
215
  }));
211
216
  }
212
217
  /** Built-ins the workspace builder offers (`agent-native.builtinAgents`). */
213
218
  export function getBuiltinAgents(selfAppId, options) {
214
- return builtinAgentsFor(readBuiltinAgentsConfig().include, selfAppId, options);
219
+ return builtinAgentsFor(readBuiltinAgentsConfig(), selfAppId, options);
215
220
  }
216
221
  function isUnofferedBuiltinManifest(manifestId, offeredBuiltinIds) {
217
222
  return (isBuiltinAgentCatalogId(manifestId) && !offeredBuiltinIds.has(manifestId));
218
223
  }
224
+ function resolveRemoteAgentManifestUrl(manifestId, rawManifestId, manifestUrl, builtin, options) {
225
+ const catalogBuiltin = BUILTIN_AGENT_CATALOG.find((candidate) => candidate.id === manifestId);
226
+ const hosted = isHostedRuntime();
227
+ let url = manifestUrl;
228
+ if (hosted && isLoopbackUrl(url)) {
229
+ if (builtin?.url)
230
+ url = builtin.url;
231
+ else
232
+ return undefined;
233
+ }
234
+ if (catalogBuiltin && builtin && manifestUrl === catalogBuiltin.url) {
235
+ url = builtin.url;
236
+ }
237
+ if (options?.preferLocalUrls && builtin && catalogBuiltin) {
238
+ url = builtin.url;
239
+ }
240
+ const isLegacyAssetsManifest = rawManifestId.trim().toLowerCase() !== manifestId;
241
+ if (isLegacyAssetsManifest && builtin?.url) {
242
+ try {
243
+ if (new URL(url).hostname === "images.agent-native.com") {
244
+ url = builtin.url;
245
+ }
246
+ }
247
+ catch {
248
+ url = builtin.url;
249
+ }
250
+ }
251
+ return { url, isLegacyAssetsManifest };
252
+ }
219
253
  export async function discoverAgents(selfAppId, options) {
220
254
  const builtins = getBuiltinAgents(selfAppId, options);
221
255
  const offeredBuiltinIds = new Set(builtins.map((agent) => agent.id));
@@ -281,32 +315,11 @@ export async function discoverAgents(selfAppId, options) {
281
315
  const manifestId = normalizeAgentId(manifest.id);
282
316
  if (isUnofferedBuiltinManifest(manifestId, offeredBuiltinIds))
283
317
  continue;
284
- let url = manifest.url;
285
- const isHosted = isHostedRuntime();
286
- if (isHosted && typeof url === "string" && isLoopbackUrl(url)) {
287
- const builtin = agentsById.get(manifestId);
288
- if (builtin?.url)
289
- url = builtin.url;
290
- else
291
- continue;
292
- }
293
318
  const builtin = agentsById.get(manifestId);
294
- if (options?.preferLocalUrls && builtin) {
295
- const isBuiltinAgent = BUILTIN_AGENT_CATALOG.some((candidate) => candidate.id === manifestId);
296
- if (isBuiltinAgent)
297
- url = builtin.url;
298
- }
299
- const isLegacyAssetsManifest = manifest.id.trim().toLowerCase() !== manifestId;
300
- if (isLegacyAssetsManifest && builtin?.url) {
301
- try {
302
- if (new URL(url).hostname === "images.agent-native.com") {
303
- url = builtin.url;
304
- }
305
- }
306
- catch {
307
- url = builtin.url;
308
- }
309
- }
319
+ const resolved = resolveRemoteAgentManifestUrl(manifestId, manifest.id, manifest.url, builtin, options);
320
+ if (!resolved)
321
+ continue;
322
+ const { url, isLegacyAssetsManifest } = resolved;
310
323
  agentsById.set(manifestId, {
311
324
  id: manifestId,
312
325
  name: isLegacyAssetsManifest && builtin?.name
@@ -414,30 +427,11 @@ async function overlayRemoteAgentResources(agentsById, offeredBuiltinIds, resour
414
427
  const manifestId = normalizeAgentId(manifest.id);
415
428
  if (isUnofferedBuiltinManifest(manifestId, offeredBuiltinIds))
416
429
  continue;
417
- let url = manifest.url;
418
430
  const builtin = agentsById.get(manifestId);
419
- if (isHostedRuntime() && isLoopbackUrl(url)) {
420
- if (builtin?.url)
421
- url = builtin.url;
422
- else
423
- continue;
424
- }
425
- if (options?.preferLocalUrls &&
426
- builtin &&
427
- BUILTIN_AGENT_CATALOG.some((candidate) => candidate.id === manifestId)) {
428
- url = builtin.url;
429
- }
430
- const isLegacyAssetsManifest = manifest.id.trim().toLowerCase() !== manifestId;
431
- if (isLegacyAssetsManifest && builtin?.url) {
432
- try {
433
- if (new URL(url).hostname === "images.agent-native.com") {
434
- url = builtin.url;
435
- }
436
- }
437
- catch {
438
- url = builtin.url;
439
- }
440
- }
431
+ const resolved = resolveRemoteAgentManifestUrl(manifestId, manifest.id, manifest.url, builtin, options);
432
+ if (!resolved)
433
+ continue;
434
+ const { url, isLegacyAssetsManifest } = resolved;
441
435
  agentsById.set(manifestId, {
442
436
  id: manifestId,
443
437
  name: isLegacyAssetsManifest && builtin?.name ? builtin.name : manifest.name,
@@ -8,17 +8,17 @@ 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
- ok?: undefined;
12
11
  error: string;
13
12
  scope?: undefined;
13
+ ok?: undefined;
14
14
  } | {
15
15
  ok: boolean;
16
16
  error: any;
17
17
  scope?: undefined;
18
18
  } | {
19
- error?: undefined;
20
19
  ok: boolean;
21
20
  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
- models?: undefined;
4
3
  ok?: undefined;
4
+ models?: undefined;
5
5
  } | {
6
+ error?: undefined;
6
7
  ok: boolean;
7
8
  models: string[];
8
- error?: undefined;
9
9
  }>>;
@@ -3,6 +3,8 @@ export interface BuiltinAgentsConfig {
3
3
  mode: BuiltinAgentsMode;
4
4
  /** Built-ins this workspace offers. Anything else is unknown to it. */
5
5
  include: string[];
6
+ /** Hosted URL overrides, applied only when a built-in is offered. */
7
+ urls?: Record<string, string>;
6
8
  }
7
9
  export declare const BUILTIN_AGENTS_ENV_KEY = "AGENT_NATIVE_BUILTIN_AGENTS_JSON";
8
10
  export declare function frameworkDefaultBuiltinAgentsConfig(): BuiltinAgentsConfig;
@@ -32,6 +32,48 @@ function parseIdList(value, field, warnings) {
32
32
  }
33
33
  return ids;
34
34
  }
35
+ function parseBuiltinAgentUrls(value) {
36
+ if (value === undefined)
37
+ return undefined;
38
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
39
+ throw new Error("builtinAgents.urls must be an object mapping built-in ids to URLs");
40
+ }
41
+ const urls = {};
42
+ const seenIds = new Set();
43
+ for (const [rawId, rawUrl] of Object.entries(value)) {
44
+ const id = normalizeAgentId(rawId);
45
+ if (!BUILTIN_AGENT_CATALOG_IDS.includes(id)) {
46
+ throw new Error("builtinAgents.urls contains an unknown built-in agent id");
47
+ }
48
+ if (seenIds.has(id)) {
49
+ throw new Error("builtinAgents.urls contains duplicate built-in agent ids");
50
+ }
51
+ seenIds.add(id);
52
+ if (typeof rawUrl !== "string" || rawUrl.trim() !== rawUrl) {
53
+ throw new Error("builtinAgents.urls values must be absolute HTTPS URLs without credentials, query, or fragment");
54
+ }
55
+ let url;
56
+ try {
57
+ url = new URL(rawUrl);
58
+ }
59
+ catch {
60
+ throw new Error("builtinAgents.urls values must be absolute HTTPS URLs without credentials, query, or fragment");
61
+ }
62
+ if (/[\s\p{Cc}]/u.test(rawUrl) ||
63
+ !/^https:\/\//i.test(rawUrl) ||
64
+ url.protocol !== "https:" ||
65
+ !url.hostname ||
66
+ url.username ||
67
+ url.password ||
68
+ url.search ||
69
+ url.hash ||
70
+ /[?#]/.test(rawUrl)) {
71
+ throw new Error("builtinAgents.urls values must be absolute HTTPS URLs without credentials, query, or fragment");
72
+ }
73
+ urls[id] = rawUrl;
74
+ }
75
+ return urls;
76
+ }
35
77
  export function parseBuiltinAgentsConfig(raw) {
36
78
  const warnings = [];
37
79
  if (raw === undefined || raw === null) {
@@ -42,13 +84,18 @@ export function parseBuiltinAgentsConfig(raw) {
42
84
  return { config: frameworkDefaultBuiltinAgentsConfig(), warnings };
43
85
  }
44
86
  const record = raw;
87
+ const urls = parseBuiltinAgentUrls(record.urls);
88
+ const urlsConfig = urls === undefined ? {} : { urls };
45
89
  const mode = record.mode ?? "all";
46
90
  if (mode !== "all" && mode !== "none" && mode !== "selected") {
47
91
  warnings.push(`builtinAgents.mode must be "all", "none", or "selected"; using the default`);
48
- return { config: frameworkDefaultBuiltinAgentsConfig(), warnings };
92
+ return {
93
+ config: { ...frameworkDefaultBuiltinAgentsConfig(), ...urlsConfig },
94
+ warnings,
95
+ };
49
96
  }
50
97
  if (mode === "none") {
51
- return { config: { mode, include: [] }, warnings };
98
+ return { config: { mode, include: [], ...urlsConfig }, warnings };
52
99
  }
53
100
  let include;
54
101
  if (mode === "all") {
@@ -64,7 +111,7 @@ export function parseBuiltinAgentsConfig(raw) {
64
111
  include =
65
112
  parseIdList(record.include, "builtinAgents.include", warnings) ?? [];
66
113
  }
67
- return { config: { mode, include }, warnings };
114
+ return { config: { mode, include, ...urlsConfig }, warnings };
68
115
  }
69
116
  function readRawBuiltinAgentsConfig() {
70
117
  const envJson = getAppConfig().workspace.builtinAgentsJson;
@@ -584,8 +584,8 @@ export declare function createPublicRemoteAgentsHandler(discover?: PublicAgentDi
584
584
  error: string;
585
585
  agents?: undefined;
586
586
  } | {
587
- agents: Omit<import("./agent-discovery.js").DiscoveredAgent, "auth" | "kind">[];
588
587
  error?: undefined;
588
+ agents: Omit<import("./agent-discovery.js").DiscoveredAgent, "auth" | "kind">[];
589
589
  }>>;
590
590
  export declare function getBuilderConnectErrorDisposition(error: unknown, connectAttemptId: string | null): "correlated" | "legacy" | null;
591
591
  export declare function getBuilderConnectErrorKey(ownerEmail: string, connectAttemptId?: string | null): string;
@@ -2,6 +2,7 @@ declare const _default: import("../../action.js").ActionDefinition<{
2
2
  resourceType: string;
3
3
  resourceId: string;
4
4
  }, {
5
+ role?: undefined;
5
6
  ownerEmail: any;
6
7
  visibility: any;
7
8
  shares: any[];
@@ -11,7 +12,6 @@ declare const _default: import("../../action.js").ActionDefinition<{
11
12
  supportsGroupShares?: boolean;
12
13
  };
13
14
  orgId?: undefined;
14
- role?: undefined;
15
15
  agentReadable?: undefined;
16
16
  } | {
17
17
  ownerEmail: string;
@@ -2,6 +2,12 @@
2
2
 
3
3
  All notable user-facing changes to this app are documented here.
4
4
 
5
+ ## 2026-10-10
6
+
7
+ ### Fixed
8
+
9
+ - Large prompts with full context remain available to retry when sending fails.
10
+
5
11
  ## 2026-09-30
6
12
 
7
13
  ### Improved
@@ -284,7 +284,7 @@ export default function HomePage() {
284
284
  </p>
285
285
  <Button asChild variant="link" size="sm" className="h-auto px-0">
286
286
  <a
287
- href={`${DOCS_URL}/getting-started#connect-an-llm`}
287
+ href={`${DOCS_URL}/environment-variables#llm-provider-keys`}
288
288
  target="_blank"
289
289
  rel="noreferrer"
290
290
  >
@@ -61,7 +61,7 @@ const messages = {
61
61
  editHint: "عدّل {{file}} واحفظه، ثم اسأل مجددًا لترى التحية الجديدة.",
62
62
  lead: "تتشارك واجهة تطبيقك ووكيله الإجراءات نفسها.",
63
63
  leadTry: "اطلب من الوكيل استدعاء الإجراء hello.",
64
- llmSetupLink: "إعداد مفتاح LLM للتطبيق بالكامل",
64
+ llmSetupLink: "إعداد موفّر LLM",
65
65
  title: "ابدأ الآن",
66
66
  },
67
67
  navigation: {
@@ -64,7 +64,7 @@ const messages = {
64
64
  "Bearbeite {{file}}, speichere und frag erneut, um die neue Begrüßung zu sehen.",
65
65
  lead: "Die Oberfläche deiner App und ihr Agent nutzen dieselben Aktionen.",
66
66
  leadTry: "Bitte den Agenten, die Aktion hello aufzurufen.",
67
- llmSetupLink: "App-weiten LLM-Schlüssel einrichten",
67
+ llmSetupLink: "LLM-Anbieter einrichten",
68
68
  title: "Loslegen",
69
69
  },
70
70
  navigation: {
@@ -62,7 +62,7 @@ const messages = {
62
62
  editHint: "Edit {{file}} and save, then ask again to see the new greeting.",
63
63
  lead: "Your app's UI and its agent share one set of actions.",
64
64
  leadTry: "Ask the agent to call the hello action.",
65
- llmSetupLink: "Set up an app-wide LLM key",
65
+ llmSetupLink: "LLM provider setup",
66
66
  title: "Get started",
67
67
  },
68
68
  navigation: {
@@ -64,7 +64,7 @@ const messages = {
64
64
  "Edita {{file}}, guarda y vuelve a preguntar para ver el nuevo saludo.",
65
65
  lead: "La interfaz de tu app y su agente comparten las mismas acciones.",
66
66
  leadTry: "Pide al agente que llame a la acción hello.",
67
- llmSetupLink: "Configurar una clave de LLM para toda la app",
67
+ llmSetupLink: "Configuración del proveedor LLM",
68
68
  title: "Empieza aquí",
69
69
  },
70
70
  navigation: {
@@ -64,7 +64,7 @@ const messages = {
64
64
  "Modifiez {{file}}, enregistrez, puis redemandez pour voir le nouveau message.",
65
65
  lead: "L’interface de votre app et son agent partagent les mêmes actions.",
66
66
  leadTry: "Demandez à l’agent d’appeler l’action hello.",
67
- llmSetupLink: "Configurer une clé LLM pour toute l’app",
67
+ llmSetupLink: "Configuration du fournisseur LLM",
68
68
  title: "Commencer",
69
69
  },
70
70
  navigation: {
@@ -63,7 +63,7 @@ const messages = {
63
63
  "{{file}} में बदलाव करके सेव करें, फिर नया अभिवादन देखने के लिए दोबारा पूछें।",
64
64
  lead: "आपके ऐप का UI और उसका एजेंट एक ही क्रियाएं साझा करते हैं।",
65
65
  leadTry: "एजेंट से hello क्रिया कॉल करने को कहें।",
66
- llmSetupLink: "पूरे ऐप के लिए LLM कुंजी सेट करें",
66
+ llmSetupLink: "LLM प्रदाता सेटअप",
67
67
  title: "शुरू करें",
68
68
  },
69
69
  navigation: {
@@ -63,7 +63,7 @@ const messages = {
63
63
  "{{file}} を編集して保存し、もう一度頼むと新しいあいさつが表示されます。",
64
64
  lead: "アプリの UI とエージェントは同じアクションを共有しています。",
65
65
  leadTry: "エージェントに hello アクションを呼び出してもらいましょう。",
66
- llmSetupLink: "アプリ全体で使う LLM キーを設定",
66
+ llmSetupLink: "LLM プロバイダーの設定",
67
67
  title: "はじめに",
68
68
  },
69
69
  navigation: {
@@ -64,7 +64,7 @@ const messages = {
64
64
  "{{file}} 파일을 수정하고 저장한 다음 다시 요청하면 새 인사말이 보입니다.",
65
65
  lead: "앱의 UI와 에이전트는 같은 작업을 공유합니다.",
66
66
  leadTry: "에이전트에게 hello 작업을 호출해 달라고 요청해 보세요.",
67
- llmSetupLink: "앱 전체에서 사용할 LLM 키 설정",
67
+ llmSetupLink: "LLM 제공자 설정",
68
68
  title: "시작하기",
69
69
  },
70
70
  navigation: {
@@ -64,7 +64,7 @@ const messages = {
64
64
  "Edite {{file}}, salve e pergunte de novo para ver a nova saudação.",
65
65
  lead: "A interface do seu app e o agente dele compartilham as mesmas ações.",
66
66
  leadTry: "Peça ao agente para chamar a ação hello.",
67
- llmSetupLink: "Configurar uma chave de LLM para todo o app",
67
+ llmSetupLink: "Configuração do provedor LLM",
68
68
  title: "Comece aqui",
69
69
  },
70
70
  navigation: {
@@ -59,7 +59,7 @@ const messages = {
59
59
  editHint: "编辑 {{file}} 并保存,再问一次就能看到新的问候语。",
60
60
  lead: "应用的界面和代理共用同一组操作。",
61
61
  leadTry: "让代理调用 hello 操作试试。",
62
- llmSetupLink: "设置应用级 LLM 密钥",
62
+ llmSetupLink: "LLM 提供商设置",
63
63
  title: "开始使用",
64
64
  },
65
65
  navigation: {
@@ -59,7 +59,7 @@ const messages = {
59
59
  editHint: "編輯 {{file}} 並儲存,再問一次就能看到新的問候語。",
60
60
  lead: "應用程式的介面和代理共用同一組操作。",
61
61
  leadTry: "讓代理呼叫 hello 操作試試。",
62
- llmSetupLink: "設定應用程式共用的 LLM 金鑰",
62
+ llmSetupLink: "LLM 提供者設定",
63
63
  title: "開始使用",
64
64
  },
65
65
  navigation: {