Skip to content

Agents and Subagents

An agent defines the AI's behavior, including system prompts, available tools, and subagents. You can use built-in agents or create custom agents.

Built-in agents

Pythinker Code provides built-in primary agents. You can select one at startup with the --agent flag:

sh
pythinker --agent ask
pythinker --agent debug
pythinker --agent okabe

default

The default agent, suitable for general use. Enabled tools:

Agent, RunAgents, ReadSkill, AskUserQuestion, SetTodoList, UpdateGoal, Progress, Suggest, Memory, Recall, Scratchpad, Shell, TaskList, TaskOutput, TaskInput, TaskHandoff, TaskStop, ReadFile, ReadMediaFile, Glob, Grep, SmartSearch, WriteFile, StrReplaceFile, SearchWeb, FetchURL, ListMcpResources, ReadMcpResource, EnterPlanMode, ExitPlanMode

ask

Read-only primary mode for answering questions, explaining code, and recommending approaches without modifying the workspace.

debug

Primary mode for systematic failure diagnosis. It reproduces or inspects failure evidence first, narrows root-cause hypotheses, then applies a minimal fix only when implementation is clearly requested.

okabe

An experimental agent for testing new prompts and tools. It inherits from default but defines its own tool list, which adds SendDMail (D-Mail checkpoint rollback).

Repository markdown agents

Pythinker Code also auto-discovers project-local markdown subagents compatible with Claude-style agent files. Put *.md files in one of these directories at the project root (the nearest .git ancestor of the working directory):

  • .pythinker/agents/
  • .claude/agents/
  • .agents/agents/
  • .codex/agents/

Each markdown file can define YAML frontmatter followed by the subagent system prompt:

markdown
---
name: local-reviewer
description: Review this repository's conventions
tools: ["Read", "Grep", "Glob", "Bash"]
---
You are a repository-specific reviewer. Read nearby tests before reporting findings.

Recognized frontmatter fields are name, description, tools, model, and when_to_use. Common Claude tool names are translated to Pythinker tools, for example ReadReadFile, GrepGrep, GlobGlob, BashShell, WriteWriteFile, and EditStrReplaceFile. Unknown tool names are skipped with a log warning. Discovered markdown agents appear as Agent tool subagent types alongside the built-in types.

Agent definition validation rollout

Pythinker currently resolves YAML and repository markdown definitions into one agent catalogue. Unknown definition fields are accepted with one aggregated startup warning per source in this release. Warnings identify the field path but do not include field values, prompt content, or raw absolute source paths.

The production policy will reject unknown fields in the immediately following minor release. Fix warnings before upgrading: required YAML definitions will then fail to load, while an invalid optional markdown definition will be skipped with a diagnostic. The existing LaborMarket compatibility interface and generated markdown YAML wrappers will remain for that strict-default release. Their earliest removal is one additional minor release later, and only after direct catalogue launch has equivalent prompt, model, tool-policy, required-MCP, foreground, and background behavior.

Custom agent files

Agents are defined in YAML format. Load a custom agent with the --agent-file flag:

sh
pythinker --agent-file /path/to/my-agent.yaml

Basic structure

yaml
version: 1
agent:
  name: my-agent
  system_prompt_path: ./system.md
  tools:
    - "pythinker_code.tools.shell:Shell"
    - "pythinker_code.tools.file:ReadFile"
    - "pythinker_code.tools.file:WriteFile"

Inheritance and overrides

Use extend to inherit another agent's configuration and only override what you need to change:

yaml
version: 1
agent:
  extend: default  # Inherit from default agent
  system_prompt_path: ./my-prompt.md  # Override system prompt
  exclude_tools:  # Exclude certain tools
    - "pythinker_code.tools.web:SearchWeb"
    - "pythinker_code.tools.web:FetchURL"

extend: default inherits from the built-in default agent. You can also specify a relative path to inherit from another agent file.

Configuration fields

