@komaa/standin-sdk/echo is the smallest thing that answers a real Microsoft Teams call. It sends
the caller’s voice back, and it exists for two reasons: to be the thing you run before you
suspect your own agent, and to be the thing you copy when you start your own.
If the echo answers, your secret, your tunnel and your StandIn identity are all correct, and whatever
breaks next is your agent rather than the transport.
Run it
Node.js 20 or newer:wss:// URL with its /msteams/calling path as
your StandIn identity’s agent voice URL, call the identity from Microsoft Teams, and talk. You should hear
yourself. The quickstart has the portal steps and
Expose your agent has the mount command and the probes.
The whole plugin
standin-echo, the licence header and the
doc comments. One line differs from the file in the repository on purpose: that copy reaches the core
by relative path, because it lives inside the package, and yours reaches it by package name. Note
what is not there: no sequence number, no timestamp, no handshake, no capacity check, no watchdog. All of that
is CallServer.
Note also that this handler defines three of the seven methods on CallHandler. onVideoFrame,
onSpeakerChange, onContext and aclose are absent because it does not need them, and the server
treats a missing method as a no-op: the interface is all-optional, so nothing extends anything. See
Call handler.
Make it yours
ReplaceonCallerAudio with your framework’s agent loop. Everything else stays.
Write your own handler
You do not need the SDK’s source, a fork or a registration to write a handler. Copy the class out of the block above into your own module, changeonCallerAudio, and pass it as handlerFactory:
CallHandler is an interface of optional methods, so your
class is a handler because it has the right method names, not because it extends or registers. That
is the whole seam, and it is the same one every plugin on this site uses.
What to add first
Once the echo answers, three things turn the template into something usable: Barge-in.await session.cancelPlayback() the moment your provider reports the caller started
speaking. Without it the bot keeps talking over the caller for the length of the buffered audio. See
cancelPlayback() is the barge-in.
Frame alignment. If your provider speaks 24 kHz, resample and align before sending. See
Audio.
Cleanup. Add aclose(reason) to close your provider socket. It is always called exactly once, on
every path, before the slot is freed.
Contribute a plugin to the SDK
This part is different: it is for adding a plugin to the@komaa/standin-sdk package itself, so it
assumes a clone of the repository rather than an npm install. If you are building for your own
deployment, the two sections above are the ones you want.
Every plugin lives inside the one package, so adding one publishes nothing new.
1
Copy the directory
2
Add its subpath export
One entry under
exports in libraries/typescript/package.json, pointing
@komaa/standin-sdk/<name> at the emitted dist/plugins/<name>/index.js. The directory name stays
short; the published specifier carries the scope, because a registry is global.The copied directory brings a cli.ts with it, so add the matching bin entry in the same file,
standin-<name> pointing at dist/plugins/<name>/cli.js, or npx standin-<name> resolves to
nothing and the install line on your page is wrong from the first day.3
Keep the framework optional
A framework the plugin needs is a peer dependency, marked optional in
peerDependenciesMeta.
The core imports nothing from plugins/, so somebody installing the SDK for one plugin never drags
in another’s framework.4
Check it
make py-check is its Python counterpart, and make check runs both halves plus the protocol and
documentation checks. Then open a pull request against
komaa-com/standin.Parity
The Python twin of this file isstandin.plugins.echo, the same handler with the same method
names in that language’s casing. Core SDK features land in both languages in the same change, with
matching defaults and behaviour. The full guide is
CONTRIBUTING.md.
Next
Call handler
All seven methods, with a full worked handler.
CallServer
Every option you may want to change once calls are real.