@agents-ensemble/core 0.20.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (270) hide show
  1. package/assets/pi/pi-cli-env-wrapper.cmd +28 -0
  2. package/assets/pi/pi-cli-env-wrapper.sh +19 -0
  3. package/assets/pi/settings.json +4 -0
  4. package/dist/acp/acp-preset-bins.d.ts +3 -3
  5. package/dist/acp/acp-preset-bins.d.ts.map +1 -1
  6. package/dist/acp/acp-preset-bins.js +3 -3
  7. package/dist/acp/acp-preset-bins.js.map +1 -1
  8. package/dist/acp/index.d.ts +3 -1
  9. package/dist/acp/index.d.ts.map +1 -1
  10. package/dist/acp/index.js +2 -1
  11. package/dist/acp/index.js.map +1 -1
  12. package/dist/acp/pi-acp-wrapper.d.ts +3 -0
  13. package/dist/acp/pi-acp-wrapper.d.ts.map +1 -0
  14. package/dist/acp/pi-acp-wrapper.js +41 -0
  15. package/dist/acp/pi-acp-wrapper.js.map +1 -0
  16. package/dist/acp/pi-builtin-config.d.ts +10 -0
  17. package/dist/acp/pi-builtin-config.d.ts.map +1 -0
  18. package/dist/acp/pi-builtin-config.js +36 -0
  19. package/dist/acp/pi-builtin-config.js.map +1 -0
  20. package/dist/acp/pi-runtime.d.ts +23 -0
  21. package/dist/acp/pi-runtime.d.ts.map +1 -0
  22. package/dist/acp/pi-runtime.js +160 -0
  23. package/dist/acp/pi-runtime.js.map +1 -0
  24. package/dist/acp/pi-session-map.d.ts +36 -0
  25. package/dist/acp/pi-session-map.d.ts.map +1 -0
  26. package/dist/acp/pi-session-map.js +266 -0
  27. package/dist/acp/pi-session-map.js.map +1 -0
  28. package/dist/acp/resolve-acp-spawn.d.ts +9 -3
  29. package/dist/acp/resolve-acp-spawn.d.ts.map +1 -1
  30. package/dist/acp/resolve-acp-spawn.js +41 -9
  31. package/dist/acp/resolve-acp-spawn.js.map +1 -1
  32. package/dist/acp/resolve-bundled-acp-bin.d.ts +2 -2
  33. package/dist/acp/resolve-bundled-acp-bin.d.ts.map +1 -1
  34. package/dist/acp/resolve-bundled-acp-bin.js +4 -4
  35. package/dist/acp/resolve-bundled-acp-bin.js.map +1 -1
  36. package/dist/acp/validate-acp-preset-prerequisites.d.ts +1 -1
  37. package/dist/acp/validate-acp-preset-prerequisites.d.ts.map +1 -1
  38. package/dist/acp/validate-acp-preset-prerequisites.js +30 -10
  39. package/dist/acp/validate-acp-preset-prerequisites.js.map +1 -1
  40. package/dist/conductor/conductor-agent.d.ts +15 -3
  41. package/dist/conductor/conductor-agent.d.ts.map +1 -1
  42. package/dist/conductor/conductor-auth.d.ts +4 -3
  43. package/dist/conductor/conductor-auth.d.ts.map +1 -1
  44. package/dist/conductor/conductor-auth.js +20 -4
  45. package/dist/conductor/conductor-auth.js.map +1 -1
  46. package/dist/conductor/conductor-dispatch-lifecycle.d.ts +85 -0
  47. package/dist/conductor/conductor-dispatch-lifecycle.d.ts.map +1 -0
  48. package/dist/conductor/conductor-dispatch-lifecycle.js +190 -0
  49. package/dist/conductor/conductor-dispatch-lifecycle.js.map +1 -0
  50. package/dist/conductor/conductor-history.d.ts +15 -0
  51. package/dist/conductor/conductor-history.d.ts.map +1 -1
  52. package/dist/conductor/conductor-history.js +38 -7
  53. package/dist/conductor/conductor-history.js.map +1 -1
  54. package/dist/conductor/conductor-path-safety.d.ts +23 -0
  55. package/dist/conductor/conductor-path-safety.d.ts.map +1 -0
  56. package/dist/conductor/conductor-path-safety.js +319 -0
  57. package/dist/conductor/conductor-path-safety.js.map +1 -0
  58. package/dist/conductor/conductor-pi-auth.d.ts +57 -2
  59. package/dist/conductor/conductor-pi-auth.d.ts.map +1 -1
  60. package/dist/conductor/conductor-pi-auth.js +718 -40
  61. package/dist/conductor/conductor-pi-auth.js.map +1 -1
  62. package/dist/conductor/conductor-recovery-inbox.d.ts +73 -0
  63. package/dist/conductor/conductor-recovery-inbox.d.ts.map +1 -0
  64. package/dist/conductor/conductor-recovery-inbox.js +181 -0
  65. package/dist/conductor/conductor-recovery-inbox.js.map +1 -0
  66. package/dist/conductor/conductor-send-reconnect.d.ts +33 -4
  67. package/dist/conductor/conductor-send-reconnect.d.ts.map +1 -1
  68. package/dist/conductor/conductor-send-reconnect.js +89 -24
  69. package/dist/conductor/conductor-send-reconnect.js.map +1 -1
  70. package/dist/conductor/conductor-session-driver.d.ts +34 -1
  71. package/dist/conductor/conductor-session-driver.d.ts.map +1 -1
  72. package/dist/conductor/conductor-session-driver.js +529 -75
  73. package/dist/conductor/conductor-session-driver.js.map +1 -1
  74. package/dist/conductor/conductor-session.d.ts +4 -0
  75. package/dist/conductor/conductor-session.d.ts.map +1 -1
  76. package/dist/conductor/conductor-session.js +416 -145
  77. package/dist/conductor/conductor-session.js.map +1 -1
  78. package/dist/conductor/conductor-setup.d.ts +30 -0
  79. package/dist/conductor/conductor-setup.d.ts.map +1 -0
  80. package/dist/conductor/conductor-setup.js +243 -0
  81. package/dist/conductor/conductor-setup.js.map +1 -0
  82. package/dist/conductor/cursor-bootstrap-state.d.ts +9 -0
  83. package/dist/conductor/cursor-bootstrap-state.d.ts.map +1 -0
  84. package/dist/conductor/cursor-bootstrap-state.js +11 -0
  85. package/dist/conductor/cursor-bootstrap-state.js.map +1 -0
  86. package/dist/conductor/cursor-run-snapshots.d.ts +30 -0
  87. package/dist/conductor/cursor-run-snapshots.d.ts.map +1 -0
  88. package/dist/conductor/cursor-run-snapshots.js +120 -0
  89. package/dist/conductor/cursor-run-snapshots.js.map +1 -0
  90. package/dist/conductor/index.d.ts +18 -7
  91. package/dist/conductor/index.d.ts.map +1 -1
  92. package/dist/conductor/index.js +9 -4
  93. package/dist/conductor/index.js.map +1 -1
  94. package/dist/conductor/operator-command.d.ts +5 -0
  95. package/dist/conductor/operator-command.d.ts.map +1 -1
  96. package/dist/conductor/operator-command.js +6 -0
  97. package/dist/conductor/operator-command.js.map +1 -1
  98. package/dist/conductor/operator-input-binding.d.ts +17 -0
  99. package/dist/conductor/operator-input-binding.d.ts.map +1 -1
  100. package/dist/conductor/pi-auth-recovery-snapshot-store.d.ts +45 -0
  101. package/dist/conductor/pi-auth-recovery-snapshot-store.d.ts.map +1 -0
  102. package/dist/conductor/pi-auth-recovery-snapshot-store.js +116 -0
  103. package/dist/conductor/pi-auth-recovery-snapshot-store.js.map +1 -0
  104. package/dist/conductor/pi-conductor-agent.d.ts +6 -3
  105. package/dist/conductor/pi-conductor-agent.d.ts.map +1 -1
  106. package/dist/conductor/pi-conductor-agent.js +276 -53
  107. package/dist/conductor/pi-conductor-agent.js.map +1 -1
  108. package/dist/conductor/pi-conductor-session-file.d.ts +13 -0
  109. package/dist/conductor/pi-conductor-session-file.d.ts.map +1 -0
  110. package/dist/conductor/pi-conductor-session-file.js +21 -0
  111. package/dist/conductor/pi-conductor-session-file.js.map +1 -0
  112. package/dist/conductor/pi-resource-loader.d.ts +6 -0
  113. package/dist/conductor/pi-resource-loader.d.ts.map +1 -1
  114. package/dist/conductor/pi-resource-loader.js +26 -12
  115. package/dist/conductor/pi-resource-loader.js.map +1 -1
  116. package/dist/conductor/pi-user-root-lock.d.ts +8 -0
  117. package/dist/conductor/pi-user-root-lock.d.ts.map +1 -0
  118. package/dist/conductor/pi-user-root-lock.js +53 -0
  119. package/dist/conductor/pi-user-root-lock.js.map +1 -0
  120. package/dist/conductor/recovery-inbox-command.d.ts +29 -0
  121. package/dist/conductor/recovery-inbox-command.d.ts.map +1 -0
  122. package/dist/conductor/recovery-inbox-command.js +248 -0
  123. package/dist/conductor/recovery-inbox-command.js.map +1 -0
  124. package/dist/conductor/session/events/index.d.ts +1 -1
  125. package/dist/conductor/session/events/index.d.ts.map +1 -1
  126. package/dist/conductor/session/events/index.js.map +1 -1
  127. package/dist/conductor/session/events/session-event.d.ts +43 -1
  128. package/dist/conductor/session/events/session-event.d.ts.map +1 -1
  129. package/dist/conductor/session/events/session-log-event-groups.d.ts +1 -1
  130. package/dist/conductor/session/events/session-log-event-groups.d.ts.map +1 -1
  131. package/dist/conductor/session/events/session-log-event-groups.js +2 -0
  132. package/dist/conductor/session/events/session-log-event-groups.js.map +1 -1
  133. package/dist/conductor/session/events/session-log-event.d.ts +4 -0
  134. package/dist/conductor/session/events/session-log-event.d.ts.map +1 -1
  135. package/dist/conductor/session/format-session-event.js +57 -5
  136. package/dist/conductor/session/format-session-event.js.map +1 -1
  137. package/dist/conductor/session/select-dispatch-batch.d.ts +2 -0
  138. package/dist/conductor/session/select-dispatch-batch.d.ts.map +1 -1
  139. package/dist/conductor/session/select-dispatch-batch.js +36 -2
  140. package/dist/conductor/session/select-dispatch-batch.js.map +1 -1
  141. package/dist/conductor/session/session-event-queue.d.ts +14 -0
  142. package/dist/conductor/session/session-event-queue.d.ts.map +1 -1
  143. package/dist/conductor/session/session-event-queue.js +82 -10
  144. package/dist/conductor/session/session-event-queue.js.map +1 -1
  145. package/dist/conductor/session/session-event.d.ts +1 -1
  146. package/dist/conductor/session/session-event.d.ts.map +1 -1
  147. package/dist/conductor/session-policy.d.ts.map +1 -1
  148. package/dist/conductor/session-policy.js +8 -4
  149. package/dist/conductor/session-policy.js.map +1 -1
  150. package/dist/conductor/submit-operator-input.d.ts +3 -0
  151. package/dist/conductor/submit-operator-input.d.ts.map +1 -1
  152. package/dist/conductor/submit-operator-input.js +21 -0
  153. package/dist/conductor/submit-operator-input.js.map +1 -1
  154. package/dist/config/deep-merge.d.ts.map +1 -1
  155. package/dist/config/deep-merge.js +13 -3
  156. package/dist/config/deep-merge.js.map +1 -1
  157. package/dist/config/defaults.d.ts.map +1 -1
  158. package/dist/config/defaults.js +1 -1
  159. package/dist/config/defaults.js.map +1 -1
  160. package/dist/config/doctor-settings.d.ts +59 -0
  161. package/dist/config/doctor-settings.d.ts.map +1 -0
  162. package/dist/config/doctor-settings.js +343 -0
  163. package/dist/config/doctor-settings.js.map +1 -0
  164. package/dist/config/ensemble-config-digest.d.ts +2 -4
  165. package/dist/config/ensemble-config-digest.d.ts.map +1 -1
  166. package/dist/config/ensemble-config-digest.js +2 -4
  167. package/dist/config/ensemble-config-digest.js.map +1 -1
  168. package/dist/config/index.d.ts +3 -1
  169. package/dist/config/index.d.ts.map +1 -1
  170. package/dist/config/index.js +1 -0
  171. package/dist/config/index.js.map +1 -1
  172. package/dist/config/load-ensemble-config.d.ts.map +1 -1
  173. package/dist/config/load-ensemble-config.js +8 -1
  174. package/dist/config/load-ensemble-config.js.map +1 -1
  175. package/dist/config/parse-config.d.ts.map +1 -1
  176. package/dist/config/parse-config.js +34 -14
  177. package/dist/config/parse-config.js.map +1 -1
  178. package/dist/config/resolve-settings.d.ts +3 -1
  179. package/dist/config/resolve-settings.d.ts.map +1 -1
  180. package/dist/config/resolve-settings.js +7 -4
  181. package/dist/config/resolve-settings.js.map +1 -1
  182. package/dist/config/types.d.ts +14 -5
  183. package/dist/config/types.d.ts.map +1 -1
  184. package/dist/dispatch/attach-worker.js +1 -1
  185. package/dist/dispatch/attach-worker.js.map +1 -1
  186. package/dist/dispatch/worker-acp-session.d.ts +21 -3
  187. package/dist/dispatch/worker-acp-session.d.ts.map +1 -1
  188. package/dist/dispatch/worker-acp-session.js +50 -13
  189. package/dist/dispatch/worker-acp-session.js.map +1 -1
  190. package/dist/ensemble-paths.d.ts +19 -19
  191. package/dist/ensemble-paths.d.ts.map +1 -1
  192. package/dist/ensemble-paths.js +40 -22
  193. package/dist/ensemble-paths.js.map +1 -1
  194. package/dist/issue/resolve-issue-url.d.ts +4 -0
  195. package/dist/issue/resolve-issue-url.d.ts.map +1 -1
  196. package/dist/issue/resolve-issue-url.js +2 -2
  197. package/dist/issue/resolve-issue-url.js.map +1 -1
  198. package/dist/operator-runtime.d.ts +19 -4
  199. package/dist/operator-runtime.d.ts.map +1 -1
  200. package/dist/operator-runtime.js +13 -2
  201. package/dist/operator-runtime.js.map +1 -1
  202. package/dist/profile/types.d.ts +4 -0
  203. package/dist/profile/types.d.ts.map +1 -1
  204. package/dist/profile/types.js +29 -12
  205. package/dist/profile/types.js.map +1 -1
  206. package/dist/representation/escape-terminal-control-characters.d.ts +9 -0
  207. package/dist/representation/escape-terminal-control-characters.d.ts.map +1 -0
  208. package/dist/representation/escape-terminal-control-characters.js +34 -0
  209. package/dist/representation/escape-terminal-control-characters.js.map +1 -0
  210. package/dist/representation/index.d.ts +1 -0
  211. package/dist/representation/index.d.ts.map +1 -1
  212. package/dist/representation/index.js +1 -0
  213. package/dist/representation/index.js.map +1 -1
  214. package/dist/runtime/types.d.ts +9 -0
  215. package/dist/runtime/types.d.ts.map +1 -1
  216. package/dist/runtime/worker-runtime.d.ts +14 -1
  217. package/dist/runtime/worker-runtime.d.ts.map +1 -1
  218. package/dist/runtime/worker-runtime.js +197 -50
  219. package/dist/runtime/worker-runtime.js.map +1 -1
  220. package/dist/runtime/worker-session.d.ts +2 -1
  221. package/dist/runtime/worker-session.d.ts.map +1 -1
  222. package/dist/runtime/worker-session.js +1 -0
  223. package/dist/runtime/worker-session.js.map +1 -1
  224. package/dist/session/export-session-bundle.d.ts +77 -0
  225. package/dist/session/export-session-bundle.d.ts.map +1 -0
  226. package/dist/session/export-session-bundle.js +640 -0
  227. package/dist/session/export-session-bundle.js.map +1 -0
  228. package/dist/session/index.d.ts +6 -3
  229. package/dist/session/index.d.ts.map +1 -1
  230. package/dist/session/index.js +4 -1
  231. package/dist/session/index.js.map +1 -1
  232. package/dist/session/open-question-control.d.ts +9 -0
  233. package/dist/session/open-question-control.d.ts.map +1 -1
  234. package/dist/session/open-question-control.js +26 -1
  235. package/dist/session/open-question-control.js.map +1 -1
  236. package/dist/session/open-questions-store.d.ts +1 -1
  237. package/dist/session/open-questions-store.d.ts.map +1 -1
  238. package/dist/session/open-questions-store.js +3 -6
  239. package/dist/session/open-questions-store.js.map +1 -1
  240. package/dist/session/persisted-file.d.ts +5 -0
  241. package/dist/session/persisted-file.d.ts.map +1 -0
  242. package/dist/session/persisted-file.js +56 -0
  243. package/dist/session/persisted-file.js.map +1 -0
  244. package/dist/session/session-resume-store.d.ts +79 -10
  245. package/dist/session/session-resume-store.d.ts.map +1 -1
  246. package/dist/session/session-resume-store.js +353 -83
  247. package/dist/session/session-resume-store.js.map +1 -1
  248. package/dist/session/session-snapshot-paths.d.ts +11 -0
  249. package/dist/session/session-snapshot-paths.d.ts.map +1 -0
  250. package/dist/session/session-snapshot-paths.js +41 -0
  251. package/dist/session/session-snapshot-paths.js.map +1 -0
  252. package/dist/session/session-state-store.d.ts +2 -2
  253. package/dist/session/session-state-store.d.ts.map +1 -1
  254. package/dist/session/session-state-store.js +5 -16
  255. package/dist/session/session-state-store.js.map +1 -1
  256. package/dist/session/tool-call-snapshot-history.d.ts +12 -1
  257. package/dist/session/tool-call-snapshot-history.d.ts.map +1 -1
  258. package/dist/session/tool-call-snapshot-history.js +75 -70
  259. package/dist/session/tool-call-snapshot-history.js.map +1 -1
  260. package/dist/session/worker-session-history.d.ts +51 -0
  261. package/dist/session/worker-session-history.d.ts.map +1 -0
  262. package/dist/session/worker-session-history.js +654 -0
  263. package/dist/session/worker-session-history.js.map +1 -0
  264. package/dist/workspace/index.d.ts +1 -1
  265. package/dist/workspace/index.d.ts.map +1 -1
  266. package/dist/worktree/worktree.d.ts +6 -1
  267. package/dist/worktree/worktree.d.ts.map +1 -1
  268. package/dist/worktree/worktree.js +123 -2
  269. package/dist/worktree/worktree.js.map +1 -1
  270. package/package.json +9 -4
