freddie 0.0.100 → 0.0.102

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/AGENTS.md CHANGED
@@ -12,6 +12,28 @@ Instructions for AI coding assistants working on Freddie.
12
12
  - `anentrypoint-design` ^0.0.94 — webjsx + ripple-ui. Use for any web UI; do NOT add React. Source in C:/dev/anentrypoint-design; freddie depends on the registry build (^0.0.94). For local SDK iteration, swap to `file:../anentrypoint-design` and rebuild via `node scripts/build.mjs`.
13
13
  - `xstate` v5 — every long-lived state machine (agent turns, gateway lifecycle, approvals).
14
14
 
15
+ ## Dynamic stack contract (2026-05-13)
16
+
17
+ The stack is **thebird → freddie → acptoapi**. Each layer owns one concern:
18
+
19
+ - **acptoapi** owns all upstream LLM/provider connectivity: HTTP/SSE to OpenAI, Anthropic, Gemini, brand providers, ACP daemons, Claude CLI. Plus chain/queue/sampler/matrix.
20
+ - **freddie** owns agent-loop orchestration: tools, skills, sessions, memory. It calls *only* acptoapi for LLM access. No direct `fetch('https://api.openai.com/...')` etc. — those are migration debt to move into acptoapi (currently still present in `plugins/vision`, `plugins/image_gen`, `plugins/tts`, `plugins/transcription`, `src/agent/codex_responses_adapter.js`, `src/agent/image_gen_provider.js`, `src/agent/model-discovery.js`).
21
+ - **thebird** owns browser presentation: webjsx UI, pyodide hermes shell. Talks to freddie for everything LLM-related when freddie is reachable; falls back to direct acptoapi only when there is no freddie.
22
+
23
+ Versioning: freddie pins `acptoapi: "latest"` so `npm install` always picks up the newest published acptoapi. Thebird vendors freddie via `scripts/sync-upstream.mjs` against upstream main. No manual version-bump churn between sibling repos.
24
+
25
+ When you touch one of the four direct-fetch utility plugins above, the right fix is to add the corresponding endpoint to acptoapi (POST /v1/images/generations, POST /v1/audio/transcriptions, etc.) and have freddie call acptoapi instead of the upstream vendor.
26
+
27
+ ## acptoapi is THE SDK (since 1.0.59 / 2026-05-13)
28
+
29
+ **Do not reimplement LLM resolution, chain fallback, sampler backoff, or matrix-aware scoring in freddie.** acptoapi is the single source of truth. `src/agent/llm_resolver.js` is now a 61-line thin shim over `acptoapi.chat({model, messages, tools, queuesMap, matrixSource, onFallback, output})`. It builds a single comma-list model string from `[explicit, input.model, agent.model_preference, keyed buildAutoChain]` and delegates everything else.
30
+
31
+ Consume these top-level acptoapi exports directly (no re-export shim, no helper module): `chat`, `stream`, `chain`, `chatChain`, `streamChain`, `fallback`, `buildAutoChain`, `resolveModel`, `parseCommaList`, `splitPrefix`, `listAllModelsAndQueues`, `resolveQueue`, `listAllQueues`, `loadMatrix`, `matrixScore`, `clearMatrixCache`, `peekStatus`, `getStatus`, `isAvailable`, `markFailed`, `markOk`, `resetAvailability`, `startSampler`, `stopSampler`, `createSampler`, `probe`, `probeModels`, `getCachedModels`, `getRunHistory`, `PROVIDER_KEYS`, `PROVIDER_DEFAULTS`.
32
+
33
+ Public surface reference: `node_modules/acptoapi/AGENTS.md` "Public API — unified chain SDK". Acceptable freddie-side adapters (cannot be deleted yet): `model-discovery.js` (claude-cli/ACP/ollama probing breadth acptoapi doesn't cover), `model-sampler.js` (13L re-export shim — test.js imports from it), `model-matrix.js` (28L MATRIX_FILE path helper), `acptoapi-bridge.js` (HTTP daemon passthrough at FREDDIE_LLM_URL when reachable, for `claude/*` etc that need the OAuth-managed daemon).
34
+
35
+ Matrix wired: shim passes `matrixSource: process.env.FREDDIE_MATRIX_URL || <repo>/.gm/model-availability.json` only for comma-list or `queue/<name>` model strings (single-shot omits to avoid leaking chain opts into upstream HTTP body — bug fixed in acptoapi 1.0.62 buildParams/_stripChainOpts, but the conditional pass-through stays as defense-in-depth).
36
+
15
37
  ## Plugin architecture (2026-05-03, pre-v1, no compat shims)
16
38
 
17
39
  The monolith was decomposed into a universal plugin contract. Every tool, platform, memory provider, GUI route, and core subsystem is a plugin under `plugins/<name>/`. The old paths (`src/tools/registry.js`, `src/tools/*.js`, `src/gateway/platforms/*.js`, `src/plugins/memory/*.js`) are GONE — do not reach for them.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "freddie",
3
- "version": "0.0.100",
3
+ "version": "0.0.102",
4
4
  "type": "module",
5
5
  "description": "Open JS agent harness built on pi-mono, floosie, xstate, and anentrypoint-design",
6
6
  "bin": {
@@ -26,8 +26,8 @@
26
26
  "plugsdk": "^1.0.16",
27
27
  "xstate": "^5.31.0",
28
28
  "zod": "^4.0.0",
29
- "anentrypoint-design": "^0.0.94",
30
- "acptoapi": "^1.0.63"
29
+ "anentrypoint-design": "^0.0.95",
30
+ "acptoapi": "latest"
31
31
  },
32
32
  "optionalDependencies": {
33
33
  "@libsql/darwin-arm64": "0.3.19",
@@ -24,10 +24,21 @@ function adapt(result) {
24
24
  return { content: typeof c.content === 'string' ? c.content : '', tool_calls: Array.isArray(c.tool_calls) ? c.tool_calls.map(tc => ({ id: tc.id, name: tc.function?.name, arguments: tryJson(tc.function?.arguments) })) : [], raw: result }
25
25
  }
26
26
 
27
+ // Names callers can use as model= to select a curated acptoapi chain.
28
+ // Mirror lib/named-chains.js BUILTIN — acptoapi resolves unknown names.
29
+ const NAMED_CHAIN_NAMES = new Set(['fast', 'cheap', 'smart', 'reasoning', 'free', 'local', 'auto'])
30
+
27
31
  function buildModel({ provider, model, inputModel }) {
28
32
  if (provider) return `${provider}/${model || DEFAULTS[provider] || ''}`.replace(/\/$/, '')
29
33
  if (model) return model
30
- if (inputModel) return inputModel
34
+ if (inputModel) {
35
+ // Bare name with no slash/comma and matching a known chain → pass through
36
+ // so acptoapi's named-chain resolver picks the curated list.
37
+ if (typeof inputModel === 'string' && !inputModel.includes('/') && !inputModel.includes(',') && NAMED_CHAIN_NAMES.has(inputModel)) {
38
+ return inputModel
39
+ }
40
+ return inputModel
41
+ }
31
42
  const pref = getConfigValue('agent.model_preference', [])
32
43
  if (Array.isArray(pref) && pref.length) {
33
44
  const links = pref.map(p => `${p.provider}/${p.model || DEFAULTS[p.provider] || ''}`.replace(/\/$/, '')).filter(s => s.includes('/'))