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.
- package/acp-client.mjs +140 -0
- package/agent-detect.mjs +1 -1
- package/bridge.mjs +134 -55
- package/claude-session.mjs +11 -11
- package/codex-session.mjs +1 -1
- package/cross-terminal.mjs +6 -8
- package/hermes-delegation-guard.mjs +15 -0
- package/hermes-event-mapper.mjs +131 -0
- package/hermes-probe.mjs +20 -0
- package/hermes-session.mjs +246 -0
- package/interrupted-resume.mjs +13 -1
- package/launcher.mjs +1 -0
- package/package.json +9 -1
- package/runtime-registry.mjs +30 -0
- package/runtime-session.mjs +15 -0
- package/thinkpool-room-prompt.mjs +9 -6
|
@@ -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
|
|
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
|
|
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
|
|
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(' ')
|