Fix agent kind#14263
Conversation
- Remove broken architecture links in openhands/README.md and enterprise/doc/architecture/README.md - Update frontend/README.md test file references to existing files - Update skills/README.md directory structure and repo.md example to actual files - Update glossary.md to reference skills/ instead of microagents/ - Rewrite app_server/README.md overview to reflect current SDK purpose - Remove empty Troubleshooting section from frontend/README.md - Update LLM docs link in Development.md Co-authored-by: openhands <openhands@all-hands.dev>
Coverage reportClick to see where and how coverage changed
This report was generated by python-coverage-comment-action |
||||||||||||||||||||||||
all-hands-bot
left a comment
There was a problem hiding this comment.
🟡 Acceptable - Prevents crashes from legacy data, but approach could be improved.
[RISK ASSESSMENT]
- [Overall PR]
⚠️ Risk Assessment: 🟡 MEDIUM
This bug fix prevents Pydantic validation errors when loading org settings with legacy agent_kind='llm' values. However, it masks the underlying data problem rather than fixing it through a migration. The risk is medium because: (1) database still contains invalid data, (2) no tests added to prevent regression, (3) the workaround could be bypassed if settings are saved elsewhere without this fix.
VERDICT:
✅ Worth merging: Fixes a real production crash, but should be followed up with data cleanup and tests.
KEY INSIGHT:
The fix prevents immediate crashes but leaves technical debt—consider a follow-up migration to clean the stored data and add regression tests for this legacy data path.
| kwargs = dict(org.agent_settings) | ||
|
|
||
| # Some saved entries have 'llm' in here which is invalid. | ||
| kwargs['agent_kind'] = 'openhands' |
There was a problem hiding this comment.
🟠 Important: This masks the underlying data problem rather than fixing it.
Issues:
- Database still contains invalid
agent_kind='llm'values - Forces value at read-time instead of cleaning up stored data
- If org settings are re-saved elsewhere without this fix, the error could return
Suggested improvements:
- Add a one-time data migration to update all
agent_kind='llm'→'openhands'in the database - Add a warning log when legacy data is detected:
if kwargs.get('agent_kind') == 'llm': logger.warning(f"Org {org.id} has legacy agent_kind='llm', auto-correcting to 'openhands'")
- Document why this workaround exists in a code comment
Why this matters: Data inconsistency between stored and read values can lead to subtle bugs and makes debugging harder.
| def get_agent_settings_from_org(org: Org) -> OpenHandsAgentSettings: | ||
| return OpenHandsAgentSettings.model_validate(dict(org.agent_settings)) | ||
| kwargs = dict(org.agent_settings) | ||
|
|
||
| # Some saved entries have 'llm' in here which is invalid. | ||
| kwargs['agent_kind'] = 'openhands' | ||
| return OpenHandsAgentSettings.model_validate(kwargs) |
There was a problem hiding this comment.
🟡 Suggestion: Add a test for legacy data handling.
No test verifies that orgs with agent_kind='llm' are handled correctly. Add a test like:
@pytest.mark.asyncio
async def test_get_agent_settings_from_org_handles_legacy_llm_agent_kind():
"""Legacy orgs with agent_kind='llm' should be auto-corrected to 'openhands'"""
# Create org with legacy agent_kind='llm'
legacy_org = Org(
name='legacy-org',
agent_settings={'agent_kind': 'llm', 'agent': 'CodeActAgent'}
)
# Should not raise ValidationError
settings = OrgStore.get_agent_settings_from_org(legacy_org)
# Should auto-correct to 'openhands'
assert settings.agent_kind == 'openhands'This prevents regression if the workaround is accidentally removed.
|
Co-authored-by: openhands <openhands@all-hands.dev>
The v1.19.0 LLMAgentSettings -> OpenHandsAgentSettings rename changed the canonical agent_kind discriminator from 'llm' to 'openhands' but did not bump the persisted-settings schema_version or register a migration. Persisted rows that still carry the legacy agent_kind='llm' now break callers that validate against the canonical OpenHandsAgentSettings class (or that route through the discriminated union expecting routing to match the deployed code path). This is an in-band incident triage: - enterprise/server/routes/org_models.py OrgResponse.from_org and OrgDefaultsSettingsResponse.from_org go through AgentSettings from_persisted, which already runs schema migrations on load. They inherit the fix automatically once this migration ships. - The point hot-fix in OpenHands/OpenHands#14263 (force agent_kind='openhands' in OrgStore.get_agent_settings_from_org) becomes redundant on top of this migration. Changes: - Bump AGENT_SETTINGS_SCHEMA_VERSION 1 -> 2. - Register _migrate_agent_settings_v1_to_v2 that rewrites legacy agent_kind='llm' to 'openhands'. The two classes are field- compatible (LLMAgentSettings only narrows the discriminator literal), and LLMAgentSettings is scheduled for removal in v1.22.0, so canonicalizing on read is safe and consistent with the deprecation direction. - Update existing migration tests for the new current_version (the v1 -> v2 step bumps schema_version on every from_persisted call, including the v0 entry-point and the ACP no-op path). - Add test for the new canonicalization migration. Co-authored-by: openhands <openhands@all-hands.dev>
Why
Some stored data has
llmin here instead ofopenhands. We fix this legacy data. I think this is because of changes in the schema between sdk versions.How to Test
I saw this when testing the slack integration - I think it will haven whenever you start a conversation in the cloud.
Video/Screenshots
Type
Notes