mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-02-04 01:25:07 +08:00
Compare commits
11 Commits
17b8bb62b6
...
7fef285af5
| Author | SHA1 | Date | |
|---|---|---|---|
| 7fef285af5 | |||
| b1efb905e5 | |||
| 6400bf87ba | |||
| f239bc02d3 | |||
| 5776fa73a7 | |||
| fc6af1998b | |||
| 0588fe79b9 | |||
| f545265f93 | |||
| c987d33649 | |||
| d72debf0db | |||
| c33134ea2c |
@ -86,8 +86,9 @@ class Agent(LLM, ToolBase):
|
||||
self.tools = {}
|
||||
for idx, cpn in enumerate(self._param.tools):
|
||||
cpn = self._load_tool_obj(cpn)
|
||||
name = cpn.get_meta()["function"]["name"]
|
||||
self.tools[f"{name}_{idx}"] = cpn
|
||||
original_name = cpn.get_meta()["function"]["name"]
|
||||
indexed_name = f"{original_name}_{idx}"
|
||||
self.tools[indexed_name] = cpn
|
||||
|
||||
self.chat_mdl = LLMBundle(self._canvas.get_tenant_id(), TenantLLMService.llm_id2llm_type(self._param.llm_id), self._param.llm_id,
|
||||
max_retries=self._param.max_retries,
|
||||
@ -95,7 +96,12 @@ class Agent(LLM, ToolBase):
|
||||
max_rounds=self._param.max_rounds,
|
||||
verbose_tool_use=True
|
||||
)
|
||||
self.tool_meta = [v.get_meta() for _,v in self.tools.items()]
|
||||
self.tool_meta = []
|
||||
for indexed_name, tool_obj in self.tools.items():
|
||||
original_meta = tool_obj.get_meta()
|
||||
indexed_meta = deepcopy(original_meta)
|
||||
indexed_meta["function"]["name"] = indexed_name
|
||||
self.tool_meta.append(indexed_meta)
|
||||
|
||||
for mcp in self._param.mcp:
|
||||
_, mcp_server = MCPServerService.get_by_id(mcp["mcp_id"])
|
||||
@ -109,7 +115,8 @@ class Agent(LLM, ToolBase):
|
||||
|
||||
def _load_tool_obj(self, cpn: dict) -> object:
|
||||
from agent.component import component_class
|
||||
param = component_class(cpn["component_name"] + "Param")()
|
||||
tool_name = cpn["component_name"]
|
||||
param = component_class(tool_name + "Param")()
|
||||
param.update(cpn["params"])
|
||||
try:
|
||||
param.check()
|
||||
@ -277,19 +284,15 @@ class Agent(LLM, ToolBase):
|
||||
else:
|
||||
user_request = history[-1]["content"]
|
||||
|
||||
def build_task_desc(prompt: str, user_request: str, tool_metas: list[dict], user_defined_prompt: dict | None = None) -> str:
|
||||
def build_task_desc(prompt: str, user_request: str, user_defined_prompt: dict | None = None) -> str:
|
||||
"""Build a minimal task_desc by concatenating prompt, query, and tool schemas."""
|
||||
user_defined_prompt = user_defined_prompt or {}
|
||||
|
||||
tools_json = json.dumps(tool_metas, ensure_ascii=False, indent=2)
|
||||
|
||||
task_desc = (
|
||||
"### Agent Prompt\n"
|
||||
f"{prompt}\n\n"
|
||||
"### User Request\n"
|
||||
f"{user_request}\n\n"
|
||||
"### Tools (schemas)\n"
|
||||
f"{tools_json}\n"
|
||||
)
|
||||
|
||||
if user_defined_prompt:
|
||||
@ -368,7 +371,7 @@ class Agent(LLM, ToolBase):
|
||||
hist.append({"role": "user", "content": content})
|
||||
|
||||
st = timer()
|
||||
task_desc = build_task_desc(prompt, user_request, tool_metas, user_defined_prompt)
|
||||
task_desc = build_task_desc(prompt, user_request, user_defined_prompt)
|
||||
self.callback("analyze_task", {}, task_desc, elapsed_time=timer()-st)
|
||||
for _ in range(self._param.max_rounds + 1):
|
||||
if self.check_if_canceled("Agent streaming"):
|
||||
|
||||
@ -56,7 +56,6 @@ class LLMParam(ComponentParamBase):
|
||||
self.check_nonnegative_number(int(self.max_tokens), "[Agent] Max tokens")
|
||||
self.check_decimal_float(float(self.top_p), "[Agent] Top P")
|
||||
self.check_empty(self.llm_id, "[Agent] LLM")
|
||||
self.check_empty(self.sys_prompt, "[Agent] System prompt")
|
||||
self.check_empty(self.prompts, "[Agent] User prompt")
|
||||
|
||||
def gen_conf(self):
|
||||
|
||||
@ -33,6 +33,7 @@ from api.db.db_models import DB, Document, Knowledgebase, Task, Tenant, UserTena
|
||||
from api.db.db_utils import bulk_insert_into_db
|
||||
from api.db.services.common_service import CommonService
|
||||
from api.db.services.knowledgebase_service import KnowledgebaseService
|
||||
from common.metadata_utils import dedupe_list
|
||||
from common.misc_utils import get_uuid
|
||||
from common.time_utils import current_timestamp, get_format_time
|
||||
from common.constants import LLMType, ParserType, StatusEnum, TaskStatus, SVR_CONSUMER_GROUP_NAME
|
||||
@ -696,10 +697,12 @@ class DocumentService(CommonService):
|
||||
for k,v in r.meta_fields.items():
|
||||
if k not in meta:
|
||||
meta[k] = {}
|
||||
v = str(v)
|
||||
if v not in meta[k]:
|
||||
meta[k][v] = []
|
||||
meta[k][v].append(doc_id)
|
||||
if not isinstance(v, list):
|
||||
v = [v]
|
||||
for vv in v:
|
||||
if vv not in meta[k]:
|
||||
meta[k][vv] = []
|
||||
meta[k][vv].append(doc_id)
|
||||
return meta
|
||||
|
||||
@classmethod
|
||||
@ -797,7 +800,10 @@ class DocumentService(CommonService):
|
||||
match_provided = "match" in upd
|
||||
if isinstance(meta[key], list):
|
||||
if not match_provided:
|
||||
meta[key] = new_value
|
||||
if isinstance(new_value, list):
|
||||
meta[key] = dedupe_list(new_value)
|
||||
else:
|
||||
meta[key] = new_value
|
||||
changed = True
|
||||
else:
|
||||
match_value = upd.get("match")
|
||||
@ -810,7 +816,7 @@ class DocumentService(CommonService):
|
||||
else:
|
||||
new_list.append(item)
|
||||
if replaced:
|
||||
meta[key] = new_list
|
||||
meta[key] = dedupe_list(new_list)
|
||||
changed = True
|
||||
else:
|
||||
if not match_provided:
|
||||
|
||||
@ -117,6 +117,8 @@ class MemoryService(CommonService):
|
||||
if len(memory_name) > MEMORY_NAME_LIMIT:
|
||||
return False, f"Memory name {memory_name} exceeds limit of {MEMORY_NAME_LIMIT}."
|
||||
|
||||
timestamp = current_timestamp()
|
||||
format_time = get_format_time()
|
||||
# build create dict
|
||||
memory_info = {
|
||||
"id": get_uuid(),
|
||||
@ -126,10 +128,10 @@ class MemoryService(CommonService):
|
||||
"embd_id": embd_id,
|
||||
"llm_id": llm_id,
|
||||
"system_prompt": PromptAssembler.assemble_system_prompt({"memory_type": memory_type}),
|
||||
"create_time": current_timestamp(),
|
||||
"create_date": get_format_time(),
|
||||
"update_time": current_timestamp(),
|
||||
"update_date": get_format_time(),
|
||||
"create_time": timestamp,
|
||||
"create_date": format_time,
|
||||
"update_time": timestamp,
|
||||
"update_date": format_time,
|
||||
}
|
||||
obj = cls.model(**memory_info).save(force_insert=True)
|
||||
|
||||
|
||||
@ -44,21 +44,27 @@ def meta_filter(metas: dict, filters: list[dict], logic: str = "and"):
|
||||
def filter_out(v2docs, operator, value):
|
||||
ids = []
|
||||
for input, docids in v2docs.items():
|
||||
|
||||
if operator in ["=", "≠", ">", "<", "≥", "≤"]:
|
||||
try:
|
||||
if isinstance(input, list):
|
||||
input = input[0]
|
||||
input = float(input)
|
||||
value = float(value)
|
||||
except Exception:
|
||||
input = str(input)
|
||||
value = str(value)
|
||||
pass
|
||||
if isinstance(input, str):
|
||||
input = input.lower()
|
||||
if isinstance(value, str):
|
||||
value = value.lower()
|
||||
|
||||
for conds in [
|
||||
(operator == "contains", str(value).lower() in str(input).lower()),
|
||||
(operator == "not contains", str(value).lower() not in str(input).lower()),
|
||||
(operator == "in", str(input).lower() in str(value).lower()),
|
||||
(operator == "not in", str(input).lower() not in str(value).lower()),
|
||||
(operator == "start with", str(input).lower().startswith(str(value).lower())),
|
||||
(operator == "end with", str(input).lower().endswith(str(value).lower())),
|
||||
(operator == "contains", input in value if not isinstance(input, list) else all([i in value for i in input])),
|
||||
(operator == "not contains", input not in value if not isinstance(input, list) else all([i not in value for i in input])),
|
||||
(operator == "in", input in value if not isinstance(input, list) else all([i in value for i in input])),
|
||||
(operator == "not in", input not in value if not isinstance(input, list) else all([i not in value for i in input])),
|
||||
(operator == "start with", str(input).lower().startswith(str(value).lower()) if not isinstance(input, list) else "".join([str(i).lower() for i in input]).startswith(str(value).lower())),
|
||||
(operator == "end with", str(input).lower().endswith(str(value).lower()) if not isinstance(input, list) else "".join([str(i).lower() for i in input]).endswith(str(value).lower())),
|
||||
(operator == "empty", not input),
|
||||
(operator == "not empty", input),
|
||||
(operator == "=", input == value),
|
||||
@ -145,6 +151,18 @@ async def apply_meta_data_filter(
|
||||
return doc_ids
|
||||
|
||||
|
||||
def dedupe_list(values: list) -> list:
|
||||
seen = set()
|
||||
deduped = []
|
||||
for item in values:
|
||||
key = str(item)
|
||||
if key in seen:
|
||||
continue
|
||||
seen.add(key)
|
||||
deduped.append(item)
|
||||
return deduped
|
||||
|
||||
|
||||
def update_metadata_to(metadata, meta):
|
||||
if not meta:
|
||||
return metadata
|
||||
@ -156,11 +174,13 @@ def update_metadata_to(metadata, meta):
|
||||
return metadata
|
||||
if not isinstance(meta, dict):
|
||||
return metadata
|
||||
|
||||
for k, v in meta.items():
|
||||
if isinstance(v, list):
|
||||
v = [vv for vv in v if isinstance(vv, str)]
|
||||
if not v:
|
||||
continue
|
||||
v = dedupe_list(v)
|
||||
if not isinstance(v, list) and not isinstance(v, str):
|
||||
continue
|
||||
if k not in metadata:
|
||||
@ -171,6 +191,7 @@ def update_metadata_to(metadata, meta):
|
||||
metadata[k].extend(v)
|
||||
else:
|
||||
metadata[k].append(v)
|
||||
metadata[k] = dedupe_list(metadata[k])
|
||||
else:
|
||||
metadata[k] = v
|
||||
|
||||
@ -202,4 +223,4 @@ def metadata_schema(metadata: list|None) -> Dict[str, Any]:
|
||||
}
|
||||
|
||||
json_schema["additionalProperties"] = False
|
||||
return json_schema
|
||||
return json_schema
|
||||
|
||||
90
docs/guides/agent/agent_component_reference/http.md
Normal file
90
docs/guides/agent/agent_component_reference/http.md
Normal file
@ -0,0 +1,90 @@
|
||||
---
|
||||
sidebar_position: 30
|
||||
slug: /http_request_component
|
||||
---
|
||||
|
||||
# HTTP request component
|
||||
|
||||
A component that calls remote services.
|
||||
|
||||
---
|
||||
|
||||
An **HTTP request** component lets you access remote APIs or services by providing a URL and an HTTP method, and then receive the response. You can customize headers, parameters, proxies, and timeout settings, and use common methods like GET and POST. It’s useful for exchanging data with external systems in a workflow.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- An accessible remote API or service.
|
||||
- Add a Token or credentials to the request header, if the target service requires authentication.
|
||||
|
||||
## Configurations
|
||||
|
||||
### Url
|
||||
|
||||
*Required*. The complete request address, for example: http://api.example.com/data.
|
||||
|
||||
### Method
|
||||
|
||||
The HTTP request method to select. Available options:
|
||||
|
||||
- GET
|
||||
- POST
|
||||
- PUT
|
||||
|
||||
### Timeout
|
||||
|
||||
The maximum waiting time for the request, in seconds. Defaults to `60`.
|
||||
|
||||
### Headers
|
||||
|
||||
Custom HTTP headers can be set here, for example:
|
||||
|
||||
```http
|
||||
{
|
||||
"Accept": "application/json",
|
||||
"Cache-Control": "no-cache",
|
||||
"Connection": "keep-alive"
|
||||
}
|
||||
```
|
||||
|
||||
### Proxy
|
||||
|
||||
Optional. The proxy server address to use for this request.
|
||||
|
||||
### Clean HTML
|
||||
|
||||
`Boolean`: Whether to remove HTML tags from the returned results and keep plain text only.
|
||||
|
||||
### Parameter
|
||||
|
||||
*Optional*. Parameters to send with the HTTP request. Supports key-value pairs:
|
||||
|
||||
- To assign a value using a dynamic system variable, set it as Variable.
|
||||
- To override these dynamic values under certain conditions and use a fixed static value instead, Value is the appropriate choice.
|
||||
|
||||
|
||||
:::tip NOTE
|
||||
- For GET requests, these parameters are appended to the end of the URL.
|
||||
- For POST/PUT requests, they are sent as the request body.
|
||||
:::
|
||||
|
||||
#### Example setting
|
||||
|
||||

|
||||
|
||||
#### Example response
|
||||
|
||||
```html
|
||||
{ "args": { "App": "RAGFlow", "Query": "How to do?", "Userid": "241ed25a8e1011f0b979424ebc5b108b" }, "headers": { "Accept": "/", "Accept-Encoding": "gzip, deflate, br, zstd", "Cache-Control": "no-cache", "Host": "httpbin.org", "User-Agent": "python-requests/2.32.2", "X-Amzn-Trace-Id": "Root=1-68c9210c-5aab9088580c130a2f065523" }, "origin": "185.36.193.38", "url": "https://httpbin.org/get?Userid=241ed25a8e1011f0b979424ebc5b108b&App=RAGFlow&Query=How+to+do%3F" }
|
||||
```
|
||||
|
||||
### Output
|
||||
|
||||
The global variable name for the output of the HTTP request component, which can be referenced by other components in the workflow.
|
||||
|
||||
- `Result`: `string` The response returned by the remote service.
|
||||
|
||||
## Example
|
||||
|
||||
This is a usage example: a workflow sends a GET request from the **Begin** component to `https://httpbin.org/get` via the **HTTP Request_0** component, passes parameters to the server, and finally outputs the result through the **Message_0** component.
|
||||
|
||||

|
||||
@ -348,7 +348,8 @@ def tokenize_table(tbls, doc, eng, batch_size=10):
|
||||
d["doc_type_kwd"] = "table"
|
||||
if img:
|
||||
d["image"] = img
|
||||
d["doc_type_kwd"] = "image"
|
||||
if d["content_with_weight"].find("<tr>") < 0:
|
||||
d["doc_type_kwd"] = "image"
|
||||
if poss:
|
||||
add_positions(d, poss)
|
||||
res.append(d)
|
||||
@ -361,7 +362,8 @@ def tokenize_table(tbls, doc, eng, batch_size=10):
|
||||
d["doc_type_kwd"] = "table"
|
||||
if img:
|
||||
d["image"] = img
|
||||
d["doc_type_kwd"] = "image"
|
||||
if d["content_with_weight"].find("<tr>") < 0:
|
||||
d["doc_type_kwd"] = "image"
|
||||
add_positions(d, poss)
|
||||
res.append(d)
|
||||
return res
|
||||
|
||||
@ -339,7 +339,7 @@ def tool_schema(tools_description: list[dict], complete_task=False):
|
||||
}
|
||||
for idx, tool in enumerate(tools_description):
|
||||
name = tool["function"]["name"]
|
||||
desc[f"{name}_{idx}"] = tool
|
||||
desc[name] = tool
|
||||
|
||||
return "\n\n".join([f"## {i+1}. {fnm}\n{json.dumps(des, ensure_ascii=False, indent=4)}" for i, (fnm, des) in enumerate(desc.items())])
|
||||
|
||||
|
||||
@ -94,7 +94,7 @@ This content will NOT be shown to the user.
|
||||
## Step 2: Structured Reflection (MANDATORY before `complete_task`)
|
||||
|
||||
### Context
|
||||
- Goal: {{ task_analysis }}
|
||||
- Goal: Reflect on the current task based on the full conversation context
|
||||
- Executed tool calls so far (if any): reflect from conversation history
|
||||
|
||||
### Task Complexity Assessment
|
||||
|
||||
@ -395,9 +395,9 @@ async def build_chunks(task, progress_callback):
|
||||
await asyncio.gather(*tasks, return_exceptions=True)
|
||||
raise
|
||||
metadata = {}
|
||||
for ck in cks:
|
||||
metadata = update_metadata_to(metadata, ck["metadata_obj"])
|
||||
del ck["metadata_obj"]
|
||||
for doc in docs:
|
||||
metadata = update_metadata_to(metadata, doc["metadata_obj"])
|
||||
del doc["metadata_obj"]
|
||||
if metadata:
|
||||
e, doc = DocumentService.get_by_id(task["doc_id"])
|
||||
if e:
|
||||
|
||||
@ -35,6 +35,7 @@ import { cn } from '@/lib/utils';
|
||||
import { t } from 'i18next';
|
||||
import { Loader } from 'lucide-react';
|
||||
import { MultiSelect, MultiSelectOptionType } from './ui/multi-select';
|
||||
import { Switch } from './ui/switch';
|
||||
|
||||
// Field type enumeration
|
||||
export enum FormFieldType {
|
||||
@ -46,6 +47,7 @@ export enum FormFieldType {
|
||||
Select = 'select',
|
||||
MultiSelect = 'multi-select',
|
||||
Checkbox = 'checkbox',
|
||||
Switch = 'switch',
|
||||
Tag = 'tag',
|
||||
Custom = 'custom',
|
||||
}
|
||||
@ -154,6 +156,7 @@ export const generateSchema = (fields: FormFieldConfig[]): ZodSchema<any> => {
|
||||
}
|
||||
break;
|
||||
case FormFieldType.Checkbox:
|
||||
case FormFieldType.Switch:
|
||||
fieldSchema = z.boolean();
|
||||
break;
|
||||
case FormFieldType.Tag:
|
||||
@ -193,6 +196,8 @@ export const generateSchema = (fields: FormFieldConfig[]): ZodSchema<any> => {
|
||||
if (
|
||||
field.type !== FormFieldType.Number &&
|
||||
field.type !== FormFieldType.Checkbox &&
|
||||
field.type !== FormFieldType.Switch &&
|
||||
field.type !== FormFieldType.Custom &&
|
||||
field.type !== FormFieldType.Tag &&
|
||||
field.required
|
||||
) {
|
||||
@ -289,7 +294,10 @@ const generateDefaultValues = <T extends FieldValues>(
|
||||
const lastKey = keys[keys.length - 1];
|
||||
if (field.defaultValue !== undefined) {
|
||||
current[lastKey] = field.defaultValue;
|
||||
} else if (field.type === FormFieldType.Checkbox) {
|
||||
} else if (
|
||||
field.type === FormFieldType.Checkbox ||
|
||||
field.type === FormFieldType.Switch
|
||||
) {
|
||||
current[lastKey] = false;
|
||||
} else if (field.type === FormFieldType.Tag) {
|
||||
current[lastKey] = [];
|
||||
@ -299,7 +307,10 @@ const generateDefaultValues = <T extends FieldValues>(
|
||||
} else {
|
||||
if (field.defaultValue !== undefined) {
|
||||
defaultValues[field.name] = field.defaultValue;
|
||||
} else if (field.type === FormFieldType.Checkbox) {
|
||||
} else if (
|
||||
field.type === FormFieldType.Checkbox ||
|
||||
field.type === FormFieldType.Switch
|
||||
) {
|
||||
defaultValues[field.name] = false;
|
||||
} else if (
|
||||
field.type === FormFieldType.Tag ||
|
||||
@ -502,6 +513,32 @@ export const RenderField = ({
|
||||
)}
|
||||
/>
|
||||
);
|
||||
case FormFieldType.Switch:
|
||||
return (
|
||||
<RAGFlowFormItem
|
||||
{...field}
|
||||
labelClassName={labelClassName || field.labelClassName}
|
||||
>
|
||||
{(fieldProps) => {
|
||||
const finalFieldProps = field.onChange
|
||||
? {
|
||||
...fieldProps,
|
||||
onChange: (checked: boolean) => {
|
||||
fieldProps.onChange(checked);
|
||||
field.onChange?.(checked);
|
||||
},
|
||||
}
|
||||
: fieldProps;
|
||||
return (
|
||||
<Switch
|
||||
checked={finalFieldProps.value as boolean}
|
||||
onCheckedChange={(checked) => finalFieldProps.onChange(checked)}
|
||||
disabled={field.disabled}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
</RAGFlowFormItem>
|
||||
);
|
||||
|
||||
case FormFieldType.Tag:
|
||||
return (
|
||||
|
||||
@ -31,14 +31,16 @@ const handleCheckChange = ({
|
||||
(value: string) => value !== item.id.toString(),
|
||||
);
|
||||
|
||||
const newValue = {
|
||||
...currentValue,
|
||||
[parentId]: newParentValues,
|
||||
};
|
||||
const newValue = newParentValues?.length
|
||||
? {
|
||||
...currentValue,
|
||||
[parentId]: newParentValues,
|
||||
}
|
||||
: { ...currentValue };
|
||||
|
||||
if (newValue[parentId].length === 0) {
|
||||
delete newValue[parentId];
|
||||
}
|
||||
// if (newValue[parentId].length === 0) {
|
||||
// delete newValue[parentId];
|
||||
// }
|
||||
|
||||
return field.onChange(newValue);
|
||||
} else {
|
||||
@ -66,20 +68,31 @@ const FilterItem = memo(
|
||||
}) => {
|
||||
return (
|
||||
<div
|
||||
className={`flex items-center justify-between text-text-primary text-xs ${level > 0 ? 'ml-4' : ''}`}
|
||||
className={`flex items-center justify-between text-text-primary text-xs ${level > 0 ? 'ml-1' : ''}`}
|
||||
>
|
||||
<FormItem className="flex flex-row space-x-3 space-y-0 items-center">
|
||||
<FormItem className="flex flex-row space-x-3 space-y-0 items-center ">
|
||||
<FormControl>
|
||||
<Checkbox
|
||||
checked={field.value?.includes(item.id.toString())}
|
||||
onCheckedChange={(checked: boolean) =>
|
||||
handleCheckChange({ checked, field, item })
|
||||
}
|
||||
/>
|
||||
<div className="flex space-x-3">
|
||||
<Checkbox
|
||||
checked={field.value?.includes(item.id.toString())}
|
||||
onCheckedChange={(checked: boolean) =>
|
||||
handleCheckChange({ checked, field, item })
|
||||
}
|
||||
// className="hidden group-hover:block"
|
||||
/>
|
||||
<FormLabel
|
||||
onClick={() =>
|
||||
handleCheckChange({
|
||||
checked: !field.value?.includes(item.id.toString()),
|
||||
field,
|
||||
item,
|
||||
})
|
||||
}
|
||||
>
|
||||
{item.label}
|
||||
</FormLabel>
|
||||
</div>
|
||||
</FormControl>
|
||||
<FormLabel onClick={(e) => e.stopPropagation()}>
|
||||
{item.label}
|
||||
</FormLabel>
|
||||
</FormItem>
|
||||
{item.count !== undefined && (
|
||||
<span className="text-sm">{item.count}</span>
|
||||
@ -107,11 +120,11 @@ export const FilterField = memo(
|
||||
<FormField
|
||||
key={item.id}
|
||||
control={form.control}
|
||||
name={parent.field as string}
|
||||
name={parent.field?.toString() as string}
|
||||
render={({ field }) => {
|
||||
if (hasNestedList) {
|
||||
return (
|
||||
<div className={`flex flex-col gap-2 ${level > 0 ? 'ml-4' : ''}`}>
|
||||
<div className={`flex flex-col gap-2 ${level > 0 ? 'ml-1' : ''}`}>
|
||||
<div
|
||||
className="flex items-center justify-between cursor-pointer"
|
||||
onClick={() => {
|
||||
@ -138,23 +151,6 @@ export const FilterField = memo(
|
||||
}}
|
||||
level={level + 1}
|
||||
/>
|
||||
// <FilterItem key={child.id} item={child} field={child.field} level={level+1} />
|
||||
// <div
|
||||
// className="flex flex-row space-x-3 space-y-0 items-center"
|
||||
// key={child.id}
|
||||
// >
|
||||
// <FormControl>
|
||||
// <Checkbox
|
||||
// checked={field.value?.includes(child.id.toString())}
|
||||
// onCheckedChange={(checked) =>
|
||||
// handleCheckChange({ checked, field, item: child })
|
||||
// }
|
||||
// />
|
||||
// </FormControl>
|
||||
// <FormLabel onClick={(e) => e.stopPropagation()}>
|
||||
// {child.label}
|
||||
// </FormLabel>
|
||||
// </div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -11,7 +11,7 @@ import {
|
||||
useMemo,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { FieldPath, useForm } from 'react-hook-form';
|
||||
import { ZodArray, ZodString, z } from 'zod';
|
||||
|
||||
import { Button } from '@/components/ui/button';
|
||||
@ -178,7 +178,9 @@ function CheckboxFormMultiple({
|
||||
<FormField
|
||||
key={x.field}
|
||||
control={form.control}
|
||||
name={x.field}
|
||||
name={
|
||||
x.field.toString() as FieldPath<z.infer<typeof FormSchema>>
|
||||
}
|
||||
render={() => (
|
||||
<FormItem className="space-y-4">
|
||||
<div>
|
||||
@ -186,19 +188,20 @@ function CheckboxFormMultiple({
|
||||
{x.label}
|
||||
</FormLabel>
|
||||
</div>
|
||||
{x.list.map((item) => {
|
||||
return (
|
||||
<FilterField
|
||||
key={item.id}
|
||||
item={{ ...item }}
|
||||
parent={{
|
||||
...x,
|
||||
id: x.field,
|
||||
// field: `${x.field}${item.field ? '.' + item.field : ''}`,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
{x.list?.length &&
|
||||
x.list.map((item) => {
|
||||
return (
|
||||
<FilterField
|
||||
key={item.id}
|
||||
item={{ ...item }}
|
||||
parent={{
|
||||
...x,
|
||||
id: x.field,
|
||||
// field: `${x.field}${item.field ? '.' + item.field : ''}`,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
|
||||
@ -176,6 +176,11 @@ Procedural Memory: Learned skills, habits, and automated procedures.`,
|
||||
},
|
||||
knowledgeDetails: {
|
||||
metadata: {
|
||||
valueExists:
|
||||
'Value already exists. Confirm to merge duplicates and combine all associated files.',
|
||||
fieldNameExists:
|
||||
'Field name already exists. Confirm to merge duplicates and combine all associated files.',
|
||||
fieldExists: 'Field already exists.',
|
||||
fieldSetting: 'Field settings',
|
||||
changesAffectNewParses: 'Changes affect new parses only.',
|
||||
editMetadataForDataset: 'View and edit metadata for ',
|
||||
@ -190,6 +195,7 @@ Procedural Memory: Learned skills, habits, and automated procedures.`,
|
||||
description: 'Description',
|
||||
fieldName: 'Field name',
|
||||
editMetadata: 'Edit metadata',
|
||||
deleteWarn: 'This {{field}} will be removed from all associated files',
|
||||
},
|
||||
metadataField: 'Metadata field',
|
||||
systemAttribute: 'System attribute',
|
||||
|
||||
@ -182,6 +182,10 @@ export default {
|
||||
description: '描述',
|
||||
fieldName: '字段名',
|
||||
editMetadata: '编辑元数据',
|
||||
valueExists: '值已存在。确认合并重复项并组合所有关联文件。',
|
||||
fieldNameExists: '字段名已存在。确认合并重复项并组合所有关联文件。',
|
||||
fieldExists: '字段名已存在。',
|
||||
deleteWarn: '此 {{field}} 将从所有关联文件中移除',
|
||||
},
|
||||
localUpload: '本地上传',
|
||||
fileSize: '文件大小',
|
||||
|
||||
@ -4,6 +4,7 @@ import { useSendAgentMessage } from './use-send-agent-message';
|
||||
|
||||
import { FileUploadProps } from '@/components/file-upload';
|
||||
import { NextMessageInput } from '@/components/message-input/next';
|
||||
import MarkdownContent from '@/components/next-markdown-content';
|
||||
import MessageItem from '@/components/next-message-item';
|
||||
import PdfSheet from '@/components/pdf-drawer';
|
||||
import { useClickDrawer } from '@/components/pdf-drawer/hooks';
|
||||
@ -102,8 +103,10 @@ function AgentChatBox() {
|
||||
{message.role === MessageType.Assistant &&
|
||||
derivedMessages.length - 1 !== i && (
|
||||
<div>
|
||||
<div>{message?.data?.tips}</div>
|
||||
|
||||
<MarkdownContent
|
||||
content={message?.data?.tips}
|
||||
loading={false}
|
||||
></MarkdownContent>
|
||||
<div>
|
||||
{buildInputList(message)?.map((item) => item.value)}
|
||||
</div>
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import MarkdownContent from '@/components/next-markdown-content';
|
||||
import { ButtonLoading } from '@/components/ui/button';
|
||||
import {
|
||||
Form,
|
||||
@ -234,7 +235,14 @@ const DebugContent = ({
|
||||
return (
|
||||
<>
|
||||
<section>
|
||||
{message?.data?.tips && <div className="mb-2">{message.data.tips}</div>}
|
||||
{message?.data?.tips && (
|
||||
<div className="mb-2">
|
||||
<MarkdownContent
|
||||
content={message?.data?.tips}
|
||||
loading={false}
|
||||
></MarkdownContent>
|
||||
</div>
|
||||
)}
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
|
||||
{parameters.map((x, idx) => {
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
import message from '@/components/ui/message';
|
||||
import { useSetModalState } from '@/hooks/common-hooks';
|
||||
import { useSetDocumentMeta } from '@/hooks/use-document-request';
|
||||
import {
|
||||
DocumentApiAction,
|
||||
useSetDocumentMeta,
|
||||
} from '@/hooks/use-document-request';
|
||||
import kbService, {
|
||||
getMetaDataService,
|
||||
updateMetaData,
|
||||
} from '@/services/knowledge-service';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useParams } from 'umi';
|
||||
@ -191,7 +194,7 @@ export const useManageMetaDataModal = (
|
||||
const { data, loading } = useFetchMetaDataManageData(type);
|
||||
|
||||
const [tableData, setTableData] = useState<IMetaDataTableData[]>(metaData);
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
const { operations, addDeleteRow, addDeleteValue, addUpdateValue } =
|
||||
useMetadataOperations();
|
||||
|
||||
@ -259,11 +262,14 @@ export const useManageMetaDataModal = (
|
||||
data: operations,
|
||||
});
|
||||
if (res.code === 0) {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: [DocumentApiAction.FetchDocumentList],
|
||||
});
|
||||
message.success(t('message.operated'));
|
||||
callback();
|
||||
}
|
||||
},
|
||||
[operations, id, t],
|
||||
[operations, id, t, queryClient],
|
||||
);
|
||||
|
||||
const handleSaveUpdateSingle = useCallback(
|
||||
|
||||
@ -39,6 +39,7 @@ export type IManageModalProps = {
|
||||
|
||||
export interface IManageValuesProps {
|
||||
title: ReactNode;
|
||||
existsKeys: string[];
|
||||
visible: boolean;
|
||||
isEditField?: boolean;
|
||||
isAddValue?: boolean;
|
||||
@ -46,6 +47,7 @@ export interface IManageValuesProps {
|
||||
isShowValueSwitch?: boolean;
|
||||
isVerticalShowValue?: boolean;
|
||||
data: IMetaDataTableData;
|
||||
type: MetadataType;
|
||||
hideModal: () => void;
|
||||
onSave: (data: IMetaDataTableData) => void;
|
||||
addUpdateValue: (key: string, value: string | string[]) => void;
|
||||
|
||||
@ -54,6 +54,7 @@ export const ManageMetadataModal = (props: IManageModalProps) => {
|
||||
values: [],
|
||||
});
|
||||
|
||||
const [currentValueIndex, setCurrentValueIndex] = useState<number>(0);
|
||||
const [deleteDialogContent, setDeleteDialogContent] = useState({
|
||||
visible: false,
|
||||
title: '',
|
||||
@ -94,12 +95,12 @@ export const ManageMetadataModal = (props: IManageModalProps) => {
|
||||
description: '',
|
||||
values: [],
|
||||
});
|
||||
// setCurrentValueIndex(tableData.length || 0);
|
||||
setCurrentValueIndex(tableData.length || 0);
|
||||
showManageValuesModal();
|
||||
};
|
||||
const handleEditValueRow = useCallback(
|
||||
(data: IMetaDataTableData) => {
|
||||
// setCurrentValueIndex(index);
|
||||
(data: IMetaDataTableData, index: number) => {
|
||||
setCurrentValueIndex(index);
|
||||
setValueData(data);
|
||||
showManageValuesModal();
|
||||
},
|
||||
@ -153,10 +154,33 @@ export const ManageMetadataModal = (props: IManageModalProps) => {
|
||||
variant={'delete'}
|
||||
className="p-0 bg-transparent"
|
||||
onClick={() => {
|
||||
handleDeleteSingleValue(
|
||||
row.getValue('field'),
|
||||
value,
|
||||
);
|
||||
setDeleteDialogContent({
|
||||
visible: true,
|
||||
title:
|
||||
t('common.delete') +
|
||||
' ' +
|
||||
t('knowledgeDetails.metadata.metadata'),
|
||||
name: row.getValue('field') + '/' + value,
|
||||
warnText: t(
|
||||
'knowledgeDetails.metadata.deleteWarn',
|
||||
{
|
||||
field:
|
||||
t('knowledgeDetails.metadata.field') +
|
||||
'/' +
|
||||
t('knowledgeDetails.metadata.values'),
|
||||
},
|
||||
),
|
||||
onOk: () => {
|
||||
hideDeleteModal();
|
||||
handleDeleteSingleValue(
|
||||
row.getValue('field'),
|
||||
value,
|
||||
);
|
||||
},
|
||||
onCancel: () => {
|
||||
hideDeleteModal();
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Trash2 />
|
||||
@ -185,7 +209,7 @@ export const ManageMetadataModal = (props: IManageModalProps) => {
|
||||
variant={'ghost'}
|
||||
className="bg-transparent px-1 py-0"
|
||||
onClick={() => {
|
||||
handleEditValueRow(row.original);
|
||||
handleEditValueRow(row.original, row.index);
|
||||
}}
|
||||
>
|
||||
<Settings />
|
||||
@ -201,7 +225,9 @@ export const ManageMetadataModal = (props: IManageModalProps) => {
|
||||
' ' +
|
||||
t('knowledgeDetails.metadata.metadata'),
|
||||
name: row.getValue('field'),
|
||||
warnText: t('knowledgeDetails.metadata.deleteWarn'),
|
||||
warnText: t('knowledgeDetails.metadata.deleteWarn', {
|
||||
field: t('knowledgeDetails.metadata.field'),
|
||||
}),
|
||||
onOk: () => {
|
||||
hideDeleteModal();
|
||||
handleDeleteSingleRow(row.getValue('field'));
|
||||
@ -243,12 +269,26 @@ export const ManageMetadataModal = (props: IManageModalProps) => {
|
||||
|
||||
const handleSaveValues = (data: IMetaDataTableData) => {
|
||||
setTableData((prev) => {
|
||||
//If the keys are the same, they need to be merged.
|
||||
const fieldMap = new Map<string, any>();
|
||||
let newData;
|
||||
if (currentValueIndex >= prev.length) {
|
||||
// Add operation
|
||||
newData = [...prev, data];
|
||||
} else {
|
||||
// Edit operation
|
||||
newData = prev.map((item, index) => {
|
||||
if (index === currentValueIndex) {
|
||||
return data;
|
||||
}
|
||||
return item;
|
||||
});
|
||||
}
|
||||
|
||||
prev.forEach((item) => {
|
||||
// Deduplicate by field and merge values
|
||||
const fieldMap = new Map<string, IMetaDataTableData>();
|
||||
newData.forEach((item) => {
|
||||
if (fieldMap.has(item.field)) {
|
||||
const existingItem = fieldMap.get(item.field);
|
||||
// Merge values if field exists
|
||||
const existingItem = fieldMap.get(item.field)!;
|
||||
const mergedValues = [
|
||||
...new Set([...existingItem.values, ...item.values]),
|
||||
];
|
||||
@ -258,20 +298,14 @@ export const ManageMetadataModal = (props: IManageModalProps) => {
|
||||
}
|
||||
});
|
||||
|
||||
if (fieldMap.has(data.field)) {
|
||||
const existingItem = fieldMap.get(data.field);
|
||||
const mergedValues = [
|
||||
...new Set([...existingItem.values, ...data.values]),
|
||||
];
|
||||
fieldMap.set(data.field, { ...existingItem, values: mergedValues });
|
||||
} else {
|
||||
fieldMap.set(data.field, data);
|
||||
}
|
||||
|
||||
return Array.from(fieldMap.values());
|
||||
});
|
||||
};
|
||||
|
||||
const existsKeys = useMemo(() => {
|
||||
return tableData.map((item) => item.field);
|
||||
}, [tableData]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal
|
||||
@ -357,6 +391,8 @@ export const ManageMetadataModal = (props: IManageModalProps) => {
|
||||
: t('knowledgeDetails.metadata.editMetadata')}
|
||||
</div>
|
||||
}
|
||||
type={metadataType}
|
||||
existsKeys={existsKeys}
|
||||
visible={manageValuesVisible}
|
||||
hideModal={hideManageValuesModal}
|
||||
data={valueData}
|
||||
|
||||
@ -1,3 +1,7 @@
|
||||
import {
|
||||
ConfirmDeleteDialog,
|
||||
ConfirmDeleteDialogNode,
|
||||
} from '@/components/confirm-delete-dialog';
|
||||
import EditTag from '@/components/edit-tag';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
@ -7,6 +11,7 @@ import { Textarea } from '@/components/ui/textarea';
|
||||
import { Plus, Trash2 } from 'lucide-react';
|
||||
import { memo, useCallback, useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { MetadataType } from './hook';
|
||||
import { IManageValuesProps, IMetaDataTableData } from './interface';
|
||||
|
||||
// Create a separate input component, wrapped with memo to avoid unnecessary re-renders
|
||||
@ -63,17 +68,62 @@ export const ManageValuesModal = (props: IManageValuesProps) => {
|
||||
onSave,
|
||||
addUpdateValue,
|
||||
addDeleteValue,
|
||||
existsKeys,
|
||||
type,
|
||||
} = props;
|
||||
const [metaData, setMetaData] = useState(data);
|
||||
const { t } = useTranslation();
|
||||
const [valueError, setValueError] = useState<Record<string, string>>({
|
||||
field: '',
|
||||
values: '',
|
||||
});
|
||||
const [deleteDialogContent, setDeleteDialogContent] = useState({
|
||||
visible: false,
|
||||
title: '',
|
||||
name: '',
|
||||
warnText: '',
|
||||
onOk: () => {},
|
||||
onCancel: () => {},
|
||||
});
|
||||
const hideDeleteModal = () => {
|
||||
setDeleteDialogContent({
|
||||
visible: false,
|
||||
title: '',
|
||||
name: '',
|
||||
warnText: '',
|
||||
onOk: () => {},
|
||||
onCancel: () => {},
|
||||
});
|
||||
};
|
||||
|
||||
// Use functional update to avoid closure issues
|
||||
const handleChange = useCallback((field: string, value: any) => {
|
||||
setMetaData((prev) => ({
|
||||
...prev,
|
||||
[field]: value,
|
||||
}));
|
||||
}, []);
|
||||
const handleChange = useCallback(
|
||||
(field: string, value: any) => {
|
||||
if (field === 'field' && existsKeys.includes(value)) {
|
||||
setValueError((prev) => {
|
||||
return {
|
||||
...prev,
|
||||
field:
|
||||
type === MetadataType.Setting
|
||||
? t('knowledgeDetails.metadata.fieldExists')
|
||||
: t('knowledgeDetails.metadata.fieldNameExists'),
|
||||
};
|
||||
});
|
||||
} else if (field === 'field' && !existsKeys.includes(value)) {
|
||||
setValueError((prev) => {
|
||||
return {
|
||||
...prev,
|
||||
field: '',
|
||||
};
|
||||
});
|
||||
}
|
||||
setMetaData((prev) => ({
|
||||
...prev,
|
||||
[field]: value,
|
||||
}));
|
||||
},
|
||||
[existsKeys, type, t],
|
||||
);
|
||||
|
||||
// Maintain separate state for each input box
|
||||
const [tempValues, setTempValues] = useState<string[]>([...data.values]);
|
||||
@ -89,6 +139,9 @@ export const ManageValuesModal = (props: IManageValuesProps) => {
|
||||
}, [hideModal]);
|
||||
|
||||
const handleSave = useCallback(() => {
|
||||
if (type === MetadataType.Setting && valueError.field) {
|
||||
return;
|
||||
}
|
||||
if (!metaData.restrictDefinedValues && isShowValueSwitch) {
|
||||
const newMetaData = { ...metaData, values: [] };
|
||||
onSave(newMetaData);
|
||||
@ -96,17 +149,35 @@ export const ManageValuesModal = (props: IManageValuesProps) => {
|
||||
onSave(metaData);
|
||||
}
|
||||
handleHideModal();
|
||||
}, [metaData, onSave, handleHideModal, isShowValueSwitch]);
|
||||
}, [metaData, onSave, handleHideModal, isShowValueSwitch, type, valueError]);
|
||||
|
||||
// Handle value changes, only update temporary state
|
||||
const handleValueChange = useCallback((index: number, value: string) => {
|
||||
setTempValues((prev) => {
|
||||
const newValues = [...prev];
|
||||
newValues[index] = value;
|
||||
const handleValueChange = useCallback(
|
||||
(index: number, value: string) => {
|
||||
setTempValues((prev) => {
|
||||
if (prev.includes(value)) {
|
||||
setValueError((prev) => {
|
||||
return {
|
||||
...prev,
|
||||
values: t('knowledgeDetails.metadata.valueExists'),
|
||||
};
|
||||
});
|
||||
} else {
|
||||
setValueError((prev) => {
|
||||
return {
|
||||
...prev,
|
||||
values: '',
|
||||
};
|
||||
});
|
||||
}
|
||||
const newValues = [...prev];
|
||||
newValues[index] = value;
|
||||
|
||||
return newValues;
|
||||
});
|
||||
}, []);
|
||||
return newValues;
|
||||
});
|
||||
},
|
||||
[t],
|
||||
);
|
||||
|
||||
// Handle blur event, synchronize to main state
|
||||
const handleValueBlur = useCallback(() => {
|
||||
@ -137,6 +208,27 @@ export const ManageValuesModal = (props: IManageValuesProps) => {
|
||||
[addDeleteValue, metaData],
|
||||
);
|
||||
|
||||
const showDeleteModal = (item: string, callback: () => void) => {
|
||||
setDeleteDialogContent({
|
||||
visible: true,
|
||||
title: t('common.delete') + ' ' + t('knowledgeDetails.metadata.metadata'),
|
||||
name: metaData.field + '/' + item,
|
||||
warnText: t('knowledgeDetails.metadata.deleteWarn', {
|
||||
field:
|
||||
t('knowledgeDetails.metadata.field') +
|
||||
'/' +
|
||||
t('knowledgeDetails.metadata.values'),
|
||||
}),
|
||||
onOk: () => {
|
||||
hideDeleteModal();
|
||||
callback();
|
||||
},
|
||||
onCancel: () => {
|
||||
hideDeleteModal();
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
// Handle adding new value
|
||||
const handleAddValue = useCallback(() => {
|
||||
setTempValues((prev) => [...new Set([...prev, ''])]);
|
||||
@ -172,9 +264,13 @@ export const ManageValuesModal = (props: IManageValuesProps) => {
|
||||
<Input
|
||||
value={metaData.field}
|
||||
onChange={(e) => {
|
||||
handleChange('field', e.target?.value || '');
|
||||
const value = e.target?.value || '';
|
||||
if (/^[a-zA-Z_]*$/.test(value)) {
|
||||
handleChange('field', value);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<div className="text-state-error text-sm">{valueError.field}</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@ -230,7 +326,11 @@ export const ManageValuesModal = (props: IManageValuesProps) => {
|
||||
item={item}
|
||||
index={index}
|
||||
onValueChange={handleValueChange}
|
||||
onDelete={handleDelete}
|
||||
onDelete={(idx: number) => {
|
||||
showDeleteModal(item, () => {
|
||||
handleDelete(idx);
|
||||
});
|
||||
}}
|
||||
onBlur={handleValueBlur}
|
||||
/>
|
||||
);
|
||||
@ -240,11 +340,41 @@ export const ManageValuesModal = (props: IManageValuesProps) => {
|
||||
{!isVerticalShowValue && (
|
||||
<EditTag
|
||||
value={metaData.values}
|
||||
onChange={(value) => handleChange('values', value)}
|
||||
onChange={(value) => {
|
||||
// find deleted value
|
||||
const item = metaData.values.find(
|
||||
(item) => !value.includes(item),
|
||||
);
|
||||
if (item) {
|
||||
showDeleteModal(item, () => {
|
||||
// handleDelete(idx);
|
||||
handleChange('values', value);
|
||||
});
|
||||
} else {
|
||||
handleChange('values', value);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<div className="text-state-error text-sm">{valueError.values}</div>
|
||||
</div>
|
||||
)}
|
||||
{deleteDialogContent.visible && (
|
||||
<ConfirmDeleteDialog
|
||||
open={deleteDialogContent.visible}
|
||||
onCancel={deleteDialogContent.onCancel}
|
||||
onOk={deleteDialogContent.onOk}
|
||||
title={deleteDialogContent.title}
|
||||
content={{
|
||||
node: (
|
||||
<ConfirmDeleteDialogNode
|
||||
name={deleteDialogContent.name}
|
||||
warnText={deleteDialogContent.warnText}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
|
||||
@ -17,6 +17,7 @@ import {
|
||||
} from '@/components/ui/form';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { FormLayout } from '@/constants/form';
|
||||
import { useFetchTenantInfo } from '@/hooks/use-user-setting-request';
|
||||
import { IModalProps } from '@/interfaces/common';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { useEffect } from 'react';
|
||||
@ -33,6 +34,7 @@ const FormId = 'dataset-creating-form';
|
||||
|
||||
export function InputForm({ onOk }: IModalProps<any>) {
|
||||
const { t } = useTranslation();
|
||||
const { data: tenantInfo } = useFetchTenantInfo();
|
||||
|
||||
const FormSchema = z
|
||||
.object({
|
||||
@ -80,7 +82,7 @@ export function InputForm({ onOk }: IModalProps<any>) {
|
||||
name: '',
|
||||
parseType: 1,
|
||||
parser_id: '',
|
||||
embd_id: '',
|
||||
embd_id: tenantInfo?.embd_id,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@ -263,7 +263,7 @@ export const documentFilter = (kb_id: string) =>
|
||||
export const getMetaDataService = ({ kb_id }: { kb_id: string }) =>
|
||||
request.post(api.getMetaData, { data: { kb_id } });
|
||||
export const updateMetaData = ({ kb_id, data }: { kb_id: string; data: any }) =>
|
||||
request.post(api.updateMetaData, { data: { kb_id, data } });
|
||||
request.post(api.updateMetaData, { data: { kb_id, ...data } });
|
||||
|
||||
export const listDataPipelineLogDocument = (
|
||||
params?: IFetchKnowledgeListRequestParams,
|
||||
|
||||
Reference in New Issue
Block a user