@kingsoftcloud/agentkit-harness-node 0.0.0-stage → 0.0.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 (151) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +1 -0
  3. package/README.md +124 -2
  4. package/THIRD_PARTY_NOTICES.md +66 -0
  5. package/ZCode-LICENSE +202 -0
  6. package/dist/index.mjs +4871 -0
  7. package/dist/native-command-plan.LICENSE.txt +221 -0
  8. package/dist/native-command-plan.json +16 -0
  9. package/dist/native-command-plan.mjs +8 -0
  10. package/dist/rpc-entry.mjs +5682 -0
  11. package/package.json +169 -4
  12. package/src/native/a2a-receipt-source.mjs +19 -0
  13. package/src/native/a2a-tools.mjs +517 -0
  14. package/src/native/activity-status.mjs +30 -0
  15. package/src/native/artifact-codec.mjs +481 -0
  16. package/src/native/artifact-store.mjs +1162 -0
  17. package/src/native/assistant-stream.mjs +76 -0
  18. package/src/native/background-command-port.mjs +95 -0
  19. package/src/native/browser-action-observation.mjs +43 -0
  20. package/src/native/browser-availability.mjs +22 -0
  21. package/src/native/browser-canvas-metrics.mjs +71 -0
  22. package/src/native/browser-dom.mjs +193 -0
  23. package/src/native/browser-playwright.mjs +1249 -0
  24. package/src/native/browser-vision.mjs +369 -0
  25. package/src/native/browser-workspace-policy.mjs +22 -0
  26. package/src/native/browser-workspace-protocol.mjs +95 -0
  27. package/src/native/browser-workspace-server.mjs +164 -0
  28. package/src/native/browser-workspace.mjs +355 -0
  29. package/src/native/captured-source.mjs +3 -0
  30. package/src/native/child-budget-allocation.mjs +87 -0
  31. package/src/native/child-capabilities.mjs +35 -0
  32. package/src/native/child-command-resource.mjs +20 -0
  33. package/src/native/child-history.mjs +188 -0
  34. package/src/native/child-merge.mjs +98 -0
  35. package/src/native/child-model-surface.mjs +19 -0
  36. package/src/native/child-observation.mjs +100 -0
  37. package/src/native/child-owner.mjs +620 -0
  38. package/src/native/child-publication.mjs +76 -0
  39. package/src/native/child-readers.mjs +366 -0
  40. package/src/native/child-tools.mjs +46 -0
  41. package/src/native/child-workspace-binding.mjs +29 -0
  42. package/src/native/child-workspace-tools.mjs +1 -0
  43. package/src/native/child-workspaces.mjs +655 -0
  44. package/src/native/children.mjs +365 -0
  45. package/src/native/command-plan-worker.mjs +14 -0
  46. package/src/native/command-plan.mjs +31 -0
  47. package/src/native/command-progress.mjs +64 -0
  48. package/src/native/command-shell.mjs +9 -0
  49. package/src/native/command-workspace-observation.mjs +36 -0
  50. package/src/native/component-tools.mjs +280 -0
  51. package/src/native/context-counter.mjs +133 -0
  52. package/src/native/context-markers.mjs +51 -0
  53. package/src/native/context-profile.mjs +72 -0
  54. package/src/native/context-status.mjs +27 -0
  55. package/src/native/conversation-command-control.mjs +133 -0
  56. package/src/native/delivery-timeline.mjs +39 -0
  57. package/src/native/dsh-background-ownership.mjs +102 -0
  58. package/src/native/dsh-managed-ownership.mjs +23 -0
  59. package/src/native/dsh-turn-contract.mjs +3 -0
  60. package/src/native/dsh-turn-ownership.mjs +54 -0
  61. package/src/native/dsh-turn-runtime.mjs +498 -0
  62. package/src/native/e2b-background-supervisor.mjs +347 -0
  63. package/src/native/e2b-background.mjs +368 -0
  64. package/src/native/e2b-command-state.mjs +40 -0
  65. package/src/native/e2b-command-tools.mjs +486 -0
  66. package/src/native/e2b-sandbox-owner.mjs +227 -0
  67. package/src/native/hook-executor.mjs +249 -0
  68. package/src/native/instruction-assembly.mjs +60 -0
  69. package/src/native/instruction-context.mjs +54 -0
  70. package/src/native/local-background-supervisor.mjs +108 -0
  71. package/src/native/local-background.mjs +207 -0
  72. package/src/native/local-command-evidence.mjs +57 -0
  73. package/src/native/local-command-policy-worker.mjs +197 -0
  74. package/src/native/local-command-policy.mjs +46 -0
  75. package/src/native/local-command-state.mjs +177 -0
  76. package/src/native/local-command-tools.mjs +302 -0
  77. package/src/native/local-execution-profile.mjs +36 -0
  78. package/src/native/local-output-policy.mjs +92 -0
  79. package/src/native/local-process-bin/darwin-arm64/launcher +0 -0
  80. package/src/native/local-process-bin/darwin-x64/launcher +0 -0
  81. package/src/native/local-process-bin/linux-arm64/launcher +0 -0
  82. package/src/native/local-process-bin/linux-x64/launcher +0 -0
  83. package/src/native/local-process-launcher.c +183 -0
  84. package/src/native/local-process-licenses/GCC-COPYING.RUNTIME +72 -0
  85. package/src/native/local-process-licenses/GCC-COPYING3 +674 -0
  86. package/src/native/local-process-licenses/NOTICE +21 -0
  87. package/src/native/local-process-licenses/musl-COPYRIGHT +193 -0
  88. package/src/native/local-process-manifest.json +32 -0
  89. package/src/native/local-process.mjs +246 -0
  90. package/src/native/local-resource-profile.mjs +32 -0
  91. package/src/native/memory-candidate.mjs +121 -0
  92. package/src/native/memory-extraction-run.mjs +60 -0
  93. package/src/native/memory-extraction-tools.mjs +116 -0
  94. package/src/native/memory-recall.mjs +65 -0
  95. package/src/native/memory-store.mjs +334 -0
  96. package/src/native/memory-tools.mjs +329 -0
  97. package/src/native/model-anthropic-cache.mjs +49 -0
  98. package/src/native/model-anthropic-tool-search.mjs +85 -0
  99. package/src/native/model-anthropic.mjs +753 -0
  100. package/src/native/model-chat-usage.mjs +24 -0
  101. package/src/native/model-inline-reasoning.mjs +111 -0
  102. package/src/native/model-media.mjs +174 -0
  103. package/src/native/model-normalize.mjs +228 -0
  104. package/src/native/model-openai-chat.mjs +561 -0
  105. package/src/native/model-port.mjs +361 -0
  106. package/src/native/model-provider-compat.mjs +129 -0
  107. package/src/native/model-replay.mjs +153 -0
  108. package/src/native/model-request.mjs +15 -0
  109. package/src/native/model-responses.mjs +1205 -0
  110. package/src/native/model-sse.mjs +171 -0
  111. package/src/native/model-surface-host.mjs +27 -0
  112. package/src/native/model-tool-search-policy.mjs +16 -0
  113. package/src/native/model-transport-observation.mjs +27 -0
  114. package/src/native/owned-child.mjs +114 -0
  115. package/src/native/owned-command.mjs +106 -0
  116. package/src/native/python-syntax-worker.mjs +60 -0
  117. package/src/native/python-syntax.mjs +50 -0
  118. package/src/native/read-interruption.mjs +16 -0
  119. package/src/native/result-stream.mjs +63 -0
  120. package/src/native/ruff-ast.mjs +95 -0
  121. package/src/native/run-observation.mjs +128 -0
  122. package/src/native/session-delivery-journal.mjs +96 -0
  123. package/src/native/session-delivery.mjs +434 -0
  124. package/src/native/shell-analysis.mjs +50 -0
  125. package/src/native/skill-disclosure.mjs +404 -0
  126. package/src/native/skill-events.mjs +164 -0
  127. package/src/native/skill-tools.mjs +813 -0
  128. package/src/native/source-page.mjs +73 -0
  129. package/src/native/sqlite-session-inbox.mjs +42 -0
  130. package/src/native/sqlite-store.mjs +617 -0
  131. package/src/native/tool-authority.mjs +99 -0
  132. package/src/native/tool-guidance.mjs +12 -0
  133. package/src/native/tool-observation.mjs +75 -0
  134. package/src/native/tool-states.mjs +14 -0
  135. package/src/native/verification-authority.mjs +37 -0
  136. package/src/native/web-tools.mjs +643 -0
  137. package/src/native/workspace-checkpoints.mjs +312 -0
  138. package/src/native/workspace-context.mjs +61 -0
  139. package/src/native/workspace-display.mjs +39 -0
  140. package/src/native/workspace-edit-match.mjs +19 -0
  141. package/src/native/workspace-edit-worker.mjs +15 -0
  142. package/src/native/workspace-editing.mjs +447 -0
  143. package/src/native/workspace-image.mjs +72 -0
  144. package/src/native/workspace-instructions.mjs +107 -0
  145. package/src/native/workspace-mutation-lock.mjs +74 -0
  146. package/src/native/workspace-patch-worker.mjs +17 -0
  147. package/src/native/workspace-patch.mjs +17 -0
  148. package/src/native/workspace-paths.mjs +225 -0
  149. package/src/native/workspace-state.mjs +272 -0
  150. package/src/native/workspace-subject-observer.mjs +84 -0
  151. package/src/native/workspace-tools.mjs +1740 -0
