Files
OpenViking/sdk/go/retrieval.go
T
Hao Zheandzhiheng.liu 797406c381 fix(sdk): consolidate model, client, and evaluation correctness (#3550)
* fix(models): route multimodal inputs to DashScope embed_content

Sweep findings: A-09. Preserve image parts through the shared embedding entrypoints.

(cherry picked from commit 50b20d7ca9)

* fix(models): constrain DashScope multimodal routing

Sweep findings: A-09. Preserve text mode and require a single fused vector for multipart input.

(cherry picked from commit 77784429d4)

* fix(models): respect DashScope Qwen fusion parameters

Sweep finding A-09

(cherry picked from commit aafc702b20)

* fix(review): preserve tongyi multipart compatibility

Addresses blocking review finding on #3400.

(cherry picked from commit 96844047c5)

* fix(eval): flush queued records on stop and adapt RAG pipeline to FindResult

Sweep findings: B-05, B-12. Drain recorder queues through the sentinel and consume current retrieval result objects.

(cherry picked from commit fecdbeb6d4)

* fix(sdk/python): support sync client inside a running event loop

Sweep findings: F-09. Run sync wrappers on one persistent worker loop with result and exception propagation.

(cherry picked from commit ba0faadc87)

* fix(sdk/python): preserve cancellation and fork safety

Sweep finding: F-09. Preserve original cancellation errors and reset worker synchronization after fork.

(cherry picked from commit a19e3c95e9)

* feat(sdk/go): add tags filter and relations API for parity

Sweep findings: F-11, F-12. Expose existing server capabilities consistently to Go callers.

(cherry picked from commit 8af0c2cb36)

* fix(sdk/python): runnable quickstarts, correct migrate payload, explicit timeout precedence

Sweep findings: F-01, F-02, F-14. Initialize documented clients and preserve Python SDK request/config semantics.

(cherry picked from commit d9a64f5665)

---------

Co-authored-by: zhiheng.liu <zhiheng.liu@bytedance.com>
2026-07-28 18:11:30 +08:00

134 lines
3.7 KiB
Go

package openviking
import (
"context"
"net/http"
)
// Find performs semantic search without session context.
func (c *Client) Find(ctx context.Context, queryText string, opts *FindOptions) (*FindResult, error) {
if opts == nil {
opts = &FindOptions{}
}
limit := opts.Limit
if limit == 0 {
limit = 10
}
actualLimit := limit
if opts.NodeLimit != nil {
actualLimit = *opts.NodeLimit
}
imageURL, err := normalizeImageInput(opts.Image)
if err != nil {
return nil, err
}
payload := map[string]any{
"query": queryText,
"target_uri": normalizeTarget(opts.TargetURI),
"limit": actualLimit,
}
setString(payload, "image_url", imageURL)
setAny(payload, "score_threshold", opts.ScoreThreshold)
setAny(payload, "filter", opts.Filter)
setAny(payload, "context_type", opts.ContextType)
setString(payload, "since", opts.Since)
setString(payload, "until", opts.Until)
setString(payload, "time_field", opts.TimeField)
if len(opts.Level) > 0 {
payload["level"] = opts.Level
}
if len(opts.Tags) > 0 {
payload["tags"] = opts.Tags
}
setAny(payload, "telemetry", opts.Telemetry)
var result FindResult
err = c.doJSON(ctx, http.MethodPost, "/api/v1/search/find", nil, payload, &result)
return &result, err
}
// Search performs semantic search with optional session context.
func (c *Client) Search(ctx context.Context, queryText string, opts *SearchOptions) (*FindResult, error) {
if opts == nil {
opts = &SearchOptions{}
}
limit := opts.Limit
if limit == 0 {
limit = 10
}
actualLimit := limit
if opts.NodeLimit != nil {
actualLimit = *opts.NodeLimit
}
imageURL, err := normalizeImageInput(opts.Image)
if err != nil {
return nil, err
}
payload := map[string]any{
"query": queryText,
"target_uri": normalizeTarget(opts.TargetURI),
"limit": actualLimit,
}
setString(payload, "image_url", imageURL)
setString(payload, "session_id", opts.SessionID)
setAny(payload, "score_threshold", opts.ScoreThreshold)
setAny(payload, "filter", opts.Filter)
setAny(payload, "context_type", opts.ContextType)
setString(payload, "since", opts.Since)
setString(payload, "until", opts.Until)
setString(payload, "time_field", opts.TimeField)
if len(opts.Level) > 0 {
payload["level"] = opts.Level
}
if len(opts.Tags) > 0 {
payload["tags"] = opts.Tags
}
setAny(payload, "telemetry", opts.Telemetry)
var result FindResult
err = c.doJSON(ctx, http.MethodPost, "/api/v1/search/search", nil, payload, &result)
return &result, err
}
// Grep searches file content by pattern.
func (c *Client) Grep(ctx context.Context, uri, pattern string, opts *GrepOptions) (map[string]any, error) {
if opts == nil {
opts = &GrepOptions{}
}
payload := map[string]any{
"uri": NormalizeURI(uri),
"pattern": pattern,
"case_insensitive": opts.CaseInsensitive,
}
if opts.NodeLimit != nil {
payload["node_limit"] = *opts.NodeLimit
}
if opts.LevelLimit != nil {
payload["level_limit"] = *opts.LevelLimit
}
if opts.ExcludeURI != "" {
payload["exclude_uri"] = NormalizeURI(opts.ExcludeURI)
}
var result map[string]any
err := c.doJSON(ctx, http.MethodPost, "/api/v1/search/grep", nil, payload, &result)
return result, err
}
// Glob finds files by glob pattern.
func (c *Client) Glob(ctx context.Context, pattern string, uri string, opts *GlobOptions) (map[string]any, error) {
if opts == nil {
opts = &GlobOptions{}
}
if uri == "" {
uri = "viking://"
}
payload := map[string]any{
"pattern": pattern,
"uri": NormalizeURI(uri),
}
if opts.NodeLimit != nil {
payload["node_limit"] = *opts.NodeLimit
}
var result map[string]any
err := c.doJSON(ctx, http.MethodPost, "/api/v1/search/glob", nil, payload, &result)
return result, err
}