Model and media
The /model subpath defines provider-neutral model requests, responses, profiles, and content contracts. Live media generation and transcription ports are published independently at /media. ModelRequest carries messages, tools, response format, sampling, and redacted metadata. ModelResponse represents either a completion or a structured error. ModelError.code distinguishes provider cancellation (cancelled) from an elapsed deadline (timeout), so callers do not retry an explicit abort as a timeout.
Content uses a closed union: text, JSON, inline binary, media reference, reasoning, tool call, and tool result. A media-ref points to a ResourceRef; an authorized resolver supplies its bytes only when execution needs them.
import { createBuiltinModel, type ModelRequest } from "@geekist/llm-core/model";
import { newCoreId, type InvocationContext, type InvocationId } from "@geekist/llm-core/contracts";
import type { ImageGenerationPort, TranscriptionPort } from "@geekist/llm-core/media";
const context: InvocationContext = {
invocationId: newCoreId<InvocationId>("0190bd0c-0000-7000-8000-000000002410"),
};
const request: ModelRequest = {
messages: [{ role: "user", content: [{ kind: "text", text: "hello" }] }],
};
const response = await createBuiltinModel().generate({ request, context });
declare const images: ImageGenerationPort;
declare const transcription: TranscriptionPort;
await images.generate({ request: { prompt: "A contour map", count: 1 }, context });
await transcription.transcribe({
request: { audio: { kind: "bytes", mediaType: "audio/wav", bytes: new Uint8Array() } },
context,
});
void response;Profiles describe verified behavior
A ModelProfile records model, provider, deployment, contract version, and evidence-backed capability claims. It is portable data, not a provider client. Registering a profile validates, clones, and freezes it.
Resolve a model binding
ModelRef expresses logical selection intent. ProviderRef identifies a service dialect, while DeploymentRef identifies one configured endpoint. None carries a credential or executable client.
import type { CapabilityRequirement } from "@geekist/llm-core/contracts";
import { createModelResolver, modelRef, type ModelBinding } from "@geekist/llm-core/model/runtime";
declare const bindings: readonly ModelBinding[];
declare const requiredCapabilities: readonly CapabilityRequirement[];
const resolver = createModelResolver({
constraintEvaluator: () => true,
policyEvaluator: ({ binding }) => binding.provider !== "provider.blocked",
});
const outcome = resolver.resolve({
selection: modelRef("model.reasoning"),
bindings,
requiredCapabilities,
policy: {
defaultModel: modelRef("model.standard"),
},
});
if (outcome.kind === "unresolved") {
throw new Error(JSON.stringify(outcome.diagnostics));
}
console.log(outcome.resolution.matchedBy, outcome.resolution.binding.bindingId);createModelResolver evaluates bindings deterministically:
- an exact
ModelRefmatch wins before aliases; - without an explicit selection, a named
policy.defaultModelis required; - policy allow-lists and required evidence-backed capabilities filter matches;
- constraints require a trusted evaluator and fail closed on throws or non-boolean results;
- zero eligible bindings and multiple eligible bindings return unresolved outcomes with diagnostics.
The resolver never selects the first candidate, reads credentials, silently downgrades a requirement, or turns a provider/deployment identity into model selection intent.
The built-in model is deterministic and useful for local composition and tests. Provider integrations remain qualified adapter imports, for example:
import { createAiSdk7Model } from "@geekist/llm-core/adapters/ai-sdk";The adapter receives live provider dependencies during composition. Provider metadata crosses the boundary only after a trusted redactor projects safe JSON into a namespaced extension.
Preserve resolved identity for usage evidence
createResolvedModelIdentity snapshots the exact model, provider, deployment, profile ID, and profile version selected for an invocation. When a live Model is already available, resolvedModelIdentityFromProfile(model.profile) derives the same identity without copying profile claims, extensions, or a provider client.
Pass that identity to the evidence capability when recording observed usage. This binds a usage receipt to what was actually resolved while keeping model selection, credentials, and pricing outside the receipt.
Media ports
ImageGenerationPort, SpeechGenerationPort, and TranscriptionPort accept live bytes or authorized resource references and return portable media. A MediaOutputProjector decides whether output is safe to inline or should become a resource reference.
Schema identity and resource identity stay separate from the live resolvers that interpret schemas or load bytes.