mirror of
https://github.com/langgenius/dify.git
synced 2024-11-16 11:42:29 +08:00
merge main
This commit is contained in:
commit
a9de7f24a2
1
.github/workflows/db-migration-test.yml
vendored
1
.github/workflows/db-migration-test.yml
vendored
|
@ -6,6 +6,7 @@ on:
|
|||
- main
|
||||
paths:
|
||||
- api/migrations/**
|
||||
- .github/workflows/db-migration-test.yml
|
||||
|
||||
concurrency:
|
||||
group: db-migration-test-${{ github.ref }}
|
||||
|
|
|
@ -285,8 +285,9 @@ UPLOAD_IMAGE_FILE_SIZE_LIMIT=10
|
|||
UPLOAD_VIDEO_FILE_SIZE_LIMIT=100
|
||||
UPLOAD_AUDIO_FILE_SIZE_LIMIT=50
|
||||
|
||||
# Model Configuration
|
||||
# Model configuration
|
||||
MULTIMODAL_SEND_IMAGE_FORMAT=base64
|
||||
MULTIMODAL_SEND_VIDEO_FORMAT=base64
|
||||
PROMPT_GENERATION_MAX_TOKENS=512
|
||||
CODE_GENERATION_MAX_TOKENS=1024
|
||||
|
||||
|
@ -324,10 +325,10 @@ UNSTRUCTURED_API_KEY=
|
|||
SSRF_PROXY_HTTP_URL=
|
||||
SSRF_PROXY_HTTPS_URL=
|
||||
SSRF_DEFAULT_MAX_RETRIES=3
|
||||
SSRF_DEFAULT_TIME_OUT=
|
||||
SSRF_DEFAULT_CONNECT_TIME_OUT=
|
||||
SSRF_DEFAULT_READ_TIME_OUT=
|
||||
SSRF_DEFAULT_WRITE_TIME_OUT=
|
||||
SSRF_DEFAULT_TIME_OUT=5
|
||||
SSRF_DEFAULT_CONNECT_TIME_OUT=5
|
||||
SSRF_DEFAULT_READ_TIME_OUT=5
|
||||
SSRF_DEFAULT_WRITE_TIME_OUT=5
|
||||
|
||||
BATCH_UPLOAD_LIMIT=10
|
||||
KEYWORD_DATA_SOURCE_TYPE=database
|
||||
|
|
|
@ -2,7 +2,7 @@ import os
|
|||
|
||||
from configs import dify_config
|
||||
|
||||
if os.environ.get("DEBUG", "false").lower() != "true":
|
||||
if not dify_config.DEBUG:
|
||||
from gevent import monkey
|
||||
|
||||
monkey.patch_all()
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import os
|
||||
|
||||
if os.environ.get("DEBUG", "false").lower() != "true":
|
||||
from configs import dify_config
|
||||
|
||||
if not dify_config.DEBUG:
|
||||
from gevent import monkey
|
||||
|
||||
monkey.patch_all()
|
||||
|
|
|
@ -276,6 +276,16 @@ class HttpConfig(BaseSettings):
|
|||
default=1 * 1024 * 1024,
|
||||
)
|
||||
|
||||
SSRF_DEFAULT_MAX_RETRIES: PositiveInt = Field(
|
||||
description="Maximum number of retries for network requests (SSRF)",
|
||||
default=3,
|
||||
)
|
||||
|
||||
SSRF_PROXY_ALL_URL: Optional[str] = Field(
|
||||
description="Proxy URL for HTTP or HTTPS requests to prevent Server-Side Request Forgery (SSRF)",
|
||||
default=None,
|
||||
)
|
||||
|
||||
SSRF_PROXY_HTTP_URL: Optional[str] = Field(
|
||||
description="Proxy URL for HTTP requests to prevent Server-Side Request Forgery (SSRF)",
|
||||
default=None,
|
||||
|
@ -624,12 +634,17 @@ class IndexingConfig(BaseSettings):
|
|||
)
|
||||
|
||||
|
||||
class ImageFormatConfig(BaseSettings):
|
||||
class VisionFormatConfig(BaseSettings):
|
||||
MULTIMODAL_SEND_IMAGE_FORMAT: Literal["base64", "url"] = Field(
|
||||
description="Format for sending images in multimodal contexts ('base64' or 'url'), default is base64",
|
||||
default="base64",
|
||||
)
|
||||
|
||||
MULTIMODAL_SEND_VIDEO_FORMAT: Literal["base64", "url"] = Field(
|
||||
description="Format for sending videos in multimodal contexts ('base64' or 'url'), default is base64",
|
||||
default="base64",
|
||||
)
|
||||
|
||||
|
||||
class CeleryBeatConfig(BaseSettings):
|
||||
CELERY_BEAT_SCHEDULER_TIME: int = Field(
|
||||
|
@ -732,7 +747,7 @@ class FeatureConfig(
|
|||
FileAccessConfig,
|
||||
FileUploadConfig,
|
||||
HttpConfig,
|
||||
ImageFormatConfig,
|
||||
VisionFormatConfig,
|
||||
InnerAPIConfig,
|
||||
IndexingConfig,
|
||||
LoggingConfig,
|
||||
|
|
|
@ -945,7 +945,7 @@ class DocumentRetryApi(DocumentResource):
|
|||
raise DocumentAlreadyFinishedError()
|
||||
retry_documents.append(document)
|
||||
except Exception as e:
|
||||
logging.error(f"Document {document_id} retry failed: {str(e)}")
|
||||
logging.exception(f"Document {document_id} retry failed: {str(e)}")
|
||||
continue
|
||||
# retry document
|
||||
DocumentService.retry_document(dataset_id, retry_documents)
|
||||
|
|
|
@ -7,7 +7,11 @@ from controllers.service_api import api
|
|||
from controllers.service_api.app.error import NotChatAppError
|
||||
from controllers.service_api.wraps import FetchUserArg, WhereisUserArg, validate_app_token
|
||||
from core.app.entities.app_invoke_entities import InvokeFrom
|
||||
from fields.conversation_fields import conversation_infinite_scroll_pagination_fields, simple_conversation_fields
|
||||
from fields.conversation_fields import (
|
||||
conversation_delete_fields,
|
||||
conversation_infinite_scroll_pagination_fields,
|
||||
simple_conversation_fields,
|
||||
)
|
||||
from libs.helper import uuid_value
|
||||
from models.model import App, AppMode, EndUser
|
||||
from services.conversation_service import ConversationService
|
||||
|
@ -49,7 +53,7 @@ class ConversationApi(Resource):
|
|||
|
||||
class ConversationDetailApi(Resource):
|
||||
@validate_app_token(fetch_user_arg=FetchUserArg(fetch_from=WhereisUserArg.JSON))
|
||||
@marshal_with(simple_conversation_fields)
|
||||
@marshal_with(conversation_delete_fields)
|
||||
def delete(self, app_model: App, end_user: EndUser, c_id):
|
||||
app_mode = AppMode.value_of(app_model.mode)
|
||||
if app_mode not in {AppMode.CHAT, AppMode.AGENT_CHAT, AppMode.ADVANCED_CHAT}:
|
||||
|
@ -58,10 +62,9 @@ class ConversationDetailApi(Resource):
|
|||
conversation_id = str(c_id)
|
||||
|
||||
try:
|
||||
ConversationService.delete(app_model, conversation_id, end_user)
|
||||
return ConversationService.delete(app_model, conversation_id, end_user)
|
||||
except services.errors.conversation.ConversationNotExistsError:
|
||||
raise NotFound("Conversation Not Exists.")
|
||||
return {"result": "success"}, 200
|
||||
|
||||
|
||||
class ConversationRenameApi(Resource):
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import contextvars
|
||||
import logging
|
||||
import os
|
||||
import threading
|
||||
import uuid
|
||||
from collections.abc import Generator
|
||||
|
@ -10,6 +9,7 @@ from flask import Flask, current_app
|
|||
from pydantic import ValidationError
|
||||
|
||||
import contexts
|
||||
from configs import dify_config
|
||||
from constants import UUID_NIL
|
||||
from core.app.app_config.features.file_upload.manager import FileUploadConfigManager
|
||||
from core.app.apps.advanced_chat.app_config_manager import AdvancedChatAppConfigManager
|
||||
|
@ -317,7 +317,7 @@ class AdvancedChatAppGenerator(MessageBasedAppGenerator):
|
|||
logger.exception("Validation Error when generating")
|
||||
queue_manager.publish_error(e, PublishFrom.APPLICATION_MANAGER)
|
||||
except (ValueError, InvokeError) as e:
|
||||
if os.environ.get("DEBUG", "false").lower() == "true":
|
||||
if dify_config.DEBUG:
|
||||
logger.exception("Error when generating")
|
||||
queue_manager.publish_error(e, PublishFrom.APPLICATION_MANAGER)
|
||||
except Exception as e:
|
||||
|
|
|
@ -242,7 +242,7 @@ class AdvancedChatAppGenerateTaskPipeline(BasedGenerateTaskPipeline, WorkflowCyc
|
|||
start_listener_time = time.time()
|
||||
yield MessageAudioStreamResponse(audio=audio_trunk.audio, task_id=task_id)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
logger.exception(e)
|
||||
break
|
||||
if tts_publisher:
|
||||
yield MessageAudioEndStreamResponse(audio="", task_id=task_id)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import logging
|
||||
import os
|
||||
import threading
|
||||
import uuid
|
||||
from collections.abc import Generator
|
||||
|
@ -8,6 +7,7 @@ from typing import Any, Literal, Union, overload
|
|||
from flask import Flask, current_app
|
||||
from pydantic import ValidationError
|
||||
|
||||
from configs import dify_config
|
||||
from constants import UUID_NIL
|
||||
from core.app.app_config.easy_ui_based_app.model_config.converter import ModelConfigConverter
|
||||
from core.app.app_config.features.file_upload.manager import FileUploadConfigManager
|
||||
|
@ -230,7 +230,7 @@ class AgentChatAppGenerator(MessageBasedAppGenerator):
|
|||
logger.exception("Validation Error when generating")
|
||||
queue_manager.publish_error(e, PublishFrom.APPLICATION_MANAGER)
|
||||
except (ValueError, InvokeError) as e:
|
||||
if os.environ.get("DEBUG") and os.environ.get("DEBUG").lower() == "true":
|
||||
if dify_config.DEBUG:
|
||||
logger.exception("Error when generating")
|
||||
queue_manager.publish_error(e, PublishFrom.APPLICATION_MANAGER)
|
||||
except Exception as e:
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import logging
|
||||
import os
|
||||
import threading
|
||||
import uuid
|
||||
from collections.abc import Generator
|
||||
|
@ -8,6 +7,7 @@ from typing import Any, Literal, Union, overload
|
|||
from flask import Flask, current_app
|
||||
from pydantic import ValidationError
|
||||
|
||||
from configs import dify_config
|
||||
from constants import UUID_NIL
|
||||
from core.app.app_config.easy_ui_based_app.model_config.converter import ModelConfigConverter
|
||||
from core.app.app_config.features.file_upload.manager import FileUploadConfigManager
|
||||
|
@ -227,7 +227,7 @@ class ChatAppGenerator(MessageBasedAppGenerator):
|
|||
logger.exception("Validation Error when generating")
|
||||
queue_manager.publish_error(e, PublishFrom.APPLICATION_MANAGER)
|
||||
except (ValueError, InvokeError) as e:
|
||||
if os.environ.get("DEBUG") and os.environ.get("DEBUG").lower() == "true":
|
||||
if dify_config.DEBUG:
|
||||
logger.exception("Error when generating")
|
||||
queue_manager.publish_error(e, PublishFrom.APPLICATION_MANAGER)
|
||||
except Exception as e:
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import logging
|
||||
import os
|
||||
import threading
|
||||
import uuid
|
||||
from collections.abc import Generator
|
||||
|
@ -8,6 +7,7 @@ from typing import Any, Literal, Union, overload
|
|||
from flask import Flask, current_app
|
||||
from pydantic import ValidationError
|
||||
|
||||
from configs import dify_config
|
||||
from core.app.app_config.easy_ui_based_app.model_config.converter import ModelConfigConverter
|
||||
from core.app.app_config.features.file_upload.manager import FileUploadConfigManager
|
||||
from core.app.apps.base_app_queue_manager import AppQueueManager, GenerateTaskStoppedError, PublishFrom
|
||||
|
@ -203,7 +203,7 @@ class CompletionAppGenerator(MessageBasedAppGenerator):
|
|||
logger.exception("Validation Error when generating")
|
||||
queue_manager.publish_error(e, PublishFrom.APPLICATION_MANAGER)
|
||||
except (ValueError, InvokeError) as e:
|
||||
if os.environ.get("DEBUG") and os.environ.get("DEBUG").lower() == "true":
|
||||
if dify_config.DEBUG:
|
||||
logger.exception("Error when generating")
|
||||
queue_manager.publish_error(e, PublishFrom.APPLICATION_MANAGER)
|
||||
except Exception as e:
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import contextvars
|
||||
import logging
|
||||
import os
|
||||
import threading
|
||||
import uuid
|
||||
from collections.abc import Generator, Mapping, Sequence
|
||||
|
@ -10,6 +9,7 @@ from flask import Flask, current_app
|
|||
from pydantic import ValidationError
|
||||
|
||||
import contexts
|
||||
from configs import dify_config
|
||||
from core.app.app_config.features.file_upload.manager import FileUploadConfigManager
|
||||
from core.app.apps.base_app_generator import BaseAppGenerator
|
||||
from core.app.apps.base_app_queue_manager import AppQueueManager, GenerateTaskStoppedError, PublishFrom
|
||||
|
@ -261,7 +261,7 @@ class WorkflowAppGenerator(BaseAppGenerator):
|
|||
logger.exception("Validation Error when generating")
|
||||
queue_manager.publish_error(e, PublishFrom.APPLICATION_MANAGER)
|
||||
except (ValueError, InvokeError) as e:
|
||||
if os.environ.get("DEBUG") and os.environ.get("DEBUG", "false").lower() == "true":
|
||||
if dify_config.DEBUG:
|
||||
logger.exception("Error when generating")
|
||||
queue_manager.publish_error(e, PublishFrom.APPLICATION_MANAGER)
|
||||
except Exception as e:
|
||||
|
|
|
@ -216,7 +216,7 @@ class WorkflowAppGenerateTaskPipeline(BasedGenerateTaskPipeline, WorkflowCycleMa
|
|||
else:
|
||||
yield MessageAudioStreamResponse(audio=audio_trunk.audio, task_id=task_id)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
logger.exception(e)
|
||||
break
|
||||
if tts_publisher:
|
||||
yield MessageAudioEndStreamResponse(audio="", task_id=task_id)
|
||||
|
|
|
@ -3,7 +3,7 @@ import base64
|
|||
from configs import dify_config
|
||||
from core.file import file_repository
|
||||
from core.helper import ssrf_proxy
|
||||
from core.model_runtime.entities import AudioPromptMessageContent, ImagePromptMessageContent
|
||||
from core.model_runtime.entities import AudioPromptMessageContent, ImagePromptMessageContent, VideoPromptMessageContent
|
||||
from extensions.ext_database import db
|
||||
from extensions.ext_storage import storage
|
||||
|
||||
|
@ -71,6 +71,12 @@ def to_prompt_message_content(f: File, /):
|
|||
if f.extension is None:
|
||||
raise ValueError("Missing file extension")
|
||||
return AudioPromptMessageContent(data=encoded_string, format=f.extension.lstrip("."))
|
||||
case FileType.VIDEO:
|
||||
if dify_config.MULTIMODAL_SEND_VIDEO_FORMAT == "url":
|
||||
data = _to_url(f)
|
||||
else:
|
||||
data = _to_base64_data_string(f)
|
||||
return VideoPromptMessageContent(data=data, format=f.extension.lstrip("."))
|
||||
case _:
|
||||
raise ValueError(f"file type {f.type} is not supported")
|
||||
|
||||
|
@ -112,7 +118,7 @@ def _download_file_content(path: str, /):
|
|||
def _get_encoded_string(f: File, /):
|
||||
match f.transfer_method:
|
||||
case FileTransferMethod.REMOTE_URL:
|
||||
response = ssrf_proxy.get(f.remote_url)
|
||||
response = ssrf_proxy.get(f.remote_url, follow_redirects=True)
|
||||
response.raise_for_status()
|
||||
content = response.content
|
||||
encoded_string = base64.b64encode(content).decode("utf-8")
|
||||
|
@ -140,6 +146,8 @@ def _file_to_encoded_string(f: File, /):
|
|||
match f.type:
|
||||
case FileType.IMAGE:
|
||||
return _to_base64_data_string(f)
|
||||
case FileType.VIDEO:
|
||||
return _to_base64_data_string(f)
|
||||
case FileType.AUDIO:
|
||||
return _get_encoded_string(f)
|
||||
case _:
|
||||
|
|
|
@ -3,26 +3,20 @@ Proxy requests to avoid SSRF
|
|||
"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import time
|
||||
|
||||
import httpx
|
||||
|
||||
SSRF_PROXY_ALL_URL = os.getenv("SSRF_PROXY_ALL_URL", "")
|
||||
SSRF_PROXY_HTTP_URL = os.getenv("SSRF_PROXY_HTTP_URL", "")
|
||||
SSRF_PROXY_HTTPS_URL = os.getenv("SSRF_PROXY_HTTPS_URL", "")
|
||||
SSRF_DEFAULT_MAX_RETRIES = int(os.getenv("SSRF_DEFAULT_MAX_RETRIES", "3"))
|
||||
SSRF_DEFAULT_TIME_OUT = float(os.getenv("SSRF_DEFAULT_TIME_OUT", "5"))
|
||||
SSRF_DEFAULT_CONNECT_TIME_OUT = float(os.getenv("SSRF_DEFAULT_CONNECT_TIME_OUT", "5"))
|
||||
SSRF_DEFAULT_READ_TIME_OUT = float(os.getenv("SSRF_DEFAULT_READ_TIME_OUT", "5"))
|
||||
SSRF_DEFAULT_WRITE_TIME_OUT = float(os.getenv("SSRF_DEFAULT_WRITE_TIME_OUT", "5"))
|
||||
from configs import dify_config
|
||||
|
||||
SSRF_DEFAULT_MAX_RETRIES = dify_config.SSRF_DEFAULT_MAX_RETRIES
|
||||
|
||||
proxy_mounts = (
|
||||
{
|
||||
"http://": httpx.HTTPTransport(proxy=SSRF_PROXY_HTTP_URL),
|
||||
"https://": httpx.HTTPTransport(proxy=SSRF_PROXY_HTTPS_URL),
|
||||
"http://": httpx.HTTPTransport(proxy=dify_config.SSRF_PROXY_HTTP_URL),
|
||||
"https://": httpx.HTTPTransport(proxy=dify_config.SSRF_PROXY_HTTPS_URL),
|
||||
}
|
||||
if SSRF_PROXY_HTTP_URL and SSRF_PROXY_HTTPS_URL
|
||||
if dify_config.SSRF_PROXY_HTTP_URL and dify_config.SSRF_PROXY_HTTPS_URL
|
||||
else None
|
||||
)
|
||||
|
||||
|
@ -38,17 +32,17 @@ def make_request(method, url, max_retries=SSRF_DEFAULT_MAX_RETRIES, **kwargs):
|
|||
|
||||
if "timeout" not in kwargs:
|
||||
kwargs["timeout"] = httpx.Timeout(
|
||||
SSRF_DEFAULT_TIME_OUT,
|
||||
connect=SSRF_DEFAULT_CONNECT_TIME_OUT,
|
||||
read=SSRF_DEFAULT_READ_TIME_OUT,
|
||||
write=SSRF_DEFAULT_WRITE_TIME_OUT,
|
||||
timeout=dify_config.SSRF_DEFAULT_TIME_OUT,
|
||||
connect=dify_config.SSRF_DEFAULT_CONNECT_TIME_OUT,
|
||||
read=dify_config.SSRF_DEFAULT_READ_TIME_OUT,
|
||||
write=dify_config.SSRF_DEFAULT_WRITE_TIME_OUT,
|
||||
)
|
||||
|
||||
retries = 0
|
||||
while retries <= max_retries:
|
||||
try:
|
||||
if SSRF_PROXY_ALL_URL:
|
||||
with httpx.Client(proxy=SSRF_PROXY_ALL_URL) as client:
|
||||
if dify_config.SSRF_PROXY_ALL_URL:
|
||||
with httpx.Client(proxy=dify_config.SSRF_PROXY_ALL_URL) as client:
|
||||
response = client.request(method=method, url=url, **kwargs)
|
||||
elif proxy_mounts:
|
||||
with httpx.Client(mounts=proxy_mounts) as client:
|
||||
|
@ -60,10 +54,12 @@ def make_request(method, url, max_retries=SSRF_DEFAULT_MAX_RETRIES, **kwargs):
|
|||
if response.status_code not in STATUS_FORCELIST:
|
||||
return response
|
||||
else:
|
||||
logging.warning(f"Received status code {response.status_code} for URL {url} which is in the force list")
|
||||
logging.warning(
|
||||
f"Received status code {response.status_code} for URL {url} which is in the force list")
|
||||
|
||||
except httpx.RequestError as e:
|
||||
logging.warning(f"Request to URL {url} failed on attempt {retries + 1}: {e}")
|
||||
logging.warning(
|
||||
f"Request to URL {url} failed on attempt {retries + 1}: {e}")
|
||||
|
||||
retries += 1
|
||||
if retries <= max_retries:
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import logging
|
||||
import os
|
||||
from collections.abc import Callable, Generator, Iterable, Sequence
|
||||
from typing import IO, Any, Optional, Union, cast
|
||||
|
||||
from configs import dify_config
|
||||
from core.entities.embedding_type import EmbeddingInputType
|
||||
from core.entities.provider_configuration import ProviderConfiguration, ProviderModelBundle
|
||||
from core.entities.provider_entities import ModelLoadBalancingConfiguration
|
||||
|
@ -473,7 +473,7 @@ class LBModelManager:
|
|||
|
||||
continue
|
||||
|
||||
if bool(os.environ.get("DEBUG", "False").lower() == "true"):
|
||||
if dify_config.DEBUG:
|
||||
logger.info(
|
||||
f"Model LB\nid: {config.id}\nname:{config.name}\n"
|
||||
f"tenant_id: {self._tenant_id}\nprovider: {self._provider}\n"
|
||||
|
|
|
@ -12,11 +12,13 @@ from .message_entities import (
|
|||
TextPromptMessageContent,
|
||||
ToolPromptMessage,
|
||||
UserPromptMessage,
|
||||
VideoPromptMessageContent,
|
||||
)
|
||||
from .model_entities import ModelPropertyKey
|
||||
|
||||
__all__ = [
|
||||
"ImagePromptMessageContent",
|
||||
"VideoPromptMessageContent",
|
||||
"PromptMessage",
|
||||
"PromptMessageRole",
|
||||
"LLMUsage",
|
||||
|
|
|
@ -56,6 +56,7 @@ class PromptMessageContentType(Enum):
|
|||
TEXT = "text"
|
||||
IMAGE = "image"
|
||||
AUDIO = "audio"
|
||||
VIDEO = "video"
|
||||
|
||||
|
||||
class PromptMessageContent(BaseModel):
|
||||
|
@ -75,6 +76,12 @@ class TextPromptMessageContent(PromptMessageContent):
|
|||
type: PromptMessageContentType = PromptMessageContentType.TEXT
|
||||
|
||||
|
||||
class VideoPromptMessageContent(PromptMessageContent):
|
||||
type: PromptMessageContentType = PromptMessageContentType.VIDEO
|
||||
data: str = Field(..., description="Base64 encoded video data")
|
||||
format: str = Field(..., description="Video format")
|
||||
|
||||
|
||||
class AudioPromptMessageContent(PromptMessageContent):
|
||||
type: PromptMessageContentType = PromptMessageContentType.AUDIO
|
||||
data: str = Field(..., description="Base64 encoded audio data")
|
||||
|
|
|
@ -47,9 +47,9 @@ class AzureRerankModel(RerankModel):
|
|||
result = response.read()
|
||||
return json.loads(result)
|
||||
except urllib.error.HTTPError as error:
|
||||
logger.error(f"The request failed with status code: {error.code}")
|
||||
logger.error(error.info())
|
||||
logger.error(error.read().decode("utf8", "ignore"))
|
||||
logger.exception(f"The request failed with status code: {error.code}")
|
||||
logger.exception(error.info())
|
||||
logger.exception(error.read().decode("utf8", "ignore"))
|
||||
raise
|
||||
|
||||
def _invoke(
|
||||
|
|
|
@ -29,6 +29,7 @@ from core.model_runtime.entities.message_entities import (
|
|||
TextPromptMessageContent,
|
||||
ToolPromptMessage,
|
||||
UserPromptMessage,
|
||||
VideoPromptMessageContent,
|
||||
)
|
||||
from core.model_runtime.entities.model_entities import (
|
||||
AIModelEntity,
|
||||
|
@ -431,6 +432,14 @@ class TongyiLargeLanguageModel(LargeLanguageModel):
|
|||
|
||||
sub_message_dict = {"image": image_url}
|
||||
sub_messages.append(sub_message_dict)
|
||||
elif message_content.type == PromptMessageContentType.VIDEO:
|
||||
message_content = cast(VideoPromptMessageContent, message_content)
|
||||
video_url = message_content.data
|
||||
if message_content.data.startswith("data:"):
|
||||
raise InvokeError("not support base64, please set MULTIMODAL_SEND_VIDEO_FORMAT to url")
|
||||
|
||||
sub_message_dict = {"video": video_url}
|
||||
sub_messages.append(sub_message_dict)
|
||||
|
||||
# resort sub_messages to ensure text is always at last
|
||||
sub_messages = sorted(sub_messages, key=lambda x: "text" in x)
|
||||
|
|
|
@ -313,21 +313,35 @@ class ZhipuAILargeLanguageModel(_CommonZhipuaiAI, LargeLanguageModel):
|
|||
return params
|
||||
|
||||
def _construct_glm_4v_messages(self, prompt_message: Union[str, list[PromptMessageContent]]) -> list[dict]:
|
||||
if isinstance(prompt_message, str):
|
||||
if isinstance(prompt_message, list):
|
||||
sub_messages = []
|
||||
for item in prompt_message:
|
||||
if item.type == PromptMessageContentType.IMAGE:
|
||||
sub_messages.append(
|
||||
{
|
||||
"type": "image_url",
|
||||
"image_url": {"url": self._remove_base64_header(item.data)},
|
||||
}
|
||||
)
|
||||
elif item.type == PromptMessageContentType.VIDEO:
|
||||
sub_messages.append(
|
||||
{
|
||||
"type": "video_url",
|
||||
"video_url": {"url": self._remove_base64_header(item.data)},
|
||||
}
|
||||
)
|
||||
else:
|
||||
sub_messages.append({"type": "text", "text": item.data})
|
||||
return sub_messages
|
||||
else:
|
||||
return [{"type": "text", "text": prompt_message}]
|
||||
|
||||
return [
|
||||
{"type": "image_url", "image_url": {"url": self._remove_image_header(item.data)}}
|
||||
if item.type == PromptMessageContentType.IMAGE
|
||||
else {"type": "text", "text": item.data}
|
||||
for item in prompt_message
|
||||
]
|
||||
def _remove_base64_header(self, file_content: str) -> str:
|
||||
if file_content.startswith("data:"):
|
||||
data_split = file_content.split(";base64,")
|
||||
return data_split[1]
|
||||
|
||||
def _remove_image_header(self, image: str) -> str:
|
||||
if image.startswith("data:image"):
|
||||
return image.split(",")[1]
|
||||
|
||||
return image
|
||||
return file_content
|
||||
|
||||
def _handle_generate_response(
|
||||
self,
|
||||
|
|
|
@ -126,6 +126,6 @@ class OutputModeration(BaseModel):
|
|||
result: ModerationOutputsResult = moderation_factory.moderation_for_outputs(moderation_buffer)
|
||||
return result
|
||||
except Exception as e:
|
||||
logger.error("Moderation Output error: %s", e)
|
||||
logger.exception("Moderation Output error: %s", e)
|
||||
|
||||
return None
|
||||
|
|
|
@ -708,7 +708,7 @@ class TraceQueueManager:
|
|||
trace_task.app_id = self.app_id
|
||||
trace_manager_queue.put(trace_task)
|
||||
except Exception as e:
|
||||
logging.error(f"Error adding trace task: {e}")
|
||||
logging.exception(f"Error adding trace task: {e}")
|
||||
finally:
|
||||
self.start_timer()
|
||||
|
||||
|
@ -727,7 +727,7 @@ class TraceQueueManager:
|
|||
if tasks:
|
||||
self.send_to_celery(tasks)
|
||||
except Exception as e:
|
||||
logging.error(f"Error processing trace tasks: {e}")
|
||||
logging.exception(f"Error processing trace tasks: {e}")
|
||||
|
||||
def start_timer(self):
|
||||
global trace_manager_timer
|
||||
|
|
|
@ -242,7 +242,7 @@ class CouchbaseVector(BaseVector):
|
|||
try:
|
||||
self._cluster.query(query, named_parameters={"doc_ids": ids}).execute()
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
logger.exception(e)
|
||||
|
||||
def delete_by_document_id(self, document_id: str):
|
||||
query = f"""
|
||||
|
|
|
@ -20,7 +20,8 @@ from extensions.ext_redis import redis_client
|
|||
from models.dataset import Dataset
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
|
||||
logging.basicConfig(level=logging.INFO,
|
||||
format="%(asctime)s - %(levelname)s - %(message)s")
|
||||
logging.getLogger("lindorm").setLevel(logging.WARN)
|
||||
|
||||
|
||||
|
@ -76,10 +77,11 @@ class LindormVectorStore(BaseVector):
|
|||
@retry(stop=stop_after_attempt(3), wait=wait_fixed(60))
|
||||
def __fetch_existing_ids(batch_ids: list[str]) -> set[str]:
|
||||
try:
|
||||
existing_docs = self._client.mget(index=self._collection_name, body={"ids": batch_ids}, _source=False)
|
||||
existing_docs = self._client.mget(index=self._collection_name, body={
|
||||
"ids": batch_ids}, _source=False)
|
||||
return {doc["_id"] for doc in existing_docs["docs"] if doc["found"]}
|
||||
except Exception as e:
|
||||
logger.error(f"Error fetching batch {batch_ids}: {e}")
|
||||
logger.exception(f"Error fetching batch {batch_ids}: {e}")
|
||||
return set()
|
||||
|
||||
@retry(stop=stop_after_attempt(3), wait=wait_fixed(60))
|
||||
|
@ -88,7 +90,8 @@ class LindormVectorStore(BaseVector):
|
|||
existing_docs = self._client.mget(
|
||||
body={
|
||||
"docs": [
|
||||
{"_index": self._collection_name, "_id": id, "routing": routing}
|
||||
{"_index": self._collection_name,
|
||||
"_id": id, "routing": routing}
|
||||
for id, routing in zip(batch_ids, route_ids)
|
||||
]
|
||||
},
|
||||
|
@ -96,7 +99,7 @@ class LindormVectorStore(BaseVector):
|
|||
)
|
||||
return {doc["_id"] for doc in existing_docs["docs"] if doc["found"]}
|
||||
except Exception as e:
|
||||
logger.error(f"Error fetching batch {batch_ids}: {e}")
|
||||
logger.exception(f"Error fetching batch {batch_ids}: {e}")
|
||||
return set()
|
||||
|
||||
if ids is None:
|
||||
|
@ -112,12 +115,13 @@ class LindormVectorStore(BaseVector):
|
|||
def batch(iterable, n):
|
||||
length = len(iterable)
|
||||
for idx in range(0, length, n):
|
||||
yield iterable[idx : min(idx + n, length)]
|
||||
yield iterable[idx: min(idx + n, length)]
|
||||
|
||||
for ids_batch, texts_batch, metadatas_batch in zip(
|
||||
batch(ids, bulk_size),
|
||||
batch(texts, bulk_size),
|
||||
batch(metadatas, bulk_size) if metadatas is not None else batch([None] * len(ids), bulk_size),
|
||||
batch(metadatas, bulk_size) if metadatas is not None else batch(
|
||||
[None] * len(ids), bulk_size),
|
||||
):
|
||||
existing_ids_set = __fetch_existing_ids(ids_batch)
|
||||
for text, metadata, doc_id in zip(texts_batch, metadatas_batch, ids_batch):
|
||||
|
@ -139,7 +143,8 @@ class LindormVectorStore(BaseVector):
|
|||
"_id": uuids[i],
|
||||
"_source": {
|
||||
Field.CONTENT_KEY.value: documents[i].page_content,
|
||||
Field.VECTOR.value: embeddings[i], # Make sure you pass an array here
|
||||
# Make sure you pass an array here
|
||||
Field.VECTOR.value: embeddings[i],
|
||||
Field.METADATA_KEY.value: documents[i].metadata,
|
||||
},
|
||||
}
|
||||
|
@ -148,7 +153,8 @@ class LindormVectorStore(BaseVector):
|
|||
self.refresh()
|
||||
|
||||
def get_ids_by_metadata_field(self, key: str, value: str):
|
||||
query = {"query": {"term": {f"{Field.METADATA_KEY.value}.{key}.keyword": value}}}
|
||||
query = {
|
||||
"query": {"term": {f"{Field.METADATA_KEY.value}.{key}.keyword": value}}}
|
||||
response = self._client.search(index=self._collection_name, body=query)
|
||||
if response["hits"]["hits"]:
|
||||
return [hit["_id"] for hit in response["hits"]["hits"]]
|
||||
|
@ -157,7 +163,8 @@ class LindormVectorStore(BaseVector):
|
|||
|
||||
def delete_by_metadata_field(self, key: str, value: str):
|
||||
query_str = {"query": {"match": {f"metadata.{key}": f"{value}"}}}
|
||||
results = self._client.search(index=self._collection_name, body=query_str)
|
||||
results = self._client.search(
|
||||
index=self._collection_name, body=query_str)
|
||||
ids = [hit["_id"] for hit in results["hits"]["hits"]]
|
||||
if ids:
|
||||
self.delete_by_ids(ids)
|
||||
|
@ -167,17 +174,20 @@ class LindormVectorStore(BaseVector):
|
|||
if self._client.exists(index=self._collection_name, id=id):
|
||||
self._client.delete(index=self._collection_name, id=id)
|
||||
else:
|
||||
logger.warning(f"DELETE BY ID: ID {id} does not exist in the index.")
|
||||
logger.warning(
|
||||
f"DELETE BY ID: ID {id} does not exist in the index.")
|
||||
|
||||
def delete(self) -> None:
|
||||
try:
|
||||
if self._client.indices.exists(index=self._collection_name):
|
||||
self._client.indices.delete(index=self._collection_name, params={"timeout": 60})
|
||||
self._client.indices.delete(
|
||||
index=self._collection_name, params={"timeout": 60})
|
||||
logger.info("Delete index success")
|
||||
else:
|
||||
logger.warning(f"Index '{self._collection_name}' does not exist. No deletion performed.")
|
||||
logger.warning(
|
||||
f"Index '{self._collection_name}' does not exist. No deletion performed.")
|
||||
except Exception as e:
|
||||
logger.error(f"Error occurred while deleting the index: {e}")
|
||||
logger.exception(f"Error occurred while deleting the index: {e}")
|
||||
raise e
|
||||
|
||||
def text_exists(self, id: str) -> bool:
|
||||
|
@ -197,11 +207,13 @@ class LindormVectorStore(BaseVector):
|
|||
raise ValueError("All elements in query_vector should be floats")
|
||||
|
||||
top_k = kwargs.get("top_k", 10)
|
||||
query = default_vector_search_query(query_vector=query_vector, k=top_k, **kwargs)
|
||||
query = default_vector_search_query(
|
||||
query_vector=query_vector, k=top_k, **kwargs)
|
||||
try:
|
||||
response = self._client.search(index=self._collection_name, body=query)
|
||||
response = self._client.search(
|
||||
index=self._collection_name, body=query)
|
||||
except Exception as e:
|
||||
logger.error(f"Error executing search: {e}")
|
||||
logger.exception(f"Error executing search: {e}")
|
||||
raise
|
||||
|
||||
docs_and_scores = []
|
||||
|
@ -244,7 +256,8 @@ class LindormVectorStore(BaseVector):
|
|||
filters=filters,
|
||||
routing=routing,
|
||||
)
|
||||
response = self._client.search(index=self._collection_name, body=full_text_query)
|
||||
response = self._client.search(
|
||||
index=self._collection_name, body=full_text_query)
|
||||
docs = []
|
||||
for hit in response["hits"]["hits"]:
|
||||
docs.append(
|
||||
|
@ -262,7 +275,8 @@ class LindormVectorStore(BaseVector):
|
|||
with redis_client.lock(lock_name, timeout=20):
|
||||
collection_exist_cache_key = f"vector_indexing_{self._collection_name}"
|
||||
if redis_client.get(collection_exist_cache_key):
|
||||
logger.info(f"Collection {self._collection_name} already exists.")
|
||||
logger.info(
|
||||
f"Collection {self._collection_name} already exists.")
|
||||
return
|
||||
if self._client.indices.exists(index=self._collection_name):
|
||||
logger.info("{self._collection_name.lower()} already exists.")
|
||||
|
@ -281,10 +295,13 @@ class LindormVectorStore(BaseVector):
|
|||
hnsw_ef_construction = kwargs.pop("hnsw_ef_construction", 500)
|
||||
ivfpq_m = kwargs.pop("ivfpq_m", dimension)
|
||||
nlist = kwargs.pop("nlist", 1000)
|
||||
centroids_use_hnsw = kwargs.pop("centroids_use_hnsw", True if nlist >= 5000 else False)
|
||||
centroids_use_hnsw = kwargs.pop(
|
||||
"centroids_use_hnsw", True if nlist >= 5000 else False)
|
||||
centroids_hnsw_m = kwargs.pop("centroids_hnsw_m", 24)
|
||||
centroids_hnsw_ef_construct = kwargs.pop("centroids_hnsw_ef_construct", 500)
|
||||
centroids_hnsw_ef_search = kwargs.pop("centroids_hnsw_ef_search", 100)
|
||||
centroids_hnsw_ef_construct = kwargs.pop(
|
||||
"centroids_hnsw_ef_construct", 500)
|
||||
centroids_hnsw_ef_search = kwargs.pop(
|
||||
"centroids_hnsw_ef_search", 100)
|
||||
mapping = default_text_mapping(
|
||||
dimension,
|
||||
method_name,
|
||||
|
@ -303,7 +320,8 @@ class LindormVectorStore(BaseVector):
|
|||
centroids_hnsw_ef_search=centroids_hnsw_ef_search,
|
||||
**kwargs,
|
||||
)
|
||||
self._client.indices.create(index=self._collection_name.lower(), body=mapping)
|
||||
self._client.indices.create(
|
||||
index=self._collection_name.lower(), body=mapping)
|
||||
redis_client.set(collection_exist_cache_key, 1, ex=3600)
|
||||
# logger.info(f"create index success: {self._collection_name}")
|
||||
|
||||
|
@ -364,7 +382,8 @@ def default_text_mapping(dimension: int, method_name: str, **kwargs: Any) -> dic
|
|||
}
|
||||
|
||||
if excludes_from_source:
|
||||
mapping["mappings"]["_source"] = {"excludes": excludes_from_source} # e.g. {"excludes": ["vector_field"]}
|
||||
# e.g. {"excludes": ["vector_field"]}
|
||||
mapping["mappings"]["_source"] = {"excludes": excludes_from_source}
|
||||
|
||||
if method_name == "ivfpq" and routing_field is not None:
|
||||
mapping["settings"]["index"]["knn_routing"] = True
|
||||
|
@ -405,7 +424,8 @@ def default_text_search_query(
|
|||
# build complex search_query when either of must/must_not/should/filter is specified
|
||||
if must:
|
||||
if not isinstance(must, list):
|
||||
raise RuntimeError(f"unexpected [must] clause with {type(filters)}")
|
||||
raise RuntimeError(
|
||||
f"unexpected [must] clause with {type(filters)}")
|
||||
if query_clause not in must:
|
||||
must.append(query_clause)
|
||||
else:
|
||||
|
@ -415,19 +435,22 @@ def default_text_search_query(
|
|||
|
||||
if must_not:
|
||||
if not isinstance(must_not, list):
|
||||
raise RuntimeError(f"unexpected [must_not] clause with {type(filters)}")
|
||||
raise RuntimeError(
|
||||
f"unexpected [must_not] clause with {type(filters)}")
|
||||
boolean_query["must_not"] = must_not
|
||||
|
||||
if should:
|
||||
if not isinstance(should, list):
|
||||
raise RuntimeError(f"unexpected [should] clause with {type(filters)}")
|
||||
raise RuntimeError(
|
||||
f"unexpected [should] clause with {type(filters)}")
|
||||
boolean_query["should"] = should
|
||||
if minimum_should_match != 0:
|
||||
boolean_query["minimum_should_match"] = minimum_should_match
|
||||
|
||||
if filters:
|
||||
if not isinstance(filters, list):
|
||||
raise RuntimeError(f"unexpected [filter] clause with {type(filters)}")
|
||||
raise RuntimeError(
|
||||
f"unexpected [filter] clause with {type(filters)}")
|
||||
boolean_query["filter"] = filters
|
||||
|
||||
search_query = {"size": k, "query": {"bool": boolean_query}}
|
||||
|
@ -471,8 +494,10 @@ def default_vector_search_query(
|
|||
|
||||
if filters is not None:
|
||||
# when using filter, transform filter from List[Dict] to Dict as valid format
|
||||
filters = {"bool": {"must": filters}} if len(filters) > 1 else filters[0]
|
||||
search_query["query"]["knn"][vector_field]["filter"] = filters # filter should be Dict
|
||||
filters = {"bool": {"must": filters}} if len(
|
||||
filters) > 1 else filters[0]
|
||||
# filter should be Dict
|
||||
search_query["query"]["knn"][vector_field]["filter"] = filters
|
||||
if filter_type:
|
||||
final_ext["lvector"]["filter_type"] = filter_type
|
||||
|
||||
|
@ -489,7 +514,8 @@ class LindormVectorStoreFactory(AbstractVectorFactory):
|
|||
else:
|
||||
dataset_id = dataset.id
|
||||
collection_name = Dataset.gen_collection_name_by_id(dataset_id)
|
||||
dataset.index_struct = json.dumps(self.gen_index_struct_dict(VectorType.LINDORM, collection_name))
|
||||
dataset.index_struct = json.dumps(
|
||||
self.gen_index_struct_dict(VectorType.LINDORM, collection_name))
|
||||
lindorm_config = LindormVectorStoreConfig(
|
||||
hosts=dify_config.LINDORM_URL,
|
||||
username=dify_config.LINDORM_USERNAME,
|
||||
|
|
|
@ -86,7 +86,7 @@ class MilvusVector(BaseVector):
|
|||
ids = self._client.insert(collection_name=self._collection_name, data=batch_insert_list)
|
||||
pks.extend(ids)
|
||||
except MilvusException as e:
|
||||
logger.error("Failed to insert batch starting at entity: %s/%s", i, total_count)
|
||||
logger.exception("Failed to insert batch starting at entity: %s/%s", i, total_count)
|
||||
raise e
|
||||
return pks
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@ class MyScaleVector(BaseVector):
|
|||
for r in self._client.query(sql).named_results()
|
||||
]
|
||||
except Exception as e:
|
||||
logging.error(f"\033[91m\033[1m{type(e)}\033[0m \033[95m{str(e)}\033[0m")
|
||||
logging.exception(f"\033[91m\033[1m{type(e)}\033[0m \033[95m{str(e)}\033[0m")
|
||||
return []
|
||||
|
||||
def delete(self) -> None:
|
||||
|
|
|
@ -129,7 +129,7 @@ class OpenSearchVector(BaseVector):
|
|||
if status == 404:
|
||||
logger.warning(f"Document not found for deletion: {doc_id}")
|
||||
else:
|
||||
logger.error(f"Error deleting document: {error}")
|
||||
logger.exception(f"Error deleting document: {error}")
|
||||
|
||||
def delete(self) -> None:
|
||||
self._client.indices.delete(index=self._collection_name.lower())
|
||||
|
@ -158,7 +158,7 @@ class OpenSearchVector(BaseVector):
|
|||
try:
|
||||
response = self._client.search(index=self._collection_name.lower(), body=query)
|
||||
except Exception as e:
|
||||
logger.error(f"Error executing search: {e}")
|
||||
logger.exception(f"Error executing search: {e}")
|
||||
raise
|
||||
|
||||
docs = []
|
||||
|
|
|
@ -89,7 +89,7 @@ class CacheEmbedding(Embeddings):
|
|||
db.session.rollback()
|
||||
except Exception as ex:
|
||||
db.session.rollback()
|
||||
logger.error("Failed to embed documents: %s", ex)
|
||||
logger.exception("Failed to embed documents: %s", ex)
|
||||
raise ex
|
||||
|
||||
return text_embeddings
|
||||
|
|
|
@ -28,7 +28,6 @@ logger = logging.getLogger(__name__)
|
|||
class WordExtractor(BaseExtractor):
|
||||
"""Load docx files.
|
||||
|
||||
|
||||
Args:
|
||||
file_path: Path to the file to load.
|
||||
"""
|
||||
|
@ -51,9 +50,9 @@ class WordExtractor(BaseExtractor):
|
|||
|
||||
self.web_path = self.file_path
|
||||
# TODO: use a better way to handle the file
|
||||
self.temp_file = tempfile.NamedTemporaryFile() # noqa: SIM115
|
||||
self.temp_file.write(r.content)
|
||||
self.file_path = self.temp_file.name
|
||||
with tempfile.NamedTemporaryFile(delete=False) as self.temp_file:
|
||||
self.temp_file.write(r.content)
|
||||
self.file_path = self.temp_file.name
|
||||
elif not os.path.isfile(self.file_path):
|
||||
raise ValueError(f"File path {self.file_path} is not a valid file or url")
|
||||
|
||||
|
@ -230,7 +229,7 @@ class WordExtractor(BaseExtractor):
|
|||
for i in url_pattern.findall(x.text):
|
||||
hyperlinks_url = str(i)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
logger.exception(e)
|
||||
|
||||
def parse_paragraph(paragraph):
|
||||
paragraph_content = []
|
||||
|
|
|
@ -48,6 +48,13 @@
|
|||
- feishu_task
|
||||
- feishu_calendar
|
||||
- feishu_spreadsheet
|
||||
- lark_base
|
||||
- lark_document
|
||||
- lark_message_and_group
|
||||
- lark_wiki
|
||||
- lark_task
|
||||
- lark_calendar
|
||||
- lark_spreadsheet
|
||||
- slack
|
||||
- twilio
|
||||
- wecom
|
||||
|
|
|
@ -34,7 +34,7 @@ parameters:
|
|||
Page size, default value: 20, maximum value: 100.
|
||||
zh_Hans: 分页大小,默认值:20,最大值:100。
|
||||
llm_description: 分页大小,默认值:20,最大值:100。
|
||||
form: llm
|
||||
form: form
|
||||
|
||||
- name: page_token
|
||||
type: string
|
||||
|
|
|
@ -147,7 +147,7 @@ parameters:
|
|||
Page size, default value: 20, maximum value: 500.
|
||||
zh_Hans: 分页大小,默认值:20,最大值:500。
|
||||
llm_description: 分页大小,默认值:20,最大值:500。
|
||||
form: llm
|
||||
form: form
|
||||
|
||||
- name: page_token
|
||||
type: string
|
||||
|
|
|
@ -47,7 +47,7 @@ parameters:
|
|||
en_US: The page size, i.e., the number of data entries returned in a single request. The default value is 50, and the value range is [50,1000].
|
||||
zh_Hans: 分页大小,即单次请求所返回的数据条目数。默认值为 50,取值范围为 [50,1000]。
|
||||
llm_description: 分页大小,即单次请求所返回的数据条目数。默认值为 50,取值范围为 [50,1000]。
|
||||
form: llm
|
||||
form: form
|
||||
|
||||
- name: page_token
|
||||
type: string
|
||||
|
|
|
@ -85,7 +85,7 @@ parameters:
|
|||
en_US: The page size, i.e., the number of data entries returned in a single request. The default value is 20, and the value range is [10,100].
|
||||
zh_Hans: 分页大小,即单次请求所返回的数据条目数。默认值为 20,取值范围为 [10,100]。
|
||||
llm_description: 分页大小,即单次请求所返回的数据条目数。默认值为 20,取值范围为 [10,100]。
|
||||
form: llm
|
||||
form: form
|
||||
|
||||
- name: page_token
|
||||
type: string
|
||||
|
|
|
@ -59,7 +59,7 @@ parameters:
|
|||
en_US: Paging size, the default and maximum value is 500.
|
||||
zh_Hans: 分页大小, 默认值和最大值为 500。
|
||||
llm_description: 分页大小, 表示一次请求最多返回多少条数据,默认值和最大值为 500。
|
||||
form: llm
|
||||
form: form
|
||||
|
||||
- name: page_token
|
||||
type: string
|
||||
|
|
|
@ -81,7 +81,7 @@ parameters:
|
|||
en_US: The page size, i.e., the number of data entries returned in a single request. The default value is 20, and the value range is [1,50].
|
||||
zh_Hans: 分页大小,即单次请求所返回的数据条目数。默认值为 20,取值范围为 [1,50]。
|
||||
llm_description: 分页大小,即单次请求所返回的数据条目数。默认值为 20,取值范围为 [1,50]。
|
||||
form: llm
|
||||
form: form
|
||||
|
||||
- name: page_token
|
||||
type: string
|
||||
|
|
|
@ -57,7 +57,7 @@ parameters:
|
|||
en_US: The page size, i.e., the number of data entries returned in a single request. The default value is 20, and the value range is [1,50].
|
||||
zh_Hans: 分页大小,即单次请求所返回的数据条目数。默认值为 20,取值范围为 [1,50]。
|
||||
llm_description: 分页大小,即单次请求所返回的数据条目数。默认值为 20,取值范围为 [1,50]。
|
||||
form: llm
|
||||
form: form
|
||||
|
||||
- name: page_token
|
||||
type: string
|
||||
|
|
|
@ -56,7 +56,7 @@ parameters:
|
|||
en_US: Number of columns to add, range (0-5000].
|
||||
zh_Hans: 要增加的列数,范围(0-5000]。
|
||||
llm_description: 要增加的列数,范围(0-5000]。
|
||||
form: llm
|
||||
form: form
|
||||
|
||||
- name: values
|
||||
type: string
|
||||
|
|
|
@ -56,7 +56,7 @@ parameters:
|
|||
en_US: Number of rows to add, range (0-5000].
|
||||
zh_Hans: 要增加行数,范围(0-5000]。
|
||||
llm_description: 要增加行数,范围(0-5000]。
|
||||
form: llm
|
||||
form: form
|
||||
|
||||
- name: values
|
||||
type: string
|
||||
|
|
|
@ -82,7 +82,7 @@ parameters:
|
|||
en_US: Starting column number, starting from 1.
|
||||
zh_Hans: 起始列号,从 1 开始。
|
||||
llm_description: 起始列号,从 1 开始。
|
||||
form: llm
|
||||
form: form
|
||||
|
||||
- name: num_cols
|
||||
type: number
|
||||
|
@ -94,4 +94,4 @@ parameters:
|
|||
en_US: Number of columns to read.
|
||||
zh_Hans: 读取列数
|
||||
llm_description: 读取列数
|
||||
form: llm
|
||||
form: form
|
||||
|
|
|
@ -82,7 +82,7 @@ parameters:
|
|||
en_US: Starting row number, starting from 1.
|
||||
zh_Hans: 起始行号,从 1 开始。
|
||||
llm_description: 起始行号,从 1 开始。
|
||||
form: llm
|
||||
form: form
|
||||
|
||||
- name: num_rows
|
||||
type: number
|
||||
|
@ -94,4 +94,4 @@ parameters:
|
|||
en_US: Number of rows to read.
|
||||
zh_Hans: 读取行数
|
||||
llm_description: 读取行数
|
||||
form: llm
|
||||
form: form
|
||||
|
|
|
@ -82,7 +82,7 @@ parameters:
|
|||
en_US: Starting row number, starting from 1.
|
||||
zh_Hans: 起始行号,从 1 开始。
|
||||
llm_description: 起始行号,从 1 开始。
|
||||
form: llm
|
||||
form: form
|
||||
|
||||
- name: num_rows
|
||||
type: number
|
||||
|
@ -94,7 +94,7 @@ parameters:
|
|||
en_US: Number of rows to read.
|
||||
zh_Hans: 读取行数
|
||||
llm_description: 读取行数
|
||||
form: llm
|
||||
form: form
|
||||
|
||||
- name: range
|
||||
type: string
|
||||
|
|
|
@ -36,7 +36,7 @@ parameters:
|
|||
en_US: The size of each page, with a maximum value of 50.
|
||||
zh_Hans: 分页大小,最大值 50。
|
||||
llm_description: 分页大小,最大值 50。
|
||||
form: llm
|
||||
form: form
|
||||
|
||||
- name: page_token
|
||||
type: string
|
||||
|
|
|
@ -13,15 +13,15 @@ class GitlabCommitsTool(BuiltinTool):
|
|||
def _invoke(
|
||||
self, user_id: str, tool_parameters: dict[str, Any]
|
||||
) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
|
||||
project = tool_parameters.get("project", "")
|
||||
branch = tool_parameters.get("branch", "")
|
||||
repository = tool_parameters.get("repository", "")
|
||||
employee = tool_parameters.get("employee", "")
|
||||
start_time = tool_parameters.get("start_time", "")
|
||||
end_time = tool_parameters.get("end_time", "")
|
||||
change_type = tool_parameters.get("change_type", "all")
|
||||
|
||||
if not project and not repository:
|
||||
return self.create_text_message("Either project or repository is required")
|
||||
if not repository:
|
||||
return self.create_text_message("Either repository is required")
|
||||
|
||||
if not start_time:
|
||||
start_time = (datetime.utcnow() - timedelta(days=1)).isoformat()
|
||||
|
@ -37,14 +37,9 @@ class GitlabCommitsTool(BuiltinTool):
|
|||
site_url = "https://gitlab.com"
|
||||
|
||||
# Get commit content
|
||||
if repository:
|
||||
result = self.fetch_commits(
|
||||
site_url, access_token, repository, employee, start_time, end_time, change_type, is_repository=True
|
||||
)
|
||||
else:
|
||||
result = self.fetch_commits(
|
||||
site_url, access_token, project, employee, start_time, end_time, change_type, is_repository=False
|
||||
)
|
||||
result = self.fetch_commits(
|
||||
site_url, access_token, repository, branch, employee, start_time, end_time, change_type, is_repository=True
|
||||
)
|
||||
|
||||
return [self.create_json_message(item) for item in result]
|
||||
|
||||
|
@ -52,7 +47,8 @@ class GitlabCommitsTool(BuiltinTool):
|
|||
self,
|
||||
site_url: str,
|
||||
access_token: str,
|
||||
identifier: str,
|
||||
repository: str,
|
||||
branch: str,
|
||||
employee: str,
|
||||
start_time: str,
|
||||
end_time: str,
|
||||
|
@ -64,27 +60,14 @@ class GitlabCommitsTool(BuiltinTool):
|
|||
results = []
|
||||
|
||||
try:
|
||||
if is_repository:
|
||||
# URL encode the repository path
|
||||
encoded_identifier = urllib.parse.quote(identifier, safe="")
|
||||
commits_url = f"{domain}/api/v4/projects/{encoded_identifier}/repository/commits"
|
||||
else:
|
||||
# Get all projects
|
||||
url = f"{domain}/api/v4/projects"
|
||||
response = requests.get(url, headers=headers)
|
||||
response.raise_for_status()
|
||||
projects = response.json()
|
||||
|
||||
filtered_projects = [p for p in projects if identifier == "*" or p["name"] == identifier]
|
||||
|
||||
for project in filtered_projects:
|
||||
project_id = project["id"]
|
||||
project_name = project["name"]
|
||||
print(f"Project: {project_name}")
|
||||
|
||||
commits_url = f"{domain}/api/v4/projects/{project_id}/repository/commits"
|
||||
# URL encode the repository path
|
||||
encoded_repository = urllib.parse.quote(repository, safe="")
|
||||
commits_url = f"{domain}/api/v4/projects/{encoded_repository}/repository/commits"
|
||||
|
||||
# Fetch commits for the repository
|
||||
params = {"since": start_time, "until": end_time}
|
||||
if branch:
|
||||
params["ref_name"] = branch
|
||||
if employee:
|
||||
params["author"] = employee
|
||||
|
||||
|
@ -96,10 +79,7 @@ class GitlabCommitsTool(BuiltinTool):
|
|||
commit_sha = commit["id"]
|
||||
author_name = commit["author_name"]
|
||||
|
||||
if is_repository:
|
||||
diff_url = f"{domain}/api/v4/projects/{encoded_identifier}/repository/commits/{commit_sha}/diff"
|
||||
else:
|
||||
diff_url = f"{domain}/api/v4/projects/{project_id}/repository/commits/{commit_sha}/diff"
|
||||
diff_url = f"{domain}/api/v4/projects/{encoded_repository}/repository/commits/{commit_sha}/diff"
|
||||
|
||||
diff_response = requests.get(diff_url, headers=headers)
|
||||
diff_response.raise_for_status()
|
||||
|
@ -120,7 +100,14 @@ class GitlabCommitsTool(BuiltinTool):
|
|||
if line.startswith("+") and not line.startswith("+++")
|
||||
]
|
||||
)
|
||||
results.append({"commit_sha": commit_sha, "author_name": author_name, "diff": final_code})
|
||||
results.append(
|
||||
{
|
||||
"diff_url": diff_url,
|
||||
"commit_sha": commit_sha,
|
||||
"author_name": author_name,
|
||||
"diff": final_code,
|
||||
}
|
||||
)
|
||||
else:
|
||||
if total_changes > 1:
|
||||
final_code = "".join(
|
||||
|
@ -134,7 +121,12 @@ class GitlabCommitsTool(BuiltinTool):
|
|||
)
|
||||
final_code_escaped = json.dumps(final_code)[1:-1] # Escape the final code
|
||||
results.append(
|
||||
{"commit_sha": commit_sha, "author_name": author_name, "diff": final_code_escaped}
|
||||
{
|
||||
"diff_url": diff_url,
|
||||
"commit_sha": commit_sha,
|
||||
"author_name": author_name,
|
||||
"diff": final_code_escaped,
|
||||
}
|
||||
)
|
||||
except requests.RequestException as e:
|
||||
print(f"Error fetching data from GitLab: {e}")
|
||||
|
|
|
@ -23,7 +23,7 @@ parameters:
|
|||
form: llm
|
||||
- name: repository
|
||||
type: string
|
||||
required: false
|
||||
required: true
|
||||
label:
|
||||
en_US: repository
|
||||
zh_Hans: 仓库路径
|
||||
|
@ -32,16 +32,16 @@ parameters:
|
|||
zh_Hans: 仓库路径,以namespace/project_name的形式。
|
||||
llm_description: Repository path for GitLab, like namespace/project_name.
|
||||
form: llm
|
||||
- name: project
|
||||
- name: branch
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: project
|
||||
zh_Hans: 项目名
|
||||
en_US: branch
|
||||
zh_Hans: 分支名
|
||||
human_description:
|
||||
en_US: project
|
||||
zh_Hans: 项目名
|
||||
llm_description: project for GitLab
|
||||
en_US: branch
|
||||
zh_Hans: 分支名
|
||||
llm_description: branch for GitLab
|
||||
form: llm
|
||||
- name: start_time
|
||||
type: string
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
import urllib.parse
|
||||
from typing import Any, Union
|
||||
|
||||
import requests
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
|
||||
|
||||
class GitlabMergeRequestsTool(BuiltinTool):
|
||||
def _invoke(
|
||||
self, user_id: str, tool_parameters: dict[str, Any]
|
||||
) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
|
||||
repository = tool_parameters.get("repository", "")
|
||||
branch = tool_parameters.get("branch", "")
|
||||
start_time = tool_parameters.get("start_time", "")
|
||||
end_time = tool_parameters.get("end_time", "")
|
||||
state = tool_parameters.get("state", "opened") # Default to "opened"
|
||||
|
||||
if not repository:
|
||||
return self.create_text_message("Repository is required")
|
||||
|
||||
access_token = self.runtime.credentials.get("access_tokens")
|
||||
site_url = self.runtime.credentials.get("site_url")
|
||||
|
||||
if not access_token:
|
||||
return self.create_text_message("Gitlab API Access Tokens is required.")
|
||||
if not site_url:
|
||||
site_url = "https://gitlab.com"
|
||||
|
||||
# Get merge requests
|
||||
result = self.get_merge_requests(site_url, access_token, repository, branch, start_time, end_time, state)
|
||||
|
||||
return [self.create_json_message(item) for item in result]
|
||||
|
||||
def get_merge_requests(
|
||||
self, site_url: str, access_token: str, repository: str, branch: str, start_time: str, end_time: str, state: str
|
||||
) -> list[dict[str, Any]]:
|
||||
domain = site_url
|
||||
headers = {"PRIVATE-TOKEN": access_token}
|
||||
results = []
|
||||
|
||||
try:
|
||||
# URL encode the repository path
|
||||
encoded_repository = urllib.parse.quote(repository, safe="")
|
||||
merge_requests_url = f"{domain}/api/v4/projects/{encoded_repository}/merge_requests"
|
||||
params = {"state": state}
|
||||
|
||||
# Add time filters if provided
|
||||
if start_time:
|
||||
params["created_after"] = start_time
|
||||
if end_time:
|
||||
params["created_before"] = end_time
|
||||
|
||||
response = requests.get(merge_requests_url, headers=headers, params=params)
|
||||
response.raise_for_status()
|
||||
merge_requests = response.json()
|
||||
|
||||
for mr in merge_requests:
|
||||
# Filter by target branch
|
||||
if branch and mr["target_branch"] != branch:
|
||||
continue
|
||||
|
||||
results.append(
|
||||
{
|
||||
"id": mr["id"],
|
||||
"title": mr["title"],
|
||||
"author": mr["author"]["name"],
|
||||
"web_url": mr["web_url"],
|
||||
"target_branch": mr["target_branch"],
|
||||
"created_at": mr["created_at"],
|
||||
"state": mr["state"],
|
||||
}
|
||||
)
|
||||
except requests.RequestException as e:
|
||||
print(f"Error fetching merge requests from GitLab: {e}")
|
||||
|
||||
return results
|
|
@ -0,0 +1,77 @@
|
|||
identity:
|
||||
name: gitlab_mergerequests
|
||||
author: Leo.Wang
|
||||
label:
|
||||
en_US: GitLab Merge Requests
|
||||
zh_Hans: GitLab 合并请求查询
|
||||
description:
|
||||
human:
|
||||
en_US: A tool for query GitLab merge requests, Input should be a exists reposity or branch.
|
||||
zh_Hans: 一个用于查询 GitLab 代码合并请求的工具,输入的内容应该是一个已存在的仓库名或者分支。
|
||||
llm: A tool for query GitLab merge requests, Input should be a exists reposity or branch.
|
||||
parameters:
|
||||
- name: repository
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: repository
|
||||
zh_Hans: 仓库路径
|
||||
human_description:
|
||||
en_US: repository
|
||||
zh_Hans: 仓库路径,以namespace/project_name的形式。
|
||||
llm_description: Repository path for GitLab, like namespace/project_name.
|
||||
form: llm
|
||||
- name: branch
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: branch
|
||||
zh_Hans: 分支名
|
||||
human_description:
|
||||
en_US: branch
|
||||
zh_Hans: 分支名
|
||||
llm_description: branch for GitLab
|
||||
form: llm
|
||||
- name: start_time
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: start_time
|
||||
zh_Hans: 开始时间
|
||||
human_description:
|
||||
en_US: start_time
|
||||
zh_Hans: 开始时间
|
||||
llm_description: Start time for GitLab
|
||||
form: llm
|
||||
- name: end_time
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: end_time
|
||||
zh_Hans: 结束时间
|
||||
human_description:
|
||||
en_US: end_time
|
||||
zh_Hans: 结束时间
|
||||
llm_description: End time for GitLab
|
||||
form: llm
|
||||
- name: state
|
||||
type: select
|
||||
required: false
|
||||
options:
|
||||
- value: opened
|
||||
label:
|
||||
en_US: opened
|
||||
zh_Hans: 打开
|
||||
- value: closed
|
||||
label:
|
||||
en_US: closed
|
||||
zh_Hans: 关闭
|
||||
default: opened
|
||||
label:
|
||||
en_US: state
|
||||
zh_Hans: 变更状态
|
||||
human_description:
|
||||
en_US: state
|
||||
zh_Hans: 变更状态
|
||||
llm_description: Merge request state type for GitLab
|
||||
form: llm
|
|
@ -0,0 +1,81 @@
|
|||
import urllib.parse
|
||||
from typing import Any, Union
|
||||
|
||||
import requests
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
|
||||
|
||||
class GitlabProjectsTool(BuiltinTool):
|
||||
def _invoke(
|
||||
self, user_id: str, tool_parameters: dict[str, Any]
|
||||
) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
|
||||
project_name = tool_parameters.get("project_name", "")
|
||||
page = tool_parameters.get("page", 1)
|
||||
page_size = tool_parameters.get("page_size", 20)
|
||||
|
||||
access_token = self.runtime.credentials.get("access_tokens")
|
||||
site_url = self.runtime.credentials.get("site_url")
|
||||
|
||||
if not access_token:
|
||||
return self.create_text_message("Gitlab API Access Tokens is required.")
|
||||
if not site_url:
|
||||
site_url = "https://gitlab.com"
|
||||
|
||||
# Get project content
|
||||
result = self.fetch_projects(site_url, access_token, project_name, page, page_size)
|
||||
|
||||
return [self.create_json_message(item) for item in result]
|
||||
|
||||
def fetch_projects(
|
||||
self,
|
||||
site_url: str,
|
||||
access_token: str,
|
||||
project_name: str,
|
||||
page: str,
|
||||
page_size: str,
|
||||
) -> list[dict[str, Any]]:
|
||||
domain = site_url
|
||||
headers = {"PRIVATE-TOKEN": access_token}
|
||||
results = []
|
||||
|
||||
try:
|
||||
if project_name:
|
||||
# URL encode the project name for the search query
|
||||
encoded_project_name = urllib.parse.quote(project_name, safe="")
|
||||
projects_url = (
|
||||
f"{domain}/api/v4/projects?search={encoded_project_name}&page={page}&per_page={page_size}"
|
||||
)
|
||||
else:
|
||||
projects_url = f"{domain}/api/v4/projects?page={page}&per_page={page_size}"
|
||||
|
||||
response = requests.get(projects_url, headers=headers)
|
||||
response.raise_for_status()
|
||||
projects = response.json()
|
||||
|
||||
for project in projects:
|
||||
# Filter projects by exact name match if necessary
|
||||
if project_name and project["name"].lower() == project_name.lower():
|
||||
results.append(
|
||||
{
|
||||
"id": project["id"],
|
||||
"name": project["name"],
|
||||
"description": project.get("description", ""),
|
||||
"web_url": project["web_url"],
|
||||
}
|
||||
)
|
||||
elif not project_name:
|
||||
# If no specific project name is provided, add all projects
|
||||
results.append(
|
||||
{
|
||||
"id": project["id"],
|
||||
"name": project["name"],
|
||||
"description": project.get("description", ""),
|
||||
"web_url": project["web_url"],
|
||||
}
|
||||
)
|
||||
except requests.RequestException as e:
|
||||
print(f"Error fetching data from GitLab: {e}")
|
||||
|
||||
return results
|
|
@ -0,0 +1,45 @@
|
|||
identity:
|
||||
name: gitlab_projects
|
||||
author: Leo.Wang
|
||||
label:
|
||||
en_US: GitLab Projects
|
||||
zh_Hans: GitLab 项目列表查询
|
||||
description:
|
||||
human:
|
||||
en_US: A tool for query GitLab projects, Input should be a project name.
|
||||
zh_Hans: 一个用于查询 GitLab 项目列表的工具,输入的内容应该是一个项目名称。
|
||||
llm: A tool for query GitLab projects, Input should be a project name.
|
||||
parameters:
|
||||
- name: project_name
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: project_name
|
||||
zh_Hans: 项目名称
|
||||
human_description:
|
||||
en_US: project_name
|
||||
zh_Hans: 项目名称
|
||||
llm_description: Project name for GitLab
|
||||
form: llm
|
||||
- name: page
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: page
|
||||
zh_Hans: 页码
|
||||
human_description:
|
||||
en_US: page
|
||||
zh_Hans: 页码
|
||||
llm_description: Page index for GitLab
|
||||
form: llm
|
||||
- name: page_size
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: page_size
|
||||
zh_Hans: 每页数量
|
||||
human_description:
|
||||
en_US: page_size
|
||||
zh_Hans: 每页数量
|
||||
llm_description: Page size for GitLab
|
||||
form: llm
|
BIN
api/core/tools/provider/builtin/lark_base/_assets/icon.png
Normal file
BIN
api/core/tools/provider/builtin/lark_base/_assets/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
7
api/core/tools/provider/builtin/lark_base/lark_base.py
Normal file
7
api/core/tools/provider/builtin/lark_base/lark_base.py
Normal file
|
@ -0,0 +1,7 @@
|
|||
from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController
|
||||
from core.tools.utils.lark_api_utils import lark_auth
|
||||
|
||||
|
||||
class LarkBaseProvider(BuiltinToolProviderController):
|
||||
def _validate_credentials(self, credentials: dict) -> None:
|
||||
lark_auth(credentials)
|
36
api/core/tools/provider/builtin/lark_base/lark_base.yaml
Normal file
36
api/core/tools/provider/builtin/lark_base/lark_base.yaml
Normal file
|
@ -0,0 +1,36 @@
|
|||
identity:
|
||||
author: Doug Lea
|
||||
name: lark_base
|
||||
label:
|
||||
en_US: Lark Base
|
||||
zh_Hans: Lark 多维表格
|
||||
description:
|
||||
en_US: |
|
||||
Lark base, requires the following permissions: bitable:app.
|
||||
zh_Hans: |
|
||||
Lark 多维表格,需要开通以下权限: bitable:app。
|
||||
icon: icon.png
|
||||
tags:
|
||||
- social
|
||||
- productivity
|
||||
credentials_for_provider:
|
||||
app_id:
|
||||
type: text-input
|
||||
required: true
|
||||
label:
|
||||
en_US: APP ID
|
||||
placeholder:
|
||||
en_US: Please input your Lark app id
|
||||
zh_Hans: 请输入你的 Lark app id
|
||||
help:
|
||||
en_US: Get your app_id and app_secret from Lark
|
||||
zh_Hans: 从 Lark 获取您的 app_id 和 app_secret
|
||||
url: https://open.larksuite.com/app
|
||||
app_secret:
|
||||
type: secret-input
|
||||
required: true
|
||||
label:
|
||||
en_US: APP Secret
|
||||
placeholder:
|
||||
en_US: Please input your app secret
|
||||
zh_Hans: 请输入你的 Lark app secret
|
|
@ -0,0 +1,21 @@
|
|||
from typing import Any
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
from core.tools.utils.lark_api_utils import LarkRequest
|
||||
|
||||
|
||||
class AddRecordsTool(BuiltinTool):
|
||||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
|
||||
app_id = self.runtime.credentials.get("app_id")
|
||||
app_secret = self.runtime.credentials.get("app_secret")
|
||||
client = LarkRequest(app_id, app_secret)
|
||||
|
||||
app_token = tool_parameters.get("app_token")
|
||||
table_id = tool_parameters.get("table_id")
|
||||
table_name = tool_parameters.get("table_name")
|
||||
records = tool_parameters.get("records")
|
||||
user_id_type = tool_parameters.get("user_id_type", "open_id")
|
||||
|
||||
res = client.add_records(app_token, table_id, table_name, records, user_id_type)
|
||||
return self.create_json_message(res)
|
|
@ -0,0 +1,91 @@
|
|||
identity:
|
||||
name: add_records
|
||||
author: Doug Lea
|
||||
label:
|
||||
en_US: Add Records
|
||||
zh_Hans: 新增多条记录
|
||||
description:
|
||||
human:
|
||||
en_US: Add Multiple Records to Multidimensional Table
|
||||
zh_Hans: 在多维表格数据表中新增多条记录
|
||||
llm: A tool for adding multiple records to a multidimensional table. (在多维表格数据表中新增多条记录)
|
||||
parameters:
|
||||
- name: app_token
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: app_token
|
||||
zh_Hans: app_token
|
||||
human_description:
|
||||
en_US: Unique identifier for the multidimensional table, supports inputting document URL.
|
||||
zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。
|
||||
llm_description: 多维表格的唯一标识符,支持输入文档 URL。
|
||||
form: llm
|
||||
|
||||
- name: table_id
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: table_id
|
||||
zh_Hans: table_id
|
||||
human_description:
|
||||
en_US: Unique identifier for the multidimensional table data, either table_id or table_name must be provided, cannot be empty simultaneously.
|
||||
zh_Hans: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。
|
||||
llm_description: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。
|
||||
form: llm
|
||||
|
||||
- name: table_name
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: table_name
|
||||
zh_Hans: table_name
|
||||
human_description:
|
||||
en_US: Name of the multidimensional table data, either table_name or table_id must be provided, cannot be empty simultaneously.
|
||||
zh_Hans: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。
|
||||
llm_description: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。
|
||||
form: llm
|
||||
|
||||
- name: records
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: records
|
||||
zh_Hans: 记录列表
|
||||
human_description:
|
||||
en_US: |
|
||||
List of records to be added in this request. Example value: [{"multi-line-text":"text content","single_select":"option 1","date":1674206443000}]
|
||||
For supported field types, refer to the integration guide (https://open.larkoffice.com/document/server-docs/docs/bitable-v1/notification). For data structures of different field types, refer to the data structure overview (https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure).
|
||||
zh_Hans: |
|
||||
本次请求将要新增的记录列表,示例值:[{"多行文本":"文本内容","单选":"选项 1","日期":1674206443000}]。
|
||||
当前接口支持的字段类型请参考接入指南(https://open.larkoffice.com/document/server-docs/docs/bitable-v1/notification),不同类型字段的数据结构请参考数据结构概述(https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure)。
|
||||
llm_description: |
|
||||
本次请求将要新增的记录列表,示例值:[{"多行文本":"文本内容","单选":"选项 1","日期":1674206443000}]。
|
||||
当前接口支持的字段类型请参考接入指南(https://open.larkoffice.com/document/server-docs/docs/bitable-v1/notification),不同类型字段的数据结构请参考数据结构概述(https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure)。
|
||||
form: llm
|
||||
|
||||
- name: user_id_type
|
||||
type: select
|
||||
required: false
|
||||
options:
|
||||
- value: open_id
|
||||
label:
|
||||
en_US: open_id
|
||||
zh_Hans: open_id
|
||||
- value: union_id
|
||||
label:
|
||||
en_US: union_id
|
||||
zh_Hans: union_id
|
||||
- value: user_id
|
||||
label:
|
||||
en_US: user_id
|
||||
zh_Hans: user_id
|
||||
default: "open_id"
|
||||
label:
|
||||
en_US: user_id_type
|
||||
zh_Hans: 用户 ID 类型
|
||||
human_description:
|
||||
en_US: User ID type, optional values are open_id, union_id, user_id, with a default value of open_id.
|
||||
zh_Hans: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。
|
||||
llm_description: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。
|
||||
form: form
|
|
@ -0,0 +1,18 @@
|
|||
from typing import Any
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
from core.tools.utils.lark_api_utils import LarkRequest
|
||||
|
||||
|
||||
class CreateBaseTool(BuiltinTool):
|
||||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
|
||||
app_id = self.runtime.credentials.get("app_id")
|
||||
app_secret = self.runtime.credentials.get("app_secret")
|
||||
client = LarkRequest(app_id, app_secret)
|
||||
|
||||
name = tool_parameters.get("name")
|
||||
folder_token = tool_parameters.get("folder_token")
|
||||
|
||||
res = client.create_base(name, folder_token)
|
||||
return self.create_json_message(res)
|
|
@ -0,0 +1,42 @@
|
|||
identity:
|
||||
name: create_base
|
||||
author: Doug Lea
|
||||
label:
|
||||
en_US: Create Base
|
||||
zh_Hans: 创建多维表格
|
||||
description:
|
||||
human:
|
||||
en_US: Create Multidimensional Table in Specified Directory
|
||||
zh_Hans: 在指定目录下创建多维表格
|
||||
llm: A tool for creating a multidimensional table in a specified directory. (在指定目录下创建多维表格)
|
||||
parameters:
|
||||
- name: name
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: name
|
||||
zh_Hans: 多维表格 App 名字
|
||||
human_description:
|
||||
en_US: |
|
||||
Name of the multidimensional table App. Example value: "A new multidimensional table".
|
||||
zh_Hans: 多维表格 App 名字,示例值:"一篇新的多维表格"。
|
||||
llm_description: 多维表格 App 名字,示例值:"一篇新的多维表格"。
|
||||
form: llm
|
||||
|
||||
- name: folder_token
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: folder_token
|
||||
zh_Hans: 多维表格 App 归属文件夹
|
||||
human_description:
|
||||
en_US: |
|
||||
Folder where the multidimensional table App belongs. Default is empty, meaning the table will be created in the root directory of the cloud space. Example values: Lf8uf6BoAlWkUfdGtpMjUV0PpZd or https://lark-japan.jp.larksuite.com/drive/folder/Lf8uf6BoAlWkUfdGtpMjUV0PpZd.
|
||||
The folder_token must be an existing folder and supports inputting folder token or folder URL.
|
||||
zh_Hans: |
|
||||
多维表格 App 归属文件夹。默认为空,表示多维表格将被创建在云空间根目录。示例值: Lf8uf6BoAlWkUfdGtpMjUV0PpZd 或者 https://lark-japan.jp.larksuite.com/drive/folder/Lf8uf6BoAlWkUfdGtpMjUV0PpZd。
|
||||
folder_token 必须是已存在的文件夹,支持输入文件夹 token 或者文件夹 URL。
|
||||
llm_description: |
|
||||
多维表格 App 归属文件夹。默认为空,表示多维表格将被创建在云空间根目录。示例值: Lf8uf6BoAlWkUfdGtpMjUV0PpZd 或者 https://lark-japan.jp.larksuite.com/drive/folder/Lf8uf6BoAlWkUfdGtpMjUV0PpZd。
|
||||
folder_token 必须是已存在的文件夹,支持输入文件夹 token 或者文件夹 URL。
|
||||
form: llm
|
|
@ -0,0 +1,20 @@
|
|||
from typing import Any
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
from core.tools.utils.lark_api_utils import LarkRequest
|
||||
|
||||
|
||||
class CreateTableTool(BuiltinTool):
|
||||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
|
||||
app_id = self.runtime.credentials.get("app_id")
|
||||
app_secret = self.runtime.credentials.get("app_secret")
|
||||
client = LarkRequest(app_id, app_secret)
|
||||
|
||||
app_token = tool_parameters.get("app_token")
|
||||
table_name = tool_parameters.get("table_name")
|
||||
default_view_name = tool_parameters.get("default_view_name")
|
||||
fields = tool_parameters.get("fields")
|
||||
|
||||
res = client.create_table(app_token, table_name, default_view_name, fields)
|
||||
return self.create_json_message(res)
|
|
@ -0,0 +1,61 @@
|
|||
identity:
|
||||
name: create_table
|
||||
author: Doug Lea
|
||||
label:
|
||||
en_US: Create Table
|
||||
zh_Hans: 新增数据表
|
||||
description:
|
||||
human:
|
||||
en_US: Add a Data Table to Multidimensional Table
|
||||
zh_Hans: 在多维表格中新增一个数据表
|
||||
llm: A tool for adding a data table to a multidimensional table. (在多维表格中新增一个数据表)
|
||||
parameters:
|
||||
- name: app_token
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: app_token
|
||||
zh_Hans: app_token
|
||||
human_description:
|
||||
en_US: Unique identifier for the multidimensional table, supports inputting document URL.
|
||||
zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。
|
||||
llm_description: 多维表格的唯一标识符,支持输入文档 URL。
|
||||
form: llm
|
||||
|
||||
- name: table_name
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: Table Name
|
||||
zh_Hans: 数据表名称
|
||||
human_description:
|
||||
en_US: |
|
||||
The name of the data table, length range: 1 character to 100 characters.
|
||||
zh_Hans: 数据表名称,长度范围:1 字符 ~ 100 字符。
|
||||
llm_description: 数据表名称,长度范围:1 字符 ~ 100 字符。
|
||||
form: llm
|
||||
|
||||
- name: default_view_name
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: Default View Name
|
||||
zh_Hans: 默认表格视图的名称
|
||||
human_description:
|
||||
en_US: The name of the default table view, defaults to "Table" if not filled.
|
||||
zh_Hans: 默认表格视图的名称,不填则默认为"表格"。
|
||||
llm_description: 默认表格视图的名称,不填则默认为"表格"。
|
||||
form: llm
|
||||
|
||||
- name: fields
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: Initial Fields
|
||||
zh_Hans: 初始字段
|
||||
human_description:
|
||||
en_US: |
|
||||
Initial fields of the data table, format: [ { "field_name": "Multi-line Text","type": 1 },{ "field_name": "Number","type": 2 },{ "field_name": "Single Select","type": 3 },{ "field_name": "Multiple Select","type": 4 },{ "field_name": "Date","type": 5 } ]. For field details, refer to: https://open.larkoffice.com/document/server-docs/docs/bitable-v1/app-table-field/guide
|
||||
zh_Hans: 数据表的初始字段,格式为:[{"field_name":"多行文本","type":1},{"field_name":"数字","type":2},{"field_name":"单选","type":3},{"field_name":"多选","type":4},{"field_name":"日期","type":5}]。字段详情参考:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/app-table-field/guide
|
||||
llm_description: 数据表的初始字段,格式为:[{"field_name":"多行文本","type":1},{"field_name":"数字","type":2},{"field_name":"单选","type":3},{"field_name":"多选","type":4},{"field_name":"日期","type":5}]。字段详情参考:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/app-table-field/guide
|
||||
form: llm
|
|
@ -0,0 +1,20 @@
|
|||
from typing import Any
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
from core.tools.utils.lark_api_utils import LarkRequest
|
||||
|
||||
|
||||
class DeleteRecordsTool(BuiltinTool):
|
||||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
|
||||
app_id = self.runtime.credentials.get("app_id")
|
||||
app_secret = self.runtime.credentials.get("app_secret")
|
||||
client = LarkRequest(app_id, app_secret)
|
||||
|
||||
app_token = tool_parameters.get("app_token")
|
||||
table_id = tool_parameters.get("table_id")
|
||||
table_name = tool_parameters.get("table_name")
|
||||
record_ids = tool_parameters.get("record_ids")
|
||||
|
||||
res = client.delete_records(app_token, table_id, table_name, record_ids)
|
||||
return self.create_json_message(res)
|
|
@ -0,0 +1,86 @@
|
|||
identity:
|
||||
name: delete_records
|
||||
author: Doug Lea
|
||||
label:
|
||||
en_US: Delete Records
|
||||
zh_Hans: 删除多条记录
|
||||
description:
|
||||
human:
|
||||
en_US: Delete Multiple Records from Multidimensional Table
|
||||
zh_Hans: 删除多维表格数据表中的多条记录
|
||||
llm: A tool for deleting multiple records from a multidimensional table. (删除多维表格数据表中的多条记录)
|
||||
parameters:
|
||||
- name: app_token
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: app_token
|
||||
zh_Hans: app_token
|
||||
human_description:
|
||||
en_US: Unique identifier for the multidimensional table, supports inputting document URL.
|
||||
zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。
|
||||
llm_description: 多维表格的唯一标识符,支持输入文档 URL。
|
||||
form: llm
|
||||
|
||||
- name: table_id
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: table_id
|
||||
zh_Hans: table_id
|
||||
human_description:
|
||||
en_US: Unique identifier for the multidimensional table data, either table_id or table_name must be provided, cannot be empty simultaneously.
|
||||
zh_Hans: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。
|
||||
llm_description: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。
|
||||
form: llm
|
||||
|
||||
- name: table_name
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: table_name
|
||||
zh_Hans: table_name
|
||||
human_description:
|
||||
en_US: Name of the multidimensional table data, either table_name or table_id must be provided, cannot be empty simultaneously.
|
||||
zh_Hans: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。
|
||||
llm_description: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。
|
||||
form: llm
|
||||
|
||||
- name: record_ids
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: Record IDs
|
||||
zh_Hans: 记录 ID 列表
|
||||
human_description:
|
||||
en_US: |
|
||||
List of IDs for the records to be deleted, example value: ["recwNXzPQv"].
|
||||
zh_Hans: 删除的多条记录 ID 列表,示例值:["recwNXzPQv"]。
|
||||
llm_description: 删除的多条记录 ID 列表,示例值:["recwNXzPQv"]。
|
||||
form: llm
|
||||
|
||||
- name: user_id_type
|
||||
type: select
|
||||
required: false
|
||||
options:
|
||||
- value: open_id
|
||||
label:
|
||||
en_US: open_id
|
||||
zh_Hans: open_id
|
||||
- value: union_id
|
||||
label:
|
||||
en_US: union_id
|
||||
zh_Hans: union_id
|
||||
- value: user_id
|
||||
label:
|
||||
en_US: user_id
|
||||
zh_Hans: user_id
|
||||
default: "open_id"
|
||||
label:
|
||||
en_US: user_id_type
|
||||
zh_Hans: 用户 ID 类型
|
||||
human_description:
|
||||
en_US: User ID type, optional values are open_id, union_id, user_id, with a default value of open_id.
|
||||
zh_Hans: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。
|
||||
llm_description: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。
|
||||
form: form
|
|
@ -0,0 +1,19 @@
|
|||
from typing import Any
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
from core.tools.utils.lark_api_utils import LarkRequest
|
||||
|
||||
|
||||
class DeleteTablesTool(BuiltinTool):
|
||||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
|
||||
app_id = self.runtime.credentials.get("app_id")
|
||||
app_secret = self.runtime.credentials.get("app_secret")
|
||||
client = LarkRequest(app_id, app_secret)
|
||||
|
||||
app_token = tool_parameters.get("app_token")
|
||||
table_ids = tool_parameters.get("table_ids")
|
||||
table_names = tool_parameters.get("table_names")
|
||||
|
||||
res = client.delete_tables(app_token, table_ids, table_names)
|
||||
return self.create_json_message(res)
|
|
@ -0,0 +1,49 @@
|
|||
identity:
|
||||
name: delete_tables
|
||||
author: Doug Lea
|
||||
label:
|
||||
en_US: Delete Tables
|
||||
zh_Hans: 删除数据表
|
||||
description:
|
||||
human:
|
||||
en_US: Batch Delete Data Tables from Multidimensional Table
|
||||
zh_Hans: 批量删除多维表格中的数据表
|
||||
llm: A tool for batch deleting data tables from a multidimensional table. (批量删除多维表格中的数据表)
|
||||
parameters:
|
||||
- name: app_token
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: app_token
|
||||
zh_Hans: app_token
|
||||
human_description:
|
||||
en_US: Unique identifier for the multidimensional table, supports inputting document URL.
|
||||
zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。
|
||||
llm_description: 多维表格的唯一标识符,支持输入文档 URL。
|
||||
form: llm
|
||||
|
||||
- name: table_ids
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: Table IDs
|
||||
zh_Hans: 数据表 ID
|
||||
human_description:
|
||||
en_US: |
|
||||
IDs of the tables to be deleted. Each operation supports deleting up to 50 tables. Example: ["tbl1TkhyTWDkSoZ3"]. Ensure that either table_ids or table_names is not empty.
|
||||
zh_Hans: 待删除的数据表的 ID,每次操作最多支持删除 50 个数据表。示例值:["tbl1TkhyTWDkSoZ3"]。请确保 table_ids 和 table_names 至少有一个不为空。
|
||||
llm_description: 待删除的数据表的 ID,每次操作最多支持删除 50 个数据表。示例值:["tbl1TkhyTWDkSoZ3"]。请确保 table_ids 和 table_names 至少有一个不为空。
|
||||
form: llm
|
||||
|
||||
- name: table_names
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: Table Names
|
||||
zh_Hans: 数据表名称
|
||||
human_description:
|
||||
en_US: |
|
||||
Names of the tables to be deleted. Each operation supports deleting up to 50 tables. Example: ["Table1", "Table2"]. Ensure that either table_names or table_ids is not empty.
|
||||
zh_Hans: 待删除的数据表的名称,每次操作最多支持删除 50 个数据表。示例值:["数据表1", "数据表2"]。请确保 table_names 和 table_ids 至少有一个不为空。
|
||||
llm_description: 待删除的数据表的名称,每次操作最多支持删除 50 个数据表。示例值:["数据表1", "数据表2"]。请确保 table_names 和 table_ids 至少有一个不为空。
|
||||
form: llm
|
|
@ -0,0 +1,17 @@
|
|||
from typing import Any
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
from core.tools.utils.lark_api_utils import LarkRequest
|
||||
|
||||
|
||||
class GetBaseInfoTool(BuiltinTool):
|
||||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
|
||||
app_id = self.runtime.credentials.get("app_id")
|
||||
app_secret = self.runtime.credentials.get("app_secret")
|
||||
client = LarkRequest(app_id, app_secret)
|
||||
|
||||
app_token = tool_parameters.get("app_token")
|
||||
|
||||
res = client.get_base_info(app_token)
|
||||
return self.create_json_message(res)
|
|
@ -0,0 +1,23 @@
|
|||
identity:
|
||||
name: get_base_info
|
||||
author: Doug Lea
|
||||
label:
|
||||
en_US: Get Base Info
|
||||
zh_Hans: 获取多维表格元数据
|
||||
description:
|
||||
human:
|
||||
en_US: Get Metadata Information of Specified Multidimensional Table
|
||||
zh_Hans: 获取指定多维表格的元数据信息
|
||||
llm: A tool for getting metadata information of a specified multidimensional table. (获取指定多维表格的元数据信息)
|
||||
parameters:
|
||||
- name: app_token
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: app_token
|
||||
zh_Hans: app_token
|
||||
human_description:
|
||||
en_US: Unique identifier for the multidimensional table, supports inputting document URL.
|
||||
zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。
|
||||
llm_description: 多维表格的唯一标识符,支持输入文档 URL。
|
||||
form: llm
|
|
@ -0,0 +1,19 @@
|
|||
from typing import Any
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
from core.tools.utils.lark_api_utils import LarkRequest
|
||||
|
||||
|
||||
class ListTablesTool(BuiltinTool):
|
||||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
|
||||
app_id = self.runtime.credentials.get("app_id")
|
||||
app_secret = self.runtime.credentials.get("app_secret")
|
||||
client = LarkRequest(app_id, app_secret)
|
||||
|
||||
app_token = tool_parameters.get("app_token")
|
||||
page_token = tool_parameters.get("page_token")
|
||||
page_size = tool_parameters.get("page_size", 20)
|
||||
|
||||
res = client.list_tables(app_token, page_token, page_size)
|
||||
return self.create_json_message(res)
|
|
@ -0,0 +1,50 @@
|
|||
identity:
|
||||
name: list_tables
|
||||
author: Doug Lea
|
||||
label:
|
||||
en_US: List Tables
|
||||
zh_Hans: 列出数据表
|
||||
description:
|
||||
human:
|
||||
en_US: Get All Data Tables under Multidimensional Table
|
||||
zh_Hans: 获取多维表格下的所有数据表
|
||||
llm: A tool for getting all data tables under a multidimensional table. (获取多维表格下的所有数据表)
|
||||
parameters:
|
||||
- name: app_token
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: app_token
|
||||
zh_Hans: app_token
|
||||
human_description:
|
||||
en_US: Unique identifier for the multidimensional table, supports inputting document URL.
|
||||
zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。
|
||||
llm_description: 多维表格的唯一标识符,支持输入文档 URL。
|
||||
form: llm
|
||||
|
||||
- name: page_size
|
||||
type: number
|
||||
required: false
|
||||
default: 20
|
||||
label:
|
||||
en_US: page_size
|
||||
zh_Hans: 分页大小
|
||||
human_description:
|
||||
en_US: |
|
||||
Page size, default value: 20, maximum value: 100.
|
||||
zh_Hans: 分页大小,默认值:20,最大值:100。
|
||||
llm_description: 分页大小,默认值:20,最大值:100。
|
||||
form: form
|
||||
|
||||
- name: page_token
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: page_token
|
||||
zh_Hans: 分页标记
|
||||
human_description:
|
||||
en_US: |
|
||||
Page token, leave empty for the first request to start from the beginning; a new page_token will be returned if there are more items in the paginated query results, which can be used for the next traversal. Example value: "tblsRc9GRRXKqhvW".
|
||||
zh_Hans: 分页标记,第一次请求不填,表示从头开始遍历;分页查询结果还有更多项时会同时返回新的 page_token,下次遍历可采用该 page_token 获取查询结果。示例值:"tblsRc9GRRXKqhvW"。
|
||||
llm_description: 分页标记,第一次请求不填,表示从头开始遍历;分页查询结果还有更多项时会同时返回新的 page_token,下次遍历可采用该 page_token 获取查询结果。示例值:"tblsRc9GRRXKqhvW"。
|
||||
form: llm
|
|
@ -0,0 +1,21 @@
|
|||
from typing import Any
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
from core.tools.utils.lark_api_utils import LarkRequest
|
||||
|
||||
|
||||
class ReadRecordsTool(BuiltinTool):
|
||||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
|
||||
app_id = self.runtime.credentials.get("app_id")
|
||||
app_secret = self.runtime.credentials.get("app_secret")
|
||||
client = LarkRequest(app_id, app_secret)
|
||||
|
||||
app_token = tool_parameters.get("app_token")
|
||||
table_id = tool_parameters.get("table_id")
|
||||
table_name = tool_parameters.get("table_name")
|
||||
record_ids = tool_parameters.get("record_ids")
|
||||
user_id_type = tool_parameters.get("user_id_type", "open_id")
|
||||
|
||||
res = client.read_records(app_token, table_id, table_name, record_ids, user_id_type)
|
||||
return self.create_json_message(res)
|
|
@ -0,0 +1,86 @@
|
|||
identity:
|
||||
name: read_records
|
||||
author: Doug Lea
|
||||
label:
|
||||
en_US: Read Records
|
||||
zh_Hans: 批量获取记录
|
||||
description:
|
||||
human:
|
||||
en_US: Batch Retrieve Records from Multidimensional Table
|
||||
zh_Hans: 批量获取多维表格数据表中的记录信息
|
||||
llm: A tool for batch retrieving records from a multidimensional table, supporting up to 100 records per call. (批量获取多维表格数据表中的记录信息,单次调用最多支持查询 100 条记录)
|
||||
|
||||
parameters:
|
||||
- name: app_token
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: app_token
|
||||
zh_Hans: app_token
|
||||
human_description:
|
||||
en_US: Unique identifier for the multidimensional table, supports inputting document URL.
|
||||
zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。
|
||||
llm_description: 多维表格的唯一标识符,支持输入文档 URL。
|
||||
form: llm
|
||||
|
||||
- name: table_id
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: table_id
|
||||
zh_Hans: table_id
|
||||
human_description:
|
||||
en_US: Unique identifier for the multidimensional table data, either table_id or table_name must be provided, cannot be empty simultaneously.
|
||||
zh_Hans: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。
|
||||
llm_description: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。
|
||||
form: llm
|
||||
|
||||
- name: table_name
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: table_name
|
||||
zh_Hans: table_name
|
||||
human_description:
|
||||
en_US: Name of the multidimensional table data, either table_name or table_id must be provided, cannot be empty simultaneously.
|
||||
zh_Hans: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。
|
||||
llm_description: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。
|
||||
form: llm
|
||||
|
||||
- name: record_ids
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: record_ids
|
||||
zh_Hans: 记录 ID 列表
|
||||
human_description:
|
||||
en_US: List of record IDs, which can be obtained by calling the "Query Records API".
|
||||
zh_Hans: 记录 ID 列表,可以通过调用"查询记录接口"获取。
|
||||
llm_description: 记录 ID 列表,可以通过调用"查询记录接口"获取。
|
||||
form: llm
|
||||
|
||||
- name: user_id_type
|
||||
type: select
|
||||
required: false
|
||||
options:
|
||||
- value: open_id
|
||||
label:
|
||||
en_US: open_id
|
||||
zh_Hans: open_id
|
||||
- value: union_id
|
||||
label:
|
||||
en_US: union_id
|
||||
zh_Hans: union_id
|
||||
- value: user_id
|
||||
label:
|
||||
en_US: user_id
|
||||
zh_Hans: user_id
|
||||
default: "open_id"
|
||||
label:
|
||||
en_US: user_id_type
|
||||
zh_Hans: 用户 ID 类型
|
||||
human_description:
|
||||
en_US: User ID type, optional values are open_id, union_id, user_id, with a default value of open_id.
|
||||
zh_Hans: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。
|
||||
llm_description: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。
|
||||
form: form
|
|
@ -0,0 +1,39 @@
|
|||
from typing import Any
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
from core.tools.utils.lark_api_utils import LarkRequest
|
||||
|
||||
|
||||
class SearchRecordsTool(BuiltinTool):
|
||||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
|
||||
app_id = self.runtime.credentials.get("app_id")
|
||||
app_secret = self.runtime.credentials.get("app_secret")
|
||||
client = LarkRequest(app_id, app_secret)
|
||||
|
||||
app_token = tool_parameters.get("app_token")
|
||||
table_id = tool_parameters.get("table_id")
|
||||
table_name = tool_parameters.get("table_name")
|
||||
view_id = tool_parameters.get("view_id")
|
||||
field_names = tool_parameters.get("field_names")
|
||||
sort = tool_parameters.get("sort")
|
||||
filters = tool_parameters.get("filter")
|
||||
page_token = tool_parameters.get("page_token")
|
||||
automatic_fields = tool_parameters.get("automatic_fields", False)
|
||||
user_id_type = tool_parameters.get("user_id_type", "open_id")
|
||||
page_size = tool_parameters.get("page_size", 20)
|
||||
|
||||
res = client.search_record(
|
||||
app_token,
|
||||
table_id,
|
||||
table_name,
|
||||
view_id,
|
||||
field_names,
|
||||
sort,
|
||||
filters,
|
||||
page_token,
|
||||
automatic_fields,
|
||||
user_id_type,
|
||||
page_size,
|
||||
)
|
||||
return self.create_json_message(res)
|
|
@ -0,0 +1,163 @@
|
|||
identity:
|
||||
name: search_records
|
||||
author: Doug Lea
|
||||
label:
|
||||
en_US: Search Records
|
||||
zh_Hans: 查询记录
|
||||
description:
|
||||
human:
|
||||
en_US: Query records in a multidimensional table, up to 500 rows per query.
|
||||
zh_Hans: 查询多维表格数据表中的记录,单次最多查询 500 行记录。
|
||||
llm: A tool for querying records in a multidimensional table, up to 500 rows per query. (查询多维表格数据表中的记录,单次最多查询 500 行记录)
|
||||
parameters:
|
||||
- name: app_token
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: app_token
|
||||
zh_Hans: app_token
|
||||
human_description:
|
||||
en_US: Unique identifier for the multidimensional table, supports inputting document URL.
|
||||
zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。
|
||||
llm_description: 多维表格的唯一标识符,支持输入文档 URL。
|
||||
form: llm
|
||||
|
||||
- name: table_id
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: table_id
|
||||
zh_Hans: table_id
|
||||
human_description:
|
||||
en_US: Unique identifier for the multidimensional table data, either table_id or table_name must be provided, cannot be empty simultaneously.
|
||||
zh_Hans: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。
|
||||
llm_description: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。
|
||||
form: llm
|
||||
|
||||
- name: table_name
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: table_name
|
||||
zh_Hans: table_name
|
||||
human_description:
|
||||
en_US: Name of the multidimensional table data, either table_name or table_id must be provided, cannot be empty simultaneously.
|
||||
zh_Hans: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。
|
||||
llm_description: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。
|
||||
form: llm
|
||||
|
||||
- name: view_id
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: view_id
|
||||
zh_Hans: 视图唯一标识
|
||||
human_description:
|
||||
en_US: |
|
||||
Unique identifier for a view in a multidimensional table. It can be found in the URL's query parameter with the key 'view'. For example: https://lark-japan.jp.larksuite.com/base/XXX0bfYEraW5OWsbhcFjEqj6pxh?table=tbl5I6jqwz8wBRMv&view=vewW5zXVEU.
|
||||
zh_Hans: 多维表格中视图的唯一标识,可在多维表格的 URL 地址栏中找到,query 参数中 key 为 view 的部分。例如:https://lark-japan.jp.larksuite.com/base/XXX0bfYEraW5OWsbhcFjEqj6pxh?table=tbl5I6jqwz8wBRMv&view=vewW5zXVEU。
|
||||
llm_description: 多维表格中视图的唯一标识,可在多维表格的 URL 地址栏中找到,query 参数中 key 为 view 的部分。例如:https://lark-japan.jp.larksuite.com/base/XXX0bfYEraW5OWsbhcFjEqj6pxh?table=tbl5I6jqwz8wBRMv&view=vewW5zXVEU。
|
||||
form: llm
|
||||
|
||||
- name: field_names
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: field_names
|
||||
zh_Hans: 字段名称
|
||||
human_description:
|
||||
en_US: |
|
||||
Field names to specify which fields to include in the returned records. Example value: ["Field1", "Field2"].
|
||||
zh_Hans: 字段名称,用于指定本次查询返回记录中包含的字段。示例值:["字段1","字段2"]。
|
||||
llm_description: 字段名称,用于指定本次查询返回记录中包含的字段。示例值:["字段1","字段2"]。
|
||||
form: llm
|
||||
|
||||
- name: sort
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: sort
|
||||
zh_Hans: 排序条件
|
||||
human_description:
|
||||
en_US: |
|
||||
Sorting conditions, for example: [{"field_name":"Multiline Text","desc":true}].
|
||||
zh_Hans: 排序条件,例如:[{"field_name":"多行文本","desc":true}]。
|
||||
llm_description: 排序条件,例如:[{"field_name":"多行文本","desc":true}]。
|
||||
form: llm
|
||||
|
||||
- name: filter
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: filter
|
||||
zh_Hans: 筛选条件
|
||||
human_description:
|
||||
en_US: Object containing filter information. For details on how to fill in the filter, refer to the record filter parameter guide (https://open.larkoffice.com/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table-record/record-filter-guide).
|
||||
zh_Hans: 包含条件筛选信息的对象。了解如何填写 filter,参考记录筛选参数填写指南(https://open.larkoffice.com/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table-record/record-filter-guide)。
|
||||
llm_description: 包含条件筛选信息的对象。了解如何填写 filter,参考记录筛选参数填写指南(https://open.larkoffice.com/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table-record/record-filter-guide)。
|
||||
form: llm
|
||||
|
||||
- name: automatic_fields
|
||||
type: boolean
|
||||
required: false
|
||||
label:
|
||||
en_US: automatic_fields
|
||||
zh_Hans: automatic_fields
|
||||
human_description:
|
||||
en_US: Whether to return automatically calculated fields. Default is false, meaning they are not returned.
|
||||
zh_Hans: 是否返回自动计算的字段。默认为 false,表示不返回。
|
||||
llm_description: 是否返回自动计算的字段。默认为 false,表示不返回。
|
||||
form: form
|
||||
|
||||
- name: user_id_type
|
||||
type: select
|
||||
required: false
|
||||
options:
|
||||
- value: open_id
|
||||
label:
|
||||
en_US: open_id
|
||||
zh_Hans: open_id
|
||||
- value: union_id
|
||||
label:
|
||||
en_US: union_id
|
||||
zh_Hans: union_id
|
||||
- value: user_id
|
||||
label:
|
||||
en_US: user_id
|
||||
zh_Hans: user_id
|
||||
default: "open_id"
|
||||
label:
|
||||
en_US: user_id_type
|
||||
zh_Hans: 用户 ID 类型
|
||||
human_description:
|
||||
en_US: User ID type, optional values are open_id, union_id, user_id, with a default value of open_id.
|
||||
zh_Hans: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。
|
||||
llm_description: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。
|
||||
form: form
|
||||
|
||||
- name: page_size
|
||||
type: number
|
||||
required: false
|
||||
default: 20
|
||||
label:
|
||||
en_US: page_size
|
||||
zh_Hans: 分页大小
|
||||
human_description:
|
||||
en_US: |
|
||||
Page size, default value: 20, maximum value: 500.
|
||||
zh_Hans: 分页大小,默认值:20,最大值:500。
|
||||
llm_description: 分页大小,默认值:20,最大值:500。
|
||||
form: form
|
||||
|
||||
- name: page_token
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: page_token
|
||||
zh_Hans: 分页标记
|
||||
human_description:
|
||||
en_US: |
|
||||
Page token, leave empty for the first request to start from the beginning; a new page_token will be returned if there are more items in the paginated query results, which can be used for the next traversal. Example value: "tblsRc9GRRXKqhvW".
|
||||
zh_Hans: 分页标记,第一次请求不填,表示从头开始遍历;分页查询结果还有更多项时会同时返回新的 page_token,下次遍历可采用该 page_token 获取查询结果。示例值:"tblsRc9GRRXKqhvW"。
|
||||
llm_description: 分页标记,第一次请求不填,表示从头开始遍历;分页查询结果还有更多项时会同时返回新的 page_token,下次遍历可采用该 page_token 获取查询结果。示例值:"tblsRc9GRRXKqhvW"。
|
||||
form: llm
|
|
@ -0,0 +1,21 @@
|
|||
from typing import Any
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
from core.tools.utils.lark_api_utils import LarkRequest
|
||||
|
||||
|
||||
class UpdateRecordsTool(BuiltinTool):
|
||||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
|
||||
app_id = self.runtime.credentials.get("app_id")
|
||||
app_secret = self.runtime.credentials.get("app_secret")
|
||||
client = LarkRequest(app_id, app_secret)
|
||||
|
||||
app_token = tool_parameters.get("app_token")
|
||||
table_id = tool_parameters.get("table_id")
|
||||
table_name = tool_parameters.get("table_name")
|
||||
records = tool_parameters.get("records")
|
||||
user_id_type = tool_parameters.get("user_id_type", "open_id")
|
||||
|
||||
res = client.update_records(app_token, table_id, table_name, records, user_id_type)
|
||||
return self.create_json_message(res)
|
|
@ -0,0 +1,91 @@
|
|||
identity:
|
||||
name: update_records
|
||||
author: Doug Lea
|
||||
label:
|
||||
en_US: Update Records
|
||||
zh_Hans: 更新多条记录
|
||||
description:
|
||||
human:
|
||||
en_US: Update Multiple Records in Multidimensional Table
|
||||
zh_Hans: 更新多维表格数据表中的多条记录
|
||||
llm: A tool for updating multiple records in a multidimensional table. (更新多维表格数据表中的多条记录)
|
||||
parameters:
|
||||
- name: app_token
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: app_token
|
||||
zh_Hans: app_token
|
||||
human_description:
|
||||
en_US: Unique identifier for the multidimensional table, supports inputting document URL.
|
||||
zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。
|
||||
llm_description: 多维表格的唯一标识符,支持输入文档 URL。
|
||||
form: llm
|
||||
|
||||
- name: table_id
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: table_id
|
||||
zh_Hans: table_id
|
||||
human_description:
|
||||
en_US: Unique identifier for the multidimensional table data, either table_id or table_name must be provided, cannot be empty simultaneously.
|
||||
zh_Hans: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。
|
||||
llm_description: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。
|
||||
form: llm
|
||||
|
||||
- name: table_name
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: table_name
|
||||
zh_Hans: table_name
|
||||
human_description:
|
||||
en_US: Name of the multidimensional table data, either table_name or table_id must be provided, cannot be empty simultaneously.
|
||||
zh_Hans: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。
|
||||
llm_description: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。
|
||||
form: llm
|
||||
|
||||
- name: records
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: records
|
||||
zh_Hans: 记录列表
|
||||
human_description:
|
||||
en_US: |
|
||||
List of records to be updated in this request. Example value: [{"fields":{"multi-line-text":"text content","single_select":"option 1","date":1674206443000},"record_id":"recupK4f4RM5RX"}].
|
||||
For supported field types, refer to the integration guide (https://open.larkoffice.com/document/server-docs/docs/bitable-v1/notification). For data structures of different field types, refer to the data structure overview (https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure).
|
||||
zh_Hans: |
|
||||
本次请求将要更新的记录列表,示例值:[{"fields":{"多行文本":"文本内容","单选":"选项 1","日期":1674206443000},"record_id":"recupK4f4RM5RX"}]。
|
||||
当前接口支持的字段类型请参考接入指南(https://open.larkoffice.com/document/server-docs/docs/bitable-v1/notification),不同类型字段的数据结构请参考数据结构概述(https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure)。
|
||||
llm_description: |
|
||||
本次请求将要更新的记录列表,示例值:[{"fields":{"多行文本":"文本内容","单选":"选项 1","日期":1674206443000},"record_id":"recupK4f4RM5RX"}]。
|
||||
当前接口支持的字段类型请参考接入指南(https://open.larkoffice.com/document/server-docs/docs/bitable-v1/notification),不同类型字段的数据结构请参考数据结构概述(https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure)。
|
||||
form: llm
|
||||
|
||||
- name: user_id_type
|
||||
type: select
|
||||
required: false
|
||||
options:
|
||||
- value: open_id
|
||||
label:
|
||||
en_US: open_id
|
||||
zh_Hans: open_id
|
||||
- value: union_id
|
||||
label:
|
||||
en_US: union_id
|
||||
zh_Hans: union_id
|
||||
- value: user_id
|
||||
label:
|
||||
en_US: user_id
|
||||
zh_Hans: user_id
|
||||
default: "open_id"
|
||||
label:
|
||||
en_US: user_id_type
|
||||
zh_Hans: 用户 ID 类型
|
||||
human_description:
|
||||
en_US: User ID type, optional values are open_id, union_id, user_id, with a default value of open_id.
|
||||
zh_Hans: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。
|
||||
llm_description: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。
|
||||
form: form
|
BIN
api/core/tools/provider/builtin/lark_calendar/_assets/icon.png
Normal file
BIN
api/core/tools/provider/builtin/lark_calendar/_assets/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.4 KiB |
|
@ -0,0 +1,7 @@
|
|||
from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController
|
||||
from core.tools.utils.lark_api_utils import lark_auth
|
||||
|
||||
|
||||
class LarkCalendarProvider(BuiltinToolProviderController):
|
||||
def _validate_credentials(self, credentials: dict) -> None:
|
||||
lark_auth(credentials)
|
|
@ -0,0 +1,36 @@
|
|||
identity:
|
||||
author: Doug Lea
|
||||
name: lark_calendar
|
||||
label:
|
||||
en_US: Lark Calendar
|
||||
zh_Hans: Lark 日历
|
||||
description:
|
||||
en_US: |
|
||||
Lark calendar, requires the following permissions: calendar:calendar:read、calendar:calendar、contact:user.id:readonly.
|
||||
zh_Hans: |
|
||||
Lark 日历,需要开通以下权限: calendar:calendar:read、calendar:calendar、contact:user.id:readonly。
|
||||
icon: icon.png
|
||||
tags:
|
||||
- social
|
||||
- productivity
|
||||
credentials_for_provider:
|
||||
app_id:
|
||||
type: text-input
|
||||
required: true
|
||||
label:
|
||||
en_US: APP ID
|
||||
placeholder:
|
||||
en_US: Please input your Lark app id
|
||||
zh_Hans: 请输入你的 Lark app id
|
||||
help:
|
||||
en_US: Get your app_id and app_secret from Lark
|
||||
zh_Hans: 从 Lark 获取您的 app_id 和 app_secret
|
||||
url: https://open.larksuite.com/app
|
||||
app_secret:
|
||||
type: secret-input
|
||||
required: true
|
||||
label:
|
||||
en_US: APP Secret
|
||||
placeholder:
|
||||
en_US: Please input your app secret
|
||||
zh_Hans: 请输入你的 Lark app secret
|
|
@ -0,0 +1,20 @@
|
|||
from typing import Any
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
from core.tools.utils.lark_api_utils import LarkRequest
|
||||
|
||||
|
||||
class AddEventAttendeesTool(BuiltinTool):
|
||||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
|
||||
app_id = self.runtime.credentials.get("app_id")
|
||||
app_secret = self.runtime.credentials.get("app_secret")
|
||||
client = LarkRequest(app_id, app_secret)
|
||||
|
||||
event_id = tool_parameters.get("event_id")
|
||||
attendee_phone_or_email = tool_parameters.get("attendee_phone_or_email")
|
||||
need_notification = tool_parameters.get("need_notification", True)
|
||||
|
||||
res = client.add_event_attendees(event_id, attendee_phone_or_email, need_notification)
|
||||
|
||||
return self.create_json_message(res)
|
|
@ -0,0 +1,54 @@
|
|||
identity:
|
||||
name: add_event_attendees
|
||||
author: Doug Lea
|
||||
label:
|
||||
en_US: Add Event Attendees
|
||||
zh_Hans: 添加日程参会人
|
||||
description:
|
||||
human:
|
||||
en_US: Add Event Attendees
|
||||
zh_Hans: 添加日程参会人
|
||||
llm: A tool for adding attendees to events in Lark. (在 Lark 中添加日程参会人)
|
||||
parameters:
|
||||
- name: event_id
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: Event ID
|
||||
zh_Hans: 日程 ID
|
||||
human_description:
|
||||
en_US: |
|
||||
The ID of the event, which will be returned when the event is created. For example: fb2a6406-26d6-4c8d-a487-6f0246c94d2f_0.
|
||||
zh_Hans: |
|
||||
创建日程时会返回日程 ID。例如: fb2a6406-26d6-4c8d-a487-6f0246c94d2f_0。
|
||||
llm_description: |
|
||||
日程 ID,创建日程时会返回日程 ID。例如: fb2a6406-26d6-4c8d-a487-6f0246c94d2f_0。
|
||||
form: llm
|
||||
|
||||
- name: need_notification
|
||||
type: boolean
|
||||
required: false
|
||||
default: true
|
||||
label:
|
||||
en_US: Need Notification
|
||||
zh_Hans: 是否需要通知
|
||||
human_description:
|
||||
en_US: |
|
||||
Whether to send a Bot notification to attendees. true: send, false: do not send.
|
||||
zh_Hans: |
|
||||
是否给参与人发送 Bot 通知,true: 发送,false: 不发送。
|
||||
llm_description: |
|
||||
是否给参与人发送 Bot 通知,true: 发送,false: 不发送。
|
||||
form: form
|
||||
|
||||
- name: attendee_phone_or_email
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: Attendee Phone or Email
|
||||
zh_Hans: 参会人电话或邮箱
|
||||
human_description:
|
||||
en_US: The list of attendee emails or phone numbers, separated by commas.
|
||||
zh_Hans: 日程参会人邮箱或者手机号列表,使用逗号分隔。
|
||||
llm_description: 日程参会人邮箱或者手机号列表,使用逗号分隔。
|
||||
form: llm
|
|
@ -0,0 +1,26 @@
|
|||
from typing import Any
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
from core.tools.utils.lark_api_utils import LarkRequest
|
||||
|
||||
|
||||
class CreateEventTool(BuiltinTool):
|
||||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
|
||||
app_id = self.runtime.credentials.get("app_id")
|
||||
app_secret = self.runtime.credentials.get("app_secret")
|
||||
client = LarkRequest(app_id, app_secret)
|
||||
|
||||
summary = tool_parameters.get("summary")
|
||||
description = tool_parameters.get("description")
|
||||
start_time = tool_parameters.get("start_time")
|
||||
end_time = tool_parameters.get("end_time")
|
||||
attendee_ability = tool_parameters.get("attendee_ability")
|
||||
need_notification = tool_parameters.get("need_notification", True)
|
||||
auto_record = tool_parameters.get("auto_record", False)
|
||||
|
||||
res = client.create_event(
|
||||
summary, description, start_time, end_time, attendee_ability, need_notification, auto_record
|
||||
)
|
||||
|
||||
return self.create_json_message(res)
|
|
@ -0,0 +1,119 @@
|
|||
identity:
|
||||
name: create_event
|
||||
author: Doug Lea
|
||||
label:
|
||||
en_US: Create Event
|
||||
zh_Hans: 创建日程
|
||||
description:
|
||||
human:
|
||||
en_US: Create Event
|
||||
zh_Hans: 创建日程
|
||||
llm: A tool for creating events in Lark.(创建 Lark 日程)
|
||||
parameters:
|
||||
- name: summary
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: Summary
|
||||
zh_Hans: 日程标题
|
||||
human_description:
|
||||
en_US: The title of the event. If not filled, the event title will display (No Subject).
|
||||
zh_Hans: 日程标题,若不填则日程标题显示 (无主题)。
|
||||
llm_description: 日程标题,若不填则日程标题显示 (无主题)。
|
||||
form: llm
|
||||
|
||||
- name: description
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: Description
|
||||
zh_Hans: 日程描述
|
||||
human_description:
|
||||
en_US: The description of the event.
|
||||
zh_Hans: 日程描述。
|
||||
llm_description: 日程描述。
|
||||
form: llm
|
||||
|
||||
- name: need_notification
|
||||
type: boolean
|
||||
required: false
|
||||
default: true
|
||||
label:
|
||||
en_US: Need Notification
|
||||
zh_Hans: 是否发送通知
|
||||
human_description:
|
||||
en_US: |
|
||||
Whether to send a bot message when the event is created, true: send, false: do not send.
|
||||
zh_Hans: 创建日程时是否发送 bot 消息,true:发送,false:不发送。
|
||||
llm_description: 创建日程时是否发送 bot 消息,true:发送,false:不发送。
|
||||
form: form
|
||||
|
||||
- name: start_time
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: Start Time
|
||||
zh_Hans: 开始时间
|
||||
human_description:
|
||||
en_US: |
|
||||
The start time of the event, format: 2006-01-02 15:04:05.
|
||||
zh_Hans: 日程开始时间,格式:2006-01-02 15:04:05。
|
||||
llm_description: 日程开始时间,格式:2006-01-02 15:04:05。
|
||||
form: llm
|
||||
|
||||
- name: end_time
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: End Time
|
||||
zh_Hans: 结束时间
|
||||
human_description:
|
||||
en_US: |
|
||||
The end time of the event, format: 2006-01-02 15:04:05.
|
||||
zh_Hans: 日程结束时间,格式:2006-01-02 15:04:05。
|
||||
llm_description: 日程结束时间,格式:2006-01-02 15:04:05。
|
||||
form: llm
|
||||
|
||||
- name: attendee_ability
|
||||
type: select
|
||||
required: false
|
||||
options:
|
||||
- value: none
|
||||
label:
|
||||
en_US: none
|
||||
zh_Hans: 无
|
||||
- value: can_see_others
|
||||
label:
|
||||
en_US: can_see_others
|
||||
zh_Hans: 可以查看参与人列表
|
||||
- value: can_invite_others
|
||||
label:
|
||||
en_US: can_invite_others
|
||||
zh_Hans: 可以邀请其它参与人
|
||||
- value: can_modify_event
|
||||
label:
|
||||
en_US: can_modify_event
|
||||
zh_Hans: 可以编辑日程
|
||||
default: "none"
|
||||
label:
|
||||
en_US: attendee_ability
|
||||
zh_Hans: 参会人权限
|
||||
human_description:
|
||||
en_US: Attendee ability, optional values are none, can_see_others, can_invite_others, can_modify_event, with a default value of none.
|
||||
zh_Hans: 参会人权限,可选值有无、可以查看参与人列表、可以邀请其它参与人、可以编辑日程,默认值为无。
|
||||
llm_description: 参会人权限,可选值有无、可以查看参与人列表、可以邀请其它参与人、可以编辑日程,默认值为无。
|
||||
form: form
|
||||
|
||||
- name: auto_record
|
||||
type: boolean
|
||||
required: false
|
||||
default: false
|
||||
label:
|
||||
en_US: Auto Record
|
||||
zh_Hans: 自动录制
|
||||
human_description:
|
||||
en_US: |
|
||||
Whether to enable automatic recording, true: enabled, automatically record when the meeting starts; false: not enabled.
|
||||
zh_Hans: 是否开启自动录制,true:开启,会议开始后自动录制;false:不开启。
|
||||
llm_description: 是否开启自动录制,true:开启,会议开始后自动录制;false:不开启。
|
||||
form: form
|
|
@ -0,0 +1,19 @@
|
|||
from typing import Any
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
from core.tools.utils.lark_api_utils import LarkRequest
|
||||
|
||||
|
||||
class DeleteEventTool(BuiltinTool):
|
||||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
|
||||
app_id = self.runtime.credentials.get("app_id")
|
||||
app_secret = self.runtime.credentials.get("app_secret")
|
||||
client = LarkRequest(app_id, app_secret)
|
||||
|
||||
event_id = tool_parameters.get("event_id")
|
||||
need_notification = tool_parameters.get("need_notification", True)
|
||||
|
||||
res = client.delete_event(event_id, need_notification)
|
||||
|
||||
return self.create_json_message(res)
|
|
@ -0,0 +1,38 @@
|
|||
identity:
|
||||
name: delete_event
|
||||
author: Doug Lea
|
||||
label:
|
||||
en_US: Delete Event
|
||||
zh_Hans: 删除日程
|
||||
description:
|
||||
human:
|
||||
en_US: Delete Event
|
||||
zh_Hans: 删除日程
|
||||
llm: A tool for deleting events in Lark.(在 Lark 中删除日程)
|
||||
parameters:
|
||||
- name: event_id
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: Event ID
|
||||
zh_Hans: 日程 ID
|
||||
human_description:
|
||||
en_US: |
|
||||
The ID of the event, for example: e8b9791c-39ae-4908-8ad8-66b13159b9fb_0.
|
||||
zh_Hans: 日程 ID,例如:e8b9791c-39ae-4908-8ad8-66b13159b9fb_0。
|
||||
llm_description: 日程 ID,例如:e8b9791c-39ae-4908-8ad8-66b13159b9fb_0。
|
||||
form: llm
|
||||
|
||||
- name: need_notification
|
||||
type: boolean
|
||||
required: false
|
||||
default: true
|
||||
label:
|
||||
en_US: Need Notification
|
||||
zh_Hans: 是否需要通知
|
||||
human_description:
|
||||
en_US: |
|
||||
Indicates whether to send bot notifications to event participants upon deletion. true: send, false: do not send.
|
||||
zh_Hans: 删除日程是否给日程参与人发送 bot 通知,true:发送,false:不发送。
|
||||
llm_description: 删除日程是否给日程参与人发送 bot 通知,true:发送,false:不发送。
|
||||
form: form
|
|
@ -0,0 +1,18 @@
|
|||
from typing import Any
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
from core.tools.utils.lark_api_utils import LarkRequest
|
||||
|
||||
|
||||
class GetPrimaryCalendarTool(BuiltinTool):
|
||||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
|
||||
app_id = self.runtime.credentials.get("app_id")
|
||||
app_secret = self.runtime.credentials.get("app_secret")
|
||||
client = LarkRequest(app_id, app_secret)
|
||||
|
||||
user_id_type = tool_parameters.get("user_id_type", "open_id")
|
||||
|
||||
res = client.get_primary_calendar(user_id_type)
|
||||
|
||||
return self.create_json_message(res)
|
|
@ -0,0 +1,37 @@
|
|||
identity:
|
||||
name: get_primary_calendar
|
||||
author: Doug Lea
|
||||
label:
|
||||
en_US: Get Primary Calendar
|
||||
zh_Hans: 查询主日历信息
|
||||
description:
|
||||
human:
|
||||
en_US: Get Primary Calendar
|
||||
zh_Hans: 查询主日历信息
|
||||
llm: A tool for querying primary calendar information in Lark.(在 Lark 中查询主日历信息)
|
||||
parameters:
|
||||
- name: user_id_type
|
||||
type: select
|
||||
required: false
|
||||
options:
|
||||
- value: open_id
|
||||
label:
|
||||
en_US: open_id
|
||||
zh_Hans: open_id
|
||||
- value: union_id
|
||||
label:
|
||||
en_US: union_id
|
||||
zh_Hans: union_id
|
||||
- value: user_id
|
||||
label:
|
||||
en_US: user_id
|
||||
zh_Hans: user_id
|
||||
default: "open_id"
|
||||
label:
|
||||
en_US: user_id_type
|
||||
zh_Hans: 用户 ID 类型
|
||||
human_description:
|
||||
en_US: User ID type, optional values are open_id, union_id, user_id, with a default value of open_id.
|
||||
zh_Hans: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。
|
||||
llm_description: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。
|
||||
form: form
|
|
@ -0,0 +1,21 @@
|
|||
from typing import Any
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
from core.tools.utils.lark_api_utils import LarkRequest
|
||||
|
||||
|
||||
class ListEventsTool(BuiltinTool):
|
||||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
|
||||
app_id = self.runtime.credentials.get("app_id")
|
||||
app_secret = self.runtime.credentials.get("app_secret")
|
||||
client = LarkRequest(app_id, app_secret)
|
||||
|
||||
start_time = tool_parameters.get("start_time")
|
||||
end_time = tool_parameters.get("end_time")
|
||||
page_token = tool_parameters.get("page_token")
|
||||
page_size = tool_parameters.get("page_size")
|
||||
|
||||
res = client.list_events(start_time, end_time, page_token, page_size)
|
||||
|
||||
return self.create_json_message(res)
|
|
@ -0,0 +1,62 @@
|
|||
identity:
|
||||
name: list_events
|
||||
author: Doug Lea
|
||||
label:
|
||||
en_US: List Events
|
||||
zh_Hans: 获取日程列表
|
||||
description:
|
||||
human:
|
||||
en_US: List Events
|
||||
zh_Hans: 获取日程列表
|
||||
llm: A tool for listing events in Lark.(在 Lark 中获取日程列表)
|
||||
parameters:
|
||||
- name: start_time
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: Start Time
|
||||
zh_Hans: 开始时间
|
||||
human_description:
|
||||
en_US: |
|
||||
The start time, defaults to 0:00 of the current day if not provided, format: 2006-01-02 15:04:05.
|
||||
zh_Hans: 开始时间,不传值时默认当天 0 点时间,格式为:2006-01-02 15:04:05。
|
||||
llm_description: 开始时间,不传值时默认当天 0 点时间,格式为:2006-01-02 15:04:05。
|
||||
form: llm
|
||||
|
||||
- name: end_time
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: End Time
|
||||
zh_Hans: 结束时间
|
||||
human_description:
|
||||
en_US: |
|
||||
The end time, defaults to 23:59 of the current day if not provided, format: 2006-01-02 15:04:05.
|
||||
zh_Hans: 结束时间,不传值时默认当天 23:59 分时间,格式为:2006-01-02 15:04:05。
|
||||
llm_description: 结束时间,不传值时默认当天 23:59 分时间,格式为:2006-01-02 15:04:05。
|
||||
form: llm
|
||||
|
||||
- name: page_size
|
||||
type: number
|
||||
required: false
|
||||
default: 50
|
||||
label:
|
||||
en_US: Page Size
|
||||
zh_Hans: 分页大小
|
||||
human_description:
|
||||
en_US: The page size, i.e., the number of data entries returned in a single request. The default value is 50, and the value range is [50,1000].
|
||||
zh_Hans: 分页大小,即单次请求所返回的数据条目数。默认值为 50,取值范围为 [50,1000]。
|
||||
llm_description: 分页大小,即单次请求所返回的数据条目数。默认值为 50,取值范围为 [50,1000]。
|
||||
form: form
|
||||
|
||||
- name: page_token
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: Page Token
|
||||
zh_Hans: 分页标记
|
||||
human_description:
|
||||
en_US: The pagination token. Leave it blank for the first request, indicating to start traversing from the beginning; when the pagination query result has more items, a new page_token will be returned simultaneously, which can be used to obtain the query result in the next traversal.
|
||||
zh_Hans: 分页标记,第一次请求不填,表示从头开始遍历;分页查询结果还有更多项时会同时返回新的 page_token,下次遍历可采用该 page_token 获取查询结果。
|
||||
llm_description: 分页标记,第一次请求不填,表示从头开始遍历;分页查询结果还有更多项时会同时返回新的 page_token,下次遍历可采用该 page_token 获取查询结果。
|
||||
form: llm
|
|
@ -0,0 +1,23 @@
|
|||
from typing import Any
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
from core.tools.utils.lark_api_utils import LarkRequest
|
||||
|
||||
|
||||
class SearchEventsTool(BuiltinTool):
|
||||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
|
||||
app_id = self.runtime.credentials.get("app_id")
|
||||
app_secret = self.runtime.credentials.get("app_secret")
|
||||
client = LarkRequest(app_id, app_secret)
|
||||
|
||||
query = tool_parameters.get("query")
|
||||
start_time = tool_parameters.get("start_time")
|
||||
end_time = tool_parameters.get("end_time")
|
||||
page_token = tool_parameters.get("page_token")
|
||||
user_id_type = tool_parameters.get("user_id_type", "open_id")
|
||||
page_size = tool_parameters.get("page_size", 20)
|
||||
|
||||
res = client.search_events(query, start_time, end_time, page_token, user_id_type, page_size)
|
||||
|
||||
return self.create_json_message(res)
|
|
@ -0,0 +1,100 @@
|
|||
identity:
|
||||
name: search_events
|
||||
author: Doug Lea
|
||||
label:
|
||||
en_US: Search Events
|
||||
zh_Hans: 搜索日程
|
||||
description:
|
||||
human:
|
||||
en_US: Search Events
|
||||
zh_Hans: 搜索日程
|
||||
llm: A tool for searching events in Lark.(在 Lark 中搜索日程)
|
||||
parameters:
|
||||
- name: user_id_type
|
||||
type: select
|
||||
required: false
|
||||
options:
|
||||
- value: open_id
|
||||
label:
|
||||
en_US: open_id
|
||||
zh_Hans: open_id
|
||||
- value: union_id
|
||||
label:
|
||||
en_US: union_id
|
||||
zh_Hans: union_id
|
||||
- value: user_id
|
||||
label:
|
||||
en_US: user_id
|
||||
zh_Hans: user_id
|
||||
default: "open_id"
|
||||
label:
|
||||
en_US: user_id_type
|
||||
zh_Hans: 用户 ID 类型
|
||||
human_description:
|
||||
en_US: User ID type, optional values are open_id, union_id, user_id, with a default value of open_id.
|
||||
zh_Hans: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。
|
||||
llm_description: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。
|
||||
form: form
|
||||
|
||||
- name: query
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: Query
|
||||
zh_Hans: 搜索关键字
|
||||
human_description:
|
||||
en_US: The search keyword used for fuzzy searching event names, with a maximum input of 200 characters.
|
||||
zh_Hans: 用于模糊查询日程名称的搜索关键字,最大输入 200 字符。
|
||||
llm_description: 用于模糊查询日程名称的搜索关键字,最大输入 200 字符。
|
||||
form: llm
|
||||
|
||||
- name: start_time
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: Start Time
|
||||
zh_Hans: 开始时间
|
||||
human_description:
|
||||
en_US: |
|
||||
The start time, defaults to 0:00 of the current day if not provided, format: 2006-01-02 15:04:05.
|
||||
zh_Hans: 开始时间,不传值时默认当天 0 点时间,格式为:2006-01-02 15:04:05。
|
||||
llm_description: 开始时间,不传值时默认当天 0 点时间,格式为:2006-01-02 15:04:05。
|
||||
form: llm
|
||||
|
||||
- name: end_time
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: End Time
|
||||
zh_Hans: 结束时间
|
||||
human_description:
|
||||
en_US: |
|
||||
The end time, defaults to 23:59 of the current day if not provided, format: 2006-01-02 15:04:05.
|
||||
zh_Hans: 结束时间,不传值时默认当天 23:59 分时间,格式为:2006-01-02 15:04:05。
|
||||
llm_description: 结束时间,不传值时默认当天 23:59 分时间,格式为:2006-01-02 15:04:05。
|
||||
form: llm
|
||||
|
||||
- name: page_size
|
||||
type: number
|
||||
required: false
|
||||
default: 20
|
||||
label:
|
||||
en_US: Page Size
|
||||
zh_Hans: 分页大小
|
||||
human_description:
|
||||
en_US: The page size, i.e., the number of data entries returned in a single request. The default value is 20, and the value range is [10,100].
|
||||
zh_Hans: 分页大小,即单次请求所返回的数据条目数。默认值为 20,取值范围为 [10,100]。
|
||||
llm_description: 分页大小,即单次请求所返回的数据条目数。默认值为 20,取值范围为 [10,100]。
|
||||
form: form
|
||||
|
||||
- name: page_token
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: Page Token
|
||||
zh_Hans: 分页标记
|
||||
human_description:
|
||||
en_US: The pagination token. Leave it blank for the first request, indicating to start traversing from the beginning; when the pagination query result has more items, a new page_token will be returned simultaneously, which can be used to obtain the query result in the next traversal.
|
||||
zh_Hans: 分页标记,第一次请求不填,表示从头开始遍历;分页查询结果还有更多项时会同时返回新的 page_token,下次遍历可采用该 page_token 获取查询结果。
|
||||
llm_description: 分页标记,第一次请求不填,表示从头开始遍历;分页查询结果还有更多项时会同时返回新的 page_token,下次遍历可采用该 page_token 获取查询结果。
|
||||
form: llm
|
|
@ -0,0 +1,24 @@
|
|||
from typing import Any
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
from core.tools.utils.lark_api_utils import LarkRequest
|
||||
|
||||
|
||||
class UpdateEventTool(BuiltinTool):
|
||||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
|
||||
app_id = self.runtime.credentials.get("app_id")
|
||||
app_secret = self.runtime.credentials.get("app_secret")
|
||||
client = LarkRequest(app_id, app_secret)
|
||||
|
||||
event_id = tool_parameters.get("event_id")
|
||||
summary = tool_parameters.get("summary")
|
||||
description = tool_parameters.get("description")
|
||||
need_notification = tool_parameters.get("need_notification", True)
|
||||
start_time = tool_parameters.get("start_time")
|
||||
end_time = tool_parameters.get("end_time")
|
||||
auto_record = tool_parameters.get("auto_record", False)
|
||||
|
||||
res = client.update_event(event_id, summary, description, need_notification, start_time, end_time, auto_record)
|
||||
|
||||
return self.create_json_message(res)
|
|
@ -0,0 +1,100 @@
|
|||
identity:
|
||||
name: update_event
|
||||
author: Doug Lea
|
||||
label:
|
||||
en_US: Update Event
|
||||
zh_Hans: 更新日程
|
||||
description:
|
||||
human:
|
||||
en_US: Update Event
|
||||
zh_Hans: 更新日程
|
||||
llm: A tool for updating events in Lark.(更新 Lark 中的日程)
|
||||
parameters:
|
||||
- name: event_id
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: Event ID
|
||||
zh_Hans: 日程 ID
|
||||
human_description:
|
||||
en_US: |
|
||||
The ID of the event, for example: e8b9791c-39ae-4908-8ad8-66b13159b9fb_0.
|
||||
zh_Hans: 日程 ID,例如:e8b9791c-39ae-4908-8ad8-66b13159b9fb_0。
|
||||
llm_description: 日程 ID,例如:e8b9791c-39ae-4908-8ad8-66b13159b9fb_0。
|
||||
form: llm
|
||||
|
||||
- name: summary
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: Summary
|
||||
zh_Hans: 日程标题
|
||||
human_description:
|
||||
en_US: The title of the event.
|
||||
zh_Hans: 日程标题。
|
||||
llm_description: 日程标题。
|
||||
form: llm
|
||||
|
||||
- name: description
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: Description
|
||||
zh_Hans: 日程描述
|
||||
human_description:
|
||||
en_US: The description of the event.
|
||||
zh_Hans: 日程描述。
|
||||
llm_description: 日程描述。
|
||||
form: llm
|
||||
|
||||
- name: need_notification
|
||||
type: boolean
|
||||
required: false
|
||||
label:
|
||||
en_US: Need Notification
|
||||
zh_Hans: 是否发送通知
|
||||
human_description:
|
||||
en_US: |
|
||||
Whether to send a bot message when the event is updated, true: send, false: do not send.
|
||||
zh_Hans: 更新日程时是否发送 bot 消息,true:发送,false:不发送。
|
||||
llm_description: 更新日程时是否发送 bot 消息,true:发送,false:不发送。
|
||||
form: form
|
||||
|
||||
- name: start_time
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: Start Time
|
||||
zh_Hans: 开始时间
|
||||
human_description:
|
||||
en_US: |
|
||||
The start time of the event, format: 2006-01-02 15:04:05.
|
||||
zh_Hans: 日程开始时间,格式:2006-01-02 15:04:05。
|
||||
llm_description: 日程开始时间,格式:2006-01-02 15:04:05。
|
||||
form: llm
|
||||
|
||||
- name: end_time
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: End Time
|
||||
zh_Hans: 结束时间
|
||||
human_description:
|
||||
en_US: |
|
||||
The end time of the event, format: 2006-01-02 15:04:05.
|
||||
zh_Hans: 日程结束时间,格式:2006-01-02 15:04:05。
|
||||
llm_description: 日程结束时间,格式:2006-01-02 15:04:05。
|
||||
form: llm
|
||||
|
||||
- name: auto_record
|
||||
type: boolean
|
||||
required: false
|
||||
label:
|
||||
en_US: Auto Record
|
||||
zh_Hans: 自动录制
|
||||
human_description:
|
||||
en_US: |
|
||||
Whether to enable automatic recording, true: enabled, automatically record when the meeting starts; false: not enabled.
|
||||
zh_Hans: 是否开启自动录制,true:开启,会议开始后自动录制;false:不开启。
|
||||
llm_description: 是否开启自动录制,true:开启,会议开始后自动录制;false:不开启。
|
||||
form: form
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="64px" height="64px" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g><path style="opacity:1" fill="#fefefe" d="M -0.5,-0.5 C 20.8333,-0.5 42.1667,-0.5 63.5,-0.5C 63.5,20.8333 63.5,42.1667 63.5,63.5C 42.1667,63.5 20.8333,63.5 -0.5,63.5C -0.5,42.1667 -0.5,20.8333 -0.5,-0.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#346df3" d="M 47.5,33.5 C 43.3272,29.8779 38.9939,29.7112 34.5,33C 32.682,35.4897 30.3487,37.3231 27.5,38.5C 23.5003,43.5136 24.167,47.847 29.5,51.5C 24.1563,51.666 18.8229,51.4994 13.5,51C 13,50.5 12.5,50 12,49.5C 11.3333,36.8333 11.3333,24.1667 12,11.5C 12.5,11 13,10.5 13.5,10C 24.1667,9.33333 34.8333,9.33333 45.5,10C 46,10.5 46.5,11 47,11.5C 47.4997,18.8258 47.6663,26.1591 47.5,33.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#f9fafe" d="M 20.5,19.5 C 25.1785,19.3342 29.8452,19.5008 34.5,20C 35.8333,21 35.8333,22 34.5,23C 29.8333,23.6667 25.1667,23.6667 20.5,23C 19.3157,21.8545 19.3157,20.6879 20.5,19.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#f3f6fe" d="M 20.5,27.5 C 22.5273,27.3379 24.5273,27.5045 26.5,28C 27.8333,29 27.8333,30 26.5,31C 24.5,31.6667 22.5,31.6667 20.5,31C 19.3157,29.8545 19.3157,28.6879 20.5,27.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#36d4c1" d="M 47.5,33.5 C 48.7298,35.2972 49.3964,37.2972 49.5,39.5C 51.3904,39.2965 52.8904,39.9632 54,41.5C 55.1825,45.2739 54.3492,48.4406 51.5,51C 44.1742,51.4997 36.8409,51.6663 29.5,51.5C 24.167,47.847 23.5003,43.5136 27.5,38.5C 30.3487,37.3231 32.682,35.4897 34.5,33C 38.9939,29.7112 43.3272,29.8779 47.5,33.5 Z"/></g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
|
@ -0,0 +1,7 @@
|
|||
from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController
|
||||
from core.tools.utils.lark_api_utils import lark_auth
|
||||
|
||||
|
||||
class LarkDocumentProvider(BuiltinToolProviderController):
|
||||
def _validate_credentials(self, credentials: dict) -> None:
|
||||
lark_auth(credentials)
|
|
@ -0,0 +1,36 @@
|
|||
identity:
|
||||
author: Doug Lea
|
||||
name: lark_document
|
||||
label:
|
||||
en_US: Lark Cloud Document
|
||||
zh_Hans: Lark 云文档
|
||||
description:
|
||||
en_US: |
|
||||
Lark cloud document, requires the following permissions: docx:document、drive:drive、docs:document.content:read.
|
||||
zh_Hans: |
|
||||
Lark 云文档,需要开通以下权限: docx:document、drive:drive、docs:document.content:read。
|
||||
icon: icon.svg
|
||||
tags:
|
||||
- social
|
||||
- productivity
|
||||
credentials_for_provider:
|
||||
app_id:
|
||||
type: text-input
|
||||
required: true
|
||||
label:
|
||||
en_US: APP ID
|
||||
placeholder:
|
||||
en_US: Please input your Lark app id
|
||||
zh_Hans: 请输入你的 Lark app id
|
||||
help:
|
||||
en_US: Get your app_id and app_secret from Lark
|
||||
zh_Hans: 从 Lark 获取您的 app_id 和 app_secret
|
||||
url: https://open.larksuite.com/app
|
||||
app_secret:
|
||||
type: secret-input
|
||||
required: true
|
||||
label:
|
||||
en_US: APP Secret
|
||||
placeholder:
|
||||
en_US: Please input your app secret
|
||||
zh_Hans: 请输入你的 Lark app secret
|
|
@ -0,0 +1,19 @@
|
|||
from typing import Any
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
from core.tools.utils.lark_api_utils import LarkRequest
|
||||
|
||||
|
||||
class CreateDocumentTool(BuiltinTool):
|
||||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
|
||||
app_id = self.runtime.credentials.get("app_id")
|
||||
app_secret = self.runtime.credentials.get("app_secret")
|
||||
client = LarkRequest(app_id, app_secret)
|
||||
|
||||
title = tool_parameters.get("title")
|
||||
content = tool_parameters.get("content")
|
||||
folder_token = tool_parameters.get("folder_token")
|
||||
|
||||
res = client.create_document(title, content, folder_token)
|
||||
return self.create_json_message(res)
|
|
@ -0,0 +1,48 @@
|
|||
identity:
|
||||
name: create_document
|
||||
author: Doug Lea
|
||||
label:
|
||||
en_US: Create Lark document
|
||||
zh_Hans: 创建 Lark 文档
|
||||
description:
|
||||
human:
|
||||
en_US: Create Lark document
|
||||
zh_Hans: 创建 Lark 文档,支持创建空文档和带内容的文档,支持 markdown 语法创建。应用需要开启机器人能力(https://open.larksuite.com/document/faq/trouble-shooting/how-to-enable-bot-ability)。
|
||||
llm: A tool for creating Lark documents.
|
||||
parameters:
|
||||
- name: title
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: Document title
|
||||
zh_Hans: 文档标题
|
||||
human_description:
|
||||
en_US: Document title, only supports plain text content.
|
||||
zh_Hans: 文档标题,只支持纯文本内容。
|
||||
llm_description: 文档标题,只支持纯文本内容,可以为空。
|
||||
form: llm
|
||||
|
||||
- name: content
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: Document content
|
||||
zh_Hans: 文档内容
|
||||
human_description:
|
||||
en_US: Document content, supports markdown syntax, can be empty.
|
||||
zh_Hans: 文档内容,支持 markdown 语法,可以为空。
|
||||
llm_description: 文档内容,支持 markdown 语法,可以为空。
|
||||
form: llm
|
||||
|
||||
- name: folder_token
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: folder_token
|
||||
zh_Hans: 文档所在文件夹的 Token
|
||||
human_description:
|
||||
en_US: |
|
||||
The token of the folder where the document is located. If it is not passed or is empty, it means the root directory. For Example: https://lark-japan.jp.larksuite.com/drive/folder/Lf8uf6BoAlWkUfdGtpMjUV0PpZd
|
||||
zh_Hans: 文档所在文件夹的 Token,不传或传空表示根目录。例如:https://lark-japan.jp.larksuite.com/drive/folder/Lf8uf6BoAlWkUfdGtpMjUV0PpZd。
|
||||
llm_description: 文档所在文件夹的 Token,不传或传空表示根目录。例如:https://lark-japan.jp.larksuite.com/drive/folder/Lf8uf6BoAlWkUfdGtpMjUV0PpZd。
|
||||
form: llm
|
|
@ -0,0 +1,19 @@
|
|||
from typing import Any
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
from core.tools.utils.lark_api_utils import LarkRequest
|
||||
|
||||
|
||||
class GetDocumentRawContentTool(BuiltinTool):
|
||||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
|
||||
app_id = self.runtime.credentials.get("app_id")
|
||||
app_secret = self.runtime.credentials.get("app_secret")
|
||||
client = LarkRequest(app_id, app_secret)
|
||||
|
||||
document_id = tool_parameters.get("document_id")
|
||||
mode = tool_parameters.get("mode", "markdown")
|
||||
lang = tool_parameters.get("lang", "0")
|
||||
|
||||
res = client.get_document_content(document_id, mode, lang)
|
||||
return self.create_json_message(res)
|
|
@ -0,0 +1,70 @@
|
|||
identity:
|
||||
name: get_document_content
|
||||
author: Doug Lea
|
||||
label:
|
||||
en_US: Get Lark Cloud Document Content
|
||||
zh_Hans: 获取 Lark 云文档的内容
|
||||
description:
|
||||
human:
|
||||
en_US: Get lark cloud document content
|
||||
zh_Hans: 获取 Lark 云文档的内容
|
||||
llm: A tool for retrieving content from Lark cloud documents.
|
||||
parameters:
|
||||
- name: document_id
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: document_id
|
||||
zh_Hans: Lark 文档的唯一标识
|
||||
human_description:
|
||||
en_US: Unique identifier for a Lark document. You can also input the document's URL.
|
||||
zh_Hans: Lark 文档的唯一标识,支持输入文档的 URL。
|
||||
llm_description: Lark 文档的唯一标识,支持输入文档的 URL。
|
||||
form: llm
|
||||
|
||||
- name: mode
|
||||
type: select
|
||||
required: false
|
||||
options:
|
||||
- value: text
|
||||
label:
|
||||
en_US: text
|
||||
zh_Hans: text
|
||||
- value: markdown
|
||||
label:
|
||||
en_US: markdown
|
||||
zh_Hans: markdown
|
||||
default: "markdown"
|
||||
label:
|
||||
en_US: mode
|
||||
zh_Hans: 文档返回格式
|
||||
human_description:
|
||||
en_US: Format of the document return, optional values are text, markdown, can be empty, default is markdown.
|
||||
zh_Hans: 文档返回格式,可选值有 text、markdown,可以为空,默认值为 markdown。
|
||||
llm_description: 文档返回格式,可选值有 text、markdown,可以为空,默认值为 markdown。
|
||||
form: form
|
||||
|
||||
- name: lang
|
||||
type: select
|
||||
required: false
|
||||
options:
|
||||
- value: "0"
|
||||
label:
|
||||
en_US: User's default name
|
||||
zh_Hans: 用户的默认名称
|
||||
- value: "1"
|
||||
label:
|
||||
en_US: User's English name
|
||||
zh_Hans: 用户的英文名称
|
||||
default: "0"
|
||||
label:
|
||||
en_US: lang
|
||||
zh_Hans: 指定@用户的语言
|
||||
human_description:
|
||||
en_US: |
|
||||
Specifies the language for MentionUser, optional values are [0, 1]. 0: User's default name, 1: User's English name, default is 0.
|
||||
zh_Hans: |
|
||||
指定返回的 MentionUser,即@用户的语言,可选值有 [0,1]。0: 该用户的默认名称,1: 该用户的英文名称,默认值为 0。
|
||||
llm_description: |
|
||||
指定返回的 MentionUser,即@用户的语言,可选值有 [0,1]。0: 该用户的默认名称,1: 该用户的英文名称,默认值为 0。
|
||||
form: form
|
|
@ -0,0 +1,20 @@
|
|||
from typing import Any
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
from core.tools.utils.lark_api_utils import LarkRequest
|
||||
|
||||
|
||||
class ListDocumentBlockTool(BuiltinTool):
|
||||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
|
||||
app_id = self.runtime.credentials.get("app_id")
|
||||
app_secret = self.runtime.credentials.get("app_secret")
|
||||
client = LarkRequest(app_id, app_secret)
|
||||
|
||||
document_id = tool_parameters.get("document_id")
|
||||
page_token = tool_parameters.get("page_token", "")
|
||||
user_id_type = tool_parameters.get("user_id_type", "open_id")
|
||||
page_size = tool_parameters.get("page_size", 500)
|
||||
|
||||
res = client.list_document_blocks(document_id, page_token, user_id_type, page_size)
|
||||
return self.create_json_message(res)
|
|
@ -0,0 +1,74 @@
|
|||
identity:
|
||||
name: list_document_blocks
|
||||
author: Doug Lea
|
||||
label:
|
||||
en_US: List Lark Document Blocks
|
||||
zh_Hans: 获取 Lark 文档所有块
|
||||
description:
|
||||
human:
|
||||
en_US: List lark document blocks
|
||||
zh_Hans: 获取 Lark 文档所有块的富文本内容并分页返回
|
||||
llm: A tool to get all blocks of Lark documents
|
||||
parameters:
|
||||
- name: document_id
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: document_id
|
||||
zh_Hans: Lark 文档的唯一标识
|
||||
human_description:
|
||||
en_US: Unique identifier for a Lark document. You can also input the document's URL.
|
||||
zh_Hans: Lark 文档的唯一标识,支持输入文档的 URL。
|
||||
llm_description: Lark 文档的唯一标识,支持输入文档的 URL。
|
||||
form: llm
|
||||
|
||||
- name: user_id_type
|
||||
type: select
|
||||
required: false
|
||||
options:
|
||||
- value: open_id
|
||||
label:
|
||||
en_US: open_id
|
||||
zh_Hans: open_id
|
||||
- value: union_id
|
||||
label:
|
||||
en_US: union_id
|
||||
zh_Hans: union_id
|
||||
- value: user_id
|
||||
label:
|
||||
en_US: user_id
|
||||
zh_Hans: user_id
|
||||
default: "open_id"
|
||||
label:
|
||||
en_US: user_id_type
|
||||
zh_Hans: 用户 ID 类型
|
||||
human_description:
|
||||
en_US: User ID type, optional values are open_id, union_id, user_id, with a default value of open_id.
|
||||
zh_Hans: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。
|
||||
llm_description: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。
|
||||
form: form
|
||||
|
||||
- name: page_size
|
||||
type: number
|
||||
required: false
|
||||
default: 500
|
||||
label:
|
||||
en_US: page_size
|
||||
zh_Hans: 分页大小
|
||||
human_description:
|
||||
en_US: Paging size, the default and maximum value is 500.
|
||||
zh_Hans: 分页大小, 默认值和最大值为 500。
|
||||
llm_description: 分页大小, 表示一次请求最多返回多少条数据,默认值和最大值为 500。
|
||||
form: form
|
||||
|
||||
- name: page_token
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: page_token
|
||||
zh_Hans: 分页标记
|
||||
human_description:
|
||||
en_US: Pagination token used to navigate through query results, allowing retrieval of additional items in subsequent requests.
|
||||
zh_Hans: 分页标记,用于分页查询结果,以便下次遍历时获取更多项。
|
||||
llm_description: 分页标记,第一次请求不填,表示从头开始遍历;分页查询结果还有更多项时会同时返回新的 page_token,下次遍历可采用该 page_token 获取查询结果。
|
||||
form: llm
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user