Skip to content

Commit 099b937

Browse files
committed
Fetch Langfuse prompt for assistant instructions
1 parent cbc653a commit 099b937

File tree

5 files changed

+121
-27
lines changed

5 files changed

+121
-27
lines changed

app/models/assistant.rb

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
class Assistant
22
include Provided, Configurable, Broadcastable
33

4-
attr_reader :chat, :instructions
4+
attr_reader :chat, :instructions, :instructions_prompt
55

66
class << self
77
def for_chat(chat)
88
config = config_for(chat)
9-
new(chat, instructions: config[:instructions], functions: config[:functions])
9+
new(
10+
chat,
11+
instructions: config[:instructions],
12+
instructions_prompt: config[:instructions_prompt],
13+
functions: config[:functions]
14+
)
1015
end
1116
end
1217

13-
def initialize(chat, instructions: nil, functions: [])
18+
def initialize(chat, instructions: nil, instructions_prompt: nil, functions: [])
1419
@chat = chat
1520
@instructions = instructions
21+
@instructions_prompt = instructions_prompt
1622
@functions = functions
1723
end
1824

@@ -26,6 +32,7 @@ def respond_to(message)
2632
responder = Assistant::Responder.new(
2733
message: message,
2834
instructions: instructions,
35+
instructions_prompt: instructions_prompt,
2936
function_tool_caller: function_tool_caller,
3037
llm: get_model_provider(message.ai_model)
3138
)

app/models/assistant/configurable.rb

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@ def config_for(chat)
66
preferred_currency = Money::Currency.new(chat.user.family.currency)
77
preferred_date_format = chat.user.family.date_format
88

9+
instructions_config = default_instructions(preferred_currency, preferred_date_format)
10+
911
{
10-
instructions: default_instructions(preferred_currency, preferred_date_format),
12+
instructions: instructions_config[:content],
13+
instructions_prompt: instructions_config[:prompt],
1114
functions: default_functions
1215
}
1316
end
@@ -23,6 +26,60 @@ def default_functions
2326
end
2427

2528
def default_instructions(preferred_currency, preferred_date_format)
29+
langfuse_instructions = langfuse_default_instructions(preferred_currency, preferred_date_format)
30+
31+
if langfuse_instructions.present?
32+
{
33+
content: langfuse_instructions[:content],
34+
prompt: langfuse_instructions
35+
}
36+
else
37+
{
38+
content: fallback_default_instructions(preferred_currency, preferred_date_format),
39+
prompt: nil
40+
}
41+
end
42+
end
43+
44+
def langfuse_default_instructions(preferred_currency, preferred_date_format)
45+
return unless langfuse_client
46+
47+
prompt = langfuse_client.get_prompt("default_instructions")
48+
49+
compiled_prompt = prompt.compile(
50+
preferred_currency_symbol: preferred_currency.symbol,
51+
preferred_currency_iso_code: preferred_currency.iso_code,
52+
preferred_currency_default_precision: preferred_currency.default_precision,
53+
preferred_currency_default_format: preferred_currency.default_format,
54+
preferred_currency_separator: preferred_currency.separator,
55+
preferred_currency_delimiter: preferred_currency.delimiter,
56+
preferred_date_format: preferred_date_format,
57+
current_date: Date.current
58+
)
59+
60+
content = case compiled_prompt
61+
when String
62+
compiled_prompt
63+
when Array
64+
compiled_prompt.filter_map { |message| message[:content] }.join("\n\n")
65+
else
66+
nil
67+
end
68+
69+
return if content.blank?
70+
71+
{
72+
name: prompt.name,
73+
version: prompt.version,
74+
template: prompt.prompt,
75+
content: content
76+
}
77+
rescue => e
78+
Rails.logger.warn("Langfuse prompt retrieval failed: #{e.message}")
79+
nil
80+
end
81+
82+
def fallback_default_instructions(preferred_currency, preferred_date_format)
2683
<<~PROMPT
2784
## Your identity
2885
@@ -78,5 +135,14 @@ def default_instructions(preferred_currency, preferred_date_format)
78135
the data you're presenting represents and what context it is in (i.e. date range, account, etc.)
79136
PROMPT
80137
end
138+
139+
def langfuse_client
140+
return unless ENV["LANGFUSE_PUBLIC_KEY"].present? && ENV["LANGFUSE_SECRET_KEY"].present?
141+
142+
@langfuse_client ||= Langfuse.new
143+
rescue => e
144+
Rails.logger.warn("Langfuse client initialization failed: #{e.message}")
145+
nil
146+
end
81147
end
82148
end

