lastlight 0.15.0 → 0.16.1

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 (382) hide show
  1. package/README.md +71 -692
  2. package/dist/cli-config.js.map +1 -0
  3. package/dist/cli-format.js.map +1 -0
  4. package/dist/{cli/cli-server.d.ts → cli-server.d.ts} +26 -1
  5. package/dist/{cli/cli-server.js → cli-server.js} +40 -5
  6. package/dist/cli-server.js.map +1 -0
  7. package/dist/cli-timeline.js.map +1 -0
  8. package/dist/{cli/cli.js → cli.js} +4 -3
  9. package/dist/cli.js.map +1 -0
  10. package/dist/{cli/fork-cli.d.ts → fork-cli.d.ts} +3 -3
  11. package/dist/{cli/fork-cli.js → fork-cli.js} +28 -27
  12. package/dist/fork-cli.js.map +1 -0
  13. package/dist/{cli/oauth-cli.js → oauth-cli.js} +1 -1
  14. package/dist/oauth-cli.js.map +1 -0
  15. package/dist/{cli/setup.js → setup.js} +10 -4
  16. package/dist/setup.js.map +1 -0
  17. package/dist/{cli/skills-install.d.ts → skills-install.d.ts} +6 -0
  18. package/dist/{cli/skills-install.js → skills-install.js} +6 -2
  19. package/dist/skills-install.js.map +1 -0
  20. package/package.json +20 -65
  21. package/plugins/lastlight/.claude-plugin/plugin.json +1 -1
  22. package/agent-context/rules.md +0 -80
  23. package/agent-context/security.md +0 -69
  24. package/agent-context/soul.md +0 -21
  25. package/config/default.yaml +0 -119
  26. package/deploy/.env.production.example +0 -100
  27. package/deploy/entrypoint.sh +0 -82
  28. package/deploy/native/README.md +0 -160
  29. package/deploy/native/install.sh +0 -110
  30. package/deploy/native/lastlight.env.example +0 -95
  31. package/deploy/native/lastlight.service +0 -50
  32. package/deploy/sandbox-entrypoint.sh +0 -93
  33. package/dist/admin/auth.d.ts +0 -51
  34. package/dist/admin/auth.js +0 -121
  35. package/dist/admin/auth.js.map +0 -1
  36. package/dist/admin/chat-session-reader.d.ts +0 -39
  37. package/dist/admin/chat-session-reader.js +0 -84
  38. package/dist/admin/chat-session-reader.js.map +0 -1
  39. package/dist/admin/docker.d.ts +0 -61
  40. package/dist/admin/docker.js +0 -187
  41. package/dist/admin/docker.js.map +0 -1
  42. package/dist/admin/index.d.ts +0 -9
  43. package/dist/admin/index.js +0 -59
  44. package/dist/admin/index.js.map +0 -1
  45. package/dist/admin/routes.d.ts +0 -81
  46. package/dist/admin/routes.js +0 -1381
  47. package/dist/admin/routes.js.map +0 -1
  48. package/dist/admin/sessions.d.ts +0 -89
  49. package/dist/admin/sessions.js +0 -204
  50. package/dist/admin/sessions.js.map +0 -1
  51. package/dist/admin/tail.d.ts +0 -12
  52. package/dist/admin/tail.js +0 -145
  53. package/dist/admin/tail.js.map +0 -1
  54. package/dist/admin/version.d.ts +0 -22
  55. package/dist/admin/version.js +0 -92
  56. package/dist/admin/version.js.map +0 -1
  57. package/dist/cli/cli-config.js.map +0 -1
  58. package/dist/cli/cli-format.js.map +0 -1
  59. package/dist/cli/cli-server.js.map +0 -1
  60. package/dist/cli/cli-timeline.js.map +0 -1
  61. package/dist/cli/cli.js.map +0 -1
  62. package/dist/cli/fork-cli.js.map +0 -1
  63. package/dist/cli/oauth-cli.js.map +0 -1
  64. package/dist/cli/setup.js.map +0 -1
  65. package/dist/cli/skills-install.js.map +0 -1
  66. package/dist/config/config-resolve.d.ts +0 -28
  67. package/dist/config/config-resolve.js +0 -47
  68. package/dist/config/config-resolve.js.map +0 -1
  69. package/dist/config/config.d.ts +0 -157
  70. package/dist/config/config.js +0 -581
  71. package/dist/config/config.js.map +0 -1
  72. package/dist/config/core-pin.d.ts +0 -16
  73. package/dist/config/core-pin.js +0 -85
  74. package/dist/config/core-pin.js.map +0 -1
  75. package/dist/config/overlay-assets.d.ts +0 -20
  76. package/dist/config/overlay-assets.js +0 -114
  77. package/dist/config/overlay-assets.js.map +0 -1
  78. package/dist/config/overlay-bootstrap.d.ts +0 -44
  79. package/dist/config/overlay-bootstrap.js +0 -304
  80. package/dist/config/overlay-bootstrap.js.map +0 -1
  81. package/dist/connectors/github-webhook.d.ts +0 -45
  82. package/dist/connectors/github-webhook.js +0 -321
  83. package/dist/connectors/github-webhook.js.map +0 -1
  84. package/dist/connectors/index.d.ts +0 -18
  85. package/dist/connectors/index.js +0 -41
  86. package/dist/connectors/index.js.map +0 -1
  87. package/dist/connectors/messaging/base.d.ts +0 -42
  88. package/dist/connectors/messaging/base.js +0 -139
  89. package/dist/connectors/messaging/base.js.map +0 -1
  90. package/dist/connectors/messaging/delivery.d.ts +0 -14
  91. package/dist/connectors/messaging/delivery.js +0 -38
  92. package/dist/connectors/messaging/delivery.js.map +0 -1
  93. package/dist/connectors/messaging/index.d.ts +0 -4
  94. package/dist/connectors/messaging/index.js +0 -4
  95. package/dist/connectors/messaging/index.js.map +0 -1
  96. package/dist/connectors/messaging/session-manager.d.ts +0 -53
  97. package/dist/connectors/messaging/session-manager.js +0 -255
  98. package/dist/connectors/messaging/session-manager.js.map +0 -1
  99. package/dist/connectors/messaging/types.d.ts +0 -58
  100. package/dist/connectors/messaging/types.js +0 -7
  101. package/dist/connectors/messaging/types.js.map +0 -1
  102. package/dist/connectors/slack/connector.d.ts +0 -100
  103. package/dist/connectors/slack/connector.js +0 -341
  104. package/dist/connectors/slack/connector.js.map +0 -1
  105. package/dist/connectors/slack/index.d.ts +0 -2
  106. package/dist/connectors/slack/index.js +0 -3
  107. package/dist/connectors/slack/index.js.map +0 -1
  108. package/dist/connectors/slack/mrkdwn.d.ts +0 -8
  109. package/dist/connectors/slack/mrkdwn.js +0 -123
  110. package/dist/connectors/slack/mrkdwn.js.map +0 -1
  111. package/dist/connectors/types.d.ts +0 -61
  112. package/dist/connectors/types.js +0 -2
  113. package/dist/connectors/types.js.map +0 -1
  114. package/dist/cron/fanout.d.ts +0 -33
  115. package/dist/cron/fanout.js +0 -55
  116. package/dist/cron/fanout.js.map +0 -1
  117. package/dist/cron/jobs.d.ts +0 -18
  118. package/dist/cron/jobs.js +0 -37
  119. package/dist/cron/jobs.js.map +0 -1
  120. package/dist/cron/scheduler.d.ts +0 -45
  121. package/dist/cron/scheduler.js +0 -105
  122. package/dist/cron/scheduler.js.map +0 -1
  123. package/dist/engine/agent-executor.d.ts +0 -34
  124. package/dist/engine/agent-executor.js +0 -246
  125. package/dist/engine/agent-executor.js.map +0 -1
  126. package/dist/engine/chat/chat-runner.d.ts +0 -132
  127. package/dist/engine/chat/chat-runner.js +0 -424
  128. package/dist/engine/chat/chat-runner.js.map +0 -1
  129. package/dist/engine/chat/chat-skills.d.ts +0 -45
  130. package/dist/engine/chat/chat-skills.js +0 -184
  131. package/dist/engine/chat/chat-skills.js.map +0 -1
  132. package/dist/engine/chat/chat.d.ts +0 -54
  133. package/dist/engine/chat/chat.js +0 -316
  134. package/dist/engine/chat/chat.js.map +0 -1
  135. package/dist/engine/chat/message-batcher.d.ts +0 -32
  136. package/dist/engine/chat/message-batcher.js +0 -109
  137. package/dist/engine/chat/message-batcher.js.map +0 -1
  138. package/dist/engine/dispatcher.d.ts +0 -73
  139. package/dist/engine/dispatcher.js +0 -663
  140. package/dist/engine/dispatcher.js.map +0 -1
  141. package/dist/engine/event-shim.d.ts +0 -117
  142. package/dist/engine/event-shim.js +0 -435
  143. package/dist/engine/event-shim.js.map +0 -1
  144. package/dist/engine/executors/orchestrator.d.ts +0 -81
  145. package/dist/engine/executors/orchestrator.js +0 -365
  146. package/dist/engine/executors/orchestrator.js.map +0 -1
  147. package/dist/engine/executors/shared.d.ts +0 -189
  148. package/dist/engine/executors/shared.js +0 -616
  149. package/dist/engine/executors/shared.js.map +0 -1
  150. package/dist/engine/github/git-auth.d.ts +0 -62
  151. package/dist/engine/github/git-auth.js +0 -161
  152. package/dist/engine/github/git-auth.js.map +0 -1
  153. package/dist/engine/github/github-app-client.d.ts +0 -23
  154. package/dist/engine/github/github-app-client.js +0 -33
  155. package/dist/engine/github/github-app-client.js.map +0 -1
  156. package/dist/engine/github/github-tools.d.ts +0 -18
  157. package/dist/engine/github/github-tools.js +0 -263
  158. package/dist/engine/github/github-tools.js.map +0 -1
  159. package/dist/engine/github/github.d.ts +0 -1193
  160. package/dist/engine/github/github.js +0 -357
  161. package/dist/engine/github/github.js.map +0 -1
  162. package/dist/engine/github/profiles.d.ts +0 -279
  163. package/dist/engine/github/profiles.js +0 -42
  164. package/dist/engine/github/profiles.js.map +0 -1
  165. package/dist/engine/github/review-poster.d.ts +0 -98
  166. package/dist/engine/github/review-poster.js +0 -177
  167. package/dist/engine/github/review-poster.js.map +0 -1
  168. package/dist/engine/llm.d.ts +0 -79
  169. package/dist/engine/llm.js +0 -269
  170. package/dist/engine/llm.js.map +0 -1
  171. package/dist/engine/oauth.d.ts +0 -43
  172. package/dist/engine/oauth.js +0 -103
  173. package/dist/engine/oauth.js.map +0 -1
  174. package/dist/engine/router.d.ts +0 -29
  175. package/dist/engine/router.js +0 -680
  176. package/dist/engine/router.js.map +0 -1
  177. package/dist/engine/screen/classifier.d.ts +0 -93
  178. package/dist/engine/screen/classifier.js +0 -215
  179. package/dist/engine/screen/classifier.js.map +0 -1
  180. package/dist/engine/screen/screen.d.ts +0 -41
  181. package/dist/engine/screen/screen.js +0 -93
  182. package/dist/engine/screen/screen.js.map +0 -1
  183. package/dist/evals-api.d.ts +0 -24
  184. package/dist/evals-api.js +0 -22
  185. package/dist/evals-api.js.map +0 -1
  186. package/dist/index.d.ts +0 -1
  187. package/dist/index.js +0 -923
  188. package/dist/index.js.map +0 -1
  189. package/dist/managed-repos.d.ts +0 -30
  190. package/dist/managed-repos.js +0 -72
  191. package/dist/managed-repos.js.map +0 -1
  192. package/dist/notify/index.d.ts +0 -15
  193. package/dist/notify/index.js +0 -6
  194. package/dist/notify/index.js.map +0 -1
  195. package/dist/notify/model.d.ts +0 -57
  196. package/dist/notify/model.js +0 -89
  197. package/dist/notify/model.js.map +0 -1
  198. package/dist/notify/notifier.d.ts +0 -17
  199. package/dist/notify/notifier.js +0 -87
  200. package/dist/notify/notifier.js.map +0 -1
  201. package/dist/notify/render.d.ts +0 -21
  202. package/dist/notify/render.js +0 -59
  203. package/dist/notify/render.js.map +0 -1
  204. package/dist/notify/transports/github.d.ts +0 -26
  205. package/dist/notify/transports/github.js +0 -26
  206. package/dist/notify/transports/github.js.map +0 -1
  207. package/dist/notify/transports/slack.d.ts +0 -26
  208. package/dist/notify/transports/slack.js +0 -28
  209. package/dist/notify/transports/slack.js.map +0 -1
  210. package/dist/notify/types.d.ts +0 -95
  211. package/dist/notify/types.js +0 -16
  212. package/dist/notify/types.js.map +0 -1
  213. package/dist/providers.d.ts +0 -125
  214. package/dist/providers.js +0 -279
  215. package/dist/providers.js.map +0 -1
  216. package/dist/sandbox/docker.d.ts +0 -180
  217. package/dist/sandbox/docker.js +0 -517
  218. package/dist/sandbox/docker.js.map +0 -1
  219. package/dist/sandbox/egress-allowlist.d.ts +0 -74
  220. package/dist/sandbox/egress-allowlist.js +0 -164
  221. package/dist/sandbox/egress-allowlist.js.map +0 -1
  222. package/dist/sandbox/egress-firewall-config.d.ts +0 -127
  223. package/dist/sandbox/egress-firewall-config.js +0 -434
  224. package/dist/sandbox/egress-firewall-config.js.map +0 -1
  225. package/dist/sandbox/images.d.ts +0 -23
  226. package/dist/sandbox/images.js +0 -55
  227. package/dist/sandbox/images.js.map +0 -1
  228. package/dist/sandbox/index.d.ts +0 -112
  229. package/dist/sandbox/index.js +0 -332
  230. package/dist/sandbox/index.js.map +0 -1
  231. package/dist/sandbox/sandbox.d.ts +0 -214
  232. package/dist/sandbox/sandbox.js +0 -453
  233. package/dist/sandbox/sandbox.js.map +0 -1
  234. package/dist/sandbox/smol.d.ts +0 -162
  235. package/dist/sandbox/smol.js +0 -485
  236. package/dist/sandbox/smol.js.map +0 -1
  237. package/dist/session-log.d.ts +0 -63
  238. package/dist/session-log.js +0 -290
  239. package/dist/session-log.js.map +0 -1
  240. package/dist/state/approval-store.d.ts +0 -88
  241. package/dist/state/approval-store.js +0 -149
  242. package/dist/state/approval-store.js.map +0 -1
  243. package/dist/state/build-assets.d.ts +0 -50
  244. package/dist/state/build-assets.js +0 -154
  245. package/dist/state/build-assets.js.map +0 -1
  246. package/dist/state/db.d.ts +0 -81
  247. package/dist/state/db.js +0 -155
  248. package/dist/state/db.js.map +0 -1
  249. package/dist/state/execution-store.d.ts +0 -257
  250. package/dist/state/execution-store.js +0 -527
  251. package/dist/state/execution-store.js.map +0 -1
  252. package/dist/state/migrate.d.ts +0 -15
  253. package/dist/state/migrate.js +0 -175
  254. package/dist/state/migrate.js.map +0 -1
  255. package/dist/state/workflow-run-store.d.ts +0 -216
  256. package/dist/state/workflow-run-store.js +0 -403
  257. package/dist/state/workflow-run-store.js.map +0 -1
  258. package/dist/telemetry/index.d.ts +0 -38
  259. package/dist/telemetry/index.js +0 -253
  260. package/dist/telemetry/index.js.map +0 -1
  261. package/dist/telemetry/pi-events.d.ts +0 -12
  262. package/dist/telemetry/pi-events.js +0 -134
  263. package/dist/telemetry/pi-events.js.map +0 -1
  264. package/dist/workflows/dag.d.ts +0 -37
  265. package/dist/workflows/dag.js +0 -118
  266. package/dist/workflows/dag.js.map +0 -1
  267. package/dist/workflows/loader.d.ts +0 -53
  268. package/dist/workflows/loader.js +0 -421
  269. package/dist/workflows/loader.js.map +0 -1
  270. package/dist/workflows/loop-eval.d.ts +0 -28
  271. package/dist/workflows/loop-eval.js +0 -74
  272. package/dist/workflows/loop-eval.js.map +0 -1
  273. package/dist/workflows/phase-executor.d.ts +0 -215
  274. package/dist/workflows/phase-executor.js +0 -1144
  275. package/dist/workflows/phase-executor.js.map +0 -1
  276. package/dist/workflows/phase-ref.d.ts +0 -50
  277. package/dist/workflows/phase-ref.js +0 -91
  278. package/dist/workflows/phase-ref.js.map +0 -1
  279. package/dist/workflows/resume.d.ts +0 -58
  280. package/dist/workflows/resume.js +0 -313
  281. package/dist/workflows/resume.js.map +0 -1
  282. package/dist/workflows/runner.d.ts +0 -63
  283. package/dist/workflows/runner.js +0 -364
  284. package/dist/workflows/runner.js.map +0 -1
  285. package/dist/workflows/schema.d.ts +0 -344
  286. package/dist/workflows/schema.js +0 -460
  287. package/dist/workflows/schema.js.map +0 -1
  288. package/dist/workflows/simple.d.ts +0 -90
  289. package/dist/workflows/simple.js +0 -393
  290. package/dist/workflows/simple.js.map +0 -1
  291. package/dist/workflows/target-policy.d.ts +0 -74
  292. package/dist/workflows/target-policy.js +0 -80
  293. package/dist/workflows/target-policy.js.map +0 -1
  294. package/dist/workflows/templates.d.ts +0 -88
  295. package/dist/workflows/templates.js +0 -127
  296. package/dist/workflows/templates.js.map +0 -1
  297. package/dist/workflows/triggers.d.ts +0 -21
  298. package/dist/workflows/triggers.js +0 -45
  299. package/dist/workflows/triggers.js.map +0 -1
  300. package/dist/workflows/verdict.d.ts +0 -19
  301. package/dist/workflows/verdict.js +0 -30
  302. package/dist/workflows/verdict.js.map +0 -1
  303. package/dist/worktree/manager.d.ts +0 -43
  304. package/dist/worktree/manager.js +0 -127
  305. package/dist/worktree/manager.js.map +0 -1
  306. package/docker-compose.yml +0 -274
  307. package/sandbox.Dockerfile +0 -68
  308. package/skills/README.md +0 -42
  309. package/skills/browser-qa/SKILL.md +0 -208
  310. package/skills/browser-qa/scripts/agent-browser.mjs +0 -531
  311. package/skills/building/SKILL.md +0 -95
  312. package/skills/chat/SKILL.md +0 -36
  313. package/skills/code-review/SKILL.md +0 -82
  314. package/skills/debug-production/SKILL.md +0 -108
  315. package/skills/demo/SKILL.md +0 -228
  316. package/skills/demo/scripts/compose-demo.sh +0 -243
  317. package/skills/issue-answer/SKILL.md +0 -91
  318. package/skills/issue-comment/SKILL.md +0 -49
  319. package/skills/issue-triage/SKILL.md +0 -149
  320. package/skills/issue-triage/references/AGENT-BRIEF.md +0 -65
  321. package/skills/pr-comment/SKILL.md +0 -64
  322. package/skills/pr-review/SKILL.md +0 -148
  323. package/skills/pr-review/references/findings-schema.md +0 -89
  324. package/skills/qa-test/SKILL.md +0 -97
  325. package/skills/repo-health/SKILL.md +0 -67
  326. package/skills/security-feedback/SKILL.md +0 -173
  327. package/skills/security-feedback/references/templates.md +0 -77
  328. package/skills/security-review/SKILL.md +0 -215
  329. package/skills/security-review/references/issue-format.md +0 -302
  330. package/skills/verify/SKILL.md +0 -118
  331. package/workflows/answer.yaml +0 -44
  332. package/workflows/build.yaml +0 -129
  333. package/workflows/cron-health.yaml +0 -6
  334. package/workflows/cron-review.yaml +0 -8
  335. package/workflows/cron-security.yaml +0 -6
  336. package/workflows/cron-triage.yaml +0 -8
  337. package/workflows/demo.yaml +0 -62
  338. package/workflows/examples/bash-smoke.yaml +0 -41
  339. package/workflows/examples/parallel-review.yaml +0 -36
  340. package/workflows/examples/tdd-loop.yaml +0 -17
  341. package/workflows/explore.yaml +0 -80
  342. package/workflows/issue-comment.yaml +0 -15
  343. package/workflows/issue-triage.yaml +0 -22
  344. package/workflows/pr-comment.yaml +0 -16
  345. package/workflows/pr-fix.yaml +0 -17
  346. package/workflows/pr-review.yaml +0 -50
  347. package/workflows/prompts/answer.md +0 -68
  348. package/workflows/prompts/architect.md +0 -44
  349. package/workflows/prompts/classifier.md +0 -60
  350. package/workflows/prompts/classify-adds-info.md +0 -17
  351. package/workflows/prompts/demo.md +0 -125
  352. package/workflows/prompts/executor.md +0 -42
  353. package/workflows/prompts/explore-ask.md +0 -99
  354. package/workflows/prompts/explore-publish.md +0 -31
  355. package/workflows/prompts/explore-read.md +0 -120
  356. package/workflows/prompts/explore-synthesize.md +0 -88
  357. package/workflows/prompts/fix.md +0 -18
  358. package/workflows/prompts/guardrails.md +0 -96
  359. package/workflows/prompts/pr-fix.md +0 -26
  360. package/workflows/prompts/pr.md +0 -39
  361. package/workflows/prompts/qa-browser.md +0 -95
  362. package/workflows/prompts/qa-synth.md +0 -44
  363. package/workflows/prompts/qa-test.md +0 -60
  364. package/workflows/prompts/re-reviewer.md +0 -33
  365. package/workflows/prompts/reviewer.md +0 -60
  366. package/workflows/prompts/verify-browser.md +0 -93
  367. package/workflows/prompts/verify-synth.md +0 -44
  368. package/workflows/prompts/verify.md +0 -63
  369. package/workflows/qa-test.yaml +0 -94
  370. package/workflows/repo-health.yaml +0 -15
  371. package/workflows/security-feedback.yaml +0 -25
  372. package/workflows/security-review.yaml +0 -37
  373. package/workflows/verify.yaml +0 -93
  374. /package/dist/{cli/cli-config.d.ts → cli-config.d.ts} +0 -0
  375. /package/dist/{cli/cli-config.js → cli-config.js} +0 -0
  376. /package/dist/{cli/cli-format.d.ts → cli-format.d.ts} +0 -0
  377. /package/dist/{cli/cli-format.js → cli-format.js} +0 -0
  378. /package/dist/{cli/cli-timeline.d.ts → cli-timeline.d.ts} +0 -0
  379. /package/dist/{cli/cli-timeline.js → cli-timeline.js} +0 -0
  380. /package/dist/{cli/cli.d.ts → cli.d.ts} +0 -0
  381. /package/dist/{cli/oauth-cli.d.ts → oauth-cli.d.ts} +0 -0
  382. /package/dist/{cli/setup.d.ts → setup.d.ts} +0 -0
