@agent-native/core 0.109.0 → 0.109.1

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 (125) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +7 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/a2a/client.ts +24 -2
  5. package/corpus/core/src/a2a/correlation.ts +50 -0
  6. package/corpus/core/src/a2a/handlers.ts +140 -14
  7. package/corpus/core/src/a2a/index.ts +1 -0
  8. package/corpus/core/src/a2a/invoke.ts +10 -1
  9. package/corpus/core/src/a2a/task-store.ts +146 -6
  10. package/corpus/core/src/a2a/types.ts +16 -0
  11. package/corpus/core/src/action.ts +2 -0
  12. package/corpus/core/src/agent/production-agent.ts +23 -0
  13. package/corpus/core/src/client/use-run-stuck-detection.ts +27 -1
  14. package/corpus/core/src/db/client.ts +55 -0
  15. package/corpus/core/src/observability/traces.ts +172 -19
  16. package/corpus/core/src/scripts/call-agent.ts +53 -2
  17. package/corpus/core/src/server/agent-chat/action-filters-a2a.ts +72 -25
  18. package/corpus/core/src/server/agent-chat-plugin.ts +107 -6
  19. package/corpus/core/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +21 -0
  20. package/corpus/core/src/templates/workspace-core/.agents/skills/observability/SKILL.md +7 -1
  21. package/corpus/core/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -1
  22. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +1 -1
  23. package/corpus/templates/analytics/changelog/2026-07-17-analytics-now-includes-a-default-alert-for-spikes-in-stuck-agent-chats.md +6 -0
  24. package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +23 -14
  25. package/corpus/templates/analytics/docs/schemas/tracked-events.md +5 -1
  26. package/corpus/templates/analytics/server/jobs/analytics-alerts.ts +3 -3
  27. package/corpus/templates/analytics/server/lib/analytics-alerts.ts +209 -87
  28. package/corpus/templates/clips/actions/finalize-recording.ts +541 -62
  29. package/corpus/templates/clips/app/components/player/playback-comment-overlay.tsx +17 -2
  30. package/corpus/templates/clips/app/components/player/video-player.tsx +14 -2
  31. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +2 -2
  32. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +1 -1
  33. package/corpus/templates/clips/app/routes/record.tsx +3 -3
  34. package/corpus/templates/clips/app/routes/share.$shareId.tsx +6 -3
  35. package/corpus/templates/clips/changelog/2026-07-17-clips-now-retries-storage-verification-in-the-background-ins.md +6 -0
  36. package/corpus/templates/clips/changelog/2026-07-17-fixed-broken-thumbnail-icons-appearing-over-playable-clip-em.md +6 -0
  37. package/corpus/templates/clips/changelog/2026-07-17-playback-comments-stay-readable-at-faster-playback-speeds.md +6 -0
  38. package/corpus/templates/clips/chrome-extension/src/finalize-recovery.ts +3 -0
  39. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +3 -3
  40. package/corpus/templates/clips/desktop/src/app.tsx +18 -6
  41. package/corpus/templates/clips/desktop/src/lib/recorder.ts +111 -13
  42. package/corpus/templates/clips/desktop/src/lib/upload-verification.ts +16 -7
  43. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +2 -4
  44. package/corpus/templates/clips/desktop/src-tauri/src/native_screen/live_upload.rs +32 -15
  45. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +45 -18
  46. package/corpus/templates/clips/server/jobs/media-verification.ts +130 -0
  47. package/corpus/templates/clips/server/lib/builder-media-compression.ts +15 -0
  48. package/corpus/templates/clips/server/lib/media-verification-state.ts +38 -0
  49. package/corpus/templates/clips/server/lib/player-thumbnail-url.ts +31 -0
  50. package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +10 -3
  51. package/corpus/templates/clips/server/plugins/auth.ts +5 -5
  52. package/corpus/templates/clips/server/plugins/calendar-jobs.ts +2 -0
  53. package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +12 -2
  54. package/corpus/templates/clips/server/routes/api/public-recording.get.ts +6 -1
  55. package/corpus/templates/clips/server/routes/api/thumbnail/[recordingId].get.ts +340 -0
  56. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +24 -7
  57. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +91 -7
  58. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/status.get.ts +14 -0
  59. package/corpus/templates/clips/shared/finalize-recovery.ts +61 -2
  60. package/corpus/templates/clips/shared/share-meta.ts +1 -1
  61. package/dist/a2a/client.d.ts +11 -2
  62. package/dist/a2a/client.d.ts.map +1 -1
  63. package/dist/a2a/client.js +16 -3
  64. package/dist/a2a/client.js.map +1 -1
  65. package/dist/a2a/correlation.d.ts +10 -0
  66. package/dist/a2a/correlation.d.ts.map +1 -0
  67. package/dist/a2a/correlation.js +40 -0
  68. package/dist/a2a/correlation.js.map +1 -0
  69. package/dist/a2a/handlers.d.ts.map +1 -1
  70. package/dist/a2a/handlers.js +100 -15
  71. package/dist/a2a/handlers.js.map +1 -1
  72. package/dist/a2a/index.d.ts +1 -1
  73. package/dist/a2a/index.d.ts.map +1 -1
  74. package/dist/a2a/index.js.map +1 -1
  75. package/dist/a2a/invoke.d.ts +4 -1
  76. package/dist/a2a/invoke.d.ts.map +1 -1
  77. package/dist/a2a/invoke.js +3 -0
  78. package/dist/a2a/invoke.js.map +1 -1
  79. package/dist/a2a/task-store.d.ts +12 -1
  80. package/dist/a2a/task-store.d.ts.map +1 -1
  81. package/dist/a2a/task-store.js +96 -6
  82. package/dist/a2a/task-store.js.map +1 -1
  83. package/dist/a2a/types.d.ts +15 -0
  84. package/dist/a2a/types.d.ts.map +1 -1
  85. package/dist/a2a/types.js.map +1 -1
  86. package/dist/action.d.ts +2 -0
  87. package/dist/action.d.ts.map +1 -1
  88. package/dist/action.js.map +1 -1
  89. package/dist/agent/production-agent.d.ts +9 -0
  90. package/dist/agent/production-agent.d.ts.map +1 -1
  91. package/dist/agent/production-agent.js +14 -0
  92. package/dist/agent/production-agent.js.map +1 -1
  93. package/dist/client/use-run-stuck-detection.d.ts.map +1 -1
  94. package/dist/client/use-run-stuck-detection.js +25 -1
  95. package/dist/client/use-run-stuck-detection.js.map +1 -1
  96. package/dist/collab/routes.d.ts +1 -1
  97. package/dist/collab/struct-routes.d.ts +1 -1
  98. package/dist/db/client.d.ts +7 -0
  99. package/dist/db/client.d.ts.map +1 -1
  100. package/dist/db/client.js +33 -0
  101. package/dist/db/client.js.map +1 -1
  102. package/dist/observability/routes.d.ts +5 -5
  103. package/dist/observability/traces.d.ts +9 -0
  104. package/dist/observability/traces.d.ts.map +1 -1
  105. package/dist/observability/traces.js +137 -19
  106. package/dist/observability/traces.js.map +1 -1
  107. package/dist/resources/handlers.d.ts +2 -2
  108. package/dist/scripts/call-agent.d.ts.map +1 -1
  109. package/dist/scripts/call-agent.js +35 -3
  110. package/dist/scripts/call-agent.js.map +1 -1
  111. package/dist/secrets/routes.d.ts +9 -9
  112. package/dist/server/agent-chat/action-filters-a2a.d.ts +18 -2
  113. package/dist/server/agent-chat/action-filters-a2a.d.ts.map +1 -1
  114. package/dist/server/agent-chat/action-filters-a2a.js +35 -7
  115. package/dist/server/agent-chat/action-filters-a2a.js.map +1 -1
  116. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  117. package/dist/server/agent-chat-plugin.js +93 -6
  118. package/dist/server/agent-chat-plugin.js.map +1 -1
  119. package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +21 -0
  120. package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +7 -1
  121. package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -1
  122. package/package.json +1 -1
  123. package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +21 -0
  124. package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +7 -1
  125. package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -1
