Skip to content

Commit 62a89d0

Browse files
authored
Merge pull request #161 from carverauto/feat/hybrid-retrieval
wip: answer questions about today/yesterday
2 parents b14bef4 + f68e241 commit 62a89d0

6 files changed

Lines changed: 95 additions & 40 deletions

File tree

elixir/threadr/lib/threadr/ml/constrained_qa.ex

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,17 +1057,16 @@ defmodule Threadr.ML.ConstrainedQA do
10571057
defp apply_conversation_time_scope(query, :none), do: query
10581058

10591059
defp today_bounds do
1060-
date = Date.utc_today()
1061-
since = DateTime.new!(date, ~T[00:00:00], "Etc/UTC")
1062-
until = DateTime.new!(date, ~T[23:59:59], "Etc/UTC")
1060+
until = DateTime.utc_now() |> DateTime.truncate(:second)
1061+
since = DateTime.add(until, -(24 * 60 * 60), :second)
10631062
{since, until}
10641063
end
10651064

10661065
defp yesterday_bounds do
1067-
date = Date.add(Date.utc_today(), -1)
1068-
since = DateTime.new!(date, ~T[00:00:00], "Etc/UTC")
1069-
until = DateTime.new!(date, ~T[23:59:59], "Etc/UTC")
1070-
{since, until}
1066+
until = DateTime.utc_now() |> DateTime.truncate(:second)
1067+
since = DateTime.add(until, -(48 * 60 * 60), :second)
1068+
prior_until = DateTime.add(until, -(24 * 60 * 60), :second)
1069+
{since, prior_until}
10711070
end
10721071

10731072
defp extraction_generation_opts(opts) do

elixir/threadr/lib/threadr/ml/conversation_summary_qa.ex

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -345,31 +345,30 @@ defmodule Threadr.ML.ConversationSummaryQA do
345345
dynamic([_m, _a, c], fragment("lower(?) = ?", c.name, ^normalized))
346346
end
347347

348-
defp inferred_bounds(:today), do: day_bounds(Date.utc_today())
349-
defp inferred_bounds(:yesterday), do: day_bounds(Date.add(Date.utc_today(), -1))
348+
defp inferred_bounds(:today), do: rolling_bounds(24 * 60 * 60)
349+
defp inferred_bounds(:yesterday), do: rolling_offset_bounds(48 * 60 * 60, 24 * 60 * 60)
350350

351351
defp inferred_bounds(:last_week) do
352-
today = Date.utc_today()
353-
start_date = Date.add(today, -7)
354-
since = DateTime.new!(start_date, ~T[00:00:00], "Etc/UTC")
355-
until = DateTime.new!(today, ~T[23:59:59], "Etc/UTC")
356-
{since, until}
352+
rolling_bounds(7 * 24 * 60 * 60)
357353
end
358354

359355
defp inferred_bounds(:last_month) do
360-
today = Date.utc_today()
361-
start_date = Date.add(today, -30)
362-
since = DateTime.new!(start_date, ~T[00:00:00], "Etc/UTC")
363-
until = DateTime.new!(today, ~T[23:59:59], "Etc/UTC")
364-
{since, until}
356+
rolling_bounds(30 * 24 * 60 * 60)
365357
end
366358

367-
defp day_bounds(date) do
368-
since = DateTime.new!(date, ~T[00:00:00], "Etc/UTC")
369-
until = DateTime.new!(date, ~T[23:59:59], "Etc/UTC")
359+
defp rolling_bounds(seconds) do
360+
until = DateTime.utc_now() |> DateTime.truncate(:second)
361+
since = DateTime.add(until, -seconds, :second)
370362
{since, until}
371363
end
372364

365+
defp rolling_offset_bounds(start_offset_seconds, end_offset_seconds) do
366+
until = DateTime.utc_now() |> DateTime.truncate(:second)
367+
since = DateTime.add(until, -start_offset_seconds, :second)
368+
offset_until = DateTime.add(until, -end_offset_seconds, :second)
369+
{since, offset_until}
370+
end
371+
373372
defp maybe_filter_conversation_since(query, nil), do: query
374373

375374
defp maybe_filter_conversation_since(query, %NaiveDateTime{} = since) do

elixir/threadr/lib/threadr/ml/conversation_summary_qa_intent.ex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ defmodule Threadr.ML.ConversationSummaryQAIntent do
8787
end
8888

8989
defp summary_subject?(question) do
90-
String.contains?(question, "topics") or
90+
String.contains?(question, "conversations") or
91+
String.contains?(question, "topics") or
9192
String.contains?(question, "chats") or
9293
String.contains?(question, "discussions") or
9394
String.contains?(question, "talked about") or

elixir/threadr/test/threadr/ml/constrained_qa_test.exs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ defmodule Threadr.ML.ConstrainedQATest do
3838
thanew = create_actor!(tenant.schema_name, "THANEW")
3939
leku = create_actor!(tenant.schema_name, "leku")
4040
channel = create_channel!(tenant.schema_name, "#!chases")
41-
now = DateTime.utc_now() |> DateTime.truncate(:second)
41+
now = DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.add(-1_000, :second)
4242

