Skip to content
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

Main #17

Merged
merged 47 commits into from
Jun 12, 2024
Merged

Main #17

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
b47a69e
Agent Registry Interface
framedintent May 26, 2024
6b137fe
naming adjustments
framedintent May 26, 2024
feaedf1
- Effective Go codestyle
framedintent May 30, 2024
9ee9803
updated readme for dev preview
May 31, 2024
c93643b
spelling and spacing edits
May 31, 2024
917a4a2
edits
May 31, 2024
857bba3
more edits
May 31, 2024
3242466
Merge pull request #82 from framedintent/feature
alex-sandrk Jun 3, 2024
2d0bec3
Merge pull request #73 from framedintent/agent-registry
alex-sandrk Jun 3, 2024
e4a3b5b
Merge pull request #83 from Lumerin-protocol/docs-basebuild
abs2023 Jun 3, 2024
f14b794
Merge pull request #84 from MorpheusAIs/main
LumerinIO Jun 3, 2024
94d4a65
fix: calc total emitted MOR by summing all distribution pools
shev-titan May 28, 2024
7292ab3
fix: subtract totalClaimed mor when calculating compute balance
shev-titan Jun 4, 2024
c56d644
feat: swagger
alex-sandrk Jun 4, 2024
a53f65e
fix: avoid double calculation of the end time in opensession call
shev-titan Jun 4, 2024
646197a
feat: update go.mod
alex-sandrk Jun 4, 2024
52582c9
Merge pull request #89 from Lumerin-protocol/feat/swagger
alex-sandrk Jun 4, 2024
58d19c5
Added some stability
bohdan-titan Jun 5, 2024
ccb056a
Merge pull request #91 from Lumerin-protocol/feature/stable-chat
alex-sandrk Jun 6, 2024
b319649
feat: update method visibility to external
shev-titan Jun 6, 2024
b44d703
test: update test to represent updated compute calculation
shev-titan Jun 6, 2024
acf84be
fix: include latest adjustments from Ryan
shev-titan Jun 7, 2024
0b815f5
feat: api integration test
alex-sandrk Jun 7, 2024
8d1f4a1
integration api tests
alex-sandrk Jun 7, 2024
cdf8244
feat: proxyctl
shev-titan Jun 10, 2024
67b7473
Merge pull request #93 from Lumerin-protocol/feat/api-tests
alex-sandrk Jun 10, 2024
bd67474
feat: persistent storage + unified prompt endpoint
alex-sandrk Jun 10, 2024
ce85697
Merge branch 'dev' of github.com:Lumerin-protocol/Morpheus-Lumerin-No…
alex-sandrk Jun 10, 2024
d9ec8b3
fix: docs, pass storage, remove prefix from priv key
alex-sandrk Jun 11, 2024
924d160
fix: pass apiBus, update docs
alex-sandrk Jun 11, 2024
ba2d55a
Merge branch 'feat/keychain' into feat/persistent-storage
alex-sandrk Jun 11, 2024
e518c57
fix: get session from header
alex-sandrk Jun 11, 2024
da1d92c
Merge pull request #94 from Lumerin-protocol/feat/keychain
alex-sandrk Jun 11, 2024
f7034c0
Merge branch 'dev' of github.com:Lumerin-protocol/Morpheus-Lumerin-No…
alex-sandrk Jun 11, 2024
e25374f
Merge pull request #95 from Lumerin-protocol/feat/persistent-storage
alex-sandrk Jun 11, 2024
49d952b
fix: add env wallet and fix logger for badger
shev-titan Jun 12, 2024
d6227ab
fix: package path
shev-titan Jun 12, 2024
82a8ed2
test: api test fix
shev-titan Jun 12, 2024
f7d95bb
feat: use single endpoint for remote and local session
alex-sandrk Jun 12, 2024
768c875
Merge pull request #97 from Lumerin-protocol/feat/single-prompt-api
bohdan-titan Jun 12, 2024
9451fb3
Merge pull request #96 from Lumerin-protocol/proxy/wallet-prkey-env
lsheva Jun 12, 2024
9b2a7e6
feat: limit session duration to 24h
shev-titan Jun 12, 2024
7f104b9
Merge pull request #88 from Lumerin-protocol/smart-contracts/session-…
alex-sandrk Jun 12, 2024
6985e7d
feat: configure host from env
alex-sandrk Jun 12, 2024
80c066d
fix: pass whout protocol
alex-sandrk Jun 12, 2024
9f93bc7
Merge pull request #98 from Lumerin-protocol/feat/swagger-dynamic-host
alex-sandrk Jun 12, 2024
1a712b6
Merge pull request #87 from Lumerin-protocol/dev
abs2023 Jun 12, 2024
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
10 changes: 6 additions & 4 deletions proxy-router/.env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
DIAMOND_CONTRACT_ADDRESS=0x70768f0fF919e194E11aBFC3a2eDF43213359dc1
ENVIRONMENT=development
ETH_NODE_ADDRESS=https://arbitrum-sepolia.blockpi.network/v1/rpc/public
ETH_NODE_LEGACY_TX=false
EXPLORER_API_URL="https://api-sepolia.arbiscan.io/api"
LOG_COLOR=true
Expand All @@ -10,7 +9,7 @@ LOG_LEVEL_CONNECTION=info
LOG_LEVEL_PROXY=info
LOG_LEVEL_SCHEDULER=info
MOR_TOKEN_ADDRESS=0xc1664f994fd3991f98ae944bc16b9aed673ef5fd
OPENAI_BASE_URL=http://localhost:11434/v1
OPENAI_BASE_URL=http://localhost:8080/v1
PROXY_ADDRESS=0.0.0.0:3333
SYS_ENABLE=false
SYS_LOCAL_PORT_RANGE=1024 65535
Expand All @@ -19,6 +18,9 @@ SYS_RLIMIT_HARD=524288
SYS_RLIMIT_SOFT=524288
SYS_SOMAXCONN=100000
SYS_TCP_MAX_SYN_BACKLOG=100000
WALLET_PRIVATE_KEY=
WEB_ADDRESS=0.0.0.0:8080
WEB_ADDRESS=0.0.0.0:8082
WEB_PUBLIC_URL=