@@ -3,6 +3,7 @@ import nodePath from "node:path";
3
3
  import { createError, defineEventHandler, setResponseStatus, setResponseHeader, getMethod, getQuery, getHeader, getRequestIP, } from "h3";
4
4
  import { appendA2AArtifactLinks, buildA2ARecoverableArtifactMessage, } from "../a2a/artifact-response.js";
5
5
  import { hasConfiguredA2ASecret, isLoopbackAddress, isTrustedLocalRuntime, } from "../a2a/auth-policy.js";
6
+ import { sanitizeA2ACorrelationId, sanitizeA2ACorrelationMetadata, } from "../a2a/correlation.js";
6
7
  import { applyAgentTextEventToBuffer } from "../a2a/response-text.js";
7
8
  import { createA2AApproval, updateTaskStatusMessage, } from "../a2a/task-store.js";
8
9
  import { canUpdateAgentAppModelDefaultSettings, normalizeAgentAppModelDefaultAppId, readAgentAppModelDefaultSettings, resetAgentAppModelDefaultSettings, writeAgentAppModelDefaultSettings, } from "../agent/app-model-defaults.js";
@@ -18,6 +19,7 @@ import { attachToolSearch } from "../agent/tool-search.js";
18
19
  import { readAppStateForCurrentTab } from "../application-state/script-helpers.js";
