@extentos/mcp-server 0.0.71 → 0.0.73

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.
@@ -1 +1 @@
1
- {"version":3,"file":"codeExamples.d.ts","sourceRoot":"","sources":["../../../src/tools/data/codeExamples.ts"],"names":[],"mappings":"AAaA,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;CAC3B;AA6zBD,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAQrD,CAAC;AAEF,eAAO,MAAM,qBAAqB,UAAoC,CAAC"}
1
+ {"version":3,"file":"codeExamples.d.ts","sourceRoot":"","sources":["../../../src/tools/data/codeExamples.ts"],"names":[],"mappings":"AAaA,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;CAC3B;AAg1BD,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAQrD,CAAC;AAEF,eAAO,MAAM,qBAAqB,UAAoC,CAAC"}
@@ -17,7 +17,6 @@ const VOICE_QA_ASSISTANT = {
17
17
  code: {
18
18
  kotlin: `import com.extentos.glasses.core.AudioRecordConfig
19
19
  import com.extentos.glasses.core.ExtentosGlasses
20
- import com.extentos.glasses.core.Transcript
21
20
  import com.extentos.glasses.core.valueOrNull
22
21
 
23
22
  class CoachHandler(
@@ -27,15 +26,27 @@ class CoachHandler(
27
26
  ) {
28
27
  private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
29
28
 
30
- fun start() = scope.launch {
31
- glasses.audio.transcriptions().collect { t ->
32
- if (t !is Transcript.Final) return@collect
33
- if ("ask my coach" !in t.text.lowercase()) return@collect
34
-
29
+ fun start() {
30
+ // glasses.voice.onPhrase registers a wake phrase + handler in one
31
+ // call. The library subscribes to transcriptions() under the
32
+ // hood; while the handler is running, "isActive" flips true so
33
+ // any declared stops can fire. Registration also surfaces the
34
+ // phrase on the connection page (\"Say to me: 'ask my coach'\")
35
+ // and the simulator's right-rail click-to-fire chips.
36
+ //
37
+ // For complex matching (regex, stateful guards), subscribe to
38
+ // glasses.audio.transcriptions() directly and optionally call
39
+ // glasses.voice.registerHint(...) to keep UI affordances in
40
+ // sync. See the matcher gotcha below.
41
+ glasses.voice.onPhrase(
42
+ phrase = "ask my coach",
43
+ label = "Ask",
44
+ stops = listOf("stop"),
45
+ ) {
35
46
  glasses.audio.speak("What would you like to know?")
36
47
 
37
- // Multi-turn loop: keep listening until user goes silent or
38
- // says "stop". Each turn captures one utterance via the
48
+ // Multi-turn loop: keep listening until user goes silent
49
+ // or says "stop". Each turn captures one utterance via the
39
50
  // built-in silence-VAD (silence_timeout_seconds = 3).
40
51
  while (currentCoroutineContext().isActive) {
41
52
  val recording = glasses.audio.recordDiscrete(
@@ -60,7 +71,7 @@ class CoachHandler(
60
71
  private let glasses: any ExtentosGlasses
61
72
  private let anthropic: AnthropicClient
62
73
  private let workouts: WorkoutRepository
63
- private var task: Task<Void, Never>?
74
+ private var registration: VoiceRegistration?
64
75
 
65
76
  init(glasses: any ExtentosGlasses, anthropic: AnthropicClient, workouts: WorkoutRepository) {
66
77
  self.glasses = glasses
@@ -69,41 +80,49 @@ class CoachHandler(
69
80
  }
70
81
 
71
82
  func start() {
72
- task = Task { [glasses, anthropic, workouts] in
73
- for await t in glasses.audio.transcriptions() {
74
- guard case .final(let text, _, _, _) = t,
75
- text.lowercased().contains("ask my coach")
76
- else { continue }
83
+ // glasses.voice.onPhrase mirrors the Android API: register the
84
+ // wake phrase + handler in one call, plus optional 'stops' for
85
+ // the connection page / simulator UI to render nested affordances.
86
+ registration = glasses.voice.onPhrase(
87
+ phrase: "ask my coach",
88
+ label: "Ask",
89
+ stops: ["stop"]
90
+ ) { [weak self] in
91
+ await self?.runConversation()
92
+ }
93
+ }
77
94
 
78
- _ = await glasses.audio.speak("What would you like to know?")
95
+ private func runConversation() async {
96
+ _ = await glasses.audio.speak("What would you like to know?")
79
97
 
80
- // Multi-turn loop — silence-VAD per turn.
81
- while !Task.isCancelled {
82
- let result = await glasses.audio.recordDiscrete(
83
- config: AudioRecordConfig(silenceTimeoutSeconds: 3)
84
- )
85
- guard case .success(let recording) = result else { break }
98
+ // Multi-turn loop — silence-VAD per turn.
99
+ while !Task.isCancelled {
100
+ let result = await glasses.audio.recordDiscrete(
101
+ config: AudioRecordConfig(silenceTimeoutSeconds: 3)
102
+ )
103
+ guard case .success(let recording) = result else { break }
86
104
 
87
- let question = recording.transcript.trimmingCharacters(in: .whitespaces)
88
- if question.isEmpty || question.lowercased().contains("stop") { break }
105
+ let question = recording.transcript.trimmingCharacters(in: .whitespaces)
106
+ if question.isEmpty || question.lowercased().contains("stop") { break }
89
107
 
90
- if let answer = try? await anthropic.ask(
91
- question: question,
92
- workoutHistory: workouts.recent()
93
- ) {
94
- _ = await glasses.audio.speak(answer)
95
- }
96
- }
108
+ if let answer = try? await anthropic.ask(
109
+ question: question,
110
+ workoutHistory: workouts.recent()
111
+ ) {
112
+ _ = await glasses.audio.speak(answer)
97
113
  }
98
114
  }
99
115
  }
100
116
 
101
- func stop() { task?.cancel() }
117
+ func stop() { registration?.cancel() }
102
118
  }`,
103
119
  },
104
- explanation: "Three SDK primitives wired together: (1) glasses.audio.transcriptions() continuous Flow of partial+final transcripts; customer matches the wake phrase via plain string contains. (2) glasses.audio.recordDiscrete(silenceTimeoutSeconds) — one-shot capture that auto-stops on N seconds of silence and returns the transcribed text. (3) glasses.audio.speak() — TTS via the platform engine. The while-loop is multi-turn voice mode (the F23 friction-log finding); break-condition is silence (recordDiscrete returns null), an empty utterance, or the user saying 'stop'.",
120
+ explanation: "Four SDK primitives wired together: (1) glasses.voice.onPhrase(phrase, label, stops) { handler } — sugar over glasses.audio.transcriptions() that surfaces the phrase on the connection page and the simulator's click-to-fire panel AND auto-cancels the handler when any `stops` phrase fires mid-execution. Matches by case-insensitive substring on FINAL transcripts; runs the handler with isActive=true so nested stops appear armed in the simulator. (2) glasses.audio.recordDiscrete(silenceTimeoutSeconds) — one-shot capture that auto-stops on N seconds of silence and returns the transcribed text. (3) glasses.audio.speak() — TTS via the platform engine. (4) Customers who need regex / stateful matching can subscribe to glasses.audio.transcriptions() directly and optionally call glasses.voice.registerHint(...) to keep the UI affordances in sync. The while-loop is multi-turn voice mode (the F23 friction-log finding); break-condition is silence (recordDiscrete returns null), an empty utterance, or the user saying 'stop'.",
105
121
  gotchas: [
106
- "transcriptions() yields BOTH partial and final transcripts Transcript is a sealed interface (Partial | Final). Always pattern-match `is Transcript.Final` before reading t.text, or you'll fire the wake on a half-heard phrase. Swift uses .partial/.final enum cases.",
122
+ "glasses.voice.onPhrase auto-cancels the handler when any `stops` phrase fires (case-insensitive substring on FINAL transcripts). Wrap cleanup that itself suspends (releasing a MediaPlayer, draining a queue) in withContext(NonCancellable) { ... } inside your finally block same pattern as any cancellable coroutine. For non-suspending cleanup, a plain try/finally is enough.",
123
+ "glasses.voice.onPhrase wraps glasses.audio.transcriptions() with a default case-insensitive `contains` match. For exact / regex / stateful matching, drop down to transcriptions().collect { ... is Transcript.Final ... } and (optionally) call glasses.voice.registerHint(phrase, label, stops) to keep the UI affordances visible. Both forms coexist; raw-mode handlers do NOT get the stops-cancellation treatment — write that yourself.",
124
+ "Voice hint cards on the simulator's right rail fire by injecting the phrase as a synthetic stt_transcript — the dispatch path matches a real utterance bit-for-bit, so any matcher you write (onPhrase or raw) is exercised identically in sim and production. Clicking a STOP chip while the parent is active fires the cancellation path the same way a spoken stop phrase would.",
125
+ "If you need raw access: transcriptions() yields BOTH partial and final transcripts — Transcript is a sealed interface (Partial | Final). Always pattern-match `is Transcript.Final` before reading t.text, or you'll fire the wake on a half-heard phrase. Swift uses .partial/.final enum cases.",
107
126
  "recordDiscrete returns ExtentosResult<AudioRecording, AudioError> — unwrap with .valueOrNull() (Kotlin) or `case .success(let r)` (Swift). The Kotlin Result/getOrNull pattern from kotlin.Result does NOT apply here; ExtentosResult is its own type defined in com.extentos.glasses.core.Errors.",
108
127
  "recordDiscrete blocks until silence — call it from a coroutine/Task that's safe to suspend. Inside the while-loop is fine because it's already in a launched scope. See getCapabilityGuide('record_audio') for the full silence-VAD gotchas (maxDurationSeconds cap, raw_audio_uri shape, HFP routing).",
109
128
  "Re-entrancy: the OUTER transcriptions() collector and the INNER recordDiscrete BOTH talk to the platform STT engine, but on Meta DAT they share the same mic stream — recordDiscrete owns it exclusively for the duration of its call. While recordDiscrete is capturing, the outer transcriptions Flow may pause (no emissions arrive) and then resume after recordDiscrete returns. Implication: the wake-phrase matcher won't re-fire on the recorded utterance unless you LEAVE the inner loop and the user re-says the wake phrase. The outer collector resuming mid-utterance after recordDiscrete returns is also harmless — the partial that triggers wake-match is the user's NEXT utterance, not the previous question.",
@@ -1 +1 @@
1
- {"version":3,"file":"codeExamples.js","sourceRoot":"","sources":["../../../src/tools/data/codeExamples.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"codeExamples.js","sourceRoot":"","sources":["../../../src/tools/data/codeExamples.ts"],"names":[],"mappings":"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"}
@@ -6,13 +6,13 @@
6
6
  // scaffold a project pointing at 1.0.0 (no probe code) while running
7
7
  // 0.0.7+ server-side smarts that needed 1.1.x to function.
8
8
  //
9
- // Pre-public-Maven note: 1.1.29-pair currently lives only on the dev's
9
+ // Pre-public-Maven note: 1.1.31-pair currently lives only on the dev's
10
10
  // mavenLocal (./gradlew :glasses-core:publishToMavenLocal). Until a
11
11
  // public Maven Central / JitPack publish lands, scaffolded projects
12
12
  // require the dev to run mavenLocal-publish first. Document next to
13
13
  // the dependency notation in generateConnectionModule.
14
14
  export const VERSION_INFO = {
15
- latestStable: "1.1.29-pair",
15
+ latestStable: "1.1.31-pair",
16
16
  specVersion: "1.0",
17
17
  android: {
18
18
  minimumSdk: 31,
@@ -34,7 +34,7 @@ export const VERSION_INFO = {
34
34
  kotlinVersion: "2.1.20",
35
35
  // Toolchain minimums (F-R4-8 from DOGFOOD_R4). The library's transitive
36
36
  // Compose deps determine the floor:
37
- // - com.extentos:glasses-ui:1.1.29-pair brings in androidx.compose.* 1.9.0
37
+ // - com.extentos:glasses-ui:1.1.31-pair brings in androidx.compose.* 1.9.0
38
38
  // (via compose-bom 2024.10.00 and direct deps)
39
39
  // - Compose 1.9.0 AAR-metadata declares "requires AGP >= 8.6.0"
40
40
  // - AGP 8.6+ requires Gradle 8.7+ (Android Gradle Plugin compatibility table)
@@ -58,13 +58,13 @@ export const VERSION_INFO = {
58
58
  },
59
59
  artifacts: {
60
60
  android: {
61
- core: "com.extentos:glasses:1.1.29-pair",
62
- ui: "com.extentos:glasses-ui:1.1.29-pair",
63
- debug: "com.extentos:glasses-debug:1.1.29-pair",
61
+ core: "com.extentos:glasses:1.1.31-pair",
62
+ ui: "com.extentos:glasses-ui:1.1.31-pair",
63
+ debug: "com.extentos:glasses-debug:1.1.31-pair",
64
64
  },
65
65
  ios: {
66
66
  package: "https://github.com/extentos/swift-glasses",
67
- version: "1.1.29-pair",
67
+ version: "1.1.31-pair",
68
68
  products: ["GlassesCore", "GlassesUI", "GlassesDebug", "GlassesLifecycle", "GlassesTesting"],
69
69
  },
70
70
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@extentos/mcp-server",
3
- "version": "0.0.71",
3
+ "version": "0.0.73",
4
4
  "description": "Extentos MCP server — deterministic tools for building Meta-glasses apps.",
5
5
  "type": "module",
6
6
  "bin": {