# Recommend using your own private ETH Node Address for better performance (via Alchemy or Infura)
ETH_NODE_ADDRESS=https://arbitrum-sepolia.blockpi.network/v1/rpc/public
# Private Key from your Wallet as Consumer or Provider (needed for the proxy-router to sign transactions)
1 change: 1 addition & 0 deletions proxy-router/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ logs
dist
bin

data
6 changes: 2 additions & 4 deletions proxy-router/.gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,8 @@ bedrock-04-PRD-rawimage:
.update_raw_task_definition: &update_raw_task_definition |
echo "**************************"
echo "*** Update Validator Task Definition"
echo "*** Unique elements that should be set in calling module are Wallet Private Key, Pool Address, Web_public_url, "
echo "*** CI_WALLET_PRIVATE_KEY, CI_POOL_ADDRESS, CI_WEB_PUBLIC_URL"
echo "*** Unique elements that should be set in calling module are Pool Address, Web_public_url, "
echo "*** CI_POOL_ADDRESS, CI_WEB_PUBLIC_URL"
echo "**************************"
aws ecs describe-task-definition --region $AWS_DEFAULT_REGION --task-definition tsk-$CI_AWS_TASK > output.json
echo "**************************"
Expand All @@ -195,8 +195,6 @@ bedrock-04-PRD-rawimage:
{ "name": "HASHRATE_ERROR_THRESHOLD", "value": "'"$HASHRATE_ERROR_THRESHOLD"'" },
{ "name": "HASHRATE_ERROR_TIMEOUT", "value": "'"$HASHRATE_ERROR_TIMEOUT"'" },
{ "name": "CLONE_FACTORY_ADDRESS", "value": "'"$CLONE_FACTORY_ADDRESS"'" },
{ "name": "CONTRACT_MNEMONIC", "value": "'"$CONTRACT_MNEMONIC"'" },
{ "name": "WALLET_PRIVATE_KEY", "value": "'"$CI_WALLET_PRIVATE_KEY"'" },
{ "name": "MINER_VETTING_DURATION", "value": "'"$MINER_VETTING_DURATION"'" },
{ "name": "MINER_SHARE_TIMEOUT", "value": "'"$MINER_SHARE_TIMEOUT"'" },
{ "name": "LOG_COLOR", "value": "'"$LOG_COLOR"'" },
Expand Down
2 changes: 1 addition & 1 deletion proxy-router/.goreleaser-internal.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ builds:
no_unique_dist_dir: true
binary: "{{ .ProjectName }}_{{ .Tag }}_{{ .Os }}_{{ .Arch }}"
ldflags:
- -s -w -X main.version={{.Version}} -X github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/internal/config.Commit={{.Commit}} -X main.date={{.Date}} -X 'github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/internal/config.BuildVersion={{.Version}}'
- -s -w -X main.version={{.Version}} -X github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/config.Commit={{.Commit}} -X main.date={{.Date}} -X 'github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/config.BuildVersion={{.Version}}'

