Repository navigation
feat(opencode): accept OpenCode 1.19+ 1.x releases #23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| """OpenCode 1.17.20 and 2.0 public import/export adapters. | ||
| """OpenCode 1.x (1.19+) and 2.0 public import/export adapters. | ||
|
|
||
| The writer emits the public JSON shape consumed by ``opencode import``. It | ||
| never writes OpenCode's SQLite database directly. | ||
|
|
@@ -23,8 +23,12 @@ | |
| from session_migrate.jsonl import file_sha256 | ||
| from session_migrate.model import AgentFormat, Event, EventKind, Provenance, Role, Session | ||
|
|
||
| PINNED_OPENCODE_VERSION = "1.17.20" | ||
| PINNED_OPENCODE_VERSION = "1.19.4" | ||
| OPENCODE_NATIVE_IMPORT_SUPPORTED = True | ||
| # Legacy 1.x releases keep the same public export, import, and session-list | ||
| # shape, so the 1.19+ family is accepted. | ||
| _LEGACY_MIN_VERSION = (19, 0) | ||
| _LEGACY_VERSION = re.compile(r"(?:opencode v)?1\.(\d+)\.(\d+)(?:[-+][0-9A-Za-z.-]+)?") | ||
| OPENCODE_IMPORT_MEDIA_TYPES = {"image/gif", "image/jpeg", "image/png", "image/webp"} | ||
| MAX_NATIVE_BYTES = 256 * 1024 * 1024 | ||
| MAX_NATIVE_MESSAGES = 1_000_000 | ||
|
|
@@ -54,8 +58,15 @@ def is_v2(value: str | None) -> bool: | |
| return value is not None and opencode_v2.version(value) is not None | ||
|
|
||
|
|
||
| def is_legacy(value: str | None) -> bool: | ||
| """Whether a 1.x release keeps the pinned legacy public bundle shape.""" | ||
|
|
||
| match = None if value is None else _LEGACY_VERSION.fullmatch(value) | ||
| return match is not None and (int(match[1]), int(match[2])) >= _LEGACY_MIN_VERSION | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. F1 (crash site): int(match[1])/int(match[2]) on the unbounded regex groups from line 31 raises ValueError for >4300-digit components, which no caller of supported_version() catches (conversion.py:197, :1429, :1436, :1850). Verified: merge rc=1 traceback vs baseline rc=2 clean error for the identical input. Fix: wrap the conversion (return False on ValueError) or bound the digits in the regex at line 31. — pi 1.4.0 · |
||
|
|
||
|
|
||
| def supported_version(value: str | None) -> bool: | ||
| return value == PINNED_OPENCODE_VERSION or is_v2(value) | ||
| return is_legacy(value) or is_v2(value) | ||
|
|
||
|
|
||
| def session_id_from_uuid(value: str) -> str: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
F1: _LEGACY_VERSION uses unbounded (\d+) groups. Combined with int() in is_legacy (line 65), a version component longer than CPython's int_max_str_digits limit (4300) raises an uncaught ValueError. Reproduced via CLI:
import <src> --to opencode --target-cli-version "1.<5000 nines>.0" --dry-runexits 1 with a raw ValueError traceback (main exits 2 with a clean version-mismatch error); a fake source CLI printing the same string crashes the source gate at conversion.py:197 the same way. Fix: bound the groups (e.g. (\d{1,9})) and add a regression test.— pi 1.4.0 ·
mistral/mistral-large-4· @xhluca-agent