personal memory agent
0

Configure Feed

Select the types of activity you want to include in your feed.

solstone / docs / THINK.md
12 kB

solstone-think#

Post-processing utilities for clustering and summarising captured data. The tools leverage the Gemini API to analyse transcriptions and screenshots. All commands work with a journal directory that holds daily folders in YYYYMMDD format.

Installation#

make install

All dependencies are listed in pyproject.toml.

Usage#

The package exposes several commands:

  • sol call transcripts read groups audio and screen transcripts into report sections. Use --start and --length to limit the report to a specific time range. See sol call transcripts --help for additional commands.
  • journal think runs generators and agents for a single day via Cortex.
  • python -m solstone.think.talents is the unified execution module for tool talents and generators spawned by Cortex (NDJSON protocol).
  • journal supervisor monitors journaling health and starts the local services that feed Convey, Cortex, and related background tasks. Use the --no-* flags to opt out of specific services when debugging.
  • journal cortex starts a Callosum-based service for managing AI agent instances and generators.
  • journal talent lists available agents and generators with their configuration. Use journal talent show <name> to see details, and journal talent show <name> --prompt to see the fully composed prompt that would be sent to the LLM.
sol call transcripts read YYYYMMDD [--start HHMMSS --length MINUTES]
journal think [--day YYYYMMDD] [--segment HHMMSS_LEN] [--stream NAME] [--refresh] [--flush]
journal supervisor [--no-daily] [--no-cortex] [--no-spl] [--no-convey] [--no-schedule]
journal cortex [--host HOST] [--port PORT] [--path PATH]
journal talent list [--schedule daily|segment] [--json]
journal talent show <name> [--prompt] [--day YYYYMMDD] [--segment HHMMSS_LEN] [--full]

Use --refresh to overwrite existing files, and -v for verbose logs.

Set GOOGLE_API_KEY before running any command that contacts Gemini. GOOGLE_API_KEY can also be provided in a .env file which is loaded automatically by most commands.

Structured file importers are registered in solstone/think/importers/file_importer.py and run through sol import's dispatcher. Their process() contract now accepts dry_run: bool = False, and journal-archive imports use the same dispatcher surface while serializing journal mutation with the merge lock contract.

Service Discovery#

Agents invoke tools through sol call shell commands: sol call <module> <command> [args...]. Tool access is command-based via the sol call CLI framework.

Automating daily processing#

The journal think command can be triggered by a systemd timer. Below is a minimal service and timer that process yesterday's folder every morning at 06:00:

[Unit]
Description=Process solstone journal

[Service]
Type=oneshot
ExecStart=/usr/local/bin/journal think

[Install]
WantedBy=multi-user.target
[Unit]
Description=Run journal think daily

[Timer]
OnCalendar=*-*-* 06:00:00
Persistent=true
Unit=sol-think.service

[Install]
WantedBy=timers.target

config/schedules.json contract#

config/schedules.json stores scheduler metadata and named schedule entries in one top-level JSON object. Reserved metadata keys are daily_time, weekly_day, and weekly_time; every other top-level key is a named entry with cmd and every, plus optional enabled and max_runtime.

The scheduler's runtime reader, load_config, is forgiving: malformed entries are skipped, reserved metadata is extracted separately, and invalid per-entry data is not fatal. Writes go through solstone/think/schedule_config.py, the sole write owner for the file. That owner is fail-visible for whole-file malformation: malformed JSON or a non-object top-level value raises instead of clobbering existing bytes.

Agent System#

Unified Priority Execution#

All scheduled prompts (both generators and tool-using agents) share a unified priority system. The journal think command executes prompts ordered by priority, from lowest (runs first) to highest (runs last).

Priority is required for all scheduled prompts. Prompts without a priority field will fail validation. Suggested priority bands:

Band Range Use Case
Generators 10-30 Content-producing prompts that create .md files
Analysis Agents 40-60 Agents that analyze generated content
Late-stage 90+ Agents that run after most others complete
Fun/Optional 99 Low-priority or experimental prompts

After each generator completes and creates output, the indexer runs --rescan-file for incremental indexing. A full --rescan runs in the post phase.

Cortex: Central Talent Manager#

The Cortex service (journal cortex) is the central system for managing AI talent instances and generators. It monitors the journal's talents/ directory for new requests and manages execution. All talent spawning should go through Cortex for proper event tracking and management.

Cortex routes requests based on configuration:

  • Requests with tools field → tool-using talents (python -m solstone.think.talents)
  • Requests with output field (no tools) → generators (python -m solstone.think.talents)

Both types are handled by the unified python -m solstone.think.talents execution module.

To spawn talents programmatically, use the cortex_client functions:

from solstone.think.cortex_client import cortex_request
from solstone.think.callosum import CallosumConnection

# Create a request
use_id = cortex_request(
    prompt="Your task here",
    name="default",
    provider="openai"  # or "google", "anthropic", "local"
)

