mirror of
https://github.com/ultraworkers/claw-code.git
synced 2026-04-16 03:35:13 +08:00
The old tracked TypeScript snapshot has been removed from the repository history and the root directory is now a Python porting workspace. README and tests now describe and verify the Python-first layout instead of treating the exposed snapshot as the active source tree. A local archive can still exist outside Git, but the tracked repository now presents only the Python porting surface, related essay context, and OmX workflow artifacts. Constraint: Tracked history should collapse to a single commit while excluding the archived snapshot from Git Rejected: Keep the exposed TypeScript tree in tracked history under an archive path | user explicitly wanted only the Python porting repo state in Git Confidence: medium Scope-risk: broad Reversibility: messy Directive: Keep future tracked additions focused on the Python port itself; do not reintroduce the exposed snapshot into Git history Tested: python3 -m unittest discover -s tests -v; python3 -m src.main summary; git diff --check Not-tested: Behavioral parity with the original TypeScript system beyond the current Python workspace surface
56 lines
2.0 KiB
Python
56 lines
2.0 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
|
|
from .commands import PORTED_COMMANDS
|
|
from .tools import PORTED_TOOLS
|
|
from .models import PortingModule
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class RoutedMatch:
|
|
kind: str
|
|
name: str
|
|
source_hint: str
|
|
score: int
|
|
|
|
|
|
class PortRuntime:
|
|
def route_prompt(self, prompt: str, limit: int = 5) -> list[RoutedMatch]:
|
|
tokens = {token.lower() for token in prompt.replace('/', ' ').replace('-', ' ').split() if token}
|
|
by_kind = {
|
|
'command': self._collect_matches(tokens, PORTED_COMMANDS, 'command'),
|
|
'tool': self._collect_matches(tokens, PORTED_TOOLS, 'tool'),
|
|
}
|
|
|
|
selected: list[RoutedMatch] = []
|
|
# Prefer at least one representative from each kind when available.
|
|
for kind in ('command', 'tool'):
|
|
if by_kind[kind]:
|
|
selected.append(by_kind[kind].pop(0))
|
|
|
|
leftovers = sorted(
|
|
[match for matches in by_kind.values() for match in matches],
|
|
key=lambda item: (-item.score, item.kind, item.name),
|
|
)
|
|
selected.extend(leftovers[: max(0, limit - len(selected))])
|
|
return selected[:limit]
|
|
|
|
def _collect_matches(self, tokens: set[str], modules: tuple[PortingModule, ...], kind: str) -> list[RoutedMatch]:
|
|
matches: list[RoutedMatch] = []
|
|
for module in modules:
|
|
score = self._score(tokens, module)
|
|
if score > 0:
|
|
matches.append(RoutedMatch(kind=kind, name=module.name, source_hint=module.source_hint, score=score))
|
|
matches.sort(key=lambda item: (-item.score, item.name))
|
|
return matches
|
|
|
|
@staticmethod
|
|
def _score(tokens: set[str], module: PortingModule) -> int:
|
|
haystacks = [module.name.lower(), module.source_hint.lower(), module.responsibility.lower()]
|
|
score = 0
|
|
for token in tokens:
|
|
if any(token in haystack for haystack in haystacks):
|
|
score += 1
|
|
return score
|