Skip to content

Commit

Permalink
🎨 Improve structure / format of the code: add ModelNotFoundError
Browse files Browse the repository at this point in the history
  • Loading branch information
k33g committed Feb 8, 2025
1 parent 3afa6ee commit 439e3b1
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 20 deletions.
43 changes: 39 additions & 4 deletions LAST_RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,45 @@
## v0.2.4 🥮 [mooncake]
> Release in progress 🚧
- Improving the RAG example with Elasticsearch: `40-rag-with-elastic-markdown`
- New examples:
- Structured output: `66-structured-outputs`
- Experiments with Hypothetical Document Embeddings (HyDE): `65-hyde` (🚧 this is a work in progress)
### RAG

Improving the RAG example with Elasticsearch: `40-rag-with-elastic-markdown` (🙏 Thank you [@codefromthecrypt](https://github.com/codefromthecrypt))

### New examples:

- Structured output: `66-structured-outputs`
- Experiments with Hypothetical Document Embeddings (HyDE): `65-hyde` (🚧 this is a work in progress)

### Error management

#### ModelNotFoundError

```golang
// package completion
type ModelNotFoundError struct {
Code int
Message string
Model string
}
```

**Usage**:
```golang
answer, err := completion.Chat(ollamaUrl, query)
if err != nil {
// test if the model is not found
if modelErr, ok := err.(*completion.ModelNotFoundError); ok {
fmt.Printf("💥 Got Model Not Found error: %s\n", modelErr.Message)
fmt.Printf("😡 Error code: %d\n", modelErr.Code)
fmt.Printf("🧠 Expected Model: %s\n", modelErr.Model)
} else {
log.Fatal("😡:", err)
}
}
```
> See these examples: `04-chat-stream` and `66-structured-outputs`
### MCP


## v0.2.3 🥧 [pie]
Expand Down
52 changes: 46 additions & 6 deletions completion/chat-completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,33 @@ import (
"fmt"
"io"
"net/http"
"strings"

"github.com/parakeet-nest/parakeet/llm"
)

type ModelNotFoundError struct {
Code int
Message string
Model string
}

func (e *ModelNotFoundError) Error() string {
return fmt.Sprintf("Code: %d, Message: %s, Model: %s", e.Code, e.Message, e.Model)
}

type CompletionError struct {
Error string
}

func Chat(url string, query llm.Query) (llm.Answer, error) {
kindOfCompletion := "chat"

/*
var outputSchema = ""
if query.Format != "" && query.Format != "json" {
outputSchema = query.Format
}
var outputSchema = ""
if query.Format != "" && query.Format != "json" {
outputSchema = query.Format
}
*/

query.Stream = false
Expand All @@ -39,8 +54,6 @@ func Chat(url string, query llm.Query) (llm.Answer, error) {
return llm.Answer{}, err
}

//fmt.Println("🔴 jsonQuery", string(jsonQuery))

req, err := http.NewRequest(http.MethodPost, url+"/api/"+kindOfCompletion, bytes.NewBuffer(jsonQuery))
if err != nil {
return llm.Answer{}, err
Expand All @@ -67,7 +80,24 @@ func Chat(url string, query llm.Query) (llm.Answer, error) {
// we need to create a new error because
// because, even if the status is not ok (ex 401 Unauthorized)
// the error == nil

if resp.StatusCode == http.StatusNotFound {
var completionError CompletionError
var modelNotFound ModelNotFoundError
err = json.Unmarshal(body, &completionError)
if err != nil {
return llm.Answer{}, err
}
if strings.HasPrefix(completionError.Error, "model") && strings.HasSuffix(completionError.Error, "not found, try pulling it first") {
modelNotFound.Code = resp.StatusCode
modelNotFound.Message = completionError.Error
modelNotFound.Model = query.Model
}
return llm.Answer{}, &modelNotFound
}

return llm.Answer{}, errors.New("Error: status code: " + resp.Status + "\n" + string(body))

}

var answer llm.Answer
Expand Down Expand Up @@ -175,6 +205,16 @@ func ChatStream(url string, query llm.Query, onChunk func(llm.Answer) error) (ll
}

if resp.StatusCode != http.StatusOK {
if resp.StatusCode == http.StatusNotFound {
var modelNotFound ModelNotFoundError

modelNotFound.Code = resp.StatusCode
modelNotFound.Message = "model " + query.Model + " not found, try pulling it first"
modelNotFound.Model = query.Model

return llm.Answer{}, &modelNotFound
}

return llm.Answer{}, errors.New("Error: status code: " + resp.Status)
} else {
return fullAnswer, nil
Expand Down
21 changes: 13 additions & 8 deletions examples/04-chat-stream/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ import (
"log"

"github.com/parakeet-nest/parakeet/completion"
"github.com/parakeet-nest/parakeet/llm"
"github.com/parakeet-nest/parakeet/enums/option"

"github.com/parakeet-nest/parakeet/llm"
)

func main() {
Expand All @@ -31,13 +30,12 @@ func main() {
And, please, be structured with bullet points`

options := llm.SetOptions(map[string]interface{}{
option.Temperature: 0.5,
option.RepeatLastN: 2,
option.Temperature: 0.5,
option.RepeatLastN: 2,
option.RepeatPenalty: 3.0,
option.Verbose: true,
option.Verbose: false,
})


query := llm.Query{
Model: model,
Messages: []llm.Message{
Expand All @@ -52,12 +50,19 @@ func main() {
fmt.Print(answer.Message.Content)
return nil
})

fmt.Println("📝 Full answer:")
fmt.Println(fullAnswer.Message.Role)
fmt.Println(fullAnswer.Message.Content)

if err != nil {
log.Fatal("😡:", err)
// test if the model is not found
if modelErr, ok := err.(*completion.ModelNotFoundError); ok {
fmt.Printf("💥 Got Model Not Found error: %s\n", modelErr.Message)
fmt.Printf("😡 Error code: %d\n", modelErr.Code)
fmt.Printf("🧠 Expected Model: %s\n", modelErr.Model)
} else {
log.Fatal("😡:", err)
}
}
}
2 changes: 1 addition & 1 deletion examples/66-structured-outputs/.env
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# if working from a container
#OLLAMA_HOST=http://host.docker.internal:11434
OLLAMA_HOST=http://localhost:11434
LLM=qwen2.5:1.5b
LLM_CHAT=qwen2.5:1.5b

9 changes: 8 additions & 1 deletion examples/66-structured-outputs/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,14 @@ func main() {

answer, err := completion.Chat(ollamaUrl, query)
if err != nil {
log.Fatal("😡:", err)
// test if the model is not found
if modelErr, ok := err.(*completion.ModelNotFoundError); ok {
fmt.Printf("💥 Got Model Not Found error: %s\n", modelErr.Message)
fmt.Printf("😡 Error code: %d\n", modelErr.Code)
fmt.Printf("🧠 Expected Model: %s\n", modelErr.Model)
} else {
log.Fatal("😡:", err)
}
}
fmt.Println(answer.Message.Content)

Expand Down

0 comments on commit 439e3b1

Please sign in to comment.