Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 710d42d6b9 | |||
| 072d900fcb | |||
| cfebd07124 | |||
| f2be6fc057 | |||
| 2af8196451 |
@@ -1,12 +1,6 @@
|
||||
import { spawn } from "node:child_process";
|
||||
|
||||
import {
|
||||
type AgentContext,
|
||||
type AgentRunResult,
|
||||
createAgent,
|
||||
createAgentStore,
|
||||
resolveStorageRoot,
|
||||
} from "@uncaged/uwf-agent-kit";
|
||||
import { type AgentContext, type AgentRunResult, createAgent } from "@uncaged/uwf-agent-kit";
|
||||
|
||||
import {
|
||||
loadHermesSession,
|
||||
@@ -18,14 +12,14 @@ import {
|
||||
const HERMES_COMMAND = "hermes";
|
||||
const HERMES_MAX_TURNS = 90;
|
||||
|
||||
function buildHistorySummary(history: AgentContext["history"]): string {
|
||||
if (history.length === 0) {
|
||||
function buildHistorySummary(steps: AgentContext["steps"]): string {
|
||||
if (steps.length === 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const lines: string[] = ["## Previous Steps"];
|
||||
for (let i = 0; i < history.length; i++) {
|
||||
const step = history[i];
|
||||
for (let i = 0; i < steps.length; i++) {
|
||||
const step = steps[i];
|
||||
if (step === undefined) {
|
||||
continue;
|
||||
}
|
||||
@@ -39,8 +33,10 @@ function buildHistorySummary(history: AgentContext["history"]): string {
|
||||
|
||||
/** Assemble system prompt, task, and prior step outputs for Hermes. */
|
||||
export function buildHermesPrompt(ctx: AgentContext): string {
|
||||
const parts: string[] = [ctx.systemPrompt, "", "## Task", ctx.prompt];
|
||||
const historyBlock = buildHistorySummary(ctx.history);
|
||||
const roleDef = ctx.workflow.roles[ctx.role];
|
||||
const systemPrompt = roleDef?.systemPrompt ?? "";
|
||||
const parts: string[] = [systemPrompt, "", "## Task", ctx.start.prompt];
|
||||
const historyBlock = buildHistorySummary(ctx.steps);
|
||||
if (historyBlock !== "") {
|
||||
parts.push("", historyBlock);
|
||||
}
|
||||
@@ -92,8 +88,7 @@ function spawnHermesChat(prompt: string): Promise<string> {
|
||||
async function runHermes(ctx: AgentContext): Promise<AgentRunResult> {
|
||||
const fullPrompt = buildHermesPrompt(ctx);
|
||||
const rawOutput = await spawnHermesChat(fullPrompt);
|
||||
const storageRoot = resolveStorageRoot();
|
||||
const { store } = await createAgentStore(storageRoot);
|
||||
const { store } = ctx;
|
||||
|
||||
const sessionId = parseSessionIdFromStdout(rawOutput);
|
||||
if (sessionId !== null) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { Store } from "@uncaged/json-cas";
|
||||
import type {
|
||||
CasRef,
|
||||
StartNodePayload,
|
||||
@@ -6,6 +7,7 @@ import type {
|
||||
ThreadId,
|
||||
} from "@uncaged/uwf-protocol";
|
||||
import { createAgentStore, loadThreadsIndex, resolveStorageRoot } from "./storage.js";
|
||||
import type { AgentStore } from "./storage.js";
|
||||
import type { AgentContext } from "./types.js";
|
||||
|
||||
type ChainState = {
|
||||
@@ -20,8 +22,8 @@ function fail(message: string): never {
|
||||
}
|
||||
|
||||
function walkChain(
|
||||
store: Awaited<ReturnType<typeof createAgentStore>>["store"],
|
||||
schemas: Awaited<ReturnType<typeof createAgentStore>>["schemas"],
|
||||
store: Store,
|
||||
schemas: AgentStore["schemas"],
|
||||
headHash: CasRef,
|
||||
): ChainState {
|
||||
const headNode = store.get(headHash);
|
||||
@@ -77,7 +79,7 @@ function walkChain(
|
||||
}
|
||||
|
||||
function expandOutput(
|
||||
store: Awaited<ReturnType<typeof createAgentStore>>["store"],
|
||||
store: Store,
|
||||
outputRef: CasRef,
|
||||
): unknown {
|
||||
const node = store.get(outputRef);
|
||||
@@ -88,7 +90,7 @@ function expandOutput(
|
||||
}
|
||||
|
||||
async function buildHistory(
|
||||
store: Awaited<ReturnType<typeof createAgentStore>>["store"],
|
||||
store: Store,
|
||||
stepsNewestFirst: StepNodePayload[],
|
||||
): Promise<StepContext[]> {
|
||||
const chronological = [...stepsNewestFirst].reverse();
|
||||
@@ -105,8 +107,8 @@ async function buildHistory(
|
||||
}
|
||||
|
||||
async function loadWorkflow(
|
||||
store: Awaited<ReturnType<typeof createAgentStore>>["store"],
|
||||
schemas: Awaited<ReturnType<typeof createAgentStore>>["schemas"],
|
||||
store: Store,
|
||||
schemas: AgentStore["schemas"],
|
||||
workflowRef: CasRef,
|
||||
) {
|
||||
const node = store.get(workflowRef);
|
||||
@@ -141,22 +143,22 @@ export async function buildContext(threadId: ThreadId, role: string): Promise<Ag
|
||||
fail(`unknown role "${role}" in workflow "${workflow.name}"`);
|
||||
}
|
||||
|
||||
const history = await buildHistory(store, chain.stepsNewestFirst);
|
||||
const steps = await buildHistory(store, chain.stepsNewestFirst);
|
||||
|
||||
return {
|
||||
threadId,
|
||||
role,
|
||||
systemPrompt: roleDef.systemPrompt,
|
||||
prompt: chain.start.prompt,
|
||||
history,
|
||||
start: chain.start,
|
||||
steps,
|
||||
workflow,
|
||||
store,
|
||||
};
|
||||
}
|
||||
|
||||
export type BuildContextMeta = {
|
||||
storageRoot: string;
|
||||
store: Awaited<ReturnType<typeof createAgentStore>>["store"];
|
||||
schemas: Awaited<ReturnType<typeof createAgentStore>>["schemas"];
|
||||
store: Store;
|
||||
schemas: AgentStore["schemas"];
|
||||
headHash: CasRef;
|
||||
chain: ChainState;
|
||||
};
|
||||
@@ -185,15 +187,15 @@ export async function buildContextWithMeta(
|
||||
fail(`unknown role "${role}" in workflow "${workflow.name}"`);
|
||||
}
|
||||
|
||||
const history = await buildHistory(store, chain.stepsNewestFirst);
|
||||
const steps = await buildHistory(store, chain.stepsNewestFirst);
|
||||
|
||||
return {
|
||||
threadId,
|
||||
role,
|
||||
systemPrompt: roleDef.systemPrompt,
|
||||
prompt: chain.start.prompt,
|
||||
history,
|
||||
start: chain.start,
|
||||
steps,
|
||||
workflow,
|
||||
store,
|
||||
meta: { storageRoot, store, schemas, headHash, chain },
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,11 +7,5 @@ export {
|
||||
resolveModel,
|
||||
} from "./extract.js";
|
||||
export { createAgent } from "./run.js";
|
||||
export {
|
||||
createAgentStore,
|
||||
getConfigPath,
|
||||
getEnvPath,
|
||||
loadWorkflowConfig,
|
||||
resolveStorageRoot,
|
||||
} from "./storage.js";
|
||||
export { getConfigPath, getEnvPath, loadWorkflowConfig } from "./storage.js";
|
||||
export type { AgentContext, AgentOptions, AgentRunFn, AgentRunResult } from "./types.js";
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import type { StepContext, ThreadId, WorkflowPayload } from "@uncaged/uwf-protocol";
|
||||
import type { Store } from "@uncaged/json-cas";
|
||||
import type { ModeratorContext, ThreadId, WorkflowPayload } from "@uncaged/uwf-protocol";
|
||||
|
||||
export type AgentContext = {
|
||||
export type AgentContext = ModeratorContext & {
|
||||
threadId: ThreadId;
|
||||
role: string;
|
||||
systemPrompt: string;
|
||||
prompt: string;
|
||||
history: StepContext[];
|
||||
store: Store;
|
||||
workflow: WorkflowPayload;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
#!/usr/bin/env bun
|
||||
// Mock agent for smoke testing
|
||||
import { bootstrap, type JSONSchema, putSchema } from "@uncaged/json-cas";
|
||||
import {
|
||||
createAgent,
|
||||
createAgentStore,
|
||||
resolveStorageRoot,
|
||||
} from "../packages/uwf-agent-kit/src/index.js";
|
||||
import { createAgent } from "../packages/uwf-agent-kit/src/index.js";
|
||||
|
||||
const MOCK_RAW_OUTPUT_SCHEMA: JSONSchema = {
|
||||
title: "mock-raw-output",
|
||||
@@ -20,8 +16,8 @@ const MOCK_RAW_OUTPUT_SCHEMA: JSONSchema = {
|
||||
const agent = createAgent({
|
||||
name: "mock",
|
||||
run: async (ctx) => {
|
||||
const output = `Mock output for role ${ctx.role}: task was "${ctx.prompt}"`;
|
||||
const { store } = await createAgentStore(resolveStorageRoot());
|
||||
const output = `Mock output for role ${ctx.role}: task was "${ctx.start.prompt}"`;
|
||||
const { store } = ctx;
|
||||
await bootstrap(store);
|
||||
const schemaHash = await putSchema(store, MOCK_RAW_OUTPUT_SCHEMA);
|
||||
const detailHash = await store.put(schemaHash, { text: output });
|
||||
|
||||
Reference in New Issue
Block a user