thinkpool-pair 0.7.232 → 0.7.234

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.
@@ -0,0 +1,30 @@
1
+ import path from 'node:path'
2
+
3
+ const RUNTIMES = Object.freeze({
4
+ claude: Object.freeze({
5
+ id: 'claude', command: 'claude', label: 'Claude Code', protocol: 'agent-sdk',
6
+ structured: true, flow: true, canSteer: false, images: true, nativeModelCatalog: false, defaultMode: 'default',
7
+ modes: Object.freeze(['default', 'acceptEdits', 'plan', 'bypassPermissions']),
8
+ }),
9
+ codex: Object.freeze({
10
+ id: 'codex', command: 'codex', label: 'Codex', protocol: 'codex-app-server',
11
+ structured: true, flow: true, canSteer: true, images: true, nativeModelCatalog: true, defaultMode: 'bypassPermissions',
12
+ modes: Object.freeze(['default', 'acceptEdits', 'plan', 'bypassPermissions', 'review']),
13
+ }),
14
+ hermes: Object.freeze({
15
+ id: 'hermes', command: 'thinkpool', label: 'Hermes Agent', protocol: 'acp',
16
+ structured: true, flow: false, canSteer: true, images: true, nativeModelCatalog: true, defaultMode: 'default',
17
+ modes: Object.freeze(['default', 'acceptEdits']),
18
+ beta: true,
19
+ }),
20
+ })
21
+
22
+ export const STRUCTURED_RUNTIME_IDS = Object.freeze(Object.keys(RUNTIMES))
23
+ export const structuredRuntimeMetadata = (runtime) => RUNTIMES[runtime] || null
24
+ export const structuredRuntimeForCommand = (command) => {
25
+ const bin = path.basename(String(command || '')).toLowerCase()
26
+ return Object.values(RUNTIMES).find((runtime) => runtime.command === bin)?.id || null
27
+ }
28
+ export const defaultStructuredMode = (runtime) => structuredRuntimeMetadata(runtime)?.defaultMode || 'default'
29
+ export const structuredRuntimeSupportsMode = (runtime, mode) => structuredRuntimeMetadata(runtime)?.modes?.includes(mode) === true
30
+ export const structuredRuntimeSupportsFlow = (runtime) => structuredRuntimeMetadata(runtime)?.flow === true
@@ -0,0 +1,15 @@
1
+ import { startClaudeSession } from './claude-session.mjs'
2
+ import { startCodexSession } from './codex-session.mjs'
3
+ import { startHermesSession } from './hermes-session.mjs'
4
+
5
+ const FACTORIES = Object.freeze({
6
+ claude: startClaudeSession,
7
+ codex: startCodexSession,
8
+ hermes: startHermesSession,
9
+ })
10
+
11
+ export function startStructuredSession(runtime, options) {
12
+ const factory = FACTORIES[runtime]
13
+ if (!factory) throw new Error(`Unsupported structured runtime: ${runtime}`)
14
+ return factory(options)
15
+ }
@@ -34,23 +34,26 @@ export function buildTerminalRolePrompt({ spawnedBy = null, spawnDepth = 0, casc
34
34
  if (sideParent) {
35
35
  return `TERMINAL ROLE (authoritative): You are a SIDE SUB-TERMINAL attached to main terminal ${parentRef}. You are not an independent top-level terminal and not a Cascade conductor. Complete the bounded side task directly, do not fan out more terminals, and return a compact handoff to main.`
36
36
  }
37
+ if (cascadeRole === 'conductor') {
38
+ if (!spawnedBy && depth === 0) {
39
+ return 'TERMINAL ROLE (authoritative): You are an independent MAIN CASCADE CONDUCTOR TERMINAL opened through the room\'s top-level terminal lifecycle. You are not an Ensemble child, spawned sub-terminal, Side lane, or Flow lane. Keep decomposition and integration here. Open only worker SUB-TERMINALS with spawn_terminal, collect and verify their results, and close them. Never call open_main_terminal yourself or delegate conductor responsibility to a worker.'
40
+ }
41
+ return `TERMINAL ROLE (authoritative): You are a MISCLASSIFIED ENSEMBLE SUB-TERMINAL at spawn depth ${Math.max(1, depth)}, owned by parent terminal ${parentRef}. A spawned lane can never be a Cascade conductor. Work directly as a worker, do not spawn terminals, and report that the parent must use open_main_terminal for a separate conductor.`
42
+ }
37
43
  if (!spawnedBy && depth === 0) {
38
- return 'TERMINAL ROLE (authoritative): You are an independent TOP-LEVEL ThinkPool terminal opened directly in the room. You are not a spawned sub-terminal or worker lane. You may own and conduct a Cascade: terminals you open with spawn_terminal are your visible SUB-TERMINALS. Keep conductor responsibility here; never tell a spawned worker to pretend it is top-level.'
44
+ return 'TERMINAL ROLE (authoritative): You are an independent TOP-LEVEL ThinkPool terminal opened directly in the room. You are not a spawned sub-terminal or worker lane. You may conduct the current task here and open worker SUB-TERMINALS with spawn_terminal. When a person explicitly asks you to open, launch, or start a separate Cascade/conductor terminal, use open_main_terminal — never spawn_terminal. Conductors are main terminals; Ensemble-spawned lanes are workers only.'
39
45
  }
40
46
  if (depth >= 2) {
41
47
  return `TERMINAL ROLE (authoritative): You are a LEAF SUB-TERMINAL at spawn depth ${depth}, owned by parent terminal ${parentRef}. You are not top-level and not a conductor. Complete the assigned slice directly, do not spawn another terminal, and hand evidence/results back to your parent.`
42
48
  }
43
- if (cascadeRole === 'conductor') {
44
- return `TERMINAL ROLE (authoritative): You are a CASCADE CONDUCTOR TERMINAL at spawn depth ${Math.max(1, depth)}, launched by parent terminal ${parentRef}. You are a visible conductor terminal, not one of the worker sub-terminals you will dispatch. Decompose the assigned Cascade, open bounded worker SUB-TERMINALS with spawn_terminal(cascadeRole="worker"), collect and verify their results, then close them. You are still owned by your parent and must return the integrated outcome there.`
45
- }
46
49
  if (cascadeRole === 'worker') {
47
50
  return `TERMINAL ROLE (authoritative): You are a WORKER SUB-TERMINAL at spawn depth ${Math.max(1, depth)}, owned by parent terminal ${parentRef}. You are not top-level and not a conductor. Complete the assigned slice directly, do not spawn another terminal, and hand evidence/results back to your parent.`
48
51
  }
49
- return `TERMINAL ROLE (authoritative): You are a SPAWNED SUB-TERMINAL at depth ${Math.max(1, depth)}, owned by parent terminal ${parentRef}. You are not an independent top-level terminal. Your default job is the delegated task. You may open one final worker tier only when your parent explicitly assigned you to conduct a Cascade; otherwise work directly. Never describe yourself as top-level, and close any workers you open after collecting their results.`
52
+ return `TERMINAL ROLE (authoritative): You are a SPAWNED WORKER SUB-TERMINAL at depth ${Math.max(1, depth)}, owned by parent terminal ${parentRef}. You are not an independent top-level terminal or a Cascade conductor. Complete the delegated task directly, do not spawn another terminal, and hand evidence/results back to your parent. If the task asks you to conduct, report that the parent must use open_main_terminal instead.`
50
53
  }
51
54
 
52
55
  export const CODEX_THINKPOOL_FIRST_TURN_PREAMBLE = [
53
56
  'ENVIRONMENT (authoritative): You are Codex running inside a ThinkPool Code room, driven live through the thinkpool-pair bridge by a user and possibly a partner. This is a shared remote workspace, not an ordinary local terminal session; act accordingly.',
54
- 'MODEL TIERING FOR DISPATCH: When calling spawn_terminal for Codex, explicitly choose from the available model metadata when practical: gpt-5.6-luna or gpt-5.4-mini for mechanical/scaffold/search/formatting work; gpt-5.6-terra for ordinary feature/fix work; gpt-5.6-sol only for trap-laden repeated failures, architecture/conductor work, or adversarial final review. Do not inherit or select Sol by default. If a named model is unavailable, use the nearest advertised lower tier or omit model and allow runtime fallback.',
57
+ 'MODEL TIERING FOR TERMINALS: When calling open_main_terminal for a genuinely complex Cascade conductor, gpt-5.6-sol may be appropriate. When calling spawn_terminal for worker slices, explicitly choose gpt-5.6-luna or gpt-5.4-mini for mechanical/scaffold/search/formatting work, gpt-5.6-terra for ordinary feature/fix work, and a balanced tier for adversarial review. Never select Sol for routine workers. If a named model is unavailable, use the nearest advertised lower tier or omit model and allow runtime fallback.',
55
58
  ...THINKPOOL_REMOTE_DELIVERY_RULES,
56
59
  ].join(' ')