mirror of
https://github.com/memohai/Memoh.git
synced 2026-04-25 07:00:48 +09:00
feat(search): add bing and google support
This commit is contained in:
@@ -74,8 +74,7 @@ CREATE TABLE IF NOT EXISTS search_providers (
|
||||
config JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
CONSTRAINT search_providers_name_unique UNIQUE (name),
|
||||
CONSTRAINT search_providers_provider_check CHECK (provider IN ('brave'))
|
||||
CONSTRAINT search_providers_name_unique UNIQUE (name)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS models (
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
-- 0015_drop_search_provider_check (down)
|
||||
-- Restore the original CHECK constraint limiting provider to 'brave'.
|
||||
|
||||
ALTER TABLE search_providers ADD CONSTRAINT search_providers_provider_check CHECK (provider IN ('brave'));
|
||||
@@ -0,0 +1,5 @@
|
||||
-- 0015_drop_search_provider_check
|
||||
-- Remove the CHECK constraint on search_providers.provider so new providers
|
||||
-- can be added without a database migration.
|
||||
|
||||
ALTER TABLE search_providers DROP CONSTRAINT IF EXISTS search_providers_provider_check;
|
||||
@@ -101,9 +101,19 @@ func (p *Executor) callWebSearch(ctx context.Context, providerName string, confi
|
||||
count = 20
|
||||
}
|
||||
|
||||
if strings.TrimSpace(providerName) != string(searchproviders.ProviderBrave) {
|
||||
switch strings.TrimSpace(providerName) {
|
||||
case string(searchproviders.ProviderBrave):
|
||||
return p.callBraveSearch(ctx, configJSON, query, count)
|
||||
case string(searchproviders.ProviderBing):
|
||||
return p.callBingSearch(ctx, configJSON, query, count)
|
||||
case string(searchproviders.ProviderGoogle):
|
||||
return p.callGoogleSearch(ctx, configJSON, query, count)
|
||||
default:
|
||||
return mcpgw.BuildToolErrorResult("unsupported search provider"), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Executor) callBraveSearch(ctx context.Context, configJSON []byte, query string, count int) (map[string]any, error) {
|
||||
cfg := parseConfig(configJSON)
|
||||
endpoint := strings.TrimRight(firstNonEmpty(stringValue(cfg["base_url"]), "https://api.search.brave.com/res/v1/web/search"), "/")
|
||||
reqURL, err := url.Parse(endpoint)
|
||||
@@ -164,6 +174,134 @@ func (p *Executor) callWebSearch(ctx context.Context, providerName string, confi
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (p *Executor) callBingSearch(ctx context.Context, configJSON []byte, query string, count int) (map[string]any, error) {
|
||||
cfg := parseConfig(configJSON)
|
||||
endpoint := strings.TrimRight(firstNonEmpty(stringValue(cfg["base_url"]), "https://api.bing.microsoft.com/v7.0/search"), "/")
|
||||
reqURL, err := url.Parse(endpoint)
|
||||
if err != nil {
|
||||
return mcpgw.BuildToolErrorResult("invalid search provider base_url"), nil
|
||||
}
|
||||
params := reqURL.Query()
|
||||
params.Set("q", query)
|
||||
params.Set("count", fmt.Sprintf("%d", count))
|
||||
reqURL.RawQuery = params.Encode()
|
||||
|
||||
timeout := parseTimeout(configJSON, 15*time.Second)
|
||||
client := &http.Client{Timeout: timeout}
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, reqURL.String(), nil)
|
||||
if err != nil {
|
||||
return mcpgw.BuildToolErrorResult(err.Error()), nil
|
||||
}
|
||||
req.Header.Set("Accept", "application/json")
|
||||
apiKey := stringValue(cfg["api_key"])
|
||||
if strings.TrimSpace(apiKey) != "" {
|
||||
req.Header.Set("Ocp-Apim-Subscription-Key", strings.TrimSpace(apiKey))
|
||||
}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return mcpgw.BuildToolErrorResult(err.Error()), nil
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return mcpgw.BuildToolErrorResult(err.Error()), nil
|
||||
}
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
return mcpgw.BuildToolErrorResult("search request failed"), nil
|
||||
}
|
||||
var raw struct {
|
||||
WebPages struct {
|
||||
Value []struct {
|
||||
Name string `json:"name"`
|
||||
URL string `json:"url"`
|
||||
Snippet string `json:"snippet"`
|
||||
} `json:"value"`
|
||||
} `json:"webPages"`
|
||||
}
|
||||
if err := json.Unmarshal(body, &raw); err != nil {
|
||||
return mcpgw.BuildToolErrorResult("invalid search response"), nil
|
||||
}
|
||||
results := make([]map[string]any, 0, len(raw.WebPages.Value))
|
||||
for _, item := range raw.WebPages.Value {
|
||||
results = append(results, map[string]any{
|
||||
"title": item.Name,
|
||||
"url": item.URL,
|
||||
"description": item.Snippet,
|
||||
})
|
||||
}
|
||||
return mcpgw.BuildToolSuccessResult(map[string]any{
|
||||
"query": query,
|
||||
"results": results,
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (p *Executor) callGoogleSearch(ctx context.Context, configJSON []byte, query string, count int) (map[string]any, error) {
|
||||
cfg := parseConfig(configJSON)
|
||||
endpoint := strings.TrimRight(firstNonEmpty(stringValue(cfg["base_url"]), "https://customsearch.googleapis.com/customsearch/v1"), "/")
|
||||
reqURL, err := url.Parse(endpoint)
|
||||
if err != nil {
|
||||
return mcpgw.BuildToolErrorResult("invalid search provider base_url"), nil
|
||||
}
|
||||
cx := stringValue(cfg["cx"])
|
||||
if cx == "" {
|
||||
return mcpgw.BuildToolErrorResult("Google Custom Search requires cx (Search Engine ID)"), nil
|
||||
}
|
||||
if count > 10 {
|
||||
count = 10
|
||||
}
|
||||
params := reqURL.Query()
|
||||
params.Set("q", query)
|
||||
params.Set("cx", cx)
|
||||
params.Set("num", fmt.Sprintf("%d", count))
|
||||
apiKey := stringValue(cfg["api_key"])
|
||||
if strings.TrimSpace(apiKey) != "" {
|
||||
params.Set("key", strings.TrimSpace(apiKey))
|
||||
}
|
||||
reqURL.RawQuery = params.Encode()
|
||||
|
||||
timeout := parseTimeout(configJSON, 15*time.Second)
|
||||
client := &http.Client{Timeout: timeout}
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, reqURL.String(), nil)
|
||||
if err != nil {
|
||||
return mcpgw.BuildToolErrorResult(err.Error()), nil
|
||||
}
|
||||
req.Header.Set("Accept", "application/json")
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return mcpgw.BuildToolErrorResult(err.Error()), nil
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return mcpgw.BuildToolErrorResult(err.Error()), nil
|
||||
}
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
return mcpgw.BuildToolErrorResult("search request failed"), nil
|
||||
}
|
||||
var raw struct {
|
||||
Items []struct {
|
||||
Title string `json:"title"`
|
||||
Link string `json:"link"`
|
||||
Snippet string `json:"snippet"`
|
||||
} `json:"items"`
|
||||
}
|
||||
if err := json.Unmarshal(body, &raw); err != nil {
|
||||
return mcpgw.BuildToolErrorResult("invalid search response"), nil
|
||||
}
|
||||
results := make([]map[string]any, 0, len(raw.Items))
|
||||
for _, item := range raw.Items {
|
||||
results = append(results, map[string]any{
|
||||
"title": item.Title,
|
||||
"url": item.Link,
|
||||
"description": item.Snippet,
|
||||
})
|
||||
}
|
||||
return mcpgw.BuildToolSuccessResult(map[string]any{
|
||||
"query": query,
|
||||
"results": results,
|
||||
}), nil
|
||||
}
|
||||
|
||||
func parseTimeout(configJSON []byte, fallback time.Duration) time.Duration {
|
||||
cfg := parseConfig(configJSON)
|
||||
raw, ok := cfg["timeout_seconds"]
|
||||
|
||||
@@ -53,6 +53,68 @@ func (s *Service) ListMeta(_ context.Context) []ProviderMeta {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Provider: string(ProviderBing),
|
||||
DisplayName: "Bing",
|
||||
ConfigSchema: ProviderConfigSchema{
|
||||
Fields: map[string]ProviderFieldSchema{
|
||||
"api_key": {
|
||||
Type: "secret",
|
||||
Title: "API Key",
|
||||
Description: "Bing Web Search API subscription key",
|
||||
Required: true,
|
||||
},
|
||||
"base_url": {
|
||||
Type: "string",
|
||||
Title: "Base URL",
|
||||
Description: "Bing API base URL",
|
||||
Required: false,
|
||||
Example: "https://api.bing.microsoft.com/v7.0/search",
|
||||
},
|
||||
"timeout_seconds": {
|
||||
Type: "number",
|
||||
Title: "Timeout (seconds)",
|
||||
Description: "HTTP timeout in seconds",
|
||||
Required: false,
|
||||
Example: 15,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Provider: string(ProviderGoogle),
|
||||
DisplayName: "Google",
|
||||
ConfigSchema: ProviderConfigSchema{
|
||||
Fields: map[string]ProviderFieldSchema{
|
||||
"api_key": {
|
||||
Type: "secret",
|
||||
Title: "API Key",
|
||||
Description: "Google Custom Search API key",
|
||||
Required: true,
|
||||
},
|
||||
"cx": {
|
||||
Type: "string",
|
||||
Title: "Search Engine ID",
|
||||
Description: "Google Programmable Search Engine ID (cx)",
|
||||
Required: true,
|
||||
},
|
||||
"base_url": {
|
||||
Type: "string",
|
||||
Title: "Base URL",
|
||||
Description: "Google Custom Search API base URL",
|
||||
Required: false,
|
||||
Example: "https://customsearch.googleapis.com/customsearch/v1",
|
||||
},
|
||||
"timeout_seconds": {
|
||||
Type: "number",
|
||||
Title: "Timeout (seconds)",
|
||||
Description: "HTTP timeout in seconds",
|
||||
Required: false,
|
||||
Example: 15,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,7 +245,7 @@ func (s *Service) toGetResponse(row sqlc.SearchProvider) GetResponse {
|
||||
|
||||
func isValidProviderName(name ProviderName) bool {
|
||||
switch name {
|
||||
case ProviderBrave:
|
||||
case ProviderBrave, ProviderBing, ProviderGoogle:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
||||
@@ -5,7 +5,9 @@ import "time"
|
||||
type ProviderName string
|
||||
|
||||
const (
|
||||
ProviderBrave ProviderName = "brave"
|
||||
ProviderBrave ProviderName = "brave"
|
||||
ProviderBing ProviderName = "bing"
|
||||
ProviderGoogle ProviderName = "google"
|
||||
)
|
||||
|
||||
type ProviderConfigSchema struct {
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -954,7 +954,7 @@ export type SearchprovidersProviderMeta = {
|
||||
provider?: string;
|
||||
};
|
||||
|
||||
export type SearchprovidersProviderName = 'brave';
|
||||
export type SearchprovidersProviderName = 'brave' | 'bing' | 'google';
|
||||
|
||||
export type SearchprovidersUpdateRequest = {
|
||||
config?: {
|
||||
@@ -3002,6 +3002,42 @@ export type DeleteBotsByBotIdMemoryByIdResponses = {
|
||||
|
||||
export type DeleteBotsByBotIdMemoryByIdResponse = DeleteBotsByBotIdMemoryByIdResponses[keyof DeleteBotsByBotIdMemoryByIdResponses];
|
||||
|
||||
export type DeleteBotsByBotIdMessagesData = {
|
||||
body?: never;
|
||||
path: {
|
||||
/**
|
||||
* Bot ID
|
||||
*/
|
||||
bot_id: string;
|
||||
};
|
||||
query?: never;
|
||||
url: '/bots/{bot_id}/messages';
|
||||
};
|
||||
|
||||
export type DeleteBotsByBotIdMessagesErrors = {
|
||||
/**
|
||||
* Bad Request
|
||||
*/
|
||||
400: HandlersErrorResponse;
|
||||
/**
|
||||
* Forbidden
|
||||
*/
|
||||
403: HandlersErrorResponse;
|
||||
/**
|
||||
* Internal Server Error
|
||||
*/
|
||||
500: HandlersErrorResponse;
|
||||
};
|
||||
|
||||
export type DeleteBotsByBotIdMessagesError = DeleteBotsByBotIdMessagesErrors[keyof DeleteBotsByBotIdMessagesErrors];
|
||||
|
||||
export type DeleteBotsByBotIdMessagesResponses = {
|
||||
/**
|
||||
* No Content
|
||||
*/
|
||||
204: unknown;
|
||||
};
|
||||
|
||||
export type GetBotsByBotIdMessagesData = {
|
||||
body?: never;
|
||||
path: {
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
const PROVIDER_ICONS: Record<string, [string, string]> = {
|
||||
brave: ['fab', 'brave'],
|
||||
bing: ['fab', 'microsoft'],
|
||||
google: ['fab', 'google'],
|
||||
}
|
||||
|
||||
const DEFAULT_ICON: [string, string] = ['fas', 'globe']
|
||||
|
||||
@@ -59,7 +59,7 @@ import {
|
||||
faComments,
|
||||
faComment,
|
||||
} from '@fortawesome/free-regular-svg-icons'
|
||||
import { faSlack, faBrave } from '@fortawesome/free-brands-svg-icons'
|
||||
import { faSlack, faBrave, faGoogle, faMicrosoft } from '@fortawesome/free-brands-svg-icons'
|
||||
|
||||
library.add(
|
||||
faGear,
|
||||
@@ -103,6 +103,8 @@ library.add(
|
||||
faComment,
|
||||
faSlack,
|
||||
faBrave,
|
||||
faGoogle,
|
||||
faMicrosoft,
|
||||
)
|
||||
|
||||
createApp(App)
|
||||
|
||||
@@ -109,7 +109,7 @@ import { useI18n } from 'vue-i18n'
|
||||
import FormDialogShell from '@/components/form-dialog-shell/index.vue'
|
||||
import { useDialogMutation } from '@/composables/useDialogMutation'
|
||||
|
||||
const PROVIDER_TYPES = ['brave'] as const
|
||||
const PROVIDER_TYPES = ['brave', 'bing', 'google'] as const
|
||||
|
||||
const open = defineModel<boolean>('open')
|
||||
const { t } = useI18n()
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<div class="space-y-4">
|
||||
<div class="space-y-2">
|
||||
<Label for="bing-api-key">API Key</Label>
|
||||
<Input
|
||||
id="bing-api-key"
|
||||
v-model="localConfig.api_key"
|
||||
type="password"
|
||||
aria-label="API Key"
|
||||
/>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<Label for="bing-base-url">Base URL</Label>
|
||||
<Input
|
||||
id="bing-base-url"
|
||||
v-model="localConfig.base_url"
|
||||
aria-label="Base URL"
|
||||
/>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<Label for="bing-timeout-seconds">Timeout (seconds)</Label>
|
||||
<Input
|
||||
id="bing-timeout-seconds"
|
||||
v-model.number="localConfig.timeout_seconds"
|
||||
type="number"
|
||||
:min="1"
|
||||
aria-label="Timeout (seconds)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, watch } from 'vue'
|
||||
import { Input, Label } from '@memoh/ui'
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: Record<string, unknown>
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: Record<string, unknown>]
|
||||
}>()
|
||||
|
||||
const localConfig = reactive({
|
||||
api_key: '',
|
||||
base_url: 'https://api.bing.microsoft.com/v7.0/search',
|
||||
timeout_seconds: 15,
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val) => {
|
||||
localConfig.api_key = String(val?.api_key ?? '')
|
||||
localConfig.base_url = String(val?.base_url ?? 'https://api.bing.microsoft.com/v7.0/search')
|
||||
const timeout = Number(val?.timeout_seconds ?? 15)
|
||||
localConfig.timeout_seconds = Number.isFinite(timeout) && timeout > 0 ? timeout : 15
|
||||
},
|
||||
{ immediate: true, deep: true },
|
||||
)
|
||||
|
||||
watch(localConfig, () => {
|
||||
emit('update:modelValue', {
|
||||
api_key: localConfig.api_key,
|
||||
base_url: localConfig.base_url,
|
||||
timeout_seconds: localConfig.timeout_seconds,
|
||||
})
|
||||
}, { deep: true })
|
||||
</script>
|
||||
@@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<div class="space-y-4">
|
||||
<div class="space-y-2">
|
||||
<Label for="google-api-key">API Key</Label>
|
||||
<Input
|
||||
id="google-api-key"
|
||||
v-model="localConfig.api_key"
|
||||
type="password"
|
||||
aria-label="API Key"
|
||||
/>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<Label for="google-cx">Search Engine ID (cx)</Label>
|
||||
<Input
|
||||
id="google-cx"
|
||||
v-model="localConfig.cx"
|
||||
aria-label="Search Engine ID"
|
||||
/>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<Label for="google-base-url">Base URL</Label>
|
||||
<Input
|
||||
id="google-base-url"
|
||||
v-model="localConfig.base_url"
|
||||
aria-label="Base URL"
|
||||
/>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<Label for="google-timeout-seconds">Timeout (seconds)</Label>
|
||||
<Input
|
||||
id="google-timeout-seconds"
|
||||
v-model.number="localConfig.timeout_seconds"
|
||||
type="number"
|
||||
:min="1"
|
||||
aria-label="Timeout (seconds)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, watch } from 'vue'
|
||||
import { Input, Label } from '@memoh/ui'
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: Record<string, unknown>
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: Record<string, unknown>]
|
||||
}>()
|
||||
|
||||
const localConfig = reactive({
|
||||
api_key: '',
|
||||
cx: '',
|
||||
base_url: 'https://customsearch.googleapis.com/customsearch/v1',
|
||||
timeout_seconds: 15,
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val) => {
|
||||
localConfig.api_key = String(val?.api_key ?? '')
|
||||
localConfig.cx = String(val?.cx ?? '')
|
||||
localConfig.base_url = String(val?.base_url ?? 'https://customsearch.googleapis.com/customsearch/v1')
|
||||
const timeout = Number(val?.timeout_seconds ?? 15)
|
||||
localConfig.timeout_seconds = Number.isFinite(timeout) && timeout > 0 ? timeout : 15
|
||||
},
|
||||
{ immediate: true, deep: true },
|
||||
)
|
||||
|
||||
watch(localConfig, () => {
|
||||
emit('update:modelValue', {
|
||||
api_key: localConfig.api_key,
|
||||
cx: localConfig.cx,
|
||||
base_url: localConfig.base_url,
|
||||
timeout_seconds: localConfig.timeout_seconds,
|
||||
})
|
||||
}, { deep: true })
|
||||
</script>
|
||||
@@ -79,6 +79,12 @@
|
||||
<template v-if="form.values.provider === 'brave'">
|
||||
<BraveSettings v-model="configProxy" />
|
||||
</template>
|
||||
<template v-else-if="form.values.provider === 'bing'">
|
||||
<BingSettings v-model="configProxy" />
|
||||
</template>
|
||||
<template v-else-if="form.values.provider === 'google'">
|
||||
<GoogleSettings v-model="configProxy" />
|
||||
</template>
|
||||
<div
|
||||
v-else-if="form.values.provider"
|
||||
class="text-sm text-muted-foreground"
|
||||
@@ -135,6 +141,8 @@ import {
|
||||
} from '@memoh/ui'
|
||||
import ConfirmPopover from '@/components/confirm-popover/index.vue'
|
||||
import BraveSettings from './brave-settings.vue'
|
||||
import BingSettings from './bing-settings.vue'
|
||||
import GoogleSettings from './google-settings.vue'
|
||||
import SearchProviderLogo from '@/components/search-provider-logo/index.vue'
|
||||
import { computed, inject, ref, watch } from 'vue'
|
||||
import { toTypedSchema } from '@vee-validate/zod'
|
||||
@@ -144,7 +152,7 @@ import { useMutation, useQueryCache } from '@pinia/colada'
|
||||
import { putSearchProvidersById, deleteSearchProvidersById } from '@memoh/sdk'
|
||||
import type { SearchprovidersGetResponse } from '@memoh/sdk'
|
||||
|
||||
const PROVIDER_TYPES = ['brave'] as const
|
||||
const PROVIDER_TYPES = ['brave', 'bing', 'google'] as const
|
||||
|
||||
const curProvider = inject('curSearchProvider', ref<SearchprovidersGetResponse>())
|
||||
const curProviderId = computed(() => curProvider.value?.id)
|
||||
|
||||
@@ -28,7 +28,7 @@ import ProviderSetting from './components/provider-setting.vue'
|
||||
import SearchProviderLogo from '@/components/search-provider-logo/index.vue'
|
||||
import MasterDetailSidebarLayout from '@/components/master-detail-sidebar-layout/index.vue'
|
||||
|
||||
const PROVIDER_TYPES = ['brave'] as const
|
||||
const PROVIDER_TYPES = ['brave', 'bing', 'google'] as const
|
||||
|
||||
const filterProvider = ref('')
|
||||
const { data: providerData } = useQuery({
|
||||
|
||||
+48
-2
@@ -2474,6 +2474,48 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"description": "Clear all persisted bot-level history messages",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"messages"
|
||||
],
|
||||
"summary": "Delete all bot history messages",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Bot ID",
|
||||
"name": "bot_id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "No Content"
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Forbidden",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/bots/{bot_id}/schedule": {
|
||||
@@ -8173,10 +8215,14 @@ const docTemplate = `{
|
||||
"searchproviders.ProviderName": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"brave"
|
||||
"brave",
|
||||
"bing",
|
||||
"google"
|
||||
],
|
||||
"x-enum-varnames": [
|
||||
"ProviderBrave"
|
||||
"ProviderBrave",
|
||||
"ProviderBing",
|
||||
"ProviderGoogle"
|
||||
]
|
||||
},
|
||||
"searchproviders.UpdateRequest": {
|
||||
|
||||
+48
-2
@@ -2465,6 +2465,48 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"description": "Clear all persisted bot-level history messages",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"messages"
|
||||
],
|
||||
"summary": "Delete all bot history messages",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Bot ID",
|
||||
"name": "bot_id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "No Content"
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Forbidden",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.ErrorResponse"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handlers.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/bots/{bot_id}/schedule": {
|
||||
@@ -8164,10 +8206,14 @@
|
||||
"searchproviders.ProviderName": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"brave"
|
||||
"brave",
|
||||
"bing",
|
||||
"google"
|
||||
],
|
||||
"x-enum-varnames": [
|
||||
"ProviderBrave"
|
||||
"ProviderBrave",
|
||||
"ProviderBing",
|
||||
"ProviderGoogle"
|
||||
]
|
||||
},
|
||||
"searchproviders.UpdateRequest": {
|
||||
|
||||
@@ -1563,9 +1563,13 @@ definitions:
|
||||
searchproviders.ProviderName:
|
||||
enum:
|
||||
- brave
|
||||
- bing
|
||||
- google
|
||||
type: string
|
||||
x-enum-varnames:
|
||||
- ProviderBrave
|
||||
- ProviderBing
|
||||
- ProviderGoogle
|
||||
searchproviders.UpdateRequest:
|
||||
properties:
|
||||
config:
|
||||
@@ -3347,6 +3351,34 @@ paths:
|
||||
tags:
|
||||
- memory
|
||||
/bots/{bot_id}/messages:
|
||||
delete:
|
||||
description: Clear all persisted bot-level history messages
|
||||
parameters:
|
||||
- description: Bot ID
|
||||
in: path
|
||||
name: bot_id
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"204":
|
||||
description: No Content
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/handlers.ErrorResponse'
|
||||
"403":
|
||||
description: Forbidden
|
||||
schema:
|
||||
$ref: '#/definitions/handlers.ErrorResponse'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/handlers.ErrorResponse'
|
||||
summary: Delete all bot history messages
|
||||
tags:
|
||||
- messages
|
||||
get:
|
||||
description: List messages for a bot history with optional pagination
|
||||
parameters:
|
||||
|
||||
Reference in New Issue
Block a user