///|
/// Lux IR — Prism 中立中间协议(v1)
///
/// 依据:docs/lux-ir-design.md
/// 骨干:LucentConversationItem 异质平级,承载消息/工具调用/工具结果/推理/Agent 动作
/// 版本:schema_version = "v1"
///|
/// LucentRole — 对话角色
pub(all) enum LucentRole {
System
User
Assistant
Tool
Model
Developer
Native(String)
} derive(Eq, Debug)
///|
/// LucentModality — 模态声明
pub(all) enum LucentModality {
Text
Image
Audio
Video
Pdf
Native(String)
} derive(Eq, Debug)
///|
/// LucentMediaSource — 多模态来源三选一
pub(all) enum LucentMediaSource {
Inline(String)
Url(String)
FileUri(String)
} derive(Eq, Debug)
///|
/// LucentMultimedia — 多模态媒体块
pub struct LucentMultimedia {
media_type : String
source : LucentMediaSource
} derive(Eq, Debug)
///|
/// LucentAnnotationKind — 标注类型
pub(all) enum LucentAnnotationKind {
Url
FileCitation
WebSearchCitation
Native(String)
} derive(Eq, Debug)
///|
/// LucentAnnotation — 标注侧信道
pub struct LucentAnnotation {
kind : LucentAnnotationKind
text : String?
reference : String?
start : Int?
end : Int?
} derive(Eq, Debug)
///|
/// LucentThinking — 推理内容
pub struct LucentThinking {
text : String
signature : String?
redacted : Bool
summary : Array[LucentContent]?
} derive(Eq, Debug)
///|
/// LucentToolUse — 工具调用(结构化)
pub struct LucentToolUse {
id : String
name : String
arguments_json : String
arguments_value : Json?
} derive(Eq, Debug)
///|
/// LucentToolResult — 工具结果(多块内容)
pub struct LucentToolResult {
tool_use_id : String
content : Array[LucentContent]
is_error : Bool
} derive(Eq, Debug)
///|
/// LucentAgentAction — Agent 动作占位(v1 仅类型化,参数走 provider_payload)
pub struct LucentAgentAction {
kind : String
id : String
call_id : String?
name : String?
arguments_json : String?
result : String?
provider_payload : Json?
} derive(Eq, Debug)
///|
/// LucentContent — 内容块主枚举
pub(all) enum LucentContent {
Text(String, Array[LucentAnnotation]?)
ToolUse(LucentToolUse)
ToolResult(LucentToolResult)
Thinking(LucentThinking)
Refusal(String)
Image(LucentMultimedia)
Audio(LucentMultimedia)
Video(LucentMultimedia)
File(LucentMultimedia)
Native(String, Json)
} derive(Eq, Debug)
///|
/// LucentMessage — 消息特例(role + content 块数组)
pub struct LucentMessage {
role : LucentRole
content : Array[LucentContent]
phase : String?
/// 消息级 reasoning(vLLM/DeepSeek/Fireworks 的 message.reasoning / reasoning_content)
reasoning : LucentThinking?
} derive(Eq, Debug)
///|
/// LucentConversationItem — 会话项异质平级
pub(all) enum LucentConversationItem {
Message(LucentMessage)
ToolCall(LucentToolUse)
ToolResult(LucentToolResult)
Reasoning(LucentThinking)
AgentAction(LucentAgentAction)
} derive(Eq, Debug)
///|
/// LucentToolKind — 工具类型(消费方处理逻辑不同)
pub(all) enum LucentToolKind {
Function
FileSearch
WebSearch
CodeInterpreter
ComputerUse
CodeExecution
Shell
ApplyPatch
MCP
Native(String)
} derive(Eq, Debug)
///|
/// LucentTool — 工具定义
pub struct LucentTool {
name : String
description : String?
parameters_json : String
strict : Bool?
kind : LucentToolKind
} derive(Eq, Debug)
///|
/// LucentToolChoice — 工具选择(类型化)
pub(all) enum LucentToolChoice {
Auto
None
Required
SpecificTool(String)
} derive(Eq, Debug)
///|
/// LucentStructuredOutput — 结构化输出
pub(all) enum LucentStructuredOutput {
JsonObject
Text
JsonSchema(String)
} derive(Eq, Debug)
///|
/// LucentOptions — 生成参数
pub struct LucentOptions {
temperature : Double?
top_p : Double?
top_k : Int?
max_output_tokens : Int?
stop : Array[String]?
stream : Bool
candidate_count : Int?
structured_output : LucentStructuredOutput?
store : Bool?
extras : Map[String, Json]?
} derive(Eq, Debug)
///|
/// LucentReasoningEffort — 推理力度
pub(all) enum LucentReasoningEffort {
Low
Medium
High
XHigh
} derive(Eq, Debug)
///|
/// LucentReasoningSummary — 推理摘要详细度
pub(all) enum LucentReasoningSummary {
Auto
Concise
Detailed
} derive(Eq, Debug)
///|
/// LucentReasoningConfig — 推理配置
pub struct LucentReasoningConfig {
enabled : Bool
budget_tokens : Int?
effort : LucentReasoningEffort?
summary : LucentReasoningSummary?
} derive(Eq, Debug)
///|
/// SupportLevel — 能力支持级别
/// 替代原有 Bool 能力声明,区分「完全支持 / 部分支持 / 不支持」三档。
/// 线格式:`"full"` / `"partial"` / `"none"`(`Absent` 命名避开 Option::None 冲突)。
pub(all) enum SupportLevel {
Full
Partial
Absent
} derive(Eq, Debug)
///|
pub fn SupportLevel::from_string(s : String) -> SupportLevel? {
match s {
"full" => Some(Full)
"partial" => Some(Partial)
"none" => Some(Absent)
_ => None
}
}
///|
pub fn SupportLevel::to_string(self : SupportLevel) -> String {
match self {
Full => "full"
Partial => "partial"
Absent => "none"
}
}
///|
/// LucentCapabilities — 标准化能力声明
pub struct LucentCapabilities {
tool_calling : SupportLevel
parallel_tool_calls : SupportLevel
reasoning : SupportLevel
multimodal_input : SupportLevel
structured_output : SupportLevel
input_modalities : Array[LucentModality]
output_modalities : Array[LucentModality]
} derive(Eq, Debug)
///|
/// LucentRequest — 完整 LLM 请求
pub struct LucentRequest {
schema_version : String
model : String
instructions : Array[LucentContent]?
conversation : Array[LucentConversationItem]
tools : Array[LucentTool]?
tool_choice : LucentToolChoice?
options : LucentOptions
capabilities : LucentCapabilities?
reasoning : LucentReasoningConfig?
metadata : Map[String, String]?
extra : Map[String, Json]?
} derive(Eq, Debug)
///|
/// LucentUsage — Token 用量(面向 reasoning 时代)
pub struct LucentUsage {
prompt_tokens : Int
completion_tokens : Int
total_tokens : Int
reasoning_tokens : Int?
cached_tokens : Int?
cache_creation_tokens : Int?
} derive(Eq, Debug)
///|
/// LucentFinishReason — 结束原因
pub(all) enum LucentFinishReason {
Stop
Length
ToolCalls
ContentFilter
Safety
Recitation
MalformedToolCall
Error
Native(String)
} derive(Eq, Debug)
///|
/// LucentSafetyRating — 安全评级
pub struct LucentSafetyRating {
category : String
probability : String
} derive(Eq, Debug)
///|
/// LucentChoice — 候选回复
pub struct LucentChoice {
index : Int
message : LucentMessage
finish_reason : LucentFinishReason
safety_ratings : Array[LucentSafetyRating]?
} derive(Eq, Debug)
///|
/// LucentResponse — 非流式 LLM 响应
pub struct LucentResponse {
schema_version : String
id : String
model : String
created_at : Int?
choices : Array[LucentChoice]
usage : LucentUsage?
provider_payload : Json?
} derive(Eq, Debug)
///|
/// ProviderCapability — 适配器能力声明(SDK 自省用)
pub struct ProviderCapability {
model_pattern : String
provider : String
capabilities : LucentCapabilities
extra_params : Map[String, Json]?
} derive(Eq, Debug)
///|
pub fn ProviderCapability::new(
model_pattern : String,
provider : String,
capabilities : LucentCapabilities,
extra_params : Map[String, Json]?,
) -> ProviderCapability {
{ model_pattern, provider, capabilities, extra_params }
}
///|
/// ConversionStatus — 字段转换状态(五道门治理要求)
pub(all) enum ConversionStatus {
Exact // 字段完全对等映射,无信息丢失
Degraded // 字段被近似映射,部分语义丢失
Unsupported // 字段不被目标协议支持,已舍弃
Invalid // 字段格式错误或值非法
} derive(Eq, Debug)
///|
/// ConversionDiagnostic — 单个字段的转换结果诊断
pub struct ConversionDiagnostic {
field : String
status : ConversionStatus
detail : String?
} derive(Eq, Debug)
///|
pub fn ConversionDiagnostic::new(
field : String,
status : ConversionStatus,
detail : String?,
) -> ConversionDiagnostic {
{ field, status, detail }
}
///|
/// ConversionResult — 带诊断的转换结果
/// 成功时不等于 Exact:value 可用但部分字段已丢失
pub struct ConversionResult[T] {
value : T
diagnostics : Array[ConversionDiagnostic]
} derive(Eq, Debug)
///|
pub fn[T] ConversionResult::new(value : T) -> ConversionResult[T] {
{ value, diagnostics: [] }
}
///|
/// 获取转换结果值。
pub fn[T] ConversionResult::value(self : ConversionResult[T]) -> T {
self.value
}
///|
/// 获取转换诊断列表。
pub fn[T] ConversionResult::diagnostics(
self : ConversionResult[T],
) -> Array[ConversionDiagnostic] {
self.diagnostics
}
///|
/// 追加一条转换诊断(返回新结果,不修改原结果的诊断数组)。
pub fn[T] ConversionResult::with_diagnostic(
self : ConversionResult[T],
diagnostic : ConversionDiagnostic,
) -> ConversionResult[T] {
let diagnostics = self.diagnostics.copy()
diagnostics.push(diagnostic)
{ ..self, diagnostics, }
}
///|
/// 批量附加诊断(返回新结果,等价于逐条 with_diagnostic)。
pub fn[T] ConversionResult::with_diagnostics(
self : ConversionResult[T],
diagnostics : Array[ConversionDiagnostic],
) -> ConversionResult[T] {
if diagnostics.length() == 0 {
return self
}
let all = self.diagnostics.copy()
for d in diagnostics {
all.push(d)
}
{ ..self, diagnostics: all }
}
///|
/// 构造 Unsupported 诊断(provider 适配器共用样板)。
pub fn ConversionDiagnostic::unsupported(
field : String,
detail : String?,
) -> ConversionDiagnostic {
{ field, status: Unsupported, detail }
}
///|
/// 构造 Degraded 诊断(provider 适配器共用样板)。
pub fn ConversionDiagnostic::degraded(
field : String,
detail : String?,
) -> ConversionDiagnostic {
{ field, status: Degraded, detail }
}
///|
/// 获取诊断状态。
pub fn ConversionDiagnostic::status(
self : ConversionDiagnostic,
) -> ConversionStatus {
self.status
}
///|
/// LucentDiscovery — 能力发现响应
/// SDK 接入时第一步调用,获取 Prism 实例的能力清单
pub struct LucentDiscovery {
schema_version : String
protocol_version : String
schema_url : String
providers : Array[ProviderCapability]
} derive(Eq, Debug)
///|
pub fn LucentDiscovery::new(
protocol_version : String,
schema_url : String,
providers : Array[ProviderCapability],
) -> LucentDiscovery {
{ schema_version: "v1", protocol_version, schema_url, providers }
}
///|
/// 构造器与辅助函数
///|
pub fn LucentRole::from_string(s : String) -> LucentRole? {
match s {
"system" => Some(System)
"user" => Some(User)
"assistant" => Some(Assistant)
"tool" => Some(Tool)
"model" => Some(Model)
"developer" => Some(Developer)
_ => None
}
}
///|
pub fn LucentRole::to_string(self : LucentRole) -> String {
match self {
System => "system"
User => "user"
Assistant => "assistant"
Tool => "tool"
Model => "model"
Developer => "developer"
Native(s) => s
}
}
///|
pub fn LucentModality::from_string(s : String) -> LucentModality? {
match s {
"text" => Some(Text)
"image" => Some(Image)
"audio" => Some(Audio)
"video" => Some(Video)
"pdf" => Some(Pdf)
_ => None
}
}
///|
pub fn LucentMediaSource::inline(data : String) -> LucentMediaSource {
Inline(data)
}
///|
pub fn LucentMediaSource::url(u : String) -> LucentMediaSource {
Url(u)
}
///|
pub fn LucentMediaSource::file_uri(uri : String) -> LucentMediaSource {
FileUri(uri)
}
///|
pub fn LucentMultimedia::new(
media_type : String,
source : LucentMediaSource,
) -> LucentMultimedia {
{ media_type, source }
}
///|
pub fn LucentAnnotation::new(
kind : LucentAnnotationKind,
text : String?,
reference : String?,
start : Int?,
end : Int?,
) -> LucentAnnotation {
{ kind, text, reference, start, end }
}
///|
pub fn LucentThinking::new(
text : String,
signature : String?,
redacted : Bool,
summary : Array[LucentContent]?,
) -> LucentThinking {
{ text, signature, redacted, summary }
}
///|
pub fn LucentThinking::visible(
text : String,
signature : String?,
) -> LucentThinking {
{ text, signature, redacted: false, summary: None }
}
///|
pub fn LucentThinking::redacted(signature : String?) -> LucentThinking {
{ text: "", signature, redacted: true, summary: None }
}
///|
pub fn LucentToolUse::new(
id : String,
name : String,
arguments_json : String,
arguments_value : Json?,
) -> LucentToolUse {
{ id, name, arguments_json, arguments_value }
}
///|
pub fn LucentToolResult::new(
tool_use_id : String,
content : Array[LucentContent],
is_error : Bool,
) -> LucentToolResult {
{ tool_use_id, content, is_error }
}
///|
pub fn LucentToolResult::ok(
tool_use_id : String,
content : Array[LucentContent],
) -> LucentToolResult {
{ tool_use_id, content, is_error: false }
}
///|
pub fn LucentToolResult::error(
tool_use_id : String,
content : Array[LucentContent],
) -> LucentToolResult {
{ tool_use_id, content, is_error: true }
}
///|
pub fn LucentAgentAction::new(
kind : String,
id : String,
call_id : String?,
name : String?,
arguments_json : String?,
result : String?,
provider_payload : Json?,
) -> LucentAgentAction {
{ kind, id, call_id, name, arguments_json, result, provider_payload }
}
///|
pub fn LucentContent::text(s : String) -> LucentContent {
Text(s, None)
}
///|
pub fn LucentContent::text_with_annotations(
s : String,
annotations : Array[LucentAnnotation],
) -> LucentContent {
Text(s, Some(annotations))
}
///|
pub fn LucentContent::tool_use(
id : String,
name : String,
arguments_json : String,
arguments_value : Json?,
) -> LucentContent {
ToolUse({ id, name, arguments_json, arguments_value })
}
///|
pub fn LucentContent::tool_result(
tool_use_id : String,
content : Array[LucentContent],
) -> LucentContent {
ToolResult({ tool_use_id, content, is_error: false })
}
///|
pub fn LucentContent::tool_result_error(
tool_use_id : String,
content : Array[LucentContent],
) -> LucentContent {
ToolResult({ tool_use_id, content, is_error: true })
}
///|
pub fn LucentContent::thinking(
text : String,
signature : String?,
) -> LucentContent {
Thinking({ text, signature, redacted: false, summary: None })
}
///|
pub fn LucentContent::redacted_thinking(signature : String?) -> LucentContent {
Thinking({ text: "", signature, redacted: true, summary: None })
}
///|
pub fn LucentContent::refusal(text : String) -> LucentContent {
Refusal(text)
}
///|
pub fn LucentContent::image(
media_type : String,
source : LucentMediaSource,
) -> LucentContent {
Image({ media_type, source })
}
///|
/// 构造文件 content(PDF 等非媒体文件),来源三选一:url / inline / file_uri
pub fn LucentContent::file(
media_type : String,
source : LucentMediaSource,
) -> LucentContent {
File({ media_type, source })
}
///|
pub fn LucentContent::audio(
media_type : String,
source : LucentMediaSource,
) -> LucentContent {
Audio({ media_type, source })
}
///|
pub fn LucentContent::video(
media_type : String,
source : LucentMediaSource,
) -> LucentContent {
Video({ media_type, source })
}
///|
pub fn LucentContent::native(type_tag : String, raw : Json) -> LucentContent {
Native(type_tag, raw)
}
///|
pub fn LucentMessage::new(
role : LucentRole,
content : Array[LucentContent],
) -> LucentMessage {
{ role, content, phase: None, reasoning: None }
}
///|
pub fn LucentMessage::with_phase(
role : LucentRole,
content : Array[LucentContent],
phase : String?,
) -> LucentMessage {
{ role, content, phase, reasoning: None }
}
///|
/// 构造带消息级 reasoning 的 message(openai-chat 等适配器入站使用)
pub fn LucentMessage::with_reasoning(
role : LucentRole,
content : Array[LucentContent],
reasoning : LucentThinking?,
) -> LucentMessage {
{ role, content, phase: None, reasoning }
}
///|
pub fn LucentConversationItem::message(
msg : LucentMessage,
) -> LucentConversationItem {
Message(msg)
}
///|
pub fn LucentConversationItem::tool_call(
tu : LucentToolUse,
) -> LucentConversationItem {
ToolCall(tu)
}
///|
pub fn LucentConversationItem::tool_result(
tr : LucentToolResult,
) -> LucentConversationItem {
ToolResult(tr)
}
///|
pub fn LucentConversationItem::reasoning(
th : LucentThinking,
) -> LucentConversationItem {
Reasoning(th)
}
///|
pub fn LucentConversationItem::agent_action(
aa : LucentAgentAction,
) -> LucentConversationItem {
AgentAction(aa)
}
///|
/// 便利:将 Array[LucentMessage] 包装为 Array[LucentConversationItem]
pub fn lucent_items_from_messages(
msgs : Array[LucentMessage],
) -> Array[LucentConversationItem] {
let result : Array[LucentConversationItem] = []
let mut i = 0
while i < msgs.length() {
result.push(LucentConversationItem::message(msgs[i]))
i = i + 1
}
result
}
///|
pub fn LucentTool::new(
name : String,
description : String?,
parameters_json : String,
strict : Bool?,
kind : LucentToolKind,
) -> LucentTool {
{ name, description, parameters_json, strict, kind }
}
///|
pub fn LucentTool::simple(
name : String,
description : String,
parameters_json : String,
) -> LucentTool {
{
name,
description: Some(description),
parameters_json,
strict: None,
kind: Function,
}
}
///|
pub fn LucentOptions::default() -> LucentOptions {
{
temperature: None,
top_p: None,
top_k: None,
max_output_tokens: None,
stop: None,
stream: false,
candidate_count: None,
structured_output: None,
store: None,
extras: None,
}
}
///|
pub fn LucentOptions::new(
temperature : Double?,
top_p : Double?,
top_k : Int?,
max_output_tokens : Int?,
stop : Array[String]?,
stream : Bool,
candidate_count : Int?,
structured_output : LucentStructuredOutput?,
store : Bool?,
extras : Map[String, Json]?,
) -> LucentOptions {
{
temperature,
top_p,
top_k,
max_output_tokens,
stop,
stream,
candidate_count,
structured_output,
store,
extras,
}
}
///|
///|
pub fn LucentCapabilities::default() -> LucentCapabilities {
{
tool_calling: Absent,
parallel_tool_calls: Absent,
reasoning: Absent,
multimodal_input: Absent,
structured_output: Absent,
input_modalities: [],
output_modalities: [],
}
}
///|
pub fn LucentCapabilities::create(
tool_calling : SupportLevel,
parallel_tool_calls : SupportLevel,
reasoning : SupportLevel,
multimodal_input : SupportLevel,
structured_output : SupportLevel,
input_modalities : Array[LucentModality],
output_modalities : Array[LucentModality],
) -> LucentCapabilities {
{
tool_calling,
parallel_tool_calls,
reasoning,
multimodal_input,
structured_output,
input_modalities,
output_modalities,
}
}
///|
pub fn LucentReasoningConfig::enabled(budget : Int?) -> LucentReasoningConfig {
{ enabled: true, budget_tokens: budget, effort: None, summary: None }
}
///|
pub fn LucentReasoningConfig::new(
effort : LucentReasoningEffort?,
summary : LucentReasoningSummary?,
) -> LucentReasoningConfig {
{ enabled: true, budget_tokens: None, effort, summary }
}
///|
pub fn LucentReasoningConfig::disabled() -> LucentReasoningConfig {
{ enabled: false, budget_tokens: None, effort: None, summary: None }
}
///|
pub fn LucentRequest::new(
model : String,
instructions : Array[LucentContent]?,
conversation : Array[LucentConversationItem],
tools : Array[LucentTool]?,
tool_choice : LucentToolChoice?,
options : LucentOptions,
capabilities : LucentCapabilities?,
reasoning : LucentReasoningConfig?,
metadata : Map[String, String]?,
extra : Map[String, Json]?,
) -> LucentRequest {
{
schema_version: "v1",
model,
instructions,
conversation,
tools,
tool_choice,
options,
capabilities,
reasoning,
metadata,
extra,
}
}
///|
/// 构建含 store 值的选项副本
pub fn LucentOptions::with_store(
self : LucentOptions,
store : Bool?,
) -> LucentOptions {
{ ..self, store, }
}
///|
/// 构建含 extras 的选项副本
pub fn LucentOptions::with_extras(
self : LucentOptions,
extras : Map[String, Json]?,
) -> LucentOptions {
{ ..self, extras, }
}
///|
/// ValidateResult — 校验结果
pub struct ValidateResult {
valid : Bool
errors : Array[String]
warnings : Array[String]
}
///|
pub fn ValidateResult::ok() -> ValidateResult {
{ valid: true, errors: [], warnings: [] }
}
///|
pub fn ValidateResult::error(msg : String) -> ValidateResult {
{ valid: false, errors: [msg], warnings: [] }
}
///|
/// 校验 LucentRequest 的字段值合法性(与 ProviderCapability 无关的基本校验)
/// 例如:temperature 范围 [0, 2],max_output_tokens >= 1,model 非空
pub fn LucentRequest::validate(self : LucentRequest) -> ValidateResult {
let errors : Array[String] = []
let warnings : Array[String] = []
if self.model == "" {
errors.push("model is required")
}
match self.options.temperature {
Some(t) =>
if t < 0.0 || t > 2.0 {
errors.push("temperature must be in [0, 2], got " + t.to_string())
}
None => ()
}
match self.options.top_p {
Some(p) =>
if p < 0.0 || p > 1.0 {
errors.push("top_p must be in [0, 1], got " + p.to_string())
}
None => ()
}
match self.options.top_k {
Some(k) =>
if k < 1 {
errors.push("top_k must be >= 1, got " + k.to_string())
}
None => ()
}
match self.options.max_output_tokens {
Some(m) =>
if m < 1 {
errors.push("max_output_tokens must be >= 1, got " + m.to_string())
}
None => ()
}
{ valid: errors.length() == 0, errors, warnings }
}
///|
/// 校验 LucentResponse 字段合法性
pub fn LucentResponse::validate(self : LucentResponse) -> ValidateResult {
let errors : Array[String] = []
if self.id == "" {
errors.push("response id is required")
}
if self.model == "" {
errors.push("response model is required")
}
if self.choices.length() == 0 {
errors.push("response must have at least one choice")
}
{ valid: errors.length() == 0, errors, warnings: [] }
}
///|
/// 构建含新 conversation 的请求(子包后处理用)
pub fn LucentRequest::with_conversation(
self : LucentRequest,
conversation : Array[LucentConversationItem],
) -> LucentRequest {
{ ..self, conversation, }
}
///|
/// 构建含 stream 标志的请求副本(SDK 使用)
pub fn LucentRequest::with_stream(
self : LucentRequest,
stream : Bool,
) -> LucentRequest {
{ ..self, options: { ..self.options, stream, } }
}
///|
/// 便利构造器:用 messages 数组(旧风格)替代 conversation
pub fn LucentRequest::from_messages(
model : String,
instructions : Array[LucentContent]?,
messages : Array[LucentMessage],
tools : Array[LucentTool]?,
tool_choice : LucentToolChoice?,
options : LucentOptions,
capabilities : LucentCapabilities?,
reasoning : LucentReasoningConfig?,
metadata : Map[String, String]?,
extra : Map[String, Json]?,
) -> LucentRequest {
{
schema_version: "v1",
model,
instructions,
conversation: lucent_items_from_messages(messages),
tools,
tool_choice,
options,
capabilities,
reasoning,
metadata,
extra,
}
}
///|
pub fn LucentUsage::new(
prompt_tokens : Int,
completion_tokens : Int,
total_tokens : Int,
) -> LucentUsage {
{
prompt_tokens,
completion_tokens,
total_tokens,
reasoning_tokens: None,
cached_tokens: None,
cache_creation_tokens: None,
}
}
///|
pub fn LucentUsage::with_reasoning(
prompt_tokens : Int,
completion_tokens : Int,
total_tokens : Int,
reasoning_tokens : Int,
) -> LucentUsage {
{
prompt_tokens,
completion_tokens,
total_tokens,
reasoning_tokens: Some(reasoning_tokens),
cached_tokens: None,
cache_creation_tokens: None,
}
}
///|
pub fn LucentSafetyRating::new(
category : String,
probability : String,
) -> LucentSafetyRating {
{ category, probability }
}
///|
pub fn LucentChoice::new(
index : Int,
message : LucentMessage,
finish_reason : LucentFinishReason,
safety_ratings : Array[LucentSafetyRating]?,
) -> LucentChoice {
{ index, message, finish_reason, safety_ratings }
}
///|
pub fn LucentResponse::new(
id : String,
model : String,
created_at : Int?,
choices : Array[LucentChoice],
usage : LucentUsage?,
provider_payload : Json?,
) -> LucentResponse {
{
schema_version: "v1",
id,
model,
created_at,
choices,
usage,
provider_payload,
}
}
///|
/// 构建含 provider_payload 的新响应(外部包访问用)
pub fn LucentResponse::with_provider_payload(
self : LucentResponse,
payload : Json?,
) -> LucentResponse {
{ ..self, provider_payload: payload }
}
///|
/// 提取响应中的纯文本(L1 SDK 使用)
pub fn LucentResponse::get_text(self : LucentResponse) -> String {
if self.choices.length() > 0 {
lucent_content_to_text(self.choices[0].message.content)
} else {
""
}
}
///|
/// 便捷访问:首个 choice 的消息级 reasoning(SDK 取用入口)
pub fn LucentResponse::reasoning(self : LucentResponse) -> LucentThinking? {
if self.choices.length() > 0 {
self.choices[0].message.reasoning
} else {
None
}
}
///|
/// LucentFinishReason 字符串映射(适配器共用)
pub fn LucentFinishReason::from_string(s : String) -> LucentFinishReason {
match s {
"stop" | "end_turn" | "completed" | "STOP" => Stop
"length" | "max_tokens" | "MAX_TOKENS" | "incomplete" => Length
"tool_calls" | "tool_use" | "function_call" => ToolCalls
"content_filter" => ContentFilter
"SAFETY" | "safety" => Safety
"RECITATION" | "recitation" => Recitation
"MALFORMED_FUNCTION_CALL" | "malformed_function_call" => MalformedToolCall
"error" | "failed" | "ERROR" => Error
other => Native(other)
}
}
///|
pub fn LucentFinishReason::to_string(self : LucentFinishReason) -> String {
match self {
Stop => "stop"
Length => "length"
ToolCalls => "tool_calls"
ContentFilter => "content_filter"
Safety => "safety"
Recitation => "recitation"
MalformedToolCall => "malformed_function_call"
Error => "error"
Native(s) => s
}
}
///|
/// 从 conversation items 中提取所有 Message 项(用于适配器需要 messages 视图的场景)
pub fn lucent_messages_from_items(
items : Array[LucentConversationItem],
) -> Array[LucentMessage] {
let result : Array[LucentMessage] = []
let mut i = 0
while i < items.length() {
match items[i] {
Message(m) => result.push(m)
_ => ()
}
i = i + 1
}
result
}
///|
/// 将 LucentContent 数组拼接为纯文本(Text 块拼接,其他块忽略)
pub fn lucent_content_to_text(parts : Array[LucentContent]) -> String {
let buf : Array[String] = []
let mut i = 0
while i < parts.length() {
match parts[i] {
Text(s, _) => buf.push(s)
_ => ()
}
i = i + 1
}
buf.join("")
}