agentnode-sdk 0.24.1__tar.gz → 0.25.0__tar.gz
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.
- agentnode_sdk-0.25.0/.gitignore +85 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/CHANGELOG.md +87 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/PKG-INFO +3 -3
- agentnode_sdk-0.25.0/agentnode_sdk/__init__.py +155 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/_agent_pip.py +22 -0
- agentnode_sdk-0.25.0/agentnode_sdk/_provenance.py +61 -0
- agentnode_sdk-0.25.0/agentnode_sdk/access/__init__.py +10 -0
- agentnode_sdk-0.25.0/agentnode_sdk/access/client.py +191 -0
- agentnode_sdk-0.25.0/agentnode_sdk/access/compatibility.py +271 -0
- agentnode_sdk-0.25.0/agentnode_sdk/access/contract.py +877 -0
- agentnode_sdk-0.25.0/agentnode_sdk/access/credentials.py +115 -0
- agentnode_sdk-0.25.0/agentnode_sdk/access/dispatch.py +2059 -0
- agentnode_sdk-0.25.0/agentnode_sdk/access/enrolment.py +278 -0
- agentnode_sdk-0.25.0/agentnode_sdk/access/mcp.py +166 -0
- agentnode_sdk-0.25.0/agentnode_sdk/access/rest.py +227 -0
- agentnode_sdk-0.25.0/agentnode_sdk/access/routes.py +160 -0
- agentnode_sdk-0.25.0/agentnode_sdk/access/schemas.py +224 -0
- agentnode_sdk-0.25.0/agentnode_sdk/access/sessions.py +235 -0
- agentnode_sdk-0.25.0/agentnode_sdk/access/stopping.py +427 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/USABILITY.md +177 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/__init__.py +56 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/_handshake.py +154 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/_pack_shim.py +210 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/_sandbox_stdlib.py +328 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/adapter.py +152 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/approval.py +240 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/audit.py +175 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/cli.py +52 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/client.py +61 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/client_config.py +119 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/contract.py +126 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/execution.py +187 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/importer.py +107 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/index.py +198 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/manifest.py +486 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/npm_import.py +135 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/npm_vendor.py +180 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/pack_import.py +1695 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/pipeline.py +54 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/tree_execution.py +205 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/tree_pack.py +165 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/tree_pipeline.py +58 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/usability.py +174 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/usability_adapter.py +151 -0
- agentnode_sdk-0.25.0/agentnode_sdk/capability/usability_cli.py +260 -0
- agentnode_sdk-0.25.0/agentnode_sdk/cli/api_auth.py +17 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/cli/commands.py +54 -5
- agentnode_sdk-0.25.0/agentnode_sdk/cli/gateway_commands.py +1829 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/cli/main.py +310 -5
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/cli/mcp_ownership.py +4 -2
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/cli/mcp_status.py +3 -1
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/cli/mcp_submit.py +2 -1
- agentnode_sdk-0.25.0/agentnode_sdk/cli/output.py +107 -0
- agentnode_sdk-0.25.0/agentnode_sdk/cli/pki_commands.py +395 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/cli/publish.py +141 -34
- agentnode_sdk-0.25.0/agentnode_sdk/cli/remote_commands.py +712 -0
- agentnode_sdk-0.25.0/agentnode_sdk/cli/serve.py +13 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/cli/validate.py +41 -17
- agentnode_sdk-0.25.0/agentnode_sdk/cli/worker_commands.py +856 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/client.py +15 -5
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/conformance/checks.py +154 -16
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/conformance/doubles.py +40 -1
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/conformance/probe.py +65 -8
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/conformance/runner.py +350 -41
- agentnode_sdk-0.25.0/agentnode_sdk/console/__init__.py +52 -0
- agentnode_sdk-0.25.0/agentnode_sdk/console/app.css +159 -0
- agentnode_sdk-0.25.0/agentnode_sdk/console/app.js +1151 -0
- agentnode_sdk-0.25.0/agentnode_sdk/console/index.html +28 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/__init__.py +52 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/accounts.py +347 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/activation.py +487 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/admission.py +416 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/allowance.py +895 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/archive.py +290 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/backup.py +339 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/billing.py +161 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/boot.py +18 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/capacity.py +305 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/certificate.py +147 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/challenge.py +231 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/client.py +597 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/connections.py +192 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/filelock.py +311 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/health.py +755 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/identity.py +1444 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/invitation.py +119 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/joining.py +316 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/ledger.py +703 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/lifecycle.py +284 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/meter.py +931 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/observability.py +418 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/operator_policy.py +361 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/pinning.py +115 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/policy_paths.py +148 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/policy_version.py +112 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/protocol.py +713 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/readiness.py +478 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/redaction.py +155 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/retention.py +998 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/runs.py +261 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/runtime_pin.py +359 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/securedir.py +280 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/server.py +5184 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/statedir.py +114 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/throttle.py +500 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/transport.py +270 -0
- agentnode_sdk-0.25.0/agentnode_sdk/gateway/website_link.py +248 -0
- agentnode_sdk-0.25.0/agentnode_sdk/machine.py +77 -0
- agentnode_sdk-0.25.0/agentnode_sdk/mcp_server.py +276 -0
- agentnode_sdk-0.25.0/agentnode_sdk/mcp_tools.py +226 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/models.py +1 -0
- agentnode_sdk-0.25.0/agentnode_sdk/pki/__init__.py +17 -0
- agentnode_sdk-0.25.0/agentnode_sdk/pki/enrolment.py +330 -0
- agentnode_sdk-0.25.0/agentnode_sdk/pki/files.py +376 -0
- agentnode_sdk-0.25.0/agentnode_sdk/pki/floor.py +370 -0
- agentnode_sdk-0.25.0/agentnode_sdk/pki/identity.py +292 -0
- agentnode_sdk-0.25.0/agentnode_sdk/pki/issuer.py +1229 -0
- agentnode_sdk-0.25.0/agentnode_sdk/pki/localfloor.py +213 -0
- agentnode_sdk-0.25.0/agentnode_sdk/pki/revocation.py +163 -0
- agentnode_sdk-0.25.0/agentnode_sdk/pki/tombstones.py +149 -0
- agentnode_sdk-0.25.0/agentnode_sdk/pki/trust.py +226 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/__init__.py +21 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/accounts_login.py +160 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/activation_export.py +219 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/agent_authority.py +229 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/agent_service.py +663 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/catalog.py +584 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/catalog_adapter.py +740 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/catalog_audit.py +169 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/catalog_cli.py +128 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/cert_check.py +149 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/control_floor.py +71 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/http_transport.py +884 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/limits.py +164 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/oauth_as.py +512 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/pairing_helper.py +283 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/personal_tokens.py +112 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/prm.py +57 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/probe_slot.py +312 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/production.py +90 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/retire.py +90 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/reverse_edge.py +386 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/reverse_hub.py +599 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/scheduler.py +191 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/server.py +492 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/target_ops.py +1195 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/target_probe.py +465 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/target_router.py +250 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/targets.py +858 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/targets_cli.py +340 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/tokens.py +315 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/trust_publication.py +1002 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/trust_timers.py +629 -0
- agentnode_sdk-0.25.0/agentnode_sdk/remote_mcp/trust_watchdog.py +1009 -0
- agentnode_sdk-0.25.0/agentnode_sdk/roles.py +207 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/runner.py +7 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/runtimes/mcp_runner.py +17 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/runtimes/python_runner.py +66 -6
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/sandbox/backend.py +60 -0
- agentnode_sdk-0.25.0/agentnode_sdk/sandbox/composition.py +167 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/sandbox/container_backend.py +273 -20
- agentnode_sdk-0.25.0/agentnode_sdk/sandbox/contract.py +573 -0
- agentnode_sdk-0.25.0/agentnode_sdk/sandbox/egress.py +721 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/sandbox/egress_proxy.py +49 -1
- agentnode_sdk-0.25.0/agentnode_sdk/sandbox/egress_verify.py +166 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/sandbox/policy.py +21 -14
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/signing_key.py +18 -5
- agentnode_sdk-0.25.0/agentnode_sdk/tools/__init__.py +1 -0
- agentnode_sdk-0.25.0/agentnode_sdk/tools/evidence.py +1717 -0
- agentnode_sdk-0.25.0/agentnode_sdk/tools/external_check.py +320 -0
- agentnode_sdk-0.25.0/agentnode_sdk/tools/external_run.py +41 -0
- agentnode_sdk-0.25.0/agentnode_sdk/verification/__init__.py +38 -0
- agentnode_sdk-0.25.0/agentnode_sdk/verification/channels.py +224 -0
- agentnode_sdk-0.25.0/agentnode_sdk/verification/config.py +244 -0
- agentnode_sdk-0.25.0/agentnode_sdk/verification/launcher.py +127 -0
- agentnode_sdk-0.25.0/agentnode_sdk/verification/run.py +870 -0
- agentnode_sdk-0.25.0/agentnode_sdk/verification/sentinels.py +231 -0
- agentnode_sdk-0.25.0/agentnode_sdk/verification/transport.py +117 -0
- agentnode_sdk-0.25.0/agentnode_sdk/worker/__init__.py +575 -0
- agentnode_sdk-0.25.0/agentnode_sdk/worker/dialback.py +265 -0
- agentnode_sdk-0.25.0/agentnode_sdk/worker/edge.py +349 -0
- agentnode_sdk-0.25.0/agentnode_sdk/worker/journal.py +538 -0
- agentnode_sdk-0.25.0/agentnode_sdk/worker/lease.py +278 -0
- agentnode_sdk-0.25.0/agentnode_sdk/worker/local.py +532 -0
- agentnode_sdk-0.25.0/agentnode_sdk/worker/pairing.py +364 -0
- agentnode_sdk-0.25.0/agentnode_sdk/worker/pairkeys.py +276 -0
- agentnode_sdk-0.25.0/agentnode_sdk/worker/pins.py +169 -0
- agentnode_sdk-0.25.0/agentnode_sdk/worker/protocol.py +595 -0
- agentnode_sdk-0.25.0/agentnode_sdk/worker/reconcile.py +208 -0
- agentnode_sdk-0.25.0/agentnode_sdk/worker/release.py +280 -0
- agentnode_sdk-0.25.0/agentnode_sdk/worker/remote.py +910 -0
- agentnode_sdk-0.25.0/agentnode_sdk/worker/rollback_proof.py +443 -0
- agentnode_sdk-0.25.0/agentnode_sdk/worker/service.py +1300 -0
- agentnode_sdk-0.25.0/agentnode_sdk/worker/service_isolation.py +51 -0
- agentnode_sdk-0.25.0/agentnode_sdk/worker/tls.py +643 -0
- agentnode_sdk-0.25.0/agentnode_sdk/worker/topology.py +250 -0
- agentnode_sdk-0.25.0/agentnode_sdk/worker/trust_install.py +212 -0
- agentnode_sdk-0.25.0/deploy/ISOLATION_TRADE.md +100 -0
- agentnode_sdk-0.25.0/deploy/README.md +142 -0
- agentnode_sdk-0.25.0/deploy/RISKS.md +96 -0
- agentnode_sdk-0.25.0/deploy/agentnode-gateway.service +78 -0
- agentnode_sdk-0.25.0/deploy/agentnode-pki-tick.service +26 -0
- agentnode_sdk-0.25.0/deploy/agentnode-pki-tick.timer +18 -0
- agentnode_sdk-0.25.0/deploy/agentnode-worker.service +139 -0
- agentnode_sdk-0.25.0/deploy/agentnode-worker.tmpfiles.conf +11 -0
- agentnode_sdk-0.25.0/deploy/backup-and-restore.sh +450 -0
- agentnode_sdk-0.25.0/deploy/build-from-commit.sh +52 -0
- agentnode_sdk-0.25.0/deploy/counter-check-r5.sh +155 -0
- agentnode_sdk-0.25.0/deploy/counter-linux.sh +39 -0
- agentnode_sdk-0.25.0/deploy/customer-worker/activate-customer-worker.sh +32 -0
- agentnode_sdk-0.25.0/deploy/customer-worker/customer-worker-floor.service.in +10 -0
- agentnode_sdk-0.25.0/deploy/customer-worker/customer-worker-floor.timer.in +10 -0
- agentnode_sdk-0.25.0/deploy/customer-worker/customer-worker-runtime.service.in +18 -0
- agentnode_sdk-0.25.0/deploy/customer-worker/customer-worker.service.in +52 -0
- agentnode_sdk-0.25.0/deploy/customer-worker/install-customer-worker.sh +103 -0
- agentnode_sdk-0.25.0/deploy/customer-worker/remove-customer-worker.sh +43 -0
- agentnode_sdk-0.25.0/deploy/deploy-pinned.sh +179 -0
- agentnode_sdk-0.25.0/deploy/encrypted-restore-drill.sh +211 -0
- agentnode_sdk-0.25.0/deploy/local-worker/README-slice1.md +114 -0
- agentnode_sdk-0.25.0/deploy/local-worker/README.md +264 -0
- agentnode_sdk-0.25.0/deploy/local-worker/control/nginx-agent-http.conf +5 -0
- agentnode_sdk-0.25.0/deploy/local-worker/control/nginx-agent-locations.conf +32 -0
- agentnode_sdk-0.25.0/deploy/local-worker/control/units.txt +88 -0
- agentnode_sdk-0.25.0/deploy/local-worker/linux/check-runtime.sh +50 -0
- agentnode_sdk-0.25.0/deploy/local-worker/linux/install.sh +388 -0
- agentnode_sdk-0.25.0/deploy/local-worker/linux/uninstall.sh +64 -0
- agentnode_sdk-0.25.0/deploy/local-worker/release-tools/build_bundle.py +162 -0
- agentnode_sdk-0.25.0/deploy/local-worker/release-tools/prepare-wsl-inputs.sh +74 -0
- agentnode_sdk-0.25.0/deploy/local-worker/windows/Ed25519.ps1 +100 -0
- agentnode_sdk-0.25.0/deploy/local-worker/windows/install-agentnode-worker.ps1 +210 -0
- agentnode_sdk-0.25.0/deploy/local-worker/windows/tests/ed25519-vectors.ps1 +40 -0
- agentnode_sdk-0.25.0/deploy/local-worker/windows/wsl-inner.sh +61 -0
- agentnode_sdk-0.25.0/deploy/remote-mcp/README.md +232 -0
- agentnode_sdk-0.25.0/deploy/remote-mcp/cert-drill.sh +232 -0
- agentnode_sdk-0.25.0/deploy/remote-mcp/cert.env.example +22 -0
- agentnode_sdk-0.25.0/deploy/remote-mcp/nginx-main.conf +24 -0
- agentnode_sdk-0.25.0/deploy/remote-mcp/nginx-mcp.conf +67 -0
- agentnode_sdk-0.25.0/deploy/remote-mcp/rmcp-alert@.service +11 -0
- agentnode_sdk-0.25.0/deploy/remote-mcp/rmcp-attest-renew.service +17 -0
- agentnode_sdk-0.25.0/deploy/remote-mcp/rmcp-attest-renew.timer +15 -0
- agentnode_sdk-0.25.0/deploy/remote-mcp/rmcp-cert-check.service +18 -0
- agentnode_sdk-0.25.0/deploy/remote-mcp/rmcp-cert-check.service.d/trust-watchdog.conf +6 -0
- agentnode_sdk-0.25.0/deploy/remote-mcp/rmcp-cert-check.timer +11 -0
- agentnode_sdk-0.25.0/deploy/remote-mcp/rmcp-cert-renew.service +18 -0
- agentnode_sdk-0.25.0/deploy/remote-mcp/rmcp-cert-renew.sh +132 -0
- agentnode_sdk-0.25.0/deploy/remote-mcp/rmcp-cert-renew.timer +10 -0
- agentnode_sdk-0.25.0/deploy/remote-mcp/rmcp-control-floor.service +13 -0
- agentnode_sdk-0.25.0/deploy/remote-mcp/rmcp-control-floor.timer +12 -0
- agentnode_sdk-0.25.0/deploy/remote-mcp/rmcp-trust-cycle.service +14 -0
- agentnode_sdk-0.25.0/deploy/remote-mcp/rmcp-trust-cycle.timer +11 -0
- agentnode_sdk-0.25.0/deploy/remote-mcp/rmcp-trust-refresh.service +16 -0
- agentnode_sdk-0.25.0/deploy/remote-mcp/rmcp-trust-refresh.timer +15 -0
- agentnode_sdk-0.25.0/deploy/remote-mcp/rmcp-trust-watchdog.service +19 -0
- agentnode_sdk-0.25.0/deploy/remote-mcp/rmcp-trust-watchdog.timer +10 -0
- agentnode_sdk-0.25.0/deploy/remote-mcp/trust-timers.sh +23 -0
- agentnode_sdk-0.25.0/deploy/rollback-artefact.sh +80 -0
- agentnode_sdk-0.25.0/deploy/rollback-drill.sh +119 -0
- agentnode_sdk-0.25.0/deploy/separate-worker-host/README.md +211 -0
- agentnode_sdk-0.25.0/deploy/separate-worker-host/agentnode-floor-advance.service +37 -0
- agentnode_sdk-0.25.0/deploy/separate-worker-host/agentnode-floor-advance.timer +19 -0
- agentnode_sdk-0.25.0/deploy/separate-worker-host/agentnode-worker-runtime.service +96 -0
- agentnode_sdk-0.25.0/deploy/separate-worker-host/build_artefacts.py +279 -0
- agentnode_sdk-0.25.0/deploy/separate-worker-host/control-plane.service +75 -0
- agentnode_sdk-0.25.0/deploy/separate-worker-host/diagnose.sh +111 -0
- agentnode_sdk-0.25.0/deploy/separate-worker-host/install-control-plane.sh +491 -0
- agentnode_sdk-0.25.0/deploy/separate-worker-host/install-worker-host.sh +590 -0
- agentnode_sdk-0.25.0/deploy/separate-worker-host/prerequisites.py +313 -0
- agentnode_sdk-0.25.0/deploy/separate-worker-host/rollback-one-host.sh +371 -0
- agentnode_sdk-0.25.0/deploy/separate-worker-host/upgrade-one-host.sh +313 -0
- agentnode_sdk-0.25.0/deploy/separate-worker-host/worker-host.service +126 -0
- agentnode_sdk-0.25.0/deploy/single-host-development.sh +321 -0
- agentnode_sdk-0.25.0/docs/RELIABILITY-test_verification_run.md +87 -0
- agentnode_sdk-0.25.0/docs/accounts-and-limits.md +159 -0
- agentnode_sdk-0.25.0/docs/cloud-sandbox-production-gaps.md +53 -0
- agentnode_sdk-0.25.0/docs/compatibility-matrix.md +109 -0
- agentnode_sdk-0.25.0/docs/evidence-contract-limits.md +98 -0
- agentnode_sdk-0.25.0/docs/evidence-criteria-split.md +123 -0
- agentnode_sdk-0.25.0/docs/incident-process.md +116 -0
- agentnode_sdk-0.25.0/docs/managed-access-migration.md +154 -0
- agentnode_sdk-0.25.0/docs/managed-sandbox-binding.md +63 -0
- agentnode_sdk-0.25.0/docs/production-readiness.md +90 -0
- agentnode_sdk-0.25.0/docs/review/BACKUP-SECRETS-CRITERION-V2.md +70 -0
- agentnode_sdk-0.25.0/docs/review/BUILD-IDENTITY-AND-WHAT-SIGNS-IT.md +100 -0
- agentnode_sdk-0.25.0/docs/review/CAPACITY-QUEUE-WHAT-WAS-FROZEN-FIRST.md +28 -0
- agentnode_sdk-0.25.0/docs/review/EARLY-ENDING-WHAT-WAS-FROZEN-FIRST.md +49 -0
- agentnode_sdk-0.25.0/docs/review/EXISTENCE-ISOLATION-CRITERION-V2.md +95 -0
- agentnode_sdk-0.25.0/docs/review/FREEZE-R2.md +73 -0
- agentnode_sdk-0.25.0/docs/review/FREEZE.md +71 -0
- agentnode_sdk-0.25.0/docs/review/GOVERNANCE-LIMIT-B-EVIDENCE-OF-A-REVIEW-IS-A-VERDICT.md +92 -0
- agentnode_sdk-0.25.0/docs/review/INTERRUPTED-AUDIT-WHAT-WAS-FROZEN-FIRST.md +43 -0
- agentnode_sdk-0.25.0/docs/review/PROFILE-R1-COULD-NOT-BE-SATISFIED.md +57 -0
- agentnode_sdk-0.25.0/docs/review/TIMING-PROTOCOL-V2.md +126 -0
- agentnode_sdk-0.25.0/docs/review/alpha-capacity-queue-r1.json +127 -0
- agentnode_sdk-0.25.0/docs/review/alpha-r2-admission-r1.json +89 -0
- agentnode_sdk-0.25.0/docs/review/alpha-r2-admission-r2.json +124 -0
- agentnode_sdk-0.25.0/docs/review/alpha-r2-admission-r3.json +151 -0
- agentnode_sdk-0.25.0/docs/review/alpha-r2-admission-r4.json +202 -0
- agentnode_sdk-0.25.0/docs/review/alpha-r2-dataops-r1.json +84 -0
- agentnode_sdk-0.25.0/docs/review/alpha-r2-dataops-r2.json +117 -0
- agentnode_sdk-0.25.0/docs/review/alpha-r2-dataops-r3.json +144 -0
- agentnode_sdk-0.25.0/docs/review/alpha-r2-dataops-r4.json +197 -0
- agentnode_sdk-0.25.0/docs/review/alpha-r2-tenancy-r1.json +75 -0
- agentnode_sdk-0.25.0/docs/review/alpha-r2-tenancy-r2.json +109 -0
- agentnode_sdk-0.25.0/docs/review/alpha-r2-tenancy-r3.json +139 -0
- agentnode_sdk-0.25.0/docs/review/alpha-r2-tenancy-r4.json +188 -0
- agentnode_sdk-0.25.0/docs/review/alpha-runtime-pin-r2.json +134 -0
- agentnode_sdk-0.25.0/docs/review/counter-checks.md +198 -0
- agentnode_sdk-0.25.0/docs/review/early-ending-success-r1.json +117 -0
- agentnode_sdk-0.25.0/docs/review/interrupted-audit-record-r1.json +125 -0
- agentnode_sdk-0.25.0/docs/review/managed-console-final-r1.json +160 -0
- agentnode_sdk-0.25.0/docs/self-hosted-sandbox.md +289 -0
- agentnode_sdk-0.25.0/docs/what-is-kept.md +226 -0
- agentnode_sdk-0.25.0/pyproject.toml +85 -0
- agentnode_sdk-0.25.0/scripts/counter-check-mtls-stage5.sh +12 -0
- agentnode_sdk-0.25.0/scripts/counter-check-mtls.sh +8 -0
- agentnode_sdk-0.25.0/scripts/counter_check_cancel.py +296 -0
- agentnode_sdk-0.25.0/scripts/counter_check_commit_range.py +518 -0
- agentnode_sdk-0.25.0/scripts/health_counter_checks.py +357 -0
- agentnode_sdk-0.25.0/scripts/mtls_counter_checks.py +339 -0
- agentnode_sdk-0.25.0/scripts/mtls_stage5_counter_checks.py +416 -0
- agentnode_sdk-0.25.0/scripts/remote_worker_counter_checks.py +593 -0
- agentnode_sdk-0.25.0/scripts/the_access_layer.py +236 -0
- agentnode_sdk-0.25.0/scripts/the_usage_records.py +225 -0
- agentnode_sdk-0.25.0/security-lane/test_timing_microbenchmark.py +192 -0
- agentnode_sdk-0.25.0/tests/a_resolver_that_can_change_its_mind.py +187 -0
- agentnode_sdk-0.25.0/tests/capability/_doubles.py +26 -0
- agentnode_sdk-0.25.0/tests/capability/_pack_fixtures.py +85 -0
- agentnode_sdk-0.25.0/tests/capability/fixtures/deterministic_add_server.py +86 -0
- agentnode_sdk-0.25.0/tests/capability/fixtures/multifile_echo_server/app/server.py +78 -0
- agentnode_sdk-0.25.0/tests/capability/fixtures/multifile_echo_server/app/toolimpl.py +12 -0
- agentnode_sdk-0.25.0/tests/capability/fixtures/packs/multi-tool-pack/agentnode.yaml +32 -0
- agentnode_sdk-0.25.0/tests/capability/fixtures/packs/multi-tool-pack/pyproject.toml +13 -0
- agentnode_sdk-0.25.0/tests/capability/fixtures/packs/multi-tool-pack/src/multi_tool_pack/__init__.py +1 -0
- agentnode_sdk-0.25.0/tests/capability/fixtures/packs/multi-tool-pack/src/multi_tool_pack/slug.py +18 -0
- agentnode_sdk-0.25.0/tests/capability/fixtures/packs/multi-tool-pack/src/multi_tool_pack/tool.py +14 -0
- agentnode_sdk-0.25.0/tests/capability/fixtures/packs/slow-pack/agentnode.yaml +32 -0
- agentnode_sdk-0.25.0/tests/capability/fixtures/packs/slow-pack/pyproject.toml +13 -0
- agentnode_sdk-0.25.0/tests/capability/fixtures/packs/slow-pack/src/slow_pack/__init__.py +1 -0
- agentnode_sdk-0.25.0/tests/capability/fixtures/packs/slow-pack/src/slow_pack/tool.py +10 -0
- agentnode_sdk-0.25.0/tests/capability/test_adapter_client.py +102 -0
- agentnode_sdk-0.25.0/tests/capability/test_capability_cli.py +55 -0
- agentnode_sdk-0.25.0/tests/capability/test_client_config.py +42 -0
- agentnode_sdk-0.25.0/tests/capability/test_contract_execution_audit.py +263 -0
- agentnode_sdk-0.25.0/tests/capability/test_index_import.py +110 -0
- agentnode_sdk-0.25.0/tests/capability/test_manifest.py +162 -0
- agentnode_sdk-0.25.0/tests/capability/test_npm_vendor.py +39 -0
- agentnode_sdk-0.25.0/tests/capability/test_pack_import.py +1563 -0
- agentnode_sdk-0.25.0/tests/capability/test_tree_capability.py +173 -0
- agentnode_sdk-0.25.0/tests/capability/test_tree_pack.py +76 -0
- agentnode_sdk-0.25.0/tests/capability/test_usability_adapter.py +104 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/conftest.py +650 -378
- agentnode_sdk-0.25.0/tests/consent.py +66 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/lanes/FROZEN_INVENTORY.json +308 -9
- agentnode_sdk-0.25.0/tests/lanes/eg8_counter_check.py +115 -0
- agentnode_sdk-0.25.0/tests/real_answers.py +163 -0
- agentnode_sdk-0.25.0/tests/reliability.py +115 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/catalog_fixtures.py +171 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/data/targets_a36ddcdd.py.txt +743 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/target_fixtures.py +80 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/target_stand.py +172 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_attest_old_reader.py +69 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_attest_renewal.py +942 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_attest_watchdog.py +300 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_catalog.py +730 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_cert_check.py +147 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_cimd_bounds.py +194 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_cimd_hardening.py +177 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_e2e_standard_client.py +343 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_limits_runtime.py +249 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_live_token_revocation.py +170 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_local_worker.py +1270 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_local_worker_catalog.py +169 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_local_worker_edge.py +652 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_local_worker_pairing.py +591 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_local_worker_release.py +434 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_local_worker_slice2_units.py +378 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_probe_slot.py +433 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_production_fail_closed.py +224 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_production_login.py +555 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_target_invariants.py +51 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_target_lifecycle.py +338 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_target_negatives.py +277 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_target_negatives_2.py +580 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_target_register.py +235 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_target_routing.py +604 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_target_scheduler.py +150 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_transport.py +716 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_trust_floor_units.py +314 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_trust_install_legacy.py +807 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_trust_publication.py +822 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_trust_refresh_confirm.py +375 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_trust_schedule.py +421 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_trust_watchdog.py +320 -0
- agentnode_sdk-0.25.0/tests/remote_mcp/test_trust_watchdog_wd1.py +1169 -0
- agentnode_sdk-0.25.0/tests/serving.py +220 -0
- agentnode_sdk-0.25.0/tests/shell_commands.py +394 -0
- agentnode_sdk-0.25.0/tests/smoke/__init__.py +0 -0
- agentnode_sdk-0.25.0/tests/smoke/test_smoke_sdk.py +357 -0
- agentnode_sdk-0.25.0/tests/test_a_device_is_called_what_it_was_paired_as.py +73 -0
- agentnode_sdk-0.25.0/tests/test_a_failed_read_is_not_an_answer.py +420 -0
- agentnode_sdk-0.25.0/tests/test_a_failed_settlement_leaves_a_trace.py +277 -0
- agentnode_sdk-0.25.0/tests/test_a_half_written_file.py +323 -0
- agentnode_sdk-0.25.0/tests/test_a_hangup_is_not_an_internal_error.py +130 -0
- agentnode_sdk-0.25.0/tests/test_a_joining_is_a_small_transaction.py +205 -0
- agentnode_sdk-0.25.0/tests/test_a_name_that_changes_where_it_points.py +260 -0
- agentnode_sdk-0.25.0/tests/test_a_pairing_is_a_small_transaction.py +308 -0
- agentnode_sdk-0.25.0/tests/test_a_policy_change_takes_effect_at_once.py +810 -0
- agentnode_sdk-0.25.0/tests/test_a_policy_refusal_is_named_as_one.py +336 -0
- agentnode_sdk-0.25.0/tests/test_a_property_this_sandbox_lacks_is_named_as_one.py +236 -0
- agentnode_sdk-0.25.0/tests/test_a_reader_is_not_refused_for_a_transient.py +171 -0
- agentnode_sdk-0.25.0/tests/test_a_rebooted_worker_comes_back.py +369 -0
- agentnode_sdk-0.25.0/tests/test_a_refusal_keeps_its_name.py +78 -0
- agentnode_sdk-0.25.0/tests/test_a_refusal_that_names_the_right_cause.py +137 -0
- agentnode_sdk-0.25.0/tests/test_a_sealed_backup.py +269 -0
- agentnode_sdk-0.25.0/tests/test_a_secret_does_not_outlive_its_use.py +221 -0
- agentnode_sdk-0.25.0/tests/test_a_self_repair_guard_can_actually_fire.py +145 -0
- agentnode_sdk-0.25.0/tests/test_a_spent_secret_does_not_linger.py +1099 -0
- agentnode_sdk-0.25.0/tests/test_a_stop_reaches_work_that_has_not_started.py +104 -0
- agentnode_sdk-0.25.0/tests/test_a_stopped_waiting_job_says_why_it_stopped.py +497 -0
- agentnode_sdk-0.25.0/tests/test_a_waiting_job_has_no_network.py +345 -0
- agentnode_sdk-0.25.0/tests/test_a_wedged_measurement.py +119 -0
- agentnode_sdk-0.25.0/tests/test_a_withdrawn_identity_stays_withdrawn.py +234 -0
- agentnode_sdk-0.25.0/tests/test_account_ceilings.py +278 -0
- agentnode_sdk-0.25.0/tests/test_activation_lock_liveness.py +109 -0
- agentnode_sdk-0.25.0/tests/test_adding_a_second_machine.py +287 -0
- agentnode_sdk-0.25.0/tests/test_admission.py +866 -0
- agentnode_sdk-0.25.0/tests/test_admission_measured.py +582 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_agent_m1_amendment.py +8 -0
- agentnode_sdk-0.25.0/tests/test_allowance.py +1400 -0
- agentnode_sdk-0.25.0/tests/test_an_answer_that_was_lost_can_be_recovered.py +412 -0
- agentnode_sdk-0.25.0/tests/test_an_interrupted_install_can_still_say_it_is_not_ready.py +208 -0
- agentnode_sdk-0.25.0/tests/test_an_unreadable_revocation_list_is_not_a_missing_one.py +501 -0
- agentnode_sdk-0.25.0/tests/test_approval_targets.py +217 -0
- agentnode_sdk-0.25.0/tests/test_backup_drill.py +525 -0
- agentnode_sdk-0.25.0/tests/test_browser_sessions.py +400 -0
- agentnode_sdk-0.25.0/tests/test_cancel_consistency.py +684 -0
- agentnode_sdk-0.25.0/tests/test_cancel_is_not_a_wait.py +662 -0
- agentnode_sdk-0.25.0/tests/test_capacity_billing.py +277 -0
- agentnode_sdk-0.25.0/tests/test_capacity_queue.py +311 -0
- agentnode_sdk-0.25.0/tests/test_capacity_standing.py +894 -0
- agentnode_sdk-0.25.0/tests/test_challenge.py +513 -0
- agentnode_sdk-0.25.0/tests/test_ci_full_lanes.py +217 -0
- agentnode_sdk-0.25.0/tests/test_ci_pr_lane.py +94 -0
- agentnode_sdk-0.25.0/tests/test_cleanup_is_the_products_own.py +1013 -0
- agentnode_sdk-0.25.0/tests/test_cli_api_key_header.py +75 -0
- agentnode_sdk-0.25.0/tests/test_cli_manifest_json.py +303 -0
- agentnode_sdk-0.25.0/tests/test_cli_run_failure_is_reported.py +91 -0
- agentnode_sdk-0.25.0/tests/test_closing_a_policy_needs_no_worker.py +449 -0
- agentnode_sdk-0.25.0/tests/test_compatibility.py +218 -0
- agentnode_sdk-0.25.0/tests/test_compatibility_challenge.py +328 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_conformance_checks.py +365 -8
- agentnode_sdk-0.25.0/tests/test_consent_and_tools.py +648 -0
- agentnode_sdk-0.25.0/tests/test_console_browser.py +556 -0
- agentnode_sdk-0.25.0/tests/test_contract_and_schemas.py +236 -0
- agentnode_sdk-0.25.0/tests/test_credentials.py +157 -0
- agentnode_sdk-0.25.0/tests/test_crosshost_rebuild_request.py +262 -0
- agentnode_sdk-0.25.0/tests/test_deleting_an_account_clears_its_ceilings.py +176 -0
- agentnode_sdk-0.25.0/tests/test_deploying_refuses.py +221 -0
- agentnode_sdk-0.25.0/tests/test_dispatch.py +228 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_e2e_runtime.py +6 -2
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_egress_lifecycle.py +37 -3
- agentnode_sdk-0.25.0/tests/test_em3_contract.py +481 -0
- agentnode_sdk-0.25.0/tests/test_em3c_cli.py +974 -0
- agentnode_sdk-0.25.0/tests/test_em3c_gateway.py +4318 -0
- agentnode_sdk-0.25.0/tests/test_end_to_end_rest.py +244 -0
- agentnode_sdk-0.25.0/tests/test_endings.py +668 -0
- agentnode_sdk-0.25.0/tests/test_ever_started_means_the_worker_took_it.py +111 -0
- agentnode_sdk-0.25.0/tests/test_every_door.py +406 -0
- agentnode_sdk-0.25.0/tests/test_every_refusal_is_actionable.py +122 -0
- agentnode_sdk-0.25.0/tests/test_evidence.py +1991 -0
- agentnode_sdk-0.25.0/tests/test_existence_is_not_disclosed.py +328 -0
- agentnode_sdk-0.25.0/tests/test_export_carries_limits_and_one_off_use.py +240 -0
- agentnode_sdk-0.25.0/tests/test_external_config.py +271 -0
- agentnode_sdk-0.25.0/tests/test_finding_p_a_pathname_lock.py +216 -0
- agentnode_sdk-0.25.0/tests/test_frozen_inventory_controls.py +109 -0
- agentnode_sdk-0.25.0/tests/test_github_action_contract.py +114 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_guard_schema.py +26 -2
- agentnode_sdk-0.25.0/tests/test_interrupted_record.py +1437 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_layer3_interpreter_and_no_runtime_install.py +9 -3
- agentnode_sdk-0.25.0/tests/test_lifecycle_deadlock.py +318 -0
- agentnode_sdk-0.25.0/tests/test_lifecycle_release.py +324 -0
- agentnode_sdk-0.25.0/tests/test_mcp_catalog_install.py +126 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_mcp_server.py +9 -9
- agentnode_sdk-0.25.0/tests/test_mcp_tool_error_result.py +79 -0
- agentnode_sdk-0.25.0/tests/test_measurement_is_about_this_state.py +221 -0
- agentnode_sdk-0.25.0/tests/test_mtls_fail_closed.py +375 -0
- agentnode_sdk-0.25.0/tests/test_mtls_floor.py +482 -0
- agentnode_sdk-0.25.0/tests/test_mtls_issuer.py +478 -0
- agentnode_sdk-0.25.0/tests/test_mtls_only_door.py +126 -0
- agentnode_sdk-0.25.0/tests/test_mtls_parity.py +236 -0
- agentnode_sdk-0.25.0/tests/test_mtls_publication.py +189 -0
- agentnode_sdk-0.25.0/tests/test_mtls_renewal.py +232 -0
- agentnode_sdk-0.25.0/tests/test_mtls_revocation.py +471 -0
- agentnode_sdk-0.25.0/tests/test_mtls_transport.py +513 -0
- agentnode_sdk-0.25.0/tests/test_no_tool_cache_is_tracked.py +40 -0
- agentnode_sdk-0.25.0/tests/test_one_key_per_pair.py +238 -0
- agentnode_sdk-0.25.0/tests/test_one_off_allowance.py +332 -0
- agentnode_sdk-0.25.0/tests/test_one_way_in.py +277 -0
- agentnode_sdk-0.25.0/tests/test_one_writer_of_the_token_file_at_a_time.py +321 -0
- agentnode_sdk-0.25.0/tests/test_only_narrowing.py +420 -0
- agentnode_sdk-0.25.0/tests/test_only_one_control_plane_owns_a_worker.py +313 -0
- agentnode_sdk-0.25.0/tests/test_optional_providers_skip_cleanly.py +93 -0
- agentnode_sdk-0.25.0/tests/test_p13_control_plane_statement.py +387 -0
- agentnode_sdk-0.25.0/tests/test_p13_rollback_waiver_needs_evidence.py +52 -0
- agentnode_sdk-0.25.0/tests/test_policy_composition.py +219 -0
- agentnode_sdk-0.25.0/tests/test_private_read_retry_windows_share.py +230 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_provider_matrix.py +20 -2
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_r1_runtime_remediation.py +77 -7
- agentnode_sdk-0.25.0/tests/test_reachable.py +1307 -0
- agentnode_sdk-0.25.0/tests/test_readme_sandbox_platforms.py +41 -0
- agentnode_sdk-0.25.0/tests/test_remote_connect_link.py +131 -0
- agentnode_sdk-0.25.0/tests/test_retention_every_class.py +414 -0
- agentnode_sdk-0.25.0/tests/test_risks_page_matches_the_transport.py +81 -0
- agentnode_sdk-0.25.0/tests/test_root_lockfile_is_sealed.py +53 -0
- agentnode_sdk-0.25.0/tests/test_routes_register.py +306 -0
- agentnode_sdk-0.25.0/tests/test_runtime_pin.py +719 -0
- agentnode_sdk-0.25.0/tests/test_sandbox_availability_docs.py +134 -0
- agentnode_sdk-0.25.0/tests/test_self_hosted_guide.py +197 -0
- agentnode_sdk-0.25.0/tests/test_serve_stdio.py +168 -0
- agentnode_sdk-0.25.0/tests/test_serve_tools.py +277 -0
- agentnode_sdk-0.25.0/tests/test_serving_ownership.py +134 -0
- agentnode_sdk-0.25.0/tests/test_socket_worker.py +2024 -0
- agentnode_sdk-0.25.0/tests/test_start_boundary.py +275 -0
- agentnode_sdk-0.25.0/tests/test_start_rehearsal.py +237 -0
- agentnode_sdk-0.25.0/tests/test_state_consistency.py +2902 -0
- agentnode_sdk-0.25.0/tests/test_stop_reason.py +563 -0
- agentnode_sdk-0.25.0/tests/test_stopping.py +691 -0
- agentnode_sdk-0.25.0/tests/test_target_pki_permanence.py +93 -0
- agentnode_sdk-0.25.0/tests/test_target_trust_install.py +105 -0
- agentnode_sdk-0.25.0/tests/test_tenancy_on_every_surface.py +915 -0
- agentnode_sdk-0.25.0/tests/test_the_binding_describes_the_right_machine.py +92 -0
- agentnode_sdk-0.25.0/tests/test_the_build_id_is_readable_while_it_serves.py +98 -0
- agentnode_sdk-0.25.0/tests/test_the_counter_is_not_a_run_record.py +202 -0
- agentnode_sdk-0.25.0/tests/test_the_durable_record_carries_the_real_ending.py +321 -0
- agentnode_sdk-0.25.0/tests/test_the_durable_record_comes_before_the_answer.py +362 -0
- agentnode_sdk-0.25.0/tests/test_the_floor_under_concurrent_accepts.py +399 -0
- agentnode_sdk-0.25.0/tests/test_the_gateway_refuses_while_its_worker_is_gone.py +615 -0
- agentnode_sdk-0.25.0/tests/test_the_gateways_own_fault_is_named_as_one.py +225 -0
- agentnode_sdk-0.25.0/tests/test_the_lease_is_kept_alive.py +240 -0
- agentnode_sdk-0.25.0/tests/test_the_meter_key_is_written_whole.py +75 -0
- agentnode_sdk-0.25.0/tests/test_the_operators_withdrawal_reaches_a_waiting_job.py +290 -0
- agentnode_sdk-0.25.0/tests/test_the_reason_reaches_the_ledger.py +229 -0
- agentnode_sdk-0.25.0/tests/test_the_repair_of_what_two_machines_found.py +494 -0
- agentnode_sdk-0.25.0/tests/test_the_route_out_is_owned_and_verified.py +1038 -0
- agentnode_sdk-0.25.0/tests/test_the_two_roles_are_separable.py +376 -0
- agentnode_sdk-0.25.0/tests/test_the_worker_may_be_on_another_host.py +400 -0
- agentnode_sdk-0.25.0/tests/test_the_worker_remembers_what_it_ran.py +436 -0
- agentnode_sdk-0.25.0/tests/test_timeout_rc_is_gone_loudly.py +59 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_toolpack_credentials_b.py +31 -2
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_toolpack_sandbox.py +63 -6
- agentnode_sdk-0.25.0/tests/test_transport_bytes.py +136 -0
- agentnode_sdk-0.25.0/tests/test_transport_claims_match_the_code.py +86 -0
- agentnode_sdk-0.25.0/tests/test_trust_install_confirm.py +200 -0
- agentnode_sdk-0.25.0/tests/test_two_accounts.py +475 -0
- agentnode_sdk-0.25.0/tests/test_two_accounts_every_door.py +245 -0
- agentnode_sdk-0.25.0/tests/test_two_accounts_in_a_browser.py +435 -0
- agentnode_sdk-0.25.0/tests/test_two_machine_claim.py +30 -0
- agentnode_sdk-0.25.0/tests/test_under_change_and_restart.py +517 -0
- agentnode_sdk-0.25.0/tests/test_upgrade_and_rollback_are_real.py +411 -0
- agentnode_sdk-0.25.0/tests/test_verification_channels.py +575 -0
- agentnode_sdk-0.25.0/tests/test_verification_run.py +716 -0
- agentnode_sdk-0.25.0/tests/test_watching.py +123 -0
- agentnode_sdk-0.25.0/tests/test_website_link.py +214 -0
- agentnode_sdk-0.25.0/tests/test_website_link_door.py +238 -0
- agentnode_sdk-0.25.0/tests/test_what_is_kept.py +1127 -0
- agentnode_sdk-0.25.0/tests/test_what_the_gateway_says_about_its_worker.py +674 -0
- agentnode_sdk-0.25.0/tests/test_what_the_host_needs_first.py +908 -0
- agentnode_sdk-0.25.0/tests/test_what_the_worker_says_about_its_doors.py +237 -0
- agentnode_sdk-0.25.0/tests/test_worker_autostart_contract.py +71 -0
- agentnode_sdk-0.25.0/tests/the_lock_contention_child.py +280 -0
- agentnode_sdk-0.25.0/tests/timing_investigation.py +187 -0
- agentnode_sdk-0.25.0/tests/timing_v2.py +301 -0
- agentnode_sdk-0.25.0/tests/two_machine_claim.py +47 -0
- agentnode_sdk-0.24.1/agentnode_sdk/__init__.py +0 -83
- agentnode_sdk-0.24.1/agentnode_sdk/cli/output.py +0 -48
- agentnode_sdk-0.24.1/agentnode_sdk/cli/serve.py +0 -10
- agentnode_sdk-0.24.1/agentnode_sdk/mcp_server.py +0 -187
- agentnode_sdk-0.24.1/agentnode_sdk/sandbox/egress.py +0 -178
- agentnode_sdk-0.24.1/pyproject.toml +0 -50
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/.env.example +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/README.md +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/REGISTRY_SIGNING_ACTIVATION.md +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/REGISTRY_SIGNING_SPEC.md +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/THREAT_MODEL.md +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/TRUST_STACK.md +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode.lock +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/_env_lock.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/_env_rwlock.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/_fileutil.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/_wheel_meta.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/async_client.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/capability_graph.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/capability_taxonomy.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/cli/__init__.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/cli/__main__.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/cli/audit.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/cli/auth.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/cli/cassette_audit.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/cli/complements.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/cli/init.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/cli/mcp_commands.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/cli/mcp_verify.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/cli/record_cases.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/cli/sandbox_commands.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/cli/setup_wizard.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/cli/smart_run.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/cli/templates.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/cli/verify_local.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/compatibility.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/config.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/conformance/__init__.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/conformance/report.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/credential_handle.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/credential_resolver.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/credential_store.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/detect.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/exceptions.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/guard.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/input_guard.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/installer.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/key_status.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/llm_providers.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/lock_integrity.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/lock_surface.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/planner.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/policy.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/references.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/registry_trust.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/resolve.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/resource_provider.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/risk_profile.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/run_log.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/runtime.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/runtime_integrity.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/runtimes/__init__.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/runtimes/agent_llm_broker.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/runtimes/agent_llm_policy.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/runtimes/agent_runner.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/runtimes/agent_sandbox.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/runtimes/mcp_consent.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/runtimes/mcp_consent_store.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/runtimes/mcp_launch.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/runtimes/remote_runner.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/runtimes/toolpack_credentials.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/sandbox/__init__.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/sandbox/agent_container_wrapper.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/sandbox/agent_rpc.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/sandbox/agent_session.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/sandbox/domain_policy.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/sandbox/mcp_preinstall.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/sandbox/refusal.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/sandbox/types.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/signature.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/agentnode_sdk/skill.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/data/compatibility/current.json +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/data/compatibility/removed_2026-07-09.txt +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/sandbox-image/Dockerfile +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/sandbox-image/README.md +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/scripts/analyze_scores.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/scripts/batch_verify.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/scripts/check_model_drift.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/scripts/ci_smoke_test.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/scripts/generate_compatibility_artifacts.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/scripts/merge_batches.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/scripts/verify_toolcalls.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/scripts/weekly_retest.sh +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/spikes/agent_sandbox_routing/README.md +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/spikes/agent_sandbox_routing/__init__.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/spikes/agent_sandbox_routing/container_agent_wrapper.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/spikes/agent_sandbox_routing/fake_llm.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/spikes/agent_sandbox_routing/host_driver.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/spikes/agent_sandbox_routing/trivial_agent.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/agent_m1_helpers.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/data/allowed_domains_vectors.json +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/hostpolicy.py +0 -0
- {agentnode_sdk-0.24.1/tests → agentnode_sdk-0.25.0/tests/lanes}/__init__.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/lanes/conftest_report.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/lanes/constraints.txt +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/lanes/freeze_inventory.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/lanes/npm_e2e_pins.json +0 -0
- {agentnode_sdk-0.24.1/tests/lanes → agentnode_sdk-0.25.0/tests/remote_mcp}/__init__.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/rwlock_worker.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_agent_host_unsupported.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_agent_llm_broker.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_agent_llm_policy.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_agent_m1_env_lock.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_agent_m1_fileutil.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_agent_m1_lock_fields.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_agent_m1_transaction.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_agent_m1_wheel_meta.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_agent_rpc.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_agent_runner.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_agent_sandbox_e2e.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_agent_sandbox_hardening.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_agent_sandbox_routing.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_agent_sandbox_spike.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_agent_session_container.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_async_client.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_audit_ux.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_auth_cli_vault.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_auto_upgrade_policy.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_cli.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_cli_lock.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_cli_lock_verify_structure.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_cli_run_resolution.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_client.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_client_json_guard.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_client_sprint_b.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_config.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_conformance_report.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_consent_prompt.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_credential_handle.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_credential_integration.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_credential_resolver.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_credential_store.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_credential_vault.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_detect.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_detect_and_install.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_domain_policy.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_edge_cases.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_egress_domain_validation.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_egress_e2e.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_egress_proxy_unit.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_egress_wrap.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_env_passthrough_wrap.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_env_rwlock.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_guard.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_guard_check.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_guard_config_cache.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_guard_policy.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_guard_preview.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_guard_set.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_guard_status.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_guard_tool_override.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_guard_tool_override_audit.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_guard_tool_override_cli.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_guard_ux.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_host_policy_snapshot.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_host_trust_policy.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_host_trust_policy_routing.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_input_guard.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_input_guard_escalation.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_install_hardening.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_installer_sprint_b.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_intelligence.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_key_status.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_layer3_admin_funnel.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_layer3_env_write_lock_core.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_layer3_install_snapshot.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_layer3_installer_concurrency.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_llm_binding.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_llm_call_runlog.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_llm_providers.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_llm_vault_binding.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_load_tool_integrity.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_lock_integrity.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_lock_runtime.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_lockfile_duplicate_keys.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_mcp_allowed_domains_seal.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_mcp_audit.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_mcp_cli_scaffold.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_mcp_consent.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_mcp_consent_resolver.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_mcp_consent_store.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_mcp_credentialed_launch.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_mcp_doctor.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_mcp_doctor_integrity.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_mcp_ownership_cli.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_mcp_preinstall.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_mcp_preinstall_cache.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_mcp_preinstall_run.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_mcp_sandbox.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_mcp_submit.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_mcp_verify_pinning.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_observability.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_planner.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_policy.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_policy_integration.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_prompt_specs.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_publish.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_r1_both_revisions.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_r1_counter_checks.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_references.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_registry_trust.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_remote_hardening.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_remote_runner.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_resource_provider.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_resource_specs.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_risk_profile.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_run_log.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_runner.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_runtime.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_runtime_audit.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_sandbox_backend.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_sandbox_doctor.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_sandbox_e2e.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_sandbox_gate.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_security_hardening.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_setup_wizard.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_shipped_default_live_paths.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_shipped_default_routing.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_signature.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_signing_key.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_skill.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_smart.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_stability.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_structure_digest.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_structure_writer_seal.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_toolpack_credentials.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_v02.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_validate.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/test_validate_skill.py +0 -0
- {agentnode_sdk-0.24.1 → agentnode_sdk-0.25.0}/tests/validation_lockfile.json +0 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
dist/
|
|
6
|
+
build/
|
|
7
|
+
.venv/
|
|
8
|
+
*.egg
|
|
9
|
+
|
|
10
|
+
# Node
|
|
11
|
+
node_modules/
|
|
12
|
+
cli/dist/
|
|
13
|
+
|
|
14
|
+
# Next.js
|
|
15
|
+
web/.next/
|
|
16
|
+
web/out/
|
|
17
|
+
|
|
18
|
+
# Environment & Secrets
|
|
19
|
+
.env
|
|
20
|
+
.env.local
|
|
21
|
+
.env.production
|
|
22
|
+
.pypirc
|
|
23
|
+
|
|
24
|
+
# IDE
|
|
25
|
+
.idea/
|
|
26
|
+
.vscode/
|
|
27
|
+
*.swp
|
|
28
|
+
*.swo
|
|
29
|
+
|
|
30
|
+
# OS
|
|
31
|
+
.DS_Store
|
|
32
|
+
Thumbs.db
|
|
33
|
+
|
|
34
|
+
# Test
|
|
35
|
+
.pytest_cache/
|
|
36
|
+
.ruff_cache/
|
|
37
|
+
.coverage
|
|
38
|
+
htmlcov/
|
|
39
|
+
|
|
40
|
+
# Build artifacts
|
|
41
|
+
*.tar.gz
|
|
42
|
+
*.whl
|
|
43
|
+
|
|
44
|
+
# Test score artifacts
|
|
45
|
+
.artifacts/
|
|
46
|
+
|
|
47
|
+
# Spec documents
|
|
48
|
+
*.docx
|
|
49
|
+
|
|
50
|
+
# Screenshots & temp files
|
|
51
|
+
*.png
|
|
52
|
+
screenshots/
|
|
53
|
+
test-screenshots/
|
|
54
|
+
spec_extracted.txt
|
|
55
|
+
calendar.ics
|
|
56
|
+
events.json
|
|
57
|
+
|
|
58
|
+
# Playwright
|
|
59
|
+
.playwright-mcp/
|
|
60
|
+
|
|
61
|
+
# Claude Code
|
|
62
|
+
.claude/
|
|
63
|
+
|
|
64
|
+
# Internal growth / marketing content
|
|
65
|
+
growth/
|
|
66
|
+
backend/.next/
|
|
67
|
+
kwfinder-*.md
|
|
68
|
+
packages_dump.json
|
|
69
|
+
snapshot_nonowner.txt
|
|
70
|
+
seo/
|
|
71
|
+
backend/scripts/enrichment_*.json
|
|
72
|
+
|
|
73
|
+
# Internal documentation (not for GitHub)
|
|
74
|
+
internal/
|
|
75
|
+
|
|
76
|
+
# Internal ops scripts (crawl, enrichment, import)
|
|
77
|
+
scripts/crawl_*.py
|
|
78
|
+
scripts/enrich_*.py
|
|
79
|
+
scripts/import_candidates.py
|
|
80
|
+
scripts/.mcp_cache/
|
|
81
|
+
candidates*.json
|
|
82
|
+
*.lock.lk
|
|
83
|
+
|
|
84
|
+
# Counter-check and exercise output: evidence for a review bundle, not source.
|
|
85
|
+
sdk/remote-worker-counter-check-results/
|
|
@@ -1,5 +1,92 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.25.0 — refuse what cannot be enforced
|
|
4
|
+
|
|
5
|
+
A pre-1.0 security release. Several things 0.24.1 did quietly -- run a pack with an open network because
|
|
6
|
+
its network level was unknown, start a run on a network that could not show it had no route out, report
|
|
7
|
+
a conformance boundary as passed when it could not be measured -- are now refused or reported as not
|
|
8
|
+
checked. That is what makes the breaking changes below; each is listed with what to do.
|
|
9
|
+
|
|
10
|
+
### Breaking changes since 0.24.1
|
|
11
|
+
|
|
12
|
+
They were measured against the published 0.24.1 wheel: the public API, the CLI and the behaviour tests
|
|
13
|
+
of 0.24.1 were run against this tree. Nothing else in the public API, the signatures, the defaults or
|
|
14
|
+
the command line was removed or changed.
|
|
15
|
+
|
|
16
|
+
- **Python 3.13 and newer are no longer supported.** `requires-python` is now `>=3.10,<3.13`. An
|
|
17
|
+
installer on Python 3.13 or 3.14 is not offered this release and stays on 0.24.1.
|
|
18
|
+
- **Network permissions are a contract.** `permissions.network_level` must be one of:
|
|
19
|
+
- `none`;
|
|
20
|
+
- `unrestricted`;
|
|
21
|
+
- `restricted`, which needs a non-empty `allowed_domains`.
|
|
22
|
+
|
|
23
|
+
A pack declaring `full`, an unknown value, or `restricted` without domains is refused and nothing
|
|
24
|
+
runs. 0.24.1 ran such packs with network access.
|
|
25
|
+
- **A network meant to have no route out must show that it is internal.** If the container runtime
|
|
26
|
+
does not report it, the run is refused rather than started.
|
|
27
|
+
- **Conformance checks say `not_checked`** where a boundary cannot be measured on the host, instead of
|
|
28
|
+
a pass or a fail.
|
|
29
|
+
- `agentnode_sdk.conformance.runner.TIMEOUT_RC` is now `SUPERSEDED_TIMEOUT_RC`; there is no alias.
|
|
30
|
+
A timeout no longer has an exit code: test `Outcome.reason == agentnode_sdk.gateway.protocol.TIMED_OUT`
|
|
31
|
+
instead of comparing the code with -1. An alias would import and then never match, so a timeout would
|
|
32
|
+
pass for an ordinary ending. Reading `runner.TIMEOUT_RC` raises an `AttributeError` that says this.
|
|
33
|
+
|
|
34
|
+
### Migrating from 0.24.1
|
|
35
|
+
|
|
36
|
+
1. **Python.** Use Python 3.10, 3.11 or 3.12. On 3.13 or 3.14 pip does not offer 0.25.0 and keeps
|
|
37
|
+
0.24.1; pin `agentnode-sdk==0.24.1` there if you need a stable choice.
|
|
38
|
+
2. **Pack network permission.** In `agentnode.yaml` it is `permissions.network.level` (with
|
|
39
|
+
`permissions.network.allowed_domains`); an installed entry carries it as `permissions.network_level`
|
|
40
|
+
and `permissions.allowed_domains`.
|
|
41
|
+
- Missing or empty means `none` (no network), as before.
|
|
42
|
+
- `full` and `limited` are refused, not translated. Write `unrestricted` if the pack really needs any
|
|
43
|
+
destination, or `restricted` with `allowed_domains`.
|
|
44
|
+
- `restricted` needs at least one domain, and each must be a real host name: no IP literal, no
|
|
45
|
+
`localhost`, no single-label name.
|
|
46
|
+
- Values are read case-insensitively; anything else is refused with the reason before anything runs.
|
|
47
|
+
- `agentnode validate` does not apply this rule yet (it only warns about broad network access): a
|
|
48
|
+
pack that validates can still be refused when it runs. Check the level by hand before publishing.
|
|
49
|
+
3. **Container runtime.** A run that asks for no network now needs a runtime that reports the network
|
|
50
|
+
it created as internal. If yours does not, the run is refused with the reason; it is not started
|
|
51
|
+
with a route out.
|
|
52
|
+
4. **Conformance reports.** Treat `not_checked` as its own outcome. It is neither a pass nor a fail:
|
|
53
|
+
the boundary could not be measured on that host.
|
|
54
|
+
5. **Timeouts in your own code.** Replace `rc == TIMEOUT_RC` with
|
|
55
|
+
`outcome.reason == agentnode_sdk.gateway.protocol.TIMED_OUT`. The exit code of a stopped run is
|
|
56
|
+
`None`. `SUPERSEDED_TIMEOUT_RC` (-1) exists only for reading old reports.
|
|
57
|
+
6. **`mcp` dependency.** The bound is now `mcp>=1.0.0,<3`, so an environment with mcp 2.x installs
|
|
58
|
+
without a conflict.
|
|
59
|
+
|
|
60
|
+
### Added
|
|
61
|
+
|
|
62
|
+
- **Remote MCP:** `agentnode serve` serves on mcp 1.x and 2.x (`mcp>=1.0.0,<3`), offers the pack
|
|
63
|
+
tools and the platform tools, and `--packs` limits what is exposed. A tool error is a failure
|
|
64
|
+
result.
|
|
65
|
+
- **Website to gateway identity link.** The website signs a single-use link, valid for two minutes.
|
|
66
|
+
The gateway redeems it with `POST /v1/link`; on the device this is
|
|
67
|
+
`agentnode remote connect ... --link`. It is inactive until the website's signing key is set.
|
|
68
|
+
- **Per-account ceilings** on a gateway (`--account-runs-per-window`, `--account-lifetime-runs`,
|
|
69
|
+
`--trial`). Deleting an account clears its ceilings, and an account export carries them.
|
|
70
|
+
- **Self-hosted gateway as a documented beta path.** The gateway refuses to start unpinned unless
|
|
71
|
+
`AGENTNODE_ALLOW_UNPINNED` is set.
|
|
72
|
+
- **A paired worker rollback needs the control plane's signed statement** (P13). An operator's
|
|
73
|
+
assertion is no longer enough.
|
|
74
|
+
- **The CLI:** a failed run says why and exits 1, and a dashboard API key is sent as `X-API-Key`.
|
|
75
|
+
- **`agentnode validate` and `agentnode publish` take `--manifest <file>` and `--json`.** The manifest
|
|
76
|
+
may be `.yaml`, `.yml` or `.json` and need not be called `agentnode.yaml` (publish packs it under
|
|
77
|
+
that name). `--json` prints one JSON document on stdout. Without the new options both commands
|
|
78
|
+
behave exactly as before.
|
|
79
|
+
|
|
80
|
+
### Fixed
|
|
81
|
+
|
|
82
|
+
- **An edge refusal closes in order,** so its answer reaches a client whose request the edge left
|
|
83
|
+
unread. Before, the connection could end in a reset.
|
|
84
|
+
|
|
85
|
+
### Not yet true
|
|
86
|
+
|
|
87
|
+
- **A worker on its own machine** was accepted by cross-host run r3 for an earlier build (df821f65).
|
|
88
|
+
The current build was **not** accepted by r4. r5 has not run.
|
|
89
|
+
|
|
3
90
|
## 0.24.1 — the sandbox does what it said
|
|
4
91
|
|
|
5
92
|
Three defects in the local sandbox runtime, found by the backend conformance suite (EM-3B)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: agentnode-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.25.0
|
|
4
4
|
Summary: Python SDK for AgentNode — the open upgrade and discovery infrastructure for AI agents.
|
|
5
5
|
Project-URL: Homepage, https://agentnode.net
|
|
6
6
|
Project-URL: Repository, https://github.com/agentnode-ai/agentnode
|
|
@@ -13,11 +13,11 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.11
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.12
|
|
15
15
|
Classifier: Topic :: Software Development :: Libraries
|
|
16
|
-
Requires-Python:
|
|
16
|
+
Requires-Python: <3.13,>=3.10
|
|
17
17
|
Requires-Dist: cryptography>=41.0
|
|
18
18
|
Requires-Dist: httpx>=0.25
|
|
19
19
|
Requires-Dist: keyring>=24
|
|
20
|
-
Requires-Dist: mcp<
|
|
20
|
+
Requires-Dist: mcp<3,>=1.0.0
|
|
21
21
|
Requires-Dist: packaging>=21
|
|
22
22
|
Requires-Dist: pyyaml>=6.0
|
|
23
23
|
Provides-Extra: dev
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"""AgentNode Python SDK — discover, resolve, and install AI agent capabilities."""
|
|
2
|
+
|
|
3
|
+
# THE EXCEPTION TYPES FIRST, and outside the guard below, because they need nothing but the
|
|
4
|
+
# standard library and the refusal this module may have to raise has to be a real AgentNodeError
|
|
5
|
+
# rather than something invented on the spot.
|
|
6
|
+
from agentnode_sdk.exceptions import (
|
|
7
|
+
AgentNodeError,
|
|
8
|
+
AgentNodeToolError,
|
|
9
|
+
AuthError,
|
|
10
|
+
NotFoundError,
|
|
11
|
+
RateLimitError,
|
|
12
|
+
ValidationError,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
#: WHICH DEPENDENCY THIS INSTALLATION IS MISSING, or "" when nothing is.
|
|
16
|
+
#:
|
|
17
|
+
#: WHY THIS EXISTS. `cli/main.py` does `import agentnode_sdk`, and importing any name of this
|
|
18
|
+
#: package executes this file -- which imports the client, the async client and the installer, each
|
|
19
|
+
#: of which imports `httpx` at module scope. On a host whose install was interrupted after the
|
|
20
|
+
#: package arrived and before its dependencies did, that raised `ModuleNotFoundError` three imports
|
|
21
|
+
#: deep and the WHOLE CLI died before argparse existed. The third beta acceptance measured exactly
|
|
22
|
+
#: that: `agentnode gateway doctor` -- the published way to ask whether a host is ready -- answered
|
|
23
|
+
#: with a traceback. A host that cannot say it is not ready is PR7 of that profile at WARN.
|
|
24
|
+
_MISSING_DEPENDENCY = ""
|
|
25
|
+
# EVERYTHING THAT CAN NEED A THIRD-PARTY PACKAGE, under one guard.
|
|
26
|
+
#
|
|
27
|
+
# `ModuleNotFoundError` ONLY, and re-raised at once when the missing module is one of ours. A
|
|
28
|
+
# missing third-party package means the dependencies never arrived -- an incomplete installation,
|
|
29
|
+
# which this package can report. A missing `agentnode_sdk` submodule means this BUILD is wrong, and
|
|
30
|
+
# swallowing that would hide the one class of error that must never be hidden.
|
|
31
|
+
try:
|
|
32
|
+
from agentnode_sdk.async_client import AsyncAgentNode
|
|
33
|
+
from agentnode_sdk.client import AgentNode, AgentNodeClient
|
|
34
|
+
from agentnode_sdk.config import load_config, config_path, installation_behavior_label
|
|
35
|
+
from agentnode_sdk.detect import detect_gap
|
|
36
|
+
from agentnode_sdk.installer import load_tool
|
|
37
|
+
from agentnode_sdk.skill import load_skill, SkillContext, SkillAsset
|
|
38
|
+
from agentnode_sdk.models import (
|
|
39
|
+
CanInstallResult,
|
|
40
|
+
DetectAndInstallResult,
|
|
41
|
+
DetectedGap,
|
|
42
|
+
InstallMetadata,
|
|
43
|
+
InstallResult,
|
|
44
|
+
PackageDetail,
|
|
45
|
+
ResolvedPackage,
|
|
46
|
+
ResolveResult,
|
|
47
|
+
RunToolResult,
|
|
48
|
+
SearchHit,
|
|
49
|
+
SearchResult,
|
|
50
|
+
SmartRunResult,
|
|
51
|
+
)
|
|
52
|
+
from agentnode_sdk.compatibility import recommend_model
|
|
53
|
+
from agentnode_sdk.risk_profile import RiskProfile, compute_risk_profile, get_risk_profile
|
|
54
|
+
from agentnode_sdk.policy import PolicyResult, check_install, check_run
|
|
55
|
+
from agentnode_sdk.runner import run_tool
|
|
56
|
+
from agentnode_sdk.runtime import AgentNodeRuntime
|
|
57
|
+
|
|
58
|
+
# Convenience aliases
|
|
59
|
+
Client = AgentNodeClient
|
|
60
|
+
ToolError = AgentNodeToolError
|
|
61
|
+
except ModuleNotFoundError as _missing: # noqa: BLE001
|
|
62
|
+
_name = str(getattr(_missing, "name", "") or "")
|
|
63
|
+
if _name.split(".")[0] == "agentnode_sdk":
|
|
64
|
+
raise
|
|
65
|
+
_MISSING_DEPENDENCY = _name or str(_missing)
|
|
66
|
+
|
|
67
|
+
#: THE ONE PLACE THE VERSION IS WRITTEN. `pyproject.toml` builds the wheel's version from this
|
|
68
|
+
#: line rather than carrying its own copy, because it did carry one: the project said 0.25.0
|
|
69
|
+
#: while this said 0.24.1, so the gateway announced 0.24.1 to every client it answered while
|
|
70
|
+
#: running the 0.25.0 build. Two copies of one number drift, and the drift is invisible until
|
|
71
|
+
#: something reports the wrong one.
|
|
72
|
+
__version__ = "0.25.0"
|
|
73
|
+
__all__ = [
|
|
74
|
+
"AgentNode",
|
|
75
|
+
"AsyncAgentNode",
|
|
76
|
+
"AgentNodeClient",
|
|
77
|
+
"Client",
|
|
78
|
+
"load_config",
|
|
79
|
+
"config_path",
|
|
80
|
+
"installation_behavior_label",
|
|
81
|
+
"detect_gap",
|
|
82
|
+
"load_tool",
|
|
83
|
+
"load_skill",
|
|
84
|
+
"SkillContext",
|
|
85
|
+
"SkillAsset",
|
|
86
|
+
"run_tool",
|
|
87
|
+
"AgentNodeError",
|
|
88
|
+
"AgentNodeToolError",
|
|
89
|
+
"ToolError",
|
|
90
|
+
"NotFoundError",
|
|
91
|
+
"AuthError",
|
|
92
|
+
"RateLimitError",
|
|
93
|
+
"ValidationError",
|
|
94
|
+
"PackageDetail",
|
|
95
|
+
"SearchResult",
|
|
96
|
+
"SearchHit",
|
|
97
|
+
"ResolveResult",
|
|
98
|
+
"ResolvedPackage",
|
|
99
|
+
"InstallMetadata",
|
|
100
|
+
"InstallResult",
|
|
101
|
+
"CanInstallResult",
|
|
102
|
+
"RunToolResult",
|
|
103
|
+
"DetectedGap",
|
|
104
|
+
"DetectAndInstallResult",
|
|
105
|
+
"SmartRunResult",
|
|
106
|
+
"AgentNodeRuntime",
|
|
107
|
+
"PolicyResult",
|
|
108
|
+
"check_install",
|
|
109
|
+
"check_run",
|
|
110
|
+
"recommend_model",
|
|
111
|
+
"RiskProfile",
|
|
112
|
+
"compute_risk_profile",
|
|
113
|
+
"get_risk_profile",
|
|
114
|
+
]
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def what_this_installation_is_missing() -> str:
|
|
118
|
+
"""The third-party package this installation needs and does not have, or "".
|
|
119
|
+
|
|
120
|
+
Read by the readiness paths -- `gateway doctor`, `gateway status`, `worker preflight` -- so that
|
|
121
|
+
a host whose install was interrupted can SAY SO in words and in a machine-readable form, rather
|
|
122
|
+
than dying three imports deep on a package nobody asked it about.
|
|
123
|
+
"""
|
|
124
|
+
return _MISSING_DEPENDENCY
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
if _MISSING_DEPENDENCY:
|
|
128
|
+
# BIND EVERY PUBLIC NAME THAT DID NOT GET ONE, to something that explains itself.
|
|
129
|
+
#
|
|
130
|
+
# Driven by `__all__` rather than by a hand-written list, so the stub set cannot drift from the
|
|
131
|
+
# public API -- a name added above and forgotten here would be an `AttributeError` on an
|
|
132
|
+
# incomplete installation instead of the sentence this is for.
|
|
133
|
+
#
|
|
134
|
+
# A STUB THAT RAISES, never one that returns something. A silent no-op would be worse than the
|
|
135
|
+
# traceback it replaces: the traceback at least said what was wrong.
|
|
136
|
+
def _needs_the_missing_package(_name):
|
|
137
|
+
def refuse(*_args, **_kwargs):
|
|
138
|
+
# `AgentNodeError(code, message)`, which is the signature it has. The first version of
|
|
139
|
+
# this passed one string and the stub raised `TypeError` instead of saying anything.
|
|
140
|
+
raise AgentNodeError(
|
|
141
|
+
"installation_incomplete",
|
|
142
|
+
"%s needs the %r package, which this installation does not have. The install "
|
|
143
|
+
"was interrupted before its dependencies arrived; re-run the installer for this "
|
|
144
|
+
"host, or `pip install %s`. Ask this host what it is missing with "
|
|
145
|
+
"`agentnode gateway doctor`."
|
|
146
|
+
% (_name, _MISSING_DEPENDENCY, _MISSING_DEPENDENCY))
|
|
147
|
+
refuse.__name__ = str(_name)
|
|
148
|
+
refuse.__doc__ = ("Unavailable: this installation is missing %r."
|
|
149
|
+
% _MISSING_DEPENDENCY)
|
|
150
|
+
return refuse
|
|
151
|
+
|
|
152
|
+
for _public in __all__:
|
|
153
|
+
if _public not in globals():
|
|
154
|
+
globals()[_public] = _needs_the_missing_package(_public)
|
|
155
|
+
del _public
|
|
@@ -274,11 +274,33 @@ for dist in im.distributions():
|
|
|
274
274
|
"editable": is_editable(dist),
|
|
275
275
|
"has_record": has_record,
|
|
276
276
|
"provides_top": expected_top in tops,
|
|
277
|
+
# WHERE it really is, so two paths to one directory can be seen as one thing. A venv
|
|
278
|
+
# with lib64 symlinked to lib puts both on sys.path, and an interpreter that walks
|
|
279
|
+
# both reports the same installation twice.
|
|
280
|
+
"where": canon(dip) if dip else "",
|
|
277
281
|
})
|
|
278
282
|
else:
|
|
279
283
|
if expected_top in tops:
|
|
280
284
|
other_top_providers.append(nm or "?")
|
|
281
285
|
|
|
286
|
+
# ONE INSTALLATION SEEN DOWN TWO PATHS IS ONE INSTALLATION. Deduplicated by the resolved
|
|
287
|
+
# location before anything counts them, because the question `post_verify` asks -- is this
|
|
288
|
+
# installed exactly once -- is about installations and was being answered about paths. Entries
|
|
289
|
+
# with no resolvable location are kept as they are: an unlocatable match is not a duplicate of
|
|
290
|
+
# anything, and silently folding them together would hide the case worth seeing.
|
|
291
|
+
seen = {}
|
|
292
|
+
unique = []
|
|
293
|
+
for m in matches:
|
|
294
|
+
where = m.get("where") or ""
|
|
295
|
+
if not where:
|
|
296
|
+
unique.append(m)
|
|
297
|
+
continue
|
|
298
|
+
if where in seen:
|
|
299
|
+
continue
|
|
300
|
+
seen[where] = True
|
|
301
|
+
unique.append(m)
|
|
302
|
+
matches = unique
|
|
303
|
+
|
|
282
304
|
print(json.dumps({"matches": matches, "other_top_providers": other_top_providers}))
|
|
283
305
|
'''
|
|
284
306
|
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""Which source this artefact was built from, written INTO it at build time.
|
|
2
|
+
|
|
3
|
+
A deployment used to be handed a commit and believe it. `deploy-pinned.sh` took the commit as an
|
|
4
|
+
argument and compared it against an expectation only when an optional environment variable
|
|
5
|
+
supplied one, so the answer to "which source is this wheel?" was whatever the caller said.
|
|
6
|
+
`ALPHA-RUNTIME-PIN-0002` named that, and it was right: nothing tied the artefact to a commit.
|
|
7
|
+
|
|
8
|
+
So the build writes it in. `PROVENANCE_NAME` is part of the package, which means it is part of the
|
|
9
|
+
wheel, which means it is covered by the wheel's digest -- changing the commit changes the artefact.
|
|
10
|
+
A deployment reads it back OUT of the wheel before installing anything and refuses if it is absent
|
|
11
|
+
or disagrees. The operator can still lie to the build; what they can no longer do is hand a
|
|
12
|
+
deployment an artefact and a commit that have nothing to do with each other.
|
|
13
|
+
"""
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import json
|
|
17
|
+
import pathlib
|
|
18
|
+
import zipfile
|
|
19
|
+
|
|
20
|
+
#: Inside the installed package and inside the wheel, at the same relative path.
|
|
21
|
+
PROVENANCE_NAME = "_provenance.json"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def written_beside_this_module() -> pathlib.Path:
|
|
25
|
+
return pathlib.Path(__file__).resolve().parent / PROVENANCE_NAME
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def record(commit: str, where: pathlib.Path | None = None) -> pathlib.Path:
|
|
29
|
+
"""Write the commit into the source tree, so the build carries it into the wheel."""
|
|
30
|
+
path = where or written_beside_this_module()
|
|
31
|
+
path.write_text(json.dumps({"commit": str(commit or "")}, indent=1) + "\n",
|
|
32
|
+
encoding="utf-8")
|
|
33
|
+
return path
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def of_this_installation() -> str:
|
|
37
|
+
"""The commit this installed package was built from, or "" when it does not say."""
|
|
38
|
+
try:
|
|
39
|
+
said = json.loads(written_beside_this_module().read_text(encoding="utf-8"))
|
|
40
|
+
except Exception: # noqa: BLE001
|
|
41
|
+
return ""
|
|
42
|
+
return str(said.get("commit") or "") if isinstance(said, dict) else ""
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def of_a_wheel(wheel) -> str:
|
|
46
|
+
"""The commit a wheel was built from, read WITHOUT installing it.
|
|
47
|
+
|
|
48
|
+
Before anything is installed is the only moment this is worth asking: a deployment that
|
|
49
|
+
discovers the artefact is the wrong one after replacing the running code has discovered it
|
|
50
|
+
too late.
|
|
51
|
+
"""
|
|
52
|
+
try:
|
|
53
|
+
with zipfile.ZipFile(str(wheel)) as inside:
|
|
54
|
+
names = [n for n in inside.namelist()
|
|
55
|
+
if n.endswith("agentnode_sdk/" + PROVENANCE_NAME)]
|
|
56
|
+
if not names:
|
|
57
|
+
return ""
|
|
58
|
+
said = json.loads(inside.read(names[0]).decode("utf-8"))
|
|
59
|
+
except Exception: # noqa: BLE001
|
|
60
|
+
return ""
|
|
61
|
+
return str(said.get("commit") or "") if isinstance(said, dict) else ""
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""How anything reaches AgentNode.
|
|
2
|
+
|
|
3
|
+
One contract, several transports over it, and no security decision anywhere but the server. What
|
|
4
|
+
lives here is the part that is the same for every client: which systems can reach us at all
|
|
5
|
+
(`compatibility`), and -- as it is built -- the canonical operation contract that MCP, REST, the
|
|
6
|
+
SDK, the CLI and the web client are each a rendering of.
|
|
7
|
+
|
|
8
|
+
Nothing here is specific to any AI vendor. A provider name may appear in a test or in a
|
|
9
|
+
compatibility record as data; it may not appear in a decision.
|
|
10
|
+
"""
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"""How something on the USER's machine reaches the sandbox: over the authenticated API.
|
|
2
|
+
|
|
3
|
+
`MANAGED-ACCESS-DECISION-0001` settled this and it is the part worth not forgetting. The CLI, the
|
|
4
|
+
stdio MCP bridge and the SDKs all run where the user is. Anything they enforce is advice: the
|
|
5
|
+
person they are protecting the sandbox from is the person who can edit them. So they get no
|
|
6
|
+
in-process shortcut, no direct `dispatch()` call, and no access to `GatewayState`, the worker or
|
|
7
|
+
the runtime -- they speak HTTP to the gateway exactly as a stranger would, and the answer they get
|
|
8
|
+
is the answer anybody would get.
|
|
9
|
+
|
|
10
|
+
What lives here is therefore a transport and nothing else: take an operation and some parameters,
|
|
11
|
+
present the device's token, and hand back what came out. Every decision was made on the other end.
|
|
12
|
+
"""
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import json
|
|
16
|
+
import urllib.error
|
|
17
|
+
import urllib.request
|
|
18
|
+
|
|
19
|
+
from agentnode_sdk.access import contract, rest
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class TheSandboxRefused(Exception):
|
|
23
|
+
"""A refusal, carried back with its name intact so a caller can branch on it."""
|
|
24
|
+
|
|
25
|
+
def __init__(self, refusal: str, because: str, what_to_do: str = "") -> None:
|
|
26
|
+
super().__init__(because)
|
|
27
|
+
self.refusal = refusal
|
|
28
|
+
self.because = because
|
|
29
|
+
self.what_to_do = what_to_do
|
|
30
|
+
|
|
31
|
+
def in_words(self) -> str:
|
|
32
|
+
said = self.because
|
|
33
|
+
if self.what_to_do:
|
|
34
|
+
said += "\n" + self.what_to_do
|
|
35
|
+
return said
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class Sandbox:
|
|
39
|
+
"""A sandbox somewhere, reached the way anybody reaches it."""
|
|
40
|
+
|
|
41
|
+
def __init__(self, base: str, token: str, opener=None, timeout: float = 60.0) -> None:
|
|
42
|
+
self.base = base.rstrip("/")
|
|
43
|
+
self.token = token
|
|
44
|
+
self.timeout = timeout
|
|
45
|
+
#: Supplied by a caller that pins a certificate. Absent here rather than reimplemented:
|
|
46
|
+
#: pinning already exists in `gateway/pinning.py` and a second version of it would be a
|
|
47
|
+
#: second thing to get wrong.
|
|
48
|
+
self.opener = opener
|
|
49
|
+
|
|
50
|
+
def ask(self, operation: str, **params):
|
|
51
|
+
"""Carry out an operation, or raise the refusal it came back with."""
|
|
52
|
+
op = contract.find(operation)
|
|
53
|
+
path = self.base + rest.NAMESPACE + operation.replace(".", "/")
|
|
54
|
+
method = "POST" if (op is None or op.changes or op.params) else "GET"
|
|
55
|
+
body = json.dumps(params).encode("utf-8") if method == "POST" else None
|
|
56
|
+
request = urllib.request.Request(path, data=body, method=method)
|
|
57
|
+
request.add_header("Content-Type", "application/json")
|
|
58
|
+
request.add_header(rest.SPEAKS_HEADER, contract.PROTOCOL_VERSION)
|
|
59
|
+
if self.token:
|
|
60
|
+
request.add_header(rest.TOKEN_HEADER, self.token)
|
|
61
|
+
opener = self.opener.open if self.opener is not None else urllib.request.urlopen
|
|
62
|
+
try:
|
|
63
|
+
with opener(request, timeout=self.timeout) as answer:
|
|
64
|
+
return json.loads(answer.read().decode("utf-8") or "{}")
|
|
65
|
+
except urllib.error.HTTPError as refused:
|
|
66
|
+
raise _as_refusal(refused) from None
|
|
67
|
+
except urllib.error.URLError as unreachable:
|
|
68
|
+
raise TheSandboxRefused(
|
|
69
|
+
"sandbox_unavailable",
|
|
70
|
+
"Could not reach the sandbox at %s: %s" % (self.base, unreachable.reason),
|
|
71
|
+
"Check that it is running and that this machine can reach it.") from None
|
|
72
|
+
|
|
73
|
+
def speak_mcp(self, message: dict) -> dict | None:
|
|
74
|
+
"""Send one JSON-RPC message to this sandbox's MCP endpoint and return its answer.
|
|
75
|
+
|
|
76
|
+
Raw, not translated. The gateway already speaks MCP; a second translation on this side
|
|
77
|
+
would be a second thing to keep in step, and it was one: the bridge used to rebuild MCP
|
|
78
|
+
out of REST calls, so the gateway recorded the channel as `rest` while the caller was an
|
|
79
|
+
MCP client. An approval given for MCP could then never be spent, which is how the most
|
|
80
|
+
prominent option in the console -- Claude Code or Codex on my machine -- could not
|
|
81
|
+
complete a job at all.
|
|
82
|
+
"""
|
|
83
|
+
request = urllib.request.Request(self.base + rest.MCP_PATH,
|
|
84
|
+
data=json.dumps(message).encode("utf-8"), method="POST")
|
|
85
|
+
request.add_header("Content-Type", "application/json")
|
|
86
|
+
request.add_header(rest.SPEAKS_HEADER, contract.PROTOCOL_VERSION)
|
|
87
|
+
if self.token:
|
|
88
|
+
request.add_header(rest.TOKEN_HEADER, self.token)
|
|
89
|
+
opener = self.opener.open if self.opener is not None else urllib.request.urlopen
|
|
90
|
+
try:
|
|
91
|
+
with opener(request, timeout=self.timeout) as answer:
|
|
92
|
+
body = answer.read().decode("utf-8")
|
|
93
|
+
except urllib.error.HTTPError as refused:
|
|
94
|
+
raise _as_refusal(refused) from None
|
|
95
|
+
except urllib.error.URLError as unreachable:
|
|
96
|
+
raise TheSandboxRefused(
|
|
97
|
+
"sandbox_unavailable",
|
|
98
|
+
"Could not reach the sandbox at %s: %s" % (self.base, unreachable.reason),
|
|
99
|
+
"Check that it is running and that this machine can reach it.") from None
|
|
100
|
+
return json.loads(body) if body.strip() else None
|
|
101
|
+
|
|
102
|
+
# -- the journey, named the way a person would say it ------------------------------------
|
|
103
|
+
|
|
104
|
+
def capabilities(self):
|
|
105
|
+
return self.ask("capabilities")
|
|
106
|
+
|
|
107
|
+
def prepare(self, **what):
|
|
108
|
+
return self.ask("prepare", **what)
|
|
109
|
+
|
|
110
|
+
def submit(self, **what):
|
|
111
|
+
return self.ask("submit", **what)
|
|
112
|
+
|
|
113
|
+
def status(self, run_id: str):
|
|
114
|
+
return self.ask("status", run_id=run_id)
|
|
115
|
+
|
|
116
|
+
def result(self, run_id: str):
|
|
117
|
+
return self.ask("result", run_id=run_id)
|
|
118
|
+
|
|
119
|
+
def cancel(self, run_id: str):
|
|
120
|
+
return self.ask("cancel", run_id=run_id)
|
|
121
|
+
|
|
122
|
+
def usage(self):
|
|
123
|
+
return self.ask("usage")
|
|
124
|
+
|
|
125
|
+
def devices(self):
|
|
126
|
+
return self.ask("devices.list")
|
|
127
|
+
|
|
128
|
+
def revoke(self, device_id: str):
|
|
129
|
+
return self.ask("devices.revoke", device_id=device_id)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def _as_refusal(refused) -> TheSandboxRefused:
|
|
133
|
+
try:
|
|
134
|
+
answer = json.loads(refused.read().decode("utf-8") or "{}")
|
|
135
|
+
except (ValueError, UnicodeDecodeError):
|
|
136
|
+
answer = {}
|
|
137
|
+
return TheSandboxRefused(
|
|
138
|
+
str(answer.get("refused") or "sandbox_unavailable"),
|
|
139
|
+
str(answer.get("because") or ("the sandbox answered %s" % refused.code)),
|
|
140
|
+
str(answer.get("what_to_do") or ""))
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
# ---------------------------------------------------------------- the local MCP bridge
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def bridge(sandbox: Sandbox, incoming, outgoing) -> None:
|
|
147
|
+
"""Speak MCP on a pipe, and forward every call over the authenticated API.
|
|
148
|
+
|
|
149
|
+
For programs that will only talk to a local MCP server. It is a relay and holds no authority
|
|
150
|
+
of its own: every message is forwarded to the sandbox's own MCP endpoint, so the tool list,
|
|
151
|
+
the refusals and the wording are the sandbox's, not this process's. A tool the device may not
|
|
152
|
+
use never appears, and calling one anyway is refused at the far end.
|
|
153
|
+
|
|
154
|
+
FORWARDED, not translated. This used to rebuild MCP out of REST operations, which meant the
|
|
155
|
+
gateway saw `rest` while the caller was an MCP client -- so an approval given for MCP could
|
|
156
|
+
never be spent, and the console's most prominent option could not finish a job. A relay that
|
|
157
|
+
changes what channel you appear to be on is not a relay.
|
|
158
|
+
"""
|
|
159
|
+
for line in incoming:
|
|
160
|
+
line = line.strip()
|
|
161
|
+
if not line:
|
|
162
|
+
continue
|
|
163
|
+
try:
|
|
164
|
+
message = json.loads(line)
|
|
165
|
+
except ValueError:
|
|
166
|
+
_write(outgoing, {"jsonrpc": "2.0", "id": None,
|
|
167
|
+
"error": {"code": -32700, "message": "that is not JSON"}})
|
|
168
|
+
continue
|
|
169
|
+
reply = _forward(sandbox, message)
|
|
170
|
+
if reply is not None:
|
|
171
|
+
_write(outgoing, reply)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def _forward(sandbox: Sandbox, message: dict):
|
|
175
|
+
"""Hand one message to the sandbox and give back what it said."""
|
|
176
|
+
method = str(message.get("method") or "")
|
|
177
|
+
if message.get("id") is None and method.startswith("notifications/"):
|
|
178
|
+
return None
|
|
179
|
+
try:
|
|
180
|
+
return sandbox.speak_mcp(message)
|
|
181
|
+
except TheSandboxRefused as refusal:
|
|
182
|
+
# Reaching the sandbox failed, which is not the same as the sandbox refusing a call. It
|
|
183
|
+
# is reported as a transport error so a client retries rather than telling a person their
|
|
184
|
+
# job was rejected.
|
|
185
|
+
return {"jsonrpc": "2.0", "id": message.get("id"),
|
|
186
|
+
"error": {"code": -32000, "message": refusal.in_words()}}
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def _write(outgoing, message) -> None:
|
|
190
|
+
outgoing.write(json.dumps(message) + "\n")
|
|
191
|
+
outgoing.flush()
|