agentnode-sdk 0.12.1__tar.gz → 0.14.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.
Files changed (191) hide show
  1. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/CHANGELOG.md +93 -0
  2. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/PKG-INFO +2 -1
  3. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/__init__.py +1 -1
  4. agentnode_sdk-0.14.0/agentnode_sdk/cli/auth.py +243 -0
  5. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/cli/main.py +8 -1
  6. agentnode_sdk-0.14.0/agentnode_sdk/cli/setup_wizard.py +340 -0
  7. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/config.py +9 -0
  8. agentnode_sdk-0.14.0/agentnode_sdk/credential_store.py +296 -0
  9. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/runtimes/agent_runner.py +64 -1
  10. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/pyproject.toml +2 -1
  11. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/conftest.py +20 -0
  12. agentnode_sdk-0.14.0/tests/test_auth_cli_vault.py +221 -0
  13. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_cli.py +4 -1
  14. agentnode_sdk-0.14.0/tests/test_credential_vault.py +217 -0
  15. agentnode_sdk-0.14.0/tests/test_llm_vault_binding.py +143 -0
  16. agentnode_sdk-0.14.0/tests/test_setup_wizard.py +342 -0
  17. agentnode_sdk-0.12.1/agentnode_sdk/cli/auth.py +0 -113
  18. agentnode_sdk-0.12.1/agentnode_sdk/cli/setup_wizard.py +0 -128
  19. agentnode_sdk-0.12.1/agentnode_sdk/credential_store.py +0 -143
  20. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/.env.example +0 -0
  21. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/.gitignore +0 -0
  22. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/README.md +0 -0
  23. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/REGISTRY_SIGNING_ACTIVATION.md +0 -0
  24. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/REGISTRY_SIGNING_SPEC.md +0 -0
  25. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/THREAT_MODEL.md +0 -0
  26. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/TRUST_STACK.md +0 -0
  27. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode.lock +0 -0
  28. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/_fileutil.py +0 -0
  29. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/async_client.py +0 -0
  30. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/capability_graph.py +0 -0
  31. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/capability_taxonomy.py +0 -0
  32. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/cli/__init__.py +0 -0
  33. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/cli/__main__.py +0 -0
  34. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/cli/audit.py +0 -0
  35. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/cli/cassette_audit.py +0 -0
  36. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/cli/commands.py +0 -0
  37. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/cli/complements.py +0 -0
  38. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/cli/init.py +0 -0
  39. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/cli/mcp_commands.py +0 -0
  40. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/cli/mcp_status.py +0 -0
  41. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/cli/mcp_submit.py +0 -0
  42. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/cli/mcp_verify.py +0 -0
  43. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/cli/output.py +0 -0
  44. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/cli/publish.py +0 -0
  45. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/cli/record_cases.py +0 -0
  46. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/cli/sandbox_commands.py +0 -0
  47. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/cli/serve.py +0 -0
  48. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/cli/smart_run.py +0 -0
  49. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/cli/templates.py +0 -0
  50. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/cli/validate.py +0 -0
  51. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/cli/verify_local.py +0 -0
  52. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/client.py +0 -0
  53. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/compatibility.py +0 -0
  54. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/credential_handle.py +0 -0
  55. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/credential_resolver.py +0 -0
  56. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/detect.py +0 -0
  57. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/exceptions.py +0 -0
  58. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/guard.py +0 -0
  59. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/input_guard.py +0 -0
  60. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/installer.py +0 -0
  61. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/key_status.py +0 -0
  62. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/lock_integrity.py +0 -0
  63. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/mcp_server.py +0 -0
  64. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/models.py +0 -0
  65. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/planner.py +0 -0
  66. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/policy.py +0 -0
  67. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/references.py +0 -0
  68. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/registry_trust.py +0 -0
  69. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/resolve.py +0 -0
  70. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/resource_provider.py +0 -0
  71. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/risk_profile.py +0 -0
  72. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/run_log.py +0 -0
  73. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/runner.py +0 -0
  74. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/runtime.py +0 -0
  75. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/runtimes/__init__.py +0 -0
  76. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/runtimes/agent_llm_broker.py +0 -0
  77. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/runtimes/agent_llm_policy.py +0 -0
  78. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/runtimes/agent_sandbox.py +0 -0
  79. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/runtimes/mcp_runner.py +0 -0
  80. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/runtimes/python_runner.py +0 -0
  81. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/runtimes/remote_runner.py +0 -0
  82. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/sandbox/__init__.py +0 -0
  83. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/sandbox/agent_container_wrapper.py +0 -0
  84. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/sandbox/agent_rpc.py +0 -0
  85. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/sandbox/agent_session.py +0 -0
  86. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/sandbox/backend.py +0 -0
  87. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/sandbox/container_backend.py +0 -0
  88. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/sandbox/policy.py +0 -0
  89. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/sandbox/types.py +0 -0
  90. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/signature.py +0 -0
  91. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/signing_key.py +0 -0
  92. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/agentnode_sdk/skill.py +0 -0
  93. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/sandbox-image/Dockerfile +0 -0
  94. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/sandbox-image/README.md +0 -0
  95. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/scripts/analyze_scores.py +0 -0
  96. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/scripts/batch_verify.py +0 -0
  97. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/scripts/ci_smoke_test.py +0 -0
  98. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/scripts/generate_compatibility_artifacts.py +0 -0
  99. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/scripts/verify_toolcalls.py +0 -0
  100. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/scripts/weekly_retest.sh +0 -0
  101. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/spikes/agent_sandbox_routing/README.md +0 -0
  102. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/spikes/agent_sandbox_routing/__init__.py +0 -0
  103. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/spikes/agent_sandbox_routing/container_agent_wrapper.py +0 -0
  104. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/spikes/agent_sandbox_routing/fake_llm.py +0 -0
  105. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/spikes/agent_sandbox_routing/host_driver.py +0 -0
  106. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/spikes/agent_sandbox_routing/trivial_agent.py +0 -0
  107. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/__init__.py +0 -0
  108. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_agent_llm_broker.py +0 -0
  109. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_agent_llm_policy.py +0 -0
  110. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_agent_rpc.py +0 -0
  111. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_agent_runner.py +0 -0
  112. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_agent_sandbox_e2e.py +0 -0
  113. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_agent_sandbox_routing.py +0 -0
  114. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_agent_sandbox_spike.py +0 -0
  115. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_agent_session_container.py +0 -0
  116. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_async_client.py +0 -0
  117. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_audit_ux.py +0 -0
  118. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_auto_upgrade_policy.py +0 -0
  119. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_cli_lock.py +0 -0
  120. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_cli_run_resolution.py +0 -0
  121. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_client.py +0 -0
  122. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_client_json_guard.py +0 -0
  123. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_client_sprint_b.py +0 -0
  124. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_config.py +0 -0
  125. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_credential_handle.py +0 -0
  126. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_credential_integration.py +0 -0
  127. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_credential_resolver.py +0 -0
  128. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_credential_store.py +0 -0
  129. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_detect.py +0 -0
  130. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_detect_and_install.py +0 -0
  131. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_e2e_runtime.py +0 -0
  132. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_edge_cases.py +0 -0
  133. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_guard.py +0 -0
  134. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_guard_check.py +0 -0
  135. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_guard_config_cache.py +0 -0
  136. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_guard_policy.py +0 -0
  137. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_guard_preview.py +0 -0
  138. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_guard_schema.py +0 -0
  139. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_guard_set.py +0 -0
  140. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_guard_status.py +0 -0
  141. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_guard_tool_override.py +0 -0
  142. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_guard_tool_override_audit.py +0 -0
  143. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_guard_tool_override_cli.py +0 -0
  144. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_guard_ux.py +0 -0
  145. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_input_guard.py +0 -0
  146. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_input_guard_escalation.py +0 -0
  147. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_install_hardening.py +0 -0
  148. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_installer_sprint_b.py +0 -0
  149. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_intelligence.py +0 -0
  150. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_key_status.py +0 -0
  151. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_llm_binding.py +0 -0
  152. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_llm_call_runlog.py +0 -0
  153. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_lock_integrity.py +0 -0
  154. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_lock_runtime.py +0 -0
  155. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_mcp_audit.py +0 -0
  156. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_mcp_doctor.py +0 -0
  157. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_mcp_sandbox.py +0 -0
  158. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_mcp_server.py +0 -0
  159. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_observability.py +0 -0
  160. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_planner.py +0 -0
  161. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_policy.py +0 -0
  162. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_policy_integration.py +0 -0
  163. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_prompt_specs.py +0 -0
  164. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_provider_matrix.py +0 -0
  165. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_publish.py +0 -0
  166. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_references.py +0 -0
  167. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_registry_trust.py +0 -0
  168. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_remote_hardening.py +0 -0
  169. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_remote_runner.py +0 -0
  170. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_resource_provider.py +0 -0
  171. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_resource_specs.py +0 -0
  172. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_risk_profile.py +0 -0
  173. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_run_log.py +0 -0
  174. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_runner.py +0 -0
  175. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_runtime.py +0 -0
  176. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_runtime_audit.py +0 -0
  177. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_sandbox_backend.py +0 -0
  178. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_sandbox_doctor.py +0 -0
  179. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_sandbox_e2e.py +0 -0
  180. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_sandbox_gate.py +0 -0
  181. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_security_hardening.py +0 -0
  182. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_signature.py +0 -0
  183. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_signing_key.py +0 -0
  184. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_skill.py +0 -0
  185. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_smart.py +0 -0
  186. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_stability.py +0 -0
  187. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_toolpack_sandbox.py +0 -0
  188. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_v02.py +0 -0
  189. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_validate.py +0 -0
  190. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/test_validate_skill.py +0 -0
  191. {agentnode_sdk-0.12.1 → agentnode_sdk-0.14.0}/tests/validation_lockfile.json +0 -0
