mirror of
https://github.com/ollama/ollama.git
synced 2025-11-11 17:37:11 +01:00
* app: add code for macOS and Windows apps under 'app' * app: add readme * app: windows and linux only for now * ci: fix ui CI validation --------- Co-authored-by: jmorganca <jmorganca@gmail.com>
144 lines
4.0 KiB
Go
144 lines
4.0 KiB
Go
//go:build windows || darwin
|
|
|
|
package tools
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
// WebSearchContent represents the content of a search result
|
|
type WebSearchContent struct {
|
|
Snippet string `json:"snippet"`
|
|
FullText string `json:"full_text"`
|
|
}
|
|
|
|
// WebSearchMetadata represents metadata for a search result
|
|
type WebSearchMetadata struct {
|
|
PublishedDate *time.Time `json:"published_date,omitempty"`
|
|
}
|
|
|
|
// WebSearchResult represents a single search result
|
|
type WebSearchResult struct {
|
|
Title string `json:"title"`
|
|
URL string `json:"url"`
|
|
Content WebSearchContent `json:"content"`
|
|
Metadata WebSearchMetadata `json:"metadata"`
|
|
}
|
|
|
|
// WebSearchResponse represents the complete response from the websearch API
|
|
type WebSearchResponse struct {
|
|
Results map[string][]WebSearchResult `json:"results"`
|
|
}
|
|
|
|
// BrowserWebSearch tool for searching the web using ollama.com search API
|
|
type BrowserWebSearch struct{}
|
|
|
|
func (w *BrowserWebSearch) Name() string {
|
|
return "gpt_oss_web_search"
|
|
}
|
|
|
|
func (w *BrowserWebSearch) Description() string {
|
|
return "Search the web for real-time information using ollama.com search API."
|
|
}
|
|
|
|
func (w *BrowserWebSearch) Prompt() string {
|
|
return `Use the gpt_oss_web_search tool to search the web.
|
|
1. Come up with a list of search queries to get comprehensive information (typically 2-3 related queries work well)
|
|
2. Use the gpt_oss_web_search tool with multiple queries to get results organized by query
|
|
3. Use the search results to provide current up to date, accurate information
|
|
|
|
Today's date is ` + time.Now().Format("January 2, 2006") + `
|
|
Add "` + time.Now().Format("January 2, 2006") + `" for news queries and ` + strconv.Itoa(time.Now().Year()+1) + ` for other queries that need current information.`
|
|
}
|
|
|
|
func (w *BrowserWebSearch) Schema() map[string]any {
|
|
schemaBytes := []byte(`{
|
|
"type": "object",
|
|
"properties": {
|
|
"queries": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"description": "List of search queries to look up"
|
|
},
|
|
"max_results": {
|
|
"type": "integer",
|
|
"description": "Maximum number of results to return per query (default: 2) up to 5",
|
|
"default": 2
|
|
}
|
|
},
|
|
"required": ["queries"]
|
|
}`)
|
|
var schema map[string]any
|
|
if err := json.Unmarshal(schemaBytes, &schema); err != nil {
|
|
return nil
|
|
}
|
|
return schema
|
|
}
|
|
|
|
func (w *BrowserWebSearch) Execute(ctx context.Context, args map[string]any) (any, error) {
|
|
queriesRaw, ok := args["queries"].([]any)
|
|
if !ok {
|
|
return nil, fmt.Errorf("queries parameter is required and must be an array of strings")
|
|
}
|
|
|
|
queries := make([]string, 0, len(queriesRaw))
|
|
for _, q := range queriesRaw {
|
|
if query, ok := q.(string); ok {
|
|
queries = append(queries, query)
|
|
}
|
|
}
|
|
|
|
if len(queries) == 0 {
|
|
return nil, fmt.Errorf("at least one query is required")
|
|
}
|
|
|
|
maxResults := 5
|
|
if mr, ok := args["max_results"].(int); ok {
|
|
maxResults = mr
|
|
}
|
|
|
|
return w.performWebSearch(ctx, queries, maxResults)
|
|
}
|
|
|
|
// performWebSearch handles the actual HTTP request to ollama.com search API
|
|
func (w *BrowserWebSearch) performWebSearch(ctx context.Context, queries []string, maxResults int) (*WebSearchResponse, error) {
|
|
response := &WebSearchResponse{Results: make(map[string][]WebSearchResult, len(queries))}
|
|
|
|
for _, query := range queries {
|
|
searchResp, err := performWebSearch(ctx, query, maxResults)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("web_search failed for %q: %w", query, err)
|
|
}
|
|
|
|
converted := make([]WebSearchResult, 0, len(searchResp.Results))
|
|
for _, item := range searchResp.Results {
|
|
converted = append(converted, WebSearchResult{
|
|
Title: item.Title,
|
|
URL: item.URL,
|
|
Content: WebSearchContent{
|
|
Snippet: truncateString(item.Content, 400),
|
|
FullText: item.Content,
|
|
},
|
|
Metadata: WebSearchMetadata{},
|
|
})
|
|
}
|
|
|
|
response.Results[query] = converted
|
|
}
|
|
|
|
return response, nil
|
|
}
|
|
|
|
func truncateString(input string, limit int) string {
|
|
if limit <= 0 || len(input) <= limit {
|
|
return input
|
|
}
|
|
return input[:limit]
|
|
}
|