unown-context
v0.1.4
Published
Unown Context is an agent-facing context provider toolkit.
Readme
Unown Context
Unown Context is an agent-facing context provider toolkit.
It retrieves bounded, structured, source-backed context from code hosting platforms, Hugging Face Hub, OpenAlex, and arXiv. The SDK does not score, classify, recommend, or analyze repositories, models, datasets, Spaces, or scholarly works. Agents use the returned documents to make their own decisions.
Current Scope
- Multi-provider routing through
UnownContext - Provider prefix source refs such as
github:vercel/next.js,gitlab:group/project,local:/path/to/repo, Hugging Face search result refs such ashuggingface:model:owner/name, OpenAlex work refs such asopenalex:work:W2741809807, and arXiv refs such asarxiv:2406.06706 - GitHub URL source refs such as
https://github.com/vercel/next.js - Public document schemas for repository overview, README,
llms.txt, agent instruction files, tree, files, activity, refs, PR files, comments, commits, context bundles, Hub metadata, and scholarly work metadata - Capability-based providers, so a provider can implement only the operations it supports
Example
import { GitHubProvider, UnownContext } from "unown-context";
const unown = new UnownContext({
providers: [new GitHubProvider({ token: process.env.GITHUB_TOKEN })]
});
const overview = await unown.getRepoOverview({
source: "github:vercel/next.js"
});Inline refs are accepted on GitHub sources:
await unown.getReadme({
source: "github:vercel/next.js#canary"
});
await unown.getReadme({
source: "https://github.com/vercel/next.js/tree/canary"
});Long-running agent calls can pass an abort signal:
const controller = new AbortController();
await unown.getFilesByPatterns({
source: "github:vercel/next.js",
patterns: ["**/package.json"],
signal: controller.signal
});GitHubProvider also supports a provider-level timeout:
const github = new GitHubProvider({
token: process.env.GITHUB_TOKEN,
timeoutMs: 10_000
});REST GET requests use in-memory ETag revalidation by default. Pass cache: false to disable it, or pass a custom cache with get, set, and optional delete.
Providers
GitHubProvider: GitHub REST and GraphQL context, including GitHub Enterprise hosts throughhosts,restBaseUrl, andgraphqlUrl.GitLabProvider: GitLab REST context forgitlab:andhttps://gitlab.com/...sources.HuggingFaceProvider: Hugging Face Hub search and README/card retrieval for models, datasets, and Spaces.LocalGitProvider: filesystem-backed context for local repositories throughlocal:/pathandfile:///pathsources.OpenAlexProvider: scholarly work search and bounded work metadata retrieval through OpenAlex.ArxivProvider: arXiv preprint search and bounded work metadata retrieval through the arXiv API.
const unown = new UnownContext({
providers: [
new GitHubProvider({
token: process.env.GITHUB_TOKEN,
hosts: ["github.company.com"],
restBaseUrl: "https://github.company.com/api/v3",
graphqlUrl: "https://github.company.com/api/graphql"
})
]
});Hugging Face Hub
HuggingFaceProvider supports Hugging Face Hub search and README/card retrieval for models, datasets, and Spaces. It returns source-backed Hub metadata and card content; it does not rank, recommend, or evaluate assets.
import { HuggingFaceProvider, UnownContext } from "unown-context";
const unown = new UnownContext({
providers: [new HuggingFaceProvider({ token: process.env.HF_TOKEN })]
});
const models = await unown.searchSources({
provider: "huggingface",
query: "model:text-generation",
first: 10
});
const datasets = await unown.searchSources({
provider: "huggingface",
query: "dataset:code",
first: 10
});
const modelCard = await unown.getReadme({
source: "huggingface:model:openai/gpt-oss-20b",
mode: "sections",
maxBytes: 64_000
});OpenAlex Works
OpenAlexProvider supports source-backed scholarly work search and single-work metadata retrieval. It returns metadata and reconstructed abstracts from OpenAlex work records; it does not download PDFs, parse full text, rank papers, or recommend related works.
import { OpenAlexProvider, UnownContext } from "unown-context";
const unown = new UnownContext({
providers: [
new OpenAlexProvider({
userAgent: "your-agent/1.0 mailto:[email protected]",
apiKey: process.env.OPENALEX_API_KEY,
retry: { retries: 2, baseDelayMs: 250, maxDelayMs: 2_000 }
})
]
});
const works = await unown.searchWorks({
provider: "openalex",
query: "retrieval augmented generation",
first: 10
});
const work = await unown.getWork({
source: "openalex:doi:10.7717/peerj.4375",
maxAbstractBytes: 8_000,
maxReferences: 50
});OpenAlex API keys are optional. Without an apiKey, the provider uses OpenAlex free polite-pool behavior and does not append an api_key query parameter; set a descriptive userAgent with contact information for polite-pool usage. When apiKey is provided, it is redacted from returned URLs and errors. OpenAlex responses preserve rate-limit headers in fetchedFrom.rateLimit when present. The provider retries 429, 502, 503, and 504 responses with conservative backoff and respects Retry-After up to the configured maxDelayMs.
arXiv Works
ArxivProvider supports source-backed arXiv preprint search and single-work metadata retrieval. It returns Atom metadata mapped into the shared work schema; it does not download PDFs, parse full text, rank papers, or recommend related works.
import { ArxivProvider, UnownContext } from "unown-context";
const unown = new UnownContext({
providers: [
new ArxivProvider({
userAgent: "your-agent/1.0",
requestSpacingMs: 3_000,
retry: { retries: 2, baseDelayMs: 1_000, maxDelayMs: 10_000 }
})
]
});
const works = await unown.searchWorks({
provider: "arxiv",
query: 'cat:q-fin.TR AND all:"reinforcement learning"',
first: 10
});
const work = await unown.getWork({
source: "arxiv:2406.06706",
maxAbstractBytes: 8_000
});The arXiv provider preserves arXiv API response order. By default it spaces requests by three seconds to follow arXiv polite usage guidance; pass requestSpacingMs only when a caller manages pacing externally.
It retries 429, 502, 503, and 504 responses with conservative backoff and respects Retry-After up to the configured maxDelayMs.
arXiv source refs support modern IDs such as 2406.06706 and legacy archive-prefixed IDs such as cond-mat/9902044v1.
searchMode and generic filter are not supported for arXiv; express precise searches directly in the arXiv query string with field prefixes such as all:, ti:, au:, and cat:.
GitHub Primitives
Agents can ask for focused primitives instead of a broad bundle:
await unown.getRefs({ source: "github:vercel/next.js", kind: "branches" });
await unown.getPullRequestFiles({
source: "github:vercel/next.js",
number: 123,
maxPatchBytes: 12_000
});
await unown.getIssueComments({ source: "github:vercel/next.js", number: 123 });
await unown.getCommit({
source: "github:vercel/next.js",
sha: "HEAD",
maxPatchBytesPerFile: 12_000
});Changelog And Release Context
Agents can retrieve source-backed changelog context without asking the SDK to summarize or classify release quality:
await unown.getChangelog({
source: "github:paperclipai/paperclip",
maxFiles: 20,
maxReleases: 10,
maxTags: 20
});The document can include changelog files, release-note files, release automation files, platform releases, and tags, depending on provider support. Returned file content is bounded and includes provenance metadata.
For release monitoring workflows, use the bundle preset:
await unown.getContextBundle({
source: "github:paperclipai/paperclip",
kind: "release-monitoring"
});Context Bundles
Bundles are fetch presets for common agent workflows. They collect source-backed documents without scoring or interpreting them.
overview: repository overview, README sections,llms.txt, recent activityonboarding: overview bundle plus tree, agent instruction files, manifests, and likely entrypointsdependency-review: tree plus manifest and lock filesdocs-review: README,llms.txt, agent docs, and markdown docsarchitecture-scan: tree plus manifests, configs, and likely entrypointsrelease-monitoring: overview, README, tree, activity where supported, and changelog context
Bundles also accept budget, includePatterns, and excludePatterns to keep agent payloads bounded and deterministic.
Live Smoke
Run a live smoke test against GitHub:
npm run live:smoke -- github:octocat/Hello-World --ref masterREST checks run without a token. GraphQL checks run when GITHUB_TOKEN is set:
GITHUB_TOKEN="$(gh auth token)" npm run live:smoke -- github:octocat/Hello-World --ref masterThe smoke command prints structured summaries and never prints token values.
GitHub Transport Behavior
GitHubProvider includes conservative retry handling for transient failures:
429502503504- network errors
GitHub rate-limit headers are exposed on document metadata:
document.fetchedFrom?.rateLimit;Non-OK GitHub responses throw GitHubProviderError, which includes status, method, URL, response body, and rate-limit metadata.
Design Boundary
SDK responsibilities:
- Fetch context
- Normalize context
- Bound payloads
- Preserve source metadata
- Route requests to the right provider
Agent responsibilities:
- Interpret context
- Compare repositories
- Rank candidates
- Decide whether to inspect more files
- Produce conclusions and recommendations