19
20
  import { createThread, forkThread, getThread, registerChatThreadsShareable, resolveThreadAccess, listThreads, searchThreads, renameThread, createThreadShareLink, getThreadByShareToken, getThreadShareState, revokeThreadShareLink, setThreadArchived, setThreadPinned, setThreadScope, updateThreadData, withThreadDataLock, deleteThread, setThreadQueuedMessages, } from "../chat-threads/store.js";
20
21
  import { createDbAdminAgentTools } from "../db-admin/agent-tools.js";
22
+ import { isTransientDatabaseError } from "../db/client.js";
21
23
  import { verifyInternalToken, extractBearerToken, } from "../integrations/internal-token.js";
22
24
  import { McpClientManager, loadMcpConfig, autoDetectMcpConfig, mcpToolsToActionEntries, syncMcpActionEntries, mountMcpServersRoutes, mountMcpHubRoutes, buildMergedConfig, startMcpConfigRefresh, getHubStatus, isHubServeEnabled, } from "../mcp-client/index.js";
23
25
  import { setProgressPreListHook } from "../progress/store.js";
@@ -38,6 +40,47 @@ import { getModelFamilyOverlay } from "./prompts/index.js";
38
40
  import { mountRealtimeVoiceRoutes } from "./realtime-voice.js";
39
41
  import { runWithRequestContext, getRequestContext, getRequestOrgId, getRequestUserEmail, getRequestRunContext, ensureRequestRunContext, } from "./request-context.js";
40
42
  export { handleSharedThreadRequest };
43
+ function withTransientDatabaseFallback(route, handler) {
44
+ return defineEventHandler(async (event) => {
45
+ try {
46
+ return await handler(event);
47
+ }
48
+ catch (error) {
49
+ if (!isTransientDatabaseError(error))
50
+ throw error;
51
+ const method = getMethod(event);
52
+ const retrySafe = method === "GET" || method === "HEAD";
53
+ const databaseError = error;
54
+ captureError(new Error("Transient database failure in agent chat"), {
55
+ route,
56
+ method,
57
+ tags: {
58
+ source: "agent-chat",
59
+ failureClass: "transient-database",
60
+ },
61
+ extra: {
62
+ databaseErrorName: error instanceof Error ? error.name : typeof error,
63
+ databaseErrorCode: typeof databaseError.code === "string"
64
+ ? databaseError.code
65
+ : undefined,
66
+ databaseCauseCode: typeof databaseError.cause?.code === "string"
67
+ ? databaseError.cause.code
68
+ : undefined,
69
+ },
70
+ });
71
+ setResponseStatus(event, 503);
72
+ if (retrySafe)
73
+ setResponseHeader(event, "Retry-After", "2");
74
+ return {
75
+ error: retrySafe
76
+ ? "The database is temporarily unavailable. Please retry."
77
+ : "The database became unavailable while processing this request. Refresh before deciding whether to retry.",
78
+ code: "database_unavailable",
79
+ retryable: retrySafe,
80
+ };
81
+ }
82
+ });
83
+ }
41
84
  // Lazy fs — loaded via dynamic import() on first use.
42
85
  // This avoids require() which bundlers convert to createRequire(import.meta.url)
