Files
hunjing/shenshi/internal/transform/stub.go
T

50 lines
1.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Package transform 定义出站适配器:IR → Provider 方言的转换层。
// M0 只含回声 stub 适配器;云 Provider adaptor(openai_compatible/anthropic)与
// 本地元炁端点按 rewrite-plan M4 落地(docs/architecture/shenshi-gateway.md §5)。
package transform
import (
"context"
"hunjing/shenshi/internal/ir"
)
// Adaptor 出站适配器契约:消费 IR 请求,产出标准化增量流。
type Adaptor interface {
// Stream 产出增量;context 取消时须及时返回。
Stream(ctx context.Context, req *ir.ChatRequest, out chan<- ir.Delta) error
// Name 适配器稳定标识(endpoint.type 取值,契约词典 §14.2)。
Name() string
}
// chunkSize stub 回声切分粒度(与灵台 EchoShenshi 对齐,便于联调对比)。
const chunkSize = 8
// StubAdaptor 回声适配器:把最后一条用户消息加前缀后按固定粒度回流。
// 仅用于 M0 骨架端到端验证,不模拟任何 Provider 行为。
type StubAdaptor struct{}
// Name 实现 Adaptor。
func (StubAdaptor) Name() string { return "stub" }
// Stream 实现 Adaptor:逐块产出增量并在末帧携带用量。
func (StubAdaptor) Stream(ctx context.Context, req *ir.ChatRequest, out chan<- ir.Delta) error {
prompt := req.LastUserMessage()
runes := []rune("【神识回声桩】" + prompt) // 按 rune 切分,与灵台回声桩的码点语义对齐
for i := 0; i < len(runes); i += chunkSize {
select {
case <-ctx.Done():
return ctx.Err()
default:
}
end := min(i+chunkSize, len(runes))
out <- ir.Delta{Delta: string(runes[i:end])}
}
out <- ir.Delta{
FinishReason: "stop",
UsagePromptTokens: max(len([]rune(prompt))/4, 1),
UsageCompletionTokens: max(len(runes)/4, 1),
}
return nil
}