Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 127 additions & 0 deletions hindsight-integrations/codex/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# Hindsight for OpenAI Codex CLI

Long-term memory for [OpenAI Codex CLI](https://github.com/openai/codex) — remembers your projects, preferences, and past sessions across every conversation.

## How it works

Three Codex hooks keep memory in sync automatically:

| Hook | Action |
|------|--------|
| `SessionStart` | Warms up the Hindsight server in the background |
| `UserPromptSubmit` | Recalls relevant memories and injects them into context |
| `Stop` | Retains the conversation to long-term memory |

## Requirements

- **OpenAI Codex CLI** v0.116.0 or later (hooks support)
- **Python 3.9+** (for hook scripts)
- **Hindsight**: [Hindsight Cloud](https://hindsight.vectorize.io) or local `hindsight-embed`

## Installation

```bash
git clone https://github.com/vectorize-io/hindsight
cd hindsight/hindsight-integrations/codex
./install.sh
```

The installer:
1. Copies scripts to `~/.hindsight/codex/scripts/`
2. Writes `~/.codex/hooks.json` with absolute paths to the scripts
3. Adds `codex_hooks = true` to `~/.codex/config.toml`

### Uninstall

```bash
./install.sh --uninstall
```

## Configuration

The default config is written to `~/.hindsight/codex/settings.json` on first install.

For personal overrides (stable across updates), create `~/.hindsight/codex.json`:

```json
{
"hindsightApiUrl": "https://api.hindsight.vectorize.io",
"hindsightApiToken": "your-api-key",
"bankId": "my-codex-memory"
}
```

### Hindsight Cloud

```json
{
"hindsightApiUrl": "https://api.hindsight.vectorize.io",
"hindsightApiToken": "your-api-key"
}
```

### Local daemon (hindsight-embed)

Set an LLM API key and Hindsight will start the local server automatically:

```bash
export OPENAI_API_KEY=sk-your-key
# or
export ANTHROPIC_API_KEY=your-key
```

### Configuration options

| Key | Default | Description |
|-----|---------|-------------|
| `hindsightApiUrl` | `""` | External API URL (empty = local daemon) |
| `hindsightApiToken` | `null` | API token for Hindsight Cloud |
| `bankId` | `"codex"` | Memory bank identifier |
| `bankMission` | (set) | Guides what facts Hindsight retains |
| `autoRecall` | `true` | Inject memories before each prompt |
| `autoRetain` | `true` | Store conversations after each turn |
| `retainMode` | `"full-session"` | `"full-session"` or `"chunked"` |
| `retainEveryNTurns` | `10` | Retain every N turns (1 = every turn) |
| `recallBudget` | `"mid"` | Recall depth: `"low"`, `"mid"`, `"high"` |
| `recallMaxTokens` | `1024` | Max tokens for injected memories |
| `dynamicBankId` | `false` | Separate bank per project/session |
| `dynamicBankGranularity` | `["agent", "project"]` | Fields for dynamic bank ID |
| `debug` | `false` | Log debug info to stderr |

### Environment variable overrides

All settings can also be set via environment variables:

```bash
export HINDSIGHT_API_URL=https://api.hindsight.vectorize.io
export HINDSIGHT_API_TOKEN=your-api-key
export HINDSIGHT_BANK_ID=my-project
export HINDSIGHT_DEBUG=true
```

## How memory works

**Recall** — before each prompt, Hindsight searches your memory bank for facts relevant to what you're about to ask. Found memories are injected as context so Codex has continuity across sessions.

**Retain** — after each turn, Codex's conversation is stored to Hindsight. The memory engine extracts facts, relationships, and experiences — so you don't need to re-explain your stack, preferences, or past decisions.

## Dynamic bank IDs

To keep separate memory per project:

```json
{
"dynamicBankId": true,
"dynamicBankGranularity": ["agent", "project"]
}
```

This creates banks like `codex::my-project` automatically, using the working directory name.

## Troubleshooting

**Memory not appearing**: Enable debug mode (`"debug": true`) and check stderr output.

**Server not starting**: Set `hindsightApiUrl` to use an external server, or ensure `uvx` is on PATH for local daemon mode.

**Hooks not firing**: Check that `~/.codex/config.toml` contains `codex_hooks = true` under `[features]`, and that your Codex CLI version supports hooks (v0.116.0+).
37 changes: 37 additions & 0 deletions hindsight-integrations/codex/hooks/hooks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "python3 \"__SCRIPTS_DIR__/session_start.py\"",
"timeout": 5
}
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "python3 \"__SCRIPTS_DIR__/recall.py\"",
"timeout": 12
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "python3 \"__SCRIPTS_DIR__/retain.py\"",
"timeout": 30
}
]
}
]
}
}
149 changes: 149 additions & 0 deletions hindsight-integrations/codex/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
#!/usr/bin/env bash
# Hindsight memory integration for OpenAI Codex CLI
#
# This script installs the Hindsight hooks into ~/.codex/ and copies
# the hook scripts to ~/.hindsight/codex/scripts/.
#
# Usage:
# ./install.sh # Install (or update)
# ./install.sh --uninstall # Remove Hindsight hooks

