mirror of
https://github.com/volcengine/OpenViking.git
synced 2026-09-30 17:28:07 +08:00
* fix(models): route multimodal inputs to DashScope embed_content Sweep findings: A-09. Preserve image parts through the shared embedding entrypoints. (cherry picked from commit50b20d7ca9) * 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 commit77784429d4) * fix(models): respect DashScope Qwen fusion parameters Sweep finding A-09 (cherry picked from commitaafc702b20) * fix(review): preserve tongyi multipart compatibility Addresses blocking review finding on #3400. (cherry picked from commit96844047c5) * 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 commitfecdbeb6d4) * 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 commitba0faadc87) * 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 commita19e3c95e9) * 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 commit8af0c2cb36) * 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 commitd9a64f5665) --------- Co-authored-by: zhiheng.liu <zhiheng.liu@bytedance.com>
134 lines
3.7 KiB
Go
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
|
|
}
|