FieldDescriptionRequired
extendAgent to inherit from, can be default or a relative pathNo
nameAgent nameYes (optional when inheriting)
system_prompt_pathSystem prompt file path, relative to agent fileYes (optional when inheriting)
system_prompt_argsCustom arguments passed to system prompt, merged when inheritingNo
modelDefault model alias for this agent or subagentNo
modeAgent mode: primary, subagent, all, or hiddenNo
hiddenHide this agent from default selection / background support metadataNo
stepsPer-agent maximum steps per turnNo
temperatureAgent model temperature metadataNo
top_pAgent model top-p metadataNo
toolsTool list, format is module:ClassNameYes (optional when inheriting)
allowed_toolsTool allowlist used instead of the inherited full tool listNo
exclude_toolsTools to excludeNo
subagentsSubagent definitionsNo

System prompt built-in parameters

The system prompt file is a Markdown template that can use ${VAR} syntax to reference variables and supports the Jinja2 {% include %} directive to include other files. Built-in variables include:

VariableDescription
${PYTHINKER_NOW}Current time (ISO format)
${PYTHINKER_WORK_DIR}Working directory path
${PYTHINKER_WORK_DIR_LS}Working directory file list
${PYTHINKER_AGENTS_MD}Merged AGENTS.md content from project root to working directory
${PYTHINKER_SKILLS}Loaded skills list
${PYTHINKER_ADDITIONAL_DIRS_INFO}Information about additional directories added via --add-dir or /add-dir

You can also define custom parameters via system_prompt_args:

yaml
agent:
  system_prompt_args:
    MY_VAR: "custom value"

Then use ${MY_VAR} in the prompt.

System prompt example

markdown
# My Agent

You are a helpful assistant. Current time: ${PYTHINKER_NOW}.

Working directory: ${PYTHINKER_WORK_DIR}

${MY_VAR}

Defining subagents in agent files

Subagents can handle specific types of tasks. After defining subagents in an agent file, the main agent can launch them via the Agent tool:

yaml
version: 1
agent:
  extend: default
  subagents:
    coder:
      path: ./coder-sub.yaml
      description: "Handle coding tasks"
    reviewer:
      path: ./reviewer-sub.yaml
      description: "Code review expert"

Subagent files are also standard agent format, typically inheriting from the main agent:

yaml
# coder-sub.yaml
version: 1
agent:
  extend: ./agent.yaml  # Inherit from main agent
  system_prompt_args:
    ROLE_ADDITIONAL: |
      You are now running as a subagent...

Built-in subagent types

The default agent configuration includes focused built-in subagent types with different tool policies and use cases:

TypePurposeAvailable tools
coderGeneral software engineering with judgment: read/write files, run commands, search codeRead/search tools, Shell, write tools, web tools
implementerScoped implementation with minimal edits and quick verificationRead/search tools, Shell, write tools, web tools
exploreFast read-only codebase exploration: search, read, summarizeRead/search tools and Shell; no write tools
planImplementation planning and architecture designRead/search tools and web tools; no write tools
plannerRead-only recon planner that decomposes broad work into parallel seedsRead/search tools and Shell; no write tools
scoutRead-only external docs, dependency-source, and API freshness researcherRead/search tools, Shell, web tools; no write tools
reviewRead-only severity-scored code reviewRead/search tools and Shell; no write tools
code-reviewerDiff-focused code review for the current branchRead/search tools and Shell; no write tools
security-reviewerDiff-focused security review with validated findingsRead/search tools and Shell; no write tools
debuggerRoot-cause analysis for failures, logs, and stack tracesRead/search tools and Shell; no write tools
verifierRead-only validation runner for tests, lint, type checks, and buildsRead/search tools and Shell; no write tools
judgeIndependent final quality gate for answers, reports, and code-change summariesRead/search tools and Shell; no write tools

All subagent types are prohibited from nesting the Agent tool (subagents cannot create their own subagents). The Agent tool is only available to the root agent.

Reviewer-class types (review, code-reviewer, security-reviewer, debugger, judge, verifier, explore) run offline by design: their permission profiles block network and external doc-lookup tools because the content they analyze is untrusted. Third-party claims they cannot verify from the repository come back under RISKS as needs verification items; the parent agent resolves those against live docs — directly or by dispatching scout, the online research type (plan also keeps web access for planning research).

How subagents run

Subagents launched via the Agent tool run in an isolated context and return results to the main agent when complete. Each subagent instance maintains its own context history and metadata under subagents/<agent_id>/ in the session directory, and can be resumed across multiple invocations. Advantages of this approach:

  • Isolated context, avoiding pollution of main agent's conversation history
  • Multiple independent tasks can be processed in parallel
  • Subagents can have targeted system prompts
  • Persistent instances preserve context across multiple calls

Built-in tools list

The following are all built-in tools in Pythinker Code.

Agent

  • Path: pythinker_code.tools.agent:Agent
  • Description: Start or resume a subagent instance for a focused task. Multiple built-in subagent types are available — for example coder, implementer, explore, plan, planner, scout, review, code-reviewer, security-reviewer, debugger, verifier, and judge; see the built-in subagent types table above for each one's tool policy. Each instance maintains its own context history and supports foreground or background execution.
ParameterTypeDescription
descriptionstringShort task description (3-5 words)
promptstringDetailed task description
subagent_typestringBuilt-in subagent type, default coder
modelstringOptional model override
resumestringOptional agent instance ID to resume an existing instance
run_in_backgroundboolWhether to run in background, default false
timeoutintTimeout in seconds, range 30–3600. Foreground defaults to no timeout (runs until completion), background defaults to the configured limit (1 hour); the task is stopped if the limit is exceeded
dependenciesarrayOptional background task IDs this task depends on. Metadata only — launch dependent tasks after their prerequisites are ready
budget_secondsintOptional time budget (seconds) recorded as planning/synthesis metadata
isolationstringnone (default) or worktree. worktree records a git-worktree isolation intent for background agents; ignored for foreground runs

RunAgents

  • Path: pythinker_code.tools.agent:RunAgents
  • Description: Launch a batch of subagents (1–8) in one call, sharing a common base_prompt and each running its own prompt. Foreground batches run the children concurrently and return all results inline; background batches return task IDs immediately, and if a background batch exceeds the available slots only the fitting prefix is launched while the rest are reported as deferred. Like Agent, this tool is only available to the root agent.
ParameterTypeDescription
summarystringShort summary of the multi-agent run
base_promptstringShared context prepended to every child prompt
agentsarrayChild agents to launch (1–8); each has its own objective
agents[].namestringStable short name for the child agent
agents[].promptstringChild-specific task prompt
agents[].titlestringOptional 3–5 word display title, defaults to name
agents[].subagent_typestringBuilt-in subagent type for the child, default coder
modelstringOptional model override applied to every child
run_in_backgroundboolWhether to run in background, default true
timeoutintOptional per-agent timeout in seconds, range 30–3600
isolationstringnone (default) or worktree for background children

To keep parallel children distinguishable in the task list, tree, and notifications, any child whose name is generic (or collides with a sibling) is given a stable adjective-noun codename (for example amber-falcon), while its subagent type stays visible separately.

AskUserQuestion

  • Path: pythinker_code.tools.ask_user:AskUserQuestion
  • Description: Present structured questions and options to the user during execution, collecting preferences or decisions. Suitable for scenarios where the user needs to choose between approaches, resolve ambiguous instructions, or provide requirements. Should not be overused — only call when the user's choice genuinely affects subsequent actions.
ParameterTypeDescription
questionsarrayQuestions list (1–4 questions)
questions[].questionstringQuestion text, ending with ?
questions[].headerstringShort label, max 12 characters (e.g., Auth, Style)
questions[].optionsarrayAvailable options (2–4), the system adds an "Other" option automatically
questions[].options[].labelstringOption label (1–5 words), append (Recommended) for recommended options
questions[].options[].descriptionstringOption description
questions[].multi_selectboolAllow multiple selections, default false

