@extentos/mcp-server 0.5.2 → 0.5.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/dist/tools/data/capabilities.d.ts +12 -280
- package/dist/tools/data/capabilities.d.ts.map +1 -1
- package/dist/tools/data/capabilities.js +19 -57
- package/dist/tools/data/capabilities.js.map +1 -1
- package/dist/tools/data/capabilityPatterns.d.ts.map +1 -1
- package/dist/tools/data/capabilityPatterns.js +60 -15
- package/dist/tools/data/capabilityPatterns.js.map +1 -1
- package/dist/tools/data/codeExamples.d.ts.map +1 -1
- package/dist/tools/data/codeExamples.js +161 -5
- package/dist/tools/data/codeExamples.js.map +1 -1
- package/dist/tools/docs/index.js +15 -15
- package/dist/tools/docs/index.js.map +1 -1
- package/dist/tools/handlers/generateConnectionModule.js +29 -3
- package/dist/tools/handlers/generateConnectionModule.js.map +1 -1
- package/dist/tools/handlers/getPlatformInfo.js +1 -1
- package/dist/tools/handlers/getPlatformInfo.js.map +1 -1
- package/dist/tools/handlers/validateIntegration.d.ts.map +1 -1
- package/dist/tools/handlers/validateIntegration.js +29 -11
- package/dist/tools/handlers/validateIntegration.js.map +1 -1
- package/package.json +1 -1
|
@@ -107,7 +107,7 @@ val recording = glasses.audio.recordDiscrete(
|
|
|
107
107
|
silenceTimeoutSeconds = 3.0, // VAD turn-end threshold (Double seconds)
|
|
108
108
|
quality = AudioQuality.STANDARD, // STANDARD or HIGH (enum, not String)
|
|
109
109
|
)
|
|
110
|
-
).valueOrNull() ?: return //
|
|
110
|
+
).valueOrNull() ?: return // null = the Err branch; keep the Result and call result.errorOrNull() for the error shape (import com.extentos.glasses.core.errorOrNull)
|
|
111
111
|
|
|
112
112
|
val text = recording.transcript // ready to feed an LLM`,
|
|
113
113
|
swift: `let result = await glasses.audio.recordDiscrete(
|
|
@@ -122,7 +122,7 @@ guard case .success(let recording) = result else { return }
|
|
|
122
122
|
let text = recording.transcript`,
|
|
123
123
|
gotchas: [
|
|
124
124
|
"silenceTimeoutSeconds is the VAD turn-end threshold. 2s is the SDK default; 3s is friendlier for thoughtful users; <1.5s cuts off normal pauses.",
|
|
125
|
-
"The block AUTO-transcribes — no separate STT pipeline needed.
|
|
125
|
+
"The block AUTO-transcribes — no separate STT pipeline needed. `rawAudioUri` is **nullable** (String?): populated on real hardware / LocalSim but **null in the browser simulator** (transcript-injection has no audio bytes), and `audioDurationMs` (a **Long**, not Int) is 0 there — so the raw-audio persist/replay path needs real glasses or LocalSim to exercise.",
|
|
126
126
|
"Audio routes over HFP mono 8 kHz on Meta DAT. 'high' quality is effectively the same as 'standard' until A2DP-grade mic capture lands upstream.",
|
|
127
127
|
"Returns immediately on the FIRST of: silenceTimeoutSeconds of silence, maxDurationSeconds elapsed (when set — null, the default, means no cap), or app-side scope cancellation.",
|
|
128
128
|
"Gated by audio_capture_enabled toggle (default true) and privacy_mode (default false).",
|
|
@@ -190,6 +190,7 @@ task.cancel()`,
|
|
|
190
190
|
"cancelSpeak() is fire-and-forget — it returns immediately. The platform TTS engine state machine handles the actual stop; the speaker falls silent within ~tens of ms.",
|
|
191
191
|
"Speak quality is bound by the phone's native TTS engine (not the glasses). Try ElevenLabs / OpenAI TTS via outgoingAudio if you need a premium voice (currently not exposed; future feature).",
|
|
192
192
|
"speak() routes audio over HFP — high-quality A2DP music playback drops to mono 8 kHz for the duration of speech.",
|
|
193
|
+
"speak() and earcon() are NOT gated by any toggle — audio OUTPUT always plays. No toggle (not even privacy_mode) silences output; the toggles gate audio/camera INPUT + STT. voice_confirmations only controls the SDK's auto-earcon pair around connection-page voice handlers, never your direct speak()/earcon(). A DisabledByUser result is therefore impossible for speak/earcon — build your own mute switch if you need one.",
|
|
193
194
|
],
|
|
194
195
|
relatedExamples: ["voice_qa_assistant", "barge_in_speak", "voice_notes", "photo_describe_voice"],
|
|
195
196
|
};
|
|
@@ -205,7 +206,7 @@ glasses.camera.videoFrames(
|
|
|
205
206
|
frameRate = 2, // 2 fps for ML; 7-15 for preview
|
|
206
207
|
)
|
|
207
208
|
).collect { frame ->
|
|
208
|
-
// process frame.
|
|
209
|
+
// process frame.data (ByteArray) — also frame.width, frame.height, frame.timestampMs
|
|
209
210
|
}`,
|
|
210
211
|
swift: `for await frame in glasses.camera.videoFrames(
|
|
211
212
|
config: VideoFrameConfig(
|
|
@@ -237,7 +238,7 @@ glasses.audio.audioChunks(
|
|
|
237
238
|
sampleRate = 16000, // 16 kHz default — match downstream STT model
|
|
238
239
|
)
|
|
239
240
|
).collect { chunk ->
|
|
240
|
-
// feed chunk.
|
|
241
|
+
// feed chunk.data (ByteArray) to your STT / VAD / classifier — also chunk.sampleRate, chunk.timestampMs
|
|
241
242
|
}`,
|
|
242
243
|
swift: `for await chunk in glasses.audio.audioChunks(
|
|
243
244
|
config: AudioChunkConfig(
|
|
@@ -253,6 +254,7 @@ glasses.audio.audioChunks(
|
|
|
253
254
|
"20ms chunk size is the standard opus/CELT frame; don't change unless your downstream model expects a specific shape.",
|
|
254
255
|
"16-chunk buffer cap; slow consumers (>50ms/chunk processing on average) will drop. Profile your consumer.",
|
|
255
256
|
"Same gates as transcriptions(): audio_capture_enabled, privacy_mode (listening_mode does NOT gate audio_chunks since it's a raw-audio path, not STT).",
|
|
257
|
+
"config.sampleRate is the REQUESTED rate, but Meta DAT delivers mic audio over HFP at 8 kHz mono i16 PCM (G.711) — on real hardware the effective rate is the HFP rate, not necessarily your config value. Read the per-chunk `chunk.sampleRate` for any rate-sensitive DSP (FFT bins, VAD windows) instead of assuming the config value; passing 16000 does not guarantee 16 kHz on the HFP path.",
|
|
256
258
|
],
|
|
257
259
|
relatedExamples: [],
|
|
258
260
|
};
|
|
@@ -364,6 +366,11 @@ class CountHandler(private val glasses: ExtentosGlasses) {
|
|
|
364
366
|
// primitive — the first FINAL transcript whose text contains
|
|
365
367
|
// any of these (case-insensitive substring) cancels the
|
|
366
368
|
// handler coroutine. Customer's try/finally runs normally.
|
|
369
|
+
// NOTE: cancellation stops the coroutine from making FURTHER
|
|
370
|
+
// calls, but does NOT interrupt TTS already handed to the
|
|
371
|
+
// engine — a speak() that's mid-utterance plays to completion.
|
|
372
|
+
// To silence the current utterance the instant a stop fires,
|
|
373
|
+
// call glasses.audio.cancelSpeak() in a finally { } block.
|
|
367
374
|
stops = listOf("stop counting", "okay stop"),
|
|
368
375
|
) {
|
|
369
376
|
for (n in 1..10) {
|
|
@@ -863,7 +870,7 @@ val session = glasses.assistant.createSession(AssistantConfig(
|
|
|
863
870
|
session.start()
|
|
864
871
|
|
|
865
872
|
// Observe lifecycle:
|
|
866
|
-
session.state.collect { state -> /* Idle,
|
|
873
|
+
session.state.collect { state -> /* Idle, Dormant, Activating, Active, Reconnecting, Sleeping, Stopping, Stopped */ }
|
|
867
874
|
|
|
868
875
|
// Stop when done:
|
|
869
876
|
session.stop() // or glasses.assistant.stop() — equivalent`,
|
|
@@ -884,15 +891,16 @@ let session = glasses.assistant.createSession(config: AssistantConfig(
|
|
|
884
891
|
try await session.start()
|
|
885
892
|
|
|
886
893
|
// Observe lifecycle (StateFlow-style — replays current on subscribe):
|
|
887
|
-
for await state in session.state.stream { /* idle,
|
|
894
|
+
for await state in session.state.stream { /* idle, dormant, activating, active, reconnecting, sleeping, stopping, stopped */ }
|
|
888
895
|
|
|
889
896
|
// Stop when done (async, NOT throwing on iOS):
|
|
890
897
|
await session.stop() // or await glasses.assistant.stop() — equivalent`,
|
|
891
898
|
gotchas: [
|
|
892
899
|
"**`start()` is suspend / async throws — call from a coroutine / Task.** Opens the WebSocket to the Extentos managed gateway (no API key in the app), sends session.update, awaits session.updated handshake (~1-2s typical). Throws AssistantException(AlreadyActive) if another session is active; AssistantException(NetworkError) on WS open failure.",
|
|
893
900
|
"**Sugar form auto-starts the session; raw form does not.** `assistant.start(provider) { ... }` returns an already-Active session. `assistant.createSession(config)` returns an Idle session — you call `session.start()` to activate. The sugar is shorthand for `createSession + start`.",
|
|
901
|
+
"**Automatic greeting on wake via the `greeting` field (type `Greeting`, package `com.extentos.glasses.core.assistant`).** Three variants: `Greeting.Default` (the default — a memory-aware greeting, no `onWake` wiring needed), `Greeting.Custom(directive)` (your own directive — prepend `Greeting.DEFAULT_DIRECTIVE` to extend rather than replace it), and `Greeting.Off` (greet manually / not at all). Replaces the old `onWake { greet(...) }` wiring.",
|
|
894
902
|
"**Customer-can-skip-it (synthesis #7).** The raw form is the primitive; the sugar reduces to it. Every customer can replace `start { tool(...) { ... } }` with `createSession(AssistantConfig(tools = listOf(ToolDefinition(...), ...)))` + `start()` and get identical behavior. Useful for programmatic tool registration (loaded from config, conditional, etc.).",
|
|
895
|
-
"**`stop()` is idempotent.** Calling stop() on
|
|
903
|
+
"**`stop()` is idempotent.** Calling stop() on a Stopped session is a no-op. Calling start() on a Stopped session throws AssistantException(SessionEnded) — create a new session via createSession() to start fresh.",
|
|
896
904
|
],
|
|
897
905
|
relatedExamples: ["assistant_agent_loop", "agent_driven_e2e_full_loop"],
|
|
898
906
|
};
|
|
@@ -1070,15 +1078,18 @@ let provider: AssistantProvider = .openAI(
|
|
|
1070
1078
|
const ASSISTANT_VISION = {
|
|
1071
1079
|
feature: "assistant_vision",
|
|
1072
1080
|
summary: "Phase 4 v1.4 addition — `session.includeImage(uri, prompt = null)`. Add an image to the assistant's conversation context and auto-trigger a response: the model sees the image, speaks about it in its configured voice, and remembers it for follow-up questions in the same session. Canonical 'glasses analyze what I'm looking at' surface — pair with `glasses.camera.capturePhoto()` inside a tool body. URI accepts `data:` (sim's capturePhoto default), `http(s)://` (provider fetches), or `file://` / `content://` / bare absolute path (library reads + base64-encodes). Active-only — throws `AssistantException(NotReady)` otherwise. Mock provider stubs with a deterministic AssistantSpoke event for the agent-test loop. v1 ships against OpenAI Realtime's `conversation.item.create` with `input_image` content block.",
|
|
1073
|
-
kotlin: `// Canonical pattern — capturePhoto + includeImage inside a tool body.
|
|
1074
|
-
//
|
|
1075
|
-
//
|
|
1081
|
+
kotlin: `// Canonical pattern — capturePhoto + includeImage inside a tool body. A tool
|
|
1082
|
+
// lambda has NO session receiver, so reach the running session via
|
|
1083
|
+
// glasses.assistant.activeSession — non-null while a tool runs (the model only
|
|
1084
|
+
// dispatches a tool while Active, so the NotReady throw can't fire). If your
|
|
1085
|
+
// handler already holds the session (captured from glasses.assistant.start(...)
|
|
1086
|
+
// to wire wake), call includeImage on that field instead — it's the same object.
|
|
1076
1087
|
tool("describe_scene", "Describe what the user is currently looking at — call when the user asks 'what do you see' or 'describe this'.") {
|
|
1077
1088
|
val photo = glasses.camera.capturePhoto().valueOrNull()
|
|
1078
1089
|
?: return@tool ToolResult.Err("camera failed")
|
|
1079
1090
|
val uri = photo.uri
|
|
1080
1091
|
?: return@tool ToolResult.Err("photo had no uri")
|
|
1081
|
-
|
|
1092
|
+
glasses.assistant.activeSession?.includeImage(uri)
|
|
1082
1093
|
ToolResult.Ok("looking")
|
|
1083
1094
|
}
|
|
1084
1095
|
|
|
@@ -1089,7 +1100,7 @@ tool("read_sign", "Read what's written on a sign in front of the user.") {
|
|
|
1089
1100
|
?: return@tool ToolResult.Err("camera failed")
|
|
1090
1101
|
val uri = photo.uri
|
|
1091
1102
|
?: return@tool ToolResult.Err("photo had no uri")
|
|
1092
|
-
|
|
1103
|
+
glasses.assistant.activeSession?.includeImage(uri, prompt = "What does this sign say? Read it back verbatim.")
|
|
1093
1104
|
ToolResult.Ok("reading")
|
|
1094
1105
|
}
|
|
1095
1106
|
|
|
@@ -1122,7 +1133,7 @@ tool("save_photo", "Save a photo to the user's library WITHOUT describing it. Ca
|
|
|
1122
1133
|
// From a file path (real hardware case — content:// / file:// URI from
|
|
1123
1134
|
// the platform camera intent). Same call shape — library handles the
|
|
1124
1135
|
// read + base64 encode internally.
|
|
1125
|
-
|
|
1136
|
+
glasses.assistant.activeSession?.includeImage("content://media/external/images/media/12345")`,
|
|
1126
1137
|
swift: `// iOS port lands after Android stabilizes (see real-hardware-validation-backlog.md).
|
|
1127
1138
|
// The Swift surface will mirror Kotlin's includeImage(uri:prompt:) signature.
|
|
1128
1139
|
config.tool("describe_scene", description: "Describe what the user is currently looking at.") {
|
|
@@ -1134,6 +1145,7 @@ config.tool("describe_scene", description: "Describe what the user is currently
|
|
|
1134
1145
|
return .ok("looking")
|
|
1135
1146
|
}`,
|
|
1136
1147
|
gotchas: [
|
|
1148
|
+
"**Reaching the session from a tool body.** A `tool { }` lambda has NO `session` receiver — call `glasses.assistant.activeSession?.includeImage(uri)`. `activeSession` is the session the model is currently running in, non-null inside any tool dispatch (the model only dispatches a tool while Active). The bare `session.…` you'll see in handler-based examples (e.g. assistant_agent_loop) assumes a field captured from `glasses.assistant.start(...)` to wire wake — equivalent, use whichever your handler has. (`onWake { }` / `onSleep { }` are different — there the session IS the lambda receiver, so you call `clearHistory()` etc. on it directly.)",
|
|
1137
1149
|
"**Auto-triggers a response — that's the point.** `includeImage` is a one-call API: image goes in, the model speaks. If you want to stage an image without an immediate response (rare — e.g. accumulating multiple images then asking one question), drop down to the raw OpenAI provider primitive (not exposed in v1; file a request if you need it).",
|
|
1138
1150
|
"**URI types map to wire format:** `data:image/...;base64,...` passes through verbatim (sim's capturePhoto returns this shape). `http(s)://...` passes through verbatim — OpenAI Realtime fetches the URL server-side; provider may reject for size / auth reasons, so prefer data: or base64 in production. `file://` / `content://` / bare path → library reads bytes via `Photos.loadBase64` + wraps with `mediaTypeFromUri` inferred MIME. Permission-gated like any other on-device read.",
|
|
1139
1151
|
"**Active-only.** Same precondition as `session.say()` — throws `AssistantException(NotReady)` outside Active. Inside a tool body the state IS Active (the model only dispatches a tool while Active), so the typical usage is always safe. Don't call from `onWake { }` either — onWake fires fire-and-forget on a separate coroutine that may race with the Active transition; use a brief `delay` or call from the FIRST tool dispatch instead.",
|
|
@@ -1153,6 +1165,10 @@ const ASSISTANT_SESSION_RUNTIME = {
|
|
|
1153
1165
|
// The model calls this tool when it senses a complex question. The
|
|
1154
1166
|
// tool body bumps reasoning effort for subsequent turns. Pair with
|
|
1155
1167
|
// "back_to_quick_chat" if you want to revert; skip it for sticky-high.
|
|
1168
|
+
//
|
|
1169
|
+
// NOTE: 'session' below = the live AssistantSession. Reach it via
|
|
1170
|
+
// glasses.assistant.activeSession? inside any tool body, or capture it from
|
|
1171
|
+
// start() (onWake { session = this }). The bare session.x calls assume that.
|
|
1156
1172
|
tool("think_harder", "Call when the user asks something complex that needs deeper reasoning. The next response will take longer but be more thorough.") {
|
|
1157
1173
|
session.setReasoningEffort(ReasoningEffort.High)
|
|
1158
1174
|
ToolResult.Ok("thinking more carefully")
|
|
@@ -1269,6 +1285,7 @@ glasses.runtime.events
|
|
|
1269
1285
|
swift: `// iOS port for these four primitives lands with the next Mac VPS handoff.
|
|
1270
1286
|
// Track in shared-context/real-hardware-validation-backlog.md.`,
|
|
1271
1287
|
gotchas: [
|
|
1288
|
+
"**Reaching the session inside a tool body vs. onWake.** A `tool { }` lambda has NO `session` receiver — call these on `glasses.assistant.activeSession?` (the running session, non-null while a tool dispatches) or on a field you captured from `glasses.assistant.start(...)`; the bare `session.…` in these snippets is that captured field. Asymmetry to know: `onWake { }` / `onSleep { }` DO receive the session as `this`, so inside them you call `clearHistory()` / `setReasoningEffort(...)` directly, no `session.` prefix.",
|
|
1272
1289
|
"**All four are Active-only except `conversationHistory`.** `setReasoningEffort` / `updateInstructions` / `cancelSpeak` throw `AssistantException(NotReady)` outside Active state — but tool bodies always run while Active (the model only dispatches a tool when the session is up), so the typical inside-a-tool-body usage is always safe. `conversationHistory` is safe in any state and returns an empty list pre-start or post-stop.",
|
|
1273
1290
|
"**`setReasoningEffort` and `updateInstructions` mutate session state.** The new value persists until changed again OR the session ends. On a reconnect (transparent ~50-min cadence), the LATEST value gets sent — not the original config — so customer-driven changes survive reconnects naturally. No special handling needed.",
|
|
1274
1291
|
"**`cancelSpeak` complements VAD-driven barge-in; it doesn't replace it.** The model already handles user-driven interruption when the VAD detects speech onset. This primitive is for the tool-driven / app-driven case where the developer wants to stop the model programmatically (e.g. after a tool completes and wants to deliver its result immediately, cutting off any filler the model was speaking).",
|
|
@@ -1327,8 +1344,9 @@ glasses.display.show(onBack = { scope.launch { glasses.display.clear() } }) {
|
|
|
1327
1344
|
// without one they fall back to positional auto-ids ("box-0", "box-1", ...).
|
|
1328
1345
|
// Enums: TextStyle HEADING/BODY/CAPTION; TextColor PRIMARY/SECONDARY;
|
|
1329
1346
|
// ButtonStyle PRIMARY/SECONDARY/OUTLINE; Background NONE/CARD; Alignment
|
|
1330
|
-
// START/CENTER/END/STRETCH. image(url) renders
|
|
1331
|
-
//
|
|
1347
|
+
// START/CENTER/END/STRETCH. image(url) renders a remote URL; image(photo)
|
|
1348
|
+
// hosts a locally-captured photo and renders that (DSP-29, the same shape as
|
|
1349
|
+
// video(clip)). There is no vector/canvas drawing path to the display.
|
|
1332
1350
|
|
|
1333
1351
|
// video(url) is FULL-SURFACE ONLY: it must be the sole top-level node of a
|
|
1334
1352
|
// show {} (the hardware renders video only as the entire display surface —
|
|
@@ -1361,6 +1379,7 @@ glasses.display.show { video("https://cdn.example.com/clip.mp4") }`,
|
|
|
1361
1379
|
"**To display a clip you just RECORDED, use `video(clip)` — never hand-roll hosting.** The glasses can only play an http(s) URL they fetch themselves (a local `data:`/`file:` clip from `captureVideo` is rejected on hardware), so `show { video(clip) }` (the VideoClip overload, alongside `video(url)`) makes the SDK upload the recorded clip to a hosted URL at show() time and play that — `val clip = glasses.camera.captureVideo(...).valueOrNull(); glasses.display.show { video(clip) }`. Use `video(url)` only for a clip already hosted at a remote URL. Hosting happens at display time (not record time — recording never uploads); a few seconds of upload latency for a multi-MB clip happens inside `show` — during which the SDK puts a 'Preparing video…' card on the lens (DSP-25) so the wait isn't a silent dead pause; on hosting failure it clears that card and emits a `display.video_delivery_failed` WARN. (Rationale + lifecycle: RDQ #37.)",
|
|
1362
1380
|
"**A hosted `video(clip)` copy outlives the on-screen display — release it with `forgetHostedVideo(clip)` when you delete the recording.** The first `show { video(clip) }` uploads the clip and the SDK REMEMBERS the hosted copy (keyed by the clip, persisted across app restarts), so re-showing the same clip — this session or a later one — REUSES it instead of re-uploading (no second upload latency, no orphaned copies). The copy is tied to the RECORDING's lifetime, not the display's, so clearing or replacing the display KEEPS it. When the user deletes the recording, call `glasses.display.forgetHostedVideo(clip)` (idempotent — a no-op if the clip was never shown) so the SDK tears the hosted copy down; skip it and the copy lingers server-side. Build the clip the same way for show and for forget (one `Recording -> VideoClip` helper) so both resolve to the same hosted copy. (DSP-23/24; rationale RDQ #38.)",
|
|
1363
1381
|
"**Make the FIRST play feel instant with `prepareVideo(clip)`.** The first display of a recorded clip is gated by an upload — the glasses fetch only a hosted URL, and that round-trip is irreducible on the public API (the direct phone→glasses byte-stream is internal/unexposed). Re-displays are already instant (the hosted copy is reused), and on a cold display the SDK shows a 'Preparing video…' card so the wait isn't silent. To make the first play instant TOO, call `glasses.display.prepareVideo(clip)` speculatively when a display is likely — e.g. when you put a list of recordings on screen — to move the upload OFF the critical path. Best-effort + idempotent (uploads at most once; single-flight-safe with a concurrent show), returns true when ready, and a pre-warmed clip then shows with no 'Preparing…' card. Prepare clips you expect to play — a prepared-but-never-shown clip keeps a hosted copy until `forgetHostedVideo`. (DSP-25; rationale RDQ #39.)",
|
|
1382
|
+
"**To display a photo you just CAPTURED, use `image(photo)` — the photo mirror of `video(clip)`.** `glasses.display.show { image(photo) }` (the Photo overload of `image`, alongside `image(url)`) hosts the local capture at show() time and renders it FULL-SURFACE — `val photo = glasses.camera.capturePhoto(...).valueOrNull(); glasses.display.show { image(photo) }`. Same hosting model as video: the glasses fetch only an http(s) URL (a local `data:`/`file:` photo from `capturePhoto` is rejected on hardware), the hosted copy is REMEMBERED (keyed by the photo, persisted across restarts, reused on re-display — the SAME shared media registry as clips), and you release it with `glasses.display.forgetHostedImage(photo)` when the user deletes the photo (idempotent — a no-op if it was never shown; skip it and the copy lingers server-side). UNLIKE video there is NO 'Preparing…' card and NO `prepareImage` — a photo hosts in well under a second, so the first `show { image(photo) }` is effectively instant; on hosting failure it emits a `display.image_delivery_failed` WARN and shows nothing (a dead image, like a dead video, is just blank under additive optics). Use `image(url)` for an already-hosted remote image. Build the photo the same way for show and for forget (one `Photo` handle) so both resolve to the same hosted copy. (DSP-29; rationale RDQ #40.)",
|
|
1364
1383
|
"**A dead video URL shows NOTHING — design for the failure, and use the observability built for it.** A video that can't load emits no light, and under additive optics 'no light' is indistinguishable from 'no content' — the panel just stays blank while everything else reports success. The platform surfaces the failure three ways: the simulator renders a visible 'video failed to load' placeholder in the viewport; a `display_error` event (source + media error code + url) lands in getEventLog(filter: 'errors') — check that chip FIRST when a display flow looks green but shows nothing; and a `display.video_error` WARN runtime event fires on `glasses.runtime.events` on BOTH transports (sim media error / Meta `VideoPlayer.error`), so app code can react — e.g. fall back to a text view. URLs must be PUBLICLY fetchable (the browser/glasses fetch them directly, no auth headers, MP4). For verification use the platform-hosted known-good clips — `https://extentos.com/sample-videos/mountain-bike.mp4` / `https://extentos.com/sample-videos/run-in-city.mp4` — and note that MP4s uploaded on the project simulator page get stable PUBLIC URLs too, a quick way to host a real clip without standing up a CDN.",
|
|
1365
1384
|
"**Agent verification loop:** a fresh sim session defaults to rayban_meta (NO display) — `setSimDevice(device: 'rayban_display')` FIRST, then drive the flow and read `getDisplayState` (the exact rendered tree + `interactiveIds`, headless — no pixels), then `injectInput(action: 'select', targetId: ...)` to fire onClicks the way a pinch would. injectInput needs the sim browser tab attached (ensureSimulatorBrowser); getDisplayState itself works headless.",
|
|
1366
1385
|
"**Two verification surfaces, use both:** getDisplayState (the live hub snapshot — the exact current tree + interactiveIds) and getEventLog(filter: 'display') (the durable trace: `display_show` with node counts, `display_select <id>`, `display_navigate` with the focused id, `display_back`). The event ordering proves causality — a select followed by a re-render shows as display_select → display_show, and a back-driven transition as display_back → display_show (the gesture routing to the current show's onBack).",
|
|
@@ -1368,12 +1387,38 @@ glasses.display.show { video("https://cdn.example.com/clip.mp4") }`,
|
|
|
1368
1387
|
],
|
|
1369
1388
|
relatedExamples: ["display_browse_detail"],
|
|
1370
1389
|
};
|
|
1390
|
+
const EARCON = {
|
|
1391
|
+
feature: "earcon",
|
|
1392
|
+
summary: "`glasses.audio.earcon(sound, volume)` — play a short built-in system sound over the glasses speaker. Cheap and non-interrupting (unlike speak(), it does not block): use it to acknowledge a capture, mark a turn boundary, or signal success/failure without speaking.",
|
|
1393
|
+
kotlin: `import com.extentos.glasses.core.EarconSound
|
|
1394
|
+
|
|
1395
|
+
// Fire-and-forget: returns immediately, does NOT block the coroutine.
|
|
1396
|
+
glasses.audio.earcon(EarconSound.CONFIRMATION) // default volume = 1.0
|
|
1397
|
+
glasses.audio.earcon(EarconSound.ERROR, volume = 0.6) // volume is a Double 0.0..1.0
|
|
1398
|
+
|
|
1399
|
+
// EarconSound: CONFIRMATION, ERROR, NOTIFICATION, START, STOP, COMPLETE`,
|
|
1400
|
+
swift: `import GlassesCore
|
|
1401
|
+
|
|
1402
|
+
await glasses.audio.earcon(.confirmation)
|
|
1403
|
+
await glasses.audio.earcon(.error, volume: 0.6)
|
|
1404
|
+
// EarconSound: .confirmation, .error, .notification, .start, .stop, .complete`,
|
|
1405
|
+
gotchas: [
|
|
1406
|
+
"earcon() is NOT gated by any toggle — like speak(), audio OUTPUT always plays (no toggle, not even privacy_mode, silences it; toggles gate audio/camera INPUT + STT). A DisabledByUser result is impossible for earcon.",
|
|
1407
|
+
"`volume` is a Kotlin `Double` (0.0-1.0, default 1.0) — not an Int, and not the Float the internal transport uses.",
|
|
1408
|
+
"Distinct from speak(): earcon() is a fixed system sound (no TTS, no text), returns immediately (non-blocking), and is far cheaper to call. Use earcon for acknowledgements, speak for content.",
|
|
1409
|
+
"voice_confirmations gates the SDK's OWN auto-earcon pair (START before / COMPLETE after) around connection-page voice-initiated handlers — NOT your direct earcon() calls, which always play.",
|
|
1410
|
+
"EarconSound is FFI-ordinal-encoded; always use the named cases, never a raw ordinal Int.",
|
|
1411
|
+
],
|
|
1412
|
+
relatedExamples: ["barge_in_speak"],
|
|
1413
|
+
};
|
|
1371
1414
|
export const CAPABILITY_GUIDES = {
|
|
1372
1415
|
capture_photo: CAPTURE_PHOTO,
|
|
1373
1416
|
capture_video: CAPTURE_VIDEO,
|
|
1374
1417
|
record_audio: RECORD_AUDIO,
|
|
1375
1418
|
transcription_incremental: TRANSCRIPTION_INCREMENTAL,
|
|
1376
1419
|
speak: SPEAK_AND_CANCEL,
|
|
1420
|
+
cancel_speak: SPEAK_AND_CANCEL,
|
|
1421
|
+
earcon: EARCON,
|
|
1377
1422
|
video_frames: VIDEO_FRAMES,
|
|
1378
1423
|
audio_chunks: AUDIO_CHUNKS,
|
|
1379
1424
|
connection_state: CONNECTION_STATE,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capabilityPatterns.js","sourceRoot":"","sources":["../../../src/tools/data/capabilityPatterns.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,iEAAiE;AACjE,+DAA+D;AAC/D,iCAAiC;AACjC,EAAE;AACF,iEAAiE;AACjE,qEAAqE;AACrE,mEAAmE;AACnE,0CAA0C;AAW1C,MAAM,aAAa,GAAoB;IACrC,OAAO,EAAE,eAAe;IACxB,OAAO,EACL,yKAAyK;IAC3K,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mGA4CyF;IACjG,KAAK,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;6BA2BoB;IAC3B,OAAO,EAAE;QACP,wQAAwQ;QACxQ,wQAAwQ;QACxQ,6JAA6J;QAC7J,+JAA+J;QAC/J,mJAAmJ;QACnJ,kJAAkJ;QAClJ,uRAAuR;KACxR;IACD,eAAe,EAAE,CAAC,sBAAsB,CAAC;CAC1C,CAAC;AAEF,MAAM,YAAY,GAAoB;IACpC,OAAO,EAAE,cAAc;IACvB,OAAO,EACL,qPAAqP;IACvP,MAAM,EAAE;;;;;;;;;;;;yDAY+C;IACvD,KAAK,EAAE;;;;;;;;;gCASuB;IAC9B,OAAO,EAAE;QACP,kJAAkJ;QAClJ,
|
|
1
|
+
{"version":3,"file":"capabilityPatterns.js","sourceRoot":"","sources":["../../../src/tools/data/capabilityPatterns.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codeExamples.d.ts","sourceRoot":"","sources":["../../../src/tools/data/codeExamples.ts"],"names":[],"mappings":"AAeA,6DAA6D;AAC7D,MAAM,WAAW,iBAAiB;IAChC,kEAAkE;IAClE,aAAa,EAAE,gBAAgB,GAAG,qBAAqB,GAAG,oBAAoB,GAAG,2BAA2B,CAAC;IAC7G,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,SAAS,EAAE,sBAAsB,CAAC;CACnC;AAED,6DAA6D;AAC7D,MAAM,WAAW,oBAAoB;IACnC,mEAAmE;IACnE,EAAE,EAAE,MAAM,CAAC;IACX,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,SAAS,EAAE,uBAAuB,GAAG,sBAAsB,CAAC;IAC5D;4EACwE;IACxE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,mEAAmE;AACnE,MAAM,WAAW,oBAAoB;IACnC,sBAAsB;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE;QACJ,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE;QACrB,OAAO,CAAC,EAAE,iBAAiB,EAAE,CAAC;QAC9B,gBAAgB,CAAC,EAAE,oBAAoB,EAAE,CAAC;KAC3C,CAAC;IACF;;;;;;OAMG;IACH,eAAe,CAAC,EAAE;QAChB,OAAO,CAAC,EAAE,oBAAoB,EAAE,CAAC;KAClC,CAAC;CACH;
|
|
1
|
+
{"version":3,"file":"codeExamples.d.ts","sourceRoot":"","sources":["../../../src/tools/data/codeExamples.ts"],"names":[],"mappings":"AAeA,6DAA6D;AAC7D,MAAM,WAAW,iBAAiB;IAChC,kEAAkE;IAClE,aAAa,EAAE,gBAAgB,GAAG,qBAAqB,GAAG,oBAAoB,GAAG,2BAA2B,CAAC;IAC7G,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,SAAS,EAAE,sBAAsB,CAAC;CACnC;AAED,6DAA6D;AAC7D,MAAM,WAAW,oBAAoB;IACnC,mEAAmE;IACnE,EAAE,EAAE,MAAM,CAAC;IACX,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,SAAS,EAAE,uBAAuB,GAAG,sBAAsB,CAAC;IAC5D;4EACwE;IACxE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,mEAAmE;AACnE,MAAM,WAAW,oBAAoB;IACnC,sBAAsB;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE;QACJ,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE;QACrB,OAAO,CAAC,EAAE,iBAAiB,EAAE,CAAC;QAC9B,gBAAgB,CAAC,EAAE,oBAAoB,EAAE,CAAC;KAC3C,CAAC;IACF;;;;;;OAMG;IACH,eAAe,CAAC,EAAE;QAChB,OAAO,CAAC,EAAE,oBAAoB,EAAE,CAAC;KAClC,CAAC;CACH;AAgsGD,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAerD,CAAC;AAEF,eAAO,MAAM,qBAAqB,UAAoC,CAAC"}
|
|
@@ -450,7 +450,7 @@ final class TranscriptionViewModel: ObservableObject {
|
|
|
450
450
|
const VOICE_NOTES = {
|
|
451
451
|
pattern: "voice_notes",
|
|
452
452
|
title: "Voice note (wake + record + persist)",
|
|
453
|
-
description: "'Take a note' style flow: wake phrase → record_audio with silence-VAD → save the transcript to the customer's notes repository (Notion, Supabase, filesystem, etc.). **Phase 3 conversation runtime** owns the audio buffer internally and only returns a transcribed `Turn.Said { text }` from `listen()` — there's no way to extract the underlying raw audio bytes for persistence (e.g. uploading the .wav alongside the transcript to a cloud notes service).
|
|
453
|
+
description: "'Take a note' style flow: wake phrase → record_audio with silence-VAD → save the transcript to the customer's notes repository (Notion, Supabase, filesystem, etc.). **Phase 3 conversation runtime** owns the audio buffer internally and only returns a transcribed `Turn.Said { text }` from `listen()` — there's no way to extract the underlying raw audio bytes for persistence (e.g. uploading the .wav alongside the transcript to a cloud notes service). This pattern uses `glasses.audio.recordDiscrete()`, which returns `AudioRecording { transcript, audioDurationMs, rawAudioUri }` (NOT a `Turn.Said` — that is the Phase-3 `listen()` shape); `rawAudioUri` is nullable (populated on real hardware / LocalSim, null in the browser sim) and holds the raw .wav for persistence. For text-only notes (just the transcript), you could rewrite this against `glasses.conversation.onWake { val t = listen(); savedRepo.append(t.text) }` — simpler but loses the audio backup.",
|
|
454
454
|
code: {
|
|
455
455
|
kotlin: `import com.extentos.glasses.core.AudioRecordConfig
|
|
456
456
|
import com.extentos.glasses.core.ExtentosGlasses
|
|
@@ -547,8 +547,8 @@ const CONNECTION_PAGE_SETUP = {
|
|
|
547
547
|
description: "The minimum wiring for any Extentos integration: bootstrap the library in Application onCreate / AppDelegate, and drop ExtentosConnectionPage into the customer's existing navigation. From there every other SDK call works.",
|
|
548
548
|
code: {
|
|
549
549
|
kotlin: `// In your Application subclass (e.g. MyApp.kt):
|
|
550
|
-
class MyApp : Application()
|
|
551
|
-
|
|
550
|
+
class MyApp : Application() {
|
|
551
|
+
lateinit var glasses: ExtentosGlasses
|
|
552
552
|
|
|
553
553
|
override fun onCreate() {
|
|
554
554
|
super.onCreate()
|
|
@@ -563,7 +563,7 @@ class MyApp : Application(), ExtentosBootstrap {
|
|
|
563
563
|
//
|
|
564
564
|
// In your NavHost (or wherever your tabs/screens live):
|
|
565
565
|
//
|
|
566
|
-
// val bootstrap = LocalContext.current.applicationContext as
|
|
566
|
+
// val bootstrap = LocalContext.current.applicationContext as MyApp
|
|
567
567
|
//
|
|
568
568
|
// NavHost(navController = nav, startDestination = "home") {
|
|
569
569
|
// composable("home") { HomeScreen() }
|
|
@@ -604,7 +604,7 @@ struct ContentView: View {
|
|
|
604
604
|
explanation: "Two pieces of wiring: (1) construct the ExtentosGlasses instance once at app init — that starts the auto-bind probe, install registration, and telemetry hooks; (2) drop the connection page into navigation. Everything else (audio.X, camera.X, etc.) just uses the glasses reference passed through your DI / view models.",
|
|
605
605
|
gotchas: [
|
|
606
606
|
"Don't construct multiple ExtentosGlasses instances — there's no caching and each one fires its own auto-bind probe + telemetry registration. Hold one at the Application level and pass it down.",
|
|
607
|
-
"Android: applicationContext must be non-null in ExtentosConfig if any handler needs Context (e.g., to use filesDir).
|
|
607
|
+
"Android: applicationContext must be non-null in ExtentosConfig if any handler needs Context (e.g., to use filesDir). Hold glasses on your Application subclass; handlers pull it via `LocalContext.current.applicationContext as MyApp`. (generateConnectionModule generates an equivalent `open class ExtentosBootstrap : Application()` for you — same shape; subclass it or use it directly instead of hand-writing MyApp. `ExtentosBootstrap` is a generated class, NOT a library interface.)",
|
|
608
608
|
"The connection page renders the pairing flow / sim status / capability indicators automatically — don't try to build your own. Customize via ConnectionPageConfig if you need to hide sections.",
|
|
609
609
|
],
|
|
610
610
|
relatedFeatures: [],
|
|
@@ -1936,7 +1936,10 @@ import com.extentos.glasses.core.ExtentosResult
|
|
|
1936
1936
|
import com.extentos.glasses.core.RuntimeEvent
|
|
1937
1937
|
import com.extentos.glasses.core.VideoClip
|
|
1938
1938
|
import com.extentos.glasses.core.VideoConfig
|
|
1939
|
+
import com.extentos.glasses.core.Photos
|
|
1939
1940
|
import com.extentos.glasses.core.assistant.AssistantEvent
|
|
1941
|
+
import com.extentos.glasses.core.assistant.Greeting
|
|
1942
|
+
import java.io.File
|
|
1940
1943
|
import com.extentos.glasses.core.assistant.AssistantProvider
|
|
1941
1944
|
import com.extentos.glasses.core.assistant.AssistantSession
|
|
1942
1945
|
import com.extentos.glasses.core.assistant.ToolResult
|
|
@@ -1984,6 +1987,10 @@ class StravaAssistantHandler(
|
|
|
1984
1987
|
private val library: ClipLibrary, // app-internal state
|
|
1985
1988
|
private val scope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.IO),
|
|
1986
1989
|
) {
|
|
1990
|
+
// Captured once the runtime is started; used to wake the session and to
|
|
1991
|
+
// reach it from OUTSIDE a tool body. Inside a tool body you can equivalently
|
|
1992
|
+
// use glasses.assistant.activeSession? (non-null while a tool dispatches) —
|
|
1993
|
+
// the assistant_vision example uses that form. Same session either way.
|
|
1987
1994
|
private var session: AssistantSession? = null
|
|
1988
1995
|
|
|
1989
1996
|
// Natural async + await + stop pattern. The library exposes
|
|
@@ -3081,6 +3088,153 @@ VERIFICATION NOTES
|
|
|
3081
3088
|
],
|
|
3082
3089
|
relatedFeatures: ["display", "assistant_runtime", "assistant_tool", "voice_command"],
|
|
3083
3090
|
};
|
|
3091
|
+
const VIDEO_FRAMES_ML = {
|
|
3092
|
+
pattern: "video_frames_ml",
|
|
3093
|
+
title: "Continuous frame stream to on-device processing",
|
|
3094
|
+
description: "Subscribe to the camera frame stream and run a per-frame computation on-device (object detection, scene classification, a brightness or QR scan) without round-tripping to the cloud. LOW resolution + a low frame rate keeps battery and thermals in check. NOTE: the browser simulator does not deliver video frames yet — exercise this on real hardware or LocalSim.",
|
|
3095
|
+
code: {
|
|
3096
|
+
kotlin: `import com.extentos.glasses.core.ExtentosGlasses
|
|
3097
|
+
import com.extentos.glasses.core.Resolution
|
|
3098
|
+
import com.extentos.glasses.core.VideoFrameConfig
|
|
3099
|
+
import kotlinx.coroutines.CoroutineScope
|
|
3100
|
+
import kotlinx.coroutines.Dispatchers
|
|
3101
|
+
import kotlinx.coroutines.SupervisorJob
|
|
3102
|
+
import kotlinx.coroutines.flow.launchIn
|
|
3103
|
+
import kotlinx.coroutines.flow.onEach
|
|
3104
|
+
|
|
3105
|
+
class SceneScanner(
|
|
3106
|
+
private val glasses: ExtentosGlasses,
|
|
3107
|
+
private val detector: Detector, // your on-device model
|
|
3108
|
+
) {
|
|
3109
|
+
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
|
|
3110
|
+
|
|
3111
|
+
fun start() {
|
|
3112
|
+
glasses.camera.videoFrames(
|
|
3113
|
+
VideoFrameConfig(
|
|
3114
|
+
resolution = Resolution.LOW, // LOW is plenty for most ML
|
|
3115
|
+
frameRate = 2, // 2 fps for ML; 7-15 for live preview
|
|
3116
|
+
)
|
|
3117
|
+
).onEach { frame ->
|
|
3118
|
+
// frame.data: ByteArray (raw bytes); frame.width / frame.height: Int;
|
|
3119
|
+
// frame.timestampMs: Long. Feed the bytes to your model.
|
|
3120
|
+
val label = detector.classify(frame.data, frame.width, frame.height)
|
|
3121
|
+
if (label != null) glasses.audio.speak("I see a " + label)
|
|
3122
|
+
}.launchIn(scope)
|
|
3123
|
+
}
|
|
3124
|
+
|
|
3125
|
+
fun stop() = scope.cancel()
|
|
3126
|
+
}`,
|
|
3127
|
+
swift: `import GlassesCore
|
|
3128
|
+
|
|
3129
|
+
actor SceneScanner {
|
|
3130
|
+
private let glasses: any ExtentosGlasses
|
|
3131
|
+
private let detector: Detector
|
|
3132
|
+
private var task: Task<Void, Never>?
|
|
3133
|
+
|
|
3134
|
+
init(glasses: any ExtentosGlasses, detector: Detector) {
|
|
3135
|
+
self.glasses = glasses
|
|
3136
|
+
self.detector = detector
|
|
3137
|
+
}
|
|
3138
|
+
|
|
3139
|
+
func start() {
|
|
3140
|
+
task = Task { [glasses, detector] in
|
|
3141
|
+
for await frame in glasses.camera.videoFrames(
|
|
3142
|
+
config: VideoFrameConfig(resolution: .low, frameRate: 2)
|
|
3143
|
+
) {
|
|
3144
|
+
// frame.buffer / frame.width / frame.height / frame.timestampMs
|
|
3145
|
+
if let label = detector.classify(frame) {
|
|
3146
|
+
_ = await glasses.audio.speak("I see a " + label)
|
|
3147
|
+
}
|
|
3148
|
+
}
|
|
3149
|
+
}
|
|
3150
|
+
}
|
|
3151
|
+
|
|
3152
|
+
func stop() { task?.cancel() }
|
|
3153
|
+
}`,
|
|
3154
|
+
},
|
|
3155
|
+
explanation: "videoFrames emits a cold Flow / AsyncStream — subscribing starts the camera, cancelling the scope/Task stops it. Keep the per-frame work light (or hand it to a worker) so a slow consumer does not backpressure the stream; the transport drops frames on a full buffer rather than blocking the camera. Frame rate x resolution is the battery dial: 2 fps LOW for ML drains negligibly, 24-30 fps HIGH drains in ~30 min — pair high rates with a thermal-driven downgrade.",
|
|
3156
|
+
gotchas: [
|
|
3157
|
+
"Kotlin frame fields are frame.data (ByteArray), frame.width, frame.height, frame.timestampMs — NOT frame.uri / frame.bytes.",
|
|
3158
|
+
"Kotlin VideoFrameConfig is { frameRate, resolution } only; codec + backpressure are iOS-only fields.",
|
|
3159
|
+
"Gated by camera_streaming_enabled + privacy_mode. battery_save_mode = true clamps the stream to LOW + 2 fps regardless of the requested config.",
|
|
3160
|
+
"Background survival needs a camera-typed foreground service on Android 14+ (see getPermissions). The browser simulator does not deliver frames — verify on real hardware or LocalSim.",
|
|
3161
|
+
],
|
|
3162
|
+
relatedFeatures: ["video_frames", "capture_photo"],
|
|
3163
|
+
};
|
|
3164
|
+
const DISPLAY_MEDIA_GALLERY = {
|
|
3165
|
+
pattern: "display_media_gallery",
|
|
3166
|
+
title: "Capture to save to browse on the display (no assistant)",
|
|
3167
|
+
description: "A self-contained media gallery driven by direct display calls plus a button or voice trigger — NO assistant runtime. Capture a photo, persist it in your own store, render a list of cards on the Ray-Ban Display, and on select show it full-surface via image(photo) (the SDK auto-hosts the local capture). Demonstrates the list-detail navigation stack via per-show onBack. (The display_browse_detail example drives the same DSL from an assistant tool — use THIS one when you do not need an LLM.)",
|
|
3168
|
+
code: {
|
|
3169
|
+
kotlin: `import com.extentos.glasses.core.Background
|
|
3170
|
+
import com.extentos.glasses.core.ExtentosGlasses
|
|
3171
|
+
import com.extentos.glasses.core.TextStyle
|
|
3172
|
+
import com.extentos.glasses.core.valueOrNull
|
|
3173
|
+
import kotlinx.coroutines.CoroutineScope
|
|
3174
|
+
import kotlinx.coroutines.Dispatchers
|
|
3175
|
+
import kotlinx.coroutines.SupervisorJob
|
|
3176
|
+
import kotlinx.coroutines.launch
|
|
3177
|
+
|
|
3178
|
+
// 'store' is YOUR persisted gallery (Room / DataStore / files). SavedPhoto.toPhoto()
|
|
3179
|
+
// rebuilds a Photo the same way for show AND forget so both hit the same hosted copy.
|
|
3180
|
+
class GalleryDisplay(
|
|
3181
|
+
private val glasses: ExtentosGlasses,
|
|
3182
|
+
private val store: PhotoStore,
|
|
3183
|
+
private val scope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main),
|
|
3184
|
+
) {
|
|
3185
|
+
fun capture() = scope.launch {
|
|
3186
|
+
val photo = glasses.camera.capturePhoto().valueOrNull() ?: return@launch
|
|
3187
|
+
store.add(photo)
|
|
3188
|
+
showList()
|
|
3189
|
+
}
|
|
3190
|
+
|
|
3191
|
+
// Root view: one card per saved photo. Display is per-DEVICE — gate on isAvailable.
|
|
3192
|
+
fun showList() = scope.launch {
|
|
3193
|
+
if (!glasses.display.isAvailable) return@launch
|
|
3194
|
+
val items = store.all().take(5)
|
|
3195
|
+
glasses.display.show(onBack = { scope.launch { glasses.display.clear() } }) {
|
|
3196
|
+
column(gap = 8, padding = 12) {
|
|
3197
|
+
text("Photos (" + store.all().size + ")", style = TextStyle.HEADING)
|
|
3198
|
+
for (p in items) {
|
|
3199
|
+
column(
|
|
3200
|
+
onClick = { showDetail(p) },
|
|
3201
|
+
id = "photo-" + p.id, // stable id — agents/gestures target it
|
|
3202
|
+
background = Background.CARD,
|
|
3203
|
+
) {
|
|
3204
|
+
text(p.label, style = TextStyle.BODY)
|
|
3205
|
+
}
|
|
3206
|
+
}
|
|
3207
|
+
}
|
|
3208
|
+
}
|
|
3209
|
+
}
|
|
3210
|
+
|
|
3211
|
+
// Detail view: the photo full-surface; back returns to the list.
|
|
3212
|
+
private fun showDetail(p: SavedPhoto) = scope.launch {
|
|
3213
|
+
glasses.display.show(onBack = { showList() }) {
|
|
3214
|
+
image(p.toPhoto()) // auto-hosts the local capture, then renders the hosted URL
|
|
3215
|
+
}
|
|
3216
|
+
}
|
|
3217
|
+
|
|
3218
|
+
// On delete, release the hosted display copy (built the same way as the show).
|
|
3219
|
+
fun delete(p: SavedPhoto) = scope.launch {
|
|
3220
|
+
store.remove(p)
|
|
3221
|
+
glasses.display.forgetHostedImage(p.toPhoto())
|
|
3222
|
+
showList()
|
|
3223
|
+
}
|
|
3224
|
+
}`,
|
|
3225
|
+
swift: `// iOS DisplayClient parity is pending — the display surface is Android-first.
|
|
3226
|
+
// iOS apps gate on glasses.display.isAvailable == false and keep the voice-first
|
|
3227
|
+
// path until the port lands; track it via the cross-platform handoffs.`,
|
|
3228
|
+
},
|
|
3229
|
+
explanation: "No assistant, no LLM — just capturePhoto + your store + the display DSL. show {} replaces the entire surface each call, so re-render the whole view on every transition and own your nav state app-side (here: list vs detail). Each show registers its own onBack: the detail view's onBack re-renders the list; the root's clears. image(photo) / video(clip) auto-host the local capture at show() time (near-instant for a photo, a few seconds for a clip) — call forgetHostedImage / forgetHostedVideo when the user deletes the item so the hosted copy is torn down.",
|
|
3230
|
+
gotchas: [
|
|
3231
|
+
"Gate every display call on glasses.display.isAvailable (Ray-Ban Display yes, Ray-Ban Meta no). A show {} on a display-less device is a safe no-op, but good UX falls back to speak().",
|
|
3232
|
+
"Pass a stable id on every clickable node (id = \"photo-\" + p.id) so injectInput / the pinch gesture route to the right item; without one, clickable containers fall back to positional box-0 / box-1.",
|
|
3233
|
+
"image(photo) / video(clip) host the LOCAL capture (data:/file:) for you — the glasses only fetch http(s) URLs. Build the Photo / VideoClip the same way for show and for forget so both resolve to the same hosted copy.",
|
|
3234
|
+
"onClick is a plain () -> Unit, but show() / clear() are suspend — launch a coroutine inside the handler.",
|
|
3235
|
+
],
|
|
3236
|
+
relatedFeatures: ["display", "capture_photo", "capture_video"],
|
|
3237
|
+
};
|
|
3084
3238
|
export const CODE_EXAMPLES = {
|
|
3085
3239
|
voice_qa_assistant: VOICE_QA_ASSISTANT,
|
|
3086
3240
|
barge_in_speak: BARGE_IN_SPEAK,
|
|
@@ -3093,6 +3247,8 @@ export const CODE_EXAMPLES = {
|
|
|
3093
3247
|
assistant_agent_loop: ASSISTANT_AGENT_LOOP,
|
|
3094
3248
|
agent_driven_e2e_full_loop: AGENT_DRIVEN_E2E_FULL_LOOP,
|
|
3095
3249
|
display_browse_detail: DISPLAY_BROWSE_DETAIL,
|
|
3250
|
+
display_media_gallery: DISPLAY_MEDIA_GALLERY,
|
|
3251
|
+
video_frames_ml: VIDEO_FRAMES_ML,
|
|
3096
3252
|
conversation_agent_loop: CONVERSATION_AGENT_LOOP,
|
|
3097
3253
|
};
|
|
3098
3254
|
export const CODE_EXAMPLE_PATTERNS = Object.keys(CODE_EXAMPLES).sort();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codeExamples.js","sourceRoot":"","sources":["../../../src/tools/data/codeExamples.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,sEAAsE;AACtE,sEAAsE;AACtE,uDAAuD;AACvD,sCAAsC;AACtC,EAAE;AACF,qEAAqE;AACrE,uDAAuD;AACvD,wEAAwE;AACxE,kEAAkE;AAClE,oEAAoE;AACpE,2DAA2D;AAE3D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAuE5C,MAAM,kBAAkB,GAAgB;IACtC,OAAO,EAAE,oBAAoB;IAC7B,KAAK,EAAE,4FAA4F;IACnG,WAAW,EACT,08BAA08B;IAC58B,IAAI,EAAE;QACJ,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwEV;QACE,KAAK,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgET;KACC;IACD,WAAW,EACT,ggCAAggC;IAClgC,OAAO,EAAE;QACP,yXAAyX;QACzX,gbAAgb;QAChb,qXAAqX;QACrX,mSAAmS;QACnS,oSAAoS;QACpS,+SAA+S;QAC/S,msBAAmsB;QACnsB,sIAAsI;QACtI,+HAA+H;QAC/H,yKAAyK;QACzK,kyBAAkyB;QAClyB,0UAA0U;KAC3U;IACD,eAAe,EAAE,CAAC,eAAe,EAAE,2BAA2B,EAAE,cAAc,CAAC;CAChF,CAAC;AAEF,MAAM,cAAc,GAAgB;IAClC,OAAO,EAAE,gBAAgB;IACzB,KAAK,EAAE,gDAAgD;IACvD,WAAW,EACT,itBAAitB;IACntB,IAAI,EAAE;QACJ,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BV;QACE,KAAK,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgCT;KACC;IACD,WAAW,EACT,+ZAA+Z;IACja,OAAO,EAAE;QACP,8IAA8I;QAC9I,6PAA6P;QAC7P,kLAAkL;KACnL;IACD,eAAe,EAAE,CAAC,2BAA2B,CAAC;CAC/C,CAAC;AAEF,MAAM,oBAAoB,GAAgB;IACxC,OAAO,EAAE,sBAAsB;IAC/B,KAAK,EAAE,gDAAgD;IACvD,WAAW,EACT,swBAAswB;IACxwB,IAAI,EAAE;QACJ,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6DV;QACE,KAAK,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkDT;KACC;IACD,WAAW,EACT,gWAAgW;IAClW,OAAO,EAAE;QACP,4OAA4O;QAC5O,4KAA4K;QAC5K,yGAAyG;QACzG,iRAAiR;QACjR,iMAAiM;QACjM,gRAAgR;QAChR,shBAAshB;KACvhB;IACD,eAAe,EAAE,CAAC,eAAe,EAAE,eAAe,EAAE,2BAA2B,CAAC;CACjF,CAAC;AAEF,MAAM,qBAAqB,GAAgB;IACzC,OAAO,EAAE,uBAAuB;IAChC,KAAK,EAAE,+CAA+C;IACtD,WAAW,EACT,0sBAA0sB;IAC5sB,IAAI,EAAE;QACJ,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBA4BU;QAClB,KAAK,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;yBAyBc;KACtB;IACD,WAAW,EACT,4QAA4Q;IAC9Q,OAAO,EAAE;QACP,gNAAgN;QAChN,2KAA2K;QAC3K,6LAA6L;KAC9L;IACD,eAAe,EAAE,CAAC,2BAA2B,CAAC;CAC/C,CAAC;AAEF,MAAM,WAAW,GAAgB;IAC/B,OAAO,EAAE,aAAa;IACtB,KAAK,EAAE,sCAAsC;IAC7C,WAAW,EACT,
|
|
1
|
+
{"version":3,"file":"codeExamples.js","sourceRoot":"","sources":["../../../src/tools/data/codeExamples.ts"],"names":[],"mappings":"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"}
|