Module: SmartPrompt::OpenAIChatShaping
- Included in:
- SenseNovaAdapter, SiliconFlowAdapter, ZhipuAIAdapter
- Defined in:
- lib/smart_prompt/concerns/openai_chat_shaping.rb
Overview
Shared shaping of Net::HTTP chat responses into the OpenAI completion / stream shape that the rest of SmartPrompt (Engine#@stream_proc, Conversation) expects.
Reasoning models expose a thinking trace under a provider-specific field —surfaced here uniformly as ‘reasoning_content`. Adapters override one hook:
reasoning_field_name — the source field on message/delta (default
"reasoning_content"; SenseNova uses "reasoning"). Its value is remapped to
reasoning_content so Engine#@stream_proc needs no per-provider logic.
extra_top_level_fields(raw) — extra top-level keys to copy onto the shaped
response/chunk (default {}; SenseNova adds system_fingerprint).
Instance Method Summary collapse
- #build_completion_response(raw) ⇒ Object
- #build_stream_chunk(data) ⇒ Object
- #extra_top_level_fields(_raw) ⇒ Object
-
#reasoning_field_name ⇒ Object
—- hooks (override in adapter) —————————————–.
Instance Method Details
#build_completion_response(raw) ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/smart_prompt/concerns/openai_chat_shaping.rb', line 15 def build_completion_response(raw) msg = raw.dig("choices", 0, "message") || {} = { "role" => msg["role"] || "assistant" } ["content"] = msg["content"] reasoning = msg[reasoning_field_name] ["reasoning_content"] = reasoning if reasoning ["tool_calls"] = msg["tool_calls"] if msg["tool_calls"] response = { "id" => raw["id"], "object" => raw["object"] || "chat.completion", "created" => raw["created"], "model" => raw["model"], "choices" => [{ "index" => 0, "message" => , "finish_reason" => raw.dig("choices", 0, "finish_reason"), }], } response["usage"] = raw["usage"] if raw["usage"] merge_extra_top_level(response, raw) response end |
#build_stream_chunk(data) ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/smart_prompt/concerns/openai_chat_shaping.rb', line 39 def build_stream_chunk(data) chunk = { "id" => data["id"], "object" => data["object"], "created" => data["created"], "model" => data["model"], } chunk["usage"] = data["usage"] if data["usage"] merge_extra_top_level(chunk, data) choices = data["choices"] || [] if choices.any? delta = choices[0]["delta"] || {} new_delta = {} new_delta["role"] = delta["role"] if delta["role"] new_delta["content"] = delta["content"] if delta["content"] reasoning = delta[reasoning_field_name] new_delta["reasoning_content"] = reasoning if reasoning new_delta["tool_calls"] = delta["tool_calls"] if delta["tool_calls"] chunk["choices"] = [{ "index" => choices[0]["index"] || 0, "delta" => new_delta, "finish_reason" => choices[0]["finish_reason"], }] else chunk["choices"] = [] end chunk end |
#extra_top_level_fields(_raw) ⇒ Object
75 76 77 |
# File 'lib/smart_prompt/concerns/openai_chat_shaping.rb', line 75 def extra_top_level_fields(_raw) {} end |
#reasoning_field_name ⇒ Object
—- hooks (override in adapter) —————————————–
71 72 73 |
# File 'lib/smart_prompt/concerns/openai_chat_shaping.rb', line 71 def reasoning_field_name "reasoning_content" end |