merge: W2 — A2 interrupt scope(传输层 + 设置项)

This commit is contained in:
AskaEth committed 2026-10-04 17:44:21 +08:00
commit b44e8d96b9
6 files changed
+233 -4

No files matched your search

@@ -155,8 +155,18 @@ class ChatSocket(
),
)
/** 发送 `interrupt`(取消在跑 turn + 清空 pending)。 */
fun sendInterrupt(sessionId: String): Boolean = send(WsOutbound.Interrupt(sessionId))
/**
* 发送 `interrupt`(api-client §3.1;契约 v0.56/A2 起支持 `scope`)。
*
* @param scope 打断范围:`null` = **省略该键**(服务端视同 `"all"`:取消在跑回合 + 清空待处理队列,
* 与加入 `scope` 之前**逐字节相同**);`"current"` = 只取消在跑回合、保留待处理队列。
* 其它取值原样发出,服务端**定向**回 `error{bad_request}` 且不打断任何会话(本层不预判取值域)。
*
* **今天没有任何调用方**:聊天的「打断」触发点属聊天区那一轮,本 API 先把传输面备好——
* 调用方从 App 偏好(`InterruptMode`)取 `scope` 后传进来即可。
*/
fun sendInterrupt(sessionId: String, scope: String? = null): Boolean =
send(WsOutbound.Interrupt(sessionId = sessionId, scope = scope))
private fun send(outbound: WsOutbound): Boolean {
if (_state.value != WsState.Connected) return false
@@ -56,14 +56,25 @@ sealed interface WsOutbound {
}
}
/** `interrupt`:`{sessionId}`。命中空闲会话为 no-op。 */
/** `interrupt`:`{sessionId, scope?}`。命中空闲会话为 no-op。 */
data class Interrupt(
val sessionId: String,
/**
* 打断范围(契约 v0.56/A2,api-client §3.1):取值域 `{"", "all", "current"}`。
* `null` = **整键省略**——服务端视同 `"all"`(取消在跑回合 + 清空待处理队列),
* 也就是加入该字段之前那条帧**逐字节相同**;`"current"` = 只取消在跑回合、**保留**待处理队列。
* 其它取值服务端定向回 `error{bad_request}`(不打断任何会话)——故本层**原样透传**,
* 不做取值校验、不静默回退成默认(服务端的开放取值域由服务端裁决)。
*/
val scope: String? = null,
override val reqId: String? = null,
) : WsOutbound {
override val type: String get() = "interrupt"
override fun data(): JsonElement = buildJsonObject { put("sessionId", sessionId) }
override fun data(): JsonElement = buildJsonObject {
put("sessionId", sessionId)
scope?.let { put("scope", it) }
}
}
/** `voice_input`:`{audio?, format?, text?, sessionId?}`。 */