agentversion 0.2.0__tar.gz → 0.2.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.

Potentially problematic release.


This version of agentversion might be problematic. Click here for more details.

Files changed (124) hide show
  1. {agentversion-0.2.0 → agentversion-0.2.1}/CHANGELOG.md +19 -0
  2. {agentversion-0.2.0 → agentversion-0.2.1}/PKG-INFO +1 -1
  3. {agentversion-0.2.0 → agentversion-0.2.1}/agentversion/contract.py +20 -1
  4. {agentversion-0.2.0 → agentversion-0.2.1}/pyproject.toml +1 -1
  5. {agentversion-0.2.0 → agentversion-0.2.1}/tests/test_contract.py +61 -0
  6. {agentversion-0.2.0 → agentversion-0.2.1}/.github/dependabot.yml +0 -0
  7. {agentversion-0.2.0 → agentversion-0.2.1}/.github/workflows/ci.yml +0 -0
  8. {agentversion-0.2.0 → agentversion-0.2.1}/.github/workflows/publish.yml +0 -0
  9. {agentversion-0.2.0 → agentversion-0.2.1}/.gitignore +0 -0
  10. {agentversion-0.2.0 → agentversion-0.2.1}/CONFORMANCE.md +0 -0
  11. {agentversion-0.2.0 → agentversion-0.2.1}/CONTRIBUTING.md +0 -0
  12. {agentversion-0.2.0 → agentversion-0.2.1}/LICENSE +0 -0
  13. {agentversion-0.2.0 → agentversion-0.2.1}/README.md +0 -0
  14. {agentversion-0.2.0 → agentversion-0.2.1}/RELEASING.md +0 -0
  15. {agentversion-0.2.0 → agentversion-0.2.1}/adrs/0000-template.md +0 -0
  16. {agentversion-0.2.0 → agentversion-0.2.1}/adrs/0001-version-spec-core.md +0 -0
  17. {agentversion-0.2.0 → agentversion-0.2.1}/agentversion/__init__.py +0 -0
  18. {agentversion-0.2.0 → agentversion-0.2.1}/agentversion/_shared.py +0 -0
  19. {agentversion-0.2.0 → agentversion-0.2.1}/agentversion/a2a.py +0 -0
  20. {agentversion-0.2.0 → agentversion-0.2.1}/agentversion/cli.py +0 -0
  21. {agentversion-0.2.0 → agentversion-0.2.1}/agentversion/compatibility.py +0 -0
  22. {agentversion-0.2.0 → agentversion-0.2.1}/agentversion/constants.py +0 -0
  23. {agentversion-0.2.0 → agentversion-0.2.1}/agentversion/dataset.py +0 -0
  24. {agentversion-0.2.0 → agentversion-0.2.1}/agentversion/decision.py +0 -0
  25. {agentversion-0.2.0 → agentversion-0.2.1}/agentversion/diff.py +0 -0
  26. {agentversion-0.2.0 → agentversion-0.2.1}/agentversion/hasher.py +0 -0
  27. {agentversion-0.2.0 → agentversion-0.2.1}/agentversion/ids.py +0 -0
  28. {agentversion-0.2.0 → agentversion-0.2.1}/agentversion/manifest.py +0 -0
  29. {agentversion-0.2.0 → agentversion-0.2.1}/agentversion/py.typed +0 -0
  30. {agentversion-0.2.0 → agentversion-0.2.1}/agentversion/refs.py +0 -0
  31. {agentversion-0.2.0 → agentversion-0.2.1}/agentversion/replay.py +0 -0
  32. {agentversion-0.2.0 → agentversion-0.2.1}/agentversion/validator.py +0 -0
  33. {agentversion-0.2.0 → agentversion-0.2.1}/compatibility-tests/environment-region-change/after.json +0 -0
  34. {agentversion-0.2.0 → agentversion-0.2.1}/compatibility-tests/environment-region-change/before.json +0 -0
  35. {agentversion-0.2.0 → agentversion-0.2.1}/compatibility-tests/environment-region-change/expected-diff.json +0 -0
  36. {agentversion-0.2.0 → agentversion-0.2.1}/compatibility-tests/model-runtime-provider-change/after.json +0 -0
  37. {agentversion-0.2.0 → agentversion-0.2.1}/compatibility-tests/model-runtime-provider-change/before.json +0 -0
  38. {agentversion-0.2.0 → agentversion-0.2.1}/compatibility-tests/model-runtime-provider-change/expected-diff.json +0 -0
  39. {agentversion-0.2.0 → agentversion-0.2.1}/compatibility-tests/output-schema-change/after.json +0 -0
  40. {agentversion-0.2.0 → agentversion-0.2.1}/compatibility-tests/output-schema-change/before.json +0 -0
  41. {agentversion-0.2.0 → agentversion-0.2.1}/compatibility-tests/output-schema-change/expected-diff.json +0 -0
  42. {agentversion-0.2.0 → agentversion-0.2.1}/compatibility-tests/prompt-stack-edit/after.json +0 -0
  43. {agentversion-0.2.0 → agentversion-0.2.1}/compatibility-tests/prompt-stack-edit/before.json +0 -0
  44. {agentversion-0.2.0 → agentversion-0.2.1}/compatibility-tests/prompt-stack-edit/expected-diff.json +0 -0
  45. {agentversion-0.2.0 → agentversion-0.2.1}/compatibility-tests/skill-registry-skill-removed/after.json +0 -0
  46. {agentversion-0.2.0 → agentversion-0.2.1}/compatibility-tests/skill-registry-skill-removed/before.json +0 -0
  47. {agentversion-0.2.0 → agentversion-0.2.1}/compatibility-tests/skill-registry-skill-removed/expected-diff.json +0 -0
  48. {agentversion-0.2.0 → agentversion-0.2.1}/compatibility-tests/subagent-handoff-change/after.json +0 -0
  49. {agentversion-0.2.0 → agentversion-0.2.1}/compatibility-tests/subagent-handoff-change/before.json +0 -0
  50. {agentversion-0.2.0 → agentversion-0.2.1}/compatibility-tests/subagent-handoff-change/expected-diff.json +0 -0
  51. {agentversion-0.2.0 → agentversion-0.2.1}/compatibility-tests/tool-rename/after.json +0 -0
  52. {agentversion-0.2.0 → agentversion-0.2.1}/compatibility-tests/tool-rename/before.json +0 -0
  53. {agentversion-0.2.0 → agentversion-0.2.1}/compatibility-tests/tool-rename/expected-diff.json +0 -0
  54. {agentversion-0.2.0 → agentversion-0.2.1}/compatibility-tests/workflow-graph-change/after.json +0 -0
  55. {agentversion-0.2.0 → agentversion-0.2.1}/compatibility-tests/workflow-graph-change/before.json +0 -0
  56. {agentversion-0.2.0 → agentversion-0.2.1}/compatibility-tests/workflow-graph-change/expected-diff.json +0 -0
  57. {agentversion-0.2.0 → agentversion-0.2.1}/examples/.gitkeep +0 -0
  58. {agentversion-0.2.0 → agentversion-0.2.1}/examples/integrations/decimalai_bridge.py +0 -0
  59. {agentversion-0.2.0 → agentversion-0.2.1}/examples/integrations/langgraph_example.py +0 -0
  60. {agentversion-0.2.0 → agentversion-0.2.1}/examples/integrations/otel_mapping.md +0 -0
  61. {agentversion-0.2.0 → agentversion-0.2.1}/examples/manifest/finance-agent-v1.json +0 -0
  62. {agentversion-0.2.0 → agentversion-0.2.1}/examples/manifest/finance-agent-v2.json +0 -0
  63. {agentversion-0.2.0 → agentversion-0.2.1}/examples/scenarios/tool-rename-drift.md +0 -0
  64. {agentversion-0.2.0 → agentversion-0.2.1}/examples/scenarios/walkthrough.py +0 -0
  65. {agentversion-0.2.0 → agentversion-0.2.1}/pyrightconfig.json +0 -0
  66. {agentversion-0.2.0 → agentversion-0.2.1}/schemas/.gitkeep +0 -0
  67. {agentversion-0.2.0 → agentversion-0.2.1}/schemas/agent-manifest.schema.json +0 -0
  68. {agentversion-0.2.0 → agentversion-0.2.1}/schemas/compatibility-batch.schema.json +0 -0
  69. {agentversion-0.2.0 → agentversion-0.2.1}/schemas/compatibility-decision.schema.json +0 -0
  70. {agentversion-0.2.0 → agentversion-0.2.1}/schemas/compatibility-policy.schema.json +0 -0
  71. {agentversion-0.2.0 → agentversion-0.2.1}/schemas/compatibility-report.schema.json +0 -0
  72. {agentversion-0.2.0 → agentversion-0.2.1}/schemas/dataset-snapshot.schema.json +0 -0
  73. {agentversion-0.2.0 → agentversion-0.2.1}/schemas/episode.schema.json +0 -0
  74. {agentversion-0.2.0 → agentversion-0.2.1}/schemas/manifest-diff.schema.json +0 -0
  75. {agentversion-0.2.0 → agentversion-0.2.1}/schemas/replay-job.schema.json +0 -0
  76. {agentversion-0.2.0 → agentversion-0.2.1}/schemas/replay-result.schema.json +0 -0
  77. {agentversion-0.2.0 → agentversion-0.2.1}/schemas/step.schema.json +0 -0
  78. {agentversion-0.2.0 → agentversion-0.2.1}/schemas/task.schema.json +0 -0
  79. {agentversion-0.2.0 → agentversion-0.2.1}/scripts/release.sh +0 -0
  80. {agentversion-0.2.0 → agentversion-0.2.1}/spec/a2a-mapping.md +0 -0
  81. {agentversion-0.2.0 → agentversion-0.2.1}/spec/attestation.md +0 -0
  82. {agentversion-0.2.0 → agentversion-0.2.1}/spec/behavioral-policy.md +0 -0
  83. {agentversion-0.2.0 → agentversion-0.2.1}/spec/compatibility-batch.md +0 -0
  84. {agentversion-0.2.0 → agentversion-0.2.1}/spec/compatibility-decision.md +0 -0
  85. {agentversion-0.2.0 → agentversion-0.2.1}/spec/compatibility-policy.md +0 -0
  86. {agentversion-0.2.0 → agentversion-0.2.1}/spec/data-classification.md +0 -0
  87. {agentversion-0.2.0 → agentversion-0.2.1}/spec/dataset.md +0 -0
  88. {agentversion-0.2.0 → agentversion-0.2.1}/spec/diff.md +0 -0
  89. {agentversion-0.2.0 → agentversion-0.2.1}/spec/environment.md +0 -0
  90. {agentversion-0.2.0 → agentversion-0.2.1}/spec/evaluation.md +0 -0
  91. {agentversion-0.2.0 → agentversion-0.2.1}/spec/hashing.md +0 -0
  92. {agentversion-0.2.0 → agentversion-0.2.1}/spec/ids.md +0 -0
  93. {agentversion-0.2.0 → agentversion-0.2.1}/spec/lifecycle.md +0 -0
  94. {agentversion-0.2.0 → agentversion-0.2.1}/spec/manifest.md +0 -0
  95. {agentversion-0.2.0 → agentversion-0.2.1}/spec/otel-mapping.md +0 -0
  96. {agentversion-0.2.0 → agentversion-0.2.1}/spec/reference.md +0 -0
  97. {agentversion-0.2.0 → agentversion-0.2.1}/spec/refs.md +0 -0
  98. {agentversion-0.2.0 → agentversion-0.2.1}/spec/replay-determinism.md +0 -0
  99. {agentversion-0.2.0 → agentversion-0.2.1}/spec/replay.md +0 -0
  100. {agentversion-0.2.0 → agentversion-0.2.1}/spec/versioning-policy.md +0 -0
  101. {agentversion-0.2.0 → agentversion-0.2.1}/tests/fixtures/frozen_hash_vectors.json +0 -0
  102. {agentversion-0.2.0 → agentversion-0.2.1}/tests/test_a2a_mapping.py +0 -0
  103. {agentversion-0.2.0 → agentversion-0.2.1}/tests/test_audit_v020.py +0 -0
  104. {agentversion-0.2.0 → agentversion-0.2.1}/tests/test_audit_v030.py +0 -0
  105. {agentversion-0.2.0 → agentversion-0.2.1}/tests/test_behavioral_policy.py +0 -0
  106. {agentversion-0.2.0 → agentversion-0.2.1}/tests/test_cli.py +0 -0
  107. {agentversion-0.2.0 → agentversion-0.2.1}/tests/test_component_surface_map.py +0 -0
  108. {agentversion-0.2.0 → agentversion-0.2.1}/tests/test_conformance.py +0 -0
  109. {agentversion-0.2.0 → agentversion-0.2.1}/tests/test_dataset.py +0 -0
  110. {agentversion-0.2.0 → agentversion-0.2.1}/tests/test_decision_replay.py +0 -0
  111. {agentversion-0.2.0 → agentversion-0.2.1}/tests/test_diff.py +0 -0
  112. {agentversion-0.2.0 → agentversion-0.2.1}/tests/test_environment.py +0 -0
  113. {agentversion-0.2.0 → agentversion-0.2.1}/tests/test_evaluation.py +0 -0
  114. {agentversion-0.2.0 → agentversion-0.2.1}/tests/test_examples_runnable.py +0 -0
  115. {agentversion-0.2.0 → agentversion-0.2.1}/tests/test_extension_hatch.py +0 -0
  116. {agentversion-0.2.0 → agentversion-0.2.1}/tests/test_frozen_hash_vectors.py +0 -0
  117. {agentversion-0.2.0 → agentversion-0.2.1}/tests/test_hasher.py +0 -0
  118. {agentversion-0.2.0 → agentversion-0.2.1}/tests/test_ids.py +0 -0
  119. {agentversion-0.2.0 → agentversion-0.2.1}/tests/test_lifecycle.py +0 -0
  120. {agentversion-0.2.0 → agentversion-0.2.1}/tests/test_manifest.py +0 -0
  121. {agentversion-0.2.0 → agentversion-0.2.1}/tests/test_refs.py +0 -0
  122. {agentversion-0.2.0 → agentversion-0.2.1}/tests/test_reproducible_replay.py +0 -0
  123. {agentversion-0.2.0 → agentversion-0.2.1}/tests/test_trust_observability.py +0 -0
  124. {agentversion-0.2.0 → agentversion-0.2.1}/tests/test_validator.py +0 -0
