Skip to main content
specialists5 ship by default

ethos · personality is architecture

Theagentframeworkwherepersonalityisarchitecture.

Each personality is a structural component, not a prompt. A curated toolset. A first-person identity. A memory scope. Specialists ship by default.

mit · node 24 · typescript strict · zero deps in the types layer

# install ethos
$ pnpm add -g @ethosagent/cli

# methodical · cites sources · flags uncertainty
$ ethos chat --personality researcher
> What is the strongest evidence for emergent abilities at scale?

tabs are personalities. swap them — the agent's behavior, tools, and memory scope change with the file.

Personality, not "an agent."

A generic agent has every tool. That is its problem. The toolset is the union of every task you might ever do, which is a security surface, a cost surface, and a quality surface. Voice is mush. Memory is a pile.

Personalities invert it. Each has a curated toolset, a first-person identity (ETHOS.md), and a memory scope. Researcher gets the 8 tools it needs. Reviewer gets 3 and a per-personality memory scope so its code-review notes never leak into your coach session.

Specialization, not configuration. Personality is architecture, not a system prompt in a costume.

researchermethodical · cites sources · flags uncertainty
"There are three families. The first is dense embedding retrieval, used by most open-source vector stores."
web_search web_extract web_crawl read_file search_files memory_read memory_write session_search
8 tools
claude-opus-4-7
memory · global
engineerterse · code-first · runs commands to verify
"On it. Plan: move apps/tui/src/agent-bridge.ts to packages/agent-bridge, update tui imports."
terminal read_file write_file patch_file search_files web_search web_extract execute_code run_tests lint
10 tools
claude-sonnet-4-6
memory · global
reviewercritical · evidence-based · always explains why
"Two real concerns. The token rotation logic at auth.ts:47 has a TOCTOU race."
read_file search_files session_search
3 tools
claude-sonnet-4-6
memory · per-personality
coachwarm but direct · question-led · helps you think
"OK. Stuck on what specifically? Walk me through what you tried so far."
web_search web_extract memory_read memory_write session_search
5 tools
claude-opus-4-7
memory · global
operatorcautious · confirms before destructive · documents everything
"Found 247 run logs older than 30 days totaling 4.2MB. Will dry-run first. OK?"
terminal read_file write_file patch_file search_files execute_code run_tests
7 tools
claude-sonnet-4-6
memory · per-personality

AgentLoop is a 9-step generator.

Every component is an interface, injected at construction. Personality decides which tools enter step 9 and which model handles step 8.

  user input
       │
       ▼
  ┌──────────────────────────────────────────────────────┐
  │  AgentLoop.run(input, options)                       │
  │  ─────────────────────────────────────────────────   │
  │  1. resolve or create session                        │
  │  2. fire session_start hooks                         │
  │  3. persist user message                             │
  │  4. load history (trimmed)                           │
  │  5. prefetch memory (per personality scope)          │
  │  6. build system prompt from injectors               │
  │  7. before-prompt-build modifying hooks              │
  │  8. agentic loop (LLM stream → tool calls → LLM ...) │
  │  9. pre-flight hooks → execute tools → collect       │
  └──────────────────────────────────────────────────────┘
       │
       ▼
  AsyncGenerator<AgentEvent>
       │ text_delta, thinking_delta, tool_start, tool_end,
       │ tool_progress, usage, done, error
       ▼
  surfaces: cli · tui · vscode · email · telegram · slack
read architecture overview →

Why not LangChain, CrewAI, or AutoGen? Personality as a structural component, not a string. Strict toolset isolation. ACP-native swarm.

see the comparison →