archives:
- format: binary
Expand Down
2 changes: 1 addition & 1 deletion proxy-router/.goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ builds:
no_unique_dist_dir: true
binary: "{{ .ProjectName }}_{{ .Tag }}_{{ .Os }}_{{ .Arch }}"
ldflags:
- -s -w -X main.version={{.Version}} -X github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/internal/config.Commit={{.Commit}} -X main.date={{.Date}} -X 'github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/internal/config.BuildVersion={{.Version}}'
- -s -w -X main.version={{.Version}} -X github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/config.Commit={{.Commit}} -X main.date={{.Date}} -X 'github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/config.BuildVersion={{.Version}}'

archives:
- format: binary
Expand Down
5 changes: 4 additions & 1 deletion proxy-router/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,7 @@ test-unit:
go test -v -p 1 $$(go list ./... | grep -v /test)

test-integration:
go test -v ./test/...
go test -v ./test/...

swagger:
swag init -g ./internal/handlers/httphandlers/http.go
273 changes: 273 additions & 0 deletions proxy-router/api_test/httphandlers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
package httphandlers_test

import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"math/big"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"time"

"github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/aiengine"
"github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/apibus"
"github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/config"
"github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/handlers/httphandlers"
"github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/interfaces"
"github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/lib"
"github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/proxyapi"
"github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/repositories/wallet"
"github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/rpcproxy"
"github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/storages"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"

"github.com/stretchr/testify/require"
)

var WALLET_PRIVATE_KEY = "" // Set this to a valid private key to run the test.

var DIAMOND_CONTRACT_ADDR = "0x70768f0ff919e194e11abfc3a2edf43213359dc1"
var MOR_CONTRACT_ADDR = "0xc1664f994fd3991f98ae944bc16b9aed673ef5fd"
var EXPLORER_API_URL = "https://api-sepolia.arbiscan.io/api"
var ETH_LEGACY_TX = false
var ETH_NODE_ADDRESS = "wss://arb-sepolia.g.alchemy.com/v2/UPDATE_HERE"

var PROVIDER_ADDR = "0x65bBb982d9B0AfE9AED13E999B79c56dDF9e04fC"
var PROVIDER_URL = "thehulk1.stg.lumerin.io:3333"
var BID_ID = "0xa0d6ea9ce7183510e16cbfd207b9e381a91c20ee75d5db483b5758ddf22a27b1"
var SESSION_DURATION = new(big.Int).SetInt64(5 * 60) // 5 minutes in seconds