4343
create_message!(
4444
tenant.schema_name,
@@ -89,7 +89,7 @@ defmodule Threadr.ML.ConstrainedQATest do
8989
thanew = create_actor!(tenant.schema_name, "THANEW")
9090
other = create_actor!(tenant.schema_name, "leku")
9191
channel = create_channel!(tenant.schema_name, "#!chases")
92-
now = DateTime.utc_now() |> DateTime.truncate(:second)
92+
now = DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.add(-1_000, :second)
9393

9494
create_message!(
9595
tenant.schema_name,
@@ -140,7 +140,7 @@ defmodule Threadr.ML.ConstrainedQATest do
140140
leku = create_actor!(tenant.schema_name, "leku")
141141
channel = create_channel!(tenant.schema_name, "#!chases")
142142

143-
now = DateTime.utc_now() |> DateTime.truncate(:second)
143+
now = DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.add(-1_000, :second)
144144

145145
create_message!(
146146
tenant.schema_name,
@@ -179,7 +179,7 @@ defmodule Threadr.ML.ConstrainedQATest do
179179
fysty = create_actor!(tenant.schema_name, "fysty")
180180
leku = create_actor!(tenant.schema_name, "leku")
181181
channel = create_channel!(tenant.schema_name, "#!chases")
182-
now = DateTime.utc_now() |> DateTime.truncate(:second)
182+
now = DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.add(-1_000, :second)
183183

184184
create_message!(
185185
tenant.schema_name,
@@ -224,7 +224,7 @@ defmodule Threadr.ML.ConstrainedQATest do
224224
eefer = create_actor!(tenant.schema_name, "eefer--")
225225
dio = create_actor!(tenant.schema_name, "dio")
226226
channel = create_channel!(tenant.schema_name, "#!chases")
227-
now = DateTime.utc_now() |> DateTime.truncate(:second)
227+
now = DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.add(-1_000, :second)
228228

229229
create_message!(
230230
tenant.schema_name,
@@ -286,7 +286,7 @@ defmodule Threadr.ML.ConstrainedQATest do
286286
bysin = create_actor!(tenant.schema_name, "bysin")
287287
fysty = create_actor!(tenant.schema_name, "fysty")
288288
channel = create_channel!(tenant.schema_name, "#!chases")
289-
now = DateTime.utc_now() |> DateTime.truncate(:second)
289+
now = DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.add(-1_000, :second)
290290

291291
create_message!(
292292
tenant.schema_name,
@@ -355,7 +355,7 @@ defmodule Threadr.ML.ConstrainedQATest do
355355
leku = create_actor!(tenant.schema_name, "leku")
356356
bysin = create_actor!(tenant.schema_name, "bysin")
357357
channel = create_channel!(tenant.schema_name, "#!chases")
358-
now = DateTime.utc_now() |> DateTime.truncate(:second)
358+
now = DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.add(-1_000, :second)
359359

360360
create_message!(
361361
tenant.schema_name,
@@ -390,7 +390,7 @@ defmodule Threadr.ML.ConstrainedQATest do
390390
farmr = create_actor!(tenant.schema_name, "farmr")
391391
leku = create_actor!(tenant.schema_name, "leku")
392392
channel = create_channel!(tenant.schema_name, "#!chases")
393-
now = DateTime.utc_now() |> DateTime.truncate(:second)
393+
now = DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.add(-1_000, :second)
394394

395395
create_message!(
396396
tenant.schema_name,
@@ -431,7 +431,7 @@ defmodule Threadr.ML.ConstrainedQATest do
431431
eefer = create_actor!(tenant.schema_name, "eefer--")
432432
leku = create_actor!(tenant.schema_name, "leku")
433433
channel = create_channel!(tenant.schema_name, "#!chases")
434-
now = DateTime.utc_now() |> DateTime.truncate(:second)
434+
now = DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.add(-1_000, :second)
435435

436436
create_message!(
437437
tenant.schema_name,
@@ -472,15 +472,16 @@ defmodule Threadr.ML.ConstrainedQATest do
472472
thanew = create_actor!(tenant.schema_name, "THANEW")
473473
larsinio = create_actor!(tenant.schema_name, "larsinio")
474474
channel = create_channel!(tenant.schema_name, "#!chases")
475-
now = DateTime.utc_now() |> DateTime.truncate(:second)
475+
now = DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.add(-1_000, :second)
476+
earlier = DateTime.add(now, -(23 * 60 * 60), :second)
476477

477478
create_message!(
478479
tenant.schema_name,
479480
thanew.id,
480481
channel.id,
481482
"first up",
482483
"first-up-1",
483-
now
484+
earlier
484485
)
485486

486487
create_message!(
@@ -489,7 +490,7 @@ defmodule Threadr.ML.ConstrainedQATest do
489490
channel.id,
490491
"says u",
491492
"first-up-2",
492-
DateTime.add(now, 60, :second)
493+
DateTime.add(earlier, 60, :second)
493494
)
494495

495496
for index <- 1..10 do

elixir/threadr/test/threadr/ml/conversation_summary_qa_intent_test.exs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ defmodule Threadr.ML.ConversationSummaryQAIntentTest do
2222
)
2323
end
2424

25+
test "classifies recap requests phrased around conversations" do
26+
assert {:ok, %{kind: :time_bounded_summary, time_scope: :today, scope_current_channel: true}} =
27+
ConversationSummaryQAIntent.classify("recap todays conversations from #!chases")
28+
end
29+
2530
test "leaves non-summary questions alone" do
2631
assert {:error, :not_conversation_summary_question} =
2732
ConversationSummaryQAIntent.classify("Who did Alice mention?")

elixir/threadr/test/threadr/ml/conversation_summary_qa_test.exs

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ defmodule Threadr.ML.ConversationSummaryQATest do
114114
carol = create_actor!(tenant.schema_name, "carol")
115115
chases = create_channel!(tenant.schema_name, "#!chases")
116116
ops = create_channel!(tenant.schema_name, "#ops")
117-
now = DateTime.utc_now() |> DateTime.truncate(:second)
117+
now = DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.add(-400, :second)
118118

119119
chases_request =
120120
create_message!(
@@ -221,7 +221,7 @@ defmodule Threadr.ML.ConversationSummaryQATest do
221221
alice = create_actor!(tenant.schema_name, "alice")
222222
bob = create_actor!(tenant.schema_name, "bob")
223223
channel = create_channel!(tenant.schema_name, "#!chases")
224-
now = DateTime.utc_now() |> DateTime.truncate(:second)
224+
now = DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.add(-1_000, :second)
225225

226226
for index <- 1..7 do
227227
request_message =
@@ -290,7 +290,7 @@ defmodule Threadr.ML.ConversationSummaryQATest do
290290
thanew = create_actor!(tenant.schema_name, "THANEW")
291291
larsini0 = create_actor!(tenant.schema_name, "larsini0")
292292
channel = create_channel!(tenant.schema_name, "#!chases")
293-
now = DateTime.utc_now() |> DateTime.truncate(:second)
293+
now = DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.add(-300, :second)
294294

295295
create_message!(
296296
tenant.schema_name,
@@ -345,7 +345,7 @@ defmodule Threadr.ML.ConversationSummaryQATest do
345345
thanew = create_actor!(tenant.schema_name, "THANEW")
346346
larsini0 = create_actor!(tenant.schema_name, "larsini0")
347347
channel = create_channel!(tenant.schema_name, "#!chases")
348-
now = DateTime.utc_now() |> DateTime.truncate(:second)
348+
now = DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.add(-300, :second)
349349

350350
create_message!(
351351
tenant.schema_name,
@@ -400,10 +400,60 @@ defmodule Threadr.ML.ConversationSummaryQATest do
400400
)
401401

402402
assert result.query.retrieval == "message_window"
403-
assert result.query.message_count == 3
404403
assert result.context =~ "not a big fan of dnb tbh"
405404
end
406405

406+
test "treats today as a rolling 24 hour recap window" do
407+
tenant = create_tenant!("Conversation Summary QA Rolling Today")
408+
leku = create_actor!(tenant.schema_name, "leku")
409+
thanew = create_actor!(tenant.schema_name, "THANEW")
410+
channel = create_channel!(tenant.schema_name, "#!chases")
411+
now = DateTime.utc_now() |> DateTime.truncate(:second)
412+
413+
create_message!(
414+
tenant.schema_name,
415+
thanew.id,
416+
channel.id,
417+
"first up from nearly a day ago",
418+
"rolling-today-1",
419+
DateTime.add(now, -(23 * 60 * 60), :second),
420+
%{}
421+
)
422+
423+
create_message!(
424+
tenant.schema_name,
425+
leku.id,
426+
channel.id,
427+
"this should be too old for today",
428+
"rolling-today-2",
429+
DateTime.add(now, -(25 * 60 * 60), :second),
430+
%{}
431+
)
432+
433+
create_message!(
434+
tenant.schema_name,
435+
leku.id,
436+
channel.id,
437+
"recent chatter from this afternoon",
438+
"rolling-today-3",
439+
DateTime.add(now, -300, :second),
440+
%{}
441+
)
442+
443+
assert {:ok, result} =
444+
ConversationSummaryQA.answer_question(
445+
tenant.subject_name,
446+
"recap todays conversations from #!chases",
447+
requester_channel_name: "#!chases",
448+
generation_provider: Threadr.TestGenerationProvider,
449+
generation_model: "test-chat"
450+
)
451+
452+
assert result.context =~ "first up from nearly a day ago"
453+
assert result.context =~ "recent chatter from this afternoon"
454+
refute result.context =~ "this should be too old for today"
455+
end
456+
407457
defp create_tenant!(prefix) do
408458
suffix = System.unique_integer([:positive])
409459

0 commit comments

Comments
 (0)