> ## Documentation Index
> Fetch the complete documentation index at: https://cadenya.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# How objectives work

> Understand objective configuration snapshots, lifecycle states, prompt data, tools, memory, events, context windows, continuations, and feedback.

An objective is one execution of an agent. Cadenya selects a variation, renders the prompts, snapshots the effective configuration, and runs the task against that fixed starting point.

```mermaid theme={null}
---
config:
  themeCSS: |
    .node rect, .node polygon, .node circle {
      fill: #347763 !important;
      stroke: #165B41 !important;
    }
    .nodeLabel, .nodeLabel p, .nodeLabel span,
    .label text, .label foreignObject div {
      color: #FFFFFF !important;
      fill: #FFFFFF !important;
    }
    .edgePath path {
      stroke: #739486 !important;
    }
---
flowchart LR
    A[Published agent] --> S{Select variation}
    V[Optional variationId] --> S
    D[Prompt data and run inputs] --> C[Create snapshot]
    S --> C
    C --> P[Pending]
    P --> R[Running]
    R --> W[Waiting]
    W --> R
    R --> F[Finalized]
    R --> E[Failed, Cancelled, or Timed Out]
```

## The creation boundary

Objective creation resolves mutable agent configuration into an immutable run snapshot:

| Input              | What Cadenya records                                                                        |
| ------------------ | ------------------------------------------------------------------------------------------- |
| Agent              | Agent metadata and objective-level behavior                                                 |
| Selected variation | Prompts, model, temperature, constraints, discovery, compaction, and assignment information |
| Tool assignments   | The callable tools available to this run                                                    |
| Schedule           | The originating schedule when a schedule fired the objective                                |
| Prompt data        | The rendered system prompt and first user message                                           |
| Per-run input      | Memory cascade, episodic key, secrets, pinned parameters, labels, tenant, and subject       |

Editing an agent, variation, tool set, or schedule later does not rewrite an existing objective. The objective continues against its snapshot.

## Variation selection happens once

Passing `variationId` pins one variation. When it is omitted, the agent's current selection mode chooses:

* **Random** selects every variation with equal probability.
* **Feedback Driven** draws one Thompson Sampling value from every variation's Beta posterior and selects the highest.

The selected variation appears in the objective's **Details** card and `configSnapshot.agentVariation`. Feedback can change which variation a future objective selects; it never swaps the variation of an objective that already exists.

## Prompt data and the first message

An objective can supply two separate JSON objects:

* `systemPromptData` renders the variation's `systemPromptTemplate`.
* `firstUserMessageData` renders its `firstUserMessageTemplate`.

Use the Liquid roots `system_prompt_data` and `first_user_message_data` inside the corresponding templates:

```markdown theme={null}
You support {{ system_prompt_data.company }}.

Review order {{ first_user_message_data.order_id }}.
```

An explicit `firstUserMessage` overrides the rendered first user message template. Objective creation fails when neither an explicit message nor a selected variation template can produce one.

When the agent defines `systemPromptDataSchema`, the supplied `systemPromptData` must satisfy it before execution starts.

## Lifecycle states

| State             | Terminal | Meaning                                                 |
| ----------------- | -------- | ------------------------------------------------------- |
| `STATE_PENDING`   | No       | Accepted and queued                                     |
| `STATE_RUNNING`   | No       | Processing the current turn                             |
| `STATE_WAITING`   | No       | The turn ended and another user message can continue it |
| `STATE_FINALIZED` | Yes      | Structured output was produced                          |
| `STATE_FAILED`    | Yes      | Execution failed                                        |
| `STATE_CANCELLED` | Yes      | A caller stopped execution                              |
| `STATE_TIMED_OUT` | Yes      | The inactivity limit was reached                        |

`STATE_WAITING` is deliberately non-terminal. A conversational agent without structured output usually ends each turn there.

<Frame caption="The timeline keeps every message, tool call, and result in execution order">
  <img src="https://mintcdn.com/cadenya/uaQ7Uw3TsXMwadaa/images/docs/objectives/faker-timeline.webp?fit=max&auto=format&n=uaQ7Uw3TsXMwadaa&q=85&s=2662b63d638205ff17b51fe234158651" alt="Objective timeline for attendee generation showing user and assistant messages with ten Faker tool calls and results" width="2664" height="2016" data-path="images/docs/objectives/faker-timeline.webp" />
</Frame>

## Tools are fixed for the run

Cadenya resolves the selected variation's individual tools and tool-set assignments at objective creation. The resulting objective tool catalog does not change when an assignment or tool set changes later.

Progressive discovery changes how much of that catalog enters the model's context at once:

* Without discovery, all reachable tool definitions are loaded.
* With discovery, `tool_search` finds matching assigned tools and loads them in batches during execution.

Approval policy also travels with the objective tool snapshot. A gated call emits `toolApprovalRequested` and waits until it is approved, denied, or times out.

The objective remains `STATE_RUNNING` while a gated tool call waits. Read the
tool call's `TOOL_CALL_STATUS_WAITING_FOR_APPROVAL` status or the
`toolApprovalRequested` event to distinguish that pause from active model work.