func TestNewHTTPHandlerIntegration(t *testing.T) {
apiBus := InitializeApiBus(t)

walletAddr, err := lib.PrivKeyStringToAddr(WALLET_PRIVATE_KEY)
if err != nil {
t.Fatalf("failed to get wallet address: %s", err)
return
}

// Create a new instance of the HTTPHandler.
handler := httphandlers.NewHTTPHandler(apiBus)

server := httptest.NewServer(handler)
defer server.Close()

// Make a request to get the token supply.
supply := GetTokenSupply(t, server)

// Make a request to get today's budget.
budget := GetTodaysBudget(t, server)

// Make a request to get the provider's bids.
bid := FindBid(t, server)

// Calculate the stake.
pricePerSecond := new(big.Float).SetFloat64(bid["PricePerSecond"].(float64))
pricePerSecondInt := new(big.Int)
pricePerSecondInt, _ = pricePerSecondInt.SetString(pricePerSecond.Text('f', 0), 10)

totalCost := SESSION_DURATION.Mul(pricePerSecondInt, SESSION_DURATION)
stake := totalCost.Div(totalCost.Mul(supply, totalCost), budget)

// Make a request to initiate a session.
initiateSessionResponse := InitiateSession(t, server, walletAddr, stake)
approval := initiateSessionResponse.Response.Result.Approval
approvalSig := initiateSessionResponse.Response.Result.ApprovalSig
providerPubKey := initiateSessionResponse.Response.Result.Message

// Make a request to open a session.
sessionId := OpenSession(t, server, approval, approvalSig, stake)

// Make a request to send a prompt.
promptRequestBody := map[string]interface{}{
"providerPublicKey": providerPubKey,
"prompt": map[string]interface{}{
"model": "llama2",
"stream": true,
"messages": []map[string]string{
{
"role": "user",
"content": "Why sky is blue?",
},
},
},
"providerUrl": PROVIDER_URL,
}

promptBody, err := json.Marshal(promptRequestBody)
require.NoError(t, err)

sendPromptURL := server.URL + fmt.Sprintf("/proxy/sessions/%s/prompt", sessionId)
sendPromptResp, err := http.Post(sendPromptURL, "application/json", bytes.NewReader(promptBody))
require.NoError(t, err)

// Make a request to close a session.
closeSessionURL := server.URL + fmt.Sprintf("/blockchain/sessions/%s/close", sessionId)
closeSessionResp, err := http.Post(closeSessionURL, "application/json", nil)
require.NoError(t, err)
require.Equal(t, http.StatusOK, closeSessionResp.StatusCode)

require.Equal(t, http.StatusOK, sendPromptResp.StatusCode)
}

func GetTokenSupply(t *testing.T, server *httptest.Server) *big.Int {
getTokenSupplyURL := server.URL + "/blockchain/token/supply"
getTokenSupplyResp, err := http.Get(getTokenSupplyURL)
require.NoError(t, err)
require.Equal(t, http.StatusOK, getTokenSupplyResp.StatusCode)

bodyBytes, err := io.ReadAll(getTokenSupplyResp.Body)
require.NoError(t, err)

var data map[string]string
err = json.Unmarshal(bodyBytes, &data)
require.NoError(t, err)

supply, ok := new(big.Int).SetString(data["supply"], 10)
require.True(t, ok)
return supply
}

func GetTodaysBudget(t *testing.T, server *httptest.Server) *big.Int {
getTodaysBudgetURL := server.URL + "/blockchain/sessions/budget"
getTodaysBudgetResp, err := http.Get(getTodaysBudgetURL)
require.NoError(t, err)
require.Equal(t, http.StatusOK, getTodaysBudgetResp.StatusCode)

bodyBytes, err := io.ReadAll(getTodaysBudgetResp.Body)
require.NoError(t, err)

var data map[string]string
err = json.Unmarshal(bodyBytes, &data)
require.NoError(t, err)

budget, ok := new(big.Int).SetString(data["budget"], 10)
require.True(t, ok)
return budget
}

func FindBid(t *testing.T, server *httptest.Server) map[string]interface{} {
getBidsUrl := server.URL + fmt.Sprintf("/blockchain/providers/%s/bids", PROVIDER_ADDR)
getBidResp, err := http.Get(getBidsUrl)
require.NoError(t, err)
require.Equal(t, http.StatusOK, getBidResp.StatusCode)

bodyBytes, err := io.ReadAll(getBidResp.Body)
require.NoError(t, err)
var data map[string][]interface{}

err = json.Unmarshal(bodyBytes, &data)
require.NoError(t, err)

var bid map[string]interface{}
for _, v := range data["bids"] {
b := v.(map[string]interface{})
if b["Id"] == BID_ID {
bid = b
break
}
}
require.NotNil(t, bid)
return bid
}

