freddie 0.0.130 → 0.0.131
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/package.json +2 -2
- package/plugins/bash/handler.js +15 -1
- package/src/agent/llm_resolver.js +24 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "freddie",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.131",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Open JS agent harness built on pi-mono, floosie, xstate, and anentrypoint-design",
|
|
6
6
|
"bin": {
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"@libsql/client": "^0.5.0",
|
|
26
26
|
"@mariozechner/pi-ai": "^0.70.6",
|
|
27
27
|
"@mariozechner/pi-tui": "^0.70.6",
|
|
28
|
-
"acptoapi": "^1.0.
|
|
28
|
+
"acptoapi": "^1.0.146",
|
|
29
29
|
"anentrypoint-design": "latest",
|
|
30
30
|
"commander": "^14.0.0",
|
|
31
31
|
"dotenv": "^16.6.1",
|
package/plugins/bash/handler.js
CHANGED
|
@@ -26,7 +26,21 @@ export const _tool = ({
|
|
|
26
26
|
const t = setTimeout(() => { try { child.kill('SIGKILL') } catch {} resolve({ exitCode: -1, stdout, stderr: stderr + '\n[timeout]', timedOut: true }) }, timeout_ms)
|
|
27
27
|
child.stdout?.on('data', d => stdout += d.toString())
|
|
28
28
|
child.stderr?.on('data', d => stderr += d.toString())
|
|
29
|
-
child.on('close', code => {
|
|
29
|
+
child.on('close', code => {
|
|
30
|
+
clearTimeout(t)
|
|
31
|
+
const result = { exitCode: code, stdout, stderr }
|
|
32
|
+
// Windows cmd.exe can silently swallow ALL output (exit 0, empty
|
|
33
|
+
// stdout+stderr) for certain nested-quote one-liners (witnessed:
|
|
34
|
+
// node -e with double-quoted body containing single-quoted JS
|
|
35
|
+
// strings plus an embedded literal \n) -- indistinguishable from
|
|
36
|
+
// "ran fine and printed nothing" without this signal, and models
|
|
37
|
+
// have been observed misdiagnosing it as "bash tool unavailable"
|
|
38
|
+
// and silently substituting an unverified reimplementation.
|
|
39
|
+
if (process.platform === 'win32' && code === 0 && !stdout && !stderr && command.length > 40) {
|
|
40
|
+
result.note = 'exitCode 0 with no output at all on a non-trivial command is unusual on Windows -- cmd.exe can silently swallow output for commands with nested quotes (e.g. node -e one-liners mixing double/single quotes and \\n). If you expected output, try writing the script to a file and running it instead of an inline -e/-c one-liner.'
|
|
41
|
+
}
|
|
42
|
+
resolve(result)
|
|
43
|
+
})
|
|
30
44
|
child.on('error', e => { clearTimeout(t); resolve({ exitCode: -1, stdout, stderr: stderr + '\n' + e.message }) })
|
|
31
45
|
})
|
|
32
46
|
},
|
|
@@ -74,6 +74,29 @@ function adapt(result) {
|
|
|
74
74
|
// Mirror lib/named-chains.js BUILTIN — acptoapi resolves unknown names.
|
|
75
75
|
const NAMED_CHAIN_NAMES = new Set(['fast', 'cheap', 'smart', 'reasoning', 'free', 'local', 'auto'])
|
|
76
76
|
|
|
77
|
+
// A hand-typed agent.model_preference used to be joined in its literal config
|
|
78
|
+
// order, permanently overriding acptoapi's own swe_bench-score-aware ranking
|
|
79
|
+
// (buildAutoChain sorts by score + tool-capability tiering) with no
|
|
80
|
+
// reconciliation at all — witnessed picking a 62-score model ahead of a
|
|
81
|
+
// 79.6-score one purely because it was configured first. Re-rank the user's
|
|
82
|
+
// chosen providers using acptoapi's OWN scored pool (buildAutoChain is a
|
|
83
|
+
// sanctioned top-level export; this never reaches into unexported internals
|
|
84
|
+
// like lib/swe-bench-scores) so provider CHOICE stays user-controlled while
|
|
85
|
+
// ORDER reflects real capability. Unscored links keep their relative config
|
|
86
|
+
// order at the tail, matching acptoapi's own null-score handling.
|
|
87
|
+
function orderByScore(links) {
|
|
88
|
+
let pool
|
|
89
|
+
try { pool = typeof sdk.buildAutoChain === 'function' ? sdk.buildAutoChain(undefined, { hasTools: true }) : [] } catch { pool = [] }
|
|
90
|
+
if (!Array.isArray(pool) || !pool.length) return links
|
|
91
|
+
const rank = new Map(pool.map((l, i) => [l.model, i]))
|
|
92
|
+
return [...links].sort((a, b) => {
|
|
93
|
+
const ra = rank.has(a) ? rank.get(a) : Infinity
|
|
94
|
+
const rb = rank.has(b) ? rank.get(b) : Infinity
|
|
95
|
+
if (ra !== rb) return ra - rb
|
|
96
|
+
return links.indexOf(a) - links.indexOf(b)
|
|
97
|
+
})
|
|
98
|
+
}
|
|
99
|
+
|
|
77
100
|
async function buildModel({ provider, model, inputModel }) {
|
|
78
101
|
if (provider) return `${provider}/${model || DEFAULTS[provider] || ''}`.replace(/\/$/, '')
|
|
79
102
|
if (model) return model
|
|
@@ -88,7 +111,7 @@ async function buildModel({ provider, model, inputModel }) {
|
|
|
88
111
|
const pref = getConfigValue('agent.model_preference', [])
|
|
89
112
|
if (Array.isArray(pref) && pref.length) {
|
|
90
113
|
const links = pref.map(p => `${p.provider}/${p.model || DEFAULTS[p.provider] || ''}`.replace(/\/$/, '')).filter(s => s.includes('/'))
|
|
91
|
-
if (links.length) return links.join(', ')
|
|
114
|
+
if (links.length) return orderByScore(links).join(', ')
|
|
92
115
|
}
|
|
93
116
|
const auto = typeof sdk.buildAutoChain === 'function' ? sdk.buildAutoChain(undefined) : []
|
|
94
117
|
const keyed = Array.isArray(auto) ? auto.filter(l => { const p = l.model.split('/')[0]; const env = PROVIDER_KEYS[p]; return env && process.env[env] }) : []
|