@komaa/standin-sdk 0.1.0

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.
Files changed (269) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +141 -0
  3. package/dist/ambient.d.ts +80 -0
  4. package/dist/ambient.d.ts.map +1 -0
  5. package/dist/ambient.js +281 -0
  6. package/dist/ambient.js.map +1 -0
  7. package/dist/attachments.d.ts +149 -0
  8. package/dist/attachments.d.ts.map +1 -0
  9. package/dist/attachments.js +451 -0
  10. package/dist/attachments.js.map +1 -0
  11. package/dist/audio.d.ts +80 -0
  12. package/dist/audio.d.ts.map +1 -0
  13. package/dist/audio.js +170 -0
  14. package/dist/audio.js.map +1 -0
  15. package/dist/avatar.d.ts +111 -0
  16. package/dist/avatar.d.ts.map +1 -0
  17. package/dist/avatar.js +201 -0
  18. package/dist/avatar.js.map +1 -0
  19. package/dist/callServer.d.ts +151 -0
  20. package/dist/callServer.d.ts.map +1 -0
  21. package/dist/callServer.js +1097 -0
  22. package/dist/callServer.js.map +1 -0
  23. package/dist/callTools.d.ts +154 -0
  24. package/dist/callTools.d.ts.map +1 -0
  25. package/dist/callTools.js +255 -0
  26. package/dist/callTools.js.map +1 -0
  27. package/dist/chat.d.ts +226 -0
  28. package/dist/chat.d.ts.map +1 -0
  29. package/dist/chat.js +574 -0
  30. package/dist/chat.js.map +1 -0
  31. package/dist/config.d.ts +32 -0
  32. package/dist/config.d.ts.map +1 -0
  33. package/dist/config.js +86 -0
  34. package/dist/config.js.map +1 -0
  35. package/dist/consult.d.ts +147 -0
  36. package/dist/consult.d.ts.map +1 -0
  37. package/dist/consult.js +388 -0
  38. package/dist/consult.js.map +1 -0
  39. package/dist/delivery.d.ts +81 -0
  40. package/dist/delivery.d.ts.map +1 -0
  41. package/dist/delivery.js +187 -0
  42. package/dist/delivery.js.map +1 -0
  43. package/dist/echoGuard.d.ts +56 -0
  44. package/dist/echoGuard.d.ts.map +1 -0
  45. package/dist/echoGuard.js +57 -0
  46. package/dist/echoGuard.js.map +1 -0
  47. package/dist/errors.d.ts +5 -0
  48. package/dist/errors.d.ts.map +1 -0
  49. package/dist/errors.js +10 -0
  50. package/dist/errors.js.map +1 -0
  51. package/dist/fetch.d.ts +40 -0
  52. package/dist/fetch.d.ts.map +1 -0
  53. package/dist/fetch.js +240 -0
  54. package/dist/fetch.js.map +1 -0
  55. package/dist/gate.d.ts +80 -0
  56. package/dist/gate.d.ts.map +1 -0
  57. package/dist/gate.js +249 -0
  58. package/dist/gate.js.map +1 -0
  59. package/dist/handler.d.ts +283 -0
  60. package/dist/handler.d.ts.map +1 -0
  61. package/dist/handler.js +4 -0
  62. package/dist/handler.js.map +1 -0
  63. package/dist/hmac.d.ts +32 -0
  64. package/dist/hmac.d.ts.map +1 -0
  65. package/dist/hmac.js +108 -0
  66. package/dist/hmac.js.map +1 -0
  67. package/dist/index.d.ts +59 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +60 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/lane.d.ts +92 -0
  72. package/dist/lane.d.ts.map +1 -0
  73. package/dist/lane.js +269 -0
  74. package/dist/lane.js.map +1 -0
  75. package/dist/lipsync.d.ts +136 -0
  76. package/dist/lipsync.d.ts.map +1 -0
  77. package/dist/lipsync.js +310 -0
  78. package/dist/lipsync.js.map +1 -0
  79. package/dist/log.d.ts +18 -0
  80. package/dist/log.d.ts.map +1 -0
  81. package/dist/log.js +20 -0
  82. package/dist/log.js.map +1 -0
  83. package/dist/media.d.ts +43 -0
  84. package/dist/media.d.ts.map +1 -0
  85. package/dist/media.js +190 -0
  86. package/dist/media.js.map +1 -0
  87. package/dist/minutes.d.ts +398 -0
  88. package/dist/minutes.d.ts.map +1 -0
  89. package/dist/minutes.js +805 -0
  90. package/dist/minutes.js.map +1 -0
  91. package/dist/outbound.d.ts +388 -0
  92. package/dist/outbound.d.ts.map +1 -0
  93. package/dist/outbound.js +933 -0
  94. package/dist/outbound.js.map +1 -0
  95. package/dist/plugins/cartesia/agent.d.ts +58 -0
  96. package/dist/plugins/cartesia/agent.d.ts.map +1 -0
  97. package/dist/plugins/cartesia/agent.js +254 -0
  98. package/dist/plugins/cartesia/agent.js.map +1 -0
  99. package/dist/plugins/cartesia/cli.d.ts +3 -0
  100. package/dist/plugins/cartesia/cli.d.ts.map +1 -0
  101. package/dist/plugins/cartesia/cli.js +10 -0
  102. package/dist/plugins/cartesia/cli.js.map +1 -0
  103. package/dist/plugins/cartesia/config.d.ts +30 -0
  104. package/dist/plugins/cartesia/config.d.ts.map +1 -0
  105. package/dist/plugins/cartesia/config.js +29 -0
  106. package/dist/plugins/cartesia/config.js.map +1 -0
  107. package/dist/plugins/cartesia/handler.d.ts +40 -0
  108. package/dist/plugins/cartesia/handler.d.ts.map +1 -0
  109. package/dist/plugins/cartesia/handler.js +142 -0
  110. package/dist/plugins/cartesia/handler.js.map +1 -0
  111. package/dist/plugins/cartesia/index.d.ts +6 -0
  112. package/dist/plugins/cartesia/index.d.ts.map +1 -0
  113. package/dist/plugins/cartesia/index.js +54 -0
  114. package/dist/plugins/cartesia/index.js.map +1 -0
  115. package/dist/plugins/deepgram/agent.d.ts +60 -0
  116. package/dist/plugins/deepgram/agent.d.ts.map +1 -0
  117. package/dist/plugins/deepgram/agent.js +302 -0
  118. package/dist/plugins/deepgram/agent.js.map +1 -0
  119. package/dist/plugins/deepgram/cli.d.ts +3 -0
  120. package/dist/plugins/deepgram/cli.d.ts.map +1 -0
  121. package/dist/plugins/deepgram/cli.js +10 -0
  122. package/dist/plugins/deepgram/cli.js.map +1 -0
  123. package/dist/plugins/deepgram/config.d.ts +39 -0
  124. package/dist/plugins/deepgram/config.d.ts.map +1 -0
  125. package/dist/plugins/deepgram/config.js +66 -0
  126. package/dist/plugins/deepgram/config.js.map +1 -0
  127. package/dist/plugins/deepgram/handler.d.ts +87 -0
  128. package/dist/plugins/deepgram/handler.d.ts.map +1 -0
  129. package/dist/plugins/deepgram/handler.js +268 -0
  130. package/dist/plugins/deepgram/handler.js.map +1 -0
  131. package/dist/plugins/deepgram/index.d.ts +11 -0
  132. package/dist/plugins/deepgram/index.d.ts.map +1 -0
  133. package/dist/plugins/deepgram/index.js +76 -0
  134. package/dist/plugins/deepgram/index.js.map +1 -0
  135. package/dist/plugins/echo/cli.d.ts +3 -0
  136. package/dist/plugins/echo/cli.d.ts.map +1 -0
  137. package/dist/plugins/echo/cli.js +10 -0
  138. package/dist/plugins/echo/cli.js.map +1 -0
  139. package/dist/plugins/echo/index.d.ts +37 -0
  140. package/dist/plugins/echo/index.d.ts.map +1 -0
  141. package/dist/plugins/echo/index.js +61 -0
  142. package/dist/plugins/echo/index.js.map +1 -0
  143. package/dist/plugins/elevenlabs/agent.d.ts +72 -0
  144. package/dist/plugins/elevenlabs/agent.d.ts.map +1 -0
  145. package/dist/plugins/elevenlabs/agent.js +305 -0
  146. package/dist/plugins/elevenlabs/agent.js.map +1 -0
  147. package/dist/plugins/elevenlabs/cli.d.ts +3 -0
  148. package/dist/plugins/elevenlabs/cli.d.ts.map +1 -0
  149. package/dist/plugins/elevenlabs/cli.js +10 -0
  150. package/dist/plugins/elevenlabs/cli.js.map +1 -0
  151. package/dist/plugins/elevenlabs/config.d.ts +27 -0
  152. package/dist/plugins/elevenlabs/config.d.ts.map +1 -0
  153. package/dist/plugins/elevenlabs/config.js +42 -0
  154. package/dist/plugins/elevenlabs/config.js.map +1 -0
  155. package/dist/plugins/elevenlabs/handler.d.ts +67 -0
  156. package/dist/plugins/elevenlabs/handler.d.ts.map +1 -0
  157. package/dist/plugins/elevenlabs/handler.js +419 -0
  158. package/dist/plugins/elevenlabs/handler.js.map +1 -0
  159. package/dist/plugins/elevenlabs/index.d.ts +11 -0
  160. package/dist/plugins/elevenlabs/index.d.ts.map +1 -0
  161. package/dist/plugins/elevenlabs/index.js +72 -0
  162. package/dist/plugins/elevenlabs/index.js.map +1 -0
  163. package/dist/plugins/livekit/cli.d.ts +3 -0
  164. package/dist/plugins/livekit/cli.d.ts.map +1 -0
  165. package/dist/plugins/livekit/cli.js +10 -0
  166. package/dist/plugins/livekit/cli.js.map +1 -0
  167. package/dist/plugins/livekit/config.d.ts +47 -0
  168. package/dist/plugins/livekit/config.d.ts.map +1 -0
  169. package/dist/plugins/livekit/config.js +46 -0
  170. package/dist/plugins/livekit/config.js.map +1 -0
  171. package/dist/plugins/livekit/handler.d.ts +59 -0
  172. package/dist/plugins/livekit/handler.d.ts.map +1 -0
  173. package/dist/plugins/livekit/handler.js +211 -0
  174. package/dist/plugins/livekit/handler.js.map +1 -0
  175. package/dist/plugins/livekit/index.d.ts +6 -0
  176. package/dist/plugins/livekit/index.d.ts.map +1 -0
  177. package/dist/plugins/livekit/index.js +68 -0
  178. package/dist/plugins/livekit/index.js.map +1 -0
  179. package/dist/plugins/livekit/room.d.ts +117 -0
  180. package/dist/plugins/livekit/room.d.ts.map +1 -0
  181. package/dist/plugins/livekit/room.js +449 -0
  182. package/dist/plugins/livekit/room.js.map +1 -0
  183. package/dist/plugins/openai/agent.d.ts +74 -0
  184. package/dist/plugins/openai/agent.d.ts.map +1 -0
  185. package/dist/plugins/openai/agent.js +264 -0
  186. package/dist/plugins/openai/agent.js.map +1 -0
  187. package/dist/plugins/openai/cli.d.ts +3 -0
  188. package/dist/plugins/openai/cli.d.ts.map +1 -0
  189. package/dist/plugins/openai/cli.js +10 -0
  190. package/dist/plugins/openai/cli.js.map +1 -0
  191. package/dist/plugins/openai/config.d.ts +29 -0
  192. package/dist/plugins/openai/config.d.ts.map +1 -0
  193. package/dist/plugins/openai/config.js +37 -0
  194. package/dist/plugins/openai/config.js.map +1 -0
  195. package/dist/plugins/openai/handler.d.ts +65 -0
  196. package/dist/plugins/openai/handler.d.ts.map +1 -0
  197. package/dist/plugins/openai/handler.js +297 -0
  198. package/dist/plugins/openai/handler.js.map +1 -0
  199. package/dist/plugins/openai/index.d.ts +6 -0
  200. package/dist/plugins/openai/index.d.ts.map +1 -0
  201. package/dist/plugins/openai/index.js +72 -0
  202. package/dist/plugins/openai/index.js.map +1 -0
  203. package/dist/plugins/openclaw/allowlist.d.ts +9 -0
  204. package/dist/plugins/openclaw/allowlist.d.ts.map +1 -0
  205. package/dist/plugins/openclaw/allowlist.js +11 -0
  206. package/dist/plugins/openclaw/allowlist.js.map +1 -0
  207. package/dist/plugins/openclaw/config.d.ts +50 -0
  208. package/dist/plugins/openclaw/config.d.ts.map +1 -0
  209. package/dist/plugins/openclaw/config.js +53 -0
  210. package/dist/plugins/openclaw/config.js.map +1 -0
  211. package/dist/plugins/openclaw/handler.d.ts +90 -0
  212. package/dist/plugins/openclaw/handler.d.ts.map +1 -0
  213. package/dist/plugins/openclaw/handler.js +146 -0
  214. package/dist/plugins/openclaw/handler.js.map +1 -0
  215. package/dist/plugins/openclaw/index.d.ts +55 -0
  216. package/dist/plugins/openclaw/index.d.ts.map +1 -0
  217. package/dist/plugins/openclaw/index.js +89 -0
  218. package/dist/plugins/openclaw/index.js.map +1 -0
  219. package/dist/plugins/openclaw/openclaw.plugin.json +74 -0
  220. package/dist/plugins/openclaw/package.json +14 -0
  221. package/dist/plugins/openclaw/realtime.d.ts +82 -0
  222. package/dist/plugins/openclaw/realtime.d.ts.map +1 -0
  223. package/dist/plugins/openclaw/realtime.js +238 -0
  224. package/dist/plugins/openclaw/realtime.js.map +1 -0
  225. package/dist/plugins/openclaw/runtime.d.ts +19 -0
  226. package/dist/plugins/openclaw/runtime.d.ts.map +1 -0
  227. package/dist/plugins/openclaw/runtime.js +160 -0
  228. package/dist/plugins/openclaw/runtime.js.map +1 -0
  229. package/dist/policy.d.ts +38 -0
  230. package/dist/policy.d.ts.map +1 -0
  231. package/dist/policy.js +95 -0
  232. package/dist/policy.js.map +1 -0
  233. package/dist/protocol.d.ts +44 -0
  234. package/dist/protocol.d.ts.map +1 -0
  235. package/dist/protocol.js +77 -0
  236. package/dist/protocol.js.map +1 -0
  237. package/dist/protocolRuntime.d.ts +19 -0
  238. package/dist/protocolRuntime.d.ts.map +1 -0
  239. package/dist/protocolRuntime.js +78 -0
  240. package/dist/protocolRuntime.js.map +1 -0
  241. package/dist/smoke.d.ts +65 -0
  242. package/dist/smoke.d.ts.map +1 -0
  243. package/dist/smoke.js +293 -0
  244. package/dist/smoke.js.map +1 -0
  245. package/dist/startup.d.ts +74 -0
  246. package/dist/startup.d.ts.map +1 -0
  247. package/dist/startup.js +112 -0
  248. package/dist/startup.js.map +1 -0
  249. package/dist/tile.d.ts +101 -0
  250. package/dist/tile.d.ts.map +1 -0
  251. package/dist/tile.js +195 -0
  252. package/dist/tile.js.map +1 -0
  253. package/dist/version.d.ts +2 -0
  254. package/dist/version.d.ts.map +1 -0
  255. package/dist/version.js +4 -0
  256. package/dist/version.js.map +1 -0
  257. package/dist/vision.d.ts +160 -0
  258. package/dist/vision.d.ts.map +1 -0
  259. package/dist/vision.js +301 -0
  260. package/dist/vision.js.map +1 -0
  261. package/dist/visionTools.d.ts +237 -0
  262. package/dist/visionTools.d.ts.map +1 -0
  263. package/dist/visionTools.js +578 -0
  264. package/dist/visionTools.js.map +1 -0
  265. package/dist/voice.d.ts +143 -0
  266. package/dist/voice.d.ts.map +1 -0
  267. package/dist/voice.js +403 -0
  268. package/dist/voice.js.map +1 -0
  269. package/package.json +129 -0