## Memory is a precedence cascade

The effective memory cascade is ordered from most specific to least specific:

1. The agent-managed episodic layer, when enabled for this objective.
2. Layers and pinned entries supplied in the objective's `memoryCascade`.
3. Memory layers assigned to the selected variation, ordered by position.

The first layer containing a requested key wins. Cadenya does not dump every memory entry into the prompt. The agent calls `get_memory` for the keys it needs.

## Context windows and compaction

Every objective begins with one context window. The selected variation controls the automatic compaction threshold.

When the context reaches that threshold:

* Optional tool-result clearing replaces older result bodies with placeholders while preserving their calls and arguments.
* Summarization condenses the older conversation.
* Cadenya creates a new context window and carries the summary forward.

Summarization uses the variation's model and is a billed model call. The dashboard's **Context Windows** tab shows each boundary, while **Debugger** and context diagnostics expose what consumed the latest iteration's input.

## Events are a discriminated union

Every durable event has `data.type` and one payload with the matching name. The TypeScript SDK represents `ObjectiveEvent.data` as an 18-variant discriminated union:

| Event                    | Meaning                                    |
| ------------------------ | ------------------------------------------ |
| `userMessage`            | Initial or continued user turn             |
| `assistantMessage`       | Agent response                             |
| `reasoning`              | Exposed reasoning text or provider summary |
| `toolCalled`             | Tool, built-in, or sub-agent call          |
| `toolResult`             | Successful tool result                     |
| `toolError`              | Failed tool execution                      |
| `toolApprovalRequested`  | Call waiting for a decision                |
| `toolApproved`           | Approval recorded                          |
| `toolDenied`             | Denial and optional steering memo recorded |
| `contextWindowCompacted` | A new context window was created           |
| `memoryRead`             | Memory lookup event shape                  |
| `subAgentSpawned`        | Child objective created                    |
| `subAgentUpdated`        | Child objective state changed              |
| `notice`                 | Non-terminal runtime diagnostic            |
| `finalized`              | Structured output produced                 |
| `cancelled`              | Cancellation recorded                      |
| `timedOut`               | Inactivity timeout recorded                |
| `error`                  | Terminal execution error                   |

Switching on `type` exposes only the payload for that branch:

```typescript theme={null}
for await (const event of stream) {
  const data = event.data;

  switch (data.type) {
    case 'assistantMessage':
      process.stdout.write(data.assistantMessage.content ?? '');
      break;
    case 'toolCalled':
      console.log(data.toolCalled.arguments);
      break;
    case 'error':
      throw new Error(data.error.message ?? 'Objective failed');
  }
}
```

Use an exhaustive `never` check when your application must handle every variant. TypeScript then reports a compile error when a future SDK adds another event type.

## Continue, finalize, or cancel

Continue a `STATE_WAITING` objective with one new message. It keeps its snapshot, history, context windows, and original secrets. Prompt data and secrets cannot be replaced on continuation, so create another objective when those inputs must change.

An agent with `outputDefinition` runs structured extraction and reaches `STATE_FINALIZED`. Its machine-readable value appears at `objective.output` and `finalized.output`.

Cancel pending or running work when it should stop. Cancellation is asynchronous, so retrieve the objective again when your application must observe `STATE_CANCELLED`.

## Feedback changes future traffic

Objective feedback accepts a score from `-1` to `1`:

* Positive scores add their magnitude to the selected variation's alpha value.
* Negative scores add their absolute magnitude to beta.
* Zero adds `0.5` to both, providing neutral evidence.

Each submission appends another record. Under **Feedback Driven** selection, those posterior updates influence objectives created later.

<Frame caption="Feedback remains attached to the objective and its selected variation">
  <img src="https://mintcdn.com/cadenya/uaQ7Uw3TsXMwadaa/images/docs/objectives/feedback-history.webp?fit=max&auto=format&n=uaQ7Uw3TsXMwadaa&q=85&s=85eedee64684464fd26dbf3ff9f01dd9" alt="Objective Feedback tab showing an Excellent score and a comment under Previous Feedback" width="2664" height="1114" data-path="images/docs/objectives/feedback-history.webp" />
</Frame>

<CardGroup cols={2}>
  <Card title="Run your first objective" icon="play" href="/docs/guides/run-an-objective">
    Create a run in the dashboard and inspect every surface.
  </Card>

  <Card title="Objectives from the SDK" icon="code" href="/docs/guides/sdk/objectives">
    Dispatch, stream, continue, cancel, and score from code.
  </Card>

  <Card title="Stream objective events" icon="tower-broadcast" href="/docs/api-reference/objectiveeventstreamsservice/stream-objective-events">
    Handle SSE control frames, reconnects, and typed payloads.
  </Card>

  <Card title="Feedback and sampling" icon="chart-line" href="/docs/guides/agents/feedback-and-sampling">
    Follow an objective score into a future variation selection.
  </Card>
</CardGroup>