type InitiateSessionData struct {
Approval string `json:"approval"`
ApprovalSig string `json:"approvalSig"`
Message string `json:"message"`
}

type InitiateSessionResult struct {
Result InitiateSessionData `json:"result"`
}

type InitiateSessionResponse struct {
Response InitiateSessionResult `json:"response"`
}

func InitiateSession(t *testing.T, server *httptest.Server, walletAddr common.Address, stake *big.Int) InitiateSessionResponse {
initiateSessionURL := server.URL + "/proxy/sessions/initiate"

var body map[string]interface{} = make(map[string]interface{})
body["user"] = walletAddr
body["provider"] = PROVIDER_ADDR
body["spend"] = stake
body["bidId"] = BID_ID
body["providerUrl"] = PROVIDER_URL
initiateSessionBody, err := json.Marshal(body)
require.NoError(t, err)

initiateSessionResp, err := http.Post(initiateSessionURL, "application/json", bytes.NewReader(initiateSessionBody))
require.NoError(t, err)
require.Equal(t, http.StatusOK, initiateSessionResp.StatusCode)

bodyBytes, err := io.ReadAll(initiateSessionResp.Body)
require.NoError(t, err)

fmt.Println(string(bodyBytes))

var response InitiateSessionResponse
err = json.Unmarshal(bodyBytes, &response)
require.NoError(t, err)

return response
}

func OpenSession(t *testing.T, server *httptest.Server, approval string, approvalSig string, stake *big.Int) string {
var openBody map[string]interface{} = make(map[string]interface{})
openBody["approval"] = approval
openBody["approvalSig"] = approvalSig
openBody["stake"] = stake.String()
openSessionBody, err := json.Marshal(openBody)
require.NoError(t, err)

openSessionURL := server.URL + "/blockchain/sessions"
openSessionResp, err := http.Post(openSessionURL, "application/json", bytes.NewReader(openSessionBody))
require.NoError(t, err)
require.Equal(t, http.StatusOK, openSessionResp.StatusCode)

bodyBytes, err := io.ReadAll(openSessionResp.Body)
fmt.Println(string(bodyBytes))
require.NoError(t, err)

var data map[string]interface{}
err = json.Unmarshal(bodyBytes, &data)
require.NoError(t, err)

sessionId := data["sessionId"]
return sessionId.(string)
}

func InitializeApiBus(t *testing.T) *apibus.ApiBus {
log, err := lib.NewLogger("debug", true, false, false, "")
if err != nil {
t.Fatalf("failed to create logger: %s", err)
return nil
}

ethClient, err := ethclient.DialContext(context.Background(), ETH_NODE_ADDRESS)
if err != nil {
t.Fatalf("failed to connect to the Ethereum node: %s", err)
return nil
}

derived := new(config.DerivedConfig)
contractLogStorage := lib.NewCollection[*interfaces.LogStorage]()

diamondContractAddr := common.HexToAddress(DIAMOND_CONTRACT_ADDR)
morContractAddr := common.HexToAddress(MOR_CONTRACT_ADDR)

sessionStorage := storages.NewSessionStorage(log)

wlt := wallet.NewEnvWallet(WALLET_PRIVATE_KEY)
rpcProxy := rpcproxy.NewRpcProxy(ethClient, diamondContractAddr, morContractAddr, EXPLORER_API_URL, wlt, sessionStorage, log, ETH_LEGACY_TX)
proxyRouterApi := proxyapi.NewProxyRouterApi(nil, &url.URL{}, wlt, nil, derived, time.Now(), contractLogStorage, sessionStorage, log)

apiBus := apibus.NewApiBus(rpcProxy, aiengine.NewAiEngine(), proxyRouterApi, wlt)
return apiBus
}
6 changes: 3 additions & 3 deletions proxy-router/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ echo COMMIT=$COMMIT

go build \
-ldflags="-s -w \
-X 'github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/internal/config.BuildVersion=$VERSION' \
-X 'github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/internal/config.Commit=$COMMIT' \
-X 'github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/config.BuildVersion=$VERSION' \
-X 'github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/config.Commit=$COMMIT' \
" \
-o bin/proxy-router cmd/main.go
-o bin/proxy-router cmd/main.go
Loading