@@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  > **Package version ≠ spec version.** This file tracks the **package** version. The on-the-wire `spec_version` is independent and frozen at `1.0.0`; a pre-1.0 package can implement a stable 1.0 spec, which is exactly the situation today.
9
9
 
10
+ ## [0.2.1] - 2026-06-24
11
+
12
+ ### Fixed
13
+ - **`contract_from_components` now emits the `behavioral_policy` and
14
+ `environment` surfaces.** 0.2.0 added the models, surface keys, and diff
15
+ classifiers, but the shared flat-components → contract assembler silently
16
+ dropped both — so a producer (the DecimalAI SDK / the platform) could never
17
+ actually populate them from components. They are now assembled verbatim from
18
+ each component's `schema_json`. Additive-only: a manifest that doesn't declare
19
+ them is unchanged (same `overall_hash`).
20
+ - **`tool_calling_mode` and `runtime_version` are now lifted to `model_runtime`
21
+ top level** (not buried in `model_config_hash`), so a `tool_calling_mode`
22
+ change is classified **breaking** by the diff as intended, and
23
+ `runtime_version` participates in `model_runtime` severity.
24
+
25
+ The DecimalAI SDK exporter (`ManifestSnapshot.to_agentversion`) was edited
26
+ byte-identically and is pinned to this assembly by its conformance test.
27
+ `SPEC_VERSION` is unchanged (1.0.0) — these surfaces were already in the spec.
28
+
10
29
  ## [0.2.0] - 2026-06-24