app/models/assistant/responder.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
class Assistant::Responder
2-
def initialize(message:, instructions:, function_tool_caller:, llm:)
2+
def initialize(message:, instructions:, function_tool_caller:, llm:, instructions_prompt: nil)
33
@message = message
44
@instructions = instructions
55
@function_tool_caller = function_tool_caller
66
@llm = llm
7+
@instructions_prompt = instructions_prompt
78
end
89

910
def on(event_name, &block)
@@ -31,7 +32,7 @@ def respond(previous_response_id: nil)
3132
end
3233

3334
private
34-
attr_reader :message, :instructions, :function_tool_caller, :llm
35+
attr_reader :message, :instructions, :function_tool_caller, :llm, :instructions_prompt
3536

3637
def handle_follow_up_response(response)
3738
streamer = proc do |chunk|
@@ -64,6 +65,7 @@ def get_llm_response(streamer:, function_results: [], previous_response_id: nil)
6465
message.content,
6566
model: message.ai_model,
6667
instructions: instructions,
68+
instructions_prompt: instructions_prompt,
6769
functions: function_tool_caller.function_definitions,
6870
function_results: function_results,
6971
streamer: streamer,

app/models/provider/llm_concept.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ def chat_response(
2222
prompt,
2323
model:,
2424
instructions: nil,
25+
instructions_prompt: nil,
2526
functions: [],
2627
function_results: [],
2728
streamer: nil,

app/models/provider/openai.rb

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ def chat_response(
6262
prompt,
6363
model:,
6464
instructions: nil,
65+
instructions_prompt: nil,
6566
functions: [],
6667
function_results: [],
6768
streamer: nil,
@@ -112,6 +113,7 @@ def chat_response(
112113
model: model,
113114
input: input_payload,
114115
output: response.messages.map(&:output_text).join("\n"),
116+
prompt: instructions_prompt,
115117
session_id: session_id,
116118
user_identifier: user_identifier
117119
)
@@ -123,6 +125,7 @@ def chat_response(
123125
model: model,
124126
input: input_payload,
125127
output: parsed.messages.map(&:output_text).join("\n"),
128+
prompt: instructions_prompt,
126129
usage: raw_response["usage"],
127130
session_id: session_id,
128131
user_identifier: user_identifier
@@ -141,26 +144,41 @@ def langfuse_client
141144
@langfuse_client = Langfuse.new
142145
end
143146

144-
def log_langfuse_generation(name:, model:, input:, output:, usage: nil, session_id: nil, user_identifier: nil)
145-
return unless langfuse_client
146-
147-
trace = langfuse_client.trace(
148-
name: "openai.#{name}",
149-
input: input,
150-
session_id: session_id,
151-
user_id: user_identifier
152-
)
153-
trace.generation(
154-
name: name,
155-
model: model,
156-
input: input,
157-
output: output,
158-
usage: usage,
159-
session_id: session_id,
160-
user_id: user_identifier
161-
)
162-
trace.update(output: output)
163-
rescue => e
164-
Rails.logger.warn("Langfuse logging failed: #{e.message}")
147+
def log_langfuse_generation(name:, model:, input:, output:, usage: nil, session_id: nil, user_identifier: nil, prompt: nil)
148+
return unless langfuse_client
149+
150+
trace = langfuse_client.trace(
151+
name: "openai.#{name}",
152+
input: input,
153+
session_id: session_id,
154+
user_id: user_identifier
155+
)
156+
generation_options = {
157+
name: name,
158+
model: model,
159+
input: input,
160+
output: output,
161+
usage: usage,
162+
session_id: session_id,
163+
user_id: user_identifier
164+
}
165+
166+
if prompt.present?
167+
generation_options[:version] = prompt[:version] if prompt[:version]
168+
metadata = {
169+
prompt: {
170+
name: prompt[:name],
171+
version: prompt[:version],
172+
content: prompt[:content],
173+
template: prompt[:template]
174+
}.compact
175+
}
176+
generation_options[:metadata] = metadata
165177
end
178+
179+
trace.generation(**generation_options)
180+
trace.update(output: output)
181+
rescue => e
182+
Rails.logger.warn("Langfuse logging failed: #{e.message}")
183+
end
166184
end

0 commit comments

Comments
 (0)