Open Harness

Signals

Signal types and structure reference

Signals

All communication in Open Harness flows through typed signals.

Signal Structure

interface Signal {
  id: string;           // Unique identifier ("sig_abc123")
  name: string;         // Signal name ("analysis:complete")
  payload: unknown;     // Signal-specific data
  timestamp: string;    // ISO timestamp
  source?: {
    agent?: string;     // Emitting agent
    parent?: string;    // Parent signal ID (causality)
  };
}

Workflow Signals

workflow:start

Emitted when workflow begins:

{
  name: "workflow:start",
  payload: {
    state: { /* initial state */ },
    agents: ["analyzer", "reviewer"],
  }
}

workflow:end

Emitted when workflow completes:

{
  name: "workflow:end",
  payload: {
    state: { /* final state */ },
    metrics: {
      durationMs: 1234,
      activations: 3,
    },
    terminatedEarly: false,
  }
}

Agent Signals

agent:activated

Emitted when an agent activates:

{
  name: "agent:activated",
  payload: {
    agent: "analyzer",
    triggeredBy: "workflow:start",
  }
}

agent:skipped

Emitted when an agent's when guard returns false:

{
  name: "agent:skipped",
  payload: {
    agent: "reviewer",
    reason: "when guard returned false",
  }
}

agent:completed

Emitted when an agent finishes:

{
  name: "agent:completed",
  payload: {
    agent: "analyzer",
    output: "Analysis result...",
  }
}

Harness Signals

harness:start

Emitted when harness begins execution:

{
  name: "harness:start",
  payload: {
    model: "claude-sonnet-4-20250514",
  }
}

harness:end

Emitted when harness completes:

{
  name: "harness:end",
  payload: {
    usage: {
      inputTokens: 150,
      outputTokens: 89,
    },
    cost: 0.0012,
    sessionId: "session_abc123",
  }
}

harness:error

Emitted on harness failure:

{
  name: "harness:error",
  payload: {
    error: "Rate limit exceeded",
    retryAfter: 30,
  }
}

Text Signals

text:delta

Streaming text chunk:

{
  name: "text:delta",
  payload: {
    content: "The ",
  }
}

text:complete

Full text after streaming:

{
  name: "text:complete",
  payload: {
    content: "The analysis shows three key findings...",
  }
}

Thinking Signals

thinking:delta

Streaming thinking chunk (extended thinking):

{
  name: "thinking:delta",
  payload: {
    content: "Let me consider the implications...",
  }
}

thinking:complete

Full thinking content:

{
  name: "thinking:complete",
  payload: {
    content: "...",
  }
}

Tool Signals

tool:call

Tool invocation:

{
  name: "tool:call",
  payload: {
    id: "call_abc123",
    name: "Read",
    input: {
      path: "/src/index.ts",
    },
  }
}

tool:result

Tool result:

{
  name: "tool:result",
  payload: {
    id: "call_abc123",
    name: "Read",
    output: "file contents...",
    error: null,
  }
}

State Signals

state:{key}:changed

Emitted when state changes:

{
  name: "state:analysis:changed",
  payload: {
    value: "New analysis result",
    previousValue: null,
  }
}

Custom Signals

Agents emit custom signals via emits:

const analyzer = agent({
  prompt: "Analyze the input",
  activateOn: ["workflow:start"],
  emits: ["analysis:complete"],
});

Emitted as:

{
  name: "analysis:complete",
  payload: { /* agent output */ },
  source: { agent: "analyzer" },
}

Signal Patterns

Use patterns to match signals:

PatternMatches
"workflow:start"Exact match
"agent:*"agent:activated, agent:completed, etc.
"harness:**"All harness signals
"*:complete"text:complete, analysis:complete, etc.

Working with Signals

Filter by Name

const agentSignals = result.signals.filter(s => s.name.startsWith("agent:"));

Extract Usage

const harnessEnds = result.signals.filter(s => s.name === "harness:end");
const totalTokens = harnessEnds.reduce((sum, s) => {
  const usage = s.payload.usage || { inputTokens: 0, outputTokens: 0 };
  return sum + usage.inputTokens + usage.outputTokens;
}, 0);

Build Causality Chain

import { getCausalityChain } from "@open-harness/core";

const chain = getCausalityChain(result.signals, targetSignalId);
// Returns array of signals leading to target

See Also

On this page