@agentdeck/bridge 0.1.0 → 0.2.1
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/LICENSE +21 -0
- package/dist/adapters/claude-code.d.ts +11 -27
- package/dist/adapters/claude-code.d.ts.map +1 -1
- package/dist/adapters/claude-code.js +29 -123
- package/dist/adapters/claude-code.js.map +1 -1
- package/dist/adapters/codex-cli.d.ts +21 -0
- package/dist/adapters/codex-cli.d.ts.map +1 -0
- package/dist/adapters/codex-cli.js +53 -0
- package/dist/adapters/codex-cli.js.map +1 -0
- package/dist/adapters/index.d.ts +4 -0
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +13 -0
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/monitor.d.ts +34 -0
- package/dist/adapters/monitor.d.ts.map +1 -0
- package/dist/adapters/monitor.js +86 -0
- package/dist/adapters/monitor.js.map +1 -0
- package/dist/adapters/openclaw.d.ts +36 -2
- package/dist/adapters/openclaw.d.ts.map +1 -1
- package/dist/adapters/openclaw.js +329 -59
- package/dist/adapters/openclaw.js.map +1 -1
- package/dist/adapters/opencode-adapter.d.ts +48 -0
- package/dist/adapters/opencode-adapter.d.ts.map +1 -0
- package/dist/adapters/opencode-adapter.js +345 -0
- package/dist/adapters/opencode-adapter.js.map +1 -0
- package/dist/adapters/pty-adapter.d.ts +56 -0
- package/dist/adapters/pty-adapter.d.ts.map +1 -0
- package/dist/adapters/pty-adapter.js +143 -0
- package/dist/adapters/pty-adapter.js.map +1 -0
- package/dist/adb-reverse.d.ts +25 -0
- package/dist/adb-reverse.d.ts.map +1 -0
- package/dist/adb-reverse.js +129 -0
- package/dist/adb-reverse.js.map +1 -0
- package/dist/antigravity-local.d.ts +7 -0
- package/dist/antigravity-local.d.ts.map +1 -0
- package/dist/antigravity-local.js +153 -0
- package/dist/antigravity-local.js.map +1 -0
- package/dist/apme/adapters/claude-hook.d.ts +15 -0
- package/dist/apme/adapters/claude-hook.d.ts.map +1 -0
- package/dist/apme/adapters/claude-hook.js +85 -0
- package/dist/apme/adapters/claude-hook.js.map +1 -0
- package/dist/apme/adapters/claude-pty.d.ts +28 -0
- package/dist/apme/adapters/claude-pty.d.ts.map +1 -0
- package/dist/apme/adapters/claude-pty.js +88 -0
- package/dist/apme/adapters/claude-pty.js.map +1 -0
- package/dist/apme/adapters/timeline.d.ts +16 -0
- package/dist/apme/adapters/timeline.d.ts.map +1 -0
- package/dist/apme/adapters/timeline.js +66 -0
- package/dist/apme/adapters/timeline.js.map +1 -0
- package/dist/apme/classifier.d.ts +53 -0
- package/dist/apme/classifier.d.ts.map +1 -0
- package/dist/apme/classifier.js +266 -0
- package/dist/apme/classifier.js.map +1 -0
- package/dist/apme/claude-transcript-reader.d.ts +38 -0
- package/dist/apme/claude-transcript-reader.d.ts.map +1 -0
- package/dist/apme/claude-transcript-reader.js +127 -0
- package/dist/apme/claude-transcript-reader.js.map +1 -0
- package/dist/apme/collector.d.ts +108 -0
- package/dist/apme/collector.d.ts.map +1 -0
- package/dist/apme/collector.js +659 -0
- package/dist/apme/collector.js.map +1 -0
- package/dist/apme/dashboard-html.d.ts +9 -0
- package/dist/apme/dashboard-html.d.ts.map +1 -0
- package/dist/apme/dashboard-html.js +416 -0
- package/dist/apme/dashboard-html.js.map +1 -0
- package/dist/apme/http.d.ts +19 -0
- package/dist/apme/http.d.ts.map +1 -0
- package/dist/apme/http.js +210 -0
- package/dist/apme/http.js.map +1 -0
- package/dist/apme/hw-sampler.d.ts +30 -0
- package/dist/apme/hw-sampler.d.ts.map +1 -0
- package/dist/apme/hw-sampler.js +106 -0
- package/dist/apme/hw-sampler.js.map +1 -0
- package/dist/apme/index.d.ts +43 -0
- package/dist/apme/index.d.ts.map +1 -0
- package/dist/apme/index.js +75 -0
- package/dist/apme/index.js.map +1 -0
- package/dist/apme/outcome.d.ts +48 -0
- package/dist/apme/outcome.d.ts.map +1 -0
- package/dist/apme/outcome.js +232 -0
- package/dist/apme/outcome.js.map +1 -0
- package/dist/apme/recommend.d.ts +32 -0
- package/dist/apme/recommend.d.ts.map +1 -0
- package/dist/apme/recommend.js +41 -0
- package/dist/apme/recommend.js.map +1 -0
- package/dist/apme/runner.d.ts +94 -0
- package/dist/apme/runner.d.ts.map +1 -0
- package/dist/apme/runner.js +812 -0
- package/dist/apme/runner.js.map +1 -0
- package/dist/apme/settings.d.ts +65 -0
- package/dist/apme/settings.d.ts.map +1 -0
- package/dist/apme/settings.js +97 -0
- package/dist/apme/settings.js.map +1 -0
- package/dist/apme/store.d.ts +99 -0
- package/dist/apme/store.d.ts.map +1 -0
- package/dist/apme/store.js +911 -0
- package/dist/apme/store.js.map +1 -0
- package/dist/apme/tuner.d.ts +64 -0
- package/dist/apme/tuner.d.ts.map +1 -0
- package/dist/apme/tuner.js +297 -0
- package/dist/apme/tuner.js.map +1 -0
- package/dist/apme/types.d.ts +11 -0
- package/dist/apme/types.d.ts.map +1 -0
- package/dist/apme/types.js +10 -0
- package/dist/apme/types.js.map +1 -0
- package/dist/auth.d.ts +1 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +15 -5
- package/dist/auth.js.map +1 -1
- package/dist/bridge-core.d.ts +162 -0
- package/dist/bridge-core.d.ts.map +1 -0
- package/dist/bridge-core.js +627 -0
- package/dist/bridge-core.js.map +1 -0
- package/dist/check-deps.d.ts +3 -1
- package/dist/check-deps.d.ts.map +1 -1
- package/dist/check-deps.js +34 -13
- package/dist/check-deps.js.map +1 -1
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +1235 -0
- package/dist/cli.js.map +1 -0
- package/dist/codex-auth.d.ts +10 -0
- package/dist/codex-auth.d.ts.map +1 -0
- package/dist/codex-auth.js +63 -0
- package/dist/codex-auth.js.map +1 -0
- package/dist/codex-output-parser.d.ts +21 -0
- package/dist/codex-output-parser.d.ts.map +1 -0
- package/dist/codex-output-parser.js +253 -0
- package/dist/codex-output-parser.js.map +1 -0
- package/dist/d200h/hid-protocol.d.ts +62 -0
- package/dist/d200h/hid-protocol.d.ts.map +1 -0
- package/dist/d200h/hid-protocol.js +124 -0
- package/dist/d200h/hid-protocol.js.map +1 -0
- package/dist/d200h/image-renderer.d.ts +36 -0
- package/dist/d200h/image-renderer.d.ts.map +1 -0
- package/dist/d200h/image-renderer.js +487 -0
- package/dist/d200h/image-renderer.js.map +1 -0
- package/dist/daemon-server.d.ts +19 -0
- package/dist/daemon-server.d.ts.map +1 -0
- package/dist/daemon-server.js +1168 -0
- package/dist/daemon-server.js.map +1 -0
- package/dist/daemon-ws-client.d.ts +82 -0
- package/dist/daemon-ws-client.d.ts.map +1 -0
- package/dist/daemon-ws-client.js +179 -0
- package/dist/daemon-ws-client.js.map +1 -0
- package/dist/daemon.d.ts +10 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +56 -0
- package/dist/daemon.js.map +1 -0
- package/dist/display-monitor.d.ts +25 -0
- package/dist/display-monitor.d.ts.map +1 -0
- package/dist/display-monitor.js +143 -0
- package/dist/display-monitor.js.map +1 -0
- package/dist/esp32-serial.d.ts +112 -0
- package/dist/esp32-serial.d.ts.map +1 -0
- package/dist/esp32-serial.js +502 -0
- package/dist/esp32-serial.js.map +1 -0
- package/dist/gateway-probe.d.ts +12 -0
- package/dist/gateway-probe.d.ts.map +1 -0
- package/dist/gateway-probe.js +39 -0
- package/dist/gateway-probe.js.map +1 -0
- package/dist/hook-migration.d.ts +2 -0
- package/dist/hook-migration.d.ts.map +1 -0
- package/dist/hook-migration.js +104 -0
- package/dist/hook-migration.js.map +1 -0
- package/dist/hook-server.d.ts +29 -0
- package/dist/hook-server.d.ts.map +1 -1
- package/dist/hook-server.js +366 -8
- package/dist/hook-server.js.map +1 -1
- package/dist/index.d.ts +20 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1304 -562
- package/dist/index.js.map +1 -1
- package/dist/log-stream.d.ts +26 -0
- package/dist/log-stream.d.ts.map +1 -0
- package/dist/log-stream.js +111 -0
- package/dist/log-stream.js.map +1 -0
- package/dist/logger.d.ts +9 -2
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +36 -5
- package/dist/logger.js.map +1 -1
- package/dist/mdns.d.ts +15 -1
- package/dist/mdns.d.ts.map +1 -1
- package/dist/mdns.js +143 -28
- package/dist/mdns.js.map +1 -1
- package/dist/mlx-probe.d.ts +14 -0
- package/dist/mlx-probe.d.ts.map +1 -0
- package/dist/mlx-probe.js +44 -0
- package/dist/mlx-probe.js.map +1 -0
- package/dist/model-catalog.d.ts +5 -3
- package/dist/model-catalog.d.ts.map +1 -1
- package/dist/model-catalog.js +45 -29
- package/dist/model-catalog.js.map +1 -1
- package/dist/modules/adb-module.d.ts +14 -0
- package/dist/modules/adb-module.d.ts.map +1 -0
- package/dist/modules/adb-module.js +36 -0
- package/dist/modules/adb-module.js.map +1 -0
- package/dist/modules/d200h-module.d.ts +43 -0
- package/dist/modules/d200h-module.d.ts.map +1 -0
- package/dist/modules/d200h-module.js +360 -0
- package/dist/modules/d200h-module.js.map +1 -0
- package/dist/modules/d200h-renderer.d.ts +7 -0
- package/dist/modules/d200h-renderer.d.ts.map +1 -0
- package/dist/modules/d200h-renderer.js +321 -0
- package/dist/modules/d200h-renderer.js.map +1 -0
- package/dist/modules/index.d.ts +23 -0
- package/dist/modules/index.d.ts.map +1 -0
- package/dist/modules/index.js +65 -0
- package/dist/modules/index.js.map +1 -0
- package/dist/modules/mdns-module.d.ts +12 -0
- package/dist/modules/mdns-module.d.ts.map +1 -0
- package/dist/modules/mdns-module.js +21 -0
- package/dist/modules/mdns-module.js.map +1 -0
- package/dist/modules/pixoo-module.d.ts +8 -0
- package/dist/modules/pixoo-module.d.ts.map +1 -0
- package/dist/modules/pixoo-module.js +24 -0
- package/dist/modules/pixoo-module.js.map +1 -0
- package/dist/modules/serial-module.d.ts +18 -0
- package/dist/modules/serial-module.d.ts.map +1 -0
- package/dist/modules/serial-module.js +47 -0
- package/dist/modules/serial-module.js.map +1 -0
- package/dist/modules/types.d.ts +39 -0
- package/dist/modules/types.d.ts.map +1 -0
- package/dist/modules/types.js +2 -0
- package/dist/modules/types.js.map +1 -0
- package/dist/ollama-probe.d.ts +13 -0
- package/dist/ollama-probe.d.ts.map +1 -0
- package/dist/ollama-probe.js +46 -0
- package/dist/ollama-probe.js.map +1 -0
- package/dist/opencode-client.d.ts +126 -0
- package/dist/opencode-client.d.ts.map +1 -0
- package/dist/opencode-client.js +181 -0
- package/dist/opencode-client.js.map +1 -0
- package/dist/output-parser.d.ts +3 -0
- package/dist/output-parser.d.ts.map +1 -1
- package/dist/output-parser.js +29 -3
- package/dist/output-parser.js.map +1 -1
- package/dist/passive-observer.d.ts +38 -0
- package/dist/passive-observer.d.ts.map +1 -0
- package/dist/passive-observer.js +632 -0
- package/dist/passive-observer.js.map +1 -0
- package/dist/pixoo/pixoo-bridge.d.ts +50 -0
- package/dist/pixoo/pixoo-bridge.d.ts.map +1 -0
- package/dist/pixoo/pixoo-bridge.js +280 -0
- package/dist/pixoo/pixoo-bridge.js.map +1 -0
- package/dist/pixoo/pixoo-camera.d.ts +80 -0
- package/dist/pixoo/pixoo-camera.d.ts.map +1 -0
- package/dist/pixoo/pixoo-camera.js +271 -0
- package/dist/pixoo/pixoo-camera.js.map +1 -0
- package/dist/pixoo/pixoo-client.d.ts +67 -0
- package/dist/pixoo/pixoo-client.d.ts.map +1 -0
- package/dist/pixoo/pixoo-client.js +335 -0
- package/dist/pixoo/pixoo-client.js.map +1 -0
- package/dist/pixoo/pixoo-font.d.ts +24 -0
- package/dist/pixoo/pixoo-font.d.ts.map +1 -0
- package/dist/pixoo/pixoo-font.js +121 -0
- package/dist/pixoo/pixoo-font.js.map +1 -0
- package/dist/pixoo/pixoo-renderer.d.ts +32 -0
- package/dist/pixoo/pixoo-renderer.d.ts.map +1 -0
- package/dist/pixoo/pixoo-renderer.js +696 -0
- package/dist/pixoo/pixoo-renderer.js.map +1 -0
- package/dist/pixoo/pixoo-settings.d.ts +10 -0
- package/dist/pixoo/pixoo-settings.d.ts.map +1 -0
- package/dist/pixoo/pixoo-settings.js +47 -0
- package/dist/pixoo/pixoo-settings.js.map +1 -0
- package/dist/pixoo/pixoo-sprites.d.ts +187 -0
- package/dist/pixoo/pixoo-sprites.d.ts.map +1 -0
- package/dist/pixoo/pixoo-sprites.js +926 -0
- package/dist/pixoo/pixoo-sprites.js.map +1 -0
- package/dist/pty-manager.d.ts +1 -1
- package/dist/pty-manager.d.ts.map +1 -1
- package/dist/pty-manager.js +36 -15
- package/dist/pty-manager.js.map +1 -1
- package/dist/session-aggregator.d.ts +41 -0
- package/dist/session-aggregator.d.ts.map +1 -0
- package/dist/session-aggregator.js +76 -0
- package/dist/session-aggregator.js.map +1 -0
- package/dist/session-focus-relay.d.ts +35 -0
- package/dist/session-focus-relay.d.ts.map +1 -0
- package/dist/session-focus-relay.js +127 -0
- package/dist/session-focus-relay.js.map +1 -0
- package/dist/session-registry.d.ts +88 -1
- package/dist/session-registry.d.ts.map +1 -1
- package/dist/session-registry.js +222 -15
- package/dist/session-registry.js.map +1 -1
- package/dist/session-timeline-relay.d.ts +27 -0
- package/dist/session-timeline-relay.d.ts.map +1 -0
- package/dist/session-timeline-relay.js +124 -0
- package/dist/session-timeline-relay.js.map +1 -0
- package/dist/state-machine.d.ts +1 -0
- package/dist/state-machine.d.ts.map +1 -1
- package/dist/state-machine.js +14 -0
- package/dist/state-machine.js.map +1 -1
- package/dist/terminal-status.d.ts +28 -0
- package/dist/terminal-status.d.ts.map +1 -0
- package/dist/terminal-status.js +152 -0
- package/dist/terminal-status.js.map +1 -0
- package/dist/timeline-store.d.ts +22 -0
- package/dist/timeline-store.d.ts.map +1 -0
- package/dist/timeline-store.js +79 -0
- package/dist/timeline-store.js.map +1 -0
- package/dist/timeline-summarizer.d.ts +14 -0
- package/dist/timeline-summarizer.d.ts.map +1 -0
- package/dist/timeline-summarizer.js +154 -0
- package/dist/timeline-summarizer.js.map +1 -0
- package/dist/tts.d.ts +25 -0
- package/dist/tts.d.ts.map +1 -0
- package/dist/tts.js +99 -0
- package/dist/tts.js.map +1 -0
- package/dist/tui/ansi.d.ts +92 -0
- package/dist/tui/ansi.d.ts.map +1 -0
- package/dist/tui/ansi.js +181 -0
- package/dist/tui/ansi.js.map +1 -0
- package/dist/tui/dashboard.d.ts +35 -0
- package/dist/tui/dashboard.d.ts.map +1 -0
- package/dist/tui/dashboard.js +436 -0
- package/dist/tui/dashboard.js.map +1 -0
- package/dist/tui/gauge.d.ts +15 -0
- package/dist/tui/gauge.d.ts.map +1 -0
- package/dist/tui/gauge.js +82 -0
- package/dist/tui/gauge.js.map +1 -0
- package/dist/tui/renderer.d.ts +15 -0
- package/dist/tui/renderer.d.ts.map +1 -0
- package/dist/tui/renderer.js +758 -0
- package/dist/tui/renderer.js.map +1 -0
- package/dist/tui/screen.d.ts +27 -0
- package/dist/tui/screen.d.ts.map +1 -0
- package/dist/tui/screen.js +109 -0
- package/dist/tui/screen.js.map +1 -0
- package/dist/tui/terrarium.d.ts +96 -0
- package/dist/tui/terrarium.d.ts.map +1 -0
- package/dist/tui/terrarium.js +912 -0
- package/dist/tui/terrarium.js.map +1 -0
- package/dist/types.d.ts +4 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +3 -2
- package/dist/types.js.map +1 -1
- package/dist/usage-api.d.ts +9 -2
- package/dist/usage-api.d.ts.map +1 -1
- package/dist/usage-api.js +224 -42
- package/dist/usage-api.js.map +1 -1
- package/dist/usage-event.d.ts +12 -0
- package/dist/usage-event.d.ts.map +1 -0
- package/dist/usage-event.js +78 -0
- package/dist/usage-event.js.map +1 -0
- package/dist/usage-tracker.d.ts +4 -0
- package/dist/usage-tracker.d.ts.map +1 -1
- package/dist/usage-tracker.js +17 -0
- package/dist/usage-tracker.js.map +1 -1
- package/dist/utility-proxy.d.ts +30 -0
- package/dist/utility-proxy.d.ts.map +1 -0
- package/dist/utility-proxy.js +217 -0
- package/dist/utility-proxy.js.map +1 -0
- package/dist/utils/project-name.d.ts +22 -0
- package/dist/utils/project-name.d.ts.map +1 -0
- package/dist/utils/project-name.js +72 -0
- package/dist/utils/project-name.js.map +1 -0
- package/dist/version-check.d.ts +26 -0
- package/dist/version-check.d.ts.map +1 -0
- package/dist/version-check.js +225 -0
- package/dist/version-check.js.map +1 -0
- package/dist/voice-assistant.d.ts +63 -0
- package/dist/voice-assistant.d.ts.map +1 -0
- package/dist/voice-assistant.js +406 -0
- package/dist/voice-assistant.js.map +1 -0
- package/dist/voice.d.ts +2 -0
- package/dist/voice.d.ts.map +1 -1
- package/dist/voice.js +26 -1
- package/dist/voice.js.map +1 -1
- package/dist/wake-word.d.ts +35 -0
- package/dist/wake-word.d.ts.map +1 -0
- package/dist/wake-word.js +225 -0
- package/dist/wake-word.js.map +1 -0
- package/dist/whisper-server-manager.d.ts +1 -1
- package/dist/whisper-server-manager.js +1 -1
- package/dist/wifi-config.d.ts +24 -0
- package/dist/wifi-config.d.ts.map +1 -0
- package/dist/wifi-config.js +84 -0
- package/dist/wifi-config.js.map +1 -0
- package/dist/ws-server.d.ts +12 -0
- package/dist/ws-server.d.ts.map +1 -1
- package/dist/ws-server.js +81 -3
- package/dist/ws-server.js.map +1 -1
- package/package.json +21 -13
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* APME Outcome Detector + Efficiency Calculator + Composite Scorer.
|
|
3
|
+
*
|
|
4
|
+
* Determines what the user DID with the agent's output (committed, abandoned,
|
|
5
|
+
* iterated, A/B tested) rather than relying on noisy explicit feedback.
|
|
6
|
+
* Computes efficiency metrics from run metadata. Calculates a weighted
|
|
7
|
+
* composite score from outcome + judge + efficiency + vibe.
|
|
8
|
+
*/
|
|
9
|
+
import { execSync } from 'child_process';
|
|
10
|
+
import { debug } from '../logger.js';
|
|
11
|
+
// ─── Outcome detection ───────────────────────────────────────────────────────
|
|
12
|
+
const OUTCOME_SCORES = {
|
|
13
|
+
committed: 1.0,
|
|
14
|
+
ab_winner: 1.0,
|
|
15
|
+
iterated: 0.6,
|
|
16
|
+
exploratory: 0.5,
|
|
17
|
+
pending: 0.5,
|
|
18
|
+
interrupted: 0.3,
|
|
19
|
+
abandoned: 0.2,
|
|
20
|
+
ab_loser: 0.1,
|
|
21
|
+
};
|
|
22
|
+
// Categories where success is measured by response quality, not git commits.
|
|
23
|
+
const NON_CODE_CATEGORIES = new Set(['conversation', 'planning', 'research', 'review']);
|
|
24
|
+
export function detectOutcome(store, run) {
|
|
25
|
+
if (!run.endedAt)
|
|
26
|
+
return { outcome: 'pending', confidence: 'low', reason: 'run still in progress' };
|
|
27
|
+
const durationSec = (run.endedAt - run.startedAt) / 1000;
|
|
28
|
+
// Non-code categories: response completion = success (no git needed)
|
|
29
|
+
if (run.taskCategory && NON_CODE_CATEGORIES.has(run.taskCategory)) {
|
|
30
|
+
const turns = store.listTurns(run.id);
|
|
31
|
+
if (turns.length > 0) {
|
|
32
|
+
return { outcome: 'committed', confidence: 'high', reason: `${run.taskCategory} session completed — ${turns.length} turn(s)` };
|
|
33
|
+
}
|
|
34
|
+
if (durationSec < 10) {
|
|
35
|
+
return { outcome: 'interrupted', confidence: 'medium', reason: `very short ${run.taskCategory} session (${Math.round(durationSec)}s)` };
|
|
36
|
+
}
|
|
37
|
+
return { outcome: 'exploratory', confidence: 'low', reason: `${run.taskCategory} session with no captured turns` };
|
|
38
|
+
}
|
|
39
|
+
// 1. Check git diff — did the session produce a commit?
|
|
40
|
+
const hasCommit = run.gitBefore && run.gitAfter && run.gitBefore !== run.gitAfter;
|
|
41
|
+
if (hasCommit) {
|
|
42
|
+
// Check how quickly the commit happened
|
|
43
|
+
if (durationSec < 120) {
|
|
44
|
+
return { outcome: 'committed', confidence: 'high', reason: `quick commit in ${Math.round(durationSec)}s — git ${run.gitBefore?.slice(0, 7)}→${run.gitAfter?.slice(0, 7)}` };
|
|
45
|
+
}
|
|
46
|
+
return { outcome: 'committed', confidence: 'high', reason: `committed — git ${run.gitBefore?.slice(0, 7)}→${run.gitAfter?.slice(0, 7)}` };
|
|
47
|
+
}
|
|
48
|
+
// Also check live git state if projectPath available (commit may have happened after session)
|
|
49
|
+
if (run.projectPath && run.gitBefore) {
|
|
50
|
+
const currentHead = readGitHead(run.projectPath);
|
|
51
|
+
if (currentHead && currentHead !== run.gitBefore) {
|
|
52
|
+
return { outcome: 'committed', confidence: 'medium', reason: `post-session commit detected — git ${run.gitBefore.slice(0, 7)}→${currentHead.slice(0, 7)}` };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// 2. Check for A/B testing pattern — similar runs close in time
|
|
56
|
+
const recentRuns = store.listRuns({ limit: 20 });
|
|
57
|
+
const siblings = recentRuns.filter((r) => r.id !== run.id &&
|
|
58
|
+
r.projectName === run.projectName &&
|
|
59
|
+
r.endedAt &&
|
|
60
|
+
Math.abs(r.startedAt - run.startedAt) < 30 * 60 * 1000 && // within 30 min
|
|
61
|
+
r.modelId !== run.modelId // different model → A/B
|
|
62
|
+
);
|
|
63
|
+
if (siblings.length > 0) {
|
|
64
|
+
const anyCommitted = siblings.some((s) => s.gitBefore && s.gitAfter && s.gitBefore !== s.gitAfter);
|
|
65
|
+
if (anyCommitted) {
|
|
66
|
+
return { outcome: 'ab_loser', confidence: 'medium', reason: `A/B test — sibling ${siblings.find((s) => s.gitBefore !== s.gitAfter)?.modelId ?? 'unknown'} was committed instead` };
|
|
67
|
+
}
|
|
68
|
+
// No sibling committed either — both abandoned or still pending
|
|
69
|
+
}
|
|
70
|
+
// 3. Check for iteration — same project, new session soon after
|
|
71
|
+
const followUps = recentRuns.filter((r) => r.id !== run.id &&
|
|
72
|
+
r.projectName === run.projectName &&
|
|
73
|
+
r.startedAt > (run.endedAt ?? 0) &&
|
|
74
|
+
r.startedAt - (run.endedAt ?? 0) < 10 * 60 * 1000 // within 10 min
|
|
75
|
+
);
|
|
76
|
+
if (followUps.length > 0) {
|
|
77
|
+
return { outcome: 'iterated', confidence: 'medium', reason: `follow-up session ${Math.round((followUps[0].startedAt - (run.endedAt ?? 0)) / 1000)}s later` };
|
|
78
|
+
}
|
|
79
|
+
// 4. Very short session → interrupted or exploratory
|
|
80
|
+
const steps = store.listSteps(run.id);
|
|
81
|
+
const toolCalls = steps.filter((s) => s.kind === 'PreToolUse' || s.kind === 'tool_start').length;
|
|
82
|
+
if (durationSec < 30 && toolCalls <= 1) {
|
|
83
|
+
return { outcome: 'interrupted', confidence: 'low', reason: `very short session (${Math.round(durationSec)}s, ${toolCalls} tools)` };
|
|
84
|
+
}
|
|
85
|
+
if (durationSec < 120 && toolCalls <= 3) {
|
|
86
|
+
return { outcome: 'exploratory', confidence: 'low', reason: `short session (${Math.round(durationSec)}s, ${toolCalls} tools) — likely exploration` };
|
|
87
|
+
}
|
|
88
|
+
// 5. Long session with no commit → abandoned
|
|
89
|
+
if (durationSec > 300) {
|
|
90
|
+
return { outcome: 'abandoned', confidence: 'medium', reason: `${Math.round(durationSec / 60)}min session with no commit` };
|
|
91
|
+
}
|
|
92
|
+
return { outcome: 'exploratory', confidence: 'low', reason: `${Math.round(durationSec)}s session, ${toolCalls} tools, no commit` };
|
|
93
|
+
}
|
|
94
|
+
// ─── Efficiency ──────────────────────────────────────────────────────────────
|
|
95
|
+
export function computeEfficiency(run) {
|
|
96
|
+
const totalTokens = (run.inputTokens ?? 0) + (run.outputTokens ?? 0);
|
|
97
|
+
const durationSec = run.endedAt && run.startedAt ? (run.endedAt - run.startedAt) / 1000 : null;
|
|
98
|
+
const diffLines = countDiffLines(run);
|
|
99
|
+
// Parse task_signals for tool call count
|
|
100
|
+
let toolCalls = 0;
|
|
101
|
+
if (run.taskSignals) {
|
|
102
|
+
try {
|
|
103
|
+
const sig = JSON.parse(run.taskSignals);
|
|
104
|
+
toolCalls = sig.totalToolCalls ?? 0;
|
|
105
|
+
}
|
|
106
|
+
catch { /* ignore */ }
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
tokensPerChange: diffLines && diffLines > 0 ? Math.round(totalTokens / diffLines) : null,
|
|
110
|
+
costPerChange: diffLines && diffLines > 0 && run.costUsd ? run.costUsd / diffLines : null,
|
|
111
|
+
timeToCompleteSec: durationSec ? Math.round(durationSec) : null,
|
|
112
|
+
toolEfficiency: toolCalls > 0 && diffLines ? Math.round((diffLines / toolCalls) * 10) / 10 : null,
|
|
113
|
+
diffLines,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function countDiffLines(run) {
|
|
117
|
+
if (!run.projectPath)
|
|
118
|
+
return null;
|
|
119
|
+
try {
|
|
120
|
+
const args = run.gitBefore && run.gitAfter && run.gitBefore !== run.gitAfter
|
|
121
|
+
? `diff --shortstat ${run.gitBefore}..${run.gitAfter}`
|
|
122
|
+
: 'diff --shortstat HEAD';
|
|
123
|
+
const out = execSync(`git ${args}`, {
|
|
124
|
+
cwd: run.projectPath, encoding: 'utf-8', timeout: 3000,
|
|
125
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
126
|
+
});
|
|
127
|
+
// "3 files changed, 45 insertions(+), 12 deletions(-)"
|
|
128
|
+
const ins = out.match(/(\d+) insertion/);
|
|
129
|
+
const del = out.match(/(\d+) deletion/);
|
|
130
|
+
return (parseInt(ins?.[1] ?? '0', 10)) + (parseInt(del?.[1] ?? '0', 10));
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// ─── Composite scorer ────────────────────────────────────────────────────────
|
|
137
|
+
export function computeComposite(store, run, outcomeResult, efficiency) {
|
|
138
|
+
const outcomeScore = OUTCOME_SCORES[outcomeResult.outcome] ?? 0.5;
|
|
139
|
+
const outcomeWeight = 0.4;
|
|
140
|
+
// LLM judge overall
|
|
141
|
+
const evals = store.listEvalsForRun(run.id);
|
|
142
|
+
const judgeOverall = evals.find((e) => e.layer === 'llm_judge' && e.metric === 'overall');
|
|
143
|
+
const judgeScore = judgeOverall?.score ?? null;
|
|
144
|
+
const judgeWeight = 0.3;
|
|
145
|
+
// Efficiency — normalize: lower tokens_per_change is better.
|
|
146
|
+
// Use a sigmoid-like normalization: score = 1 / (1 + tpc/median)
|
|
147
|
+
// Median for coding tasks ~200 tokens/line. Null = 0.5 (neutral).
|
|
148
|
+
const medianTpc = 200;
|
|
149
|
+
let efficiencyScore = null;
|
|
150
|
+
if (efficiency.tokensPerChange !== null && efficiency.tokensPerChange > 0) {
|
|
151
|
+
efficiencyScore = Math.round((1 / (1 + efficiency.tokensPerChange / medianTpc)) * 100) / 100;
|
|
152
|
+
}
|
|
153
|
+
const efficiencyWeight = 0.2;
|
|
154
|
+
// Vibe — lowest weight due to noise
|
|
155
|
+
const vibe = store.latestVibeForRun(run.id);
|
|
156
|
+
let vibeScore = null;
|
|
157
|
+
if (vibe) {
|
|
158
|
+
vibeScore = vibe.verdict === 'approve' ? 1.0 : vibe.verdict === 'reject' ? 0.0 : 0.5;
|
|
159
|
+
}
|
|
160
|
+
const vibeWeight = 0.1;
|
|
161
|
+
// Weighted sum (only count axes that have values)
|
|
162
|
+
let sum = outcomeScore * outcomeWeight;
|
|
163
|
+
let totalWeight = outcomeWeight;
|
|
164
|
+
if (judgeScore !== null) {
|
|
165
|
+
sum += judgeScore * judgeWeight;
|
|
166
|
+
totalWeight += judgeWeight;
|
|
167
|
+
}
|
|
168
|
+
if (efficiencyScore !== null) {
|
|
169
|
+
sum += efficiencyScore * efficiencyWeight;
|
|
170
|
+
totalWeight += efficiencyWeight;
|
|
171
|
+
}
|
|
172
|
+
if (vibeScore !== null) {
|
|
173
|
+
sum += vibeScore * vibeWeight;
|
|
174
|
+
totalWeight += vibeWeight;
|
|
175
|
+
}
|
|
176
|
+
const composite = totalWeight > 0 ? Math.round((sum / totalWeight) * 100) / 100 : 0.5;
|
|
177
|
+
return {
|
|
178
|
+
outcomeScore, outcomeWeight,
|
|
179
|
+
judgeScore, judgeWeight,
|
|
180
|
+
efficiencyScore, efficiencyWeight,
|
|
181
|
+
vibeScore, vibeWeight,
|
|
182
|
+
composite,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
// ─── Full evaluation pass ────────────────────────────────────────────────────
|
|
186
|
+
/** Run outcome detection + efficiency + composite scoring on a single run. */
|
|
187
|
+
export function evaluateOutcome(store, runId) {
|
|
188
|
+
const run = store.getRun(runId);
|
|
189
|
+
if (!run || !run.endedAt)
|
|
190
|
+
return null;
|
|
191
|
+
const outcome = detectOutcome(store, run);
|
|
192
|
+
const efficiency = computeEfficiency(run);
|
|
193
|
+
const composite = computeComposite(store, run, outcome, efficiency);
|
|
194
|
+
// Persist
|
|
195
|
+
store.updateRun(runId, {
|
|
196
|
+
outcome: outcome.outcome,
|
|
197
|
+
outcomeConfidence: outcome.confidence,
|
|
198
|
+
efficiencyJson: JSON.stringify(efficiency),
|
|
199
|
+
compositeScore: composite.composite,
|
|
200
|
+
});
|
|
201
|
+
debug('APME', `outcome ${runId.slice(0, 8)}: ${outcome.outcome}(${outcome.confidence}) composite=${composite.composite}`);
|
|
202
|
+
return { outcome, efficiency, composite };
|
|
203
|
+
}
|
|
204
|
+
/** Lightweight composite re-computation — called after judge evals are inserted
|
|
205
|
+
* so the judge contribution is reflected without re-detecting outcome/efficiency. */
|
|
206
|
+
export function recomputeComposite(store, runId) {
|
|
207
|
+
const run = store.getRun(runId);
|
|
208
|
+
if (!run || !run.outcome || !run.efficiencyJson)
|
|
209
|
+
return;
|
|
210
|
+
try {
|
|
211
|
+
const outcomeResult = { outcome: run.outcome, confidence: (run.outcomeConfidence ?? 'low'), reason: '' };
|
|
212
|
+
const efficiency = JSON.parse(run.efficiencyJson);
|
|
213
|
+
const composite = computeComposite(store, run, outcomeResult, efficiency);
|
|
214
|
+
store.updateRun(runId, { compositeScore: composite.composite });
|
|
215
|
+
debug('APME', `recomputeComposite ${runId.slice(0, 8)}: ${composite.composite}`);
|
|
216
|
+
}
|
|
217
|
+
catch (err) {
|
|
218
|
+
debug('APME', `recomputeComposite failed ${runId.slice(0, 8)}: ${String(err)}`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// ─── helpers ─────────────────────────────────────────────────────────────────
|
|
222
|
+
function readGitHead(cwd) {
|
|
223
|
+
try {
|
|
224
|
+
return execSync('git rev-parse HEAD', {
|
|
225
|
+
cwd, encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'], timeout: 2000,
|
|
226
|
+
}).trim() || null;
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=outcome.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outcome.js","sourceRoot":"","sources":["../../src/apme/outcome.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* APME Recommendation Engine — Phase 4.
|
|
3
|
+
*
|
|
4
|
+
* Given a task context and the user's available models/subscriptions, return a
|
|
5
|
+
* ranked list of model candidates with expected score, expected cost, and
|
|
6
|
+
* confidence. v1 uses the v_model_scorecard view; v2 (stretch) layers in
|
|
7
|
+
* task-similarity via local embeddings.
|
|
8
|
+
*/
|
|
9
|
+
import type { AgentType } from '@agentdeck/shared';
|
|
10
|
+
import type { ApmeStore } from './store.js';
|
|
11
|
+
export interface RecommendInput {
|
|
12
|
+
taskKind?: string;
|
|
13
|
+
budgetUsd?: number;
|
|
14
|
+
latencyBudgetMs?: number;
|
|
15
|
+
preferLocal?: boolean;
|
|
16
|
+
/** Models the user has access to — comes from settings.json.apme.subscriptions. */
|
|
17
|
+
availableModels?: string[];
|
|
18
|
+
}
|
|
19
|
+
export interface RecommendCandidate {
|
|
20
|
+
modelId: string;
|
|
21
|
+
agentType: AgentType;
|
|
22
|
+
expectedScore: number;
|
|
23
|
+
expectedCostUsd: number;
|
|
24
|
+
confidence: number;
|
|
25
|
+
rationale: string;
|
|
26
|
+
}
|
|
27
|
+
export declare class ApmeRecommender {
|
|
28
|
+
private readonly store;
|
|
29
|
+
constructor(store: ApmeStore);
|
|
30
|
+
recommend(input: RecommendInput): RecommendCandidate[];
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=recommend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recommend.d.ts","sourceRoot":"","sources":["../../src/apme/recommend.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,mFAAmF;IACnF,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,SAAS,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,SAAS;IAE7C,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,kBAAkB,EAAE;CA2BvD"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* APME Recommendation Engine — Phase 4.
|
|
3
|
+
*
|
|
4
|
+
* Given a task context and the user's available models/subscriptions, return a
|
|
5
|
+
* ranked list of model candidates with expected score, expected cost, and
|
|
6
|
+
* confidence. v1 uses the v_model_scorecard view; v2 (stretch) layers in
|
|
7
|
+
* task-similarity via local embeddings.
|
|
8
|
+
*/
|
|
9
|
+
export class ApmeRecommender {
|
|
10
|
+
store;
|
|
11
|
+
constructor(store) {
|
|
12
|
+
this.store = store;
|
|
13
|
+
}
|
|
14
|
+
recommend(input) {
|
|
15
|
+
if (!this.store.enabled)
|
|
16
|
+
return [];
|
|
17
|
+
const rows = this.store.scorecard();
|
|
18
|
+
const filtered = input.availableModels
|
|
19
|
+
? rows.filter((r) => input.availableModels.includes(r.modelId))
|
|
20
|
+
: rows;
|
|
21
|
+
return filtered
|
|
22
|
+
.filter((r) => r.runs >= 3 && (r.avgOverall ?? 0) > 0)
|
|
23
|
+
.sort((a, b) => {
|
|
24
|
+
// Prefer cost-per-quality if budget is tight, otherwise raw quality.
|
|
25
|
+
if (input.budgetUsd !== undefined && input.budgetUsd < 5) {
|
|
26
|
+
return (a.costPerQuality ?? Infinity) - (b.costPerQuality ?? Infinity);
|
|
27
|
+
}
|
|
28
|
+
return (b.avgOverall ?? 0) - (a.avgOverall ?? 0);
|
|
29
|
+
})
|
|
30
|
+
.slice(0, 3)
|
|
31
|
+
.map((r) => ({
|
|
32
|
+
modelId: r.modelId,
|
|
33
|
+
agentType: r.agentType,
|
|
34
|
+
expectedScore: r.avgOverall ?? 0,
|
|
35
|
+
expectedCostUsd: (r.totalCost ?? 0) / Math.max(r.runs, 1),
|
|
36
|
+
confidence: Math.min(1, r.runs / 20),
|
|
37
|
+
rationale: `${r.runs} runs, avg ${((r.avgOverall ?? 0) * 100).toFixed(0)}%${r.avgTestsPass != null ? `, tests ${((r.avgTestsPass) * 100).toFixed(0)}%` : ''}`,
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=recommend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recommend.js","sourceRoot":"","sources":["../../src/apme/recommend.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAuBH,MAAM,OAAO,eAAe;IACG;IAA7B,YAA6B,KAAgB;QAAhB,UAAK,GAAL,KAAK,CAAW;IAAG,CAAC;IAEjD,SAAS,CAAC,KAAqB;QAC7B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO;YAAE,OAAO,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,KAAK,CAAC,eAAe;YACpC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,eAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YAChE,CAAC,CAAC,IAAI,CAAC;QACT,OAAO,QAAQ;aACZ,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;aACrD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACb,qEAAqE;YACrE,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,KAAK,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;gBACzD,OAAO,CAAC,CAAC,CAAC,cAAc,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,IAAI,QAAQ,CAAC,CAAC;YACzE,CAAC;YACD,OAAO,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC;QACnD,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;aACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACX,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,SAAS,EAAE,CAAC,CAAC,SAAsB;YACnC,aAAa,EAAE,CAAC,CAAC,UAAU,IAAI,CAAC;YAChC,eAAe,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACzD,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;YACpC,SAAS,EAAE,GAAG,CAAC,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IACtE,CAAC,CAAC,YAAY,IAAI,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAC/E,EAAE;SACH,CAAC,CAAC,CAAC;IACR,CAAC;CACF"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* APME Evaluation Runner — two-layer pipeline executed after a run closes.
|
|
3
|
+
*
|
|
4
|
+
* Layer 1 (deterministic): detect project language from the run's projectPath,
|
|
5
|
+
* run lint/build/test in-place with a hard timeout, normalize each outcome to
|
|
6
|
+
* 0/1 in `evals` (metrics: lint_clean, build_ok, tests_pass).
|
|
7
|
+
*
|
|
8
|
+
* Layer 2 (llm_judge): G-Eval style rubric against the latest `rubrics` row.
|
|
9
|
+
* Backend is pluggable — default is local MLX (cost-free), API/OpenClaw are
|
|
10
|
+
* opt-in via `~/.agentdeck/settings.json`. Gated by `shouldJudge()` so the
|
|
11
|
+
* common "clear pass" case skips layer 2 entirely.
|
|
12
|
+
*/
|
|
13
|
+
import type { ApmeStore } from './store.js';
|
|
14
|
+
import type { ApmeConfig, ApmeJudgeConfig } from './settings.js';
|
|
15
|
+
import type { ApmeRunRow, ParsedJudge } from './types.js';
|
|
16
|
+
export interface EvalJob {
|
|
17
|
+
runId: string;
|
|
18
|
+
/** Optional project path override; falls back to the run row. */
|
|
19
|
+
projectPath?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface EvalJobResult {
|
|
22
|
+
runId: string;
|
|
23
|
+
turnId?: string;
|
|
24
|
+
taskId?: string;
|
|
25
|
+
layer1Ran: boolean;
|
|
26
|
+
layer2Ran: boolean;
|
|
27
|
+
overall?: number;
|
|
28
|
+
}
|
|
29
|
+
type Lang = 'typescript' | 'swift' | 'kotlin';
|
|
30
|
+
interface DetStepResult {
|
|
31
|
+
metric: 'lint_clean' | 'build_ok' | 'tests_pass';
|
|
32
|
+
score: 0 | 1;
|
|
33
|
+
exitCode: number;
|
|
34
|
+
durationMs: number;
|
|
35
|
+
outputTail: string;
|
|
36
|
+
command: string;
|
|
37
|
+
}
|
|
38
|
+
export declare class ApmeRunner {
|
|
39
|
+
private readonly store;
|
|
40
|
+
private queue;
|
|
41
|
+
private drainPromise;
|
|
42
|
+
private readonly listeners;
|
|
43
|
+
private configOverride;
|
|
44
|
+
private judgeOverride;
|
|
45
|
+
private detOverride;
|
|
46
|
+
constructor(store: ApmeStore);
|
|
47
|
+
_setConfig(cfg: ApmeConfig): void;
|
|
48
|
+
_setJudgeFn(fn: ((prompt: string, judgeCfg: ApmeJudgeConfig) => Promise<string>) | null): void;
|
|
49
|
+
_setDeterministicFn(fn: ((runRow: ApmeRunRow, cfg: ApmeConfig) => Promise<DetStepResult[]>) | null): void;
|
|
50
|
+
onResult(fn: (r: EvalJobResult) => void): () => void;
|
|
51
|
+
enqueue(job: EvalJob): void;
|
|
52
|
+
/** Immediately judge a single completed turn (mid-session eval).
|
|
53
|
+
* Used for non-code categories where turn prompt+response is the eval unit.
|
|
54
|
+
* Fires-and-forgets; result is stored and notified via onResult listeners. */
|
|
55
|
+
enqueueTurn(job: {
|
|
56
|
+
runId: string;
|
|
57
|
+
turnId: string;
|
|
58
|
+
category?: string;
|
|
59
|
+
}): void;
|
|
60
|
+
/** Judge a closed task (group of turns between boundary signals —
|
|
61
|
+
* TodoWrite all-completed, /clear, session_end). Fires-and-forgets;
|
|
62
|
+
* task-level summary and axis scores are persisted in tasks + evals. */
|
|
63
|
+
enqueueTask(job: {
|
|
64
|
+
runId: string;
|
|
65
|
+
taskId: string;
|
|
66
|
+
category?: string;
|
|
67
|
+
boundarySignal?: string;
|
|
68
|
+
}): void;
|
|
69
|
+
private runTaskEval;
|
|
70
|
+
private runTurnEval;
|
|
71
|
+
/** Runs the queue until empty. Awaitable — callers can join the current drain. */
|
|
72
|
+
drain(): Promise<void>;
|
|
73
|
+
private doDrain;
|
|
74
|
+
private runOne;
|
|
75
|
+
}
|
|
76
|
+
export declare function detectLanguage(projectPath: string | null | undefined): Lang | null;
|
|
77
|
+
export declare function runDeterministic(run: ApmeRunRow, cfg: ApmeConfig): Promise<DetStepResult[]>;
|
|
78
|
+
export declare function buildJudgePrompt(run: ApmeRunRow, rubricPrompt: string, layer1Passed: boolean | null, store?: import('./store.js').ApmeStore): string;
|
|
79
|
+
/** Response classification stored by ApmeCollector under turns.efficiency_json.response_kind.
|
|
80
|
+
* Drives which turns make it to the LLM judge — `tool_only` / `empty` are silence
|
|
81
|
+
* to the judge and produce noise scores. Fallback is 'text' when the tag is missing
|
|
82
|
+
* (older rows) but response content is non-trivial. */
|
|
83
|
+
export type ResponseKind = 'text' | 'tool_only' | 'empty';
|
|
84
|
+
export declare function readResponseKind(turn: Record<string, unknown>): ResponseKind;
|
|
85
|
+
/**
|
|
86
|
+
* Build the `judgeModel` DB tag. For MLX backend the effective model is the
|
|
87
|
+
* llm.mlx pin when set — otherwise cfg.judge.model (may still be the legacy
|
|
88
|
+
* "qwen3-30b" placeholder). Non-MLX backends use cfg.judge.model verbatim.
|
|
89
|
+
*/
|
|
90
|
+
export declare function effectiveJudgeModelTag(cfg: ApmeJudgeConfig): string;
|
|
91
|
+
export declare function callJudge(prompt: string, judgeCfg: ApmeJudgeConfig): Promise<string>;
|
|
92
|
+
export declare function parseJudgeJson(text: string): ParsedJudge | null;
|
|
93
|
+
export {};
|
|
94
|
+
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/apme/runner.ts"],"names":[],"mappings":"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"}
|