SetTodoList

  • Path: pythinker_code.tools.todo:SetTodoList
  • Description: Manage todo list, track task progress. Supports three usage modes: update mode (pass todos array to replace the entire list), query mode (omit todos to return the current list), and clear mode (pass an empty array [] to clear the list). Todo items are persisted to session state.
ParameterTypeDescription
todosarray | nullTodo list items. Omit to query the current list; pass [] to clear
todos[].titlestringTodo item title
todos[].statusstringStatus: pending, in_progress, done

Shell

  • Path: pythinker_code.tools.shell:Shell
  • Description: Execute shell commands. Requires user approval. Uses the appropriate shell for the OS (bash/zsh on Unix, PowerShell on Windows).
ParameterTypeDescription
commandstringCommand to execute
timeoutintTimeout in seconds, default 60, max 300 for foreground / 86400 for background
run_in_backgroundboolWhether to run as a background task, default false
descriptionstringShort description for the background task, required when run_in_background=true

When run_in_background=true, the command is launched as a background task and the tool immediately returns a task ID, allowing the AI to continue working. The system automatically sends a notification when the task completes. Ideal for long-running builds, tests, watchers, and servers.

ReadFile

  • Path: pythinker_code.tools.file:ReadFile
  • Description: Read text file content. Max 1000 lines per read, max 2000 characters per line. Files outside working directory require absolute paths. Every read returns the total number of lines in the file. Sensitive files (such as .env, SSH private keys, and cloud credentials) are rejected.
ParameterTypeDescription
pathstringFile path
line_offsetintStarting line number, default 1. Supports negative values to read from the end of the file (e.g. -100 reads the last 100 lines); absolute value cannot exceed 1000
n_linesintNumber of lines to read, default/max 1000

ReadMediaFile

  • Path: pythinker_code.tools.file:ReadMediaFile
  • Description: Read image or video files. Max file size 100MB. Only available when the model supports image/video input. Files outside working directory require absolute paths.
ParameterTypeDescription
pathstringFile path

Glob

  • Path: pythinker_code.tools.file:Glob
  • Description: Match files and directories by pattern. Returns max 1000 matches, patterns starting with ** not allowed. Can also search within discovered skill roots, and ~ in paths is expanded to the user's home directory.
ParameterTypeDescription
patternstringGlob pattern (e.g., *.py, src/**/*.ts)
directorystringSearch directory, defaults to working directory
include_dirsboolInclude directories, default true

Grep

  • Path: pythinker_code.tools.file:Grep
  • Description: Search file content with regular expressions, based on ripgrep. Hidden files (dotfiles) are searched by default, but files excluded by .gitignore are not. Sensitive files (such as .env, SSH private keys, and cloud credentials) are always filtered out, even when include_ignored is set.
ParameterTypeDescription
patternstringRegular expression pattern
pathstringSearch path, defaults to current directory
globstringFile filter (e.g., *.js)
typestringFile type (e.g., py, js, go)
output_modestringOutput mode: files_with_matches (default), content, count_matches
-BintShow N lines before match
-AintShow N lines after match
-CintShow N lines before and after match
-nboolShow line numbers, default true
-iboolCase insensitive
multilineboolEnable multiline matching
head_limitintLimit output lines, default 250
offsetintSkip first N results for pagination, default 0
include_ignoredboolSearch files excluded by .gitignore (e.g. node_modules, build artifacts), default false

WriteFile

  • Path: pythinker_code.tools.file:WriteFile
  • Description: Write files. Requires user approval. Absolute paths are required when writing files outside the working directory.
ParameterTypeDescription
pathstringAbsolute path
contentstringFile content
modestringoverwrite (default) or append

StrReplaceFile

  • Path: pythinker_code.tools.file:StrReplaceFile
  • Description: Edit files using string replacement. Requires user approval. Absolute paths are required when editing files outside the working directory.
