@agentdeck/bridge 0.2.2 → 1.0.0
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/assets/fm-helper/agentdeck-fm-helper +0 -0
- package/assets/fonts/IBMPlexSans-Bold.ttf +0 -0
- package/assets/fonts/IBMPlexSans-Regular.ttf +0 -0
- package/assets/fonts/JetBrainsMono-Bold.ttf +0 -0
- package/assets/fonts/JetBrainsMono-Regular.ttf +0 -0
- package/assets/fonts/LICENSES.md +22 -0
- package/dist/adapters/claude-code.d.ts +6 -0
- package/dist/adapters/claude-code.d.ts.map +1 -1
- package/dist/adapters/claude-code.js +8 -0
- package/dist/adapters/claude-code.js.map +1 -1
- package/dist/adapters/openclaw.d.ts +24 -0
- package/dist/adapters/openclaw.d.ts.map +1 -1
- package/dist/adapters/openclaw.js +291 -35
- package/dist/adapters/openclaw.js.map +1 -1
- package/dist/adapters/opencode-adapter.d.ts +59 -0
- package/dist/adapters/opencode-adapter.d.ts.map +1 -1
- package/dist/adapters/opencode-adapter.js +297 -35
- package/dist/adapters/opencode-adapter.js.map +1 -1
- package/dist/adb-reverse.d.ts +1 -1
- package/dist/adb-reverse.js +1 -1
- package/dist/antigravity-local.d.ts +1 -0
- package/dist/antigravity-local.d.ts.map +1 -1
- package/dist/antigravity-local.js +33 -0
- package/dist/antigravity-local.js.map +1 -1
- package/dist/apme/adapters/claude-hook.d.ts.map +1 -1
- package/dist/apme/adapters/claude-hook.js +5 -0
- package/dist/apme/adapters/claude-hook.js.map +1 -1
- package/dist/apme/adapters/codex-hook.d.ts +17 -0
- package/dist/apme/adapters/codex-hook.d.ts.map +1 -0
- package/dist/apme/adapters/codex-hook.js +95 -0
- package/dist/apme/adapters/codex-hook.js.map +1 -0
- package/dist/apme/adapters/codex-turn-manager.d.ts +86 -0
- package/dist/apme/adapters/codex-turn-manager.d.ts.map +1 -0
- package/dist/apme/adapters/codex-turn-manager.js +496 -0
- package/dist/apme/adapters/codex-turn-manager.js.map +1 -0
- package/dist/apme/adapters/openclaw-hook.d.ts +99 -0
- package/dist/apme/adapters/openclaw-hook.d.ts.map +1 -0
- package/dist/apme/adapters/openclaw-hook.js +234 -0
- package/dist/apme/adapters/openclaw-hook.js.map +1 -0
- package/dist/apme/adapters/opencode-hook.d.ts +56 -0
- package/dist/apme/adapters/opencode-hook.d.ts.map +1 -0
- package/dist/apme/adapters/opencode-hook.js +182 -0
- package/dist/apme/adapters/opencode-hook.js.map +1 -0
- package/dist/apme/adapters/timeline.d.ts.map +1 -1
- package/dist/apme/adapters/timeline.js +6 -1
- package/dist/apme/adapters/timeline.js.map +1 -1
- package/dist/apme/antigravity-transcript.d.ts +18 -0
- package/dist/apme/antigravity-transcript.d.ts.map +1 -0
- package/dist/apme/antigravity-transcript.js +94 -0
- package/dist/apme/antigravity-transcript.js.map +1 -0
- package/dist/apme/classify-turn.d.ts +13 -0
- package/dist/apme/classify-turn.d.ts.map +1 -0
- package/dist/apme/classify-turn.js +49 -0
- package/dist/apme/classify-turn.js.map +1 -0
- package/dist/apme/claude-transcript-reader.d.ts +10 -0
- package/dist/apme/claude-transcript-reader.d.ts.map +1 -1
- package/dist/apme/claude-transcript-reader.js +35 -0
- package/dist/apme/claude-transcript-reader.js.map +1 -1
- package/dist/apme/collector.d.ts +133 -6
- package/dist/apme/collector.d.ts.map +1 -1
- package/dist/apme/collector.js +471 -23
- package/dist/apme/collector.js.map +1 -1
- package/dist/apme/dashboard-html.d.ts.map +1 -1
- package/dist/apme/dashboard-html.js +117 -11
- package/dist/apme/dashboard-html.js.map +1 -1
- package/dist/apme/http.d.ts.map +1 -1
- package/dist/apme/http.js +52 -6
- package/dist/apme/http.js.map +1 -1
- package/dist/apme/index.d.ts +26 -5
- package/dist/apme/index.d.ts.map +1 -1
- package/dist/apme/index.js +146 -9
- package/dist/apme/index.js.map +1 -1
- package/dist/apme/judge-detect.d.ts +26 -0
- package/dist/apme/judge-detect.d.ts.map +1 -0
- package/dist/apme/judge-detect.js +69 -0
- package/dist/apme/judge-detect.js.map +1 -0
- package/dist/apme/pareto.d.ts +39 -0
- package/dist/apme/pareto.d.ts.map +1 -0
- package/dist/apme/pareto.js +59 -0
- package/dist/apme/pareto.js.map +1 -0
- package/dist/apme/recommend.d.ts +3 -0
- package/dist/apme/recommend.d.ts.map +1 -1
- package/dist/apme/recommend.js +43 -1
- package/dist/apme/recommend.js.map +1 -1
- package/dist/apme/runner.d.ts +99 -4
- package/dist/apme/runner.d.ts.map +1 -1
- package/dist/apme/runner.js +743 -72
- package/dist/apme/runner.js.map +1 -1
- package/dist/apme/sample-to-timeline.d.ts +26 -0
- package/dist/apme/sample-to-timeline.d.ts.map +1 -0
- package/dist/apme/sample-to-timeline.js +95 -0
- package/dist/apme/sample-to-timeline.js.map +1 -0
- package/dist/apme/scorers/index.d.ts +47 -0
- package/dist/apme/scorers/index.d.ts.map +1 -0
- package/dist/apme/scorers/index.js +96 -0
- package/dist/apme/scorers/index.js.map +1 -0
- package/dist/apme/settings.d.ts +17 -11
- package/dist/apme/settings.d.ts.map +1 -1
- package/dist/apme/settings.js +30 -9
- package/dist/apme/settings.js.map +1 -1
- package/dist/apme/store.d.ts +33 -1
- package/dist/apme/store.d.ts.map +1 -1
- package/dist/apme/store.js +334 -25
- package/dist/apme/store.js.map +1 -1
- package/dist/awaiting-overlay.d.ts +112 -0
- package/dist/awaiting-overlay.d.ts.map +1 -0
- package/dist/awaiting-overlay.js +179 -0
- package/dist/awaiting-overlay.js.map +1 -0
- package/dist/ble-sync-spawn.d.ts +63 -0
- package/dist/ble-sync-spawn.d.ts.map +1 -0
- package/dist/ble-sync-spawn.js +196 -0
- package/dist/ble-sync-spawn.js.map +1 -0
- package/dist/bridge-core.d.ts +34 -1
- package/dist/bridge-core.d.ts.map +1 -1
- package/dist/bridge-core.js +207 -24
- package/dist/bridge-core.js.map +1 -1
- package/dist/broadcast.d.ts +3 -0
- package/dist/broadcast.d.ts.map +1 -0
- package/dist/broadcast.js +122 -0
- package/dist/broadcast.js.map +1 -0
- package/dist/check-deps.d.ts.map +1 -1
- package/dist/check-deps.js +25 -9
- package/dist/check-deps.js.map +1 -1
- package/dist/claude-permission-rules.d.ts +55 -0
- package/dist/claude-permission-rules.d.ts.map +1 -0
- package/dist/claude-permission-rules.js +197 -0
- package/dist/claude-permission-rules.js.map +1 -0
- package/dist/cli.d.ts +15 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1030 -93
- package/dist/cli.js.map +1 -1
- package/dist/codex-auth.d.ts +21 -0
- package/dist/codex-auth.d.ts.map +1 -1
- package/dist/codex-auth.js +52 -1
- package/dist/codex-auth.js.map +1 -1
- package/dist/codex-output-parser.d.ts +8 -0
- package/dist/codex-output-parser.d.ts.map +1 -1
- package/dist/codex-output-parser.js +110 -25
- package/dist/codex-output-parser.js.map +1 -1
- package/dist/codex-rate-limits.d.ts +16 -0
- package/dist/codex-rate-limits.d.ts.map +1 -0
- package/dist/codex-rate-limits.js +197 -0
- package/dist/codex-rate-limits.js.map +1 -0
- package/dist/codex-rollout-response.d.ts +31 -0
- package/dist/codex-rollout-response.d.ts.map +1 -0
- package/dist/codex-rollout-response.js +135 -0
- package/dist/codex-rollout-response.js.map +1 -0
- package/dist/d200h/image-renderer.d.ts +4 -16
- package/dist/d200h/image-renderer.d.ts.map +1 -1
- package/dist/d200h/image-renderer.js +46 -212
- package/dist/d200h/image-renderer.js.map +1 -1
- package/dist/daemon-server.d.ts +85 -0
- package/dist/daemon-server.d.ts.map +1 -1
- package/dist/daemon-server.js +1975 -159
- package/dist/daemon-server.js.map +1 -1
- package/dist/daemon.js +15 -6
- package/dist/daemon.js.map +1 -1
- package/dist/display-dim.d.ts +9 -0
- package/dist/display-dim.d.ts.map +1 -0
- package/dist/display-dim.js +53 -0
- package/dist/display-dim.js.map +1 -0
- package/dist/display-monitor.d.ts +15 -2
- package/dist/display-monitor.d.ts.map +1 -1
- package/dist/display-monitor.js +104 -26
- package/dist/display-monitor.js.map +1 -1
- package/dist/esp32-serial.d.ts +190 -1
- package/dist/esp32-serial.d.ts.map +1 -1
- package/dist/esp32-serial.js +1090 -156
- package/dist/esp32-serial.js.map +1 -1
- package/dist/fallback-task-timeline.d.ts +42 -0
- package/dist/fallback-task-timeline.d.ts.map +1 -0
- package/dist/fallback-task-timeline.js +119 -0
- package/dist/fallback-task-timeline.js.map +1 -0
- package/dist/foundation-models-helper.d.ts +11 -0
- package/dist/foundation-models-helper.d.ts.map +1 -0
- package/dist/foundation-models-helper.js +241 -0
- package/dist/foundation-models-helper.js.map +1 -0
- package/dist/hook-migration.js +1 -1
- package/dist/hook-migration.js.map +1 -1
- package/dist/hook-server.d.ts +2 -3
- package/dist/hook-server.d.ts.map +1 -1
- package/dist/hook-server.js +23 -10
- package/dist/hook-server.js.map +1 -1
- package/dist/idotmatrix/idotmatrix-daemon-sync.d.ts +33 -0
- package/dist/idotmatrix/idotmatrix-daemon-sync.d.ts.map +1 -0
- package/dist/idotmatrix/idotmatrix-daemon-sync.js +164 -0
- package/dist/idotmatrix/idotmatrix-daemon-sync.js.map +1 -0
- package/dist/idotmatrix/idotmatrix-discover.d.ts +18 -0
- package/dist/idotmatrix/idotmatrix-discover.d.ts.map +1 -0
- package/dist/idotmatrix/idotmatrix-discover.js +85 -0
- package/dist/idotmatrix/idotmatrix-discover.js.map +1 -0
- package/dist/idotmatrix/idotmatrix-settings.d.ts +20 -0
- package/dist/idotmatrix/idotmatrix-settings.d.ts.map +1 -0
- package/dist/idotmatrix/idotmatrix-settings.js +57 -0
- package/dist/idotmatrix/idotmatrix-settings.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +217 -179
- package/dist/index.js.map +1 -1
- package/dist/log-stream.d.ts +15 -16
- package/dist/log-stream.d.ts.map +1 -1
- package/dist/log-stream.js +18 -96
- package/dist/log-stream.js.map +1 -1
- package/dist/logger.d.ts +3 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +18 -5
- package/dist/logger.js.map +1 -1
- package/dist/mdns.d.ts +17 -0
- package/dist/mdns.d.ts.map +1 -1
- package/dist/mdns.js +52 -18
- package/dist/mdns.js.map +1 -1
- package/dist/model-catalog.d.ts +1 -1
- package/dist/model-catalog.d.ts.map +1 -1
- package/dist/model-catalog.js +2 -4
- package/dist/model-catalog.js.map +1 -1
- package/dist/modules/adb-module.d.ts +1 -1
- package/dist/modules/adb-module.d.ts.map +1 -1
- package/dist/modules/adb-module.js +4 -3
- package/dist/modules/adb-module.js.map +1 -1
- package/dist/modules/broadcast-module.d.ts +17 -0
- package/dist/modules/broadcast-module.d.ts.map +1 -0
- package/dist/modules/broadcast-module.js +26 -0
- package/dist/modules/broadcast-module.js.map +1 -0
- package/dist/modules/d200h-module.d.ts +22 -0
- package/dist/modules/d200h-module.d.ts.map +1 -1
- package/dist/modules/d200h-module.js +200 -65
- package/dist/modules/d200h-module.js.map +1 -1
- package/dist/modules/idotmatrix-module.d.ts +9 -0
- package/dist/modules/idotmatrix-module.d.ts.map +1 -0
- package/dist/modules/idotmatrix-module.js +46 -0
- package/dist/modules/idotmatrix-module.js.map +1 -0
- package/dist/modules/index.d.ts +3 -1
- package/dist/modules/index.d.ts.map +1 -1
- package/dist/modules/index.js +9 -3
- package/dist/modules/index.js.map +1 -1
- package/dist/modules/pixoo-module.d.ts.map +1 -1
- package/dist/modules/pixoo-module.js +14 -4
- package/dist/modules/pixoo-module.js.map +1 -1
- package/dist/modules/serial-module.d.ts +4 -0
- package/dist/modules/serial-module.d.ts.map +1 -1
- package/dist/modules/serial-module.js +14 -12
- package/dist/modules/serial-module.js.map +1 -1
- package/dist/modules/timebox-module.d.ts +9 -0
- package/dist/modules/timebox-module.d.ts.map +1 -0
- package/dist/modules/timebox-module.js +46 -0
- package/dist/modules/timebox-module.js.map +1 -0
- package/dist/modules/trmnl-module.d.ts +38 -0
- package/dist/modules/trmnl-module.d.ts.map +1 -0
- package/dist/modules/trmnl-module.js +111 -0
- package/dist/modules/trmnl-module.js.map +1 -0
- package/dist/modules/types.d.ts +4 -2
- package/dist/modules/types.d.ts.map +1 -1
- package/dist/observed-steering.d.ts +93 -0
- package/dist/observed-steering.d.ts.map +1 -0
- package/dist/observed-steering.js +247 -0
- package/dist/observed-steering.js.map +1 -0
- package/dist/openclaw-session.d.ts +18 -0
- package/dist/openclaw-session.d.ts.map +1 -0
- package/dist/openclaw-session.js +34 -0
- package/dist/openclaw-session.js.map +1 -0
- package/dist/opencode-steering.d.ts +36 -0
- package/dist/opencode-steering.d.ts.map +1 -0
- package/dist/opencode-steering.js +84 -0
- package/dist/opencode-steering.js.map +1 -0
- package/dist/output-parser.d.ts +30 -0
- package/dist/output-parser.d.ts.map +1 -1
- package/dist/output-parser.js +172 -18
- package/dist/output-parser.js.map +1 -1
- package/dist/passive-observer.d.ts +32 -0
- package/dist/passive-observer.d.ts.map +1 -1
- package/dist/passive-observer.js +288 -49
- package/dist/passive-observer.js.map +1 -1
- package/dist/permission-resolver.d.ts +55 -0
- package/dist/permission-resolver.d.ts.map +1 -0
- package/dist/permission-resolver.js +112 -0
- package/dist/permission-resolver.js.map +1 -0
- package/dist/pixoo/micro-glyphs.d.ts +18 -0
- package/dist/pixoo/micro-glyphs.d.ts.map +1 -0
- package/dist/pixoo/micro-glyphs.js +143 -0
- package/dist/pixoo/micro-glyphs.js.map +1 -0
- package/dist/pixoo/official-dot-glyphs.generated.d.ts +8 -0
- package/dist/pixoo/official-dot-glyphs.generated.d.ts.map +1 -0
- package/dist/pixoo/official-dot-glyphs.generated.js +247 -0
- package/dist/pixoo/official-dot-glyphs.generated.js.map +1 -0
- package/dist/pixoo/pixoo-bridge.d.ts +16 -8
- package/dist/pixoo/pixoo-bridge.d.ts.map +1 -1
- package/dist/pixoo/pixoo-bridge.js +127 -35
- package/dist/pixoo/pixoo-bridge.js.map +1 -1
- package/dist/pixoo/pixoo-camera.d.ts +19 -3
- package/dist/pixoo/pixoo-camera.d.ts.map +1 -1
- package/dist/pixoo/pixoo-camera.js +62 -27
- package/dist/pixoo/pixoo-camera.js.map +1 -1
- package/dist/pixoo/pixoo-client.d.ts +13 -3
- package/dist/pixoo/pixoo-client.d.ts.map +1 -1
- package/dist/pixoo/pixoo-client.js +51 -22
- package/dist/pixoo/pixoo-client.js.map +1 -1
- package/dist/pixoo/pixoo-discover.d.ts +37 -0
- package/dist/pixoo/pixoo-discover.d.ts.map +1 -0
- package/dist/pixoo/pixoo-discover.js +105 -0
- package/dist/pixoo/pixoo-discover.js.map +1 -0
- package/dist/pixoo/pixoo-renderer.d.ts +27 -3
- package/dist/pixoo/pixoo-renderer.d.ts.map +1 -1
- package/dist/pixoo/pixoo-renderer.js +533 -135
- package/dist/pixoo/pixoo-renderer.js.map +1 -1
- package/dist/pixoo/pixoo-settings.d.ts +6 -0
- package/dist/pixoo/pixoo-settings.d.ts.map +1 -1
- package/dist/pixoo/pixoo-settings.js +9 -0
- package/dist/pixoo/pixoo-settings.js.map +1 -1
- package/dist/pixoo/pixoo-sprites.d.ts +84 -11
- package/dist/pixoo/pixoo-sprites.d.ts.map +1 -1
- package/dist/pixoo/pixoo-sprites.js +620 -209
- package/dist/pixoo/pixoo-sprites.js.map +1 -1
- package/dist/pty-manager.d.ts.map +1 -1
- package/dist/pty-manager.js +8 -2
- package/dist/pty-manager.js.map +1 -1
- package/dist/review-runner.d.ts +113 -0
- package/dist/review-runner.d.ts.map +1 -0
- package/dist/review-runner.js +428 -0
- package/dist/review-runner.js.map +1 -0
- package/dist/session-activity.d.ts +14 -0
- package/dist/session-activity.d.ts.map +1 -0
- package/dist/session-activity.js +160 -0
- package/dist/session-activity.js.map +1 -0
- package/dist/session-aggregator.d.ts +25 -0
- package/dist/session-aggregator.d.ts.map +1 -1
- package/dist/session-aggregator.js +48 -9
- package/dist/session-aggregator.js.map +1 -1
- package/dist/session-focus-relay.d.ts.map +1 -1
- package/dist/session-focus-relay.js +7 -1
- package/dist/session-focus-relay.js.map +1 -1
- package/dist/session-registry.d.ts +74 -3
- package/dist/session-registry.d.ts.map +1 -1
- package/dist/session-registry.js +140 -8
- package/dist/session-registry.js.map +1 -1
- package/dist/session-timeline-relay.d.ts.map +1 -1
- package/dist/session-timeline-relay.js +13 -4
- package/dist/session-timeline-relay.js.map +1 -1
- package/dist/session-transcript-timeline.d.ts +49 -0
- package/dist/session-transcript-timeline.d.ts.map +1 -0
- package/dist/session-transcript-timeline.js +276 -0
- package/dist/session-transcript-timeline.js.map +1 -0
- package/dist/state-machine.d.ts +6 -1
- package/dist/state-machine.d.ts.map +1 -1
- package/dist/state-machine.js +86 -28
- package/dist/state-machine.js.map +1 -1
- package/dist/timebox/timebox-daemon-sync.d.ts +19 -0
- package/dist/timebox/timebox-daemon-sync.d.ts.map +1 -0
- package/dist/timebox/timebox-daemon-sync.js +135 -0
- package/dist/timebox/timebox-daemon-sync.js.map +1 -0
- package/dist/timebox/timebox-discover.d.ts +19 -0
- package/dist/timebox/timebox-discover.d.ts.map +1 -0
- package/dist/timebox/timebox-discover.js +87 -0
- package/dist/timebox/timebox-discover.js.map +1 -0
- package/dist/timebox/timebox-settings.d.ts +32 -0
- package/dist/timebox/timebox-settings.d.ts.map +1 -0
- package/dist/timebox/timebox-settings.js +80 -0
- package/dist/timebox/timebox-settings.js.map +1 -0
- package/dist/timeline-store.d.ts +112 -3
- package/dist/timeline-store.d.ts.map +1 -1
- package/dist/timeline-store.js +460 -14
- package/dist/timeline-store.js.map +1 -1
- package/dist/timeline-summarizer.d.ts.map +1 -1
- package/dist/timeline-summarizer.js +29 -5
- package/dist/timeline-summarizer.js.map +1 -1
- package/dist/trmnl/byos-server.d.ts +39 -0
- package/dist/trmnl/byos-server.d.ts.map +1 -0
- package/dist/trmnl/byos-server.js +301 -0
- package/dist/trmnl/byos-server.js.map +1 -0
- package/dist/trmnl/frame-cache.d.ts +37 -0
- package/dist/trmnl/frame-cache.d.ts.map +1 -0
- package/dist/trmnl/frame-cache.js +157 -0
- package/dist/trmnl/frame-cache.js.map +1 -0
- package/dist/trmnl/image-renderer.d.ts +27 -0
- package/dist/trmnl/image-renderer.d.ts.map +1 -0
- package/dist/trmnl/image-renderer.js +235 -0
- package/dist/trmnl/image-renderer.js.map +1 -0
- package/dist/trmnl/trmnl-settings.d.ts +96 -0
- package/dist/trmnl/trmnl-settings.d.ts.map +1 -0
- package/dist/trmnl/trmnl-settings.js +177 -0
- package/dist/trmnl/trmnl-settings.js.map +1 -0
- package/dist/trmnl/trmnl-telemetry.d.ts +47 -0
- package/dist/trmnl/trmnl-telemetry.d.ts.map +1 -0
- package/dist/trmnl/trmnl-telemetry.js +56 -0
- package/dist/trmnl/trmnl-telemetry.js.map +1 -0
- package/dist/tui/ansi.d.ts +0 -4
- package/dist/tui/ansi.d.ts.map +1 -1
- package/dist/tui/ansi.js +14 -7
- package/dist/tui/ansi.js.map +1 -1
- package/dist/tui/dashboard.d.ts +1 -0
- package/dist/tui/dashboard.d.ts.map +1 -1
- package/dist/tui/dashboard.js +38 -11
- package/dist/tui/dashboard.js.map +1 -1
- package/dist/tui/renderer.d.ts +36 -0
- package/dist/tui/renderer.d.ts.map +1 -1
- package/dist/tui/renderer.js +355 -121
- package/dist/tui/renderer.js.map +1 -1
- package/dist/tui/terrarium.d.ts.map +1 -1
- package/dist/tui/terrarium.js +44 -51
- package/dist/tui/terrarium.js.map +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -2
- package/dist/types.js.map +1 -1
- package/dist/usage-api.d.ts.map +1 -1
- package/dist/usage-api.js +7 -1
- package/dist/usage-api.js.map +1 -1
- package/dist/usage-event.d.ts +10 -3
- package/dist/usage-event.d.ts.map +1 -1
- package/dist/usage-event.js +98 -13
- package/dist/usage-event.js.map +1 -1
- package/dist/utility-proxy.d.ts.map +1 -1
- package/dist/utility-proxy.js +8 -0
- package/dist/utility-proxy.js.map +1 -1
- package/dist/utils/project-name.d.ts +3 -0
- package/dist/utils/project-name.d.ts.map +1 -1
- package/dist/utils/project-name.js +44 -2
- package/dist/utils/project-name.js.map +1 -1
- package/dist/version-check.d.ts.map +1 -1
- package/dist/version-check.js +1 -17
- package/dist/version-check.js.map +1 -1
- package/dist/windows-service.d.ts +26 -0
- package/dist/windows-service.d.ts.map +1 -0
- package/dist/windows-service.js +145 -0
- package/dist/windows-service.js.map +1 -0
- package/dist/ws-server.d.ts +17 -3
- package/dist/ws-server.d.ts.map +1 -1
- package/dist/ws-server.js +78 -8
- package/dist/ws-server.js.map +1 -1
- package/fm-helper/AgentDeckFMHelper.swift +112 -0
- package/package.json +10 -4
- package/scripts/build-fm-helper.mjs +26 -0
- package/LICENSE +0 -21
- package/dist/apme/tuner.d.ts +0 -64
- package/dist/apme/tuner.d.ts.map +0 -1
- package/dist/apme/tuner.js +0 -297
- package/dist/apme/tuner.js.map +0 -1
package/dist/apme/index.js
CHANGED
|
@@ -13,43 +13,175 @@
|
|
|
13
13
|
import { writeFileSync } from 'fs';
|
|
14
14
|
import { join } from 'path';
|
|
15
15
|
import { homedir } from 'os';
|
|
16
|
-
import {
|
|
16
|
+
import { logError } from '../logger.js';
|
|
17
17
|
import { ApmeStore } from './store.js';
|
|
18
18
|
import { apmeDashboardHtml } from './dashboard-html.js';
|
|
19
19
|
import { ApmeCollector } from './collector.js';
|
|
20
20
|
import { ApmeRunner } from './runner.js';
|
|
21
|
-
import { ApmeTuner } from './tuner.js';
|
|
22
21
|
import { ApmeHwSampler } from './hw-sampler.js';
|
|
23
22
|
import { ApmeRecommender } from './recommend.js';
|
|
23
|
+
import { sampleEventToTimeline } from './sample-to-timeline.js';
|
|
24
|
+
import { formatDurationSec } from '@agentdeck/shared';
|
|
25
|
+
/** Task boundary rows read "<signal> · <N> turns · <duration>" — the turn
|
|
26
|
+
* count says what the boundary covered, the human duration replaces the
|
|
27
|
+
* raw "3672s" second counts. */
|
|
28
|
+
function taskEndRowText(signalLabel, turns, durationSec) {
|
|
29
|
+
const parts = [signalLabel];
|
|
30
|
+
if (turns && turns > 0)
|
|
31
|
+
parts.push(turns === 1 ? '1 turn' : `${turns} turns`);
|
|
32
|
+
parts.push(formatDurationSec(durationSec));
|
|
33
|
+
return parts.join(' · ');
|
|
34
|
+
}
|
|
24
35
|
let singleton = null;
|
|
25
|
-
/** Initialize the APME subsystem. Returns null if the SQLite store can't open.
|
|
26
|
-
|
|
36
|
+
/** Initialize the APME subsystem. Returns null if the SQLite store can't open.
|
|
37
|
+
* When null, the failure reason is logged at ERROR level — silent disable was
|
|
38
|
+
* the dominant cause of multi-day data outages observed in user telemetry. */
|
|
39
|
+
export async function initApme(dbPath, opts = {}) {
|
|
27
40
|
if (singleton)
|
|
28
41
|
return singleton;
|
|
29
42
|
const store = new ApmeStore(dbPath);
|
|
30
43
|
const ok = await store.init();
|
|
31
44
|
if (!ok) {
|
|
32
|
-
|
|
45
|
+
logError(`APME disabled — ${store.lastInitError ?? 'unknown init failure'}. Agent runs will not be measured.`);
|
|
33
46
|
return null;
|
|
34
47
|
}
|
|
35
48
|
const hwSampler = new ApmeHwSampler();
|
|
36
49
|
const collector = new ApmeCollector(store, hwSampler);
|
|
37
50
|
const runner = new ApmeRunner(store);
|
|
38
|
-
const tuner = new ApmeTuner(store);
|
|
39
51
|
const recommender = new ApmeRecommender(store);
|
|
40
|
-
singleton = { store, collector, runner,
|
|
52
|
+
singleton = { store, collector, runner, hwSampler, recommender };
|
|
53
|
+
const emitTimeline = opts.emitTimeline;
|
|
54
|
+
// Task headers are DEFERRED (collector emits `task_start` only once a task
|
|
55
|
+
// proves itself multi-turn). Track which task ids actually reached the
|
|
56
|
+
// timeline so the async judge re-emit (`onTaskEvaluated`, below) can skip
|
|
57
|
+
// unpromoted single-turn tasks — otherwise it would insert an orphan
|
|
58
|
+
// `task_end` with a score badge under no header. `onTaskOpened` fires at the
|
|
59
|
+
// deferred promotion moment, so membership here == "header is on the timeline".
|
|
60
|
+
const promotedTaskIds = new Set();
|
|
41
61
|
// Wire task-level judge: whenever the collector closes a task (TodoWrite
|
|
42
62
|
// all-completed / /clear / session_end), enqueue a task_rollup judge call.
|
|
43
63
|
// Kept here — not in the collector constructor — so the collector has no
|
|
44
64
|
// hard dependency on the runner.
|
|
45
|
-
collector.onTaskClosed = ({ taskId, runId, boundarySignal, taskCategory }) => {
|
|
65
|
+
collector.onTaskClosed = ({ taskId, runId, sessionId, agentType, projectName, startedAt, endedAt, boundarySignal, taskCategory, turns, timelineEmitted, }) => {
|
|
46
66
|
runner.enqueueTask({
|
|
47
67
|
runId,
|
|
48
68
|
taskId,
|
|
49
69
|
category: taskCategory ?? undefined,
|
|
50
70
|
boundarySignal,
|
|
51
71
|
});
|
|
72
|
+
// Gate the `task_end` row on the header having been emitted — an
|
|
73
|
+
// unpromoted single-turn task shows only its chat rows, never a bare
|
|
74
|
+
// "Task end" marker. The eval enqueue above runs regardless.
|
|
75
|
+
if (emitTimeline && timelineEmitted) {
|
|
76
|
+
const durationSec = Math.max(0, Math.round((endedAt - startedAt) / 1000));
|
|
77
|
+
const signalLabel = boundarySignal === 'todo_complete' ? 'TODO done'
|
|
78
|
+
: boundarySignal === 'clear' ? '/clear'
|
|
79
|
+
: boundarySignal === 'session_end' ? 'Session end'
|
|
80
|
+
: 'Task end';
|
|
81
|
+
emitTimeline({
|
|
82
|
+
ts: endedAt,
|
|
83
|
+
type: 'task_end',
|
|
84
|
+
raw: taskEndRowText(signalLabel, turns, durationSec),
|
|
85
|
+
agentType: agentType ?? undefined,
|
|
86
|
+
projectName: projectName ?? undefined,
|
|
87
|
+
sessionId,
|
|
88
|
+
runId,
|
|
89
|
+
taskId,
|
|
90
|
+
boundarySignal,
|
|
91
|
+
startedAt,
|
|
92
|
+
endedAt,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
52
95
|
};
|
|
96
|
+
// Wire the SessionSample → Timeline projection. When enabled, the timeline
|
|
97
|
+
// is a projection of the canonical sample (one row per typed trajectory
|
|
98
|
+
// event), replacing display-time grouping + the race-sensitive dedup window.
|
|
99
|
+
if (emitTimeline && opts.projectSampleTimeline) {
|
|
100
|
+
const emitProjected = opts.emitProjectedTimeline ?? emitTimeline;
|
|
101
|
+
collector.onSampleEvent = ({ event, sessionId, runId, taskId, agentType, projectName }) => {
|
|
102
|
+
const entry = sampleEventToTimeline(event, { sessionId, runId, taskId, agentType, projectName });
|
|
103
|
+
if (entry)
|
|
104
|
+
emitProjected(entry);
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
// Wire task-start emission. The runner has no opinion on opens — only the
|
|
108
|
+
// dashboard does — so we keep this strictly local to the timeline path.
|
|
109
|
+
if (emitTimeline) {
|
|
110
|
+
collector.onTaskOpened = ({ taskId, runId, sessionId, agentType, projectName, taskIndex, startedAt, }) => {
|
|
111
|
+
promotedTaskIds.add(taskId);
|
|
112
|
+
emitTimeline({
|
|
113
|
+
ts: startedAt,
|
|
114
|
+
type: 'task_start',
|
|
115
|
+
raw: `Task ${taskIndex + 1}`,
|
|
116
|
+
agentType: agentType ?? undefined,
|
|
117
|
+
projectName: projectName ?? undefined,
|
|
118
|
+
sessionId,
|
|
119
|
+
runId,
|
|
120
|
+
taskId,
|
|
121
|
+
startedAt,
|
|
122
|
+
});
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
// Wire the mid-task completion milestone. TodoWrite-all-completed is a
|
|
126
|
+
// non-segmenting soft hint (fires ~18% of the time on Claude Code v2.1), so
|
|
127
|
+
// it must not split the task — but when it DOES fire it is a strong "the
|
|
128
|
+
// agent declared this chunk done" signal, and long sessions otherwise show
|
|
129
|
+
// no completion marks until /clear or session_end.
|
|
130
|
+
if (emitTimeline) {
|
|
131
|
+
collector.onTaskMilestone = ({ taskId, runId, sessionId, agentType, projectName, todoCount, at, }) => {
|
|
132
|
+
emitTimeline({
|
|
133
|
+
ts: at,
|
|
134
|
+
type: 'task_milestone',
|
|
135
|
+
raw: todoCount ? `Todos done (${todoCount})` : 'Todos done',
|
|
136
|
+
agentType: agentType ?? undefined,
|
|
137
|
+
projectName: projectName ?? undefined,
|
|
138
|
+
sessionId,
|
|
139
|
+
runId,
|
|
140
|
+
taskId,
|
|
141
|
+
});
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
// Wire task-eval completion → re-emit `task_end` with score + outcome.
|
|
145
|
+
// The original `task_end` (above) fires synchronously on closeTask so the
|
|
146
|
+
// boundary is visible immediately; the judge runs async and may take
|
|
147
|
+
// 5-30 s. When it resolves, this listener emits a second `task_end` with
|
|
148
|
+
// the same `taskId`. Timeline stores upsert by (type='task_end', taskId)
|
|
149
|
+
// and merge the new score fields onto the existing row, so dashboard task
|
|
150
|
+
// headers get the score badge as soon as the judge returns.
|
|
151
|
+
if (emitTimeline) {
|
|
152
|
+
runner.onTaskEvaluated((e) => {
|
|
153
|
+
// Skip the score re-emit for tasks whose header never reached the
|
|
154
|
+
// timeline (single-turn Q&A). Without this the merge-or-insert
|
|
155
|
+
// timeline store would insert a fresh orphan `task_end` here. Consume
|
|
156
|
+
// the id so the set doesn't grow unbounded across a long-lived daemon.
|
|
157
|
+
if (!promotedTaskIds.delete(e.taskId))
|
|
158
|
+
return;
|
|
159
|
+
const durationSec = Math.max(0, Math.round((e.endedAt - e.startedAt) / 1000));
|
|
160
|
+
const signalLabel = e.boundarySignal === 'todo_complete' ? 'TODO done'
|
|
161
|
+
: e.boundarySignal === 'clear' ? '/clear'
|
|
162
|
+
: e.boundarySignal === 'session_end' ? 'Session end'
|
|
163
|
+
: e.boundarySignal === 'manual' ? 'Manual'
|
|
164
|
+
: e.boundarySignal === 'idle_gap' ? 'Idle gap'
|
|
165
|
+
: 'Task end';
|
|
166
|
+
emitTimeline({
|
|
167
|
+
ts: e.endedAt,
|
|
168
|
+
type: 'task_end',
|
|
169
|
+
raw: taskEndRowText(signalLabel, e.turns, durationSec),
|
|
170
|
+
agentType: e.agentType,
|
|
171
|
+
projectName: e.projectName,
|
|
172
|
+
sessionId: e.sessionId,
|
|
173
|
+
runId: e.runId,
|
|
174
|
+
taskId: e.taskId,
|
|
175
|
+
boundarySignal: e.boundarySignal,
|
|
176
|
+
startedAt: e.startedAt,
|
|
177
|
+
endedAt: e.endedAt,
|
|
178
|
+
taskScore: e.compositeScore ?? undefined,
|
|
179
|
+
taskOutcome: e.outcome,
|
|
180
|
+
taskCategory: e.taskCategory,
|
|
181
|
+
taskSummary: e.summary,
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
}
|
|
53
185
|
// Write dashboard HTML for Swift daemon to pick up.
|
|
54
186
|
try {
|
|
55
187
|
const dataDir = process.env.AGENTDECK_DATA_DIR || join(homedir(), '.agentdeck');
|
|
@@ -63,11 +195,16 @@ export async function initApme(dbPath) {
|
|
|
63
195
|
export function getApme() {
|
|
64
196
|
return singleton;
|
|
65
197
|
}
|
|
198
|
+
/** Phase 6 cutover switch (default OFF). Set `AGENTDECK_TIMELINE_PROJECTION=1`
|
|
199
|
+
* to make the timeline a projection of the canonical SessionSample. Read at
|
|
200
|
+
* daemon/session-bridge startup so it can be flipped without a recompile. */
|
|
201
|
+
export function isTimelineProjectionEnabled() {
|
|
202
|
+
return process.env.AGENTDECK_TIMELINE_PROJECTION === '1';
|
|
203
|
+
}
|
|
66
204
|
export { loadApmeConfig, shouldJudge, DEFAULT_APME_CONFIG } from './settings.js';
|
|
67
205
|
export { ApmeStore } from './store.js';
|
|
68
206
|
export { ApmeCollector } from './collector.js';
|
|
69
207
|
export { ApmeRunner } from './runner.js';
|
|
70
|
-
export { ApmeTuner } from './tuner.js';
|
|
71
208
|
export { ApmeHwSampler } from './hw-sampler.js';
|
|
72
209
|
export { ApmeRecommender } from './recommend.js';
|
|
73
210
|
export { classifyRun, classifyRunSmart, classifyWithLlm, classify, computeSignals, TASK_CATEGORIES } from './classifier.js';
|
package/dist/apme/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/apme/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/apme/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP-only detection of locally-running, de-facto-standard inference servers
|
|
3
|
+
* so onboarding + the REVIEW judge-setup guide can offer "use what you already
|
|
4
|
+
* have" instead of asking the user to configure an endpoint by hand.
|
|
5
|
+
*
|
|
6
|
+
* App Store safety: this is pure network I/O against loopback ports — NO
|
|
7
|
+
* subprocess, NO CLI probe (`ollama list` etc.). The macOS sandbox's
|
|
8
|
+
* `com.apple.security.network.client` covers loopback HTTP, so this runs
|
|
9
|
+
* unchanged in the signed App Store daemon. Mirror: apple ApmeJudgeDetect.swift.
|
|
10
|
+
*/
|
|
11
|
+
export interface DetectedProvider {
|
|
12
|
+
/** Stable key: 'ollama' | 'lmstudio' | 'mlx' | 'openai-generic'. */
|
|
13
|
+
provider: string;
|
|
14
|
+
label: string;
|
|
15
|
+
/** OpenAI-compatible base to store as apme.judge.endpoint. */
|
|
16
|
+
endpoint: string;
|
|
17
|
+
/** Chat model ids advertised by the server (first is a sensible default). */
|
|
18
|
+
models: string[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Probe the standard local endpoints concurrently. Returns only servers that
|
|
22
|
+
* are reachable AND advertise at least one usable chat model. De-duplicated by
|
|
23
|
+
* (provider, endpoint) so the two MLX ports don't both show when one answers.
|
|
24
|
+
*/
|
|
25
|
+
export declare function detectLocalJudgeProviders(timeoutMs?: number): Promise<DetectedProvider[]>;
|
|
26
|
+
//# sourceMappingURL=judge-detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"judge-detect.d.ts","sourceRoot":"","sources":["../../src/apme/judge-detect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AA2CD;;;;GAIG;AACH,wBAAsB,yBAAyB,CAAC,SAAS,SAAO,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAgB7F"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP-only detection of locally-running, de-facto-standard inference servers
|
|
3
|
+
* so onboarding + the REVIEW judge-setup guide can offer "use what you already
|
|
4
|
+
* have" instead of asking the user to configure an endpoint by hand.
|
|
5
|
+
*
|
|
6
|
+
* App Store safety: this is pure network I/O against loopback ports — NO
|
|
7
|
+
* subprocess, NO CLI probe (`ollama list` etc.). The macOS sandbox's
|
|
8
|
+
* `com.apple.security.network.client` covers loopback HTTP, so this runs
|
|
9
|
+
* unchanged in the signed App Store daemon. Mirror: apple ApmeJudgeDetect.swift.
|
|
10
|
+
*/
|
|
11
|
+
const CANDIDATES = [
|
|
12
|
+
{ provider: 'ollama', label: 'Ollama', base: 'http://127.0.0.1:11434', endpoint: 'http://127.0.0.1:11434/v1', tags: true },
|
|
13
|
+
{ provider: 'lmstudio', label: 'LM Studio', base: 'http://127.0.0.1:1234', endpoint: 'http://127.0.0.1:1234/v1' },
|
|
14
|
+
{ provider: 'mlx', label: 'Local MLX server', base: 'http://127.0.0.1:8800', endpoint: 'http://127.0.0.1:8800/v1' },
|
|
15
|
+
{ provider: 'mlx', label: 'Local MLX server', base: 'http://127.0.0.1:8080', endpoint: 'http://127.0.0.1:8080/v1' },
|
|
16
|
+
];
|
|
17
|
+
const NANO = 'nanollava';
|
|
18
|
+
async function modelsFor(c, timeoutMs) {
|
|
19
|
+
// Ollama's canonical list is /api/tags; every OpenAI-compatible server
|
|
20
|
+
// (LM Studio, MLX, vLLM, Ollama's compat shim) exposes /v1/models.
|
|
21
|
+
if (c.tags) {
|
|
22
|
+
try {
|
|
23
|
+
const r = await fetch(`${c.base}/api/tags`, { signal: AbortSignal.timeout(timeoutMs) }).catch(() => null);
|
|
24
|
+
if (r?.ok) {
|
|
25
|
+
const j = await r.json();
|
|
26
|
+
const names = (j.models ?? []).map((m) => m.name).filter((n) => !!n);
|
|
27
|
+
if (names.length)
|
|
28
|
+
return names;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch { /* fall through to /v1/models */ }
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
const r = await fetch(`${c.base}/v1/models`, { signal: AbortSignal.timeout(timeoutMs) }).catch(() => null);
|
|
35
|
+
if (r?.ok) {
|
|
36
|
+
const j = await r.json();
|
|
37
|
+
const ids = (j.data ?? []).map((m) => m.id).filter((id) => !!id && !id.toLowerCase().includes(NANO));
|
|
38
|
+
return ids; // empty array = reachable but no usable model
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch { /* unreachable */ }
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Probe the standard local endpoints concurrently. Returns only servers that
|
|
46
|
+
* are reachable AND advertise at least one usable chat model. De-duplicated by
|
|
47
|
+
* (provider, endpoint) so the two MLX ports don't both show when one answers.
|
|
48
|
+
*/
|
|
49
|
+
export async function detectLocalJudgeProviders(timeoutMs = 1200) {
|
|
50
|
+
const results = await Promise.all(CANDIDATES.map(async (c) => {
|
|
51
|
+
const models = await modelsFor(c, timeoutMs);
|
|
52
|
+
if (!models || models.length === 0)
|
|
53
|
+
return null;
|
|
54
|
+
return { provider: c.provider, label: c.label, endpoint: c.endpoint, models: models.slice(0, 12) };
|
|
55
|
+
}));
|
|
56
|
+
const seen = new Set();
|
|
57
|
+
const out = [];
|
|
58
|
+
for (const r of results) {
|
|
59
|
+
if (!r)
|
|
60
|
+
continue;
|
|
61
|
+
const key = `${r.provider}:${r.endpoint}`;
|
|
62
|
+
if (seen.has(key))
|
|
63
|
+
continue;
|
|
64
|
+
seen.add(key);
|
|
65
|
+
out.push(r);
|
|
66
|
+
}
|
|
67
|
+
return out;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=judge-detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"judge-detect.js","sourceRoot":"","sources":["../../src/apme/judge-detect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pareto frontier over (quality, cost) for model orchestration.
|
|
3
|
+
*
|
|
4
|
+
* A model is on the frontier if no other model dominates it — i.e. no other
|
|
5
|
+
* model is BOTH higher quality AND lower (or equal) cost per sample. Dominated
|
|
6
|
+
* models are strictly worse on both axes and should never be recommended; the
|
|
7
|
+
* frontier is the real menu of quality/cost tradeoffs.
|
|
8
|
+
*
|
|
9
|
+
* "Same quality, 40% cheaper" decisions fall straight out of this: walk the
|
|
10
|
+
* frontier from cheapest to best and pick the knee that fits the budget.
|
|
11
|
+
*
|
|
12
|
+
* Pure + synchronous + unit-testable. Input is the sample-granularity
|
|
13
|
+
* scorecard; output partitions candidates into frontier vs dominated.
|
|
14
|
+
*/
|
|
15
|
+
import type { ApmeSampleScorecardRow } from '@agentdeck/shared';
|
|
16
|
+
export interface ParetoPoint {
|
|
17
|
+
agentType: string;
|
|
18
|
+
modelId: string;
|
|
19
|
+
taskCategory: string | null;
|
|
20
|
+
/** Quality axis (avg composite, [0,1]). Higher is better. */
|
|
21
|
+
quality: number;
|
|
22
|
+
/** Cost axis: average USD per sample. Lower is better. */
|
|
23
|
+
costPerSample: number;
|
|
24
|
+
avgLatencyMs: number | null;
|
|
25
|
+
samples: number;
|
|
26
|
+
}
|
|
27
|
+
export interface ParetoResult {
|
|
28
|
+
frontier: ParetoPoint[];
|
|
29
|
+
dominated: ParetoPoint[];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Partition scorecard rows into the Pareto frontier and the dominated set.
|
|
33
|
+
* @param rows sample scorecard rows (optionally pre-filtered by category)
|
|
34
|
+
* @param minSamples ignore models with too little data to trust
|
|
35
|
+
*/
|
|
36
|
+
export declare function computePareto(rows: ApmeSampleScorecardRow[], minSamples?: number): ParetoResult;
|
|
37
|
+
/** Convenience: filter scorecard to a category before computing the frontier. */
|
|
38
|
+
export declare function paretoForCategory(rows: ApmeSampleScorecardRow[], category: string | null | undefined, minSamples?: number): ParetoResult;
|
|
39
|
+
//# sourceMappingURL=pareto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pareto.d.ts","sourceRoot":"","sources":["../../src/apme/pareto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAEhE,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,SAAS,EAAE,WAAW,EAAE,CAAC;CAC1B;AAsBD;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,sBAAsB,EAAE,EAC9B,UAAU,SAAI,GACb,YAAY,CAcd;AAED,iFAAiF;AACjF,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,sBAAsB,EAAE,EAC9B,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACnC,UAAU,SAAI,GACb,YAAY,CAGd"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pareto frontier over (quality, cost) for model orchestration.
|
|
3
|
+
*
|
|
4
|
+
* A model is on the frontier if no other model dominates it — i.e. no other
|
|
5
|
+
* model is BOTH higher quality AND lower (or equal) cost per sample. Dominated
|
|
6
|
+
* models are strictly worse on both axes and should never be recommended; the
|
|
7
|
+
* frontier is the real menu of quality/cost tradeoffs.
|
|
8
|
+
*
|
|
9
|
+
* "Same quality, 40% cheaper" decisions fall straight out of this: walk the
|
|
10
|
+
* frontier from cheapest to best and pick the knee that fits the budget.
|
|
11
|
+
*
|
|
12
|
+
* Pure + synchronous + unit-testable. Input is the sample-granularity
|
|
13
|
+
* scorecard; output partitions candidates into frontier vs dominated.
|
|
14
|
+
*/
|
|
15
|
+
function toPoint(r) {
|
|
16
|
+
return {
|
|
17
|
+
agentType: r.agentType,
|
|
18
|
+
modelId: r.modelId,
|
|
19
|
+
taskCategory: r.taskCategory,
|
|
20
|
+
quality: r.avgQuality ?? 0,
|
|
21
|
+
costPerSample: r.samples > 0 ? (r.totalCost ?? 0) / r.samples : 0,
|
|
22
|
+
avgLatencyMs: r.avgLatencyMs,
|
|
23
|
+
samples: r.samples,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/** True when `b` dominates `a`: at least as good on both axes and strictly
|
|
27
|
+
* better on at least one (higher quality, lower cost). */
|
|
28
|
+
function dominates(b, a) {
|
|
29
|
+
const betterOrEqual = b.quality >= a.quality && b.costPerSample <= a.costPerSample;
|
|
30
|
+
const strictlyBetter = b.quality > a.quality || b.costPerSample < a.costPerSample;
|
|
31
|
+
return betterOrEqual && strictlyBetter;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Partition scorecard rows into the Pareto frontier and the dominated set.
|
|
35
|
+
* @param rows sample scorecard rows (optionally pre-filtered by category)
|
|
36
|
+
* @param minSamples ignore models with too little data to trust
|
|
37
|
+
*/
|
|
38
|
+
export function computePareto(rows, minSamples = 3) {
|
|
39
|
+
const points = rows
|
|
40
|
+
.filter((r) => r.samples >= minSamples && (r.avgQuality ?? 0) > 0)
|
|
41
|
+
.map(toPoint);
|
|
42
|
+
const frontier = [];
|
|
43
|
+
const dominated = [];
|
|
44
|
+
for (const a of points) {
|
|
45
|
+
if (points.some((b) => b !== a && dominates(b, a)))
|
|
46
|
+
dominated.push(a);
|
|
47
|
+
else
|
|
48
|
+
frontier.push(a);
|
|
49
|
+
}
|
|
50
|
+
// Frontier sorted cheapest → most expensive (the natural tradeoff curve).
|
|
51
|
+
frontier.sort((x, y) => x.costPerSample - y.costPerSample || y.quality - x.quality);
|
|
52
|
+
return { frontier, dominated };
|
|
53
|
+
}
|
|
54
|
+
/** Convenience: filter scorecard to a category before computing the frontier. */
|
|
55
|
+
export function paretoForCategory(rows, category, minSamples = 3) {
|
|
56
|
+
const scoped = category ? rows.filter((r) => r.taskCategory === category) : rows;
|
|
57
|
+
return computePareto(scoped, minSamples);
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=pareto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pareto.js","sourceRoot":"","sources":["../../src/apme/pareto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAqBH,SAAS,OAAO,CAAC,CAAyB;IACxC,OAAO;QACL,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,YAAY,EAAE,CAAC,CAAC,YAAY;QAC5B,OAAO,EAAE,CAAC,CAAC,UAAU,IAAI,CAAC;QAC1B,aAAa,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACjE,YAAY,EAAE,CAAC,CAAC,YAAY;QAC5B,OAAO,EAAE,CAAC,CAAC,OAAO;KACnB,CAAC;AACJ,CAAC;AAED;2DAC2D;AAC3D,SAAS,SAAS,CAAC,CAAc,EAAE,CAAc;IAC/C,MAAM,aAAa,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,aAAa,CAAC;IACnF,MAAM,cAAc,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,aAAa,CAAC;IAClF,OAAO,aAAa,IAAI,cAAc,CAAC;AACzC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,IAA8B,EAC9B,UAAU,GAAG,CAAC;IAEd,MAAM,MAAM,GAAG,IAAI;SAChB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,UAAU,IAAI,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;SACjE,GAAG,CAAC,OAAO,CAAC,CAAC;IAEhB,MAAM,QAAQ,GAAkB,EAAE,CAAC;IACnC,MAAM,SAAS,GAAkB,EAAE,CAAC;IACpC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;;YACjE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC;IACD,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;IACpF,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AACjC,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,iBAAiB,CAC/B,IAA8B,EAC9B,QAAmC,EACnC,UAAU,GAAG,CAAC;IAEd,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACjF,OAAO,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAC3C,CAAC"}
|
package/dist/apme/recommend.d.ts
CHANGED
|
@@ -28,5 +28,8 @@ export declare class ApmeRecommender {
|
|
|
28
28
|
private readonly store;
|
|
29
29
|
constructor(store: ApmeStore);
|
|
30
30
|
recommend(input: RecommendInput): RecommendCandidate[];
|
|
31
|
+
/** Legacy run-level recommendation (v_model_scorecard). Used when no
|
|
32
|
+
* sample-granularity composite scores exist yet. */
|
|
33
|
+
private recommendFromRuns;
|
|
31
34
|
}
|
|
32
35
|
//# sourceMappingURL=recommend.d.ts.map
|
|
@@ -1 +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;
|
|
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;AAG5C,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;IAgDtD;yDACqD;IACrD,OAAO,CAAC,iBAAiB;CAyB1B"}
|
package/dist/apme/recommend.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* confidence. v1 uses the v_model_scorecard view; v2 (stretch) layers in
|
|
7
7
|
* task-similarity via local embeddings.
|
|
8
8
|
*/
|
|
9
|
+
import { paretoForCategory } from './pareto.js';
|
|
9
10
|
export class ApmeRecommender {
|
|
10
11
|
store;
|
|
11
12
|
constructor(store) {
|
|
@@ -14,6 +15,48 @@ export class ApmeRecommender {
|
|
|
14
15
|
recommend(input) {
|
|
15
16
|
if (!this.store.enabled)
|
|
16
17
|
return [];
|
|
18
|
+
// Work at sample granularity (the canonical eval unit) and restrict to the
|
|
19
|
+
// Pareto frontier — dominated models (strictly worse on quality AND cost)
|
|
20
|
+
// are never worth recommending. This is the model-orchestration payoff:
|
|
21
|
+
// the menu is the quality/cost tradeoff curve, not a flat ranking.
|
|
22
|
+
const scorecard = this.store.sampleScorecard();
|
|
23
|
+
let { frontier } = paretoForCategory(scorecard, input.taskKind);
|
|
24
|
+
// Fall back to the whole frontier if the category has too little data.
|
|
25
|
+
if (frontier.length === 0)
|
|
26
|
+
frontier = paretoForCategory(scorecard, undefined).frontier;
|
|
27
|
+
// Fall back to the run-level scorecard when no sample-granularity data has
|
|
28
|
+
// accumulated yet (legacy runs, or before the first task judge resolves).
|
|
29
|
+
if (frontier.length === 0)
|
|
30
|
+
return this.recommendFromRuns(input);
|
|
31
|
+
let candidates = frontier;
|
|
32
|
+
if (input.availableModels) {
|
|
33
|
+
candidates = candidates.filter((p) => input.availableModels.includes(p.modelId));
|
|
34
|
+
}
|
|
35
|
+
if (input.budgetUsd !== undefined) {
|
|
36
|
+
candidates = candidates.filter((p) => p.costPerSample <= input.budgetUsd);
|
|
37
|
+
}
|
|
38
|
+
if (input.latencyBudgetMs !== undefined) {
|
|
39
|
+
candidates = candidates.filter((p) => p.avgLatencyMs == null || p.avgLatencyMs <= input.latencyBudgetMs);
|
|
40
|
+
}
|
|
41
|
+
candidates = [...candidates].sort((a, b) => {
|
|
42
|
+
// Budget-conscious or local-preferring → cheapest first; else best quality.
|
|
43
|
+
if (input.preferLocal || (input.budgetUsd !== undefined && input.budgetUsd < 5)) {
|
|
44
|
+
return a.costPerSample - b.costPerSample || b.quality - a.quality;
|
|
45
|
+
}
|
|
46
|
+
return b.quality - a.quality || a.costPerSample - b.costPerSample;
|
|
47
|
+
});
|
|
48
|
+
return candidates.slice(0, 3).map((p) => ({
|
|
49
|
+
modelId: p.modelId,
|
|
50
|
+
agentType: p.agentType,
|
|
51
|
+
expectedScore: p.quality,
|
|
52
|
+
expectedCostUsd: p.costPerSample,
|
|
53
|
+
confidence: Math.min(1, p.samples / 20),
|
|
54
|
+
rationale: `${p.samples} samples, avg ${(p.quality * 100).toFixed(0)}%, $${p.costPerSample.toFixed(4)}/sample${p.avgLatencyMs != null ? `, ${Math.round(p.avgLatencyMs)}ms` : ''} — on the cost/quality frontier`,
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
/** Legacy run-level recommendation (v_model_scorecard). Used when no
|
|
58
|
+
* sample-granularity composite scores exist yet. */
|
|
59
|
+
recommendFromRuns(input) {
|
|
17
60
|
const rows = this.store.scorecard();
|
|
18
61
|
const filtered = input.availableModels
|
|
19
62
|
? rows.filter((r) => input.availableModels.includes(r.modelId))
|
|
@@ -21,7 +64,6 @@ export class ApmeRecommender {
|
|
|
21
64
|
return filtered
|
|
22
65
|
.filter((r) => r.runs >= 3 && (r.avgOverall ?? 0) > 0)
|
|
23
66
|
.sort((a, b) => {
|
|
24
|
-
// Prefer cost-per-quality if budget is tight, otherwise raw quality.
|
|
25
67
|
if (input.budgetUsd !== undefined && input.budgetUsd < 5) {
|
|
26
68
|
return (a.costPerQuality ?? Infinity) - (b.costPerQuality ?? Infinity);
|
|
27
69
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recommend.js","sourceRoot":"","sources":["../../src/apme/recommend.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"recommend.js","sourceRoot":"","sources":["../../src/apme/recommend.ts"],"names":[],"mappings":"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"}
|