AI adapter interface
Provider boundaries for optional model calls
Org2's core parsing, formatting, linting, publishing, corpus compilation, query, and manifest validation work without an LLM provider. AI workflows that need model output call a small adapter boundary, keeping vendor SDKs out of the rest of Org2.
The TypeScript contract lives in src/aiAdapter.ts. It defines:
AiProviderAdapter: the interface implemented by local or hosted model adaptersAiAdapterRequest: structured prompt, task, context, output, and provenance requirementsAiAdapterResponse: text/JSON output, citations, and model metadataMockAiAdapter: deterministic test adapter for job orchestration tests
Request contract
An adapter request packages context already selected and prepared by Org2:
{
schema: "org2:ai-adapter-request:v1",
jobId: "weekly-summary",
task: {
type: "summarize-meeting",
template: "weekly-summary@v1",
instructions: "Summarize decisions with citations."
},
prompt: [
{ role: "system", content: "Use only the supplied Org2 context." },
{ role: "user", content: "Create a weekly summary." }
],
context: [
{
id: "meeting-1",
type: "org-headline",
title: "Team Sync",
text: "Decision: ship the adapter interface first.",
sourceRefs: [{ file: "notes/team.org", id: "abc", line: 12, endLine: 16 }]
}
],
output: { contentType: "text+json", schemaHint: "weekly-summary@v1" },
provenance: { requireSourceRefs: true, promptTemplateVersion: "weekly-summary@v1" }
}
The adapter receives already-curated context. It should not crawl notes, mutate canonical files, or decide review policy.
Response contract
Adapters return text and/or structured JSON plus metadata:
{
schema: "org2:ai-adapter-response:v1",
text: "Decisions: ...",
json: { decisions: [] },
citations: [{ source: { file: "notes/team.org", line: 12, endLine: 16 } }],
metadata: {
adapterName: "work-summary",
model: "summary-profile",
provider: "local-or-hosted-provider",
invocationId: "optional-provider-run-id",
usage: { inputTokens: 1200, outputTokens: 300 }
}
}
Job orchestration can write this metadata into generated artifacts without knowing which provider produced it.
Adapter responsibilities
Adapters should:
accept
AiAdapterRequestand returnAiAdapterResponsekeep provider credentials in local config/environment, never in notes, manifests, or generated artifacts
report provider/model metadata needed for provenance
support deterministic mock behavior in tests
avoid changing non-AI Org2 command behavior
Adapters should not:
modify canonical notes directly
embed secrets in response metadata
require provider configuration for parser/compiler/lint/publish/query commands
bypass manifest review/provenance policies
Mock adapter
MockAiAdapter gives future job orchestration deterministic tests before real providers exist:
import { MockAiAdapter, createAiAdapterRequest } from "./dist/aiAdapter.js";
const adapter = new MockAiAdapter({ name: "local-test", model: "deterministic-v1" });
const response = await adapter.generate(createAiAdapterRequest({
task: { type: "summarize-meeting" },
prompt: [{ role: "user", content: "Summarize." }],
context: [{ id: "a", type: "text", text: "Decision: ship it." }],
output: { contentType: "text+json" }
}));
The default mock response records calls, echoes task/context counts, and emits citations from supplied context source refs. A custom responder can simulate structured model output, failures, or provider metadata without changing orchestration code.