Documentation Index
Fetch the complete documentation index at: https://docs.agentmark.co/llms.txt
Use this file to discover all available pages before exploring further.
AgentMark uses adapters to convert its normalized prompt configuration (PromptShape) into model-specific input formats.
This guide walks you through how to build a custom adapter, using the AI SDK adapter as a reference implementation.
What is an adapter?
An adapter implements methods to transform AgentMark prompt types (text, object, image, speech) into provider-specific input formats (OpenAI chat completions, Claude messages, etc.).
It takes the raw prompt configuration (TextConfig, ObjectConfig, ImageConfig, SpeechConfig) and combines it with:
- Model configuration (name, temperature, max tokens, etc.)
- Tool definitions (functions to be called during inference)
- Optional telemetry or metadata
Requirements
To create an adapter, implement the Adapter interface from @agentmark-ai/prompt-core:
export interface Adapter<D extends PromptShape<D>> {
readonly __dict: D;
readonly __name: string;
adaptText<_K extends KeysWithKind<D, "text"> & string>(
input: TextConfig,
options: AdaptOptions,
metadata: PromptMetadata
): any;
adaptObject<_K extends KeysWithKind<D, "object"> & string>(
input: ObjectConfig,
options: AdaptOptions,
metadata: PromptMetadata
): any;
adaptImage<_K extends KeysWithKind<D, "image"> & string>(
input: ImageConfig,
options: AdaptOptions
): any;
adaptSpeech<_K extends KeysWithKind<D, "speech"> & string>(
input: SpeechConfig,
options: AdaptOptions
): any;
// Optional — adapters that support dev mode provide this.
getDevServerFactory?(): (options: { port: number; client: any }) => Promise<any>;
}
Note the asymmetry: adaptText and adaptObject receive a third metadata: PromptMetadata argument; adaptImage and adaptSpeech do not.
Minimal adapter skeleton
import {
Adapter,
AdaptOptions,
ImageConfig,
KeysWithKind,
ObjectConfig,
PromptMetadata,
PromptShape,
SpeechConfig,
TextConfig,
} from "@agentmark-ai/prompt-core";
export class MyCustomAdapter<T extends PromptShape<T>> implements Adapter<T> {
declare readonly __dict: T;
readonly __name = "my-custom-adapter";
adaptText<_K extends KeysWithKind<T, "text"> & string>(
input: TextConfig,
options: AdaptOptions,
metadata: PromptMetadata
) {
// Transform AgentMark config into your provider's request shape.
return { /* ... */ };
}
adaptObject<_K extends KeysWithKind<T, "object"> & string>(
input: ObjectConfig,
options: AdaptOptions,
metadata: PromptMetadata
) {
return { /* ... */ };
}
adaptImage<_K extends KeysWithKind<T, "image"> & string>(
input: ImageConfig,
options: AdaptOptions
) {
return { /* ... */ };
}
adaptSpeech<_K extends KeysWithKind<T, "speech"> & string>(
input: SpeechConfig,
options: AdaptOptions
) {
return { /* ... */ };
}
}
Each method must transform the AgentMark prompt config into the correct shape for your target provider.
Creating a custom client
You can wrap AgentMark directly, or expose a factory that wires up your adapter:
import { AgentMark, Loader, PromptShape } from "@agentmark-ai/prompt-core";
import { MyCustomAdapter } from "./my-custom-adapter";
export function createCustomAgentMarkClient<D extends PromptShape<D>>(opts: {
loader?: Loader<D>;
}) {
return new AgentMark<D, MyCustomAdapter<D>>({
loader: opts.loader,
adapter: new MyCustomAdapter<D>(),
});
}
PromptShape<D> describes the shape of your prompts (generated by npx agentmark build as agentmark.types.ts). KeysWithKind<D, "object"> extracts the keys whose prompt kind is object. See Type safety for details.
Model registry
A model registry lets you register AI model constructors and look them up by name during adaptText / adaptObject / etc. It’s useful for swapping providers or configuring per-model parameters.
class CustomModelRegistry {
private models: Record<string, (name: string) => unknown> = {};
register(modelName: string, creator: (name: string) => unknown) {
this.models[modelName] = creator;
}
getModelFunction(name: string): (name: string) => unknown {
const fn = this.models[name];
if (!fn) throw new Error(`Model not registered: ${name}`);
return fn;
}
}
Your adapter’s constructor can accept this registry and look up model instances when processing prompts. See the AI SDK adapter source for a reference implementation.
Tools
Adapters accept native SDK tool objects as a Record<string, Tool> passed to createAgentMarkClient. Your adapter should implement a resolveTools() helper that takes the tool name strings from prompt frontmatter and looks them up in the provided tools record.
import { createCustomAgentMarkClient } from "./my-custom-adapter";
import { mySearchTool, myCalculatorTool } from "./tools";
const client = createCustomAgentMarkClient({
loader,
// If your adapter supports tools, accept them here and thread to the adapter.
});
AgentMark prompt files reference tools by name:
---
tools:
- search
- calculator
---
The adapter’s resolveTools() maps each name to its implementation before dispatching the LLM call. See the AI SDK adapter source for a reference implementation.
Have Questions?
We’re here to help! Choose the best way to reach us: