prompt_builder 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +24 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +763 -0
  5. data/VERSION +1 -0
  6. data/lib/prompt_builder/content/base.rb +44 -0
  7. data/lib/prompt_builder/content/input_file.rb +63 -0
  8. data/lib/prompt_builder/content/input_image.rb +64 -0
  9. data/lib/prompt_builder/content/input_text.rb +42 -0
  10. data/lib/prompt_builder/content/input_video.rb +43 -0
  11. data/lib/prompt_builder/content/output_text.rb +59 -0
  12. data/lib/prompt_builder/content/reasoning_text.rb +42 -0
  13. data/lib/prompt_builder/content/refusal_content.rb +42 -0
  14. data/lib/prompt_builder/content/summary_text.rb +42 -0
  15. data/lib/prompt_builder/content/text.rb +42 -0
  16. data/lib/prompt_builder/content.rb +28 -0
  17. data/lib/prompt_builder/errors.rb +18 -0
  18. data/lib/prompt_builder/items/base.rb +41 -0
  19. data/lib/prompt_builder/items/compaction.rb +60 -0
  20. data/lib/prompt_builder/items/function_call.rb +97 -0
  21. data/lib/prompt_builder/items/function_call_output.rb +110 -0
  22. data/lib/prompt_builder/items/item_reference.rb +42 -0
  23. data/lib/prompt_builder/items/message.rb +113 -0
  24. data/lib/prompt_builder/items/reasoning.rb +75 -0
  25. data/lib/prompt_builder/items.rb +13 -0
  26. data/lib/prompt_builder/response.rb +257 -0
  27. data/lib/prompt_builder/serializers/base.rb +37 -0
  28. data/lib/prompt_builder/serializers/chat_completion/request.rb +389 -0
  29. data/lib/prompt_builder/serializers/chat_completion/response.rb +139 -0
  30. data/lib/prompt_builder/serializers/chat_completion.rb +30 -0
  31. data/lib/prompt_builder/serializers/converse/request.rb +623 -0
  32. data/lib/prompt_builder/serializers/converse/response.rb +140 -0
  33. data/lib/prompt_builder/serializers/converse.rb +30 -0
  34. data/lib/prompt_builder/serializers/gemini/request.rb +562 -0
  35. data/lib/prompt_builder/serializers/gemini/response.rb +233 -0
  36. data/lib/prompt_builder/serializers/gemini.rb +30 -0
  37. data/lib/prompt_builder/serializers/messages/request.rb +634 -0
  38. data/lib/prompt_builder/serializers/messages/response.rb +157 -0
  39. data/lib/prompt_builder/serializers/messages.rb +30 -0
  40. data/lib/prompt_builder/serializers/open_responses/request.rb +229 -0
  41. data/lib/prompt_builder/serializers/open_responses/response.rb +18 -0
  42. data/lib/prompt_builder/serializers/open_responses.rb +30 -0
  43. data/lib/prompt_builder/serializers.rb +35 -0
  44. data/lib/prompt_builder/session.rb +383 -0
  45. data/lib/prompt_builder/tool_registry.rb +75 -0
  46. data/lib/prompt_builder/tools/definition.rb +66 -0
  47. data/lib/prompt_builder/tools.rb +7 -0
  48. data/lib/prompt_builder/usage.rb +100 -0
  49. data/lib/prompt_builder.rb +86 -0
  50. data/prompt_builder.gemspec +41 -0
  51. metadata +107 -0
