Files
Yeuoly 888ad788bc refactor: plugin lifecycle control panel (#499)
* refactor: introduce local plugin control panel and cleanup environment setup process

* fix: args

* refactor: new local runtime

* temp: stash work for refactor on RemotePluginServer

* refactor: unify local runtime lifetime and sperate init environment process

* chore: add missing files

* stash

* refactor: local plugin lifetime control

* refactor: complete installation process of control panel

* refactor: adapt service layer to new controlpanel

* refactor: pluginManager.Install

* fix: add routine wrap to InstallServerless, avoid blocking main thread

* feat: reinstall serverless runtime

* chore: add comments to Reinstall and update confusing naming

* refactor: unify install plugin service

* refactor: add labels to debugging runtime

* refactor: add getters to plugin manager

* refactor: split install service to decode/install_task/install service

* ???

* refactor: adapt controllers

* refactor: session write

* refactor: session runtime

* Refine install task orchestration (#501)

* refactor: installing task

* refactor cluster management, decouple lifetime management and cluster

* fix cli test command

* fix: cleanup TODO comments and implement GracefulStop for instance

* feat: add logger to control panel

* fix: multiple nil references

* refactor: better lifetime control

* refactor: better cycle interval

* fix(LocalPluginRuntime): prevent returning err when it's not  error

* fix: avoid adding empty PipExtraArgs

* fix: missing errors in Environment init

* fix: add truncateMessage to avoid db explosion

* cleanup: better lifecycle management

* fix: init status at the beginning of installation

* optimize: GracefulStop for pluginInstance

* refactor: tests

* refactor: centralize routine labels (#504)

* cleanup: RoutineKey

* fix: init routine pool

* fix: correctly handle cluster register error

* fix: memory leak

* fix: add \n to instance write

* fix(installer.go): set success to true after succeed for defer func

* refactor

* fix: missing cwd in testutils

* fix: scaleup default runtime nums to 1 when testing

* fix: localruntime appconfig in testing module

* Update internal/core/local_runtime/load_balancing.go

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* fix: more efficiency implement in installer_local.go

* fix: returns after failing in onDebuggingRuntimeDisconnected

* fix: returns after failing in onDebuggingRuntimeDisconnected

* fix: splits tests

* refactor: naming

* refactor: manifest.VersionX

* fix: adapt SetDefault to tests

* fix: enforce use constants in DBType

* fix: generate

* fix: linter

* cleanup tests

* refactor: change  package to

* cleanup: useless codes

* Update internal/cluster/plugin.go

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* cleanup

* refactor: decouple connection_key management from debugging_time

* refactor: confused naming

* feat: recycle resources to adapt to https://github.com/langgenius/dify-plugin-daemon/pull/500

* refactor: confusing redirecting

* fix: support get serverless runtime

* fix: race condition in Launching

* fix: avoid ManifestValidate in first step of debugging handshake

* fix: adding ReleaseAllLocks to finalizers

* wtf: what a beautiful code

* refactor: rename Stream.Async to Stream.Process

* fix: kill process if daed instance was detected

* fix: correctly handle failures

* fix: consistence of difference interfaces

* fix: add stacktrace to panic

* fix: only trigger once  event

* fix: ensure plugin runtime was shutdown

* feat: cleanup install tasks

* fix: add scale logs

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-11-18 17:28:02 +08:00

1178 lines
22 KiB
Go

package plugin_entities
import (
"strings"
"testing"
"github.com/langgenius/dify-plugin-daemon/pkg/utils/parser"
)
func TestFullFunctionToolProvider_Validate(t *testing.T) {
const json_data = `
{
"identity": {
"author": "author",
"name": "name",
"description": {
"en_US": "description",
"zh_Hans": "描述",
"pt_BR": "descrição"
},
"icon": "icon",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
},
"tags": [
"image",
"videos"
]
},
"credentials_schema": [
{
"name": "api_key",
"type": "secret-input",
"required": false,
"default": "default",
"label": {
"en_US": "API Key",
"zh_Hans": "API 密钥",
"pt_BR": "Chave da API"
},
"help": {
"en_US": "API Key",
"zh_Hans": "API 密钥",
"pt_BR": "Chave da API"
},
"url": "https://example.com",
"placeholder": {
"en_US": "API Key",
"zh_Hans": "API 密钥",
"pt_BR": "Chave da API"
}
}
],
"tools": [
{
"identity": {
"author": "author",
"name": "tool",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
}
},
"description": {
"human": {
"en_US": "description",
"zh_Hans": "描述",
"pt_BR": "descrição"
},
"llm": "description"
},
"parameters": [
{
"name": "parameter",
"type": "string",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
},
"human_description": {
"en_US": "description",
"zh_Hans": "描述",
"pt_BR": "descrição"
},
"form": "llm",
"required": true,
"default": "default",
"options": [
{
"value": "value",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
}
}
]
}
]
}
]
}
`
const yaml_data = `identity:
author: author
name: name
description:
en_US: description
zh_Hans: 描述
pt_BR: descrição
icon: icon
label:
en_US: label
zh_Hans: 标签
pt_BR: etiqueta
tags:
- image
- videos
credentials_schema:
- name: api_key
type: secret-input
required: false
default: default
label:
en_US: API Key
zh_Hans: API 密钥
pt_BR: Chave da API
help:
en_US: API Key
zh_Hans: API 密钥
pt_BR: Chave da API
url: https://example.com
placeholder:
en_US: API Key
zh_Hans: API 密钥
pt_BR: Chave da API
tools:
- identity:
author: author
name: tool
label:
en_US: label
zh_Hans: 标签
pt_BR: etiqueta
description:
human:
en_US: description
zh_Hans: 描述
pt_BR: descrição
llm: description
parameters:
- name: parameter
type: string
label:
en_US: label
zh_Hans: 标签
pt_BR: etiqueta
human_description:
en_US: description
zh_Hans: 描述
pt_BR: descrição
form: llm
required: true
default: default
options:
- value: value
label:
en_US: label
zh_Hans: 标签
pt_BR: etiqueta
`
jsonDeclaration, jsonErr := parser.UnmarshalJsonBytes[ToolProviderDeclaration]([]byte(json_data))
if jsonErr != nil {
t.Errorf("UnmarshalToolProviderConfiguration() error for JSON = %v", jsonErr)
return
}
if len(jsonDeclaration.CredentialsSchema) != 1 {
t.Errorf("UnmarshalToolProviderConfiguration() error for JSON: incorrect CredentialsSchema length")
return
}
yamlDeclaration, yamlErr := parser.UnmarshalYamlBytes[ToolProviderDeclaration]([]byte(yaml_data))
if yamlErr != nil {
t.Errorf("UnmarshalToolProviderConfiguration() error for YAML = %v", yamlErr)
return
}
if len(yamlDeclaration.CredentialsSchema) != 1 {
t.Errorf("UnmarshalToolProviderConfiguration() error for YAML: incorrect CredentialsSchema length")
return
}
}
func TestToolProviderWithMapCredentials_Validate(t *testing.T) {
const json_data = `
{
"identity": {
"author": "author",
"name": "name",
"description": {
"en_US": "description",
"zh_Hans": "描述",
"pt_BR": "descrição"
},
"icon": "icon",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
},
"tags": [
"image",
"videos"
]
},
"credentials_schema": {
"api_key": {
"type": "secret-input",
"required": false,
"default": "default",
"label": {
"en_US": "API Key",
"zh_Hans": "API 密钥",
"pt_BR": "Chave da API"
},
"help": {
"en_US": "API Key",
"zh_Hans": "API 密钥",
"pt_BR": "Chave da API"
},
"url": "https://example.com",
"placeholder": {
"en_US": "API Key",
"zh_Hans": "API 密钥",
"pt_BR": "Chave da API"
}
}
},
"tools": [
{
"identity": {
"author": "author",
"name": "tool",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
}
},
"description": {
"human": {
"en_US": "description",
"zh_Hans": "描述",
"pt_BR": "descrição"
},
"llm": "description"
},
"parameters": [
{
"name": "parameter",
"type": "string",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
},
"human_description": {
"en_US": "description",
"zh_Hans": "描述",
"pt_BR": "descrição"
},
"form": "llm",
"required": true,
"default": "default",
"options": [
{
"value": "value",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
}
}
]
}
]
}
]
}
`
const yaml_data = `identity:
author: author
name: name
description:
en_US: description
zh_Hans: 描述
pt_BR: descrição
icon: icon
label:
en_US: label
zh_Hans: 标签
pt_BR: etiqueta
tags:
- image
- videos
credentials_schema:
api_key:
type: secret-input
required: false
default: default
label:
en_US: API Key
zh_Hans: API 密钥
pt_BR: Chave da API
help:
en_US: API Key
zh_Hans: API 密钥
pt_BR: Chave da API
url: https://example.com
placeholder:
en_US: API Key
zh_Hans: API 密钥
pt_BR: Chave da API
tools:
- identity:
author: author
name: tool
label:
en_US: label
zh_Hans: 标签
pt_BR: etiqueta
description:
human:
en_US: description
zh_Hans: 描述
pt_BR: descrição
llm: description
parameters:
- name: parameter
type: string
label:
en_US: label
zh_Hans: 标签
pt_BR: etiqueta
human_description:
en_US: description
zh_Hans: 描述
pt_BR: descrição
form: llm
required: true
default: default
options:
- value: value
label:
en_US: label
zh_Hans: 标签
pt_BR: etiqueta
`
jsonDeclaration, jsonErr := parser.UnmarshalJsonBytes[ToolProviderDeclaration]([]byte(json_data))
if jsonErr != nil {
t.Errorf("UnmarshalToolProviderConfiguration() error for JSON = %v", jsonErr)
return
}
if len(jsonDeclaration.CredentialsSchema) != 1 {
t.Errorf("UnmarshalToolProviderConfiguration() error for JSON: incorrect CredentialsSchema length")
return
}
if len(jsonDeclaration.Tools) != 1 {
t.Errorf("UnmarshalToolProviderConfiguration() error for JSON: incorrect Tools length")
return
}
yamlDeclaration, yamlErr := parser.UnmarshalYamlBytes[ToolProviderDeclaration]([]byte(yaml_data))
if yamlErr != nil {
t.Errorf("UnmarshalToolProviderConfiguration() error for YAML = %v", yamlErr)
return
}
if len(yamlDeclaration.CredentialsSchema) != 1 {
t.Errorf("UnmarshalToolProviderConfiguration() error for YAML: incorrect CredentialsSchema length")
return
}
if len(yamlDeclaration.Tools) != 1 {
t.Errorf("UnmarshalToolProviderConfiguration() error for YAML: incorrect Tools length")
return
}
}
func TestWithoutAuthorToolProvider_Validate(t *testing.T) {
const data = `
{
"identity": {
"name": "name",
"description": {
"en_US": "description",
"zh_Hans": "描述",
"pt_BR": "descrição"
},
"icon": "icon",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
},
"tags": [
"image",
"videos"
]
},
"credentials_schema": [
{
"name": "api_key",
"type": "secret-input",
"required": false,
"default": "default",
"label": {
"en_US": "API Key",
"zh_Hans": "API 密钥",
"pt_BR": "Chave da API"
},
"help": {
"en_US": "API Key",
"zh_Hans": "API 密钥",
"pt_BR": "Chave da API"
},
"url": "https://example.com",
"placeholder": {
"en_US": "API Key",
"zh_Hans": "API 密钥",
"pt_BR": "Chave da API"
}
}
]
},
"tools": [
]
}
`
_, err := UnmarshalToolProviderDeclaration([]byte(data))
if err == nil {
t.Errorf("UnmarshalToolProviderConfiguration() error = %v, wantErr %v", err, true)
return
}
}
func TestWithoutNameToolProvider_Validate(t *testing.T) {
const data = `
{
"identity": {
"author": "author",
"description": {
"en_US": "description",
"zh_Hans": "描述",
"pt_BR": "descrição"
},
"icon": "icon",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
},
"tags": [
"image",
"videos"
]
},
"credentials_schema": [
{
"name": "api_key",
"type": "secret-input",
"type": "secret-input",
"required": false,
"default": "default",
"label": {
"en_US": "API Key",
"zh_Hans": "API 密钥",
"pt_BR": "Chave da API"
},
"help": {
"en_US": "API Key",
"zh_Hans": "API 密钥",
"pt_BR": "Chave da API"
},
"url": "https://example.com",
"placeholder": {
"en_US": "API Key",
"zh_Hans": "API 密钥",
"pt_BR": "Chave da API"
}
}
],
"tools": [
]
}
`
_, err := UnmarshalToolProviderDeclaration([]byte(data))
if err == nil {
t.Errorf("UnmarshalToolProviderConfiguration() error = %v, wantErr %v", err, true)
return
}
}
func TestWithoutDescriptionToolProvider_Validate(t *testing.T) {
const data = `
{
"identity": {
"author": "author",
"name": "name",
"icon": "icon",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
},
"tags": [
"image",
"videos"
]
},
"credentials_schema": [
{
"name": "api_key",
"type": "secret-input",
"required": false,
"default": "default",
"label": {
"en_US": "API Key",
"zh_Hans": "API 密钥",
"pt_BR": "Chave da API"
},
"help": {
"en_US": "API Key",
"zh_Hans": "API 密钥",
"pt_BR": "Chave da API"
},
"url": "https://example.com",
"placeholder": {
"en_US": "API Key",
"zh_Hans": "API 密钥",
"pt_BR": "Chave da API"
}
}
],
"tools": [
]
}
`
_, err := UnmarshalToolProviderDeclaration([]byte(data))
if err == nil {
t.Errorf("UnmarshalToolProviderConfiguration() error = %v, wantErr %v", err, true)
return
}
}
func TestWrongCredentialTypeToolProvider_Validate(t *testing.T) {
const data = `
{
"identity": {
"author": "author",
"name": "name",
"description": {
"en_US": "description",
"zh_Hans": "描述",
"pt_BR": "descrição"
},
"icon": "icon",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
},
"tags": [
"image",
"videos"
]
},
"credentials_schema": [
{
"name": "api_key",
"type": "wrong",
"required": false,
"default": "default",
"label": {
"en_US": "API Key",
"zh_Hans": "API 密钥",
"pt_BR": "Chave da API"
},
"help": {
"en_US": "API Key",
"zh_Hans": "API 密钥",
"pt_BR": "Chave da API"
},
"url": "https://example.com",
"placeholder": {
"en_US": "API Key",
"zh_Hans": "API 密钥",
"pt_BR": "Chave da API"
}
}
],
"tools": [
]
}
`
_, err := UnmarshalToolProviderDeclaration([]byte(data))
if err == nil {
t.Errorf("UnmarshalToolProviderConfiguration() error = %v, wantErr %v", err, true)
return
}
}
func TestWrongIdentityTagsToolProvider_Validate(t *testing.T) {
const data = `
{
"identity": {
"author": "author",
"name": "name",
"description": {
"en_US": "description",
"zh_Hans": "描述",
"pt_BR": "descrição"
},
"icon": "icon",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
},
"tags": [
"wrong",
"videos"
]
},
"credentials_schema": [
{
"name": "api_key",
"type": "secret-input",
"required": false,
"default": "default",
"label": {
"en_US": "API Key",
"zh_Hans": "API 密钥",
"pt_BR": "Chave da API"
},
"help": {
"en_US": "API Key",
"zh_Hans": "API 密钥",
"pt_BR": "Chave da API"
},
"url": "https://example.com",
"placeholder": {
"en_US": "API Key",
"zh_Hans": "API 密钥",
"pt_BR": "Chave da API"
}
}
],
"tools": [
]
}
`
_, err := UnmarshalToolProviderDeclaration([]byte(data))
if err == nil {
t.Errorf("UnmarshalToolProviderConfiguration() error = %v, wantErr %v", err, true)
return
}
}
func TestWrongToolParameterTypeToolProvider_Validate(t *testing.T) {
const data = `
{
"identity": {
"author": "author",
"name": "name",
"description": {
"en_US": "description",
"zh_Hans": "描述",
"pt_BR": "descrição"
},
"icon": "icon",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
},
"tags": []
},
"credentials_schema": [],
"tools": [
{
"identity": {
"author": "author",
"name": "tool",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
}
},
"description": {
"human": {
"en_US": "description",
"zh_Hans": "描述",
"pt_BR": "descrição"
},
"llm": "description"
},
"parameters": [
{
"name": "parameter",
"type": "wrong",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
},
"human_description": {
"en_US": "description",
"zh_Hans": "描述",
"pt_BR": "descrição"
},
"form": "llm",
"required": true,
"default": "default",
"options": []
}
]
}
]
}
`
_, err := UnmarshalToolProviderDeclaration([]byte(data))
if err == nil {
t.Errorf("UnmarshalToolProviderConfiguration() error = %v, wantErr %v", err, true)
return
}
}
func TestWrongToolParameterFormToolProvider_Validate(t *testing.T) {
const data = `
{
"identity": {
"author": "author",
"name": "name",
"description": {
"en_US": "description",
"zh_Hans": "描述",
"pt_BR": "descrição"
},
"icon": "icon",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
},
"tags": []
},
"credentials_schema": [],
"tools": [
{
"identity": {
"author": "author",
"name": "tool",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
}
},
"description": {
"human": {
"en_US": "description",
"zh_Hans": "描述",
"pt_BR": "descrição"
},
"llm": "description"
},
"parameters": [
{
"name": "parameter",
"type": "string",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
},
"human_description": {
"en_US": "description",
"zh_Hans": "描述",
"pt_BR": "descrição"
},
"form": "wrong",
"required": true,
"default": "default",
"options": []
}
]
}
]
}
`
_, err := UnmarshalToolProviderDeclaration([]byte(data))
if err == nil {
t.Errorf("UnmarshalToolProviderConfiguration() error = %v, wantErr %v", err, true)
return
}
}
func TestJSONSchemaTypeToolProvider_Validate(t *testing.T) {
const data = `
{
"identity": {
"author": "author",
"name": "name",
"description": {
"en_US": "description",
"zh_Hans": "描述",
"pt_BR": "descrição"
},
"icon": "icon",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
},
"tags": []
},
"credentials_schema": [],
"tools": [
{
"identity": {
"author": "author",
"name": "tool",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
}
},
"description": {
"human": {
"en_US": "description",
"zh_Hans": "描述",
"pt_BR": "descrição"
},
"llm": "description"
},
"output_schema": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
}
}
]
}
`
_, err := UnmarshalToolProviderDeclaration([]byte(data))
if err != nil {
t.Errorf("UnmarshalToolProviderConfiguration() error = %v, wantErr %v", err, true)
return
}
}
func TestWrongAppSelectorScopeToolProvider_Validate(t *testing.T) {
const data = `
{
"identity": {
"author": "author",
"name": "name",
"description": {
"en_US": "description",
"zh_Hans": "描述",
"pt_BR": "descrição"
},
"icon": "icon",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
},
"tags": []
},
"credentials_schema": [
{
"name": "api_key",
"type": "app-selector",
"scope": "wrong",
"required": false,
"default": null,
"label": {
"en_US": "app-selector",
"zh_Hans": "app-selector",
"pt_BR": "app-selector"
},
"help": {
"en_US": "app-selector",
"zh_Hans": "app-selector",
"pt_BR": "app-selector"
},
"url": "https://example.com",
"placeholder": {
"en_US": "app-selector",
"zh_Hans": "app-selector",
"pt_BR": "app-selector"
}
}
],
"tools": [
{
"identity": {
"author": "author",
"name": "tool",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
}
},
"description": {
"human": {
"en_US": "description",
"zh_Hans": "描述",
"pt_BR": "descrição"
},
"llm": "description"
},
"parameters": [
{
"name": "parameter-app-selector",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
},
"human_description": {
"en_US": "description",
"zh_Hans": "描述",
"pt_BR": "descrição"
},
"type": "app-selector",
"form": "llm",
"scope": "wrong",
"required": true,
"default": "default",
"options": []
}
]
}
]
}
`
_, err := UnmarshalToolProviderDeclaration([]byte(data))
if err == nil {
t.Errorf("UnmarshalToolProviderConfiguration() error = %v, wantErr %v", err, true)
return
}
str := err.Error()
if !strings.Contains(str, "is_scope") {
t.Errorf("UnmarshalToolProviderConfiguration() error = %v, wantErr %v", err, true)
return
}
if !strings.Contains(str, "ToolProviderDeclaration.Tools[0].Parameters[0].Scope") {
t.Errorf("UnmarshalToolProviderConfiguration() error = %v, wantErr %v", err, true)
return
}
}
func TestAppSelectorScopeToolProvider_Validate(t *testing.T) {
const data = `
{
"identity": {
"author": "author",
"name": "name",
"description": {
"en_US": "description",
"zh_Hans": "描述",
"pt_BR": "descrição"
},
"icon": "icon",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
},
"tags": []
},
"credentials_schema": [
{
"name": "app-selector",
"type": "app-selector",
"scope": "all",
"required": false,
"default": null,
"label": {
"en_US": "app-selector",
"zh_Hans": "app-selector",
"pt_BR": "app-selector"
},
"help": {
"en_US": "app-selector",
"zh_Hans": "app-selector",
"pt_BR": "app-selector"
},
"url": "https://example.com",
"placeholder": {
"en_US": "app-selector",
"zh_Hans": "app-selector",
"pt_BR": "app-selector"
}
}
],
"tools": [
{
"identity": {
"author": "author",
"name": "tool",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
}
},
"description": {
"human": {
"en_US": "description",
"zh_Hans": "描述",
"pt_BR": "descrição"
},
"llm": "description"
},
"parameters": [
{
"name": "parameter-app-selector",
"label": {
"en_US": "label",
"zh_Hans": "标签",
"pt_BR": "etiqueta"
},
"human_description": {
"en_US": "description",
"zh_Hans": "描述",
"pt_BR": "descrição"
},
"type": "app-selector",
"form": "llm",
"scope": "all",
"required": true,
"default": "default",
"options": []
}
]
}
]
}
`
_, err := UnmarshalToolProviderDeclaration([]byte(data))
if err != nil {
t.Errorf("UnmarshalToolProviderConfiguration() error = %v, wantErr %v", err, true)
return
}
}
func TestParameterScope_Validate(t *testing.T) {
config := ToolParameter{
Name: "test",
Type: TOOL_PARAMETER_TYPE_MODEL_SELECTOR,
Scope: parser.ToPtr("llm& document&tool-call"),
Required: true,
Label: I18nObject{
ZhHans: "模型",
EnUS: "Model",
},
HumanDescription: I18nObject{
ZhHans: "请选择模型",
EnUS: "Please select a model",
},
LLMDescription: "please select a model",
Form: TOOL_PARAMETER_FORM_FORM,
}
data := parser.MarshalJsonBytes(config)
if _, err := parser.UnmarshalJsonBytes[ToolParameter](data); err != nil {
t.Errorf("ParameterScope_Validate() error = %v", err)
}
}
func TestToolName_Validate(t *testing.T) {
data := parser.MarshalJsonBytes(ToolProviderIdentity{
Author: "author",
Name: "tool-name",
Description: I18nObject{
EnUS: "description",
ZhHans: "描述",
},
Icon: "icon",
Label: I18nObject{
EnUS: "label",
ZhHans: "标签",
},
})
if _, err := parser.UnmarshalJsonBytes[ToolProviderIdentity](data); err != nil {
t.Errorf("TestToolName_Validate() error = %v", err)
}
data = parser.MarshalJsonBytes(ToolProviderIdentity{
Author: "author",
Name: "tool AA",
Label: I18nObject{
EnUS: "label",
ZhHans: "标签",
},
})
if _, err := parser.UnmarshalJsonBytes[ToolProviderIdentity](data); err == nil {
t.Errorf("TestToolName_Validate() error = %v", err)
}
data = parser.MarshalJsonBytes(ToolIdentity{
Author: "author",
Name: "tool-name-123",
Label: I18nObject{
EnUS: "label",
ZhHans: "标签",
},
})
if _, err := parser.UnmarshalJsonBytes[ToolIdentity](data); err != nil {
t.Errorf("TestToolName_Validate() error = %v", err)
}
data = parser.MarshalJsonBytes(ToolIdentity{
Author: "author",
Name: "tool name-123",
Label: I18nObject{
EnUS: "label",
ZhHans: "标签",
},
})
if _, err := parser.UnmarshalJsonBytes[ToolIdentity](data); err == nil {
t.Errorf("TestToolName_Validate() error = %v", err)
}
}