fix(context): use repo-scoping /scope/context endpoint
Cherry-picked from stale branch codex/wp-0012-scope-context (9709692).
main was still calling the old /repos/{slug}/scope path; repo-scoping now
serves GET /repos/{slug}/scope/context (web_api/app.py:1449). Includes the
resolver test and consistent workplan-doc updates. Test: 2 passed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
2f4ef5809b
commit
e4d6222d22
4 changed files with 70 additions and 4 deletions
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
Registered as source type 'repo-scoping'.
|
Registered as source type 'repo-scoping'.
|
||||||
Supported queries:
|
Supported queries:
|
||||||
- repo_profile: GET {REPO_SCOPING_URL}/repos/{repo_slug}/scope
|
- repo_profile: GET {REPO_SCOPING_URL}/repos/{repo_slug}/scope/context
|
||||||
|
|
||||||
5-minute in-process cache keyed by (query, repo_slug). Cache is per-worker-
|
5-minute in-process cache keyed by (query, repo_slug). Cache is per-worker-
|
||||||
process; not shared across Temporal workers.
|
process; not shared across Temporal workers.
|
||||||
|
|
@ -36,7 +36,7 @@ class RepoScopingContextResolver(ContextResolver):
|
||||||
ts, val = _CACHE[cache_key]
|
ts, val = _CACHE[cache_key]
|
||||||
if now - ts < _CACHE_TTL:
|
if now - ts < _CACHE_TTL:
|
||||||
return val
|
return val
|
||||||
url = f"{_REPO_SCOPING_URL.rstrip('/')}/repos/{repo_slug}/scope"
|
url = f"{_REPO_SCOPING_URL.rstrip('/')}/repos/{repo_slug}/scope/context"
|
||||||
resp = httpx.get(url, timeout=10.0)
|
resp = httpx.get(url, timeout=10.0)
|
||||||
resp.raise_for_status()
|
resp.raise_for_status()
|
||||||
result: dict[str, Any] = resp.json()
|
result: dict[str, Any] = resp.json()
|
||||||
|
|
|
||||||
66
tests/test_repo_scoping_context_resolver.py
Normal file
66
tests/test_repo_scoping_context_resolver.py
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
from activity_core.context_resolvers import repo_scoping
|
||||||
|
|
||||||
|
|
||||||
|
class Response:
|
||||||
|
def __init__(self, body):
|
||||||
|
self.body = body
|
||||||
|
|
||||||
|
def raise_for_status(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
def json(self):
|
||||||
|
return self.body
|
||||||
|
|
||||||
|
|
||||||
|
def test_repo_scoping_context_resolver_calls_scope_context_endpoint(monkeypatch):
|
||||||
|
calls = []
|
||||||
|
body = {
|
||||||
|
"repo_slug": "repo-scoping",
|
||||||
|
"capabilities": ["Generate SCOPE.md"],
|
||||||
|
"tags": ["api", "scope"],
|
||||||
|
"scope_md_exists": True,
|
||||||
|
"scope_summary": "Maps repositories into reviewable context.",
|
||||||
|
}
|
||||||
|
|
||||||
|
def fake_get(url, timeout):
|
||||||
|
calls.append((url, timeout))
|
||||||
|
return Response(body)
|
||||||
|
|
||||||
|
repo_scoping._CACHE.clear()
|
||||||
|
monkeypatch.setattr(repo_scoping, "_REPO_SCOPING_URL", "http://repo-scoping.local/")
|
||||||
|
monkeypatch.setattr(repo_scoping.httpx, "get", fake_get)
|
||||||
|
|
||||||
|
resolver = repo_scoping.RepoScopingContextResolver()
|
||||||
|
result = resolver.resolve(
|
||||||
|
"repo_profile",
|
||||||
|
None,
|
||||||
|
{"repo_slug": "repo-scoping"},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result == body
|
||||||
|
assert calls == [
|
||||||
|
(
|
||||||
|
"http://repo-scoping.local/repos/repo-scoping/scope/context",
|
||||||
|
10.0,
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
cached = resolver.resolve(
|
||||||
|
"repo_profile",
|
||||||
|
None,
|
||||||
|
{"repo_slug": "repo-scoping"},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert cached == body
|
||||||
|
assert len(calls) == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_repo_scoping_context_resolver_ignores_unknown_queries(monkeypatch):
|
||||||
|
repo_scoping._CACHE.clear()
|
||||||
|
monkeypatch.setattr(
|
||||||
|
repo_scoping.httpx,
|
||||||
|
"get",
|
||||||
|
lambda *args, **kwargs: (_ for _ in ()).throw(AssertionError("unexpected HTTP")),
|
||||||
|
)
|
||||||
|
|
||||||
|
assert repo_scoping.RepoScopingContextResolver().resolve("unknown", None, {}) == {}
|
||||||
|
|
@ -604,7 +604,7 @@ to `context[source.bind_to]`. A resolver that raises logs a warning and binds
|
||||||
Registered as source type `repo-scoping`.
|
Registered as source type `repo-scoping`.
|
||||||
|
|
||||||
Supported queries:
|
Supported queries:
|
||||||
- `repo_profile`: `GET {REPO_SCOPING_URL}/repos/{params['repo_slug']}/scope`
|
- `repo_profile`: `GET {REPO_SCOPING_URL}/repos/{params['repo_slug']}/scope/context`
|
||||||
Returns dict with `capabilities`, `tags`, `scope_summary`, `scope_md_exists`.
|
Returns dict with `capabilities`, `tags`, `scope_summary`, `scope_md_exists`.
|
||||||
|
|
||||||
5-minute in-process cache keyed by `(query, repo_slug)`. Cache is per-worker-
|
5-minute in-process cache keyed by `(query, repo_slug)`. Cache is per-worker-
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ to `context[source.bind_to]`. A resolver that raises logs a warning and binds
|
||||||
Registered as source type `repo-scoping`.
|
Registered as source type `repo-scoping`.
|
||||||
|
|
||||||
Supported queries:
|
Supported queries:
|
||||||
- `repo_profile`: `GET {REPO_SCOPING_URL}/repos/{params['repo_slug']}/scope`
|
- `repo_profile`: `GET {REPO_SCOPING_URL}/repos/{params['repo_slug']}/scope/context`
|
||||||
Returns dict with `capabilities`, `tags`, `scope_summary`, `scope_md_exists`.
|
Returns dict with `capabilities`, `tags`, `scope_summary`, `scope_md_exists`.
|
||||||
|
|
||||||
5-minute in-process cache keyed by `(query, repo_slug)`. Cache is per-worker-
|
5-minute in-process cache keyed by `(query, repo_slug)`. Cache is per-worker-
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue