mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-06-29 15:31:05 +08:00
Go CLI: Add create and drop commands (#16430)
### What problem does this PR solve? 1. Add CREATE and DROP DATASET / MEMORY / AGENT / SEARCH / CHAT. 2. Add option to build.sh to strip RAGFlow binary. ### Type of change - [x] Refactoring --------- Signed-off-by: Jin Hai <haijin.chn@gmail.com>
This commit is contained in:
27
build.sh
27
build.sh
@@ -19,6 +19,9 @@ ADMIN_SERVER_BINARY="$PROJECT_ROOT/bin/admin_server"
|
||||
INGESTOR_BINARY="$PROJECT_ROOT/bin/ingestor"
|
||||
RAGFLOW_CLI_BINARY="$PROJECT_ROOT/bin/ragflow-cli"
|
||||
|
||||
# Strip symbols from Go binaries (set via --strip / -s)
|
||||
STRIP_SYMBOLS=""
|
||||
|
||||
# office_oxide native library settings
|
||||
OFFICE_OXIDE_PREFIX="${HOME}/.office_oxide"
|
||||
OFFICE_OXIDE_VERSION="0.1.2"
|
||||
@@ -255,19 +258,22 @@ build_go() {
|
||||
|
||||
setup_cgo_env
|
||||
|
||||
local strip_flags=()
|
||||
[ -n "$STRIP_SYMBOLS" ] && strip_flags=(-ldflags="-s -w")
|
||||
|
||||
echo "Building RAGFlow binary: $RAGFLOW_SERVER_BINARY, $ADMIN_SERVER_BINARY, $INGESTOR_BINARY, and $RAGFLOW_CLI_BINARY"
|
||||
GOPROXY=${GOPROXY:-https://goproxy.cn,https://proxy.golang.org,direct} CGO_ENABLED=1 \
|
||||
CGO_CFLAGS="$CGO_CFLAGS" CGO_LDFLAGS="$CGO_LDFLAGS" \
|
||||
go build -o "$RAGFLOW_SERVER_BINARY" cmd/server_main.go
|
||||
go build "${strip_flags[@]}" -o "$RAGFLOW_SERVER_BINARY" cmd/server_main.go
|
||||
GOPROXY=${GOPROXY:-https://goproxy.cn,https://proxy.golang.org,direct} CGO_ENABLED=1 \
|
||||
CGO_CFLAGS="$CGO_CFLAGS" CGO_LDFLAGS="$CGO_LDFLAGS" \
|
||||
go build -o "$ADMIN_SERVER_BINARY" cmd/admin_server.go
|
||||
go build "${strip_flags[@]}" -o "$ADMIN_SERVER_BINARY" cmd/admin_server.go
|
||||
GOPROXY=${GOPROXY:-https://goproxy.cn,https://proxy.golang.org,direct} CGO_ENABLED=1 \
|
||||
CGO_CFLAGS="$CGO_CFLAGS" CGO_LDFLAGS="$CGO_LDFLAGS" \
|
||||
go build -o "$INGESTOR_BINARY" cmd/ingestor.go
|
||||
go build "${strip_flags[@]}" -o "$INGESTOR_BINARY" cmd/ingestor.go
|
||||
GOPROXY=${GOPROXY:-https://goproxy.cn,https://proxy.golang.org,direct} CGO_ENABLED=1 \
|
||||
CGO_CFLAGS="$CGO_CFLAGS" CGO_LDFLAGS="$CGO_LDFLAGS" \
|
||||
go build -o "$RAGFLOW_CLI_BINARY" cmd/ragflow-cli.go
|
||||
go build "${strip_flags[@]}" -o "$RAGFLOW_CLI_BINARY" cmd/ragflow-cli.go
|
||||
|
||||
if [ ! -f "$RAGFLOW_SERVER_BINARY" ]; then
|
||||
echo -e "${RED}Error: Failed to build RAGFlow server binary${NC}"
|
||||
@@ -389,6 +395,8 @@ OPTIONS:
|
||||
`$0 --test -- -run TestFoo ./internal/admin/...`
|
||||
--clean, -C Clean all build artifacts
|
||||
--run, -r Build and run the server
|
||||
--strip, -s Strip debug symbols from Go binaries (-ldflags="-s -w")
|
||||
(disabled by default, useful for smaller production binaries)
|
||||
--help, -h Show this help message
|
||||
|
||||
EXAMPLES:
|
||||
@@ -415,7 +423,16 @@ EOF
|
||||
|
||||
# Main function
|
||||
main() {
|
||||
case "${1:-}" in
|
||||
# Parse --strip / -s before other arguments
|
||||
local args=()
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--strip|-s) STRIP_SYMBOLS="1" ;;
|
||||
*) args+=("$arg") ;;
|
||||
esac
|
||||
done
|
||||
|
||||
case "${args[0]:-}" in
|
||||
--cpp|-c)
|
||||
check_cpp_deps
|
||||
build_cpp
|
||||
|
||||
@@ -1269,42 +1269,6 @@ func (p *Parser) parseAdminDropRole() (*Command, error) {
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseAdminDropDataset() (*Command, error) {
|
||||
p.nextToken() // consume DATASET
|
||||
datasetName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cmd := NewCommand("drop_user_dataset")
|
||||
cmd.Params["dataset_name"] = datasetName
|
||||
|
||||
p.nextToken()
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseAdminDropChat() (*Command, error) {
|
||||
p.nextToken() // consume CHAT
|
||||
chatName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cmd := NewCommand("drop_user_chat")
|
||||
cmd.Params["chat_name"] = chatName
|
||||
|
||||
p.nextToken()
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// endregion DROP commands
|
||||
|
||||
// region ALTER commands
|
||||
|
||||
@@ -312,6 +312,8 @@ func (c *CLI) ExecuteUserCommand(cmd *Command) (ResponseIf, error) {
|
||||
return c.APIListChatsCommand(cmd)
|
||||
case "api_list_searches":
|
||||
return c.APIListSearchesCommand(cmd)
|
||||
case "api_list_memories":
|
||||
return c.APIListMemoriesCommand(cmd)
|
||||
case "list_dataset_documents":
|
||||
return c.ListDatasetDocumentUserCommand(cmd)
|
||||
case "search_on_datasets":
|
||||
@@ -380,6 +382,16 @@ func (c *CLI) ExecuteUserCommand(cmd *Command) (ResponseIf, error) {
|
||||
return c.APIListProviders(cmd)
|
||||
case "delete_provider":
|
||||
return c.DeleteProvider(cmd)
|
||||
case "api_drop_dataset":
|
||||
return c.APIDropDatasetCommand(cmd)
|
||||
case "api_drop_chat":
|
||||
return c.APIDropChatCommand(cmd)
|
||||
case "api_drop_search":
|
||||
return c.APIDropSearchCommand(cmd)
|
||||
case "api_drop_memory":
|
||||
return c.APIDropMemoryCommand(cmd)
|
||||
case "api_drop_agent":
|
||||
return c.APIDropAgentCommand(cmd)
|
||||
// Provider instance commands
|
||||
case "api_create_provider_instance":
|
||||
return c.APICreateProviderInstanceCommand(cmd)
|
||||
|
||||
@@ -1613,3 +1613,79 @@ func (c *CLI) getDatasetIDByName(datasetName string) (string, error) {
|
||||
}
|
||||
return "", fmt.Errorf("dataset %s not found", datasetName)
|
||||
}
|
||||
|
||||
func (c *CLI) getAgentIDByName(agentName string) (string, error) {
|
||||
response, err := c.APIListAgentsCommand(nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
commonResponse, ok := response.(*CommonResponse)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("invalid response")
|
||||
}
|
||||
for _, agent := range commonResponse.Data {
|
||||
if agent["name"] == agentName {
|
||||
return agent["id"].(string), nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("agent %s not found", agentName)
|
||||
}
|
||||
|
||||
func (c *CLI) getSearchIDByName(searchName string) (string, error) {
|
||||
response, err := c.APIListSearchesCommand(nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
searchesResponse, ok := response.(*ListSearchesResponse)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("invalid response")
|
||||
}
|
||||
searches := searchesResponse.Data["search_apps"].([]interface{})
|
||||
for _, search := range searches {
|
||||
searchMap := search.(map[string]interface{})
|
||||
if searchMap["name"] == searchName {
|
||||
return searchMap["id"].(string), nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("search %s not found", searchName)
|
||||
}
|
||||
|
||||
func (c *CLI) getChatIDByName(chatName string) (string, error) {
|
||||
response, err := c.APIListChatsCommand(nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
commonResponse, ok := response.(*CommonResponse)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("invalid response")
|
||||
}
|
||||
for _, chat := range commonResponse.Data {
|
||||
if chat["name"] == chatName {
|
||||
return chat["id"].(string), nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("chat %s not found", chatName)
|
||||
}
|
||||
|
||||
func (c *CLI) getMemoryIDByName(memoryName string) (string, error) {
|
||||
response, err := c.APIListMemoriesCommand(nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
listMemoriesResponse, ok := response.(*ListMemoriesResponse)
|
||||
memories := listMemoriesResponse.Data["memory_list"].([]interface{})
|
||||
if !ok {
|
||||
return "", fmt.Errorf("invalid response")
|
||||
}
|
||||
for _, memory := range memories {
|
||||
var memoryMap map[string]interface{}
|
||||
memoryMap, ok = memory.(map[string]interface{})
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if memoryMap["name"] == memoryName {
|
||||
return memoryMap["id"].(string), nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("memory %s not found", memoryName)
|
||||
}
|
||||
|
||||
@@ -365,6 +365,8 @@ func (l *Lexer) lookupIdent(ident string) Token {
|
||||
return Token{Type: TokenAgent, Value: ident}
|
||||
case "MEMORY":
|
||||
return Token{Type: TokenMemory, Value: ident}
|
||||
case "MEMORIES":
|
||||
return Token{Type: TokenMemories, Value: ident}
|
||||
case "RETRIEVE":
|
||||
return Token{Type: TokenRetrieve, Value: ident}
|
||||
case "CURRENT":
|
||||
|
||||
@@ -288,6 +288,42 @@ func (r *ListSearchesResponse) PrintOut() {
|
||||
}
|
||||
}
|
||||
|
||||
type ListMemoriesResponse struct {
|
||||
Code int `json:"code"`
|
||||
Data map[string]interface{} `json:"data"`
|
||||
Message string `json:"message"`
|
||||
Duration float64
|
||||
OutputFormat OutputFormat
|
||||
}
|
||||
|
||||
func (r *ListMemoriesResponse) Type() string {
|
||||
return "list_memories"
|
||||
}
|
||||
|
||||
func (r *ListMemoriesResponse) TimeCost() float64 {
|
||||
return r.Duration
|
||||
}
|
||||
|
||||
func (r *ListMemoriesResponse) SetOutputFormat(format OutputFormat) {
|
||||
r.OutputFormat = format
|
||||
}
|
||||
|
||||
func (r *ListMemoriesResponse) PrintOut() {
|
||||
if r.Code == 0 {
|
||||
total := r.Data["total_count"].(float64)
|
||||
fmt.Printf("Total: %0.0f\n", total)
|
||||
docs := r.Data["memory_list"].([]interface{})
|
||||
table := make([]map[string]interface{}, 0)
|
||||
for _, doc := range docs {
|
||||
table = append(table, doc.(map[string]interface{}))
|
||||
}
|
||||
PrintTableSimpleByFormat(table, r.OutputFormat)
|
||||
} else {
|
||||
fmt.Println("ERROR")
|
||||
fmt.Printf("%d, %s\n", r.Code, r.Message)
|
||||
}
|
||||
}
|
||||
|
||||
type ChunkResponse struct {
|
||||
Code int `json:"code"`
|
||||
Data map[string]interface{} `json:"data"`
|
||||
@@ -414,6 +450,20 @@ func (r *SimpleResponse) PrintOut() {
|
||||
}
|
||||
}
|
||||
|
||||
func HandleSimpleResponse(response *Response, command string) (ResponseIf, error) {
|
||||
var result SimpleResponse
|
||||
if err := json.Unmarshal(response.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("%s failed: invalid JSON (%w)", command, err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = response.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
type MessageResponse struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
|
||||
@@ -102,6 +102,7 @@ const (
|
||||
TokenPipeline
|
||||
TokenSearch
|
||||
TokenAgent
|
||||
TokenMemories
|
||||
TokenMemory
|
||||
TokenRetrieve
|
||||
TokenCurrent
|
||||
|
||||
@@ -248,16 +248,10 @@ func (c *CLI) APISetLogLevelCommand(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to register user: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
return nil, fmt.Errorf("failed to change log level: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result SimpleResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("change log level failed: invalid JSON (%w)", err)
|
||||
}
|
||||
result.Code = 0
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
return HandleSimpleResponse(resp, "change log level")
|
||||
}
|
||||
|
||||
func (c *CLI) RegisterUser(cmd *Command) (ResponseIf, error) {
|
||||
@@ -602,6 +596,50 @@ func (c *CLI) APIListSearchesCommand(cmd *Command) (ResponseIf, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// APIListMemoriesCommand lists memories
|
||||
func (c *CLI) APIListMemoriesCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != APIMode {
|
||||
return nil, fmt.Errorf("this command is only allowed in USER mode")
|
||||
}
|
||||
|
||||
httpClient := c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer]
|
||||
|
||||
if httpClient.LoginToken == nil && !c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].useAPIKey {
|
||||
return nil, fmt.Errorf("no authorization")
|
||||
}
|
||||
|
||||
authKind := "web"
|
||||
if httpClient.useAPIKey {
|
||||
authKind = "api"
|
||||
}
|
||||
|
||||
if httpClient.LoginToken != nil {
|
||||
authKind = "web"
|
||||
}
|
||||
|
||||
// Normal mode
|
||||
resp, err := httpClient.Request("GET", "/memories", authKind, nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list memories: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to list memories: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result ListMemoriesResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("list memories failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
result.Duration = resp.Duration
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// ListDatasetDocumentUserCommand lists dataset documents
|
||||
func (c *CLI) ListDatasetDocumentUserCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != APIMode {
|
||||
@@ -1000,7 +1038,16 @@ func (c *CLI) APICreateDatasetCommand(cmd *Command) (ResponseIf, error) {
|
||||
return nil, fmt.Errorf("no authorization")
|
||||
}
|
||||
|
||||
resp, err := httpClient.Request("POST", "/datasets", "web", nil, nil)
|
||||
datasetName, ok := cmd.Params["dataset_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("dataset_name parameter is required")
|
||||
}
|
||||
|
||||
payload := map[string]interface{}{
|
||||
"name": datasetName,
|
||||
}
|
||||
|
||||
resp, err := httpClient.Request("POST", "/datasets", "web", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create dataset: %w", err)
|
||||
}
|
||||
@@ -1009,20 +1056,7 @@ func (c *CLI) APICreateDatasetCommand(cmd *Command) (ResponseIf, error) {
|
||||
return nil, fmt.Errorf("failed to create dataset: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var createResult CommonDataResponse
|
||||
if err = json.Unmarshal(resp.Body, &createResult); err != nil {
|
||||
return nil, fmt.Errorf("create dataset failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if createResult.Code != 0 {
|
||||
return nil, fmt.Errorf("error code: %d, message: %s", createResult.Code, createResult.Message)
|
||||
}
|
||||
|
||||
var result SimpleResponse
|
||||
result.Code = 0
|
||||
result.Message = "Dataset created successfully"
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
return HandleSimpleResponse(resp, "create dataset")
|
||||
}
|
||||
|
||||
func (c *CLI) APICreateAgentCommand(cmd *Command) (ResponseIf, error) {
|
||||
@@ -1111,7 +1145,16 @@ func (c *CLI) APICreateSearchCommand(cmd *Command) (ResponseIf, error) {
|
||||
return nil, fmt.Errorf("no authorization")
|
||||
}
|
||||
|
||||
resp, err := httpClient.Request("POST", "/searches", "web", nil, nil)
|
||||
searchName, ok := cmd.Params["search_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("search_name parameter is required")
|
||||
}
|
||||
|
||||
payload := map[string]interface{}{
|
||||
"name": searchName,
|
||||
}
|
||||
|
||||
resp, err := httpClient.Request("POST", "/searches", "web", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create search: %w", err)
|
||||
}
|
||||
@@ -1148,7 +1191,16 @@ func (c *CLI) APICreateMemoryCommand(cmd *Command) (ResponseIf, error) {
|
||||
return nil, fmt.Errorf("no authorization")
|
||||
}
|
||||
|
||||
resp, err := httpClient.Request("POST", "/memories", "web", nil, nil)
|
||||
memoryName, ok := cmd.Params["memory_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("memory_name parameter is required")
|
||||
}
|
||||
|
||||
payload := map[string]interface{}{
|
||||
"name": memoryName,
|
||||
}
|
||||
|
||||
resp, err := httpClient.Request("POST", "/memories", "web", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create memory: %w", err)
|
||||
}
|
||||
@@ -1221,16 +1273,7 @@ func (c *CLI) APIDeleteAPIKeyCommand(cmd *Command) (ResponseIf, error) {
|
||||
return nil, fmt.Errorf("failed to delete key: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result SimpleResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("delete key failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
return HandleSimpleResponse(resp, "delete key")
|
||||
}
|
||||
|
||||
// APISetAPIKeyCommand sets the API key after validating it
|
||||
@@ -1628,17 +1671,7 @@ func (c *CLI) AddProvider(cmd *Command) (ResponseIf, error) {
|
||||
return nil, fmt.Errorf("failed to add provider: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result SimpleResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("add provider failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
return HandleSimpleResponse(resp, "add provider")
|
||||
}
|
||||
|
||||
// APIListProviders lists added providers
|
||||
@@ -1702,17 +1735,196 @@ func (c *CLI) DeleteProvider(cmd *Command) (ResponseIf, error) {
|
||||
return nil, fmt.Errorf("failed to delete provider: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result SimpleResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("delete provider failed: invalid JSON (%w)", err)
|
||||
return HandleSimpleResponse(resp, "delete provider")
|
||||
}
|
||||
|
||||
// APIDropDatasetCommand DROP DATASET 'dataset_name'
|
||||
func (c *CLI) APIDropDatasetCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != APIMode {
|
||||
return nil, fmt.Errorf("this command is only allowed in USER mode")
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
httpClient := c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer]
|
||||
|
||||
if httpClient.LoginToken == nil && !c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].useAPIKey {
|
||||
return nil, fmt.Errorf("no authorization")
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
datasetName, ok := cmd.Params["dataset_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("dataset_name parameter is required")
|
||||
}
|
||||
|
||||
datasetID, err := c.getDatasetIDByName(datasetName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get dataset ID: %w by dataset name: %s", err, datasetName)
|
||||
}
|
||||
|
||||
payload := map[string]interface{}{
|
||||
"ids": []string{datasetID},
|
||||
"delete_all": true,
|
||||
}
|
||||
|
||||
resp, err := httpClient.Request("DELETE", "/datasets", "web", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create dataset: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to create dataset: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
return HandleSimpleResponse(resp, "create provider instance")
|
||||
}
|
||||
|
||||
// APIDropAgentCommand DROP AGENT 'agent_name'
|
||||
func (c *CLI) APIDropAgentCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != APIMode {
|
||||
return nil, fmt.Errorf("this command is only allowed in USER mode")
|
||||
}
|
||||
|
||||
httpClient := c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer]
|
||||
|
||||
if httpClient.LoginToken == nil && !c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].useAPIKey {
|
||||
return nil, fmt.Errorf("no authorization")
|
||||
}
|
||||
|
||||
agentName, ok := cmd.Params["agent_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("agent_name parameter is required")
|
||||
}
|
||||
|
||||
agentID, err := c.getAgentIDByName(agentName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get agent ID: %w by agent name: %s", err, agentName)
|
||||
}
|
||||
|
||||
payload := map[string]interface{}{
|
||||
"ids": []string{agentID},
|
||||
"delete_all": true,
|
||||
}
|
||||
|
||||
resp, err := httpClient.Request("DELETE", "/agents", "web", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create agent: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to create agent: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
return HandleSimpleResponse(resp, "delete agent")
|
||||
}
|
||||
|
||||
// APIDropChatCommand DROP CHAT 'chat_name'
|
||||
func (c *CLI) APIDropChatCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != APIMode {
|
||||
return nil, fmt.Errorf("this command is only allowed in USER mode")
|
||||
}
|
||||
|
||||
httpClient := c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer]
|
||||
|
||||
if httpClient.LoginToken == nil && !c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].useAPIKey {
|
||||
return nil, fmt.Errorf("no authorization")
|
||||
}
|
||||
|
||||
chatName, ok := cmd.Params["chat_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("chat_name parameter is required")
|
||||
}
|
||||
|
||||
chatID, err := c.getChatIDByName(chatName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get chat ID: %w by chat name: %s", err, chatName)
|
||||
}
|
||||
|
||||
payload := map[string]interface{}{
|
||||
"ids": []string{chatID},
|
||||
"delete_all": true,
|
||||
}
|
||||
|
||||
resp, err := httpClient.Request("DELETE", "/chats", "web", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create chat: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to create chat: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
return HandleSimpleResponse(resp, "delete chat")
|
||||
}
|
||||
|
||||
// APIDropSearchCommand DROP SEARCH 'search_name'
|
||||
func (c *CLI) APIDropSearchCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != APIMode {
|
||||
return nil, fmt.Errorf("this command is only allowed in USER mode")
|
||||
}
|
||||
|
||||
httpClient := c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer]
|
||||
|
||||
if httpClient.LoginToken == nil && !c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].useAPIKey {
|
||||
return nil, fmt.Errorf("no authorization")
|
||||
}
|
||||
|
||||
searchName, ok := cmd.Params["search_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("search_name parameter is required")
|
||||
}
|
||||
|
||||
searchID, err := c.getSearchIDByName(searchName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get search ID: %w by search name: %s", err, searchName)
|
||||
}
|
||||
|
||||
endPoint := fmt.Sprintf("/searches/%s", searchID)
|
||||
|
||||
resp, err := httpClient.Request("DELETE", endPoint, "web", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to delete search: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to delete search: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
return HandleSimpleResponse(resp, "delete search")
|
||||
}
|
||||
|
||||
// APIDropMemoryCommand DROP MEMORY 'memory_name'
|
||||
func (c *CLI) APIDropMemoryCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != APIMode {
|
||||
return nil, fmt.Errorf("this command is only allowed in USER mode")
|
||||
}
|
||||
|
||||
httpClient := c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer]
|
||||
|
||||
if httpClient.LoginToken == nil && !c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].useAPIKey {
|
||||
return nil, fmt.Errorf("no authorization")
|
||||
}
|
||||
|
||||
memoryName, ok := cmd.Params["memory_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("memory_name parameter is required")
|
||||
}
|
||||
|
||||
memoryID, err := c.getMemoryIDByName(memoryName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get memory ID: %w by memory name: %s", err, memoryName)
|
||||
}
|
||||
|
||||
endPoint := fmt.Sprintf("/memories/%s", memoryID)
|
||||
|
||||
resp, err := httpClient.Request("DELETE", endPoint, "web", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to delete memory: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to delete memory: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
return HandleSimpleResponse(resp, "delete memory")
|
||||
}
|
||||
|
||||
// APICreateProviderInstanceCommand creates a new provider instance
|
||||
@@ -1770,17 +1982,7 @@ func (c *CLI) APICreateProviderInstanceCommand(cmd *Command) (ResponseIf, error)
|
||||
return nil, fmt.Errorf("failed to create provider instance: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result SimpleResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("create provider instance failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
return HandleSimpleResponse(resp, "create provider instance")
|
||||
}
|
||||
|
||||
// ShowInstanceBalance shows balance of a specific instance
|
||||
@@ -1856,17 +2058,7 @@ func (c *CLI) DropProviderInstance(cmd *Command) (ResponseIf, error) {
|
||||
return nil, fmt.Errorf("failed to drop instance: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result SimpleResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("drop instance failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
return HandleSimpleResponse(resp, "drop instance")
|
||||
}
|
||||
|
||||
// DROP MODEL <name1 name2 name3> FROM <provider_name> <instance_name>
|
||||
@@ -1899,24 +2091,14 @@ func (c *CLI) DropInstanceModel(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
resp, err := c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].Request("DELETE", url, "web", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to drop instance: %w", err)
|
||||
return nil, fmt.Errorf("failed to drop model: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to drop instance: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
return nil, fmt.Errorf("failed to drop model: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result SimpleResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("drop instance failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
return HandleSimpleResponse(resp, "drop model")
|
||||
}
|
||||
|
||||
func isValidURL(str string) bool {
|
||||
@@ -3043,16 +3225,8 @@ func (c *CLI) AddCustomModel(cmd *Command) (ResponseIf, error) {
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to add custom model: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
var result SimpleResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("add custom model failed: invalid JSON (%w)", err)
|
||||
}
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
|
||||
return HandleSimpleResponse(resp, "add custom model")
|
||||
}
|
||||
|
||||
// InsertChunksFromFile inserts chunks from a JSON file
|
||||
@@ -3522,17 +3696,7 @@ func (c *CLI) ParseDocumentsUserCommand(cmd *Command) (ResponseIf, error) {
|
||||
return nil, fmt.Errorf("failed to list documents: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result SimpleResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("list documents failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
result.Duration = resp.Duration
|
||||
|
||||
return &result, nil
|
||||
return HandleSimpleResponse(resp, "list documents")
|
||||
}
|
||||
|
||||
func (c *CLI) UserParseLocalFile(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
@@ -140,6 +140,8 @@ func (p *Parser) parseAPIListCommands() (*Command, error) {
|
||||
return p.parseAPIListChats()
|
||||
case TokenSearches:
|
||||
return p.parseAPIListSearches()
|
||||
case TokenMemories:
|
||||
return p.parseAPIListMemories()
|
||||
case TokenKeys:
|
||||
return p.parseAPIListAPIKeys()
|
||||
case TokenProviders:
|
||||
@@ -283,6 +285,17 @@ func (p *Parser) parseAPIListSearches() (*Command, error) {
|
||||
return NewCommand("api_list_searches"), nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseAPIListMemories() (*Command, error) {
|
||||
p.nextToken() // consume MEMORIES
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
return NewCommand("api_list_memories"), nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseGetMetadata() (*Command, error) {
|
||||
p.nextToken() // consume METADATA
|
||||
|
||||
@@ -1247,8 +1260,7 @@ func (p *Parser) parseAPISaveConfig() (*Command, error) {
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// CREATE DATASET 'abc' WITH EMBEDDING 'modelName@instanceName@providerName' PARSER 'parserType'
|
||||
// CREATE DATASET 'abc' WITH EMBEDDING 'modelName@instanceName@providerName' PIPELINE 'pipelineName'
|
||||
// CREATE DATASET 'abc';
|
||||
func (p *Parser) parseAPICreateDataset() (*Command, error) {
|
||||
p.nextToken() // consume DATASET
|
||||
datasetName, err := p.parseQuotedString()
|
||||
@@ -1256,52 +1268,13 @@ func (p *Parser) parseAPICreateDataset() (*Command, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p.nextToken()
|
||||
if p.curToken.Type != TokenWith {
|
||||
return nil, fmt.Errorf("expected WITH")
|
||||
}
|
||||
p.nextToken()
|
||||
if p.curToken.Type != TokenEmbedding {
|
||||
return nil, fmt.Errorf("expected EMBEDDING")
|
||||
}
|
||||
p.nextToken()
|
||||
|
||||
embedding, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p.nextToken()
|
||||
cmd := NewCommand("api_create_dataset")
|
||||
cmd.Params["dataset_name"] = datasetName
|
||||
cmd.Params["embedding"] = embedding
|
||||
|
||||
if p.curToken.Type == TokenParser {
|
||||
p.nextToken()
|
||||
var parserType string
|
||||
parserType, err = p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd.Params["parser_type"] = parserType
|
||||
p.nextToken()
|
||||
} else if p.curToken.Type == TokenPipeline {
|
||||
p.nextToken()
|
||||
var pipeline string
|
||||
pipeline, err = p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd.Params["pipeline"] = pipeline
|
||||
p.nextToken()
|
||||
} else {
|
||||
return nil, fmt.Errorf("expected PARSER or PIPELINE")
|
||||
}
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
cmd := NewCommand("api_create_dataset")
|
||||
cmd.Params["dataset_name"] = datasetName
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
@@ -1389,9 +1362,15 @@ func (p *Parser) parseAPIDropCommands() (*Command, error) {
|
||||
|
||||
switch p.curToken.Type {
|
||||
case TokenDataset:
|
||||
return p.parseDropDataset()
|
||||
return p.parseAPIDropDataset()
|
||||
case TokenChat:
|
||||
return p.parseDropChat()
|
||||
return p.parseAPIDropChat()
|
||||
case TokenSearch:
|
||||
return p.parseAPIDropSearch()
|
||||
case TokenMemory:
|
||||
return p.parseAPIDropMemory()
|
||||
case TokenAgent:
|
||||
return p.parseAPIDropAgent()
|
||||
case TokenKey:
|
||||
return p.parseAPIDeleteAPIKey()
|
||||
case TokenChunkStore:
|
||||
@@ -1529,16 +1508,52 @@ func (p *Parser) parseDeleteProvider() (*Command, error) {
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseDropDataset() (*Command, error) {
|
||||
func (p *Parser) parseAPIDropDataset() (*Command, error) {
|
||||
p.nextToken() // consume DATASET
|
||||
datasetName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.nextToken()
|
||||
|
||||
cmd := NewCommand("drop_user_dataset")
|
||||
cmd := NewCommand("api_drop_dataset")
|
||||
cmd.Params["dataset_name"] = datasetName
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseAPIDropSearch() (*Command, error) {
|
||||
p.nextToken() // consume SEARCH
|
||||
searchName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.nextToken()
|
||||
|
||||
cmd := NewCommand("api_drop_search")
|
||||
cmd.Params["search_name"] = searchName
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseAPIDropChat() (*Command, error) {
|
||||
p.nextToken() // consume CHAT
|
||||
chatName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cmd := NewCommand("api_drop_chat")
|
||||
cmd.Params["chat_name"] = chatName
|
||||
|
||||
p.nextToken()
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
@@ -1547,15 +1562,33 @@ func (p *Parser) parseDropDataset() (*Command, error) {
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseDropChat() (*Command, error) {
|
||||
p.nextToken() // consume CHAT
|
||||
chatName, err := p.parseQuotedString()
|
||||
func (p *Parser) parseAPIDropMemory() (*Command, error) {
|
||||
p.nextToken() // consume MEMORY
|
||||
memoryName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cmd := NewCommand("drop_user_chat")
|
||||
cmd.Params["chat_name"] = chatName
|
||||
cmd := NewCommand("api_drop_memory")
|
||||
cmd.Params["memory_name"] = memoryName
|
||||
|
||||
p.nextToken()
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseAPIDropAgent() (*Command, error) {
|
||||
p.nextToken() // consume AGENT
|
||||
agentName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cmd := NewCommand("api_drop_agent")
|
||||
cmd.Params["agent_name"] = agentName
|
||||
|
||||
p.nextToken()
|
||||
// Semicolon is optional
|
||||
|
||||
@@ -19,6 +19,14 @@ docker compose -f docker/docker-compose-base.yml up -d
|
||||
./build.sh --go
|
||||
```
|
||||
|
||||
- Production builds (strip debug symbols for smaller binaries):
|
||||
|
||||
```bash
|
||||
./build.sh --strip --all
|
||||
# or
|
||||
./build.sh -s --go
|
||||
```
|
||||
|
||||
> **Note**: If you use IDEs like GoLand to run/debug directly (via Run/Debug buttons), or run `go build` / `go run` from command line, you must set the following two CGO environment variables in your run configuration or shell:
|
||||
>
|
||||
> ```bash
|
||||
|
||||
@@ -2488,7 +2488,7 @@ func (s *DatasetService) CreateDataset(req *CreateDatasetRequest, tenantID strin
|
||||
kb.Language = language
|
||||
}
|
||||
|
||||
if err := s.kbDAO.Create(kb); err != nil {
|
||||
if err = s.kbDAO.Create(kb); err != nil {
|
||||
return nil, common.CodeServerError, errors.New("Failed to save dataset")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user