agentnode-sdk 0.19.0__tar.gz → 0.20.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.19.0 → agentnode_sdk-0.20.0}/CHANGELOG.md +33 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/PKG-INFO +1 -1
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/__init__.py +1 -1
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/cli/commands.py +39 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/cli/mcp_submit.py +165 -161
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/cli/mcp_verify.py +747 -747
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/cli/publish.py +523 -494
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/client.py +4 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/installer.py +5 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/lock_integrity.py +5 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/models.py +6 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/runner.py +5 -1
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/runtimes/python_runner.py +78 -10
- agentnode_sdk-0.20.0/agentnode_sdk/runtimes/toolpack_credentials.py +151 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/pyproject.toml +1 -1
- agentnode_sdk-0.20.0/tests/test_mcp_submit.py +68 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_publish.py +701 -678
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_runner.py +3 -1
- agentnode_sdk-0.20.0/tests/test_toolpack_credentials.py +114 -0
- agentnode_sdk-0.20.0/tests/test_toolpack_credentials_b.py +257 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/.env.example +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/.gitignore +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/README.md +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/REGISTRY_SIGNING_ACTIVATION.md +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/REGISTRY_SIGNING_SPEC.md +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/THREAT_MODEL.md +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/TRUST_STACK.md +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode.lock +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/_fileutil.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/async_client.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/capability_graph.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/capability_taxonomy.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/cli/__init__.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/cli/__main__.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/cli/audit.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/cli/auth.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/cli/cassette_audit.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/cli/complements.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/cli/init.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/cli/main.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/cli/mcp_commands.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/cli/mcp_status.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/cli/output.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/cli/record_cases.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/cli/sandbox_commands.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/cli/serve.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/cli/setup_wizard.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/cli/smart_run.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/cli/templates.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/cli/validate.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/cli/verify_local.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/compatibility.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/config.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/credential_handle.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/credential_resolver.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/credential_store.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/detect.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/exceptions.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/guard.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/input_guard.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/key_status.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/llm_providers.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/mcp_server.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/planner.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/policy.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/references.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/registry_trust.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/resolve.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/resource_provider.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/risk_profile.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/run_log.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/runtime.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/runtimes/__init__.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/runtimes/agent_llm_broker.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/runtimes/agent_llm_policy.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/runtimes/agent_runner.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/runtimes/agent_sandbox.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/runtimes/mcp_consent.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/runtimes/mcp_consent_store.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/runtimes/mcp_runner.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/runtimes/remote_runner.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/sandbox/__init__.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/sandbox/agent_container_wrapper.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/sandbox/agent_rpc.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/sandbox/agent_session.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/sandbox/backend.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/sandbox/container_backend.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/sandbox/domain_policy.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/sandbox/egress.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/sandbox/egress_proxy.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/sandbox/mcp_preinstall.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/sandbox/policy.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/sandbox/types.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/signature.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/signing_key.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/agentnode_sdk/skill.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/data/compatibility/current.json +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/dist-0.18.0/.gitignore +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/dist-0.19.0/.gitignore +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/sandbox-image/Dockerfile +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/sandbox-image/README.md +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/scripts/analyze_scores.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/scripts/batch_verify.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/scripts/ci_smoke_test.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/scripts/generate_compatibility_artifacts.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/scripts/merge_batches.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/scripts/verify_toolcalls.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/scripts/weekly_retest.sh +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/spikes/agent_sandbox_routing/README.md +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/spikes/agent_sandbox_routing/__init__.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/spikes/agent_sandbox_routing/container_agent_wrapper.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/spikes/agent_sandbox_routing/fake_llm.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/spikes/agent_sandbox_routing/host_driver.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/spikes/agent_sandbox_routing/trivial_agent.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/__init__.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/conftest.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/data/allowed_domains_vectors.json +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_agent_llm_broker.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_agent_llm_policy.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_agent_rpc.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_agent_runner.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_agent_sandbox_e2e.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_agent_sandbox_routing.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_agent_sandbox_spike.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_agent_session_container.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_async_client.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_audit_ux.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_auth_cli_vault.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_auto_upgrade_policy.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_cli.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_cli_lock.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_cli_run_resolution.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_client.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_client_json_guard.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_client_sprint_b.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_config.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_consent_prompt.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_credential_handle.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_credential_integration.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_credential_resolver.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_credential_store.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_credential_vault.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_detect.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_detect_and_install.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_domain_policy.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_e2e_runtime.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_edge_cases.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_egress_domain_validation.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_egress_e2e.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_egress_lifecycle.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_egress_proxy_unit.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_egress_wrap.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_env_passthrough_wrap.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_guard.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_guard_check.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_guard_config_cache.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_guard_policy.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_guard_preview.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_guard_schema.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_guard_set.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_guard_status.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_guard_tool_override.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_guard_tool_override_audit.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_guard_tool_override_cli.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_guard_ux.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_host_trust_policy.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_host_trust_policy_routing.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_input_guard.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_input_guard_escalation.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_install_hardening.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_installer_sprint_b.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_intelligence.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_key_status.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_llm_binding.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_llm_call_runlog.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_llm_providers.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_llm_vault_binding.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_lock_integrity.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_lock_runtime.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_mcp_allowed_domains_seal.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_mcp_audit.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_mcp_consent.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_mcp_consent_resolver.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_mcp_consent_store.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_mcp_credentialed_launch.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_mcp_doctor.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_mcp_preinstall.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_mcp_preinstall_run.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_mcp_sandbox.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_mcp_server.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_observability.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_planner.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_policy.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_policy_integration.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_prompt_specs.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_provider_matrix.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_references.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_registry_trust.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_remote_hardening.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_remote_runner.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_resource_provider.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_resource_specs.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_risk_profile.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_run_log.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_runtime.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_runtime_audit.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_sandbox_backend.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_sandbox_doctor.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_sandbox_e2e.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_sandbox_gate.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_security_hardening.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_setup_wizard.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_signature.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_signing_key.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_skill.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_smart.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_stability.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_toolpack_sandbox.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_v02.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_validate.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/test_validate_skill.py +0 -0
- {agentnode_sdk-0.19.0 → agentnode_sdk-0.20.0}/tests/validation_lockfile.json +0 -0
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.20.0 — Credentialed toolpacks (bring your own API key)
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Toolpacks can declare the credentials they need (`env_requirements` in the
|
|
8
|
+
manifest: names, required flag, description — never values). The declaration
|
|
9
|
+
and the publisher's `permissions.network.allowed_domains` egress allowlist
|
|
10
|
+
are sealed into the lockfile at install (integrity-covered; tampering with
|
|
11
|
+
either breaks lockfile integrity).
|
|
12
|
+
- `agentnode install` lists the declared environment variables with their
|
|
13
|
+
set/not-set status and tells you to set required ones before running.
|
|
14
|
+
- Sandboxed community toolpacks can now receive user-provided API keys under
|
|
15
|
+
a fail-closed regime mirroring credentialed MCPs: a consent prompt (or a
|
|
16
|
+
stored grant) bound to the exact package identity
|
|
17
|
+
(slug + version + artifact hash + key names + domains), an enforced egress
|
|
18
|
+
proxy restricted to the sealed `allowed_domains`, and name-only key
|
|
19
|
+
pass-through (`--env NAME` — the value never appears on argv, in the
|
|
20
|
+
process spec, or in logs).
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- Running a toolpack with a missing *required* environment variable now fails
|
|
25
|
+
before dispatch with an actionable, value-free message
|
|
26
|
+
(`mode_used="credentials_missing"`) instead of a cryptic tool error.
|
|
27
|
+
|
|
28
|
+
### Security
|
|
29
|
+
|
|
30
|
+
- A credentialed toolpack without a valid, non-empty `allowed_domains`
|
|
31
|
+
allowlist is refused — a secret never rides an open or unrestricted
|
|
32
|
+
network. Consent cannot transfer between packages, versions, artifacts,
|
|
33
|
+
key sets, or domain sets. There is no fallback run without these
|
|
34
|
+
protections. Non-credentialed toolpacks behave exactly as before.
|
|
35
|
+
|
|
3
36
|
## 0.19.0 — Full setup wizard coverage
|
|
4
37
|
|
|
5
38
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentnode-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.20.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
|
|
@@ -813,6 +813,7 @@ def cmd_install(capability: str, version: str | None = None, yes: bool = False)
|
|
|
813
813
|
_print_install_trust_summary(result.slug)
|
|
814
814
|
_print_install_guard_summary(result.slug)
|
|
815
815
|
_print_install_mcp_guidance(result.slug)
|
|
816
|
+
_print_install_env_guidance(result.slug)
|
|
816
817
|
print()
|
|
817
818
|
else:
|
|
818
819
|
print(f"\n {result.message}\n")
|
|
@@ -1937,6 +1938,44 @@ def _print_install_mcp_guidance(slug: str) -> None:
|
|
|
1937
1938
|
pass
|
|
1938
1939
|
|
|
1939
1940
|
|
|
1941
|
+
def _print_install_env_guidance(slug: str) -> None:
|
|
1942
|
+
"""Post-install guidance for toolpacks that declare env_requirements.
|
|
1943
|
+
|
|
1944
|
+
Names + set/missing status only — a credential VALUE is never read or
|
|
1945
|
+
printed.
|
|
1946
|
+
"""
|
|
1947
|
+
import os
|
|
1948
|
+
from agentnode_sdk.installer import read_lockfile
|
|
1949
|
+
|
|
1950
|
+
try:
|
|
1951
|
+
lock = read_lockfile()
|
|
1952
|
+
pkg = lock.get("packages", {}).get(slug, {})
|
|
1953
|
+
if not pkg or pkg.get("runtime") == "mcp":
|
|
1954
|
+
return
|
|
1955
|
+
reqs = pkg.get("env_requirements") or []
|
|
1956
|
+
if not reqs:
|
|
1957
|
+
return
|
|
1958
|
+
print()
|
|
1959
|
+
print(" This toolpack declares environment variables:")
|
|
1960
|
+
for r in reqs:
|
|
1961
|
+
if not isinstance(r, dict) or not r.get("name"):
|
|
1962
|
+
continue
|
|
1963
|
+
name = r["name"]
|
|
1964
|
+
required = r.get("required", True)
|
|
1965
|
+
status = "set" if name in os.environ else "not set"
|
|
1966
|
+
tag = "required" if required else "optional"
|
|
1967
|
+
print(f" {name} ({tag}, {status})")
|
|
1968
|
+
missing_required = [
|
|
1969
|
+
r["name"] for r in reqs
|
|
1970
|
+
if isinstance(r, dict) and r.get("name")
|
|
1971
|
+
and r.get("required", True) and r["name"] not in os.environ
|
|
1972
|
+
]
|
|
1973
|
+
if missing_required:
|
|
1974
|
+
print(" Set the required variable(s) before running this toolpack.")
|
|
1975
|
+
except Exception:
|
|
1976
|
+
pass
|
|
1977
|
+
|
|
1978
|
+
|
|
1940
1979
|
def _severity(action: str) -> int:
|
|
1941
1980
|
return {"allow": 0, "prompt": 1, "deny": 2}.get(action, 0)
|
|
1942
1981
|
|
|
@@ -1,161 +1,165 @@
|
|
|
1
|
-
"""Submit an MCP manifest to the AgentNode registry.
|
|
2
|
-
|
|
3
|
-
Runs verification locally, then sends manifest + report to the backend.
|
|
4
|
-
Requires a publisher account and API key.
|
|
5
|
-
"""
|
|
6
|
-
from __future__ import annotations
|
|
7
|
-
|
|
8
|
-
import json
|
|
9
|
-
import os
|
|
10
|
-
import sys
|
|
11
|
-
from pathlib import Path
|
|
12
|
-
|
|
13
|
-
import httpx
|
|
14
|
-
import yaml
|
|
15
|
-
|
|
16
|
-
from agentnode_sdk.cli.mcp_verify import verify_manifest
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def _resolve_api_base() -> str:
|
|
20
|
-
from agentnode_sdk.client import DEFAULT_BASE_URL
|
|
21
|
-
return os.environ.get("AGENTNODE_API_URL", DEFAULT_BASE_URL).rstrip("/")
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def cmd_mcp_submit(
|
|
25
|
-
path_str: str,
|
|
26
|
-
*,
|
|
27
|
-
token: str | None = None,
|
|
28
|
-
test: bool = False,
|
|
29
|
-
dry_run: bool = False,
|
|
30
|
-
) -> int:
|
|
31
|
-
"""Submit an MCP server for catalog review."""
|
|
32
|
-
manifest_path = Path(path_str).resolve()
|
|
33
|
-
if manifest_path.is_dir():
|
|
34
|
-
manifest_path = manifest_path / "agentnode.yaml"
|
|
35
|
-
|
|
36
|
-
if not manifest_path.exists():
|
|
37
|
-
print(f" Error: {manifest_path} not found", file=sys.stderr)
|
|
38
|
-
return 1
|
|
39
|
-
|
|
40
|
-
# Step 1: Read manifest
|
|
41
|
-
try:
|
|
42
|
-
manifest = yaml.safe_load(manifest_path.read_text(encoding="utf-8"))
|
|
43
|
-
except Exception as e:
|
|
44
|
-
print(f" Error: Failed to parse agentnode.yaml: {e}", file=sys.stderr)
|
|
45
|
-
return 1
|
|
46
|
-
|
|
47
|
-
if not isinstance(manifest, dict):
|
|
48
|
-
print(" Error: agentnode.yaml root must be a mapping.", file=sys.stderr)
|
|
49
|
-
return 1
|
|
50
|
-
|
|
51
|
-
mcp = manifest.get("mcp_server", {})
|
|
52
|
-
pkg_name = mcp.get("npm_package") or mcp.get("pypi_package") or "unknown"
|
|
53
|
-
|
|
54
|
-
print()
|
|
55
|
-
print(" AgentNode MCP Submit")
|
|
56
|
-
print(" " + "-" * 22)
|
|
57
|
-
print(f" Package: {pkg_name}")
|
|
58
|
-
print()
|
|
59
|
-
|
|
60
|
-
# Step 2: Run verification
|
|
61
|
-
print(" Running verification...")
|
|
62
|
-
report = verify_manifest(manifest_path, run_test=test)
|
|
63
|
-
report_dict = report.to_dict()
|
|
64
|
-
|
|
65
|
-
print(f" Status: {report.status}")
|
|
66
|
-
print(f" Summary: {report.summary}")
|
|
67
|
-
|
|
68
|
-
if report.actions:
|
|
69
|
-
high = sum(1 for a in report.actions if a.severity == "high")
|
|
70
|
-
med = sum(1 for a in report.actions if a.severity == "medium")
|
|
71
|
-
if high:
|
|
72
|
-
print(f" Actions: {high} required, {med} recommended")
|
|
73
|
-
elif med:
|
|
74
|
-
print(f" Actions: {med} recommended")
|
|
75
|
-
|
|
76
|
-
if report.status == "INVALID":
|
|
77
|
-
print()
|
|
78
|
-
print(" Cannot submit: verification has blocking errors.")
|
|
79
|
-
print(" Run: agentnode mcp verify . to see details.")
|
|
80
|
-
return 1
|
|
81
|
-
|
|
82
|
-
print()
|
|
83
|
-
|
|
84
|
-
if dry_run:
|
|
85
|
-
print(" Dry run -- not submitting.")
|
|
86
|
-
print(" Verification report generated successfully.")
|
|
87
|
-
print(f" To submit: agentnode mcp submit {path_str}")
|
|
88
|
-
print()
|
|
89
|
-
return 0
|
|
90
|
-
|
|
91
|
-
# Step 3: Auth
|
|
92
|
-
api_key = token or os.environ.get("AGENTNODE_API_KEY", "")
|
|
93
|
-
if not api_key:
|
|
94
|
-
print(
|
|
95
|
-
" Error: No AgentNode API key configured.\n\n"
|
|
96
|
-
" Create an account at https://agentnode.net,\n"
|
|
97
|
-
" then create an API key in your dashboard.\n\n"
|
|
98
|
-
" Set it with:\n"
|
|
99
|
-
" export AGENTNODE_API_KEY=...\n\n"
|
|
100
|
-
" or run:\n"
|
|
101
|
-
f" agentnode mcp submit {path_str} --token <key>\n",
|
|
102
|
-
file=sys.stderr,
|
|
103
|
-
)
|
|
104
|
-
return 1
|
|
105
|
-
|
|
106
|
-
# Step 4: Submit
|
|
107
|
-
api_base = _resolve_api_base()
|
|
108
|
-
url = f"{api_base}/v1/mcp/submit"
|
|
109
|
-
api_host = api_base.replace("https://", "").replace("http://", "")
|
|
110
|
-
|
|
111
|
-
print(f" Submitting to {api_host}...")
|
|
112
|
-
|
|
113
|
-
try:
|
|
114
|
-
resp = httpx.post(
|
|
115
|
-
url,
|
|
116
|
-
json={
|
|
117
|
-
"manifest": manifest,
|
|
118
|
-
"verification_report": report_dict,
|
|
119
|
-
},
|
|
120
|
-
headers={"Authorization": f"Bearer {api_key}"},
|
|
121
|
-
timeout=30,
|
|
122
|
-
)
|
|
123
|
-
except Exception as e:
|
|
124
|
-
print(f" Error: Connection failed: {e}", file=sys.stderr)
|
|
125
|
-
return 1
|
|
126
|
-
|
|
127
|
-
if resp.status_code == 201:
|
|
128
|
-
data = resp.json()
|
|
129
|
-
|
|
130
|
-
print(f"
|
|
131
|
-
print(f"
|
|
132
|
-
print(f"
|
|
133
|
-
print()
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
1
|
+
"""Submit an MCP manifest to the AgentNode registry.
|
|
2
|
+
|
|
3
|
+
Runs verification locally, then sends manifest + report to the backend.
|
|
4
|
+
Requires a publisher account and API key.
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
import os
|
|
10
|
+
import sys
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
import httpx
|
|
14
|
+
import yaml
|
|
15
|
+
|
|
16
|
+
from agentnode_sdk.cli.mcp_verify import verify_manifest
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _resolve_api_base() -> str:
|
|
20
|
+
from agentnode_sdk.client import DEFAULT_BASE_URL
|
|
21
|
+
return os.environ.get("AGENTNODE_API_URL", DEFAULT_BASE_URL).rstrip("/")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def cmd_mcp_submit(
|
|
25
|
+
path_str: str,
|
|
26
|
+
*,
|
|
27
|
+
token: str | None = None,
|
|
28
|
+
test: bool = False,
|
|
29
|
+
dry_run: bool = False,
|
|
30
|
+
) -> int:
|
|
31
|
+
"""Submit an MCP server for catalog review."""
|
|
32
|
+
manifest_path = Path(path_str).resolve()
|
|
33
|
+
if manifest_path.is_dir():
|
|
34
|
+
manifest_path = manifest_path / "agentnode.yaml"
|
|
35
|
+
|
|
36
|
+
if not manifest_path.exists():
|
|
37
|
+
print(f" Error: {manifest_path} not found", file=sys.stderr)
|
|
38
|
+
return 1
|
|
39
|
+
|
|
40
|
+
# Step 1: Read manifest
|
|
41
|
+
try:
|
|
42
|
+
manifest = yaml.safe_load(manifest_path.read_text(encoding="utf-8"))
|
|
43
|
+
except Exception as e:
|
|
44
|
+
print(f" Error: Failed to parse agentnode.yaml: {e}", file=sys.stderr)
|
|
45
|
+
return 1
|
|
46
|
+
|
|
47
|
+
if not isinstance(manifest, dict):
|
|
48
|
+
print(" Error: agentnode.yaml root must be a mapping.", file=sys.stderr)
|
|
49
|
+
return 1
|
|
50
|
+
|
|
51
|
+
mcp = manifest.get("mcp_server", {})
|
|
52
|
+
pkg_name = mcp.get("npm_package") or mcp.get("pypi_package") or "unknown"
|
|
53
|
+
|
|
54
|
+
print()
|
|
55
|
+
print(" AgentNode MCP Submit")
|
|
56
|
+
print(" " + "-" * 22)
|
|
57
|
+
print(f" Package: {pkg_name}")
|
|
58
|
+
print()
|
|
59
|
+
|
|
60
|
+
# Step 2: Run verification
|
|
61
|
+
print(" Running verification...")
|
|
62
|
+
report = verify_manifest(manifest_path, run_test=test)
|
|
63
|
+
report_dict = report.to_dict()
|
|
64
|
+
|
|
65
|
+
print(f" Status: {report.status}")
|
|
66
|
+
print(f" Summary: {report.summary}")
|
|
67
|
+
|
|
68
|
+
if report.actions:
|
|
69
|
+
high = sum(1 for a in report.actions if a.severity == "high")
|
|
70
|
+
med = sum(1 for a in report.actions if a.severity == "medium")
|
|
71
|
+
if high:
|
|
72
|
+
print(f" Actions: {high} required, {med} recommended")
|
|
73
|
+
elif med:
|
|
74
|
+
print(f" Actions: {med} recommended")
|
|
75
|
+
|
|
76
|
+
if report.status == "INVALID":
|
|
77
|
+
print()
|
|
78
|
+
print(" Cannot submit: verification has blocking errors.")
|
|
79
|
+
print(" Run: agentnode mcp verify . to see details.")
|
|
80
|
+
return 1
|
|
81
|
+
|
|
82
|
+
print()
|
|
83
|
+
|
|
84
|
+
if dry_run:
|
|
85
|
+
print(" Dry run -- not submitting.")
|
|
86
|
+
print(" Verification report generated successfully.")
|
|
87
|
+
print(f" To submit: agentnode mcp submit {path_str}")
|
|
88
|
+
print()
|
|
89
|
+
return 0
|
|
90
|
+
|
|
91
|
+
# Step 3: Auth
|
|
92
|
+
api_key = token or os.environ.get("AGENTNODE_API_KEY", "")
|
|
93
|
+
if not api_key:
|
|
94
|
+
print(
|
|
95
|
+
" Error: No AgentNode API key configured.\n\n"
|
|
96
|
+
" Create an account at https://agentnode.net,\n"
|
|
97
|
+
" then create an API key in your dashboard.\n\n"
|
|
98
|
+
" Set it with:\n"
|
|
99
|
+
" export AGENTNODE_API_KEY=...\n\n"
|
|
100
|
+
" or run:\n"
|
|
101
|
+
f" agentnode mcp submit {path_str} --token <key>\n",
|
|
102
|
+
file=sys.stderr,
|
|
103
|
+
)
|
|
104
|
+
return 1
|
|
105
|
+
|
|
106
|
+
# Step 4: Submit
|
|
107
|
+
api_base = _resolve_api_base()
|
|
108
|
+
url = f"{api_base}/v1/mcp/submit"
|
|
109
|
+
api_host = api_base.replace("https://", "").replace("http://", "")
|
|
110
|
+
|
|
111
|
+
print(f" Submitting to {api_host}...")
|
|
112
|
+
|
|
113
|
+
try:
|
|
114
|
+
resp = httpx.post(
|
|
115
|
+
url,
|
|
116
|
+
json={
|
|
117
|
+
"manifest": manifest,
|
|
118
|
+
"verification_report": report_dict,
|
|
119
|
+
},
|
|
120
|
+
headers={"Authorization": f"Bearer {api_key}"},
|
|
121
|
+
timeout=30,
|
|
122
|
+
)
|
|
123
|
+
except Exception as e:
|
|
124
|
+
print(f" Error: Connection failed: {e}", file=sys.stderr)
|
|
125
|
+
return 1
|
|
126
|
+
|
|
127
|
+
if resp.status_code == 201:
|
|
128
|
+
data = resp.json()
|
|
129
|
+
sub_id = data.get("id", "?")
|
|
130
|
+
print(f" Submitted: {data.get('package_name', pkg_name)}")
|
|
131
|
+
print(f" ID: {sub_id}")
|
|
132
|
+
print(f" Status: {data.get('status', '?')}")
|
|
133
|
+
print(f" Message: {data.get('message', '')}")
|
|
134
|
+
print()
|
|
135
|
+
print(f" Check status: agentnode mcp status {sub_id}")
|
|
136
|
+
print(" Your MCP is queued for review and won't be listed until approved.")
|
|
137
|
+
print()
|
|
138
|
+
return 0
|
|
139
|
+
|
|
140
|
+
# Error handling
|
|
141
|
+
try:
|
|
142
|
+
err = resp.json()
|
|
143
|
+
code = err.get("code", "")
|
|
144
|
+
message = err.get("message", resp.text)
|
|
145
|
+
except Exception:
|
|
146
|
+
code = ""
|
|
147
|
+
message = resp.text
|
|
148
|
+
|
|
149
|
+
if resp.status_code == 409:
|
|
150
|
+
print(f" {message}", file=sys.stderr)
|
|
151
|
+
elif resp.status_code == 401:
|
|
152
|
+
print(" Error: Authentication failed. Check your API key.", file=sys.stderr)
|
|
153
|
+
elif resp.status_code == 403:
|
|
154
|
+
if "PUBLISHER" in code:
|
|
155
|
+
print(" Error: You need a publisher profile.", file=sys.stderr)
|
|
156
|
+
print(" Create one at https://agentnode.net/dashboard", file=sys.stderr)
|
|
157
|
+
else:
|
|
158
|
+
print(f" Error: {message}", file=sys.stderr)
|
|
159
|
+
elif resp.status_code == 400:
|
|
160
|
+
print(f" Error: {message}", file=sys.stderr)
|
|
161
|
+
else:
|
|
162
|
+
print(f" Error ({resp.status_code}): {message}", file=sys.stderr)
|
|
163
|
+
|
|
164
|
+
print()
|
|
165
|
+
return 1
|