@agent-native/core 0.131.9 → 0.132.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/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +99 -0
- package/corpus/core/docs/content/durable-background-runs.mdx +15 -6
- package/corpus/core/docs/design/durable-agent-runs.md +15 -11
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/a2a/activity.ts +127 -10
- package/corpus/core/src/a2a/index.ts +3 -0
- package/corpus/core/src/agent/durable-background.ts +38 -28
- package/corpus/core/src/agent/harness/background.ts +12 -2
- package/corpus/core/src/agent/production-agent.ts +18 -15
- package/corpus/core/src/agent/run-store.ts +45 -3
- package/corpus/core/src/application-state/handlers.ts +45 -0
- package/corpus/core/src/application-state/index.ts +3 -0
- package/corpus/core/src/application-state/store.ts +28 -11
- package/corpus/core/src/audit/redact.ts +104 -18
- package/corpus/core/src/client/AgentPanel.tsx +2 -7
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +3 -0
- package/corpus/core/src/client/RunStuckBanner.tsx +29 -6
- package/corpus/core/src/client/agent-chat.ts +4 -9
- package/corpus/core/src/client/application-state.ts +115 -12
- package/corpus/core/src/client/dynamic-suggestions.ts +4 -12
- package/corpus/core/src/client/guided-questions.tsx +12 -23
- package/corpus/core/src/db/client.ts +148 -28
- package/corpus/core/src/db/create-get-db.ts +39 -6
- package/corpus/core/src/db/runtime-diagnostics.ts +41 -6
- package/corpus/core/src/deploy/build.ts +26 -33
- package/corpus/core/src/feature-flags/store.ts +10 -5
- package/corpus/core/src/integrations/a2a-continuations-store.ts +11 -0
- package/corpus/core/src/integrations/config-store.ts +13 -0
- package/corpus/core/src/integrations/google-docs-poller.ts +26 -2
- package/corpus/core/src/mcp-client/routes.ts +33 -2
- package/corpus/core/src/onboarding/plugin.ts +31 -25
- package/corpus/core/src/org/accept-pending.ts +2 -0
- package/corpus/core/src/org/auto-join-domain.ts +2 -0
- package/corpus/core/src/org/context.ts +35 -10
- package/corpus/core/src/org/handlers.ts +6 -0
- package/corpus/core/src/org/request-org-cache.ts +71 -0
- package/corpus/core/src/resources/store.ts +10 -9
- package/corpus/core/src/scripts/runner.ts +6 -3
- package/corpus/core/src/secrets/storage.ts +97 -5
- package/corpus/core/src/server/action-change.ts +33 -0
- package/corpus/core/src/server/action-routes.ts +11 -9
- package/corpus/core/src/server/agent-teams.ts +10 -2
- package/corpus/core/src/server/better-auth-instance.ts +39 -12
- package/corpus/core/src/server/core-routes-plugin.ts +19 -2
- package/corpus/core/src/server/credential-provider.ts +57 -14
- package/corpus/core/src/server/http-response-telemetry.ts +1 -0
- package/corpus/core/src/server/poll.ts +95 -57
- package/corpus/core/src/server/voice-providers-status.ts +19 -4
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +38 -0
- package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +1 -1
- package/corpus/templates/analytics/actions/ensure-native-v2-dashboards.ts +299 -0
- package/corpus/templates/analytics/actions/list-native-v2-dashboard-templates.ts +34 -0
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +82 -0
- package/corpus/templates/analytics/app/components/layout/NewDashboardDialog.tsx +2 -2
- package/corpus/templates/analytics/app/hooks/use-dashboard-chat-context.ts +40 -34
- package/corpus/templates/analytics/app/hooks/use-user-pref.ts +3 -3
- package/corpus/templates/analytics/app/i18n-data.ts +40 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +18 -10
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +14 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +1 -0
- package/corpus/templates/analytics/app/routes/chart.tsx +3 -0
- package/corpus/templates/analytics/changelog/2026-07-30-analytics-dashboards-now-expose-native-funnel-heatmap-callou.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-30-analytics-now-ships-reusable-native-v2-dashboard-manifests-w.md +6 -0
- package/corpus/templates/analytics/server/lib/dashboard-report-render.ts +81 -1
- package/corpus/templates/analytics/server/lib/native-v2-dashboards.ts +457 -0
- package/corpus/templates/analytics/server/lib/report-chart-svg.ts +73 -2
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +1 -1
- package/corpus/templates/analytics/shared/dashboard-funnel.ts +83 -0
- package/corpus/templates/content/changelog/2026-07-30-long-running-delegated-requests-now-continue-reliably.md +6 -0
- package/corpus/templates/content/netlify.toml +3 -0
- package/corpus/templates/content/server/plugins/agent-chat.ts +1 -0
- package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +2 -1
- package/corpus/templates/slides/actions/patch-deck.ts +25 -1
- package/corpus/templates/slides/app/components/deck/DeckCard.tsx +17 -4
- package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +9 -1
- package/corpus/templates/slides/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/slides/app/context/DeckContext.tsx +11 -3
- package/corpus/templates/slides/app/lib/sanitize-slide-html.ts +39 -11
- package/corpus/templates/slides/app/pages/Index.tsx +2 -2
- package/corpus/templates/slides/changelog/2026-07-30-slide-previews-keep-their-aspect-ratio-isolate-embedded-styl.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-30-slides-no-longer-lose-decks-while-organization-access-is-loa.md +6 -0
- package/corpus/toolkit/CHANGELOG.md +8 -0
- package/corpus/toolkit/package.json +1 -1
- package/corpus/toolkit/src/composer/runtime-adapters.tsx +16 -11
- package/dist/a2a/activity.d.ts +22 -4
- package/dist/a2a/activity.d.ts.map +1 -1
- package/dist/a2a/activity.js +97 -11
- package/dist/a2a/activity.js.map +1 -1
- package/dist/a2a/index.d.ts +1 -1
- package/dist/a2a/index.d.ts.map +1 -1
- package/dist/a2a/index.js +1 -1
- package/dist/a2a/index.js.map +1 -1
- package/dist/agent/durable-background.d.ts +13 -8
- package/dist/agent/durable-background.d.ts.map +1 -1
- package/dist/agent/durable-background.js +36 -28
- package/dist/agent/durable-background.js.map +1 -1
- package/dist/agent/harness/background.d.ts.map +1 -1
- package/dist/agent/harness/background.js +12 -2
- package/dist/agent/harness/background.js.map +1 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +18 -15
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-store.d.ts +2 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +44 -3
- package/dist/agent/run-store.js.map +1 -1
- package/dist/application-state/handlers.d.ts +15 -0
- package/dist/application-state/handlers.d.ts.map +1 -1
- package/dist/application-state/handlers.js +42 -2
- package/dist/application-state/handlers.js.map +1 -1
- package/dist/application-state/index.d.ts +2 -2
- package/dist/application-state/index.d.ts.map +1 -1
- package/dist/application-state/index.js +2 -2
- package/dist/application-state/index.js.map +1 -1
- package/dist/application-state/store.d.ts +11 -0
- package/dist/application-state/store.d.ts.map +1 -1
- package/dist/application-state/store.js +23 -10
- package/dist/application-state/store.js.map +1 -1
- package/dist/audit/redact.d.ts +25 -2
- package/dist/audit/redact.d.ts.map +1 -1
- package/dist/audit/redact.js +85 -21
- package/dist/audit/redact.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +2 -7
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +1 -1
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/RunStuckBanner.d.ts +11 -1
- package/dist/client/RunStuckBanner.d.ts.map +1 -1
- package/dist/client/RunStuckBanner.js +20 -7
- package/dist/client/RunStuckBanner.js.map +1 -1
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +4 -6
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/application-state.d.ts +11 -0
- package/dist/client/application-state.d.ts.map +1 -1
- package/dist/client/application-state.js +87 -9
- package/dist/client/application-state.js.map +1 -1
- package/dist/client/dynamic-suggestions.d.ts.map +1 -1
- package/dist/client/dynamic-suggestions.js +4 -13
- package/dist/client/dynamic-suggestions.js.map +1 -1
- package/dist/client/guided-questions.d.ts.map +1 -1
- package/dist/client/guided-questions.js +6 -22
- package/dist/client/guided-questions.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/db/client.d.ts +57 -10
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +122 -31
- package/dist/db/client.js.map +1 -1
- package/dist/db/create-get-db.d.ts.map +1 -1
- package/dist/db/create-get-db.js +31 -7
- package/dist/db/create-get-db.js.map +1 -1
- package/dist/db/runtime-diagnostics.d.ts +1 -0
- package/dist/db/runtime-diagnostics.d.ts.map +1 -1
- package/dist/db/runtime-diagnostics.js +31 -6
- package/dist/db/runtime-diagnostics.js.map +1 -1
- package/dist/deploy/build.d.ts +5 -20
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +18 -30
- package/dist/deploy/build.js.map +1 -1
- package/dist/feature-flags/store.d.ts.map +1 -1
- package/dist/feature-flags/store.js +10 -5
- package/dist/feature-flags/store.js.map +1 -1
- package/dist/integrations/a2a-continuations-store.d.ts.map +1 -1
- package/dist/integrations/a2a-continuations-store.js +12 -0
- package/dist/integrations/a2a-continuations-store.js.map +1 -1
- package/dist/integrations/config-store.d.ts +1 -0
- package/dist/integrations/config-store.d.ts.map +1 -1
- package/dist/integrations/config-store.js +11 -0
- package/dist/integrations/config-store.js.map +1 -1
- package/dist/integrations/google-docs-poller.d.ts.map +1 -1
- package/dist/integrations/google-docs-poller.js +19 -2
- package/dist/integrations/google-docs-poller.js.map +1 -1
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/mcp/screen-memory-stdio.d.ts.map +1 -1
- package/dist/mcp-client/routes.d.ts.map +1 -1
- package/dist/mcp-client/routes.js +30 -2
- package/dist/mcp-client/routes.js.map +1 -1
- package/dist/notifications/routes.d.ts +6 -6
- package/dist/observability/routes.d.ts +3 -3
- package/dist/onboarding/plugin.d.ts.map +1 -1
- package/dist/onboarding/plugin.js +12 -8
- package/dist/onboarding/plugin.js.map +1 -1
- package/dist/org/accept-pending.d.ts.map +1 -1
- package/dist/org/accept-pending.js +2 -0
- package/dist/org/accept-pending.js.map +1 -1
- package/dist/org/auto-join-domain.d.ts.map +1 -1
- package/dist/org/auto-join-domain.js +2 -0
- package/dist/org/auto-join-domain.js.map +1 -1
- package/dist/org/context.d.ts.map +1 -1
- package/dist/org/context.js +29 -9
- package/dist/org/context.js.map +1 -1
- package/dist/org/handlers.d.ts.map +1 -1
- package/dist/org/handlers.js +5 -0
- package/dist/org/handlers.js.map +1 -1
- package/dist/org/request-org-cache.d.ts +16 -0
- package/dist/org/request-org-cache.d.ts.map +1 -0
- package/dist/org/request-org-cache.js +62 -0
- package/dist/org/request-org-cache.js.map +1 -0
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/resources/store.d.ts.map +1 -1
- package/dist/resources/store.js +11 -9
- package/dist/resources/store.js.map +1 -1
- package/dist/scripts/runner.d.ts.map +1 -1
- package/dist/scripts/runner.js +3 -3
- package/dist/scripts/runner.js.map +1 -1
- package/dist/secrets/storage.d.ts.map +1 -1
- package/dist/secrets/storage.js +82 -5
- package/dist/secrets/storage.js.map +1 -1
- package/dist/server/action-change.d.ts +20 -0
- package/dist/server/action-change.d.ts.map +1 -1
- package/dist/server/action-change.js +29 -0
- package/dist/server/action-change.js.map +1 -1
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +7 -8
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/agent-teams.d.ts.map +1 -1
- package/dist/server/agent-teams.js +10 -2
- package/dist/server/agent-teams.js.map +1 -1
- package/dist/server/better-auth-instance.d.ts.map +1 -1
- package/dist/server/better-auth-instance.js +31 -14
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts +1 -0
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +18 -4
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/credential-provider.d.ts +16 -0
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +49 -13
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/http-response-telemetry.d.ts.map +1 -1
- package/dist/server/http-response-telemetry.js +1 -0
- package/dist/server/http-response-telemetry.js.map +1 -1
- package/dist/server/poll.d.ts +6 -0
- package/dist/server/poll.d.ts.map +1 -1
- package/dist/server/poll.js +84 -47
- package/dist/server/poll.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/server/voice-providers-status.d.ts.map +1 -1
- package/dist/server/voice-providers-status.js +12 -3
- package/dist/server/voice-providers-status.js.map +1 -1
- package/docs/content/durable-background-runs.mdx +15 -6
- package/docs/design/durable-agent-runs.md +15 -11
- package/package.json +2 -2
- package/src/a2a/activity.ts +127 -10
- package/src/a2a/index.ts +3 -0
- package/src/agent/durable-background.ts +38 -28
- package/src/agent/harness/background.ts +12 -2
- package/src/agent/production-agent.ts +18 -15
- package/src/agent/run-store.ts +45 -3
- package/src/application-state/handlers.ts +45 -0
- package/src/application-state/index.ts +3 -0
- package/src/application-state/store.ts +28 -11
- package/src/audit/redact.ts +104 -18
- package/src/client/AgentPanel.tsx +2 -7
- package/src/client/MultiTabAssistantChat.tsx +3 -0
- package/src/client/RunStuckBanner.tsx +29 -6
- package/src/client/agent-chat.ts +4 -9
- package/src/client/application-state.ts +115 -12
- package/src/client/dynamic-suggestions.ts +4 -12
- package/src/client/guided-questions.tsx +12 -23
- package/src/db/client.ts +148 -28
- package/src/db/create-get-db.ts +39 -6
- package/src/db/runtime-diagnostics.ts +41 -6
- package/src/deploy/build.ts +26 -33
- package/src/feature-flags/store.ts +10 -5
- package/src/integrations/a2a-continuations-store.ts +11 -0
- package/src/integrations/config-store.ts +13 -0
- package/src/integrations/google-docs-poller.ts +26 -2
- package/src/mcp-client/routes.ts +33 -2
- package/src/onboarding/plugin.ts +31 -25
- package/src/org/accept-pending.ts +2 -0
- package/src/org/auto-join-domain.ts +2 -0
- package/src/org/context.ts +35 -10
- package/src/org/handlers.ts +6 -0
- package/src/org/request-org-cache.ts +71 -0
- package/src/resources/store.ts +10 -9
- package/src/scripts/runner.ts +6 -3
- package/src/secrets/storage.ts +97 -5
- package/src/server/action-change.ts +33 -0
- package/src/server/action-routes.ts +11 -9
- package/src/server/agent-teams.ts +10 -2
- package/src/server/better-auth-instance.ts +39 -12
- package/src/server/core-routes-plugin.ts +19 -2
- package/src/server/credential-provider.ts +57 -14
- package/src/server/http-response-telemetry.ts +1 -0
- package/src/server/poll.ts +95 -57
- package/src/server/voice-providers-status.ts +19 -4
package/src/server/poll.ts
CHANGED
|
@@ -442,6 +442,12 @@ export class AppSyncState {
|
|
|
442
442
|
private lastExtensionsUpdatedAt: string | number | undefined;
|
|
443
443
|
private lastExtensionMarkerTs = 0;
|
|
444
444
|
private lastActionMarkerTs = 0;
|
|
445
|
+
/**
|
|
446
|
+
* Set by the seed when a durable action marker predates this process, so the
|
|
447
|
+
* first `doCheckExternalDbChanges` reads the marker rows even though the
|
|
448
|
+
* MAX(updated_at) probe cannot distinguish that row from the seeded max.
|
|
449
|
+
*/
|
|
450
|
+
private replayActionMarkerOnce = false;
|
|
445
451
|
|
|
446
452
|
/**
|
|
447
453
|
* Tracks the latest updated_at seen on the `__screen_refresh__` key.
|
|
@@ -1355,6 +1361,7 @@ export class AppSyncState {
|
|
|
1355
1361
|
// performed by a separate action process. Do not baseline past an existing
|
|
1356
1362
|
// marker on cold start, or the first poll after the action will miss it.
|
|
1357
1363
|
this.lastActionMarkerTs = 0;
|
|
1364
|
+
this.replayActionMarkerOnce = actionMarkerTs > 0;
|
|
1358
1365
|
this.lastScreenRefreshTs = refreshTs;
|
|
1359
1366
|
this.lastScreenRefreshTsBySession.clear();
|
|
1360
1367
|
for (const row of refreshResult.rows) {
|
|
@@ -1416,28 +1423,54 @@ export class AppSyncState {
|
|
|
1416
1423
|
// concurrently to shave stacked latency; results are still processed in
|
|
1417
1424
|
// the original sequential order, and conditional follow-up queries stay
|
|
1418
1425
|
// sequential within their branch.
|
|
1426
|
+
//
|
|
1427
|
+
// `lastAppStateTs` is maintained as MAX(updated_at) over the whole
|
|
1428
|
+
// `application_state` table (seeded in `seedVersionFromDb`, advanced by
|
|
1429
|
+
// the scan below over every key, not just the ones that emit events).
|
|
1430
|
+
// The application-state row scan and screen/extension marker reads only
|
|
1431
|
+
// report rows strictly newer than a watermark that is itself <=
|
|
1432
|
+
// `lastAppStateTs`, so an unadvanced MAX proves those reads are no-ops.
|
|
1433
|
+
// The action marker keeps its own max probe because its watermark must
|
|
1434
|
+
// remain independent under cross-process clock skew.
|
|
1419
1435
|
const [
|
|
1420
|
-
|
|
1436
|
+
appStateMaxTs,
|
|
1421
1437
|
actionMarkerTs,
|
|
1422
|
-
refreshResult,
|
|
1423
|
-
extensionMarkerTs,
|
|
1424
1438
|
settingsTs,
|
|
1425
1439
|
extensionsMaxUpdatedAt,
|
|
1426
1440
|
] = await Promise.all([
|
|
1427
|
-
db
|
|
1428
|
-
sql: "SELECT session_id, key, updated_at FROM application_state WHERE updated_at > ? ORDER BY updated_at ASC",
|
|
1429
|
-
args: [this.lastAppStateTs],
|
|
1430
|
-
}),
|
|
1441
|
+
readMaxUpdatedAt(db, "application_state"),
|
|
1431
1442
|
readActionMarkerMaxUpdatedAt(db),
|
|
1432
|
-
db.execute({
|
|
1433
|
-
sql: "SELECT session_id, updated_at, value FROM application_state WHERE key = ?",
|
|
1434
|
-
args: [SCREEN_REFRESH_KEY],
|
|
1435
|
-
}),
|
|
1436
|
-
readExtensionMarkerMaxUpdatedAt(db),
|
|
1437
1443
|
readMaxUpdatedAt(db, "settings"),
|
|
1438
1444
|
readMaxUpdatedAtRaw(db, "tools"),
|
|
1439
1445
|
]);
|
|
1440
1446
|
|
|
1447
|
+
// The seed deliberately rewinds `lastActionMarkerTs` to 0 so a marker
|
|
1448
|
+
// written before this process booted still reaches the first poll. That
|
|
1449
|
+
// replay is invisible to the MAX probe (the row is already counted in the
|
|
1450
|
+
// seeded max), so it gets one forced full read.
|
|
1451
|
+
const replayActionMarker = this.replayActionMarkerOnce;
|
|
1452
|
+
this.replayActionMarkerOnce = false;
|
|
1453
|
+
const appStateChanged =
|
|
1454
|
+
appStateMaxTs > this.lastAppStateTs || replayActionMarker;
|
|
1455
|
+
|
|
1456
|
+
const [appResult, refreshResult, extensionMarkerTs] = appStateChanged
|
|
1457
|
+
? await Promise.all([
|
|
1458
|
+
db.execute({
|
|
1459
|
+
sql: "SELECT session_id, key, updated_at FROM application_state WHERE updated_at > ? ORDER BY updated_at ASC",
|
|
1460
|
+
args: [this.lastAppStateTs],
|
|
1461
|
+
}),
|
|
1462
|
+
db.execute({
|
|
1463
|
+
sql: "SELECT session_id, updated_at, value FROM application_state WHERE key = ?",
|
|
1464
|
+
args: [SCREEN_REFRESH_KEY],
|
|
1465
|
+
}),
|
|
1466
|
+
readExtensionMarkerMaxUpdatedAt(db),
|
|
1467
|
+
])
|
|
1468
|
+
: ([
|
|
1469
|
+
{ rows: [] as Record<string, unknown>[] },
|
|
1470
|
+
null,
|
|
1471
|
+
this.lastExtensionMarkerTs,
|
|
1472
|
+
] as const);
|
|
1473
|
+
|
|
1441
1474
|
// Check application_state for external writes. Preserve the changed key so
|
|
1442
1475
|
// clients can invalidate one-shot command queries (`navigate`, `__set_url__`)
|
|
1443
1476
|
// only when those command rows actually change; noisy keys such as
|
|
@@ -1497,54 +1530,59 @@ export class AppSyncState {
|
|
|
1497
1530
|
// tool writes to application_state under a well-known key; when its
|
|
1498
1531
|
// updated_at bumps, emit a distinct event so the client invalidates
|
|
1499
1532
|
// all queries (not just the ones matching its default queryKey prefix).
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
)
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
)
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
// advanced, scoped with `owner` so canSeeChangeForUser delivers it only
|
|
1518
|
-
// to that user — not every authenticated poller.
|
|
1519
|
-
for (const row of refreshResult.rows) {
|
|
1520
|
-
const owner =
|
|
1521
|
-
typeof row.session_id === "string" ? row.session_id : undefined;
|
|
1522
|
-
if (!owner) continue;
|
|
1523
|
-
const rowTs = timestampValue(row.updated_at);
|
|
1524
|
-
if (rowTs <= (this.lastScreenRefreshTsBySession.get(owner) ?? 0)) {
|
|
1525
|
-
continue;
|
|
1533
|
+
// `refreshResult` is null exactly when the MAX probe proved no
|
|
1534
|
+
// application_state row moved, which is also exactly when this block
|
|
1535
|
+
// could not emit anything.
|
|
1536
|
+
if (refreshResult) {
|
|
1537
|
+
const refreshTs = refreshResult.rows.reduce(
|
|
1538
|
+
(max, row) => Math.max(max, timestampValue(row.updated_at)),
|
|
1539
|
+
0,
|
|
1540
|
+
);
|
|
1541
|
+
if (!this.screenRefreshInitialized) {
|
|
1542
|
+
this.lastScreenRefreshTs = refreshTs;
|
|
1543
|
+
for (const row of refreshResult.rows) {
|
|
1544
|
+
if (typeof row.session_id === "string") {
|
|
1545
|
+
this.lastScreenRefreshTsBySession.set(
|
|
1546
|
+
row.session_id,
|
|
1547
|
+
timestampValue(row.updated_at),
|
|
1548
|
+
);
|
|
1549
|
+
}
|
|
1526
1550
|
}
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1551
|
+
this.screenRefreshInitialized = true;
|
|
1552
|
+
} else if (refreshTs > this.lastScreenRefreshTs) {
|
|
1553
|
+
// Emit a per-user event only for the session(s) whose row actually
|
|
1554
|
+
// advanced, scoped with `owner` so canSeeChangeForUser delivers it only
|
|
1555
|
+
// to that user — not every authenticated poller.
|
|
1556
|
+
for (const row of refreshResult.rows) {
|
|
1557
|
+
const owner =
|
|
1558
|
+
typeof row.session_id === "string" ? row.session_id : undefined;
|
|
1559
|
+
if (!owner) continue;
|
|
1560
|
+
const rowTs = timestampValue(row.updated_at);
|
|
1561
|
+
if (rowTs <= (this.lastScreenRefreshTsBySession.get(owner) ?? 0)) {
|
|
1562
|
+
continue;
|
|
1533
1563
|
}
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1564
|
+
let scope: string | undefined;
|
|
1565
|
+
try {
|
|
1566
|
+
const raw = row.value;
|
|
1567
|
+
if (typeof raw === "string") {
|
|
1568
|
+
const parsed = JSON.parse(raw);
|
|
1569
|
+
if (typeof parsed?.scope === "string") scope = parsed.scope;
|
|
1570
|
+
}
|
|
1571
|
+
} catch {}
|
|
1572
|
+
this.recordChange(
|
|
1573
|
+
{
|
|
1574
|
+
source: "screen-refresh",
|
|
1575
|
+
type: "change",
|
|
1576
|
+
key: SCREEN_REFRESH_KEY,
|
|
1577
|
+
owner,
|
|
1578
|
+
...(scope ? { scope } : {}),
|
|
1579
|
+
},
|
|
1580
|
+
{ dedupeKey: `screen-refresh|${rowTs}` },
|
|
1581
|
+
);
|
|
1582
|
+
this.lastScreenRefreshTsBySession.set(owner, rowTs);
|
|
1583
|
+
}
|
|
1584
|
+
this.lastScreenRefreshTs = refreshTs;
|
|
1546
1585
|
}
|
|
1547
|
-
this.lastScreenRefreshTs = refreshTs;
|
|
1548
1586
|
}
|
|
1549
1587
|
|
|
1550
1588
|
// Extension mutations write a durable marker row so delete and hide/unhide
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
import { getOrgContext } from "../org/context.js";
|
|
23
23
|
import { getSession } from "./auth.js";
|
|
24
24
|
import {
|
|
25
|
+
prefetchSecrets,
|
|
25
26
|
resolveHasCompleteBuilderConnection,
|
|
26
27
|
resolveSecret,
|
|
27
28
|
} from "./credential-provider.js";
|
|
@@ -74,10 +75,14 @@ export function createVoiceProvidersStatusHandler() {
|
|
|
74
75
|
async function hasKey(key: string): Promise<boolean> {
|
|
75
76
|
try {
|
|
76
77
|
if (key === "GOOGLE_APPLICATION_CREDENTIALS") {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
// Same identity, passed explicitly — the context is here only so this
|
|
79
|
+
// scope sweep shares the prefetched per-request memo below.
|
|
80
|
+
const resolved = await withRequestContext(() =>
|
|
81
|
+
resolveGoogleRealtimeCredentials({
|
|
82
|
+
userEmail: session?.email,
|
|
83
|
+
orgId: orgCtx?.orgId ?? undefined,
|
|
84
|
+
}),
|
|
85
|
+
);
|
|
81
86
|
return typeof resolved === "string" && resolved.length > 0;
|
|
82
87
|
}
|
|
83
88
|
const resolved = await withRequestContext(() => resolveSecret(key));
|
|
@@ -87,6 +92,16 @@ export function createVoiceProvidersStatusHandler() {
|
|
|
87
92
|
}
|
|
88
93
|
}
|
|
89
94
|
|
|
95
|
+
// One read per scope for every key below, instead of one per key per scope.
|
|
96
|
+
await withRequestContext(() =>
|
|
97
|
+
prefetchSecrets([
|
|
98
|
+
"GEMINI_API_KEY",
|
|
99
|
+
"OPENAI_API_KEY",
|
|
100
|
+
"GROQ_API_KEY",
|
|
101
|
+
"GOOGLE_APPLICATION_CREDENTIALS",
|
|
102
|
+
]),
|
|
103
|
+
);
|
|
104
|
+
|
|
90
105
|
let builder = false;
|
|
91
106
|
try {
|
|
92
107
|
builder =
|