- Add Usage type to protocol (turns, inputTokens, outputTokens, duration) - Add usage to StepRecord, StepNodePayload, StepEntry, STEP_NODE_SCHEMA - Thread usage through util-agent extract pipeline (writeStepNode → persistStep → createAgent) - All adapters return usage: null as placeholder (mock, hermes, claude-code, builtin) - 746 tests pass, no breaking changes (usage not in schema required array) Fixes #74 Refs #68
This commit is contained in:
@@ -132,6 +132,7 @@ async function buildHistory(
|
||||
completedAtMs: step.completedAtMs,
|
||||
cwd: step.cwd ?? "",
|
||||
assembledPrompt: step.assembledPrompt ?? null,
|
||||
usage: step.usage ?? null,
|
||||
content,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getSchema, validate } from "@ocas/core";
|
||||
import type { CasRef, StepNodePayload, ThreadId } from "@united-workforce/protocol";
|
||||
import type { CasRef, StepNodePayload, ThreadId, Usage } from "@united-workforce/protocol";
|
||||
import { config as loadDotenv } from "dotenv";
|
||||
import { buildOutputFormatInstruction } from "./build-output-format-instruction.js";
|
||||
import { buildContextWithMeta } from "./context.js";
|
||||
@@ -65,6 +65,7 @@ async function writeStepNode(options: {
|
||||
startedAtMs: number;
|
||||
completedAtMs: number;
|
||||
assembledPromptHash: CasRef | null;
|
||||
usage: Usage | null;
|
||||
}): Promise<CasRef> {
|
||||
const payload: StepNodePayload = {
|
||||
start: options.startHash,
|
||||
@@ -78,6 +79,7 @@ async function writeStepNode(options: {
|
||||
completedAtMs: options.completedAtMs,
|
||||
cwd: process.cwd(),
|
||||
assembledPrompt: options.assembledPromptHash,
|
||||
usage: options.usage,
|
||||
};
|
||||
const hash = await options.store.cas.put(options.schemas.stepNode, payload);
|
||||
const node = options.store.cas.get(hash);
|
||||
@@ -117,6 +119,7 @@ async function persistStep(options: {
|
||||
startedAtMs: number;
|
||||
completedAtMs: number;
|
||||
assembledPromptHash: CasRef | null;
|
||||
usage: Usage | null;
|
||||
}): Promise<CasRef> {
|
||||
const { store, schemas, chain, headHash } = options.ctx.meta;
|
||||
return writeStepNode({
|
||||
@@ -132,6 +135,7 @@ async function persistStep(options: {
|
||||
startedAtMs: options.startedAtMs,
|
||||
completedAtMs: options.completedAtMs,
|
||||
assembledPromptHash: options.assembledPromptHash,
|
||||
usage: options.usage,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -200,6 +204,7 @@ export function createAgent(options: AgentOptions): () => Promise<void> {
|
||||
);
|
||||
}
|
||||
const completedAtMs = Date.now();
|
||||
const usage = agentResult.usage;
|
||||
|
||||
// Store the assembled prompt in CAS for later inspection via `step read --prompt`
|
||||
const promptText = agentResult.assembledPrompt;
|
||||
@@ -220,6 +225,7 @@ export function createAgent(options: AgentOptions): () => Promise<void> {
|
||||
startedAtMs,
|
||||
completedAtMs,
|
||||
assembledPromptHash,
|
||||
usage,
|
||||
});
|
||||
|
||||
const adapterOutput: AdapterOutput = {
|
||||
@@ -230,6 +236,7 @@ export function createAgent(options: AgentOptions): () => Promise<void> {
|
||||
body: extracted.body,
|
||||
startedAtMs,
|
||||
completedAtMs,
|
||||
usage,
|
||||
};
|
||||
process.stdout.write(`${JSON.stringify(adapterOutput)}\n`);
|
||||
};
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import type { Store } from "@ocas/core";
|
||||
import type { ModeratorContext, ThreadId, WorkflowPayload } from "@united-workforce/protocol";
|
||||
import type {
|
||||
ModeratorContext,
|
||||
ThreadId,
|
||||
Usage,
|
||||
WorkflowPayload,
|
||||
} from "@united-workforce/protocol";
|
||||
|
||||
export type AgentContext = ModeratorContext & {
|
||||
threadId: ThreadId;
|
||||
@@ -33,6 +38,8 @@ export type AgentRunResult = {
|
||||
sessionId: string;
|
||||
/** The fully assembled prompt that was sent to the agent. */
|
||||
assembledPrompt: string;
|
||||
/** Token usage statistics for this run. null when the adapter does not report usage. */
|
||||
usage: Usage | null;
|
||||
};
|
||||
|
||||
export type AgentContinueFn = (
|
||||
@@ -51,6 +58,7 @@ export type AdapterOutput = {
|
||||
body: string;
|
||||
startedAtMs: number;
|
||||
completedAtMs: number;
|
||||
usage: Usage | null;
|
||||
};
|
||||
|
||||
export type AgentOptions = {
|
||||
|
||||
Reference in New Issue
Block a user