@glassly/engine 0.3.2-dev.566 → 0.3.2-dev.574
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/README.md +1 -1
- package/build/engine.d.ts +1 -1
- package/build/engine.d.ts.map +1 -1
- package/build/engine.js +3 -3
- package/build/engine.js.map +1 -1
- package/build/facades/dev.d.ts +2 -2
- package/build/facades/dev.d.ts.map +1 -1
- package/build/facades/dev.js +2 -2
- package/build/facades/dev.js.map +1 -1
- package/build/facades/reports.js +2 -2
- package/build/facades/reports.js.map +1 -1
- package/build/facades/session.d.ts +1 -1
- package/build/facades/session.js +2 -2
- package/build/facades/session.js.map +1 -1
- package/build/generated/releaseMetadata.js +3 -3
- package/build/generated/releaseMetadata.js.map +1 -1
- package/build/index.d.ts +1 -1
- package/build/index.js +1 -1
- package/build/index.js.map +1 -1
- package/build/runtime/bootstrap.d.ts +2 -2
- package/build/runtime/bootstrap.d.ts.map +1 -1
- package/build/runtime/bootstrap.js.map +1 -1
- package/build/services/CloudAudioSubscriptionSync.d.ts +2 -2
- package/build/services/CloudAudioSubscriptionSync.js +2 -2
- package/build/services/CloudAudioSubscriptionSync.js.map +1 -1
- package/build/services/CloudClientService.d.ts +2 -2
- package/build/services/CloudClientService.d.ts.map +1 -1
- package/build/services/CloudClientService.js +4 -4
- package/build/services/CloudClientService.js.map +1 -1
- package/build/services/CloudTranscriptE2EMetrics.d.ts +2 -2
- package/build/services/CloudTranscriptE2EMetrics.d.ts.map +1 -1
- package/build/services/CloudTranscriptE2EMetrics.js +3 -3
- package/build/services/CloudTranscriptE2EMetrics.js.map +1 -1
- package/build/services/LocalMiniappRuntime.d.ts +1 -1
- package/build/services/LocalMiniappRuntime.js +3 -3
- package/build/services/LocalMiniappRuntime.js.map +1 -1
- package/build/services/PhonePhotoCoordinator.d.ts +1 -1
- package/build/services/PhonePhotoCoordinator.js +4 -4
- package/build/services/PhonePhotoCoordinator.js.map +1 -1
- package/build/services/PhoneStreamCoordinator.d.ts +1 -1
- package/build/services/PhoneStreamCoordinator.js +1 -1
- package/build/services/PhoneStreamCoordinator.js.map +1 -1
- package/build/services/SupportProfileSync.d.ts +1 -1
- package/build/services/SupportProfileSync.js +2 -2
- package/build/services/SupportProfileSync.js.map +1 -1
- package/build/services/cloudStreamApi.d.ts +2 -2
- package/build/services/cloudStreamApi.js +2 -2
- package/build/services/cloudStreamApi.js.map +1 -1
- package/build/services/soniox/SonioxRealtimeClient.d.ts +2 -2
- package/build/services/soniox/SonioxRealtimeClient.js +2 -2
- package/build/services/soniox/SonioxRealtimeClient.js.map +1 -1
- package/build/services/soniox/SonioxTokenAssembler.d.ts +1 -1
- package/build/services/soniox/SonioxTokenAssembler.js +1 -1
- package/build/services/soniox/SonioxTokenAssembler.js.map +1 -1
- package/build/stores/cloudClientStatus.js +1 -1
- package/build/stores/cloudClientStatus.js.map +1 -1
- package/build/stores/settings.js +3 -3
- package/build/stores/settings.js.map +1 -1
- package/build/utils/cloudClient/cloudSecureStore.js +2 -2
- package/build/utils/cloudClient/cloudSecureStore.js.map +1 -1
- package/package.json +7 -7
- package/src/engine.ts +3 -3
- package/src/facades/dev.ts +2 -2
- package/src/facades/reports.ts +2 -2
- package/src/facades/session.ts +2 -2
- package/src/generated/releaseMetadata.ts +3 -3
- package/src/index.ts +1 -1
- package/src/runtime/bootstrap.ts +2 -2
- package/src/services/CloudAudioSubscriptionSync.ts +2 -2
- package/src/services/CloudClientService.ts +4 -4
- package/src/services/CloudTranscriptE2EMetrics.ts +3 -3
- package/src/services/LocalMiniappRuntime.ts +3 -3
- package/src/services/PhonePhotoCoordinator.ts +4 -4
- package/src/services/PhoneStreamCoordinator.ts +1 -1
- package/src/services/SupportProfileSync.ts +2 -2
- package/src/services/cloudStreamApi.ts +3 -3
- package/src/services/soniox/SonioxRealtimeClient.ts +2 -2
- package/src/services/soniox/SonioxTokenAssembler.ts +1 -1
- package/src/stores/cloudClientStatus.ts +1 -1
- package/src/stores/settings.ts +3 -3
- package/src/utils/cloudClient/cloudSecureStore.ts +2 -2
|
@@ -12,9 +12,9 @@ export interface EngineReleaseMetadata {
|
|
|
12
12
|
export const ENGINE_RELEASE_METADATA: Readonly<EngineReleaseMetadata> = Object.freeze({
|
|
13
13
|
"schemaVersion": 1,
|
|
14
14
|
"familyBaseVersion": "0.3.2",
|
|
15
|
-
"releaseIdentity": "0.3.2-dev.
|
|
16
|
-
"releaseSetId": "glassly-0.3.2-dev.
|
|
17
|
-
"sourceCommit": "
|
|
15
|
+
"releaseIdentity": "0.3.2-dev.574",
|
|
16
|
+
"releaseSetId": "glassly-0.3.2-dev.574",
|
|
17
|
+
"sourceCommit": "959420ded485d85438cc44e085ba61388cbdd72a",
|
|
18
18
|
"otaManifestUrl": null,
|
|
19
19
|
"otaManifestSha256": null
|
|
20
20
|
})
|
package/src/index.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* capability tables, timers). Judgment rule: read models, commands, pure
|
|
8
8
|
* functions and types belong here; anything that mutates runtime state or
|
|
9
9
|
* exposes a raw store/service remains private to the Glassly host.
|
|
10
|
-
* See cloud
|
|
10
|
+
* See cloud/docs/issues/020-glasses-status-boundary/integration-review.md §D.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
// The namespaced OEM-facing engine API (the "(A) host API"). See ./engine.
|
package/src/runtime/bootstrap.ts
CHANGED
|
@@ -29,9 +29,9 @@ export interface IslandAuth {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
export interface IslandConfigValues {
|
|
32
|
-
/** cloud
|
|
32
|
+
/** cloud core service base URL (defaults resolved by the cloud client). */
|
|
33
33
|
coreUrl?: string
|
|
34
|
-
/** cloud
|
|
34
|
+
/** cloud runtime service base URL. */
|
|
35
35
|
runtimeUrl?: string
|
|
36
36
|
/** OEM identifier (Glassly is OEM #0); reserved for OEM auth/telemetry. */
|
|
37
37
|
oemId?: string
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Failure mode this protects:
|
|
7
7
|
* 1. Local captions subscribes to transcription.
|
|
8
|
-
* 2. The first Cloud
|
|
8
|
+
* 2. The first Cloud `PUT /api/audio/subscriptions` throws while the socket
|
|
9
9
|
* is reconnecting or Core is briefly unreachable.
|
|
10
10
|
* 3. A reconnect/resync recomputes the same desired subscription set.
|
|
11
11
|
*
|
|
12
12
|
* If we mark the set as "last applied" before the PUT succeeds, step 3 is
|
|
13
|
-
* incorrectly deduped and captions can wait forever even though Cloud
|
|
13
|
+
* incorrectly deduped and captions can wait forever even though Cloud later
|
|
14
14
|
* reconnects. So `begin()` only blocks exact duplicates while a write is in
|
|
15
15
|
* flight; only `succeeded()` promotes that key to the applied state.
|
|
16
16
|
*/
|
|
@@ -35,7 +35,7 @@ import {storage as mmkvStorage} from "../utils/storage"
|
|
|
35
35
|
import {useCloudClientStatusStore} from "../stores/cloudClientStatus"
|
|
36
36
|
import {islandNotifications} from "./NotificationsEmitter"
|
|
37
37
|
import {BgTimer} from "../utils/timers"
|
|
38
|
-
import {
|
|
38
|
+
import {logCloudTranscriptMetric} from "./CloudTranscriptE2EMetrics"
|
|
39
39
|
import {isLocalUserId, LocalMiniappUserIdentity} from "./LocalMiniappUserIdentity"
|
|
40
40
|
import {migrateLocalMiniappData, type LocalMiniappDataMigrationBackend} from "./LocalMiniappDataMigration"
|
|
41
41
|
import {nativeHttpResponseBody} from "./NativeHttpResponse"
|
|
@@ -580,7 +580,7 @@ function construct(): void {
|
|
|
580
580
|
})
|
|
581
581
|
transcriptUnsubscribe = c.runtime.onTranscript((data) => {
|
|
582
582
|
if (c !== client) return
|
|
583
|
-
|
|
583
|
+
logCloudTranscriptMetric(data)
|
|
584
584
|
emitTranscript(data)
|
|
585
585
|
})
|
|
586
586
|
translationUnsubscribe = c.runtime.onTranslation((data) => {
|
|
@@ -857,7 +857,7 @@ export const cloudClientService = {
|
|
|
857
857
|
stopDisableCloudWatcher()
|
|
858
858
|
},
|
|
859
859
|
|
|
860
|
-
/** Device-side managed photo
|
|
860
|
+
/** Device-side managed photo: presign now, deliver bytes, await ready. */
|
|
861
861
|
startManagedPhoto(opts: Record<string, unknown> = {}) {
|
|
862
862
|
if (!client) throw new Error("cloud client not connected")
|
|
863
863
|
return client.runtime.startManagedPhoto(opts)
|
|
@@ -867,7 +867,7 @@ export const cloudClientService = {
|
|
|
867
867
|
return client.runtime.awaitManagedPhotoReady(requestId)
|
|
868
868
|
},
|
|
869
869
|
|
|
870
|
-
/** Managed stream
|
|
870
|
+
/** Managed stream: provision ingest+playback on the runtime. */
|
|
871
871
|
startManagedStream(opts: Record<string, unknown> = {}) {
|
|
872
872
|
if (!client) throw new Error("cloud client not connected")
|
|
873
873
|
return client.runtime.startManagedStream(opts)
|
|
@@ -2,7 +2,7 @@ import type {TranscriptionData} from "@glassly/cloud-protocol"
|
|
|
2
2
|
|
|
3
3
|
import {buildE2EMetric, logE2EMetricPayload} from "../utils/e2eMetrics"
|
|
4
4
|
|
|
5
|
-
export function
|
|
5
|
+
export function buildCloudTranscriptMetric(data: TranscriptionData): Record<string, unknown> {
|
|
6
6
|
return buildE2EMetric("cloud_v2_transcript", {
|
|
7
7
|
text: data.text,
|
|
8
8
|
state: data.isFinal ? "final" : "interim",
|
|
@@ -22,6 +22,6 @@ export function buildCloudV2TranscriptMetric(data: TranscriptionData): Record<st
|
|
|
22
22
|
})
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
export function
|
|
26
|
-
logE2EMetricPayload(
|
|
25
|
+
export function logCloudTranscriptMetric(data: TranscriptionData): void {
|
|
26
|
+
logE2EMetricPayload(buildCloudTranscriptMetric(data), "cloud_v2_transcript")
|
|
27
27
|
}
|
|
@@ -286,7 +286,7 @@ const MINIAPP_AUTH_REFRESH_MIN_DELAY_MS = 5_000
|
|
|
286
286
|
// (e.g. the cloud client had not finished its first-boot Core token exchange
|
|
287
287
|
// when the miniapp connected). Exponential from base, capped, so a transient
|
|
288
288
|
// not-yet-connected client self-heals within seconds instead of needing a full
|
|
289
|
-
// manual Cloud
|
|
289
|
+
// manual Cloud reconnect.
|
|
290
290
|
const MINIAPP_AUTH_RETRY_BASE_MS = 1_000
|
|
291
291
|
const MINIAPP_AUTH_RETRY_MAX_MS = 15_000
|
|
292
292
|
const FOREGROUND_LIVENESS_PROBE_TIMEOUT_MS = 2_500
|
|
@@ -1826,7 +1826,7 @@ class LocalMiniappRuntime {
|
|
|
1826
1826
|
// right after app start. CONNECT_ACK already went out without auth; keep
|
|
1827
1827
|
// trying to mint (and re-drive on cloud-connect) so the app authenticates
|
|
1828
1828
|
// to its backend on its own, instead of staying dead until a full manual
|
|
1829
|
-
// Cloud
|
|
1829
|
+
// Cloud reconnect re-runs the whole handshake.
|
|
1830
1830
|
this.deliverInitialMiniappAuth(packageName, authPromise, 0)
|
|
1831
1831
|
}
|
|
1832
1832
|
this.sendCloudStatusToMiniapp(packageName)
|
|
@@ -1988,7 +1988,7 @@ class LocalMiniappRuntime {
|
|
|
1988
1988
|
* When the cloud client (re)connects, immediately re-attempt the initial mint
|
|
1989
1989
|
* for any handshook app still missing its token, instead of waiting out the
|
|
1990
1990
|
* backoff. This is what turns "scan a dev app before the cloud is ready" from
|
|
1991
|
-
* "dead until you manually reconnect Cloud
|
|
1991
|
+
* "dead until you manually reconnect Cloud" into "authenticates on its own
|
|
1992
1992
|
* the instant the connection comes up".
|
|
1993
1993
|
*/
|
|
1994
1994
|
private redriveMiniappAuthDelivery(): void {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* miniapp → SDK → LocalMiniappRuntime → photo runtime hook
|
|
6
6
|
* → coordinator.takePhoto(packageName, opts)
|
|
7
7
|
* ├── (precheck) glasses connected + hasCamera
|
|
8
|
-
* ├── cloudClientService.startManagedPhoto → {requestId, uploadUrl, readUrl} (cloud
|
|
8
|
+
* ├── cloudClientService.startManagedPhoto → {requestId, uploadUrl, readUrl} (cloud runtime presign)
|
|
9
9
|
* ├── BluetoothSdk.requestPhoto(requestId, size, uploadUrl, compress, sound)
|
|
10
10
|
* └── race:
|
|
11
11
|
* - cloudClientService.awaitManagedPhotoReady(requestId) resolves on photo.ready push
|
|
@@ -179,8 +179,8 @@ export class PhonePhotoCoordinator {
|
|
|
179
179
|
// high-capacity tier and let the glasses ignore the public size when mode=text.
|
|
180
180
|
const captureSize = opts.size ?? "medium"
|
|
181
181
|
|
|
182
|
-
// 1) Presign via the cloud
|
|
183
|
-
// ONLY the cloud
|
|
182
|
+
// 1) Presign via the cloud managed-photo service. Local miniapps use
|
|
183
|
+
// ONLY the cloud path: the runtime presigns upload+read URLs and the
|
|
184
184
|
// phone (as the device controller) delivers the bytes; the legacy
|
|
185
185
|
// backend_url mint is gone from this flow.
|
|
186
186
|
let requestId: string
|
|
@@ -419,7 +419,7 @@ export class PhonePhotoCoordinator {
|
|
|
419
419
|
// Abort the in-flight long-poll first so we don't double-resolve.
|
|
420
420
|
entry.abort.abort()
|
|
421
421
|
entry.reject(new PhotoError(errorCode || "GLASSES_ERROR", errorMessage || "Glasses error", "capture", "ble"))
|
|
422
|
-
// cloud
|
|
422
|
+
// cloud pending photo requests TTL out on their own; nothing to free.
|
|
423
423
|
}
|
|
424
424
|
|
|
425
425
|
private toPhotoError(err: unknown, fallbackCode: string, stage?: PhotoStage, transport?: PhotoTransport): PhotoError {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Architecture:
|
|
5
5
|
* miniapp → SDK → LocalMiniappRuntime → coordinator
|
|
6
6
|
* coordinator → BluetoothSdk (BLE → glasses publisher)
|
|
7
|
-
* coordinator ↔ cloudStreamApi (managed only, cloud
|
|
7
|
+
* coordinator ↔ cloudStreamApi (managed only, cloud runtime provisioning)
|
|
8
8
|
* coordinator ↔ StreamLifecycleController (keep-alive heartbeat)
|
|
9
9
|
* coordinator → status listeners → routed back to miniapp(s)
|
|
10
10
|
*
|
|
@@ -26,7 +26,7 @@ let lastFailure: {code: string; stage: string} | null = null
|
|
|
26
26
|
let lastConnectionState: string | null = null
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
|
-
* Keep Cloud
|
|
29
|
+
* Keep Cloud's canonical support snapshot current without creating an event
|
|
30
30
|
* stream from noisy store updates. Only the explicitly selected fields below
|
|
31
31
|
* leave the phone; Wi-Fi, Bluetooth addresses, location and diagnostics do not.
|
|
32
32
|
*/
|
|
@@ -110,7 +110,7 @@ async function sendCurrentSnapshot(force: boolean, generation = syncGeneration):
|
|
|
110
110
|
consecutiveSendFailures += 1
|
|
111
111
|
retryDelayMs = retryDelayForSendFailure(consecutiveSendFailures)
|
|
112
112
|
console.warn(
|
|
113
|
-
`supportProfile: Cloud
|
|
113
|
+
`supportProfile: Cloud update failed (retry in ${Math.round(retryDelayMs / 1_000)}s):`,
|
|
114
114
|
error instanceof Error ? error.message : error,
|
|
115
115
|
)
|
|
116
116
|
} finally {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Managed-stream provisioning over the cloud
|
|
2
|
+
* Managed-stream provisioning over the cloud runtime (cloud-client REST):
|
|
3
3
|
*
|
|
4
4
|
* POST /api/camera/stream -> provision (Cloudflare live input)
|
|
5
5
|
* GET /api/camera/stream/:id -> provider's ingest status
|
|
@@ -61,7 +61,7 @@ export class StreamApiError extends Error {
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
/** The cloud
|
|
64
|
+
/** The cloud runtime's ManagedStream wire shape (open records, see protocol). */
|
|
65
65
|
interface ManagedStreamWire {
|
|
66
66
|
streamId: string
|
|
67
67
|
ingest: {
|
|
@@ -79,7 +79,7 @@ interface ManagedStreamWire {
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
/**
|
|
82
|
-
* Provision a managed stream on the cloud
|
|
82
|
+
* Provision a managed stream on the cloud runtime. Returns ready-to-publish
|
|
83
83
|
* ingest URLs (credentials embedded) plus the playback URLs.
|
|
84
84
|
*/
|
|
85
85
|
export async function provisionManagedStream(
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
* machinery) or `@soniox/web` (MediaStream capture): the wire protocol is one
|
|
11
11
|
* JSON config message, then binary PCM frames up / JSON token results down.
|
|
12
12
|
* Protocol shape mirrors the vendored SDK's buildConfigMessage /
|
|
13
|
-
* parseResultMessage (cloud
|
|
14
|
-
* implementation: cloud
|
|
13
|
+
* parseResultMessage (cloud runtime's provider is the reference
|
|
14
|
+
* implementation: cloud/packages/runtime/src/services/audio/providers/soniox.ts).
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import {BgTimer} from "../../utils/timers"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* SonioxTokenAssembler
|
|
3
3
|
*
|
|
4
4
|
* Pure port of the cloud Soniox provider's utterance assembly
|
|
5
|
-
* (cloud
|
|
5
|
+
* (cloud/packages/runtime/src/services/audio/providers/soniox.ts). Soniox
|
|
6
6
|
* emits a rolling token window that is re-finalized/compacted across results;
|
|
7
7
|
* this class turns that stream into stable interim/final utterances:
|
|
8
8
|
*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cloud-client runtime status store — moved into engine so engine owns the
|
|
3
|
-
* cloud
|
|
3
|
+
* cloud runtime status (connection status + audio transport). Re-exported
|
|
4
4
|
* through the host's `@/stores/cloudClientStatus` shim so the app keeps its
|
|
5
5
|
* imports, and surfaced as `engine.stores.cloudClientStatus`.
|
|
6
6
|
*/
|
package/src/stores/settings.ts
CHANGED
|
@@ -262,7 +262,7 @@ export const SETTINGS: Record<string, Setting> = {
|
|
|
262
262
|
saveOnServer: false,
|
|
263
263
|
persist: true,
|
|
264
264
|
},
|
|
265
|
-
// Cloud
|
|
265
|
+
// Cloud endpoint OVERRIDES. Empty = no override; cloudClient's resolveUrl
|
|
266
266
|
// owns the full precedence (override -> env -> Metro-derived dev default).
|
|
267
267
|
// The value may be an explicit URL or the METRO_AUTO sentinel ("my dev
|
|
268
268
|
// laptop", resolved live from Metro so it survives network changes). Never
|
|
@@ -284,7 +284,7 @@ export const SETTINGS: Record<string, Setting> = {
|
|
|
284
284
|
persist: true,
|
|
285
285
|
resetOnBuildEnvChange: true,
|
|
286
286
|
},
|
|
287
|
-
// Bookmarked Cloud
|
|
287
|
+
// Bookmarked Cloud endpoint pairs. Each entry is {label, coreUrl,
|
|
288
288
|
// runtimeUrl} — core + runtime are saved together because they are always
|
|
289
289
|
// applied as a matched set (presets fill both; Save & Test verifies both).
|
|
290
290
|
saved_cloud_url_pairs: {
|
|
@@ -411,7 +411,7 @@ export const SETTINGS: Record<string, Setting> = {
|
|
|
411
411
|
persist: true,
|
|
412
412
|
},
|
|
413
413
|
location_tier: {key: "location_tier", defaultValue: () => "", writable: true, saveOnServer: true, persist: true},
|
|
414
|
-
// Volatile bearer synced to Bluetooth for glasses-side Cloud
|
|
414
|
+
// Volatile bearer synced to Bluetooth for glasses-side Cloud calls. The
|
|
415
415
|
// key name is kept for BLE compatibility, but the value must never be loaded
|
|
416
416
|
// from or saved to the legacy Cloud V1 settings store.
|
|
417
417
|
core_token: {key: "core_token", defaultValue: () => "", writable: true, saveOnServer: false, persist: false},
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MMKV-backed KeyValueStore for @glassly/cloud-client — moved into engine so
|
|
3
|
-
* engine owns the cloud
|
|
3
|
+
* engine owns the cloud credential storage (the v2 refresh token, so a
|
|
4
4
|
* relaunch does not force a new login). A dedicated MMKV instance keeps
|
|
5
|
-
* cloud
|
|
5
|
+
* cloud credentials out of the app's general store. Re-exported through the
|
|
6
6
|
* host's `@/utils/cloudClient/MmkvSecureStore` shim.
|
|
7
7
|
*
|
|
8
8
|
* NOTE: MMKV is not hardware-backed. Before production handling of the
|