This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

at main 111 lines 3.8 kB View raw View rendered
1# Recommendation Engine — HTTP API 2 3Standalone FastAPI service for Tangled repo/issue discovery. 4 5**Storage:** `DATA_STORAGE=sql` (default, Postgres+pgvector) or `DATA_STORAGE=git` 6(in-memory numpy+jsonl bundle cloned from `REC_DATA_GIT_URL` at boot). See 7`.env.example`. 8 9Endpoints: `/recommendations`, `/questionnaire` (sql only today), `/health`. 10 11Base URL: whatever you deploy to (the Tangled appview points `TANGLED_DISCOVER_ENDPOINT` 12at the `/recommendations` path). 13 14--- 15 16## `GET /recommendations` 17 18The contract consumed by the Tangled appview. Returns the user's interest chips plus 19ranked repo + issue recommendations, with the user's own/collaborated repos and 20self-authored issues excluded. 21 22**Query params** 23 24| Param | Required | Notes | 25| --- | --- | --- | 26| `handle` | yes | The user's Tangled DID, e.g. `did:plc:abc123`. | 27| `gh` | no | Connected GitHub username. Accepted but currently ignored (no GitHub data). | 28 29**Response** `200 OK` — see [`schema.md`](../../schema.md) for the authoritative shape. Summary: 30 31```jsonc 32{ 33 "profile": { 34 "interests": [{ "label": "nix", "slug": "nix" }], // from the user's repo topics 35 "languages": [], // no language signal yet 36 "sources": { "tangled": { "repos": 10 } } // github omitted (no data) 37 }, 38 "repos": [{ 39 "name": "...", "owner": "@handle", "language": "", "description": "...", 40 "stars": 0, "openIssues": 3, "lastActive": "<RFC3339>", 41 "url": "https://tangled.org/@handle/name", 42 "basedOnRepoUrl": "https://tangled.org/@you/your-seed-repo" 43 }], 44 "issues": [{ 45 "title": "...", "repo": "handle/name", "owner": "@handle", 46 "issueUri": "at://did:plc:…/sh.tangled.repo.issue/3k…", 47 "repoDid": "did:plc:...", "rkey": "3k...", 48 "url": "https://tangled.org/@handle/name", 49 "basedOnRepoUrl": "https://tangled.org/@you/your-seed-repo", 50 "repoReadme": "...", 51 "labels": [], "comments": 0, "language": "", "lastActive": "<RFC3339>" 52 }] 53} 54``` 55 56Notes: 57- Empty user → `"repos": []` (the frontend then shows its cold-start view). 58- `stars`/`comments`/`language`/`languages` are stubbed (no source in the shared DB yet). 59- Issues omit `number` (issue permalink); the frontend resolves it from `(repoDid, rkey)`. 60 `url` is the parent repo; `basedOnRepoUrl` is the user's seed repo that surfaced the hit. 61- `basedOnRepoUrl` on repos is the same seed attribution (the user's repo whose README 62 embedding produced the closest match). 63 64--- 65 66## `GET /questionnaire` 67 68Return the cached AI-solve questionnaire JSON for an issue (written by the questionnaire 69Cloud Run job). Does not generate on demand — returns `404` if not cached yet. 70 71**Query params** 72 73| Param | Required | Notes | 74| --- | --- | --- | 75| `issue` | yes* | Full `at://…/sh.tangled.repo.issue/<rkey>` URI, or bare rkey (DB lookup). | 76| `issue-uri` | yes* | Alias for `issue`. | 77 78\* Provide one of `issue` or `issue-uri`. 79 80**Response** `200 OK` — questionnaire object (version 2: `introduction`, `items[]`, …). 81 82**Errors** 83 84| Status | When | 85| --- | --- | 86| `400` | Missing param, invalid URI, or ambiguous rkey | 87| `404` | Issue URI valid but no cached questionnaire | 88 89```bash 90curl 'localhost:8000/questionnaire?issue=at://did:plc:…/sh.tangled.repo.issue/3lv…' 91``` 92 93--- 94 95## `GET /health` 96 97```jsonc 98{ "status": "ok", "db": true } 99``` 100 101`status` is `"degraded"` with `db:false` (and an `error`) if the database is unreachable. 102 103--- 104 105## Conventions 106 107- Timestamps (`lastActive`) are RFC-3339; the frontend humanizes them. 108- `owner` carries a leading `@`; repo `url` is absolute. 109- Ordering is the engine's call — arrays are returned already ranked, most relevant first. 110- Errors: any non-200 (or timeout) makes the appview fall back to its cold-start view; no 111 structured error body is required.