ParameterTypeDescription
pathstringAbsolute path
editobject/arraySingle edit or list of edits
edit.oldstringOriginal string to replace
edit.newstringReplacement string
edit.replace_allboolReplace all matches, default false

SearchWeb

  • Path: pythinker_code.tools.web:SearchWeb
  • Description: Search the web. Requires search service configuration (auto-configured on Pythinker platform).
ParameterTypeDescription
querystringSearch keywords
limitintNumber of results, default 5, max 20
include_contentboolInclude page content, default false

FetchURL

  • Path: pythinker_code.tools.web:FetchURL
  • Description: Fetch webpage content, returns extracted main text. Uses fetch service if configured, otherwise uses local HTTP request.
ParameterTypeDescription
urlstringURL to fetch

Think

  • Path: pythinker_code.tools.think:Think
  • Description: Let the agent record thinking process, suitable for complex reasoning scenarios
ParameterTypeDescription
thoughtstringThinking content

SendDMail

  • Path: pythinker_code.tools.dmail:SendDMail
  • Description: Send delayed message (D-Mail), for checkpoint rollback scenarios
ParameterTypeDescription
messagestringMessage to send
checkpoint_idintCheckpoint ID to send back to (>= 0)

EnterPlanMode

  • Path: pythinker_code.tools.plan.enter:EnterPlanMode
  • Description: Request to enter plan mode. After calling, an approval request is presented to the user unless the session is in YOLO or auto mode; YOLO auto-approves entering plan mode, but ExitPlanMode still presents the final plan for user approval. Use this only when the user explicitly requests planning or when there is significant architectural ambiguity. See Plan mode.

This tool takes no parameters.

ExitPlanMode

  • Path: pythinker_code.tools.plan:ExitPlanMode
  • Description: Submit a plan for user approval while in plan mode. Before calling, the plan must be written to the plan file. This tool reads the plan file content and presents it to the user for approval. The user can select an implementation path (exit plan mode and start execution), reject (stay in plan mode and wait for feedback), or provide revision comments. See Plan mode.
ParameterTypeDescription
optionslist | nullWhen the plan contains multiple alternative implementation paths, list 2–3 options for the user to choose from. Each option has a label (1–8 word short name, may append "(Recommended)") and an optional description (brief summary). The labels "Approve", "Reject", and "Revise" are reserved and cannot be used.

TaskList

  • Path: pythinker_code.tools.background:TaskList
  • Description: List background tasks in the current session. Useful for re-enumerating task IDs after context compaction or checking which tasks are still running.
ParameterTypeDescription
active_onlyboolList only active tasks, default true
limitintMaximum number of tasks to return (1–100), default 20

TaskOutput

  • Path: pythinker_code.tools.background:TaskOutput
  • Description: Retrieve output and status of a background task. Returns a non-blocking status/output snapshot by default; use ReadFile with the returned output_path to read the full log if output is truncated.
ParameterTypeDescription
task_idstringTask ID to query
blockboolWhether to wait for task completion, default false
timeoutintMaximum wait time in seconds when block=true (0–3600), default 30

TaskStop

  • Path: pythinker_code.tools.background:TaskStop
  • Description: Stop a running background task. Requires user approval. Use only when a task must be cancelled; for normal completion, wait for the automatic notification. Not available in plan mode.
ParameterTypeDescription
task_idstringTask ID to stop
reasonstringReason for stopping (optional), default "Stopped by TaskStop"

Tool security boundaries

Workspace scope

  • File reading and writing are typically done within the working directory (and additional directories added via --add-dir or /add-dir)
  • Absolute paths are required when reading files outside the workspace
  • Write and edit operations require user approval; absolute paths are required when operating on files outside the workspace

Approval mechanism

The following operations require user approval:

OperationApproval required
Shell command executionEach execution
File write/editEach operation
MCP tool callsEach call
Stop background taskEach stop