@@ -0,0 +1,99 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { canonical, copy, invariant, scopeKey, sourceReadBudgetForState, activePlanMode,
3
+ projectRunToolAuthority } from '@kingsoftcloud/agentkit-harness-core';
4
+ const hash = value => createHash('sha256').update(canonical(value)).digest('hex');
5
+
6
+ /** A DSH registration/permission decision alone cannot authorize a later
7
+ * publication after waiting for a workspace lock. Re-read the Native ledger. */
8
+ export function createNativeToolAuthority({ scope, sessionId, store, isClosed = () => false, expectedHostBindingDigest }) {
9
+ const read = createNativeToolAuthorityReader({ scope, sessionId, store, isClosed, expectedHostBindingDigest });
10
+ return request => read(request) !== null;
11
+ }
12
+
13
+ /** Read one validated current authority view. Callers may inspect its immutable
14
+ * identity; it grants no authority after another wait or generation change. */
15
+ export function createNativeToolAuthorityReader({ scope, sessionId, store, isClosed = () => false, expectedHostBindingDigest }) {
16
+ scopeKey(scope);
17
+ invariant(typeof sessionId === 'string' && sessionId.trim() && typeof store?.load === 'function'
18
+ && typeof isClosed === 'function' && (expectedHostBindingDigest === undefined
19
+ || typeof expectedHostBindingDigest === 'string' && expectedHostBindingDigest.trim() && expectedHostBindingDigest.length <= 1024), 'studio_native_tool_authority_binding_invalid');
20
+ const fixedScope = copy(scope);
21
+ return request => {
22
+ try {
23
+ if (isClosed() || !(request.signal instanceof AbortSignal) || request.signal.aborted
24
+ || canonical(request.scope) !== canonical(fixedScope) || request.sessionId !== sessionId) return null;
25
+ let current;
26
+ if (store.toolAuthority) current = store.toolAuthority(fixedScope, request.runId);
27
+ else {
28
+ const record = store.authority?.(fixedScope, request.runId) ?? store.load(fixedScope, request.runId);
29
+ current = projectRunToolAuthority({ ...record, pendingIntent: 'pendingIntent' in record ? record.pendingIntent
30
+ : record.intents.find(item => item.operationKey === record.snapshot.pendingIntent) ?? null });
31
+ }
32
+ const snapshot = current.snapshot;
33
+ if (expectedHostBindingDigest !== undefined && current.configuration.hostBindingDigest !== expectedHostBindingDigest) return null;
34
+ if (request.resultGovernance !== (current.configuration.artifactPolicy === 'runtime-artifacts/v1'
35
+ ? 'runtime-artifacts/v1' : undefined)) return null;
36
+ if (!snapshot || snapshot.phase !== 'executing_tools'
37
+ || !['sessionId', 'runId', 'turnId', 'buildId', 'parentRunId', 'taskChainId'].every(key => request[key] === snapshot[key])
38
+ || !current.lease || current.lease.expiresAt <= Date.now()
39
+ || !Number.isSafeInteger(request.executionFence) || request.executionFence <= 0
40
+ || current.lease.fence !== request.executionFence) return null;
41
+ const intent = current.pendingIntent;
42
+ if (intent?.kind !== 'tool' || intent.status !== 'running' || intent.claimedFence !== request.executionFence
43
+ || !Array.isArray(intent.payload?.calls)) return null;
44
+ const index = intent.payload.calls.findIndex(call => canonical(call) === canonical(request.call));
45
+ if (index < 0 || request.operationKey !== (intent.payload.calls.length === 1
46
+ ? intent.operationKey : `${intent.operationKey}:call:${index + 1}`)) return null;
47
+ if (request.definition.approvalPolicy === 'durable-preflight/v1'
48
+ && canonical(request.interaction ?? null) !== canonical(intent.payload.interaction ?? null)) return null;
49
+ const definition = current.configuration.tools.find(tool => tool.name === request.call.name);
50
+ if (request.planMode !== (activePlanMode(snapshot, current.configuration)
51
+ && definition?.planModeCommandPolicy ? 'session-plan/v1' : undefined)) return null;
52
+ if (canonical(request.sourceReadBudget ?? null) !== canonical(sourceReadBudgetForState(snapshot, current.configuration,
53
+ current.sourceReadMessage, request.call, hash) ?? null)) return null;
54
+ return definition && canonical(definition) === canonical(request.definition) ? current : null;
55
+ } catch { return null; }
56
+ };
57
+ }
58
+
59
+ /** Current read intent authority never grants execution rights to the old tool. */
60
+ export function createNativeToolReceiptAuthority(options) {
61
+ return originalEffectAuthority(options, false);
62
+ }
63
+ /** A new operator write claim; a receipt-read claim is never interchangeable. */
64
+ export function createNativeWorkspaceRepairAuthority(options) {
65
+ return originalEffectAuthority(options, true);
66
+ }
67
+ function originalEffectAuthority({ scope, sessionId, store, isClosed = () => false }, repair) {
68
+ scopeKey(scope); const fixedScope = copy(scope);
69
+ invariant(typeof sessionId === 'string' && sessionId.trim() && typeof store?.load === 'function',
70
+ 'studio_native_tool_receipt_binding_invalid');
71
+ return request => {
72
+ try {
73
+ if (isClosed() || !(request.signal instanceof AbortSignal) || request.signal.aborted
74
+ || request.contract !== (repair ? 'agentkit.workspace-compensation/v1' : 'agentkit.tool-receipt-observation/v1')
75
+ || canonical(request.scope) !== canonical(fixedScope) || request.sessionId !== sessionId) return false;
76
+ const record = store.load(fixedScope, request.runId), snapshot = record.snapshot;
77
+ if (snapshot.phase !== 'reconciling_tool' || !record.lease || record.lease.expiresAt <= Date.now()
78
+ || record.lease.fence !== request.executionFence
79
+ || !['sessionId', 'runId', 'turnId', 'buildId', 'parentRunId', 'taskChainId'].every(key => request[key] === snapshot[key])
80
+ || snapshot.toolReconciliation?.operationKey !== request.originalOperationKey
81
+ || snapshot.toolReconciliation?.callId !== request.call?.callId) return false;
82
+ const query = record.intents.find(item => item.operationKey === snapshot.pendingIntent);
83
+ if (query?.kind !== (repair ? 'workspace_repair' : 'tool_receipt') || query.status !== 'running' || query.claimedFence !== request.executionFence
84
+ || query.operationKey !== request.operationKey || query.payload.contract !== request.contract
85
+ || query.payload.originalOperationKey !== request.originalOperationKey
86
+ || query.payload.originalClaimedFence !== request.originalClaimedFence || query.payload.callId !== request.call.callId) return false;
87
+ const original = record.intents.find(item => item.operationKey === request.originalOperationKey);
88
+ const receipt = record.receipts.find(item => item.operationKey === request.originalOperationKey);
89
+ const definition = record.configuration.tools.find(item => item.name === request.call.name);
90
+ return original?.kind === 'tool' && original.status === 'running' && original.claimedFence === request.originalClaimedFence
91
+ && Array.isArray(original.payload.calls) && original.payload.calls.length === 1
92
+ && canonical(original.payload.calls[0]) === canonical(request.call)
93
+ && Boolean(receipt && (receipt.status === 'uncertain' || receipt.result.results?.[0]?.status === 'uncertain'))
94
+ && definition?.recoveryPolicy === 'receipt-observation/v1'
95
+ && (!repair || definition.workspaceRepairPolicy === 'preimage-compensation/v1')
96
+ && canonical(definition) === canonical(request.definition);
97
+ } catch { return false; }
98
+ };
99
+ }
@@ -0,0 +1,12 @@
1
+ /** Tool owners contribute usage guidance; the core only assembles admitted contributions. */
2
+ export function nativeToolModelGuidance(tool, { commandBackend } = {}) {
3
+ if (tool.name === 'read_workspace_file' && tool.workspaceMediaPolicy === 'bounded-image-read/v1')
4
+ return ['Inspect workspace text or supported images through this tool. A partial read is not a complete observation.'];
5
+ if (tool.name === 'run_command') return [
6
+ 'Use the bound backend and its reported cwd. Read saved output using task_id and cursors; a truncated preview is not command failure. Never relaunch an unknown write to recover output.',
7
+ ...(commandBackend === 'e2b' ? ['Commands run in a remote sandbox. Workspace paths describe the host filesystem; do not assume they exist as remote command paths.'] : []),
8
+ ];
9
+ if (tool.childBudgetPolicy === 'start/v1' || tool.childBudgetPolicy === 'delegate/v1')
10
+ return ['Child tasks share the parent task budget and permissions. Set smaller explicit limits when useful; await owned results rather than duplicating the work.'];
11
+ return [];
12
+ }
@@ -0,0 +1,75 @@
1
+ import { terminal } from '@kingsoftcloud/agentkit-harness-core';
2
+
3
+ /** Content-free presentation evidence. Never a permission, retry or execution input. */
4
+ export const NATIVE_TOOL_OBSERVATION = 'agentkit.native-tool-observation/v1';
5
+ export function advanceNativeToolObservation(previous, { intents = [], receipts = [], events = [] }) {
6
+ const calls = new Map((previous?.calls ?? []).map(call => [call.callId, { ...call }]));
7
+ const byKey = new Map(intents.map(intent => [intent.operationKey, intent]));
8
+ for (const intent of intents) {
9
+ if (intent.kind !== 'tool') continue;
10
+ for (const [index, call] of (intent.payload.calls ?? []).entries()) {
11
+ const old = calls.get(call.callId), same = old?.operationKey === intent.operationKey;
12
+ const priorUncertain = !same && (old?.priorUncertain === true || old?.receiptStatus === 'uncertain'
13
+ || old?.resultStatus === 'uncertain' || old?.eventStatus === 'uncertain');
14
+ calls.set(call.callId, same ? { ...old, claimed: intent.status === 'running' ? true : old.claimed }
15
+ : { callId: call.callId, operationKey: intent.operationKey, index,
16
+ claimed: intent.status === 'running' ? true : intent.status === 'prepared' ? false : null,
17
+ preparedSeq: 0, receiptStatus: null, resultStatus: null, eventStatus: null, reconciledStatus: null,
18
+ notDispatched: old?.notDispatched === true, ...(priorUncertain ? { priorUncertain: true } : {}) });
19
+ }
20
+ }
21
+ const byOperation = new Map();
22
+ for (const call of calls.values()) {
23
+ if (!byOperation.has(call.operationKey)) byOperation.set(call.operationKey, []);
24
+ byOperation.get(call.operationKey).push(call);
25
+ }
26
+ for (const receipt of receipts) {
27
+ const intent = byKey.get(receipt.operationKey);
28
+ if (intent?.kind === 'tool_receipt' && receipt.status === 'committed') {
29
+ for (const call of byOperation.get(intent.payload.originalOperationKey) ?? [])
30
+ if (!intent.payload.callId || call.callId === intent.payload.callId)
31
+ call.reconciledStatus = receipt.result.result?.status ?? null;
32
+ continue;
33
+ }
34
+ for (const call of byOperation.get(receipt.operationKey) ?? []) {
35
+ call.receiptStatus = receipt.status;
36
+ call.resultStatus = receipt.status === 'committed' ? receipt.result.results?.[call.index]?.status ?? null : null;
37
+ }
38
+ }
39
+ // Locate the latest attempt before folding completion events. A result from
40
+ // an earlier attempt cannot erase a later claimed effect with no receipt.
41
+ for (const event of events) if (event.kind === 'effect.prepared' && event.payload.kind === 'tool')
42
+ for (const call of byOperation.get(event.payload.operationKey) ?? []) call.preparedSeq = event.seq;
43
+ for (const event of events) {
44
+ const call = calls.get(event.payload.callId);
45
+ if (event.kind === 'tool.not_dispatched') {
46
+ if (call) call.notDispatched = true;
47
+ else calls.set(event.payload.callId, { callId: event.payload.callId, operationKey: null, index: null,
48
+ claimed: null, preparedSeq: 0, receiptStatus: null, resultStatus: null, eventStatus: null,
49
+ reconciledStatus: null, notDispatched: true });
50
+ } else if (event.kind === 'tool.completed') {
51
+ if (call && event.seq >= call.preparedSeq) call.eventStatus = event.payload.status;
52
+ else if (!call) calls.set(event.payload.callId, { callId: event.payload.callId, operationKey: null, index: null,
53
+ claimed: null, preparedSeq: 0, receiptStatus: null, resultStatus: null, eventStatus: event.payload.status,
54
+ reconciledStatus: null, notDispatched: false });
55
+ }
56
+ }
57
+ return { contract: NATIVE_TOOL_OBSERVATION, calls: [...calls.values()] };
58
+ }
59
+
60
+ export function nativeObservedToolStates(observation, snapshot, { driving = false } = {}) {
61
+ return observation.calls.flatMap(call => {
62
+ const result = call.reconciledStatus ?? call.eventStatus ?? call.resultStatus;
63
+ const status = call.notDispatched || call.receiptStatus === 'not_dispatched' ? 'not_dispatched'
64
+ : { ok: 'completed', error: 'failed', uncertain: 'uncertain' }[result]
65
+ // A durable preflight refusal is not an effect. It can remain waiting
66
+ // only while the Run is open. A later attempt replaces this evidence.
67
+ ?? (result === 'approval_required' ? terminal(snapshot.phase) ? 'not_dispatched' : 'waiting'
68
+ : call.receiptStatus === 'uncertain' || call.priorUncertain ? 'uncertain'
69
+ : terminal(snapshot.phase) && !call.receiptStatus && call.claimed !== null
70
+ ? call.claimed ? 'uncertain' : 'not_dispatched'
71
+ : driving && !call.receiptStatus && snapshot.pendingIntent === call.operationKey
72
+ && snapshot.phase === 'executing_tools' ? 'running' : null);
73
+ return status ? [{ callId: call.callId, status }] : [];
74
+ });
75
+ }
@@ -0,0 +1,14 @@
1
+ import { nativeDeliveryId } from './delivery-timeline.mjs';
2
+ import { advanceNativeToolObservation, nativeObservedToolStates } from './tool-observation.mjs';
3
+
4
+ /** A content-free display projection, never a tool execution authority. */
5
+ export function nativeToolStates(record, { driving = false } = {}) {
6
+ if (!record) return null;
7
+ return projectedNativeToolStates(advanceNativeToolObservation(null, record), record.snapshot, { driving });
8
+ }
9
+
10
+ export function projectedNativeToolStates(observation, snapshot, options) {
11
+ return { contract: 'agentkit.native-tool-states/v1', runId: snapshot.runId,
12
+ calls: nativeObservedToolStates(observation, snapshot, options).map(call => ({ ...call,
13
+ callId: nativeDeliveryId(snapshot.scope, snapshot.runId, `call:${call.callId}`) })) };
14
+ }
@@ -0,0 +1,37 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { canonical, copy, effectiveRunConfiguration, invariant, scopeKey, webDelivery } from '@kingsoftcloud/agentkit-harness-core';
3
+ const digest = value => createHash('sha256').update(canonical(value)).digest('hex');
4
+
5
+ /** A verifier may observe through a granted tool while its own verify intent
6
+ * is claimed. It cannot borrow ordinary tool-dispatch authority or execute an
7
+ * old model call. Every publication after permission waits re-reads this claim. */
8
+ export function createNativeVerificationAuthority({ scope, sessionId, store, toolName, isClosed = () => false }) {
9
+ scopeKey(scope); const boundScope = copy(scope);
10
+ invariant(typeof sessionId === 'string' && sessionId && typeof store?.load === 'function'
11
+ && typeof toolName === 'string' && toolName && typeof isClosed === 'function', 'native_verification_authority_binding_invalid');
12
+ return request => {
13
+ try {
14
+ if (isClosed() || !(request.signal instanceof AbortSignal) || request.signal.aborted
15
+ || canonical(request.scope) !== canonical(boundScope) || request.sessionId !== sessionId) return false;
16
+ const current = store.authority?.(boundScope, request.runId) ?? store.load(boundScope, request.runId), snapshot = current.snapshot;
17
+ if (snapshot.phase !== 'verifying' || !current.lease || current.lease.expiresAt <= Date.now()
18
+ || !Number.isSafeInteger(request.executionFence) || request.executionFence <= 0
19
+ || current.lease.fence !== request.executionFence
20
+ || !['sessionId', 'runId', 'turnId', 'buildId', 'parentRunId', 'taskChainId'].every(key => request[key] === snapshot[key])) return false;
21
+ const intent = 'pendingIntent' in current ? current.pendingIntent
22
+ : current.intents.find(item => item.operationKey === snapshot.pendingIntent);
23
+ if (intent?.kind !== 'verify' || intent.status !== 'running' || intent.claimedFence !== request.executionFence
24
+ || intent.operationKey !== request.operationKey || !snapshot.candidate
25
+ || request.candidateId !== snapshot.candidate.candidateId
26
+ || canonical(request.candidate) !== canonical(snapshot.candidate)
27
+ || canonical(intent.payload.candidate) !== canonical(snapshot.candidate)
28
+ || request.snapshot?.revision !== snapshot.revision || request.snapshot?.configDigest !== snapshot.configDigest) return false;
29
+ const config = effectiveRunConfiguration(snapshot, current.configuration, digest);
30
+ if (canonical(request.contract) !== canonical(config.contract)
31
+ || !config.tools.some(tool => tool.name === toolName && tool.observationRole === 'browser')
32
+ || config.contract.allowedToolNames !== null && !config.contract.allowedToolNames.includes(toolName)) return false;
33
+ const entry = webDelivery(snapshot);
34
+ return typeof request.entryPath === 'string' && request.entryPath.length > 0 && (!entry || entry.path === request.entryPath);
35
+ } catch { return false; }
36
+ };
37
+ }