Files
Elydora-Python-SDK/elydora/plugins/qwen_config.py
T

231 lines
6.9 KiB
Python

"""Qwen Code JSONC parsing and source-preserving hook edits."""
from __future__ import annotations
from dataclasses import dataclass
from typing import Dict, Optional
from ._jsonc import JsoncEditor
from ._managed_files import FileSnapshot
from .qwen_contract import (
MANAGED_EVENTS,
JsonObject,
QwenHooks,
managed_qwen_removals,
read_qwen_hooks,
)
OWNED_FILE_MARKER = "// Managed by Elydora"
@dataclass(frozen=True)
class QwenDocument:
kind: str
file_path: str
exists: bool
raw: str
snapshot: Optional[FileSnapshot]
root: JsonObject
hooks: QwenHooks
has_hooks_container: bool
disable_all_hooks: Optional[bool]
folder_trust_enabled: Optional[bool]
owned_file: bool
@dataclass(frozen=True)
class RenderedQwenDocument:
document: QwenDocument
changed: bool
next_source: Optional[str]
def qwen_source_label(kind: str) -> str:
labels = {
"system-defaults": "Qwen Code system defaults",
"user": "Qwen Code user settings",
"workspace": "Qwen Code workspace settings",
"system": "Qwen Code system override settings",
}
try:
return labels[kind]
except KeyError as error:
raise ValueError(f"Unsupported Qwen Code document kind: {kind}") from error
def qwen_document_label(document: QwenDocument) -> str:
return qwen_source_label(document.kind)
def parse_qwen_jsonc_object(raw: str, label: str) -> JsonObject:
editor = JsoncEditor(raw, label, allow_trailing_commas=False)
if not isinstance(editor.value, dict):
raise ValueError(f"{label} must contain a JSON object")
return editor.value
def _folder_trust_enabled(
root: JsonObject, label: str
) -> Optional[bool]:
if "security" not in root:
return None
security = root["security"]
if not isinstance(security, dict):
raise ValueError(f'{label} field "security" must be an object')
if "folderTrust" not in security:
return None
folder_trust = security["folderTrust"]
if not isinstance(folder_trust, dict):
raise ValueError(
f'{label} field "security.folderTrust" must be an object'
)
enabled = folder_trust.get("enabled")
if enabled is not None and not isinstance(enabled, bool):
raise ValueError(
f'{label} field "security.folderTrust.enabled" must be a boolean'
)
return enabled
def parse_qwen_document(
*,
kind: str,
exists: bool,
file_path: str,
raw: str,
snapshot: Optional[FileSnapshot] = None,
) -> QwenDocument:
label = f"{qwen_source_label(kind)} at {file_path}"
root = parse_qwen_jsonc_object(raw, label)
disabled = root.get("disableAllHooks")
if "disableAllHooks" in root and not isinstance(disabled, bool):
raise ValueError(f'{label} field "disableAllHooks" must be a boolean')
has_hooks = "hooks" in root
return QwenDocument(
kind=kind,
file_path=file_path,
exists=exists,
raw=raw,
snapshot=snapshot,
root=root,
hooks=read_qwen_hooks(root["hooks"]) if has_hooks else {},
has_hooks_container=has_hooks,
disable_all_hooks=disabled if isinstance(disabled, bool) else None,
folder_trust_enabled=_folder_trust_enabled(root, label),
owned_file=kind == "user" and raw.startswith(OWNED_FILE_MARKER),
)
def create_qwen_document(kind: str, file_path: str) -> QwenDocument:
raw = f"{OWNED_FILE_MARKER}\n{{}}\n" if kind == "user" else "{}\n"
return parse_qwen_document(
kind=kind,
exists=False,
file_path=file_path,
raw=raw,
)
def _current_document(
document: QwenDocument, editor: JsoncEditor
) -> QwenDocument:
return parse_qwen_document(
kind=document.kind,
exists=document.exists,
file_path=document.file_path,
raw=editor.raw,
snapshot=document.snapshot,
)
def _remove_managed(
editor: JsoncEditor,
document: QwenDocument,
agent_id: Optional[str],
) -> None:
removals = managed_qwen_removals(document.hooks, agent_id)
for event in MANAGED_EVENTS:
event_removals = sorted(
(item for item in removals if item.event == event),
key=lambda item: item.group_index,
reverse=True,
)
for removal in event_removals:
group_path = ("hooks", event, removal.group_index)
if removal.remove_group:
editor.delete(group_path)
continue
for handler_index in sorted(removal.handler_indexes, reverse=True):
editor.delete((*group_path, "hooks", handler_index))
if event_removals:
current = _current_document(document, editor)
if event in current.hooks and not current.hooks[event]:
editor.delete(("hooks", event))
current = _current_document(document, editor)
if current.has_hooks_container and not current.hooks:
editor.delete(("hooks",))
def _append_group(
editor: JsoncEditor,
document: QwenDocument,
event: str,
group: JsonObject,
) -> None:
current = _current_document(document, editor)
if not current.has_hooks_container:
editor.add_property((), "hooks", {event: [group]})
elif event in current.hooks:
editor.append(("hooks", event), group)
else:
editor.add_property(("hooks",), event, [group])
def _already_installed(
document: QwenDocument, additions: Dict[str, JsonObject]
) -> bool:
if set(additions) != set(MANAGED_EVENTS):
return False
removals = managed_qwen_removals(document.hooks)
for event in MANAGED_EVENTS:
expected = additions[event]
event_removals = [item for item in removals if item.event == event]
exact_groups = [
group for group in document.hooks.get(event, []) if group == expected
]
if (
len(event_removals) != 1
or not event_removals[0].remove_group
or len(exact_groups) != 1
):
return False
return True
def render_qwen_document(
document: QwenDocument,
agent_id: Optional[str],
additions: Dict[str, JsonObject],
) -> RenderedQwenDocument:
if agent_id is None and _already_installed(document, additions):
return RenderedQwenDocument(document, False, document.raw)
editor = JsoncEditor(
document.raw,
f"{qwen_document_label(document)} at {document.file_path}",
allow_trailing_commas=False,
)
_remove_managed(editor, document, agent_id)
for event in MANAGED_EVENTS:
group = additions.get(event)
if group is not None:
_append_group(editor, document, event, group)
current = _current_document(document, editor)
if not additions and document.owned_file and not current.root:
return RenderedQwenDocument(document, True, None)
return RenderedQwenDocument(
document,
editor.raw != document.raw,
editor.raw,
)