Pi từ mã nguồnpi v1.4.0

Chương 3Phần 1: Bối cảnh

Bản đồ monorepo

Mười một package, đồ thị phụ thuộc giữa chúng, và nên đọc theo thứ tự nào.

  • 5 phút đọc
  • 5 đoạn code
  • 7 mục
Trong chương này7 mục
  1. Mười một package
  2. Đồ thị phụ thuộc: hai chồng tách biệt
  3. Phụ thuộc bên ngoài đáng chú ý
  4. Ngoài packages/
  5. Quy ước kỹ thuật
  6. Những package đã biến mất
  7. Nên đọc theo thứ tự nào

Repo earendil-works/pi là một monorepo dùng npm workspaces: mọi package nằm dưới packages/, cùng chung một package-lock.json và cùng số phiên bản (mọi package ở tag này đều là 1.4.0). Chương này vẽ bản đồ để bạn biết mỗi thư mục làm gì, package nào dựa trên package nào, và nên đọc theo thứ tự nào.

Mười một package#

Số dòng dưới đây đếm các file .ts/.tsx trong src/ của từng package ở v1.4.0 (không gồm test); số file test đếm trong test/. README gốc liệt kê bảy package công khai chính (README.md:72–84); bốn package còn lại là phụ trợ.

Thư mụcTên npmVai tròDòng srcFile testChương
ai@earendil-works/pi-aiAPI thống nhất cho mọi provider LLM, danh mục mô hình, OAuth27.854184pi-ai, provider
agent@earendil-works/pi-agent-coreVòng lặp agent: gọi mô hình, chạy tool, hàng đợi steer/follow-up2.5397agent-core
coding-agent@earendil-works/pi-coding-agentCLI pi: session, tool, extension, các chế độ chạy, SDK76.067321từ AgentSession trở đi
tui@earendil-works/pi-tuiThư viện giao diện terminal vẽ lại theo vi sai19.62353pi-tui
codemode@earendil-works/pi-codemodeSandbox JavaScript (QuickJS) mà khả năng duy nhất là gọi tool được tiêm vào3.0378Codemode
mcp@earendil-works/pi-mcpClient Model Context Protocol độc lập (stdio, HTTP, OAuth)3.2776Codemode, MCP
chord@earendil-works/chordRuntime có kiểu cho plugin, contract, state nhân bản và RPC qua JSON14.61262Chord
durable@earendil-works/pi-durableHarness bền: hội thoại, task và document lưu bằng commit nguyên tử27.259121Pi Durable
env@earendil-works/pi-envMôi trường thực thi từ xa cho Pi Durable: daemon nhỏ triển khai qua SSH2.3468pi-env
telemetry@earendil-works/pi-telemetryHợp đồng telemetry trung lập nhà cung cấp: span, event, metric1.5728telemetry
evals@earendil-works/pi-evalsBộ đánh giá coding agent bằng vitest (không phát hành như thư viện)1.4466evals

Bài công bố Pi Durable nói harness này khoảng 15.000 dòng không tính test. Ở v1.4.0, thư mục src/ của nó đã khoảng 27.000 dòng, vì gồm cả các backend storage, bộ kiểm thử tuân thủ trong src/testing/, môi trường Node và code mode bền; phần lõi harness vẫn nhỏ hơn nhiều.

Đồ thị phụ thuộc: hai chồng tách biệt#

Điều quan trọng nhất cần nhận ra khi nhìn các file package.json: Pi không phải một khối, mà là hai chồng dùng chung tầng dưới.

  Chồng coding agent (CLI pi)                    Chồng Pi Durable (thư viện, thử nghiệm)

      pi-telemetry                                    pi-telemetry
           │                                          │          │
           ▼                                          ▼          ▼
         pi-ai                                      pi-ai      chord      pi-codemode
           │                                          │          │            │
           ▼                                          └──────────┼────────────┘
     pi-agent-core    pi-tui    pi-mcp    pi-codemode            ▼
           │            │         │           │              pi-durable
           └────────────┴─────────┴─────┬─────┘                  │
                                        ▼                        ▼
                                 pi-coding-agent              pi-env
Mũi tên đi từ package nền tới package dùng nó. pi-coding-agent không phụ thuộc pi-durable hay chord; pi-durable không phụ thuộc pi-agent-core. Hai chồng gặp nhau ở pi-ai, pi-codemode và pi-telemetry.

Phụ thuộc nội bộ của coding agent nằm ngay đầu khối dependencies:

