Skip to content

Raphael/chat go #101

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 29 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
1a50e2f
Update settings.json
rderbier Mar 24, 2025
6740982
Create .gitignore
rderbier Mar 24, 2025
639001c
go mod update
rderbier Mar 24, 2025
03a02d4
Create modus.json
rderbier Mar 24, 2025
4973a50
update API
rderbier Mar 24, 2025
b752a2e
add hypermot-chat
rderbier May 14, 2025
12ca472
Merge branch 'main' into raphael/chat-go
rderbier May 14, 2025
8ed9d29
use model router
rderbier May 15, 2025
e6ebb51
add working chatAgent logic
rderbier May 23, 2025
31fd70f
chat agent connected to Dgraph
rderbier May 27, 2025
2ad54a3
Merge branch 'main' into raphael/chat-go
danstarns May 30, 2025
aec52ad
restore img
danstarns May 30, 2025
449f7b1
remove pnpm lock
danstarns May 30, 2025
c83315b
trunk fixes
danstarns May 30, 2025
61a9a55
custom adapter to talk to backend
danstarns May 30, 2025
6b0ef12
remove unused
danstarns May 30, 2025
07fc75b
mod tidy
danstarns May 30, 2025
0c17d95
trunk fixes
danstarns May 30, 2025
e5100f0
chatkit alpha.4
danstarns May 30, 2025
2725b78
docs: *
danstarns May 30, 2025
e42d060
Merge branch 'main' into raphael/chat-go
rderbier Jun 2, 2025
9a08826
Merge branch 'raphael/chat-go' of github.com:hypermodeinc/modus-recip…
rderbier Jun 2, 2025
50e7bca
update chat agent
rderbier Jun 2, 2025
6ac5461
update logic and schema
rderbier Jun 6, 2025
1b50b98
add makefile for local
rderbier Jun 11, 2025
aac801a
remove unused SessionID
rderbier Jun 11, 2025
1a7b9e7
update to latest modus alpha release to resolve agent start error
johnymontana Jun 11, 2025
c722db9
add username and use alpha.7
rderbier Jun 13, 2025
44b643b
Merge branch 'raphael/chat-go' of github.com:hypermodeinc/modus-recip…
rderbier Jun 13, 2025
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
56 changes: 56 additions & 0 deletions chat-agent/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# usage example
# make ENV=local schema-gql
# make drop-data

# Default environment 'local' - other env 'hypermode'
ENV ?= local

# .env.hypermode file with the following variables
# DGRAPH_CONNECTION_STRING=dgraph://agent-context-havona-tech-ltd.hypermode.host:443?sslmode=verify-ca&bearertoken=<token>

# you can copy paste the connection string from the Hypermode console

# Load the .env file based on the environment
ifneq (,$(wildcard .env.$(ENV)))
include .env.$(ENV)
export $(shell sed 's/=.*//' .env.$(ENV))
else
$(error Environment file .env.$(ENV) not found!)
endif


DGRAPH_HOST_PORT = $(shell echo '$(DGRAPH_CONNECTION_STRING)' | sed -E 's|^[a-z]+://([^/?]+).*|\1|')
DGRAPH_ENDPOINT = https://$(DGRAPH_HOST_PORT)/dgraph
DGRAPH_API_TOKEN := $(shell echo '$(DGRAPH_CONNECTION_STRING)' | sed -E 's/.*[?&]bearertoken=([^&]+).*/\1/')


## define DGRAPH_API_TOKEN in env
## define API_TOKEN in env

current_dir = $(shell pwd)

help: ## Print target help
@echo "Usage: make <target> or make <target> ENV=<environment>"
@echo "Targets:"
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m %-20s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)


echo: ## Print the current environment
@echo "Current environment: $(ENV)"
@echo "DGRAPH_HOST_PORT: $(DGRAPH_HOST_PORT)"
@echo "DGRAPH_ENDPOINT: $(DGRAPH_ENDPOINT)"