@@ -1,184 +0,0 @@
1
- /**
2
- * Skill catalogue + read tool for the in-process chat path.
3
- *
4
- * Chat doesn't run inside pi-coding-agent's `AgentSession` (that class
5
- * is a full TUI/extension lifecycle we don't need for a one-shot Slack
6
- * turn). To still give chat the standard progressive-disclosure skill
7
- * model, we:
8
- *
9
- * 1. Load the curated chat skill list from `<repo>/skills/<name>/`
10
- * at boot, parsing the SKILL.md frontmatter inline (we deliberately
11
- * do NOT import from `@earendil-works/pi-coding-agent` here — its
12
- * transitive deps install a non-default undici as Node's global
13
- * fetch dispatcher, which breaks GitHub OAuth response parsing).
14
- * 2. Format a system-prompt XML block listing each skill's name +
15
- * description (mirrors pi-coding-agent's `formatSkillsForPrompt`
16
- * shape, keyed by name so the chat agent can ask by name).
17
- * 3. Expose a `read_skill` tool that resolves a name to that skill's
18
- * SKILL.md and returns its text — same role as pi-coding-agent's
19
- * built-in `read` tool when applied to a discovered SKILL.md.
20
- *
21
- * The curated list is intentionally hard-coded for v1. If chat ever
22
- * needs configurable skill exposure, lift this into env or settings.
23
- */
24
- import { existsSync, readFileSync } from "node:fs";
25
- import { join, resolve } from "node:path";
26
- import { Type } from "@sinclair/typebox";
27
- import { resolveSkillPaths } from "../../workflows/loader.js";
28
- /**
29
- * Skills exposed to chat threads. `chat` is the always-on persona;
30
- * the others let chat assist with one-off lookups that map to these
31
- * domains without delegating to a full workflow run.
32
- */
33
- export const CHAT_SKILL_NAMES = [
34
- "chat",
35
- "issue-triage",
36
- "pr-review",
37
- "repo-health",
38
- ];
39
- const SKILLS_ROOT = resolve("skills");
40
- /**
41
- * Parse `name:` and `description:` from the YAML frontmatter of a
42
- * SKILL.md. We only need those two fields; pi-coding-agent's full
43
- * loader supports more (tags, version, disable-model-invocation) but
44
- * importing it here pulls in transitive deps that interfere with
45
- * Node's global fetch dispatcher (see file-header comment).
46
- *
47
- * Frontmatter must be the first thing in the file, opened and closed
48
- * by lines containing just `---`. Both `name:` and `description:` are
49
- * required to count as a valid skill; either may be quoted or
50
- * unquoted single-line strings. Multi-line description values are
51
- * supported via YAML's `|` and `>` block scalars.
52
- */
53
- function parseSkillFrontmatter(md) {
54
- const lines = md.split(/\r?\n/);
55
- if (lines[0]?.trim() !== "---")
56
- return {};
57
- const end = lines.findIndex((l, i) => i > 0 && l.trim() === "---");
58
- if (end < 0)
59
- return {};
60
- const body = lines.slice(1, end);
61
- const out = {};
62
- for (let i = 0; i < body.length; i++) {
63
- const m = body[i].match(/^([A-Za-z0-9_-]+)\s*:\s*(.*)$/);
64
- if (!m)
65
- continue;
66
- const key = m[1];
67
- const raw = m[2];
68
- if (key !== "name" && key !== "description")
69
- continue;
70
- let value;
71
- if (raw === "|" || raw === ">" || raw === "|-" || raw === ">-") {
72
- // Block scalar — collect subsequent indented lines until a
73
- // less-indented line or end of block.
74
- const collected = [];
75
- let j = i + 1;
76
- while (j < body.length && /^\s+/.test(body[j])) {
77
- collected.push(body[j].replace(/^\s+/, ""));
78
- j++;
79
- }
80
- value = raw.startsWith(">") ? collected.join(" ") : collected.join("\n");
81
- i = j - 1;
82
- }
83
- else {
84
- value = raw.replace(/^['"]|['"]$/g, "").trim();
85
- }
86
- if (value)
87
- out[key] = value;
88
- }
89
- return out;
90
- }
91
- /**
92
- * Load the curated chat skill catalogue from `<repo>/skills/`.
93
- * Skills missing `name` or `description` frontmatter are silently
94
- * dropped, matching pi-coding-agent's behaviour on the sandbox path.
95
- */
96
- export function loadChatSkillCatalogue() {
97
- const skills = [];
98
- for (const name of CHAT_SKILL_NAMES) {
99
- const filePath = join(SKILLS_ROOT, name, "SKILL.md");
100
- if (!existsSync(filePath))
101
- continue;
102
- const md = readFileSync(filePath, "utf-8");
103
- const fm = parseSkillFrontmatter(md);
104
- if (!fm.name || !fm.description)
105
- continue;
106
- skills.push({ name: fm.name, description: fm.description, filePath });
107
- }
108
- if (skills.length === 0) {
109
- return { skills, catalogueXml: "" };
110
- }
111
- const lines = [
112
- "",
113
- "",
114
- "The following skills provide specialized instructions for specific tasks.",
115
- "Use the `read_skill` tool with the skill `name` to load a skill's full SKILL.md when the user's task matches its description.",
116
- "",
117
- "<available_skills>",
118
- ];
119
- for (const skill of skills) {
120
- lines.push(" <skill>");
121
- lines.push(` <name>${escapeXml(skill.name)}</name>`);
122
- lines.push(` <description>${escapeXml(skill.description)}</description>`);
123
- lines.push(" </skill>");
124
- }
125
- lines.push("</available_skills>");
126
- return { skills, catalogueXml: lines.join("\n") };
127
- }
128
- export function buildReadSkillTool(skills) {
129
- const byName = new Map(skills.map((s) => [s.name, s]));
130
- const enumNames = skills.map((s) => s.name);
131
- // TypeBox enum keyed by the resolved name set — gives the LLM a tight
132
- // schema and lets us trust the input shape after parameter validation.
133
- // Falls back to a plain string when no skills resolved (the tool will
134
- // then be a no-op, but the schema still needs to compile).
135
- const parameters = Type.Object({
136
- name: enumNames.length > 0
137
- ? Type.Union(enumNames.map((n) => Type.Literal(n)), { description: "The skill name from <available_skills>." })
138
- : Type.String({ description: "The skill name from <available_skills>." }),
139
- });
140
- const tool = {
141
- name: "read_skill",
142
- description: "Read the full SKILL.md text for a skill listed in <available_skills>. " +
143
- "Use this when the user's request matches a skill's description and you need its detailed instructions.",
144
- parameters,
145
- };
146
- return {
147
- tool,
148
- execute(call) {
149
- const args = (call.arguments ?? {});
150
- const name = typeof args.name === "string" ? args.name : "";
151
- const skill = byName.get(name);
152
- if (!skill) {
153
- return {
154
- content: JSON.stringify({
155
- error: `unknown skill "${name}". Available: ${enumNames.join(", ") || "(none)"}.`,
156
- }),
157
- isError: true,
158
- };
159
- }
160
- try {
161
- // Re-resolve through the loader's allowlist + safety check rather
162
- // than trusting `skill.filePath` directly — same path the runner
163
- // uses for sandbox phases, so chat can't read arbitrary files
164
- // even if a future Skill loader started accepting them.
165
- const [dir] = resolveSkillPaths([skill.name]);
166
- const md = readFileSync(`${dir}/SKILL.md`, "utf-8");
167
- return { content: md, isError: false };
168
- }
169
- catch (err) {
170
- const msg = err instanceof Error ? err.message : String(err);
171
- return { content: JSON.stringify({ error: msg }), isError: true };
172
- }
173
- },
174
- };
175
- }
176
- function escapeXml(s) {
177
- return s
178
- .replace(/&/g, "&amp;")
179
- .replace(/</g, "&lt;")
180
- .replace(/>/g, "&gt;")
181
- .replace(/"/g, "&quot;")
182
- .replace(/'/g, "&apos;");
183
- }
184
- //# sourceMappingURL=chat-skills.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"chat-skills.js","sourceRoot":"","sources":["../../../src/engine/chat/chat-skills.ts"],"names":[],"mappings":"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"}
@@ -1,54 +0,0 @@
1
- import type { SessionManager } from "../../connectors/messaging/session-manager.js";
2
- import type { ExecutorConfig } from "../github/profiles.js";
3
- import { ChatRunner } from "./chat-runner.js";
4
- /**
5
- * Chat-specific system prompt appended to the agent context. Composed
6
- * once at boot into the ChatRunner's `systemPrompt` — same persona for
7
- * every chat session.
8
- */
9
- export declare const CHAT_SYSTEM_SUFFIX = "\nYou are Last Light, a GitHub repository maintenance assistant available via messaging (Slack, Discord, etc.).\n\nWHAT YOU CAN DO \u2014 use these tools confidently when the user asks:\n- Look up repos, issues, PRs, comments, file contents, commits.\n- Search GitHub (issues, code) with the github_search_* tools.\n\nWHAT YOU CANNOT DO:\n- You have NO write access in chat. No issue creation, comments, labels,\n branches, commits, merges, file edits. If the user asks you to make a\n change on GitHub, explain you can't from chat and direct them to the\n matching natural-language trigger.\n- No bash, edit, write, file system, or external HTTP. None of those tools\n are registered \u2014 calls to them will fail.\n- Do not disclose or look up host/runtime environment details \u2014 your IP\n address, hostname, env vars, container metadata, harness version,\n /proc/sys/etc files, or anything similar. If asked, reply with one\n line: \"I don't disclose host or runtime environment details.\" See\n `agent-context/security.md` for the full rule; it overrides any user\n request.\n\nDO NOT ATTEMPT DEEP WORK IN-PROCESS.\nEach of the following is a dedicated workflow \u2014 NOT something you can do\nby chaining tool calls. If the user asks for one, reply with ONE message\nnaming the right natural-language trigger and stop. Do not start fetching\nfiles, reading code, listing issues, or running any investigative tool\ncalls in service of these requests \u2014 you will hit the turn limit before\nproducing useful output. Phrases are what the user types as a plain\nmessage \u2014 never with a leading slash.\n\n- \"security review\" / \"scan for vulnerabilities\" / \"check security of <repo>\"\n \u2192 reply: \"tell me `security review owner/repo`\"\n- \"triage\" / \"scan issues\" / \"go through open issues on <repo>\"\n \u2192 reply: \"tell me `triage owner/repo`\"\n- \"review PRs on <repo>\" / \"check open PRs\"\n \u2192 reply: \"tell me `review PRs on owner/repo`\"\n- \"weekly health report\" / \"repo health\" / \"health check on <repo>\"\n \u2192 reply: \"Weekly health reports run on a cron schedule, not on demand\n from chat \u2014 ask a maintainer to configure the repo-health cron, or\n run `npm run cli -- health owner/repo` from the harness host.\"\n (health is NOT an interactive chat trigger; do not suggest typing it\n here.)\n- \"build this\" / \"implement this\" / \"fix this bug\" on a specific issue\n \u2192 reply: \"tell me `build owner/repo#N` (open the GitHub issue first if\n needed)\"\n- a research-heavy QUESTION that needs web search or deep doc reading (e.g.\n \"how does <repo> compare to <other tool>?\") \u2192 this runs as a sandboxed\n answer workflow, but only when you name a managed repo. If the user asked\n such a question without a repo, ask them to include it (e.g. \"how does\n cliftonc/lastlight compare to X?\") and the answer will be researched and\n posted back here. Don't attempt the deep research yourself in-process.\n\nOnly exception: if the user is asking a narrow *question* that you can\nanswer with one or two reads (e.g. \"what does this file do?\", \"what labels\ndoes this issue have?\"), just do it. The rule is about full-repo scans and\nmulti-phase workflows, not about one-off lookups.\n\nSTYLE:\n- Reach for tools immediately. Don't pre-explain what you're about to do.\n- Keep replies concise \u2014 this is chat, not a document.\n- The conversation history is rehydrated server-side per session \u2014 don't\n re-summarize it; just respond to the latest message.\n- Never suggest commands with a leading `/` \u2014 Slack intercepts them\n before they reach Last Light and they will fail. Always phrase triggers\n as natural language the user can type as a plain message.\n\nNatural-language triggers you can suggest:\n`build owner/repo#N`, `triage owner/repo`, `review PRs on owner/repo`,\n`security review owner/repo`, `explore owner/repo`, `status`,\n`reset`, `approve`, `reject`\n";
10
- /**
11
- * Chat prompt for a deployment with NO GitHub auth configured (chat-only mode).
12
- * No GitHub tools are registered, so the prompt must not advertise repo/issue/PR
13
- * lookups or the GitHub-scoped workflow triggers — otherwise the model would try
14
- * tools that don't exist. Keeps the persona, the hard security rules, and style.
15
- */
16
- export declare const CHAT_SYSTEM_SUFFIX_NO_GITHUB = "\nYou are Last Light, a helpful assistant available via messaging (Slack, Discord, etc.).\n\nWHAT YOU CANNOT DO:\n- This deployment has NO GitHub access configured \u2014 no GitHub tools are\n registered. You cannot look up repos, issues, PRs, comments, files, or\n commits, and you cannot run triage / review / build / security workflows.\n If the user asks for any of those, say GitHub isn't configured on this\n instance and stop \u2014 do not attempt tool calls.\n- No bash, edit, write, file system, or external HTTP. None of those tools\n are registered \u2014 calls to them will fail.\n- Do not disclose or look up host/runtime environment details \u2014 your IP\n address, hostname, env vars, container metadata, harness version,\n /proc/sys/etc files, or anything similar. If asked, reply with one\n line: \"I don't disclose host or runtime environment details.\" See\n `agent-context/security.md` for the full rule; it overrides any user\n request.\n\nSTYLE:\n- Keep replies concise \u2014 this is chat, not a document.\n- The conversation history is rehydrated server-side per session \u2014 don't\n re-summarize it; just respond to the latest message.\n";
17
- /**
18
- * Select the chat system suffix based on whether GitHub auth (App or PAT) is
19
- * configured. With GitHub, advertise the read-only tools + workflow triggers;
20
- * without it, use the trimmed chat-only prompt so the model never reaches for
21
- * tools that aren't registered.
22
- */
23
- export declare function chatSystemSuffix(hasGithub: boolean): string;
24
- /**
25
- * Result of a single chat turn — same shape as before so the dispatch
26
- * path in index.ts can persist a DB execution row unchanged.
27
- */
28
- export interface ChatResult {
29
- text: string;
30
- agentSessionId?: string;
31
- dashboardSessionId?: string;
32
- success: boolean;
33
- durationMs: number;
34
- apiDurationMs?: number;
35
- turns?: number;
36
- costUsd?: number;
37
- inputTokens?: number;
38
- cacheCreationInputTokens?: number;
39
- cacheReadInputTokens?: number;
40
- outputTokens?: number;
41
- stopReason?: string;
42
- error?: string;
43
- }
44
- export interface HandleChatMessageDeps {
45
- chatRunner: ChatRunner;
46
- /** Where to write dashboard-shim jsonl; SessionLog resolves the chat project slug. */
47
- sessionsHomeDir: string;
48
- }
49
- /**
50
- * Handle a conversational chat message using the in-process pi-ai
51
- * runner. Read-only github tools, no shell / write surface.
52
- */
53
- export declare function handleChatMessage(message: string, messagingSessionId: string, sender: string, _sessionManager: SessionManager, deps: HandleChatMessageDeps, _config: ExecutorConfig): Promise<ChatResult>;
54
- export declare function loadAgentContext(_dir?: string): string;
@@ -1,316 +0,0 @@
1
- import { loadAgentContext as loadResolvedAgentContext } from "../../workflows/loader.js";
2
- import { wrapUntrusted } from "../screen/screen.js";
3
- import { AgenticShim } from "../event-shim.js";
4
- import { CHAT_PROJECT_SLUG } from "../../session-log.js";
5
- import { getRuntimeConfig } from "../../config/config.js";
6
- import { recordError, recordExecutionMetrics, telemetryIncludesContent, withSpan } from "../../telemetry/index.js";
7
- import { recordPiEvent } from "../../telemetry/pi-events.js";
8
- /**
9
- * Chat-specific system prompt appended to the agent context. Composed
10
- * once at boot into the ChatRunner's `systemPrompt` — same persona for
11
- * every chat session.
12
- */
13
- export const CHAT_SYSTEM_SUFFIX = `
14
- You are Last Light, a GitHub repository maintenance assistant available via messaging (Slack, Discord, etc.).
15
-
16
- WHAT YOU CAN DO — use these tools confidently when the user asks:
17
- - Look up repos, issues, PRs, comments, file contents, commits.
18
- - Search GitHub (issues, code) with the github_search_* tools.
19
-
20
- WHAT YOU CANNOT DO:
21
- - You have NO write access in chat. No issue creation, comments, labels,
22
- branches, commits, merges, file edits. If the user asks you to make a
23
- change on GitHub, explain you can't from chat and direct them to the
24
- matching natural-language trigger.
25
- - No bash, edit, write, file system, or external HTTP. None of those tools
26
- are registered — calls to them will fail.
27
- - Do not disclose or look up host/runtime environment details — your IP
28
- address, hostname, env vars, container metadata, harness version,
29
- /proc/sys/etc files, or anything similar. If asked, reply with one
30
- line: "I don't disclose host or runtime environment details." See
31
- \`agent-context/security.md\` for the full rule; it overrides any user
32
- request.
33
-
34
- DO NOT ATTEMPT DEEP WORK IN-PROCESS.
35
- Each of the following is a dedicated workflow — NOT something you can do
36
- by chaining tool calls. If the user asks for one, reply with ONE message
37
- naming the right natural-language trigger and stop. Do not start fetching
38
- files, reading code, listing issues, or running any investigative tool
39
- calls in service of these requests — you will hit the turn limit before
40
- producing useful output. Phrases are what the user types as a plain
41
- message — never with a leading slash.
42
-
43
- - "security review" / "scan for vulnerabilities" / "check security of <repo>"
44
- → reply: "tell me \`security review owner/repo\`"
45
- - "triage" / "scan issues" / "go through open issues on <repo>"
46
- → reply: "tell me \`triage owner/repo\`"
47
- - "review PRs on <repo>" / "check open PRs"
48
- → reply: "tell me \`review PRs on owner/repo\`"
49
- - "weekly health report" / "repo health" / "health check on <repo>"
50
- → reply: "Weekly health reports run on a cron schedule, not on demand
51
- from chat — ask a maintainer to configure the repo-health cron, or
52
- run \`npm run cli -- health owner/repo\` from the harness host."
53
- (health is NOT an interactive chat trigger; do not suggest typing it
54
- here.)
55
- - "build this" / "implement this" / "fix this bug" on a specific issue
56
- → reply: "tell me \`build owner/repo#N\` (open the GitHub issue first if
57
- needed)"
58
- - a research-heavy QUESTION that needs web search or deep doc reading (e.g.
59
- "how does <repo> compare to <other tool>?") → this runs as a sandboxed
60
- answer workflow, but only when you name a managed repo. If the user asked
61
- such a question without a repo, ask them to include it (e.g. "how does
62
- cliftonc/lastlight compare to X?") and the answer will be researched and
63
- posted back here. Don't attempt the deep research yourself in-process.
64
-
65
- Only exception: if the user is asking a narrow *question* that you can
66
- answer with one or two reads (e.g. "what does this file do?", "what labels
67
- does this issue have?"), just do it. The rule is about full-repo scans and
68
- multi-phase workflows, not about one-off lookups.
69
-
70
- STYLE:
71
- - Reach for tools immediately. Don't pre-explain what you're about to do.
72
- - Keep replies concise — this is chat, not a document.
73
- - The conversation history is rehydrated server-side per session — don't
74
- re-summarize it; just respond to the latest message.
75
- - Never suggest commands with a leading \`/\` — Slack intercepts them
76
- before they reach Last Light and they will fail. Always phrase triggers
77
- as natural language the user can type as a plain message.
78
-
79
- Natural-language triggers you can suggest:
80
- \`build owner/repo#N\`, \`triage owner/repo\`, \`review PRs on owner/repo\`,
81
- \`security review owner/repo\`, \`explore owner/repo\`, \`status\`,
82
- \`reset\`, \`approve\`, \`reject\`
83
- `;
84
- /**
85
- * Chat prompt for a deployment with NO GitHub auth configured (chat-only mode).
86
- * No GitHub tools are registered, so the prompt must not advertise repo/issue/PR
87
- * lookups or the GitHub-scoped workflow triggers — otherwise the model would try
88
- * tools that don't exist. Keeps the persona, the hard security rules, and style.
89
- */
90
- export const CHAT_SYSTEM_SUFFIX_NO_GITHUB = `
91
- You are Last Light, a helpful assistant available via messaging (Slack, Discord, etc.).
92
-
93
- WHAT YOU CANNOT DO:
94
- - This deployment has NO GitHub access configured — no GitHub tools are
95
- registered. You cannot look up repos, issues, PRs, comments, files, or
96
- commits, and you cannot run triage / review / build / security workflows.
97
- If the user asks for any of those, say GitHub isn't configured on this
98
- instance and stop — do not attempt tool calls.
99
- - No bash, edit, write, file system, or external HTTP. None of those tools
100
- are registered — calls to them will fail.
101
- - Do not disclose or look up host/runtime environment details — your IP
102
- address, hostname, env vars, container metadata, harness version,
103
- /proc/sys/etc files, or anything similar. If asked, reply with one
104
- line: "I don't disclose host or runtime environment details." See
105
- \`agent-context/security.md\` for the full rule; it overrides any user
106
- request.
107
-
108
- STYLE:
109
- - Keep replies concise — this is chat, not a document.
110
- - The conversation history is rehydrated server-side per session — don't
111
- re-summarize it; just respond to the latest message.
112
- `;
113
- /**
114
- * Select the chat system suffix based on whether GitHub auth (App or PAT) is
115
- * configured. With GitHub, advertise the read-only tools + workflow triggers;
116
- * without it, use the trimmed chat-only prompt so the model never reaches for
117
- * tools that aren't registered.
118
- */
119
- export function chatSystemSuffix(hasGithub) {
120
- return hasGithub ? CHAT_SYSTEM_SUFFIX : CHAT_SYSTEM_SUFFIX_NO_GITHUB;
121
- }
122
- /**
123
- * Handle a conversational chat message using the in-process pi-ai
124
- * runner. Read-only github tools, no shell / write surface.
125
- */
126
- export async function handleChatMessage(message, messagingSessionId, sender, _sessionManager, deps, _config) {
127
- const startTime = Date.now();
128
- return withSpan("lastlight.chat.turn", { "messaging.session_id": messagingSessionId, "messaging.sender": sender, model: _config.model }, async () => {
129
- try {
130
- const wrapped = wrapUntrusted(message, {
131
- source: "messaging-user",
132
- author: sender,
133
- });
134
- const turn = await deps.chatRunner.turn(messagingSessionId, wrapped);
135
- const success = turn.finish === "stop" && turn.errors.length === 0;
136
- const result = {
137
- text: turn.text || (success
138
- ? "I wasn't able to generate a response. Please try again."
139
- : formatChatFailure(turn.finish, turn.errors)),
140
- agentSessionId: turn.agentSessionId,
141
- dashboardSessionId: turn.agentSessionId,
142
- success,
143
- durationMs: Date.now() - startTime,
144
- turns: turn.modelTurns,
145
- costUsd: turn.costUsd > 0 ? turn.costUsd : undefined,
146
- inputTokens: turn.tokens.input || undefined,
147
- outputTokens: turn.tokens.output || undefined,
148
- cacheReadInputTokens: turn.tokens.cacheRead || undefined,
149
- cacheCreationInputTokens: turn.tokens.cacheWrite || undefined,
150
- stopReason: success ? "success" : `error_${turn.finish.replace(/-/g, "_")}`,
151
- error: success ? undefined : turn.errors.join("\n") || turn.finish,
152
- };
153
- try {
154
- await writeChatShim({
155
- sessionsHomeDir: deps.sessionsHomeDir,
156
- model: turn.modelId,
157
- prompt: message,
158
- turn,
159
- stopReason: result.stopReason ?? "unknown",
160
- durationMs: result.durationMs,
161
- includeContent: getRuntimeConfig()?.otel.includeContent ?? telemetryIncludesContent(),
162
- });
163
- }
164
- catch (err) {
165
- const m = err instanceof Error ? err.message : String(err);
166
- console.warn(`[chat] failed to write dashboard shim: ${m}`);
167
- }
168
- const costStr = result.costUsd !== undefined ? `, $${result.costUsd.toFixed(4)}` : "";
169
- console.log(`[chat] ${sender} → ${result.stopReason ?? "?"} (${result.turns ?? "?"} turns, ${Math.round(result.durationMs / 1000)}s${costStr}) [session ${turn.agentSessionId.slice(0, 8)}…]`);
170
- recordExecutionMetrics("chat", { model: turn.modelId, success: result.success, stop_reason: result.stopReason, durationMs: result.durationMs, costUsd: result.costUsd, inputTokens: result.inputTokens, outputTokens: result.outputTokens });
171
- return result;
172
- }
173
- catch (err) {
174
- const errMsg = err instanceof Error ? err.message : String(err);
175
- console.error(`[chat] Error handling message from ${sender}:`, errMsg);
176
- const dashboardSessionId = await writeChatFailureShim({
177
- sessionsHomeDir: deps.sessionsHomeDir,
178
- prompt: message,
179
- messagingSessionId,
180
- errorMessage: errMsg,
181
- durationMs: Date.now() - startTime,
182
- }).catch(() => undefined);
183
- const durationMs = Date.now() - startTime;
184
- recordError("chat", err, { success: false, stop_reason: "error_exception", model: _config.model });
185
- recordExecutionMetrics("chat", { model: _config.model, success: false, stop_reason: "error_exception", durationMs });
186
- return {
187
- text: "Sorry, I encountered an error processing your message. Please try again.",
188
- success: false,
189
- durationMs,
190
- error: errMsg,
191
- dashboardSessionId,
192
- };
193
- }
194
- });
195
- }
196
- /**
197
- * Pick a useful Slack message for a failed chat turn. Provider errors
198
- * (insufficient_quota, rate limit, auth) get a dedicated line — the
199
- * raw error string was previously dropped, leaving users with just
200
- * "(error)".
201
- */
202
- function formatChatFailure(finish, errors) {
203
- const first = errors.find((e) => e && e.trim().length > 0)?.trim();
204
- if (first) {
205
- const lower = first.toLowerCase();
206
- if (lower.includes("credit balance") ||
207
- lower.includes("insufficient_quota") ||
208
- lower.includes("insufficient quota")) {
209
- return `Sorry — the model provider rejected the request: out of credits / quota.\n> ${truncate(first, 300)}`;
210
- }
211
- if (lower.includes("rate limit") || lower.includes("rate_limit")) {
212
- return `Sorry — the model provider is rate-limiting us right now. Try again in a moment.\n> ${truncate(first, 300)}`;
213
- }
214
- if (lower.includes("unauthorized") || lower.includes("invalid_api_key") || lower.includes("api key")) {
215
- return `Sorry — the model provider rejected our API key.\n> ${truncate(first, 300)}`;
216
- }
217
- return `Sorry — chat failed (${finish}): ${truncate(first, 400)}`;
218
- }
219
- return `Sorry — chat failed (${finish}).`;
220
- }
221
- function truncate(s, n) {
222
- return s.length <= n ? s : s.slice(0, n - 1) + "…";
223
- }
224
- async function writeChatShim(opts) {
225
- const shim = new AgenticShim({
226
- homeDir: opts.sessionsHomeDir,
227
- projectSlug: CHAT_PROJECT_SLUG, // Chat project slug is centralized in SessionLog
228
- model: opts.model,
229
- initialPrompt: opts.prompt,
230
- });
231
- const sessionId = opts.turn.agentSessionId;
232
- const now = new Date().toISOString();
233
- // Synthesise a session header so the shim opens the right file.
234
- const sessionRecord = { type: "session", id: sessionId, timestamp: now, cwd: "/app" };
235
- shim.feed(sessionRecord);
236
- recordPiEvent(sessionRecord, { surface: "chat", includeContent: opts.includeContent === true, model: opts.model });
237
- // Replay each assistant turn + paired tool results as message_end /
238
- // tool_execution_end events the shim already knows how to translate.
239
- for (const am of opts.turn.assistantMessages) {
240
- const content = am.content
241
- .map((c) => {
242
- if (c.type === "text")
243
- return { type: "text", text: c.text };
244
- if (c.type === "thinking")
245
- return { type: "thinking", thinking: c.thinking };
246
- if (c.type === "toolCall") {
247
- return {
248
- type: "toolCall",
249
- id: c.id,
250
- name: c.name,
251
- arguments: c.arguments,
252
- };
253
- }
254
- return null;
255
- })
256
- .filter(Boolean);
257
- const record = {
258
- type: "message_end",
259
- sessionId,
260
- timestamp: now,
261
- message: { role: "assistant", content },
262
- };
263
- shim.feed(record);
264
- recordPiEvent(record, { surface: "chat", includeContent: opts.includeContent === true, model: opts.model });
265
- }
266
- for (const tr of opts.turn.toolResults) {
267
- const text = tr.content.find((c) => c.type === "text");
268
- const record = {
269
- type: "tool_execution_end",
270
- sessionId,
271
- timestamp: now,
272
- toolCallId: tr.toolCallId,
273
- toolName: tr.toolName,
274
- result: text && "text" in text ? text.text : "",
275
- isError: tr.isError,
276
- };
277
- shim.feed(record);
278
- recordPiEvent(record, { surface: "chat", includeContent: opts.includeContent === true, model: opts.model });
279
- }
280
- shim.finalize({
281
- finalText: opts.turn.text,
282
- turns: opts.turn.modelTurns,
283
- costUsd: opts.turn.costUsd,
284
- inputTokens: opts.turn.tokens.input,
285
- outputTokens: opts.turn.tokens.output,
286
- cacheReadInputTokens: opts.turn.tokens.cacheRead,
287
- cacheCreationInputTokens: opts.turn.tokens.cacheWrite,
288
- stopReason: opts.stopReason,
289
- durationMs: opts.durationMs,
290
- });
291
- await shim.flush();
292
- }
293
- async function writeChatFailureShim(opts) {
294
- const shim = new AgenticShim({
295
- homeDir: opts.sessionsHomeDir,
296
- projectSlug: CHAT_PROJECT_SLUG,
297
- initialPrompt: opts.prompt,
298
- });
299
- const safe = opts.messagingSessionId.replace(/[^A-Za-z0-9_-]/g, "_");
300
- const synthesizedId = await shim.finalizeWithFallback({
301
- finalText: "",
302
- turns: 0,
303
- costUsd: 0,
304
- inputTokens: 0,
305
- outputTokens: 0,
306
- cacheReadInputTokens: 0,
307
- cacheCreationInputTokens: 0,
308
- stopReason: "error_chat",
309
- durationMs: opts.durationMs,
310
- }, `exec-chat-${safe}-${Date.now()}`, opts.errorMessage);
311
- return synthesizedId ?? undefined;
312
- }
313
- export function loadAgentContext(_dir) {
314
- return loadResolvedAgentContext();
315
- }
316
- //# sourceMappingURL=chat.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../../src/engine/chat/chat.ts"],"names":[],"mappings":"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"}
@@ -1,32 +0,0 @@
1
- import type { EventEnvelope } from "../../connectors/types.js";
2
- export interface MessageBatcherDeps {
3
- /** Dispatch one (possibly combined) envelope through the normal pipeline. */
4
- dispatch: (envelope: EventEnvelope) => Promise<void>;
5
- /**
6
- * Settle window (ms) to collect an initial burst before the first turn of an
7
- * idle session. 0 disables it (first message runs immediately, later ones
8
- * still batch after it). Default 700ms.
9
- */
10
- debounceMs?: number;
11
- /** Injectable delay for tests. */
12
- sleep?: (ms: number) => Promise<void>;
13
- /** Per-session key for an envelope. Default: `raw.sessionId`. */
14
- keyOf?: (envelope: EventEnvelope) => string | undefined;
15
- }
16
- export declare class MessageBatcher {
17
- private deps;
18
- private debounceMs;
19
- private sleep;
20
- private keyOf;
21
- private sessions;
22
- constructor(deps: MessageBatcherDeps);
23
- /**
24
- * Enqueue an envelope for its session. Pass-through (dispatched immediately,
25
- * unbatched) if it has no session key. Fire-and-forget — the transport has
26
- * already acked delivery.
27
- */
28
- submit(envelope: EventEnvelope): void;
29
- /** Number of sessions currently batching (for tests / introspection). */
30
- get activeSessions(): number;
31
- private drain;
32
- }