Nodes: advertise canvas invoke commands

This commit is contained in:
Peter Steinberger
2025-12-18 02:05:06 +00:00
parent 54830e8401
commit efed2ae30f
15 changed files with 212 additions and 153 deletions

View File

@@ -266,6 +266,20 @@ class NodeRuntime(context: Context) {
.joinToString(" ")
.trim()
.ifEmpty { null }
val invokeCommands =
buildList {
add("canvas.show")
add("canvas.hide")
add("canvas.setMode")
add("canvas.navigate")
add("canvas.eval")
add("canvas.snapshot")
if (cameraEnabled.value) {
add("camera.snap")
add("camera.clip")
}
}
val resolved =
if (storedToken.isNullOrBlank()) {
_statusText.value = "Pairing…"
@@ -288,6 +302,7 @@ class NodeRuntime(context: Context) {
deviceFamily = "Android",
modelIdentifier = modelIdentifier,
caps = caps,
commands = invokeCommands,
),
)
} else {
@@ -311,19 +326,20 @@ class NodeRuntime(context: Context) {
platform = "Android",
version = "dev",
deviceFamily = "Android",
modelIdentifier = modelIdentifier,
caps =
buildList {
add(ClawdisCapability.Canvas.rawValue)
if (cameraEnabled.value) add(ClawdisCapability.Camera.rawValue)
if (voiceWakeMode.value != VoiceWakeMode.Off && hasRecordAudioPermission()) {
add(ClawdisCapability.VoiceWake.rawValue)
}
},
),
)
}
}
modelIdentifier = modelIdentifier,
caps =
buildList {
add(ClawdisCapability.Canvas.rawValue)
if (cameraEnabled.value) add(ClawdisCapability.Camera.rawValue)
if (voiceWakeMode.value != VoiceWakeMode.Off && hasRecordAudioPermission()) {
add(ClawdisCapability.VoiceWake.rawValue)
}
},
commands = invokeCommands,
),
)
}
}
private fun hasRecordAudioPermission(): Boolean {
return (

View File

@@ -28,6 +28,7 @@ class BridgePairingClient {
val deviceFamily: String?,
val modelIdentifier: String?,
val caps: List<String>?,
val commands: List<String>?,
)
data class PairResult(val ok: Boolean, val token: String?, val error: String? = null)
@@ -62,6 +63,7 @@ class BridgePairingClient {
hello.deviceFamily?.let { put("deviceFamily", JsonPrimitive(it)) }
hello.modelIdentifier?.let { put("modelIdentifier", JsonPrimitive(it)) }
hello.caps?.let { put("caps", JsonArray(it.map(::JsonPrimitive))) }
hello.commands?.let { put("commands", JsonArray(it.map(::JsonPrimitive))) }
},
)
@@ -86,6 +88,7 @@ class BridgePairingClient {
hello.deviceFamily?.let { put("deviceFamily", JsonPrimitive(it)) }
hello.modelIdentifier?.let { put("modelIdentifier", JsonPrimitive(it)) }
hello.caps?.let { put("caps", JsonArray(it.map(::JsonPrimitive))) }
hello.commands?.let { put("commands", JsonArray(it.map(::JsonPrimitive))) }
},
)

View File

@@ -43,6 +43,7 @@ class BridgeSession(
val deviceFamily: String?,
val modelIdentifier: String?,
val caps: List<String>?,
val commands: List<String>?,
)
data class InvokeRequest(val id: String, val command: String, val paramsJson: String?)
@@ -198,6 +199,7 @@ class BridgeSession(
hello.deviceFamily?.let { put("deviceFamily", JsonPrimitive(it)) }
hello.modelIdentifier?.let { put("modelIdentifier", JsonPrimitive(it)) }
hello.caps?.let { put("caps", JsonArray(it.map(::JsonPrimitive))) }
hello.commands?.let { put("commands", JsonArray(it.map(::JsonPrimitive))) }
},
)

View File

@@ -49,6 +49,7 @@ class BridgePairingClientTest {
deviceFamily = "Android",
modelIdentifier = "SM-X000",
caps = null,
commands = null,
),
)
assertTrue(res.ok)
@@ -97,6 +98,7 @@ class BridgePairingClientTest {
deviceFamily = "Android",
modelIdentifier = "SM-X000",
caps = null,
commands = null,
),
)
assertTrue(res.ok)

View File

@@ -72,6 +72,7 @@ class BridgeSessionTest {
deviceFamily = null,
modelIdentifier = null,
caps = null,
commands = null,
),
)
@@ -137,6 +138,7 @@ class BridgeSessionTest {
deviceFamily = null,
modelIdentifier = null,
caps = null,
commands = null,
),
)
connected.await()
@@ -207,6 +209,7 @@ class BridgeSessionTest {
deviceFamily = null,
modelIdentifier = null,
caps = null,
commands = null,
),
)
connected.await()
@@ -279,6 +282,7 @@ class BridgeSessionTest {
deviceFamily = null,
modelIdentifier = null,
caps = null,
commands = null,
),
)