Files
kb/client/cmd/addnote.go
T

111 lines
2.8 KiB
Go

package cmd
import (
"fmt"
"net/http"
"os"
"time"
"github.com/kb-search/kb/internal/api"
"github.com/kb-search/kb/internal/output"
"github.com/spf13/cobra"
)
var addnoteCmd = &cobra.Command{
Use: "addnote <text>",
Short: "Add a text note to the knowledge base",
Args: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
return fmt.Errorf("requires a note text argument\n\n Usage: kb addnote \"your note text here\"")
}
if len(args) > 1 {
return fmt.Errorf("accepts 1 arg but received %d — quote your note text, e.g. kb addnote \"your note text here\"", len(args))
}
return nil
},
RunE: runAddnote,
}
func init() {
addnoteCmd.Flags().String("tags", "", "tags (comma-separated)")
addnoteCmd.Flags().Bool("wait", false, "wait for ingestion to finish")
addnoteCmd.Flags().Duration("wait-timeout", 10*time.Minute, "maximum time to wait for ingestion")
rootCmd.AddCommand(addnoteCmd)
}
func runAddnote(cmd *cobra.Command, args []string) error {
tags, _ := cmd.Flags().GetString("tags")
wait, _ := cmd.Flags().GetBool("wait")
timeout, _ := cmd.Flags().GetDuration("wait-timeout")
client := api.NewClient()
return submitNote(client, args[0], tags, wait, timeout)
}
func submitNote(client *api.Client, note, tags string, wait bool, timeout time.Duration) error {
fields := map[string]string{
"note": note,
}
if tags != "" {
fields["tags"] = tags
}
resp, err := client.PostMultipart("/api/v1/jobs", fields, nil)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
if resp.StatusCode == http.StatusConflict {
var result interface{}
if err := api.DecodeJSON(resp, &result); err != nil {
return fmt.Errorf("failed to decode response: %w", err)
}
if output.IsJSON() {
output.PrintJSON(result)
} else {
if m, ok := result.(map[string]interface{}); ok {
if docID, ok := m["document_id"].(float64); ok {
fmt.Printf("Already imported: %s (doc ID: %.0f)\n", m["title"], docID)
} else if jobID, ok := m["job_id"].(float64); ok {
fmt.Printf("Already queued: %s (job ID: %.0f)\n", m["title"], jobID)
}
}
}
return nil
}
if err := api.CheckError(resp); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
var result struct {
JobID int `json:"job_id"`
Status string `json:"status"`
Filename string `json:"filename"`
}
if err := api.DecodeJSON(resp, &result); err != nil {
return fmt.Errorf("failed to decode response: %w", err)
}
if output.IsJSON() {
if !wait {
output.PrintJSON(result)
}
} else {
fmt.Println("Queued: note")
}
if wait {
job, err := waitForJob(client, result.JobID, timeout)
if err != nil {
return err
}
if output.IsJSON() {
output.PrintJSON(job)
} else {
fmt.Printf("Ingested: note (doc ID: %d, chunks: %d)\n", job.DocumentID, job.ChunkCount)
}
}
return nil
}