agentnode-sdk 0.11.0__tar.gz → 0.11.1__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.11.0 → agentnode_sdk-0.11.1}/CHANGELOG.md +24 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/PKG-INFO +1 -1
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/__init__.py +1 -1
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/installer.py +12 -1
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/runtimes/agent_runner.py +9 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/pyproject.toml +1 -1
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_agent_runner.py +27 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_install_hardening.py +10 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/.env.example +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/.gitignore +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/README.md +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/REGISTRY_SIGNING_ACTIVATION.md +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/REGISTRY_SIGNING_SPEC.md +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/THREAT_MODEL.md +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/TRUST_STACK.md +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode.lock +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/_fileutil.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/async_client.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/capability_graph.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/capability_taxonomy.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/cli/__init__.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/cli/__main__.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/cli/audit.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/cli/auth.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/cli/cassette_audit.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/cli/commands.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/cli/complements.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/cli/init.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/cli/main.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/cli/mcp_commands.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/cli/mcp_status.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/cli/mcp_submit.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/cli/mcp_verify.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/cli/output.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/cli/publish.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/cli/record_cases.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/cli/sandbox_commands.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/cli/serve.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/cli/setup_wizard.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/cli/smart_run.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/cli/templates.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/cli/validate.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/cli/verify_local.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/client.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/compatibility.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/config.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/credential_handle.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/credential_resolver.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/credential_store.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/detect.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/exceptions.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/guard.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/input_guard.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/key_status.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/lock_integrity.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/mcp_server.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/models.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/planner.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/policy.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/registry_trust.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/resolve.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/resource_provider.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/risk_profile.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/run_log.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/runner.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/runtime.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/runtimes/__init__.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/runtimes/mcp_runner.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/runtimes/python_runner.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/runtimes/remote_runner.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/sandbox/__init__.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/sandbox/backend.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/sandbox/container_backend.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/sandbox/policy.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/sandbox/types.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/signature.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/signing_key.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/agentnode_sdk/skill.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/sandbox-image/Dockerfile +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/sandbox-image/README.md +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/scripts/analyze_scores.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/scripts/batch_verify.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/scripts/ci_smoke_test.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/scripts/generate_compatibility_artifacts.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/scripts/verify_toolcalls.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/scripts/weekly_retest.sh +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/__init__.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/conftest.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_async_client.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_audit_ux.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_auto_upgrade_policy.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_cli.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_cli_lock.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_client.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_client_json_guard.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_client_sprint_b.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_config.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_credential_handle.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_credential_integration.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_credential_resolver.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_credential_store.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_detect.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_detect_and_install.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_e2e_runtime.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_edge_cases.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_guard.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_guard_check.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_guard_config_cache.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_guard_policy.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_guard_preview.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_guard_schema.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_guard_set.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_guard_status.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_guard_tool_override.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_guard_tool_override_audit.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_guard_tool_override_cli.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_guard_ux.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_input_guard.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_input_guard_escalation.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_installer_sprint_b.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_intelligence.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_key_status.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_llm_binding.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_llm_call_runlog.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_lock_integrity.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_lock_runtime.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_mcp_audit.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_mcp_doctor.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_mcp_sandbox.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_mcp_server.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_observability.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_planner.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_policy.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_policy_integration.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_prompt_specs.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_provider_matrix.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_publish.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_registry_trust.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_remote_hardening.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_remote_runner.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_resource_provider.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_resource_specs.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_risk_profile.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_run_log.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_runner.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_runtime.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_runtime_audit.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_sandbox_backend.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_sandbox_doctor.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_sandbox_e2e.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_sandbox_gate.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_security_hardening.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_signature.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_signing_key.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_skill.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_smart.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_stability.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_toolpack_sandbox.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_v02.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_validate.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/test_validate_skill.py +0 -0
- {agentnode_sdk-0.11.0 → agentnode_sdk-0.11.1}/tests/validation_lockfile.json +0 -0
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.11.1 — Bugfix + hardening
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **Install targets the running interpreter.** `installer.resolve_python()` now
|
|
8
|
+
returns `sys.executable` first, so the host build (`agentnode install` of a
|
|
9
|
+
trusted/curated pack) and `agentnode run` use the **same** Python. Previously
|
|
10
|
+
it resolved `$VIRTUAL_ENV → ./.venv → PATH python3 → PATH python` and never
|
|
11
|
+
the interpreter actually running AgentNode, so under **pipx** or an
|
|
12
|
+
**unactivated venv** the pack installed into a different environment and the
|
|
13
|
+
run could not import it. The existing fallbacks are kept for the rare case of
|
|
14
|
+
an empty `sys.executable`. Host build path only — the community/sandbox path
|
|
15
|
+
builds with `python -m pip` inside the container and was never affected.
|
|
16
|
+
|
|
17
|
+
### Hardened
|
|
18
|
+
|
|
19
|
+
- **Agent execution-vector invariant documented + regression-tested.** An
|
|
20
|
+
agent's own entrypoint code runs on the host (not via `SandboxBackend`), so
|
|
21
|
+
the `trust >= trusted` gate in `run_agent` is a security invariant. Added an
|
|
22
|
+
audit comment at the gate (no logic change) and a named regression test
|
|
23
|
+
asserting that `None`/unknown/`unverified`/`verified`/`preview` agents are
|
|
24
|
+
refused while `trusted`/`curated` pass — locking the gate against silent
|
|
25
|
+
lowering that would run community code unsandboxed.
|
|
26
|
+
|
|
3
27
|
## 0.11.0 — Execution Sandbox (isolated or not at all)
|
|
4
28
|
|
|
5
29
|
The execution plane is now sandboxed. Community/unverified code (toolpack
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentnode-sdk
|
|
3
|
-
Version: 0.11.
|
|
3
|
+
Version: 0.11.1
|
|
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
|
|
@@ -40,9 +40,15 @@ PIP_TIMEOUT = 120
|
|
|
40
40
|
# ---------------------------------------------------------------------------
|
|
41
41
|
|
|
42
42
|
def resolve_python() -> str:
|
|
43
|
-
"""Find a usable Python 3 interpreter.
|
|
43
|
+
"""Find a usable Python 3 interpreter for the host package build.
|
|
44
44
|
|
|
45
45
|
Resolution order:
|
|
46
|
+
0. ``sys.executable`` — the interpreter actually running AgentNode, so a host
|
|
47
|
+
build (``agentnode install``) installs into the SAME environment that
|
|
48
|
+
``agentnode run`` later imports from. This fixes pipx / unactivated-venv
|
|
49
|
+
installs, where ``$VIRTUAL_ENV`` is unset and ``python`` on PATH is a
|
|
50
|
+
DIFFERENT interpreter (the package would install into the wrong env and
|
|
51
|
+
``agentnode run`` would fail to import it).
|
|
46
52
|
1. $VIRTUAL_ENV/bin/python (or Scripts/python.exe on Windows)
|
|
47
53
|
2. .venv/bin/python in cwd
|
|
48
54
|
3. python3 on PATH
|
|
@@ -50,6 +56,11 @@ def resolve_python() -> str:
|
|
|
50
56
|
"""
|
|
51
57
|
is_windows = sys.platform == "win32"
|
|
52
58
|
|
|
59
|
+
# 0. The interpreter actually running AgentNode — guarantees install and run
|
|
60
|
+
# use the same Python. Most reliable; prefer it over PATH/venv heuristics.
|
|
61
|
+
if sys.executable and os.path.isfile(sys.executable):
|
|
62
|
+
return sys.executable
|
|
63
|
+
|
|
53
64
|
# 1. Active virtual environment
|
|
54
65
|
venv = os.environ.get("VIRTUAL_ENV")
|
|
55
66
|
if venv:
|
|
@@ -1245,6 +1245,15 @@ def run_agent(
|
|
|
1245
1245
|
)
|
|
1246
1246
|
|
|
1247
1247
|
# --- 2. Agent-specific policy: trust >= trusted ---
|
|
1248
|
+
# SECURITY INVARIANT (audit 2026-06): an agent's OWN entrypoint code runs on
|
|
1249
|
+
# the HOST — in a thread (_execute_with_timeout) or a child process
|
|
1250
|
+
# (_execute_with_process) — NOT inside SandboxBackend. The exec-sandbox bow
|
|
1251
|
+
# (P0.0-P0.3) isolates the agent's *tool calls* (they re-enter run_tool's
|
|
1252
|
+
# gate), but NOT the agent's own orchestration code. So `trust >= trusted` is
|
|
1253
|
+
# the ONLY thing keeping community/unverified agent code off the host. Do NOT
|
|
1254
|
+
# lower this gate without first routing agent execution through SandboxBackend,
|
|
1255
|
+
# or community code runs unsandboxed (reintroducing the RCE class the sandbox
|
|
1256
|
+
# bow closed). Locked by test_agent_runner's execution-vector regression test.
|
|
1248
1257
|
trust_level = entry.get("trust_level", "unverified")
|
|
1249
1258
|
if not _trust_meets_minimum(trust_level, "trusted"):
|
|
1250
1259
|
_audit_agent_run(
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "agentnode-sdk"
|
|
7
|
-
version = "0.11.
|
|
7
|
+
version = "0.11.1"
|
|
8
8
|
description = "Python SDK for AgentNode — the open upgrade and discovery infrastructure for AI agents."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -319,6 +319,33 @@ class TestRunAgentTrustPolicy:
|
|
|
319
319
|
assert "trust level" not in (result.error or "")
|
|
320
320
|
|
|
321
321
|
|
|
322
|
+
# ---------------------------------------------------------------------------
|
|
323
|
+
# run_agent() — execution-vector invariant (0.11.1 hardening, audit 2026-06)
|
|
324
|
+
# ---------------------------------------------------------------------------
|
|
325
|
+
# An agent's OWN entrypoint code runs on the HOST (thread _execute_with_timeout /
|
|
326
|
+
# process _execute_with_process), NOT through SandboxBackend. The exec-sandbox
|
|
327
|
+
# bow does NOT cover the agent's own code. So `trust >= trusted` at the gate
|
|
328
|
+
# (agent_runner.py ~1248) is a SECURITY INVARIANT: lowering it would run
|
|
329
|
+
# community/unverified agent code unsandboxed on the host. These tests lock the
|
|
330
|
+
# gate against silent regressions — any non-(trusted|curated) level, including an
|
|
331
|
+
# unrecognized or missing one, must be refused with a trust-level error.
|
|
332
|
+
|
|
333
|
+
class TestRunAgentExecutionVectorInvariant:
|
|
334
|
+
@pytest.mark.parametrize("trust_level", [None, "unknown", "unverified", "verified", "preview"])
|
|
335
|
+
def test_community_or_unknown_agent_refused(self, trust_level):
|
|
336
|
+
entry = _agent_entry(trust_level=trust_level)
|
|
337
|
+
result = run_agent("test-agent", entry=entry)
|
|
338
|
+
assert result.success is False
|
|
339
|
+
assert "trust level" in (result.error or "")
|
|
340
|
+
|
|
341
|
+
@pytest.mark.parametrize("trust_level", ["trusted", "curated"])
|
|
342
|
+
def test_trusted_or_curated_agent_not_gated(self, trust_level):
|
|
343
|
+
entry = _agent_entry(trust_level=trust_level)
|
|
344
|
+
result = run_agent("test-agent", entry=entry)
|
|
345
|
+
# Passes the trust gate (may still fail later at entrypoint loading).
|
|
346
|
+
assert "trust level" not in (result.error or "")
|
|
347
|
+
|
|
348
|
+
|
|
322
349
|
# ---------------------------------------------------------------------------
|
|
323
350
|
# run_agent() — execution
|
|
324
351
|
# ---------------------------------------------------------------------------
|
|
@@ -93,3 +93,13 @@ def test_missing_artifact_hash_blocked(monkeypatch, tmp_path):
|
|
|
93
93
|
artifact_hash=None, entrypoint="pk.tool", trust_level="trusted",
|
|
94
94
|
)
|
|
95
95
|
assert pip_calls == []
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def test_resolve_python_prefers_sys_executable():
|
|
99
|
+
"""0.11.1 bugfix: the host build must target the interpreter actually running
|
|
100
|
+
AgentNode, so `agentnode install` + `agentnode run` use the SAME Python. In a
|
|
101
|
+
pipx / unactivated venv, $VIRTUAL_ENV is unset and `python` on PATH is a
|
|
102
|
+
DIFFERENT interpreter — the pack would install into the wrong env and the run
|
|
103
|
+
couldn't import it. resolve_python() must return sys.executable."""
|
|
104
|
+
import sys
|
|
105
|
+
assert installer.resolve_python() == sys.executable
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|