@agent-native/core 0.200.0-nightly-20261002124406 → 0.200.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 (48) hide show
  1. package/dist/agent/production-agent.d.ts +5 -1
  2. package/dist/agent/production-agent.js +36 -1
  3. package/dist/app-config/runtime.d.ts +1 -0
  4. package/dist/app-config/runtime.js +4 -0
  5. package/dist/app-config/schema.d.ts +1 -0
  6. package/dist/cli/design-connect.d.ts +1 -0
  7. package/dist/cli/design-connect.js +147 -7
  8. package/dist/client/analytics.js +24 -1
  9. package/dist/client/session-replay.d.ts +6 -0
  10. package/dist/client/session-replay.js +47 -5
  11. package/dist/collab/awareness.d.ts +2 -2
  12. package/dist/collab/routes.d.ts +1 -1
  13. package/dist/file-upload/builder.js +20 -2
  14. package/dist/mcp-client/app-api.d.ts +11 -1
  15. package/dist/mcp-client/app-api.js +17 -3
  16. package/dist/mcp-client/index.d.ts +1 -1
  17. package/dist/mcp-client/manager.d.ts +3 -1
  18. package/dist/mcp-client/manager.js +4 -0
  19. package/dist/notifications/routes.d.ts +3 -3
  20. package/dist/observability/metrics.js +14 -7
  21. package/dist/provider-api/actions/custom-provider-registration.d.ts +6 -6
  22. package/dist/provider-api/actions/provider-api.d.ts +15 -15
  23. package/dist/resource-changes/store.d.ts +166 -0
  24. package/dist/resource-changes/store.js +499 -0
  25. package/dist/search/index-store.d.ts +9 -0
  26. package/dist/search/index-store.js +50 -0
  27. package/dist/search/index.d.ts +5 -1
  28. package/dist/search/index.js +5 -0
  29. package/dist/search/indexer.d.ts +32 -0
  30. package/dist/search/indexer.js +651 -0
  31. package/dist/search/query-parser.d.ts +29 -0
  32. package/dist/search/query-parser.js +71 -0
  33. package/dist/search/query.d.ts +46 -0
  34. package/dist/search/query.js +149 -0
  35. package/dist/search/registry.d.ts +55 -0
  36. package/dist/search/registry.js +93 -0
  37. package/dist/search/tokenize.d.ts +103 -0
  38. package/dist/search/tokenize.js +367 -0
  39. package/dist/server/action-change-marker-write.js +5 -1
  40. package/dist/server/agent-chat/run-code-tools.d.ts +7 -0
  41. package/dist/server/agent-chat/run-code-tools.js +7 -0
  42. package/dist/server/agent-chat-plugin.d.ts +5 -1
  43. package/dist/server/agent-chat-plugin.js +18 -12
  44. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  45. package/dist/server/agent-engine-default-model-route.d.ts +2 -2
  46. package/dist/server/release-schema.js +8 -0
  47. package/dist/triggers/actions/manage-automation.d.ts +3 -3
  48. package/package.json +6 -9
@@ -10,10 +10,20 @@ export interface AppMcpTool {
10
10
  }
11
11
  export interface ListVisibleMcpToolsOptions {
12
12
  serverId?: string;
13
+ /**
14
+ * Keep only tools served from this provider's MCP endpoint, matched on the
15
+ * server URL. A server id is a name the user chose, so it cannot prove which
16
+ * provider answers the call.
17
+ */
18
+ providerId?: string;
19
+ }
20
+ export interface CallMcpToolOptions {
21
+ /** Refuse the call unless the server's URL belongs to this provider. */
22
+ providerId?: string;
13
23
  }
14
24
  export declare class McpAppApiError extends Error {
15
25
  readonly statusCode: 401 | 403 | 503;
16
26
  constructor(message: string, statusCode: 401 | 403 | 503);
17
27
  }
18
28
  export declare function listVisibleMcpTools(options?: ListVisibleMcpToolsOptions): Promise<AppMcpTool[]>;
19
- export declare function callMcpTool(serverId: string, originalToolName: string, args?: Record<string, unknown>): Promise<unknown>;
29
+ export declare function callMcpTool(serverId: string, originalToolName: string, args?: Record<string, unknown>, options?: CallMcpToolOptions): Promise<unknown>;
@@ -1,6 +1,7 @@
1
1
  import { isToolVisibilityModelOnly } from "@modelcontextprotocol/ext-apps/app-bridge";
2
2
  import { getMcpManagerForPrincipal } from "../server/agent-chat/mcp-glue.js";
3
3
  import { getRequestContext } from "../server/request-context.js";
4
+ import { hasMcpProviderMatchRules, mcpServerUrlMatchesProvider, } from "../shared/mcp-provider-hosts.js";
4
5
  import { buildMcpToolName, } from "./manager.js";
5
6
  import { normalizeMcpPrincipal } from "./principal.js";
6
7
  import { parseMergedKey } from "./remote-store.js";
@@ -20,16 +21,19 @@ export async function listVisibleMcpTools(options = {}) {
20
21
  ? manager.getToolsForServer(options.serverId)
21
22
  : manager.getTools();
22
23
  return tools
23
- .filter((tool) => isToolVisibleToApp(tool, context))
24
+ .filter((tool) => isToolVisibleToApp(tool, context) &&
25
+ isServerForProvider(manager, tool.source, options.providerId))
24
26
  .map(toAppMcpTool);
25
27
  }
26
- export async function callMcpTool(serverId, originalToolName, args = {}) {
28
+ export async function callMcpTool(serverId, originalToolName, args = {}, options = {}) {
27
29
  const context = requireAuthenticatedRequest();
28
30
  const manager = await requireMcpManager(context);
29
31
  const tool = manager
30
32
  .getToolsForServer(serverId)
31
33
  .find((candidate) => candidate.originalName === originalToolName);
32
- if (!tool || !isToolVisibleToApp(tool, context)) {
34
+ if (!tool ||
35
+ !isToolVisibleToApp(tool, context) ||
36
+ !isServerForProvider(manager, serverId, options.providerId)) {
33
37
  throw new McpAppApiError("MCP tool is not available in this request scope.", 403);
34
38
  }
35
39
  return manager.callTool(buildMcpToolName(serverId, originalToolName), args);
@@ -81,6 +85,16 @@ function isToolVisibleToApp(tool, context) {
81
85
  return false;
82
86
  }
83
87
  }
88
+ function isServerForProvider(manager, serverId, providerId) {
89
+ if (providerId === undefined)
90
+ return true;
91
+ if (!hasMcpProviderMatchRules(providerId)) {
92
+ throw new Error(`No MCP provider match rules for "${providerId}". Add it to MCP_PROVIDER_ENDPOINTS or MCP_LINK_HOSTS before filtering by it.`);
93
+ }
94
+ const config = manager.getServerConfig(serverId);
95
+ return (config?.type === "http" &&
96
+ mcpServerUrlMatchesProvider(providerId, config.url) === true);
97
+ }
84
98
  function toAppMcpTool(tool) {
85
99
  return {
86
100
  serverId: tool.source,
@@ -10,7 +10,7 @@ export { mountMcpServersRoutes, buildMergedConfig, builtinMergedConfigKey, McpCo
10
10
  export { mountMcpHubRoutes, listHubServers, getHubStatus, isHubServeEnabled, isHubConsumeEnabled, type HubServerRecord, type HubServersResponse, } from "./hub-routes.js";
11
11
  export { fetchHubServers } from "./hub-client.js";
12
12
  export { isMcpToolAllowedForRequest } from "./visibility.js";
13
- export { callMcpTool, listVisibleMcpTools, McpAppApiError, type AppMcpTool, type ListVisibleMcpToolsOptions, } from "./app-api.js";
13
+ export { callMcpTool, listVisibleMcpTools, McpAppApiError, type AppMcpTool, type CallMcpToolOptions, type ListVisibleMcpToolsOptions, } from "./app-api.js";
14
14
  export { classifyMcpToolCall, evaluateMcpToolCallPolicy, type McpToolCallClassification, type McpToolEffect, type McpToolFamily, type McpToolInvocationPolicy, type McpToolPolicyDecision, } from "./tool-policy.js";
15
15
  export { configureScreenMemory, queryScreenMemoryForAgent, queryScreenMemoryContext, readScreenMemoryStatus, type ScreenMemoryConfig, type ScreenMemoryAgentQueryResult, type ScreenMemoryContextItem, type ScreenMemoryCoverageGap, type ScreenMemoryEvidenceItem, type ScreenMemoryEvidenceSourceType, type ScreenMemoryQueryResult, type ScreenMemoryRetrievalCoverage, type ScreenMemorySegmentReference, type ScreenMemoryStatus, type ScreenMemoryTimeRange, type ScreenMemoryTruncation, } from "./screen-memory-local.js";
16
16
  export { MCP_ACTION_RESULT_MARKER, isMcpActionResult, type AgentMcpAppPayload, type AgentMcpAppResourceContent, type McpActionResult, } from "./app-result.js";
@@ -1,4 +1,4 @@
1
- import type { McpConfig } from "./config.js";
1
+ import type { McpConfig, McpServerConfig } from "./config.js";
2
2
  export declare const MCP_TOOL_PREFIX = "mcp__";
3
3
  export interface McpTool {
4
4
  source: string;
@@ -66,6 +66,8 @@ export declare class McpClientManager {
66
66
  getTools(): McpTool[];
67
67
  getTool(prefixedName: string): McpTool | null;
68
68
  getToolsForServer(serverId: string): McpTool[];
69
+ /** The config the server's current tools were loaded from. */
70
+ getServerConfig(serverId: string): McpServerConfig | null;
69
71
  hasServer(serverId: string): boolean;
70
72
  callTool(prefixedName: string, args: unknown): Promise<unknown>;
71
73
  readResource(serverId: string, uri: string): Promise<unknown>;
@@ -526,6 +526,10 @@ export class McpClientManager {
526
526
  getToolsForServer(serverId) {
527
527
  return [...(this.servers.get(serverId)?.tools ?? [])];
528
528
  }
529
+ /** The config the server's current tools were loaded from. */
530
+ getServerConfig(serverId) {
531
+ return this.servers.get(serverId)?.config ?? null;
532
+ }
529
533
  hasServer(serverId) {
530
534
  const entry = this.servers.get(serverId);
531
535
  return !!entry?.client && !entry.error;
@@ -1,21 +1,21 @@
1
1
  export declare function createNotificationsHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<"" | import("./types.js").Notification[] | {
2
+ error?: undefined;
2
3
  count: number;
3
4
  updated?: undefined;
4
5
  ok?: undefined;
5
- error?: undefined;
6
6
  } | {
7
+ error?: undefined;
7
8
  count?: undefined;
8
9
  updated: number;
9
10
  ok?: undefined;
10
- error?: undefined;
11
11
  } | {
12
12
  count?: undefined;
13
13
  updated?: undefined;
14
14
  error: string;
15
15
  ok?: undefined;
16
16
  } | {
17
+ error?: undefined;
17
18
  count?: undefined;
18
19
  updated?: undefined;
19
20
  ok: boolean;
20
- error?: undefined;
21
21
  }>>;
@@ -64,8 +64,11 @@ export function recordHttpServerRequest(request) {
64
64
  function flushErrorType(error) {
65
65
  return error instanceof Error && error.name ? error.name : "unknown";
66
66
  }
67
- function recordFlushFailure(errorType) {
68
- instruments()?.flushFailures.add(1, { "error.type": errorType });
67
+ function recordFlushFailure(signal, errorType) {
68
+ instruments()?.flushFailures.add(1, {
69
+ "agent_native.telemetry.signal": signal,
70
+ "error.type": errorType,
71
+ });
69
72
  }
70
73
  /**
71
74
  * Export buffered telemetry before a serverless function can freeze. Never
@@ -85,17 +88,21 @@ export async function flushObservability() {
85
88
  try {
86
89
  // One provider failing must not end the wait for the other: the response
87
90
  // hook returning early lets the runtime freeze mid-export.
88
- const failures = await Promise.all([provider.meterProvider, provider.tracerProvider].map((signal) => Promise.race([
91
+ const flushes = [
92
+ ["metrics", provider.meterProvider],
93
+ ["traces", provider.tracerProvider],
94
+ ];
95
+ const failures = await Promise.all(flushes.map(([, signalProvider]) => Promise.race([
89
96
  (async () => {
90
- await signal?.forceFlush?.();
97
+ await signalProvider?.forceFlush?.();
91
98
  return undefined;
92
99
  })().catch(flushErrorType),
93
100
  timeout,
94
101
  ])));
95
- for (const failure of failures) {
102
+ failures.forEach((failure, index) => {
96
103
  if (failure)
97
- recordFlushFailure(failure);
98
- }
104
+ recordFlushFailure(flushes[index][0], failure);
105
+ });
99
106
  }
100
107
  finally {
101
108
  clearTimeout(timer);
@@ -75,10 +75,11 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
75
75
  user: "user";
76
76
  }>>;
77
77
  }, z.core.$strip>>, {
78
+ provider?: undefined;
78
79
  id?: undefined;
79
80
  deleted?: undefined;
80
- provider?: undefined;
81
81
  message?: undefined;
82
+ found?: undefined;
82
83
  providers: {
83
84
  id: string;
84
85
  label: string;
@@ -89,7 +90,6 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
89
90
  updatedAt: number;
90
91
  }[];
91
92
  count: number;
92
- found?: undefined;
93
93
  registered?: undefined;
94
94
  label?: undefined;
95
95
  } | {
@@ -103,8 +103,8 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
103
103
  registered?: undefined;
104
104
  label?: undefined;
105
105
  } | {
106
- deleted?: undefined;
107
106
  provider?: undefined;
107
+ deleted?: undefined;
108
108
  message?: undefined;
109
109
  providers?: undefined;
110
110
  count?: undefined;
@@ -115,19 +115,19 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
115
115
  } | {
116
116
  provider?: undefined;
117
117
  message?: undefined;
118
+ found?: undefined;
118
119
  providers?: undefined;
119
120
  count?: undefined;
120
- found?: undefined;
121
121
  deleted: boolean;
122
122
  id: string;
123
123
  registered?: undefined;
124
124
  label?: undefined;
125
125
  } | {
126
- deleted?: undefined;
127
126
  provider?: undefined;
127
+ deleted?: undefined;
128
+ found?: undefined;
128
129
  providers?: undefined;
129
130
  count?: undefined;
130
- found?: undefined;
131
131
  registered: boolean;
132
132
  id: string;
133
133
  label: string;
@@ -311,10 +311,9 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
311
311
  notes?: string | undefined;
312
312
  scope?: "org" | "user" | undefined;
313
313
  }, {
314
- message?: undefined;
315
- provider?: undefined;
316
314
  id?: undefined;
317
- deleted?: undefined;
315
+ message?: undefined;
316
+ found?: undefined;
318
317
  providers: {
319
318
  id: string;
320
319
  label: string;
@@ -325,45 +324,46 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
325
324
  updatedAt: number;
326
325
  }[];
327
326
  count: number;
328
- found?: undefined;
327
+ provider?: undefined;
328
+ deleted?: undefined;
329
329
  registered?: undefined;
330
330
  label?: undefined;
331
331
  } | {
332
- message?: undefined;
333
332
  id?: undefined;
334
333
  count?: undefined;
335
- deleted?: undefined;
334
+ message?: undefined;
336
335
  providers?: undefined;
337
336
  found: boolean;
338
337
  provider: import("../custom-registry.js").CustomProviderConfig;
338
+ deleted?: undefined;
339
339
  registered?: undefined;
340
340
  label?: undefined;
341
341
  } | {
342
- message?: undefined;
343
- provider?: undefined;
344
342
  count?: undefined;
345
- deleted?: undefined;
343
+ message?: undefined;
346
344
  providers?: undefined;
345
+ provider?: undefined;
347
346
  found: boolean;
348
347
  id: string;
348
+ deleted?: undefined;
349
349
  registered?: undefined;
350
350
  label?: undefined;
351
351
  } | {
352
- message?: undefined;
353
- provider?: undefined;
354
352
  count?: undefined;
355
- providers?: undefined;
353
+ message?: undefined;
356
354
  found?: undefined;
355
+ providers?: undefined;
356
+ provider?: undefined;
357
357
  deleted: boolean;
358
358
  id: string;
359
359
  registered?: undefined;
360
360
  label?: undefined;
361
361
  } | {
362
- provider?: undefined;
363
362
  count?: undefined;
364
- deleted?: undefined;
365
- providers?: undefined;
366
363
  found?: undefined;
364
+ providers?: undefined;
365
+ provider?: undefined;
366
+ deleted?: undefined;
367
367
  registered: boolean;
368
368
  id: string;
369
369
  label: string;
@@ -0,0 +1,166 @@
1
+ /**
2
+ * The app resource change feed: a durable note that one of an app's
3
+ * resources changed, kept once for every consumer that asked to hear about
4
+ * that resource type.
5
+ *
6
+ * Producers call one SQL function, `agent_native_app_resource_changed`, in the
7
+ * writer's own transaction, so nothing is recorded unless the write commits.
8
+ * Today the producers are row triggers that core generates for a registered
9
+ * table. They catch every writer: actions, sync jobs, raw SQL, and deletes.
10
+ * If core later gains a data layer that every write goes through, it calls the
11
+ * same function and the triggers retire; consumers don't change.
12
+ *
13
+ * Each (consumer, resource) pair is one row. Repeated changes update that row
14
+ * rather than adding rows, so autosave doesn't grow the feed. Every change
15
+ * takes a new value from one sequence, taken after the row lock, so for any
16
+ * one resource a larger `seq` always means a later committed change. Consumers
17
+ * use it to reject stale work and to delete only what they processed.
18
+ *
19
+ * A change that fails is retried with backoff, and after its last allowed
20
+ * attempt it is marked failed but still retried every few minutes. It stays
21
+ * pending the whole time, so a consumer that reports freshness never treats
22
+ * it as done.
23
+ *
24
+ * Consumers never poll. They process changes only where the database is
25
+ * already awake: before a read that needs fresh data, right after a write, or
26
+ * inside the framework's recurring sweep. See docs/search-architecture.md.
27
+ */
28
+ import { type DbExec } from "../db/client.js";
29
+ export declare const RESOURCE_CHANGES_TABLE = "app_resource_changes";
30
+ export declare const RESOURCE_CHANGE_CONSUMERS_TABLE = "app_resource_change_consumers";
31
+ export declare const RESOURCE_CHANGE_SEQUENCE = "app_resource_change_seq";
32
+ export declare const RESOURCE_CHANGED_FUNCTION = "agent_native_app_resource_changed";
33
+ /** After this many attempts a change is marked failed. */
34
+ export declare const RESOURCE_CHANGE_MAX_ATTEMPTS = 5;
35
+ /**
36
+ * Creates the feed's tables, sequence, and producer function. Listed in
37
+ * `server/release-schema.ts`; trigger installation calls it too, so the
38
+ * function a trigger calls always exists before the trigger does.
39
+ */
40
+ export declare function ensureResourceChangeTables(injectedClient?: DbExec): Promise<void>;
41
+ /** Where a registered resource lives, for generating its triggers. */
42
+ export interface ResourceChangeSource {
43
+ app: string;
44
+ resourceType: string;
45
+ table: string;
46
+ idColumn: string;
47
+ }
48
+ export declare function assertResourceKey(value: string, label: string): string;
49
+ /**
50
+ * Names of the function and triggers generated for one source. Functions are
51
+ * schema-wide and the readable part is shortened to fit Postgres's 63
52
+ * characters, so a hash of the app, table, and type keeps every source's
53
+ * names distinct. Installing a source replaces whatever has its names, so
54
+ * the hash is wide enough that two sources never share them.
55
+ */
56
+ export declare function resourceChangeTriggerNames(source: ResourceChangeSource): {
57
+ function: string;
58
+ insertDeleteTrigger: string;
59
+ updateTrigger: string;
60
+ truncateTrigger: string;
61
+ };
62
+ /**
63
+ * SQL that makes every committed insert, update, delete, and truncate on the
64
+ * source table call the producer function. An update that changes nothing is
65
+ * skipped. An update that changes the id reports both ids. A truncate
66
+ * reports every row it removes as deleted.
67
+ *
68
+ * "Changes nothing" compares the rows' stored bytes (`*<>`), not their
69
+ * values: a `json` or `point` column has no equality operator, and comparing
70
+ * such rows by value would make every update on the table fail.
71
+ *
72
+ * Triggers are replaced in place, never dropped and recreated: a write
73
+ * committed between a drop and a create would never be recorded.
74
+ */
75
+ export declare function resourceChangeTriggerSql(source: ResourceChangeSource): string[];
76
+ /**
77
+ * Installs change capture for a source and subscribes a consumer to it.
78
+ * Apps call this from a named migration, so the triggers ship with the app's
79
+ * schema rather than being created on a request path.
80
+ *
81
+ * Creating a trigger waits for every open transaction on the table, and
82
+ * queues the table's writes behind it while it waits, so each waits at most
83
+ * a few seconds. Returns false when one gave up; the caller retries later.
84
+ */
85
+ export declare function installResourceChangeCapture(exec: DbExec, source: ResourceChangeSource, consumer: string): Promise<boolean>;
86
+ export declare function subscribeResourceChangeConsumer(exec: DbExec, source: Pick<ResourceChangeSource, "app" | "resourceType">, consumer: string): Promise<void>;
87
+ /**
88
+ * True when every generated trigger exists on the source table and fires.
89
+ * A disabled trigger (`ALTER TABLE ... DISABLE TRIGGER`) records nothing, so
90
+ * it counts as missing.
91
+ */
92
+ export declare function resourceChangeCaptureInstalled(exec: DbExec, source: ResourceChangeSource): Promise<boolean>;
93
+ export interface ResourceChangeFeed {
94
+ consumer: string;
95
+ app: string;
96
+ resourceType: string;
97
+ }
98
+ export interface ClaimedResourceChange {
99
+ resourceId: string;
100
+ seq: string;
101
+ attempts: number;
102
+ }
103
+ /**
104
+ * A condition a consumer attaches to its claim, complete, and fail
105
+ * statements. It is checked inside each statement, so once it stops holding,
106
+ * those statements change nothing. Search uses it so a process running an
107
+ * older index version can't consume changes queued for a newer one.
108
+ */
109
+ export interface ResourceChangeFence {
110
+ sql: string;
111
+ args: unknown[];
112
+ }
113
+ /**
114
+ * Leases up to `limit` ready changes, oldest first. Rows another claimant is
115
+ * locking right now are skipped, and the lease expires on its own if this
116
+ * process dies, so there is nothing to clean up.
117
+ */
118
+ export declare function claimResourceChanges(exec: DbExec, feed: ResourceChangeFeed, limit: number, fence?: ResourceChangeFence): Promise<ClaimedResourceChange[]>;
119
+ export declare function compareSeq(a: string, b: string): number;
120
+ /**
121
+ * Deletes processed changes, but only rows whose seq is still the one that
122
+ * was claimed. A change recorded meanwhile stays for the next pass.
123
+ */
124
+ export declare function completeResourceChanges(exec: DbExec, feed: ResourceChangeFeed, changes: readonly ClaimedResourceChange[], fence?: ResourceChangeFence): Promise<void>;
125
+ /**
126
+ * Backs off failed changes, doubling the wait up to five minutes. After the
127
+ * last allowed attempt a change is also marked failed, which a consumer can
128
+ * report, but it keeps being retried: a failure that was only temporary
129
+ * clears itself, and a later write to the resource starts it fresh.
130
+ */
131
+ export declare function failResourceChanges(exec: DbExec, feed: ResourceChangeFeed, changes: readonly ClaimedResourceChange[], fence?: ResourceChangeFence): Promise<void>;
132
+ /**
133
+ * Two boolean columns for a caller's own SELECT, so checking the feed costs
134
+ * no extra round trip: `pending` while any change is waiting, leased, or
135
+ * backing off, and `failing` while any has used up its attempts.
136
+ */
137
+ export declare function resourceChangeBacklogColumns(feed: ResourceChangeFeed): {
138
+ sql: string;
139
+ args: unknown[];
140
+ };
141
+ /** True while any change at or below `seq` is still pending for this feed. */
142
+ export declare function hasPendingResourceChanges(exec: DbExec, feed: ResourceChangeFeed, options?: {
143
+ atOrBelowSeq?: string;
144
+ }): Promise<boolean>;
145
+ /**
146
+ * Records a change for every row of the source table, for this consumer
147
+ * only, and returns a seq at or above every one it assigned. Consumers use
148
+ * it to rebuild from scratch.
149
+ *
150
+ * A change already queued is replaced by a fresh one, even if another
151
+ * process has it leased or it has failed: that work was done for the old
152
+ * consumer state, so it must not complete what the rebuild queued.
153
+ */
154
+ export declare function enqueueAllResourceChanges(exec: DbExec, source: ResourceChangeSource, consumer: string, reason: string): Promise<string>;
155
+ type DrainHook = () => Promise<unknown>;
156
+ /**
157
+ * Registers work to run right after a request that changed data, while the
158
+ * database is known to be awake. Returns an unregister function.
159
+ */
160
+ export declare function registerAfterWriteDrain(id: string, drain: DrainHook): () => void;
161
+ /**
162
+ * Runs registered after-write drains without delaying the caller. On
163
+ * serverless the request's `waitUntil` keeps the function alive for them.
164
+ */
165
+ export declare function runAfterWriteDrains(waitUntil?: (promise: Promise<unknown>) => void): void;
166
+ export {};