### Install via Script on Windows Source: https://penguin.ooo/docs/installation Executes the PowerShell installation script for Windows systems. ```powershell irm https://penguin.ooo/install.ps1 | iex ``` -------------------------------- ### Offline Installation on Linux or macOS Source: https://penguin.ooo/docs/installation Executes the local installation script after transferring the release bundle to the target machine. ```bash ./install.sh ``` -------------------------------- ### Offline Installation on Windows Source: https://penguin.ooo/docs/installation Executes the local installation script after transferring the release bundle to the target machine. ```powershell .\install.ps1 ``` -------------------------------- ### Initialize Environment Source: https://penguin.ooo/docs/interfaces Example of instantiating an Environment with a workspace directory and tool configuration. ```typescript const environment = new Environment({ workspaceDir, toolConfig, sessionScratchpadDir, // e.g. //agents//scratchpad/ }); ``` -------------------------------- ### Start the Web Application Source: https://penguin.ooo/docs/web-app Command to initialize the web server and access the interface via the browser. ```bash penguin web # open http://127.0.0.1:7364 ``` -------------------------------- ### Install PenguinHarness via CLI Source: https://penguin.ooo/docs/quickstart Use this command to install PenguinHarness on Linux or macOS systems. ```bash curl -fsSL https://penguin.ooo/install.sh | sh ``` -------------------------------- ### Verify Installation Source: https://penguin.ooo/docs/installation Checks the installed version of PenguinHarness. ```bash penguin -v ``` -------------------------------- ### Configure Windows Installation Environment Source: https://penguin.ooo/docs/installation Environment variables for customizing the installation directory, version pinning, and local archive usage on Windows. ```powershell $env:PENGUIN_VERSION = "vX.Y.Z" ``` ```powershell $env:PENGUIN_ARCHIVE = "" ``` -------------------------------- ### Start the Web Application Source: https://penguin.ooo/docs/quickstart Launch the web service locally. The default address is http://127.0.0.1:7364. ```bash penguin web ``` -------------------------------- ### POST /tasks Source: https://penguin.ooo/docs/server-api Start a new task within the session. ```APIDOC ## POST /api/sessions/:sessionId/tasks ### Description Start a Task. With `queueIfBusy`, a busy session holds the input as a follow-up. ### Method POST ### Endpoint /api/sessions/:sessionId/tasks ### Request Body - **input** (array) - Required - TaskInputPart[] - **thinkingLevel** (number) - Optional - **queueIfBusy** (boolean) - Optional ``` -------------------------------- ### Define project models in TOML Source: https://penguin.ooo/docs/configuration Example configuration for a model entry including pricing and provider details. ```toml default_model = { provider = "deepseek", model_id = "deepseek-v4-flash" } [[models]] provider = "deepseek" model_id = "deepseek-v4-flash" context_window = 1000000 vision = false api_key = "sk-..." [models.pricing] unit = "usd_per_mtok" cache_read = 0.003571 cache_write = 0.428571 output = 0.857143 ``` -------------------------------- ### Install Penguin CLI via npm Source: https://penguin.ooo/docs/installation Installs the Penguin CLI globally using npm. Requires Node.js version 24 or higher. ```bash npm install -g @prismshadow/penguin-cli ``` -------------------------------- ### Define Project Model Configuration Source: https://penguin.ooo/docs/models Example structure for the .project_config.toml file defining default models and individual model entries. ```toml default_model = { provider = "deepseek", model_id = "deepseek-v4-flash" } vision_model = { provider = "google", model_id = "gemini-3.1-pro-preview" } [[models]] provider = "deepseek" model_id = "deepseek-v4-flash" context_window = 1000000 [[models]] provider = "custom" model_id = "my-model" client_type = "openai" base_url = "https://llm.example.com/v1" api_key = "sk-..." ``` -------------------------------- ### Start Interactive Chat Source: https://penguin.ooo/docs/quickstart Initiate an interactive chat session with the agent. ```bash penguin chat ``` -------------------------------- ### GET /files Source: https://penguin.ooo/docs/server-api Browse the workspace directory. ```APIDOC ## GET /api/sessions/:sessionId/files ### Description Browse the Workspace directory. ### Method GET ### Endpoint /api/sessions/:sessionId/files ### Query Parameters - **path** (string) - Required - The directory path to browse ``` -------------------------------- ### Define a scheduled task in TOML Source: https://penguin.ooo/docs/configuration Example configuration for a recurring task that triggers a prompt every 12 hours starting from a specific date. ```toml prompt = "Check yesterday's builds and summarize the failures" enabled = true start_at = 2026-08-01T09:00:00Z period = "12h" ``` -------------------------------- ### Update the Penguin CLI Source: https://penguin.ooo/docs/cli Upgrades the current installation in place using the detected installation method. ```bash penguin update --check # report versions only penguin update # upgrade to the latest release, after confirming ``` -------------------------------- ### Configure Agent Settings Source: https://penguin.ooo/docs/configuration Example of a partial-override configuration for an agent. Note that writing a key replaces the default wholesale, and the system_prompt is mandatory. ```yaml name: default_agent description: General-purpose agent version: 3 # Required: keep the full generated default template ({{AGENTS_MD}} and friends; elided here). system_prompt: | … max_turns: 100 model: max_tokens: 32000 thinking_level: medium timeoutMs: 120000 compaction: max_context_length: 128000 max_session_turns: -1 mode: summarize # Omitting the whole tools section = the full default toolset. Writing tools.builtin # REPLACES the default list wholesale: carry the complete definition (including the # parameters JSON Schema) for every tool you keep — see Tools & Approval. ``` -------------------------------- ### GOAL.yaml File Structure Source: https://penguin.ooo/docs/goal-mode The initial structure of the GOAL.yaml file created at the start of a goal. ```yaml objective: make all tests pass status: active ``` -------------------------------- ### GET /usage Source: https://penguin.ooo/docs/server-api Retrieve usage statistics for the project. ```APIDOC ## GET /api/projects/:projectId/usage ### Description Retrieve usage statistics for the project. ### Method GET ### Endpoint /api/projects/:projectId/usage ### Query Parameters - **from** (string) - Optional - Start date filter. - **to** (string) - Optional - End date filter. - **groupBy** (string) - Optional - Field to group results by. - **agentId** (string) - Optional - Filter by agent ID. - **provider** (string) - Optional - Filter by provider. - **modelId** (string) - Optional - Filter by model ID. ``` -------------------------------- ### Pin Version during Windows Installation Source: https://penguin.ooo/docs/installation Sets the PENGUIN_VERSION environment variable before executing the installation script to target a specific release. ```powershell $env:PENGUIN_VERSION = "vX.Y.Z"; irm https://penguin.ooo/install.ps1 | iex ``` -------------------------------- ### GET / Source: https://penguin.ooo/docs/server-api Retrieve session information. ```APIDOC ## GET /api/sessions/:sessionId/ ### Description Retrieve session information. The single-session GET additionally carries `tracePath`, the absolute path of the latest Trace file. ### Method GET ### Endpoint /api/sessions/:sessionId/ ``` -------------------------------- ### Streaming sequence diagram Source: https://penguin.ooo/docs/omni-message Visual representation of the streaming lifecycle from start to completion. ```text partial_text(start) → partial_text(delta) → … → partial_text(stop) → text (complete) └── concatenation of all deltas ≡ the complete message ──┘ (truncation applies to both alike) ``` -------------------------------- ### GET /agents Source: https://penguin.ooo/docs/server-api List all agents associated with the project. ```APIDOC ## GET /api/projects/:projectId/agents ### Description List all agents associated with the project. ### Method GET ### Endpoint /api/projects/:projectId/agents ``` -------------------------------- ### GET /api/projects Source: https://penguin.ooo/docs/server-api Retrieves a list of projects accessible to the current user. ```APIDOC ## GET /api/projects ### Description Returns a list of projects visible to the current user. ### Method GET ### Endpoint /api/projects ``` -------------------------------- ### GET /api/version Source: https://penguin.ooo/docs/server-api Retrieves the running release identity of the server. ```APIDOC ## GET /api/version ### Description Returns the running release identity including version and build date. ### Method GET ### Endpoint /api/version ### Response #### Success Response (200) - **version** (string) - The current version - **buildDate** (string) - The release date of the version ``` -------------------------------- ### GET /api/events Source: https://penguin.ooo/docs/server-api Establishes a per-user SSE stream for handshakes and cross-session notifications. ```APIDOC ## GET /api/events ### Description Provides a real-time stream for user-wide events, including the initial 'hello' handshake and notifications such as schedule firings or session creation. ### Method GET ### Endpoint /api/events ``` -------------------------------- ### GET /scratchpad/:fileName Source: https://penguin.ooo/docs/server-api Serves untrusted bytes from uploads or Agent-written temp files with strict security lockdowns. ```APIDOC ## GET /scratchpad/:fileName ### Description Serves untrusted file content. Images (.png, .jpg, .jpeg, .gif, .webp) are served inline, while all other files are served as 'application/octet-stream' with 'Content-Disposition: attachment'. ### Method GET ### Endpoint /scratchpad/:fileName ### Parameters #### Path Parameters - **fileName** (string) - Required - The name of the file to retrieve. ``` -------------------------------- ### Trace File Structure Source: https://penguin.ooo/docs/sessions-and-traces Example of the JSON Lines format used for Trace files, where each line represents a single OmniMessage envelope. ```json {"timestamp":"2026-07-18T03:10:22.531Z","type":"session_meta","payload":{"session_id":"session-2026-07-18-11-10-22-3f8a1c2d","provider":"deepseek","model_id":"deepseek-v4-pro","model_context_window":1000000,"system_prompt":"…","tools":[…],"agent_state":"/home/u/.penguin/data/default_project/agents/default_agent/agent_state","workspace":"/home/u/work"}} {"timestamp":"…","type":"event_msg","payload":{"type":"request_begin"}} {"timestamp":"…","type":"model_msg","payload":{"type":"text","role":"user","text":"Create hello.txt"}} {"timestamp":"…","type":"model_msg","payload":{"type":"tool_call","role":"assistant","name":"exec_command","arguments":"{\"cmd\":\"printf hi > hello.txt\"}","tool_call_id":"call_0"}} {"timestamp":"…","type":"event_msg","payload":{"type":"approval_decision","decision":"allow","tool_call_id":"call_0"}} {"timestamp":"…","type":"model_msg","payload":{"type":"tool_call_output","role":"user","output":"[no output]","tool_call_id":"call_0"}} {"timestamp":"…","type":"event_msg","payload":{"type":"request_end","status":"completed"}} {"timestamp":"…","type":"event_msg","payload":{"type":"token_usage","session":{…},"request":{…}}} ``` -------------------------------- ### GET /api/sessions/:sessionId/files/preview-redirect Source: https://penguin.ooo/docs/server-api Authenticates the caller and redirects to a separate origin for secure file previewing. ```APIDOC ## GET /api/sessions/:sessionId/files/preview-redirect ### Description Authenticates the caller, mints a short-lived HMAC token, and performs a 302 redirect to a different origin for previewing files. ### Method GET ### Endpoint /api/sessions/:sessionId/files/preview-redirect ### Parameters #### Path Parameters - **sessionId** (string) - Required - The ID of the session. #### Query Parameters - **path** (string) - Required - The path to the file to preview. ``` -------------------------------- ### GET /files/content Source: https://penguin.ooo/docs/server-api Retrieves file content with security headers. Supports preview and download modes. ```APIDOC ## GET /files/content ### Description Retrieves file content. Responses are treated as untrusted and include 'X-Content-Type-Options: nosniff'. ### Method GET ### Endpoint /files/content ### Parameters #### Query Parameters - **preview** (integer) - Optional - If set to 1, serves the file with its real content type and inline disposition. - **download** (integer) - Optional - If set to 1, serves the file as an attachment. ``` -------------------------------- ### Define provider-specific fidelity objects Source: https://penguin.ooo/docs/omni-message Examples of fidelity objects for different LLM providers, including Claude, GPT-5, and OpenAI-compatible formats. ```json // Claude: a thinking block closed by its signature { type: "thinking", thinking: "…", fidelity: { signature: "EqQBCkYIBxgCKkB…" } } // GPT-5: encrypted reasoning (empty thinking text, fidelity only) { type: "thinking", thinking: "", fidelity: { id: "rs_0d3…", encrypted_content: "gAAAA…" } } // OpenAI-compatible: the upstream field the reasoning text came from { type: "thinking", thinking: "…", fidelity: { reasoning_field: "reasoning_content" } } ``` -------------------------------- ### POST /api/sessions/:sessionId/tasks Source: https://penguin.ooo/docs/server-api Starts a new task within a specific session. The request body allows for providing input parts such as text, images, or file attachments. ```APIDOC ## POST /api/sessions/:sessionId/tasks ### Description Starts a new task within a specific session. The request body allows for providing input parts such as text, images, or file attachments. ### Method POST ### Endpoint /api/sessions/:sessionId/tasks ### Parameters #### Path Parameters - **sessionId** (string) - Required - The ID of the session to start the task in. #### Request Body - **input** (TaskInputPart[]) - Required - An array of input parts (text, image_url, or file). - **thinkingLevel** (string) - Optional - The thinking level for this task (none, low, medium, high, xhigh). ### Request Example { "input": [ { "type": "text", "text": "Analyze this file" }, { "type": "file", "fileName": "report.pdf", "dataUrl": "data:application/pdf;base64,..." } ], "thinkingLevel": "medium" } ``` -------------------------------- ### GET /api/sessions/:sessionId/stream Source: https://penguin.ooo/docs/server-api Establishes a per-session SSE stream to receive message streams and run events. ```APIDOC ## GET /api/sessions/:sessionId/stream ### Description Provides a real-time stream of messages and run events specific to a single session. ### Method GET ### Endpoint /api/sessions/:sessionId/stream ### Parameters #### Path Parameters - **sessionId** (string) - Required - The unique identifier of the session. ``` -------------------------------- ### GET /messages Source: https://penguin.ooo/docs/server-api Retrieves message history. If a session is active, the response includes a 'live' field containing a cursor and accumulated streaming fragments. ```APIDOC ## GET /messages ### Description Retrieves the message history. While a session is running or compacting, the response includes a 'live' field with a cursor and current streaming fragments to ensure the client can synchronize with in-progress streams. ### Method GET ### Endpoint /messages ### Response #### Success Response (200) - **messages** (OmniMessage[]) - The list of complete messages. - **live** (object, optional) - Contains the current stream state. - **cursor** (string) - The session channel's most recently assigned SSE event id. - **fragments** (OmniMessage[]) - Accumulated content for open streaming fragments. ``` -------------------------------- ### Environment Initialization Source: https://penguin.ooo/docs/interfaces How to instantiate the environment using EnvironmentConfig. ```APIDOC ## Environment Initialization ### Constructor new Environment(config: EnvironmentConfig) ### Configuration Parameters - **workspaceDir** (string) - The root directory for the workspace. - **toolConfig** (ToolConfig) - Configuration for custom tools and MCP servers. - **sessionScratchpadDir** (string, optional) - Directory for session-specific scratchpad data. - **services** (EnvironmentServices, optional) - Runtime services injected into tools. - **vault** (Record, optional) - Vault environment variables. ``` -------------------------------- ### Server Source Directory Layout Source: https://penguin.ooo/docs/server-api Overview of the server package structure, highlighting key modules for configuration, database, and runtime services. ```text packages/server/src ├── index.ts / config.ts / app.ts # startup entry · env config · Hono assembly (createApp binds no port — testable) ├── api/types.ts # the outward DTO contract (type-only import via the "./api" subpath) ├── auth/ # scrypt passwords, admin seeding, cookie sessions, auth middleware ├── db/ # node:sqlite connection, schema SQL, one repo per table ├── http/ # error bodies, request validation, SSE adapter, routes/ all route groups ├── runtime/ # session-manager (runtime driving) · channel (SSE ring buffer) │ # approvals · usage-recorder · scheduler · title-generator └── services/ # authorization rules, TOML/YAML config IO, Session/Trace/usage/snapshot services ``` -------------------------------- ### Manage model defaults, vision, and listing Source: https://penguin.ooo/docs/cli Commands to set the default model, configure the vision proxy model, or list all currently configured models. ```bash penguin config model default --model-id --provider penguin config model vision --model-id --provider penguin config model list ``` -------------------------------- ### Authenticate with the API Source: https://penguin.ooo/docs/server-api Use the initial admin password to log in and establish a session cookie. ```bash # Use the initial password printed at first start (or your changed one). curl -c cookies.txt -H "Content-Type: application/json" \ -d '{"userId":"admin","password":"penguin-1234"}' \ http://127.0.0.1:7364/api/auth/login ``` -------------------------------- ### Build Penguin from Source Source: https://penguin.ooo/docs/installation Clones the repository and builds the project using pnpm. Requires Node.js version 24 or higher and pnpm. ```bash git clone https://github.com/Prism-Shadow/penguin-harness.git cd penguin-harness pnpm install && pnpm build ``` -------------------------------- ### Initialize and run an agent session Source: https://penguin.ooo/docs/agent-loop Creates an agent session and iterates through the output stream using an approval callback and abort signal. ```typescript const agent = await createAgent({ agentId: "default_agent" }); const session = await agent.createSession({ workspaceDir: process.cwd() }); for await (const output of session.run([userText("Clean up the CSV files under data/")], { approve: async (toolCall) => "allow", signal: abortController.signal, })) { // output: partial_* fragments, complete model_msg, event_msg } ``` -------------------------------- ### Configure a Model Source: https://penguin.ooo/docs/quickstart Add a model provider and ID to the configuration. The API key can be provided inline or via environment variables. ```bash penguin config model add --provider deepseek --model-id deepseek-v4-flash --api-key sk-... --set-default ``` -------------------------------- ### Configure Custom Tools and MCP Servers Source: https://penguin.ooo/docs/tools The tools section in system_config.yaml allows wholesale replacement of the default toolset and configuration of MCP servers. ```yaml tools: # Writing builtin replaces the default toolset wholesale (this example deliberately # keeps a minimal single-tool set). builtin: - name: exec_command description: Run a shell command in the workspace. permission: rw # Optional per-tool toggle: false filters the `description` call argument # (declared in parameters.properties) out of the schema (missing = kept). call_description: false timeoutMs: 120000 maxOutputLength: 16000 # parameters: the complete JSON Schema is required (see the default definition # in packages/core/src/state/default-config.ts); elided here. mcpServers: [] ``` -------------------------------- ### POST /agents Source: https://penguin.ooo/docs/server-api Create a new agent. ```APIDOC ## POST /api/projects/:projectId/agents ### Description Create a new agent. ### Method POST ### Endpoint /api/projects/:projectId/agents ``` -------------------------------- ### Architectural Interface Overview Source: https://penguin.ooo/docs/interfaces Visual representation of the interaction flow between the Human boundary, context_engine, and the LLM/Environment interfaces. ```text Human (a boundary, not a class) session.run(newMessages, { approve, signal }) │ ▲ ▼ │ streamed OmniMessage context_engine │ │ LLMInterface │ │ EnvironmentInterface ▼ ▼ GenerativeModel Environment └─ AgentHub gateway └─ BuiltinTool registry (exec_command …) ``` -------------------------------- ### Project Directory Structure Source: https://penguin.ooo/docs/architecture Visual representation of the package hierarchy and file responsibilities within the repository. ```text packages/ ├── core/src │ ├── agent.ts / session.ts # the createAgent composition layer and Session (run / compact / generateTitle) │ ├── session-title.ts # one-shot title generation (out-of-band LLM call, never in Trace) │ ├── engine/context-engine.ts # ReAct loop orchestration: turn lifecycle, approvals, carry-over, reconnect, compaction │ ├── omnimessage/ # types.ts protocol types · builders.ts constructors · aggregate.ts partial aggregation │ ├── llm/ # generative-model.ts AgentHub adapter · tool-call-ids.ts id uniqueness │ ├── environment/ # environment.ts execution close-out · tools/ registry, 9 builtin tools, background sessions │ ├── state/ # paths · default-config · project-config · model-catalog │ │ # agent-state (Skill install, prompt assembly) · agent-vault · builtin-agents │ ├── trace/ # writer.ts append-only JSONL · resume.ts replay-based recovery │ └── internal/ # date and Session helpers ├── cli/src # commander entry + run / chat / config / serve commands and approval prompts ├── server/src # app assembly · db (node:sqlite) · auth · http/routes · runtime · services ├── web/src # api client · state · lib/omni stream rendering · components · feature pages ├── skills/ # loader + the skills//SKILL.md library ├── landing/ # the product landing page (with the blog) └── docs/ # this documentation site ``` -------------------------------- ### POST /api/auth/login Source: https://penguin.ooo/docs/server-api Authenticates a user and establishes a session. ```APIDOC ## POST /api/auth/login ### Description Logs in a user and returns the user object. ### Method POST ### Endpoint /api/auth/login ### Request Body - **userId** (string) - Required - The user identifier - **password** (string) - Required - The user password ### Response #### Success Response (200) - **user** (object) - The authenticated user object ``` -------------------------------- ### Web Application Source Directory Structure Source: https://penguin.ooo/docs/web-app Overview of the file organization within the web package, highlighting API, state management, and feature modules. ```text packages/web/src ├── api/ # fetch wrapper · one function per API (DTOs type-only from @prismshadow/penguin-server/api) · SSE wrapper ├── state/ # auth / project / sessions / theme / locale contexts ├── lib/omni/ # OmniMessage stream → view-model reducer; connect-first + dedup stream controller ├── components/ # ui primitives (modal / drawer / select …) and the app layout └── features/ # chat / agents / skills / models / usage / traces / benchmark / admin pages ``` -------------------------------- ### SubagentHandle.run Source: https://penguin.ooo/docs/interfaces Runs a prompt on an existing subagent session. ```APIDOC ## SubagentHandle.run ### Description Executes a prompt on a previously spawned subagent session. ### Parameters - **input** (Object) - Required - **prompt** (string) - Required - The prompt text. - **signal** (AbortSignal) - Optional - Used to interrupt the execution. - **approve** (ApproveFn) - Optional - The parent's approval callback. ### Returns - **AsyncGenerator** - A stream of response messages. ``` -------------------------------- ### agent.createSession Source: https://penguin.ooo/docs/agent-loop Initializes a new session for the agent within a specified workspace directory. ```APIDOC ## agent.createSession(options) ### Description Creates a new session for the agent to execute tasks within the provided workspace directory. ### Parameters - **workspaceDir** (string) - Required - The file system path to the workspace directory. ``` -------------------------------- ### Execute a One-shot Task Source: https://penguin.ooo/docs/quickstart Run a single task directly from the command line. ```bash penguin run -m "Create hello.txt containing Hello, Penguin" ``` -------------------------------- ### Create a user text message and validate with a guard Source: https://penguin.ooo/docs/omni-message Demonstrates initializing a user text message using the builder and checking its structure with a runtime guard. ```typescript import { userText, isCompleteModelMessage } from "@prismshadow/penguin-core"; const prompt = userText("List the files in the current directory"); // { timestamp: "…", type: "model_msg", payload: { type: "text", role: "user", text: "…" } } ``` -------------------------------- ### Benchmark Directory Structure Source: https://penguin.ooo/docs/self-improvement The file system layout for storing benchmark configurations, task statements, scoring rubrics, and evaluation records. ```text benchmarks// ├── benchmark_config.toml # Benchmark configuration (Builder runs is fixed at 1) ├── / │ ├── statement/ # the task given to the Target Agent │ └── rubric/ # private scoring rubric, isolated from the Target Agent └── scoreboard.yaml # evaluation records (current format) ``` -------------------------------- ### Define Skill Metadata Source: https://penguin.ooo/docs/skills The SKILL.md file requires frontmatter to define the skill's identity and behavior for the system prompt. ```yaml --- name: my-skill description: One-line English description injected into the system prompt. short_description: Short UI label. short_description_zh: 简短的中文标签。 version: 1 updated: 2026-07-17 --- # My Skill Concrete steps, boundaries and acceptance criteria... ``` -------------------------------- ### session.run Source: https://penguin.ooo/docs/agent-loop Executes a series of tasks within the session, supporting tool approval and cancellation signals. ```APIDOC ## session.run(messages, options) ### Description Runs the agent loop for a given set of messages. Returns an async iterable of output fragments and messages. ### Parameters - **messages** (Array) - Required - The input messages for the turn. - **options** (RunOptions) - Optional - Configuration for the execution. ### RunOptions - **signal** (AbortSignal) - Optional - Used to interrupt the execution (e.g., Ctrl-C). - **approve** (ApproveFn) - Optional - Callback for per-tool approval; denies by default if omitted. - **thinkingLevel** (ThinkingLevelName) - Optional - Sets the thinking level for the current run. ``` -------------------------------- ### System Architecture Diagram Source: https://penguin.ooo/docs/architecture Visual representation of the interaction between the core engine and various human-facing interfaces. ```text ┌─────────────┐ ┌─────────────────────────────┐ │ CLI │ │ Web App (React SPA) │ │ (penguin) │ │ ↑ OmniMessage over SSE │ │ │ │ Server (Hono + SQLite) │ └──────┬──────┘ └──────────────┬──────────────┘ │ session.run(...) │ ← Human boundary ┌──────┴────────────────────────┴──────────────┐ │ core: context_engine (ReAct loop) │ │ ├── LLMInterface ──→ AgentHub ──→ models │ │ ├── EnvironmentInterface ──→ builtin tools│ │ ├── Agent State (editable files) │ │ └── Trace (append-only JSONL) │ └──────────────────────────────────────────────┘ ``` -------------------------------- ### Add or update a model entry Source: https://penguin.ooo/docs/cli Configures a new model provider entry with required credentials and optional parameters. ```bash penguin config model add --provider deepseek --model-id deepseek-v4-pro --api-key sk-... --set-default ``` -------------------------------- ### SubagentRunner.spawn Source: https://penguin.ooo/docs/interfaces Spawns a new subagent session. ```APIDOC ## SubagentRunner.spawn ### Description Creates a new subagent session, returning a handle to control the subagent. ### Parameters - **input** (Object) - Required - **agentId** (string) - Optional - Defaults to the current agent. - **modelId** (string) - Optional - Inherits parent session model if omitted. ### Returns - **Promise** - A handle to interact with the spawned subagent. ``` -------------------------------- ### EnvironmentInterface Source: https://penguin.ooo/docs/interfaces The primary interface for interacting with the tool execution environment. ```APIDOC ## EnvironmentInterface ### listTools() Returns a promise that resolves to an array of ToolDefinition objects. ### executeTool(request: ToolExecutionRequest) Executes a tool based on the provided request. Returns an AsyncGenerator yielding OmniMessage fragments, ending with a complete tool_call_output. ### toolPermission(name: string) Returns the permission level ('r' | 'rw' | undefined) for a given tool name. ### dispose() Optional method to release runtime resources. ``` -------------------------------- ### Use the Penguin Core SDK Source: https://penguin.ooo/docs/quickstart Programmatically interact with an agent using the @prismshadow/penguin-core package. ```typescript import { createAgent, isCompleteModelMessage, userText } from "@prismshadow/penguin-core"; const agent = await createAgent({ agentId: "default_agent" }); const session = await agent.createSession({ workspaceDir: process.cwd() }); for await (const output of session.run([userText("Create hello.txt containing hi")], { approve: async () => "allow", })) { if (isCompleteModelMessage(output) && output.payload.type === "text") { console.log(output.payload.text); } } ``` -------------------------------- ### Command Execution and Input Tool Schemas Source: https://penguin.ooo/docs/tools Defines the required and optional parameters for executing shell commands and interacting with running command sessions. ```typescript // exec_command { cmd: string; // required: the shell command to run workdir?: string; // working directory; defaults to the Workspace root, relative paths resolve against it yield_time_ms?: number; // foreground wait; default 60000, minimum 250, capped below the tool timeout description: string; // required while call_description is on: one sentence shown to the user while the call runs, emitted first } // input_command { process_id: string; // required: the command-session id returned by exec_command chars?: string; // characters for stdin; send "\u0003" alone to deliver Ctrl-C; empty = poll only yield_time_ms?: number; // wait; defaults 250 for writes, 5000 for empty polls description: string; // required while call_description is on } ``` -------------------------------- ### PUT /files/content Source: https://penguin.ooo/docs/server-api Upload a file to the workspace. ```APIDOC ## PUT /api/sessions/:sessionId/files/content ### Description Upload a file to the workspace. Capped at 14MB. ### Method PUT ### Endpoint /api/sessions/:sessionId/files/content ### Query Parameters - **path** (string) - Required - Destination path ### Request Body - **dataBase64** (string) - Required - Base64 encoded file data ``` -------------------------------- ### Define ToolExecutionRequest and EnvironmentConfig Source: https://penguin.ooo/docs/interfaces Structures for requesting tool execution and configuring the environment, including workspace directories and service injections. ```typescript interface ToolExecutionRequest { toolCall: OmniMessage; // an approved call signal?: AbortSignal; approve?: ApproveFn; // forwarded to tools that spawn child Sessions (approval inheritance) } interface EnvironmentConfig { workspaceDir: string; toolConfig: ToolConfig; // { customTools: ToolDefinitionConfig[]; mcpServers: MCPServerConfig[] } sessionScratchpadDir?: string; // this Session's scratchpad (scratchpad/); enables truncated-output recovery services?: EnvironmentServices; // runtime services injected into individual tools vault?: Record; // Vault env vars, injected into exec_command / input_command subprocesses } interface EnvironmentServices { subagentRunner?: SubagentRunner; // needed by run_subagent visionDescriber?: VisionDescriberService; // needed by describe_image on text-only models commandSessions?: CommandSessionManager; // long-running command session registry (built by Environment) subagentSessions?: SubagentSessionManager;// background subagent session registry (likewise) } interface MCPServerConfig { name: string; config: Record; } ``` -------------------------------- ### input_command Source: https://penguin.ooo/docs/tools Interacts with a backgrounded command session using its process ID. ```APIDOC ## input_command ### Description Sends input to a backgrounded command session or polls for status. Sending "\u0003" delivers a Ctrl-C signal. ### Parameters - **process_id** (string) - Required - The command-session id returned by exec_command. - **chars** (string) - Optional - Characters for stdin; empty string polls only. - **yield_time_ms** (number) - Optional - Wait time; defaults 250 for writes, 5000 for empty polls. - **description** (string) - Required - One sentence shown to the user while the call runs. ``` -------------------------------- ### Configure PowerShell Execution Policy Source: https://penguin.ooo/docs/installation Command to allow local scripts if the PowerShell execution policy blocks the launcher. ```powershell Set-ExecutionPolicy -Scope CurrentUser RemoteSigned ``` -------------------------------- ### session.run Source: https://penguin.ooo/docs/interfaces Executes a sequence of messages within a session and returns a stream of responses. ```APIDOC ## session.run ### Description Executes a prompt within an active session and returns an asynchronous generator of messages. ### Parameters - **newMessages** (OmniMessage[]) - Required - The input prompt messages. - **opts** (RunOptions) - Optional - Configuration options for the run. ### RunOptions - **signal** (AbortSignal) - Optional - Used to interrupt the execution. - **approve** (ApproveFn) - Optional - Callback for per-tool approval. - **thinkingLevel** (ThinkingLevelName) - Optional - Sets the thinking level for this specific turn. ### Returns - **AsyncGenerator** - A stream of response messages. ``` -------------------------------- ### PenguinHarness Data Directory Layout Source: https://penguin.ooo/docs/sessions-and-traces The directory structure rooted at PENGUIN_HOME, defining where project configurations, agent states, traces, and workspaces are stored. ```text // ├── .project_config.toml # Project-level models & credentials (hidden file, 0600) └── agents/ └── / ├── agent_state/ # system_config.yaml, AGENTS.md, .vault.toml, │ # tools/, memory/, skills/, schedule/ ├── traces/ │ └── /_.jsonl ├── scratchpad/ # temp files, one subdirectory per Session id (e.g. pasted images) ├── shared_env/ # shared interpreter/tool environments (virtualenvs, pipx, │ # caches) the Agent creates on demand — a system prompt │ # convention, not a path the code creates, so tooling is │ # installed once for any task; project dependencies stay │ # in the project ├── workspaces/ # temp Workspaces (tmp-<8hex>) ├── benchmarks/ # capability Benchmark cases and scores └── snapshots/ # Agent State version snapshots ``` -------------------------------- ### Message Delivery Path Visualization Source: https://penguin.ooo/docs/message-flow A diagram illustrating the flow of messages between actors within a single turn, including stream generation and tool execution. ```text Human ──run(newMessages)──► engine engine ──write Prompt──────────────────► Trace engine ──request_begin──► Human and Trace engine ──streamGenerate(new messages)──► LLM ┌──────────── LLM streams partial_* and complete messages ────────┐ │ engine forwards each: simultaneously ──► Human (yield) │ │ and ──► Trace (write) │ └──────────────────────────────────────────────────────────────────┘ complete tool_call ──► engine: await approve(tc) (one at a time) engine ──approval_decision──► Human and Trace allow ──► Environment.executeTool (concurrent, never blocks the LLM stream) Environment ──partial_tool_call_output──► Human, and (complete) ──► Trace LLM stream ends: token_usage is its last message, request_end follows at once still-running tools keep streaming output (possibly after request_end) all outputs settled ──► reordered to original call order as the next turn's LLM input ``` -------------------------------- ### Define run options for agent tasks Source: https://penguin.ooo/docs/agent-loop Configuration interface for controlling task execution, including signal handling, tool approval, and thinking levels. ```typescript interface RunOptions { signal?: AbortSignal; // interrupt (e.g. Ctrl-C) approve?: ApproveFn; // per-tool approval; denies everything when omitted (conservative default) thinkingLevel?: ThinkingLevelName; // this run's thinking level (per-turn, carried through reconnect retries; compaction requests keep the default) } ``` -------------------------------- ### Set CLI UI language Source: https://penguin.ooo/docs/cli Updates the PENGUIN_LANG environment variable in the shell startup file to change the CLI interface language. ```bash penguin config lang en ``` -------------------------------- ### Manage vault environment variables Source: https://penguin.ooo/docs/cli Commands to set, list, or remove environment variables stored in the agent's vault. ```bash penguin config vault set --key GITHUB_TOKEN --value ghp_xxx penguin config vault list penguin config vault remove --key GITHUB_TOKEN ``` -------------------------------- ### Define BuiltinTool and ToolDefinitionConfig Source: https://penguin.ooo/docs/interfaces The contract for individual tools and their configuration definitions, including permission levels and timeout settings. ```typescript interface BuiltinTool { name: string; definition: ToolDefinitionConfig; execute( args: Record, ctx: ToolExecutionContext, // { workspaceDir, toolCallId, signal?, approve? } ): AsyncGenerator; } interface ToolDefinitionConfig { name: string; description: string; parameters?: Record; // JSON Schema permission?: "r" | "rw"; forModel?: "vision" | "text-only"; // assembled per session-model class timeoutMs?: number; // default 120000; <=0 disables maxOutputLength?: number; // default 16000, head-kept truncation; <=0 disables } ``` -------------------------------- ### Define Message Origin Structure Source: https://penguin.ooo/docs/omni-message Demonstrates how messages are structured with and without origin tags for subagent tracking. ```javascript // message from the main Session: no origin { timestamp: "…", type: "model_msg", payload: { type: "text", … } } // message from a one-level Subagent: origin = [child Session id] { timestamp: "…", type: "model_msg", origin: ["session-2026-07-18-…-a1b2c3d4"], payload: { … } } ``` -------------------------------- ### Task and Approval Request Interfaces Source: https://penguin.ooo/docs/server-api Defines the request structures for creating tasks and submitting approval decisions for tool calls. ```typescript // POST /api/sessions/:sessionId/tasks — start a Task interface TaskCreateRequest { input: TaskInputPart[]; // Thinking level for this Task (a per-turn parameter, one of the five names; 400 otherwise); // omitted = falls back to the Agent config thinkingLevel?: "none" | "low" | "medium" | "high" | "xhigh"; } type TaskInputPart = | { type: "text"; text: string } | { type: "image_url"; imageUrl: string } // pasted images arrive as data URLs // File attachment: base64 data: URL, ≤10MB each (413 file_too_large beyond that), at most 20 // per request and 12MB of decoded bytes in total (413 too_many_files / payload_too_large; // all three are checked before anything is written). The server writes it into the Session // scratchpad and appends an `[attached file: ]` line to the message text — the model // opens the file by path. `fileName` carries no path separators; on disk it keeps its own // words (`报告 2026.pdf` → `报告-2026.pdf`: non-ASCII survives, shell-hostile ASCII becomes // `-`), so a name is readable in the message and safe to paste into a command. | { type: "file"; fileName: string; dataUrl: string }; // POST /api/sessions/:sessionId/approvals/:toolCallId interface ApprovalDecisionRequest { decision: "allow" | "deny"; } ``` -------------------------------- ### write_file Source: https://penguin.ooo/docs/tools Writes content to a file, creating it if it does not exist or overwriting it if it does. ```APIDOC ## write_file ### Description Writes full content to a file. Creates parent directories as needed. ### Parameters - **file_path** (string) - Required - Path to the file. - **content** (string) - Required - Full file content. ``` -------------------------------- ### Preview redirect flow Source: https://penguin.ooo/docs/server-api The preview redirect process involves authenticating the caller and redirecting to a separate origin using a short-lived HMAC token. ```http GET /api/sessions/:sessionId/files/preview-redirect?path=index.html 302 Location: http://localhost:7364/preview//index.html GET /preview// (unauthenticated; the token is the credential) ``` -------------------------------- ### Define CompactionSettings Interface Source: https://penguin.ooo/docs/agent-loop Interface defining the configuration parameters for compaction, including thresholds and modes. ```typescript interface CompactionSettings { maxContextLength: number; // context-token threshold (last token_usage's request.total); <=0 disables maxSessionTurns: number; // cumulative Session turn threshold (counted across Tasks); <=0 = unlimited mode: "summarize" | "discard"; prompt: string; // the Prompt used by summarize compaction } ``` -------------------------------- ### Image Tool API Definitions Source: https://penguin.ooo/docs/tools Definitions for image reading and description tools. These tools support png, jpeg, gif, and webp formats up to 5MB. ```typescript // read_image (vision models) { source: string; // required: an http(s) URL, or a file path inside the Workspace } // describe_image (text-only models) { source: string; // required: as above prompt?: string; // what to ask about the image; defaults to a detailed description } ``` -------------------------------- ### Define session_meta and ToolDefinition interfaces Source: https://penguin.ooo/docs/omni-message Defines the structure for session metadata and tool definitions used within the OmniMessage protocol. ```typescript interface SessionMetaPayload { session_id: string; provider: string; // one half of the model-identity pair model_id: string; // the upstream request id sent to AgentHub model_context_window: number | string; system_prompt: string; // fully assembled, placeholders substituted tools: ToolDefinition[]; // the complete tool schema sent to the model agent_state: string; // absolute path of the Agent State workspace: string; // absolute path of the Workspace source?: "subagent" | "schedule"; // session origin; absent = user-created } interface ToolDefinition { name: string; description: string; parameters?: Record; // JSON Schema } ``` -------------------------------- ### exec_command Source: https://penguin.ooo/docs/tools Executes a shell command. If the command exceeds the foreground yield time, it is moved to the background and returns a process ID for further interaction. ```APIDOC ## exec_command ### Description Executes a shell command. If the command finishes within the foreground window, it returns the full output and exit code. If it outruns the yield time, it backgrounds the process and returns the output so far along with a process_id. ### Parameters - **cmd** (string) - Required - The shell command to run. - **workdir** (string) - Optional - Working directory; defaults to the Workspace root. - **yield_time_ms** (number) - Optional - Foreground wait time; default 60000, minimum 250. - **description** (string) - Required - One sentence shown to the user while the call runs. ``` -------------------------------- ### describe_image Source: https://penguin.ooo/docs/tools Describes an image using a text-only model via the configured vision_model. ```APIDOC ## describe_image ### Description Forwards an image and an optional prompt to the project's configured vision_model to generate a text description. ### Parameters - **source** (string) - Required - An http(s) URL or a file path inside the Workspace. - **prompt** (string) - Optional - Specific question about the image; defaults to a detailed description. ``` -------------------------------- ### Run a single task with penguin run Source: https://penguin.ooo/docs/cli Executes a single message or task and exits, returning a non-zero exit code if the task fails. ```bash penguin run -m "Summarize the code structure of this directory" ``` -------------------------------- ### POST /approvals/:toolCallId Source: https://penguin.ooo/docs/server-api Submit an approval decision. ```APIDOC ## POST /api/sessions/:sessionId/approvals/:toolCallId ### Description Submit an approval decision for a tool call. ### Method POST ### Endpoint /api/sessions/:sessionId/approvals/:toolCallId ### Request Body - **decision** (string) - Required - 'allow' or 'deny' ``` -------------------------------- ### POST /agents/:agentId/sessions Source: https://penguin.ooo/docs/server-api Create a new session for a specific agent. ```APIDOC ## POST /api/projects/:projectId/agents/:agentId/sessions ### Description Create a new session for a specific agent. ### Method POST ### Endpoint /api/projects/:projectId/agents/:agentId/sessions ### Request Body - **modelId** (string) - Optional - The model ID to use. - **provider** (string) - Optional - The provider to use. - **workspace** (string) - Optional - The workspace path. - **approvalMode** (string) - Optional - The approval mode (defaults to allow-all). ``` -------------------------------- ### Import Server DTO Types Source: https://penguin.ooo/docs/server-api Use this import statement to access type-only definitions from the server API package. ```typescript import type { ServerEvent, SessionInfo } from "@prismshadow/penguin-server/api"; ```