drop-data: ## Drops all data (but not the schema, local development)
@curl -X POST -H 'Authorization: Bearer $(DGRAPH_API_TOKEN)' $(DGRAPH_ENDPOINT)/alter -d '{"drop_op": "DATA"}'

drop-all: ## Drops data and schema (local development)
@curl -X POST -H 'Authorization: Bearer $(DGRAPH_API_TOKEN)' $(DGRAPH_ENDPOINT)/alter -d '{"drop_all": true}'


schema-dql: ## Load/update a DQL schema
ifneq (,$(wildcard ./schema.dql))
@curl --data-binary '@./schema.dql' -H 'content-type: application/dql' -H 'Authorization: Bearer $(DGRAPH_API_TOKEN)' $(DGRAPH_ENDPOINT)/alter
else
@echo "No schema.dql found"
endif
14 changes: 14 additions & 0 deletions chat-agent/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Deploying Dgraph schema

Create a `.env.local` file containing the Dgraph connection string

```shell .env.local
DGRAPH_CONNECTION_STRING=dgraph://dgraph-instance-name.hypermode.host:443?sslmode=verify-ca&bearertoken=...

```

Run

```shell
make schema-dql
```
16 changes: 16 additions & 0 deletions chat-agent/api-go/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Ignore macOS system files
.DS_Store

# Ignore environment variable files
.env
.env.*

# Ignore build output directories
build/

# Ignore Go debuger and generated files
__debug_bin*
*_generated.go
*.generated.go

.modusdb/
85 changes: 85 additions & 0 deletions chat-agent/api-go/chatAgent.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package main

import (
"encoding/json"
"fmt"

"github.com/hypermodeinc/modus/sdk/go/pkg/agents"
"github.com/hypermodeinc/modus/sdk/go/pkg/models"
"github.com/hypermodeinc/modus/sdk/go/pkg/models/openai"
)

const (
MAX_HISTORY = 10
MODEL_NAME = "text-generator"
)

type ChatAgent struct {
agents.AgentBase
state ChatAgentState
}

type ChatAgentState struct {
ChatHistory string
}

func (c *ChatAgent) Name() string {
return "Chat-v1"
}

func (c *ChatAgent) GetState() *string {
serializedState, _ := json.Marshal(c.state)
serializedStateStr := string(serializedState)
return &serializedStateStr
}

func (c *ChatAgent) SetState(data *string) {
err := json.Unmarshal([]byte(*data), &c.state)
if err != nil {
fmt.Println("Error unmarshalling state:", err)
}
}

func (c *ChatAgent) OnStart() error {
c.state.ChatHistory = ""
fmt.Println("Agent started")
return nil
}

func (c *ChatAgent) OnReceiveMessage(msgName string, data *string) (*string, error) {
switch msgName {
case "new_user_message":
return c.chat(data)
case "get_chat_history":
return &c.state.ChatHistory, nil
default:
return nil, nil
}
}

func (c *ChatAgent) chat(data *string) (*string, error) {
model, _ := models.GetModel[openai.ChatModel](MODEL_NAME)
loopLimit := 3

llmResponse := llmWithTools(
model,
chatTools(),
systemPrompt(),
*data,
c.state.ChatHistory,
openai.ResponseFormatText,
executeToolCall,
loopLimit,
MAX_HISTORY,
)

c.state.ChatHistory = llmResponse.ChatHistory
fmt.Println(llmResponse.Response)

return &llmResponse.Response, nil
}

func (c *ChatAgent) DeleteAgent(id string) error {
_, err := agents.Stop(id)
return err
}
14 changes: 14 additions & 0 deletions chat-agent/api-go/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module api-go

go 1.24.2

require (
github.com/hypermodeinc/modus/sdk/go v0.18.0-alpha.4
github.com/tidwall/gjson v1.18.0
)

