feat(sdk-python): first-class spec.git helper for durable workspaces#823
Conversation
Add mitos.git(...) so a caller declares a Workspace spec.git (the mitos.run/v1 WorkspaceGit) declaratively: the repo paths that get version history and the fork-and-merge rendezvous remote, plus an optional push-credentials reference, instead of hand-patching the Workspace CRD. The helper is pure spec construction (no server, no cluster, no KVM). It is plumbed into AgentRun.create_workspace(name, git=...) and Workspace.set_git(...), accepting a GitSpec or a bare list of paths. Validation fails fast with LLM-legible errors (invalid_git_paths, invalid_git_credentials). The push token is a secret value: the helper only ever records a Secret name and key, never the token itself. Simplify the background_agent example to declare spec.git.paths through the helper at create time, removing the raw patch_namespaced_custom_object workaround, and document the helper in the SDK README. Closes #619 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Jannes Stubbemann <jannes@openclaw.rocks>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdds a first-class Changesspec.git helper feature
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Caller
participant AgentRun
participant coerce_git
participant KubernetesAPI
participant Workspace
Caller->>AgentRun: create_workspace(name, git)
AgentRun->>coerce_git: normalize git input
coerce_git-->>AgentRun: return GitSpec
AgentRun->>KubernetesAPI: create Workspace with spec.git
Caller->>Workspace: set_git(git)
Workspace->>coerce_git: normalize git input
coerce_git-->>Workspace: return GitSpec
Workspace->>KubernetesAPI: patch spec.git
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@sdk/python/mitos/git.py`:
- Around line 37-130: Validation currently lives only in git(), so direct
GitSpec(...) construction can bypass the fail-fast checks and let invalid data
reach coerce_git() and to_spec(). Move the existing paths/credentials validation
logic into GitSpec.__post_init__ so every construction path is enforced,
including exported mitos.GitSpec usage, and keep git() as a thin wrapper that
just builds GitSpec. Make sure __post_init__ covers the same rules for paths,
credentials_secret, and credentials_username-without-secret.
In `@sdk/python/mitos/workspace.py`:
- Around line 246-262: The set_git method in Workspace currently patches
spec.git with merge-patch semantics, so unset credential fields are preserved
instead of cleared. Update set_git() to include credentialsSecretRef and
credentialsUsername as explicit null values whenever coerce_git(git).to_spec()
does not set them, so patch_namespaced_custom_object removes any previously
stored credentials. Use the existing Workspace.set_git and coerce_git helpers to
locate and adjust the patch payload.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 23cb622b-119d-4d05-ad06-614f12cc70c5
📒 Files selected for processing (7)
sdk/python/README.mdsdk/python/examples/background_agent.pysdk/python/mitos/__init__.pysdk/python/mitos/client.pysdk/python/mitos/git.pysdk/python/mitos/workspace.pysdk/python/tests/test_git.py
…stale creds Address CodeRabbit review on the spec.git helper: - Move validation into GitSpec.__post_init__ (shared _validate_git_args) so a directly constructed mitos.GitSpec is validated too, not only the git() factory; git() is now a thin wrapper. - In Workspace.set_git, send credentialsSecretRef and credentialsUsername as explicit null when unset, so a merge-patch that drops credentials actually clears the previously stored reference instead of preserving it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Jannes Stubbemann <jannes@openclaw.rocks>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
sdk/python/tests/test_git.py (1)
55-80: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider parametrizing validation tests.
Per the description, this segment covers multiple invalid-input cases (empty paths, malformed credential tuples) as separate test functions. Consolidating with
pytest.mark.parametrizewould reduce duplication as more invalid-input cases are added later.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@sdk/python/tests/test_git.py` around lines 55 - 80, The validation tests in test_git.py are duplicated across multiple near-identical cases, so consolidate them into a parametrized pytest test to make adding future invalid-input cases easier. Update the existing test functions around mitos.git to use pytest.mark.parametrize for the invalid paths and malformed credentials scenarios, while preserving the current AgentRunError assertions and expected error codes/remediation checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@sdk/python/tests/test_git.py`:
- Around line 55-80: The validation tests in test_git.py are duplicated across
multiple near-identical cases, so consolidate them into a parametrized pytest
test to make adding future invalid-input cases easier. Update the existing test
functions around mitos.git to use pytest.mark.parametrize for the invalid paths
and malformed credentials scenarios, while preserving the current AgentRunError
assertions and expected error codes/remediation checks.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 6ec4b3bd-dacb-4ea9-8768-7deb0a58a48a
📒 Files selected for processing (3)
sdk/python/mitos/git.pysdk/python/mitos/workspace.pysdk/python/tests/test_git.py
…id_git_credentials error A realistic misuse of a credentials-named argument is passing the raw token itself; the repr in the error cause would put that token verbatim into an exception message. Report the received type instead of the value, and pin the hygiene with a test. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Jannes Stubbemann <jannes@openclaw.rocks>
Thinking Path
Linked Issues or Issue Description
Closes #619
What Changed
sdk/python/mitos/git.py:GitSpecdataclass plus themitos.git(paths, *, credentials_secret=None, credentials_username=None)factory, which validates arguments and renders the mitos.run/v1spec.gitJSON. Fail-fast LLM-legible errors:invalid_git_paths(empty or blank path) andinvalid_git_credentials(malformed secret ref, or username without a secret). Acoerce_gitnormaliser accepts aGitSpecor a bare list of paths.git=intoAgentRun.create_workspace(name, git=...)so the workspace is created withspec.gitalready set; omit the key entirely whengitis not passed.Workspace.set_git(...)to declarespec.giton an existing workspace first-class, replacing the rawpatch_namespaced_custom_objectidiom.gitandGitSpecfrom themitospackage.sdk/python/examples/background_agent.py: create the workspace withgit=mitos.git(paths=["/workspace/repo"]), remove the hand-rolled CRD patch and its honest-gap note, and add an import-time spec-surface check.sdk/python/README.mdunder a new "Durable workspaces and spec.git" subsection.sdk/python/tests/test_git.py(12 tests) covering construction, defaults, credentials rendering, validation errors, create_workspace plumbing, set_git, and the package export.Verification
cd sdk/python && PYTHONPATH=. python3 -m pytest tests/: 352 passed, 1 skipped.PYTHONPATH=. python3 -m pytest tests/test_git.py -v: 12 passed.python3 -m py_compile sdk/python/examples/*.pyand the import-check (module-level exec) pass for every example; every README python fence byte-compiles (24 fences, 0 failures).Risks
Low risk. The change is additive and pure spec construction: no server, cluster, or KVM path is touched.
create_workspacekeeps its prior behavior whengitis not passed (thespec.gitkey is omitted). The push-credentials token is never accepted or emitted; only a Secret name and key reference is recorded.Model Used
Claude Opus 4.8 (1M context), model id claude-opus-4-8[1m], extended thinking mode.
Checklist
#NNN/ mitos-run/mitos URLs)Signed-off-bytrailer (git commit -s)Summary by CodeRabbit
mitos.git/GitSpec) to declaratively setspec.git.pathsand optional credential references.Workspace.set_git(...).gitandGitSpecas part of the public Python API.