@@ -0,0 +1,140 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ module PromptBuilder
6
+ module Serializers
7
+ class Converse < Base
8
+ # Response parser for the Amazon Bedrock Converse API format.
9
+ class Response < Base
10
+ class << self
11
+ private
12
+
13
+ def deserialize_response(hash)
14
+ usage_hash = hash["usage"]
15
+ usage = if usage_hash
16
+ cache_read = usage_hash["cacheReadInputTokens"]
17
+ cache_write = usage_hash["cacheWriteInputTokens"]
18
+
19
+ input_tokens_details = {}
20
+ input_tokens_details["cached_tokens"] = cache_read if cache_read
21
+ input_tokens_details["cache_creation_input_tokens"] = cache_write if cache_write
22
+
23
+ Usage.new(
24
+ input_tokens: usage_hash["inputTokens"],
25
+ output_tokens: usage_hash["outputTokens"],
26
+ total_tokens: usage_hash["totalTokens"],
27
+ input_tokens_details: input_tokens_details.empty? ? nil : input_tokens_details
28
+ )
29
+ end
30
+
31
+ message = hash.dig("output", "message") || {}
32
+ content_blocks = message["content"] || []
33
+
34
+ PromptBuilder::Response.new(
35
+ id: nil,
36
+ object: nil,
37
+ model: nil,
38
+ output: build_output_items(content_blocks),
39
+ status: map_stop_reason(hash["stopReason"]),
40
+ usage: usage,
41
+ service_tier: hash.dig("serviceTier", "type"),
42
+ extra: provider_data(hash)
43
+ )
44
+ end
45
+
46
+ def map_stop_reason(reason)
47
+ case reason
48
+ when "end_turn", "tool_use", "stop_sequence"
49
+ "completed"
50
+ when "max_tokens"
51
+ "incomplete"
52
+ when "guardrail_intervened", "content_filtered"
53
+ "failed"
54
+ when "malformed_model_output", "malformed_tool_use"
55
+ "failed"
56
+ when "model_context_window_exceeded"
57
+ "incomplete"
58
+ else
59
+ reason
60
+ end
61
+ end
62
+
63
+ def provider_data(hash)
64
+ data = {}
65
+ %w[additionalModelResponseFields metrics performanceConfig serviceTier trace].each do |key|
66
+ data[key] = hash[key] if hash[key]
67
+ end
68
+ data
69
+ end
70
+
71
+ def build_output_items(content_blocks)
72
+ output = []
73
+ text_contents = []
74
+ reasoning_contents = []
75
+
76
+ content_blocks.each do |block|
77
+ if block["text"]
78
+ flush_reasoning_contents!(output, reasoning_contents)
79
+ text_contents << Content::OutputText.new(text: block["text"])
80
+ elsif block["toolUse"]
81
+ flush_text_contents!(output, text_contents)
82
+ flush_reasoning_contents!(output, reasoning_contents)
83
+
84
+ tool_use = block["toolUse"]
85
+ output << Items::FunctionCall.new(
86
+ name: tool_use["name"],
87
+ call_id: tool_use["toolUseId"],
88
+ arguments: JSON.generate(tool_use["input"] || {})
89
+ )
90
+ elsif block["reasoningContent"]
91
+ flush_text_contents!(output, text_contents)
92
+
93
+ reasoning = block["reasoningContent"]
94
+ if reasoning["reasoningText"]
95
+ thinking_block = {
96
+ "type" => "thinking",
97
+ "thinking" => reasoning["reasoningText"]["text"] || ""
98
+ }
99
+ signature = reasoning["reasoningText"]["signature"]
100
+ thinking_block["signature"] = signature if signature
101
+ reasoning_contents << thinking_block
102
+ elsif reasoning["redactedContent"]
103
+ reasoning_contents << {
104
+ "type" => "redacted_thinking",
105
+ "data" => reasoning["redactedContent"]
106
+ }
107
+ end
108
+ else
109
+ # Unrecognized content blocks (citationsContent, guardContent,
110
+ # etc.) are silently skipped.
111
+ next
112
+ end
113
+ end
114
+
115
+ flush_text_contents!(output, text_contents)
116
+ flush_reasoning_contents!(output, reasoning_contents)
117
+ output
118
+ end
119
+
120
+ def flush_text_contents!(output, text_contents)
121
+ return if text_contents.empty?
122
+
123
+ output << Items::Message.new(
124
+ role: "assistant",
125
+ content: text_contents.dup
126
+ )
127
+ text_contents.clear
128
+ end
129
+
130
+ def flush_reasoning_contents!(output, reasoning_contents)
131
+ return if reasoning_contents.empty?
132
+
133
+ output << Items::Reasoning.new(content: reasoning_contents.dup)
134
+ reasoning_contents.clear
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PromptBuilder
4
+ module Serializers
5
+ # Serializer for the Amazon Bedrock Converse API format.
6
+ # Delegates request and response handling to dedicated nested classes.
7
+ class Converse < Base
8
+ autoload :Request, File.expand_path("converse/request", __dir__)
9
+ autoload :Response, File.expand_path("converse/response", __dir__)
10
+
11
+ class << self
12
+ # Export a session to Converse request payload.
13
+ #
14
+ # @param session [Session] the session to export
15
+ # @return [Hash] the serialized request payload
16
+ def request_payload(session)
17
+ Request.request_payload(session)
18
+ end
19
+
20
+ # Parse a Converse response into a PromptBuilder::Response.
21
+ #
22
+ # @param hash [Hash] the response hash in Converse format
23
+ # @return [PromptBuilder::Response] the parsed response
24
+ def parse_response(hash)
25
+ Response.parse_response(hash)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end