]> Piment Noir Git Repositories - e-mobility-charging-stations-simulator.git/commitdiff
fix(sandcastle): patch pi thinking option and replace type indirections
authorJérôme Benoit <jerome.benoit@sap.com>
Fri, 8 May 2026 15:08:22 +0000 (17:08 +0200)
committerJérôme Benoit <jerome.benoit@sap.com>
Fri, 8 May 2026 15:29:17 +0000 (17:29 +0200)
Apply pnpm patch for @ai-hero/sandcastle porting PR #584 (pi --thinking
flag). Wire the thinking option through agentProvider() and replace
Awaited<ReturnType<...>> indirections with direct type imports (Sandbox,
SandboxRunResult, RunResult, PiOptions).

.sandcastle/constants.ts
.sandcastle/refinement-loop.ts
.sandcastle/task-source.ts
.sandcastle/types.ts
.sandcastle/utils.ts
package.json
patches/@ai-hero__sandcastle.patch [new file with mode: 0644]
pnpm-lock.yaml

index 98a595eea5ff5d3386ce63a55975fd93b3e211bf..07ba0382764379fd1f3d1d8e8c3d7b12968e5041 100644 (file)
@@ -7,11 +7,11 @@ export type AgentProviderType = 'opencode' | 'pi'
 
 export const AGENT_PROVIDER = 'pi' as AgentProviderType
 
-export const AGENT_ACTOR_EFFORT = 'high'
+export const AGENT_ACTOR_EFFORT = 'high' as const
 
 export const AGENT_ACTOR_MODEL = 'github-copilot/claude-opus-4.6'
 
-export const AGENT_CRITIC_EFFORT = 'medium'
+export const AGENT_CRITIC_EFFORT = 'medium' as const
 
 export const AGENT_CRITIC_MODEL = 'github-copilot/gpt-5.4'
 
@@ -21,7 +21,7 @@ export const AGENT_ITERATION_BUDGET = 50
 
 export const AGENT_MAX_CRITIC_ROUNDS = 10
 
-export const AGENT_PLANNER_EFFORT = 'medium'
+export const AGENT_PLANNER_EFFORT = 'medium' as const
 
 export const AGENT_PLANNER_MODEL = 'github-copilot/claude-sonnet-4.6'
 
index ad546ab528bff7e559fbd9a996a66525b6fa53b6..49f9981ebd3aaba337aefef479e190d57d2cd68e 100644 (file)
@@ -1,3 +1,5 @@
+import type { SandboxRunResult } from '@ai-hero/sandcastle'
+
 import crypto from 'node:crypto'
 import { readFile, realpath } from 'node:fs/promises'
 import { join, sep } from 'node:path'
@@ -459,7 +461,7 @@ async function executeRound (
   }
 
   // Actor
