feat(robomp): added local issue indexing and commit-search tool support

- Added `ROBOMP_ISSUE_INDEX_SYNC_SECONDS` configuration and lifecycle-managed issue indexing through startup/shutdown hooks.
- Added issue/PR index tables with FTS5 triggers plus upsert and keyword/filter search helpers for indexed records.
- Added GitHub backend/proxy support for `IssueIndexEntry` and issue-index page retrieval, including webhook ingestion and periodic watermark-driven sync.
- Updated `gh_search_issues` to prefer local index queries when synchronized and added `search_commits` host tool with query modes and validation.
This commit is contained in:
can1357
2026-07-15 00:46:08 +02:00
parent 8e2aa9ea94
commit e426186e46
16 changed files with 1129 additions and 29 deletions
+36
View File
@@ -958,6 +958,42 @@ def test_webhook_incoming_pr_comment_without_directive_skips_without_counting_bu
assert states == ["queued", "queued", "skipped"]
def test_webhook_delivery_populates_issue_index(settings: Settings) -> None:
"""Every issue-carrying delivery upserts the local search index — including
ones the router skips (here: a conversation comment on an incoming PR)."""
app = create_app(settings)
with TestClient(app) as client:
payload = {
"action": "opened",
"issue": {
"number": 501,
"title": "grep misses colon filenames",
"body": "read tool peels the selector suffix",
"state": "open",
"user": {"login": "alice"},
"author_association": "NONE",
},
"repository": {"full_name": "octo/widget"},
}
body = json.dumps(payload).encode()
resp = client.post(
"/webhook/github",
content=body,
headers=_signed_headers("test-webhook-secret", body, event="issues", delivery="idx-1"),
)
assert resp.status_code == 202
skipped = _post_pr_issue_comment(client, delivery="idx-2", user="stranger", pr_number=502)
assert skipped.json()["state"] == "skipped"
db = get_database(settings.sqlite_path)
by_body = db.search_issue_index("octo/widget", keywords=("selector", "suffix"))
pr_row = db.search_issue_index("octo/widget", is_pr=True)
close_database()
assert [e.number for e in by_body] == [501]
assert [e.number for e in pr_row] == [502]
def test_webhook_contributor_gets_higher_cap(rate_limited_settings: Settings) -> None:
app = create_app(rate_limited_settings)
with TestClient(app) as client: