Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions app/lib/meadow/chat/message.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
defmodule Meadow.Chat.Message do
@moduledoc """
Struct for chat messages
"""

defstruct id: nil,
conversation_id: nil,
type: nil,
message: nil,
inserted_at: nil
end
24 changes: 24 additions & 0 deletions app/lib/meadow_web/resolvers/chat.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
defmodule MeadowWeb.Resolvers.Chat do

@moduledoc """
Absinthe GraphQL query resolver for Chat Context

"""

def send_chat_message(_, %{conversation_id: conversation_id, type: type, query: query, prompt: prompt}, _) do
response = %{
conversation_id: conversation_id,
message: "Here is your plan....",
type: "plan",
}


Absinthe.Subscription.publish(
MeadowWeb.Endpoint,
response,
chat_response: "conversation:#{conversation_id}"
)

{:ok, %{conversation_id: conversation_id, type: type, query: query, prompt: prompt}}
end
end
3 changes: 3 additions & 0 deletions app/lib/meadow_web/schema/schema.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ defmodule MeadowWeb.Schema do
import_types(__MODULE__.HelperTypes)
import_types(__MODULE__.Data.CSVMetadataUpdateTypes)
import_types(__MODULE__.NULAuthorityTypes)
import_types(__MODULE__.ChatTypes)

query do
import_fields(:account_queries)
Expand Down Expand Up @@ -53,10 +54,12 @@ defmodule MeadowWeb.Schema do
import_fields(:nul_authority_mutations)
import_fields(:shared_link_mutations)
import_fields(:work_mutations)
import_fields(:chat_mutations)
end

subscription do
import_fields(:ingest_subscriptions)
import_fields(:chat_subscriptions)
end

enum :sort_order do
Expand Down
54 changes: 54 additions & 0 deletions app/lib/meadow_web/schema/types/chat_types.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
defmodule MeadowWeb.Schema.ChatTypes do
@moduledoc """
Absinthe schema for Chat and ChatMessage types
"""
use Absinthe.Schema.Notation

alias MeadowWeb.Resolvers
alias MeadowWeb.Schema.Middleware

object :chat_subscriptions do
field :chat_response, :chat_response do
arg :conversation_id, non_null(:id)

config fn args, _ ->
{:ok, topic: "conversation:#{args.conversation_id}"}
end
end
end

object :chat_mutations do
field :send_chat_message, type: :chat_message do
arg :conversation_id, non_null(:id)
arg :type, non_null(:string)
arg :query, non_null(:string)
arg :prompt, non_null(:string)
middleware(Middleware.Authenticate)
middleware(Middleware.Authorize, "Editor")

resolve &Resolvers.Chat.send_chat_message/3
end
end



object :chat_message do
field :conversation_id, :id,
description: "Ref for the conversation"
field :type, :string,
description: "Type of message, e.g. 'chat'"
field :query, :string,
description: "The search query associated with the message"
field :prompt, :string,
description: "The prompt associated with the message"
end

object :chat_response do
field :conversation_id, :id
field :type, :string,
description: "Type of message, e.g. 'chat'"
field :message, :string,
description: "AI response message"
end

end
6 changes: 6 additions & 0 deletions app/test/gql/ChatResponse.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
subscription ChatResponse($conversationId: ID!) {
chatResponse(conversationId: $conversationId) {
conversationId
message
}
}
18 changes: 18 additions & 0 deletions app/test/gql/SendChatMessage.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
mutation SendChatMessage(
$conversationId: ID!
$type: String!
$query: String!
$prompt: String!
) {
sendChatMessage(
conversationId: $conversationId
type: $type
query: $query
prompt: $prompt
) {
conversationId
type
query
prompt
}
}
45 changes: 45 additions & 0 deletions app/test/meadow_web/schema/mutation/send_chat_message_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
defmodule MeadowWeb.Schema.Mutation.SendChatMessageTest do
use Meadow.DataCase
use MeadowWeb.ConnCase, async: true
use Wormwood.GQLCase

load_gql(MeadowWeb.Schema, "test/gql/SendChatMessage.gql")

test "should send a chat message as editor" do
result =
query_gql(
variables: %{
"conversationId" => "test-conversation-123",
"type" => "chat",
"query" => "test query",
"prompt" => "test prompt"
},
context: gql_context(%{role: :editor})
)

assert {:ok, query_data} = result

message = get_in(query_data, [:data, "sendChatMessage"])

assert message["conversationId"] == "test-conversation-123"
assert message["type"] == "chat"
assert message["query"] == "test query"
assert message["prompt"] == "test prompt"
end

test "should reject unauthorized users" do
result =
query_gql(
variables: %{
"conversationId" => "test-conversation-123",
"type" => "chat",
"query" => "test query",
"prompt" => "test prompt"
},
context: gql_context(%{role: :user})
)

assert {:ok, query_data} = result
assert get_in(query_data, [:errors]) != nil
end
end
14 changes: 14 additions & 0 deletions app/test/meadow_web/schema/subscription/chat_response_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
defmodule MeadowWeb.Schema.Subscription.ChatResponseTest do
use Meadow.DataCase
use MeadowWeb.SubscriptionCase, async: true

@reply_timeout 5000

load_gql(MeadowWeb.Schema, "test/gql/ChatResponse.gql")

test "should initiate subscription as editor", %{socket: socket} do
conversation_id = "test-conversation-123"
ref = subscribe_gql(socket, variables: %{"conversationId" => conversation_id}, context: gql_context(%{role: :editor}))
assert_reply ref, :ok, %{subscriptionId: _subscription_id}, @reply_timeout
end
end
Loading