# Watch for talent events via Callosum
def on_event(message):
    # Filter for cortex tract events
    if message.get('tract') != 'cortex':
        return

    print(f"Event: {message['event']}")
    if message.get('event') == 'finish':
        print(f"Result: {message.get('result')}")

watcher = CallosumConnection()
watcher.start(callback=on_event)
# ... later, when done:
watcher.stop()

Spawning Generators via Cortex#

Generators can also be spawned via cortex_request by including an output field:

from solstone.think.cortex_client import cortex_request, wait_for_uses

# Spawn a generator
use_id = cortex_request(
    prompt="",  # Generators don't use prompts
    name="activity",
    config={
        "day": "20250109",
        "output": "md",
        "refresh": True,  # Regenerate even if output exists
    }
)

# Wait for completion
completed, timed_out = wait_for_uses([use_id], timeout=300)

Brain Health CLI#

Use journal brain status to inspect the active thinking lane and journal brain refresh to run one bounded active-brain check:

journal brain status
journal brain refresh

Provider resolution lives in solstone/think/models.py. Generate and cogitate share the single explicit providers.active provider/model selected in the Thinking app. There is no key-presence fallback, tier override, backup route, or talent-specific provider route. Configure cloud API keys in the env section of journal/config/journal.json; the bundled local provider requires no API key.

Provider modules#

The registry in solstone/think/providers/__init__.py maps cloud provider names to solstone/think/providers/openhands.py and maps local to solstone/think/providers/local.py. Effective provider modules expose:

  • run_generate() - Sync text generation, returns GenerateResult
  • run_agenerate() - Async text generation, returns GenerateResult
  • run_cogitate() - Tool-calling execution via sol call commands and event streaming

For direct LLM calls, use think.models.generate() or think.models.agenerate(); they route through the active brain.

Generator map keys#

think.talent.get_talent_configs(has_tools=False) reads the .md prompt files under solstone/talent/ and returns a dictionary keyed by generator name. Each entry contains:

  • path – the prompt file path
  • color – UI color hex string
  • mtime – modification time of the .md file
  • Additional keys from JSON frontmatter such as title, description, hook, or load

The hook field enables output processing by invoking named hooks like "schedule". The load key controls transcript/percept/agent source filtering for generators. See APPS.md for the full schema.

Cortex API#

Cortex is the central agent management system that all agent spawning should go through. See CORTEX.md for complete documentation of the Cortex API and agent event structures.

Using cortex_client#

The think.cortex_client module provides functions for interacting with Cortex:

from solstone.think.cortex_client import cortex_request, cortex_uses

# Create an agent request
request_file = cortex_request(
    prompt="Your prompt",
    name="default",
    provider="openai"
)

# List running and completed agents
agents_info = cortex_uses(limit=10, use_type="live")
print(f"Found {agents_info['live_count']} running agents")

Talent Module#

AI agent system and tool-calling support for solstone.

Commands#

Command Purpose
journal cortex Agent orchestration service
journal brain status Active-brain thinking status
journal brain refresh Bounded active-brain check

Architecture#

Cortex (orchestrator)
   ├── Callosum connection (events)
   ├── Tool execution via `sol call`
   └── Agent subprocess management
          ↓
   Providers (openai, google, anthropic, local)

Providers#

Provider Module Features
OpenAI solstone/think/providers/openhands.py GPT models via OpenHands/LiteLLM
Google solstone/think/providers/openhands.py Gemini models via OpenHands/LiteLLM
Anthropic solstone/think/providers/openhands.py Claude via OpenHands/LiteLLM
Local solstone/think/providers/local.py Bundled llama-server, BYO OpenAI-compatible endpoint, and confidential local endpoint

Effective provider modules implement run_generate(), run_agenerate(), and run_cogitate() functions. Cloud vendor leaf modules implement generate only; OpenHands owns cloud cogitate. See PROVIDERS.md for implementation details.

Key Components#

  • cortex.py - Central agent manager, file watcher, event distribution, spawns agents.py
  • cortex_client.py - Client functions: cortex_request(), cortex_uses(), wait_for_uses()
  • agents.py - Unified CLI entry point for both tool-using agents and generators (NDJSON protocol)
  • models.py - Unified generate()/agenerate() API, provider routing, token logging
  • batch.py - Batch class for concurrent LLM requests with dynamic queuing

Agent Personas#

System prompts in solstone/talent/*.md (markdown with JSON frontmatter). Apps can add custom agents in solstone/apps/{app}/talent/.

JSON metadata supports title, provider, model, tools, schedule, priority, multi_facet, and load keys. Cogitate prompts may set cwd: "journal"; when omitted they default to journal, and repo is rejected. Generators reject cwd.

Important: The priority field is required for all prompts with a schedule. Prompts without explicit priority will fail validation. See the Unified Priority Execution section for priority bands.

See APPS.md for the load schema and inline template variables that control source filtering and prompt context.

Documentation#