6b7636b088
CI / check (pull_request) Failing after 3m6s
Breaking changes: - UWF_STORAGE_ROOT → UWF_HOME - WORKFLOW_STORAGE_ROOT removed (no fallback) - OCAS_DIR → OCAS_HOME (aligned with ocas CLI) Library functions no longer read process.env: - util-agent/storage.ts: resolveStorageRoot(override), getGlobalCasDir(override) - agent-hermes: isResumeDisabled(flag) pure function, CLI reads env - agent-claude-code: CLI reads CLAUDE_MODEL and passes to agent Fixes #37
204 lines
5.4 KiB
Markdown
204 lines
5.4 KiB
Markdown
# @united-workforce/util-agent
|
|
|
|
Agent framework — `createAgent` factory, context builder, frontmatter fast-path, and LLM extract pipeline.
|
|
|
|
## Overview
|
|
|
|
Layer 2 agent framework. Provides the standard entrypoint for all agent CLIs: parse `<thread-id> <role>` from argv, load thread/workflow context from CAS, invoke the agent's `run`/`continue` functions, validate output via frontmatter fast-path or LLM extract, and write a `StepNodePayload` to CAS.
|
|
|
|
Also exports prompt builders, config/storage helpers, and session ID caching for multi-turn agents.
|
|
|
|
**Dependencies:** `@ocas/core`, `@ocas/fs`, `@united-workforce/protocol`, `@united-workforce/util`, `dotenv`, `yaml`
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
bun add @united-workforce/util-agent
|
|
```
|
|
|
|
## API
|
|
|
|
All exports come from `src/index.ts`.
|
|
|
|
### Agent factory
|
|
|
|
```typescript
|
|
function createAgent(options: AgentOptions): () => Promise<void>
|
|
|
|
type AgentOptions = {
|
|
name: string;
|
|
run: AgentRunFn;
|
|
continue: AgentContinueFn;
|
|
};
|
|
|
|
type AgentRunFn = (ctx: AgentContext) => Promise<AgentRunResult>;
|
|
type AgentContinueFn = (
|
|
sessionId: string,
|
|
message: string,
|
|
store: AgentContext["store"],
|
|
) => Promise<AgentRunResult>;
|
|
|
|
type AgentRunResult = {
|
|
output: string;
|
|
detailHash: string;
|
|
sessionId: string;
|
|
};
|
|
```
|
|
|
|
Agent CLIs call `createAgent(...)` and invoke the returned function as `main()`.
|
|
|
|
### Context
|
|
|
|
```typescript
|
|
function buildContext(
|
|
threadId: ThreadId,
|
|
role: string,
|
|
edgePrompt: string,
|
|
storageRoot: string,
|
|
casDir: string,
|
|
): Promise<AgentContext>
|
|
function buildContextWithMeta(
|
|
threadId: ThreadId,
|
|
role: string,
|
|
edgePrompt: string,
|
|
storageRoot: string,
|
|
casDir: string,
|
|
): Promise<AgentContext & { meta: BuildContextMeta }>
|
|
|
|
type AgentContext = ModeratorContext & {
|
|
threadId: ThreadId;
|
|
role: string;
|
|
store: Store;
|
|
workflow: WorkflowPayload;
|
|
outputFormatInstruction: string;
|
|
edgePrompt: string;
|
|
isFirstVisit: boolean;
|
|
storageRoot: string;
|
|
casDir: string;
|
|
};
|
|
|
|
type BuildContextMeta = {
|
|
storageRoot: string;
|
|
store: Store;
|
|
schemas: AgentStore["schemas"];
|
|
headHash: CasRef;
|
|
chain: ChainState;
|
|
};
|
|
```
|
|
|
|
Requires `UWF_EDGE_PROMPT` in the environment (set by `uwf thread step`).
|
|
|
|
### Prompt builders
|
|
|
|
```typescript
|
|
function buildRolePrompt(role: RoleDefinition): string
|
|
function buildOutputFormatInstruction(schema: JSONSchema): string
|
|
function buildContinuationPrompt(
|
|
steps: StepContext[],
|
|
role: string,
|
|
edgePrompt: string,
|
|
options?: { includeContent?: boolean; quota?: number },
|
|
): string
|
|
```
|
|
|
|
### Extract pipeline
|
|
|
|
```typescript
|
|
function resolveExtractModelAlias(config: WorkflowConfig): ModelAlias
|
|
function resolveModel(config: WorkflowConfig, alias: ModelAlias): ResolvedLlmProvider
|
|
function extract(
|
|
rawOutput: string,
|
|
outputSchema: CasRef,
|
|
config: WorkflowConfig,
|
|
storageRoot: string,
|
|
casDir: string,
|
|
): Promise<ExtractResult>
|
|
|
|
type ResolvedLlmProvider = { baseUrl: string; apiKey: string; model: string };
|
|
type ExtractResult = { value: unknown; hash: CasRef };
|
|
```
|
|
|
|
### Frontmatter fast-path
|
|
|
|
```typescript
|
|
function tryFrontmatterFastPath(
|
|
rawOutput: string,
|
|
outputSchema: CasRef,
|
|
store: Store,
|
|
): Promise<FrontmatterFastPathResult | null>
|
|
|
|
type FrontmatterFastPathResult = { body: string; outputHash: CasRef };
|
|
```
|
|
|
|
### Session cache
|
|
|
|
```typescript
|
|
function getCachedSessionId(
|
|
agentName: string,
|
|
threadId: ThreadId,
|
|
role: string,
|
|
storageRoot: string,
|
|
): Promise<string | null>
|
|
function setCachedSessionId(
|
|
agentName: string,
|
|
threadId: ThreadId,
|
|
role: string,
|
|
sessionId: string,
|
|
storageRoot: string,
|
|
): Promise<void>
|
|
```
|
|
|
|
### Config and storage
|
|
|
|
```typescript
|
|
function getConfigPath(storageRoot: string): string
|
|
function getEnvPath(storageRoot: string): string
|
|
function resolveStorageRoot(override: string | null): string
|
|
function loadWorkflowConfig(storageRoot: string): Promise<WorkflowConfig>
|
|
```
|
|
|
|
## Usage
|
|
|
|
```typescript
|
|
import { createAgent, buildRolePrompt } from "@united-workforce/util-agent";
|
|
import type { AgentContext, AgentRunResult } from "@united-workforce/util-agent";
|
|
|
|
async function run(ctx: AgentContext): Promise<AgentRunResult> {
|
|
const prompt = buildRolePrompt(ctx.workflow.roles[ctx.role]!);
|
|
// ... spawn external process, capture output ...
|
|
return { output: markdown, detailHash: "...", sessionId: "..." };
|
|
}
|
|
|
|
async function continueSession(
|
|
sessionId: string,
|
|
message: string,
|
|
): Promise<AgentRunResult> {
|
|
// ... continue multi-turn session ...
|
|
return { output: markdown, detailHash: "...", sessionId };
|
|
}
|
|
|
|
export const main = createAgent({ name: "my-agent", run, continue: continueSession });
|
|
```
|
|
|
|
## Internal Structure
|
|
|
|
```
|
|
src/
|
|
├── index.ts
|
|
├── run.ts createAgent entrypoint
|
|
├── context.ts Thread chain walk, AgentContext builder
|
|
├── extract.ts LLM structured extract fallback
|
|
├── frontmatter.ts Frontmatter fast-path validation
|
|
├── build-role-prompt.ts Role definition → prompt text
|
|
├── build-output-format-instruction.ts
|
|
├── build-continuation-prompt.ts
|
|
├── session-cache.ts Per-thread/session ID persistence
|
|
├── storage.ts CAS store, config, threads index
|
|
├── schemas.ts Agent CAS schema registration
|
|
└── types.ts AgentContext, AgentOptions, etc.
|
|
```
|
|
|
|
## Configuration
|
|
|
|
Reads `config.yaml` and `.env` from the workflow storage root (`~/.uwf` by default). See `@united-workforce/protocol` for `WorkflowConfig` shape. Set via `uwf setup`.
|