@extentos/mcp-server 0.0.80 → 0.0.82
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/codeExamples.d.ts.map +1 -1
- package/dist/tools/data/codeExamples.js +296 -12
- package/dist/tools/data/codeExamples.js.map +1 -1
- package/dist/tools/data/version.js +7 -7
- package/dist/tools/definitions.d.ts.map +1 -1
- package/dist/tools/definitions.js +3 -2
- package/dist/tools/definitions.js.map +1 -1
- package/dist/tools/docs/index.d.ts.map +1 -1
- package/dist/tools/docs/index.js +105 -0
- package/dist/tools/docs/index.js.map +1 -1
- package/dist/tools/handlers/createSimulatorSession.d.ts.map +1 -1
- package/dist/tools/handlers/createSimulatorSession.js +24 -3
- package/dist/tools/handlers/createSimulatorSession.js.map +1 -1
- package/dist/tools/handlers/getSimulatorStatus.d.ts.map +1 -1
- package/dist/tools/handlers/getSimulatorStatus.js +37 -2
- package/dist/tools/handlers/getSimulatorStatus.js.map +1 -1
- package/dist/tools/handlers/validateIntegration.d.ts.map +1 -1
- package/dist/tools/handlers/validateIntegration.js +36 -7
- package/dist/tools/handlers/validateIntegration.js.map +1 -1
- package/package.json +1 -1
|
@@ -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;AAu/CD,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CASrD,CAAC;AAEF,eAAO,MAAM,qBAAqB,UAAoC,CAAC"}
|
|
@@ -64,9 +64,15 @@ class CoachHandler(
|
|
|
64
64
|
// going to help?). Compile-time exhaustive \`when\` makes
|
|
65
65
|
// adding a new variant break every caller until they
|
|
66
66
|
// handle it explicitly.
|
|
67
|
+
// workouts.systemPrompt() flattens the customer's data layer
|
|
68
|
+
// into a grounding-context string (today's date, recent N
|
|
69
|
+
// sets formatted compactly, etc.) — fed via Anthropic's
|
|
70
|
+
// system-prompt slot so the coach references real records,
|
|
71
|
+
// not generic advice. The customer owns the format and the
|
|
72
|
+
// method name; the contract is "returns a String."
|
|
67
73
|
val spoken = when (val r = anthropic.ask(
|
|
68
74
|
question = question,
|
|
69
|
-
|
|
75
|
+
system = workouts.systemPrompt(),
|
|
70
76
|
)) {
|
|
71
77
|
is LlmResult.Ok -> r.text
|
|
72
78
|
LlmResult.AuthFailure -> "Your Anthropic key isn't set up — add it to local.properties and rebuild."
|
|
@@ -125,8 +131,14 @@ class CoachHandler(
|
|
|
125
131
|
// them into one "try again" line confuses users and the
|
|
126
132
|
// debugging agent. Exhaustive switch breaks compilation if a
|
|
127
133
|
// new variant is added — that's the point.
|
|
134
|
+
// workouts.systemPrompt() flattens the customer's data layer
|
|
135
|
+
// into a grounding-context string (today's date, recent N sets
|
|
136
|
+
// formatted compactly, etc.) — fed via Anthropic's system-prompt
|
|
137
|
+
// slot so the coach references real records, not generic advice.
|
|
138
|
+
// The customer owns the format and the method name; the contract
|
|
139
|
+
// is "returns a String."
|
|
128
140
|
let spoken: String
|
|
129
|
-
switch await anthropic.ask(question: question,
|
|
141
|
+
switch await anthropic.ask(question: question, system: workouts.systemPrompt()) {
|
|
130
142
|
case .ok(let text): spoken = text
|
|
131
143
|
case .authFailure: spoken = "Your Anthropic key isn't set up — check Info.plist."
|
|
132
144
|
case .connectivity: spoken = "I can't reach the network. Check your connection."
|
|
@@ -153,7 +165,7 @@ class CoachHandler(
|
|
|
153
165
|
"Don't subscribe to transcriptions() inside the while-loop — that creates a new recognizer per turn. Subscribe once outside the loop.",
|
|
154
166
|
"speak() blocks until done by default. If you want speak + listen-for-barge-in simultaneously, see the barge_in_speak pattern.",
|
|
155
167
|
"BuildConfig API-key fields don't reflect rotations because kotlinc inlines them at compile time. Use resValue / R.string.X for Android secrets. See getCredentialGuide.",
|
|
156
|
-
"AnthropicClient is
|
|
168
|
+
"AnthropicClient is the CANONICAL paste-ready client from getCodeExample('byok_anthropic') — composes here unchanged. The `ask(question, history, system)` signature in byok_anthropic accepts the `system =` parameter this example passes; no signature reconciliation needed. WorkoutRepository is YOUR app's data layer; the example calls `workouts.systemPrompt(): String` which returns the grounding-context block (today's date, recent N sets formatted compactly) that gets fed via Anthropic's `system` slot so the coach's answers reference real records instead of generic advice. The contract is: returns a String. Name + format are yours — Room + a custom flattener, DataStore + a JSON-to-prose converter, anything. F-R5-01 — previously the two examples used different `ask()` shapes; now they compose.",
|
|
157
169
|
"ask() returns LlmResult — 6 variants: Ok / AuthFailure / Connectivity / Transient / ClientBug / Empty. Pattern-match each into a distinct spoken line. R2 F-R2-10 + R3 F-R3-10: collapsing them obscures both the user's remediation (was it wifi? key? AI?) and the debugging agent's signal (was a retry going to help?).",
|
|
158
170
|
],
|
|
159
171
|
relatedFeatures: ["voice_command", "transcription_incremental", "record_audio"],
|
|
@@ -596,7 +608,7 @@ struct ContentView: View {
|
|
|
596
608
|
const BYOK_ANTHROPIC = {
|
|
597
609
|
pattern: "byok_anthropic",
|
|
598
610
|
title: "BYOK Anthropic Claude API client (text + Vision, OkHttp / URLSession, with retry + observability)",
|
|
599
|
-
description: "Minimal AnthropicClient that voice_qa_assistant and photo_describe_voice reference. Two methods: `ask(question, history)` for text-only Q&A, `describe(imageBase64, mediaType, prompt)` for Claude Vision (image content blocks). There is no first-party Anthropic Kotlin SDK; this is the canonical OkHttp + kotlinx.serialization wrapper around POST /v1/messages. iOS uses URLSession + Codable. Returns LlmResult (Ok / AuthFailure / Connectivity / Transient / ClientBug / Empty) — distinct failure variants for distinct user-facing remediations. Built-in retry-with-backoff (200ms / 800ms / 3.2s, 3 attempts) for Transient (429 + 5xx) and Connectivity (IOException) failures so most upstream blips never reach the caller. Optional `observability: glasses.observability` wiring — pass it and every call surfaces under getEventLog's 'ai' filter chip. Paste, then wire the API key through resValue (Android) / Info.plist (iOS) per getCredentialGuide.",
|
|
611
|
+
description: "Minimal AnthropicClient that voice_qa_assistant and photo_describe_voice reference. Two methods: `ask(question, history, system)` for text-only Q&A — the `system` parameter is Anthropic's system-prompt slot, where you feed grounding context (a flattened representation of your app's data, today's date, role instructions) so the AI's answers derive from real records rather than generic prose — and `describe(imageBase64, mediaType, prompt, system)` for Claude Vision (image content blocks). There is no first-party Anthropic Kotlin SDK; this is the canonical OkHttp + kotlinx.serialization wrapper around POST /v1/messages. iOS uses URLSession + Codable. Returns LlmResult (Ok / AuthFailure / Connectivity / Transient / ClientBug / Empty) — distinct failure variants for distinct user-facing remediations. Built-in retry-with-backoff (200ms / 800ms / 3.2s, 3 attempts) for Transient (429 + 5xx) and Connectivity (IOException) failures so most upstream blips never reach the caller. Optional `observability: glasses.observability` wiring — pass it and every call surfaces under getEventLog's 'ai' filter chip. Paste, then wire the API key through resValue (Android) / Info.plist (iOS) per getCredentialGuide. F-R5-01 — ask() exposes `system` so voice_qa_assistant composes against this client unchanged.",
|
|
600
612
|
code: {
|
|
601
613
|
kotlin: `import com.extentos.glasses.core.ObservabilityClient
|
|
602
614
|
import java.io.IOException
|
|
@@ -723,8 +735,19 @@ class AnthropicClient(
|
|
|
723
735
|
// ---- Public API ----
|
|
724
736
|
|
|
725
737
|
/** Text-only Q&A. Anthropic's content field accepts either a bare String or a
|
|
726
|
-
* list of ContentBlock; we use the list shape so this client can also do Vision.
|
|
727
|
-
|
|
738
|
+
* list of ContentBlock; we use the list shape so this client can also do Vision.
|
|
739
|
+
*
|
|
740
|
+
* \`history\` is prior user turns concatenated as user messages — useful for
|
|
741
|
+
* short multi-turn loops where the user's earlier questions matter.
|
|
742
|
+
* \`system\` is Anthropic's system-prompt slot — feed grounding context
|
|
743
|
+
* here (a flattened view of your app's data, today's date, role
|
|
744
|
+
* instructions) so the AI's answers reference real records instead of
|
|
745
|
+
* generic advice. F-R5-01 — composes with voice_qa_assistant unchanged. */
|
|
746
|
+
suspend fun ask(
|
|
747
|
+
question: String,
|
|
748
|
+
history: List<String> = emptyList(),
|
|
749
|
+
system: String? = null,
|
|
750
|
+
): LlmResult =
|
|
728
751
|
wrap("anthropic.ask") {
|
|
729
752
|
post(
|
|
730
753
|
messages = buildList {
|
|
@@ -733,6 +756,7 @@ class AnthropicClient(
|
|
|
733
756
|
}
|
|
734
757
|
add(Message("user", listOf(ContentBlock.Text(question))))
|
|
735
758
|
},
|
|
759
|
+
system = system,
|
|
736
760
|
)
|
|
737
761
|
}
|
|
738
762
|
|
|
@@ -877,8 +901,11 @@ class AnthropicClient(
|
|
|
877
901
|
// observability = glasses.observability, // surfaces in getEventLog "ai" chip
|
|
878
902
|
// )
|
|
879
903
|
//
|
|
880
|
-
// // text:
|
|
881
|
-
// val spoken = when (val r = anthropic.ask(
|
|
904
|
+
// // text — grounded in your app's data via the system slot:
|
|
905
|
+
// val spoken = when (val r = anthropic.ask(
|
|
906
|
+
// question = "How many bench reps did I do this week?",
|
|
907
|
+
// system = workoutRepo.systemPrompt(), // your app's grounding context
|
|
908
|
+
// )) {
|
|
882
909
|
// is LlmResult.Ok -> r.text
|
|
883
910
|
// LlmResult.AuthFailure -> "Your Anthropic key isn't set up — add it to local.properties and rebuild."
|
|
884
911
|
// LlmResult.Connectivity -> "I can't reach the network. Check your connection."
|
|
@@ -1006,13 +1033,24 @@ actor AnthropicClient {
|
|
|
1006
1033
|
// ---- Public API ----
|
|
1007
1034
|
|
|
1008
1035
|
/// Text-only Q&A. Non-throwing: any error becomes an LlmResult case.
|
|
1009
|
-
|
|
1036
|
+
///
|
|
1037
|
+
/// \`history\` is prior user turns concatenated as user messages — useful
|
|
1038
|
+
/// for short multi-turn loops where earlier questions matter.
|
|
1039
|
+
/// \`system\` is Anthropic's system-prompt slot — feed grounding context
|
|
1040
|
+
/// here (today's date, a flattened view of your app's data, role
|
|
1041
|
+
/// instructions) so answers reference real records instead of generic
|
|
1042
|
+
/// advice. F-R5-01 — composes with voice_qa_assistant unchanged.
|
|
1043
|
+
func ask(
|
|
1044
|
+
question: String,
|
|
1045
|
+
history: [String] = [],
|
|
1046
|
+
system: String? = nil
|
|
1047
|
+
) async -> LlmResult {
|
|
1010
1048
|
var messages = history.map {
|
|
1011
1049
|
Message(role: "user", content: [.text($0)])
|
|
1012
1050
|
}
|
|
1013
1051
|
messages.append(Message(role: "user", content: [.text(question)]))
|
|
1014
1052
|
return await wrap(label: "anthropic.ask") {
|
|
1015
|
-
await post(messages: messages, system:
|
|
1053
|
+
await post(messages: messages, system: system)
|
|
1016
1054
|
}
|
|
1017
1055
|
}
|
|
1018
1056
|
|
|
@@ -1152,9 +1190,12 @@ actor AnthropicClient {
|
|
|
1152
1190
|
// observability: glasses.observability // surfaces in getEventLog "ai" chip
|
|
1153
1191
|
// )
|
|
1154
1192
|
//
|
|
1155
|
-
// // text:
|
|
1193
|
+
// // text — grounded in your app's data via the system slot:
|
|
1156
1194
|
// let spoken: String
|
|
1157
|
-
// switch await anthropic.ask(
|
|
1195
|
+
// switch await anthropic.ask(
|
|
1196
|
+
// question: "How many bench reps did I do this week?",
|
|
1197
|
+
// system: workoutRepo.systemPrompt() // your app's grounding context
|
|
1198
|
+
// ) {
|
|
1158
1199
|
// case .ok(let text): spoken = text
|
|
1159
1200
|
// case .authFailure: spoken = "Your Anthropic key isn't set up — check Info.plist."
|
|
1160
1201
|
// case .connectivity: spoken = "I can't reach the network. Check your connection."
|
|
@@ -1186,6 +1227,7 @@ actor AnthropicClient {
|
|
|
1186
1227
|
"Vision content-block shape: each user message's `content` is a LIST of blocks. Image block: `{ type: \"image\", source: { type: \"base64\", media_type, data } }`. Text block: `{ type: \"text\", text }`. Image first, then text prompt — Claude reads them in order. media_type must match what Photos.mediaTypeFromUri returned (image/jpeg, image/png, image/webp).",
|
|
1187
1228
|
"max_tokens defaults to 1024 here — bump for longer answers, but the glasses TTS engine will speak whatever comes back, so consider trimming on your side before speak() rather than asking for unbounded length. For Vision specifically, 256 is often plenty (you typically want a short action: hit / stand / split, not paragraphs).",
|
|
1188
1229
|
"history is a list of prior user turns. For real multi-turn you'll likely want to interleave 'user' and 'assistant' roles — extend the schema's role enum and pass alternating turns.",
|
|
1230
|
+
"`system` vs `history` — both feed information into the prompt, but they serve different roles. `system` is Anthropic's system-prompt slot: stable grounding context that applies to EVERY turn (today's date, a flattened view of your app's data, role instructions like \"be brief, you're a fitness coach\"). `history` is a list of prior USER utterances concatenated into the messages array; useful for short multi-turn loops where what the user just said matters to the next answer. Rule of thumb: data → `system`; conversation continuity → `history`. The voice_qa_assistant pattern passes workout records via `system` so the coach grounds in real numbers across every turn, even when `history` is empty.",
|
|
1189
1231
|
"OkHttp's .execute() blocks the calling thread — wrapping in withContext(Dispatchers.IO) keeps it off the main dispatcher. Don't call ask() / describe() from the UI thread directly.",
|
|
1190
1232
|
"Vision LLM response p95 is 2-8 seconds. Play an earcon (`glasses.audio.earcon(EarconSound.START)`) BEFORE the call so the user knows the request fired. The retry-with-backoff loop adds up to ~4.2s in the worst-case Transient path, so plan UX timing accordingly (or lower maxAttempts).",
|
|
1191
1233
|
"LlmResult has 6 variants — Ok / AuthFailure / Connectivity / Transient / ClientBug / Empty. Each has a distinct user-facing message; don't collapse them. The compile-time exhaustive `when` (Kotlin) / `switch` (Swift) makes the requirement explicit — adding a new variant breaks every caller until they handle it. Don't try/catch around the call; the sealed type IS the error channel.",
|
|
@@ -1230,6 +1272,247 @@ actor AnthropicClient {
|
|
|
1230
1272
|
],
|
|
1231
1273
|
},
|
|
1232
1274
|
};
|
|
1275
|
+
const AGENT_TEST_LOOP = {
|
|
1276
|
+
pattern: "agent_test_loop",
|
|
1277
|
+
title: "Agent-driven E2E test loop (dual-layer assertion)",
|
|
1278
|
+
description: "How an AI coding agent verifies its own generated handler end-to-end from the same MCP session that scaffolded it — no human in the loop. Pairs the canonical `voice_qa_assistant` handler with a test driver that asserts against THREE independent surfaces: the simulator event log (`getEventLog`), the emulator's persisted state (Room / SQLite via `adb run-as`), and the rendered UI (`adb screencap`). When all three agree, the flow really worked — not just at the protocol layer. See `searchDocs(topic: 'agent_e2e_testing')` for the conceptual framing.",
|
|
1279
|
+
code: {
|
|
1280
|
+
kotlin: `// HANDLER UNDER TEST — the agent writes this against the SDK.
|
|
1281
|
+
// Two assertion-relevant points marked **ASSERT** in comments below.
|
|
1282
|
+
import com.extentos.glasses.core.AudioRecordConfig
|
|
1283
|
+
import com.extentos.glasses.core.ExtentosGlasses
|
|
1284
|
+
import com.extentos.glasses.core.Transcript
|
|
1285
|
+
import com.extentos.glasses.core.valueOrNull
|
|
1286
|
+
import kotlinx.coroutines.flow.filterIsInstance
|
|
1287
|
+
import kotlinx.coroutines.flow.first
|
|
1288
|
+
|
|
1289
|
+
@Entity(tableName = "coaching_turns")
|
|
1290
|
+
data class CoachingTurn(
|
|
1291
|
+
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
|
1292
|
+
val sessionId: String,
|
|
1293
|
+
val role: String, // "user" or "assistant"
|
|
1294
|
+
val text: String,
|
|
1295
|
+
val createdAt: Long = System.currentTimeMillis(),
|
|
1296
|
+
)
|
|
1297
|
+
|
|
1298
|
+
@Dao
|
|
1299
|
+
interface CoachingTurnDao {
|
|
1300
|
+
@Insert suspend fun insert(turn: CoachingTurn)
|
|
1301
|
+
@Query("SELECT * FROM coaching_turns ORDER BY id") suspend fun all(): List<CoachingTurn>
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
class CoachHandler(
|
|
1305
|
+
private val glasses: ExtentosGlasses,
|
|
1306
|
+
private val anthropic: AnthropicClient,
|
|
1307
|
+
private val dao: CoachingTurnDao,
|
|
1308
|
+
) {
|
|
1309
|
+
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
|
|
1310
|
+
|
|
1311
|
+
fun start() = scope.launch {
|
|
1312
|
+
glasses.audio.transcriptions().filterIsInstance<Transcript.Final>().collect { t ->
|
|
1313
|
+
if (!t.text.lowercase().contains("ask my coach")) return@collect
|
|
1314
|
+
handleWake()
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
private suspend fun handleWake() {
|
|
1319
|
+
val sessionId = UUID.randomUUID().toString()
|
|
1320
|
+
glasses.audio.speak("Yes coach?", SpeakConfig())
|
|
1321
|
+
|
|
1322
|
+
// **ASSERT POINT 1** — handler enters recordDiscrete; agent's
|
|
1323
|
+
// injectTranscript will satisfy this via the F-R5-03 race fix.
|
|
1324
|
+
val recording = glasses.audio.recordDiscrete(AudioRecordConfig(silenceTimeoutSeconds = 2.0)).valueOrNull()
|
|
1325
|
+
?: return
|
|
1326
|
+
if (recording.transcript.isBlank()) return
|
|
1327
|
+
|
|
1328
|
+
// **ASSERT POINT 2** — user turn persisted BEFORE the LLM call.
|
|
1329
|
+
// Agent's DB-read assertion reads this row.
|
|
1330
|
+
dao.insert(CoachingTurn(sessionId = sessionId, role = "user", text = recording.transcript))
|
|
1331
|
+
|
|
1332
|
+
val answer = glasses.observability.aiCall("coach_q", mapOf("session" to sessionId)) {
|
|
1333
|
+
anthropic.complete(recording.transcript)
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1336
|
+
// **ASSERT POINT 3** — assistant turn persisted AFTER the LLM call.
|
|
1337
|
+
// Agent asserts the row exists with the answer text.
|
|
1338
|
+
dao.insert(CoachingTurn(sessionId = sessionId, role = "assistant", text = answer))
|
|
1339
|
+
|
|
1340
|
+
glasses.audio.speak(answer, SpeakConfig())
|
|
1341
|
+
}
|
|
1342
|
+
}`,
|
|
1343
|
+
swift: `// HANDLER UNDER TEST — the agent writes this against the SDK.
|
|
1344
|
+
// Three assertion-relevant points marked **ASSERT** in comments below.
|
|
1345
|
+
import Extentos
|
|
1346
|
+
import GRDB // or Core Data; this example uses GRDB for sqlite-readable schema
|
|
1347
|
+
|
|
1348
|
+
struct CoachingTurn: Codable, FetchableRecord, PersistableRecord {
|
|
1349
|
+
var id: Int64?
|
|
1350
|
+
var sessionId: String
|
|
1351
|
+
var role: String // "user" or "assistant"
|
|
1352
|
+
var text: String
|
|
1353
|
+
var createdAt: Date
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
actor CoachHandler {
|
|
1357
|
+
let glasses: Extentos
|
|
1358
|
+
let anthropic: AnthropicClient
|
|
1359
|
+
let db: DatabaseQueue
|
|
1360
|
+
|
|
1361
|
+
func start() async {
|
|
1362
|
+
for await transcript in glasses.audio.transcriptions() {
|
|
1363
|
+
guard case .final(let t) = transcript,
|
|
1364
|
+
t.text.lowercased().contains("ask my coach") else { continue }
|
|
1365
|
+
await handleWake()
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1369
|
+
func handleWake() async {
|
|
1370
|
+
let sessionId = UUID().uuidString
|
|
1371
|
+
_ = await glasses.audio.speak("Yes coach?", config: SpeakConfig())
|
|
1372
|
+
|
|
1373
|
+
// **ASSERT POINT 1** — handler enters recordDiscrete; agent's
|
|
1374
|
+
// injectTranscript satisfies this via the F-R5-03 race fix on iOS.
|
|
1375
|
+
guard case .success(let rec) = await glasses.audio.recordDiscrete(
|
|
1376
|
+
config: AudioRecordConfig(silenceTimeoutSeconds: 2.0)
|
|
1377
|
+
), !rec.transcript.isEmpty else { return }
|
|
1378
|
+
|
|
1379
|
+
// **ASSERT POINT 2** — user turn persisted BEFORE the LLM call.
|
|
1380
|
+
try? await db.write { db in
|
|
1381
|
+
try CoachingTurn(sessionId: sessionId, role: "user",
|
|
1382
|
+
text: rec.transcript, createdAt: Date()).insert(db)
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
let answer = try? await glasses.observability.aiCall(label: "coach_q",
|
|
1386
|
+
metadata: ["session": sessionId]) {
|
|
1387
|
+
try await anthropic.complete(rec.transcript)
|
|
1388
|
+
}
|
|
1389
|
+
guard let answer else { return }
|
|
1390
|
+
|
|
1391
|
+
// **ASSERT POINT 3** — assistant turn persisted AFTER the LLM call.
|
|
1392
|
+
try? await db.write { db in
|
|
1393
|
+
try CoachingTurn(sessionId: sessionId, role: "assistant",
|
|
1394
|
+
text: answer, createdAt: Date()).insert(db)
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
_ = await glasses.audio.speak(answer, config: SpeakConfig())
|
|
1398
|
+
}
|
|
1399
|
+
}`,
|
|
1400
|
+
},
|
|
1401
|
+
explanation: `THE AGENT-SIDE TEST LOOP (run from the MCP session after the handler is installed)
|
|
1402
|
+
|
|
1403
|
+
The handler above writes to Room/GRDB and calls the LLM via observability.aiCall. That gives the agent three independent surfaces to assert against:
|
|
1404
|
+
|
|
1405
|
+
1. Protocol activity → \`getEventLog\` (sees stt_transcript, record_audio, record_audio_returned, ai_call_start, ai_call_end, speak, speak_completed)
|
|
1406
|
+
2. Persisted state → \`adb exec-out run-as <pkg> cat databases/<name>.db*\` + \`sqlite3\` (sees the coaching_turns rows)
|
|
1407
|
+
3. Rendered UI → \`adb exec-out screencap -p\` (sees what the user sees)
|
|
1408
|
+
|
|
1409
|
+
CANONICAL DRIVER (run after \`./gradlew :app:installDebug && adb shell am start ...\`):
|
|
1410
|
+
|
|
1411
|
+
// 0. Confirm the install is attached to the sim.
|
|
1412
|
+
await getSimulatorStatus({ sessionId });
|
|
1413
|
+
// → connectedRoles.app must be non-null; hardwareReady: true.
|
|
1414
|
+
//
|
|
1415
|
+
// If connectedRoles.app is still null ~10s after the app started
|
|
1416
|
+
// (or createSimulatorSession returned autoBind: "no_device"), the
|
|
1417
|
+
// MCP local bridge probe didn't reach this MCP install. Don't keep
|
|
1418
|
+
// waiting — fall back to URL-bake (F-DF-04):
|
|
1419
|
+
// 1. Read createSimulatorSession's androidBuildConfigPatch.field.snippet.
|
|
1420
|
+
// 2. In app/build.gradle.kts, replace the existing
|
|
1421
|
+
// buildConfigField("String", "EXTENTOS_SESSION_URL", "null") line
|
|
1422
|
+
// with the snippet (or add it inside android.defaultConfig if absent).
|
|
1423
|
+
// 3. Rebuild + reinstall + relaunch — the app now connects to the
|
|
1424
|
+
// baked URL directly. Poll getSimulatorStatus again; expect
|
|
1425
|
+
// connectedRoles.app to populate within ~3s.
|
|
1426
|
+
// Diagnostic: \`adb logcat -d | grep ExtentosTransport\` will show
|
|
1427
|
+
// "mcp probe failed: InterruptedIOException timeout" when the auto-bind
|
|
1428
|
+
// path silently lost the probe (the most common cause).
|
|
1429
|
+
|
|
1430
|
+
// 0.5. If hardwareReady.ready is false with reason "awaiting_browser",
|
|
1431
|
+
// load the sim URL in any browser once — the simulator's React app
|
|
1432
|
+
// attaches as the "browser" role and hardwareReady flips to true
|
|
1433
|
+
// within ~5s. Use the OS-level one-liner (sessionUrl is the
|
|
1434
|
+
// https://extentos.com/s/... form from createSimulatorSession,
|
|
1435
|
+
// NOT the wss:// transport endpoint):
|
|
1436
|
+
//
|
|
1437
|
+
// Windows: cmd //c start "" "<sessionUrl>"
|
|
1438
|
+
// macOS: open "<sessionUrl>"
|
|
1439
|
+
// Linux: xdg-open "<sessionUrl>"
|
|
1440
|
+
//
|
|
1441
|
+
// Once loaded, the sim persists across app and MCP restarts — only
|
|
1442
|
+
// needed once per fresh sim (F-DF-05).
|
|
1443
|
+
|
|
1444
|
+
// 1. Drive the wake.
|
|
1445
|
+
await injectTranscript({ sessionId, text: "ask my coach", isFinal: true });
|
|
1446
|
+
|
|
1447
|
+
// 2. Wait for the handler to enter recordDiscrete. Poll the event log
|
|
1448
|
+
// until a record_audio request frame appears — that's proof the
|
|
1449
|
+
// handler's recordDiscrete is subscribed and ready for the question.
|
|
1450
|
+
// Without this poll, a fast follow-up inject can race past the
|
|
1451
|
+
// subscriber and only reach the wake matcher.
|
|
1452
|
+
let log = await getEventLog({ sessionId, filter: "voice", limit: 50 });
|
|
1453
|
+
while (!log.events.some(e => e.type === "record_audio")) {
|
|
1454
|
+
await sleep(200);
|
|
1455
|
+
log = await getEventLog({ sessionId, filter: "voice", limit: 50, since: log.lastTs });
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
// 3. Inject the question. The F-R5-03 race fix routes this directly
|
|
1459
|
+
// into the pending recordDiscrete — no visible browser tab needed.
|
|
1460
|
+
await injectTranscript({ sessionId, text: "what was my max bench press last week", isFinal: true });
|
|
1461
|
+
|
|
1462
|
+
// 4. Wait for the speak completion. Same polling shape.
|
|
1463
|
+
log = await getEventLog({ sessionId, filter: "voice", limit: 100 });
|
|
1464
|
+
while (!log.events.some(e => e.type === "speak_completed")) {
|
|
1465
|
+
await sleep(500);
|
|
1466
|
+
log = await getEventLog({ sessionId, filter: "voice", limit: 100, since: log.lastTs });
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1469
|
+
// 5. THREE-SURFACE ASSERTION ─────────────────────────────────────────────
|
|
1470
|
+
|
|
1471
|
+
// Surface A: protocol log.
|
|
1472
|
+
// Assert record_audio_returned arrived with via="transcript_injection"
|
|
1473
|
+
// (proves the agent's inject won the race) and success=true.
|
|
1474
|
+
const aiCall = log.events.find(e => e.type === "ai_call_end");
|
|
1475
|
+
const recDone = log.events.find(e => e.type === "record_audio_returned");
|
|
1476
|
+
assert(recDone?.details?.via === "transcript_injection");
|
|
1477
|
+
assert(recDone?.details?.success === true);
|
|
1478
|
+
assert(aiCall?.details?.success === true);
|
|
1479
|
+
|
|
1480
|
+
// Surface B: persisted state. Pull all three SQLite files (the WAL
|
|
1481
|
+
// is mandatory — without it the file looks empty even after writes).
|
|
1482
|
+
await sh(\`adb exec-out run-as <pkg> cat databases/coach.db > local.db\`);
|
|
1483
|
+
await sh(\`adb exec-out run-as <pkg> cat databases/coach.db-wal > local.db-wal\`);
|
|
1484
|
+
await sh(\`adb exec-out run-as <pkg> cat databases/coach.db-shm > local.db-shm\`);
|
|
1485
|
+
const rows = await sh(
|
|
1486
|
+
\`$ANDROID_HOME/platform-tools/sqlite3.exe -header -column local.db \` +
|
|
1487
|
+
\`"SELECT role, text FROM coaching_turns ORDER BY id DESC LIMIT 2;"\`
|
|
1488
|
+
);
|
|
1489
|
+
assert(rows.includes("assistant")); // assistant turn was written
|
|
1490
|
+
assert(rows.includes("max bench")); // user's question was persisted
|
|
1491
|
+
|
|
1492
|
+
// Surface C: rendered screen. Confirms the UI observes the new state.
|
|
1493
|
+
await sh(\`adb exec-out screencap -p > screen.png\`);
|
|
1494
|
+
// Then Read the PNG path — agent sees the Today screen showing the new
|
|
1495
|
+
// exchange. Visual confirmation the user would have if they were holding
|
|
1496
|
+
// the phone.
|
|
1497
|
+
|
|
1498
|
+
When all three agree, the flow really happened end-to-end. When they diverge:
|
|
1499
|
+
|
|
1500
|
+
- Surface A passes, Surface B empty → persistence bug. The model returned text but the handler dropped it before insert.
|
|
1501
|
+
- Surface B has the row, Surface A missing speak_completed → output regression. Persisted but never spoken.
|
|
1502
|
+
- Surface A + B agree, Surface C unchanged → UI binding bug. State updated but the screen didn't recompose.
|
|
1503
|
+
|
|
1504
|
+
Each disagreement points to a specific layer of the handler to fix. With only Surface A, half these failures look identical.`,
|
|
1505
|
+
gotchas: [
|
|
1506
|
+
"**WAL caveat (Android Room).** Room writes in WAL mode by default. Pulling only the .db file gives a stale snapshot — recent writes live in .db-wal. Always pull .db + .db-wal + .db-shm together; the agent's first DB-read returning zero rows almost always means missing .db-wal.",
|
|
1507
|
+
"**Poll-before-inject for multi-turn.** Between the wake inject and the question inject, poll getEventLog until a `record_audio` request frame appears. Otherwise the second inject can land before the handler subscribes and only the wake matcher sees it.",
|
|
1508
|
+
"**hardwareReady requires the browser tab to load once.** Even with autoOpenBrowser: false, the simulator browser must be reached at least once for hardwareReady to flip to true. After that the sim persists. A future headless-surrogate mode would close this; not built yet.",
|
|
1509
|
+
"**adb on the same machine as the emulator.** This recipe needs adb where the agent runs. Cloud-hosted / headless agents can do Surface A but not B or C. A future `getAppState(sessionId, probe)` MCP tool routed through the local MCP bridge would lift this restriction.",
|
|
1510
|
+
"**Read record_audio_returned's `via` field.** Three values: \"transcript_injection\" (your inject won), \"browser_surrogate\" (the browser tab responded — unexpected in a headless agent loop), \"timeout\" (neither path resolved). Anything other than \"transcript_injection\" in an agent test is a signal to investigate.",
|
|
1511
|
+
"**BYOK keys inherit from local.properties / Info.plist.** The agent's installed APK picks up the dev's existing Anthropic key automatically; no per-test wiring. See searchDocs(topic: 'credentials').",
|
|
1512
|
+
"**Don't mint a fresh sim per test.** createSimulatorSession is get-or-create — the same sim resumes across test runs. Use resetFresh: true ONLY when you need a clean event-log slate; otherwise rebuild + reinstall and the library reattaches.",
|
|
1513
|
+
],
|
|
1514
|
+
relatedFeatures: ["record_audio", "transcription_incremental", "speak", "voice_command"],
|
|
1515
|
+
};
|
|
1233
1516
|
export const CODE_EXAMPLES = {
|
|
1234
1517
|
voice_qa_assistant: VOICE_QA_ASSISTANT,
|
|
1235
1518
|
barge_in_speak: BARGE_IN_SPEAK,
|
|
@@ -1238,6 +1521,7 @@ export const CODE_EXAMPLES = {
|
|
|
1238
1521
|
voice_notes: VOICE_NOTES,
|
|
1239
1522
|
connection_page_setup: CONNECTION_PAGE_SETUP,
|
|
1240
1523
|
byok_anthropic: BYOK_ANTHROPIC,
|
|
1524
|
+
agent_test_loop: AGENT_TEST_LOOP,
|
|
1241
1525
|
};
|
|
1242
1526
|
export const CODE_EXAMPLE_PATTERNS = Object.keys(CODE_EXAMPLES).sort();
|
|
1243
1527
|
//# sourceMappingURL=codeExamples.js.map
|
|
@@ -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,qDAAqD;IAC5D,WAAW,EACT,kSAAkS;IACpS,IAAI,EAAE;QACJ,MAAM,EAAE
|
|
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.
|
|
9
|
+
// Pre-public-Maven note: 1.1.35-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.
|
|
15
|
+
latestStable: "1.1.35-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.
|
|
37
|
+
// - com.extentos:glasses-ui:1.1.35-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.
|
|
62
|
-
ui: "com.extentos:glasses-ui:1.1.
|
|
63
|
-
debug: "com.extentos:glasses-debug:1.1.
|
|
61
|
+
core: "com.extentos:glasses:1.1.35-pair",
|
|
62
|
+
ui: "com.extentos:glasses-ui:1.1.35-pair",
|
|
63
|
+
debug: "com.extentos:glasses-debug:1.1.35-pair",
|
|
64
64
|
},
|
|
65
65
|
ios: {
|
|
66
66
|
package: "https://github.com/extentos/swift-glasses",
|
|
67
|
-
version: "1.1.
|
|
67
|
+
version: "1.1.35-pair",
|
|
68
68
|
products: ["GlassesCore", "GlassesUI", "GlassesDebug", "GlassesLifecycle", "GlassesTesting"],
|
|
69
69
|
},
|
|
70
70
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/tools/definitions.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IAMpB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,oBAAoB,EAAE,KAAK,CAAC;KAC7B,CAAC;CACH;AAMD,eAAO,MAAM,eAAe,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/tools/definitions.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IAMpB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,oBAAoB,EAAE,KAAK,CAAC;KAC7B,CAAC;CACH;AAMD,eAAO,MAAM,eAAe,EAAE,OAAO,EA6ZpC,CAAC;AAEF,eAAO,MAAM,SAAS,QAAyB,CAAC;AAShD,wBAAgB,iCAAiC,CAC/C,IAAI,GAAE,SAAS,OAAO,EAAoB,GACzC,IAAI,CAiBN"}
|
|
@@ -47,7 +47,7 @@ export const toolDefinitions = [
|
|
|
47
47
|
// getPlatformInfo these are how a fresh agent learns to compose the SDK.
|
|
48
48
|
{
|
|
49
49
|
name: "getCodeExample",
|
|
50
|
-
description: "Reference library — retrieve a complete SDK code example (Kotlin + Swift) for a use case. Patterns cover the canonical voice-glasses compositions: voice_qa_assistant (the multi-turn wake+question+LLM+speak flow that motivated the pure-SDK pivot), barge_in_speak (cancel TTS on user interrupt), photo_describe_voice (wake → photo → vision LLM → speak), live_transcription_ui (transcripts into Compose/SwiftUI state), voice_notes (wake → record → persist), connection_page_setup (the minimum bootstrap wiring). USE when you're about to write handler code and want the canonical shape to peel from. DON'T USE for capability discovery (use getPlatformInfo) or per-feature minimal usage (use getCapabilityGuide).",
|
|
50
|
+
description: "Reference library — retrieve a complete SDK code example (Kotlin + Swift) for a use case. Patterns cover the canonical voice-glasses compositions: voice_qa_assistant (the multi-turn wake+question+LLM+speak flow that motivated the pure-SDK pivot), barge_in_speak (cancel TTS on user interrupt), photo_describe_voice (wake → photo → vision LLM → speak), live_transcription_ui (transcripts into Compose/SwiftUI state), voice_notes (wake → record → persist), connection_page_setup (the minimum bootstrap wiring), byok_anthropic (BYOK LLM client integration), agent_test_loop (the agent-driven E2E verification recipe — handler skeleton + dual-layer assertion against the sim event log, the emulator's Room/SQLite state, and the rendered screen). USE when you're about to write handler code and want the canonical shape to peel from, OR when you want the agent test driver that asserts the handler works end-to-end. DON'T USE for capability discovery (use getPlatformInfo) or per-feature minimal usage (use getCapabilityGuide).",
|
|
51
51
|
inputSchema: {
|
|
52
52
|
type: "object",
|
|
53
53
|
properties: {
|
|
@@ -61,6 +61,7 @@ export const toolDefinitions = [
|
|
|
61
61
|
"voice_notes",
|
|
62
62
|
"connection_page_setup",
|
|
63
63
|
"byok_anthropic",
|
|
64
|
+
"agent_test_loop",
|
|
64
65
|
],
|
|
65
66
|
description: "Which compositional pattern to fetch. Each returns full Kotlin + Swift code, an explanation, gotchas, and the SDK features it exercises.",
|
|
66
67
|
},
|
|
@@ -365,7 +366,7 @@ export const toolDefinitions = [
|
|
|
365
366
|
// --- 7. Documentation ---
|
|
366
367
|
{
|
|
367
368
|
name: "searchDocs",
|
|
368
|
-
description: "Search Extentos documentation by topic or keyword. The conceptual / narrative layer that complements the action-oriented tools — read these to understand *how* the SDK is meant to be used, not just what calls exist. Canonical post-pivot topics: `getting_started` (full topic index — read first), `custom_handlers` (the central composition doc — how to write a Handler class that subscribes to capability primitives), `voice_integration`, `connection_ui_placement`, `host_app_scaffold`, `auto_bind_session_lifecycle`, `local_bridge_discovery`, `device_code_flow`, `connection_state_model`, `permissions`, `production_checklist`, `concurrency_modes`, `multi_platform_projects`, `library_api`, `toggles`, `audio_video_coexistence`, `simulator_browser_mode`, `event_log_schema`, `file_actions
|
|
369
|
+
description: "Search Extentos documentation by topic or keyword. The conceptual / narrative layer that complements the action-oriented tools — read these to understand *how* the SDK is meant to be used, not just what calls exist. Canonical post-pivot topics: `getting_started` (full topic index — read first), `custom_handlers` (the central composition doc — how to write a Handler class that subscribes to capability primitives), `voice_integration`, `connection_ui_placement`, `host_app_scaffold`, `auto_bind_session_lifecycle`, `local_bridge_discovery`, `device_code_flow`, `connection_state_model`, `permissions`, `production_checklist`, `concurrency_modes`, `multi_platform_projects`, `library_api`, `toggles`, `audio_video_coexistence`, `simulator_browser_mode`, `event_log_schema`, `file_actions`, `agent_e2e_testing` (how an AI coding agent verifies its own generated handler end-to-end — sim event log + adb-mediated emulator DB read + screencap, the dual-layer pattern that closes the agent loop without a human). Topic IDs are stable. **At least one of `topic` or `query` is required** (enforced by the handler — calling with neither returns an invalid_arguments error). Pass `topic` alone to fetch the full topic content (most common); pass `query` alone for keyword search across all topics; pass both to narrow keyword search inside a topic. **mode: \"snippets\" (F-R4-10)** returns only the matching paragraphs instead of full topic bodies — pair with a query when keyword-searching across topics so a single search doesn't dump ~20KB of unrelated content into context. USE to learn how primitives compose into a real flow, or to read up on a specific feature (permissions, toggles, connection lifecycle). DON'T USE for the platform capability list (use getPlatformInfo), call-shape per feature (use getCapabilityGuide), or project-installed state (use inspectIntegration).",
|
|
369
370
|
inputSchema: {
|
|
370
371
|
type: "object",
|
|
371
372
|
properties: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/tools/definitions.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,EAAE;AACF,iFAAiF;AACjF,uEAAuE;AACvE,6EAA6E;AAC7E,gFAAgF;AAChF,yEAAyE;AACzE,iFAAiF;AACjF,4EAA4E;AAC5E,EAAE;AACF,yEAAyE;AACzE,6EAA6E;AAC7E,yEAAyE;AAEzE,OAAO,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AAkBzE,MAAM,YAAY,GAAG,EAAE,IAAI,EAAE,QAAiB,EAAE,IAAI,EAAE,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC;AAC3E,MAAM,WAAW,GAAG,EAAE,IAAI,EAAE,QAAiB,EAAE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC;AACvE,MAAM,kBAAkB,GAAG,EAAE,IAAI,EAAE,QAAiB,EAAE,IAAI,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE,CAAC;AAEtF,MAAM,CAAC,MAAM,eAAe,GAAc;IACxC,oCAAoC;IACpC;QACE,IAAI,EAAE,iBAAiB;QACvB,WAAW,EACT,8mCAA8mC;QAChnC,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,QAAQ,EAAE;oBACR,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,SAAS,EAAE,cAAc,CAAC,EAAE;oBAC5D,QAAQ,EAAE,CAAC;iBACZ;gBACD,OAAO,EAAE,WAAW;gBACpB,MAAM,EAAE;oBACN,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE;wBACL,IAAI,EAAE,QAAQ;wBACd,IAAI,EAAE,CAAC,QAAQ,EAAE,mBAAmB,EAAE,uBAAuB,CAAC;qBAC/D;oBACD,WAAW,EACT,+PAA+P;iBAClQ;aACF;YACD,QAAQ,EAAE,CAAC,UAAU,CAAC;YACtB,oBAAoB,EAAE,KAAK;SAC5B;KACF;IACD,oCAAoC;IACpC,oEAAoE;IACpE,yEAAyE;IACzE;QACE,IAAI,EAAE,gBAAgB;QACtB,WAAW,EACT,
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/tools/definitions.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/docs/index.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AA2LD,eAAO,MAAM,SAAS,EAAE,QAAQ,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/docs/index.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AA2LD,eAAO,MAAM,SAAS,EAAE,QAAQ,EAs7B/B,CAAC;AAEF,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,QAAQ,EAAE,CAuB/E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,WAAW,GAAE,MAAU,EACvB,eAAe,GAAE,MAAY,GAC5B,MAAM,EAAE,CAmBV"}
|