Skip to content

Repository files navigation

s2s-tools

The Tools plugin for speech-to-speech-mobile.

speech-to-speech-mobile
        │
        │ Tools contract
        ▼
     s2s-tools
        │
        └── core   — ToolRegistry (the dispatcher) + CalculatorTool (example)

What's here now

coreToolRegistry, moved unchanged from speech-to-speech-mobile (behavior preserved exactly: flat-JSON tool-call parsing, hand-written parser kept testable off-device without org.json). Registers/dispatches ToolDefinition/ToolFunction pairs, extracts a ToolCall from model output, executes it and returns a ToolResult.

CalculatorTool — one worked stateless example (pure function of its arguments, ignores ToolContext entirely).

What's NOT here yet

fetch and webdroid adapters are not wired in. Both are separate, existing, generic repos (loyality7/fetch, loyality7/webdroid) that stay completely S2S-unaware — this repo's job is to adapt their APIs into ToolDefinition/ToolFunction, never the other way around. As of this writing neither repo publishes a JitPack-resolvable artifact: fetch's Gradle modules have no maven-publish plugin configured, and webdroid's own README states Maven Central deployment will accompany a future v1.1.0 release. Once either fixes that, add it as its own module here (s2s-tools/fetch, s2s-tools/webdroid) — same one-module-per-dependency isolation pattern s2s-llm uses (llama-cpp/remote never share a dependency), so installing one adapter never pulls the other's transitive deps. Do not modify fetch or webdroid themselves to make this work.

For the worked example of what a stateful, session-isolated tool adapter looks like (the pattern a real webdroid adapter should follow), see speech-to-speech-mobile/templates/s2s-tools-plugin-template's BrowserTool — it demonstrates exactly the ToolContext.sessionId-keyed isolation a real browsing tool needs, using a fake in-memory page instead of a real WebDroid session.

Installing

dependencyResolutionManagement {
    repositories {
        maven { url = uri("https://jitpack.io") }
    }
}

dependencies {
    // Single-module repo today — JitPack publishes under the plain repo
    // coordinate (com.github.loyality7:s2s-tools), not the ".repo:module"
    // multi-module convention s2s-llm/s2s-context use. That convention only
    // kicks in once a second module (e.g. fetch/webdroid, once they're
    // JitPack-resolvable) exists here.
    implementation("com.github.loyality7:s2s-tools:0.1.0")
}

Host composition

import com.s2s.tools.core.CalculatorTool
import com.s2s.tools.core.ToolRegistry

val tools = ToolRegistry()
CalculatorTool.registerOn(tools)

val engine = S2SEngine(
    context = androidContext,
    config = config,
    languageModel = languageModel,
    history = history,
    tools = tools,
)

Core's default (when no tools arg is passed) is NoopTools — a genuine no-op, not a hidden concrete registry. A host that wants real tool calling must supply a Tools implementation, whether ToolRegistry from here or its own.

Session identity

ToolContext(sessionId, turnId, callId) is engine-generated — S2SEngine creates it and passes it into every Tools.execute() / ToolFunction.invoke() call. No tool, including anything built on top of ToolRegistry here, generates its own session identity. See ToolRegistrySessionIsolationTest.kt for the proof that keying tool state on ToolContext.sessionId keeps two concurrent conversations' tool state fully isolated.

Testing strategy

ToolRegistryTest and ToolRegistrySessionIsolationTest run on the JVM with plain JUnit — no Android instrumentation needed for the pure-Kotlin dispatch/parsing logic. A real fetch/webdroid adapter touching actual network/WebView APIs will need instrumented tests in its own module for that part; the session-isolation logic itself should stay testable this way.

Publishing

Same JitPack mechanism as speech-to-speech-mobile and s2s-llm — push, tag, JitPack builds on first resolution. No custom groupId/artifactId override in core/build.gradle.kts.

With only one module (:core), JitPack publishes under the plain repo coordinate com.github.loyality7:s2s-tools, NOT com.github.loyality7. s2s-tools:core — the .repo:module multi-module convention (what s2s-llm/s2s-context use) only applies once a repo has more than one Gradle module. Confirmed by directly listing the published artifact directory after the first tag build — do not assume the multi-module pattern applies here until fetch/webdroid modules actually exist.

About

Tools plugin for speech-to-speech-mobile: ToolRegistry dispatcher, adapters for fetch/webdroid pending their JitPack publishing

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages