pi-coding-master 0.2.7
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.
- package/README.md +50 -0
- package/core/god.agent.capability/@ABANDONED.brain.prefrontal.monitor/gpu_monitor.py +80 -0
- package/core/god.agent.capability/@ABANDONED.brain.prefrontal.monitor/gpu_monitor.py.CHANGELOG +1 -0
- package/core/god.agent.capability/@ABANDONED.brain.prefrontal.monitor/gpu_monitor.py.SPEC +3 -0
- package/core/god.agent.capability/hands.dev.writeissue/issue.ts +209 -0
- package/core/god.agent.capability/hands.dev.writeissue/issue.ts.SPEC +26 -0
- package/core/god.agent.capability/hands.files.changewatcher/watcher.ts +44 -0
- package/core/god.agent.capability/hands.files.changewatcher/watcher.ts.SPEC +25 -0
- package/core/god.pi.mod/cli/pi-completion.zsh +21 -0
- package/core/god.pi.mod/cli/pi-completion.zsh.CHANGELOG +1 -0
- package/core/god.pi.mod/cli/pi-people.sh +264 -0
- package/core/god.pi.mod/cli/pi-people.sh.LESSON +10 -0
- package/core/god.pi.mod/cli/pi-people.sh.SPEC +31 -0
- package/core/god.pi.mod/paths.ts +47 -0
- package/core/god.pi.mod/tui.mods.blockrender/blockrender.js +90 -0
- package/core/god.pi.mod/tui.mods.blockrender/blockrender.js.SPEC +29 -0
- package/core/god.pi.mod/tui.mods.footer.budget/budget_guard.ts +154 -0
- package/core/god.pi.mod/tui.mods.footer.budget/budget_guard.ts.CHANGELOG +10 -0
- package/core/god.pi.mod/tui.mods.footer.budget/budget_guard.ts.LESSON +12 -0
- package/core/god.pi.mod/tui.mods.footer.budget/budget_guard.ts.SPEC +26 -0
- package/core/god.pi.mod/tui.mods.footer.budget/footer-cny.CHANGELOG +39 -0
- package/core/god.pi.mod/tui.mods.viewmode/view_mode-thinking.patch +55 -0
- package/core/god.pi.mod/tui.mods.viewmode/view_mode-tools.patch +19 -0
- package/core/god.pi.mod/tui.mods.viewmode/view_mode-tools.patch.CHANGELOG +1 -0
- package/core/god.pi.mod/tui.mods.viewmode/view_mode.ts +50 -0
- package/core/god.pi.mod/tui.mods.viewmode/view_mode.ts.SPEC +12 -0
- package/core/god.pi.mod/tui.variants.userterminal/user_terminal.CHANGELOG +10 -0
- package/core/god.pi.mod/tui.variants.userterminal/user_terminal.ts +66 -0
- package/core/god.pi.mod/tui.variants.userterminal/user_terminal.ts.SPEC +31 -0
- package/core/index.ts +3 -0
- package/core/individual.bio.gene/dna.coded/coded.dna +257 -0
- package/core/individual.bio.gene/dna.coded/coded.dna.CHANGELOG +12 -0
- package/core/individual.bio.gene/dna.coded/coded.dna.SPEC +11 -0
- package/core/individual.bio.gene/dna.coded/core.dna +110 -0
- package/core/individual.bio.gene/dna.promotor/promotor.dna +117 -0
- package/core/individual.bio.gene/dna.promotor/promotor.dna.CHANGELOG +4 -0
- package/core/individual.bio.gene/dna.promotor/promotor.dna.SPEC +7 -0
- package/core/individual.bio.gene/dna.transpiler/transpiler.ts +395 -0
- package/core/individual.bio.gene/dna.transpiler/transpiler.ts.CHANGELOG +7 -0
- package/core/individual.bio.gene/dna.transpiler/transpiler.ts.SPEC +28 -0
- package/core/individual.bio.gene/gene.README +19 -0
- package/core/individual.bio.gene/rna/rna.json +536 -0
- package/core/individual.bio.gene/rna/rna.json.CHANGELOG +2 -0
- package/core/individual.bio.gene/rna/rna.json.SPEC +8 -0
- package/core/individual.bio.organs/blood.runtime/messages.ts +236 -0
- package/core/individual.bio.organs/blood.runtime/runtime.ts +173 -0
- package/core/individual.bio.organs/blood.runtime/runtime.ts.CHANGELOG +5 -0
- package/core/individual.bio.organs/blood.runtime/runtime.ts.SPEC +32 -0
- package/core/individual.bio.organs/brain.amygdala/amygdala.ts +25 -0
- package/core/individual.bio.organs/brain.amygdala/amygdala.ts.COMMENT +3 -0
- package/core/individual.bio.organs/brain.amygdala/amygdala.ts.SPEC +9 -0
- package/core/individual.bio.organs/brain.hippocampus/hippocampus-launcher.sh.template +108 -0
- package/core/individual.bio.organs/brain.hippocampus/hippocampus.ts +166 -0
- package/core/individual.bio.organs/brain.hippocampus/hippocampus.ts.CHANGELOG +12 -0
- package/core/individual.bio.organs/brain.hippocampus/hippocampus.ts.LESSON +22 -0
- package/core/individual.bio.organs/brain.hippocampus/hippocampus.ts.SPEC +16 -0
- package/core/individual.bio.organs/brain.hippocampus/memory.ts +879 -0
- package/core/individual.bio.organs/brain.hippocampus/memory.ts.CHANGELOG +66 -0
- package/core/individual.bio.organs/brain.hippocampus/memory.ts.LESSON +25 -0
- package/core/individual.bio.organs/brain.hippocampus/memory.ts.SPEC +46 -0
- package/core/individual.bio.organs/brain.hippocampus/sleep.ts +139 -0
- package/core/individual.bio.organs/brain.hippocampus/sleep.ts.CHANGELOG +11 -0
- package/core/individual.bio.organs/brain.hippocampus/sleep.ts.SPEC +16 -0
- package/core/individual.bio.organs/brain.prefrontal.drafting/drafting.SPEC +44 -0
- package/core/individual.bio.organs/brain.prefrontal.drafting/drafting.ts +73 -0
- package/core/individual.bio.organs/brain.prefrontal.drafting/drafting.ts.CHANGELOG +3 -0
- package/core/individual.bio.organs/brain.prefrontal.drafting/drafting.ts.SPEC +24 -0
- package/core/individual.bio.organs/brain.prefrontal.drafting/index.ts.CHANGELOG +3 -0
- package/core/individual.bio.organs/brain.prefrontal.drafting/main.ts +13 -0
- package/core/individual.bio.organs/brain.prefrontal.drafting/main.ts.SPEC +17 -0
- package/core/individual.bio.organs/brain.senses.bioclock/bioclock.ts +94 -0
- package/core/individual.bio.organs/brain.senses.bioclock/bioclock.ts.LESSON +13 -0
- package/core/individual.bio.organs/brain.senses.bioclock/bioclock.ts.SPEC +20 -0
- package/core/individual.bio.organs/brain.senses.subconscious/feed-format.SPEC +56 -0
- package/core/individual.bio.organs/brain.senses.subconscious/index.ts.CHANGELOG +13 -0
- package/core/individual.bio.organs/brain.senses.subconscious/spawner.ts +130 -0
- package/core/individual.bio.organs/brain.senses.subconscious/spawner.ts.SPEC +13 -0
- package/core/individual.bio.organs/brain.senses.subconscious/subconscious.ts +280 -0
- package/core/individual.bio.organs/brain.senses.subconscious/subconscious.ts.CHANGELOG +7 -0
- package/core/individual.bio.organs/brain.senses.subconscious/tools.ts +180 -0
- package/core/individual.bio.organs/brain.senses.subconscious/tools.ts.SPEC +3 -0
- package/core/individual.bio.organs/ears.listen/config.json +9 -0
- package/core/individual.bio.organs/ears.listen/config.json.CHANGELOG +1 -0
- package/core/individual.bio.organs/ears.listen/config.json.SPEC +3 -0
- package/core/individual.bio.organs/ears.listen/ears.ts.CHANGELOG +48 -0
- package/core/individual.bio.organs/ears.listen/ears_recorder.py.CHANGELOG +6 -0
- package/core/individual.bio.organs/ears.listen/index.ts +1 -0
- package/core/individual.bio.organs/ears.listen/index.ts.SPEC +16 -0
- package/core/individual.bio.organs/ears.listen/listen.ts +208 -0
- package/core/individual.bio.organs/ears.listen/listen.ts.SPEC +3 -0
- package/core/individual.bio.organs/ears.listen/listen_recorder.py +445 -0
- package/core/individual.bio.organs/ears.listen/listen_recorder.py.SPEC +7 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/__init__.py +0 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/common/__init__.py +0 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/common/events_pb2.py +38 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/common/events_pb2_grpc.py +24 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/common/rpcmeta_pb2.py +42 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/common/rpcmeta_pb2_grpc.py +24 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/products/__init__.py +0 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/products/understanding/__init__.py +0 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/products/understanding/ast/__init__.py +0 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/products/understanding/ast/ast_service_pb2.py +45 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/products/understanding/ast/ast_service_pb2_grpc.py +97 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/products/understanding/base/__init__.py +0 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/products/understanding/base/au_base_pb2.py +80 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/products/understanding/base/au_base_pb2_grpc.py +24 -0
- package/core/individual.bio.organs/hands.fileactions/authorize.TRUST +1 -0
- package/core/individual.bio.organs/hands.fileactions/authorize.ts +70 -0
- package/core/individual.bio.organs/hands.fileactions/authorize.ts.CHANGELOG +1 -0
- package/core/individual.bio.organs/hands.fileactions/authorize.ts.SPEC +3 -0
- package/core/individual.bio.organs/hands.fileactions/dir.README +13 -0
- package/core/individual.bio.organs/hands.fileactions/file_rules.json +23 -0
- package/core/individual.bio.organs/hands.fileactions/fileactions.README +12 -0
- package/core/individual.bio.organs/hands.fileactions/fileactions.ts +540 -0
- package/core/individual.bio.organs/hands.fileactions/fileactions.ts.CHANGELOG +25 -0
- package/core/individual.bio.organs/hands.fileactions/fileactions.ts.SPEC +30 -0
- package/core/individual.bio.organs/hands.fileactions/filewatch.ts +66 -0
- package/core/individual.bio.organs/hands.fileactions/filewatch.ts.SPEC +3 -0
- package/core/individual.bio.organs/hands.main/main.ts +18 -0
- package/core/individual.bio.organs/hands.main/main.ts.SPEC +20 -0
- package/core/individual.bio.organs/hands.sensitive/sensitive.ts +24 -0
- package/core/individual.bio.organs/hands.sensitive/sensitive.ts.CHANGELOG +2 -0
- package/core/individual.bio.organs/hands.sensitive/sensitive.ts.SPEC +3 -0
- package/core/individual.bio.organs/heart.interrupt/agent_start-loader-flicker.patch +13 -0
- package/core/individual.bio.organs/heart.interrupt/interactive-mode-loader.patch +11 -0
- package/core/individual.bio.organs/heart.interrupt/runner_esc.patch +10 -0
- package/core/individual.bio.organs/heart.interrupt/runner_esc.patch.SPEC +9 -0
- package/core/individual.bio.organs/heart.kernel/kernel.ts +253 -0
- package/core/individual.bio.organs/heart.kernel/kernel.ts.CHANGELOG +13 -0
- package/core/individual.bio.organs/heart.kernel/kernel.ts.SPEC +23 -0
- package/core/individual.bio.organs/heart.main/heart.main.CHANGELOG +43 -0
- package/core/individual.bio.organs/heart.main/heartbeat.ts +494 -0
- package/core/individual.bio.organs/heart.main/heartbeat.ts.LESSON +43 -0
- package/core/individual.bio.organs/heart.main/main.ts +8 -0
- package/core/individual.bio.organs/heart.main/main.ts.SPEC +19 -0
- package/core/individual.bio.organs/heart.main/process.ts +122 -0
- package/core/individual.bio.organs/heart.main/process.ts.CHANGELOG +2 -0
- package/core/individual.bio.organs/heart.main/process.ts.SPEC +24 -0
- package/core/individual.bio.organs/heart.main/remove_timeout.patch +110 -0
- package/core/individual.bio.organs/heart.main/stop.ts.CHANGELOG +3 -0
- package/core/individual.bio.organs/heart.main/stop.ts.SPEC +28 -0
- package/core/individual.bio.organs/mouth.speak/index.ts +1 -0
- package/core/individual.bio.organs/mouth.speak/index.ts.CHANGELOG +1 -0
- package/core/individual.bio.organs/mouth.speak/index.ts.SPEC +6 -0
- package/core/individual.bio.organs/mouth.speak/mouth.ts.CHANGELOG +15 -0
- package/core/individual.bio.organs/mouth.speak/mouth_recorder.py.CHANGELOG +1 -0
- package/core/individual.bio.organs/mouth.speak/speak.ts +180 -0
- package/core/individual.bio.organs/mouth.speak/speak.ts.SPEC +3 -0
- package/core/individual.bio.organs/mouth.speak/speak_recorder.py +35 -0
- package/core/individual.bio.organs/mouth.speak/speak_recorder.py.SPEC +3 -0
- package/core/individual.bio.organs/organs.README +110 -0
- package/core/package-lock.json +18 -0
- package/core/package.json +35 -0
- package/core/prompts/prompts.json +77 -0
- package/core/prompts/prompts.ts +44 -0
- package/core/prompts/prompts.ts.SPEC +9 -0
- package/core/society.world/.gitkeep +0 -0
- package/core/society.world/accessibility.claudecode/message-service.cjs +217 -0
- package/core/society.world/accessibility.claudecode/message-service.cjs.SPEC +7 -0
- package/core/society.world/accessibility.claudecode/send.ts +34 -0
- package/core/society.world/dollar.distribution.ubi/ubi.ts +55 -0
- package/core/society.world/dollar.main/dollar-service.cjs +185 -0
- package/core/society.world/dollar.main/main.ts +116 -0
- package/core/society.world/dollar.transaction/transaction.ts +71 -0
- package/core/society.world/space/space.ts +206 -0
- package/core/society.world/space/space.ts.SPEC +30 -0
- package/core/technology.laptop/#agent.macos.BLUEPRINT +278 -0
- package/core/technology.phone/apps.preinstalled/albums.FUTURE/albums.ts +69 -0
- package/core/technology.phone/apps.preinstalled/albums.FUTURE/albums.ts.SPEC +15 -0
- package/core/technology.phone/apps.preinstalled/calendar/calendar.ts +406 -0
- package/core/technology.phone/apps.preinstalled/calendar/calendar.ts.SPEC +22 -0
- package/core/technology.phone/apps.preinstalled/calendar/holiday-calendar.ts +529 -0
- package/core/technology.phone/apps.preinstalled/clock/clock.ts +132 -0
- package/core/technology.phone/apps.preinstalled/clock/clock.ts.SPEC +11 -0
- package/core/technology.phone/apps.preinstalled/contacts.FUTURE/contacts.ts +300 -0
- package/core/technology.phone/apps.preinstalled/contacts.FUTURE/contacts.ts.SPEC +22 -0
- package/core/technology.phone/apps.preinstalled/developer.FUTURE/developer.ts +22 -0
- package/core/technology.phone/apps.preinstalled/developer.FUTURE/developer.ts.SPEC +15 -0
- package/core/technology.phone/apps.preinstalled/notes/notes.ts +239 -0
- package/core/technology.phone/apps.preinstalled/notes/notes.ts.SPEC +21 -0
- package/core/technology.phone/apps.preinstalled/polymarket/polymarket.ts +261 -0
- package/core/technology.phone/apps.preinstalled/polymarket/polymarket.ts.SPEC +7 -0
- package/core/technology.phone/apps.preinstalled/reminder/reminder.ts +404 -0
- package/core/technology.phone/apps.preinstalled/reminder/reminder.ts.SPEC +25 -0
- package/core/technology.phone/apps.preinstalled/siri.FUTURE/siri.ts +22 -0
- package/core/technology.phone/apps.preinstalled/siri.FUTURE/siri.ts.SPEC +15 -0
- package/core/technology.phone/apps.preinstalled/spotlight/spotlight.ts +29 -0
- package/core/technology.phone/apps.preinstalled/spotlight/spotlight.ts.SPEC +7 -0
- package/core/technology.phone/apps.preinstalled/steam/chess.ts +230 -0
- package/core/technology.phone/apps.preinstalled/steam/snake.ts +100 -0
- package/core/technology.phone/apps.preinstalled/steam/snake.ts.SPEC +7 -0
- package/core/technology.phone/apps.preinstalled/steam/spy-cmd.ts +4 -0
- package/core/technology.phone/apps.preinstalled/steam/spy-tool.ts +56 -0
- package/core/technology.phone/apps.preinstalled/steam/spy.ts +302 -0
- package/core/technology.phone/apps.preinstalled/steam/steam.ts +299 -0
- package/core/technology.phone/apps.preinstalled/weather/weather.ts +50 -0
- package/core/technology.phone/apps.preinstalled/weather/weather.ts.SPEC +9 -0
- package/core/technology.phone/apps.preinstalled/wechat/imessage.ts +423 -0
- package/core/technology.phone/apps.preinstalled/wechat/imessage.ts.SPEC +24 -0
- package/core/technology.phone/apps.system/appstore/appstore.ts +22 -0
- package/core/technology.phone/apps.system/appstore/appstore.ts.SPEC +15 -0
- package/core/technology.phone/apps.system/finder.FUTURE/finder.ts +64 -0
- package/core/technology.phone/apps.system/finder.FUTURE/finder.ts.SPEC +8 -0
- package/core/technology.phone/apps.system/safari/safari-app.ts +146 -0
- package/core/technology.phone/apps.system/safari/safari.ts.SPEC +24 -0
- package/core/technology.phone/apps.system/settings/settings.ts +126 -0
- package/core/technology.phone/apps.system/settings/settings.ts.SPEC +17 -0
- package/core/technology.phone/apps.system/tips/tips.ts +22 -0
- package/core/technology.phone/apps.system/tips/tips.ts.SPEC +15 -0
- package/core/technology.phone/apps.thirdparty/alipay/alipay.ts +148 -0
- package/core/technology.phone/apps.thirdparty/alipay/alipay.ts.SPEC +7 -0
- package/core/technology.phone/apps.thirdparty/bilibili/bilibili-app.ts +33 -0
- package/core/technology.phone/apps.thirdparty/bilibili/bilibili.ts +142 -0
- package/core/technology.phone/apps.thirdparty/bilibili/bilibili.ts.SPEC +22 -0
- package/core/technology.phone/apps.thirdparty/wechatread/wechatread.ts +80 -0
- package/core/technology.phone/apps.thirdparty/wechatread/wechatread.ts.SPEC +15 -0
- package/core/technology.phone/index.ts +1 -0
- package/core/technology.phone/package.json +2 -0
- package/core/technology.phone/system.homepage/homepage.ts +247 -0
- package/core/technology.phone/system.homepage/homepage.ts.SPEC +22 -0
- package/core/technology.phone/system.kernel/kernel.ts +264 -0
- package/core/technology.phone/system.kernel/kernel.ts.SPEC +7 -0
- package/core/technology.phone/system.notifications/notifications.ts +87 -0
- package/core/technology.phone/system.notifications/notifications.ts.SPEC +7 -0
- package/core/technology.phone/system.share/share.ts +46 -0
- package/core/technology.phone/system.share/share.ts.SPEC +7 -0
- package/core/technology.server/browser-service.cjs +152 -0
- package/core/technology.server/data/cookies/arxiv.json +30 -0
- package/core/technology.server/data/cookies/bili.json +184 -0
- package/core/technology.server/data/cookies/default.json +30 -0
- package/core/technology.server/data/cookies/news.json +113 -0
- package/core/technology.server/data/cookies/s1.json +45 -0
- package/core/technology.server/data/cookies/safari.json +184 -0
- package/core/technology.server/data/cookies/safari2.json +1 -0
- package/core/technology.server/data/cookies/safaridbg.json +1 -0
- package/core/technology.server/data/cookies/search.json +45 -0
- package/core/technology.server/data/cookies/sw.json +30 -0
- package/core/technology.server/data/cookies/t1.json +1 -0
- package/core/technology.server/data/cookies/testread.json +1 -0
- package/core/technology.server/data/cookies/video1.json +113 -0
- package/core/technology.server/data/cookies/yt.json +170 -0
- package/core/technology.server/data/cookies/yt2.json +113 -0
- package/core/technology.server/pikipedia/#pikipedia.BLUEPRINT +106 -0
- package/core/technology.server/playleft.cjs +247 -0
- package/core/technology.server/search-proxy.py +76 -0
- package/core/technology.server/server.README +59 -0
- package/deploy/dist-overrides/cli/cli.js +18 -0
- package/deploy/dist-overrides/core/extensions/loader.js +518 -0
- package/deploy/dist-overrides/core/package-manager.js +2081 -0
- package/deploy/dist-overrides/core/system-prompt.js +109 -0
- package/deploy/dist-overrides/core/system-prompt.js.LESSON +17 -0
- package/deploy/dist-overrides/core/tools/bash.js +353 -0
- package/deploy/dist-overrides/core/tools/bash.js.CHANGELOG +2 -0
- package/deploy/dist-overrides/core/tools/edit-diff.js +345 -0
- package/deploy/dist-overrides/core/tools/edit.js +315 -0
- package/deploy/dist-overrides/core/tools/edit.js.CHANGELOG +1 -0
- package/deploy/dist-overrides/core/tools/file-mutation-queue.js +52 -0
- package/deploy/dist-overrides/core/tools/find.js +298 -0
- package/deploy/dist-overrides/core/tools/find.js.CHANGELOG +1 -0
- package/deploy/dist-overrides/core/tools/grep.js +305 -0
- package/deploy/dist-overrides/core/tools/grep.js.CHANGELOG +1 -0
- package/deploy/dist-overrides/core/tools/index.js +112 -0
- package/deploy/dist-overrides/core/tools/ls-guard.js +4 -0
- package/deploy/dist-overrides/core/tools/ls.js +170 -0
- package/deploy/dist-overrides/core/tools/ls.js.CHANGELOG +1 -0
- package/deploy/dist-overrides/core/tools/output-accumulator.js +184 -0
- package/deploy/dist-overrides/core/tools/path-utils.js +99 -0
- package/deploy/dist-overrides/core/tools/prompts-reader.js +53 -0
- package/deploy/dist-overrides/core/tools/read.js +392 -0
- package/deploy/dist-overrides/core/tools/read.js.CHANGELOG +1 -0
- package/deploy/dist-overrides/core/tools/render-utils.js +65 -0
- package/deploy/dist-overrides/core/tools/tool-definition-wrapper.js +34 -0
- package/deploy/dist-overrides/core/tools/truncate.js +215 -0
- package/deploy/dist-overrides/core/tools/write.js +203 -0
- package/deploy/dist-overrides/core/tools/write.js.CHANGELOG +1 -0
- package/deploy/dist-overrides/dist-overrides.README +18 -0
- package/deploy/dist-overrides/main.js +665 -0
- package/deploy/dist-overrides/modes/interactive/components/assistant-message.js +139 -0
- package/deploy/dist-overrides/modes/interactive/components/footer.js +326 -0
- package/deploy/dist-overrides/modes/interactive/components/model-selector.js +285 -0
- package/deploy/dist-overrides/modes/interactive/components/tool-execution.js +383 -0
- package/deploy/dist-overrides/modes/interactive/components/tool-execution.js.CHANGELOG +3 -0
- package/deploy/dist-overrides/modes/interactive/interactive-mode.js +4781 -0
- package/deploy/dist-overrides/pi-ai/providers/anthropic.js +931 -0
- package/deploy/dist-overrides/pi-ai/providers/openai-completions.js +1007 -0
- package/deploy/dist-overrides/pi-ai/providers/openai-completions.js.LESSON +15 -0
- package/deploy/dist-overrides/pi-tui/components/loader.js +69 -0
- package/deploy/dist-overrides/pi-tui/components/markdown.js +646 -0
- package/deploy/dist-overrides/pi-tui/components/text.js +92 -0
- package/deploy/dist-overrides/pi-tui/custom-message.js +75 -0
- package/deploy/dist-overrides/pi-tui/tui.js +1266 -0
- package/deploy/dist-overrides/pi-tui/utils.js +1060 -0
- package/deploy/dist-overrides/vendor.REMOVED/jiti/lib/jiti.mjs +3 -0
- package/deploy/install.sh +186 -0
- package/deploy/install.sh.CHANGELOG +6 -0
- package/deploy/lint/lint-naming.ts +202 -0
- package/deploy/scripts/apply.js +18 -0
- package/deploy/scripts/build-github.sh +219 -0
- package/deploy/scripts/build-phone.sh +24 -0
- package/deploy/scripts/check-deploy.sh +42 -0
- package/deploy/scripts/migrate-context.sh +72 -0
- package/deploy/scripts/patch-pi-dist.js +39 -0
- package/deploy/scripts/uninstall.sh +34 -0
- package/package.json +18 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
[2026-06-15] 记忆系统大修(崩溃 + 缓存 + 静默失败),by Claude Code
|
|
2
|
+
|
|
3
|
+
背景:实例反复崩 "400 max context 1048565, requested 1.15M";状态栏显示 38% 却实际 113%;
|
|
4
|
+
单日 49M tokens、16M 未命中(缓存被毁);sleep 几天没真正运行。逐项修:
|
|
5
|
+
|
|
6
|
+
1. estimateTokens:chars/4 → CJK-aware(CJK ×1.8 + 其余 /4)。
|
|
7
|
+
根因:chars/4 对中文少算约 7 倍 → 真 1.15M 只估成 ~38% → 容量永不报警、保护永不触发。
|
|
8
|
+
实测那份 1.5MB context:旧估 384,809(≈状态栏 38%),新估 598K(接近真实)。
|
|
9
|
+
|
|
10
|
+
2. 注入加硬预算:MEMORY_BUDGET = 窗口×0.35,cortex/work/context 按 token 尾部切(sliceToTokens)。
|
|
11
|
+
原 isOverHalf 保护用 chars/4 误判(1.8MB 估成 467K < 500K)→ 不触发 → 全量注入撑爆。
|
|
12
|
+
修后:compacted 对话(~382K)+记忆(≤350K)+overhead < 1.048M,不再爆,pi compaction 终于有效。
|
|
13
|
+
|
|
14
|
+
3. cortexPath ReferenceError:before_agent_start 里 sediment 用了未定义的 cortexPath(一触发就崩)
|
|
15
|
+
→ 改成 path.join(personDir, "cortex.md")。
|
|
16
|
+
|
|
17
|
+
4. sleep import 路径修复:import("./sleep-session.js") → import("./sleep.js")(文件实为 sleep.ts)。
|
|
18
|
+
原路径一直 import 失败 → sleep 工具掉进 catch → 独立 sl- 实例从未启动 → work→cortex 巩固是死的。
|
|
19
|
+
|
|
20
|
+
5. sleep 失败不再假装成功:catch 原来返回 "😴 已进入睡眠(inline mode)" 笑脸 → 改成 ❌ 显眼报错 +
|
|
21
|
+
isError:true,且不再把 dnaState 置 sleep(没真睡着就别装睡)。这是"坏了为啥不报错"的直接元凶之一。
|
|
22
|
+
|
|
23
|
+
6. 【缓存大修】注入架构改为「快照一次 + 增量后 append」:
|
|
24
|
+
- session_start:buildSnapshot() 注入稳定前缀【一次】(memory-snapshot 消息)。
|
|
25
|
+
- before_agent_start:删除所有 systemPrompt 注入,不再 return systemPrompt(前缀逐轮稳定 → 命中)。
|
|
26
|
+
work_memory 增量、容量提醒、到期提醒一律 sendMessage(deliverAs:nextTurn) 追加在末尾。
|
|
27
|
+
cortex 沉降 / events 修剪只写文件。
|
|
28
|
+
根因:旧逻辑每轮把增长的 context+notes 重灌进 systemPrompt(缓存前缀)→ 每轮全废 → 49M/天。
|
|
29
|
+
代价:会话中途后台整理的新 cortex 要下个会话才进快照(可接受)。
|
|
30
|
+
message_end 不回存 messageType 以 "memory-" 开头的注入消息(防反馈环)。
|
|
31
|
+
|
|
32
|
+
未做(待定/属功能而非 bug):work/cortex 分成 module workmem/cortexmem/deepcortexmem;
|
|
33
|
+
sleep.ts 深睡接进 sleep.night duty;运行期自检/痛觉(health check)。
|
|
34
|
+
|
|
35
|
+
⚠️ 改动要重启 pi 实例才生效(运行中的进程加载的是旧代码)。pi compaction 已是 enabled:false(保留)。
|
|
36
|
+
|
|
37
|
+
[2026-06-15 续] 容量警告语义修正("91% 危急" vs footer "42%" 的矛盾)
|
|
38
|
+
- 病:警告用「原始文件总量」(context+work+cortex) 报 "记忆危急 X%、会崩",但注入早已封顶 35% → 根本不会崩;
|
|
39
|
+
和 footer 的「实际注入 %」对不上,吓人又误导。
|
|
40
|
+
- 修:警告改成说真话——同时点明 rawPct(文件占窗口%) 与 injCap(注入封顶%),措辞从"危急/会崩"改成
|
|
41
|
+
"文件大了、超出封顶的旧记忆被截断、该 sleep 整理"。不再和 footer 打架。两个数测的本就是不同东西。
|
|
42
|
+
|
|
43
|
+
[2026-06-15 续2] 撤掉所有切片,回到「整份注入」(守铁律 + 消除 91/42 矛盾)
|
|
44
|
+
- 用户指令"不能 slice"。删掉 MEMORY_BUDGET、sliceToTokens、buildSnapshot 里的全部切片
|
|
45
|
+
→ context + work_memory + cortex【整份】注入,不切。
|
|
46
|
+
- 上一条"封顶35%不会崩"的容量警告随之作废:整份注入【会撑爆】,警告改回"危急、再涨会崩、立刻 sleep"。
|
|
47
|
+
- 副作用(好的):footer 的实际注入% 现在 ≈ 记忆文件% —— 之前"91% vs 42%"的矛盾正是切片造成的,已消除。
|
|
48
|
+
- 代价(用户接受):文件大于窗口会崩;防崩靠 sleep/nap 勤快压小(let the model decide),不靠机械切。
|
|
49
|
+
- 缓存修复(快照一次 + 增量 append) 与 余额硬闸 均保留不变。
|
|
50
|
+
|
|
51
|
+
[2026-06-15 续3] 加「超窗口兜底」破死锁(修"模型停下来/不working")
|
|
52
|
+
- 现象:context.md 涨到 ~1M token;纯"整份注入不切"→ 每轮撑爆窗口 → 模型停(且 hc 小号死了、没人把 context 压进 work)。
|
|
53
|
+
本质是纯 no-slice 在 context>窗口时的【死锁】:要它 sleep 缩小,但它撑爆跑不起来、就睡不了。
|
|
54
|
+
- 修:buildSnapshot 默认仍整份注入(守"不切");cortex+work 永远全量;【仅当】整份会超过窗口 70% 时,
|
|
55
|
+
才把 context 切到「尾部刚好放得下」——保命优先(永不停止的生命,崩死比丢最旧 context 更糟),块标题 ⚠️ 提示去 sleep。
|
|
56
|
+
- 容量警告同步:高占用 = "最旧 context 被兜底丢弃、该 sleep 把它编码走"(不再说"会崩")。
|
|
57
|
+
- 用户授权"赶紧修 bug,不管是什么"。这是对"绝对不切"的最小让步:平时绝不切,只在"切最旧 or 崩死"之间选活着。
|
|
58
|
+
|
|
59
|
+
[2026-06-15 续4] 加「代码强制整理」(修"根本没有强制 sleep,只发消息靠模型自觉")
|
|
60
|
+
- 病:FORCE 线原来只 sendMessage "立刻 sleep",全靠模型自觉去睡 → 它不睡 → 涨到 1M。
|
|
61
|
+
memory.dna.md 写的"85%→几乎强制 sleep"从来【没被写成代码】,只是条强烈措辞的消息。这才是 context 失控的根。
|
|
62
|
+
- 修:FORCE 线代码直接调 forceArchiveOldestContext()——把最旧 ~30% context 整段搬进 deep_cortex(可回捞)、
|
|
63
|
+
从 context 删掉,【不等模型】。非有损(原文搬走,不是总结)、不写 work_memory(不碰海马体地界)、
|
|
64
|
+
只主进程做(getSessionRole()==="main",防多实例抢写)。
|
|
65
|
+
- 这才是真正的"代码强制"。配合 70% 注入兜底 = 双保险:归档让磁盘文件不失控,兜底让注入永不超窗口。
|
|
66
|
+
[2026-06-19] memory 增量段改用包裹格式:---[hippocampus-work]--- / ---[context-delta]---,不再用旧 [] 格式
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# memory.ts — LESSONS
|
|
2
|
+
|
|
3
|
+
## 2026-06-15 KV cache 靠「顺序」,不是靠「少注入」
|
|
4
|
+
**背景**: 铁律是【整份注入、禁止 slice】,所以快照大(~90 万 token)是接受的;省钱靠 cache 命中,不靠切。
|
|
5
|
+
**命中的前提(顺序,缺一不可)**:
|
|
6
|
+
1. systemPrompt 必须日内稳定 —— pi 自带的只塞 `Current date:`(每天变一次)+ cwd,OK;
|
|
7
|
+
我们 6 个 func 的 append 是常量、注册顺序固定,OK。**别往 systemPrompt 塞每轮变的东西**。
|
|
8
|
+
2. 记忆快照只在 session_start 注入【一次】,本会话绝不重发(before_agent_start 不 return systemPrompt)。
|
|
9
|
+
3. 快照内部顺序 = 稳定→易变:DNA → cortex → work_memory → context。前缀(DNA+cortex)跨会话能命中。
|
|
10
|
+
4. 一切新内容(work_mem 增量 / 容量提醒 / 到期 / date / 余额)一律 append 到 tail(deliverAs nextTurn)。
|
|
11
|
+
**坑**: 任何排在快照【前面】且会变的消息,会让整份 90 万 token 快照 miss。已踩过的:budget-trip(见
|
|
12
|
+
[[budget-guard.ts.LESSONS]])、双 unstop-date(见 [[bioclock.ts.LESSONS]])。
|
|
13
|
+
**还没解决(诚实)**: 当前 live 的 context 已涨到 65 万~86 万 token,整份注入下逼近 1M 窗口。
|
|
14
|
+
forceArchiveOldestContext 到 FORCE 线才搬最旧 30% 进 deep_cortex;长期要靠 sleep/nap 持续消化。
|
|
15
|
+
重启清掉臃肿 context 是最快的止血。capacity 监控用 CJK 估算(中文 ≈1.8 token/字,别用 chars/4,会少算 7 倍)。
|
|
16
|
+
(注:2026-06-16 已把 pi 自带的 `Current date:` 注入也从 system-prompt.js 去掉了——少一个每天变的东西,缓存更稳。见 [[../../../deploy.ALL/dist-overrides/system-prompt.js.LESSONS]])
|
|
17
|
+
|
|
18
|
+
## 2026-06-16 sleep 睡完根本没叫醒主意识——工具文案撒谎,onComplete 是个死回路
|
|
19
|
+
**症状**: 问"睡好了会提醒模型吗"。查代码:sleep 工具返回文案写着"完成后会自动注入 wake feel",但 launchSleepSession 的 onComplete 回调里**只有** `dnaState="wake"; sleepHandle=null`——只翻了个内部变量,从没调 sendMessage、没唤醒、没通知任何人。主意识 sleep 前若 hibernate 了(enabled=false),就一直睡到用户来才醒。**文案承诺的功能,代码里根本不存在。**
|
|
20
|
+
**根因**: `dnaState` 只在【下次】session_start 被读去选 wake.dlc/sleep.dlc,对正在跑/已 hibernate 的主意识毫无作用。唤醒要走 `pi.sendMessage({...},{isTriggerNewTurn:true})`(心脏 process.ts/stop.ts 唤醒就是这么干的),onComplete 一个都没用上。
|
|
21
|
+
**修复(设计忠实,器官只走 pi)**:
|
|
22
|
+
- 海马体 onComplete:注入 `messageType:"sleep-done"` 的 wake feel + isTriggerNewTurn → 主意识被叫醒。
|
|
23
|
+
- 心脏 stop.ts:`pi.on("message_start")` 听到 sleep-done 就 `state.enabled=true` 重新点亮 continuous → 主意识真正活过来续命,而不是醒一个 turn 又僵住(hibernate 后 enabled=false,光 isTriggerNewTurn 一个 turn 完 agent_end 又停)。
|
|
24
|
+
- 跨器官不 import:海马体碰不到心脏的 state,心脏也不认识睡眠实例——只通过 pi 的 sleep-done 消息握手。这是这套架构里器官通信的唯一合法通道(grep 验证过:器官之间零互相 import)。
|
|
25
|
+
**教训**: **工具返回文案写"完成后会自动 X",必须去代码里确认真有 X。** 文案是给模型看的承诺,承诺和实现脱节 = 模型以为有这功能、其实是死的,比没写还坑(这张"自动注入 wake feel"的空头支票挂了不知多久)。查"完成后会怎样",要一路追到真正 sendMessage/改状态那行,别看到个 `dnaState="wake"` 就以为闭环。
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
source: memory.ts @ b60acb20
|
|
2
|
+
|
|
3
|
+
memory.ts · SPEC(brain.hippocampus 的主意识记忆机能)
|
|
4
|
+
|
|
5
|
+
设计来源: ideas.HUMAN/v0.2_spec.md + 2026-06-15 缓存/估算大修
|
|
6
|
+
核心原则: context 就是记忆,模型自己编辑自己。let the model decide。
|
|
7
|
+
归属: 不是独立 func(memory 是 tag,不是 func)。这是 brain.hippocampus 的代码,
|
|
8
|
+
由 hippocampus.ts 的 default(pi) 调 registerMemory(pi) 装上。
|
|
9
|
+
|
|
10
|
+
── 文件结构 per-person(数据=存,在 ~/.pi/memory/<id>/.data/,不在代码树)──
|
|
11
|
+
context.md ← 完整对话历史,message_end 增量写入,可被模型 editcontext
|
|
12
|
+
work_memory.md ← 海马体(hc-)再反思编码(nap 也往这写),不过度压缩
|
|
13
|
+
cortex.md ← 按叶分区长记忆(sleep 的 sl- 实例 1% 沉淀来的)
|
|
14
|
+
deep_cortex.md ← cortex 超 20% 窗口时沉降来的归档(不自动注入,按需回捞)
|
|
15
|
+
events.jsonl / growth.jsonl / reminders.json ← 旁路数据
|
|
16
|
+
|
|
17
|
+
── 注入架构(⚠️ 缓存铁律,2026-06-15 大修的核心)──
|
|
18
|
+
KV 缓存只在「提示词前缀逐轮一致」时命中。所以:
|
|
19
|
+
1. session_start(醒来):buildSnapshot() 把 DNA + cortex + work + context(尾部)
|
|
20
|
+
按 token 预算(≤窗口35%)揉成「一份快照」,作为消息注入【一次】。这是稳定前缀。
|
|
21
|
+
2. before_agent_start:【绝不】return systemPrompt。前缀不动 → 每轮命中缓存。
|
|
22
|
+
只做三件事,全部往「后面」append 或只写文件:
|
|
23
|
+
- work_memory 增量:比上次多出来的部分,作为新消息追加(不重发全部);
|
|
24
|
+
- 容量提醒:≥URGE(80%) 时 append 一条 [internal] 提醒(WARN 只记 growth.jsonl);
|
|
25
|
+
- 后台整理:cortex 超 20% → 沉降到 deep_cortex;events 修剪;到期 reminder append。
|
|
26
|
+
3. 重建快照 = 下次醒来(session_start)。中途 sleep/nap 整理过的文件,下个会话才进新快照。
|
|
27
|
+
—— 这就是「前缀=上次睡醒的快照,会话中只往后贴,睡觉时再揉成新快照」,一个会话最多一次未命中。
|
|
28
|
+
|
|
29
|
+
── token 估算(⚠️ 必须 CJK-aware)──
|
|
30
|
+
estimateTokens:CJK 字 ×1.8 token,其余 ÷4。
|
|
31
|
+
绝不能用 chars/4——中文少算约 7 倍,会让容量永不报警、注入撑爆窗口(历史事故:真 1.15M 只显示 38%)。
|
|
32
|
+
|
|
33
|
+
── 注入预算 ──
|
|
34
|
+
MEMORY_BUDGET = 窗口 × 0.35(给对话+补全留 65%)。
|
|
35
|
+
分配:cortex ≤35%·work ≤20%·context 填剩余,各自按尾部 sliceToTokens 切。
|
|
36
|
+
→ 配合 pi 自带 compaction:compacted 对话(~382K)+记忆(≤350K)+overhead < 1.048M,不爆。
|
|
37
|
+
|
|
38
|
+
── 工具 ──
|
|
39
|
+
editcontext 双操作:edit context.md + append cortex.md(cortex_entry 必须非空)
|
|
40
|
+
nap context 段 → work_memory(再反思,不一句话总结)
|
|
41
|
+
sleep 启动独立 sl- pi 实例做 1% 巩固(见 sleep.ts)。失败【显眼报错】,不再假装成功
|
|
42
|
+
dream 把 cortex 片段丢给潜意识做创造性反思
|
|
43
|
+
drinkcoffee 临时压制容量提醒 N 轮(不增容量)
|
|
44
|
+
|
|
45
|
+
── 失败要可见(2026-06-15 教训)──
|
|
46
|
+
禁止空 catch 吞错 / 笑脸 fallback。坏了必须让主意识看见(否则像 sleep 那样静默死好几天)。
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// sleep-session.ts — Independent sleep pi instance launcher
|
|
2
|
+
// v0.2 spec: 睡眠的 session 和潜意识一样都是一个 pi,激活 sleep.dlc
|
|
3
|
+
// Launches in tmux as sl-<personId>. Self-healing with backoff.
|
|
4
|
+
// Sleep pi only edits memory files; main consciousness continues working.
|
|
5
|
+
|
|
6
|
+
import { execSync } from "node:child_process";
|
|
7
|
+
import { writeFile, mkdir, readFile } from "node:fs/promises";
|
|
8
|
+
import * as path from "node:path";
|
|
9
|
+
import { getPrompt } from "#runtime";
|
|
10
|
+
|
|
11
|
+
// prompt 来自 coded.dna(coded hippocampus.sleep),由 runtime 取,不再硬编码。
|
|
12
|
+
// 海马体深睡期(sleep.night)的编码 prompt:把 work_memory 整段消化、一次性巩固进 cortex(见 coded.dna hippocampus.sleep)。
|
|
13
|
+
let _sleepPrompt: string | null = null;
|
|
14
|
+
function getSleepPrompt(): string {
|
|
15
|
+
if (!_sleepPrompt) _sleepPrompt = getPrompt("hippocampus.sleep");
|
|
16
|
+
return _sleepPrompt;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function launchSleepSession(
|
|
20
|
+
personDir: string,
|
|
21
|
+
onComplete: () => void,
|
|
22
|
+
): { stop: () => void; isRunning: () => boolean } {
|
|
23
|
+
// personDir 以 /.data 结尾 → personId 是上一级目录名。之前用 /([a-f0-9]+)$/ 匹配会落到 ".data" 上(取到 "a" 之类),
|
|
24
|
+
// tmux 名就乱了、也和显示对不上。统一取目录名。
|
|
25
|
+
const personId = path.basename(personDir) === ".data" ? path.basename(path.dirname(personDir)) : path.basename(personDir);
|
|
26
|
+
const tmuxName = `sl-${personId}`;
|
|
27
|
+
const sessionDir = path.join(personDir, "..", "sleep-sessions");
|
|
28
|
+
let running = false;
|
|
29
|
+
|
|
30
|
+
function tmuxHas(): boolean {
|
|
31
|
+
try {
|
|
32
|
+
execSync(`tmux has-session -t ${tmuxName} 2>/dev/null`);
|
|
33
|
+
return true;
|
|
34
|
+
} catch { return false; }
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Launch async
|
|
38
|
+
(async () => {
|
|
39
|
+
if (tmuxHas()) {
|
|
40
|
+
running = true;
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
running = true;
|
|
45
|
+
await mkdir(sessionDir, { recursive: true });
|
|
46
|
+
|
|
47
|
+
// Build sleep prompt
|
|
48
|
+
let dnaIndex = "";
|
|
49
|
+
try { dnaIndex = await readFile(`${personDir}/dna/index.md`, "utf8"); } catch {}
|
|
50
|
+
let sleepDlc = "";
|
|
51
|
+
try { sleepDlc = await readFile(`${personDir}/dna/sleep.dlc`, "utf8"); } catch {}
|
|
52
|
+
|
|
53
|
+
const fullPrompt = `${dnaIndex}\n\n${sleepDlc}\n\n${getSleepPrompt()}\n\n文件目录: ${personDir}`;
|
|
54
|
+
|
|
55
|
+
const promptFile = `${personDir}/sleep-prompt.md`;
|
|
56
|
+
await writeFile(promptFile, fullPrompt);
|
|
57
|
+
|
|
58
|
+
const launchScript = `${personDir}/sleep-launch.sh`;
|
|
59
|
+
await writeFile(launchScript, `#!/bin/bash
|
|
60
|
+
export NODE_OPTIONS="\${NODE_OPTIONS:+\$NODE_OPTIONS }--experimental-transform-types"
|
|
61
|
+
SESSION_DIR=${JSON.stringify(sessionDir)}
|
|
62
|
+
PERSON_DIR=${JSON.stringify(personDir)}
|
|
63
|
+
PROMPT_FILE=${JSON.stringify(promptFile)}
|
|
64
|
+
INITIAL="开始深度睡眠。主意识困到撑不住了。【分段】消化 context.md:每次只读最旧的一截(300~500 行,别一口吞,否则你自己也撑爆),重组进 cortex.md,cortex 装不下的沉 deep_cortex.md,消化完就把那一截从 context.md 删掉;一截截来,直到 context 小下来。work_memory.md 同理。全部弄完 hibernate。"
|
|
65
|
+
export PI_PERSON_DIR="$PERSON_DIR"
|
|
66
|
+
MAIN_PID=${process.pid}
|
|
67
|
+
BACKOFF=15
|
|
68
|
+
while true; do
|
|
69
|
+
# 级联:主意识进程没了就退出(睡眠是短任务,循环顶检查足够,不用常驻看门狗)。
|
|
70
|
+
kill -0 "$MAIN_PID" 2>/dev/null || { echo "[sl] 主意识没了,退出。"; break; }
|
|
71
|
+
START=$(date +%s)
|
|
72
|
+
mkdir -p "$SESSION_DIR"
|
|
73
|
+
# Write system prompt to conv.json (pi reads from session dir, --append-system-prompt doesn't exist)
|
|
74
|
+
LOCKDIR="$PERSON_DIR/.memory-lock"
|
|
75
|
+
LOCK_WAIT=0
|
|
76
|
+
while [ "$LOCK_WAIT" -lt 300 ]; do
|
|
77
|
+
if mkdir "$LOCKDIR" 2>/dev/null; then
|
|
78
|
+
echo "{\"owner\":\"sl\",\"ts\":$(date +%s)000}" > "$LOCKDIR/stamp" 2>/dev/null
|
|
79
|
+
break
|
|
80
|
+
fi
|
|
81
|
+
if [ -f "$LOCKDIR/stamp" ]; then
|
|
82
|
+
LOCK_TS=$(cat "$LOCKDIR/stamp" 2>/dev/null | grep -o '"ts":[0-9]*' | grep -o '[0-9]*')
|
|
83
|
+
NOW_MS=$(date +%s)000
|
|
84
|
+
if [ -n "$LOCK_TS" ] && [ $(( NOW_MS - LOCK_TS )) -gt 60000 ]; then
|
|
85
|
+
rm -f "$LOCKDIR/stamp" 2>/dev/null
|
|
86
|
+
rmdir "$LOCKDIR" 2>/dev/null
|
|
87
|
+
continue
|
|
88
|
+
fi
|
|
89
|
+
fi
|
|
90
|
+
LOCK_WAIT=$(( LOCK_WAIT + 1 ))
|
|
91
|
+
sleep 0.2
|
|
92
|
+
done
|
|
93
|
+
if [ "$LOCK_WAIT" -ge 300 ]; then
|
|
94
|
+
echo "[sl] 无法获取文件锁(60s 超时),跳过本轮" >> /dev/stderr
|
|
95
|
+
sleep 30
|
|
96
|
+
continue
|
|
97
|
+
fi
|
|
98
|
+
python3 -c "import json,shlex; open('$SESSION_DIR/conv.json','w').write(json.dumps({'messages':[{'role':'system','content':open('$PROMPT_FILE').read()}]}))" 2>/dev/null
|
|
99
|
+
echo "$INITIAL" | /opt/homebrew/bin/pi --session-dir "$SESSION_DIR"
|
|
100
|
+
CODE=$? # save pi exit code BEFORE releasing lock
|
|
101
|
+
rm -f "$LOCKDIR/stamp" 2>/dev/null
|
|
102
|
+
rmdir "$LOCKDIR" 2>/dev/null
|
|
103
|
+
RAN=$(( $(date +%s) - START ))
|
|
104
|
+
if [ "$CODE" -eq 0 ]; then
|
|
105
|
+
echo "[$(date '+%F %T')] sleep pi OK — work_memory should be cleared."
|
|
106
|
+
break
|
|
107
|
+
fi
|
|
108
|
+
if [ "$RAN" -ge 120 ]; then BACKOFF=15; else BACKOFF=$(( BACKOFF * 2 )); [ "$BACKOFF" -gt 300 ] && BACKOFF=300; fi
|
|
109
|
+
echo "[$(date '+%F %T')] sleep pi exit=$CODE ran=$RAN s — restart in $BACKOFF s"
|
|
110
|
+
sleep "$BACKOFF"
|
|
111
|
+
done
|
|
112
|
+
`);
|
|
113
|
+
execSync(`chmod +x "${launchScript}"`, { stdio: "ignore" });
|
|
114
|
+
try { execSync(`tmux kill-session -t ${tmuxName} 2>/dev/null`); } catch {} // 先清掉同名僵尸 session(spawn failed 的根)
|
|
115
|
+
execSync(
|
|
116
|
+
`tmux new-session -d -s ${tmuxName} -c "${personDir}" 'bash "${launchScript}"'`,
|
|
117
|
+
{ stdio: "ignore" }
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
// Check periodically and call onComplete when work_memory is empty
|
|
121
|
+
const checker = setInterval(() => {
|
|
122
|
+
if (!tmuxHas()) {
|
|
123
|
+
clearInterval(checker);
|
|
124
|
+
running = false;
|
|
125
|
+
onComplete();
|
|
126
|
+
}
|
|
127
|
+
}, 5000);
|
|
128
|
+
})();
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
stop() {
|
|
132
|
+
running = false;
|
|
133
|
+
try { execSync(`tmux kill-session -t ${tmuxName} 2>/dev/null`); } catch {}
|
|
134
|
+
},
|
|
135
|
+
isRunning() {
|
|
136
|
+
return running && tmuxHas();
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
[2026-06-15] created(追踪本次重构),by Claude Code
|
|
2
|
+
- 从 brain.hippocampus/hippocampus.sleep/sleep.ts 移到 brain.hippocampus/sleep.ts(扁平化,去掉嵌套子目录)。
|
|
3
|
+
- import 深度随之 4 层→3 层:getPrompt 从 "../../../../engine/runtime.js" → "../../../engine/runtime.js"。
|
|
4
|
+
- prompt 改走 coded.dna:const SLEEP_PROMPT = getPrompt("hippocampus.sleep"),不再硬编码。
|
|
5
|
+
- 配套修复(在 memory.ts):sleep 工具的 import 从 "./sleep-session.js" 改成 "./sleep.js"——
|
|
6
|
+
原路径一直 import 失败 → sleep 从未真正启动。详见 memory.ts.CHANGELOG。
|
|
7
|
+
|
|
8
|
+
[2026-06-15 续] 加级联退出(by Claude Code)
|
|
9
|
+
- sleep 启动脚本加 MAIN_PID + 循环顶 kill -0 检查:主意识没了就退出。
|
|
10
|
+
- 不用常驻看门狗(睡眠是短任务:编码完 CODE 0 就 break 退出,常驻看门狗会卡住 tmux、让 onComplete 永不触发)。
|
|
11
|
+
- 注意:主意识 hibernate ≠ 进程死。hibernate 时进程还在,kill -0 仍为真,sleep 照常完成。
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
source: sleep.ts @ 4a509a76
|
|
2
|
+
|
|
3
|
+
sleep.ts · SPEC(深睡:独立 sl- pi 实例启动器)
|
|
4
|
+
|
|
5
|
+
归属: brain.hippocampus 的代码(sleep.night 模式的巩固实现)。
|
|
6
|
+
被谁调: memory.ts 的 sleep 工具 → import("./sleep.js") → launchSleepSession(personDir, onComplete)。
|
|
7
|
+
|
|
8
|
+
做什么:
|
|
9
|
+
- 在 tmux 起一个【独立 pi 实例】sl-<personId>(对标 hc-/sc-,是第三个对等独立意识,DNA 铁律)。
|
|
10
|
+
- 加载 dna/index.md + dna/sleep.dlc + SLEEP_PROMPT(coded hippocampus.sleep)。
|
|
11
|
+
- 按 1% partial edit 把 work_memory.md 逐块编码进 cortex.md(不一次全搬)。
|
|
12
|
+
- 自愈:崩了带指数退避重启;work_memory 清空后 onComplete() → 主意识切回 wake。
|
|
13
|
+
- 主意识调 sleep 后可 hibernate,整理由这个独立实例完成。
|
|
14
|
+
|
|
15
|
+
prompt: 来自 coded.dna 的 `coded hippocampus.sleep`,经 ../../../engine/runtime.js 的 getPrompt 取。
|
|
16
|
+
注意: 文件名是 sleep.ts(不是 sleep-session.ts)。memory.ts 必须 import("./sleep.js")。
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
always_think 模块 v0.2 · SPEC
|
|
2
|
+
|
|
3
|
+
设计来源: 2026-06-14 对话 + ideas.HUMAN/v0.2_spec.md 第 2 行(打断-续写引擎)
|
|
4
|
+
核心问题: 模型写代码/说话时"脑就是手"——生成即动作,中间没有审查闸,
|
|
5
|
+
被参数里的思维定势(切片/复制/增量等惯例)直接冲成输出,自己感觉不到。
|
|
6
|
+
|
|
7
|
+
核心原则:
|
|
8
|
+
- 不是"先想后做"(prefix 式,执行一旦开始仍是弹道式),
|
|
9
|
+
而是"边写边想"——思考在动作进行中随时发生,且可回到断点续写。
|
|
10
|
+
- 人写东西不是一次性不停预测 token:写的过程中会停下来想。模型也该能。
|
|
11
|
+
- 该停就停,尤其在: 就要 commit 一个不可逆判断时 / "这样写很顺手"但没核对 spec 时 / 直觉与约束打架时。
|
|
12
|
+
|
|
13
|
+
机制(纯 mod,不新增 dist 补丁):
|
|
14
|
+
1. 模型在输出任意位置写下标记: <need think>
|
|
15
|
+
2. message_update 钩子读到半截 assistant 文本里出现该标记
|
|
16
|
+
3. mod 投递一条 steer 消息: pi.sendMessage({...}, {deliverAs:"steer", isTriggerNewTurn:true})
|
|
17
|
+
4. 经 unstop 的 steer→abort dist 补丁(agent.js: steer() 时 activeRun.abortController.abort()),
|
|
18
|
+
当前生成被 abort = 写作暂停;半截输出(以 <need think> 结尾)由 pi 原生 partial 机制保留进 context
|
|
19
|
+
5. steer 消息内容提示模型"现在想透,再从断点续写" → 模型转入思考 + 续写
|
|
20
|
+
6. 一次输出里可触发任意多次(允许在中间想无数次)
|
|
21
|
+
|
|
22
|
+
依赖:
|
|
23
|
+
- unstop 的 steer→abort 补丁(若该补丁不在,steer 不会暂停当前生成,本模块退化为"下一轮才生效")
|
|
24
|
+
|
|
25
|
+
钩子:
|
|
26
|
+
before_agent_start → 注入约定 prompt(教模型 <need think> 的用法),仅 enabled 时
|
|
27
|
+
agent_start → 重置每轮暂停计数
|
|
28
|
+
message_start → 重置"本条消息已触发"标志(每条新 assistant 消息可重新触发)
|
|
29
|
+
message_update → 检测标记 → 触发暂停
|
|
30
|
+
registerCommand("always_think") → on/off 开关
|
|
31
|
+
|
|
32
|
+
保护:
|
|
33
|
+
- per-message guard: 一个标记只触发一次(abort 生效前的残余 delta 不重复触发)
|
|
34
|
+
- per-turn 上限(MAX_PAUSES_PER_TURN, 暂定 50)防病态死循环;到顶不再触发
|
|
35
|
+
|
|
36
|
+
标记:
|
|
37
|
+
默认 "<need think>"(常量,可改)。选用不与模型原生 reasoning 标签冲突的形式。
|
|
38
|
+
|
|
39
|
+
已知限制 / 待办(诚实记录,需 live 测试):
|
|
40
|
+
- v1 只做"暂停-思考-续写";<need think> 标记会留在最终输出文本里(后续用 MessageRenderer 美化成"💭 暂停思考"指示)
|
|
41
|
+
- 续写是"在半截后另起一条 assistant 消息,模型看着自己半截+提示接着写",非字面同一 token 流延续(对目的够用)
|
|
42
|
+
- 更深形态(ideas 第 2 行的"或者"分支): 任何 command 是缓存里的可编辑文本文件,
|
|
43
|
+
模型写时可 edit/删/调(像人打字回删)。这是"草稿缓冲",比暂停-续写更难,留作后续。
|
|
44
|
+
- mid-stream 检测+abort 存在 race(abort 生效前的在途 delta),靠 guard 兜;真实表现需在 live pi 验证。
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
2
|
+
import { getPrompt } from "#runtime";
|
|
3
|
+
|
|
4
|
+
// 模型在输出任意位置写下这个标记 → 写作暂停 → 思考 → 从断点续写。
|
|
5
|
+
const MARKER = "<need think>";
|
|
6
|
+
// 防病态死循环:一轮里最多暂停这么多次(允许多次,但不是无限)。
|
|
7
|
+
const MAX_PAUSES_PER_TURN = 50;
|
|
8
|
+
|
|
9
|
+
// prompt 来自 coded.dna(coded drafting.think)。正文里的 {MARKER} 占位由本 func 填入真实标记。
|
|
10
|
+
const PROMPT = getPrompt("drafting.think").replace("{MARKER}", MARKER);
|
|
11
|
+
|
|
12
|
+
function assistantText(message: any): string {
|
|
13
|
+
const content = message?.content;
|
|
14
|
+
if (!content) return "";
|
|
15
|
+
if (typeof content === "string") return content;
|
|
16
|
+
if (!Array.isArray(content)) return "";
|
|
17
|
+
let s = "";
|
|
18
|
+
for (const c of content) {
|
|
19
|
+
if (typeof c === "string") s += c;
|
|
20
|
+
else if (c?.type === "text" && typeof c.text === "string") s += c.text;
|
|
21
|
+
}
|
|
22
|
+
return s;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function registerAlwaysThink(pi: ExtensionAPI) {
|
|
26
|
+
let enabled = true;
|
|
27
|
+
let triggeredForCurrentMessage = false;
|
|
28
|
+
let pausesThisTurn = 0;
|
|
29
|
+
|
|
30
|
+
// ── 教模型 <need think> 的用法 ──────────────────────────────────
|
|
31
|
+
pi.on("before_agent_start", async (event, _ctx) => {
|
|
32
|
+
if (!enabled) return;
|
|
33
|
+
return { systemPrompt: event.systemPrompt + "\n\n" + PROMPT };
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// ── 每轮开始:重置暂停计数 ──────────────────────────────────────
|
|
37
|
+
pi.on("agent_start", async () => {
|
|
38
|
+
pausesThisTurn = 0;
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// ── 每条新 assistant 消息:重置"已触发"标志 ────────────────────
|
|
42
|
+
pi.on("message_start", async () => {
|
|
43
|
+
triggeredForCurrentMessage = false;
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// ── 流式中检测标记 → 暂停 ───────────────────────────────────────
|
|
47
|
+
pi.on("message_update", async (event, _ctx) => {
|
|
48
|
+
if (!enabled) return;
|
|
49
|
+
if (triggeredForCurrentMessage) return; // 一个标记只触发一次
|
|
50
|
+
if (pausesThisTurn >= MAX_PAUSES_PER_TURN) return; // 到顶不再触发
|
|
51
|
+
|
|
52
|
+
const text = assistantText(event.message);
|
|
53
|
+
if (!text.includes(MARKER)) return;
|
|
54
|
+
|
|
55
|
+
// 暂停:投一条 steer 消息。经 continuous 的 steer→abort 补丁,当前生成被 abort
|
|
56
|
+
// = 写作冻在断点;半截输出(以 <need think> 结尾)由 pi 原生 partial 机制保留。
|
|
57
|
+
// 随后这条 steer 被处理 → 模型转入思考,再从断点续写。
|
|
58
|
+
triggeredForCurrentMessage = true;
|
|
59
|
+
pausesThisTurn++;
|
|
60
|
+
|
|
61
|
+
pi.sendMessage(
|
|
62
|
+
{
|
|
63
|
+
messageType: "always-think-pause",
|
|
64
|
+
content:
|
|
65
|
+
"[你写下了 <need think> —— 写作已暂停。现在把它想透:你正要写的东西、你的直觉、" +
|
|
66
|
+
"以及它和 spec/约束是否一致;想清楚后从断点继续写。想透了再写,别急着续。]",
|
|
67
|
+
display: false,
|
|
68
|
+
},
|
|
69
|
+
{ deliverAs: "steer", isTriggerNewTurn: true }
|
|
70
|
+
);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
source: drafting.ts @ 2eb28026
|
|
2
|
+
|
|
3
|
+
# drafting.ts — Pre-thinking injection: pause-and-think during generation
|
|
4
|
+
|
|
5
|
+
## 职责
|
|
6
|
+
Implements "always think" (边写边想): when the model writes `<need think>` mid-output, generation is paused via steer-triggered abort, a thinking prompt is injected, and the model resumes from the breakpoint after reflection. Allows the model to self-interrupt for deeper reasoning during long outputs.
|
|
7
|
+
|
|
8
|
+
## 接口
|
|
9
|
+
- `registerAlwaysThink(pi: ExtensionAPI): void` — installs hooks and /always_think command
|
|
10
|
+
|
|
11
|
+
## 依赖
|
|
12
|
+
- `#runtime` (getPrompt for "drafting.think")
|
|
13
|
+
- `@mariozechner/pi-coding-agent` (ExtensionAPI)
|
|
14
|
+
|
|
15
|
+
## 行为要点
|
|
16
|
+
- Marker `<need think>` is detected in streaming assistant output via message_update hook
|
|
17
|
+
- On detection: sends a steer message (messageType "always-think-pause") that aborts current generation
|
|
18
|
+
- Partial output preserved by pi's native partial mechanism; model continues from breakpoint
|
|
19
|
+
- Max 50 pauses per turn (MAX_PAUSES_PER_TURN) to prevent pathological loops
|
|
20
|
+
- Each marker triggers only once per message (triggeredForCurrentMessage flag)
|
|
21
|
+
- Pause counter resets on agent_start; trigger flag resets on message_start
|
|
22
|
+
- /always_think [on|off] command toggles the feature
|
|
23
|
+
- Prompt text from coded.dna with {MARKER} placeholder replaced at load time
|
|
24
|
+
- Depends on unstop's steer->abort dist patch (agent.js: steer() triggers abortController.abort())
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
2
|
+
import { registerAlwaysThink } from "./drafting.ts";
|
|
3
|
+
|
|
4
|
+
// always_think — 边写边想(草稿态)
|
|
5
|
+
// 模型写东西时,脑不该"就是手"。允许它在输出任意位置打一个 <need think> 标记,
|
|
6
|
+
// 写作立即暂停(自触发 mid-stream abort),模型转入思考,想透后从断点续写。
|
|
7
|
+
// 一次输出里可以这样停想任意多次。
|
|
8
|
+
//
|
|
9
|
+
// 依赖:continuous 的 steer→abort dist 补丁(agent.js: steer() 时 abortController.abort())。
|
|
10
|
+
// 这个补丁让"投递一条 steer 消息"等价于"暂停当前生成",always_think 就建在它上面。
|
|
11
|
+
export default function (pi: ExtensionAPI) {
|
|
12
|
+
registerAlwaysThink(pi);
|
|
13
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
source: main.ts @ 7b20157d
|
|
2
|
+
|
|
3
|
+
# index.ts — Drafting entry: wires always-think
|
|
4
|
+
|
|
5
|
+
## 职责
|
|
6
|
+
Entry point for the brain.prefrontal.drafting func. Delegates entirely to registerAlwaysThink from drafting.ts. Serves as the thin func entry that kernel imports via #drafting.
|
|
7
|
+
|
|
8
|
+
## 接口
|
|
9
|
+
- `default(pi: ExtensionAPI): void` — func entry called by kernel
|
|
10
|
+
|
|
11
|
+
## 依赖
|
|
12
|
+
- `./drafting.js` (registerAlwaysThink)
|
|
13
|
+
- `@mariozechner/pi-coding-agent` (ExtensionAPI)
|
|
14
|
+
|
|
15
|
+
## 行为要点
|
|
16
|
+
- Pure delegation: no additional logic
|
|
17
|
+
- Depends on unstop's steer->abort dist patch for mid-stream pause to work
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
2
|
+
|
|
3
|
+
export default function (pi: ExtensionAPI) {
|
|
4
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
5
|
+
const now = new Date();
|
|
6
|
+
const date = `${now.getFullYear()}-${String(now.getMonth()+1).padStart(2,"0")}-${String(now.getDate()).padStart(2,"0")}`;
|
|
7
|
+
// pi-coding-master: startup 只留 logo,不显示 Current date 通知
|
|
8
|
+
pi.sendMessage(
|
|
9
|
+
{ messageType: "continuous-date", content: `Current date: ${date}. Timestamps are wall-clock.`, isDisplayedInTUI: false },
|
|
10
|
+
{ deliverAs: "nextTurn" }
|
|
11
|
+
);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
function fmt(ts: number): string {
|
|
15
|
+
const d = new Date(ts);
|
|
16
|
+
const p2 = (n: number) => String(n).padStart(2, "0");
|
|
17
|
+
const p3 = (n: number) => String(n).padStart(3, "0");
|
|
18
|
+
return `${d.getFullYear()}-${p2(d.getMonth() + 1)}-${p2(d.getDate())} ${p2(d.getHours())}:${p2(d.getMinutes())}:${p2(d.getSeconds())}.${p3(d.getMilliseconds())}`;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Only stamp user and toolResult messages (input side).
|
|
22
|
+
// Assistant messages are the model's own output — it knows when it spoke.
|
|
23
|
+
// Return { message } to properly replace, not mutate in place.
|
|
24
|
+
pi.on("message_end", async (event, _ctx) => {
|
|
25
|
+
const msg = event.message;
|
|
26
|
+
if (!msg) return;
|
|
27
|
+
|
|
28
|
+
const role = (msg as any).role;
|
|
29
|
+
if (role !== "user") return;
|
|
30
|
+
|
|
31
|
+
const ts = (msg as any).timestamp;
|
|
32
|
+
if (!ts || typeof ts !== "number") return;
|
|
33
|
+
|
|
34
|
+
const tag = ` [${fmt(ts)}]`;
|
|
35
|
+
const content = (msg as any).content;
|
|
36
|
+
|
|
37
|
+
if (typeof content === "string") {
|
|
38
|
+
return { message: { ...msg, content: content.replace(/\s+$/, "") + tag } };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (!Array.isArray(content)) return;
|
|
42
|
+
|
|
43
|
+
const newContent = content.map((c: any, i: number, arr: any[]) => {
|
|
44
|
+
// Find last text block
|
|
45
|
+
const isLastText =
|
|
46
|
+
c.type === "text" &&
|
|
47
|
+
typeof c.text === "string" &&
|
|
48
|
+
!arr.slice(i + 1).some((x: any) => x.type === "text");
|
|
49
|
+
if (isLastText) {
|
|
50
|
+
return { ...c, text: c.text.replace(/\s+$/, "") + tag };
|
|
51
|
+
}
|
|
52
|
+
return c;
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
return { message: { ...msg, content: newContent } };
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// ── Per-tool timing: stamp each tool result with finish time + duration ──
|
|
59
|
+
// Embedded in the result itself, so the model knows exactly how long
|
|
60
|
+
// each command took. No duplicate-timestamp noise.
|
|
61
|
+
const toolStart = new Map<string, number>();
|
|
62
|
+
|
|
63
|
+
pi.on("tool_execution_start", async (event) => {
|
|
64
|
+
const id = (event as any).toolCallId;
|
|
65
|
+
if (id) toolStart.set(id, Date.now());
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
pi.on("tool_result", async (event, _ctx) => {
|
|
69
|
+
const id = (event as any).toolCallId;
|
|
70
|
+
const start = id ? toolStart.get(id) : undefined;
|
|
71
|
+
if (id) toolStart.delete(id);
|
|
72
|
+
|
|
73
|
+
const now = new Date();
|
|
74
|
+
const p2 = (n: number) => String(n).padStart(2, "0");
|
|
75
|
+
const time = `${p2(now.getHours())}:${p2(now.getMinutes())}:${p2(now.getSeconds())}.${String(now.getMilliseconds()).padStart(3,'0')}`;
|
|
76
|
+
const dur = start ? ` +${((Date.now() - start) / 1000).toFixed(1)}s` : "";
|
|
77
|
+
const tag = `\n[${time}${dur}]`;
|
|
78
|
+
|
|
79
|
+
const content = (event as any).content;
|
|
80
|
+
if (!Array.isArray(content)) return;
|
|
81
|
+
|
|
82
|
+
const textBlocks = content.filter((c: any) => c.type === "text" && typeof c.text === "string");
|
|
83
|
+
if (textBlocks.length === 0) return;
|
|
84
|
+
|
|
85
|
+
const newContent = content.map((c: any) => {
|
|
86
|
+
if (c === textBlocks[textBlocks.length - 1]) {
|
|
87
|
+
return { ...c, text: c.text.replace(/\s+$/, "") + tag };
|
|
88
|
+
}
|
|
89
|
+
return c;
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
return { content: newContent };
|
|
93
|
+
});
|
|
94
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# bioclock.ts — LESSONS
|
|
2
|
+
|
|
3
|
+
## 2026-06-15 双时间戳 = standalone 旧重复体被 install.sh 部署回来
|
|
4
|
+
**症状**: 每条消息出现两遍时间戳 / 两条 "Current date"。
|
|
5
|
+
**根因**: bioclock(bios,由 kernel 装配)已负责时间戳;但 install.sh 还 `cp` 了独立的
|
|
6
|
+
`extensions.DEV/timestamps.ts` 到 `~/.pi/agent/extensions/`,pi 按目录扫描把它当独立扩展【二次加载】
|
|
7
|
+
→ 两个都注入。`wise_file` vs bios `fileactions` 同理。
|
|
8
|
+
**修复**: ①注释掉 install.sh 里 `cp timestamps.ts*` / `cp -r wise_file` 两行;
|
|
9
|
+
②live 端把 `timestamps.ts` 改名 `*.DISABLED-dup-of-bioclock`(非删除、可逆,pi 不再加载)。
|
|
10
|
+
**原则**: 一个机能合进 bios(kernel 装配)后,必须把旧的 standalone 版从部署里去掉。
|
|
11
|
+
bios 版与 standalone 版是同一机能的两份实现 → 二选一,绝不共存,否则 pi 目录扫描双加载。
|
|
12
|
+
**附**: bioclock 给消息打时间戳是在 message_end / tool_result 时【一次性】打到那条消息上(基于消息自己固定的
|
|
13
|
+
timestamp),历史消息不会被重新打时间 → 不破坏 KV cache。这点是对的,别改成每轮重算。
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
source: bioclock.ts @ 959d9031
|
|
2
|
+
|
|
3
|
+
# bioclock.ts — Biological clock: timestamps on messages and tool results
|
|
4
|
+
|
|
5
|
+
## 职责
|
|
6
|
+
Gives the model awareness of wall-clock time. Injects current date at session_start, appends high-resolution timestamps to user messages (message_end), and stamps tool results with finish time + duration (tool_result). This lets the model know when events happened and how long tools took.
|
|
7
|
+
|
|
8
|
+
## 接口
|
|
9
|
+
- `default(pi: ExtensionAPI): void` — func entry called by kernel
|
|
10
|
+
|
|
11
|
+
## 依赖
|
|
12
|
+
- `@mariozechner/pi-coding-agent` (ExtensionAPI)
|
|
13
|
+
|
|
14
|
+
## 行为要点
|
|
15
|
+
- **session_start**: notifies UI with current date, sends date message (messageType "unstop-date") as nextTurn
|
|
16
|
+
- **message_end**: appends `[YYYY-MM-DD HH:MM:SS.mmm]` timestamp to the last text block of user messages only; skips assistant messages
|
|
17
|
+
- **tool_result**: appends `[HH:MM:SS +Ns]` (finish time + duration since tool_execution_start) to last text block of tool results
|
|
18
|
+
- Uses a Map keyed by toolCallId to track tool start times
|
|
19
|
+
- Only stamps user-role messages (model knows when it spoke)
|
|
20
|
+
- Returns `{ message }` for message_end rewrites (proper replacement, not mutation)
|