mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-15 03:12:21 +02:00
Skills tagged remote-only in frontmatter are excluded from the injected skill index when the active model's endpoint is local (loopback/private/ tailscale per is_local_endpoint). Big on-demand reference lookups overwhelm small local contexts; local models never see the skill, while remote models and API/UI listings are unaffected. - SkillsManager.index_for gains optional keyword-only local_model flag (None = don't gate, same contract as active_toolsets=None) - _build_system_prompt/_build_base_prompt thread endpoint_url from _build_route_request_state; unknown endpoint fails open - tests: cover hidden-on-local, visible-on-remote/unknown, untagged skills never gated Refs: discussed for the local-model overwhelm problem Co-authored-by: Alexandre Teixeira <111787685+alteixeira20@users.noreply.github.com>
99 lines
3.5 KiB
Python
99 lines
3.5 KiB
Python
"""index_for() local-model gating: a `remote-only` tag must hide a skill
|
|
from local/private-endpoint models while staying visible to remote API
|
|
models and to callers that don't know the endpoint at all.
|
|
|
|
Big on-demand reference lookups overwhelm small local contexts, so the
|
|
skill must vanish from the injected index there. local_model=None (API
|
|
listings, chat preface) means "don't gate" — same contract as
|
|
active_toolsets=None.
|
|
"""
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
from unittest.mock import MagicMock
|
|
|
|
# ── module-load stubbing (matches other tests in this repo) ──────────
|
|
for _mod in ("sqlalchemy", "sqlalchemy.orm", "sqlalchemy.ext", "sqlalchemy.ext.declarative"):
|
|
if _mod not in sys.modules:
|
|
try:
|
|
__import__(_mod)
|
|
except ImportError:
|
|
sys.modules[_mod] = MagicMock()
|
|
|
|
from services.memory.skills import SkillsManager # noqa: E402
|
|
|
|
|
|
def _write_skill_md(skills_root: Path, name: str, *, tags: str = "[]",
|
|
owner: str = "admin") -> None:
|
|
skill_dir = skills_root / "general" / name
|
|
skill_dir.mkdir(parents=True, exist_ok=True)
|
|
fm = "\n".join([
|
|
"---",
|
|
f"name: {name}",
|
|
"description: test skill",
|
|
"version: 1.0.0",
|
|
"category: general",
|
|
f"tags: [{tags}]",
|
|
"status: published",
|
|
"confidence: 0.9",
|
|
"audit_verdict: pass",
|
|
"source: learned",
|
|
f"owner: {owner}",
|
|
"created: 2026-01-01T00:00:00Z",
|
|
"---",
|
|
"",
|
|
"## When to Use",
|
|
"- test",
|
|
"",
|
|
"## Procedure",
|
|
"1. step 1",
|
|
"",
|
|
])
|
|
(skill_dir / "SKILL.md").write_text(fm, encoding="utf-8")
|
|
|
|
|
|
def _names(idx):
|
|
return {s["name"] for s in idx}
|
|
|
|
|
|
def test_remote_only_hidden_from_local_model(tmp_path):
|
|
(tmp_path / "skills").mkdir()
|
|
_write_skill_md(tmp_path / "skills", "agents-map", tags="reference, remote-only")
|
|
sm = SkillsManager(str(tmp_path))
|
|
sm.set_audit("agents-map", "pass", owner="admin")
|
|
|
|
assert "agents-map" not in _names(
|
|
sm.index_for(owner="admin", local_model=True))
|
|
|
|
|
|
def test_remote_only_visible_to_remote_model_and_unknown_endpoint(tmp_path):
|
|
(tmp_path / "skills").mkdir()
|
|
_write_skill_md(tmp_path / "skills", "agents-map", tags="reference, remote-only")
|
|
sm = SkillsManager(str(tmp_path))
|
|
sm.set_audit("agents-map", "pass", owner="admin")
|
|
|
|
assert "agents-map" in _names(sm.index_for(owner="admin", local_model=False))
|
|
# Unknown endpoint (background callers without a URL) fails open.
|
|
assert "agents-map" in _names(sm.index_for(owner="admin", local_model=None))
|
|
assert "agents-map" in _names(sm.index_for(owner="admin"))
|
|
|
|
|
|
def test_untagged_skills_are_never_gated(tmp_path):
|
|
(tmp_path / "skills").mkdir()
|
|
_write_skill_md(tmp_path / "skills", "plain-skill", tags="reference")
|
|
sm = SkillsManager(str(tmp_path))
|
|
sm.set_audit("plain-skill", "pass", owner="admin")
|
|
|
|
assert "plain-skill" in _names(sm.index_for(owner="admin", local_model=True))
|
|
assert "plain-skill" in _names(sm.index_for(owner="admin", local_model=False))
|
|
|
|
|
|
def test_tag_in_ui_listings_is_not_gated(tmp_path):
|
|
(tmp_path / "skills").mkdir()
|
|
_write_skill_md(tmp_path / "skills", "agents-map", tags="reference, remote-only")
|
|
sm = SkillsManager(str(tmp_path))
|
|
sm.set_audit("agents-map", "pass", owner="admin")
|
|
|
|
# API listings / UI pass no local_model → must still see the skill.
|
|
assert "agents-map" in _names(sm.index_for(owner="admin", local_model=None))
|