# Complete Guide to ObservationKind Values for ai-memory Lifecycle Hooks

> Explore the ten ObservationKind values like SessionStart UserPrompt PreToolUse and SessionEnd available for ai-memory lifecycle hooks in this comprehensive guide.

- Repository: [Fabio Akita/ai-memory](https://github.com/akitaonrails/ai-memory)
- Tags: api-reference
- Published: 2026-09-06

---

**The `ai-memory` crate defines ten `ObservationKind` enum variants—including `SessionStart`, `UserPrompt`, `PreToolUse`, and `SessionEnd`—in [`crates/ai-memory-core/src/observation.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-core/src/observation.rs) to categorize every agent lifecycle hook event.**

The `akitaonrails/ai-memory` repository provides a Rust-based memory system for AI agents, where each lifecycle hook fires an observation classified by the `ObservationKind` enum. These values determine how events are serialized, stored in SQLite, and indexed for retrieval. Understanding the available variants is essential for implementing custom memory providers or analyzing agent behavior patterns.

## The ObservationKind Enum Location and Structure

Located in [`crates/ai-memory-core/src/observation.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-core/src/observation.rs), the `ObservationKind` enum serves as the core taxonomy for agent observations. As implemented in `akitaonrails/ai-memory`, this enum captures every significant state transition during an agent's execution cycle, providing granular visibility into session boundaries, user interactions, tool executions, and memory compaction events.

## Available ObservationKind Variants

The system recognizes ten distinct observation types that cover the complete agent lifecycle:

### Session Boundaries

- **SessionStart**: Marks the beginning of a new agent session, capturing metadata such as the current working directory and agent type.
- **SessionEnd**: Indicates the session has been permanently closed and no further observations will be recorded for this session.

### User Interactions

- **UserPrompt**: Records when a user submits a prompt to the agent, typically containing the raw input text.
- **Notification**: Captures non-prompt information emitted by the agent, such as status updates or informational messages.
- **Stop**: Signals that the agent's current turn has ended, often used to mark completion of a response generation cycle.

### Tool Execution

- **PreToolUse**: Fires immediately before the agent invokes a tool, allowing capture of intent and input parameters.
- **PostToolUse**: Records completion of a tool invocation, typically containing execution output, return values, or error states.

### Memory Management

- **PreCompact**: Triggered when a compaction event is about to occur, such as when the context window approaches capacity limits.
- **PostCompaction**: Indicates a compaction event has just finished; this variant is development-specific and aids in debugging memory optimization.

### Fallback Category

- **Other**: Represents any observation that does not fit the predefined categories, providing extensibility for custom hook implementations.

## String Serialization and Parsing Formats

According to the source code in [`crates/ai-memory-core/src/observation.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-core/src/observation.rs), the enum serializes to **kebab-case** strings for storage and wire format (e.g., `session-start`, `user-prompt`, `post-tool-use`).

The `FromStr` implementation in the same file provides flexible parsing that accepts three case formats:

- **Kebab-case**: `pre-tool-use`
- **Snake_case**: `pre_tool_use`  
- **PascalCase**: `PreToolUse`

This flexibility ensures compatibility with various hook payloads, configuration files, and external API inputs while maintaining consistent kebab-case storage in the SQLite backend.

## Creating Observations in Rust

The following example demonstrates instantiating `NewObservation` structs with specific `ObservationKind` variants as defined in the `ai-memory-core` crate:

```rust
use ai_memory_core::{ObservationKind, NewObservation, SessionId, WorkspaceId, ProjectId};

// Create a "user prompt" observation
let obs = NewObservation {
    session_id: SessionId::new(),
    workspace_id: WorkspaceId::new(),
    project_id: ProjectId::new(),
    kind: ObservationKind::UserPrompt,
    extension: None,
    source_event: None,
    title: "Ask about rust enums".into(),
    body: "What are the ObservationKind variants?".into(),
    importance: 5,
};

// A "post-tool-use" observation (e.g., after calling `git status`)
let tool_obs = NewObservation {
    kind: ObservationKind::PostToolUse,
    title: "git status output".into(),
    body: "On branch main\nnothing to commit".into(),
    ..obs.clone()   // reuse ids, workspace, project, etc.
};

```

## Parsing ObservationKind from Hook Payloads

When processing incoming hook payloads, you can parse string representations into enum variants using the standard `FromStr` trait:

```rust
let kind: ObservationKind = "post-tool-use".parse().expect("valid kind");
assert_eq!(kind, ObservationKind::PostToolUse);

```

The parser automatically handles kebab-case, snake_case, and PascalCase inputs, returning a valid `ObservationKind` or an error for unrecognized variants.

## Key Source Files and Architecture

Understanding the codebase structure helps when extending observation handling or debugging serialization issues:

- **[`crates/ai-memory-core/src/observation.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-core/src/observation.rs)**: Defines `ObservationKind`, `NewObservation`, and the `FromStr` parsing logic.
- **[`crates/ai-memory-core/src/lib.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-core/src/lib.rs)**: Re-exports observation types for the public API surface.
- **[`crates/ai-memory-store/src/writer.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/writer.rs)**: Handles ingestion of `NewObservation` instances into the SQLite store.
- **[`crates/ai-memory-web/tests/suite/routes.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-web/tests/suite/routes.rs)**: Contains HTTP API test cases exercising the various `ObservationKind` values through integration tests.

## Summary

- The `ObservationKind` enum in [`crates/ai-memory-core/src/observation.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-core/src/observation.rs) defines ten variants for classifying agent lifecycle events in `akitaonrails/ai-memory`.
- Variants cover session boundaries (`SessionStart`, `SessionEnd`), user interactions (`UserPrompt`, `Notification`), tool execution (`PreToolUse`, `PostToolUse`), and memory compaction (`PreCompact`, `PostCompaction`).
- Storage and wire format use kebab-case strings (e.g., `session-start`), while the `FromStr` implementation accepts kebab-case, snake_case, and PascalCase for flexible input parsing.
- Observations are instantiated using the `NewObservation` struct and persisted through the `ai-memory-store` crate's SQLite writer.

## Frequently Asked Questions

### Where is the ObservationKind enum defined in the ai-memory repository?

The `ObservationKind` enum is defined in [`crates/ai-memory-core/src/observation.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-core/src/observation.rs) within the `akitaonrails/ai-memory` repository. This file also contains the `FromStr` trait implementation for parsing string values and the serialization logic for converting enum variants to kebab-case strings.

### What string formats does ObservationKind accept when parsing?

The `FromStr` implementation accepts three case formats: kebab-case (e.g., `post-tool-use`), snake_case (e.g., `post_tool_use`), and PascalCase (e.g., `PostToolUse`). However, the system always serializes values to kebab-case for storage in SQLite and transmission over the wire.

### How do PreToolUse and PostToolUse differ in the ai-memory lifecycle?

`PreToolUse` fires immediately before the agent invokes a tool, capturing the intent and input parameters, while `PostToolUse` records the completion state including execution output, return values, or errors. Both variants are essential for reconstructing the complete tool execution flow in the memory store.

### Can I extend ObservationKind with custom variants for specialized hooks?

The enum includes an `Other` variant specifically for observations that do not fit the predefined categories. To add entirely new first-class variants such as `CustomAnalysis`, you would need to modify the `ObservationKind` definition in [`crates/ai-memory-core/src/observation.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-core/src/observation.rs) and rebuild the crate, as the current implementation uses a closed enum with nine specific variants plus the `Other` catch-all.