@@ -0,0 +1,146 @@
1
+ // Copyright (c) 2026 Komaa DigiTech
2
+ // SPDX-License-Identifier: MIT
3
+ /**
4
+ * The seam adapter: one {@link CallHandler} per Microsoft Teams call.
5
+ *
6
+ * This is the whole surface between StandIn and OpenClaw, and it is deliberately
7
+ * thin. Everything framework-independent - the socket, the HMAC handshake and its
8
+ * replay guard, capacity, the wire protocol, the outbound sequence number and
9
+ * audio timeline, the pre-start and audio-idle watchdogs, idempotent teardown -
10
+ * belongs to the SDK's `CallServer`. Everything model-shaped belongs to
11
+ * {@link createRealtimeCall}. What is left here is the decision of whether to
12
+ * take the call at all, and the wiring between the two.
13
+ *
14
+ * There are four refusal paths, and each is one line, because `session.end()` is
15
+ * safe to call from inside `onStart`: it returns immediately and the close runs
16
+ * once `onStart` unwinds, so refusing a call needs no dance around a teardown
17
+ * deadlock.
18
+ */
19
+ import { contextSentences, } from "../../index.js";
20
+ import { describeInboundRejection, isInboundCallAllowed } from "./allowlist.js";
21
+ import { createRealtimeCall, } from "./realtime.js";
22
+ /**
23
+ * One Microsoft Teams call.
24
+ *
25
+ * Implements four of the SDK's five methods. `onCallerAudio` is the hot path and
26
+ * does no work of its own - it hands the frame to the realtime bridge, which owns
27
+ * the recording gate, the echo guard and the resampling.
28
+ */
29
+ export class TeamsCallHandler {
30
+ #deps;
31
+ #call;
32
+ #callId = "";
33
+ /** Set only once a slot is actually reserved, so a refusal never frees someone else's. */
34
+ #held = false;
35
+ constructor(deps) {
36
+ this.#deps = deps;
37
+ }
38
+ async onStart(session) {
39
+ const { config, realtime, registry, logger } = this.#deps;
40
+ this.#callId = session.callId;
41
+ // REFUSAL 1: no realtime provider. The startup log already said this would
42
+ // happen; the close reason is what makes it visible on the call itself
43
+ // instead of as silence.
44
+ if (!realtime) {
45
+ logger?.error?.(`standin-msteams: no realtime voice provider resolved - refusing call ${session.callId}`);
46
+ await session.end("realtime-unavailable");
47
+ return;
48
+ }
49
+ // REFUSAL 2: inbound policy. Checked before the slot is taken, so a refused
50
+ // caller cannot consume capacity by dialling repeatedly.
51
+ const from = session.start.caller.aadId ?? "";
52
+ if (!isInboundCallAllowed(config.voice.inboundPolicy, config.voice.allowFrom, from)) {
53
+ logger?.warn?.(`standin-msteams: ${describeInboundRejection(config.voice.inboundPolicy, from)}`);
54
+ await session.end("not-allowed");
55
+ return;
56
+ }
57
+ // REFUSAL 3: the operator's concurrency cap.
58
+ if (!registry.acquire(session.callId)) {
59
+ logger?.warn?.(`standin-msteams: at maxConcurrentCalls (${config.media.maxConcurrentCalls}) - refusing call ${session.callId}`);
60
+ await session.end("busy");
61
+ return;
62
+ }
63
+ this.#held = true;
64
+ const call = createRealtimeCall({
65
+ session,
66
+ deps: {
67
+ provider: realtime.provider,
68
+ providerConfig: realtime.providerConfig,
69
+ cfg: this.#deps.cfg,
70
+ instructions: config.voice.realtime.instructions,
71
+ greetingInstructions: config.voice.inboundGreeting,
72
+ requireRecordingStatus: config.voice.requireRecordingStatus,
73
+ echo: config.voice.realtime,
74
+ logger,
75
+ },
76
+ });
77
+ // REFUSAL 4: the model never came up.
78
+ //
79
+ // Awaited, not fired off: the SDK bounds onStart and holds caller audio until
80
+ // it resolves, so a failed connect becomes a refusal with a reason rather than
81
+ // an answered call that never speaks.
82
+ try {
83
+ await call.connect();
84
+ }
85
+ catch (err) {
86
+ logger?.error?.(`standin-msteams: realtime connect failed on ${session.callId} - ${err instanceof Error ? err.message : String(err)}`);
87
+ call.close();
88
+ await session.end("realtime-unavailable");
89
+ return;
90
+ }
91
+ this.#call = call;
92
+ registry.bind(session.callId, call);
93
+ logger?.info?.(`standin-msteams: call ${session.callId} live` +
94
+ (session.start.caller.displayName
95
+ ? ` with ${session.start.caller.displayName}`
96
+ : ""));
97
+ }
98
+ /** PCM16, 16 kHz, mono, little-endian, already validated by the SDK. */
99
+ async onCallerAudio(pcm) {
100
+ this.#call?.pushAudio(pcm);
101
+ }
102
+ /**
103
+ * Participant counts, DTMF and recording status, as plain sentences.
104
+ *
105
+ * Recording status is the one that is not just text: it opens and closes the
106
+ * media gate, so it is matched rather than forwarded. Matched against the SDK's
107
+ * own {@link contextSentences} rather than a string literal of our own, so the
108
+ * two cannot drift apart the next time the wording is improved.
109
+ */
110
+ async onContext(text) {
111
+ if (!this.#call)
112
+ return;
113
+ if (text === contextSentences.recording("active")) {
114
+ this.#call.setRecordingActive(true);
115
+ return;
116
+ }
117
+ if (text === contextSentences.recording("inactive")) {
118
+ this.#call.setRecordingActive(false);
119
+ return;
120
+ }
121
+ this.#call.pushContext(text);
122
+ }
123
+ /**
124
+ * StandIn is ending the call and wants this line spoken first.
125
+ *
126
+ * Interrupt, then say. A goodbye queued behind a long answer is a goodbye the
127
+ * caller never hears, and teardown follows within seconds.
128
+ */
129
+ async onGoodbye(text) {
130
+ if (!this.#call)
131
+ return;
132
+ this.#call.interrupt();
133
+ this.#call.say(text);
134
+ }
135
+ /** Always called exactly once, on every path, before the slot is freed. */
136
+ async aclose(reason) {
137
+ this.#call?.close();
138
+ this.#call = undefined;
139
+ if (this.#held) {
140
+ this.#deps.registry.release(this.#callId);
141
+ this.#held = false;
142
+ }
143
+ this.#deps.logger?.info?.(`standin-msteams: call ${this.#callId} ended (${reason})`);
144
+ }
145
+ }
146
+ //# sourceMappingURL=handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/plugins/openclaw/handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * The StandIn plugin for OpenClaw: your agent, in a real Microsoft Teams call.
3
+ *
4
+ * This is not a worker you run. It is an OpenClaw plugin, and it has to be: it
5
+ * consumes the host's realtime speech-to-speech session, its provider registry
6
+ * and its logger, all of which are in-process objects inside the gateway.
7
+ * OpenClaw's external HTTP surface is text-only, so a standalone worker could only
8
+ * use OpenClaw as a text brain and bring its own STT and TTS - which is exactly
9
+ * the part this plugin exists to avoid.
10
+ *
11
+ * It lives inside `@komaa/standin-sdk` rather than in a package of its own, and
12
+ * nothing in the SDK core imports it, so an install that never touches OpenClaw
13
+ * never loads this file. The `openclaw` imports below are therefore at module
14
+ * scope on purpose: by the time anything reaches here, the host IS the process.
15
+ *
16
+ * OpenClaw does not load a plugin by package specifier. It is given a DIRECTORY
17
+ * through `plugins.load.paths`, so the built form of this file ships as a
18
+ * self-describing directory inside the published package:
19
+ *
20
+ * ```jsonc
21
+ * // openclaw.json
22
+ * { "plugins": {
23
+ * "load": { "paths": ["node_modules/@komaa/standin-sdk/dist/plugins/openclaw"] },
24
+ * "entries": { "standin-msteams": { "enabled": true, "config": {
25
+ * "secret": "sk_standin_...",
26
+ * "inboundPolicy": "allowlist",
27
+ * "allowFrom": ["<caller AAD object id>"],
28
+ * "realtime": { "provider": "openai", "providers": { "openai": { "apiKey": "sk-..." } } }
29
+ * } } }
30
+ * } }
31
+ * ```
32
+ *
33
+ * `openclaw.plugin.json` and the directory's own `package.json` are placed beside
34
+ * the emitted `index.js` by `scripts/emit-openclaw-plugin-dir.mjs`, because `tsc`
35
+ * emits only `.ts` and a manifest one level up is a manifest the host never sees.
36
+ *
37
+ * The plugin registers ONE host-managed background service, so OpenClaw's own
38
+ * lifecycle starts the call listener at boot and tears it down on shutdown or
39
+ * reload. There is nothing to supervise separately.
40
+ */
41
+ import { type OpenClawPluginDefinition } from "openclaw/plugin-sdk/core";
42
+ export { resolvePluginConfig, type ResolvedPluginConfig } from "./config.js";
43
+ export { TeamsCallHandler, type CallRegistry, type HandlerDeps, } from "./handler.js";
44
+ export { createRealtimeCall, type RealtimeCall, type RealtimeCallDeps, } from "./realtime.js";
45
+ export { StandInCallRuntime } from "./runtime.js";
46
+ /**
47
+ * The entry OpenClaw loads.
48
+ *
49
+ * Annotated rather than inferred: the inferred type reaches into an internal
50
+ * OpenClaw declaration file whose name is a build hash, and a `.d.ts` that names
51
+ * it would not survive that package being rebuilt.
52
+ */
53
+ declare const entry: OpenClawPluginDefinition;
54
+ export default entry;
55
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/openclaw/index.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,EAEL,KAAK,wBAAwB,EAC9B,MAAM,0BAA0B,CAAC;AAKlC,OAAO,EAAE,mBAAmB,EAAE,KAAK,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,EACL,gBAAgB,EAChB,KAAK,YAAY,EACjB,KAAK,WAAW,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,kBAAkB,EAClB,KAAK,YAAY,EACjB,KAAK,gBAAgB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD;;;;;;GAMG;AACH,QAAA,MAAM,KAAK,EAAE,wBAqCX,CAAC;AAEH,eAAe,KAAK,CAAC"}
@@ -0,0 +1,89 @@
1
+ // Copyright (c) 2026 Komaa DigiTech
2
+ // SPDX-License-Identifier: MIT
3
+ /**
4
+ * The StandIn plugin for OpenClaw: your agent, in a real Microsoft Teams call.
5
+ *
6
+ * This is not a worker you run. It is an OpenClaw plugin, and it has to be: it
7
+ * consumes the host's realtime speech-to-speech session, its provider registry
8
+ * and its logger, all of which are in-process objects inside the gateway.
9
+ * OpenClaw's external HTTP surface is text-only, so a standalone worker could only
10
+ * use OpenClaw as a text brain and bring its own STT and TTS - which is exactly
11
+ * the part this plugin exists to avoid.
12
+ *
13
+ * It lives inside `@komaa/standin-sdk` rather than in a package of its own, and
14
+ * nothing in the SDK core imports it, so an install that never touches OpenClaw
15
+ * never loads this file. The `openclaw` imports below are therefore at module
16
+ * scope on purpose: by the time anything reaches here, the host IS the process.
17
+ *
18
+ * OpenClaw does not load a plugin by package specifier. It is given a DIRECTORY
19
+ * through `plugins.load.paths`, so the built form of this file ships as a
20
+ * self-describing directory inside the published package:
21
+ *
22
+ * ```jsonc
23
+ * // openclaw.json
24
+ * { "plugins": {
25
+ * "load": { "paths": ["node_modules/@komaa/standin-sdk/dist/plugins/openclaw"] },
26
+ * "entries": { "standin-msteams": { "enabled": true, "config": {
27
+ * "secret": "sk_standin_...",
28
+ * "inboundPolicy": "allowlist",
29
+ * "allowFrom": ["<caller AAD object id>"],
30
+ * "realtime": { "provider": "openai", "providers": { "openai": { "apiKey": "sk-..." } } }
31
+ * } } }
32
+ * } }
33
+ * ```
34
+ *
35
+ * `openclaw.plugin.json` and the directory's own `package.json` are placed beside
36
+ * the emitted `index.js` by `scripts/emit-openclaw-plugin-dir.mjs`, because `tsc`
37
+ * emits only `.ts` and a manifest one level up is a manifest the host never sees.
38
+ *
39
+ * The plugin registers ONE host-managed background service, so OpenClaw's own
40
+ * lifecycle starts the call listener at boot and tears it down on shutdown or
41
+ * reload. There is nothing to supervise separately.
42
+ */
43
+ import { definePluginEntry, } from "openclaw/plugin-sdk/core";
44
+ import { resolvePluginConfig } from "./config.js";
45
+ import { StandInCallRuntime } from "./runtime.js";
46
+ export { resolvePluginConfig } from "./config.js";
47
+ export { TeamsCallHandler, } from "./handler.js";
48
+ export { createRealtimeCall, } from "./realtime.js";
49
+ export { StandInCallRuntime } from "./runtime.js";
50
+ /**
51
+ * The entry OpenClaw loads.
52
+ *
53
+ * Annotated rather than inferred: the inferred type reaches into an internal
54
+ * OpenClaw declaration file whose name is a build hash, and a `.d.ts` that names
55
+ * it would not survive that package being rebuilt.
56
+ */
57
+ const entry = definePluginEntry({
58
+ id: "standin-msteams",
59
+ name: "Microsoft Teams calls by StandIn",
60
+ description: "Put your OpenClaw agent in a real Microsoft Teams call, through StandIn.",
61
+ register(api) {
62
+ const config = resolvePluginConfig(api.pluginConfig);
63
+ if (!config.enabled)
64
+ return;
65
+ // Fail CLOSED on the secret. Every socket StandIn dials is HMAC-authenticated
66
+ // with it, so starting without one would mean either refusing every call or,
67
+ // worse, accepting anything - and `CallServer` rightly throws rather than
68
+ // choose. Say why here, where an operator is reading the log, instead of
69
+ // letting the service registration throw during boot.
70
+ if (!config.media.secret) {
71
+ api.logger.warn("standin-msteams: no secret configured - set `secret` to the value the StandIn portal shows you. Nothing started.");
72
+ return;
73
+ }
74
+ let runtime;
75
+ api.registerService({
76
+ id: "standin-msteams",
77
+ start: async () => {
78
+ runtime = new StandInCallRuntime(api, config);
79
+ await runtime.start();
80
+ },
81
+ stop: async () => {
82
+ await runtime?.stop();
83
+ runtime = undefined;
84
+ },
85
+ });
86
+ },
87
+ });
88
+ export default entry;
89
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/openclaw/index.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,+BAA+B;AAE/B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,EACL,iBAAiB,GAElB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EAAE,mBAAmB,EAA6B,MAAM,aAAa,CAAC;AAC7E,OAAO,EACL,gBAAgB,GAGjB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,kBAAkB,GAGnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD;;;;;;GAMG;AACH,MAAM,KAAK,GAA6B,iBAAiB,CAAC;IACxD,EAAE,EAAE,iBAAiB;IACrB,IAAI,EAAE,kCAAkC;IACxC,WAAW,EACT,0EAA0E;IAC5E,QAAQ,CAAC,GAAG;QACV,MAAM,MAAM,GAAG,mBAAmB,CAC/B,GAAkC,CAAC,YAAY,CACjD,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO;QAE5B,8EAA8E;QAC9E,6EAA6E;QAC7E,0EAA0E;QAC1E,yEAAyE;QACzE,sDAAsD;QACtD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACzB,GAAG,CAAC,MAAM,CAAC,IAAI,CACb,kHAAkH,CACnH,CAAC;YACF,OAAO;QACT,CAAC;QAED,IAAI,OAAuC,CAAC;QAE5C,GAAG,CAAC,eAAe,CAAC;YAClB,EAAE,EAAE,iBAAiB;YACrB,KAAK,EAAE,KAAK,IAAI,EAAE;gBAChB,OAAO,GAAG,IAAI,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;gBAC9C,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;YACxB,CAAC;YACD,IAAI,EAAE,KAAK,IAAI,EAAE;gBACf,MAAM,OAAO,EAAE,IAAI,EAAE,CAAC;gBACtB,OAAO,GAAG,SAAS,CAAC;YACtB,CAAC;SACF,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC;AAEH,eAAe,KAAK,CAAC"}
@@ -0,0 +1,74 @@
1
+ {
2
+ "id": "standin-msteams",
3
+ "name": "Microsoft Teams calls by StandIn",
4
+ "description": "Put your OpenClaw agent in a real Microsoft Teams call. StandIn owns the Microsoft side and dials this plugin once per call; the call is bridged straight to your configured realtime speech-to-speech provider.",
5
+ "icon": "https://standin.komaa.com/brand/standin-s-mark.png",
6
+ "activation": { "onStartup": true },
7
+ "configSchema": {
8
+ "type": "object",
9
+ "additionalProperties": false,
10
+ "properties": {
11
+ "enabled": { "type": "boolean" },
12
+ "secret": {
13
+ "type": "string",
14
+ "description": "The StandIn connection secret. Paste the value the StandIn portal shows you. Without it nothing starts."
15
+ },
16
+ "callingPort": {
17
+ "type": "integer",
18
+ "minimum": 1,
19
+ "maximum": 65535,
20
+ "description": "Port the call listener binds (default 9442)."
21
+ },
22
+ "bindAddress": {
23
+ "type": "string",
24
+ "description": "Address the call listener binds. Defaults to 0.0.0.0; set 127.0.0.1 when only a local tunnel should reach it."
25
+ },
26
+ "path": {
27
+ "type": "string",
28
+ "description": "Path StandIn dials (default /msteams/calling)."
29
+ },
30
+ "maxConcurrentCalls": { "type": "integer", "minimum": 1 },
31
+ "inboundPolicy": {
32
+ "type": "string",
33
+ "enum": ["disabled", "allowlist", "pairing", "open"],
34
+ "description": "Who may call. Defaults to disabled, which refuses every call."
35
+ },
36
+ "allowFrom": {
37
+ "type": "array",
38
+ "items": { "type": "string" },
39
+ "description": "AAD object ids (or phone numbers) accepted under allowlist/pairing."
40
+ },
41
+ "inboundGreeting": {
42
+ "type": "string",
43
+ "description": "What the agent says when it picks up. Omitted means it waits for the caller to speak first."
44
+ },
45
+ "requireRecordingStatus": {
46
+ "type": "boolean",
47
+ "description": "Hold caller audio back until Microsoft Teams reports recording active (Microsoft Media Access API obligation)."
48
+ },
49
+ "realtime": {
50
+ "type": "object",
51
+ "additionalProperties": false,
52
+ "properties": {
53
+ "provider": { "type": "string" },
54
+ "providers": {
55
+ "type": "object",
56
+ "additionalProperties": { "type": "object", "additionalProperties": true }
57
+ },
58
+ "instructions": { "type": "string" },
59
+ "suppressInputDuringPlayback": { "type": "boolean" },
60
+ "echoSuppressionWindowMs": { "type": "integer", "minimum": 0 },
61
+ "echoBargeInRms": { "type": "number", "minimum": 0, "maximum": 1 }
62
+ }
63
+ }
64
+ }
65
+ },
66
+ "configContracts": {
67
+ "secretInputs": {
68
+ "paths": [
69
+ { "path": "secret", "expected": "string" },
70
+ { "path": "realtime.providers.*.apiKey", "expected": "string" }
71
+ ]
72
+ }
73
+ }
74
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "@komaa/standin-sdk-openclaw",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "openclaw": {
7
+ "extensions": [
8
+ "./index.js"
9
+ ],
10
+ "compat": {
11
+ "pluginApi": ">=2026.6.10"
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,82 @@
1
+ /**
2
+ * One Microsoft Teams call, bridged to OpenClaw's realtime speech-to-speech session.
3
+ *
4
+ * This file is the reason the plugin cannot be a standalone worker. It does not
5
+ * drive a model: it CONSUMES the host's realtime session
6
+ * (`createRealtimeVoiceBridgeSession`), the host's provider registry and the
7
+ * host's config, all of which are in-process objects inside the OpenClaw gateway.
8
+ * Nothing here opens a provider socket, and nothing here knows which vendor is on
9
+ * the other end.
10
+ *
11
+ * What it does own is the audio boundary between two rates and two framings:
12
+ *
13
+ * caller 16 kHz --> 24 kHz --> host realtime session
14
+ * model 24 kHz --> 16 kHz --> session.sendAudio
15
+ *
16
+ * and the three things that make a spoken call feel right rather than merely
17
+ * work: the echo guard, the playout clock the guard keys on, and barge-in.
18
+ *
19
+ * Everything the SDK owns is deliberately absent here: the socket, the sequence
20
+ * number, the outbound timeline, the frame loop and the watchdogs.
21
+ */
22
+ import { type CallSession } from "../../index.js";
23
+ import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
24
+ import { type RealtimeVoiceProviderConfig, type RealtimeVoiceProviderPlugin } from "openclaw/plugin-sdk/realtime-voice";
25
+ import { type EchoGuardOptions } from "../../echoGuard.js";
26
+ /**
27
+ * The logging surface this file needs, and no more.
28
+ *
29
+ * Structural, not OpenClaw's `PluginLogger`, so a test can pass `{}` and the call
30
+ * path stays identical. Every method is optional for the same reason.
31
+ */
32
+ export interface CallLogger {
33
+ debug?(message: string): void;
34
+ info?(message: string): void;
35
+ warn?(message: string): void;
36
+ error?(message: string): void;
37
+ }
38
+ /** What the runtime hands one call. Resolved once at startup, shared by every call. */
39
+ export interface RealtimeCallDeps {
40
+ /** The host's realtime voice provider, already resolved and credentialed. */
41
+ provider: RealtimeVoiceProviderPlugin;
42
+ providerConfig: RealtimeVoiceProviderConfig;
43
+ /** The gateway's own config, which the host session reads for model defaults. */
44
+ cfg?: OpenClawConfig;
45
+ /** System instructions for this call. */
46
+ instructions?: string;
47
+ /** Spoken on pickup. Undefined means the agent waits for the caller to speak. */
48
+ greetingInstructions?: string;
49
+ /** Withhold caller media until Microsoft Teams reports recording active. */
50
+ requireRecordingStatus: boolean;
51
+ echo: EchoGuardOptions;
52
+ logger?: CallLogger;
53
+ }
54
+ /** One bridged call, as {@link TeamsCallHandler} drives it. */
55
+ export interface RealtimeCall {
56
+ /** Open the provider session. Rejects if the model never comes up. */
57
+ connect(): Promise<void>;
58
+ /** One frame of caller audio, PCM16 16 kHz mono LE, straight off the wire. */
59
+ pushAudio(pcm16k: Buffer): void;
60
+ /** Put a plain sentence in front of the model without interrupting it. */
61
+ pushContext(text: string): void;
62
+ /** Microsoft Teams recording status changed. Opens or closes the media gate. */
63
+ setRecordingActive(active: boolean): void;
64
+ /** Cut the model off mid-turn. Call before {@link RealtimeCall.say}. */
65
+ interrupt(): void;
66
+ /** Speak this line in the agent's own voice, now. */
67
+ say(text: string): void;
68
+ /** Release the provider session. Idempotent. */
69
+ close(): void;
70
+ }
71
+ /**
72
+ * Build the bridge for one call.
73
+ *
74
+ * `session` is the SDK's {@link CallSession}: the only route to the caller, and
75
+ * the owner of the sequence number and the outbound timeline, so nothing here
76
+ * tracks either.
77
+ */
78
+ export declare function createRealtimeCall(params: {
79
+ session: CallSession;
80
+ deps: RealtimeCallDeps;
81
+ }): RealtimeCall;
82
+ //# sourceMappingURL=realtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime.d.ts","sourceRoot":"","sources":["../../../src/plugins/openclaw/realtime.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAML,KAAK,WAAW,EACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,EAGL,KAAK,2BAA2B,EAChC,KAAK,2BAA2B,EACjC,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAsB,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG/E;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,uFAAuF;AACvF,MAAM,WAAW,gBAAgB;IAC/B,6EAA6E;IAC7E,QAAQ,EAAE,2BAA2B,CAAC;IACtC,cAAc,EAAE,2BAA2B,CAAC;IAC5C,iFAAiF;IACjF,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,yCAAyC;IACzC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,4EAA4E;IAC5E,sBAAsB,EAAE,OAAO,CAAC;IAChC,IAAI,EAAE,gBAAgB,CAAC;IACvB,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,+DAA+D;AAC/D,MAAM,WAAW,YAAY;IAC3B,sEAAsE;IACtE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,8EAA8E;IAC9E,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,0EAA0E;IAC1E,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,gFAAgF;IAChF,kBAAkB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1C,wEAAwE;IACxE,SAAS,IAAI,IAAI,CAAC;IAClB,qDAAqD;IACrD,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,gDAAgD;IAChD,KAAK,IAAI,IAAI,CAAC;CACf;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IACzC,OAAO,EAAE,WAAW,CAAC;IACrB,IAAI,EAAE,gBAAgB,CAAC;CACxB,GAAG,YAAY,CAwOf"}