feat(agent-integrator): convert tools list to object for opencode target#1478
Open
futbolsalas15 wants to merge 9 commits into
Open
feat(agent-integrator): convert tools list to object for opencode target#1478futbolsalas15 wants to merge 9 commits into
futbolsalas15 wants to merge 9 commits into
Conversation
OpenCode expects the `tools` frontmatter field in agent files to be an
object (`{Read: true, Glob: true}`) rather than a list
(`[Read, Glob]`). This adds a new `_write_opencode_agent` method
that converts list- or comma-separated-string `tools` to the object
format, and wires it into the `integrate_agents_for_target` dispatch
for the `opencode_agent` format_id.
Previously, the opencode target fell through to `copy_agent` (verbatim
copy), which would pass the list-format `tools` through to opencode,
causing a schema validation error:
SchemaError: Expected object | undefined, got [...]
at ["tools"]
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds OpenCode agent integration by converting the tools frontmatter field from list/string formats into OpenCode’s expected object format, and covers the behavior with unit/integration tests.
Changes:
- Add
opencode_agentdispatch path inAgentIntegrator.integrate_agents_for_target. - Implement
_write_opencode_agentto converttoolsfrontmatter (list / comma-separated string → object). - Add tests covering conversion behavior, symlink rejection, and end-to-end target integration.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| tests/unit/integration/test_agent_integrator.py | Adds test coverage for OpenCode-specific tools conversion and target integration behavior. |
| src/apm_cli/integration/agent_integrator.py | Introduces OpenCode agent transformer and hooks it into target-driven dispatch. |
…ists in opencode agent writer
- Normalize yaml.safe_load result: if frontmatter is not a dict (e.g.
bare list), treat as empty and emit a diagnostic warning instead of
crashing on fm.get('tools').
- Add target.parent.mkdir(parents=True, exist_ok=True) before writing,
aligning with _write_windsurf_agent_skill pattern.
- Add test for non-dict frontmatter handling.
Addresses Copilot review comments on lines 393, 406, and 426.
…r docstring The docstring claimed 'preserving all other frontmatter' but re-serialising via yaml.safe_dump drops YAML comments and can reorder keys. Updated to accurately describe what is preserved (key values) and what is not (comments, ordering). Addresses Copilot review comments on line 424.
Author
|
@microsoft-github-policy-service agree company="JobNimbus" |
…ir consistency - Move conversion diagnostic inside list/str branches so it only fires when actual conversion occurs (not for e.g. int/float tools) - Strip whitespace from list-form tools entries, aligning with string-form behavior - Add target.parent.mkdir() to the early-return (no frontmatter) path Addresses Copilot review comments 1, 2, 3.
- Change 'tools' not-in-content assertion to 'tools:' to avoid false negatives from the word appearing in body/frontmatter - Add whitespace-padded list entry to exercise strip() normalization Addresses Copilot review comment 4.
…ve early-return branch
- Emit diagnostic warn when YAML parsing fails (comment 1)
- Use conversion_occurred flag: when no tools conversion is needed, pass through original content verbatim instead of re-serialising (fixes empty-fm {} output, comment 2)
- Drop the early-return branch that duplicated copy_agent; all paths now share a single resolve_links + write tail (comment 3)
- Update docstring to reflect pass-through preservation when no conversion occurs
- Wrap os.symlink() in try/except (OSError, NotImplementedError) with pytest.skip, matching established project pattern - Move import pytest to top of function so skip guard is reachable Addresses Copilot review comment 4.
…dict frontmatter preservation - Catch yaml.YAMLError instead of broad Exception - Update test_handles_non_dict_frontmatter docstring from "treated as empty" to "preserved as-is" - Verify original list items survive serialisation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TL;DR
OpenCode expects the
toolsfrontmatter field in agent/skill files to be an object ({Read: true, Glob: true}). Some agent files — especially those authored for other harnesses — define it as a list (e.g.[Read, Glob]) or a comma-separated string. Whenapm installcopies such files to.opencode/agents/verbatim, opencode rejects them with a schema validation error.What this PR does
_write_opencode_agent()toAgentIntegrator— a new transform method that convertstoolsfrom list or comma-separated-string to object format, preserving all other frontmatter and the markdown body.opencode_agentformat_id into theintegrate_agents_for_targetdispatch so the conversion runs automatically when deploying to.opencode/agents/.How to test