This repository has no description
0

Configure Feed

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

Recommendation Engine — HTTP API#

Standalone FastAPI service for Tangled repo/issue discovery.

Storage: DATA_STORAGE=sql (default, Postgres+pgvector) or DATA_STORAGE=git (in-memory numpy+jsonl bundle cloned from REC_DATA_GIT_URL at boot). See .env.example.

Endpoints: /recommendations, /questionnaire (sql only today), /health.

Base URL: whatever you deploy to (the Tangled appview points TANGLED_DISCOVER_ENDPOINT at the /recommendations path).


GET /recommendations#

The contract consumed by the Tangled appview. Returns the user's interest chips plus ranked repo + issue recommendations, with the user's own/collaborated repos and self-authored issues excluded.

Query params

Param Required Notes
handle yes The user's Tangled DID, e.g. did:plc:abc123.
gh no Connected GitHub username. Accepted but currently ignored (no GitHub data).

Response 200 OK — see schema.md for the authoritative shape. Summary:

{
  "profile": {
    "interests": [{ "label": "nix", "slug": "nix" }],   // from the user's repo topics
    "languages": [],                                     // no language signal yet
    "sources": { "tangled": { "repos": 10 } }            // github omitted (no data)
  },
  "repos": [{
    "name": "...", "owner": "@handle", "language": "", "description": "...",
    "stars": 0, "openIssues": 3, "lastActive": "<RFC3339>",
    "url": "https://tangled.org/@handle/name",
    "basedOnRepoUrl": "https://tangled.org/@you/your-seed-repo"
  }],
  "issues": [{
    "title": "...", "repo": "handle/name", "owner": "@handle",
    "issueUri": "at://did:plc:…/sh.tangled.repo.issue/3k…",
    "repoDid": "did:plc:...", "rkey": "3k...",
    "url": "https://tangled.org/@handle/name",
    "basedOnRepoUrl": "https://tangled.org/@you/your-seed-repo",
    "repoReadme": "...",
    "labels": [], "comments": 0, "language": "", "lastActive": "<RFC3339>"
  }]
}

Notes:

  • Empty user → "repos": [] (the frontend then shows its cold-start view).
  • stars/comments/language/languages are stubbed (no source in the shared DB yet).
  • Issues omit number (issue permalink); the frontend resolves it from (repoDid, rkey). url is the parent repo; basedOnRepoUrl is the user's seed repo that surfaced the hit.
  • basedOnRepoUrl on repos is the same seed attribution (the user's repo whose README embedding produced the closest match).

GET /questionnaire#

Return the cached AI-solve questionnaire JSON for an issue (written by the questionnaire Cloud Run job). Does not generate on demand — returns 404 if not cached yet.

Query params

Param Required Notes
issue yes* Full at://…/sh.tangled.repo.issue/<rkey> URI, or bare rkey (DB lookup).
issue-uri yes* Alias for issue.

* Provide one of issue or issue-uri.

Response 200 OK — questionnaire object (version 2: introduction, items[], …).

Errors

Status When
400 Missing param, invalid URI, or ambiguous rkey
404 Issue URI valid but no cached questionnaire
curl 'localhost:8000/questionnaire?issue=at://did:plc:…/sh.tangled.repo.issue/3lv…'

GET /health#

{ "status": "ok", "db": true }

status is "degraded" with db:false (and an error) if the database is unreachable.


Conventions#

  • Timestamps (lastActive) are RFC-3339; the frontend humanizes them.
  • owner carries a leading @; repo url is absolute.
  • Ordering is the engine's call — arrays are returned already ranked, most relevant first.
  • Errors: any non-200 (or timeout) makes the appview fall back to its cold-start view; no structured error body is required.