@agentdeck/bridge 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/fm-helper/agentdeck-fm-helper +0 -0
- package/dist/apme/collector.d.ts.map +1 -1
- package/dist/apme/collector.js +5 -2
- package/dist/apme/collector.js.map +1 -1
- package/dist/apme/runner.d.ts +11 -0
- package/dist/apme/runner.d.ts.map +1 -1
- package/dist/apme/runner.js +60 -4
- package/dist/apme/runner.js.map +1 -1
- package/dist/apme/settings.d.ts +10 -0
- package/dist/apme/settings.d.ts.map +1 -1
- package/dist/apme/settings.js +14 -0
- package/dist/apme/settings.js.map +1 -1
- package/dist/awaiting-overlay.d.ts +44 -10
- package/dist/awaiting-overlay.d.ts.map +1 -1
- package/dist/awaiting-overlay.js +96 -28
- package/dist/awaiting-overlay.js.map +1 -1
- package/dist/bridge-core.d.ts +10 -0
- package/dist/bridge-core.d.ts.map +1 -1
- package/dist/bridge-core.js +47 -12
- package/dist/bridge-core.js.map +1 -1
- package/dist/card-feed.d.ts +107 -0
- package/dist/card-feed.d.ts.map +1 -0
- package/dist/card-feed.js +277 -0
- package/dist/card-feed.js.map +1 -0
- package/dist/card-modules.d.ts +87 -0
- package/dist/card-modules.d.ts.map +1 -0
- package/dist/card-modules.js +179 -0
- package/dist/card-modules.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +232 -69
- package/dist/cli.js.map +1 -1
- package/dist/daemon-server.d.ts.map +1 -1
- package/dist/daemon-server.js +1008 -47
- package/dist/daemon-server.js.map +1 -1
- package/dist/daemon-ws-client.d.ts +2 -1
- package/dist/daemon-ws-client.d.ts.map +1 -1
- package/dist/daemon-ws-client.js +2 -1
- package/dist/daemon-ws-client.js.map +1 -1
- package/dist/daemon.js +1 -1
- package/dist/device-photo.d.ts +86 -0
- package/dist/device-photo.d.ts.map +1 -0
- package/dist/device-photo.js +200 -0
- package/dist/device-photo.js.map +1 -0
- package/dist/device-voice-reply.d.ts +124 -0
- package/dist/device-voice-reply.d.ts.map +1 -0
- package/dist/device-voice-reply.js +236 -0
- package/dist/device-voice-reply.js.map +1 -0
- package/dist/device-voice.d.ts +56 -0
- package/dist/device-voice.d.ts.map +1 -0
- package/dist/device-voice.js +134 -0
- package/dist/device-voice.js.map +1 -0
- package/dist/esp32-serial.d.ts +40 -0
- package/dist/esp32-serial.d.ts.map +1 -1
- package/dist/esp32-serial.js +109 -13
- package/dist/esp32-serial.js.map +1 -1
- package/dist/foundation-models-helper.d.ts +30 -0
- package/dist/foundation-models-helper.d.ts.map +1 -1
- package/dist/foundation-models-helper.js +45 -0
- package/dist/foundation-models-helper.js.map +1 -1
- package/dist/idotmatrix/idotmatrix-daemon-sync.d.ts.map +1 -1
- package/dist/idotmatrix/idotmatrix-daemon-sync.js +5 -18
- package/dist/idotmatrix/idotmatrix-daemon-sync.js.map +1 -1
- package/dist/idotmatrix/idotmatrix-discover.d.ts.map +1 -1
- package/dist/idotmatrix/idotmatrix-discover.js +6 -14
- package/dist/idotmatrix/idotmatrix-discover.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/mdns.d.ts +11 -0
- package/dist/mdns.d.ts.map +1 -1
- package/dist/mdns.js +13 -0
- package/dist/mdns.js.map +1 -1
- package/dist/observed-inject.d.ts +119 -0
- package/dist/observed-inject.d.ts.map +1 -0
- package/dist/observed-inject.js +405 -0
- package/dist/observed-inject.js.map +1 -0
- package/dist/passive-observer.d.ts +14 -0
- package/dist/passive-observer.d.ts.map +1 -1
- package/dist/passive-observer.js +35 -5
- package/dist/passive-observer.js.map +1 -1
- package/dist/peripheral-mapping.d.ts +65 -0
- package/dist/peripheral-mapping.d.ts.map +1 -0
- package/dist/peripheral-mapping.js +115 -0
- package/dist/peripheral-mapping.js.map +1 -0
- package/dist/python-ble-runtime.d.ts +62 -0
- package/dist/python-ble-runtime.d.ts.map +1 -0
- package/dist/python-ble-runtime.js +215 -0
- package/dist/python-ble-runtime.js.map +1 -0
- package/dist/session-aggregator.d.ts +4 -1
- package/dist/session-aggregator.d.ts.map +1 -1
- package/dist/session-aggregator.js +5 -5
- package/dist/session-aggregator.js.map +1 -1
- package/dist/session-id-resolve.d.ts +17 -0
- package/dist/session-id-resolve.d.ts.map +1 -0
- package/dist/session-id-resolve.js +35 -0
- package/dist/session-id-resolve.js.map +1 -0
- package/dist/session-transcript-timeline.d.ts +7 -0
- package/dist/session-transcript-timeline.d.ts.map +1 -1
- package/dist/session-transcript-timeline.js +16 -6
- package/dist/session-transcript-timeline.js.map +1 -1
- package/dist/timebox/timebox-daemon-sync.d.ts.map +1 -1
- package/dist/timebox/timebox-daemon-sync.js +5 -20
- package/dist/timebox/timebox-daemon-sync.js.map +1 -1
- package/dist/timebox/timebox-discover.d.ts.map +1 -1
- package/dist/timebox/timebox-discover.js +6 -15
- package/dist/timebox/timebox-discover.js.map +1 -1
- package/dist/timeline-store.js +2 -2
- package/dist/timeline-store.js.map +1 -1
- package/dist/usage-event.d.ts.map +1 -1
- package/dist/usage-event.js +14 -7
- package/dist/usage-event.js.map +1 -1
- package/dist/voice.d.ts +13 -10
- package/dist/voice.d.ts.map +1 -1
- package/dist/voice.js +26 -272
- package/dist/voice.js.map +1 -1
- package/dist/ws-server.d.ts +14 -0
- package/dist/ws-server.d.ts.map +1 -1
- package/dist/ws-server.js +66 -1
- package/dist/ws-server.js.map +1 -1
- package/fm-helper/AgentDeckFMHelper.swift +303 -0
- package/package.json +8 -4
- package/python/requirements-ble.txt +5 -0
- package/src/idotmatrix/brightness.py +40 -0
- package/src/idotmatrix/scan.py +35 -0
- package/src/idotmatrix/sync.py +400 -0
- package/src/pysync/matrix_sync_common.py +89 -0
- package/src/timebox/scan_ble.py +52 -0
- package/src/timebox/sync_ble.py +394 -0
- package/dist/d200h/hid-protocol.d.ts +0 -62
- package/dist/d200h/hid-protocol.d.ts.map +0 -1
- package/dist/d200h/hid-protocol.js +0 -124
- package/dist/d200h/hid-protocol.js.map +0 -1
- package/dist/d200h/image-renderer.d.ts +0 -24
- package/dist/d200h/image-renderer.d.ts.map +0 -1
- package/dist/d200h/image-renderer.js +0 -321
- package/dist/d200h/image-renderer.js.map +0 -1
- package/dist/hook-migration.d.ts +0 -2
- package/dist/hook-migration.d.ts.map +0 -1
- package/dist/hook-migration.js +0 -104
- package/dist/hook-migration.js.map +0 -1
- package/dist/modules/d200h-module.d.ts +0 -65
- package/dist/modules/d200h-module.d.ts.map +0 -1
- package/dist/modules/d200h-module.js +0 -495
- package/dist/modules/d200h-module.js.map +0 -1
- package/dist/modules/d200h-renderer.d.ts +0 -7
- package/dist/modules/d200h-renderer.d.ts.map +0 -1
- package/dist/modules/d200h-renderer.js +0 -321
- package/dist/modules/d200h-renderer.js.map +0 -1
- package/dist/modules/trmnl-module.d.ts +0 -38
- package/dist/modules/trmnl-module.d.ts.map +0 -1
- package/dist/modules/trmnl-module.js +0 -111
- package/dist/modules/trmnl-module.js.map +0 -1
- package/dist/trmnl/byos-server.d.ts +0 -39
- package/dist/trmnl/byos-server.d.ts.map +0 -1
- package/dist/trmnl/byos-server.js +0 -301
- package/dist/trmnl/byos-server.js.map +0 -1
- package/dist/trmnl/frame-cache.d.ts +0 -37
- package/dist/trmnl/frame-cache.d.ts.map +0 -1
- package/dist/trmnl/frame-cache.js +0 -157
- package/dist/trmnl/frame-cache.js.map +0 -1
- package/dist/trmnl/image-renderer.d.ts +0 -27
- package/dist/trmnl/image-renderer.d.ts.map +0 -1
- package/dist/trmnl/image-renderer.js +0 -235
- package/dist/trmnl/image-renderer.js.map +0 -1
- package/dist/trmnl/trmnl-settings.d.ts +0 -96
- package/dist/trmnl/trmnl-settings.d.ts.map +0 -1
- package/dist/trmnl/trmnl-settings.js +0 -177
- package/dist/trmnl/trmnl-settings.js.map +0 -1
- package/dist/trmnl/trmnl-telemetry.d.ts +0 -47
- package/dist/trmnl/trmnl-telemetry.d.ts.map +0 -1
- package/dist/trmnl/trmnl-telemetry.js +0 -56
- package/dist/trmnl/trmnl-telemetry.js.map +0 -1
- package/dist/whisper-server-manager.d.ts +0 -19
- package/dist/whisper-server-manager.d.ts.map +0 -1
- package/dist/whisper-server-manager.js +0 -171
- package/dist/whisper-server-manager.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon-ws-client.d.ts","sourceRoot":"","sources":["../src/daemon-ws-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AASH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,oBAAoB,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,uBAAuB,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,cAAc;IASvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;IAC3B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;IAC7B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;IAxBhC,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAS;gBAGR,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,YAAA,EAClB,WAAW,CAAC,EAAE,MAAM,YAAA;IACrC;;;;;;;;;;;OAWG;IACc,YAAY,CAAC,GAAE,MAAM,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,aAAA;IAG9E;;;;OAIG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAUxC,kCAAkC;IAClC,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"daemon-ws-client.d.ts","sourceRoot":"","sources":["../src/daemon-ws-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AASH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,oBAAoB,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,uBAAuB,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,cAAc;IASvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;IAC3B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;IAC7B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;IAxBhC,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAS;gBAGR,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,YAAA,EAClB,WAAW,CAAC,EAAE,MAAM,YAAA;IACrC;;;;;;;;;;;OAWG;IACc,YAAY,CAAC,GAAE,MAAM,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,aAAA;IAG9E;;;;OAIG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAUxC,kCAAkC;IAClC,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI;IAejG,qBAAqB;IACrB,KAAK,IAAI,IAAI;IAcb,IAAI,WAAW,IAAI,OAAO,CAEzB;YAIa,SAAS;IA4DvB,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,iBAAiB;CAS1B"}
|
package/dist/daemon-ws-client.js
CHANGED
|
@@ -64,7 +64,7 @@ export class DaemonWsClient {
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
/** Push state update to daemon */
|
|
67
|
-
pushState(state, modelName, effortLevel) {
|
|
67
|
+
pushState(state, modelName, effortLevel, permissionMode) {
|
|
68
68
|
if (!this.ws || this.ws.readyState !== WebSocket.OPEN)
|
|
69
69
|
return;
|
|
70
70
|
const msg = {
|
|
@@ -73,6 +73,7 @@ export class DaemonWsClient {
|
|
|
73
73
|
state,
|
|
74
74
|
modelName,
|
|
75
75
|
effortLevel,
|
|
76
|
+
permissionMode,
|
|
76
77
|
projectName: this.projectName,
|
|
77
78
|
agentType: this.agentType,
|
|
78
79
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon-ws-client.js","sourceRoot":"","sources":["../src/daemon-ws-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,SAAS,MAAM,IAAI,CAAC;AAC3B,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,MAAM,GAAG,GAAG,gBAAgB,CAAC;AAC7B,MAAM,cAAc,GAAG,IAAI,CAAC;AAC5B,MAAM,aAAa,GAAG,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"daemon-ws-client.js","sourceRoot":"","sources":["../src/daemon-ws-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,SAAS,MAAM,IAAI,CAAC;AAC3B,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,MAAM,GAAG,GAAG,gBAAgB,CAAC;AAC7B,MAAM,cAAc,GAAG,IAAI,CAAC;AAC5B,MAAM,aAAa,GAAG,KAAK,CAAC;AAqB5B,MAAM,OAAO,cAAc;IASN;IACA;IACA;IACA;IAaA;IAxBX,EAAE,GAAqB,IAAI,CAAC;IAC5B,UAAU,GAAkB,IAAI,CAAC;IACjC,cAAc,GAAyC,IAAI,CAAC;IAC5D,cAAc,GAAG,cAAc,CAAC;IAChC,MAAM,GAAG,KAAK,CAAC;IACf,UAAU,GAAG,KAAK,CAAC;IAE3B,YACmB,SAAiB,EACjB,WAAmB,EACnB,SAAkB,EAClB,WAAoB;IACrC;;;;;;;;;;;OAWG;IACc,YAA2D;QAhB3D,cAAS,GAAT,SAAS,CAAQ;QACjB,gBAAW,GAAX,WAAW,CAAQ;QACnB,cAAS,GAAT,SAAS,CAAS;QAClB,gBAAW,GAAX,WAAW,CAAS;QAapB,iBAAY,GAAZ,YAAY,CAA+C;IAC3E,CAAC;IAEJ;;;;OAIG;IACH,OAAO,CAAC,UAAyB;QAC/B,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;YAC7B,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;QACxB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,kCAAkC;IAClC,SAAS,CAAC,KAAa,EAAE,SAAkB,EAAE,WAAoB,EAAE,cAAuB;QACxF,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI;YAAE,OAAO;QAC9D,MAAM,GAAG,GAAqB;YAC5B,IAAI,EAAE,oBAAoB;YAC1B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,KAAK;YACL,SAAS;YACT,WAAW;YACX,cAAc;YACd,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC;QACF,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IACpC,CAAC;IAED,qBAAqB;IACrB,KAAK;QACH,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAClC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;QACD,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACZ,IAAI,CAAC,EAAE,CAAC,kBAAkB,EAAE,CAAC;YAC7B,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;QACjB,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;IAC1B,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,EAAE,EAAE,UAAU,KAAK,SAAS,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC;IACnE,CAAC;IAED,sBAAsB;IAEd,KAAK,CAAC,SAAS;QACrB,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,IAAI,QAAuB,CAAC;YAC5B,IAAI,CAAC;gBACH,QAAQ,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;YACvC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,KAAK,CAAC,GAAG,EAAE,uBAAuB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACtF,QAAQ,GAAG,IAAI,CAAC;YAClB,CAAC;YACD,IAAI,IAAI,CAAC,MAAM;gBAAE,OAAO;YACxB,IAAI,QAAQ,IAAI,IAAI,IAAI,QAAQ,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;gBACrD,KAAK,CAAC,GAAG,EAAE,wBAAwB,IAAI,CAAC,UAAU,IAAI,MAAM,MAAM,QAAQ,EAAE,CAAC,CAAC;gBAC9E,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC;YAC7B,CAAC;QACH,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACzB,OAAO;QACT,CAAC;QACD,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACZ,IAAI,CAAC,EAAE,CAAC,kBAAkB,EAAE,CAAC;YAC7B,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;QAClB,CAAC;QAED,MAAM,GAAG,GAAG,kBAAkB,IAAI,CAAC,UAAU,EAAE,CAAC;QAChD,KAAK,CAAC,GAAG,EAAE,2BAA2B,GAAG,EAAE,CAAC,CAAC;QAE7C,IAAI,CAAC,EAAE,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;QAE7B,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;YACtB,KAAK,CAAC,GAAG,EAAE,uBAAuB,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;YACrD,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;YACrC,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACvB,KAAK,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;YAC/B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;YACxB,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC3B,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YAC1B,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACvC,oCAAoC;QACtC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE;YAC7B,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;gBACxC,IAAI,GAAG,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;oBACpC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;oBACvB,KAAK,CAAC,GAAG,EAAE,2BAA2B,CAAC,CAAC;gBAC1C,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,oCAAoC;YACtC,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,YAAY;QAClB,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI;YAAE,OAAO;QAC9D,MAAM,GAAG,GAAwB;YAC/B,IAAI,EAAE,uBAAuB;YAC7B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,IAAI,EAAE,IAAI,CAAC,WAAW;YACtB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,WAAW,EAAE,IAAI,CAAC,WAAW;SAC9B,CAAC;QACF,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IACpC,CAAC;IAEO,iBAAiB;QACvB,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,cAAc;YAAE,OAAO;QAC/C,KAAK,CAAC,GAAG,EAAE,mBAAmB,IAAI,CAAC,cAAc,IAAI,CAAC,CAAC;QACvD,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC,GAAG,EAAE;YACpC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC3B,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;QACxB,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QACxB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,GAAG,GAAG,EAAE,aAAa,CAAC,CAAC;IAC3E,CAAC;CACF"}
|
package/dist/daemon.js
CHANGED
|
@@ -17,7 +17,7 @@ const program = new Command();
|
|
|
17
17
|
program
|
|
18
18
|
.name('agentdeck')
|
|
19
19
|
.description('AgentDeck daemon (legacy entry point — use `agentdeck daemon` instead)')
|
|
20
|
-
.version('1.0.
|
|
20
|
+
.version('1.0.4');
|
|
21
21
|
program
|
|
22
22
|
.command('start', { isDefault: true })
|
|
23
23
|
.description('Start monitoring daemon')
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Device-sourced photos: a board captures a JPEG (T-Display-S3-Pro rear
|
|
3
|
+
* camera) and the daemon turns it into a prompt for the session the board was
|
|
4
|
+
* pointing at — "show-and-tell" for coding agents: snap a whiteboard, an app
|
|
5
|
+
* screen, an error dialog, and the agent gets a file path it can read.
|
|
6
|
+
*
|
|
7
|
+
* Wire shape (per WS connection), mirroring device-voice:
|
|
8
|
+
* {"type":"photo_begin","format":"jpeg","width":…,"height":…,"sessionId":…}
|
|
9
|
+
* <binary frames: raw JPEG bytes>
|
|
10
|
+
* {"type":"photo_end","bytes":…,"cancel":false}
|
|
11
|
+
* Serial transport wraps the same bytes base64 in `photo_chunk` lines.
|
|
12
|
+
*
|
|
13
|
+
* Binary frames carry no envelope, so they are attributed to whichever socket
|
|
14
|
+
* has an open capture — hence the per-connection state here. A connection may
|
|
15
|
+
* hold an open voice utterance OR an open photo, never both; the daemon's
|
|
16
|
+
* onBinary router offers the frame to each collector in turn.
|
|
17
|
+
*
|
|
18
|
+
* Unlike a voice WAV (deleted after transcription), the JPEG must outlive this
|
|
19
|
+
* module: the prompt references the path and the agent reads it seconds or
|
|
20
|
+
* minutes later. Photos land under <dataDir>/photos with a small retention
|
|
21
|
+
* sweep instead of a cleanup callback.
|
|
22
|
+
*/
|
|
23
|
+
export interface PhotoCapture {
|
|
24
|
+
sessionId: string;
|
|
25
|
+
board: string;
|
|
26
|
+
format: string;
|
|
27
|
+
width: number;
|
|
28
|
+
height: number;
|
|
29
|
+
chunks: Buffer[];
|
|
30
|
+
bytes: number;
|
|
31
|
+
startedAt: number;
|
|
32
|
+
truncated: boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface PhotoCaptureResult {
|
|
35
|
+
sessionId: string;
|
|
36
|
+
board: string;
|
|
37
|
+
path: string;
|
|
38
|
+
bytes: number;
|
|
39
|
+
width: number;
|
|
40
|
+
height: number;
|
|
41
|
+
truncated: boolean;
|
|
42
|
+
}
|
|
43
|
+
export declare function defaultPhotoDir(): string;
|
|
44
|
+
/** Drop the oldest files beyond the retention count. Best-effort. */
|
|
45
|
+
export declare function prunePhotoDir(dir: string, retain?: number): void;
|
|
46
|
+
/**
|
|
47
|
+
* Per-connection photo assembly. One instance per daemon; connections are
|
|
48
|
+
* keyed by whatever opaque handle the server uses for a socket (WS object or
|
|
49
|
+
* serial port string), exactly like DeviceVoiceCollector.
|
|
50
|
+
*/
|
|
51
|
+
export declare class DevicePhotoCollector {
|
|
52
|
+
private photoDir;
|
|
53
|
+
private open;
|
|
54
|
+
constructor(photoDir?: string);
|
|
55
|
+
begin(conn: unknown, msg: Record<string, unknown>): void;
|
|
56
|
+
/** True while this connection has an open capture. */
|
|
57
|
+
isOpen(conn: unknown): boolean;
|
|
58
|
+
/** Returns false when no capture is open — the caller should offer the frame
|
|
59
|
+
* to the next collector. */
|
|
60
|
+
append(conn: unknown, data: Buffer): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Finish the capture: write the JPEG under the photo dir and return its
|
|
63
|
+
* path. Returns null when cancelled, empty, truncated, or nothing was open.
|
|
64
|
+
*/
|
|
65
|
+
end(conn: unknown, msg: Record<string, unknown>): PhotoCaptureResult | null;
|
|
66
|
+
/**
|
|
67
|
+
* Save a photo that arrived whole (HTTP POST body) rather than assembled
|
|
68
|
+
* from chunks. Same directory, retention and result shape as end().
|
|
69
|
+
*/
|
|
70
|
+
saveDirect(jpeg: Buffer, meta: {
|
|
71
|
+
board: string;
|
|
72
|
+
sessionId: string;
|
|
73
|
+
width: number;
|
|
74
|
+
height: number;
|
|
75
|
+
}): PhotoCaptureResult;
|
|
76
|
+
/** Drop a capture whose socket died mid-stream. */
|
|
77
|
+
abandon(conn: unknown): void;
|
|
78
|
+
/**
|
|
79
|
+
* Reap captures whose photo_end never arrived. Returns the reaped
|
|
80
|
+
* connections so the caller can tell each board its shutter press died —
|
|
81
|
+
* a silently expired capture left the strip showing "sending" forever.
|
|
82
|
+
*/
|
|
83
|
+
sweep(now?: number): unknown[];
|
|
84
|
+
get openCount(): number;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=device-photo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-photo.d.ts","sourceRoot":"","sources":["../src/device-photo.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAeH,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,qEAAqE;AACrE,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,SAAe,GAAG,IAAI,CActE;AAED;;;;GAIG;AACH,qBAAa,oBAAoB;IAGnB,OAAO,CAAC,QAAQ;IAF5B,OAAO,CAAC,IAAI,CAAoC;gBAE5B,QAAQ,GAAE,MAA0B;IAExD,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAgBxD,sDAAsD;IACtD,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;IAI9B;iCAC6B;IAC7B,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAe5C;;;OAGG;IACH,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,kBAAkB,GAAG,IAAI;IAyC3E;;;OAGG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;QAC7B,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;KACjE,GAAG,kBAAkB;IAkBtB,mDAAmD;IACnD,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAI5B;;;;OAIG;IACH,KAAK,CAAC,GAAG,SAAa,GAAG,OAAO,EAAE;IAYlC,IAAI,SAAS,IAAI,MAAM,CAEtB;CACF"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Device-sourced photos: a board captures a JPEG (T-Display-S3-Pro rear
|
|
3
|
+
* camera) and the daemon turns it into a prompt for the session the board was
|
|
4
|
+
* pointing at — "show-and-tell" for coding agents: snap a whiteboard, an app
|
|
5
|
+
* screen, an error dialog, and the agent gets a file path it can read.
|
|
6
|
+
*
|
|
7
|
+
* Wire shape (per WS connection), mirroring device-voice:
|
|
8
|
+
* {"type":"photo_begin","format":"jpeg","width":…,"height":…,"sessionId":…}
|
|
9
|
+
* <binary frames: raw JPEG bytes>
|
|
10
|
+
* {"type":"photo_end","bytes":…,"cancel":false}
|
|
11
|
+
* Serial transport wraps the same bytes base64 in `photo_chunk` lines.
|
|
12
|
+
*
|
|
13
|
+
* Binary frames carry no envelope, so they are attributed to whichever socket
|
|
14
|
+
* has an open capture — hence the per-connection state here. A connection may
|
|
15
|
+
* hold an open voice utterance OR an open photo, never both; the daemon's
|
|
16
|
+
* onBinary router offers the frame to each collector in turn.
|
|
17
|
+
*
|
|
18
|
+
* Unlike a voice WAV (deleted after transcription), the JPEG must outlive this
|
|
19
|
+
* module: the prompt references the path and the agent reads it seconds or
|
|
20
|
+
* minutes later. Photos land under <dataDir>/photos with a small retention
|
|
21
|
+
* sweep instead of a cleanup callback.
|
|
22
|
+
*/
|
|
23
|
+
import { mkdirSync, writeFileSync, readdirSync, statSync, rmSync } from 'fs';
|
|
24
|
+
import { homedir } from 'os';
|
|
25
|
+
import { join } from 'path';
|
|
26
|
+
import { debug } from './logger.js';
|
|
27
|
+
/** Refuse to buffer more than one plausible photo. VGA-class JPEGs are tens of
|
|
28
|
+
* KB; a 5 MP OV5640 shield tops out around 1–2 MB. */
|
|
29
|
+
const MAX_PHOTO_BYTES = 4 * 1024 * 1024;
|
|
30
|
+
/** A capture whose photo_end never arrives (board reboot, WiFi drop). */
|
|
31
|
+
const CAPTURE_TTL_MS = 60_000;
|
|
32
|
+
/** Keep this many photos; older ones are pruned on each save. */
|
|
33
|
+
const RETAIN_COUNT = 40;
|
|
34
|
+
export function defaultPhotoDir() {
|
|
35
|
+
return join(process.env.AGENTDECK_DATA_DIR || join(homedir(), '.agentdeck'), 'photos');
|
|
36
|
+
}
|
|
37
|
+
/** Drop the oldest files beyond the retention count. Best-effort. */
|
|
38
|
+
export function prunePhotoDir(dir, retain = RETAIN_COUNT) {
|
|
39
|
+
try {
|
|
40
|
+
const files = readdirSync(dir)
|
|
41
|
+
.filter((f) => f.endsWith('.jpg'))
|
|
42
|
+
.map((f) => {
|
|
43
|
+
const p = join(dir, f);
|
|
44
|
+
try {
|
|
45
|
+
return { p, mtime: statSync(p).mtimeMs };
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
.filter((x) => x !== null)
|
|
52
|
+
.sort((a, b) => b.mtime - a.mtime);
|
|
53
|
+
for (const f of files.slice(retain)) {
|
|
54
|
+
try {
|
|
55
|
+
rmSync(f.p, { force: true });
|
|
56
|
+
}
|
|
57
|
+
catch { /* best effort */ }
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch { /* dir missing — nothing to prune */ }
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Per-connection photo assembly. One instance per daemon; connections are
|
|
64
|
+
* keyed by whatever opaque handle the server uses for a socket (WS object or
|
|
65
|
+
* serial port string), exactly like DeviceVoiceCollector.
|
|
66
|
+
*/
|
|
67
|
+
export class DevicePhotoCollector {
|
|
68
|
+
photoDir;
|
|
69
|
+
open = new Map();
|
|
70
|
+
constructor(photoDir = defaultPhotoDir()) {
|
|
71
|
+
this.photoDir = photoDir;
|
|
72
|
+
}
|
|
73
|
+
begin(conn, msg) {
|
|
74
|
+
this.open.set(conn, {
|
|
75
|
+
sessionId: typeof msg.sessionId === 'string' ? msg.sessionId : '',
|
|
76
|
+
board: typeof msg.board === 'string' ? msg.board : 'esp32',
|
|
77
|
+
format: typeof msg.format === 'string' && msg.format ? msg.format : 'jpeg',
|
|
78
|
+
width: typeof msg.width === 'number' ? msg.width : 0,
|
|
79
|
+
height: typeof msg.height === 'number' ? msg.height : 0,
|
|
80
|
+
chunks: [],
|
|
81
|
+
bytes: 0,
|
|
82
|
+
startedAt: Date.now(),
|
|
83
|
+
truncated: false,
|
|
84
|
+
});
|
|
85
|
+
debug('photo', `capture begin (${String(msg.width ?? '?')}x${String(msg.height ?? '?')}, `
|
|
86
|
+
+ `session ${String(msg.sessionId ?? '').slice(0, 20)})`);
|
|
87
|
+
}
|
|
88
|
+
/** True while this connection has an open capture. */
|
|
89
|
+
isOpen(conn) {
|
|
90
|
+
return this.open.has(conn);
|
|
91
|
+
}
|
|
92
|
+
/** Returns false when no capture is open — the caller should offer the frame
|
|
93
|
+
* to the next collector. */
|
|
94
|
+
append(conn, data) {
|
|
95
|
+
const c = this.open.get(conn);
|
|
96
|
+
if (!c)
|
|
97
|
+
return false;
|
|
98
|
+
if (c.bytes + data.length > MAX_PHOTO_BYTES) {
|
|
99
|
+
// A truncated JPEG is undecodable (unlike truncated PCM), so mark it and
|
|
100
|
+
// let end() refuse — but keep consuming frames so they don't leak into
|
|
101
|
+
// another collector.
|
|
102
|
+
c.truncated = true;
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
c.chunks.push(Buffer.from(data));
|
|
106
|
+
c.bytes += data.length;
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Finish the capture: write the JPEG under the photo dir and return its
|
|
111
|
+
* path. Returns null when cancelled, empty, truncated, or nothing was open.
|
|
112
|
+
*/
|
|
113
|
+
end(conn, msg) {
|
|
114
|
+
const c = this.open.get(conn);
|
|
115
|
+
this.open.delete(conn);
|
|
116
|
+
if (!c)
|
|
117
|
+
return null;
|
|
118
|
+
if (msg.cancel === true) {
|
|
119
|
+
debug('photo', 'capture cancelled by device');
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
if (c.bytes === 0) {
|
|
123
|
+
debug('photo', 'capture empty — nothing received');
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
if (c.truncated) {
|
|
127
|
+
debug('photo', `capture exceeded ${MAX_PHOTO_BYTES} bytes — dropped`);
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
const claimed = typeof msg.bytes === 'number' ? msg.bytes : undefined;
|
|
131
|
+
if (claimed !== undefined && claimed !== c.bytes) {
|
|
132
|
+
// Frame loss over a flaky link produces a corrupt JPEG; better an
|
|
133
|
+
// explicit failure the board can show than a garbage image prompt.
|
|
134
|
+
debug('photo', `byte mismatch: board sent ${claimed}, received ${c.bytes} — dropped`);
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
const jpeg = Buffer.concat(c.chunks);
|
|
138
|
+
mkdirSync(this.photoDir, { recursive: true });
|
|
139
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
|
|
140
|
+
const path = join(this.photoDir, `${stamp}-${c.board}.jpg`);
|
|
141
|
+
writeFileSync(path, jpeg);
|
|
142
|
+
prunePhotoDir(this.photoDir);
|
|
143
|
+
debug('photo', `capture end: ${c.bytes} bytes → ${path}`);
|
|
144
|
+
return {
|
|
145
|
+
sessionId: c.sessionId,
|
|
146
|
+
board: c.board,
|
|
147
|
+
path,
|
|
148
|
+
bytes: c.bytes,
|
|
149
|
+
width: c.width,
|
|
150
|
+
height: c.height,
|
|
151
|
+
truncated: c.truncated,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Save a photo that arrived whole (HTTP POST body) rather than assembled
|
|
156
|
+
* from chunks. Same directory, retention and result shape as end().
|
|
157
|
+
*/
|
|
158
|
+
saveDirect(jpeg, meta) {
|
|
159
|
+
mkdirSync(this.photoDir, { recursive: true });
|
|
160
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
|
|
161
|
+
const path = join(this.photoDir, `${stamp}-${meta.board}.jpg`);
|
|
162
|
+
writeFileSync(path, jpeg);
|
|
163
|
+
prunePhotoDir(this.photoDir);
|
|
164
|
+
debug('photo', `direct upload: ${jpeg.length} bytes → ${path}`);
|
|
165
|
+
return {
|
|
166
|
+
sessionId: meta.sessionId,
|
|
167
|
+
board: meta.board,
|
|
168
|
+
path,
|
|
169
|
+
bytes: jpeg.length,
|
|
170
|
+
width: meta.width,
|
|
171
|
+
height: meta.height,
|
|
172
|
+
truncated: false,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
/** Drop a capture whose socket died mid-stream. */
|
|
176
|
+
abandon(conn) {
|
|
177
|
+
if (this.open.delete(conn))
|
|
178
|
+
debug('photo', 'capture abandoned (socket closed)');
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Reap captures whose photo_end never arrived. Returns the reaped
|
|
182
|
+
* connections so the caller can tell each board its shutter press died —
|
|
183
|
+
* a silently expired capture left the strip showing "sending" forever.
|
|
184
|
+
*/
|
|
185
|
+
sweep(now = Date.now()) {
|
|
186
|
+
const expired = [];
|
|
187
|
+
for (const [conn, c] of this.open) {
|
|
188
|
+
if (now - c.startedAt > CAPTURE_TTL_MS) {
|
|
189
|
+
this.open.delete(conn);
|
|
190
|
+
expired.push(conn);
|
|
191
|
+
debug('photo', `capture expired without photo_end (${c.bytes} bytes buffered)`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return expired;
|
|
195
|
+
}
|
|
196
|
+
get openCount() {
|
|
197
|
+
return this.open.size;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=device-photo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-photo.js","sourceRoot":"","sources":["../src/device-photo.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spoken replies back to the board that asked the question.
|
|
3
|
+
*
|
|
4
|
+
* The mic half of the voice round trip (device → daemon → session) ends with
|
|
5
|
+
* text arriving in a terminal. This is the other half: when the session that
|
|
6
|
+
* was dictated to finishes its turn, the reply is synthesized on the host and
|
|
7
|
+
* streamed to that board's own amplifier. The host's speakers are the wrong
|
|
8
|
+
* output here by construction — the reason to hold a battery-powered board is
|
|
9
|
+
* that you walked away from the desk.
|
|
10
|
+
*
|
|
11
|
+
* Shape of the exchange (WS only; the serial transport has no binary framing):
|
|
12
|
+
* daemon → board {"type":"audio_play_begin","sampleRate":16000,"text":"…"}
|
|
13
|
+
* daemon → board binary frames of PCM16LE
|
|
14
|
+
* daemon → board {"type":"audio_play_end"}
|
|
15
|
+
*
|
|
16
|
+
* The board cannot buffer a whole reply, so frames are paced at roughly
|
|
17
|
+
* playback speed. Sending as fast as the socket allows would overrun a ring
|
|
18
|
+
* buffer measured in seconds and cost the tail of every long answer.
|
|
19
|
+
*/
|
|
20
|
+
export interface ReplySink {
|
|
21
|
+
/** Send a JSON control frame. */
|
|
22
|
+
send(data: string): void;
|
|
23
|
+
/** Send one binary PCM frame. */
|
|
24
|
+
sendBinary(data: Buffer): void;
|
|
25
|
+
/** False once the socket is gone — streaming stops rather than piling up. */
|
|
26
|
+
isOpen(): boolean;
|
|
27
|
+
/** Capability strings the board advertised in device_info. */
|
|
28
|
+
capabilities(): string[];
|
|
29
|
+
/** Short transport label for logs, e.g. `serial:/dev/cu.usbmodem…` or `ws`. */
|
|
30
|
+
describe(): string;
|
|
31
|
+
/**
|
|
32
|
+
* Stable identity of the physical board behind this transport — NOT of the
|
|
33
|
+
* socket. A board is routinely reachable over both USB serial and WiFi, and
|
|
34
|
+
* it drops the WebSocket when serial becomes primary, so the transport a
|
|
35
|
+
* dictation arrived on may be gone by the time the reply exists. The reply
|
|
36
|
+
* follows the board.
|
|
37
|
+
*/
|
|
38
|
+
deviceKey(): string;
|
|
39
|
+
}
|
|
40
|
+
export interface ArmedReply {
|
|
41
|
+
sessionId: string;
|
|
42
|
+
armedAt: number;
|
|
43
|
+
}
|
|
44
|
+
/** PCM16 mono frame size. 1 KB = 32 ms at 16 kHz — small enough that a dropped
|
|
45
|
+
* frame is inaudible, large enough that framing overhead stays negligible. */
|
|
46
|
+
export declare const PCM_FRAME_BYTES = 1024;
|
|
47
|
+
/** A spoken reply past this is a monologue, not an answer. Truncated at a
|
|
48
|
+
* sentence boundary when one is near the cap. */
|
|
49
|
+
export declare const MAX_SPOKEN_CHARS = 700;
|
|
50
|
+
/**
|
|
51
|
+
* How long an arming survives *without the session making progress*. Measured
|
|
52
|
+
* from the last sign of work, not from the dictation: a question that kicks off
|
|
53
|
+
* half an hour of tool calls still deserves its answer read out, while a session
|
|
54
|
+
* that went quiet has moved on and speaking then is worse than silence.
|
|
55
|
+
*/
|
|
56
|
+
export declare const REPLY_ARM_TTL_MS: number;
|
|
57
|
+
/**
|
|
58
|
+
* Strip the parts of an assistant reply that make no sense read aloud (code
|
|
59
|
+
* fences, markdown scaffolding, bare URLs) and cap the length. Returns an empty
|
|
60
|
+
* string when nothing speakable is left — a reply that was only a diff should
|
|
61
|
+
* play nothing rather than spell out punctuation.
|
|
62
|
+
*/
|
|
63
|
+
export declare function speakableReply(raw: string, maxChars?: number): string;
|
|
64
|
+
/**
|
|
65
|
+
* Extract PCM samples from a canonical RIFF/WAVE file by walking the chunk
|
|
66
|
+
* list. Fixed-offset slicing at byte 44 is wrong for any file carrying a LIST
|
|
67
|
+
* or fact chunk, and would emit metadata as audio.
|
|
68
|
+
*/
|
|
69
|
+
export declare function pcmFromWav(wav: Buffer): {
|
|
70
|
+
pcm: Buffer;
|
|
71
|
+
sampleRate: number;
|
|
72
|
+
} | null;
|
|
73
|
+
/** Split PCM into fixed-size frames; the last one may be short. */
|
|
74
|
+
export declare function pcmFrames(pcm: Buffer, frameBytes?: number): Buffer[];
|
|
75
|
+
/**
|
|
76
|
+
* Tracks which board is waiting to hear the answer to which session, and
|
|
77
|
+
* streams the audio when it arrives.
|
|
78
|
+
*/
|
|
79
|
+
export declare class DeviceVoiceReplyRouter {
|
|
80
|
+
private readonly now;
|
|
81
|
+
private readonly sleep;
|
|
82
|
+
/** Current live transport for a board, when its original one has gone. */
|
|
83
|
+
private readonly resolveLive;
|
|
84
|
+
private armed;
|
|
85
|
+
private streaming;
|
|
86
|
+
constructor(now?: () => number, sleep?: (ms: number) => Promise<void>,
|
|
87
|
+
/** Current live transport for a board, when its original one has gone. */
|
|
88
|
+
resolveLive?: (deviceKey: string) => ReplySink | null);
|
|
89
|
+
/**
|
|
90
|
+
* Remember that this board dictated into this session and should hear the
|
|
91
|
+
* reply. Only boards advertising an amplifier are armed — streaming audio at
|
|
92
|
+
* a board that cannot play it wastes the link and, worse, makes the feature
|
|
93
|
+
* look broken on the boards that can.
|
|
94
|
+
*/
|
|
95
|
+
arm(sink: ReplySink, sessionId: string): boolean;
|
|
96
|
+
disarm(sink: ReplySink): void;
|
|
97
|
+
/**
|
|
98
|
+
* Mark these sessions as still working, so a long turn does not age out
|
|
99
|
+
* mid-flight. Called with whatever the daemon currently considers active.
|
|
100
|
+
*/
|
|
101
|
+
refresh(activeSessionIds: readonly string[]): void;
|
|
102
|
+
/**
|
|
103
|
+
* Drop armings that have gone stale. Deliberately does NOT evict on a closed
|
|
104
|
+
* transport: a board's link can blink between the dictation and the end of the
|
|
105
|
+
* turn — a serial connection gets recycled, a WebSocket reconnects — and
|
|
106
|
+
* dropping the arming then loses the reply permanently for a device that is
|
|
107
|
+
* about to be reachable again. Liveness is checked where it matters, at the
|
|
108
|
+
* moment of streaming.
|
|
109
|
+
*/
|
|
110
|
+
sweep(): void;
|
|
111
|
+
/** How many armings are outstanding — for diagnostics only. */
|
|
112
|
+
armedCount(): number;
|
|
113
|
+
/** Transport labels of everything currently armed, for diagnostics. */
|
|
114
|
+
describeArmed(): string;
|
|
115
|
+
/** Boards currently waiting on this session's reply. */
|
|
116
|
+
targetsFor(sessionId: string): ReplySink[];
|
|
117
|
+
/**
|
|
118
|
+
* Stream one already-synthesized WAV to a board. Consumes the arming, so a
|
|
119
|
+
* single dictation yields a single spoken reply rather than narrating every
|
|
120
|
+
* subsequent turn of that session.
|
|
121
|
+
*/
|
|
122
|
+
stream(armedSink: ReplySink, wav: Buffer, spokenText: string): Promise<boolean>;
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=device-voice-reply.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-voice-reply.d.ts","sourceRoot":"","sources":["../src/device-voice-reply.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,MAAM,WAAW,SAAS;IACxB,iCAAiC;IACjC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,iCAAiC;IACjC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,6EAA6E;IAC7E,MAAM,IAAI,OAAO,CAAC;IAClB,8DAA8D;IAC9D,YAAY,IAAI,MAAM,EAAE,CAAC;IACzB,+EAA+E;IAC/E,QAAQ,IAAI,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,SAAS,IAAI,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;+EAC+E;AAC/E,eAAO,MAAM,eAAe,OAAO,CAAC;AAEpC;kDACkD;AAClD,eAAO,MAAM,gBAAgB,MAAM,CAAC;AAEpC;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,QAAiB,CAAC;AAE/C;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,SAAmB,GAAG,MAAM,CAwB/E;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAqBlF;AAED,mEAAmE;AACnE,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,SAAkB,GAAG,MAAM,EAAE,CAM7E;AAED;;;GAGG;AACH,qBAAa,sBAAsB;IAK/B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAEtB,0EAA0E;IAC1E,OAAO,CAAC,QAAQ,CAAC,WAAW;IAR9B,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,SAAS,CAAwB;gBAGtB,GAAG,GAAE,MAAM,MAAyB,EACpC,KAAK,GAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CACL;IAC/C,0EAA0E;IACzD,WAAW,GAAE,CAAC,SAAS,EAAE,MAAM,KAAK,SAAS,GAAG,IAAiB;IAGpF;;;;;OAKG;IACH,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAUhD,MAAM,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAI7B;;;OAGG;IACH,OAAO,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI;IASlD;;;;;;;OAOG;IACH,KAAK,IAAI,IAAI;IAOb,+DAA+D;IAC/D,UAAU,IAAI,MAAM;IAIpB,uEAAuE;IACvE,aAAa,IAAI,MAAM;IAKvB,wDAAwD;IACxD,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE;IAU1C;;;;OAIG;IACG,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAqCtF"}
|