fix(harness): ship coherent vendor harness cluster

Rebuild PR C to ship the vendor/photocraft harness as a coherent unit
(vendor implementation + vendor tests) instead of a per-file ahead/behind
mix that produced broken imports and 6+ test failures.

- Flip 36 harness impl/route/test files back to vendor (the per-file
  line-set policy misclassified user-rewritten files as 'behind').
- Flip core/models.py + src/tool_approval_scopes.py to vendor: vendor's
  harness (authority.py, turn_contract.py, clean_agent_preview.py) depends
  on vendor's older approval-scope API; upstream added
  CHAT_SESSION_APPROVAL_SIGNATURE_FIELD that vendor's core/models.py lacks.
- Add src/shutdown.py (new vendor infra) required by routes/chat_routes.py.
- Keep src/agent_tools/__init__.py at upstream (editor_tools registration
  lives in PR B).

Upstream-only security divergence preserved in C_upstream_delta.patch and
flagged for integration-time reconciliation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
pewdiepie-archdaemon
2026-10-13 13:59:04 +00:00
co-authored by Claude Opus 5.5
parent 364229f2dc
commit 9bdea753ae
39 changed files with 804 additions and 3076 deletions
+15 -22
View File
@@ -19,7 +19,7 @@ from pydantic import BaseModel, Field
from services.memory.skills import SkillsManager
from src.auth_helpers import get_current_user
from src.prompt_security import untrusted_context_message
from src.text_helpers import strip_closed_think_blocks
from src.model_profiles import uses_odysseus_progressive_thinking
from core.middleware import require_admin
logger = logging.getLogger(__name__)
@@ -251,7 +251,7 @@ async def _eval_skill_run(skill_md: str, task: str, transcript: str,
# Strip closed think blocks. If a <think> was opened but never closed
# (the model ran out of budget mid-reasoning), drop everything from it
# onward so its stray braces don't poison JSON extraction.
text = strip_closed_think_blocks(text)
text = _re.sub(r'<think(?:ing)?>[\s\S]*?</think(?:ing)?>', '', text, flags=_re.I)
text = _re.sub(r'<think(?:ing)?>[\s\S]*$', '', text, flags=_re.I).strip()
def _coerce(d):
@@ -348,6 +348,8 @@ async def _eval_skill_run(skill_md: str, task: str, transcript: str,
url, model, msgs,
temperature=0.1, max_tokens=32768, headers=headers, timeout=180,
workload=workload,
thinking_mode=('on' if attempt == 0 else 'off')
if uses_odysseus_progressive_thinking(model) else None,
)
except Exception as e:
# Don't give up on a transient first-attempt error — let the second
@@ -400,11 +402,12 @@ async def _eval_skill_necessity(skill_md: str, others: list, url: str, model: st
[{"role": "system", "content": sys_prompt}, {"role": "user", "content": user_msg}],
temperature=0.1, max_tokens=8192, headers=headers, timeout=120,
workload=workload,
thinking_mode='on' if uses_odysseus_progressive_thinking(model) else None,
)
except Exception as e:
logger.warning(f"Necessity check failed: {e}")
return None
text = strip_closed_think_blocks(raw or '')
text = _re.sub(r'<think(?:ing)?>[\s\S]*?</think(?:ing)?>', '', (raw or ''), flags=_re.I)
text = _re.sub(r'<think(?:ing)?>[\s\S]*$', '', text, flags=_re.I).strip()
data = None
a, b = text.find('{'), text.rfind('}')
@@ -490,11 +493,12 @@ async def _eval_skill_retrieval_precision(skill_md: str, others: list,
[{"role": "system", "content": sys_prompt}, {"role": "user", "content": user_msg}],
temperature=0.1, max_tokens=4096, headers=headers, timeout=90,
workload=workload,
thinking_mode='on' if uses_odysseus_progressive_thinking(model) else None,
)
except Exception as e:
logger.warning(f"Retrieval precision check failed: {e}")
return None
text = strip_closed_think_blocks(raw or '')
text = _re.sub(r'<think(?:ing)?>[\s\S]*?</think(?:ing)?>', '', (raw or ''), flags=_re.I)
text = _re.sub(r'<think(?:ing)?>[\s\S]*$', '', text, flags=_re.I).strip()
data = None
a, b = text.find('{'), text.rfind('}')
@@ -1185,11 +1189,12 @@ async def _improve_skill_md(skill_md: str, verdict: dict, transcript: str, url,
[{"role": "system", "content": sys_prompt},
{"role": "user", "content": user_msg}],
temperature=0.2, max_tokens=16384, headers=headers, timeout=180,
workload=workload)
workload=workload,
thinking_mode='on' if uses_odysseus_progressive_thinking(model) else None)
except Exception as e:
logger.warning(f"Audit: improve call failed: {e}")
return None
text = strip_closed_think_blocks(raw or '')
text = _re.sub(r'<think(?:ing)?>[\s\S]*?</think(?:ing)?>', '', (raw or ''), flags=_re.I)
text = _re.sub(r'<think(?:ing)?>[\s\S]*$', '', text, flags=_re.I)
text = _re.sub(r'</think(?:ing)?>', '', text, flags=_re.I).strip()
if text.startswith("```"):
@@ -2004,11 +2009,7 @@ def setup_skills_routes(skills_manager: SkillsManager) -> APIRouter:
it untouched). It never changes the skill's published/draft STATUS."""
import time as _time
import asyncio as _asyncio
from core.database import SessionLocal
from src.endpoint_resolver import (
build_chat_url, build_headers, resolve_endpoint,
resolve_endpoint_runtime, resolve_owner_registered_endpoint,
)
from src.endpoint_resolver import resolve_endpoint
user = _owner(request)
body = await request.json()
@@ -2032,18 +2033,10 @@ def setup_skills_routes(skills_manager: SkillsManager) -> APIRouter:
# session's model. Fall back to the caller's session model only if unset.
url, model, headers = resolve_endpoint("utility", owner=user)
if not url or not model:
if not url and body.get("endpoint_url") is not None:
db = SessionLocal()
try:
endpoint = resolve_owner_registered_endpoint(db, body["endpoint_url"], user)
base, api_key = resolve_endpoint_runtime(endpoint, owner=user)
url = build_chat_url(base)
headers = build_headers(api_key, base)
except ValueError as exc:
raise HTTPException(400, str(exc)) from exc
finally:
db.close()
url = url or ((body.get("endpoint_url") or "").strip() or None)
model = model or ((body.get("model") or "").strip() or None)
if headers is None and isinstance(body.get("headers"), dict):
headers = body.get("headers")
if not url or not model:
raise HTTPException(400, "No model configured — set a Default or Utility model in Settings.")