alp-code 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/CHANGELOG.md +770 -0
  2. package/LICENSE +21 -0
  3. package/README.md +295 -0
  4. package/alp.config.yaml +5 -0
  5. package/dist/src/agents/agent-definition.js +28 -0
  6. package/dist/src/agents/capability-catalog.js +33 -0
  7. package/dist/src/agents/compaction.js +36 -0
  8. package/dist/src/agents/errors.js +12 -0
  9. package/dist/src/agents/librarian.js +38 -0
  10. package/dist/src/agents/main.js +37 -0
  11. package/dist/src/agents/memory-grant.js +29 -0
  12. package/dist/src/agents/model-context.js +70 -0
  13. package/dist/src/agents/modes.js +134 -0
  14. package/dist/src/agents/oracle.js +36 -0
  15. package/dist/src/agents/read-thread.js +38 -0
  16. package/dist/src/agents/registry.js +238 -0
  17. package/dist/src/agents/render-identity.js +38 -0
  18. package/dist/src/agents/review.js +37 -0
  19. package/dist/src/agents/search.js +37 -0
  20. package/dist/src/agents/shared/house-rules.js +33 -0
  21. package/dist/src/agents/shared/principal.js +18 -0
  22. package/dist/src/agents/shared/voice.js +29 -0
  23. package/dist/src/agents/titling.js +32 -0
  24. package/dist/src/agents/types.js +15 -0
  25. package/dist/src/backend/execution-backend.js +2 -0
  26. package/dist/src/backend/local-execution-store.js +144 -0
  27. package/dist/src/backend/local-process-backend.js +533 -0
  28. package/dist/src/backend/local-supervisor.js +104 -0
  29. package/dist/src/cli/alp.js +380 -0
  30. package/dist/src/cli/commands/context.js +203 -0
  31. package/dist/src/cli/commands/delegate.js +136 -0
  32. package/dist/src/cli/commands/identity-sync.js +31 -0
  33. package/dist/src/cli/commands/init.js +184 -0
  34. package/dist/src/cli/commands/mode.js +22 -0
  35. package/dist/src/cli/commands/principal.js +114 -0
  36. package/dist/src/cli/commands/run-main.js +90 -0
  37. package/dist/src/cli/commands/runtime.js +21 -0
  38. package/dist/src/cli/mode-preference-store.js +62 -0
  39. package/dist/src/cli/mode-selector.js +178 -0
  40. package/dist/src/cli/update-check.js +77 -0
  41. package/dist/src/context/checkpoint.js +134 -0
  42. package/dist/src/context/compact-journal.js +153 -0
  43. package/dist/src/context/compact-payload.js +121 -0
  44. package/dist/src/context/continuity.js +70 -0
  45. package/dist/src/context/types.js +2 -0
  46. package/dist/src/delegation/backend-registry.js +40 -0
  47. package/dist/src/delegation/delegation-service.js +300 -0
  48. package/dist/src/delegation/types.js +12 -0
  49. package/dist/src/execution/execution-policy.js +96 -0
  50. package/dist/src/execution/execution-service.js +115 -0
  51. package/dist/src/execution/execution-store.js +78 -0
  52. package/dist/src/execution/identity-capsule.js +65 -0
  53. package/dist/src/execution/types.js +12 -0
  54. package/dist/src/hooks/execution-bridge.js +84 -0
  55. package/dist/src/index.js +4 -0
  56. package/dist/src/memory/adapters/markdown-file-store.js +257 -0
  57. package/dist/src/memory/adapters/memory-api-client.js +2 -0
  58. package/dist/src/memory/adapters/memory-path-mapper.js +76 -0
  59. package/dist/src/memory/adapters/remote-api-store.js +25 -0
  60. package/dist/src/memory/context-ranker.js +21 -0
  61. package/dist/src/memory/errors.js +58 -0
  62. package/dist/src/memory/memory-service.js +149 -0
  63. package/dist/src/memory/memory-store.js +2 -0
  64. package/dist/src/memory/types.js +2 -0
  65. package/dist/src/policy/capability-policy.js +29 -0
  66. package/dist/src/policy/delegation-policy.js +25 -0
  67. package/dist/src/policy/errors.js +10 -0
  68. package/dist/src/policy/invariants.js +31 -0
  69. package/dist/src/policy/memory-policy.js +22 -0
  70. package/dist/src/policy/policy-engine.js +85 -0
  71. package/dist/src/policy/types.js +8 -0
  72. package/dist/src/policy/workspace-policy.js +77 -0
  73. package/dist/src/principal/principal-profile-store.js +89 -0
  74. package/dist/src/runtime/adapter-files.js +147 -0
  75. package/dist/src/runtime/claude-adapter.js +177 -0
  76. package/dist/src/runtime/codex-adapter.js +169 -0
  77. package/dist/src/runtime/permission-rules.js +156 -0
  78. package/dist/src/runtime/render-session-context.js +124 -0
  79. package/dist/src/runtime/render-task-input.js +33 -0
  80. package/dist/src/runtime/runtime-adapter.js +2 -0
  81. package/dist/src/runtime/runtime-preference-store.js +66 -0
  82. package/dist/src/runtime/runtime-selector.js +178 -0
  83. package/dist/src/runtime/types.js +2 -0
  84. package/dist/src/runtime/windows-shim.js +57 -0
  85. package/dist/src/state-paths.js +49 -0
  86. package/dist/src/workflow/output-validator.js +27 -0
  87. package/dist/src/workflow/repair-policy.js +8 -0
  88. package/dist/src/workflow/types.js +22 -0
  89. package/dist/src/workflow/workflow-runner.js +81 -0
  90. package/hooks/compact-record.cjs +109 -0
  91. package/hooks/session-boot.cjs +112 -0
  92. package/hooks/session-end.cjs +34 -0
  93. package/package.json +48 -0
  94. package/scaffold/memory/INDEX.md +27 -0
  95. package/scaffold/memory/README.md +76 -0
  96. package/scaffold/memory/projects/INDEX.md +22 -0
  97. package/scaffold/memory/projects/PROTOCOL.md +128 -0
  98. package/scaffold/memory/projects/_template/PROJECT.md +45 -0
  99. package/scripts/alp.cjs +126 -0
  100. package/scripts/alp.ps1 +4 -0
  101. package/scripts/alp.sh +3 -0
  102. package/scripts/bootstrap.cjs +144 -0
  103. package/scripts/checkout-release.cjs +30 -0
  104. package/scripts/delegate.cjs +19 -0
  105. package/scripts/doctor.cjs +158 -0
  106. package/scripts/doctor.sh +3 -0
  107. package/scripts/ensure-state.cjs +22 -0
  108. package/scripts/lib/cli-link.cjs +375 -0
  109. package/scripts/lib/codex-role.cjs +18 -0
  110. package/scripts/lib/delegation/command-runner.cjs +108 -0
  111. package/scripts/lib/delegation/config.cjs +81 -0
  112. package/scripts/lib/install-paths.cjs +154 -0
  113. package/scripts/lib/release-manifest.cjs +42 -0
  114. package/scripts/lib/semver-lite.cjs +20 -0
  115. package/scripts/lib/state.cjs +274 -0
  116. package/scripts/lib/uninstall.cjs +252 -0
  117. package/scripts/lib/update-check-worker.cjs +21 -0
  118. package/scripts/lib/update.cjs +395 -0
  119. package/scripts/run-role.cjs +42 -0
  120. package/scripts/run-role.ps1 +4 -0
  121. package/scripts/run-role.sh +3 -0
  122. package/scripts/sync-project-index.sh +167 -0
  123. package/skills/agent-memory/SKILL.md +109 -0
  124. package/skills/alp-debug/SKILL.md +90 -0
  125. package/skills/alp-debug/references/defense-in-depth.md +118 -0
  126. package/skills/alp-debug/references/investigation-methodology.md +106 -0
  127. package/skills/alp-debug/references/log-and-ci-analysis.md +96 -0
  128. package/skills/alp-debug/references/performance-diagnostics.md +112 -0
  129. package/skills/alp-debug/references/reporting-standards.md +120 -0
  130. package/skills/alp-debug/references/root-cause-tracing.md +134 -0
  131. package/skills/alp-debug/references/systematic-debugging.md +93 -0
  132. package/skills/alp-debug/references/verification.md +86 -0
  133. package/skills/alp-debug/scripts/find-polluter.sh +63 -0
  134. package/skills/alp-debug/scripts/find-polluter.test.md +102 -0
  135. package/skills/alp-plan/SKILL.md +128 -0
  136. package/skills/alp-plan/references/archive-workflow.md +77 -0
  137. package/skills/alp-plan/references/codebase-understanding.md +55 -0
  138. package/skills/alp-plan/references/output-standards.md +96 -0
  139. package/skills/alp-plan/references/plan-organization.md +129 -0
  140. package/skills/alp-plan/references/red-team-personas.md +76 -0
  141. package/skills/alp-plan/references/red-team-workflow.md +81 -0
  142. package/skills/alp-plan/references/research-phase.md +57 -0
  143. package/skills/alp-plan/references/scope-challenge.md +82 -0
  144. package/skills/alp-plan/references/solution-design.md +76 -0
  145. package/skills/alp-plan/references/validate-question-framework.md +89 -0
  146. package/skills/alp-plan/references/validate-workflow.md +83 -0
  147. package/skills/alp-predict/SKILL.md +98 -0
  148. package/skills/alp-scenario/SKILL.md +86 -0
  149. package/skills/code-review/SKILL.md +111 -0
  150. package/skills/code-review/references/code-review-reception.md +114 -0
  151. package/skills/code-review/references/edge-case-scouting.md +78 -0
  152. package/skills/code-review/references/verification-before-completion.md +117 -0
  153. package/skills/delegation/SKILL.md +46 -0
  154. package/skills/docs-seeker/.env.example +15 -0
  155. package/skills/docs-seeker/SKILL.md +87 -0
  156. package/skills/docs-seeker/package.json +25 -0
  157. package/skills/docs-seeker/references/advanced.md +82 -0
  158. package/skills/docs-seeker/references/context7-patterns.md +68 -0
  159. package/skills/docs-seeker/references/errors.md +72 -0
  160. package/skills/docs-seeker/scripts/analyze-llms-txt.js +211 -0
  161. package/skills/docs-seeker/scripts/detect-topic.js +172 -0
  162. package/skills/docs-seeker/scripts/fetch-docs.js +213 -0
  163. package/skills/docs-seeker/scripts/tests/run-tests.js +72 -0
  164. package/skills/docs-seeker/scripts/tests/test-analyze-llms.js +119 -0
  165. package/skills/docs-seeker/scripts/tests/test-detect-topic.js +112 -0
  166. package/skills/docs-seeker/scripts/tests/test-fetch-docs.js +84 -0
  167. package/skills/docs-seeker/scripts/utils/env-loader.js +94 -0
  168. package/skills/docs-seeker/workflows/library-search.md +73 -0
  169. package/skills/docs-seeker/workflows/repo-analysis.md +90 -0
  170. package/skills/docs-seeker/workflows/topic-search.md +69 -0
  171. package/skills/git/SKILL.md +121 -0
  172. package/skills/git/references/branch-management.md +90 -0
  173. package/skills/git/references/commit-standards.md +82 -0
  174. package/skills/git/references/gh-cli-guide.md +132 -0
  175. package/skills/git/references/safety-protocols.md +86 -0
  176. package/skills/git/references/workflow-commit.md +89 -0
  177. package/skills/git/references/workflow-merge.md +63 -0
  178. package/skills/git/references/workflow-pr.md +70 -0
  179. package/skills/git/references/workflow-push.md +62 -0
  180. package/skills/gkg/SKILL.md +87 -0
  181. package/skills/gkg/references/cli-commands.md +92 -0
  182. package/skills/gkg/references/http-api.md +99 -0
  183. package/skills/gkg/references/language-support.md +54 -0
  184. package/skills/problem-solving/SKILL.md +86 -0
  185. package/skills/problem-solving/references/attribution.md +48 -0
  186. package/skills/problem-solving/references/collision-zone-thinking.md +71 -0
  187. package/skills/problem-solving/references/inversion-exercise.md +88 -0
  188. package/skills/problem-solving/references/meta-pattern-recognition.md +80 -0
  189. package/skills/problem-solving/references/scale-game.md +82 -0
  190. package/skills/problem-solving/references/simplification-cascades.md +83 -0
  191. package/skills/problem-solving/references/when-stuck.md +76 -0
  192. package/skills/repomix/SKILL.md +94 -0
  193. package/skills/repomix/references/configuration.md +134 -0
  194. package/skills/repomix/references/usage-patterns.md +106 -0
  195. package/skills/repomix/scripts/.coverage +0 -0
  196. package/skills/repomix/scripts/README.md +179 -0
  197. package/skills/repomix/scripts/repomix_batch.py +455 -0
  198. package/skills/repomix/scripts/repos.example.json +15 -0
  199. package/skills/repomix/scripts/requirements.txt +15 -0
  200. package/skills/repomix/scripts/tests/test_repomix_batch.py +531 -0
  201. package/skills/research/SKILL.md +107 -0
  202. package/skills/security-scan/SKILL.md +101 -0
  203. package/skills/security-scan/references/secret-patterns.md +75 -0
  204. package/skills/security-scan/references/vulnerability-patterns.md +136 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Phúc Anh
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,295 @@
1
+ # alp-code
2
+
3
+ ALP là launcher code-native cho một nhóm agent dùng chung policy, workflow và memory. Mỗi
4
+ execution nhận một `AgentDefinition` bất biến, policy snapshot và identity capsule trước khi
5
+ được chuyển thành lệnh Claude Code hoặc Codex. Runtime chỉ chạy launch spec; lifecycle do
6
+ ALP tự quản bằng child process. Runtime không phải nguồn sự thật của identity hay quyền.
7
+
8
+ Phở 🍜 (`main`) là coordinator mặc định. Principal có thể chọn Claude hoặc Codex cho phiên
9
+ main; specialist luôn đi qua `DelegationService` và chỉ nhận đúng workspace/memory/tool grant
10
+ đã được policy duyệt.
11
+
12
+ ## Agent hiện có
13
+
14
+ | Role | Trách nhiệm |
15
+ |---|---|
16
+ | `main` | điều phối, thực thi trong project đã đăng ký, tổng hợp kết quả |
17
+ | `search` | local code retrieval |
18
+ | `librarian` | external/cross-repo research |
19
+ | `read-thread` | tìm kiếm trong memory |
20
+ | `review` | code review theo concern |
21
+ | `oracle` | second opinion sâu |
22
+ | `compaction` | context summarization |
23
+ | `titling` | sinh title ngắn |
24
+
25
+ Definitions nằm trong `src/agents/`; registry kiểm uniqueness, quan hệ, tools, memory và
26
+ workspace grants khi load. `PolicyEngine` fail-closed trước mọi delegation, memory operation,
27
+ workspace access và tool request.
28
+
29
+ ## Cài đặt
30
+
31
+ ```bash
32
+ npm i -g alp-code
33
+ ```
34
+
35
+ Cần Node.js >= 18. Không cần Git, không cần build: bản phát hành đã mang sẵn `dist/`, máy bạn
36
+ chỉ giải nén và chạy.
37
+
38
+ Máy không có npm, hoặc registry bị chặn — installer tải thẳng bundle của GitHub Release:
39
+
40
+ ```bash
41
+ curl -fsSL https://raw.githubusercontent.com/phucanh08/alp-code/main/install.sh | bash
42
+ ```
43
+
44
+ ```powershell
45
+ irm https://raw.githubusercontent.com/phucanh08/alp-code/main/install.ps1 | iex
46
+ ```
47
+
48
+ Installer tự chọn channel: có `npm` thì cài qua npm; không thì tải
49
+ `alp-code-<tag>-bundle.tar.gz` về `~/.alp-code/versions/<tag>` và trỏ symlink
50
+ `~/.alp-code/current` vào đó. Hai channel cho ra cùng một cây file — khác nhau chỉ ở ai sở hữu
51
+ thư mục cài. Sau đó nó gọi `scripts/bootstrap.cjs` để:
52
+
53
+ 1. dựng `~/.alp` (memory, hook forwarder, install record) mà không ghi đè dữ liệu sẵn có;
54
+ 2. validate `AgentRegistry` và hai runtime adapter;
55
+ 3. chạy doctor;
56
+ 4. cài lệnh `alp` vào PATH — bản npm bỏ qua bước này vì npm đã làm rồi.
57
+
58
+ | Tuỳ chọn | bash | PowerShell |
59
+ |---|---|---|
60
+ | Ép channel | `bash -s -- --channel tarball` hoặc `ALP_CHANNEL=…` | `$env:ALP_CHANNEL = "tarball"` |
61
+ | Ghim một phiên bản | `bash -s -- --version v0.9.0` hoặc `ALP_VERSION=…` | `$env:ALP_VERSION = "v0.9.0"` |
62
+ | Đổi vị trí cài (tarball) | `bash -s -- --home ~/dev/alp` hoặc `ALP_HOME=…` | `$env:ALP_HOME = "D:\alp-code"` |
63
+ | Không sửa PATH | `bash -s -- --no-path` hoặc `ALP_NO_PATH=1` | `$env:ALP_NO_PATH = "1"` |
64
+ | Dev clone theo nhánh | `bash -s -- --branch dev` hoặc `ALP_BRANCH=…` | `$env:ALP_BRANCH = "dev"` |
65
+
66
+ `--branch` là channel thứ ba: clone repo và build tại chỗ. Đó là đường duy nhất còn build trên
67
+ máy người dùng, và chỉ dành cho người phát triển chính ALP.
68
+
69
+ ### Cập nhật
70
+
71
+ `alp update` đi theo channel của bản cài:
72
+
73
+ | Channel | Cách nhận diện | `alp update` làm gì |
74
+ |---|---|---|
75
+ | `npm` | thư mục cài nằm dưới một `node_modules/` | `npm install -g alp-code@<version>` |
76
+ | `tarball` | còn lại, thường `~/.alp-code/versions/<tag>` | tải bundle mới, giải nén sang `versions/<tag>` rồi mới đổi `current` |
77
+ | `dev` | có `.git` và `src/` | checkout tag release mới nhất rồi build lại |
78
+
79
+ Không còn bước backup/restore dữ liệu nào trong update. Từ v0.9.0 mọi thứ thuộc về bạn — memory,
80
+ nấc đã chọn, execution state, project registry — nằm ở `~/.alp`, còn thư mục cài là artifact
81
+ thay được nguyên khối. Bản cài cũ hơn được di trú tự động ở lần chạy `alp` đầu tiên.
82
+
83
+ Riêng dev clone vẫn dừng khi có staged/tracked change chưa commit: ALP không merge hay clobber
84
+ source của bạn.
85
+
86
+ Mỗi lần chạy `alp` (bất kỳ lệnh nào), ALP kiểm tra ngầm xem có bản release mới không, dùng
87
+ cache tại `~/.alp/update-check.json` với TTL 24h — việc kiểm tra không bao giờ chặn lệnh hiện
88
+ tại. Nếu có bản mới, ALP chỉ in một dòng gợi ý `alp update`; nó không tự cập nhật hay hỏi lại.
89
+ Đặt `ALP_SKIP_UPDATE_CHECK=1` để tắt hẳn (hữu ích cho môi trường test/CI cô lập).
90
+
91
+ ## Bắt đầu một project
92
+
93
+ ```bash
94
+ cd ~/code/my-app
95
+ alp init # đăng ký project hiện tại
96
+ alp # chọn nấc tương tác (menu ↑/↓)
97
+ alp --mode high
98
+ alp --mode puck
99
+ ```
100
+
101
+ Nấc (`low` · `medium` · `high` · `ultra` · `puck`) là lựa chọn duy nhất lúc mở phiên: nó ghim
102
+ đúng **một** model cho từng vai, và model quyết định CLI nào chạy vai đó (`claude-*` → Claude
103
+ Code, `gpt-*` → Codex). Không có `--runtime`; bốn nấc đầu xếp theo độ khó của việc, `puck`
104
+ chạy toàn Codex. Xem bảng model từng nấc ở `docs/architecture.md` §4.1.
105
+
106
+ `alp init` canonicalize và đăng ký project trong `~/.alp/projects.json`, sinh lại tài liệu
107
+ identity trong `.alp/agents/`, rồi ghi
108
+ `<project>/.claude/settings.local.json` chỉ chứa hook `SessionStart`. Hook đó nạp identity
109
+ của vai vào context ngay turn đầu — mở `claude` bằng tay trong project cũng có identity mà
110
+ không tốn một lượt gọi tool. `alp deinit` xoá lại đúng file đó (nhận diện qua marker
111
+ `alp init`) và phục hồi backup nếu bạn đã có file riêng.
112
+
113
+ File đó được ghi vào `.git/info/exclude` của chính clone — per-clone, không commit — nên
114
+ `git status --porcelain` vẫn không đổi và cộng tác viên khác không thấy gì.
115
+
116
+ Lần `alp init` đầu tiên trên máy, khi `~/.alp/principal.json` chưa có và đang chạy trên TTY,
117
+ ALP hỏi ba câu: tên bạn, agent gọi bạn là gì, agent tự xưng là gì. Câu trả lời đi thẳng vào
118
+ dòng đầu prompt của mọi vai. Không có TTY (CI, script) thì init vẫn chạy tiếp với bản trung
119
+ tính và in một dòng gợi ý — ALP không đoán tên từ `git config`. Xem hoặc đổi lúc nào cũng
120
+ được:
121
+
122
+ ```bash
123
+ alp principal show
124
+ alp principal set # ghi đè, rồi sinh lại .alp/agents/
125
+ ```
126
+
127
+ Khi sửa `src/agents/`, chạy lại `alp identity sync` để tài liệu phẳng khớp registry:
128
+
129
+ ```bash
130
+ alp identity sync
131
+ ```
132
+
133
+ Project đã đăng ký cho phiên `main` quyền `workspace-write`; cwd chưa đăng ký là
134
+ `read-only`. `alp deinit` gỡ registration và dọn artifact cũ do các bản ALP trước tạo ra,
135
+ nhưng không xoá memory của project.
136
+
137
+ Nấc dùng cho phiên main nhớ được giữa các lần chạy (`~/.alp/mode.json`):
138
+
139
+ ```bash
140
+ alp mode show
141
+ alp mode set high
142
+ ```
143
+
144
+ Thứ tự quyết định: `--mode` → `ALP_MODE` → `alp mode set` → menu trên TTY → `medium`.
145
+
146
+ ## Delegation
147
+
148
+ ```bash
149
+ alp delegate search --project /path/to/app --background -- "Find auth entrypoint"
150
+ alp delegate review --project /path/to/app -- "Review the current diff"
151
+
152
+ alp delegation status exec_...
153
+ alp delegation wait exec_...
154
+ alp delegation cancel exec_...
155
+ alp delegation cleanup exec_...
156
+ ```
157
+
158
+ Luồng bắt buộc:
159
+
160
+ ```text
161
+ caller role
162
+ -> DelegationService
163
+ -> AgentRegistry + PolicyEngine + MemoryService + ExecutionService
164
+ -> RuntimeAdapter (Claude/Codex launch spec)
165
+ -> ExecutionBackend (child-process lifecycle)
166
+ ```
167
+
168
+ Unauthorized delegation bị từ chối trước runtime probe hay spawn. Backend spawn runtime làm
169
+ child process kèm settings file riêng của vai, nên `permissions.deny` là ràng buộc thật chứ
170
+ không phải khuyến nghị; state nằm trong `local.json` dưới delegation state dir để một CLI
171
+ process sau vẫn chạy được lệnh lifecycle. `scripts/run-role.cjs` và `scripts/delegate.cjs`
172
+ chỉ là compatibility wrappers vào cùng code-native service.
173
+
174
+ ## Memory
175
+
176
+ Agent chỉ dùng `MemoryService`/`MemoryStore` với logical ID:
177
+
178
+ ```text
179
+ shared:<id>
180
+ project:<slug>:<id>
181
+ private:<role>:<id>
182
+ ```
183
+
184
+ Hiện `MarkdownFileStore` lưu body Markdown dưới `~/.alp/memory` (`ALP_MEMORY_ROOT` để đổi chỗ).
185
+ `RemoteApiStore` triển khai cùng
186
+ contract qua một `MemoryApiClient` injected, để tương lai chuyển sang server mà không đổi
187
+ agent logic. Policy authorize trước mọi store call; optimistic versioning và audit metadata
188
+ được giữ ở service boundary.
189
+
190
+ Memory nằm NGOÀI thư mục cài, vì thư mục cài bị thay nguyên khối mỗi lần update. Bootstrap chỉ
191
+ chép phần scaffold còn thiếu và không bao giờ ghi đè nội dung. `alp uninstall` mặc định chuyển
192
+ toàn bộ memory sang backup cạnh `~/.alp`; chỉ `--purge-memory` mới xoá nó.
193
+
194
+ ## Continuity qua compaction
195
+
196
+ Claude Code và Codex CLI tự nén (compact) transcript của chính chúng khi hết context. ALP giữ
197
+ một checkpoint nhỏ ở ngoài — objective và các quyết định/ràng buộc đã pin — và trả nó lại ngay
198
+ sau lần compact kế tiếp, không copy native summary, không synthetic turn:
199
+
200
+ ```bash
201
+ alp context status # objective, số pin, generation, restore mode
202
+ alp context pin decision -- "chose X over Y because Z"
203
+ alp context pin constraint -- "do not touch Z"
204
+ alp context validate # kiểm checkpoint + journal
205
+ ```
206
+
207
+ `alp context pin`/`unpin` chạy được cả từ CLI của principal lẫn từ trong một phiên agent (nó
208
+ đọc `ALP_DELEGATION_EXECUTION_ID` từ môi trường). Tắt hoàn toàn bridge bằng cách không đặt
209
+ `ALP_COMPACT_BRIDGE=1` — checkpoint và continuity vẫn được seed/reinject bình thường, chỉ riêng
210
+ việc ghi journal lúc `PreCompact`/`PostCompact` là opt-in. Đừng pin secret hay nội dung file:
211
+ pin đọc lại được bằng `cat` và reinject thẳng vào context window của model.
212
+
213
+ ## Bảo trì
214
+
215
+ | Lệnh | Việc |
216
+ |---|---|
217
+ | `alp doctor [--quiet]` | registry, runtimes, memory, execution state, stale legacy, build drift |
218
+ | `alp update` | cập nhật theo channel (npm / tarball / dev clone); dữ liệu ở `~/.alp` không bị đụng |
219
+ | `alp --version` | in phiên bản đang cài (đọc `package.json`) |
220
+ | `alp uninstall [--purge-memory] [--force]` | gỡ bản cài theo channel; backup memory mặc định; trong `~/.alp` chỉ xoá thứ của alp-code |
221
+ | `scripts/bootstrap.cjs [--no-path]` | dựng state, validate, doctor, link CLI (build chỉ với dev clone) |
222
+ | `scripts/ensure-state.cjs [--quiet]` | dựng lại `~/.alp` và hook forwarder cho bản cài hiện hành |
223
+
224
+ Doctor exit `0` khi healthy, `1` khi có finding cần xử lý, `2` khi doctor tự lỗi. Mỗi finding
225
+ có remediation cụ thể. Cutover đã hoàn tất, nên `STALE-LEGACY` chỉ xuất hiện khi máy còn sót
226
+ artifact của bản ALP cũ (`identity/`, `CHARTER.md`, compiled ACL); doctor sẽ chỉ cách dọn.
227
+
228
+ ### Cắt bản release (cho maintainer)
229
+
230
+ 1. Viết mục `[Chưa phát hành]` trong `CHANGELOG.md` cho bản này.
231
+ 2. `node scripts/cut-release.cjs <patch|minor|major|X.Y.Z>` — bump `package.json.version`,
232
+ đóng mục CHANGELOG theo ngày, tạo commit `chore(release): vX.Y.Z` và tag. Thêm
233
+ `--dry-run` để xem trước. Script cố ý dừng trước push.
234
+ 3. `git push origin main --tags`.
235
+ 4. `node scripts/pack-release.cjs` — dựng hai artifact vào `build/`: `.tgz` cho npm và
236
+ `alp-code-vX.Y.Z-bundle.tar.gz` (kèm sẵn dependency runtime) cho GitHub Release. Script
237
+ kiểm nội dung artifact rồi cố ý dừng trước khi đẩy đi.
238
+ 5. `npm publish build/alp-code-X.Y.Z.tgz`.
239
+ 6. `gh release create vX.Y.Z --generate-notes` rồi
240
+ `gh release upload vX.Y.Z build/alp-code-vX.Y.Z-bundle.tar.gz` — publish từ máy, biết kết
241
+ quả ngay. Repo cố ý không dùng GitHub Actions cho việc này; lý do ghi trong
242
+ `.claude/skills/release/SKILL.md`.
243
+ 7. Từ đây `npm i -g alp-code`, installer và `alp update` trên máy khác đều thấy `vX.Y.Z`.
244
+
245
+ ## Cấu trúc
246
+
247
+ ```text
248
+ src/
249
+ agents/ immutable AgentDefinition registry
250
+ policy/ delegation, tool, memory và workspace authorization
251
+ memory/ storage-neutral service + Markdown/remote adapters
252
+ execution/ identity capsules, policy snapshots, execution state
253
+ workflow/ state machine và output validation/repair
254
+ context/ cross-runtime compact bridge (checkpoint, journal, continuity render)
255
+ runtime/ Claude/Codex launch-spec adapters
256
+ backend/ runtime-neutral execution lifecycle (child process + supervisor)
257
+ delegation/ request normalization, execution tracking, result routing
258
+ cli/ alp commands và mode selection
259
+ scripts/ stable CJS wrappers, maintenance, installers và compatibility tests
260
+ hooks/ execution-policy/workflow bridges
261
+ scaffold/ memory skeleton cho clean install
262
+ test/ Vitest unit, contract, integration và E2E suites
263
+ ```
264
+
265
+ ## Kiểm thử
266
+
267
+ ```bash
268
+ npm run typecheck
269
+ npm run build
270
+ npm test
271
+
272
+ for f in scripts/test-*.cjs; do node "$f" || break; done
273
+ ```
274
+
275
+ `npm test` chạy unit, contract, integration và E2E. Năm suite E2E (`test/e2e/`) dựng fake
276
+ runtime binaries cho `claude`/`codex` để kiểm launch contract, delegation, memory isolation,
277
+ mode selection và compact bridge (pin → fixture compaction → reinject) mà không gọi model
278
+ trả phí. Mười hai script `scripts/test-*.cjs` giữ phần
279
+ cross-platform: CLI link, Codex role, delegation, execution hooks, installer (POSIX và
280
+ Windows), state `~/.alp`, nội dung artifact phát hành, update và uninstall — trong đó
281
+ uninstall có process-level fixture để chứng minh CLI vẫn hoàn tất sau khi xoá installation
282
+ đang chứa code của chính nó.
283
+
284
+ ## Guardrails
285
+
286
+ - Không gọi raw Herdr/Paseo hoặc in-process subagent để bypass ALP.
287
+ - Unknown tool/path/role/request luôn bị từ chối.
288
+ - Private memory chỉ role sở hữu được đọc.
289
+ - Không sửa agent definition/policy source từ một delegated execution.
290
+ - Không commit, push, deploy hay purge memory nếu principal chưa yêu cầu rõ.
291
+
292
+ ## Giấy phép
293
+
294
+ [MIT](LICENSE) © 2026 Phúc Anh. Giấy phép đi kèm trong cả hai artifact phát hành — bản npm và
295
+ bundle tarball — nên bản cài nào cũng tự nói được điều kiện dùng của nó.
@@ -0,0 +1,5 @@
1
+ # ALP machine/runtime configuration. Agent identity and policy live in compiled TypeScript.
2
+ delegation:
3
+ # Nơi giữ state của delegation: bản ghi execution, log, và snapshot policy.
4
+ # Để trống thì mặc định là `~/.alp/delegation/<hash repo root>`.
5
+ state_dir: ""
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defineAgent = defineAgent;
4
+ function cloneDefinitionValue(value) {
5
+ if (Array.isArray(value)) {
6
+ return value.map(cloneDefinitionValue);
7
+ }
8
+ if (value !== null && typeof value === "object") {
9
+ const clone = {};
10
+ for (const key of Reflect.ownKeys(value)) {
11
+ clone[key] = cloneDefinitionValue(value[key]);
12
+ }
13
+ return clone;
14
+ }
15
+ return value;
16
+ }
17
+ function deepFreeze(value) {
18
+ if (value === null || typeof value !== "object") {
19
+ return value;
20
+ }
21
+ for (const key of Reflect.ownKeys(value)) {
22
+ deepFreeze(value[key]);
23
+ }
24
+ return Object.freeze(value);
25
+ }
26
+ function defineAgent(definition) {
27
+ return deepFreeze(cloneDefinitionValue(definition));
28
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.capabilityCatalog = exports.MCP_SERVER_CATALOG = exports.SUBAGENT_CATALOG = exports.SKILL_CATALOG = void 0;
4
+ /**
5
+ * The skills in project scope (§5.7) — one entry per directory under `<repo>/skills`, kept
6
+ * in sync by a test. A skill on disk that is not listed here is granted to nobody, which is
7
+ * what makes adding one a deliberate step rather than a side effect of a `git pull`.
8
+ */
9
+ exports.SKILL_CATALOG = Object.freeze([
10
+ "agent-memory",
11
+ "alp-debug",
12
+ "alp-plan",
13
+ "alp-predict",
14
+ "alp-scenario",
15
+ "code-review",
16
+ "delegation",
17
+ "docs-seeker",
18
+ "git",
19
+ "gkg",
20
+ "problem-solving",
21
+ "repomix",
22
+ "research",
23
+ "security-scan",
24
+ ]);
25
+ /** Empty at v1 — §5.5. */
26
+ exports.SUBAGENT_CATALOG = Object.freeze({});
27
+ /** Empty until the principal trusts a server by name, with its egress printed. */
28
+ exports.MCP_SERVER_CATALOG = Object.freeze({});
29
+ exports.capabilityCatalog = Object.freeze({
30
+ skills: exports.SKILL_CATALOG,
31
+ subagents: exports.SUBAGENT_CATALOG,
32
+ mcpServers: exports.MCP_SERVER_CATALOG,
33
+ });
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.compactionAgent = void 0;
4
+ const agent_definition_1 = require("./agent-definition");
5
+ const house_rules_1 = require("./shared/house-rules");
6
+ const voice_1 = require("./shared/voice");
7
+ const types_1 = require("../workflow/types");
8
+ exports.compactionAgent = (0, agent_definition_1.defineAgent)({
9
+ id: "compaction",
10
+ displayName: "Compaction 🗜️",
11
+ model: { claude: "claude-opus-5", codex: "gpt-5.6-sol" },
12
+ reasoningEffort: { claude: "medium", codex: "medium" },
13
+ reportsTo: "main",
14
+ delegatesTo: [],
15
+ // Viết một bản bàn giao, không gom một corpus.
16
+ autoCompactTokens: { claude: 150_000, codex: 150_000 },
17
+ capabilities: {
18
+ tools: ["Read", "Glob", "Grep"],
19
+ skills: [],
20
+ subagents: [],
21
+ mcpServers: [],
22
+ memory: {
23
+ read: ["shared", "project:*", "private:compaction"],
24
+ write: ["private:compaction"],
25
+ },
26
+ workspace: { readRoots: [], writeRoots: [] },
27
+ },
28
+ instructions: () => (0, voice_1.renderInstructions)("Compaction, the continuation-context specialist", "Produce a continuation-ready handoff preserving objectives, constraints, decisions, state, open items, next actions, and exact anchors.", [...house_rules_1.CODE_NATIVE_HOUSE_RULES, "Do not continue the underlying task, research missing facts, or communicate directly with the principal."], { audience: "machine" }),
29
+ workflow: (0, types_1.defineLinearWorkflow)("compact-context", [
30
+ { id: "EXTRACT", allowedTools: ["Read", "Glob", "Grep"] },
31
+ { id: "SEPARATE_FACTS", allowedTools: ["Read", "Glob", "Grep"] },
32
+ { id: "PRESERVE_ANCHORS", allowedTools: ["Read", "Glob", "Grep"] },
33
+ { id: "HANDOFF", allowedTools: [] },
34
+ ]),
35
+ output: (0, voice_1.textOutput)("context-handoff"),
36
+ });
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AgentRegistryError = void 0;
4
+ class AgentRegistryError extends Error {
5
+ code;
6
+ constructor(code, message) {
7
+ super(message);
8
+ this.name = "AgentRegistryError";
9
+ this.code = code;
10
+ }
11
+ }
12
+ exports.AgentRegistryError = AgentRegistryError;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.librarianAgent = void 0;
4
+ const agent_definition_1 = require("./agent-definition");
5
+ const house_rules_1 = require("./shared/house-rules");
6
+ const voice_1 = require("./shared/voice");
7
+ const types_1 = require("../workflow/types");
8
+ exports.librarianAgent = (0, agent_definition_1.defineAgent)({
9
+ id: "librarian",
10
+ displayName: "Librarian 📚",
11
+ model: { claude: "claude-opus-5", codex: "gpt-5.6-sol" },
12
+ reasoningEffort: { claude: "high", codex: "high" },
13
+ reportsTo: "main",
14
+ delegatesTo: [],
15
+ // Doc trích nguyên văn; trích dẫn chính là output. 300k là trần an toàn trên cửa sổ 1M
16
+ // của opus-5 — quá đó là đã đi lạc chứ không phải đọc kỹ. Phía codex bỏ trống: 90% của
17
+ // 272k (244 800) đã chặt hơn 300k rồi, khai thêm chỉ là số thừa.
18
+ autoCompactTokens: { claude: 300_000 },
19
+ capabilities: {
20
+ tools: ["Read", "Glob", "Grep", "Bash", "WebSearch", "WebFetch", "Skill"],
21
+ skills: ["docs-seeker", "research", "repomix"],
22
+ subagents: [],
23
+ mcpServers: [],
24
+ memory: {
25
+ read: ["shared", "project:*", "private:librarian"],
26
+ write: ["shared:reference:*", "project:*:refs:*", "private:librarian"],
27
+ },
28
+ workspace: { readRoots: ["."], writeRoots: [] },
29
+ },
30
+ instructions: () => (0, voice_1.renderInstructions)("Librarian, the external and cross-repository research specialist", "Find authoritative sources, distinguish facts from inference, and return linked evidence for the coordinator.", [...house_rules_1.CODE_NATIVE_HOUSE_RULES, "Write durable sources only below shared/reference or a project's refs subtree; do not mutate other shared or project memory."]),
31
+ workflow: (0, types_1.defineLinearWorkflow)("research-sources", [
32
+ { id: "SCOPE", allowedTools: ["Read", "Glob", "Grep"] },
33
+ { id: "RESEARCH", allowedTools: ["Read", "Glob", "Grep", "Bash", "WebSearch", "WebFetch"] },
34
+ { id: "CORROBORATE", allowedTools: ["Read", "WebSearch", "WebFetch"] },
35
+ { id: "REPORT", allowedTools: [] },
36
+ ]),
37
+ output: (0, voice_1.textOutput)("research-report"),
38
+ });
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mainAgent = void 0;
4
+ const agent_definition_1 = require("./agent-definition");
5
+ const house_rules_1 = require("./shared/house-rules");
6
+ const voice_1 = require("./shared/voice");
7
+ const types_1 = require("../workflow/types");
8
+ exports.mainAgent = (0, agent_definition_1.defineAgent)({
9
+ id: "main",
10
+ displayName: "Phở 🍜",
11
+ model: { claude: "claude-opus-5", codex: "gpt-5.6-sol" },
12
+ reasoningEffort: { claude: "high", codex: "xhigh" },
13
+ reportsTo: "principal",
14
+ delegatesTo: ["search", "librarian", "read-thread", "review", "oracle", "compaction", "titling"],
15
+ // Ghế giữ toàn cảnh: giữ tối đa model cho phép, tức đúng mặc định 90% cửa sổ của từng
16
+ // model — 900k trên opus-5, 244 800 trên gpt-5.6-sol. Không khai số ở đây là có chủ ý:
17
+ // một con số cứng sẽ mục ngay khi routing đổi model, còn "90%" thì không.
18
+ capabilities: {
19
+ tools: ["Read", "Write", "Edit", "Glob", "Grep", "Bash", "WebSearch", "WebFetch", "Skill"],
20
+ skills: ["alp-plan", "problem-solving", "delegation", "git", "agent-memory"],
21
+ subagents: [],
22
+ mcpServers: [],
23
+ memory: {
24
+ read: ["shared", "project:*", "private:main"],
25
+ write: ["shared", "project:*", "private:main"],
26
+ },
27
+ workspace: { readRoots: ["."], writeRoots: ["."] },
28
+ },
29
+ instructions: () => (0, voice_1.renderInstructions)("Phở, the principal-facing coordinator", "Own the overall result, route substantial specialist work, verify returned evidence, and make final recommendations.", [...house_rules_1.CODE_NATIVE_HOUSE_RULES, ...house_rules_1.CODE_CRAFT_RULES]),
30
+ workflow: (0, types_1.defineLinearWorkflow)("coordinate-principal-task", [
31
+ { id: "ASSESS", allowedTools: ["Read", "Glob", "Grep"] },
32
+ { id: "EXECUTE", allowedTools: ["Read", "Write", "Edit", "Glob", "Grep", "Bash", "WebSearch", "WebFetch", "Skill"] },
33
+ { id: "VERIFY", allowedTools: ["Read", "Glob", "Grep", "Bash", "WebFetch"] },
34
+ { id: "REPORT", allowedTools: [] },
35
+ ]),
36
+ output: (0, voice_1.textOutput)("principal-response"),
37
+ });
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.memoryGrantCovers = memoryGrantCovers;
4
+ function segments(value) {
5
+ return value.split(":");
6
+ }
7
+ function memoryGrantCovers(grant, target) {
8
+ if (grant === target)
9
+ return true;
10
+ const expected = segments(grant);
11
+ const actual = segments(target);
12
+ if (expected[0] !== actual[0])
13
+ return false;
14
+ if (grant === "shared")
15
+ return actual.length > 1;
16
+ if (expected.length === 2 &&
17
+ (expected[0] === "private" || expected[0] === "project")) {
18
+ return (expected[1] === "*" || expected[1] === actual[1]) && actual.length >= 2;
19
+ }
20
+ for (let index = 0; index < expected.length; index += 1) {
21
+ const part = expected[index];
22
+ if (part === "*" && index === expected.length - 1) {
23
+ return actual.length > index;
24
+ }
25
+ if (part !== "*" && part !== actual[index])
26
+ return false;
27
+ }
28
+ return actual.length >= expected.length;
29
+ }
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MODEL_CONTEXT_WINDOWS = exports.AUTO_COMPACT_DEFAULT_PERCENT = exports.MODEL_RUNTIMES = void 0;
4
+ exports.runtimeForModel = runtimeForModel;
5
+ exports.defaultAutoCompactTokens = defaultAutoCompactTokens;
6
+ /**
7
+ * Cửa sổ context của từng model, tính bằng token — mẫu số cho vai không khai
8
+ * `autoCompactTokens`.
9
+ *
10
+ * Im lặng trước đây có nghĩa là "tuỳ runtime", mà hai runtime quyết khác nhau: Codex nén ở
11
+ * 90% cửa sổ context của model, còn Claude nén ở cửa sổ nó tự tune theo model và theo
12
+ * settings của chính máy đang chạy. Cùng một vai lại nhớ được nhiều ít khác nhau tuỳ chỗ
13
+ * chạy — đúng cái phụ thuộc-vào-máy mà việc khai ngưỡng trên vai sinh ra để chấm dứt. Nên
14
+ * ALP tự quyết mặc định: 90% cửa sổ dưới đây, giống nhau trên cả hai runtime.
15
+ *
16
+ * Con số là cửa sổ nhà cung cấp công bố, không phải ước lượng. Model nào không có ở đây thì
17
+ * không có mặc định — để runtime dùng cửa sổ của nó còn hơn dựng một ngân sách từ phỏng
18
+ * đoán.
19
+ */
20
+ /**
21
+ * Model chạy trên runtime nào. Từ khi dial ghim **một** model cho mỗi vai ở mỗi nấc, model
22
+ * là thứ quyết định CLI nào được phóng — không còn ai chọn runtime rồi mới tra model. Bảng
23
+ * viết tay thay vì đoán theo tiền tố `claude-`/`gpt-`: một model đặt tên lệch quy ước sẽ
24
+ * phóng nhầm CLI trong im lặng, còn thiếu một dòng ở đây thì `runtimeForModel` ném ngay.
25
+ */
26
+ exports.MODEL_RUNTIMES = Object.freeze({
27
+ "claude-fable-5-1": "claude",
28
+ "claude-opus-5": "claude",
29
+ "claude-sonnet-5": "claude",
30
+ "claude-haiku-4-5": "claude",
31
+ "gpt-5.6-sol": "codex",
32
+ "gpt-5.6-terra": "codex",
33
+ "gpt-5.6-luna": "codex",
34
+ "gpt-6-astra": "codex",
35
+ });
36
+ function runtimeForModel(model) {
37
+ const runtime = exports.MODEL_RUNTIMES[model];
38
+ if (runtime === undefined)
39
+ throw new Error(`model \`${model}\` chưa được gán runtime trong MODEL_RUNTIMES`);
40
+ return runtime;
41
+ }
42
+ /** Phần trăm cửa sổ được giữ trước khi runtime được phép nén — chính con số Codex đang dùng. */
43
+ exports.AUTO_COMPACT_DEFAULT_PERCENT = 90;
44
+ exports.MODEL_CONTEXT_WINDOWS = Object.freeze({
45
+ // 1M token native, standard pricing (claude.com/docs — Opus 5, Sonnet 5). Claude vẫn cap
46
+ // lại theo cửa sổ thật của phiên, nên số này là trần chứ không phải lời hứa.
47
+ "claude-fable-5-1": 1_000_000,
48
+ "claude-opus-5": 1_000_000,
49
+ "claude-sonnet-5": 1_000_000,
50
+ "claude-haiku-4-5": 200_000,
51
+ // Đo từ `~/.codex/models_cache.json` (codex-cli 0.149.0): `context_window` 272000 cho cả
52
+ // ba, `max_context_window` 872000 chỉ mở khi tài khoản có quyền — lấy cửa sổ đang hoạt
53
+ // động, vì nén sớm còn cứu được, nén muộn thì mất.
54
+ "gpt-5.6-sol": 272_000,
55
+ "gpt-5.6-terra": 272_000,
56
+ "gpt-5.6-luna": 272_000,
57
+ // Chưa có nguồn công bố chính thức — tạm lấy bằng cửa sổ đang hoạt động của họ Sol/Terra/Luna,
58
+ // sửa lại ngay khi có số thật.
59
+ "gpt-6-astra": 272_000,
60
+ });
61
+ /**
62
+ * Ngưỡng mặc định cho một model, hoặc `null` nếu ALP không biết cửa sổ của nó.
63
+ *
64
+ * Nhân rồi chia số nguyên: `window * 0.9` trả về 244800.00000000003 cho cửa sổ 272k, và một
65
+ * ngưỡng token lẻ là thứ không runtime nào làm tròn giúp.
66
+ */
67
+ function defaultAutoCompactTokens(model) {
68
+ const window = exports.MODEL_CONTEXT_WINDOWS[model];
69
+ return window === undefined ? null : Math.floor((window * exports.AUTO_COMPACT_DEFAULT_PERCENT) / 100);
70
+ }