@@ -1,5 +1,98 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.14.0 — Setup wizard: guided credentials + sandbox onboarding
4
+
5
+ ### Added
6
+
7
+ - **`agentnode setup` now guides through optional LLM credentials.** A new
8
+ wizard screen offers storing a provider key (OpenAI, Anthropic, OpenRouter —
9
+ or Skip, the default). Entry is via hidden getpass or an import from an
10
+ existing environment variable; the honest storage label (OS keychain /
11
+ plaintext file) is shown, and an optional key test runs against a free
12
+ endpoint (no completion call) without ever blocking the wizard.
13
+ - **`agentnode setup` now includes a "Local sandbox" screen.** It shows the
14
+ doctor's diagnosis (runtime, daemon, pinned image, digest) with clear next
15
+ steps. If only the image is missing, the wizard offers the digest-pinned
16
+ pull — on a TTY and only after an explicit Yes (default No).
17
+ - **Optional agent-sandbox enable prompt.** Only when the sandbox is fully
18
+ ready, the wizard asks "Enable sandboxed community agents now? [y/N]"
19
+ (default No). The choice is persisted with the wizard's normal save step;
20
+ cancelling saves nothing.
21
+ - The summary and finish screens show credentials, sandbox status, and the
22
+ exact follow-up commands (`agentnode auth status`, `agentnode sandbox
23
+ doctor`, `agentnode sandbox pull`, `agentnode config set
24
+ agent_sandbox.enabled true`).
25
+
26
+ ### Hardened
27
+
28
+ - No keys in wizard output (masked last-4 only), no keys in config files, no
29
+ keys via CLI arguments — entry is getpass or env import only.
30
+ - No automatic Docker pull: the only pull path is the existing, fully guarded
31
+ `agentnode sandbox pull`, offered solely on a TTY after an explicit Yes.
32
+ - The sandbox flag is never enabled without an explicit Yes, and never offered
33
+ when the sandbox is not ready.
34
+ - Pull failures never abort setup; non-interactive sessions never block
35
+ (credential and sandbox prompts skip themselves with guidance).
36
+
37
+ ### BREAKING / Upgrade Notes
38
+
39
+ - None. The wizard changes are additive; all defaults preserve previous
40
+ behavior (credentials skipped, sandbox flag stays off). No new dependency.
41
+
42
+ ## 0.13.0 — Credential vault for LLM providers
43
+
44
+ ### Added
45
+
46
+ - **OS-keychain credential storage:** `agentnode auth set openai|anthropic|openrouter`
47
+ now stores the key in the OS keychain (Windows Credential Manager, macOS
48
+ Keychain, Linux Secret Service). `credentials.json` keeps only non-secret
49
+ metadata for keychain-backed entries. If no keychain is available (e.g.
50
+ headless Linux/CI), storage falls back to the plaintext file (0600) — and
51
+ says so honestly.
52
+ - **The LLM runtime now reads stored credentials:** `_auto_detect_llm` falls
53
+ back to the credential store when no env var is set — `agentnode auth set
54
+ openai` is finally picked up by host agents AND the sandboxed-agent LLM
55
+ broker (the key still never enters the sandbox container).
56
+ - `agentnode auth test <provider>` — validates the effective key via a free
57
+ provider endpoint (no completion call, no cost). Exit codes: 0 valid,
58
+ 1 rejected, 2 not configured, 3 indeterminate (network errors are never
59
+ reported as "invalid").
60
+ - `agentnode auth set <provider> --from-env ENV_VAR` — import an existing
61
+ environment key into the store.
62
+ - `llm.default_provider` config key — which stored credential to try first
63
+ (`openai`, `anthropic`, `openrouter`). OpenRouter bindings pin the
64
+ namespaced default model (`openai/gpt-4o-mini`).
65
+
66
+ ### Changed
67
+
68
+ - `agentnode auth status` now leads with an LLM-provider section showing the
69
+ storage backend and the EFFECTIVE source per provider — including an
70
+ explicit "env var X — overrides stored credential" callout when an
71
+ environment variable shadows a stored key.
72
+ - `agentnode auth list` shows a storage column (OS keychain / plaintext file).
73
+ - Environment variables (and `~/.agentnode/.env`) always override stored
74
+ credentials — explicit/CI intent wins.
75
+
76
+ ### Hardened
77
+
78
+ - Keys are never printed (masked last-4 only), never logged (provider/backend
79
+ errors are reported by type, never message), never echoed from provider
80
+ responses, and never enter the sandbox container, audit records, manifests,
81
+ or lockfiles. `auth test` never accepts a key as a CLI argument.
82
+ - Keychain access is probed once per process with a timeout — a locked or
83
+ hanging Secret Service degrades cleanly to file storage instead of blocking.
84
+
85
+ ### Upgrade Notes
86
+
87
+ - New dependency: `keyring>=24` (pure Python, installed automatically).
88
+ - Honest scope of the OS keychain: it protects against other local users and
89
+ accidental file exposure; it does NOT protect against programs running as
90
+ the same user. The fallback is a plaintext file (0600) when no keychain is
91
+ available — neither mode is "encrypted at rest by AgentNode".
92
+ - Existing plaintext credentials keep working unchanged. Nothing migrates on
93
+ read; a credential moves into the keychain the next time you `auth set` it.
94
+ - No breaking changes.
95
+
3
96
  ## 0.12.1 — agent_sandbox config fix