-  let actorResult: Awaited<ReturnType<typeof sandbox.run>>
+  let actorResult: SandboxRunResult
   try {
     actorResult = await sandbox.run({
       agent: agentProvider(
index 5452e8b990697a11927c867c0edc16fa5f79dd6c..36c6bb1bf3c37950a709db3a1c6992c568f5f091 100644 (file)
@@ -1,3 +1,5 @@
+import type { RunResult } from '@ai-hero/sandcastle'
+
 import * as sandcastle from '@ai-hero/sandcastle'
 import { docker } from '@ai-hero/sandcastle/sandboxes/docker'
 import { z } from 'zod'
@@ -95,7 +97,7 @@ export class GithubIssueSource implements TaskSource {
     for (let attempt = 1; attempt <= this.maxRetries; attempt++) {
       console.log(`\n=== Planner attempt ${String(attempt)}/${String(this.maxRetries)} ===\n`)
 
-      let plan: Awaited<ReturnType<typeof sandcastle.run>>
+      let plan: RunResult
       try {
         plan = await sandcastle.run({
           agent: agentProvider(AGENT_PLANNER_MODEL, AGENT_PLANNER_EFFORT),
index 6688a97fad440264ad720c560cc0704d9b36b419..90e787bd97579a21c7c254be569256b271301504 100644 (file)
@@ -1,4 +1,4 @@
-import type * as sandcastle from '@ai-hero/sandcastle'
+import type { PiOptions, Sandbox } from '@ai-hero/sandcastle'
 
 import { z } from 'zod'
 
@@ -67,7 +67,7 @@ export type LoopStatus = 'converged' | 'exhausted' | 'failed' | 'skipped'
 // eslint-disable-next-line @typescript-eslint/consistent-type-definitions
 export type LoopStrategy = {
   /** Reasoning effort for the actor agent. Defaults to AGENT_ACTOR_EFFORT constant. */
-  actorEffort?: string
+  actorEffort?: PiOptions['thinking']
   /** Model for the actor agent. Defaults to AGENT_ACTOR_MODEL constant. */
   actorModel?: string
   /** Path to the actor prompt file. */
@@ -77,7 +77,7 @@ export type LoopStrategy = {
   /** Builds promptArgs for the critic run from task spec and base branch. */
   buildCriticArgs: (spec: TaskSpec, baseBranch: string) => Record<string, string>
   /** Reasoning effort for the critic agent. Defaults to AGENT_CRITIC_EFFORT constant. */
-  criticEffort?: string
+  criticEffort?: PiOptions['thinking']
   /** Model for the critic agent. Defaults to AGENT_CRITIC_MODEL constant. */
   criticModel?: string
   /** Path to the critic prompt file. */
@@ -101,7 +101,7 @@ export interface RoundSnapshot {
 }
 
 /** Type alias for a sandcastle sandbox instance. */
-export type SandboxInstance = Awaited<ReturnType<typeof sandcastle.createSandbox>>
+export type SandboxInstance = Sandbox
 
 /** Specification for a task to be implemented. */
 export interface TaskSpec {
index ec05d7c892b442748d60ec76d5bf2e3ef7eb0548..efddc89d1f2b580bdc54af18851a4d229ebd6364 100644 (file)
@@ -1,4 +1,4 @@
-import type { AgentProvider } from '@ai-hero/sandcastle'
+import type { AgentProvider, PiOptions } from '@ai-hero/sandcastle'
 
 import * as sandcastle from '@ai-hero/sandcastle'
 import { execFile } from 'node:child_process'
@@ -12,15 +12,15 @@ export const execFileAsync = util.promisify(execFile)
 /**
  * Returns a sandcastle agent provider for the given model, selected by AGENT_PROVIDER constant.
  * @param model - The model identifier (e.g., 'github-copilot/claude-sonnet-4.6').
- * @param effort - Reasoning effort level passed as `variant` to opencode.
+ * @param effort - Reasoning effort level passed as `variant` to opencode or `thinking` to pi.
  * @returns The configured agent provider.
  */
-export function agentProvider (model: string, effort?: string): AgentProvider {
+export function agentProvider (model: string, effort?: PiOptions['thinking']): AgentProvider {
   switch (AGENT_PROVIDER) {
     case 'opencode':
       return sandcastle.opencode(model, effort ? { variant: effort } : undefined)
     case 'pi':
-      return sandcastle.pi(model)
+      return sandcastle.pi(model, effort ? { thinking: effort } : undefined)
   }
 }
 
index 0e5d2758905bd9a3224ff6935ef0681a9f64b54e..9842f2cd59529cd80e256d162796148fb6233133 100644 (file)
   "pnpm": {
     "onlyBuiltDependencies": [
       "better-sqlite3"
-    ]
+    ],
+    "patchedDependencies": {
+      "@ai-hero/sandcastle": "patches/@ai-hero__sandcastle.patch"
+    }
   }
 }
diff --git a/patches/@ai-hero__sandcastle.patch b/patches/@ai-hero__sandcastle.patch
new file mode 100644 (file)
index 0000000..a5784c9
--- /dev/null
@@ -0,0 +1,30 @@
+diff --git a/dist/AgentProvider.d.ts b/dist/AgentProvider.d.ts
+index 134d7cbea22e9f4525f69de0549f0c2e5c9bac67..c661e939c6e40eefc8f8b2dbbb6ed1154b0e8dd6 100644
+--- a/dist/AgentProvider.d.ts
++++ b/dist/AgentProvider.d.ts
+@@ -48,6 +48,8 @@ export interface AgentProvider {
+ export declare const DEFAULT_MODEL = "claude-opus-4-6";
+ /** Options for the pi agent provider. */
+ export interface PiOptions {
++    /** Reasoning/thinking level for the agent. */
++    readonly thinking?: "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
+     /** Environment variables injected by this agent provider. */
+     readonly env?: Record<string, string>;
+ }
+diff --git a/dist/AgentProvider.js b/dist/AgentProvider.js
+index 01b533cb129675070c618dc790b74d41259dab0c..f2a72b46e7e01d534027cb1efec81fdbe9761fa8 100644
+--- a/dist/AgentProvider.js
++++ b/dist/AgentProvider.js
+@@ -140,8 +140,11 @@ export const pi = (model, options) => ({
+     env: options?.env ?? {},
+     captureSessions: false,
+     buildPrintCommand({ prompt }) {
++        const thinkingFlag = options?.thinking
++            ? ` --thinking ${options.thinking}`
++            : "";
+         return {
+-            command: `pi -p --mode json --no-session --model ${shellEscape(model)}`,
++            command: `pi -p --mode json --no-session${thinkingFlag} --model ${shellEscape(model)}`,
+             stdin: prompt,
+         };
+     },
index 910000ebea41d82aa92247877a3ac5e073f7128d..8524dfa6576fc700816c879e1464df887671dedf 100644 (file)
@@ -25,6 +25,11 @@ overrides:
   tough-cookie@<4.1.3: '>=4.1.3'
   uuid@<7: '>=7.0.0'
 
+patchedDependencies:
+  '@ai-hero/sandcastle':
+    hash: 98ac71a9a8d3bc7df881ffb9c3a698ac315e90f9c507c5d8c356868e3e35a4d5
+    path: patches/@ai-hero__sandcastle.patch
+
 importers:
 
   .:
@@ -92,7 +97,7 @@ importers:
     devDependencies:
       '@ai-hero/sandcastle':
         specifier: ^0.5.10
-        version: 0.5.10(@effect/cluster@0.57.0(@effect/platform@0.95.0(effect@3.21.0))(@effect/rpc@0.74.0(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/sql@0.50.0(@effect/experimental@0.59.0(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/workflow@0.17.0(@effect/experimental@0.59.0(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.95.0(effect@3.21.0))(@effect/rpc@0.74.0(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(effect@3.21.0))(effect@3.21.0))(@effect/rpc@0.74.0(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/sql@0.50.0(@effect/experimental@0.59.0(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/typeclass@0.39.0(effect@3.21.0))(bufferutil@4.1.0)(utf-8-validate@6.0.6)
+        version: 0.5.10(patch_hash=98ac71a9a8d3bc7df881ffb9c3a698ac315e90f9c507c5d8c356868e3e35a4d5)(@effect/cluster@0.57.0(@effect/platform@0.95.0(effect@3.21.0))(@effect/rpc@0.74.0(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/sql@0.50.0(@effect/experimental@0.59.0(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/workflow@0.17.0(@effect/experimental@0.59.0(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.95.0(effect@3.21.0))(@effect/rpc@0.74.0(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(effect@3.21.0))(effect@3.21.0))(@effect/rpc@0.74.0(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/sql@0.50.0(@effect/experimental@0.59.0(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/typeclass@0.39.0(effect@3.21.0))(bufferutil@4.1.0)(utf-8-validate@6.0.6)
       '@commitlint/cli':
         specifier: ^20.5.3
         version: 20.5.3(@types/node@24.12.3)(conventional-commits-parser@6.4.0)(typescript@6.0.3)
@@ -6988,7 +6993,7 @@ snapshots:
     transitivePeerDependencies:
       - supports-color
 
-  '@ai-hero/sandcastle@0.5.10(@effect/cluster@0.57.0(@effect/platform@0.95.0(effect@3.21.0))(@effect/rpc@0.74.0(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/sql@0.50.0(@effect/experimental@0.59.0(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/workflow@0.17.0(@effect/experimental@0.59.0(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.95.0(effect@3.21.0))(@effect/rpc@0.74.0(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(effect@3.21.0))(effect@3.21.0))(@effect/rpc@0.74.0(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/sql@0.50.0(@effect/experimental@0.59.0(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/typeclass@0.39.0(effect@3.21.0))(bufferutil@4.1.0)(utf-8-validate@6.0.6)':
+  '@ai-hero/sandcastle@0.5.10(patch_hash=98ac71a9a8d3bc7df881ffb9c3a698ac315e90f9c507c5d8c356868e3e35a4d5)(@effect/cluster@0.57.0(@effect/platform@0.95.0(effect@3.21.0))(@effect/rpc@0.74.0(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/sql@0.50.0(@effect/experimental@0.59.0(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/workflow@0.17.0(@effect/experimental@0.59.0(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.95.0(effect@3.21.0))(@effect/rpc@0.74.0(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(effect@3.21.0))(effect@3.21.0))(@effect/rpc@0.74.0(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/sql@0.50.0(@effect/experimental@0.59.0(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.95.0(effect@3.21.0))(effect@3.21.0))(@effect/typeclass@0.39.0(effect@3.21.0))(bufferutil@4.1.0)(utf-8-validate@6.0.6)':
     dependencies:
       '@clack/prompts': 1.3.0
       '@effect/cli': 0.74.0(@effect/platform@0.95.0(effect@3.21.0))(@effect/printer-ansi@0.48.0(@effect/typeclass@0.39.0(effect@3.21.0))(effect@3.21.0))(@effect/printer@0.48.0(@effect/typeclass@0.39.0(effect@3.21.0))(effect@3.21.0))(effect@3.21.0)