@@ -4,8 +4,6 @@ import type { ConductorAgent, ConductorAgentCreateOptions, ConductorAgentFactory
4
4
  import { type PiHeadlessSettingsManagerOverrides } from './pi-headless-settings.js';
5
5
  import { type PiResourceLoaderOptions, type PiResources } from './pi-resource-loader.js';
6
6
  import type { McpServerConfigMap } from '../mcp/load-mcp-config.js';
7
- /** Project-local Pi transcript storage used by the conductor backend. */
8
- export declare const PI_SESSION_ROOT = ".ensemble/pi/sessions";
9
7
  export declare const PI_CONDUCTOR_MESSAGE_HISTORY_ENTRY_TYPE = "agents-ensemble/conductor-message-history/v1";
10
8
  interface PiMcpStartupState {
11
9
  error?: string;
@@ -13,6 +11,9 @@ interface PiMcpStartupState {
13
11
  interface PiMcpLifecycleState {
14
12
  enabled: boolean;
15
13
  }
14
+ interface PiCommandAuthRequestGate {
15
+ active: boolean;
16
+ }
16
17
  export interface PiResolvedModel {
17
18
  provider: string;
18
19
  modelId: string;
@@ -36,7 +37,9 @@ export declare class PiConductorAgent implements ConductorAgent {
36
37
  private readonly modelId;
37
38
  private readonly mcpStartupState;
38
39
  private readonly mcpLifecycleState;
40
+ private readonly commandAuthRequestGate;
39
41
  private readonly piSkills;
42
+ private readonly piPromptResources;
40
43
  private readonly onStreamText?;
41
44
  private readonly onContextCompaction?;
42
45
  private readonly unsubscribe;
@@ -45,7 +48,7 @@ export declare class PiConductorAgent implements ConductorAgent {
45
48
  private closePromise?;
46
49
  constructor(session: AgentSession, resources: PiResources, settingsManager: SettingsManager, headlessSettingsOverrides: PiHeadlessSettingsManagerOverrides, systemPromptRef: {
47
50
  value: string;
48
- }, agentId: string, modelId: string, mcpStartupState: PiMcpStartupState, mcpLifecycleState: PiMcpLifecycleState, piSkills: boolean, onStreamText?: ((text: string) => void) | undefined, onContextCompaction?: (() => void) | undefined);
51
+ }, agentId: string, modelId: string, mcpStartupState: PiMcpStartupState, mcpLifecycleState: PiMcpLifecycleState, commandAuthRequestGate: PiCommandAuthRequestGate, piSkills: boolean, piPromptResources: boolean, onStreamText?: ((text: string) => void) | undefined, onContextCompaction?: (() => void) | undefined);
49
52
  static create(options: ConductorAgentCreateOptions): Promise<PiConductorAgent>;
50
53
  static resume(agentId: string, options: ConductorAgentCreateOptions): Promise<PiConductorAgent>;
51
54
  send(prompt: string, callbacks?: ConductorSendCallbacks): Promise<ConductorSendResult>;
@@ -1 +1 @@
1
- {"version":3,"file":"pi-conductor-agent.d.ts","sourceRoot":"","sources":["../../src/conductor/pi-conductor-agent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pi-conductor-agent.d.ts","sourceRoot":"","sources":["../../src/conductor/pi-conductor-agent.ts"],"names":[],"mappings":"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"}
@@ -1,20 +1,19 @@
1
1
  import { randomUUID } from 'node:crypto';
2
- import { constants } from 'node:fs';
3
- import { chmod, copyFile, mkdir } from 'node:fs/promises';
4
- import { basename, join } from 'node:path';
2
+ import { chmod, mkdir } from 'node:fs/promises';
3
+ import { basename } from 'node:path';
5
4
  import { getModel, getModels, getProviders, } from '@earendil-works/pi-ai/compat';
6
- import { getSupportedThinkingLevels, } from '@earendil-works/pi-ai';
5
+ import { createAssistantMessageEventStream, getSupportedThinkingLevels, } from '@earendil-works/pi-ai';
6
+ import { ModelsError } from '@earendil-works/pi-ai/models';
7
7
  import { createAgentSession, createCodemodeExtension, createMcpExtension, createToolSearchExtension, DefaultResourceLoader, SessionManager, SettingsManager, } from '@earendil-works/pi-coding-agent';
8
8
  import { resolveEnsemblePaths } from '../ensemble-paths.js';
9
- import { createPiConductorAuthContext, resolvePiConductorApiKey, } from './conductor-pi-auth.js';
9
+ import { createPiConductorAuthContext, hasPiConductorCommandCredential, preparePiConductorCommandAuthForRequest, resolvePiConductorApiKey, } from './conductor-pi-auth.js';
10
10
  import { markConductorAgentFactoryCleanupIncomplete } from './conductor-agent-factory-cleanup.js';
11
11
  import { toPiCodingAgentTools } from './conductor-tool-pi-adapter.js';
12
12
  import { getPiHeadlessSettingsManagerOverrides, getPiHeadlessSetting, getPiSkillsDiscoverySettingsOverrides, } from './pi-headless-settings.js';
13
13
  import { expandPiResourcePrompt, loadPiResources, } from './pi-resource-loader.js';
14
- /** Project-local Pi transcript storage used by the conductor backend. */
15
- export const PI_SESSION_ROOT = '.ensemble/pi/sessions';
16
14
  export const PI_CONDUCTOR_MESSAGE_HISTORY_ENTRY_TYPE = 'agents-ensemble/conductor-message-history/v1';
17
15
  const PI_MCP_STARTUP_OBSERVATION_MS = 2_000;
16
+ const PI_COMMAND_RESOLUTION_ERROR_MESSAGE = 'API key auth failed for provider: failed to resolve API key for Pi provider from the configured command.';
18
17
  const PI_THINKING_LEVELS = [
19
18
  'off',
20
19
  'minimal',
@@ -30,7 +29,7 @@ export async function resolvePiModelConfig(options) {
30
29
  const authContext = await createPiConductorAuthContext(options, resources);
31
30
  return resolvePiModelConfigFromResources(options, resources, authContext);
32
31
  }
33
- async function resolvePiModelConfigFromResources(options, resources, authContext) {
32
+ async function resolvePiModelConfigFromResources(options, resources, authContext, commandAuthRequestGate) {
34
33
  const env = options.env ?? process.env;
35
34
  const settings = resources.settings;
36
35
  const selection = resolvePiModelSelection(options.modelId, settings, resources.models);
@@ -40,19 +39,36 @@ async function resolvePiModelConfigFromResources(options, resources, authContext
40
39
  const registryModel = projectDefinesModel
41
40
  ? undefined
42
41
  : authContext.modelRegistry.find(selection.provider, selection.modelId);
43
- const apiKey = await resolvePiConductorApiKey({
44
- modelRuntime: authContext.modelRuntime,
45
- resources,
46
- provider: selection.provider,
47
- explicitApiKey: options.apiKey,
48
- env,
49
- });
42
+ const commandAuthConfigured = options.apiKey === undefined &&
43
+ hasPiConductorCommandCredential(resources, selection.provider, env);
44
+ const apiKey = commandAuthConfigured
45
+ ? undefined
46
+ : await resolvePiConductorApiKey({
47
+ modelRuntime: authContext.modelRuntime,
48
+ resources,
49
+ provider: selection.provider,
50
+ explicitApiKey: options.apiKey,
51
+ env,
52
+ });
50
53
  const builtInModel = getModel(selection.provider, selection.modelId);
51
54
  const model = resolvePiModel(selection.provider, selection.modelId, providerConfig, registryModel ?? builtInModel, registryModel);
52
55
  if (!model) {
53
56
  throw new Error(`Pi conductor model "${selection.provider}/${selection.modelId}" was not found in pi-ai or models.json. ` +
54
57
  'Set defaultProvider/defaultModel in Pi settings.json or pass a built-in provider/model id.');
55
58
  }
59
+ if (commandAuthConfigured) {
60
+ // Pi calls hasConfiguredAuth() during prompt setup and getAuth() just
61
+ // before sending a provider request. Keep the command out of setup and
62
+ // defer registration/resolution until the latter, while preserving Pi's
63
+ // own auth resolver and precedence.
64
+ installPiCommandAuthRequestGate({
65
+ modelRuntime: authContext.modelRuntime,
66
+ resources,
67
+ provider: selection.provider,
68
+ env,
69
+ gate: commandAuthRequestGate ?? { active: false },
70
+ });
71
+ }
56
72
  return {
57
73
  provider: selection.provider,
58
74
  modelId: selection.modelId,
@@ -72,14 +88,16 @@ export class PiConductorAgent {
72
88
  modelId;
73
89
  mcpStartupState;
74
90
  mcpLifecycleState;
91
+ commandAuthRequestGate;
75
92
  piSkills;
93
+ piPromptResources;
76
94
  onStreamText;
77
95
  onContextCompaction;
78
96
  unsubscribe;
79
97
  activeSend;
80
98
  closed = false;
81
99
  closePromise;
82
- constructor(session, resources, settingsManager, headlessSettingsOverrides, systemPromptRef, agentId, modelId, mcpStartupState, mcpLifecycleState, piSkills, onStreamText, onContextCompaction) {
100
+ constructor(session, resources, settingsManager, headlessSettingsOverrides, systemPromptRef, agentId, modelId, mcpStartupState, mcpLifecycleState, commandAuthRequestGate, piSkills, piPromptResources, onStreamText, onContextCompaction) {
83
101
  this.session = session;
84
102
  this.resources = resources;
85
103
  this.settingsManager = settingsManager;
@@ -89,7 +107,9 @@ export class PiConductorAgent {
89
107
  this.modelId = modelId;
90
108
  this.mcpStartupState = mcpStartupState;
91
109
  this.mcpLifecycleState = mcpLifecycleState;
110
+ this.commandAuthRequestGate = commandAuthRequestGate;
92
111
  this.piSkills = piSkills;
112
+ this.piPromptResources = piPromptResources;
93
113
  this.onStreamText = onStreamText;
94
114
  this.onContextCompaction = onContextCompaction;
95
115
  this.unsubscribe = this.session.subscribe((event) => this.handleEvent(event));
@@ -134,9 +154,11 @@ export class PiConductorAgent {
134
154
  };
135
155
  this.activeSend = state;
136
156
  try {
137
- await this.session.prompt(expandPiResourcePrompt(prompt, this.resources, {
138
- expandSkills: !this.piSkills,
139
- }), {
157
+ await this.session.prompt(this.piPromptResources
158
+ ? expandPiResourcePrompt(prompt, this.resources, {
159
+ expandSkills: !this.piSkills,
160
+ })
161
+ : prompt, {
140
162
  expandPromptTemplates: false,
141
163
  source: 'rpc',
142
164
  });
@@ -145,7 +167,10 @@ export class PiConductorAgent {
145
167
  return {
146
168
  runId,
147
169
  status: 'error',
148
- error: { message: errorMessage(error) },
170
+ error: {
171
+ message: piConductorErrorMessage(error),
172
+ ...(error instanceof ModelsError ? { code: error.code } : {}),
173
+ },
149
174
  modelId: this.modelId,
150
175
  };
151
176
  }
@@ -160,6 +185,7 @@ export class PiConductorAgent {
160
185
  modelId: this.modelId,
161
186
  };
162
187
  }
188
+ sanitizePiAssistantMessageInPlace(finalMessage);
163
189
  const status = statusFromStopReason(finalMessage.stopReason);
164
190
  const result = assistantText(finalMessage) || undefined;
165
191
  if (status === 'finished' &&
@@ -319,6 +345,15 @@ export class PiConductorAgent {
319
345
  }
320
346
  handleEvent(event) {
321
347
  const activeSend = this.activeSend;
348
+ if ((event.type === 'message_start' ||
349
+ event.type === 'message_update' ||
350
+ event.type === 'message_end') &&
351
+ event.message.role === 'assistant') {
352
+ // AgentSession emits public listeners before appending message_end to the
353
+ // Pi transcript. Mutating this message keeps the event and persisted entry
354
+ // safe if a failure came from a nonstandard Pi stream path.
355
+ sanitizePiAssistantMessageInPlace(event.message);
356
+ }
322
357
  if (event.type === 'compaction_end' &&
323
358
  event.result != null &&
324
359
  !event.aborted &&
@@ -340,6 +375,12 @@ export class PiConductorAgent {
340
375
  }
341
376
  return;
342
377
  }
378
+ if (event.type === 'agent_end') {
379
+ for (const message of event.messages) {
380
+ if (message.role === 'assistant')
381
+ sanitizePiAssistantMessageInPlace(message);
382
+ }
383
+ }
343
384
  if (event.type === 'agent_end' && activeSend) {
344
385
  activeSend.finalMessage = lastAssistantMessage(event.messages);
345
386
  for (const message of event.messages) {
@@ -350,6 +391,135 @@ export class PiConductorAgent {
350
391
  }
351
392
  }
352
393
  }
394
+ function installPiCommandAuthRequestGate(input) {
395
+ const originalHasConfiguredAuth = input.modelRuntime.hasConfiguredAuth.bind(input.modelRuntime);
396
+ input.modelRuntime.hasConfiguredAuth = (provider) => provider === input.provider || originalHasConfiguredAuth(provider);
397
+ const originalGetAuth = input.modelRuntime.getAuth.bind(input.modelRuntime);
398
+ input.modelRuntime.getAuth = (async (providerOrModel, overrides) => {
399
+ const provider = typeof providerOrModel === 'string'
400
+ ? providerOrModel
401
+ : providerOrModel.provider;
402
+ if (provider !== input.provider ||
403
+ !input.gate.active ||
404
+ overrides?.apiKey !== undefined) {
405
+ return originalGetAuth(providerOrModel, overrides);
406
+ }
407
+ await preparePiConductorCommandAuthForRequest({
408
+ modelRuntime: input.modelRuntime,
409
+ resources: input.resources,
410
+ provider: input.provider,
411
+ env: input.env,
412
+ });
413
+ try {
414
+ return await originalGetAuth(providerOrModel, overrides);
415
+ }
416
+ catch (error) {
417
+ if (isPiCommandResolutionError(error)) {
418
+ throw new Error(PI_COMMAND_RESOLUTION_ERROR_MESSAGE);
419
+ }
420
+ throw error;
421
+ }
422
+ });
423
+ const originalStreamSimple = input.modelRuntime.streamSimple.bind(input.modelRuntime);
424
+ input.modelRuntime.streamSimple = ((model, context, options) => {
425
+ if (model.provider !== input.provider) {
426
+ return originalStreamSimple(model, context, options);
427
+ }
428
+ // Pi 1.2.0's lazy stream starts its setup synchronously. That setup calls
429
+ // prepareRequest(), which starts getAuth() before streamSimple() returns.
430
+ // Keep the command gate active only for that setup call: prompt hooks and
431
+ // the provider response stream itself must not trigger command resolution
432
+ // through an unrelated getAuth() lookup.
433
+ const output = createAssistantMessageEventStream();
434
+ void (async () => {
435
+ try {
436
+ const wasActive = input.gate.active;
437
+ let response;
438
+ input.gate.active = true;
439
+ try {
440
+ response = originalStreamSimple(model, context, options);
441
+ }
442
+ finally {
443
+ input.gate.active = wasActive;
444
+ }
445
+ let terminalEventSeen = false;
446
+ for await (const event of response) {
447
+ if (event.type === 'done' || event.type === 'error') {
448
+ terminalEventSeen = true;
449
+ }
450
+ output.push(sanitizePiAssistantEvent(event));
451
+ }
452
+ if (!terminalEventSeen) {
453
+ output.end(sanitizePiAssistantMessage(await response.result()));
454
+ }
455
+ }
456
+ catch (error) {
457
+ output.push({
458
+ type: 'error',
459
+ reason: 'error',
460
+ error: createPiRequestFailureMessage(model, piConductorErrorMessage(error)),
461
+ });
462
+ }
463
+ })();
464
+ return output;
465
+ });
466
+ }
467
+ function sanitizePiAssistantEvent(event) {
468
+ if (event.type === 'done') {
469
+ return { ...event, message: sanitizePiAssistantMessage(event.message) };
470
+ }
471
+ if (event.type === 'error') {
472
+ return { ...event, error: sanitizePiAssistantMessage(event.error) };
473
+ }
474
+ if ('partial' in event) {
475
+ return { ...event, partial: sanitizePiAssistantMessage(event.partial) };
476
+ }
477
+ return event;
478
+ }
479
+ function sanitizePiAssistantMessage(message) {
480
+ if (!message.errorMessage)
481
+ return message;
482
+ const safeErrorMessage = sanitizePiCommandResolutionMessage(message.errorMessage);
483
+ return safeErrorMessage === message.errorMessage
484
+ ? message
485
+ : { ...message, errorMessage: safeErrorMessage };
486
+ }
487
+ function sanitizePiAssistantMessageInPlace(message) {
488
+ if (!message.errorMessage)
489
+ return;
490
+ message.errorMessage = sanitizePiCommandResolutionMessage(message.errorMessage);
491
+ }
492
+ function sanitizePiCommandResolutionMessage(message) {
493
+ return isPiCommandResolutionError(message)
494
+ ? PI_COMMAND_RESOLUTION_ERROR_MESSAGE
495
+ : message;
496
+ }
497
+ function createPiRequestFailureMessage(model, errorMessage) {
498
+ return {
499
+ role: 'assistant',
500
+ content: [],
501
+ api: model.api,
502
+ provider: model.provider,
503
+ model: model.id,
504
+ usage: {
505
+ input: 0,
506
+ output: 0,
507
+ cacheRead: 0,
508
+ cacheWrite: 0,
509
+ totalTokens: 0,
510
+ cost: {
511
+ input: 0,
512
+ output: 0,
513
+ cacheRead: 0,
514
+ cacheWrite: 0,
515
+ total: 0,
516
+ },
517
+ },
518
+ stopReason: 'error',
519
+ errorMessage: sanitizePiCommandResolutionMessage(errorMessage),
520
+ timestamp: Date.now(),
521
+ };
522
+ }
353
523
  function appendPiConductorMessageHistory(sessionManager, input) {
354
524
  const branch = sessionManager.getBranch();
355
525
  let assistantIndex = -1;
@@ -426,55 +596,62 @@ function resolvePiConductorThinkingLevel(model, provider, modelId, value) {
426
596
  }
427
597
  return reasoning;
428
598
  }
599
+ function resolvePiConductorSessionDir(options) {
600
+ if (options.sessionDir !== undefined)
601
+ return options.sessionDir;
602
+ if (!options.issueUrl) {
603
+ throw new Error('Pi conductor transcript storage requires issueUrl or an explicit sessionDir.');
604
+ }
605
+ return resolveEnsemblePaths({ repoRoot: options.cwd })
606
+ .canonicalPiSessionsDir(options.issueUrl);
607
+ }
429
608
  async function createPiConductorSession(agentId, options, reason) {
609
+ const sessionDir = resolvePiConductorSessionDir(options);
610
+ const piInternalExtensions = options.piInternalExtensions !== false;
430
611
  const piMcpResolution = { cwd: options.cwd };
431
612
  const mcpLifecycleState = {
432
- enabled: Object.keys(options.mcpServers ?? {}).length > 0,
613
+ enabled: piInternalExtensions && Object.keys(options.mcpServers ?? {}).length > 0,
433
614
  };
434
615
  // Validate the harness-resolved map before creating the SDK session so an
435
616
  // unsupported transport fails with an actionable Pi-specific error.
436
- if (options.mcpServers)
617
+ if (piInternalExtensions && options.mcpServers) {
437
618
  loadPiMcpConfig(options.mcpServers, piMcpResolution);
619
+ }
438
620
  const piSkills = options.piSkills !== false;
621
+ const piPromptResources = options.piPromptResources !== false;
439
622
  const resources = await loadPiResources({
440
623
  ...options,
441
624
  loadExtensions: options.piExtensions !== false,
625
+ loadPromptResources: piPromptResources,
442
626
  loadSkillContents: !piSkills,
443
627
  });
444
628
  const headlessSettingsOverrides = getPiHeadlessSettingsManagerOverrides(resources.settings);
445
629
  const authContext = await createPiConductorAuthContext(options, resources);
446
- const resolved = await resolvePiModelConfigFromResources(options, resources, authContext);
630
+ const commandAuthRequestGate = { active: false };
631
+ const resolved = await resolvePiModelConfigFromResources(options, resources, authContext, commandAuthRequestGate);
447
632
  const thinkingLevel = options.reasoning !== undefined
448
633
  ? resolvePiConductorThinkingLevel(resolved.model, resolved.provider, resolved.modelId, options.reasoning)
449
634
  : undefined;
450
635
  if (options.apiKey !== undefined) {
451
636
  await authContext.modelRuntime.setRuntimeApiKey(resolved.provider, options.apiKey);
452
637
  }
453
- const sessionDir = options.sessionDir ??
454
- resolveEnsemblePaths({ repoRoot: options.cwd }).piSessionsDir;
455
- const legacySessionDir = options.legacySessionDir ?? join(options.cwd, PI_SESSION_ROOT);
456
638
  await mkdir(sessionDir, { recursive: true, mode: 0o700 });
457
639
  await chmod(sessionDir, 0o700);
458
640
  let sessionManager;
459
641
  let previousSessionFile;
460
642
  if (reason === 'resume') {
461
- previousSessionFile = SessionManager.findById(options.cwd, agentId, sessionDir);
462
- if (!previousSessionFile && legacySessionDir !== sessionDir) {
463
- const legacyFile = SessionManager.findById(options.cwd, agentId, legacySessionDir);
464
- if (legacyFile) {
465
- await mkdir(sessionDir, { recursive: true, mode: 0o700 });
466
- const migratedFile = join(sessionDir, basename(legacyFile));
467
- try {
468
- await copyFile(legacyFile, migratedFile, constants.COPYFILE_EXCL);
469
- }
470
- catch (error) {
471
- if (!isAlreadyExists(error))
472
- throw error;
473
- }
474
- await chmod(migratedFile, 0o600);
475
- previousSessionFile = migratedFile;
643
+ const resumeCwds = [
644
+ ...new Set([options.cwd, ...(options.resumeCwds ?? [])]),
645
+ ];
646
+ const findSessionFile = (directory) => {
647
+ for (const cwd of resumeCwds) {
648
+ const sessionFile = SessionManager.findById(cwd, agentId, directory);
649
+ if (sessionFile)
650
+ return sessionFile;
476
651
  }
477
- }
652
+ return undefined;
653
+ };
654
+ previousSessionFile = findSessionFile(sessionDir);
478
655
  if (!previousSessionFile) {
479
656
  throw new Error(`Pi session not found for resume (sessionId=${agentId}, cwd=${options.cwd}, ` +
480
657
  `sessionsRoot=${sessionDir})`);
@@ -492,7 +669,7 @@ async function createPiConductorSession(agentId, options, reason) {
492
669
  // (.ensemble/pi), so use an in-memory manager and populate it only through
493
670
  // the code-level headless settings allowlist below.
494
671
  const settingsManager = SettingsManager.inMemory();
495
- if (piSkills) {
672
+ if (piSkills && piPromptResources) {
496
673
  applyPiHeadlessSettings(settingsManager, getPiSkillsDiscoverySettingsOverrides(resources.settings));
497
674
  settingsManager.setProjectTrusted(true);
498
675
  }
@@ -501,18 +678,22 @@ async function createPiConductorSession(agentId, options, reason) {
501
678
  agentDir: authContext.agentDir,
502
679
  settingsManager,
503
680
  noExtensions: true,
504
- noSkills: !piSkills,
505
- additionalSkillPaths: piSkills ? resources.skillPaths : [],
681
+ noSkills: !piSkills || !piPromptResources,
682
+ additionalSkillPaths: piSkills && piPromptResources ? resources.skillPaths : [],
506
683
  noPromptTemplates: true,
507
684
  noThemes: true,
508
685
  noContextFiles: true,
509
686
  systemPrompt: systemPromptRef.value,
510
687
  extensionFactories: [
511
- createMcpExtension({
512
- loadConfig: () => loadPiMcpConfig(mcpLifecycleState.enabled ? options.mcpServers : undefined, piMcpResolution),
513
- }),
514
- createCodemodeExtension({ mode: 'on' }),
515
- createToolSearchExtension(),
688
+ ...(piInternalExtensions
689
+ ? [
690
+ createMcpExtension({
691
+ loadConfig: () => loadPiMcpConfig(mcpLifecycleState.enabled ? options.mcpServers : undefined, piMcpResolution),
692
+ }),
693
+ createCodemodeExtension({ mode: 'on' }),
694
+ createToolSearchExtension(),
695
+ ]
696
+ : []),
516
697
  createPiSystemPromptExtension(systemPromptRef),
517
698
  ],
518
699
  });
@@ -551,11 +732,11 @@ async function createPiConductorSession(agentId, options, reason) {
551
732
  }
552
733
  },
553
734
  });
554
- await observePiMcpStartup(session, options.mcpServers, mcpStartupState);
735
+ await observePiMcpStartup(session, piInternalExtensions ? options.mcpServers : undefined, mcpStartupState);
555
736
  if (mcpStartupState.error) {
556
737
  throw new Error(mcpStartupState.error);
557
738
  }
558
- return new PiConductorAgent(session, resources, settingsManager, headlessSettingsOverrides, systemPromptRef, agentId, resolved.modelId, mcpStartupState, mcpLifecycleState, piSkills, options.onStreamText, options.onContextCompaction);
739
+ return new PiConductorAgent(session, resources, settingsManager, headlessSettingsOverrides, systemPromptRef, agentId, resolved.modelId, mcpStartupState, mcpLifecycleState, commandAuthRequestGate, piSkills, piPromptResources, options.onStreamText, options.onContextCompaction);
559
740
  }
560
741
  catch (error) {
561
742
  if (!session)
@@ -965,7 +1146,49 @@ function addConductorTokenUsage(current, usage) {
965
1146
  function isRecord(value) {
966
1147
  return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
967
1148
  }
968
- function errorMessage(error) {
1149
+ function piConductorErrorMessage(error) {
1150
+ if (isPiCommandResolutionError(error)) {
1151
+ return PI_COMMAND_RESOLUTION_ERROR_MESSAGE;
1152
+ }
969
1153
  return error instanceof Error ? error.message : String(error);
970
1154
  }
1155
+ function isPiCommandResolutionError(error) {
1156
+ if (typeof error === 'string' &&
1157
+ /failed to resolve api key|from shell command/i.test(error)) {
1158
+ return true;
1159
+ }
1160
+ if (!error || typeof error !== 'object')
1161
+ return false;
1162
+ if (error instanceof ModelsError && error.code !== 'auth')
1163
+ return false;
1164
+ const isAuthModelsError = error instanceof ModelsError && error.code === 'auth';
1165
+ const errorMessage = 'message' in error && typeof error.message === 'string' ? error.message : '';
1166
+ if (/failed to resolve api key|from shell command/i.test(errorMessage)) {
1167
+ return true;
1168
+ }
1169
+ const topLevelDetails = error;
1170
+ if (isAuthModelsError &&
1171
+ (topLevelDetails.stdout !== undefined || topLevelDetails.stderr !== undefined)) {
1172
+ return true;
1173
+ }
1174
+ const pending = [error.cause];
1175
+ const seen = new Set();
1176
+ while (pending.length > 0) {
1177
+ const cause = pending.pop();
1178
+ if (!cause || typeof cause !== 'object' || seen.has(cause))
1179
+ continue;
1180
+ seen.add(cause);
1181
+ const details = cause;
1182
+ if (isAuthModelsError &&
1183
+ (details.stdout !== undefined || details.stderr !== undefined)) {
1184
+ return true;
1185
+ }
1186
+ if (typeof details.message === 'string' &&
1187
+ /failed to resolve api key|from shell command/i.test(details.message)) {
1188
+ return true;
1189
+ }
1190
+ pending.push(details.cause);
1191
+ }
1192
+ return false;
1193
+ }
971
1194
  //# sourceMappingURL=pi-conductor-agent.js.map