11
30
 
12
31
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentversion
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: An open specification for versioning agent runtimes and keeping datasets valid.
5
5
  Project-URL: Homepage, https://github.com/decimal-labs/agentversion
6
6
  Project-URL: Documentation, https://github.com/decimal-labs/agentversion/tree/main/spec
@@ -12,7 +12,8 @@ Each component is a plain dict::
12
12
  {
13
13
  "component_type": "tool" | "skill" | "prompt" | "model" | "subagent"
14
14
  | "output_schema" | "workflow" | "guardrail"
15
- | "context_config",
15
+ | "context_config" | "behavioral_policy"
16
+ | "environment",
16
17
  "component_name": str,
17
18
  "component_version": str | None,
18
19
  "content_hash": str | None, # producer-supplied content fingerprint
@@ -146,6 +147,13 @@ def contract_from_components(components: list[dict[str, Any]]) -> dict[str, Any]
146
147
  gen["response_format"] = cfg["response_format"]
147
148
  if gen:
148
149
  model_runtime["generation_config"] = gen
150
+ # tool_calling_mode + runtime_version are TOP-LEVEL model_runtime fields
151
+ # (not under generation_config); the diff classifies a tool_calling_mode
152
+ # change as breaking. Must stay byte-identical with the SDK exporter.
153
+ if isinstance(cfg.get("tool_calling_mode"), str):
154
+ model_runtime["tool_calling_mode"] = cfg["tool_calling_mode"]
155
+ if isinstance(cfg.get("runtime_version"), str):
156
+ model_runtime["runtime_version"] = cfg["runtime_version"]
149
157
  else:
150
158
  model_runtime = {"provider": "unknown", "model": "unknown"}
151
159
 
@@ -252,4 +260,15 @@ def contract_from_components(components: list[dict[str, Any]]) -> dict[str, Any]
252
260
  ctx["retrieval_config_hash"] = ctx_comps[0]["content_hash"]
253
261
  contract["context_config"] = ctx
254
262
 
263
+ # behavioral_policy / environment are single structured surfaces (the surface
264
+ # IS the config), emitted verbatim from schema_json so hash_manifest hashes
265
+ # their contents. Must stay byte-identical with the SDK exporter.
266
+ bp_comps = by_type.get("behavioral_policy", [])
267
+ if bp_comps:
268
+ contract["behavioral_policy"] = dict(bp_comps[0].get("schema_json") or {})
269
+
270
+ env_comps = by_type.get("environment", [])
271
+ if env_comps:
272
+ contract["environment"] = dict(env_comps[0].get("schema_json") or {})
273
+
255
274
  return contract
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "agentversion"
7
- version = "0.2.0"
7
+ version = "0.2.1"
8
8
  description = "An open specification for versioning agent runtimes and keeping datasets valid."
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -59,6 +59,67 @@ def test_model_provider_inferred_when_absent():
59
59
  assert c["model_runtime"]["provider"] == "anthropic"
60
60
 
61
61
 
62
+ # ── OSS-1/3/7: new 0.2.0 surfaces (must mirror the SDK exporter) ────────────
63
+
64
+ def test_model_runtime_lifts_tool_calling_mode_and_runtime_version():
65
+ """OSS-1: tool_calling_mode + runtime_version are TOP-LEVEL model_runtime
66
+ fields (not under generation_config), so the diff classifies them."""
67
+ c = contract_from_components([
68
+ _comp("model", "default", content_hash="sha256:m",
69
+ schema_json={"provider": "openai", "model": "gpt-4o",
70
+ "tool_calling_mode": "native", "runtime_version": "1.2"}),
71
+ ])
72
+ mr = c["model_runtime"]
73
+ assert mr["tool_calling_mode"] == "native"
74
+ assert mr["runtime_version"] == "1.2"
75
+ assert "tool_calling_mode" not in mr.get("generation_config", {})
76
+
77
+
78
+ def test_behavioral_policy_surface_assembled():
79
+ """OSS-3: behavioral_policy is emitted verbatim from its schema_json."""
80
+ sj = {"policy_id": "refund", "policy_hash": "sha256:p", "objection_threshold": 3,
81
+ "always_forbidden": ["admit_liability"]}
82
+ c = contract_from_components([
83
+ _comp("model", "default", schema_json={"model": "gpt-4o"}),
84
+ _comp("behavioral_policy", "behavioral_policy", content_hash="sha256:p", schema_json=sj),
85
+ ])
86
+ assert c["behavioral_policy"] == sj
87
+
88
+
89
+ def test_environment_surface_assembled():
90
+ """OSS-7: environment is emitted verbatim from its schema_json."""
91
+ sj = {"deployment_id": "d", "region": "us", "runtime_versions": {"python": "3.12"}}
92
+ c = contract_from_components([
93
+ _comp("model", "default", schema_json={"model": "gpt-4o"}),
94
+ _comp("environment", "environment", content_hash="sha256:e", schema_json=sj),
95
+ ])
96
+ assert c["environment"] == sj
97
+
98
+
99
+ def test_new_optional_surfaces_absent_when_undeclared():
100
+ """Additive-only: a model-only contract carries neither new surface, so
101
+ existing manifests keep their exact prior identity hash."""
102
+ c = contract_from_components([_comp("model", "default", schema_json={"model": "gpt-4o"})])
103
+ assert "behavioral_policy" not in c
104
+ assert "environment" not in c
105
+
106
+
107
+ def test_behavioral_policy_participates_in_identity_hash():
108
+ """Adding behavioral_policy, and changing its policy_hash, each change the
109
+ canonical jcs-sha256 identity hash."""
110
+ base = [_comp("model", "default", content_hash="sha256:m",
111
+ schema_json={"provider": "openai", "model": "gpt-4o"})]
112
+ with_p = base + [_comp("behavioral_policy", "behavioral_policy", content_hash="sha256:p",
113
+ schema_json={"policy_id": "p", "policy_hash": "sha256:p"})]
114
+ with_p2 = base + [_comp("behavioral_policy", "behavioral_policy", content_hash="sha256:p2",
115
+ schema_json={"policy_id": "p", "policy_hash": "sha256:p2"})]
116
+ h_base = hash_manifest({"contract": contract_from_components(base)})
117
+ h_p = hash_manifest({"contract": contract_from_components(with_p)})
118
+ h_p2 = hash_manifest({"contract": contract_from_components(with_p2)})
119
+ assert h_base != h_p # the surface participates in identity
120
+ assert h_p != h_p2 # a rule change re-versions
121
+
122
+
62
123
  def test_tool_and_skill_registry_hashes_are_computed():
63
124
  c = contract_from_components([
64
125
  _comp("tool", "t1", version="1", content_hash="sha256:t1",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes