@agent-dashboard/protocol
v0.1.4
Published
The Generic Agent Protocol — a runtime-agnostic TypeScript contract that any agent runtime can implement to plug into the Agent Dashboard.
Readme
@agent-dashboard/protocol
The Generic Agent Protocol — a runtime-agnostic TypeScript contract that any agent runtime can implement to plug into the Agent Dashboard.
This package has zero runtime dependencies. Adapters import the type contract, implement it, and emit a closed set of events; the orchestrator does the rest.
What's in here
AgentAdapter— the interface every runtime adapter implements.TaskContext,TaskHandle— request/response shapes forstartTask.AgentEventType,AgentEventPayloadMap— typed event taxonomy with payload shapes per event. See events.md.validateAdapter,validateEventPayload— pure runtime guards used by the orchestrator's dynamic loader and the event ingest path.PROTOCOL_VERSION— semver string. Bump policy is documented insrc/version.ts.
Implementing an adapter
Below is a minimal "echo" adapter that emits a started event, a single tool call, and then a completed event. It demonstrates the full lifecycle.
import type {
AgentAdapter,
AgentEventPayloadMap,
AgentEventType,
TaskContext,
TaskHandle,
} from '@agent-dashboard/protocol';
type Listeners = {
[E in AgentEventType]?: Set<(p: AgentEventPayloadMap[E]) => void>;
};
export const echoAdapter = (): AgentAdapter => {
const listeners: Listeners = {};
const emit = <E extends AgentEventType>(event: E, payload: AgentEventPayloadMap[E]): void => {
listeners[event]?.forEach((fn) => fn(payload));
};
return {
runtime: 'echo',
startTask: async (ctx: TaskContext): Promise<TaskHandle> => {
const handle: TaskHandle = {
agentId: ctx.agentId,
runtime: 'echo',
pid: null,
startedAt: new Date().toISOString(),
};
const base = { timestamp: handle.startedAt, agentId: ctx.agentId, storyId: ctx.storyId };
emit('agent.started', { ...base, runtime: 'echo', pid: null });
emit('agent.tool_called', { ...base, tool: 'Echo', arg: ctx.story.title });
emit('agent.completed', { ...base, exitCode: 0, summary: 'echoed' });
return handle;
},
kill: async () => undefined,
on: (event, listener) => {
const set = (listeners[event] ??= new Set()) as Set<typeof listener>;
set.add(listener);
return () => set.delete(listener);
},
dispose: async () => undefined,
};
};Soft-pause (optional)
AgentAdapter exposes an optional pause(handle) method (Story 7.1). It's
a best-effort soft signal — the agent should land at its next safe
checkpoint without losing in-flight work. Adapters that don't have a
runtime pause primitive may omit this method entirely or implement it as a
no-op; the orchestrator won't hang waiting on it.
pause is not a hard kill. The CLI's agent-dashboard kill command
(separate story) is the destructive path.
Architecture references
- AD-11 (Generic Agent Protocol) — this contract.
- AD-12 (Adapter loader) — orchestrator dynamically imports adapters and calls
validateAdapter()before use. - AD-20 (Single-writer) — adapters never write state files; they emit events. The orchestrator (Story 4.3) is the lone state writer.
For payload-by-payload details, see events.md.
