@agent-native/core 0.209.0 → 0.209.1-nightly-20261015093558
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/dist/a2a/task-store.d.ts +1 -0
- package/dist/a2a/task-store.js +63 -62
- package/dist/action-call-classification.d.ts +15 -0
- package/dist/action-call-classification.js +24 -0
- package/dist/action-input-coercion.d.ts +10 -0
- package/dist/action-input-coercion.js +77 -0
- package/dist/action.d.ts +19 -1
- package/dist/action.js +37 -74
- package/dist/agent/engine/ai-sdk-engine.js +21 -4
- package/dist/agent/engine/continuation-dispatch-retry.d.ts +3 -0
- package/dist/agent/engine/continuation-dispatch-retry.js +53 -6
- package/dist/agent/harness/store.d.ts +1 -0
- package/dist/agent/harness/store.js +14 -16
- package/dist/agent/observational-memory/store.d.ts +1 -0
- package/dist/agent/observational-memory/store.js +28 -24
- package/dist/agent/production-agent.d.ts +16 -1
- package/dist/agent/production-agent.js +63 -10
- package/dist/agent/run-store.d.ts +1 -0
- package/dist/agent/run-store.js +61 -56
- package/dist/agent/tool-approval-store.d.ts +2 -0
- package/dist/agent/tool-approval-store.js +31 -29
- package/dist/app-config/migration.d.ts +1 -0
- package/dist/app-config/migration.js +4 -0
- package/dist/app-config/schema.d.ts +1 -0
- package/dist/application-state/store.d.ts +1 -0
- package/dist/application-state/store.js +36 -25
- package/dist/audit/store.d.ts +1 -0
- package/dist/audit/store.js +26 -28
- package/dist/browser-sessions/store.d.ts +1 -0
- package/dist/browser-sessions/store.js +15 -17
- package/dist/chat-threads/store.d.ts +1 -0
- package/dist/chat-threads/store.js +26 -19
- package/dist/checkpoints/store.d.ts +1 -0
- package/dist/checkpoints/store.js +19 -18
- package/dist/client/agent-sidebar-state.d.ts +1 -1
- package/dist/client/agent-sidebar-state.js +97 -5
- package/dist/coding-tools/run-code.js +5 -2
- package/dist/coding-tools/sandbox/executions-store.d.ts +1 -0
- package/dist/coding-tools/sandbox/executions-store.js +29 -30
- package/dist/collab/awareness-store.d.ts +1 -0
- package/dist/collab/awareness-store.js +15 -19
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/storage.d.ts +1 -0
- package/dist/collab/storage.js +25 -24
- package/dist/data-programs/store.d.ts +1 -0
- package/dist/data-programs/store.js +25 -24
- package/dist/db/client.d.ts +1 -1
- package/dist/db/client.js +10 -30
- package/dist/db/ddl-guard.js +11 -3
- package/dist/db/index.d.ts +1 -1
- package/dist/db/index.js +1 -1
- package/dist/db/migration-policy.d.ts +2 -0
- package/dist/db/migration-policy.js +4 -0
- package/dist/db/runtime-facts.d.ts +11 -0
- package/dist/db/runtime-facts.js +41 -0
- package/dist/db/schema-catalog.d.ts +17 -0
- package/dist/db/schema-catalog.js +156 -0
- package/dist/db/store-registry.d.ts +85 -0
- package/dist/db/store-registry.generated.d.ts +2 -0
- package/dist/db/store-registry.generated.js +273 -0
- package/dist/db/store-registry.js +354 -0
- package/dist/db/widen-columns.js +7 -2
- package/dist/email-catalog/log.d.ts +1 -0
- package/dist/email-catalog/log.js +37 -25
- package/dist/extensions/slots/store.d.ts +1 -0
- package/dist/extensions/slots/store.js +20 -21
- package/dist/extensions/store.d.ts +1 -0
- package/dist/extensions/store.js +41 -26
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/guards/identity-columns-registered.js +5 -0
- package/dist/guards/release-schema-complete.d.ts +7 -13
- package/dist/guards/release-schema-complete.js +67 -32
- package/dist/guards/store-migrations-lock.d.ts +18 -0
- package/dist/guards/store-migrations-lock.js +49 -0
- package/dist/guards/store-registry-codegen.d.ts +16 -0
- package/dist/guards/store-registry-codegen.js +90 -0
- package/dist/history/store.d.ts +1 -0
- package/dist/history/store.js +20 -18
- package/dist/identity/retired-emails.d.ts +1 -0
- package/dist/identity/retired-emails.js +14 -13
- package/dist/integrations/a2a-continuations-store.d.ts +1 -0
- package/dist/integrations/a2a-continuations-store.js +46 -33
- package/dist/integrations/awaiting-input-store.d.ts +1 -0
- package/dist/integrations/awaiting-input-store.js +15 -19
- package/dist/integrations/computer-supervision-store.d.ts +1 -0
- package/dist/integrations/computer-supervision-store.js +15 -21
- package/dist/integrations/config-store.d.ts +1 -0
- package/dist/integrations/config-store.js +14 -16
- package/dist/integrations/controls-store.d.ts +1 -0
- package/dist/integrations/controls-store.js +15 -16
- package/dist/integrations/identity-links-store.d.ts +1 -0
- package/dist/integrations/identity-links-store.js +14 -21
- package/dist/integrations/installations-store.d.ts +1 -0
- package/dist/integrations/installations-store.js +15 -23
- package/dist/integrations/integration-campaigns-store.d.ts +1 -0
- package/dist/integrations/integration-campaigns-store.js +16 -23
- package/dist/integrations/pending-tasks-store.d.ts +1 -0
- package/dist/integrations/pending-tasks-store.js +16 -18
- package/dist/integrations/remote-commands-store.d.ts +1 -0
- package/dist/integrations/remote-commands-store.js +14 -16
- package/dist/integrations/remote-devices-store.d.ts +1 -0
- package/dist/integrations/remote-devices-store.js +39 -38
- package/dist/integrations/remote-push-store.d.ts +1 -0
- package/dist/integrations/remote-push-store.js +25 -24
- package/dist/integrations/remote-run-events-store.d.ts +1 -0
- package/dist/integrations/remote-run-events-store.js +17 -16
- package/dist/integrations/scope-store.d.ts +1 -0
- package/dist/integrations/scope-store.js +18 -36
- package/dist/integrations/thread-mapping-store.d.ts +1 -0
- package/dist/integrations/thread-mapping-store.js +25 -24
- package/dist/integrations/usage-budget-store.d.ts +1 -0
- package/dist/integrations/usage-budget-store.js +40 -49
- package/dist/jobs/actions/manage-recurring-job.d.ts +1 -1
- package/dist/jobs/automation-work-evidence.js +7 -3
- package/dist/jobs/run-history.d.ts +1 -0
- package/dist/jobs/run-history.js +38 -40
- package/dist/jobs/scheduler-health.d.ts +1 -0
- package/dist/jobs/scheduler-health.js +28 -30
- package/dist/mcp/approval-store.d.ts +1 -0
- package/dist/mcp/approval-store.js +23 -24
- package/dist/mcp/connect-store.d.ts +1 -0
- package/dist/mcp/connect-store.js +50 -49
- package/dist/mcp/oauth-store.d.ts +1 -0
- package/dist/mcp/oauth-store.js +24 -23
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/mcp-client/oauth-routes.js +20 -13
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/notifications/store.d.ts +1 -0
- package/dist/notifications/store.js +14 -16
- package/dist/oauth-tokens/store.d.ts +1 -0
- package/dist/oauth-tokens/store.js +45 -31
- package/dist/observability/store.d.ts +1 -0
- package/dist/observability/store.js +24 -26
- package/dist/org/index.d.ts +1 -1
- package/dist/org/service-principal-policy.d.ts +1 -0
- package/dist/org/service-principal-policy.js +29 -28
- package/dist/progress/routes.d.ts +1 -1
- package/dist/progress/store.d.ts +1 -0
- package/dist/progress/store.js +27 -29
- package/dist/provider-api/actions/custom-provider-registration.d.ts +8 -8
- package/dist/provider-api/actions/provider-api.d.ts +14 -9
- package/dist/provider-api/actions/provider-api.js +16 -1
- package/dist/provider-api/actions/staged-datasets.js +10 -2
- package/dist/provider-api/corpus-jobs-store.d.ts +1 -0
- package/dist/provider-api/corpus-jobs-store.js +81 -79
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/provider-api/corpus-jobs.js +43 -6
- package/dist/provider-api/custom-registry.d.ts +1 -0
- package/dist/provider-api/custom-registry.js +23 -17
- package/dist/provider-api/index.js +34 -2
- package/dist/provider-api/quota-governor.d.ts +1 -0
- package/dist/provider-api/quota-governor.js +33 -26
- package/dist/provider-api/staged-datasets-store.d.ts +57 -0
- package/dist/provider-api/staged-datasets-store.js +311 -149
- package/dist/provider-api/staging.js +14 -4
- package/dist/resource-changes/store.d.ts +1 -0
- package/dist/resource-changes/store.js +8 -7
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/resources/store.d.ts +1 -0
- package/dist/resources/store.js +92 -56
- package/dist/review/store.d.ts +1 -0
- package/dist/review/store.js +27 -25
- package/dist/review/suggestions/store.d.ts +1 -0
- package/dist/review/suggestions/store.js +56 -50
- package/dist/search/index-store.d.ts +2 -2
- package/dist/search/index-store.js +6 -7
- package/dist/secrets/storage.d.ts +1 -0
- package/dist/secrets/storage.js +18 -17
- package/dist/server/action-discovery.js +6 -0
- package/dist/server/agent-chat/action-filters-a2a.js +11 -0
- package/dist/server/agent-chat/framework-prompts.js +6 -2
- package/dist/server/agent-chat-plugin.js +8 -16
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agent-engine-default-model-route.d.ts +1 -1
- package/dist/server/agent-engine-ollama-models-route.d.ts +2 -2
- package/dist/server/agent-teams-run-queue.d.ts +1 -0
- package/dist/server/agent-teams-run-queue.js +21 -20
- package/dist/server/auth.d.ts +1 -0
- package/dist/server/auth.js +20 -17
- package/dist/server/embed-session.d.ts +1 -0
- package/dist/server/embed-session.js +34 -33
- package/dist/server/filesystem-action-entry.d.ts +7 -0
- package/dist/server/filesystem-action-entry.js +35 -0
- package/dist/server/google-oauth.d.ts +8 -0
- package/dist/server/google-oauth.js +8 -5
- package/dist/server/identity-sso-store.d.ts +1 -0
- package/dist/server/identity-sso-store.js +18 -27
- package/dist/server/poll.d.ts +2 -0
- package/dist/server/poll.js +74 -29
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/recap-image-store.d.ts +1 -0
- package/dist/server/recap-image-store.js +15 -14
- package/dist/server/release-migrations.js +54 -49
- package/dist/server/release-schema.d.ts +8 -27
- package/dist/server/release-schema.js +41 -314
- package/dist/server/request-context.d.ts +3 -0
- package/dist/server/self-dispatch.d.ts +9 -0
- package/dist/server/self-dispatch.js +20 -1
- package/dist/settings/store.d.ts +1 -0
- package/dist/settings/store.js +33 -23
- package/dist/shared/analytics-events.js +1 -0
- package/dist/sharing/access-request-store.d.ts +1 -0
- package/dist/sharing/access-request-store.js +17 -16
- package/dist/sharing/indexes.js +1 -0
- package/dist/templates/chat/.agents/skills/storing-data/SKILL.md +2 -2
- package/dist/templates/default/.agents/skills/storing-data/SKILL.md +2 -2
- package/dist/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +5 -0
- package/dist/templates/factory/.agents/skills/review-latest-feedback/references/chat-run-health.md +50 -0
- package/dist/templates/headless/.agents/skills/storing-data/SKILL.md +2 -2
- package/dist/templates/workspace-core/.agents/skills/storing-data/SKILL.md +2 -2
- package/dist/triggers/actions/manage-automation.d.ts +2 -2
- package/dist/triggers/event-queue.js +1 -0
- package/dist/triggers/webhook-store.d.ts +1 -0
- package/dist/triggers/webhook-store.js +14 -18
- package/dist/usage/alerts-store.d.ts +1 -0
- package/dist/usage/alerts-store.js +47 -48
- package/dist/usage/store.d.ts +1 -0
- package/dist/usage/store.js +67 -59
- package/dist/workspace-connections/groups.d.ts +1 -0
- package/dist/workspace-connections/groups.js +30 -42
- package/dist/workspace-connections/store.d.ts +1 -0
- package/dist/workspace-connections/store.js +17 -19
- package/docs/content/create-with-an-agent.mdx +160 -0
- package/docs/content/getting-started.mdx +3 -0
- package/docs/content/integrations.mdx +6 -2
- package/docs/content/template-clips-features.mdx +1 -1
- package/docs/content/tracking.mdx +1 -1
- package/package.json +4 -4
- package/src/templates/chat/.agents/skills/storing-data/SKILL.md +2 -2
- package/src/templates/default/.agents/skills/storing-data/SKILL.md +2 -2
- package/src/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +5 -0
- package/src/templates/factory/.agents/skills/review-latest-feedback/references/chat-run-health.md +50 -0
- package/src/templates/headless/.agents/skills/storing-data/SKILL.md +2 -2
- package/src/templates/workspace-core/.agents/skills/storing-data/SKILL.md +2 -2
package/dist/a2a/task-store.d.ts
CHANGED
package/dist/a2a/task-store.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import crypto from "crypto";
|
|
2
2
|
import { getDbExec } from "../db/client.js";
|
|
3
3
|
import { ensureTableExists, ensureColumnExists, ensureIndexExists, } from "../db/ddl-guard.js";
|
|
4
|
-
import {
|
|
4
|
+
import { defineStore } from "../db/store-registry.js";
|
|
5
5
|
import { assertA2APersistablePayload } from "./persistence-safety.js";
|
|
6
|
-
let _initPromise;
|
|
7
6
|
export const MAX_A2A_IDEMPOTENCY_KEY_CHARS = 128;
|
|
8
7
|
const A2A_IDEMPOTENCY_INDEX = "idx_a2a_tasks_owner_scope_idempotency";
|
|
9
8
|
const A2A_ORG_IDEMPOTENCY_INDEX = "idx_a2a_tasks_org_scope_idempotency";
|
|
@@ -11,66 +10,68 @@ const A2A_RECOVERY_INDEX = "idx_a2a_tasks_recovery_created";
|
|
|
11
10
|
export const A2A_PERSONAL_OWNER_SCOPE = "__personal__";
|
|
12
11
|
export const A2A_ORG_ID_OWNER_SCOPE_PREFIX = "__a2a_org_id__:";
|
|
13
12
|
const MAX_TASK_LIST_PAGE_SIZE = 100;
|
|
14
|
-
export
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
13
|
+
export const a2aTasksStore = defineStore({
|
|
14
|
+
id: "a2a_tasks",
|
|
15
|
+
migrations: [
|
|
16
|
+
{
|
|
17
|
+
name: "baseline",
|
|
18
|
+
run: async () => {
|
|
19
|
+
const createSql = `
|
|
20
|
+
CREATE TABLE IF NOT EXISTS a2a_tasks (
|
|
21
|
+
id TEXT PRIMARY KEY,
|
|
22
|
+
context_id TEXT,
|
|
23
|
+
status_state TEXT NOT NULL DEFAULT 'submitted',
|
|
24
|
+
status_message TEXT,
|
|
25
|
+
status_timestamp TEXT NOT NULL,
|
|
26
|
+
history TEXT NOT NULL DEFAULT '[]',
|
|
27
|
+
artifacts TEXT NOT NULL DEFAULT '[]',
|
|
28
|
+
metadata TEXT,
|
|
29
|
+
owner_email TEXT,
|
|
30
|
+
owner_scope TEXT NOT NULL DEFAULT '',
|
|
31
|
+
idempotency_key TEXT,
|
|
32
|
+
created_at BIGINT NOT NULL,
|
|
33
|
+
updated_at BIGINT NOT NULL
|
|
34
|
+
)
|
|
35
|
+
`;
|
|
36
|
+
const createIdempotencyIndexSql = `CREATE UNIQUE INDEX IF NOT EXISTS ${A2A_IDEMPOTENCY_INDEX} ` +
|
|
37
|
+
`ON a2a_tasks(owner_email, owner_scope, idempotency_key)`;
|
|
38
|
+
const createOrgIdempotencyIndexSql = `CREATE UNIQUE INDEX IF NOT EXISTS ${A2A_ORG_IDEMPOTENCY_INDEX} ` +
|
|
39
|
+
"ON a2a_tasks(owner_scope, idempotency_key) " +
|
|
40
|
+
"WHERE owner_email IS NULL AND idempotency_key IS NOT NULL";
|
|
41
|
+
const createRecoveryIndexSql = `CREATE INDEX IF NOT EXISTS ${A2A_RECOVERY_INDEX} ` +
|
|
42
|
+
"ON a2a_tasks(created_at) " +
|
|
43
|
+
"WHERE status_state IN ('submitted', 'working', 'processing')";
|
|
44
|
+
const createApprovalsSql = `
|
|
45
|
+
CREATE TABLE IF NOT EXISTS a2a_approvals (
|
|
46
|
+
id TEXT PRIMARY KEY,
|
|
47
|
+
task_id TEXT NOT NULL UNIQUE,
|
|
48
|
+
owner_email TEXT NOT NULL,
|
|
49
|
+
org_id TEXT,
|
|
50
|
+
tool_name TEXT NOT NULL,
|
|
51
|
+
tool_input TEXT NOT NULL,
|
|
52
|
+
approval_key TEXT NOT NULL,
|
|
53
|
+
call_id TEXT NOT NULL,
|
|
54
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
55
|
+
result TEXT,
|
|
56
|
+
expires_at BIGINT NOT NULL,
|
|
57
|
+
created_at BIGINT NOT NULL,
|
|
58
|
+
updated_at BIGINT NOT NULL
|
|
59
|
+
)
|
|
60
|
+
`;
|
|
61
|
+
await ensureTableExists("a2a_tasks", createSql);
|
|
62
|
+
await ensureColumnExists("a2a_tasks", "owner_email", `ALTER TABLE a2a_tasks ADD COLUMN IF NOT EXISTS owner_email TEXT`);
|
|
63
|
+
await ensureColumnExists("a2a_tasks", "owner_scope", `ALTER TABLE a2a_tasks ADD COLUMN IF NOT EXISTS owner_scope TEXT NOT NULL DEFAULT ''`);
|
|
64
|
+
await ensureColumnExists("a2a_tasks", "idempotency_key", `ALTER TABLE a2a_tasks ADD COLUMN IF NOT EXISTS idempotency_key TEXT`);
|
|
65
|
+
await ensureIndexExists(A2A_IDEMPOTENCY_INDEX, createIdempotencyIndexSql);
|
|
66
|
+
await ensureIndexExists(A2A_ORG_IDEMPOTENCY_INDEX, createOrgIdempotencyIndexSql);
|
|
67
|
+
await ensureIndexExists(A2A_RECOVERY_INDEX, createRecoveryIndexSql);
|
|
68
|
+
await ensureTableExists("a2a_approvals", createApprovalsSql);
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
});
|
|
73
|
+
export function ensureTable() {
|
|
74
|
+
return a2aTasksStore.ready();
|
|
74
75
|
}
|
|
75
76
|
async function withDbTransaction(client, fn) {
|
|
76
77
|
if (client.transaction)
|
|
@@ -1,8 +1,23 @@
|
|
|
1
1
|
import type { ActionChangeResource, ActionPlanModeConfig } from "./action.js";
|
|
2
|
+
import type { ActionTool } from "./agent/types.js";
|
|
2
3
|
export declare function actionCallIsReadOnly(entry: {
|
|
3
4
|
readOnly?: boolean;
|
|
4
5
|
planMode?: ActionPlanModeConfig<any>;
|
|
5
6
|
}, params: unknown, fallback: boolean): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Whether re-running this call after an error or a lost result is safe. An
|
|
9
|
+
* action opts in with `retrySafe`; an undeclared action is not, so an
|
|
10
|
+
* ambiguous write keeps blocking the run. A predicate sees the arguments after
|
|
11
|
+
* the same gateway-string repair schema validation applies (`"true"` already
|
|
12
|
+
* `true`), never the raw model input a stringified flag could slip past a
|
|
13
|
+
* strict comparison in.
|
|
14
|
+
*/
|
|
15
|
+
export declare function actionCallIsRetrySafe(entry: {
|
|
16
|
+
retrySafe?: boolean | ((input: any) => boolean);
|
|
17
|
+
tool?: {
|
|
18
|
+
parameters?: ActionTool["parameters"];
|
|
19
|
+
};
|
|
20
|
+
}, params: unknown): boolean;
|
|
6
21
|
/**
|
|
7
22
|
* Whether a successful call should publish an `action` change event.
|
|
8
23
|
*
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { coerceGatewayStringifiedArgs } from "./action-input-coercion.js";
|
|
1
2
|
export function actionCallIsReadOnly(entry, params, fallback) {
|
|
2
3
|
const effect = entry.planMode?.effect;
|
|
3
4
|
if (typeof effect === "string")
|
|
@@ -15,6 +16,29 @@ export function actionCallIsReadOnly(entry, params, fallback) {
|
|
|
15
16
|
return entry.readOnly;
|
|
16
17
|
return fallback;
|
|
17
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Whether re-running this call after an error or a lost result is safe. An
|
|
21
|
+
* action opts in with `retrySafe`; an undeclared action is not, so an
|
|
22
|
+
* ambiguous write keeps blocking the run. A predicate sees the arguments after
|
|
23
|
+
* the same gateway-string repair schema validation applies (`"true"` already
|
|
24
|
+
* `true`), never the raw model input a stringified flag could slip past a
|
|
25
|
+
* strict comparison in.
|
|
26
|
+
*/
|
|
27
|
+
export function actionCallIsRetrySafe(entry, params) {
|
|
28
|
+
const { retrySafe } = entry;
|
|
29
|
+
if (typeof retrySafe === "boolean")
|
|
30
|
+
return retrySafe;
|
|
31
|
+
if (typeof retrySafe !== "function")
|
|
32
|
+
return false;
|
|
33
|
+
try {
|
|
34
|
+
return (retrySafe(coerceGatewayStringifiedArgs(params, entry.tool?.parameters)) === true);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// coercion-ok: a throwing predicate declares nothing, so the call stays
|
|
38
|
+
// conservative (blocked) rather than being treated as safe to replay.
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
18
42
|
/**
|
|
19
43
|
* Whether a successful call should publish an `action` change event.
|
|
20
44
|
*
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ActionTool } from "./agent/types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The repair a tool call's arguments get before schema validation: a gateway
|
|
4
|
+
* that stringifies `true`, `3`, or a JSON array/object is undone per the
|
|
5
|
+
* declared parameter type. Anything that reads a call's input to decide what
|
|
6
|
+
* the handler will do (`retrySafe`) must see this form, not the raw model
|
|
7
|
+
* input, or a stringified flag passes a strict comparison and still runs as
|
|
8
|
+
* `true`.
|
|
9
|
+
*/
|
|
10
|
+
export declare function coerceGatewayStringifiedArgs(args: unknown, parameters?: ActionTool["parameters"]): unknown;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const NO_COERCE = Symbol("no-coerce");
|
|
2
|
+
function coerceStringToSchemaType(raw, types) {
|
|
3
|
+
const trimmed = raw.trim();
|
|
4
|
+
if (types.includes("boolean")) {
|
|
5
|
+
if (trimmed === "true")
|
|
6
|
+
return true;
|
|
7
|
+
if (trimmed === "false")
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
if ((types.includes("array") &&
|
|
11
|
+
trimmed.startsWith("[") &&
|
|
12
|
+
trimmed.endsWith("]")) ||
|
|
13
|
+
(types.includes("object") &&
|
|
14
|
+
trimmed.startsWith("{") &&
|
|
15
|
+
trimmed.endsWith("}"))) {
|
|
16
|
+
try {
|
|
17
|
+
const parsed = JSON.parse(trimmed);
|
|
18
|
+
if (types.includes("array") && Array.isArray(parsed))
|
|
19
|
+
return parsed;
|
|
20
|
+
if (types.includes("object") &&
|
|
21
|
+
parsed &&
|
|
22
|
+
typeof parsed === "object" &&
|
|
23
|
+
!Array.isArray(parsed)) {
|
|
24
|
+
return parsed;
|
|
25
|
+
}
|
|
26
|
+
// coercion-ok: unparseable text stays a string and schema validation rejects it
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// fall through — leave the original so validation reports the real error
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if ((types.includes("number") || types.includes("integer")) &&
|
|
33
|
+
trimmed !== "" &&
|
|
34
|
+
Number.isFinite(Number(trimmed))) {
|
|
35
|
+
const n = Number(trimmed);
|
|
36
|
+
if (types.includes("number") || Number.isInteger(n))
|
|
37
|
+
return n;
|
|
38
|
+
}
|
|
39
|
+
return NO_COERCE;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The repair a tool call's arguments get before schema validation: a gateway
|
|
43
|
+
* that stringifies `true`, `3`, or a JSON array/object is undone per the
|
|
44
|
+
* declared parameter type. Anything that reads a call's input to decide what
|
|
45
|
+
* the handler will do (`retrySafe`) must see this form, not the raw model
|
|
46
|
+
* input, or a stringified flag passes a strict comparison and still runs as
|
|
47
|
+
* `true`.
|
|
48
|
+
*/
|
|
49
|
+
export function coerceGatewayStringifiedArgs(args, parameters) {
|
|
50
|
+
const properties = parameters?.properties;
|
|
51
|
+
if (!properties)
|
|
52
|
+
return args;
|
|
53
|
+
if (!args || typeof args !== "object" || Array.isArray(args))
|
|
54
|
+
return args;
|
|
55
|
+
let out = null;
|
|
56
|
+
for (const [key, raw] of Object.entries(args)) {
|
|
57
|
+
if (typeof raw !== "string")
|
|
58
|
+
continue;
|
|
59
|
+
const spec = properties[key];
|
|
60
|
+
if (!spec)
|
|
61
|
+
continue;
|
|
62
|
+
const types = Array.isArray(spec.type)
|
|
63
|
+
? spec.type
|
|
64
|
+
: spec.type
|
|
65
|
+
? [spec.type]
|
|
66
|
+
: [];
|
|
67
|
+
if (types.length === 0 || types.includes("string"))
|
|
68
|
+
continue;
|
|
69
|
+
const coerced = coerceStringToSchemaType(raw, types);
|
|
70
|
+
if (coerced === NO_COERCE)
|
|
71
|
+
continue;
|
|
72
|
+
if (!out)
|
|
73
|
+
out = { ...args };
|
|
74
|
+
out[key] = coerced;
|
|
75
|
+
}
|
|
76
|
+
return out ?? args;
|
|
77
|
+
}
|
package/dist/action.d.ts
CHANGED
|
@@ -3,6 +3,11 @@ import { type ActionChatUIConfig } from "./action-ui.js";
|
|
|
3
3
|
import type { ActionTool, AgentChatAttachment, AgentChatEvent } from "./agent/types.js";
|
|
4
4
|
import type { ActionAuditConfig } from "./audit/types.js";
|
|
5
5
|
import { type ActionAccessConfig } from "./authorization/action-access-runtime.js";
|
|
6
|
+
/**
|
|
7
|
+
* Carries an action's execution-frame key across `{ ...entry, run }` wrappers
|
|
8
|
+
* and the registry rebuilds that copy named fields (`preserveActionFlags`).
|
|
9
|
+
*/
|
|
10
|
+
export declare const ACTION_EXECUTION_KEY: unique symbol;
|
|
6
11
|
export type ActionCaller = "tool" | "http" | "frontend" | "mcp-widget" | "mcp-widget-write" | "cli" | "mcp" | "webmcp" | "a2a" | "automation";
|
|
7
12
|
export interface ActionAutomationContext {
|
|
8
13
|
triggerId: string;
|
|
@@ -308,6 +313,16 @@ interface DefineActionWithSchema<TSchema extends StandardSchemaV1, TReturn = any
|
|
|
308
313
|
* names); return `null` when the call touches no resource or changed nothing. */
|
|
309
314
|
changeResource?: (input: StandardSchemaV1.InferInput<TSchema>, result: TReturn) => ActionChangeResource | null | undefined;
|
|
310
315
|
parallelSafe?: boolean;
|
|
316
|
+
/**
|
|
317
|
+
* Re-running this write after an error or a lost result cannot duplicate or
|
|
318
|
+
* corrupt data: it validates before it writes, or it sets an end state
|
|
319
|
+
* (replace-by-id, search-and-replace that fails loudly on a second run). The
|
|
320
|
+
* agent loop then lets the model correct its arguments and retry instead of
|
|
321
|
+
* ending the run as `write_tool_outcome_unknown`. Pass a predicate when only
|
|
322
|
+
* some inputs qualify. Do not set it on an action that appends, sends, or
|
|
323
|
+
* charges.
|
|
324
|
+
*/
|
|
325
|
+
retrySafe?: boolean | ((input: StandardSchemaV1.InferInput<TSchema>) => boolean);
|
|
311
326
|
endsTurn?: boolean;
|
|
312
327
|
dedupe?: boolean;
|
|
313
328
|
toolCallable?: boolean;
|
|
@@ -373,6 +388,8 @@ interface DefineActionWithParams<TParams extends Record<string, ParameterSchema>
|
|
|
373
388
|
persistInBrowser?: boolean;
|
|
374
389
|
changeResource?: (input: InferParams<TParams>, result: TReturn) => ActionChangeResource | null | undefined;
|
|
375
390
|
parallelSafe?: boolean;
|
|
391
|
+
/** See `ActionDefinition.retrySafe`. */
|
|
392
|
+
retrySafe?: boolean | ((input: InferParams<TParams>) => boolean);
|
|
376
393
|
endsTurn?: boolean;
|
|
377
394
|
dedupe?: boolean;
|
|
378
395
|
toolCallable?: boolean;
|
|
@@ -409,6 +426,7 @@ export interface ActionDefinition<TInput, TReturn> {
|
|
|
409
426
|
readonly persistInBrowser?: boolean;
|
|
410
427
|
readonly changeResource?: (input: TInput, result: TReturn) => ActionChangeResource | null | undefined;
|
|
411
428
|
readonly parallelSafe?: boolean;
|
|
429
|
+
readonly retrySafe?: boolean | ((input: TInput) => boolean);
|
|
412
430
|
readonly endsTurn?: boolean;
|
|
413
431
|
readonly dedupe?: boolean;
|
|
414
432
|
readonly toolCallable?: boolean;
|
|
@@ -449,6 +467,6 @@ type ActionExecutionRun = (args: any, ctx?: ActionRunContext) => Promise<any>;
|
|
|
449
467
|
/** @internal Observe one public action invocation without transferring child refusals. */
|
|
450
468
|
export declare function runActionWithExecutionOutcome(run: ActionExecutionRun, args: unknown, ctx: ActionRunContext | undefined, outcome: {
|
|
451
469
|
refused: boolean;
|
|
452
|
-
}): Promise<any>;
|
|
470
|
+
}, entry?: object): Promise<any>;
|
|
453
471
|
export declare function validateActionArgs(schema: StandardSchemaV1, args: unknown, toolParameters?: ActionTool["parameters"], ctx?: object): Promise<any>;
|
|
454
472
|
export {};
|
package/dist/action.js
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
|
+
import { coerceGatewayStringifiedArgs } from "./action-input-coercion.js";
|
|
1
2
|
import { normalizeActionChatUIConfig, } from "./action-ui.js";
|
|
2
3
|
import { normalizeAuditConfig, resolveAuditAttach } from "./audit/config.js";
|
|
3
4
|
import { assertRegisteredActionAccess, } from "./authorization/action-access-runtime.js";
|
|
4
5
|
import { parseServiceIdentityEmail } from "./org/service-identity.js";
|
|
5
6
|
import { getAsyncLocalStorageCtor } from "./shared/optional-node-builtins.js";
|
|
6
7
|
import { wrapRunWithActionTracking } from "./tracking/action-lifecycle.js";
|
|
8
|
+
/**
|
|
9
|
+
* Carries an action's execution-frame key across `{ ...entry, run }` wrappers
|
|
10
|
+
* and the registry rebuilds that copy named fields (`preserveActionFlags`).
|
|
11
|
+
*/
|
|
12
|
+
export const ACTION_EXECUTION_KEY = Symbol.for("agent-native.action.executionKey");
|
|
7
13
|
export class ActionContractError extends Error {
|
|
8
14
|
actionContractError = true;
|
|
9
15
|
errorCode;
|
|
@@ -175,6 +181,10 @@ export function defineAction(options) {
|
|
|
175
181
|
const parallelSafe = typeof options.parallelSafe === "boolean"
|
|
176
182
|
? options.parallelSafe
|
|
177
183
|
: undefined;
|
|
184
|
+
const retrySafe = typeof options.retrySafe === "boolean" ||
|
|
185
|
+
typeof options.retrySafe === "function"
|
|
186
|
+
? options.retrySafe
|
|
187
|
+
: undefined;
|
|
178
188
|
const endsTurn = typeof options.endsTurn === "boolean" ? options.endsTurn : undefined;
|
|
179
189
|
const dedupe = typeof options.dedupe === "boolean" ? options.dedupe : undefined;
|
|
180
190
|
const publicAgent = options.publicAgent &&
|
|
@@ -204,7 +214,7 @@ export function defineAction(options) {
|
|
|
204
214
|
return undefined;
|
|
205
215
|
})();
|
|
206
216
|
const chatUI = normalizeActionChatUIConfig(options.chatUI);
|
|
207
|
-
|
|
217
|
+
const entry = {
|
|
208
218
|
tool: {
|
|
209
219
|
...(typeof options.title === "string" && options.title.trim()
|
|
210
220
|
? { title: options.title.trim() }
|
|
@@ -252,6 +262,7 @@ export function defineAction(options) {
|
|
|
252
262
|
? { changeResource: options.changeResource }
|
|
253
263
|
: {}),
|
|
254
264
|
...(typeof parallelSafe === "boolean" ? { parallelSafe } : {}),
|
|
265
|
+
...(retrySafe !== undefined ? { retrySafe } : {}),
|
|
255
266
|
...(typeof endsTurn === "boolean" ? { endsTurn } : {}),
|
|
256
267
|
...(typeof dedupe === "boolean" ? { dedupe } : {}),
|
|
257
268
|
...(typeof toolCallable === "boolean" ? { toolCallable } : {}),
|
|
@@ -288,6 +299,15 @@ export function defineAction(options) {
|
|
|
288
299
|
...(auditConfig ? { audit: auditConfig } : {}),
|
|
289
300
|
...(options.access ? { access: options.access } : {}),
|
|
290
301
|
};
|
|
302
|
+
// Enumerable on purpose: an app that wraps `run` with `{ ...entry, run }`
|
|
303
|
+
// keeps the key, so the loop can still tell a pre-handler refusal from a
|
|
304
|
+
// handler failure. Without it the wrapper's own frame never becomes the
|
|
305
|
+
// action's frame and every validation error reads as an unknown write.
|
|
306
|
+
Object.defineProperty(entry, ACTION_EXECUTION_KEY, {
|
|
307
|
+
value: executionKey,
|
|
308
|
+
enumerable: true,
|
|
309
|
+
});
|
|
310
|
+
return entry;
|
|
291
311
|
}
|
|
292
312
|
export function isActionExposedToExternalAgents(entry) {
|
|
293
313
|
if (entry.uiOnly === true)
|
|
@@ -671,74 +691,6 @@ function zodDefToJsonSchema(def) {
|
|
|
671
691
|
}
|
|
672
692
|
return { type: "string" };
|
|
673
693
|
}
|
|
674
|
-
const NO_COERCE = Symbol("no-coerce");
|
|
675
|
-
function coerceStringToSchemaType(raw, types) {
|
|
676
|
-
const trimmed = raw.trim();
|
|
677
|
-
if (types.includes("boolean")) {
|
|
678
|
-
if (trimmed === "true")
|
|
679
|
-
return true;
|
|
680
|
-
if (trimmed === "false")
|
|
681
|
-
return false;
|
|
682
|
-
}
|
|
683
|
-
if ((types.includes("array") &&
|
|
684
|
-
trimmed.startsWith("[") &&
|
|
685
|
-
trimmed.endsWith("]")) ||
|
|
686
|
-
(types.includes("object") &&
|
|
687
|
-
trimmed.startsWith("{") &&
|
|
688
|
-
trimmed.endsWith("}"))) {
|
|
689
|
-
try {
|
|
690
|
-
const parsed = JSON.parse(trimmed);
|
|
691
|
-
if (types.includes("array") && Array.isArray(parsed))
|
|
692
|
-
return parsed;
|
|
693
|
-
if (types.includes("object") &&
|
|
694
|
-
parsed &&
|
|
695
|
-
typeof parsed === "object" &&
|
|
696
|
-
!Array.isArray(parsed)) {
|
|
697
|
-
return parsed;
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
catch {
|
|
701
|
-
// fall through — leave the original so validation reports the real error
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
if ((types.includes("number") || types.includes("integer")) &&
|
|
705
|
-
trimmed !== "" &&
|
|
706
|
-
Number.isFinite(Number(trimmed))) {
|
|
707
|
-
const n = Number(trimmed);
|
|
708
|
-
if (types.includes("number") || Number.isInteger(n))
|
|
709
|
-
return n;
|
|
710
|
-
}
|
|
711
|
-
return NO_COERCE;
|
|
712
|
-
}
|
|
713
|
-
function coerceGatewayStringifiedArgs(args, parameters) {
|
|
714
|
-
const properties = parameters?.properties;
|
|
715
|
-
if (!properties)
|
|
716
|
-
return args;
|
|
717
|
-
if (!args || typeof args !== "object" || Array.isArray(args))
|
|
718
|
-
return args;
|
|
719
|
-
let out = null;
|
|
720
|
-
for (const [key, raw] of Object.entries(args)) {
|
|
721
|
-
if (typeof raw !== "string")
|
|
722
|
-
continue;
|
|
723
|
-
const spec = properties[key];
|
|
724
|
-
if (!spec)
|
|
725
|
-
continue;
|
|
726
|
-
const types = Array.isArray(spec.type)
|
|
727
|
-
? spec.type
|
|
728
|
-
: spec.type
|
|
729
|
-
? [spec.type]
|
|
730
|
-
: [];
|
|
731
|
-
if (types.length === 0 || types.includes("string"))
|
|
732
|
-
continue;
|
|
733
|
-
const coerced = coerceStringToSchemaType(raw, types);
|
|
734
|
-
if (coerced === NO_COERCE)
|
|
735
|
-
continue;
|
|
736
|
-
if (!out)
|
|
737
|
-
out = { ...args };
|
|
738
|
-
out[key] = coerced;
|
|
739
|
-
}
|
|
740
|
-
return out ?? args;
|
|
741
|
-
}
|
|
742
694
|
const MAX_SIGNATURE_DEPTH = 4;
|
|
743
695
|
const MAX_SIGNATURE_LENGTH = 1200;
|
|
744
696
|
function describeSchemaType(spec, depth) {
|
|
@@ -799,7 +751,8 @@ function wrapRunWithExecutionBoundary(run, key) {
|
|
|
799
751
|
if (!actionExecutionStorage)
|
|
800
752
|
return run(args, ctx);
|
|
801
753
|
const parent = actionExecutionStorage.getStore();
|
|
802
|
-
const frame = parent?.frame?.boundaryPending &&
|
|
754
|
+
const frame = parent?.frame?.boundaryPending &&
|
|
755
|
+
(parent.frame.run === boundaryRun || parent.frame.key === key)
|
|
803
756
|
? parent.frame
|
|
804
757
|
: {
|
|
805
758
|
key,
|
|
@@ -830,14 +783,19 @@ function wrapRunWithExecutionBoundary(run, key) {
|
|
|
830
783
|
return boundaryRun;
|
|
831
784
|
}
|
|
832
785
|
/** @internal Observe one public action invocation without transferring child refusals. */
|
|
833
|
-
export async function runActionWithExecutionOutcome(run, args, ctx, outcome) {
|
|
786
|
+
export async function runActionWithExecutionOutcome(run, args, ctx, outcome, entry) {
|
|
834
787
|
outcome.refused = false;
|
|
835
788
|
// A mutable async stack cannot safely attribute overlapping invocations.
|
|
836
789
|
if (!actionExecutionStorage)
|
|
837
790
|
return run(args, ctx);
|
|
838
791
|
const parent = actionExecutionStorage.getStore();
|
|
792
|
+
const entryKey = entry
|
|
793
|
+
? entry[ACTION_EXECUTION_KEY]
|
|
794
|
+
: undefined;
|
|
839
795
|
const frame = {
|
|
840
|
-
key
|
|
796
|
+
// The entry's own key lets its boundary adopt this frame when an app has
|
|
797
|
+
// wrapped `run`; an unkeyed entry gets a placeholder nothing can match.
|
|
798
|
+
key: entryKey !== null && typeof entryKey === "object" ? entryKey : {},
|
|
841
799
|
run,
|
|
842
800
|
parent: parent?.frame,
|
|
843
801
|
handlerEntered: true,
|
|
@@ -857,10 +815,15 @@ export async function runActionWithExecutionOutcome(run, args, ctx, outcome) {
|
|
|
857
815
|
? state.failures.get(error)
|
|
858
816
|
: undefined;
|
|
859
817
|
// Error types cannot prove non-execution once the handler has entered.
|
|
818
|
+
// A keyed entry whose boundary was never entered threw in an app
|
|
819
|
+
// wrapper around `run`, before any handler could start.
|
|
860
820
|
outcome.refused =
|
|
861
821
|
!frame.descendantWriteEntered &&
|
|
862
|
-
!frame.handlerEntered &&
|
|
863
|
-
|
|
822
|
+
((!frame.handlerEntered && failure === frame) ||
|
|
823
|
+
(frame.key !== undefined &&
|
|
824
|
+
frame.boundaryPending === true &&
|
|
825
|
+
entryKey !== null &&
|
|
826
|
+
typeof entryKey === "object"));
|
|
864
827
|
throw error;
|
|
865
828
|
}
|
|
866
829
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ssrfSafeFetch } from "../../extensions/url-safety.js";
|
|
2
2
|
import { clearProviderCredentialAuthFailure, readDeployCredentialEnv, recordProviderCredentialAuthFailure, } from "../../server/credential-provider.js";
|
|
3
|
-
import { allowsSamplingParams, anthropicManualThinkingBudget, normalizeReasoningEffortForModel, supportsClaudeAdaptiveThinking, } from "../../shared/reasoning-effort.js";
|
|
3
|
+
import { allowsSamplingParams, anthropicManualThinkingBudget, isGPTReasoningModel, normalizeReasoningEffortForModel, supportsClaudeAdaptiveThinking, } from "../../shared/reasoning-effort.js";
|
|
4
4
|
import { isNodeRuntime } from "../../shared/runtime.js";
|
|
5
5
|
import { AI_SDK_MODEL_CONFIG } from "../model-config.js";
|
|
6
6
|
import { LLM_MISSING_CREDENTIALS_ERROR_CODE, LLM_MISSING_CREDENTIALS_MESSAGE, } from "./credential-errors.js";
|
|
@@ -364,6 +364,18 @@ class AISDKEngine {
|
|
|
364
364
|
};
|
|
365
365
|
}
|
|
366
366
|
}
|
|
367
|
+
// @ai-sdk/openai infers reasoning models from its own id prefixes, which
|
|
368
|
+
// miss gpt-6-*. Without forceReasoning, Chat Completions sends max_tokens,
|
|
369
|
+
// which OpenAI rejects for reasoning models. isGPTReasoningModel also
|
|
370
|
+
// matches gpt-5-chat-*, which is not a reasoning model.
|
|
371
|
+
if (this.usesOpenAiChatCompletions() &&
|
|
372
|
+
isGPTReasoningModel(opts.model) &&
|
|
373
|
+
!/^(openai\/)?gpt-5-chat/i.test(opts.model)) {
|
|
374
|
+
providerOpts.openai = {
|
|
375
|
+
...(providerOpts.openai ?? {}),
|
|
376
|
+
forceReasoning: true,
|
|
377
|
+
};
|
|
378
|
+
}
|
|
367
379
|
const samplingAllowed = allowsSamplingParams({
|
|
368
380
|
model: opts.model,
|
|
369
381
|
thinkingEnabled: this.provider === "anthropic" &&
|
|
@@ -482,6 +494,13 @@ class AISDKEngine {
|
|
|
482
494
|
firstEventAbort.cleanup();
|
|
483
495
|
}
|
|
484
496
|
}
|
|
497
|
+
// Provider construction and the OpenAI reasoning options must agree on the
|
|
498
|
+
// endpoint shape, so both read this one decision.
|
|
499
|
+
usesOpenAiChatCompletions() {
|
|
500
|
+
return (this.provider === "openai" &&
|
|
501
|
+
!this.forceResponses &&
|
|
502
|
+
isCustomOpenAiBaseUrl(this.baseUrl));
|
|
503
|
+
}
|
|
485
504
|
async createProviderModel(model) {
|
|
486
505
|
const pkg = PROVIDER_PACKAGES[this.provider];
|
|
487
506
|
let providerModule;
|
|
@@ -511,9 +530,7 @@ class AISDKEngine {
|
|
|
511
530
|
config.appUrl = this.appUrl;
|
|
512
531
|
}
|
|
513
532
|
const provider = createFn(config);
|
|
514
|
-
return this.
|
|
515
|
-
!this.forceResponses &&
|
|
516
|
-
isCustomOpenAiBaseUrl(this.baseUrl)
|
|
533
|
+
return this.usesOpenAiChatCompletions()
|
|
517
534
|
? provider.chat(model)
|
|
518
535
|
: provider(model);
|
|
519
536
|
}
|
|
@@ -12,6 +12,9 @@ export declare function attemptContinuationDispatch(params: {
|
|
|
12
12
|
isLoopProtectionDispatchError: (err: unknown) => boolean;
|
|
13
13
|
maxNestedSelfDispatchDepth: number;
|
|
14
14
|
deps: ContinuationDispatchRetryDeps;
|
|
15
|
+
random?: () => number;
|
|
16
|
+
/** Wall clock for the overload budget; injectable so specs need no timers. */
|
|
17
|
+
now?: () => number;
|
|
15
18
|
}): Promise<{
|
|
16
19
|
dispatched: boolean;
|
|
17
20
|
lastDispatchErr: unknown;
|