set -euo pipefail

INTEGRATION_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
INSTALL_DIR="${HOME}/.hindsight/codex"
SCRIPTS_DIR="${INSTALL_DIR}/scripts"
CODEX_DIR="${HOME}/.codex"
HOOKS_FILE="${CODEX_DIR}/hooks.json"
CONFIG_FILE="${CODEX_DIR}/config.toml"

# ──────────────────────────────────────────────────────────────────────────────
# Uninstall
# ──────────────────────────────────────────────────────────────────────────────
if [[ "${1:-}" == "--uninstall" ]]; then
echo "Uninstalling Hindsight Codex integration..."

# Remove scripts directory
if [[ -d "${SCRIPTS_DIR}" ]]; then
rm -rf "${SCRIPTS_DIR}"
echo " Removed ${SCRIPTS_DIR}"
fi

# Remove hooks.json
if [[ -f "${HOOKS_FILE}" ]]; then
rm -f "${HOOKS_FILE}"
echo " Removed ${HOOKS_FILE}"
fi

# Remove codex_hooks feature flag from config.toml (if present)
if [[ -f "${CONFIG_FILE}" ]]; then
# Remove the [features] block line for codex_hooks
sed -i.bak '/^codex_hooks *= *true/d' "${CONFIG_FILE}" && rm -f "${CONFIG_FILE}.bak"
echo " Removed codex_hooks from ${CONFIG_FILE}"
fi

echo "Uninstall complete."
exit 0
fi

# ──────────────────────────────────────────────────────────────────────────────
# Install
# ──────────────────────────────────────────────────────────────────────────────
echo "Installing Hindsight Codex integration..."

# 1. Copy scripts to ~/.hindsight/codex/scripts/
mkdir -p "${SCRIPTS_DIR}"
cp -r "${INTEGRATION_DIR}/scripts/." "${SCRIPTS_DIR}/"
chmod +x "${SCRIPTS_DIR}/session_start.py"
chmod +x "${SCRIPTS_DIR}/recall.py"
chmod +x "${SCRIPTS_DIR}/retain.py"
echo " Scripts installed to ${SCRIPTS_DIR}"

# 2. Copy default settings (don't overwrite user's existing settings)
SETTINGS_DST="${INSTALL_DIR}/settings.json"
if [[ ! -f "${SETTINGS_DST}" ]]; then
cp "${INTEGRATION_DIR}/settings.json" "${SETTINGS_DST}"
echo " Default settings written to ${SETTINGS_DST}"
else
echo " Keeping existing settings at ${SETTINGS_DST}"
fi

# 3. Write ~/.codex/hooks.json with absolute paths
mkdir -p "${CODEX_DIR}"
cat > "${HOOKS_FILE}" <<EOF
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "python3 \"${SCRIPTS_DIR}/session_start.py\"",
"timeout": 5
}
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "python3 \"${SCRIPTS_DIR}/recall.py\"",
"timeout": 12
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "python3 \"${SCRIPTS_DIR}/retain.py\"",
"timeout": 30
}
]
}
]
}
}
EOF
echo " Hooks written to ${HOOKS_FILE}"

# 4. Enable codex_hooks in ~/.codex/config.toml
if [[ ! -f "${CONFIG_FILE}" ]]; then
touch "${CONFIG_FILE}"
fi

# Check if [features] section exists
if grep -q '^\[features\]' "${CONFIG_FILE}" 2>/dev/null; then
# Section exists — add codex_hooks under it if not already present
if ! grep -q '^codex_hooks' "${CONFIG_FILE}"; then
# Insert codex_hooks after [features]
sed -i.bak '/^\[features\]/a codex_hooks = true' "${CONFIG_FILE}" && rm -f "${CONFIG_FILE}.bak"
echo " Added codex_hooks = true to [features] in ${CONFIG_FILE}"
else
echo " codex_hooks already enabled in ${CONFIG_FILE}"
fi
else
# No [features] section — append it
printf '\n[features]\ncodex_hooks = true\n' >> "${CONFIG_FILE}"
echo " Added [features] codex_hooks = true to ${CONFIG_FILE}"
fi

echo ""
echo "Hindsight is installed for Codex."
echo ""
echo "Configuration:"
echo " Edit ${SETTINGS_DST} to customize settings."
echo " Or create ~/.hindsight/codex.json for personal overrides."
echo ""
echo "For Hindsight Cloud, set:"
echo " \"hindsightApiUrl\": \"https://api.hindsight.vectorize.io\""
echo " \"hindsightApiToken\": \"your-api-key\""
echo ""
echo "For local daemon mode, set an LLM API key:"
echo " export OPENAI_API_KEY=sk-your-key"
echo ""
echo "Start a new Codex session to activate."
Empty file.
Loading
Loading