// 适配 `DC-Z-lab/moonllm@0.1.0`。
//
// 该 SDK 的 `ToolCallAccumulator` 把参数片段拼进 StringBuilder,等到
// `finish` 才给出完整字符串;`ToolCallDelta.arguments` 就是本库要消费的
// "参数文本片段"。本适配器把每个 `ToolCallDelta` 直接送进 Session,
// 于是同一个流的消费方不必再自己维护一套拼接与部分解析。
//
// 键映射:`ToolCallDelta.index`(该 choice 内的工具调用序号)→ `CallKey.index`,
// `choice` 固定为 0(该 SDK 的 `parse_stream_data` 只读取 choices[0])。
//
// apply 在收到 StreamChunk.finish_reason 时自动收尾。
// 意外断流由调用方使用显式 Truncated / Cancelled 原因收尾。
///|
/// `moonllm` 流式 chunk 到 MoonStream 会话的适配器。
pub struct MoonllmAdapter {
session : @session.Session
response_id : String
choice : Int
}
///|
/// 创建适配器。
pub fn MoonllmAdapter::new(
response_id? : String,
choice? : Int,
) -> MoonllmAdapter raise @session.SessionError {
{
session: @session.Session::new(),
response_id: match response_id {
Some(value) => value
None => ""
},
choice: match choice {
Some(value) => value
None => 0
},
}
}
///|
/// 底层会话。
pub fn MoonllmAdapter::session(self : MoonllmAdapter) -> @session.Session {
self.session
}
///|
/// 工具调用序号对应的调用键。
pub fn MoonllmAdapter::key(
self : MoonllmAdapter,
index : Int,
) -> @session.CallKey {
@session.CallKey::new(response=self.response_id, choice=self.choice, index~)
}
///|
/// 处理一个流式 chunk。
///
/// 首个带 `id` / `name` 的片段会注册调用上下文;带 `arguments` 的片段被喂入解析器。
/// 文本增量与其它字段被忽略。
pub fn MoonllmAdapter::apply(
self : MoonllmAdapter,
chunk : @sdk.StreamChunk,
) -> @adapter.AdapterOutcome raise @session.SessionError {
let updates = []
for delta in chunk.tool_calls {
let key = self.key(delta.index)
// 总是尝试注册:首个片段建立上下文,后续片段的 id / name 若与已有值冲突,
// Session 会报 CallIdConflict / CallNameConflict,而不是把两个调用拼在一起。
self.session.open(key, id=delta.id, name=delta.name)
match delta.arguments {
Some(arguments) =>
match self.session.feed(key, @utf8.encode(arguments)) {
[] => ()
events => updates.push(@adapter.CallUpdate::delta(key, events))
}
None => ()
}
}
match chunk.finish_reason {
Some(reason) => updates.append(self.finish_updates(reason.end_reason()))
None => ()
}
if updates.is_empty() {
@adapter.AdapterOutcome::Ignored
} else {
@adapter.AdapterOutcome::Updates(updates~)
}
}
///|
fn String::end_reason(self : String) -> @moonstream.EndReason {
match self {
"stop" | "end_turn" | "tool_calls" | "tool_use" =>
@moonstream.EndReason::EndOfStream
_ => @moonstream.EndReason::Truncated
}
}
///|
fn MoonllmAdapter::finish_updates(
self : MoonllmAdapter,
reason : @moonstream.EndReason,
) -> Array[@adapter.CallUpdate] {
@adapter.finish_open(self.session, reason)
}
///|
/// 结束一个调用(例如收到 `finish_reason` 时)。
pub fn MoonllmAdapter::finish_call(
self : MoonllmAdapter,
index : Int,
reason~ : @moonstream.EndReason,
) -> (Array[@moonstream.Event], @moonstream.FinishResult) raise @session.SessionError {
self.session.finish(self.key(index), reason~)
}
///|
/// 结束所有仍在进行的调用,按注册顺序返回带收尾事件、结果或 failure 的更新。
pub fn MoonllmAdapter::finish_all(
self : MoonllmAdapter,
reason~ : @moonstream.EndReason,
) -> Array[@adapter.CallUpdate] {
self.finish_updates(reason)
}