43
86
  // that crashes on CF Workers where import.meta.url is undefined.
@@ -869,6 +912,7 @@ export function createAgentChatPlugin(options) {
869
912
  : undefined;
870
913
  const { mountA2A } = await import("../a2a/server.js");
871
914
  mountA2A(nitroApp, {
915
+ appId: options?.appId,
872
916
  name: options?.appId
873
917
  ? options.appId.charAt(0).toUpperCase() + options.appId.slice(1)
874
918
  : "Agent",
@@ -877,7 +921,7 @@ export function createAgentChatPlugin(options) {
877
921
  publicSkillsOnly: true,
878
922
  streaming: true,
879
923
  durableBackgroundRuns: options?.durableBackgroundRuns,
880
- executeReadOnlyAction: async ({ action, input }) => {
924
+ executeReadOnlyAction: async ({ action, input, invocationId }) => {
881
925
  const actions = filterDirectA2AActions(mcpFullActions ?? allScripts, options ?? {});
882
926
  const entry = actions[action];
883
927
  if (!entry) {
@@ -890,10 +934,12 @@ export function createAgentChatPlugin(options) {
890
934
  actions: { [action]: entry },
891
935
  name: action,
892
936
  input,
893
- callId: `a2a-action-${crypto.randomUUID()}`,
937
+ callId: `a2a-action-${invocationId}`,
894
938
  ownerEmail: getRequestUserEmail(),
895
939
  orgId: getRequestOrgId() ?? null,
896
940
  caller: "a2a",
941
+ networkProtocol: "a2a",
942
+ networkId: invocationId,
897
943
  });
898
944
  if (result.status === "approval_required") {
899
945
  return {
@@ -1199,6 +1245,10 @@ export function createAgentChatPlugin(options) {
1199
1245
  const recoverableArtifactSecret = await resolveA2ARecoverableArtifactSecret();
1200
1246
  const recoverableArtifactStatusWriter = createSerializedA2ATaskStatusWriter(context.taskId);
1201
1247
  const controller = new AbortController();
1248
+ const correlation = sanitizeA2ACorrelationMetadata(context.metadata);
1249
+ const telemetryThreadId = sanitizeA2ACorrelationId(context.contextId) ??
1250
+ correlation.callerThreadId ??
1251
+ context.taskId;
1202
1252
  console.log(`[A2A] Starting agent loop: ${a2aToolSurface.tools.length}/${a2aToolSurface.availableTools.length} initial tools, prompt ${systemPrompt.length} chars`);
1203
1253
  await runA2AAgentLoop({
1204
1254
  engine: a2aEngine,
@@ -1216,6 +1266,11 @@ export function createAgentChatPlugin(options) {
1216
1266
  orgId: getRequestOrgId() ?? null,
1217
1267
  approvedToolCalls: context.approvedActions?.map((approved) => toolCallCacheKey(approved.tool, approved.input)),
1218
1268
  executionMode: "act",
1269
+ runId: context.taskId,
1270
+ networkProtocol: "a2a",
1271
+ networkId: context.taskId,
1272
+ threadId: context.taskId,
1273
+ turnId: context.taskId,
1219
1274
  send: (event) => {
1220
1275
  a2aEvents.push(event);
1221
1276
  if (event.type === "tool_start") {
@@ -1268,6 +1323,25 @@ export function createAgentChatPlugin(options) {
1268
1323
  }, {
1269
1324
  backgroundFunction: options?.durableBackgroundRuns === true &&
1270
1325
  isInBackgroundFunctionRuntime(),
1326
+ }, {
1327
+ telemetry: {
1328
+ runId: context.taskId,
1329
+ threadId: telemetryThreadId,
1330
+ userId: userEmail,
1331
+ delegation: {
1332
+ protocol: "a2a",
1333
+ taskId: context.taskId,
1334
+ ...(correlation.callerApp
1335
+ ? { callerApp: correlation.callerApp }
1336
+ : {}),
1337
+ ...(correlation.parentRunId
1338
+ ? { parentRunId: correlation.parentRunId }
1339
+ : {}),
1340
+ ...(correlation.parentTurnId
1341
+ ? { parentTurnId: correlation.parentTurnId }
1342
+ : {}),
1343
+ },
1344
+ },
1271
1345
  });
1272
1346
  // The continuation can observe terminal output immediately, so make
1273
1347
  // its latest mutation checkpoint durable first.
@@ -1391,6 +1465,7 @@ export function createAgentChatPlugin(options) {
1391
1465
  : {}),
1392
1466
  askAgent: async (message) => {
1393
1467
  const ownerEmail = getRequestUserEmail();
1468
+ const mcpRunId = crypto.randomUUID();
1394
1469
  const { getOwnerActiveApiKey } = await import("../agent/production-agent.js");
1395
1470
  const ownerApiKey = ownerEmail
1396
1471
  ? await getOwnerActiveApiKey(ownerEmail)
@@ -1501,9 +1576,14 @@ export function createAgentChatPlugin(options) {
1501
1576
  },
1502
1577
  ],
1503
1578
  actions: mcpActions,
1504
- ownerEmail: getRequestUserEmail(),
1579
+ ownerEmail,
1505
1580
  orgId: getRequestOrgId() ?? null,
1506
1581
  executionMode: "act",
1582
+ runId: mcpRunId,
1583
+ networkProtocol: "mcp",
1584
+ networkId: mcpRunId,
1585
+ threadId: mcpRunId,
1586
+ turnId: mcpRunId,
1507
1587
  send: (event) => {
1508
1588
  accumulatedText = applyAgentTextEventToBuffer(accumulatedText, event);
1509
1589
  },
@@ -1514,6 +1594,13 @@ export function createAgentChatPlugin(options) {
1514
1594
  }, {
1515
1595
  backgroundFunction: options?.durableBackgroundRuns === true &&
1516
1596
  isInBackgroundFunctionRuntime(),
1597
+ }, {
1598
+ telemetry: {
1599
+ runId: mcpRunId,
1600
+ threadId: mcpRunId,
1601
+ userId: ownerEmail ?? null,
1602
+ delegation: { protocol: "mcp" },
1603
+ },
1517
1604
  });
1518
1605
  return accumulatedText || "(no response)";
1519
1606
  },
@@ -3370,7 +3457,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
3370
3457
  }));
3371
3458
  // ─── Run management endpoints (for hot-reload resilience) ─────────────
3372
3459
  // GET /runs/active?threadId=X — check if there's an active run for a thread
3373
- getH3App(nitroApp).use(`${routePath}/runs`, defineEventHandler(async (event) => {
3460
+ getH3App(nitroApp).use(`${routePath}/runs`, withTransientDatabaseFallback(`${routePath}/runs`, async (event) => {
3374
3461
  // Auth check — ensure the user is authenticated
3375
3462
  const owner = await getOwnerFromEvent(event);
3376
3463
  const method = getMethod(event);
@@ -3795,7 +3882,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
3795
3882
  return { threadId: null, tail: [] };
3796
3883
  };
3797
3884
  const buildShareUrl = (event, token) => `${getOrigin(event)}${routePath}/shared/${encodeURIComponent(token)}`;
3798
- getH3App(nitroApp).use(`${routePath}/threads`, defineEventHandler(async (event) => {
3885
+ getH3App(nitroApp).use(`${routePath}/threads`, withTransientDatabaseFallback(`${routePath}/threads`, async (event) => {
3799
3886
  const owner = await getOwnerFromEvent(event);
3800
3887
  const orgId = await getOrgIdFromEvent(event);
3801
3888
  const method = getMethod(event);
@@ -4306,7 +4393,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
4306
4393
  // This is mounted last because h3's use() is prefix-based, meaning /_agent-native/agent-chat
4307
4394
  // also matches /_agent-native/agent-chat/threads/... — we skip sub-path requests here so the
4308
4395
  // earlier-mounted handlers (mode, save-key, files, skills, mentions, threads) handle them.
4309
- getH3App(nitroApp).use(routePath, defineEventHandler(async (event) => {
4396
+ getH3App(nitroApp).use(routePath, withTransientDatabaseFallback(routePath, async (event) => {
4310
4397
  // Skip sub-path requests — they're handled by earlier-mounted handlers
4311
4398
  const url = event.node?.req?.url || event.path || "";
4312
4399
  const afterBase = url.slice(url.indexOf(routePath) + routePath.length);