coding-agent dựa trên agent-core, ai, codemode, mcp và tui
pi/packages/coding-agent/package.jsondòng 43–48JSON
"dependencies": {	"@earendil-works/pi-agent-core": "1.4.0",	"@earendil-works/pi-ai": "1.4.0",	"@earendil-works/pi-codemode": "1.4.0",	"@earendil-works/pi-mcp": "1.4.0",	"@earendil-works/pi-tui": "1.4.0",

Còn Pi Durable dựa trên Chord, pi-ai, pi-codemode và pi-telemetry, không có pi-agent-core:

pi-durable có vòng lặp riêng, không dùng agent-core
pi/packages/durable/package.jsondòng 152–156JSON
"dependencies": {	"@earendil-works/chord": "1.4.0",	"@earendil-works/pi-ai": "1.4.0",	"@earendil-works/pi-codemode": "1.4.0",	"@earendil-works/pi-telemetry": "1.4.0",

Thứ tự build trong package.json gốc chính là một thứ tự topo của đồ thị trên: telemetry, chord, tui, codemode, mcp, ai, durable, env, agent, rồi coding-agent.

Workspaces và lệnh build của monorepo (dòng 16 rất dài, hãy cuộn ngang)
pi/./package.jsondòng 5–16JSON
"workspaces": [	"packages/*",	"apps/*",	"packages/coding-agent/examples/extensions/with-deps",	"packages/coding-agent/examples/extensions/custom-provider-anthropic",	"packages/coding-agent/examples/extensions/custom-provider-gitlab-duo",	"packages/coding-agent/examples/extensions/sandbox",	"packages/coding-agent/examples/extensions/gondolin"],"scripts": {	"clean": "npm run clean --workspaces",	"build": "cd packages/telemetry && npm run build && cd ../chord && npm run build && cd ../tui && npm run build && cd ../codemode && npm run build && cd ../mcp && npm run build && cd ../ai && npm run build && cd ../durable && npm run build && cd ../env && npm run build && cd ../agent && npm run build && cd ../coding-agent && npm run build",

Phụ thuộc bên ngoài đáng chú ý#

Danh sách phụ thuộc bên ngoài cho biết mỗi package tự làm gì và giao gì cho thư viện khác:

  • pi-ai dùng SDK chính thức của từng provider (@anthropic-ai/sdk, openai, @google/genai, AWS Bedrock), partial-json để đọc đối số tool khi nó còn đang stream, và typebox cho schema của tool (ai/package.json).
  • pi-coding-agent dùng jiti để nạp extension viết bằng TypeScript lúc chạy, quickjs-wasi cho codemode, @silvia-odwyer/photon-node để xử lý ảnh, diff cho tool edit, highlight.js để tô màu code trong terminal, undici cho HTTP, proper-lockfile để khoá file cấu hình khi nhiều tiến trình cùng ghi (coding-agent/package.json).
  • pi-tui chỉ cần marked (parse Markdown) và get-east-asian-width (độ rộng ký tự CJK); phần còn lại, kể cả thuật toán vẽ, là tự viết.
  • pi-durable dùng @silvia-odwyer/photon (bản WebAssembly, chạy được cả trên Cloudflare), diff và typebox; còn lại đều là code của chính nó và Chord.

Các package thư viện công khai nhiều điểm vào con (subpath exports) để ứng dụng chỉ nạp phần mình cần. Ví dụ pi-ai có ./models, ./providers/*, ./api/*, ./oauth (ai/package.json:13), còn pi-durable tách riêng từng backend storage (./storage/sqlite/node, ./storage/sqlite/cloudflare, ./storage/jsonl/node, ./storage/indexeddb), các tool (./tools), code mode (./codemode) và bộ kiểm thử tuân thủ (./testing) (durable/package.json:8). Nhờ vậy một Durable Object trên Cloudflare không phải kéo theo code chỉ dành cho Node.

Ngoài packages/#

Đường dẫnNội dung
AGENTS.md, CONTRIBUTING.mdQuy tắc cho người và agent đóng góp; quy trình duyệt issue/PR.
.pi/Tài nguyên Pi của chính repo: prompt template (/cl kiểm changelog, /is phân tích issue, /pr review PR, /wr “wrap it”: changelog, commit, push), skill (release, add-llm-provider, interactive-testing, github-work) và vài extension nhỏ. Đây là cách maintainer dùng Pi để phát triển Pi.
scripts/Kiểm tra (pin dependency, import, install lock), phát hành, đóng gói, sinh danh mục mô hình.
test.sh, pi-test.shChạy test trong môi trường cô lập (HOME, tmp, cache riêng); chạy Pi từ mã nguồn ở bất kỳ thư mục nào.
flake.nix, nix/Build Pi bằng Nix (thêm ở 1.0.1), kèm bản ghim danh mục mô hình để build offline.
.github/CI và các workflow tự động đóng issue/PR của người mới.

Một prompt template của maintainer trông như sau: frontmatter có mô tả và gợi ý đối số, thân là chỉ dẫn, và $ARGUMENTS được thay bằng những gì gõ sau lệnh. Cơ chế này được giải thích trong chương Extensions.

Prompt template /is mà maintainer dùng để phân tích issue
pi/.pi/prompts/is.mddòng 1–5Markdown
---description: Analyze GitHub issues (bugs or feature requests)argument-hint: "<issue>"---Analyze GitHub issue(s): $ARGUMENTS

Quy ước kỹ thuật#

TypeScript chạy thẳng, không biên dịch khi phát triển
Từ 0.99.0 repo dùng TypeScript 7.0 (target ES2024) để kiểm kiểu và build, còn khi chạy từ mã nguồn thì dùng chế độ bỏ kiểu có sẵn của Node thay cho tsx (CHANGELOG:463). Hệ quả là quy tắc chỉ dùng cú pháp xoá được (AGENTS.md:24), và các import tương đối ghi rõ đuôi .ts.
Định dạng và lint bằng Biome
Thụt lề bằng tab, dòng tối đa 120 ký tự; file models.generated.ts được loại khỏi kiểm tra (biome.json:19–36). Trang này hiển thị tab rộng 2 ký tự.
Danh mục mô hình được sinh ra
Không ai sửa tay packages/ai/src/models.generated.ts; nó được sinh bằng script, còn dữ liệu mô hình chi tiết trong providers/data/ bị gitignore (AGENTS.md:28). Vì vậy bản clone của bạn không có dữ liệu đó; chương pi-ai giải thích nó được nạp thế nào.
Tài nguyên của coding agent đi qua src/config.ts
Code không dùng __dirname trực tiếp mà gọi helper trong config.ts, vì cùng một mã phải chạy từ checkout, từ gói npm và từ binary độc lập (AGENTS.md:22).
Test cô lập
test.sh tạo HOME, thư mục tạm và cache npm riêng, chỉ cho qua các biến môi trường cần thiết, và bỏ qua test cần gọi LLM thật khi không có khoá API (test.sh:4–13). Phần lớn test dùng vitest; riêng pi-tui dùng node:test.

Điểm vào của lệnh pi ngắn đúng sáu dòng; mọi thứ còn lại bắt đầu từ main(), được giải thích trong chương Các chế độ chạy:

packages/coding-agent/src/cli.ts: điểm vào của CLI
pi/packages/coding-agent/src/cli.tsdòng 1–6TypeScript
#!/usr/bin/env nodeimport { setupCli } from "./cli/setup.ts";import { main } from "./main.ts";setupCli();main(process.argv.slice(2));

Những package đã biến mất#

Nếu đọc issue cũ, changelog hay blog, bạn sẽ gặp các package không còn trong packages/. Lịch sử git cho biết chúng đi đâu:

PackageTồn tạiSố phận
pods2025-08-09 → 2026-04-30Công cụ triển khai vLLM; gỡ cùng mom.
mom2025-11-26 → 2026-04-30Bot Slack dựa trên Pi; mảng chat nay ở repo earendil-works/pi-chat (README.md:86).
web-ui2025-10-05 → 2026-05-20Thành phần giao diện web cho chat; gỡ khỏi workspace.
browser-extension2025-10-01 → 2025-10-06Chuyển sang repo riêng (sitegeist).
proxy, agent-old2025-10 → 2025-11/12Thử nghiệm sớm, đã gỡ.
server, protocol, client2026-07 → 2026-10-12Bộ client/server từ xa thử nghiệm của coding agent (giao thức CBOR); gỡ sau khi Pi Durable ra đời.
session-backends/sqlite-node2026-08-05 → 2026-10-01Backend SQLite cho harness thử nghiệm trong agent-core; gỡ cùng harness đó.

Nên đọc theo thứ tự nào#

Tài liệu này đi từ dưới lên, khớp với đồ thị phụ thuộc. Nếu bạn có mục tiêu cụ thể, có thể nhảy thẳng:

Mục lục

Giao diện