require (
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/tidwall/sjson v1.2.5 // indirect
)
12 changes: 12 additions & 0 deletions chat-agent/api-go/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
github.com/hypermodeinc/modus/sdk/go v0.18.0-alpha.4 h1:xMtpkKri92G6DONcxDEiBSa/WZJH4o8pUwJkfaBHbNQ=
github.com/hypermodeinc/modus/sdk/go v0.18.0-alpha.4/go.mod h1:yyusqlY9R0ffe5XnXDqhnf1HDVky1VI+wSz9roKHGA4=
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
95 changes: 95 additions & 0 deletions chat-agent/api-go/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package main

import (
"github.com/hypermodeinc/modus/sdk/go/pkg/agents"
)

type SearchResponse struct {
Message string `json:"message"`
History string `json:"history"`
User_preferences string `json:"user_preferences"`
}

var session_ID = ""

func init() {
agents.Register(&ChatAgent{})
}

// The following are regular Modus functions.
// They are not part of the agent, but are used to start the agent and interact with it.
// Note that they cannot use an instance of the CounterAgent struct directly,
// but rather they will start an instance by name, and then send messages to it by ID.
// This is because the agent instance will actually be running in a different WASM instance,
// perhaps on a different process or even on a different machine.

// Creates a counter agent and returns info including its ID and status.
func CreateConversation() (id *string, err error) {
info, err := agents.Start("Chat-v1")
if err != nil {
return nil, err
}

return &info.Id, nil
}
func ContinueChat(id string, query string) (*string, error) {
// Send a message to the agent and get a response.
// The agent will use the chat history to generate a response.
// The response will be in the form of a JSON string.
// The response will include the message, the chat history, and any user preferences.
// The user preferences are optional and can be used to customize the response.
response, err := agents.SendMessage(id, "new_user_message", agents.WithData(query))
if err != nil {
return nil, err
}

return response, nil
}

type ChatResponse struct {
Message string `json:"message"`
History string `json:"history"`
}

func Chat(query string, chat_history string) (ChatResponse, error) {
// Send a message to the agent and get a response.
// The agent will use the chat history to generate a response.
// The response will be in the form of a JSON string.
// The response will include the message, the chat history, and any user preferences.
// The user preferences are optional and can be used to customize the response.
id := "d0qun08vf4i4h9fn6s60"
response, err := agents.SendMessage(id, "new_user_message", agents.WithData(query))
if err != nil {

*response = "Error: " + err.Error()
}

return ChatResponse{
Message: *response,
History: "",
}, nil

}

func ChatHistory(id string) (*string, error) {
// Send a message to the agent and get a response.
// The agent will use the chat history to generate a response.
// The response will be in the form of a JSON string.
// The response will include the message, the chat history, and any user preferences.
// The user preferences are optional and can be used to customize the response.
return agents.SendMessage(id, "get_chat_history")
}

/*func SaveFact(id string, fact string, location string) (*string, error) {
// Send a message to the agent to save a fact.
return (save_fact(id, fact, location))
}
*/

func DeleteAgent(id string) (*string, error) {
_, err := agents.Stop(id)
if err != nil {
return nil, err
}
return &id, nil
}
30 changes: 30 additions & 0 deletions chat-agent/api-go/modus.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"$schema": "https://schema.hypermode.com/modus.json",
"endpoints": {
"default": {
"type": "graphql",
"path": "/graphql",
"auth": "bearer-token"
}
},
"models": {
"text-generator": {
"sourceModel": "gpt-4o",
"connection": "hypermode-router",
"path": "v1/chat/completions"
}
},
"connections": {
"hypermode-router": {
"type": "http",
"baseUrl": "https://models.hypermode.host/",
"headers": {
"Authorization": "Bearer {{TOKEN}}"
}
},
"dgraph": {
"type": "dgraph",
"connString": "dgraph://modus-recipes-backend-hypermode.hypermode.host:443?sslmode=verify-ca&bearertoken={{API_KEY}}"
}
}
}
Loading
Loading