@peakflo/agent-harness 0.2.9-rc.3 → 0.2.9-rc.4
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/README.md +6 -4
- package/dist/adapters/claude-code-adapter.js +1 -5
- package/dist/harness.js +8 -4
- package/dist/vendor-backends.d.ts +12 -20
- package/dist/vendor-backends.js +13 -82
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -57,10 +57,12 @@ cloud sandbox runs Pi only.
|
|
|
57
57
|
through the Peakflo model gateway and are not metered by Peakflo.
|
|
58
58
|
- When you sign out of a harness, or remove it, the runner stops taking work
|
|
59
59
|
for it after its next check.
|
|
60
|
-
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
- What the runner brings and what it expects, the same split as the 20x app:
|
|
61
|
+
it brings the Claude Agent SDK (a dependency of this package, installed with
|
|
62
|
+
it); it expects the tools themselves — `codex`, `claude`, `cursor-agent` —
|
|
63
|
+
to be installed and signed in on the machine. The SDK includes a copy of the
|
|
64
|
+
Claude binary for your platform, which is most of this package's install
|
|
65
|
+
size (about 260 MB installed).
|
|
64
66
|
- Each turn starts the harness's own program and stops it when the turn ends.
|
|
65
67
|
The conversation continues from the session the harness saved on this
|
|
66
68
|
machine.
|
|
@@ -46,7 +46,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
46
46
|
exports.ClaudeCodeAdapter = exports.ClaudeSystemSubtype = void 0;
|
|
47
47
|
const coding_agent_adapter_1 = require("./coding-agent-adapter");
|
|
48
48
|
const permission_mode_1 = require("../runtime/permission-mode");
|
|
49
|
-
const vendor_backends_1 = require("../vendor-backends");
|
|
50
49
|
let ClaudeAgentSDK = null;
|
|
51
50
|
/** Module-level cache for the resolved Claude executable path (persists across adapter instances) */
|
|
52
51
|
let resolvedClaudeExecutablePath = null;
|
|
@@ -271,10 +270,7 @@ class ClaudeCodeAdapter {
|
|
|
271
270
|
}
|
|
272
271
|
async loadSDK() {
|
|
273
272
|
try {
|
|
274
|
-
|
|
275
|
-
// ~190 MB to every install), so it is also looked for in the global
|
|
276
|
-
// node_modules. See `vendor-backends.ts`.
|
|
277
|
-
ClaudeAgentSDK = (await (0, vendor_backends_1.importClaudeSdk)());
|
|
273
|
+
ClaudeAgentSDK = await Promise.resolve().then(() => __importStar(require('@anthropic-ai/claude-agent-sdk')));
|
|
278
274
|
console.log('[ClaudeCodeAdapter] SDK loaded successfully');
|
|
279
275
|
}
|
|
280
276
|
catch (error) {
|
package/dist/harness.js
CHANGED
|
@@ -1035,12 +1035,16 @@ class Harness {
|
|
|
1035
1035
|
blocked.set(harness.name, reason);
|
|
1036
1036
|
continue;
|
|
1037
1037
|
}
|
|
1038
|
+
/*
|
|
1039
|
+
* NAME AND VERSION ONLY. The harness's models are already in
|
|
1040
|
+
* `harnesses[]`, which is sent once and then by digest. Repeating them
|
|
1041
|
+
* here put them back into every heartbeat: about 15 KB each time on a
|
|
1042
|
+
* machine with Cursor's 200 models, seen on the first release candidate
|
|
1043
|
+
* that had this.
|
|
1044
|
+
*/
|
|
1038
1045
|
capabilities.backends.push({
|
|
1039
1046
|
name: harness.name,
|
|
1040
|
-
version: harness.version ?? null
|
|
1041
|
-
...(harness.models && harness.models.length > 0
|
|
1042
|
-
? { models: harness.models.map(({ id, name }) => ({ id, name })) }
|
|
1043
|
-
: {})
|
|
1047
|
+
version: harness.version ?? null
|
|
1044
1048
|
});
|
|
1045
1049
|
}
|
|
1046
1050
|
return blocked;
|
|
@@ -47,31 +47,23 @@ export declare const CLAUDE_SDK_PACKAGE = "@anthropic-ai/claude-agent-sdk";
|
|
|
47
47
|
* runner. Fixed sentences, like every other reason in the report.
|
|
48
48
|
*/
|
|
49
49
|
export declare const NOT_RUNNABLE_REASONS: {
|
|
50
|
-
readonly claudeSdkMissing: "The Claude Agent SDK
|
|
50
|
+
readonly claudeSdkMissing: "The Claude Agent SDK that ships with this runner could not be loaded. Reinstall the runner.";
|
|
51
51
|
readonly sandbox: "A cloud sandbox runs Pi only.";
|
|
52
52
|
};
|
|
53
53
|
/**
|
|
54
|
-
*
|
|
55
|
-
* `node_modules`.
|
|
54
|
+
* Where the SDK is, or null.
|
|
56
55
|
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Where the SDK can be loaded from, or null. Synchronous and cheap (a few
|
|
67
|
-
* file reads), so it can be asked on every capability report.
|
|
56
|
+
* THE SDK IS A DEPENDENCY OF THIS PACKAGE, as it is of the 20x app: installing
|
|
57
|
+
* the runner installs it, and nothing else has to be done on the machine. So
|
|
58
|
+
* it is looked for in one place, this package's own dependency tree.
|
|
59
|
+
*
|
|
60
|
+
* Null is still possible and still handled, because "declared" is not
|
|
61
|
+
* "present": an install that was interrupted, pruned, or made with
|
|
62
|
+
* dependencies left out has no SDK. Claude Code is then reported as not
|
|
63
|
+
* runnable, with a reason, instead of being routed a turn it must fail.
|
|
68
64
|
*
|
|
69
|
-
* `ownTree` is
|
|
70
|
-
* repository has the SDK as a dev dependency, so "not installed" could not be
|
|
71
|
-
* tested otherwise.
|
|
65
|
+
* `ownTree` is replaced in tests, which could not otherwise see "missing".
|
|
72
66
|
*/
|
|
73
|
-
export declare function resolveClaudeSdk(
|
|
74
|
-
/** Import the SDK from wherever `resolveClaudeSdk` finds it. Throws when absent. */
|
|
75
|
-
export declare function importClaudeSdk(): Promise<unknown>;
|
|
67
|
+
export declare function resolveClaudeSdk(ownTree?: () => string): string | null;
|
|
76
68
|
/** Whether this runner can build an adapter for a vendor backend right now. */
|
|
77
69
|
export declare function vendorBackendBlocker(backend: string, runtime: string): string | null;
|
package/dist/vendor-backends.js
CHANGED
|
@@ -25,14 +25,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
25
25
|
exports.NOT_RUNNABLE_REASONS = exports.CLAUDE_SDK_PACKAGE = exports.VENDOR_BACKENDS = void 0;
|
|
26
26
|
exports.isVendorBackend = isVendorBackend;
|
|
27
27
|
exports.vendorModelId = vendorModelId;
|
|
28
|
-
exports.claudeSdkSearchRoots = claudeSdkSearchRoots;
|
|
29
28
|
exports.resolveClaudeSdk = resolveClaudeSdk;
|
|
30
|
-
exports.importClaudeSdk = importClaudeSdk;
|
|
31
29
|
exports.vendorBackendBlocker = vendorBackendBlocker;
|
|
32
|
-
const node_fs_1 = require("node:fs");
|
|
33
30
|
const node_module_1 = require("node:module");
|
|
34
|
-
const node_path_1 = require("node:path");
|
|
35
|
-
const node_url_1 = require("node:url");
|
|
36
31
|
exports.VENDOR_BACKENDS = ['codex', 'claude-code', 'cursor'];
|
|
37
32
|
function isVendorBackend(name) {
|
|
38
33
|
return exports.VENDOR_BACKENDS.includes(name);
|
|
@@ -65,94 +60,30 @@ exports.CLAUDE_SDK_PACKAGE = '@anthropic-ai/claude-agent-sdk';
|
|
|
65
60
|
* runner. Fixed sentences, like every other reason in the report.
|
|
66
61
|
*/
|
|
67
62
|
exports.NOT_RUNNABLE_REASONS = {
|
|
68
|
-
claudeSdkMissing: 'The Claude Agent SDK
|
|
63
|
+
claudeSdkMissing: 'The Claude Agent SDK that ships with this runner could not be loaded. Reinstall the runner.',
|
|
69
64
|
sandbox: 'A cloud sandbox runs Pi only.'
|
|
70
65
|
};
|
|
71
66
|
/**
|
|
72
|
-
*
|
|
73
|
-
* `node_modules`.
|
|
67
|
+
* Where the SDK is, or null.
|
|
74
68
|
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const roots = [
|
|
84
|
-
env.PF_CLAUDE_AGENT_SDK_DIR,
|
|
85
|
-
// `npm install -g` beside the running node: <prefix>/lib/node_modules
|
|
86
|
-
(0, node_path_1.join)((0, node_path_1.dirname)((0, node_path_1.dirname)(execPath)), 'lib', 'node_modules'),
|
|
87
|
-
// Windows: <prefix>\node_modules
|
|
88
|
-
(0, node_path_1.join)((0, node_path_1.dirname)(execPath), 'node_modules'),
|
|
89
|
-
'/opt/homebrew/lib/node_modules',
|
|
90
|
-
'/usr/local/lib/node_modules'
|
|
91
|
-
];
|
|
92
|
-
return [...new Set(roots.filter((root) => Boolean(root)))];
|
|
93
|
-
}
|
|
94
|
-
/** The file a package directory loads as, read from its own package.json. */
|
|
95
|
-
function packageEntry(directory) {
|
|
96
|
-
try {
|
|
97
|
-
const manifest = JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(directory, 'package.json'), 'utf8'));
|
|
98
|
-
const root = manifest.exports && typeof manifest.exports === 'object'
|
|
99
|
-
? (manifest.exports['.'] ??
|
|
100
|
-
manifest.exports)
|
|
101
|
-
: manifest.exports;
|
|
102
|
-
const fromExports = typeof root === 'string'
|
|
103
|
-
? root
|
|
104
|
-
: root && typeof root === 'object'
|
|
105
|
-
? (root.import ??
|
|
106
|
-
root.default)
|
|
107
|
-
: undefined;
|
|
108
|
-
const entry = [
|
|
109
|
-
fromExports,
|
|
110
|
-
manifest.module,
|
|
111
|
-
manifest.main,
|
|
112
|
-
'index.js'
|
|
113
|
-
].find((candidate) => typeof candidate === 'string');
|
|
114
|
-
const file = entry ? (0, node_path_1.join)(directory, entry) : null;
|
|
115
|
-
return file && (0, node_fs_1.existsSync)(file) ? file : null;
|
|
116
|
-
}
|
|
117
|
-
catch {
|
|
118
|
-
return null;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Where the SDK can be loaded from, or null. Synchronous and cheap (a few
|
|
123
|
-
* file reads), so it can be asked on every capability report.
|
|
69
|
+
* THE SDK IS A DEPENDENCY OF THIS PACKAGE, as it is of the 20x app: installing
|
|
70
|
+
* the runner installs it, and nothing else has to be done on the machine. So
|
|
71
|
+
* it is looked for in one place, this package's own dependency tree.
|
|
72
|
+
*
|
|
73
|
+
* Null is still possible and still handled, because "declared" is not
|
|
74
|
+
* "present": an install that was interrupted, pruned, or made with
|
|
75
|
+
* dependencies left out has no SDK. Claude Code is then reported as not
|
|
76
|
+
* runnable, with a reason, instead of being routed a turn it must fail.
|
|
124
77
|
*
|
|
125
|
-
* `ownTree` is
|
|
126
|
-
* repository has the SDK as a dev dependency, so "not installed" could not be
|
|
127
|
-
* tested otherwise.
|
|
78
|
+
* `ownTree` is replaced in tests, which could not otherwise see "missing".
|
|
128
79
|
*/
|
|
129
|
-
function resolveClaudeSdk(
|
|
80
|
+
function resolveClaudeSdk(ownTree = () => (0, node_module_1.createRequire)(__filename).resolve(exports.CLAUDE_SDK_PACKAGE)) {
|
|
130
81
|
try {
|
|
131
82
|
return ownTree();
|
|
132
83
|
}
|
|
133
84
|
catch {
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
for (const root of roots) {
|
|
137
|
-
const entry = packageEntry((0, node_path_1.join)(root, exports.CLAUDE_SDK_PACKAGE));
|
|
138
|
-
if (entry)
|
|
139
|
-
return entry;
|
|
140
|
-
}
|
|
141
|
-
return null;
|
|
142
|
-
}
|
|
143
|
-
/** Import the SDK from wherever `resolveClaudeSdk` finds it. Throws when absent. */
|
|
144
|
-
async function importClaudeSdk() {
|
|
145
|
-
const resolved = resolveClaudeSdk();
|
|
146
|
-
if (!resolved) {
|
|
147
|
-
throw new Error(exports.NOT_RUNNABLE_REASONS.claudeSdkMissing);
|
|
85
|
+
return null;
|
|
148
86
|
}
|
|
149
|
-
/*
|
|
150
|
-
* `new Function` keeps this a REAL dynamic import in the compiled CommonJS
|
|
151
|
-
* output. Written as `import(x)`, TypeScript turns it into `require(x)`,
|
|
152
|
-
* and the SDK is an ES module that `require` cannot load on every Node.
|
|
153
|
-
*/
|
|
154
|
-
const dynamicImport = new Function('specifier', 'return import(specifier)');
|
|
155
|
-
return dynamicImport((0, node_url_1.pathToFileURL)(resolved).href);
|
|
156
87
|
}
|
|
157
88
|
/** Whether this runner can build an adapter for a vendor backend right now. */
|
|
158
89
|
function vendorBackendBlocker(backend, runtime) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peakflo/agent-harness",
|
|
3
|
-
"version": "0.2.9-rc.
|
|
3
|
+
"version": "0.2.9-rc.4",
|
|
4
4
|
"description": "Headless Peakflo coding-agent harness. One codebase, three hosting modes: a Daytona cloud sandbox, a customer VM, and the 20x desktop.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -29,7 +29,6 @@
|
|
|
29
29
|
"test": "jest"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@anthropic-ai/claude-agent-sdk": "^0.3.195",
|
|
33
32
|
"@opencode-ai/sdk": "^1.15.13",
|
|
34
33
|
"@types/node": "^22.10.0",
|
|
35
34
|
"tsx": "^4.19.3",
|
|
@@ -37,6 +36,7 @@
|
|
|
37
36
|
"undici": "^7.21.0"
|
|
38
37
|
},
|
|
39
38
|
"dependencies": {
|
|
39
|
+
"@anthropic-ai/claude-agent-sdk": "0.3.258",
|
|
40
40
|
"@modelcontextprotocol/client": "2.0.0",
|
|
41
41
|
"@peculiar/x509": "^2.1.0",
|
|
42
42
|
"reflect-metadata": "^0.2.2"
|