4
97
 
5
98
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentnode-sdk
3
- Version: 0.12.1
3
+ Version: 0.14.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
@@ -16,6 +16,7 @@ Classifier: Topic :: Software Development :: Libraries
16
16
  Requires-Python: >=3.10
17
17
  Requires-Dist: cryptography>=41.0
18
18
  Requires-Dist: httpx>=0.25
19
+ Requires-Dist: keyring>=24
19
20
  Requires-Dist: mcp>=1.0.0
20
21
  Requires-Dist: pyyaml>=6.0
21
22
  Provides-Extra: dev
@@ -38,7 +38,7 @@ from agentnode_sdk.runtime import AgentNodeRuntime
38
38
  Client = AgentNodeClient
39
39
  ToolError = AgentNodeToolError
40
40
 
41
- __version__ = "0.12.1"
41
+ __version__ = "0.14.0"
42
42
  __all__ = [
43
43
  "AgentNode",
44
44
  "AsyncAgentNode",
@@ -0,0 +1,243 @@
1
+ """agentnode auth — credential management CLI.
2
+
3
+ Secrets are entered via getpass (never argv, never echoed) and only ever
4
+ shown masked (last 4 chars). Storage labels are honest: "OS keychain" or
5
+ "plaintext file" — never "encrypted"."""
6
+ from __future__ import annotations
7
+
8
+ import getpass
9
+ import os
10
+ import sys
11
+
12
+ from agentnode_sdk.credential_store import (
13
+ LLM_PROVIDER_ENV,
14
+ has_credential,
15
+ list_credentials,
16
+ load_credentials,
17
+ remove_credential,
18
+ set_credential,
19
+ )
20
+ from agentnode_sdk.installer import read_lockfile
21
+ from agentnode_sdk.cli.output import bold, dim, section
22
+
23
+
24
+ def _masked(token: str) -> str:
25
+ """Only ever show the last 4 chars of a secret."""
26
+ return "..." + token[-4:] if len(token) >= 8 else "..."
27
+
28
+
29
+ def _storage_short(storage: str) -> str:
30
+ return "OS keychain" if storage == "keyring" else "plaintext file"
31
+
32
+
33
+ def _llm_effective_source(provider: str) -> tuple[str | None, str]:
34
+ """(effective key or None, human-readable source) for an LLM provider.
35
+
36
+ Mirrors the runtime's resolution: env (incl. ~/.agentnode/.env) overrides
37
+ the stored credential. Uses metadata only for the stored check here —
38
+ the real keychain read happens in ``auth test``."""
39
+ from agentnode_sdk.runtimes.agent_runner import _load_agentnode_env
40
+ _load_agentnode_env()
41
+
42
+ env_var = LLM_PROVIDER_ENV[provider]
43
+ env_key = os.environ.get(env_var) or None
44
+ meta = load_credentials().get("providers", {}).get(provider)
45
+ stored = isinstance(meta, dict)
46
+ storage = (meta or {}).get("storage", "file")
47
+
48
+ if env_key and stored:
49
+ return env_key, f"env var {env_var} — overrides stored credential"
50
+ if env_key:
51
+ return env_key, f"env var {env_var}"
52
+ if stored:
53
+ return None, _storage_short(storage)
54
+ return None, "not configured"
55
+
56
+
57
+ def _resolve_auth_type(provider: str) -> str:
58
+ """Read auth_type from lockfile connector entry. Falls back to 'api_key'.
59
+
60
+ If multiple installed connectors share a provider with different auth
61
+ types, this returns the first match — may need disambiguation later.
62
+ """
63
+ lock = read_lockfile()
64
+ for _slug, info in lock.get("packages", {}).items():
65
+ connector = info.get("connector")
66
+ if isinstance(connector, dict) and connector.get("provider", "").lower() == provider:
67
+ return connector.get("auth_type", "api_key")
68
+ return "api_key"
69
+
70
+
71
+ def cmd_auth_set(provider: str, from_env: str | None = None) -> int:
72
+ provider = provider.lower().strip()
73
+ if not provider:
74
+ print(" Error: provider name required.", file=sys.stderr)
75
+ return 1
76
+ if from_env:
77
+ # Import an existing env key (also honors ~/.agentnode/.env). A flag,
78
+ # not a prompt — keeps piped-stdin flows intact.
79
+ from agentnode_sdk.runtimes.agent_runner import _load_agentnode_env
80
+ _load_agentnode_env()
81
+ token = (os.environ.get(from_env) or "").strip()
82
+ if not token:
83
+ print(f" Error: environment variable {from_env} is not set.", file=sys.stderr)
84
+ return 1
85
+ else:
86
+ try:
87
+ token = getpass.getpass(f" Enter access token for {provider}: ")
88
+ except (KeyboardInterrupt, EOFError):
89
+ print("\n Cancelled.")
90
+ return 130
91
+ token = token.strip()
92
+ if not token:
93
+ print(" Error: no token provided.", file=sys.stderr)
94
+ return 1
95
+ auth_type = _resolve_auth_type(provider)
96
+ storage = set_credential(provider, token, auth_type=auth_type)
97
+ if storage == "keyring":
98
+ where = "OS keychain"
99
+ else:
100
+ where = "plaintext file (0600) — OS keychain unavailable on this system"
101
+ print(f"\n Credential stored for {provider} ({_masked(token)}) — storage: {where}.\n")
102
+ return 0
103
+
104
+
105
+ def cmd_auth_list() -> int:
106
+ creds = list_credentials()
107
+ if not creds:
108
+ print("\n No credentials configured.")
109
+ print(dim(" Run `agentnode auth set <provider>` to store a credential.\n"))
110
+ return 0
111
+ print()
112
+ print(section("Credentials"))
113
+ print(f" {'Provider':<14}{'Auth type':<13}{'Storage':<16}{'Stored'}")
114
+ print(f" {'--------':<14}{'--------':<13}{'-------':<16}{'------'}")
115
+ for provider, info in sorted(creds.items()):
116
+ stored = info.get("stored_at", "")[:10]
117
+ auth_type = info.get("auth_type", "unknown")
118
+ storage = _storage_short(info.get("storage", "file"))
119
+ print(f" {provider:<14}{auth_type:<13}{storage:<16}{stored}")
120
+ print(f"\n {len(creds)} credential(s) configured.\n")
121
+ return 0
122
+
123
+
124
+ def cmd_auth_remove(provider: str) -> int:
125
+ provider = provider.lower().strip()
126
+ if remove_credential(provider):
127
+ print(f"\n Removed credential for {provider}.\n")
128
+ return 0
129
+ print(f"\n No credential found for {provider}.\n")
130
+ return 1
131
+
132
+
133
+ def cmd_auth_status() -> int:
134
+ # --- LLM providers (host runtime / sandbox broker) -----------------------
135
+ print()
136
+ print(section("LLM Providers"))
137
+ print(f" {'Provider':<14}{'Status':<16}{'Effective source'}")
138
+ print(f" {'--------':<14}{'------':<16}{'----------------'}")
139
+ for provider in sorted(LLM_PROVIDER_ENV):
140
+ key, source = _llm_effective_source(provider)
141
+ configured = key is not None or source not in ("not configured",)
142
+ status = "configured" if configured else "missing"
143
+ print(f" {provider:<14}{status:<16}{source}")
144
+ print(dim(" Env vars always override stored credentials. "
145
+ "Test a key: agentnode auth test <provider>"))
146
+
147
+ # --- connector packages (unchanged) --------------------------------------
148
+ lock = read_lockfile()
149
+ pkgs = lock.get("packages", {})
150
+
151
+ # Collect provider → list of slugs
152
+ provider_packages: dict[str, list[str]] = {}
153
+ for slug, info in pkgs.items():
154
+ connector = info.get("connector")
155
+ if isinstance(connector, dict) and connector.get("provider"):
156
+ provider = connector["provider"].lower().strip()
157
+ provider_packages.setdefault(provider, []).append(slug)
158
+
159
+ if not provider_packages:
160
+ print("\n No installed packages require connector credentials.\n")
161
+ return 0
162
+
163
+ print()
164
+ print(section("Credential Status"))
165
+ print(f" {'Provider':<14}{'Status':<16}{'Used by'}")
166
+ print(f" {'--------':<14}{'------':<16}{'------'}")
167
+ missing: list[str] = []
168
+ for provider in sorted(provider_packages):
169
+ configured = has_credential(provider)
170
+ status = "configured" if configured else "missing"
171
+ slugs = ", ".join(sorted(provider_packages[provider]))
172
+ print(f" {provider:<14}{status:<16}{slugs}")
173
+ if not configured:
174
+ missing.append(provider)
175
+
176
+ if missing:
177
+ print()
178
+ print(dim(" Fix missing:"))
179
+ for p in missing:
180
+ print(dim(f" agentnode auth set {p}"))
181
+ print()
182
+ return 0
183
+
184
+
185
+ # Free, cost-less validation endpoints (no completion call, no charge).
186
+ # anthropic REQUIRES the anthropic-version header (a 400 without it would be
187
+ # misread as a bad key); openrouter's /models is UNAUTHENTICATED (validates
188
+ # nothing) — /auth/key is the correct probe.
189
+ _TEST_REQUESTS = {
190
+ "openai": lambda key: (
191
+ "https://api.openai.com/v1/models",
192
+ {"Authorization": f"Bearer {key}"},
193
+ ),
194
+ "anthropic": lambda key: (
195
+ "https://api.anthropic.com/v1/models",
196
+ {"x-api-key": key, "anthropic-version": "2023-06-01"},
197
+ ),
198
+ "openrouter": lambda key: (
199
+ "https://openrouter.ai/api/v1/auth/key",
200
+ {"Authorization": f"Bearer {key}"},
201
+ ),
202
+ }
203
+
204
+
205
+ def cmd_auth_test(provider: str) -> int:
206
+ """Validate the EFFECTIVE key for an LLM provider (env beats vault) via a
207
+ free endpoint. Exit codes: 0 valid / 1 rejected (401/403) / 2 not
208
+ configured or unsupported / 3 indeterminate (network/5xx — never reported
209
+ as invalid). Never prints the key (masked last-4 only) and never echoes
210
+ the provider's response body (it can contain key fragments)."""
211
+ provider = provider.lower().strip()
212
+ if provider not in _TEST_REQUESTS:
213
+ supported = ", ".join(sorted(_TEST_REQUESTS))
214
+ print(f" auth test supports: {supported}", file=sys.stderr)
215
+ return 2
216
+
217
+ key, source = _llm_effective_source(provider)
218
+ if key is None:
219
+ # No env override — resolve the stored credential (real keychain read).
220
+ from agentnode_sdk.credential_store import get_llm_api_key
221
+ key = get_llm_api_key(provider)
222
+ if not key:
223
+ print(f"\n {provider}: not configured. Run `agentnode auth set {provider}`.\n")
224
+ return 2
225
+
226
+ url, headers = _TEST_REQUESTS[provider](key)
227
+ import httpx
228
+ try:
229
+ resp = httpx.get(url, headers=headers, timeout=10.0)
230
+ except Exception:
231
+ print(f"\n {provider} ({_masked(key)}, {source}): could not reach the "
232
+ "provider — key validity unknown.\n")
233
+ return 3
234
+ if resp.status_code == 200:
235
+ print(f"\n {provider} ({_masked(key)}, {source}): key is valid.\n")
236
+ return 0
237
+ if resp.status_code in (401, 403):
238
+ print(f"\n {provider} ({_masked(key)}, {source}): key was rejected by "
239
+ f"the provider (HTTP {resp.status_code}).\n")
240
+ return 1
241
+ print(f"\n {provider} ({_masked(key)}, {source}): unexpected provider "
242
+ f"response (HTTP {resp.status_code}) — key validity unknown.\n")
243
+ return 3
@@ -63,10 +63,14 @@ def main(argv: list[str] | None = None) -> int:
63
63
  auth_sub = auth_parser.add_subparsers(dest="auth_action")
64
64
  auth_set_p = auth_sub.add_parser("set", help="Store a credential for a provider")
65
65
  auth_set_p.add_argument("provider")
66
+ auth_set_p.add_argument("--from-env", default=None, metavar="ENV_VAR",
67
+ help="Import the key from this environment variable instead of prompting")
66
68
  auth_sub.add_parser("list", help="Show configured credentials")
67
69
  auth_rm_p = auth_sub.add_parser("remove", help="Remove a stored credential")
68
70
  auth_rm_p.add_argument("provider")
69
71
  auth_sub.add_parser("status", help="Check credential status for installed packages")
72
+ auth_test_p = auth_sub.add_parser("test", help="Validate a stored LLM key via a free provider endpoint")
73
+ auth_test_p.add_argument("provider")
70
74
 
71
75
  # config
72
76
  config_parser = sub.add_parser("config", help="View or modify settings")
@@ -270,15 +274,18 @@ def main(argv: list[str] | None = None) -> int:
270
274
  if args.command == "auth":
271
275
  from agentnode_sdk.cli.auth import (
272
276
  cmd_auth_set, cmd_auth_list, cmd_auth_remove, cmd_auth_status,
277
+ cmd_auth_test,
273
278
  )
274
279
  if args.auth_action == "set":
275
- return cmd_auth_set(args.provider)
280
+ return cmd_auth_set(args.provider, from_env=args.from_env)
276
281
  if args.auth_action == "list":
277
282
  return cmd_auth_list()
278
283
  if args.auth_action == "remove":
279
284
  return cmd_auth_remove(args.provider)
280
285
  if args.auth_action == "status":
281
286
  return cmd_auth_status()
287
+ if args.auth_action == "test":
288
+ return cmd_auth_test(args.provider)
282
289
  return cmd_auth_list()
283
290
  if args.command == "config":
284
291
  if args.config_action == "list":