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
3 changes: 3 additions & 0 deletions .claude/settings.local.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"enableAllProjectMcpServers": false
}
15 changes: 12 additions & 3 deletions cmd/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,16 +155,26 @@ func toMessages(inputs []string) []client.NewMessage {

func addMessagesToContextCmd() *cobra.Command {
var id string
var name string
var messages []string
var files []string
cmd := &cobra.Command{
Use: "add",
Short: "Add messages to a given context",
Run: func(cmd *cobra.Command, args []string) {
if id == "" && name == "" {
exitIfError(errors.New("you should pass a context ID or a context name"))
}
c, err := client.New()
exitIfError(err)
ctx := context.Background()
messages := toMessages(messages)
if name != "" {
context, err := c.GetContextByName(ctx, name)
exitIfError(err)
id = context.ID
}

for _, input := range files {
role, path, found := strings.Cut(input, ":")
if !found {
Expand All @@ -188,9 +198,8 @@ func addMessagesToContextCmd() *cobra.Command {
printJson(*response)
},
}
cmd.PersistentFlags().StringVar(&id, "id", "", "The context ID")
err := cmd.MarkPersistentFlagRequired("id")
exitIfError(err)
cmd.PersistentFlags().StringVar(&id, "context-id", "", "The context ID")
cmd.PersistentFlags().StringVar(&name, "context-name", "", "The context name")
cmd.PersistentFlags().StringArrayVar(&messages, "message", []string{}, "Messages to add to this context. They should be prefixed by the role name (example: user:hello-world)")
cmd.PersistentFlags().StringArrayVar(&files, "message-from-file", []string{}, "A list of files paths, the content will be added to the context. They should be prefixed by the role name (example: user:/my/file)")
return cmd
Expand Down
3 changes: 3 additions & 0 deletions cmd/conversation.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func buildConversationCmd() *cobra.Command {
var ragModel string
var ragProvider string
var ragLimit uint32
var systemPromptID string
cmd := &cobra.Command{
Use: "conversation",
Short: `Send a message to an AI provider.
Expand Down Expand Up @@ -96,6 +97,7 @@ If a context ID is provided, it will be used as input for the conversation. Else
QueryOptions: options,
NewContextOptions: contextOptions,
Messages: msg,
SystemPromptID: systemPromptID,
}
if interactive {
input.Stream = stream
Expand Down Expand Up @@ -167,6 +169,7 @@ If a context ID is provided, it will be used as input for the conversation. Else
exitIfError(err)

cmd.PersistentFlags().StringVar(&system, "system", "", "System promt for the AI provider")
cmd.PersistentFlags().StringVar(&systemPromptID, "system-prompt-id", "", "ID of a system prompt to use (will be concatenated with --system if both are provided)")
cmd.PersistentFlags().StringVar(&contextID, "context-id", "", "The ID of the context to reuse for this conversation")
cmd.PersistentFlags().StringVar(&contextName, "context-name", "", "The name of the context to reuse for this conversation")
cmd.PersistentFlags().StringVar(&newContextName, "new-context-name", "", "The name of the new context that will be created for this conversation if a context ID is not provided")
Expand Down
10 changes: 10 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ func Run() error {
Use: "embedding",
Short: "Embedding commands",
}
systemPromptCmd := &cobra.Command{
Use: "system-prompt",
Short: "System prompt subcommands",
}
serverCmd := buildServerCmd()
embeddingCmd.AddCommand(embeddingMatchCmd())
documentCmd.AddCommand(documentListCmd())
Expand All @@ -103,13 +107,19 @@ func Run() error {
contextMessageCmd.AddCommand(deleteContextMessagesCmd())
contextSourceCmd.AddCommand(contextSourceContextDeleteCmd())
contextSourceCmd.AddCommand(contextSourceContextAddCmd())
systemPromptCmd.AddCommand(systemPromptListCmd())
systemPromptCmd.AddCommand(systemPromptGetCmd())
systemPromptCmd.AddCommand(systemPromptCreateCmd())
systemPromptCmd.AddCommand(systemPromptUpdateCmd())
systemPromptCmd.AddCommand(systemPromptDeleteCmd())

conversationCmd := buildConversationCmd()
rootCmd.AddCommand(embeddingCmd)
rootCmd.AddCommand(documentCmd)
rootCmd.AddCommand(documentChunkCmd)
rootCmd.AddCommand(conversationCmd)
rootCmd.AddCommand(contextCmd)
rootCmd.AddCommand(systemPromptCmd)
rootCmd.AddCommand(serverCmd)
shutdown, err := initOpentelemetry()
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func RunServer() error {
rag := rag.New(db, embeddingProviders)
ai := assistant.New(clients, manager, rag)

handlersBuilder := handlers.NewBuilder(ai, manager, rag)
handlersBuilder := handlers.NewBuilder(ai, manager, rag, db)
server, err := http.New(config.HTTP, registry, handlersBuilder)
if err != nil {
return err
Expand Down
160 changes: 160 additions & 0 deletions cmd/system.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
package cmd

import (
"context"
"errors"
"os"

"github.com/appclacks/maizai/internal/http/client"
"github.com/spf13/cobra"
)

func systemPromptListCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "list",
Short: "List system prompts",
Run: func(cmd *cobra.Command, args []string) {
client, err := client.New()
exitIfError(err)
ctx := context.Background()
prompts, err := client.ListSystemPrompts(ctx)
exitIfError(err)
printJson(prompts)
},
}
return cmd
}

func systemPromptGetCmd() *cobra.Command {
var id string
cmd := &cobra.Command{
Use: "get",
Short: "Get a system prompt by ID",
Run: func(cmd *cobra.Command, args []string) {
if id == "" {
exitIfError(errors.New("the command expects a system prompt id as input"))
}
client, err := client.New()
exitIfError(err)
ctx := context.Background()
prompt, err := client.GetSystemPrompt(ctx, id)
exitIfError(err)
printJson(*prompt)
},
}
cmd.PersistentFlags().StringVar(&id, "id", "", "The ID of the system prompt to retrieve")
err := cmd.MarkPersistentFlagRequired("id")
exitIfError(err)
return cmd
}

func systemPromptCreateCmd() *cobra.Command {
var name string
var description string
var content string
var contentFile string
cmd := &cobra.Command{
Use: "create",
Short: "Create a new system prompt",
Run: func(cmd *cobra.Command, args []string) {
if content == "" && contentFile == "" {
exitIfError(errors.New("either --content or --content-from-file must be provided"))
}
if content != "" && contentFile != "" {
exitIfError(errors.New("cannot specify both --content and --content-from-file"))
}

finalContent := content
if contentFile != "" {
fileContent, err := os.ReadFile(contentFile)
if err != nil {
exitIfError(err)
}
finalContent = string(fileContent)
}

c, err := client.New()
exitIfError(err)
ctx := context.Background()
input := client.CreateSystemPromptInput{
Name: name,
Description: description,
Content: finalContent,
}
response, err := c.CreateSystemPrompt(ctx, input)
exitIfError(err)
printJson(*response)
},
}
cmd.PersistentFlags().StringVar(&name, "name", "", "The name of the new system prompt")
err := cmd.MarkPersistentFlagRequired("name")
exitIfError(err)
cmd.PersistentFlags().StringVar(&description, "description", "", "The description of the new system prompt")
cmd.PersistentFlags().StringVar(&content, "content", "", "The content of the system prompt")
cmd.PersistentFlags().StringVar(&contentFile, "content-from-file", "", "Path to file containing the system prompt content")
return cmd
}

func systemPromptUpdateCmd() *cobra.Command {
var id string
var content string
var contentFile string
cmd := &cobra.Command{
Use: "update",
Short: "Update a system prompt's content",
Run: func(cmd *cobra.Command, args []string) {
if content == "" && contentFile == "" {
exitIfError(errors.New("either --content or --content-from-file must be provided"))
}
if content != "" && contentFile != "" {
exitIfError(errors.New("cannot specify both --content and --content-from-file"))
}

finalContent := content
if contentFile != "" {
fileContent, err := os.ReadFile(contentFile)
if err != nil {
exitIfError(err)
}
finalContent = string(fileContent)
}

c, err := client.New()
exitIfError(err)
ctx := context.Background()
input := client.UpdateSystemPromptInput{
ID: id,
Content: finalContent,
}
response, err := c.UpdateSystemPrompt(ctx, input)
exitIfError(err)
printJson(*response)
},
}
cmd.PersistentFlags().StringVar(&id, "id", "", "The ID of the system prompt to update")
err := cmd.MarkPersistentFlagRequired("id")
exitIfError(err)
cmd.PersistentFlags().StringVar(&content, "content", "", "The new content for the system prompt")
cmd.PersistentFlags().StringVar(&contentFile, "content-from-file", "", "Path to file containing the new system prompt content")
return cmd
}

func systemPromptDeleteCmd() *cobra.Command {
var id string
cmd := &cobra.Command{
Use: "delete",
Short: "Delete a system prompt by ID",
Run: func(cmd *cobra.Command, args []string) {
client, err := client.New()
exitIfError(err)
ctx := context.Background()
response, err := client.DeleteSystemPrompt(ctx, id)
exitIfError(err)
printJson(*response)
},
}
cmd.PersistentFlags().StringVar(&id, "id", "", "The ID of the system prompt to delete")
err := cmd.MarkPersistentFlagRequired("id")
exitIfError(err)
return cmd
}
Loading