mirror of
https://github.com/langgenius/dify.git
synced 2024-11-16 03:32:23 +08:00
Merge branch 'main' into feat/iteration-single-run-time
This commit is contained in:
commit
eca2cb0af3
36
.github/actions/setup-poetry/action.yml
vendored
Normal file
36
.github/actions/setup-poetry/action.yml
vendored
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
name: Setup Poetry and Python
|
||||||
|
|
||||||
|
inputs:
|
||||||
|
python-version:
|
||||||
|
description: Python version to use and the Poetry installed with
|
||||||
|
required: true
|
||||||
|
default: '3.10'
|
||||||
|
poetry-version:
|
||||||
|
description: Poetry version to set up
|
||||||
|
required: true
|
||||||
|
default: '1.8.4'
|
||||||
|
poetry-lockfile:
|
||||||
|
description: Path to the Poetry lockfile to restore cache from
|
||||||
|
required: true
|
||||||
|
default: ''
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- name: Set up Python ${{ inputs.python-version }}
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: ${{ inputs.python-version }}
|
||||||
|
cache: pip
|
||||||
|
|
||||||
|
- name: Install Poetry
|
||||||
|
shell: bash
|
||||||
|
run: pip install poetry==${{ inputs.poetry-version }}
|
||||||
|
|
||||||
|
- name: Restore Poetry cache
|
||||||
|
if: ${{ inputs.poetry-lockfile != '' }}
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: ${{ inputs.python-version }}
|
||||||
|
cache: poetry
|
||||||
|
cache-dependency-path: ${{ inputs.poetry-lockfile }}
|
10
.github/workflows/api-tests.yml
vendored
10
.github/workflows/api-tests.yml
vendored
|
@ -28,15 +28,11 @@ jobs:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install Poetry
|
- name: Setup Poetry and Python ${{ matrix.python-version }}
|
||||||
uses: abatilo/actions-poetry@v3
|
uses: ./.github/actions/setup-poetry
|
||||||
|
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
|
||||||
uses: actions/setup-python@v5
|
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
cache: poetry
|
poetry-lockfile: api/poetry.lock
|
||||||
cache-dependency-path: api/poetry.lock
|
|
||||||
|
|
||||||
- name: Check Poetry lockfile
|
- name: Check Poetry lockfile
|
||||||
run: |
|
run: |
|
||||||
|
|
16
.github/workflows/db-migration-test.yml
vendored
16
.github/workflows/db-migration-test.yml
vendored
|
@ -15,25 +15,15 @@ concurrency:
|
||||||
jobs:
|
jobs:
|
||||||
db-migration-test:
|
db-migration-test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
python-version:
|
|
||||||
- "3.10"
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Setup Poetry and Python
|
||||||
uses: actions/setup-python@v5
|
uses: ./.github/actions/setup-poetry
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
poetry-lockfile: api/poetry.lock
|
||||||
cache-dependency-path: |
|
|
||||||
api/pyproject.toml
|
|
||||||
api/poetry.lock
|
|
||||||
|
|
||||||
- name: Install Poetry
|
|
||||||
uses: abatilo/actions-poetry@v3
|
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: poetry install -C api
|
run: poetry install -C api
|
||||||
|
|
24
.github/workflows/style.yml
vendored
24
.github/workflows/style.yml
vendored
|
@ -22,34 +22,28 @@ jobs:
|
||||||
id: changed-files
|
id: changed-files
|
||||||
uses: tj-actions/changed-files@v45
|
uses: tj-actions/changed-files@v45
|
||||||
with:
|
with:
|
||||||
files: api/**
|
files: |
|
||||||
|
api/**
|
||||||
|
.github/workflows/style.yml
|
||||||
|
|
||||||
- name: Install Poetry
|
- name: Setup Poetry and Python
|
||||||
if: steps.changed-files.outputs.any_changed == 'true'
|
if: steps.changed-files.outputs.any_changed == 'true'
|
||||||
uses: abatilo/actions-poetry@v3
|
uses: ./.github/actions/setup-poetry
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Install dependencies
|
||||||
uses: actions/setup-python@v5
|
|
||||||
if: steps.changed-files.outputs.any_changed == 'true'
|
|
||||||
with:
|
|
||||||
python-version: '3.10'
|
|
||||||
|
|
||||||
- name: Python dependencies
|
|
||||||
if: steps.changed-files.outputs.any_changed == 'true'
|
if: steps.changed-files.outputs.any_changed == 'true'
|
||||||
run: poetry install -C api --only lint
|
run: poetry install -C api --only lint
|
||||||
|
|
||||||
- name: Ruff check
|
- name: Ruff check
|
||||||
if: steps.changed-files.outputs.any_changed == 'true'
|
if: steps.changed-files.outputs.any_changed == 'true'
|
||||||
run: poetry run -C api ruff check ./api
|
run: |
|
||||||
|
poetry run -C api ruff check ./api
|
||||||
|
poetry run -C api ruff format --check ./api
|
||||||
|
|
||||||
- name: Dotenv check
|
- name: Dotenv check
|
||||||
if: steps.changed-files.outputs.any_changed == 'true'
|
if: steps.changed-files.outputs.any_changed == 'true'
|
||||||
run: poetry run -C api dotenv-linter ./api/.env.example ./web/.env.example
|
run: poetry run -C api dotenv-linter ./api/.env.example ./web/.env.example
|
||||||
|
|
||||||
- name: Ruff formatter check
|
|
||||||
if: steps.changed-files.outputs.any_changed == 'true'
|
|
||||||
run: poetry run -C api ruff format --check ./api
|
|
||||||
|
|
||||||
- name: Lint hints
|
- name: Lint hints
|
||||||
if: failure()
|
if: failure()
|
||||||
run: echo "Please run 'dev/reformat' to fix the fixable linting errors."
|
run: echo "Please run 'dev/reformat' to fix the fixable linting errors."
|
||||||
|
|
10
.github/workflows/vdb-tests.yml
vendored
10
.github/workflows/vdb-tests.yml
vendored
|
@ -28,15 +28,11 @@ jobs:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install Poetry
|
- name: Setup Poetry and Python ${{ matrix.python-version }}
|
||||||
uses: abatilo/actions-poetry@v3
|
uses: ./.github/actions/setup-poetry
|
||||||
|
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
|
||||||
uses: actions/setup-python@v5
|
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
cache: poetry
|
poetry-lockfile: api/poetry.lock
|
||||||
cache-dependency-path: api/poetry.lock
|
|
||||||
|
|
||||||
- name: Check Poetry lockfile
|
- name: Check Poetry lockfile
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -177,3 +177,4 @@ To protect your privacy, please avoid posting security issues on GitHub. Instead
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This repository is available under the [Dify Open Source License](LICENSE), which is essentially Apache 2.0 with a few additional restrictions.
|
This repository is available under the [Dify Open Source License](LICENSE), which is essentially Apache 2.0 with a few additional restrictions.
|
||||||
|
|
||||||
|
|
|
@ -367,6 +367,10 @@ LOG_FILE=
|
||||||
LOG_FILE_MAX_SIZE=20
|
LOG_FILE_MAX_SIZE=20
|
||||||
# Log file max backup count
|
# Log file max backup count
|
||||||
LOG_FILE_BACKUP_COUNT=5
|
LOG_FILE_BACKUP_COUNT=5
|
||||||
|
# Log dateformat
|
||||||
|
LOG_DATEFORMAT=%Y-%m-%d %H:%M:%S
|
||||||
|
# Log Timezone
|
||||||
|
LOG_TZ=UTC
|
||||||
|
|
||||||
# Indexing configuration
|
# Indexing configuration
|
||||||
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH=1000
|
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH=1000
|
||||||
|
@ -396,3 +400,5 @@ POSITION_PROVIDER_EXCLUDES=
|
||||||
|
|
||||||
# Reset password token expiry minutes
|
# Reset password token expiry minutes
|
||||||
RESET_PASSWORD_TOKEN_EXPIRY_MINUTES=5
|
RESET_PASSWORD_TOKEN_EXPIRY_MINUTES=5
|
||||||
|
|
||||||
|
CREATE_TIDB_SERVICE_JOB_ENABLED=false
|
|
@ -4,7 +4,7 @@ FROM python:3.10-slim-bookworm AS base
|
||||||
WORKDIR /app/api
|
WORKDIR /app/api
|
||||||
|
|
||||||
# Install Poetry
|
# Install Poetry
|
||||||
ENV POETRY_VERSION=1.8.3
|
ENV POETRY_VERSION=1.8.4
|
||||||
|
|
||||||
# if you located in China, you can use aliyun mirror to speed up
|
# if you located in China, you can use aliyun mirror to speed up
|
||||||
# RUN pip install --no-cache-dir poetry==${POETRY_VERSION} -i https://mirrors.aliyun.com/pypi/simple/
|
# RUN pip install --no-cache-dir poetry==${POETRY_VERSION} -i https://mirrors.aliyun.com/pypi/simple/
|
||||||
|
|
|
@ -376,7 +376,7 @@ class LoggingConfig(BaseSettings):
|
||||||
|
|
||||||
LOG_TZ: Optional[str] = Field(
|
LOG_TZ: Optional[str] = Field(
|
||||||
description="Timezone for log timestamps (e.g., 'America/New_York')",
|
description="Timezone for log timestamps (e.g., 'America/New_York')",
|
||||||
default=None,
|
default="UTC",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -611,6 +611,11 @@ class DataSetConfig(BaseSettings):
|
||||||
default=500,
|
default=500,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
CREATE_TIDB_SERVICE_JOB_ENABLED: bool = Field(
|
||||||
|
description="Enable or disable create tidb service job",
|
||||||
|
default=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class WorkspaceConfig(BaseSettings):
|
class WorkspaceConfig(BaseSettings):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -317,8 +317,11 @@ class DatasetInitApi(Resource):
|
||||||
raise ValueError("embedding model and embedding model provider are required for high quality indexing.")
|
raise ValueError("embedding model and embedding model provider are required for high quality indexing.")
|
||||||
try:
|
try:
|
||||||
model_manager = ModelManager()
|
model_manager = ModelManager()
|
||||||
model_manager.get_default_model_instance(
|
model_manager.get_model_instance(
|
||||||
tenant_id=current_user.current_tenant_id, model_type=ModelType.TEXT_EMBEDDING
|
tenant_id=current_user.current_tenant_id,
|
||||||
|
provider=args["embedding_model_provider"],
|
||||||
|
model_type=ModelType.TEXT_EMBEDDING,
|
||||||
|
model=args["embedding_model"],
|
||||||
)
|
)
|
||||||
except InvokeAuthorizationError:
|
except InvokeAuthorizationError:
|
||||||
raise ProviderNotInitializeError(
|
raise ProviderNotInitializeError(
|
||||||
|
|
|
@ -62,9 +62,10 @@ class ConversationDetailApi(Resource):
|
||||||
conversation_id = str(c_id)
|
conversation_id = str(c_id)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return ConversationService.delete(app_model, conversation_id, end_user)
|
ConversationService.delete(app_model, conversation_id, end_user)
|
||||||
except services.errors.conversation.ConversationNotExistsError:
|
except services.errors.conversation.ConversationNotExistsError:
|
||||||
raise NotFound("Conversation Not Exists.")
|
raise NotFound("Conversation Not Exists.")
|
||||||
|
return {"result": "success"}, 200
|
||||||
|
|
||||||
|
|
||||||
class ConversationRenameApi(Resource):
|
class ConversationRenameApi(Resource):
|
||||||
|
|
|
@ -10,6 +10,7 @@ from controllers.service_api.app.error import NotChatAppError
|
||||||
from controllers.service_api.wraps import FetchUserArg, WhereisUserArg, validate_app_token
|
from controllers.service_api.wraps import FetchUserArg, WhereisUserArg, validate_app_token
|
||||||
from core.app.entities.app_invoke_entities import InvokeFrom
|
from core.app.entities.app_invoke_entities import InvokeFrom
|
||||||
from fields.conversation_fields import message_file_fields
|
from fields.conversation_fields import message_file_fields
|
||||||
|
from fields.raws import FilesContainedField
|
||||||
from libs.helper import TimestampField, uuid_value
|
from libs.helper import TimestampField, uuid_value
|
||||||
from models.model import App, AppMode, EndUser
|
from models.model import App, AppMode, EndUser
|
||||||
from services.errors.message import SuggestedQuestionsAfterAnswerDisabledError
|
from services.errors.message import SuggestedQuestionsAfterAnswerDisabledError
|
||||||
|
@ -55,7 +56,7 @@ class MessageListApi(Resource):
|
||||||
"id": fields.String,
|
"id": fields.String,
|
||||||
"conversation_id": fields.String,
|
"conversation_id": fields.String,
|
||||||
"parent_message_id": fields.String,
|
"parent_message_id": fields.String,
|
||||||
"inputs": fields.Raw,
|
"inputs": FilesContainedField,
|
||||||
"query": fields.String,
|
"query": fields.String,
|
||||||
"answer": fields.String(attribute="re_sign_file_url_answer"),
|
"answer": fields.String(attribute="re_sign_file_url_answer"),
|
||||||
"message_files": fields.List(fields.Nested(message_file_fields)),
|
"message_files": fields.List(fields.Nested(message_file_fields)),
|
||||||
|
|
|
@ -30,6 +30,7 @@ from core.model_runtime.entities import (
|
||||||
ToolPromptMessage,
|
ToolPromptMessage,
|
||||||
UserPromptMessage,
|
UserPromptMessage,
|
||||||
)
|
)
|
||||||
|
from core.model_runtime.entities.message_entities import ImagePromptMessageContent
|
||||||
from core.model_runtime.entities.model_entities import ModelFeature
|
from core.model_runtime.entities.model_entities import ModelFeature
|
||||||
from core.model_runtime.model_providers.__base.large_language_model import LargeLanguageModel
|
from core.model_runtime.model_providers.__base.large_language_model import LargeLanguageModel
|
||||||
from core.model_runtime.utils.encoders import jsonable_encoder
|
from core.model_runtime.utils.encoders import jsonable_encoder
|
||||||
|
@ -65,7 +66,7 @@ class BaseAgentRunner(AppRunner):
|
||||||
prompt_messages: Optional[list[PromptMessage]] = None,
|
prompt_messages: Optional[list[PromptMessage]] = None,
|
||||||
variables_pool: Optional[ToolRuntimeVariablePool] = None,
|
variables_pool: Optional[ToolRuntimeVariablePool] = None,
|
||||||
db_variables: Optional[ToolConversationVariables] = None,
|
db_variables: Optional[ToolConversationVariables] = None,
|
||||||
model_instance: ModelInstance = None,
|
model_instance: ModelInstance | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.tenant_id = tenant_id
|
self.tenant_id = tenant_id
|
||||||
self.application_generate_entity = application_generate_entity
|
self.application_generate_entity = application_generate_entity
|
||||||
|
@ -508,24 +509,27 @@ class BaseAgentRunner(AppRunner):
|
||||||
|
|
||||||
def organize_agent_user_prompt(self, message: Message) -> UserPromptMessage:
|
def organize_agent_user_prompt(self, message: Message) -> UserPromptMessage:
|
||||||
files = db.session.query(MessageFile).filter(MessageFile.message_id == message.id).all()
|
files = db.session.query(MessageFile).filter(MessageFile.message_id == message.id).all()
|
||||||
if files:
|
if not files:
|
||||||
file_extra_config = FileUploadConfigManager.convert(message.app_model_config.to_dict())
|
|
||||||
|
|
||||||
if file_extra_config:
|
|
||||||
file_objs = file_factory.build_from_message_files(
|
|
||||||
message_files=files, tenant_id=self.tenant_id, config=file_extra_config
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
file_objs = []
|
|
||||||
|
|
||||||
if not file_objs:
|
|
||||||
return UserPromptMessage(content=message.query)
|
|
||||||
else:
|
|
||||||
prompt_message_contents: list[PromptMessageContent] = []
|
|
||||||
prompt_message_contents.append(TextPromptMessageContent(data=message.query))
|
|
||||||
for file_obj in file_objs:
|
|
||||||
prompt_message_contents.append(file_manager.to_prompt_message_content(file_obj))
|
|
||||||
|
|
||||||
return UserPromptMessage(content=prompt_message_contents)
|
|
||||||
else:
|
|
||||||
return UserPromptMessage(content=message.query)
|
return UserPromptMessage(content=message.query)
|
||||||
|
file_extra_config = FileUploadConfigManager.convert(message.app_model_config.to_dict())
|
||||||
|
if not file_extra_config:
|
||||||
|
return UserPromptMessage(content=message.query)
|
||||||
|
|
||||||
|
image_detail_config = file_extra_config.image_config.detail if file_extra_config.image_config else None
|
||||||
|
image_detail_config = image_detail_config or ImagePromptMessageContent.DETAIL.LOW
|
||||||
|
|
||||||
|
file_objs = file_factory.build_from_message_files(
|
||||||
|
message_files=files, tenant_id=self.tenant_id, config=file_extra_config
|
||||||
|
)
|
||||||
|
if not file_objs:
|
||||||
|
return UserPromptMessage(content=message.query)
|
||||||
|
prompt_message_contents: list[PromptMessageContent] = []
|
||||||
|
prompt_message_contents.append(TextPromptMessageContent(data=message.query))
|
||||||
|
for file in file_objs:
|
||||||
|
prompt_message_contents.append(
|
||||||
|
file_manager.to_prompt_message_content(
|
||||||
|
file,
|
||||||
|
image_detail_config=image_detail_config,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return UserPromptMessage(content=prompt_message_contents)
|
||||||
|
|
|
@ -10,6 +10,7 @@ from core.model_runtime.entities import (
|
||||||
TextPromptMessageContent,
|
TextPromptMessageContent,
|
||||||
UserPromptMessage,
|
UserPromptMessage,
|
||||||
)
|
)
|
||||||
|
from core.model_runtime.entities.message_entities import ImagePromptMessageContent
|
||||||
from core.model_runtime.utils.encoders import jsonable_encoder
|
from core.model_runtime.utils.encoders import jsonable_encoder
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,8 +37,24 @@ class CotChatAgentRunner(CotAgentRunner):
|
||||||
if self.files:
|
if self.files:
|
||||||
prompt_message_contents: list[PromptMessageContent] = []
|
prompt_message_contents: list[PromptMessageContent] = []
|
||||||
prompt_message_contents.append(TextPromptMessageContent(data=query))
|
prompt_message_contents.append(TextPromptMessageContent(data=query))
|
||||||
for file_obj in self.files:
|
|
||||||
prompt_message_contents.append(file_manager.to_prompt_message_content(file_obj))
|
# get image detail config
|
||||||
|
image_detail_config = (
|
||||||
|
self.application_generate_entity.file_upload_config.image_config.detail
|
||||||
|
if (
|
||||||
|
self.application_generate_entity.file_upload_config
|
||||||
|
and self.application_generate_entity.file_upload_config.image_config
|
||||||
|
)
|
||||||
|
else None
|
||||||
|
)
|
||||||
|
image_detail_config = image_detail_config or ImagePromptMessageContent.DETAIL.LOW
|
||||||
|
for file in self.files:
|
||||||
|
prompt_message_contents.append(
|
||||||
|
file_manager.to_prompt_message_content(
|
||||||
|
file,
|
||||||
|
image_detail_config=image_detail_config,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
prompt_messages.append(UserPromptMessage(content=prompt_message_contents))
|
prompt_messages.append(UserPromptMessage(content=prompt_message_contents))
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -22,6 +22,7 @@ from core.model_runtime.entities import (
|
||||||
ToolPromptMessage,
|
ToolPromptMessage,
|
||||||
UserPromptMessage,
|
UserPromptMessage,
|
||||||
)
|
)
|
||||||
|
from core.model_runtime.entities.message_entities import ImagePromptMessageContent
|
||||||
from core.prompt.agent_history_prompt_transform import AgentHistoryPromptTransform
|
from core.prompt.agent_history_prompt_transform import AgentHistoryPromptTransform
|
||||||
from core.tools.entities.tool_entities import ToolInvokeMeta
|
from core.tools.entities.tool_entities import ToolInvokeMeta
|
||||||
from core.tools.tool_engine import ToolEngine
|
from core.tools.tool_engine import ToolEngine
|
||||||
|
@ -397,8 +398,24 @@ class FunctionCallAgentRunner(BaseAgentRunner):
|
||||||
if self.files:
|
if self.files:
|
||||||
prompt_message_contents: list[PromptMessageContent] = []
|
prompt_message_contents: list[PromptMessageContent] = []
|
||||||
prompt_message_contents.append(TextPromptMessageContent(data=query))
|
prompt_message_contents.append(TextPromptMessageContent(data=query))
|
||||||
for file_obj in self.files:
|
|
||||||
prompt_message_contents.append(file_manager.to_prompt_message_content(file_obj))
|
# get image detail config
|
||||||
|
image_detail_config = (
|
||||||
|
self.application_generate_entity.file_upload_config.image_config.detail
|
||||||
|
if (
|
||||||
|
self.application_generate_entity.file_upload_config
|
||||||
|
and self.application_generate_entity.file_upload_config.image_config
|
||||||
|
)
|
||||||
|
else None
|
||||||
|
)
|
||||||
|
image_detail_config = image_detail_config or ImagePromptMessageContent.DETAIL.LOW
|
||||||
|
for file in self.files:
|
||||||
|
prompt_message_contents.append(
|
||||||
|
file_manager.to_prompt_message_content(
|
||||||
|
file,
|
||||||
|
image_detail_config=image_detail_config,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
prompt_messages.append(UserPromptMessage(content=prompt_message_contents))
|
prompt_messages.append(UserPromptMessage(content=prompt_message_contents))
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -4,7 +4,7 @@ from typing import Any, Optional
|
||||||
|
|
||||||
from pydantic import BaseModel, Field, field_validator
|
from pydantic import BaseModel, Field, field_validator
|
||||||
|
|
||||||
from core.file import FileExtraConfig, FileTransferMethod, FileType
|
from core.file import FileTransferMethod, FileType, FileUploadConfig
|
||||||
from core.model_runtime.entities.message_entities import PromptMessageRole
|
from core.model_runtime.entities.message_entities import PromptMessageRole
|
||||||
from models.model import AppMode
|
from models.model import AppMode
|
||||||
|
|
||||||
|
@ -211,7 +211,7 @@ class TracingConfigEntity(BaseModel):
|
||||||
|
|
||||||
|
|
||||||
class AppAdditionalFeatures(BaseModel):
|
class AppAdditionalFeatures(BaseModel):
|
||||||
file_upload: Optional[FileExtraConfig] = None
|
file_upload: Optional[FileUploadConfig] = None
|
||||||
opening_statement: Optional[str] = None
|
opening_statement: Optional[str] = None
|
||||||
suggested_questions: list[str] = []
|
suggested_questions: list[str] = []
|
||||||
suggested_questions_after_answer: bool = False
|
suggested_questions_after_answer: bool = False
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from collections.abc import Mapping
|
from collections.abc import Mapping
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from core.file import FileExtraConfig
|
from core.file import FileUploadConfig
|
||||||
|
|
||||||
|
|
||||||
class FileUploadConfigManager:
|
class FileUploadConfigManager:
|
||||||
|
@ -29,19 +29,18 @@ class FileUploadConfigManager:
|
||||||
if is_vision:
|
if is_vision:
|
||||||
data["image_config"]["detail"] = file_upload_dict.get("image", {}).get("detail", "low")
|
data["image_config"]["detail"] = file_upload_dict.get("image", {}).get("detail", "low")
|
||||||
|
|
||||||
return FileExtraConfig.model_validate(data)
|
return FileUploadConfig.model_validate(data)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def validate_and_set_defaults(cls, config: dict, is_vision: bool = True) -> tuple[dict, list[str]]:
|
def validate_and_set_defaults(cls, config: dict) -> tuple[dict, list[str]]:
|
||||||
"""
|
"""
|
||||||
Validate and set defaults for file upload feature
|
Validate and set defaults for file upload feature
|
||||||
|
|
||||||
:param config: app model config args
|
:param config: app model config args
|
||||||
:param is_vision: if True, the feature is vision feature
|
|
||||||
"""
|
"""
|
||||||
if not config.get("file_upload"):
|
if not config.get("file_upload"):
|
||||||
config["file_upload"] = {}
|
config["file_upload"] = {}
|
||||||
else:
|
else:
|
||||||
FileExtraConfig.model_validate(config["file_upload"])
|
FileUploadConfig.model_validate(config["file_upload"])
|
||||||
|
|
||||||
return config, ["file_upload"]
|
return config, ["file_upload"]
|
||||||
|
|
|
@ -52,9 +52,7 @@ class AdvancedChatAppConfigManager(BaseAppConfigManager):
|
||||||
related_config_keys = []
|
related_config_keys = []
|
||||||
|
|
||||||
# file upload validation
|
# file upload validation
|
||||||
config, current_related_config_keys = FileUploadConfigManager.validate_and_set_defaults(
|
config, current_related_config_keys = FileUploadConfigManager.validate_and_set_defaults(config=config)
|
||||||
config=config, is_vision=False
|
|
||||||
)
|
|
||||||
related_config_keys.extend(current_related_config_keys)
|
related_config_keys.extend(current_related_config_keys)
|
||||||
|
|
||||||
# opening_statement
|
# opening_statement
|
||||||
|
|
|
@ -26,7 +26,6 @@ from core.ops.ops_trace_manager import TraceQueueManager
|
||||||
from extensions.ext_database import db
|
from extensions.ext_database import db
|
||||||
from factories import file_factory
|
from factories import file_factory
|
||||||
from models.account import Account
|
from models.account import Account
|
||||||
from models.enums import CreatedByRole
|
|
||||||
from models.model import App, Conversation, EndUser, Message
|
from models.model import App, Conversation, EndUser, Message
|
||||||
from models.workflow import Workflow
|
from models.workflow import Workflow
|
||||||
|
|
||||||
|
@ -98,13 +97,10 @@ class AdvancedChatAppGenerator(MessageBasedAppGenerator):
|
||||||
# parse files
|
# parse files
|
||||||
files = args["files"] if args.get("files") else []
|
files = args["files"] if args.get("files") else []
|
||||||
file_extra_config = FileUploadConfigManager.convert(workflow.features_dict, is_vision=False)
|
file_extra_config = FileUploadConfigManager.convert(workflow.features_dict, is_vision=False)
|
||||||
role = CreatedByRole.ACCOUNT if isinstance(user, Account) else CreatedByRole.END_USER
|
|
||||||
if file_extra_config:
|
if file_extra_config:
|
||||||
file_objs = file_factory.build_from_mappings(
|
file_objs = file_factory.build_from_mappings(
|
||||||
mappings=files,
|
mappings=files,
|
||||||
tenant_id=app_model.tenant_id,
|
tenant_id=app_model.tenant_id,
|
||||||
user_id=user.id,
|
|
||||||
role=role,
|
|
||||||
config=file_extra_config,
|
config=file_extra_config,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
@ -127,10 +123,11 @@ class AdvancedChatAppGenerator(MessageBasedAppGenerator):
|
||||||
application_generate_entity = AdvancedChatAppGenerateEntity(
|
application_generate_entity = AdvancedChatAppGenerateEntity(
|
||||||
task_id=str(uuid.uuid4()),
|
task_id=str(uuid.uuid4()),
|
||||||
app_config=app_config,
|
app_config=app_config,
|
||||||
|
file_upload_config=file_extra_config,
|
||||||
conversation_id=conversation.id if conversation else None,
|
conversation_id=conversation.id if conversation else None,
|
||||||
inputs=conversation.inputs
|
inputs=conversation.inputs
|
||||||
if conversation
|
if conversation
|
||||||
else self._prepare_user_inputs(user_inputs=inputs, app_config=app_config, user_id=user.id, role=role),
|
else self._prepare_user_inputs(user_inputs=inputs, app_config=app_config),
|
||||||
query=query,
|
query=query,
|
||||||
files=file_objs,
|
files=file_objs,
|
||||||
parent_message_id=args.get("parent_message_id") if invoke_from != InvokeFrom.SERVICE_API else UUID_NIL,
|
parent_message_id=args.get("parent_message_id") if invoke_from != InvokeFrom.SERVICE_API else UUID_NIL,
|
||||||
|
|
|
@ -23,7 +23,6 @@ from core.ops.ops_trace_manager import TraceQueueManager
|
||||||
from extensions.ext_database import db
|
from extensions.ext_database import db
|
||||||
from factories import file_factory
|
from factories import file_factory
|
||||||
from models import Account, App, EndUser
|
from models import Account, App, EndUser
|
||||||
from models.enums import CreatedByRole
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -103,8 +102,6 @@ class AgentChatAppGenerator(MessageBasedAppGenerator):
|
||||||
# always enable retriever resource in debugger mode
|
# always enable retriever resource in debugger mode
|
||||||
override_model_config_dict["retriever_resource"] = {"enabled": True}
|
override_model_config_dict["retriever_resource"] = {"enabled": True}
|
||||||
|
|
||||||
role = CreatedByRole.ACCOUNT if isinstance(user, Account) else CreatedByRole.END_USER
|
|
||||||
|
|
||||||
# parse files
|
# parse files
|
||||||
files = args.get("files") or []
|
files = args.get("files") or []
|
||||||
file_extra_config = FileUploadConfigManager.convert(override_model_config_dict or app_model_config.to_dict())
|
file_extra_config = FileUploadConfigManager.convert(override_model_config_dict or app_model_config.to_dict())
|
||||||
|
@ -112,8 +109,6 @@ class AgentChatAppGenerator(MessageBasedAppGenerator):
|
||||||
file_objs = file_factory.build_from_mappings(
|
file_objs = file_factory.build_from_mappings(
|
||||||
mappings=files,
|
mappings=files,
|
||||||
tenant_id=app_model.tenant_id,
|
tenant_id=app_model.tenant_id,
|
||||||
user_id=user.id,
|
|
||||||
role=role,
|
|
||||||
config=file_extra_config,
|
config=file_extra_config,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
@ -135,10 +130,11 @@ class AgentChatAppGenerator(MessageBasedAppGenerator):
|
||||||
task_id=str(uuid.uuid4()),
|
task_id=str(uuid.uuid4()),
|
||||||
app_config=app_config,
|
app_config=app_config,
|
||||||
model_conf=ModelConfigConverter.convert(app_config),
|
model_conf=ModelConfigConverter.convert(app_config),
|
||||||
|
file_upload_config=file_extra_config,
|
||||||
conversation_id=conversation.id if conversation else None,
|
conversation_id=conversation.id if conversation else None,
|
||||||
inputs=conversation.inputs
|
inputs=conversation.inputs
|
||||||
if conversation
|
if conversation
|
||||||
else self._prepare_user_inputs(user_inputs=inputs, app_config=app_config, user_id=user.id, role=role),
|
else self._prepare_user_inputs(user_inputs=inputs, app_config=app_config),
|
||||||
query=query,
|
query=query,
|
||||||
files=file_objs,
|
files=file_objs,
|
||||||
parent_message_id=args.get("parent_message_id") if invoke_from != InvokeFrom.SERVICE_API else UUID_NIL,
|
parent_message_id=args.get("parent_message_id") if invoke_from != InvokeFrom.SERVICE_API else UUID_NIL,
|
||||||
|
|
|
@ -2,12 +2,11 @@ from collections.abc import Mapping
|
||||||
from typing import TYPE_CHECKING, Any, Optional
|
from typing import TYPE_CHECKING, Any, Optional
|
||||||
|
|
||||||
from core.app.app_config.entities import VariableEntityType
|
from core.app.app_config.entities import VariableEntityType
|
||||||
from core.file import File, FileExtraConfig
|
from core.file import File, FileUploadConfig
|
||||||
from factories import file_factory
|
from factories import file_factory
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from core.app.app_config.entities import AppConfig, VariableEntity
|
from core.app.app_config.entities import AppConfig, VariableEntity
|
||||||
from models.enums import CreatedByRole
|
|
||||||
|
|
||||||
|
|
||||||
class BaseAppGenerator:
|
class BaseAppGenerator:
|
||||||
|
@ -16,8 +15,6 @@ class BaseAppGenerator:
|
||||||
*,
|
*,
|
||||||
user_inputs: Optional[Mapping[str, Any]],
|
user_inputs: Optional[Mapping[str, Any]],
|
||||||
app_config: "AppConfig",
|
app_config: "AppConfig",
|
||||||
user_id: str,
|
|
||||||
role: "CreatedByRole",
|
|
||||||
) -> Mapping[str, Any]:
|
) -> Mapping[str, Any]:
|
||||||
user_inputs = user_inputs or {}
|
user_inputs = user_inputs or {}
|
||||||
# Filter input variables from form configuration, handle required fields, default values, and option values
|
# Filter input variables from form configuration, handle required fields, default values, and option values
|
||||||
|
@ -34,9 +31,7 @@ class BaseAppGenerator:
|
||||||
k: file_factory.build_from_mapping(
|
k: file_factory.build_from_mapping(
|
||||||
mapping=v,
|
mapping=v,
|
||||||
tenant_id=app_config.tenant_id,
|
tenant_id=app_config.tenant_id,
|
||||||
user_id=user_id,
|
config=FileUploadConfig(
|
||||||
role=role,
|
|
||||||
config=FileExtraConfig(
|
|
||||||
allowed_file_types=entity_dictionary[k].allowed_file_types,
|
allowed_file_types=entity_dictionary[k].allowed_file_types,
|
||||||
allowed_extensions=entity_dictionary[k].allowed_file_extensions,
|
allowed_extensions=entity_dictionary[k].allowed_file_extensions,
|
||||||
allowed_upload_methods=entity_dictionary[k].allowed_file_upload_methods,
|
allowed_upload_methods=entity_dictionary[k].allowed_file_upload_methods,
|
||||||
|
@ -50,9 +45,7 @@ class BaseAppGenerator:
|
||||||
k: file_factory.build_from_mappings(
|
k: file_factory.build_from_mappings(
|
||||||
mappings=v,
|
mappings=v,
|
||||||
tenant_id=app_config.tenant_id,
|
tenant_id=app_config.tenant_id,
|
||||||
user_id=user_id,
|
config=FileUploadConfig(
|
||||||
role=role,
|
|
||||||
config=FileExtraConfig(
|
|
||||||
allowed_file_types=entity_dictionary[k].allowed_file_types,
|
allowed_file_types=entity_dictionary[k].allowed_file_types,
|
||||||
allowed_extensions=entity_dictionary[k].allowed_file_extensions,
|
allowed_extensions=entity_dictionary[k].allowed_file_extensions,
|
||||||
allowed_upload_methods=entity_dictionary[k].allowed_file_upload_methods,
|
allowed_upload_methods=entity_dictionary[k].allowed_file_upload_methods,
|
||||||
|
|
|
@ -23,7 +23,6 @@ from core.ops.ops_trace_manager import TraceQueueManager
|
||||||
from extensions.ext_database import db
|
from extensions.ext_database import db
|
||||||
from factories import file_factory
|
from factories import file_factory
|
||||||
from models.account import Account
|
from models.account import Account
|
||||||
from models.enums import CreatedByRole
|
|
||||||
from models.model import App, EndUser
|
from models.model import App, EndUser
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -101,8 +100,6 @@ class ChatAppGenerator(MessageBasedAppGenerator):
|
||||||
# always enable retriever resource in debugger mode
|
# always enable retriever resource in debugger mode
|
||||||
override_model_config_dict["retriever_resource"] = {"enabled": True}
|
override_model_config_dict["retriever_resource"] = {"enabled": True}
|
||||||
|
|
||||||
role = CreatedByRole.ACCOUNT if isinstance(user, Account) else CreatedByRole.END_USER
|
|
||||||
|
|
||||||
# parse files
|
# parse files
|
||||||
files = args["files"] if args.get("files") else []
|
files = args["files"] if args.get("files") else []
|
||||||
file_extra_config = FileUploadConfigManager.convert(override_model_config_dict or app_model_config.to_dict())
|
file_extra_config = FileUploadConfigManager.convert(override_model_config_dict or app_model_config.to_dict())
|
||||||
|
@ -110,8 +107,6 @@ class ChatAppGenerator(MessageBasedAppGenerator):
|
||||||
file_objs = file_factory.build_from_mappings(
|
file_objs = file_factory.build_from_mappings(
|
||||||
mappings=files,
|
mappings=files,
|
||||||
tenant_id=app_model.tenant_id,
|
tenant_id=app_model.tenant_id,
|
||||||
user_id=user.id,
|
|
||||||
role=role,
|
|
||||||
config=file_extra_config,
|
config=file_extra_config,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
@ -133,10 +128,11 @@ class ChatAppGenerator(MessageBasedAppGenerator):
|
||||||
task_id=str(uuid.uuid4()),
|
task_id=str(uuid.uuid4()),
|
||||||
app_config=app_config,
|
app_config=app_config,
|
||||||
model_conf=ModelConfigConverter.convert(app_config),
|
model_conf=ModelConfigConverter.convert(app_config),
|
||||||
|
file_upload_config=file_extra_config,
|
||||||
conversation_id=conversation.id if conversation else None,
|
conversation_id=conversation.id if conversation else None,
|
||||||
inputs=conversation.inputs
|
inputs=conversation.inputs
|
||||||
if conversation
|
if conversation
|
||||||
else self._prepare_user_inputs(user_inputs=inputs, app_config=app_config, user_id=user.id, role=role),
|
else self._prepare_user_inputs(user_inputs=inputs, app_config=app_config),
|
||||||
query=query,
|
query=query,
|
||||||
files=file_objs,
|
files=file_objs,
|
||||||
parent_message_id=args.get("parent_message_id") if invoke_from != InvokeFrom.SERVICE_API else UUID_NIL,
|
parent_message_id=args.get("parent_message_id") if invoke_from != InvokeFrom.SERVICE_API else UUID_NIL,
|
||||||
|
|
|
@ -22,7 +22,6 @@ from core.ops.ops_trace_manager import TraceQueueManager
|
||||||
from extensions.ext_database import db
|
from extensions.ext_database import db
|
||||||
from factories import file_factory
|
from factories import file_factory
|
||||||
from models import Account, App, EndUser, Message
|
from models import Account, App, EndUser, Message
|
||||||
from models.enums import CreatedByRole
|
|
||||||
from services.errors.app import MoreLikeThisDisabledError
|
from services.errors.app import MoreLikeThisDisabledError
|
||||||
from services.errors.message import MessageNotExistsError
|
from services.errors.message import MessageNotExistsError
|
||||||
|
|
||||||
|
@ -88,8 +87,6 @@ class CompletionAppGenerator(MessageBasedAppGenerator):
|
||||||
tenant_id=app_model.tenant_id, config=args.get("model_config")
|
tenant_id=app_model.tenant_id, config=args.get("model_config")
|
||||||
)
|
)
|
||||||
|
|
||||||
role = CreatedByRole.ACCOUNT if isinstance(user, Account) else CreatedByRole.END_USER
|
|
||||||
|
|
||||||
# parse files
|
# parse files
|
||||||
files = args["files"] if args.get("files") else []
|
files = args["files"] if args.get("files") else []
|
||||||
file_extra_config = FileUploadConfigManager.convert(override_model_config_dict or app_model_config.to_dict())
|
file_extra_config = FileUploadConfigManager.convert(override_model_config_dict or app_model_config.to_dict())
|
||||||
|
@ -97,8 +94,6 @@ class CompletionAppGenerator(MessageBasedAppGenerator):
|
||||||
file_objs = file_factory.build_from_mappings(
|
file_objs = file_factory.build_from_mappings(
|
||||||
mappings=files,
|
mappings=files,
|
||||||
tenant_id=app_model.tenant_id,
|
tenant_id=app_model.tenant_id,
|
||||||
user_id=user.id,
|
|
||||||
role=role,
|
|
||||||
config=file_extra_config,
|
config=file_extra_config,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
@ -110,7 +105,6 @@ class CompletionAppGenerator(MessageBasedAppGenerator):
|
||||||
)
|
)
|
||||||
|
|
||||||
# get tracing instance
|
# get tracing instance
|
||||||
user_id = user.id if isinstance(user, Account) else user.session_id
|
|
||||||
trace_manager = TraceQueueManager(app_model.id)
|
trace_manager = TraceQueueManager(app_model.id)
|
||||||
|
|
||||||
# init application generate entity
|
# init application generate entity
|
||||||
|
@ -118,7 +112,8 @@ class CompletionAppGenerator(MessageBasedAppGenerator):
|
||||||
task_id=str(uuid.uuid4()),
|
task_id=str(uuid.uuid4()),
|
||||||
app_config=app_config,
|
app_config=app_config,
|
||||||
model_conf=ModelConfigConverter.convert(app_config),
|
model_conf=ModelConfigConverter.convert(app_config),
|
||||||
inputs=self._prepare_user_inputs(user_inputs=inputs, app_config=app_config, user_id=user.id, role=role),
|
file_upload_config=file_extra_config,
|
||||||
|
inputs=self._prepare_user_inputs(user_inputs=inputs, app_config=app_config),
|
||||||
query=query,
|
query=query,
|
||||||
files=file_objs,
|
files=file_objs,
|
||||||
user_id=user.id,
|
user_id=user.id,
|
||||||
|
@ -259,14 +254,11 @@ class CompletionAppGenerator(MessageBasedAppGenerator):
|
||||||
override_model_config_dict["model"] = model_dict
|
override_model_config_dict["model"] = model_dict
|
||||||
|
|
||||||
# parse files
|
# parse files
|
||||||
role = CreatedByRole.ACCOUNT if isinstance(user, Account) else CreatedByRole.END_USER
|
|
||||||
file_extra_config = FileUploadConfigManager.convert(override_model_config_dict)
|
file_extra_config = FileUploadConfigManager.convert(override_model_config_dict)
|
||||||
if file_extra_config:
|
if file_extra_config:
|
||||||
file_objs = file_factory.build_from_mappings(
|
file_objs = file_factory.build_from_mappings(
|
||||||
mappings=message.message_files,
|
mappings=message.message_files,
|
||||||
tenant_id=app_model.tenant_id,
|
tenant_id=app_model.tenant_id,
|
||||||
user_id=user.id,
|
|
||||||
role=role,
|
|
||||||
config=file_extra_config,
|
config=file_extra_config,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -46,9 +46,7 @@ class WorkflowAppConfigManager(BaseAppConfigManager):
|
||||||
related_config_keys = []
|
related_config_keys = []
|
||||||
|
|
||||||
# file upload validation
|
# file upload validation
|
||||||
config, current_related_config_keys = FileUploadConfigManager.validate_and_set_defaults(
|
config, current_related_config_keys = FileUploadConfigManager.validate_and_set_defaults(config=config)
|
||||||
config=config, is_vision=False
|
|
||||||
)
|
|
||||||
related_config_keys.extend(current_related_config_keys)
|
related_config_keys.extend(current_related_config_keys)
|
||||||
|
|
||||||
# text_to_speech
|
# text_to_speech
|
||||||
|
|
|
@ -25,7 +25,6 @@ from core.ops.ops_trace_manager import TraceQueueManager
|
||||||
from extensions.ext_database import db
|
from extensions.ext_database import db
|
||||||
from factories import file_factory
|
from factories import file_factory
|
||||||
from models import Account, App, EndUser, Workflow
|
from models import Account, App, EndUser, Workflow
|
||||||
from models.enums import CreatedByRole
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -70,15 +69,11 @@ class WorkflowAppGenerator(BaseAppGenerator):
|
||||||
):
|
):
|
||||||
files: Sequence[Mapping[str, Any]] = args.get("files") or []
|
files: Sequence[Mapping[str, Any]] = args.get("files") or []
|
||||||
|
|
||||||
role = CreatedByRole.ACCOUNT if isinstance(user, Account) else CreatedByRole.END_USER
|
|
||||||
|
|
||||||
# parse files
|
# parse files
|
||||||
file_extra_config = FileUploadConfigManager.convert(workflow.features_dict, is_vision=False)
|
file_extra_config = FileUploadConfigManager.convert(workflow.features_dict, is_vision=False)
|
||||||
system_files = file_factory.build_from_mappings(
|
system_files = file_factory.build_from_mappings(
|
||||||
mappings=files,
|
mappings=files,
|
||||||
tenant_id=app_model.tenant_id,
|
tenant_id=app_model.tenant_id,
|
||||||
user_id=user.id,
|
|
||||||
role=role,
|
|
||||||
config=file_extra_config,
|
config=file_extra_config,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -100,7 +95,8 @@ class WorkflowAppGenerator(BaseAppGenerator):
|
||||||
application_generate_entity = WorkflowAppGenerateEntity(
|
application_generate_entity = WorkflowAppGenerateEntity(
|
||||||
task_id=str(uuid.uuid4()),
|
task_id=str(uuid.uuid4()),
|
||||||
app_config=app_config,
|
app_config=app_config,
|
||||||
inputs=self._prepare_user_inputs(user_inputs=inputs, app_config=app_config, user_id=user.id, role=role),
|
file_upload_config=file_extra_config,
|
||||||
|
inputs=self._prepare_user_inputs(user_inputs=inputs, app_config=app_config),
|
||||||
files=system_files,
|
files=system_files,
|
||||||
user_id=user.id,
|
user_id=user.id,
|
||||||
stream=stream,
|
stream=stream,
|
||||||
|
|
|
@ -7,7 +7,7 @@ from pydantic import BaseModel, ConfigDict, Field, ValidationInfo, field_validat
|
||||||
from constants import UUID_NIL
|
from constants import UUID_NIL
|
||||||
from core.app.app_config.entities import AppConfig, EasyUIBasedAppConfig, WorkflowUIBasedAppConfig
|
from core.app.app_config.entities import AppConfig, EasyUIBasedAppConfig, WorkflowUIBasedAppConfig
|
||||||
from core.entities.provider_configuration import ProviderModelBundle
|
from core.entities.provider_configuration import ProviderModelBundle
|
||||||
from core.file.models import File
|
from core.file import File, FileUploadConfig
|
||||||
from core.model_runtime.entities.model_entities import AIModelEntity
|
from core.model_runtime.entities.model_entities import AIModelEntity
|
||||||
from core.ops.ops_trace_manager import TraceQueueManager
|
from core.ops.ops_trace_manager import TraceQueueManager
|
||||||
|
|
||||||
|
@ -80,6 +80,7 @@ class AppGenerateEntity(BaseModel):
|
||||||
|
|
||||||
# app config
|
# app config
|
||||||
app_config: AppConfig
|
app_config: AppConfig
|
||||||
|
file_upload_config: Optional[FileUploadConfig] = None
|
||||||
|
|
||||||
inputs: Mapping[str, Any]
|
inputs: Mapping[str, Any]
|
||||||
files: Sequence[File]
|
files: Sequence[File]
|
||||||
|
|
|
@ -2,13 +2,13 @@ from .constants import FILE_MODEL_IDENTITY
|
||||||
from .enums import ArrayFileAttribute, FileAttribute, FileBelongsTo, FileTransferMethod, FileType
|
from .enums import ArrayFileAttribute, FileAttribute, FileBelongsTo, FileTransferMethod, FileType
|
||||||
from .models import (
|
from .models import (
|
||||||
File,
|
File,
|
||||||
FileExtraConfig,
|
FileUploadConfig,
|
||||||
ImageConfig,
|
ImageConfig,
|
||||||
)
|
)
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"FileType",
|
"FileType",
|
||||||
"FileExtraConfig",
|
"FileUploadConfig",
|
||||||
"FileTransferMethod",
|
"FileTransferMethod",
|
||||||
"FileBelongsTo",
|
"FileBelongsTo",
|
||||||
"File",
|
"File",
|
||||||
|
|
|
@ -33,25 +33,28 @@ def get_attr(*, file: File, attr: FileAttribute):
|
||||||
raise ValueError(f"Invalid file attribute: {attr}")
|
raise ValueError(f"Invalid file attribute: {attr}")
|
||||||
|
|
||||||
|
|
||||||
def to_prompt_message_content(f: File, /):
|
def to_prompt_message_content(
|
||||||
|
f: File,
|
||||||
|
/,
|
||||||
|
*,
|
||||||
|
image_detail_config: ImagePromptMessageContent.DETAIL = ImagePromptMessageContent.DETAIL.LOW,
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Convert a File object to an ImagePromptMessageContent object.
|
Convert a File object to an ImagePromptMessageContent or AudioPromptMessageContent object.
|
||||||
|
|
||||||
This function takes a File object and converts it to an ImagePromptMessageContent
|
This function takes a File object and converts it to an appropriate PromptMessageContent
|
||||||
object, which can be used as a prompt for image-based AI models.
|
object, which can be used as a prompt for image or audio-based AI models.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
file (File): The File object to convert. Must be of type FileType.IMAGE.
|
f (File): The File object to convert.
|
||||||
|
detail (Optional[ImagePromptMessageContent.DETAIL]): The detail level for image prompts.
|
||||||
|
If not provided, defaults to ImagePromptMessageContent.DETAIL.LOW.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
ImagePromptMessageContent: An object containing the image data and detail level.
|
Union[ImagePromptMessageContent, AudioPromptMessageContent]: An object containing the file data and detail level
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
ValueError: If the file is not an image or if the file data is missing.
|
ValueError: If the file type is not supported or if required data is missing.
|
||||||
|
|
||||||
Note:
|
|
||||||
The detail level of the image prompt is determined by the file's extra_config.
|
|
||||||
If not specified, it defaults to ImagePromptMessageContent.DETAIL.LOW.
|
|
||||||
"""
|
"""
|
||||||
match f.type:
|
match f.type:
|
||||||
case FileType.IMAGE:
|
case FileType.IMAGE:
|
||||||
|
@ -60,12 +63,7 @@ def to_prompt_message_content(f: File, /):
|
||||||
else:
|
else:
|
||||||
data = _to_base64_data_string(f)
|
data = _to_base64_data_string(f)
|
||||||
|
|
||||||
if f._extra_config and f._extra_config.image_config and f._extra_config.image_config.detail:
|
return ImagePromptMessageContent(data=data, detail=image_detail_config)
|
||||||
detail = f._extra_config.image_config.detail
|
|
||||||
else:
|
|
||||||
detail = ImagePromptMessageContent.DETAIL.LOW
|
|
||||||
|
|
||||||
return ImagePromptMessageContent(data=data, detail=detail)
|
|
||||||
case FileType.AUDIO:
|
case FileType.AUDIO:
|
||||||
encoded_string = _file_to_encoded_string(f)
|
encoded_string = _file_to_encoded_string(f)
|
||||||
if f.extension is None:
|
if f.extension is None:
|
||||||
|
@ -78,7 +76,7 @@ def to_prompt_message_content(f: File, /):
|
||||||
data = _to_base64_data_string(f)
|
data = _to_base64_data_string(f)
|
||||||
return VideoPromptMessageContent(data=data, format=f.extension.lstrip("."))
|
return VideoPromptMessageContent(data=data, format=f.extension.lstrip("."))
|
||||||
case _:
|
case _:
|
||||||
raise ValueError(f"file type {f.type} is not supported")
|
raise ValueError("file type f.type is not supported")
|
||||||
|
|
||||||
|
|
||||||
def download(f: File, /):
|
def download(f: File, /):
|
||||||
|
|
|
@ -21,7 +21,7 @@ class ImageConfig(BaseModel):
|
||||||
detail: ImagePromptMessageContent.DETAIL | None = None
|
detail: ImagePromptMessageContent.DETAIL | None = None
|
||||||
|
|
||||||
|
|
||||||
class FileExtraConfig(BaseModel):
|
class FileUploadConfig(BaseModel):
|
||||||
"""
|
"""
|
||||||
File Upload Entity.
|
File Upload Entity.
|
||||||
"""
|
"""
|
||||||
|
@ -46,7 +46,6 @@ class File(BaseModel):
|
||||||
extension: Optional[str] = Field(default=None, description="File extension, should contains dot")
|
extension: Optional[str] = Field(default=None, description="File extension, should contains dot")
|
||||||
mime_type: Optional[str] = None
|
mime_type: Optional[str] = None
|
||||||
size: int = -1
|
size: int = -1
|
||||||
_extra_config: FileExtraConfig | None = None
|
|
||||||
|
|
||||||
def to_dict(self) -> Mapping[str, str | int | None]:
|
def to_dict(self) -> Mapping[str, str | int | None]:
|
||||||
data = self.model_dump(mode="json")
|
data = self.model_dump(mode="json")
|
||||||
|
@ -107,34 +106,4 @@ class File(BaseModel):
|
||||||
case FileTransferMethod.TOOL_FILE:
|
case FileTransferMethod.TOOL_FILE:
|
||||||
if not self.related_id:
|
if not self.related_id:
|
||||||
raise ValueError("Missing file related_id")
|
raise ValueError("Missing file related_id")
|
||||||
|
|
||||||
# Validate the extra config.
|
|
||||||
if not self._extra_config:
|
|
||||||
return self
|
|
||||||
|
|
||||||
if self._extra_config.allowed_file_types:
|
|
||||||
if self.type not in self._extra_config.allowed_file_types and self.type != FileType.CUSTOM:
|
|
||||||
raise ValueError(f"Invalid file type: {self.type}")
|
|
||||||
|
|
||||||
if self._extra_config.allowed_extensions and self.extension not in self._extra_config.allowed_extensions:
|
|
||||||
raise ValueError(f"Invalid file extension: {self.extension}")
|
|
||||||
|
|
||||||
if (
|
|
||||||
self._extra_config.allowed_upload_methods
|
|
||||||
and self.transfer_method not in self._extra_config.allowed_upload_methods
|
|
||||||
):
|
|
||||||
raise ValueError(f"Invalid transfer method: {self.transfer_method}")
|
|
||||||
|
|
||||||
match self.type:
|
|
||||||
case FileType.IMAGE:
|
|
||||||
# NOTE: This part of validation is deprecated, but still used in app features "Image Upload".
|
|
||||||
if not self._extra_config.image_config:
|
|
||||||
return self
|
|
||||||
# TODO: skip check if transfer_methods is empty, because many test cases are not setting this field
|
|
||||||
if (
|
|
||||||
self._extra_config.image_config.transfer_methods
|
|
||||||
and self.transfer_method not in self._extra_config.image_config.transfer_methods
|
|
||||||
):
|
|
||||||
raise ValueError(f"Invalid transfer method: {self.transfer_method}")
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
|
@ -81,15 +81,18 @@ class TokenBufferMemory:
|
||||||
db.session.query(WorkflowRun).filter(WorkflowRun.id == message.workflow_run_id).first()
|
db.session.query(WorkflowRun).filter(WorkflowRun.id == message.workflow_run_id).first()
|
||||||
)
|
)
|
||||||
|
|
||||||
if workflow_run:
|
if workflow_run and workflow_run.workflow:
|
||||||
file_extra_config = FileUploadConfigManager.convert(
|
file_extra_config = FileUploadConfigManager.convert(
|
||||||
workflow_run.workflow.features_dict, is_vision=False
|
workflow_run.workflow.features_dict, is_vision=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
detail = ImagePromptMessageContent.DETAIL.LOW
|
||||||
if file_extra_config and app_record:
|
if file_extra_config and app_record:
|
||||||
file_objs = file_factory.build_from_message_files(
|
file_objs = file_factory.build_from_message_files(
|
||||||
message_files=files, tenant_id=app_record.tenant_id, config=file_extra_config
|
message_files=files, tenant_id=app_record.tenant_id, config=file_extra_config
|
||||||
)
|
)
|
||||||
|
if file_extra_config.image_config and file_extra_config.image_config.detail:
|
||||||
|
detail = file_extra_config.image_config.detail
|
||||||
else:
|
else:
|
||||||
file_objs = []
|
file_objs = []
|
||||||
|
|
||||||
|
@ -98,12 +101,16 @@ class TokenBufferMemory:
|
||||||
else:
|
else:
|
||||||
prompt_message_contents: list[PromptMessageContent] = []
|
prompt_message_contents: list[PromptMessageContent] = []
|
||||||
prompt_message_contents.append(TextPromptMessageContent(data=message.query))
|
prompt_message_contents.append(TextPromptMessageContent(data=message.query))
|
||||||
for file_obj in file_objs:
|
for file in file_objs:
|
||||||
if file_obj.type in {FileType.IMAGE, FileType.AUDIO}:
|
if file.type in {FileType.IMAGE, FileType.AUDIO}:
|
||||||
prompt_message = file_manager.to_prompt_message_content(file_obj)
|
prompt_message = file_manager.to_prompt_message_content(
|
||||||
|
file,
|
||||||
|
image_detail_config=detail,
|
||||||
|
)
|
||||||
prompt_message_contents.append(prompt_message)
|
prompt_message_contents.append(prompt_message)
|
||||||
|
|
||||||
prompt_messages.append(UserPromptMessage(content=prompt_message_contents))
|
prompt_messages.append(UserPromptMessage(content=prompt_message_contents))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
prompt_messages.append(UserPromptMessage(content=message.query))
|
prompt_messages.append(UserPromptMessage(content=message.query))
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,9 @@ parameter_rules:
|
||||||
use_template: max_tokens
|
use_template: max_tokens
|
||||||
required: true
|
required: true
|
||||||
type: int
|
type: int
|
||||||
default: 4096
|
default: 8192
|
||||||
min: 1
|
min: 1
|
||||||
max: 4096
|
max: 8192
|
||||||
help:
|
help:
|
||||||
zh_Hans: 停止前生成的最大令牌数。请注意,Anthropic Claude 模型可能会在达到 max_tokens 的值之前停止生成令牌。不同的 Anthropic Claude 模型对此参数具有不同的最大值。
|
zh_Hans: 停止前生成的最大令牌数。请注意,Anthropic Claude 模型可能会在达到 max_tokens 的值之前停止生成令牌。不同的 Anthropic Claude 模型对此参数具有不同的最大值。
|
||||||
en_US: The maximum number of tokens to generate before stopping. Note that Anthropic Claude models might stop generating tokens before reaching the value of max_tokens. Different Anthropic Claude models have different maximum values for this parameter.
|
en_US: The maximum number of tokens to generate before stopping. Note that Anthropic Claude models might stop generating tokens before reaching the value of max_tokens. Different Anthropic Claude models have different maximum values for this parameter.
|
||||||
|
|
|
@ -13,9 +13,9 @@ parameter_rules:
|
||||||
use_template: max_tokens
|
use_template: max_tokens
|
||||||
required: true
|
required: true
|
||||||
type: int
|
type: int
|
||||||
default: 4096
|
default: 8192
|
||||||
min: 1
|
min: 1
|
||||||
max: 4096
|
max: 8192
|
||||||
help:
|
help:
|
||||||
zh_Hans: 停止前生成的最大令牌数。请注意,Anthropic Claude 模型可能会在达到 max_tokens 的值之前停止生成令牌。不同的 Anthropic Claude 模型对此参数具有不同的最大值。
|
zh_Hans: 停止前生成的最大令牌数。请注意,Anthropic Claude 模型可能会在达到 max_tokens 的值之前停止生成令牌。不同的 Anthropic Claude 模型对此参数具有不同的最大值。
|
||||||
en_US: The maximum number of tokens to generate before stopping. Note that Anthropic Claude models might stop generating tokens before reaching the value of max_tokens. Different Anthropic Claude models have different maximum values for this parameter.
|
en_US: The maximum number of tokens to generate before stopping. Note that Anthropic Claude models might stop generating tokens before reaching the value of max_tokens. Different Anthropic Claude models have different maximum values for this parameter.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
provider: vessl_ai
|
provider: vessl_ai
|
||||||
label:
|
label:
|
||||||
en_US: vessl_ai
|
en_US: VESSL AI
|
||||||
icon_small:
|
icon_small:
|
||||||
en_US: icon_s_en.svg
|
en_US: icon_s_en.svg
|
||||||
icon_large:
|
icon_large:
|
||||||
|
@ -20,28 +20,28 @@ model_credential_schema:
|
||||||
label:
|
label:
|
||||||
en_US: Model Name
|
en_US: Model Name
|
||||||
placeholder:
|
placeholder:
|
||||||
en_US: Enter your model name
|
en_US: Enter model name
|
||||||
credential_form_schemas:
|
credential_form_schemas:
|
||||||
- variable: endpoint_url
|
- variable: endpoint_url
|
||||||
label:
|
label:
|
||||||
en_US: endpoint url
|
en_US: Endpoint Url
|
||||||
type: text-input
|
type: text-input
|
||||||
required: true
|
required: true
|
||||||
placeholder:
|
placeholder:
|
||||||
en_US: Enter the url of your endpoint url
|
en_US: Enter VESSL AI service endpoint url
|
||||||
- variable: api_key
|
- variable: api_key
|
||||||
required: true
|
required: true
|
||||||
label:
|
label:
|
||||||
en_US: API Key
|
en_US: API Key
|
||||||
type: secret-input
|
type: secret-input
|
||||||
placeholder:
|
placeholder:
|
||||||
en_US: Enter your VESSL AI secret key
|
en_US: Enter VESSL AI secret key
|
||||||
- variable: mode
|
- variable: mode
|
||||||
show_on:
|
show_on:
|
||||||
- variable: __model_type
|
- variable: __model_type
|
||||||
value: llm
|
value: llm
|
||||||
label:
|
label:
|
||||||
en_US: Completion mode
|
en_US: Completion Mode
|
||||||
type: select
|
type: select
|
||||||
required: false
|
required: false
|
||||||
default: chat
|
default: chat
|
||||||
|
|
|
@ -15,6 +15,7 @@ from core.model_runtime.entities import (
|
||||||
TextPromptMessageContent,
|
TextPromptMessageContent,
|
||||||
UserPromptMessage,
|
UserPromptMessage,
|
||||||
)
|
)
|
||||||
|
from core.model_runtime.entities.message_entities import ImagePromptMessageContent
|
||||||
from core.prompt.entities.advanced_prompt_entities import ChatModelMessage, CompletionModelPromptTemplate, MemoryConfig
|
from core.prompt.entities.advanced_prompt_entities import ChatModelMessage, CompletionModelPromptTemplate, MemoryConfig
|
||||||
from core.prompt.prompt_transform import PromptTransform
|
from core.prompt.prompt_transform import PromptTransform
|
||||||
from core.prompt.utils.prompt_template_parser import PromptTemplateParser
|
from core.prompt.utils.prompt_template_parser import PromptTemplateParser
|
||||||
|
@ -26,8 +27,13 @@ class AdvancedPromptTransform(PromptTransform):
|
||||||
Advanced Prompt Transform for Workflow LLM Node.
|
Advanced Prompt Transform for Workflow LLM Node.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, with_variable_tmpl: bool = False) -> None:
|
def __init__(
|
||||||
|
self,
|
||||||
|
with_variable_tmpl: bool = False,
|
||||||
|
image_detail_config: ImagePromptMessageContent.DETAIL = ImagePromptMessageContent.DETAIL.LOW,
|
||||||
|
) -> None:
|
||||||
self.with_variable_tmpl = with_variable_tmpl
|
self.with_variable_tmpl = with_variable_tmpl
|
||||||
|
self.image_detail_config = image_detail_config
|
||||||
|
|
||||||
def get_prompt(
|
def get_prompt(
|
||||||
self,
|
self,
|
||||||
|
|
24
api/core/tools/provider/builtin/cogview/tools/cogvideo.py
Normal file
24
api/core/tools/provider/builtin/cogview/tools/cogvideo.py
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
from typing import Any, Union
|
||||||
|
|
||||||
|
from zhipuai import ZhipuAI
|
||||||
|
|
||||||
|
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||||
|
from core.tools.tool.builtin_tool import BuiltinTool
|
||||||
|
|
||||||
|
|
||||||
|
class CogVideoTool(BuiltinTool):
|
||||||
|
def _invoke(
|
||||||
|
self, user_id: str, tool_parameters: dict[str, Any]
|
||||||
|
) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
|
||||||
|
client = ZhipuAI(
|
||||||
|
base_url=self.runtime.credentials["zhipuai_base_url"],
|
||||||
|
api_key=self.runtime.credentials["zhipuai_api_key"],
|
||||||
|
)
|
||||||
|
if not tool_parameters.get("prompt") and not tool_parameters.get("image_url"):
|
||||||
|
return self.create_text_message("require at least one of prompt and image_url")
|
||||||
|
|
||||||
|
response = client.videos.generations(
|
||||||
|
model="cogvideox", prompt=tool_parameters.get("prompt"), image_url=tool_parameters.get("image_url")
|
||||||
|
)
|
||||||
|
|
||||||
|
return self.create_json_message(response.dict())
|
32
api/core/tools/provider/builtin/cogview/tools/cogvideo.yaml
Normal file
32
api/core/tools/provider/builtin/cogview/tools/cogvideo.yaml
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
identity:
|
||||||
|
name: cogvideo
|
||||||
|
author: hjlarry
|
||||||
|
label:
|
||||||
|
en_US: CogVideo
|
||||||
|
zh_Hans: CogVideo 视频生成
|
||||||
|
description:
|
||||||
|
human:
|
||||||
|
en_US: Use the CogVideox model provided by ZhipuAI to generate videos based on user prompts and images.
|
||||||
|
zh_Hans: 使用智谱cogvideox模型,根据用户输入的提示词和图片,生成视频。
|
||||||
|
llm: A tool for generating videos. The input is user's prompt or image url or both of them, the output is a task id. You can use another tool with this task id to check the status and get the video.
|
||||||
|
parameters:
|
||||||
|
- name: prompt
|
||||||
|
type: string
|
||||||
|
label:
|
||||||
|
en_US: prompt
|
||||||
|
zh_Hans: 提示词
|
||||||
|
human_description:
|
||||||
|
en_US: The prompt text used to generate video.
|
||||||
|
zh_Hans: 用于生成视频的提示词。
|
||||||
|
llm_description: The prompt text used to generate video. Optional.
|
||||||
|
form: llm
|
||||||
|
- name: image_url
|
||||||
|
type: string
|
||||||
|
label:
|
||||||
|
en_US: image url
|
||||||
|
zh_Hans: 图片链接
|
||||||
|
human_description:
|
||||||
|
en_US: The image url used to generate video.
|
||||||
|
zh_Hans: 输入一个图片链接,生成的视频将基于该图片和提示词。
|
||||||
|
llm_description: The image url used to generate video. Optional.
|
||||||
|
form: llm
|
|
@ -0,0 +1,30 @@
|
||||||
|
from typing import Any, Union
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
from zhipuai import ZhipuAI
|
||||||
|
|
||||||
|
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||||
|
from core.tools.tool.builtin_tool import BuiltinTool
|
||||||
|
|
||||||
|
|
||||||
|
class CogVideoJobTool(BuiltinTool):
|
||||||
|
def _invoke(
|
||||||
|
self, user_id: str, tool_parameters: dict[str, Any]
|
||||||
|
) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
|
||||||
|
client = ZhipuAI(
|
||||||
|
api_key=self.runtime.credentials["zhipuai_api_key"],
|
||||||
|
base_url=self.runtime.credentials["zhipuai_base_url"],
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.videos.retrieve_videos_result(id=tool_parameters.get("id"))
|
||||||
|
result = [self.create_json_message(response.dict())]
|
||||||
|
if response.task_status == "SUCCESS":
|
||||||
|
for item in response.video_result:
|
||||||
|
video_cover_image = self.create_image_message(item.cover_image_url)
|
||||||
|
result.append(video_cover_image)
|
||||||
|
video = self.create_blob_message(
|
||||||
|
blob=httpx.get(item.url).content, meta={"mime_type": "video/mp4"}, save_as=self.VariableKey.VIDEO
|
||||||
|
)
|
||||||
|
result.append(video)
|
||||||
|
|
||||||
|
return result
|
|
@ -0,0 +1,21 @@
|
||||||
|
identity:
|
||||||
|
name: cogvideo_job
|
||||||
|
author: hjlarry
|
||||||
|
label:
|
||||||
|
en_US: CogVideo Result
|
||||||
|
zh_Hans: CogVideo 结果获取
|
||||||
|
description:
|
||||||
|
human:
|
||||||
|
en_US: Get the result of CogVideo tool generation.
|
||||||
|
zh_Hans: 根据 CogVideo 工具返回的 id 获取视频生成结果。
|
||||||
|
llm: Get the result of CogVideo tool generation. The input is the id which is returned by the CogVideo tool. The output is the url of video and video cover image.
|
||||||
|
parameters:
|
||||||
|
- name: id
|
||||||
|
type: string
|
||||||
|
label:
|
||||||
|
en_US: id
|
||||||
|
human_description:
|
||||||
|
en_US: The id returned by the CogVideo.
|
||||||
|
zh_Hans: CogVideo 工具返回的 id。
|
||||||
|
llm_description: The id returned by the cogvideo.
|
||||||
|
form: llm
|
|
@ -48,7 +48,6 @@ class ComfyUiClient:
|
||||||
prompt = origin_prompt.copy()
|
prompt = origin_prompt.copy()
|
||||||
id_to_class_type = {id: details["class_type"] for id, details in prompt.items()}
|
id_to_class_type = {id: details["class_type"] for id, details in prompt.items()}
|
||||||
k_sampler = [key for key, value in id_to_class_type.items() if value == "KSampler"][0]
|
k_sampler = [key for key, value in id_to_class_type.items() if value == "KSampler"][0]
|
||||||
prompt.get(k_sampler)["inputs"]["seed"] = random.randint(10**14, 10**15 - 1)
|
|
||||||
positive_input_id = prompt.get(k_sampler)["inputs"]["positive"][0]
|
positive_input_id = prompt.get(k_sampler)["inputs"]["positive"][0]
|
||||||
prompt.get(positive_input_id)["inputs"]["text"] = positive_prompt
|
prompt.get(positive_input_id)["inputs"]["text"] = positive_prompt
|
||||||
|
|
||||||
|
@ -72,6 +71,18 @@ class ComfyUiClient:
|
||||||
prompt.get(load_image)["inputs"]["image"] = image_name
|
prompt.get(load_image)["inputs"]["image"] = image_name
|
||||||
return prompt
|
return prompt
|
||||||
|
|
||||||
|
def set_prompt_seed_by_id(self, origin_prompt: dict, seed_id: str) -> dict:
|
||||||
|
prompt = origin_prompt.copy()
|
||||||
|
if seed_id not in prompt:
|
||||||
|
raise Exception("Not a valid seed node")
|
||||||
|
if "seed" in prompt[seed_id]["inputs"]:
|
||||||
|
prompt[seed_id]["inputs"]["seed"] = random.randint(10**14, 10**15 - 1)
|
||||||
|
elif "noise_seed" in prompt[seed_id]["inputs"]:
|
||||||
|
prompt[seed_id]["inputs"]["noise_seed"] = random.randint(10**14, 10**15 - 1)
|
||||||
|
else:
|
||||||
|
raise Exception("Not a valid seed node")
|
||||||
|
return prompt
|
||||||
|
|
||||||
def track_progress(self, prompt: dict, ws: WebSocket, prompt_id: str):
|
def track_progress(self, prompt: dict, ws: WebSocket, prompt_id: str):
|
||||||
node_ids = list(prompt.keys())
|
node_ids = list(prompt.keys())
|
||||||
finished_nodes = []
|
finished_nodes = []
|
||||||
|
|
|
@ -70,6 +70,9 @@ class ComfyUIWorkflowTool(BuiltinTool):
|
||||||
else:
|
else:
|
||||||
prompt = comfyui.set_prompt_images_by_default(prompt, image_names)
|
prompt = comfyui.set_prompt_images_by_default(prompt, image_names)
|
||||||
|
|
||||||
|
if seed_id := tool_parameters.get("seed_id"):
|
||||||
|
prompt = comfyui.set_prompt_seed_by_id(prompt, seed_id)
|
||||||
|
|
||||||
images = comfyui.generate_image_by_prompt(prompt)
|
images = comfyui.generate_image_by_prompt(prompt)
|
||||||
result = []
|
result = []
|
||||||
for img in images:
|
for img in images:
|
||||||
|
|
|
@ -52,3 +52,12 @@ parameters:
|
||||||
en_US: When the workflow has multiple image nodes, enter the ID list of these nodes, and the images will be passed to ComfyUI in the order of the list.
|
en_US: When the workflow has multiple image nodes, enter the ID list of these nodes, and the images will be passed to ComfyUI in the order of the list.
|
||||||
zh_Hans: 当工作流有多个图片节点时,输入这些节点的ID列表,图片将按列表顺序传给ComfyUI
|
zh_Hans: 当工作流有多个图片节点时,输入这些节点的ID列表,图片将按列表顺序传给ComfyUI
|
||||||
form: form
|
form: form
|
||||||
|
- name: seed_id
|
||||||
|
type: string
|
||||||
|
label:
|
||||||
|
en_US: Seed Node Id
|
||||||
|
zh_Hans: 种子节点ID
|
||||||
|
human_description:
|
||||||
|
en_US: If you need to generate different images each time, you need to enter the ID of the seed node.
|
||||||
|
zh_Hans: 如果需要每次生成时使用不同的种子,需要输入包含种子的节点的ID
|
||||||
|
form: form
|
||||||
|
|
|
@ -1,19 +1,23 @@
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from core.file import File
|
from core.file import FileTransferMethod, FileType
|
||||||
from core.file.enums import FileTransferMethod, FileType
|
|
||||||
from core.tools.errors import ToolProviderCredentialValidationError
|
from core.tools.errors import ToolProviderCredentialValidationError
|
||||||
from core.tools.provider.builtin.vectorizer.tools.vectorizer import VectorizerTool
|
from core.tools.provider.builtin.vectorizer.tools.vectorizer import VectorizerTool
|
||||||
from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController
|
from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController
|
||||||
|
from factories import file_factory
|
||||||
|
|
||||||
|
|
||||||
class VectorizerProvider(BuiltinToolProviderController):
|
class VectorizerProvider(BuiltinToolProviderController):
|
||||||
def _validate_credentials(self, credentials: dict[str, Any]) -> None:
|
def _validate_credentials(self, credentials: dict[str, Any]) -> None:
|
||||||
test_img = File(
|
mapping = {
|
||||||
|
"transfer_method": FileTransferMethod.TOOL_FILE,
|
||||||
|
"type": FileType.IMAGE,
|
||||||
|
"id": "test_id",
|
||||||
|
"url": "https://cloud.dify.ai/logo/logo-site.png",
|
||||||
|
}
|
||||||
|
test_img = file_factory.build_from_mapping(
|
||||||
|
mapping=mapping,
|
||||||
tenant_id="__test_123",
|
tenant_id="__test_123",
|
||||||
remote_url="https://cloud.dify.ai/logo/logo-site.png",
|
|
||||||
type=FileType.IMAGE,
|
|
||||||
transfer_method=FileTransferMethod.REMOTE_URL,
|
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
VectorizerTool().fork_tool_runtime(
|
VectorizerTool().fork_tool_runtime(
|
||||||
|
|
|
@ -49,13 +49,7 @@ class CodeNode(BaseNode[CodeNodeData]):
|
||||||
for variable_selector in self.node_data.variables:
|
for variable_selector in self.node_data.variables:
|
||||||
variable_name = variable_selector.variable
|
variable_name = variable_selector.variable
|
||||||
variable = self.graph_runtime_state.variable_pool.get(variable_selector.value_selector)
|
variable = self.graph_runtime_state.variable_pool.get(variable_selector.value_selector)
|
||||||
if variable is None:
|
variables[variable_name] = variable.to_object() if variable else None
|
||||||
return NodeRunResult(
|
|
||||||
status=WorkflowNodeExecutionStatus.FAILED,
|
|
||||||
inputs=variables,
|
|
||||||
error=f"Variable `{variable_selector.value_selector}` not found",
|
|
||||||
)
|
|
||||||
variables[variable_name] = variable.to_object()
|
|
||||||
# Run code
|
# Run code
|
||||||
try:
|
try:
|
||||||
result = CodeExecutor.execute_workflow_code_template(
|
result = CodeExecutor.execute_workflow_code_template(
|
||||||
|
|
|
@ -13,6 +13,7 @@ from core.workflow.nodes.base import BaseNode
|
||||||
from core.workflow.nodes.enums import NodeType
|
from core.workflow.nodes.enums import NodeType
|
||||||
from core.workflow.nodes.http_request.executor import Executor
|
from core.workflow.nodes.http_request.executor import Executor
|
||||||
from core.workflow.utils import variable_template_parser
|
from core.workflow.utils import variable_template_parser
|
||||||
|
from factories import file_factory
|
||||||
from models.workflow import WorkflowNodeExecutionStatus
|
from models.workflow import WorkflowNodeExecutionStatus
|
||||||
|
|
||||||
from .entities import (
|
from .entities import (
|
||||||
|
@ -161,16 +162,15 @@ class HttpRequestNode(BaseNode[HttpRequestNodeData]):
|
||||||
mimetype=content_type,
|
mimetype=content_type,
|
||||||
)
|
)
|
||||||
|
|
||||||
files.append(
|
mapping = {
|
||||||
File(
|
"tool_file_id": tool_file.id,
|
||||||
tenant_id=self.tenant_id,
|
"type": FileType.IMAGE.value,
|
||||||
type=FileType.IMAGE,
|
"transfer_method": FileTransferMethod.TOOL_FILE.value,
|
||||||
transfer_method=FileTransferMethod.TOOL_FILE,
|
}
|
||||||
related_id=tool_file.id,
|
file = file_factory.build_from_mapping(
|
||||||
filename=filename,
|
mapping=mapping,
|
||||||
extension=extension,
|
tenant_id=self.tenant_id,
|
||||||
mime_type=content_type,
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
files.append(file)
|
||||||
|
|
||||||
return files
|
return files
|
||||||
|
|
|
@ -34,12 +34,7 @@ class TemplateTransformNode(BaseNode[TemplateTransformNodeData]):
|
||||||
for variable_selector in self.node_data.variables:
|
for variable_selector in self.node_data.variables:
|
||||||
variable_name = variable_selector.variable
|
variable_name = variable_selector.variable
|
||||||
value = self.graph_runtime_state.variable_pool.get(variable_selector.value_selector)
|
value = self.graph_runtime_state.variable_pool.get(variable_selector.value_selector)
|
||||||
if value is None:
|
variables[variable_name] = value.to_object() if value else None
|
||||||
return NodeRunResult(
|
|
||||||
status=WorkflowNodeExecutionStatus.FAILED,
|
|
||||||
error=f"Variable {variable_name} not found in variable pool",
|
|
||||||
)
|
|
||||||
variables[variable_name] = value.to_object()
|
|
||||||
# Run code
|
# Run code
|
||||||
try:
|
try:
|
||||||
result = CodeExecutor.execute_workflow_code_template(
|
result = CodeExecutor.execute_workflow_code_template(
|
||||||
|
|
|
@ -17,6 +17,7 @@ from core.workflow.nodes.base import BaseNode
|
||||||
from core.workflow.nodes.enums import NodeType
|
from core.workflow.nodes.enums import NodeType
|
||||||
from core.workflow.utils.variable_template_parser import VariableTemplateParser
|
from core.workflow.utils.variable_template_parser import VariableTemplateParser
|
||||||
from extensions.ext_database import db
|
from extensions.ext_database import db
|
||||||
|
from factories import file_factory
|
||||||
from models import ToolFile
|
from models import ToolFile
|
||||||
from models.workflow import WorkflowNodeExecutionStatus
|
from models.workflow import WorkflowNodeExecutionStatus
|
||||||
|
|
||||||
|
@ -189,19 +190,17 @@ class ToolNode(BaseNode[ToolNodeData]):
|
||||||
if tool_file is None:
|
if tool_file is None:
|
||||||
raise ToolFileError(f"Tool file {tool_file_id} does not exist")
|
raise ToolFileError(f"Tool file {tool_file_id} does not exist")
|
||||||
|
|
||||||
result.append(
|
mapping = {
|
||||||
File(
|
"tool_file_id": tool_file_id,
|
||||||
tenant_id=self.tenant_id,
|
"type": FileType.IMAGE,
|
||||||
type=FileType.IMAGE,
|
"transfer_method": transfer_method,
|
||||||
transfer_method=transfer_method,
|
"url": url,
|
||||||
remote_url=url,
|
}
|
||||||
related_id=tool_file.id,
|
file = file_factory.build_from_mapping(
|
||||||
filename=tool_file.name,
|
mapping=mapping,
|
||||||
extension=ext,
|
tenant_id=self.tenant_id,
|
||||||
mime_type=tool_file.mimetype,
|
|
||||||
size=tool_file.size,
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
result.append(file)
|
||||||
elif response.type == ToolInvokeMessage.MessageType.BLOB:
|
elif response.type == ToolInvokeMessage.MessageType.BLOB:
|
||||||
# get tool file id
|
# get tool file id
|
||||||
tool_file_id = str(response.message).split("/")[-1].split(".")[0]
|
tool_file_id = str(response.message).split("/")[-1].split(".")[0]
|
||||||
|
@ -209,19 +208,17 @@ class ToolNode(BaseNode[ToolNodeData]):
|
||||||
stmt = select(ToolFile).where(ToolFile.id == tool_file_id)
|
stmt = select(ToolFile).where(ToolFile.id == tool_file_id)
|
||||||
tool_file = session.scalar(stmt)
|
tool_file = session.scalar(stmt)
|
||||||
if tool_file is None:
|
if tool_file is None:
|
||||||
raise ToolFileError(f"Tool file {tool_file_id} does not exist")
|
raise ValueError(f"tool file {tool_file_id} not exists")
|
||||||
result.append(
|
mapping = {
|
||||||
File(
|
"tool_file_id": tool_file_id,
|
||||||
tenant_id=self.tenant_id,
|
"type": FileType.IMAGE,
|
||||||
type=FileType.IMAGE,
|
"transfer_method": FileTransferMethod.TOOL_FILE,
|
||||||
transfer_method=FileTransferMethod.TOOL_FILE,
|
}
|
||||||
related_id=tool_file.id,
|
file = file_factory.build_from_mapping(
|
||||||
filename=tool_file.name,
|
mapping=mapping,
|
||||||
extension=path.splitext(response.save_as)[1],
|
tenant_id=self.tenant_id,
|
||||||
mime_type=tool_file.mimetype,
|
|
||||||
size=tool_file.size,
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
result.append(file)
|
||||||
elif response.type == ToolInvokeMessage.MessageType.LINK:
|
elif response.type == ToolInvokeMessage.MessageType.LINK:
|
||||||
url = str(response.message)
|
url = str(response.message)
|
||||||
transfer_method = FileTransferMethod.TOOL_FILE
|
transfer_method = FileTransferMethod.TOOL_FILE
|
||||||
|
@ -235,16 +232,15 @@ class ToolNode(BaseNode[ToolNodeData]):
|
||||||
extension = "." + url.split("/")[-1].split(".")[1]
|
extension = "." + url.split("/")[-1].split(".")[1]
|
||||||
else:
|
else:
|
||||||
extension = ".bin"
|
extension = ".bin"
|
||||||
file = File(
|
mapping = {
|
||||||
|
"tool_file_id": tool_file_id,
|
||||||
|
"type": FileType.IMAGE,
|
||||||
|
"transfer_method": transfer_method,
|
||||||
|
"url": url,
|
||||||
|
}
|
||||||
|
file = file_factory.build_from_mapping(
|
||||||
|
mapping=mapping,
|
||||||
tenant_id=self.tenant_id,
|
tenant_id=self.tenant_id,
|
||||||
type=FileType(response.save_as),
|
|
||||||
transfer_method=transfer_method,
|
|
||||||
remote_url=url,
|
|
||||||
filename=tool_file.name,
|
|
||||||
related_id=tool_file.id,
|
|
||||||
extension=extension,
|
|
||||||
mime_type=tool_file.mimetype,
|
|
||||||
size=tool_file.size,
|
|
||||||
)
|
)
|
||||||
result.append(file)
|
result.append(file)
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,10 @@ from collections.abc import Generator, Mapping, Sequence
|
||||||
from typing import Any, Optional, cast
|
from typing import Any, Optional, cast
|
||||||
|
|
||||||
from configs import dify_config
|
from configs import dify_config
|
||||||
from core.app.app_config.entities import FileExtraConfig
|
from core.app.app_config.entities import FileUploadConfig
|
||||||
from core.app.apps.base_app_queue_manager import GenerateTaskStoppedError
|
from core.app.apps.base_app_queue_manager import GenerateTaskStoppedError
|
||||||
from core.app.entities.app_invoke_entities import InvokeFrom
|
from core.app.entities.app_invoke_entities import InvokeFrom
|
||||||
from core.file.models import File, FileTransferMethod, FileType, ImageConfig
|
from core.file.models import File, FileTransferMethod, ImageConfig
|
||||||
from core.workflow.callbacks import WorkflowCallback
|
from core.workflow.callbacks import WorkflowCallback
|
||||||
from core.workflow.entities.variable_pool import VariablePool
|
from core.workflow.entities.variable_pool import VariablePool
|
||||||
from core.workflow.errors import WorkflowNodeRunFailedError
|
from core.workflow.errors import WorkflowNodeRunFailedError
|
||||||
|
@ -22,6 +22,7 @@ from core.workflow.nodes.base import BaseNode, BaseNodeData
|
||||||
from core.workflow.nodes.event import NodeEvent
|
from core.workflow.nodes.event import NodeEvent
|
||||||
from core.workflow.nodes.llm import LLMNodeData
|
from core.workflow.nodes.llm import LLMNodeData
|
||||||
from core.workflow.nodes.node_mapping import node_type_classes_mapping
|
from core.workflow.nodes.node_mapping import node_type_classes_mapping
|
||||||
|
from factories import file_factory
|
||||||
from models.enums import UserFrom
|
from models.enums import UserFrom
|
||||||
from models.workflow import (
|
from models.workflow import (
|
||||||
Workflow,
|
Workflow,
|
||||||
|
@ -271,19 +272,17 @@ class WorkflowEntry:
|
||||||
for item in input_value:
|
for item in input_value:
|
||||||
if isinstance(item, dict) and "type" in item and item["type"] == "image":
|
if isinstance(item, dict) and "type" in item and item["type"] == "image":
|
||||||
transfer_method = FileTransferMethod.value_of(item.get("transfer_method"))
|
transfer_method = FileTransferMethod.value_of(item.get("transfer_method"))
|
||||||
file = File(
|
mapping = {
|
||||||
|
"id": item.get("id"),
|
||||||
|
"transfer_method": transfer_method,
|
||||||
|
"upload_file_id": item.get("upload_file_id"),
|
||||||
|
"url": item.get("url"),
|
||||||
|
}
|
||||||
|
config = FileUploadConfig(image_config=ImageConfig(detail=detail) if detail else None)
|
||||||
|
file = file_factory.build_from_mapping(
|
||||||
|
mapping=mapping,
|
||||||
tenant_id=tenant_id,
|
tenant_id=tenant_id,
|
||||||
type=FileType.IMAGE,
|
config=config,
|
||||||
transfer_method=transfer_method,
|
|
||||||
remote_url=item.get("url")
|
|
||||||
if transfer_method == FileTransferMethod.REMOTE_URL
|
|
||||||
else None,
|
|
||||||
related_id=item.get("upload_file_id")
|
|
||||||
if transfer_method == FileTransferMethod.LOCAL_FILE
|
|
||||||
else None,
|
|
||||||
_extra_config=FileExtraConfig(
|
|
||||||
image_config=ImageConfig(detail=detail) if detail else None
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
new_value.append(file)
|
new_value.append(file)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
|
import pytz
|
||||||
from celery import Celery, Task
|
from celery import Celery, Task
|
||||||
from celery.schedules import crontab
|
from celery.schedules import crontab
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
|
@ -43,6 +44,11 @@ def init_app(app: Flask) -> Celery:
|
||||||
result_backend=dify_config.CELERY_RESULT_BACKEND,
|
result_backend=dify_config.CELERY_RESULT_BACKEND,
|
||||||
broker_transport_options=broker_transport_options,
|
broker_transport_options=broker_transport_options,
|
||||||
broker_connection_retry_on_startup=True,
|
broker_connection_retry_on_startup=True,
|
||||||
|
worker_log_format=dify_config.LOG_FORMAT,
|
||||||
|
worker_task_log_format=dify_config.LOG_FORMAT,
|
||||||
|
worker_logfile=dify_config.LOG_FILE,
|
||||||
|
worker_hijack_root_logger=False,
|
||||||
|
timezone=pytz.timezone(dify_config.LOG_TZ),
|
||||||
)
|
)
|
||||||
|
|
||||||
if dify_config.BROKER_USE_SSL:
|
if dify_config.BROKER_USE_SSL:
|
||||||
|
|
|
@ -1,23 +1,21 @@
|
||||||
import mimetypes
|
import mimetypes
|
||||||
from collections.abc import Mapping, Sequence
|
from collections.abc import Callable, Mapping, Sequence
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
from sqlalchemy import select
|
from sqlalchemy import select
|
||||||
|
|
||||||
from constants import AUDIO_EXTENSIONS, DOCUMENT_EXTENSIONS, IMAGE_EXTENSIONS, VIDEO_EXTENSIONS
|
from core.file import File, FileBelongsTo, FileTransferMethod, FileType, FileUploadConfig
|
||||||
from core.file import File, FileBelongsTo, FileExtraConfig, FileTransferMethod, FileType
|
|
||||||
from core.helper import ssrf_proxy
|
from core.helper import ssrf_proxy
|
||||||
from extensions.ext_database import db
|
from extensions.ext_database import db
|
||||||
from models import MessageFile, ToolFile, UploadFile
|
from models import MessageFile, ToolFile, UploadFile
|
||||||
from models.enums import CreatedByRole
|
|
||||||
|
|
||||||
|
|
||||||
def build_from_message_files(
|
def build_from_message_files(
|
||||||
*,
|
*,
|
||||||
message_files: Sequence["MessageFile"],
|
message_files: Sequence["MessageFile"],
|
||||||
tenant_id: str,
|
tenant_id: str,
|
||||||
config: FileExtraConfig,
|
config: FileUploadConfig,
|
||||||
) -> Sequence[File]:
|
) -> Sequence[File]:
|
||||||
results = [
|
results = [
|
||||||
build_from_message_file(message_file=file, tenant_id=tenant_id, config=config)
|
build_from_message_file(message_file=file, tenant_id=tenant_id, config=config)
|
||||||
|
@ -31,7 +29,7 @@ def build_from_message_file(
|
||||||
*,
|
*,
|
||||||
message_file: "MessageFile",
|
message_file: "MessageFile",
|
||||||
tenant_id: str,
|
tenant_id: str,
|
||||||
config: FileExtraConfig,
|
config: FileUploadConfig,
|
||||||
):
|
):
|
||||||
mapping = {
|
mapping = {
|
||||||
"transfer_method": message_file.transfer_method,
|
"transfer_method": message_file.transfer_method,
|
||||||
|
@ -43,8 +41,6 @@ def build_from_message_file(
|
||||||
return build_from_mapping(
|
return build_from_mapping(
|
||||||
mapping=mapping,
|
mapping=mapping,
|
||||||
tenant_id=tenant_id,
|
tenant_id=tenant_id,
|
||||||
user_id=message_file.created_by,
|
|
||||||
role=CreatedByRole(message_file.created_by_role),
|
|
||||||
config=config,
|
config=config,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -53,38 +49,30 @@ def build_from_mapping(
|
||||||
*,
|
*,
|
||||||
mapping: Mapping[str, Any],
|
mapping: Mapping[str, Any],
|
||||||
tenant_id: str,
|
tenant_id: str,
|
||||||
user_id: str,
|
config: FileUploadConfig | None = None,
|
||||||
role: "CreatedByRole",
|
) -> File:
|
||||||
config: FileExtraConfig,
|
config = config or FileUploadConfig()
|
||||||
):
|
|
||||||
transfer_method = FileTransferMethod.value_of(mapping.get("transfer_method"))
|
transfer_method = FileTransferMethod.value_of(mapping.get("transfer_method"))
|
||||||
match transfer_method:
|
|
||||||
case FileTransferMethod.REMOTE_URL:
|
build_functions: dict[FileTransferMethod, Callable] = {
|
||||||
file = _build_from_remote_url(
|
FileTransferMethod.LOCAL_FILE: _build_from_local_file,
|
||||||
mapping=mapping,
|
FileTransferMethod.REMOTE_URL: _build_from_remote_url,
|
||||||
tenant_id=tenant_id,
|
FileTransferMethod.TOOL_FILE: _build_from_tool_file,
|
||||||
config=config,
|
}
|
||||||
transfer_method=transfer_method,
|
|
||||||
)
|
build_func = build_functions.get(transfer_method)
|
||||||
case FileTransferMethod.LOCAL_FILE:
|
if not build_func:
|
||||||
file = _build_from_local_file(
|
raise ValueError(f"Invalid file transfer method: {transfer_method}")
|
||||||
mapping=mapping,
|
|
||||||
tenant_id=tenant_id,
|
file = build_func(
|
||||||
user_id=user_id,
|
mapping=mapping,
|
||||||
role=role,
|
tenant_id=tenant_id,
|
||||||
config=config,
|
transfer_method=transfer_method,
|
||||||
transfer_method=transfer_method,
|
)
|
||||||
)
|
|
||||||
case FileTransferMethod.TOOL_FILE:
|
if not _is_file_valid_with_config(file=file, config=config):
|
||||||
file = _build_from_tool_file(
|
raise ValueError(f"File validation failed for file: {file.filename}")
|
||||||
mapping=mapping,
|
|
||||||
tenant_id=tenant_id,
|
|
||||||
user_id=user_id,
|
|
||||||
config=config,
|
|
||||||
transfer_method=transfer_method,
|
|
||||||
)
|
|
||||||
case _:
|
|
||||||
raise ValueError(f"Invalid file transfer method: {transfer_method}")
|
|
||||||
|
|
||||||
return file
|
return file
|
||||||
|
|
||||||
|
@ -92,10 +80,8 @@ def build_from_mapping(
|
||||||
def build_from_mappings(
|
def build_from_mappings(
|
||||||
*,
|
*,
|
||||||
mappings: Sequence[Mapping[str, Any]],
|
mappings: Sequence[Mapping[str, Any]],
|
||||||
config: FileExtraConfig | None,
|
config: FileUploadConfig | None,
|
||||||
tenant_id: str,
|
tenant_id: str,
|
||||||
user_id: str,
|
|
||||||
role: "CreatedByRole",
|
|
||||||
) -> Sequence[File]:
|
) -> Sequence[File]:
|
||||||
if not config:
|
if not config:
|
||||||
return []
|
return []
|
||||||
|
@ -104,8 +90,6 @@ def build_from_mappings(
|
||||||
build_from_mapping(
|
build_from_mapping(
|
||||||
mapping=mapping,
|
mapping=mapping,
|
||||||
tenant_id=tenant_id,
|
tenant_id=tenant_id,
|
||||||
user_id=user_id,
|
|
||||||
role=role,
|
|
||||||
config=config,
|
config=config,
|
||||||
)
|
)
|
||||||
for mapping in mappings
|
for mapping in mappings
|
||||||
|
@ -128,31 +112,20 @@ def _build_from_local_file(
|
||||||
*,
|
*,
|
||||||
mapping: Mapping[str, Any],
|
mapping: Mapping[str, Any],
|
||||||
tenant_id: str,
|
tenant_id: str,
|
||||||
user_id: str,
|
|
||||||
role: "CreatedByRole",
|
|
||||||
config: FileExtraConfig,
|
|
||||||
transfer_method: FileTransferMethod,
|
transfer_method: FileTransferMethod,
|
||||||
):
|
) -> File:
|
||||||
# check if the upload file exists.
|
|
||||||
file_type = FileType.value_of(mapping.get("type"))
|
file_type = FileType.value_of(mapping.get("type"))
|
||||||
stmt = select(UploadFile).where(
|
stmt = select(UploadFile).where(
|
||||||
UploadFile.id == mapping.get("upload_file_id"),
|
UploadFile.id == mapping.get("upload_file_id"),
|
||||||
UploadFile.tenant_id == tenant_id,
|
UploadFile.tenant_id == tenant_id,
|
||||||
UploadFile.created_by == user_id,
|
|
||||||
UploadFile.created_by_role == role,
|
|
||||||
)
|
)
|
||||||
if file_type == FileType.IMAGE:
|
|
||||||
stmt = stmt.where(UploadFile.extension.in_(IMAGE_EXTENSIONS))
|
|
||||||
elif file_type == FileType.VIDEO:
|
|
||||||
stmt = stmt.where(UploadFile.extension.in_(VIDEO_EXTENSIONS))
|
|
||||||
elif file_type == FileType.AUDIO:
|
|
||||||
stmt = stmt.where(UploadFile.extension.in_(AUDIO_EXTENSIONS))
|
|
||||||
elif file_type == FileType.DOCUMENT:
|
|
||||||
stmt = stmt.where(UploadFile.extension.in_(DOCUMENT_EXTENSIONS))
|
|
||||||
row = db.session.scalar(stmt)
|
row = db.session.scalar(stmt)
|
||||||
|
|
||||||
if row is None:
|
if row is None:
|
||||||
raise ValueError("Invalid upload file")
|
raise ValueError("Invalid upload file")
|
||||||
file = File(
|
|
||||||
|
return File(
|
||||||
id=mapping.get("id"),
|
id=mapping.get("id"),
|
||||||
filename=row.name,
|
filename=row.name,
|
||||||
extension="." + row.extension,
|
extension="." + row.extension,
|
||||||
|
@ -162,23 +135,37 @@ def _build_from_local_file(
|
||||||
transfer_method=transfer_method,
|
transfer_method=transfer_method,
|
||||||
remote_url=row.source_url,
|
remote_url=row.source_url,
|
||||||
related_id=mapping.get("upload_file_id"),
|
related_id=mapping.get("upload_file_id"),
|
||||||
_extra_config=config,
|
|
||||||
size=row.size,
|
size=row.size,
|
||||||
)
|
)
|
||||||
return file
|
|
||||||
|
|
||||||
|
|
||||||
def _build_from_remote_url(
|
def _build_from_remote_url(
|
||||||
*,
|
*,
|
||||||
mapping: Mapping[str, Any],
|
mapping: Mapping[str, Any],
|
||||||
tenant_id: str,
|
tenant_id: str,
|
||||||
config: FileExtraConfig,
|
|
||||||
transfer_method: FileTransferMethod,
|
transfer_method: FileTransferMethod,
|
||||||
):
|
) -> File:
|
||||||
url = mapping.get("url")
|
url = mapping.get("url")
|
||||||
if not url:
|
if not url:
|
||||||
raise ValueError("Invalid file url")
|
raise ValueError("Invalid file url")
|
||||||
|
|
||||||
|
mime_type, filename, file_size = _get_remote_file_info(url)
|
||||||
|
extension = mimetypes.guess_extension(mime_type) or "." + filename.split(".")[-1] if "." in filename else ".bin"
|
||||||
|
|
||||||
|
return File(
|
||||||
|
id=mapping.get("id"),
|
||||||
|
filename=filename,
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
type=FileType.value_of(mapping.get("type")),
|
||||||
|
transfer_method=transfer_method,
|
||||||
|
remote_url=url,
|
||||||
|
mime_type=mime_type,
|
||||||
|
extension=extension,
|
||||||
|
size=file_size,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_remote_file_info(url: str):
|
||||||
mime_type = mimetypes.guess_type(url)[0] or ""
|
mime_type = mimetypes.guess_type(url)[0] or ""
|
||||||
file_size = -1
|
file_size = -1
|
||||||
filename = url.split("/")[-1].split("?")[0] or "unknown_file"
|
filename = url.split("/")[-1].split("?")[0] or "unknown_file"
|
||||||
|
@ -186,56 +173,34 @@ def _build_from_remote_url(
|
||||||
resp = ssrf_proxy.head(url, follow_redirects=True)
|
resp = ssrf_proxy.head(url, follow_redirects=True)
|
||||||
if resp.status_code == httpx.codes.OK:
|
if resp.status_code == httpx.codes.OK:
|
||||||
if content_disposition := resp.headers.get("Content-Disposition"):
|
if content_disposition := resp.headers.get("Content-Disposition"):
|
||||||
filename = content_disposition.split("filename=")[-1].strip('"')
|
filename = str(content_disposition.split("filename=")[-1].strip('"'))
|
||||||
file_size = int(resp.headers.get("Content-Length", file_size))
|
file_size = int(resp.headers.get("Content-Length", file_size))
|
||||||
mime_type = mime_type or str(resp.headers.get("Content-Type", ""))
|
mime_type = mime_type or str(resp.headers.get("Content-Type", ""))
|
||||||
|
|
||||||
# Determine file extension
|
return mime_type, filename, file_size
|
||||||
extension = mimetypes.guess_extension(mime_type) or "." + filename.split(".")[-1] if "." in filename else ".bin"
|
|
||||||
|
|
||||||
if not mime_type:
|
|
||||||
mime_type, _ = mimetypes.guess_type(url)
|
|
||||||
file = File(
|
|
||||||
id=mapping.get("id"),
|
|
||||||
filename=filename,
|
|
||||||
tenant_id=tenant_id,
|
|
||||||
type=FileType.value_of(mapping.get("type")),
|
|
||||||
transfer_method=transfer_method,
|
|
||||||
remote_url=url,
|
|
||||||
_extra_config=config,
|
|
||||||
mime_type=mime_type,
|
|
||||||
extension=extension,
|
|
||||||
size=file_size,
|
|
||||||
)
|
|
||||||
return file
|
|
||||||
|
|
||||||
|
|
||||||
def _build_from_tool_file(
|
def _build_from_tool_file(
|
||||||
*,
|
*,
|
||||||
mapping: Mapping[str, Any],
|
mapping: Mapping[str, Any],
|
||||||
tenant_id: str,
|
tenant_id: str,
|
||||||
user_id: str,
|
|
||||||
config: FileExtraConfig,
|
|
||||||
transfer_method: FileTransferMethod,
|
transfer_method: FileTransferMethod,
|
||||||
):
|
) -> File:
|
||||||
tool_file = (
|
tool_file = (
|
||||||
db.session.query(ToolFile)
|
db.session.query(ToolFile)
|
||||||
.filter(
|
.filter(
|
||||||
ToolFile.id == mapping.get("tool_file_id"),
|
ToolFile.id == mapping.get("tool_file_id"),
|
||||||
ToolFile.tenant_id == tenant_id,
|
ToolFile.tenant_id == tenant_id,
|
||||||
ToolFile.user_id == user_id,
|
|
||||||
)
|
)
|
||||||
.first()
|
.first()
|
||||||
)
|
)
|
||||||
|
|
||||||
if tool_file is None:
|
if tool_file is None:
|
||||||
raise ValueError(f"ToolFile {mapping.get('tool_file_id')} not found")
|
raise ValueError(f"ToolFile {mapping.get('tool_file_id')} not found")
|
||||||
|
|
||||||
path = tool_file.file_key
|
extension = "." + tool_file.file_key.split(".")[-1] if "." in tool_file.file_key else ".bin"
|
||||||
if "." in path:
|
|
||||||
extension = "." + path.split("/")[-1].split(".")[-1]
|
return File(
|
||||||
else:
|
|
||||||
extension = ".bin"
|
|
||||||
file = File(
|
|
||||||
id=mapping.get("id"),
|
id=mapping.get("id"),
|
||||||
tenant_id=tenant_id,
|
tenant_id=tenant_id,
|
||||||
filename=tool_file.name,
|
filename=tool_file.name,
|
||||||
|
@ -246,6 +211,21 @@ def _build_from_tool_file(
|
||||||
extension=extension,
|
extension=extension,
|
||||||
mime_type=tool_file.mimetype,
|
mime_type=tool_file.mimetype,
|
||||||
size=tool_file.size,
|
size=tool_file.size,
|
||||||
_extra_config=config,
|
|
||||||
)
|
)
|
||||||
return file
|
|
||||||
|
|
||||||
|
def _is_file_valid_with_config(*, file: File, config: FileUploadConfig) -> bool:
|
||||||
|
if config.allowed_file_types and file.type not in config.allowed_file_types and file.type != FileType.CUSTOM:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if config.allowed_extensions and file.extension not in config.allowed_extensions:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if config.allowed_upload_methods and file.transfer_method not in config.allowed_upload_methods:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if file.type == FileType.IMAGE and config.image_config:
|
||||||
|
if config.image_config.transfer_methods and file.transfer_method not in config.image_config.transfer_methods:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
|
@ -23,7 +23,7 @@ v0_9_0_release_date= '2024-09-29 12:00:00'
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
sql = f"""UPDATE
|
sql = f"""UPDATE
|
||||||
public.messages
|
messages
|
||||||
SET
|
SET
|
||||||
parent_message_id = '{UUID_NIL}'
|
parent_message_id = '{UUID_NIL}'
|
||||||
WHERE
|
WHERE
|
||||||
|
@ -37,7 +37,7 @@ WHERE
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
sql = f"""UPDATE
|
sql = f"""UPDATE
|
||||||
public.messages
|
messages
|
||||||
SET
|
SET
|
||||||
parent_message_id = NULL
|
parent_message_id = NULL
|
||||||
WHERE
|
WHERE
|
||||||
|
|
|
@ -13,7 +13,7 @@ from sqlalchemy import Float, func, text
|
||||||
from sqlalchemy.orm import Mapped, mapped_column
|
from sqlalchemy.orm import Mapped, mapped_column
|
||||||
|
|
||||||
from configs import dify_config
|
from configs import dify_config
|
||||||
from core.file import FILE_MODEL_IDENTITY, File, FileExtraConfig, FileTransferMethod, FileType
|
from core.file import FILE_MODEL_IDENTITY, File, FileTransferMethod, FileType
|
||||||
from core.file import helpers as file_helpers
|
from core.file import helpers as file_helpers
|
||||||
from core.file.tool_file_parser import ToolFileParser
|
from core.file.tool_file_parser import ToolFileParser
|
||||||
from extensions.ext_database import db
|
from extensions.ext_database import db
|
||||||
|
@ -949,9 +949,6 @@ class Message(db.Model):
|
||||||
"type": message_file.type,
|
"type": message_file.type,
|
||||||
},
|
},
|
||||||
tenant_id=current_app.tenant_id,
|
tenant_id=current_app.tenant_id,
|
||||||
user_id=self.from_account_id or self.from_end_user_id or "",
|
|
||||||
role=CreatedByRole(message_file.created_by_role),
|
|
||||||
config=FileExtraConfig(),
|
|
||||||
)
|
)
|
||||||
elif message_file.transfer_method == "remote_url":
|
elif message_file.transfer_method == "remote_url":
|
||||||
if message_file.url is None:
|
if message_file.url is None:
|
||||||
|
@ -964,9 +961,6 @@ class Message(db.Model):
|
||||||
"url": message_file.url,
|
"url": message_file.url,
|
||||||
},
|
},
|
||||||
tenant_id=current_app.tenant_id,
|
tenant_id=current_app.tenant_id,
|
||||||
user_id=self.from_account_id or self.from_end_user_id or "",
|
|
||||||
role=CreatedByRole(message_file.created_by_role),
|
|
||||||
config=FileExtraConfig(),
|
|
||||||
)
|
)
|
||||||
elif message_file.transfer_method == "tool_file":
|
elif message_file.transfer_method == "tool_file":
|
||||||
if message_file.upload_file_id is None:
|
if message_file.upload_file_id is None:
|
||||||
|
@ -981,9 +975,6 @@ class Message(db.Model):
|
||||||
file = file_factory.build_from_mapping(
|
file = file_factory.build_from_mapping(
|
||||||
mapping=mapping,
|
mapping=mapping,
|
||||||
tenant_id=current_app.tenant_id,
|
tenant_id=current_app.tenant_id,
|
||||||
user_id=self.from_account_id or self.from_end_user_id or "",
|
|
||||||
role=CreatedByRole(message_file.created_by_role),
|
|
||||||
config=FileExtraConfig(),
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
|
|
550
api/poetry.lock
generated
550
api/poetry.lock
generated
|
@ -125,13 +125,13 @@ speedups = ["Brotli", "aiodns (>=3.2.0)", "brotlicffi"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aiohttp-retry"
|
name = "aiohttp-retry"
|
||||||
version = "2.8.3"
|
version = "2.9.0"
|
||||||
description = "Simple retry client for aiohttp"
|
description = "Simple retry client for aiohttp"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
files = [
|
files = [
|
||||||
{file = "aiohttp_retry-2.8.3-py3-none-any.whl", hash = "sha256:3aeeead8f6afe48272db93ced9440cf4eda8b6fd7ee2abb25357b7eb28525b45"},
|
{file = "aiohttp_retry-2.9.0-py3-none-any.whl", hash = "sha256:7661af92471e9a96c69d9b8f32021360272073397e6a15bc44c1726b12f46056"},
|
||||||
{file = "aiohttp_retry-2.8.3.tar.gz", hash = "sha256:9a8e637e31682ad36e1ff9f8bcba912fcfc7d7041722bc901a4b948da4d71ea9"},
|
{file = "aiohttp_retry-2.9.0.tar.gz", hash = "sha256:92c47f1580040208bac95d9a8389a87227ef22758530f2e3f4683395e42c41b5"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -172,12 +172,12 @@ tz = ["backports.zoneinfo"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "alibabacloud-credentials"
|
name = "alibabacloud-credentials"
|
||||||
version = "0.3.5"
|
version = "0.3.6"
|
||||||
description = "The alibabacloud credentials module of alibabaCloud Python SDK."
|
description = "The alibabacloud credentials module of alibabaCloud Python SDK."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6"
|
||||||
files = [
|
files = [
|
||||||
{file = "alibabacloud_credentials-0.3.5.tar.gz", hash = "sha256:ad065ec95921eaf51939195485d0e5cc9e0ea050282059c7d8bf74bdb5496177"},
|
{file = "alibabacloud_credentials-0.3.6.tar.gz", hash = "sha256:caa82cf258648dcbe1ca14aeba50ba21845567d6ac3cd48d318e0a445fff7f96"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -847,13 +847,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "botocore"
|
name = "botocore"
|
||||||
version = "1.35.47"
|
version = "1.35.52"
|
||||||
description = "Low-level, data-driven core of boto 3."
|
description = "Low-level, data-driven core of boto 3."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "botocore-1.35.47-py3-none-any.whl", hash = "sha256:05f4493119a96799ff84d43e78691efac3177e1aec8840cca99511de940e342a"},
|
{file = "botocore-1.35.52-py3-none-any.whl", hash = "sha256:cdbb5e43c9c3a977763e2a10d3b8b9c405d51279f9fcfd4ca4800763b22acba5"},
|
||||||
{file = "botocore-1.35.47.tar.gz", hash = "sha256:f8f703463d3cd8b6abe2bedc443a7ab29f0e2ff1588a2e83164b108748645547"},
|
{file = "botocore-1.35.52.tar.gz", hash = "sha256:1fe7485ea13d638b089103addd818c12984ff1e4d208de15f180b1e25ad944c5"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -1098,13 +1098,13 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "celery"
|
name = "celery"
|
||||||
version = "5.3.6"
|
version = "5.4.0"
|
||||||
description = "Distributed Task Queue."
|
description = "Distributed Task Queue."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "celery-5.3.6-py3-none-any.whl", hash = "sha256:9da4ea0118d232ce97dff5ed4974587fb1c0ff5c10042eb15278487cdd27d1af"},
|
{file = "celery-5.4.0-py3-none-any.whl", hash = "sha256:369631eb580cf8c51a82721ec538684994f8277637edde2dfc0dacd73ed97f64"},
|
||||||
{file = "celery-5.3.6.tar.gz", hash = "sha256:870cc71d737c0200c397290d730344cc991d13a057534353d124c9380267aab9"},
|
{file = "celery-5.4.0.tar.gz", hash = "sha256:504a19140e8d3029d5acad88330c541d4c3f64c789d85f94756762d8bca7e706"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -1120,7 +1120,7 @@ vine = ">=5.1.0,<6.0"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
arangodb = ["pyArango (>=2.0.2)"]
|
arangodb = ["pyArango (>=2.0.2)"]
|
||||||
auth = ["cryptography (==41.0.5)"]
|
auth = ["cryptography (==42.0.5)"]
|
||||||
azureblockblob = ["azure-storage-blob (>=12.15.0)"]
|
azureblockblob = ["azure-storage-blob (>=12.15.0)"]
|
||||||
brotli = ["brotli (>=1.0.0)", "brotlipy (>=0.7.0)"]
|
brotli = ["brotli (>=1.0.0)", "brotlipy (>=0.7.0)"]
|
||||||
cassandra = ["cassandra-driver (>=3.25.0,<4)"]
|
cassandra = ["cassandra-driver (>=3.25.0,<4)"]
|
||||||
|
@ -1130,22 +1130,23 @@ couchbase = ["couchbase (>=3.0.0)"]
|
||||||
couchdb = ["pycouchdb (==1.14.2)"]
|
couchdb = ["pycouchdb (==1.14.2)"]
|
||||||
django = ["Django (>=2.2.28)"]
|
django = ["Django (>=2.2.28)"]
|
||||||
dynamodb = ["boto3 (>=1.26.143)"]
|
dynamodb = ["boto3 (>=1.26.143)"]
|
||||||
elasticsearch = ["elastic-transport (<=8.10.0)", "elasticsearch (<=8.11.0)"]
|
elasticsearch = ["elastic-transport (<=8.13.0)", "elasticsearch (<=8.13.0)"]
|
||||||
eventlet = ["eventlet (>=0.32.0)"]
|
eventlet = ["eventlet (>=0.32.0)"]
|
||||||
|
gcs = ["google-cloud-storage (>=2.10.0)"]
|
||||||
gevent = ["gevent (>=1.5.0)"]
|
gevent = ["gevent (>=1.5.0)"]
|
||||||
librabbitmq = ["librabbitmq (>=2.0.0)"]
|
librabbitmq = ["librabbitmq (>=2.0.0)"]
|
||||||
memcache = ["pylibmc (==1.6.3)"]
|
memcache = ["pylibmc (==1.6.3)"]
|
||||||
mongodb = ["pymongo[srv] (>=4.0.2)"]
|
mongodb = ["pymongo[srv] (>=4.0.2)"]
|
||||||
msgpack = ["msgpack (==1.0.7)"]
|
msgpack = ["msgpack (==1.0.8)"]
|
||||||
pymemcache = ["python-memcached (==1.59)"]
|
pymemcache = ["python-memcached (>=1.61)"]
|
||||||
pyro = ["pyro4 (==4.82)"]
|
pyro = ["pyro4 (==4.82)"]
|
||||||
pytest = ["pytest-celery (==0.0.0)"]
|
pytest = ["pytest-celery[all] (>=1.0.0)"]
|
||||||
redis = ["redis (>=4.5.2,!=4.5.5,<6.0.0)"]
|
redis = ["redis (>=4.5.2,!=4.5.5,<6.0.0)"]
|
||||||
s3 = ["boto3 (>=1.26.143)"]
|
s3 = ["boto3 (>=1.26.143)"]
|
||||||
slmq = ["softlayer-messaging (>=1.0.3)"]
|
slmq = ["softlayer-messaging (>=1.0.3)"]
|
||||||
solar = ["ephem (==4.1.5)"]
|
solar = ["ephem (==4.1.5)"]
|
||||||
sqlalchemy = ["sqlalchemy (>=1.4.48,<2.1)"]
|
sqlalchemy = ["sqlalchemy (>=1.4.48,<2.1)"]
|
||||||
sqs = ["boto3 (>=1.26.143)", "kombu[sqs] (>=5.3.0)", "pycurl (>=7.43.0.5)", "urllib3 (>=1.26.16)"]
|
sqs = ["boto3 (>=1.26.143)", "kombu[sqs] (>=5.3.4)", "pycurl (>=7.43.0.5)", "urllib3 (>=1.26.16)"]
|
||||||
tblib = ["tblib (>=1.3.0)", "tblib (>=1.5.0)"]
|
tblib = ["tblib (>=1.3.0)", "tblib (>=1.5.0)"]
|
||||||
yaml = ["PyYAML (>=3.10)"]
|
yaml = ["PyYAML (>=3.10)"]
|
||||||
zookeeper = ["kazoo (>=1.3.1)"]
|
zookeeper = ["kazoo (>=1.3.1)"]
|
||||||
|
@ -2257,18 +2258,18 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "duckduckgo-search"
|
name = "duckduckgo-search"
|
||||||
version = "6.3.2"
|
version = "6.3.3"
|
||||||
description = "Search for words, documents, images, news, maps and text translation using the DuckDuckGo.com search engine."
|
description = "Search for words, documents, images, news, maps and text translation using the DuckDuckGo.com search engine."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "duckduckgo_search-6.3.2-py3-none-any.whl", hash = "sha256:cd631275292460d590d1d496995d002bf2fe6db9752713fab17b9e95924ced98"},
|
{file = "duckduckgo_search-6.3.3-py3-none-any.whl", hash = "sha256:63e5d6b958bd532016bc8a53e8b18717751bf7ef51b1c83e59b9f5780c79e64c"},
|
||||||
{file = "duckduckgo_search-6.3.2.tar.gz", hash = "sha256:53dbf45f8749bfc67483eb9f281f2e722a5fe644d61c54ed9e551d26cb6bcbf2"},
|
{file = "duckduckgo_search-6.3.3.tar.gz", hash = "sha256:4d49508f01f85c8675765fdd4cc25eedbb3450e129b35209897fded874f6568f"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
click = ">=8.1.7"
|
click = ">=8.1.7"
|
||||||
primp = ">=0.6.4"
|
primp = ">=0.6.5"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
dev = ["mypy (>=1.11.1)", "pytest (>=8.3.1)", "pytest-asyncio (>=0.23.8)", "ruff (>=0.6.1)"]
|
dev = ["mypy (>=1.11.1)", "pytest (>=8.3.1)", "pytest-asyncio (>=0.23.8)", "ruff (>=0.6.1)"]
|
||||||
|
@ -2373,13 +2374,13 @@ pycryptodome = ">=3.10.1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "et-xmlfile"
|
name = "et-xmlfile"
|
||||||
version = "1.1.0"
|
version = "2.0.0"
|
||||||
description = "An implementation of lxml.xmlfile for the standard library"
|
description = "An implementation of lxml.xmlfile for the standard library"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "et_xmlfile-1.1.0-py3-none-any.whl", hash = "sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada"},
|
{file = "et_xmlfile-2.0.0-py3-none-any.whl", hash = "sha256:7a91720bc756843502c3b7504c77b8fe44217c85c537d85037f0f536151b2caa"},
|
||||||
{file = "et_xmlfile-1.1.0.tar.gz", hash = "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c"},
|
{file = "et_xmlfile-2.0.0.tar.gz", hash = "sha256:dab3f4764309081ce75662649be815c4c9081e88f0837825f90fd28317d4da54"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2412,13 +2413,13 @@ test = ["pytest (>=6)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fastapi"
|
name = "fastapi"
|
||||||
version = "0.115.3"
|
version = "0.115.4"
|
||||||
description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
|
description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "fastapi-0.115.3-py3-none-any.whl", hash = "sha256:8035e8f9a2b0aa89cea03b6c77721178ed5358e1aea4cd8570d9466895c0638c"},
|
{file = "fastapi-0.115.4-py3-none-any.whl", hash = "sha256:0b504a063ffb3cf96a5e27dc1bc32c80ca743a2528574f9cdc77daa2d31b4742"},
|
||||||
{file = "fastapi-0.115.3.tar.gz", hash = "sha256:c091c6a35599c036d676fa24bd4a6e19fa30058d93d950216cdc672881f6f7db"},
|
{file = "fastapi-0.115.4.tar.gz", hash = "sha256:db653475586b091cb8b2fec2ac54a680ac6a158e07406e1abae31679e8826349"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -3336,13 +3337,13 @@ grpc = ["grpcio (>=1.38.0,<2.0dev)", "grpcio-status (>=1.38.0,<2.0.dev0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "google-cloud-resource-manager"
|
name = "google-cloud-resource-manager"
|
||||||
version = "1.12.5"
|
version = "1.13.0"
|
||||||
description = "Google Cloud Resource Manager API client library"
|
description = "Google Cloud Resource Manager API client library"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
files = [
|
files = [
|
||||||
{file = "google_cloud_resource_manager-1.12.5-py2.py3-none-any.whl", hash = "sha256:2708a718b45c79464b7b21559c701b5c92e6b0b1ab2146d0a256277a623dc175"},
|
{file = "google_cloud_resource_manager-1.13.0-py2.py3-none-any.whl", hash = "sha256:33beb4528c2b7aee7a97ed843710581a7b4a27f3dd1fa41a0bf3359b3d68853f"},
|
||||||
{file = "google_cloud_resource_manager-1.12.5.tar.gz", hash = "sha256:b7af4254401ed4efa3aba3a929cb3ddb803fa6baf91a78485e45583597de5891"},
|
{file = "google_cloud_resource_manager-1.13.0.tar.gz", hash = "sha256:ae4bf69443f14b37007d4d84150115b0942e8b01650fd7a1fc6ff4dc1760e5c4"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -3606,70 +3607,70 @@ protobuf = ">=3.20.2,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "grpcio"
|
name = "grpcio"
|
||||||
version = "1.67.0"
|
version = "1.67.1"
|
||||||
description = "HTTP/2-based RPC framework"
|
description = "HTTP/2-based RPC framework"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "grpcio-1.67.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:bd79929b3bb96b54df1296cd3bf4d2b770bd1df6c2bdf549b49bab286b925cdc"},
|
{file = "grpcio-1.67.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:8b0341d66a57f8a3119b77ab32207072be60c9bf79760fa609c5609f2deb1f3f"},
|
||||||
{file = "grpcio-1.67.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:16724ffc956ea42967f5758c2f043faef43cb7e48a51948ab593570570d1e68b"},
|
{file = "grpcio-1.67.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:f5a27dddefe0e2357d3e617b9079b4bfdc91341a91565111a21ed6ebbc51b22d"},
|
||||||
{file = "grpcio-1.67.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:2b7183c80b602b0ad816315d66f2fb7887614ead950416d60913a9a71c12560d"},
|
{file = "grpcio-1.67.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:43112046864317498a33bdc4797ae6a268c36345a910de9b9c17159d8346602f"},
|
||||||
{file = "grpcio-1.67.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:efe32b45dd6d118f5ea2e5deaed417d8a14976325c93812dd831908522b402c9"},
|
{file = "grpcio-1.67.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9b929f13677b10f63124c1a410994a401cdd85214ad83ab67cc077fc7e480f0"},
|
||||||
{file = "grpcio-1.67.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe89295219b9c9e47780a0f1c75ca44211e706d1c598242249fe717af3385ec8"},
|
{file = "grpcio-1.67.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7d1797a8a3845437d327145959a2c0c47c05947c9eef5ff1a4c80e499dcc6fa"},
|
||||||
{file = "grpcio-1.67.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa8d025fae1595a207b4e47c2e087cb88d47008494db258ac561c00877d4c8f8"},
|
{file = "grpcio-1.67.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0489063974d1452436139501bf6b180f63d4977223ee87488fe36858c5725292"},
|
||||||
{file = "grpcio-1.67.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f95e15db43e75a534420e04822df91f645664bf4ad21dfaad7d51773c80e6bb4"},
|
{file = "grpcio-1.67.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9fd042de4a82e3e7aca44008ee2fb5da01b3e5adb316348c21980f7f58adc311"},
|
||||||
{file = "grpcio-1.67.0-cp310-cp310-win32.whl", hash = "sha256:a6b9a5c18863fd4b6624a42e2712103fb0f57799a3b29651c0e5b8119a519d65"},
|
{file = "grpcio-1.67.1-cp310-cp310-win32.whl", hash = "sha256:638354e698fd0c6c76b04540a850bf1db27b4d2515a19fcd5cf645c48d3eb1ed"},
|
||||||
{file = "grpcio-1.67.0-cp310-cp310-win_amd64.whl", hash = "sha256:b6eb68493a05d38b426604e1dc93bfc0137c4157f7ab4fac5771fd9a104bbaa6"},
|
{file = "grpcio-1.67.1-cp310-cp310-win_amd64.whl", hash = "sha256:608d87d1bdabf9e2868b12338cd38a79969eaf920c89d698ead08f48de9c0f9e"},
|
||||||
{file = "grpcio-1.67.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:e91d154689639932305b6ea6f45c6e46bb51ecc8ea77c10ef25aa77f75443ad4"},
|
{file = "grpcio-1.67.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:7818c0454027ae3384235a65210bbf5464bd715450e30a3d40385453a85a70cb"},
|
||||||
{file = "grpcio-1.67.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cb204a742997277da678611a809a8409657b1398aaeebf73b3d9563b7d154c13"},
|
{file = "grpcio-1.67.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ea33986b70f83844cd00814cee4451055cd8cab36f00ac64a31f5bb09b31919e"},
|
||||||
{file = "grpcio-1.67.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:ae6de510f670137e755eb2a74b04d1041e7210af2444103c8c95f193340d17ee"},
|
{file = "grpcio-1.67.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:c7a01337407dd89005527623a4a72c5c8e2894d22bead0895306b23c6695698f"},
|
||||||
{file = "grpcio-1.67.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:74b900566bdf68241118f2918d312d3bf554b2ce0b12b90178091ea7d0a17b3d"},
|
{file = "grpcio-1.67.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80b866f73224b0634f4312a4674c1be21b2b4afa73cb20953cbbb73a6b36c3cc"},
|
||||||
{file = "grpcio-1.67.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4e95e43447a02aa603abcc6b5e727d093d161a869c83b073f50b9390ecf0fa8"},
|
{file = "grpcio-1.67.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9fff78ba10d4250bfc07a01bd6254a6d87dc67f9627adece85c0b2ed754fa96"},
|
||||||
{file = "grpcio-1.67.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0bb94e66cd8f0baf29bd3184b6aa09aeb1a660f9ec3d85da615c5003154bc2bf"},
|
{file = "grpcio-1.67.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:8a23cbcc5bb11ea7dc6163078be36c065db68d915c24f5faa4f872c573bb400f"},
|
||||||
{file = "grpcio-1.67.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:82e5bd4b67b17c8c597273663794a6a46a45e44165b960517fe6d8a2f7f16d23"},
|
{file = "grpcio-1.67.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1a65b503d008f066e994f34f456e0647e5ceb34cfcec5ad180b1b44020ad4970"},
|
||||||
{file = "grpcio-1.67.0-cp311-cp311-win32.whl", hash = "sha256:7fc1d2b9fd549264ae585026b266ac2db53735510a207381be509c315b4af4e8"},
|
{file = "grpcio-1.67.1-cp311-cp311-win32.whl", hash = "sha256:e29ca27bec8e163dca0c98084040edec3bc49afd10f18b412f483cc68c712744"},
|
||||||
{file = "grpcio-1.67.0-cp311-cp311-win_amd64.whl", hash = "sha256:ac11ecb34a86b831239cc38245403a8de25037b448464f95c3315819e7519772"},
|
{file = "grpcio-1.67.1-cp311-cp311-win_amd64.whl", hash = "sha256:786a5b18544622bfb1e25cc08402bd44ea83edfb04b93798d85dca4d1a0b5be5"},
|
||||||
{file = "grpcio-1.67.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:227316b5631260e0bef8a3ce04fa7db4cc81756fea1258b007950b6efc90c05d"},
|
{file = "grpcio-1.67.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:267d1745894200e4c604958da5f856da6293f063327cb049a51fe67348e4f953"},
|
||||||
{file = "grpcio-1.67.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d90cfdafcf4b45a7a076e3e2a58e7bc3d59c698c4f6470b0bb13a4d869cf2273"},
|
{file = "grpcio-1.67.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:85f69fdc1d28ce7cff8de3f9c67db2b0ca9ba4449644488c1e0303c146135ddb"},
|
||||||
{file = "grpcio-1.67.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:77196216d5dd6f99af1c51e235af2dd339159f657280e65ce7e12c1a8feffd1d"},
|
{file = "grpcio-1.67.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:f26b0b547eb8d00e195274cdfc63ce64c8fc2d3e2d00b12bf468ece41a0423a0"},
|
||||||
{file = "grpcio-1.67.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15c05a26a0f7047f720da41dc49406b395c1470eef44ff7e2c506a47ac2c0591"},
|
{file = "grpcio-1.67.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4422581cdc628f77302270ff839a44f4c24fdc57887dc2a45b7e53d8fc2376af"},
|
||||||
{file = "grpcio-1.67.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3840994689cc8cbb73d60485c594424ad8adb56c71a30d8948d6453083624b52"},
|
{file = "grpcio-1.67.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d7616d2ded471231c701489190379e0c311ee0a6c756f3c03e6a62b95a7146e"},
|
||||||
{file = "grpcio-1.67.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:5a1e03c3102b6451028d5dc9f8591131d6ab3c8a0e023d94c28cb930ed4b5f81"},
|
{file = "grpcio-1.67.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8a00efecde9d6fcc3ab00c13f816313c040a28450e5e25739c24f432fc6d3c75"},
|
||||||
{file = "grpcio-1.67.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:682968427a63d898759474e3b3178d42546e878fdce034fd7474ef75143b64e3"},
|
{file = "grpcio-1.67.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:699e964923b70f3101393710793289e42845791ea07565654ada0969522d0a38"},
|
||||||
{file = "grpcio-1.67.0-cp312-cp312-win32.whl", hash = "sha256:d01793653248f49cf47e5695e0a79805b1d9d4eacef85b310118ba1dfcd1b955"},
|
{file = "grpcio-1.67.1-cp312-cp312-win32.whl", hash = "sha256:4e7b904484a634a0fff132958dabdb10d63e0927398273917da3ee103e8d1f78"},
|
||||||
{file = "grpcio-1.67.0-cp312-cp312-win_amd64.whl", hash = "sha256:985b2686f786f3e20326c4367eebdaed3e7aa65848260ff0c6644f817042cb15"},
|
{file = "grpcio-1.67.1-cp312-cp312-win_amd64.whl", hash = "sha256:5721e66a594a6c4204458004852719b38f3d5522082be9061d6510b455c90afc"},
|
||||||
{file = "grpcio-1.67.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:8c9a35b8bc50db35ab8e3e02a4f2a35cfba46c8705c3911c34ce343bd777813a"},
|
{file = "grpcio-1.67.1-cp313-cp313-linux_armv7l.whl", hash = "sha256:aa0162e56fd10a5547fac8774c4899fc3e18c1aa4a4759d0ce2cd00d3696ea6b"},
|
||||||
{file = "grpcio-1.67.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:42199e704095b62688998c2d84c89e59a26a7d5d32eed86d43dc90e7a3bd04aa"},
|
{file = "grpcio-1.67.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:beee96c8c0b1a75d556fe57b92b58b4347c77a65781ee2ac749d550f2a365dc1"},
|
||||||
{file = "grpcio-1.67.0-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:c4c425f440fb81f8d0237c07b9322fc0fb6ee2b29fbef5f62a322ff8fcce240d"},
|
{file = "grpcio-1.67.1-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:a93deda571a1bf94ec1f6fcda2872dad3ae538700d94dc283c672a3b508ba3af"},
|
||||||
{file = "grpcio-1.67.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:323741b6699cd2b04a71cb38f502db98f90532e8a40cb675393d248126a268af"},
|
{file = "grpcio-1.67.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e6f255980afef598a9e64a24efce87b625e3e3c80a45162d111a461a9f92955"},
|
||||||
{file = "grpcio-1.67.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:662c8e105c5e5cee0317d500eb186ed7a93229586e431c1bf0c9236c2407352c"},
|
{file = "grpcio-1.67.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e838cad2176ebd5d4a8bb03955138d6589ce9e2ce5d51c3ada34396dbd2dba8"},
|
||||||
{file = "grpcio-1.67.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:f6bd2ab135c64a4d1e9e44679a616c9bc944547357c830fafea5c3caa3de5153"},
|
{file = "grpcio-1.67.1-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:a6703916c43b1d468d0756c8077b12017a9fcb6a1ef13faf49e67d20d7ebda62"},
|
||||||
{file = "grpcio-1.67.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:2f55c1e0e2ae9bdd23b3c63459ee4c06d223b68aeb1961d83c48fb63dc29bc03"},
|
{file = "grpcio-1.67.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:917e8d8994eed1d86b907ba2a61b9f0aef27a2155bca6cbb322430fc7135b7bb"},
|
||||||
{file = "grpcio-1.67.0-cp313-cp313-win32.whl", hash = "sha256:fd6bc27861e460fe28e94226e3673d46e294ca4673d46b224428d197c5935e69"},
|
{file = "grpcio-1.67.1-cp313-cp313-win32.whl", hash = "sha256:e279330bef1744040db8fc432becc8a727b84f456ab62b744d3fdb83f327e121"},
|
||||||
{file = "grpcio-1.67.0-cp313-cp313-win_amd64.whl", hash = "sha256:cf51d28063338608cd8d3cd64677e922134837902b70ce00dad7f116e3998210"},
|
{file = "grpcio-1.67.1-cp313-cp313-win_amd64.whl", hash = "sha256:fa0c739ad8b1996bd24823950e3cb5152ae91fca1c09cc791190bf1627ffefba"},
|
||||||
{file = "grpcio-1.67.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:7f200aca719c1c5dc72ab68be3479b9dafccdf03df530d137632c534bb6f1ee3"},
|
{file = "grpcio-1.67.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:178f5db771c4f9a9facb2ab37a434c46cb9be1a75e820f187ee3d1e7805c4f65"},
|
||||||
{file = "grpcio-1.67.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0892dd200ece4822d72dd0952f7112c542a487fc48fe77568deaaa399c1e717d"},
|
{file = "grpcio-1.67.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0f3e49c738396e93b7ba9016e153eb09e0778e776df6090c1b8c91877cc1c426"},
|
||||||
{file = "grpcio-1.67.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:f4d613fbf868b2e2444f490d18af472ccb47660ea3df52f068c9c8801e1f3e85"},
|
{file = "grpcio-1.67.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:24e8a26dbfc5274d7474c27759b54486b8de23c709d76695237515bc8b5baeab"},
|
||||||
{file = "grpcio-1.67.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c69bf11894cad9da00047f46584d5758d6ebc9b5950c0dc96fec7e0bce5cde9"},
|
{file = "grpcio-1.67.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b6c16489326d79ead41689c4b84bc40d522c9a7617219f4ad94bc7f448c5085"},
|
||||||
{file = "grpcio-1.67.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9bca3ca0c5e74dea44bf57d27e15a3a3996ce7e5780d61b7c72386356d231db"},
|
{file = "grpcio-1.67.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60e6a4dcf5af7bbc36fd9f81c9f372e8ae580870a9e4b6eafe948cd334b81cf3"},
|
||||||
{file = "grpcio-1.67.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:014dfc020e28a0d9be7e93a91f85ff9f4a87158b7df9952fe23cc42d29d31e1e"},
|
{file = "grpcio-1.67.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:95b5f2b857856ed78d72da93cd7d09b6db8ef30102e5e7fe0961fe4d9f7d48e8"},
|
||||||
{file = "grpcio-1.67.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d4ea4509d42c6797539e9ec7496c15473177ce9abc89bc5c71e7abe50fc25737"},
|
{file = "grpcio-1.67.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b49359977c6ec9f5d0573ea4e0071ad278ef905aa74e420acc73fd28ce39e9ce"},
|
||||||
{file = "grpcio-1.67.0-cp38-cp38-win32.whl", hash = "sha256:9d75641a2fca9ae1ae86454fd25d4c298ea8cc195dbc962852234d54a07060ad"},
|
{file = "grpcio-1.67.1-cp38-cp38-win32.whl", hash = "sha256:f5b76ff64aaac53fede0cc93abf57894ab2a7362986ba22243d06218b93efe46"},
|
||||||
{file = "grpcio-1.67.0-cp38-cp38-win_amd64.whl", hash = "sha256:cff8e54d6a463883cda2fab94d2062aad2f5edd7f06ae3ed030f2a74756db365"},
|
{file = "grpcio-1.67.1-cp38-cp38-win_amd64.whl", hash = "sha256:804c6457c3cd3ec04fe6006c739579b8d35c86ae3298ffca8de57b493524b771"},
|
||||||
{file = "grpcio-1.67.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:62492bd534979e6d7127b8a6b29093161a742dee3875873e01964049d5250a74"},
|
{file = "grpcio-1.67.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:a25bdea92b13ff4d7790962190bf6bf5c4639876e01c0f3dda70fc2769616335"},
|
||||||
{file = "grpcio-1.67.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eef1dce9d1a46119fd09f9a992cf6ab9d9178b696382439446ca5f399d7b96fe"},
|
{file = "grpcio-1.67.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cdc491ae35a13535fd9196acb5afe1af37c8237df2e54427be3eecda3653127e"},
|
||||||
{file = "grpcio-1.67.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:f623c57a5321461c84498a99dddf9d13dac0e40ee056d884d6ec4ebcab647a78"},
|
{file = "grpcio-1.67.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:85f862069b86a305497e74d0dc43c02de3d1d184fc2c180993aa8aa86fbd19b8"},
|
||||||
{file = "grpcio-1.67.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54d16383044e681f8beb50f905249e4e7261dd169d4aaf6e52eab67b01cbbbe2"},
|
{file = "grpcio-1.67.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec74ef02010186185de82cc594058a3ccd8d86821842bbac9873fd4a2cf8be8d"},
|
||||||
{file = "grpcio-1.67.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2a44e572fb762c668e4812156b81835f7aba8a721b027e2d4bb29fb50ff4d33"},
|
{file = "grpcio-1.67.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01f616a964e540638af5130469451cf580ba8c7329f45ca998ab66e0c7dcdb04"},
|
||||||
{file = "grpcio-1.67.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:391df8b0faac84d42f5b8dfc65f5152c48ed914e13c522fd05f2aca211f8bfad"},
|
{file = "grpcio-1.67.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:299b3d8c4f790c6bcca485f9963b4846dd92cf6f1b65d3697145d005c80f9fe8"},
|
||||||
{file = "grpcio-1.67.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cfd9306511fdfc623a1ba1dc3bc07fbd24e6cfbe3c28b4d1e05177baa2f99617"},
|
{file = "grpcio-1.67.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:60336bff760fbb47d7e86165408126f1dded184448e9a4c892189eb7c9d3f90f"},
|
||||||
{file = "grpcio-1.67.0-cp39-cp39-win32.whl", hash = "sha256:30d47dbacfd20cbd0c8be9bfa52fdb833b395d4ec32fe5cff7220afc05d08571"},
|
{file = "grpcio-1.67.1-cp39-cp39-win32.whl", hash = "sha256:5ed601c4c6008429e3d247ddb367fe8c7259c355757448d7c1ef7bd4a6739e8e"},
|
||||||
{file = "grpcio-1.67.0-cp39-cp39-win_amd64.whl", hash = "sha256:f55f077685f61f0fbd06ea355142b71e47e4a26d2d678b3ba27248abfe67163a"},
|
{file = "grpcio-1.67.1-cp39-cp39-win_amd64.whl", hash = "sha256:5db70d32d6703b89912af16d6d45d78406374a8b8ef0d28140351dd0ec610e98"},
|
||||||
{file = "grpcio-1.67.0.tar.gz", hash = "sha256:e090b2553e0da1c875449c8e75073dd4415dd71c9bde6a406240fdf4c0ee467c"},
|
{file = "grpcio-1.67.1.tar.gz", hash = "sha256:3dc2ed4cabea4dc14d5e708c2b426205956077cc5de419b4d4079315017e9732"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
protobuf = ["grpcio-tools (>=1.67.0)"]
|
protobuf = ["grpcio-tools (>=1.67.1)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "grpcio-status"
|
name = "grpcio-status"
|
||||||
|
@ -4644,13 +4645,13 @@ openai = ["openai (>=0.27.8)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "langsmith"
|
name = "langsmith"
|
||||||
version = "0.1.137"
|
version = "0.1.138"
|
||||||
description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform."
|
description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "<4.0,>=3.8.1"
|
python-versions = "<4.0,>=3.8.1"
|
||||||
files = [
|
files = [
|
||||||
{file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"},
|
{file = "langsmith-0.1.138-py3-none-any.whl", hash = "sha256:5c2bd5c11c75f7b3d06a0f06b115186e7326ca969fd26d66ffc65a0669012aee"},
|
||||||
{file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"},
|
{file = "langsmith-0.1.138.tar.gz", hash = "sha256:1ecf613bb52f6bf17f1510e24ad8b70d4b0259bc9d3dbfd69b648c66d4644f0b"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -5611,12 +5612,12 @@ twitter = ["twython"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nomic"
|
name = "nomic"
|
||||||
version = "3.1.2"
|
version = "3.1.3"
|
||||||
description = "The official Nomic python client."
|
description = "The official Nomic python client."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
files = [
|
files = [
|
||||||
{file = "nomic-3.1.2.tar.gz", hash = "sha256:2de1ab1dcf2429011c92987bb2f1eafe1a3a4901c3185b18f994bf89616f606d"},
|
{file = "nomic-3.1.3.tar.gz", hash = "sha256:b06744b79fbe47451874ca7b272cafa1bb272cfb82acc79c64abfc943a98e035"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -5636,7 +5637,7 @@ tqdm = "*"
|
||||||
[package.extras]
|
[package.extras]
|
||||||
all = ["nomic[aws,local]"]
|
all = ["nomic[aws,local]"]
|
||||||
aws = ["boto3", "sagemaker"]
|
aws = ["boto3", "sagemaker"]
|
||||||
dev = ["black (==24.3.0)", "cairosvg", "coverage", "isort", "mkautodoc", "mkdocs-jupyter", "mkdocs-material", "mkdocstrings[python]", "myst-parser", "nomic[all]", "pandas", "pillow", "pylint", "pyright", "pytest", "pytorch-lightning", "twine"]
|
dev = ["black (==24.3.0)", "cairosvg", "coverage", "isort", "mkautodoc", "mkdocs-jupyter", "mkdocs-material", "mkdocstrings[python]", "myst-parser", "nomic[all]", "pandas", "pillow", "pylint", "pyright (<=1.1.377)", "pytest", "pytorch-lightning", "twine"]
|
||||||
local = ["gpt4all (>=2.5.0,<3)"]
|
local = ["gpt4all (>=2.5.0,<3)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -6705,19 +6706,19 @@ dill = ["dill (>=0.3.9)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "primp"
|
name = "primp"
|
||||||
version = "0.6.4"
|
version = "0.6.5"
|
||||||
description = "HTTP client that can impersonate web browsers, mimicking their headers and `TLS/JA3/JA4/HTTP2` fingerprints"
|
description = "HTTP client that can impersonate web browsers, mimicking their headers and `TLS/JA3/JA4/HTTP2` fingerprints"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "primp-0.6.4-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:e627330c1f2b723b523dc2e47caacbc5b5d0cd51ca11583b42fb8cde4da60d7d"},
|
{file = "primp-0.6.5-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:b2bab0250d38c02a437c75ed94b99e3a8c03a281ba9a4c33780ccd04999c741b"},
|
||||||
{file = "primp-0.6.4-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:e0cb7c05dd56c8b9741042fd568c0983fc19b0f3aa209a3940ecc04b4fd60314"},
|
{file = "primp-0.6.5-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:0aedb33515d86df4c1f91b9d5772e1b74d1593dfe8978c258b136c171f8ab94c"},
|
||||||
{file = "primp-0.6.4-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4adc200ccb39e130c478d8b1a94f43a5b359068c6cb65b7c848812f96d96992"},
|
{file = "primp-0.6.5-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0e8850be30fbfefeb76c1eb5859a55c5f11c8c285a4a03ebf99c73fea964b2a"},
|
||||||
{file = "primp-0.6.4-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:0ebae2d3aa36b04028e4accf2609d31d2e6981659e8e2effb09ee8ba960192e1"},
|
{file = "primp-0.6.5-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:e9b71ac07a79cbb401390e2ee5a5767d0bf202a956a533fd084957020fcb2a64"},
|
||||||
{file = "primp-0.6.4-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:77f5fa5b34eaf251815622258419a484a2a9179dcbae2a1e702a254d91f613f1"},
|
{file = "primp-0.6.5-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:79c65fcb07b36bd0f8c3966a4a18c4f6a6d624a33a0b0133b0f0cc8d0050c351"},
|
||||||
{file = "primp-0.6.4-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:14cddf535cd2c4987412e90ca3ca35ae52cddbee6e0f0953d26b33a652a95692"},
|
{file = "primp-0.6.5-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:5a55e450bb52a88f4a2891db50577c8f20b134d17d37e93361ee51de1a6fe8c8"},
|
||||||
{file = "primp-0.6.4-cp38-abi3-win_amd64.whl", hash = "sha256:96177ec2dadc47eaecbf0b22d2e93aeaf964a1be9a71e6e318d2ffb9e4242743"},
|
{file = "primp-0.6.5-cp38-abi3-win_amd64.whl", hash = "sha256:cbe584de5c177b9f0656b77e88721296ae6151b6c4565e2e0a342b6473990f27"},
|
||||||
{file = "primp-0.6.4.tar.gz", hash = "sha256:0a3de63e46a50664bcdc76e7aaf7060bf8443698efa902864669c5fca0d1abdd"},
|
{file = "primp-0.6.5.tar.gz", hash = "sha256:abb46c579ae682f34c1f339faac38709c85ab76c056ec3711a26823334ab8124"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
|
@ -6904,52 +6905,55 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pyarrow"
|
name = "pyarrow"
|
||||||
version = "17.0.0"
|
version = "18.0.0"
|
||||||
description = "Python library for Apache Arrow"
|
description = "Python library for Apache Arrow"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.9"
|
||||||
files = [
|
files = [
|
||||||
{file = "pyarrow-17.0.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:a5c8b238d47e48812ee577ee20c9a2779e6a5904f1708ae240f53ecbee7c9f07"},
|
{file = "pyarrow-18.0.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:2333f93260674e185cfbf208d2da3007132572e56871f451ba1a556b45dae6e2"},
|
||||||
{file = "pyarrow-17.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:db023dc4c6cae1015de9e198d41250688383c3f9af8f565370ab2b4cb5f62655"},
|
{file = "pyarrow-18.0.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:4c381857754da44326f3a49b8b199f7f87a51c2faacd5114352fc78de30d3aba"},
|
||||||
{file = "pyarrow-17.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da1e060b3876faa11cee287839f9cc7cdc00649f475714b8680a05fd9071d545"},
|
{file = "pyarrow-18.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:603cd8ad4976568954598ef0a6d4ed3dfb78aff3d57fa8d6271f470f0ce7d34f"},
|
||||||
{file = "pyarrow-17.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75c06d4624c0ad6674364bb46ef38c3132768139ddec1c56582dbac54f2663e2"},
|
{file = "pyarrow-18.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58a62549a3e0bc9e03df32f350e10e1efb94ec6cf63e3920c3385b26663948ce"},
|
||||||
{file = "pyarrow-17.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:fa3c246cc58cb5a4a5cb407a18f193354ea47dd0648194e6265bd24177982fe8"},
|
{file = "pyarrow-18.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:bc97316840a349485fbb137eb8d0f4d7057e1b2c1272b1a20eebbbe1848f5122"},
|
||||||
{file = "pyarrow-17.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:f7ae2de664e0b158d1607699a16a488de3d008ba99b3a7aa5de1cbc13574d047"},
|
{file = "pyarrow-18.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:2e549a748fa8b8715e734919923f69318c953e077e9c02140ada13e59d043310"},
|
||||||
{file = "pyarrow-17.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:5984f416552eea15fd9cee03da53542bf4cddaef5afecefb9aa8d1010c335087"},
|
{file = "pyarrow-18.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:606e9a3dcb0f52307c5040698ea962685fb1c852d72379ee9412be7de9c5f9e2"},
|
||||||
{file = "pyarrow-17.0.0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:1c8856e2ef09eb87ecf937104aacfa0708f22dfeb039c363ec99735190ffb977"},
|
{file = "pyarrow-18.0.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:d5795e37c0a33baa618c5e054cd61f586cf76850a251e2b21355e4085def6280"},
|
||||||
{file = "pyarrow-17.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2e19f569567efcbbd42084e87f948778eb371d308e137a0f97afe19bb860ccb3"},
|
{file = "pyarrow-18.0.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:5f0510608ccd6e7f02ca8596962afb8c6cc84c453e7be0da4d85f5f4f7b0328a"},
|
||||||
{file = "pyarrow-17.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b244dc8e08a23b3e352899a006a26ae7b4d0da7bb636872fa8f5884e70acf15"},
|
{file = "pyarrow-18.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:616ea2826c03c16e87f517c46296621a7c51e30400f6d0a61be645f203aa2b93"},
|
||||||
{file = "pyarrow-17.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b72e87fe3e1db343995562f7fff8aee354b55ee83d13afba65400c178ab2597"},
|
{file = "pyarrow-18.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1824f5b029ddd289919f354bc285992cb4e32da518758c136271cf66046ef22"},
|
||||||
{file = "pyarrow-17.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:dc5c31c37409dfbc5d014047817cb4ccd8c1ea25d19576acf1a001fe07f5b420"},
|
{file = "pyarrow-18.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:6dd1b52d0d58dd8f685ced9971eb49f697d753aa7912f0a8f50833c7a7426319"},
|
||||||
{file = "pyarrow-17.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:e3343cb1e88bc2ea605986d4b94948716edc7a8d14afd4e2c097232f729758b4"},
|
{file = "pyarrow-18.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:320ae9bd45ad7ecc12ec858b3e8e462578de060832b98fc4d671dee9f10d9954"},
|
||||||
{file = "pyarrow-17.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:a27532c38f3de9eb3e90ecab63dfda948a8ca859a66e3a47f5f42d1e403c4d03"},
|
{file = "pyarrow-18.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:2c992716cffb1088414f2b478f7af0175fd0a76fea80841b1706baa8fb0ebaad"},
|
||||||
{file = "pyarrow-17.0.0-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:9b8a823cea605221e61f34859dcc03207e52e409ccf6354634143e23af7c8d22"},
|
{file = "pyarrow-18.0.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:e7ab04f272f98ebffd2a0661e4e126036f6936391ba2889ed2d44c5006237802"},
|
||||||
{file = "pyarrow-17.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f1e70de6cb5790a50b01d2b686d54aaf73da01266850b05e3af2a1bc89e16053"},
|
{file = "pyarrow-18.0.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:03f40b65a43be159d2f97fd64dc998f769d0995a50c00f07aab58b0b3da87e1f"},
|
||||||
{file = "pyarrow-17.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0071ce35788c6f9077ff9ecba4858108eebe2ea5a3f7cf2cf55ebc1dbc6ee24a"},
|
{file = "pyarrow-18.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be08af84808dff63a76860847c48ec0416928a7b3a17c2f49a072cac7c45efbd"},
|
||||||
{file = "pyarrow-17.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:757074882f844411fcca735e39aae74248a1531367a7c80799b4266390ae51cc"},
|
{file = "pyarrow-18.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c70c1965cde991b711a98448ccda3486f2a336457cf4ec4dca257a926e149c9"},
|
||||||
{file = "pyarrow-17.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:9ba11c4f16976e89146781a83833df7f82077cdab7dc6232c897789343f7891a"},
|
{file = "pyarrow-18.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:00178509f379415a3fcf855af020e3340254f990a8534294ec3cf674d6e255fd"},
|
||||||
{file = "pyarrow-17.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:b0c6ac301093b42d34410b187bba560b17c0330f64907bfa4f7f7f2444b0cf9b"},
|
{file = "pyarrow-18.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:a71ab0589a63a3e987beb2bc172e05f000a5c5be2636b4b263c44034e215b5d7"},
|
||||||
{file = "pyarrow-17.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:392bc9feabc647338e6c89267635e111d71edad5fcffba204425a7c8d13610d7"},
|
{file = "pyarrow-18.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:fe92efcdbfa0bcf2fa602e466d7f2905500f33f09eb90bf0bcf2e6ca41b574c8"},
|
||||||
{file = "pyarrow-17.0.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:af5ff82a04b2171415f1410cff7ebb79861afc5dae50be73ce06d6e870615204"},
|
{file = "pyarrow-18.0.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:907ee0aa8ca576f5e0cdc20b5aeb2ad4d3953a3b4769fc4b499e00ef0266f02f"},
|
||||||
{file = "pyarrow-17.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:edca18eaca89cd6382dfbcff3dd2d87633433043650c07375d095cd3517561d8"},
|
{file = "pyarrow-18.0.0-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:66dcc216ebae2eb4c37b223feaf82f15b69d502821dde2da138ec5a3716e7463"},
|
||||||
{file = "pyarrow-17.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c7916bff914ac5d4a8fe25b7a25e432ff921e72f6f2b7547d1e325c1ad9d155"},
|
{file = "pyarrow-18.0.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc1daf7c425f58527900876354390ee41b0ae962a73ad0959b9d829def583bb1"},
|
||||||
{file = "pyarrow-17.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f553ca691b9e94b202ff741bdd40f6ccb70cdd5fbf65c187af132f1317de6145"},
|
{file = "pyarrow-18.0.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:871b292d4b696b09120ed5bde894f79ee2a5f109cb84470546471df264cae136"},
|
||||||
{file = "pyarrow-17.0.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:0cdb0e627c86c373205a2f94a510ac4376fdc523f8bb36beab2e7f204416163c"},
|
{file = "pyarrow-18.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:082ba62bdcb939824ba1ce10b8acef5ab621da1f4c4805e07bfd153617ac19d4"},
|
||||||
{file = "pyarrow-17.0.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:d7d192305d9d8bc9082d10f361fc70a73590a4c65cf31c3e6926cd72b76bc35c"},
|
{file = "pyarrow-18.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:2c664ab88b9766413197733c1720d3dcd4190e8fa3bbdc3710384630a0a7207b"},
|
||||||
{file = "pyarrow-17.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:02dae06ce212d8b3244dd3e7d12d9c4d3046945a5933d28026598e9dbbda1fca"},
|
{file = "pyarrow-18.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:dc892be34dbd058e8d189b47db1e33a227d965ea8805a235c8a7286f7fd17d3a"},
|
||||||
{file = "pyarrow-17.0.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:13d7a460b412f31e4c0efa1148e1d29bdf18ad1411eb6757d38f8fbdcc8645fb"},
|
{file = "pyarrow-18.0.0-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:28f9c39a56d2c78bf6b87dcc699d520ab850919d4a8c7418cd20eda49874a2ea"},
|
||||||
{file = "pyarrow-17.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9b564a51fbccfab5a04a80453e5ac6c9954a9c5ef2890d1bcf63741909c3f8df"},
|
{file = "pyarrow-18.0.0-cp313-cp313t-macosx_12_0_x86_64.whl", hash = "sha256:f1a198a50c409ab2d009fbf20956ace84567d67f2c5701511d4dd561fae6f32e"},
|
||||||
{file = "pyarrow-17.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32503827abbc5aadedfa235f5ece8c4f8f8b0a3cf01066bc8d29de7539532687"},
|
{file = "pyarrow-18.0.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5bd7fd32e3ace012d43925ea4fc8bd1b02cc6cc1e9813b518302950e89b5a22"},
|
||||||
{file = "pyarrow-17.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a155acc7f154b9ffcc85497509bcd0d43efb80d6f733b0dc3bb14e281f131c8b"},
|
{file = "pyarrow-18.0.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:336addb8b6f5208be1b2398442c703a710b6b937b1a046065ee4db65e782ff5a"},
|
||||||
{file = "pyarrow-17.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:dec8d129254d0188a49f8a1fc99e0560dc1b85f60af729f47de4046015f9b0a5"},
|
{file = "pyarrow-18.0.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:45476490dd4adec5472c92b4d253e245258745d0ccaabe706f8d03288ed60a79"},
|
||||||
{file = "pyarrow-17.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:a48ddf5c3c6a6c505904545c25a4ae13646ae1f8ba703c4df4a1bfe4f4006bda"},
|
{file = "pyarrow-18.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:b46591222c864e7da7faa3b19455196416cd8355ff6c2cc2e65726a760a3c420"},
|
||||||
{file = "pyarrow-17.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:42bf93249a083aca230ba7e2786c5f673507fa97bbd9725a1e2754715151a204"},
|
{file = "pyarrow-18.0.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:eb7e3abcda7e1e6b83c2dc2909c8d045881017270a119cc6ee7fdcfe71d02df8"},
|
||||||
{file = "pyarrow-17.0.0.tar.gz", hash = "sha256:4beca9521ed2c0921c1023e68d097d0299b62c362639ea315572a58f3f50fd28"},
|
{file = "pyarrow-18.0.0-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:09f30690b99ce34e0da64d20dab372ee54431745e4efb78ac938234a282d15f9"},
|
||||||
|
{file = "pyarrow-18.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d5ca5d707e158540312e09fd907f9f49bacbe779ab5236d9699ced14d2293b8"},
|
||||||
|
{file = "pyarrow-18.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d6331f280c6e4521c69b201a42dd978f60f7e129511a55da9e0bfe426b4ebb8d"},
|
||||||
|
{file = "pyarrow-18.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:3ac24b2be732e78a5a3ac0b3aa870d73766dd00beba6e015ea2ea7394f8b4e55"},
|
||||||
|
{file = "pyarrow-18.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b30a927c6dff89ee702686596f27c25160dd6c99be5bcc1513a763ae5b1bfc03"},
|
||||||
|
{file = "pyarrow-18.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:8f40ec677e942374e3d7f2fad6a67a4c2811a8b975e8703c6fd26d3b168a90e2"},
|
||||||
|
{file = "pyarrow-18.0.0.tar.gz", hash = "sha256:a6aa027b1a9d2970cf328ccd6dbe4a996bc13c39fd427f502782f5bdb9ca20f5"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
numpy = ">=1.16.6"
|
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
test = ["cffi", "hypothesis", "pandas", "pytest", "pytz"]
|
test = ["cffi", "hypothesis", "pandas", "pytest", "pytz"]
|
||||||
|
|
||||||
|
@ -7257,13 +7261,13 @@ tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pymilvus"
|
name = "pymilvus"
|
||||||
version = "2.4.8"
|
version = "2.4.9"
|
||||||
description = "Python Sdk for Milvus"
|
description = "Python Sdk for Milvus"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "pymilvus-2.4.8-py3-none-any.whl", hash = "sha256:5824f8ef4ecb14cfd4b205bf976aa52576c3a83c3cd848d21c8f5f9bb99b29e1"},
|
{file = "pymilvus-2.4.9-py3-none-any.whl", hash = "sha256:45313607d2c164064bdc44e0f933cb6d6afa92e9efcc7f357c5240c57db58fbe"},
|
||||||
{file = "pymilvus-2.4.8.tar.gz", hash = "sha256:0ddd18a060635fc8f1d1ab5635d9cc340ef29a97783b73db186df6334fa31ee2"},
|
{file = "pymilvus-2.4.9.tar.gz", hash = "sha256:0937663700007c23a84cfc0656160b301f6ff9247aaec4c96d599a6b43572136"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -7372,23 +7376,24 @@ diagrams = ["jinja2", "railroad-diagrams"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pypdf"
|
name = "pypdf"
|
||||||
version = "5.0.1"
|
version = "5.1.0"
|
||||||
description = "A pure-python PDF library capable of splitting, merging, cropping, and transforming PDF files"
|
description = "A pure-python PDF library capable of splitting, merging, cropping, and transforming PDF files"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "pypdf-5.0.1-py3-none-any.whl", hash = "sha256:ff8a32da6c7a63fea9c32fa4dd837cdd0db7966adf6c14f043e3f12592e992db"},
|
{file = "pypdf-5.1.0-py3-none-any.whl", hash = "sha256:3bd4f503f4ebc58bae40d81e81a9176c400cbbac2ba2d877367595fb524dfdfc"},
|
||||||
{file = "pypdf-5.0.1.tar.gz", hash = "sha256:a361c3c372b4a659f9c8dd438d5ce29a753c79c620dc6e1fd66977651f5547ea"},
|
{file = "pypdf-5.1.0.tar.gz", hash = "sha256:425a129abb1614183fd1aca6982f650b47f8026867c0ce7c4b9f281c443d2740"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
typing_extensions = {version = ">=4.0", markers = "python_version < \"3.11\""}
|
typing_extensions = {version = ">=4.0", markers = "python_version < \"3.11\""}
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
crypto = ["PyCryptodome", "cryptography"]
|
crypto = ["cryptography"]
|
||||||
|
cryptodome = ["PyCryptodome"]
|
||||||
dev = ["black", "flit", "pip-tools", "pre-commit (<2.18.0)", "pytest-cov", "pytest-socket", "pytest-timeout", "pytest-xdist", "wheel"]
|
dev = ["black", "flit", "pip-tools", "pre-commit (<2.18.0)", "pytest-cov", "pytest-socket", "pytest-timeout", "pytest-xdist", "wheel"]
|
||||||
docs = ["myst_parser", "sphinx", "sphinx_rtd_theme"]
|
docs = ["myst_parser", "sphinx", "sphinx_rtd_theme"]
|
||||||
full = ["Pillow (>=8.0.0)", "PyCryptodome", "cryptography"]
|
full = ["Pillow (>=8.0.0)", "cryptography"]
|
||||||
image = ["Pillow (>=8.0.0)"]
|
image = ["Pillow (>=8.0.0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -7924,99 +7929,99 @@ dev = ["pytest"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rapidfuzz"
|
name = "rapidfuzz"
|
||||||
version = "3.10.0"
|
version = "3.10.1"
|
||||||
description = "rapid fuzzy string matching"
|
description = "rapid fuzzy string matching"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
files = [
|
files = [
|
||||||
{file = "rapidfuzz-3.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:884453860de029380dded8f3c1918af2d8eb5adf8010261645c7e5c88c2b5428"},
|
{file = "rapidfuzz-3.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f17d9f21bf2f2f785d74f7b0d407805468b4c173fa3e52c86ec94436b338e74a"},
|
||||||
{file = "rapidfuzz-3.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:718c9bd369288aca5fa929df6dbf66fdbe9768d90940a940c0b5cdc96ade4309"},
|
{file = "rapidfuzz-3.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b31f358a70efc143909fb3d75ac6cd3c139cd41339aa8f2a3a0ead8315731f2b"},
|
||||||
{file = "rapidfuzz-3.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a68e3724b7dab761c01816aaa64b0903734d999d5589daf97c14ef5cc0629a8e"},
|
{file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f4f43f2204b56a61448ec2dd061e26fd344c404da99fb19f3458200c5874ba2"},
|
||||||
{file = "rapidfuzz-3.10.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1af60988d47534246d9525f77288fdd9de652608a4842815d9018570b959acc6"},
|
{file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d81bf186a453a2757472133b24915768abc7c3964194406ed93e170e16c21cb"},
|
||||||
{file = "rapidfuzz-3.10.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3084161fc3e963056232ef8d937449a2943852e07101f5a136c8f3cfa4119217"},
|
{file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3611c8f45379a12063d70075c75134f2a8bd2e4e9b8a7995112ddae95ca1c982"},
|
||||||
{file = "rapidfuzz-3.10.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6cd67d3d017296d98ff505529104299f78433e4b8af31b55003d901a62bbebe9"},
|
{file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3c3b537b97ac30da4b73930fa8a4fe2f79c6d1c10ad535c5c09726612cd6bed9"},
|
||||||
{file = "rapidfuzz-3.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b11a127ac590fc991e8a02c2d7e1ac86e8141c92f78546f18b5c904064a0552c"},
|
{file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:231ef1ec9cf7b59809ce3301006500b9d564ddb324635f4ea8f16b3e2a1780da"},
|
||||||
{file = "rapidfuzz-3.10.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:aadce42147fc09dcef1afa892485311e824c050352e1aa6e47f56b9b27af4cf0"},
|
{file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ed4f3adc1294834955b7e74edd3c6bd1aad5831c007f2d91ea839e76461a5879"},
|
||||||
{file = "rapidfuzz-3.10.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b54853c2371bf0e38d67da379519deb6fbe70055efb32f6607081641af3dc752"},
|
{file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:7b6015da2e707bf632a71772a2dbf0703cff6525732c005ad24987fe86e8ec32"},
|
||||||
{file = "rapidfuzz-3.10.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ce19887268e90ee81a3957eef5e46a70ecc000713796639f83828b950343f49e"},
|
{file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:1b35a118d61d6f008e8e3fb3a77674d10806a8972c7b8be433d6598df4d60b01"},
|
||||||
{file = "rapidfuzz-3.10.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:f39a2a5ded23b9b9194ec45740dce57177b80f86c6d8eba953d3ff1a25c97766"},
|
{file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:bc308d79a7e877226f36bdf4e149e3ed398d8277c140be5c1fd892ec41739e6d"},
|
||||||
{file = "rapidfuzz-3.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0ec338d5f4ad8d9339a88a08db5c23e7f7a52c2b2a10510c48a0cef1fb3f0ddc"},
|
{file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f017dbfecc172e2d0c37cf9e3d519179d71a7f16094b57430dffc496a098aa17"},
|
||||||
{file = "rapidfuzz-3.10.0-cp310-cp310-win32.whl", hash = "sha256:56fd15ea8f4c948864fa5ebd9261c67cf7b89a1c517a0caef4df75446a7af18c"},
|
{file = "rapidfuzz-3.10.1-cp310-cp310-win32.whl", hash = "sha256:36c0e1483e21f918d0f2f26799fe5ac91c7b0c34220b73007301c4f831a9c4c7"},
|
||||||
{file = "rapidfuzz-3.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:43dfc5e733808962a822ff6d9c29f3039a3cfb3620706f5953e17cfe4496724c"},
|
{file = "rapidfuzz-3.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:10746c1d4c8cd8881c28a87fd7ba0c9c102346dfe7ff1b0d021cdf093e9adbff"},
|
||||||
{file = "rapidfuzz-3.10.0-cp310-cp310-win_arm64.whl", hash = "sha256:ae7966f205b5a7fde93b44ca8fed37c1c8539328d7f179b1197de34eceaceb5f"},
|
{file = "rapidfuzz-3.10.1-cp310-cp310-win_arm64.whl", hash = "sha256:dfa64b89dcb906835e275187569e51aa9d546a444489e97aaf2cc84011565fbe"},
|
||||||
{file = "rapidfuzz-3.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bb0013795b40db5cf361e6f21ee7cda09627cf294977149b50e217d7fe9a2f03"},
|
{file = "rapidfuzz-3.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:92958ae075c87fef393f835ed02d4fe8d5ee2059a0934c6c447ea3417dfbf0e8"},
|
||||||
{file = "rapidfuzz-3.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:69ef5b363afff7150a1fbe788007e307b9802a2eb6ad92ed51ab94e6ad2674c6"},
|
{file = "rapidfuzz-3.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ba7521e072c53e33c384e78615d0718e645cab3c366ecd3cc8cb732befd94967"},
|
||||||
{file = "rapidfuzz-3.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c582c46b1bb0b19f1a5f4c1312f1b640c21d78c371a6615c34025b16ee56369b"},
|
{file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00d02cbd75d283c287471b5b3738b3e05c9096150f93f2d2dfa10b3d700f2db9"},
|
||||||
{file = "rapidfuzz-3.10.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:288f6f6e7410cacb115fb851f3f18bf0e4231eb3f6cb5bd1cec0e7b25c4d039d"},
|
{file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:efa1582a397da038e2f2576c9cd49b842f56fde37d84a6b0200ffebc08d82350"},
|
||||||
{file = "rapidfuzz-3.10.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9e29a13d2fd9be3e7d8c26c7ef4ba60b5bc7efbc9dbdf24454c7e9ebba31768"},
|
{file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f12912acee1f506f974f58de9fdc2e62eea5667377a7e9156de53241c05fdba8"},
|
||||||
{file = "rapidfuzz-3.10.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea2da0459b951ee461bd4e02b8904890bd1c4263999d291c5cd01e6620177ad4"},
|
{file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:666d5d8b17becc3f53447bcb2b6b33ce6c2df78792495d1fa82b2924cd48701a"},
|
||||||
{file = "rapidfuzz-3.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:457827ba82261aa2ae6ac06a46d0043ab12ba7216b82d87ae1434ec0f29736d6"},
|
{file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26f71582c0d62445067ee338ddad99b655a8f4e4ed517a90dcbfbb7d19310474"},
|
||||||
{file = "rapidfuzz-3.10.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5d350864269d56f51ab81ab750c9259ae5cad3152c0680baef143dcec92206a1"},
|
{file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8a2ef08b27167bcff230ffbfeedd4c4fa6353563d6aaa015d725dd3632fc3de7"},
|
||||||
{file = "rapidfuzz-3.10.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a9b8f51e08c3f983d857c3889930af9ddecc768453822076683664772d87e374"},
|
{file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:365e4fc1a2b95082c890f5e98489b894e6bf8c338c6ac89bb6523c2ca6e9f086"},
|
||||||
{file = "rapidfuzz-3.10.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7f3a6aa6e70fc27e4ff5c479f13cc9fc26a56347610f5f8b50396a0d344c5f55"},
|
{file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1996feb7a61609fa842e6b5e0c549983222ffdedaf29644cc67e479902846dfe"},
|
||||||
{file = "rapidfuzz-3.10.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:803f255f10d63420979b1909ef976e7d30dec42025c9b067fc1d2040cc365a7e"},
|
{file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:cf654702f144beaa093103841a2ea6910d617d0bb3fccb1d1fd63c54dde2cd49"},
|
||||||
{file = "rapidfuzz-3.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2026651761bf83a0f31495cc0f70840d5c0d54388f41316e3f9cb51bd85e49a5"},
|
{file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec108bf25de674781d0a9a935030ba090c78d49def3d60f8724f3fc1e8e75024"},
|
||||||
{file = "rapidfuzz-3.10.0-cp311-cp311-win32.whl", hash = "sha256:4df75b3ebbb8cfdb9bf8b213b168620b88fd92d0c16a8bc9f9234630b282db59"},
|
{file = "rapidfuzz-3.10.1-cp311-cp311-win32.whl", hash = "sha256:031f8b367e5d92f7a1e27f7322012f3c321c3110137b43cc3bf678505583ef48"},
|
||||||
{file = "rapidfuzz-3.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:f9f0bbfb6787b97c51516f3ccf97737d504db5d239ad44527673b81f598b84ab"},
|
{file = "rapidfuzz-3.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:f98f36c6a1bb9a6c8bbec99ad87c8c0e364f34761739b5ea9adf7b48129ae8cf"},
|
||||||
{file = "rapidfuzz-3.10.0-cp311-cp311-win_arm64.whl", hash = "sha256:10fdad800441b9c97d471a937ba7d42625f1b530db05e572f1cb7d401d95c893"},
|
{file = "rapidfuzz-3.10.1-cp311-cp311-win_arm64.whl", hash = "sha256:f1da2028cb4e41be55ee797a82d6c1cf589442504244249dfeb32efc608edee7"},
|
||||||
{file = "rapidfuzz-3.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7dc87073ba3a40dd65591a2100aa71602107443bf10770579ff9c8a3242edb94"},
|
{file = "rapidfuzz-3.10.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1340b56340896bede246f612b6ecf685f661a56aabef3d2512481bfe23ac5835"},
|
||||||
{file = "rapidfuzz-3.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a425a0a868cf8e9c6e93e1cda4b758cdfd314bb9a4fc916c5742c934e3613480"},
|
{file = "rapidfuzz-3.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2316515169b7b5a453f0ce3adbc46c42aa332cae9f2edb668e24d1fc92b2f2bb"},
|
||||||
{file = "rapidfuzz-3.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a86d5d1d75e61df060c1e56596b6b0a4422a929dff19cc3dbfd5eee762c86b61"},
|
{file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e06fe6a12241ec1b72c0566c6b28cda714d61965d86569595ad24793d1ab259"},
|
||||||
{file = "rapidfuzz-3.10.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34f213d59219a9c3ca14e94a825f585811a68ac56b4118b4dc388b5b14afc108"},
|
{file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d99c1cd9443b19164ec185a7d752f4b4db19c066c136f028991a480720472e23"},
|
||||||
{file = "rapidfuzz-3.10.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:96ad46f5f56f70fab2be9e5f3165a21be58d633b90bf6e67fc52a856695e4bcf"},
|
{file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1d9aa156ed52d3446388ba4c2f335e312191d1ca9d1f5762ee983cf23e4ecf6"},
|
||||||
{file = "rapidfuzz-3.10.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9178277f72d144a6c7704d7ae7fa15b7b86f0f0796f0e1049c7b4ef748a662ef"},
|
{file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:54bcf4efaaee8e015822be0c2c28214815f4f6b4f70d8362cfecbd58a71188ac"},
|
||||||
{file = "rapidfuzz-3.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76a35e9e19a7c883c422ffa378e9a04bc98cb3b29648c5831596401298ee51e6"},
|
{file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0c955e32afdbfdf6e9ee663d24afb25210152d98c26d22d399712d29a9b976b"},
|
||||||
{file = "rapidfuzz-3.10.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8a6405d34c394c65e4f73a1d300c001f304f08e529d2ed6413b46ee3037956eb"},
|
{file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:191633722203f5b7717efcb73a14f76f3b124877d0608c070b827c5226d0b972"},
|
||||||
{file = "rapidfuzz-3.10.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:bd393683129f446a75d8634306aed7e377627098a1286ff3af2a4f1736742820"},
|
{file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:195baad28057ec9609e40385991004e470af9ef87401e24ebe72c064431524ab"},
|
||||||
{file = "rapidfuzz-3.10.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b0445fa9880ead81f5a7d0efc0b9c977a947d8052c43519aceeaf56eabaf6843"},
|
{file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0fff4a6b87c07366662b62ae994ffbeadc472e72f725923f94b72a3db49f4671"},
|
||||||
{file = "rapidfuzz-3.10.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:c50bc308fa29767ed8f53a8d33b7633a9e14718ced038ed89d41b886e301da32"},
|
{file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4ffed25f9fdc0b287f30a98467493d1e1ce5b583f6317f70ec0263b3c97dbba6"},
|
||||||
{file = "rapidfuzz-3.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e89605afebbd2d4b045bccfdc12a14b16fe8ccbae05f64b4b4c64a97dad1c891"},
|
{file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d02cf8e5af89a9ac8f53c438ddff6d773f62c25c6619b29db96f4aae248177c0"},
|
||||||
{file = "rapidfuzz-3.10.0-cp312-cp312-win32.whl", hash = "sha256:2db9187f3acf3cd33424ecdbaad75414c298ecd1513470df7bda885dcb68cc15"},
|
{file = "rapidfuzz-3.10.1-cp312-cp312-win32.whl", hash = "sha256:f3bb81d4fe6a5d20650f8c0afcc8f6e1941f6fecdb434f11b874c42467baded0"},
|
||||||
{file = "rapidfuzz-3.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:50e3d0c72ea15391ba9531ead7f2068a67c5b18a6a365fef3127583aaadd1725"},
|
{file = "rapidfuzz-3.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:aaf83e9170cb1338922ae42d320699dccbbdca8ffed07faeb0b9257822c26e24"},
|
||||||
{file = "rapidfuzz-3.10.0-cp312-cp312-win_arm64.whl", hash = "sha256:9eac95b4278bd53115903d89118a2c908398ee8bdfd977ae844f1bd2b02b917c"},
|
{file = "rapidfuzz-3.10.1-cp312-cp312-win_arm64.whl", hash = "sha256:c5da802a0d085ad81b0f62828fb55557996c497b2d0b551bbdfeafd6d447892f"},
|
||||||
{file = "rapidfuzz-3.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fe5231e8afd069c742ac5b4f96344a0fe4aff52df8e53ef87faebf77f827822c"},
|
{file = "rapidfuzz-3.10.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fc22d69a1c9cccd560a5c434c0371b2df0f47c309c635a01a913e03bbf183710"},
|
||||||
{file = "rapidfuzz-3.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:886882367dbc985f5736356105798f2ae6e794e671fc605476cbe2e73838a9bb"},
|
{file = "rapidfuzz-3.10.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:38b0dac2c8e057562b8f0d8ae5b663d2d6a28c5ab624de5b73cef9abb6129a24"},
|
||||||
{file = "rapidfuzz-3.10.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b33e13e537e3afd1627d421a142a12bbbe601543558a391a6fae593356842f6e"},
|
{file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fde3bbb14e92ce8fcb5c2edfff72e474d0080cadda1c97785bf4822f037a309"},
|
||||||
{file = "rapidfuzz-3.10.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:094c26116d55bf9c53abd840d08422f20da78ec4c4723e5024322321caedca48"},
|
{file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9141fb0592e55f98fe9ac0f3ce883199b9c13e262e0bf40c5b18cdf926109d16"},
|
||||||
{file = "rapidfuzz-3.10.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:545fc04f2d592e4350f59deb0818886c1b444ffba3bec535b4fbb97191aaf769"},
|
{file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:237bec5dd1bfc9b40bbd786cd27949ef0c0eb5fab5eb491904c6b5df59d39d3c"},
|
||||||
{file = "rapidfuzz-3.10.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:916a6abf3632e592b937c3d04c00a6efadd8fd30539cdcd4e6e4d92be7ca5d90"},
|
{file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18123168cba156ab5794ea6de66db50f21bb3c66ae748d03316e71b27d907b95"},
|
||||||
{file = "rapidfuzz-3.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb6ec40cef63b1922083d33bfef2f91fc0b0bc07b5b09bfee0b0f1717d558292"},
|
{file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b75fe506c8e02769cc47f5ab21ce3e09b6211d3edaa8f8f27331cb6988779be"},
|
||||||
{file = "rapidfuzz-3.10.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c77a7330dd15c7eb5fd3631dc646fc96327f98db8181138766bd14d3e905f0ba"},
|
{file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9da82aa4b46973aaf9e03bb4c3d6977004648c8638febfc0f9d237e865761270"},
|
||||||
{file = "rapidfuzz-3.10.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:949b5e9eeaa4ecb4c7e9c2a4689dddce60929dd1ff9c76a889cdbabe8bbf2171"},
|
{file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c34c022d5ad564f1a5a57a4a89793bd70d7bad428150fb8ff2760b223407cdcf"},
|
||||||
{file = "rapidfuzz-3.10.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b5363932a5aab67010ae1a6205c567d1ef256fb333bc23c27582481606be480c"},
|
{file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1e96c84d6c2a0ca94e15acb5399118fff669f4306beb98a6d8ec6f5dccab4412"},
|
||||||
{file = "rapidfuzz-3.10.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:5dd6eec15b13329abe66cc241b484002ecb0e17d694491c944a22410a6a9e5e2"},
|
{file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e8e154b84a311263e1aca86818c962e1fa9eefdd643d1d5d197fcd2738f88cb9"},
|
||||||
{file = "rapidfuzz-3.10.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79e7f98525b60b3c14524e0a4e1fedf7654657b6e02eb25f1be897ab097706f3"},
|
{file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:335fee93188f8cd585552bb8057228ce0111bd227fa81bfd40b7df6b75def8ab"},
|
||||||
{file = "rapidfuzz-3.10.0-cp313-cp313-win32.whl", hash = "sha256:d29d1b9857c65f8cb3a29270732e1591b9bacf89de9d13fa764f79f07d8f1fd2"},
|
{file = "rapidfuzz-3.10.1-cp313-cp313-win32.whl", hash = "sha256:6729b856166a9e95c278410f73683957ea6100c8a9d0a8dbe434c49663689255"},
|
||||||
{file = "rapidfuzz-3.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:fa9720e56663cc3649d62b4b5f3145e94b8f5611e8a8e1b46507777249d46aad"},
|
{file = "rapidfuzz-3.10.1-cp313-cp313-win_amd64.whl", hash = "sha256:0e06d99ad1ad97cb2ef7f51ec6b1fedd74a3a700e4949353871cf331d07b382a"},
|
||||||
{file = "rapidfuzz-3.10.0-cp313-cp313-win_arm64.whl", hash = "sha256:eda4c661e68dddd56c8fbfe1ca35e40dd2afd973f7ebb1605f4d151edc63dff8"},
|
{file = "rapidfuzz-3.10.1-cp313-cp313-win_arm64.whl", hash = "sha256:8d1b7082104d596a3eb012e0549b2634ed15015b569f48879701e9d8db959dbb"},
|
||||||
{file = "rapidfuzz-3.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cffbc50e0767396ed483900900dd58ce4351bc0d40e64bced8694bd41864cc71"},
|
{file = "rapidfuzz-3.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:779027d3307e1a2b1dc0c03c34df87a470a368a1a0840a9d2908baf2d4067956"},
|
||||||
{file = "rapidfuzz-3.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c038b9939da3035afb6cb2f465f18163e8f070aba0482923ecff9443def67178"},
|
{file = "rapidfuzz-3.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:440b5608ab12650d0390128d6858bc839ae77ffe5edf0b33a1551f2fa9860651"},
|
||||||
{file = "rapidfuzz-3.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca366c2e2a54e2f663f4529b189fdeb6e14d419b1c78b754ec1744f3c01070d4"},
|
{file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82cac41a411e07a6f3dc80dfbd33f6be70ea0abd72e99c59310819d09f07d945"},
|
||||||
{file = "rapidfuzz-3.10.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c4c82b1689b23b1b5e6a603164ed2be41b6f6de292a698b98ba2381e889eb9d"},
|
{file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:958473c9f0bca250590200fd520b75be0dbdbc4a7327dc87a55b6d7dc8d68552"},
|
||||||
{file = "rapidfuzz-3.10.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:98f6ebe28831a482981ecfeedc8237047878424ad0c1add2c7f366ba44a20452"},
|
{file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ef60dfa73749ef91cb6073be1a3e135f4846ec809cc115f3cbfc6fe283a5584"},
|
||||||
{file = "rapidfuzz-3.10.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4bd1a7676ee2a4c8e2f7f2550bece994f9f89e58afb96088964145a83af7408b"},
|
{file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7fbac18f2c19fc983838a60611e67e3262e36859994c26f2ee85bb268de2355"},
|
||||||
{file = "rapidfuzz-3.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec9139baa3f85b65adc700eafa03ed04995ca8533dd56c924f0e458ffec044ab"},
|
{file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a0d519ff39db887cd73f4e297922786d548f5c05d6b51f4e6754f452a7f4296"},
|
||||||
{file = "rapidfuzz-3.10.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:26de93e6495078b6af4c4d93a42ca067b16cc0e95699526c82ab7d1025b4d3bf"},
|
{file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bebb7bc6aeb91cc57e4881b222484c26759ca865794187217c9dcea6c33adae6"},
|
||||||
{file = "rapidfuzz-3.10.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f3a0bda83c18195c361b5500377d0767749f128564ca95b42c8849fd475bb327"},
|
{file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fe07f8b9c3bb5c5ad1d2c66884253e03800f4189a60eb6acd6119ebaf3eb9894"},
|
||||||
{file = "rapidfuzz-3.10.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:63e4c175cbce8c3adc22dca5e6154588ae673f6c55374d156f3dac732c88d7de"},
|
{file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:bfa48a4a2d45a41457f0840c48e579db157a927f4e97acf6e20df8fc521c79de"},
|
||||||
{file = "rapidfuzz-3.10.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4dd3d8443970eaa02ab5ae45ce584b061f2799cd9f7e875190e2617440c1f9d4"},
|
{file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2cf44d01bfe8ee605b7eaeecbc2b9ca64fc55765f17b304b40ed8995f69d7716"},
|
||||||
{file = "rapidfuzz-3.10.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e5ddb2388610799fc46abe389600625058f2a73867e63e20107c5ad5ffa57c47"},
|
{file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1e6bbca9246d9eedaa1c84e04a7f555493ba324d52ae4d9f3d9ddd1b740dcd87"},
|
||||||
{file = "rapidfuzz-3.10.0-cp39-cp39-win32.whl", hash = "sha256:2e9be5d05cd960914024412b5406fb75a82f8562f45912ff86255acbfdbfb78e"},
|
{file = "rapidfuzz-3.10.1-cp39-cp39-win32.whl", hash = "sha256:567f88180f2c1423b4fe3f3ad6e6310fc97b85bdba574801548597287fc07028"},
|
||||||
{file = "rapidfuzz-3.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:47aca565a39c9a6067927871973ca827023e8b65ba6c5747f4c228c8d7ddc04f"},
|
{file = "rapidfuzz-3.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:6b2cd7c29d6ecdf0b780deb587198f13213ac01c430ada6913452fd0c40190fc"},
|
||||||
{file = "rapidfuzz-3.10.0-cp39-cp39-win_arm64.whl", hash = "sha256:b0732343cdc4273b5921268026dd7266f75466eb21873cb7635a200d9d9c3fac"},
|
{file = "rapidfuzz-3.10.1-cp39-cp39-win_arm64.whl", hash = "sha256:9f912d459e46607ce276128f52bea21ebc3e9a5ccf4cccfef30dd5bddcf47be8"},
|
||||||
{file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f744b5eb1469bf92dd143d36570d2bdbbdc88fe5cb0b5405e53dd34f479cbd8a"},
|
{file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ac4452f182243cfab30ba4668ef2de101effaedc30f9faabb06a095a8c90fd16"},
|
||||||
{file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b67cc21a14327a0eb0f47bc3d7e59ec08031c7c55220ece672f9476e7a8068d3"},
|
{file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:565c2bd4f7d23c32834652b27b51dd711814ab614b4e12add8476be4e20d1cf5"},
|
||||||
{file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fe5783676f0afba4a522c80b15e99dbf4e393c149ab610308a8ef1f04c6bcc8"},
|
{file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:187d9747149321607be4ccd6f9f366730078bed806178ec3eeb31d05545e9e8f"},
|
||||||
{file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4688862f957c8629d557d084f20b2d803f8738b6c4066802a0b1cc472e088d9"},
|
{file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:616290fb9a8fa87e48cb0326d26f98d4e29f17c3b762c2d586f2b35c1fd2034b"},
|
||||||
{file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20bd153aacc244e4c907d772c703fea82754c4db14f8aa64d75ff81b7b8ab92d"},
|
{file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:073a5b107e17ebd264198b78614c0206fa438cce749692af5bc5f8f484883f50"},
|
||||||
{file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:50484d563f8bfa723c74c944b0bb15b9e054db9c889348c8c307abcbee75ab92"},
|
{file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:39c4983e2e2ccb9732f3ac7d81617088822f4a12291d416b09b8a1eadebb3e29"},
|
||||||
{file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5897242d455461f2c5b82d7397b29341fd11e85bf3608a522177071044784ee8"},
|
{file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ac7adee6bcf0c6fee495d877edad1540a7e0f5fc208da03ccb64734b43522d7a"},
|
||||||
{file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:116c71a81e046ba56551d8ab68067ca7034d94b617545316d460a452c5c3c289"},
|
{file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:425f4ac80b22153d391ee3f94bc854668a0c6c129f05cf2eaf5ee74474ddb69e"},
|
||||||
{file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0a547e4350d1fa32624d3eab51eff8cf329f4cae110b4ea0402486b1da8be40"},
|
{file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65a2fa13e8a219f9b5dcb9e74abe3ced5838a7327e629f426d333dfc8c5a6e66"},
|
||||||
{file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:399b9b79ccfcf50ca3bad7692bc098bb8eade88d7d5e15773b7f866c91156d0c"},
|
{file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:75561f3df9a906aaa23787e9992b228b1ab69007932dc42070f747103e177ba8"},
|
||||||
{file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7947a425d1be3e744707ee58c6cb318b93a56e08f080722dcc0347e0b7a1bb9a"},
|
{file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:edd062490537e97ca125bc6c7f2b7331c2b73d21dc304615afe61ad1691e15d5"},
|
||||||
{file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:94c48b4a2a4b1d22246f48e2b11cae01ec7d23f0c9123f8bb822839ad79d0a88"},
|
{file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfcc8feccf63245a22dfdd16e222f1a39771a44b870beb748117a0e09cbb4a62"},
|
||||||
{file = "rapidfuzz-3.10.0.tar.gz", hash = "sha256:6b62af27e65bb39276a66533655a2fa3c60a487b03935721c45b7809527979be"},
|
{file = "rapidfuzz-3.10.1.tar.gz", hash = "sha256:5a15546d847a915b3f42dc79ef9b0c78b998b4e2c53b252e7166284066585979"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
|
@ -8680,13 +8685,13 @@ test = ["accelerate (>=0.24.1,<=0.27.0)", "apache-airflow (==2.9.3)", "apache-ai
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sagemaker-core"
|
name = "sagemaker-core"
|
||||||
version = "1.0.10"
|
version = "1.0.11"
|
||||||
description = "An python package for sagemaker core functionalities"
|
description = "An python package for sagemaker core functionalities"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "sagemaker_core-1.0.10-py3-none-any.whl", hash = "sha256:0bdcf6a467db988919cc6b6d0077f74871ee24c24adf7f759f9cb98460e08953"},
|
{file = "sagemaker_core-1.0.11-py3-none-any.whl", hash = "sha256:d8ee3db83759073aa8c9f2bd4899113088a7c2acf340597e76cf9934e384d915"},
|
||||||
{file = "sagemaker_core-1.0.10.tar.gz", hash = "sha256:6d34a9b6dc5e17e8bfffd1d0650726865779c92b3b8f1b59fc15d42061a0dd29"},
|
{file = "sagemaker_core-1.0.11.tar.gz", hash = "sha256:fb48a5dcb859a54de7461c71cf58562a3be259294dcd39c317020a9b018f5016"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -8735,6 +8740,11 @@ files = [
|
||||||
{file = "scikit_learn-1.5.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f60021ec1574e56632be2a36b946f8143bf4e5e6af4a06d85281adc22938e0dd"},
|
{file = "scikit_learn-1.5.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f60021ec1574e56632be2a36b946f8143bf4e5e6af4a06d85281adc22938e0dd"},
|
||||||
{file = "scikit_learn-1.5.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:394397841449853c2290a32050382edaec3da89e35b3e03d6cc966aebc6a8ae6"},
|
{file = "scikit_learn-1.5.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:394397841449853c2290a32050382edaec3da89e35b3e03d6cc966aebc6a8ae6"},
|
||||||
{file = "scikit_learn-1.5.2-cp312-cp312-win_amd64.whl", hash = "sha256:57cc1786cfd6bd118220a92ede80270132aa353647684efa385a74244a41e3b1"},
|
{file = "scikit_learn-1.5.2-cp312-cp312-win_amd64.whl", hash = "sha256:57cc1786cfd6bd118220a92ede80270132aa353647684efa385a74244a41e3b1"},
|
||||||
|
{file = "scikit_learn-1.5.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9a702e2de732bbb20d3bad29ebd77fc05a6b427dc49964300340e4c9328b3f5"},
|
||||||
|
{file = "scikit_learn-1.5.2-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:b0768ad641981f5d3a198430a1d31c3e044ed2e8a6f22166b4d546a5116d7908"},
|
||||||
|
{file = "scikit_learn-1.5.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:178ddd0a5cb0044464fc1bfc4cca5b1833bfc7bb022d70b05db8530da4bb3dd3"},
|
||||||
|
{file = "scikit_learn-1.5.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7284ade780084d94505632241bf78c44ab3b6f1e8ccab3d2af58e0e950f9c12"},
|
||||||
|
{file = "scikit_learn-1.5.2-cp313-cp313-win_amd64.whl", hash = "sha256:b7b0f9a0b1040830d38c39b91b3a44e1b643f4b36e36567b80b7c6bd2202a27f"},
|
||||||
{file = "scikit_learn-1.5.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:757c7d514ddb00ae249832fe87100d9c73c6ea91423802872d9e74970a0e40b9"},
|
{file = "scikit_learn-1.5.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:757c7d514ddb00ae249832fe87100d9c73c6ea91423802872d9e74970a0e40b9"},
|
||||||
{file = "scikit_learn-1.5.2-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:52788f48b5d8bca5c0736c175fa6bdaab2ef00a8f536cda698db61bd89c551c1"},
|
{file = "scikit_learn-1.5.2-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:52788f48b5d8bca5c0736c175fa6bdaab2ef00a8f536cda698db61bd89c551c1"},
|
||||||
{file = "scikit_learn-1.5.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:643964678f4b5fbdc95cbf8aec638acc7aa70f5f79ee2cdad1eec3df4ba6ead8"},
|
{file = "scikit_learn-1.5.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:643964678f4b5fbdc95cbf8aec638acc7aa70f5f79ee2cdad1eec3df4ba6ead8"},
|
||||||
|
@ -8860,23 +8870,23 @@ tornado = ["tornado (>=5)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "setuptools"
|
name = "setuptools"
|
||||||
version = "75.2.0"
|
version = "75.3.0"
|
||||||
description = "Easily download, build, install, upgrade, and uninstall Python packages"
|
description = "Easily download, build, install, upgrade, and uninstall Python packages"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"},
|
{file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"},
|
||||||
{file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"},
|
{file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"]
|
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"]
|
||||||
core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"]
|
core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"]
|
||||||
cover = ["pytest-cov"]
|
cover = ["pytest-cov"]
|
||||||
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
|
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
|
||||||
enabler = ["pytest-enabler (>=2.2)"]
|
enabler = ["pytest-enabler (>=2.2)"]
|
||||||
test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
|
test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
|
||||||
type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"]
|
type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sgmllib3k"
|
name = "sgmllib3k"
|
||||||
|
@ -9625,13 +9635,13 @@ six = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tqdm"
|
name = "tqdm"
|
||||||
version = "4.66.5"
|
version = "4.66.6"
|
||||||
description = "Fast, Extensible Progress Meter"
|
description = "Fast, Extensible Progress Meter"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
files = [
|
files = [
|
||||||
{file = "tqdm-4.66.5-py3-none-any.whl", hash = "sha256:90279a3770753eafc9194a0364852159802111925aa30eb3f9d85b0e805ac7cd"},
|
{file = "tqdm-4.66.6-py3-none-any.whl", hash = "sha256:223e8b5359c2efc4b30555531f09e9f2f3589bcd7fdd389271191031b49b7a63"},
|
||||||
{file = "tqdm-4.66.5.tar.gz", hash = "sha256:e1020aef2e5096702d8a025ac7d16b1577279c9d63f8375b63083e9a5f0fcbad"},
|
{file = "tqdm-4.66.6.tar.gz", hash = "sha256:4bdd694238bef1485ce839d67967ab50af8f9272aab687c0d7702a01da0be090"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -9885,13 +9895,13 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unstructured"
|
name = "unstructured"
|
||||||
version = "0.16.1"
|
version = "0.16.3"
|
||||||
description = "A library that prepares raw documents for downstream ML tasks."
|
description = "A library that prepares raw documents for downstream ML tasks."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "<3.13,>=3.9.0"
|
python-versions = "<3.13,>=3.9.0"
|
||||||
files = [
|
files = [
|
||||||
{file = "unstructured-0.16.1-py3-none-any.whl", hash = "sha256:7512281a2917809a563cbb186876b77d5a361e1f3089eca61e9219aecd1218f9"},
|
{file = "unstructured-0.16.3-py3-none-any.whl", hash = "sha256:e0e3b56531b44e62154d17cbfdae7fd7fa1d795b7cf510fb654c6714d4257655"},
|
||||||
{file = "unstructured-0.16.1.tar.gz", hash = "sha256:03608b5189a004412cd618ce2d083ff926c56dbbca41b41c92e08ffa9e2bac3a"},
|
{file = "unstructured-0.16.3.tar.gz", hash = "sha256:f9528636773c910a53c8a34e32d4733ea54b79cbd507d0e956e299ab1da3003f"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -9922,19 +9932,19 @@ unstructured-client = "*"
|
||||||
wrapt = "*"
|
wrapt = "*"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
all-docs = ["effdet", "google-cloud-vision", "markdown", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pi-heif", "pikepdf", "pypandoc", "pypdf", "python-docx (>=1.1.2)", "python-pptx (>=1.0.1)", "unstructured-inference (==0.8.0)", "unstructured.pytesseract (>=0.3.12)", "xlrd"]
|
all-docs = ["effdet", "google-cloud-vision", "markdown", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pi-heif", "pikepdf", "pypandoc", "pypdf", "python-docx (>=1.1.2)", "python-pptx (>=1.0.1)", "unstructured-inference (==0.8.1)", "unstructured.pytesseract (>=0.3.12)", "xlrd"]
|
||||||
csv = ["pandas"]
|
csv = ["pandas"]
|
||||||
doc = ["python-docx (>=1.1.2)"]
|
doc = ["python-docx (>=1.1.2)"]
|
||||||
docx = ["python-docx (>=1.1.2)"]
|
docx = ["python-docx (>=1.1.2)"]
|
||||||
epub = ["pypandoc"]
|
epub = ["pypandoc"]
|
||||||
huggingface = ["langdetect", "sacremoses", "sentencepiece", "torch", "transformers"]
|
huggingface = ["langdetect", "sacremoses", "sentencepiece", "torch", "transformers"]
|
||||||
image = ["effdet", "google-cloud-vision", "onnx", "pdf2image", "pdfminer.six", "pi-heif", "pikepdf", "pypdf", "unstructured-inference (==0.8.0)", "unstructured.pytesseract (>=0.3.12)"]
|
image = ["effdet", "google-cloud-vision", "onnx", "pdf2image", "pdfminer.six", "pi-heif", "pikepdf", "pypdf", "unstructured-inference (==0.8.1)", "unstructured.pytesseract (>=0.3.12)"]
|
||||||
local-inference = ["effdet", "google-cloud-vision", "markdown", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pi-heif", "pikepdf", "pypandoc", "pypdf", "python-docx (>=1.1.2)", "python-pptx (>=1.0.1)", "unstructured-inference (==0.8.0)", "unstructured.pytesseract (>=0.3.12)", "xlrd"]
|
local-inference = ["effdet", "google-cloud-vision", "markdown", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pi-heif", "pikepdf", "pypandoc", "pypdf", "python-docx (>=1.1.2)", "python-pptx (>=1.0.1)", "unstructured-inference (==0.8.1)", "unstructured.pytesseract (>=0.3.12)", "xlrd"]
|
||||||
md = ["markdown"]
|
md = ["markdown"]
|
||||||
odt = ["pypandoc", "python-docx (>=1.1.2)"]
|
odt = ["pypandoc", "python-docx (>=1.1.2)"]
|
||||||
org = ["pypandoc"]
|
org = ["pypandoc"]
|
||||||
paddleocr = ["paddlepaddle (==3.0.0b1)", "unstructured.paddleocr (==2.8.1.0)"]
|
paddleocr = ["paddlepaddle (==3.0.0b1)", "unstructured.paddleocr (==2.8.1.0)"]
|
||||||
pdf = ["effdet", "google-cloud-vision", "onnx", "pdf2image", "pdfminer.six", "pi-heif", "pikepdf", "pypdf", "unstructured-inference (==0.8.0)", "unstructured.pytesseract (>=0.3.12)"]
|
pdf = ["effdet", "google-cloud-vision", "onnx", "pdf2image", "pdfminer.six", "pi-heif", "pikepdf", "pypdf", "unstructured-inference (==0.8.1)", "unstructured.pytesseract (>=0.3.12)"]
|
||||||
ppt = ["python-pptx (>=1.0.1)"]
|
ppt = ["python-pptx (>=1.0.1)"]
|
||||||
pptx = ["python-pptx (>=1.0.1)"]
|
pptx = ["python-pptx (>=1.0.1)"]
|
||||||
rst = ["pypandoc"]
|
rst = ["pypandoc"]
|
||||||
|
@ -9944,13 +9954,13 @@ xlsx = ["networkx", "openpyxl", "pandas", "xlrd"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unstructured-client"
|
name = "unstructured-client"
|
||||||
version = "0.26.1"
|
version = "0.26.2"
|
||||||
description = "Python Client SDK for Unstructured API"
|
description = "Python Client SDK for Unstructured API"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "<4.0,>=3.8"
|
python-versions = "<4.0,>=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "unstructured_client-0.26.1-py3-none-any.whl", hash = "sha256:b8b839d477122bab3f37242cbe44b39f7eb7b564b07b53500321f953710119b6"},
|
{file = "unstructured_client-0.26.2-py3-none-any.whl", hash = "sha256:0adb22b7d175814f333ee2425a279005f253220a55f459fd5830a6779b679780"},
|
||||||
{file = "unstructured_client-0.26.1.tar.gz", hash = "sha256:907cceb470529b45b0fddb2d0f1bbf4d6568f347c757ab68639a7bb620ec2484"},
|
{file = "unstructured_client-0.26.2.tar.gz", hash = "sha256:02f7183ab16db6ec48ad1ac75c01b05967c87c561a89e96d9ffb836baed902d7"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -10445,13 +10455,13 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "werkzeug"
|
name = "werkzeug"
|
||||||
version = "3.0.4"
|
version = "3.0.6"
|
||||||
description = "The comprehensive WSGI web application library."
|
description = "The comprehensive WSGI web application library."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "werkzeug-3.0.4-py3-none-any.whl", hash = "sha256:02c9eb92b7d6c06f31a782811505d2157837cea66aaede3e217c7c27c039476c"},
|
{file = "werkzeug-3.0.6-py3-none-any.whl", hash = "sha256:1bc0c2310d2fbb07b1dd1105eba2f7af72f322e1e455f2f93c993bee8c8a5f17"},
|
||||||
{file = "werkzeug-3.0.4.tar.gz", hash = "sha256:34f2371506b250df4d4f84bfe7b0921e4762525762bbd936614909fe25cd7306"},
|
{file = "werkzeug-3.0.6.tar.gz", hash = "sha256:a8dd59d4de28ca70471a34cba79bed5f7ef2e036a76b3ab0835474246eb41f8d"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -10745,13 +10755,13 @@ multidict = ">=4.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yfinance"
|
name = "yfinance"
|
||||||
version = "0.2.46"
|
version = "0.2.48"
|
||||||
description = "Download market data from Yahoo! Finance API"
|
description = "Download market data from Yahoo! Finance API"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
files = [
|
files = [
|
||||||
{file = "yfinance-0.2.46-py2.py3-none-any.whl", hash = "sha256:371860d532cae76605195678a540e29382bfd0607f8aa61695f753e714916ffc"},
|
{file = "yfinance-0.2.48-py2.py3-none-any.whl", hash = "sha256:eda797145faa4536595eb629f869d3616e58ed7e71de36856b19f1abaef71a5b"},
|
||||||
{file = "yfinance-0.2.46.tar.gz", hash = "sha256:a6e2a128915532a54b8f6614cfdb7a8c242d2386e05f95c89b15865b5d9c0352"},
|
{file = "yfinance-0.2.48.tar.gz", hash = "sha256:1434cd8bf22f345fa27ef1ed82bfdd291c1bb5b6fe3067118a94e256aa90c4eb"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -10995,4 +11005,4 @@ cffi = ["cffi (>=1.11)"]
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = ">=3.10,<3.13"
|
python-versions = ">=3.10,<3.13"
|
||||||
content-hash = "bb8385625eb61de086b7a7156745066b4fb171d9ca67afd1d092fa7e872f3abd"
|
content-hash = "f20bd678044926913dbbc24bd0cf22503a75817aa55f59457ff7822032139b77"
|
||||||
|
|
|
@ -118,7 +118,7 @@ beautifulsoup4 = "4.12.2"
|
||||||
boto3 = "1.35.17"
|
boto3 = "1.35.17"
|
||||||
bs4 = "~0.0.1"
|
bs4 = "~0.0.1"
|
||||||
cachetools = "~5.3.0"
|
cachetools = "~5.3.0"
|
||||||
celery = "~5.3.6"
|
celery = "~5.4.0"
|
||||||
chardet = "~5.1.0"
|
chardet = "~5.1.0"
|
||||||
cohere = "~5.2.4"
|
cohere = "~5.2.4"
|
||||||
dashscope = { version = "~1.17.0", extras = ["tokenizer"] }
|
dashscope = { version = "~1.17.0", extras = ["tokenizer"] }
|
||||||
|
|
|
@ -12,6 +12,8 @@ from models.dataset import TidbAuthBinding
|
||||||
@app.celery.task(queue="dataset")
|
@app.celery.task(queue="dataset")
|
||||||
def create_tidb_serverless_task():
|
def create_tidb_serverless_task():
|
||||||
click.echo(click.style("Start create tidb serverless task.", fg="green"))
|
click.echo(click.style("Start create tidb serverless task.", fg="green"))
|
||||||
|
if not dify_config.CREATE_TIDB_SERVICE_JOB_ENABLED:
|
||||||
|
return
|
||||||
tidb_serverless_number = dify_config.TIDB_SERVERLESS_NUMBER
|
tidb_serverless_number = dify_config.TIDB_SERVERLESS_NUMBER
|
||||||
start_at = time.perf_counter()
|
start_at = time.perf_counter()
|
||||||
while True:
|
while True:
|
||||||
|
|
|
@ -14,8 +14,6 @@ from configs import dify_config
|
||||||
from core.errors.error import LLMBadRequestError, ProviderTokenNotInitError
|
from core.errors.error import LLMBadRequestError, ProviderTokenNotInitError
|
||||||
from core.model_manager import ModelManager
|
from core.model_manager import ModelManager
|
||||||
from core.model_runtime.entities.model_entities import ModelType
|
from core.model_runtime.entities.model_entities import ModelType
|
||||||
from core.rag.datasource.keyword.keyword_factory import Keyword
|
|
||||||
from core.rag.models.document import Document as RAGDocument
|
|
||||||
from core.rag.retrieval.retrieval_methods import RetrievalMethod
|
from core.rag.retrieval.retrieval_methods import RetrievalMethod
|
||||||
from events.dataset_event import dataset_was_deleted
|
from events.dataset_event import dataset_was_deleted
|
||||||
from events.document_event import document_was_deleted
|
from events.document_event import document_was_deleted
|
||||||
|
@ -37,6 +35,7 @@ from models.dataset import (
|
||||||
)
|
)
|
||||||
from models.model import UploadFile
|
from models.model import UploadFile
|
||||||
from models.source import DataSourceOauthBinding
|
from models.source import DataSourceOauthBinding
|
||||||
|
from services.entities.knowledge_entities.knowledge_entities import SegmentUpdateEntity
|
||||||
from services.errors.account import NoPermissionError
|
from services.errors.account import NoPermissionError
|
||||||
from services.errors.dataset import DatasetNameDuplicateError
|
from services.errors.dataset import DatasetNameDuplicateError
|
||||||
from services.errors.document import DocumentIndexingError
|
from services.errors.document import DocumentIndexingError
|
||||||
|
@ -1415,9 +1414,13 @@ class SegmentService:
|
||||||
created_by=current_user.id,
|
created_by=current_user.id,
|
||||||
)
|
)
|
||||||
if document.doc_form == "qa_model":
|
if document.doc_form == "qa_model":
|
||||||
|
segment_document.word_count += len(args["answer"])
|
||||||
segment_document.answer = args["answer"]
|
segment_document.answer = args["answer"]
|
||||||
|
|
||||||
db.session.add(segment_document)
|
db.session.add(segment_document)
|
||||||
|
# update document word count
|
||||||
|
document.word_count += segment_document.word_count
|
||||||
|
db.session.add(document)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
# save vector index
|
# save vector index
|
||||||
|
@ -1436,6 +1439,7 @@ class SegmentService:
|
||||||
@classmethod
|
@classmethod
|
||||||
def multi_create_segment(cls, segments: list, document: Document, dataset: Dataset):
|
def multi_create_segment(cls, segments: list, document: Document, dataset: Dataset):
|
||||||
lock_name = "multi_add_segment_lock_document_id_{}".format(document.id)
|
lock_name = "multi_add_segment_lock_document_id_{}".format(document.id)
|
||||||
|
increment_word_count = 0
|
||||||
with redis_client.lock(lock_name, timeout=600):
|
with redis_client.lock(lock_name, timeout=600):
|
||||||
embedding_model = None
|
embedding_model = None
|
||||||
if dataset.indexing_technique == "high_quality":
|
if dataset.indexing_technique == "high_quality":
|
||||||
|
@ -1461,7 +1465,10 @@ class SegmentService:
|
||||||
tokens = 0
|
tokens = 0
|
||||||
if dataset.indexing_technique == "high_quality" and embedding_model:
|
if dataset.indexing_technique == "high_quality" and embedding_model:
|
||||||
# calc embedding use tokens
|
# calc embedding use tokens
|
||||||
tokens = embedding_model.get_text_embedding_num_tokens(texts=[content])
|
if document.doc_form == "qa_model":
|
||||||
|
tokens = embedding_model.get_text_embedding_num_tokens(texts=[content + segment_item["answer"]])
|
||||||
|
else:
|
||||||
|
tokens = embedding_model.get_text_embedding_num_tokens(texts=[content])
|
||||||
segment_document = DocumentSegment(
|
segment_document = DocumentSegment(
|
||||||
tenant_id=current_user.current_tenant_id,
|
tenant_id=current_user.current_tenant_id,
|
||||||
dataset_id=document.dataset_id,
|
dataset_id=document.dataset_id,
|
||||||
|
@ -1479,6 +1486,8 @@ class SegmentService:
|
||||||
)
|
)
|
||||||
if document.doc_form == "qa_model":
|
if document.doc_form == "qa_model":
|
||||||
segment_document.answer = segment_item["answer"]
|
segment_document.answer = segment_item["answer"]
|
||||||
|
segment_document.word_count += len(segment_item["answer"])
|
||||||
|
increment_word_count += segment_document.word_count
|
||||||
db.session.add(segment_document)
|
db.session.add(segment_document)
|
||||||
segment_data_list.append(segment_document)
|
segment_data_list.append(segment_document)
|
||||||
|
|
||||||
|
@ -1487,7 +1496,9 @@ class SegmentService:
|
||||||
keywords_list.append(segment_item["keywords"])
|
keywords_list.append(segment_item["keywords"])
|
||||||
else:
|
else:
|
||||||
keywords_list.append(None)
|
keywords_list.append(None)
|
||||||
|
# update document word count
|
||||||
|
document.word_count += increment_word_count
|
||||||
|
db.session.add(document)
|
||||||
try:
|
try:
|
||||||
# save vector index
|
# save vector index
|
||||||
VectorService.create_segments_vector(keywords_list, pre_segment_data_list, dataset)
|
VectorService.create_segments_vector(keywords_list, pre_segment_data_list, dataset)
|
||||||
|
@ -1503,12 +1514,13 @@ class SegmentService:
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def update_segment(cls, args: dict, segment: DocumentSegment, document: Document, dataset: Dataset):
|
def update_segment(cls, args: dict, segment: DocumentSegment, document: Document, dataset: Dataset):
|
||||||
|
segment_update_entity = SegmentUpdateEntity(**args)
|
||||||
indexing_cache_key = "segment_{}_indexing".format(segment.id)
|
indexing_cache_key = "segment_{}_indexing".format(segment.id)
|
||||||
cache_result = redis_client.get(indexing_cache_key)
|
cache_result = redis_client.get(indexing_cache_key)
|
||||||
if cache_result is not None:
|
if cache_result is not None:
|
||||||
raise ValueError("Segment is indexing, please try again later")
|
raise ValueError("Segment is indexing, please try again later")
|
||||||
if "enabled" in args and args["enabled"] is not None:
|
if segment_update_entity.enabled is not None:
|
||||||
action = args["enabled"]
|
action = segment_update_entity.enabled
|
||||||
if segment.enabled != action:
|
if segment.enabled != action:
|
||||||
if not action:
|
if not action:
|
||||||
segment.enabled = action
|
segment.enabled = action
|
||||||
|
@ -1521,37 +1533,34 @@ class SegmentService:
|
||||||
disable_segment_from_index_task.delay(segment.id)
|
disable_segment_from_index_task.delay(segment.id)
|
||||||
return segment
|
return segment
|
||||||
if not segment.enabled:
|
if not segment.enabled:
|
||||||
if "enabled" in args and args["enabled"] is not None:
|
if segment_update_entity.enabled is not None:
|
||||||
if not args["enabled"]:
|
if not segment_update_entity.enabled:
|
||||||
raise ValueError("Can't update disabled segment")
|
raise ValueError("Can't update disabled segment")
|
||||||
else:
|
else:
|
||||||
raise ValueError("Can't update disabled segment")
|
raise ValueError("Can't update disabled segment")
|
||||||
try:
|
try:
|
||||||
content = args["content"]
|
word_count_change = segment.word_count
|
||||||
|
content = segment_update_entity.content
|
||||||
if segment.content == content:
|
if segment.content == content:
|
||||||
|
segment.word_count = len(content)
|
||||||
if document.doc_form == "qa_model":
|
if document.doc_form == "qa_model":
|
||||||
segment.answer = args["answer"]
|
segment.answer = segment_update_entity.answer
|
||||||
if args.get("keywords"):
|
segment.word_count += len(segment_update_entity.answer)
|
||||||
segment.keywords = args["keywords"]
|
word_count_change = segment.word_count - word_count_change
|
||||||
|
if segment_update_entity.keywords:
|
||||||
|
segment.keywords = segment_update_entity.keywords
|
||||||
segment.enabled = True
|
segment.enabled = True
|
||||||
segment.disabled_at = None
|
segment.disabled_at = None
|
||||||
segment.disabled_by = None
|
segment.disabled_by = None
|
||||||
db.session.add(segment)
|
db.session.add(segment)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
# update document word count
|
||||||
|
if word_count_change != 0:
|
||||||
|
document.word_count = max(0, document.word_count + word_count_change)
|
||||||
|
db.session.add(document)
|
||||||
# update segment index task
|
# update segment index task
|
||||||
if "keywords" in args:
|
if segment_update_entity.enabled:
|
||||||
keyword = Keyword(dataset)
|
VectorService.create_segments_vector([segment_update_entity.keywords], [segment], dataset)
|
||||||
keyword.delete_by_ids([segment.index_node_id])
|
|
||||||
document = RAGDocument(
|
|
||||||
page_content=segment.content,
|
|
||||||
metadata={
|
|
||||||
"doc_id": segment.index_node_id,
|
|
||||||
"doc_hash": segment.index_node_hash,
|
|
||||||
"document_id": segment.document_id,
|
|
||||||
"dataset_id": segment.dataset_id,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
keyword.add_texts([document], keywords_list=[args["keywords"]])
|
|
||||||
else:
|
else:
|
||||||
segment_hash = helper.generate_text_hash(content)
|
segment_hash = helper.generate_text_hash(content)
|
||||||
tokens = 0
|
tokens = 0
|
||||||
|
@ -1565,7 +1574,10 @@ class SegmentService:
|
||||||
)
|
)
|
||||||
|
|
||||||
# calc embedding use tokens
|
# calc embedding use tokens
|
||||||
tokens = embedding_model.get_text_embedding_num_tokens(texts=[content])
|
if document.doc_form == "qa_model":
|
||||||
|
tokens = embedding_model.get_text_embedding_num_tokens(texts=[content + segment.answer])
|
||||||
|
else:
|
||||||
|
tokens = embedding_model.get_text_embedding_num_tokens(texts=[content])
|
||||||
segment.content = content
|
segment.content = content
|
||||||
segment.index_node_hash = segment_hash
|
segment.index_node_hash = segment_hash
|
||||||
segment.word_count = len(content)
|
segment.word_count = len(content)
|
||||||
|
@ -1579,11 +1591,17 @@ class SegmentService:
|
||||||
segment.disabled_at = None
|
segment.disabled_at = None
|
||||||
segment.disabled_by = None
|
segment.disabled_by = None
|
||||||
if document.doc_form == "qa_model":
|
if document.doc_form == "qa_model":
|
||||||
segment.answer = args["answer"]
|
segment.answer = segment_update_entity.answer
|
||||||
|
segment.word_count += len(segment_update_entity.answer)
|
||||||
|
word_count_change = segment.word_count - word_count_change
|
||||||
|
# update document word count
|
||||||
|
if word_count_change != 0:
|
||||||
|
document.word_count = max(0, document.word_count + word_count_change)
|
||||||
|
db.session.add(document)
|
||||||
db.session.add(segment)
|
db.session.add(segment)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
# update segment vector index
|
# update segment vector index
|
||||||
VectorService.update_segment_vector(args["keywords"], segment, dataset)
|
VectorService.update_segment_vector(segment_update_entity.keywords, segment, dataset)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.exception("update segment index failed")
|
logging.exception("update segment index failed")
|
||||||
|
@ -1608,6 +1626,9 @@ class SegmentService:
|
||||||
redis_client.setex(indexing_cache_key, 600, 1)
|
redis_client.setex(indexing_cache_key, 600, 1)
|
||||||
delete_segment_from_index_task.delay(segment.id, segment.index_node_id, dataset.id, document.id)
|
delete_segment_from_index_task.delay(segment.id, segment.index_node_id, dataset.id, document.id)
|
||||||
db.session.delete(segment)
|
db.session.delete(segment)
|
||||||
|
# update document word count
|
||||||
|
document.word_count -= segment.word_count
|
||||||
|
db.session.add(document)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
|
||||||
|
class SegmentUpdateEntity(BaseModel):
|
||||||
|
content: str
|
||||||
|
answer: Optional[str] = None
|
||||||
|
keywords: Optional[list[str]] = None
|
||||||
|
enabled: Optional[bool] = None
|
|
@ -13,7 +13,7 @@ from core.app.app_config.entities import (
|
||||||
from core.app.apps.agent_chat.app_config_manager import AgentChatAppConfigManager
|
from core.app.apps.agent_chat.app_config_manager import AgentChatAppConfigManager
|
||||||
from core.app.apps.chat.app_config_manager import ChatAppConfigManager
|
from core.app.apps.chat.app_config_manager import ChatAppConfigManager
|
||||||
from core.app.apps.completion.app_config_manager import CompletionAppConfigManager
|
from core.app.apps.completion.app_config_manager import CompletionAppConfigManager
|
||||||
from core.file.models import FileExtraConfig
|
from core.file.models import FileUploadConfig
|
||||||
from core.helper import encrypter
|
from core.helper import encrypter
|
||||||
from core.model_runtime.entities.llm_entities import LLMMode
|
from core.model_runtime.entities.llm_entities import LLMMode
|
||||||
from core.model_runtime.utils.encoders import jsonable_encoder
|
from core.model_runtime.utils.encoders import jsonable_encoder
|
||||||
|
@ -381,7 +381,7 @@ class WorkflowConverter:
|
||||||
graph: dict,
|
graph: dict,
|
||||||
model_config: ModelConfigEntity,
|
model_config: ModelConfigEntity,
|
||||||
prompt_template: PromptTemplateEntity,
|
prompt_template: PromptTemplateEntity,
|
||||||
file_upload: Optional[FileExtraConfig] = None,
|
file_upload: Optional[FileUploadConfig] = None,
|
||||||
external_data_variable_node_mapping: dict[str, str] | None = None,
|
external_data_variable_node_mapping: dict[str, str] | None = None,
|
||||||
) -> dict:
|
) -> dict:
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -57,7 +57,7 @@ def batch_create_segment_to_index_task(
|
||||||
model_type=ModelType.TEXT_EMBEDDING,
|
model_type=ModelType.TEXT_EMBEDDING,
|
||||||
model=dataset.embedding_model,
|
model=dataset.embedding_model,
|
||||||
)
|
)
|
||||||
|
word_count_change = 0
|
||||||
for segment in content:
|
for segment in content:
|
||||||
content = segment["content"]
|
content = segment["content"]
|
||||||
doc_id = str(uuid.uuid4())
|
doc_id = str(uuid.uuid4())
|
||||||
|
@ -86,8 +86,13 @@ def batch_create_segment_to_index_task(
|
||||||
)
|
)
|
||||||
if dataset_document.doc_form == "qa_model":
|
if dataset_document.doc_form == "qa_model":
|
||||||
segment_document.answer = segment["answer"]
|
segment_document.answer = segment["answer"]
|
||||||
|
segment_document.word_count += len(segment["answer"])
|
||||||
|
word_count_change += segment_document.word_count
|
||||||
db.session.add(segment_document)
|
db.session.add(segment_document)
|
||||||
document_segments.append(segment_document)
|
document_segments.append(segment_document)
|
||||||
|
# update document word count
|
||||||
|
dataset_document.word_count += word_count_change
|
||||||
|
db.session.add(dataset_document)
|
||||||
# add index to db
|
# add index to db
|
||||||
indexing_runner = IndexingRunner()
|
indexing_runner = IndexingRunner()
|
||||||
indexing_runner.batch_add_segments(document_segments, dataset)
|
indexing_runner.batch_add_segments(document_segments, dataset)
|
||||||
|
|
|
@ -430,37 +430,3 @@ def test_multi_colons_parse(setup_http_mock):
|
||||||
assert urlencode({"Redirect": "http://example2.com"}) in result.process_data.get("request", "")
|
assert urlencode({"Redirect": "http://example2.com"}) in result.process_data.get("request", "")
|
||||||
assert 'form-data; name="Redirect"\r\n\r\nhttp://example6.com' in result.process_data.get("request", "")
|
assert 'form-data; name="Redirect"\r\n\r\nhttp://example6.com' in result.process_data.get("request", "")
|
||||||
# assert "http://example3.com" == resp.get("headers", {}).get("referer")
|
# assert "http://example3.com" == resp.get("headers", {}).get("referer")
|
||||||
|
|
||||||
|
|
||||||
def test_image_file(monkeypatch):
|
|
||||||
from types import SimpleNamespace
|
|
||||||
|
|
||||||
monkeypatch.setattr(
|
|
||||||
"core.tools.tool_file_manager.ToolFileManager.create_file_by_raw",
|
|
||||||
lambda *args, **kwargs: SimpleNamespace(id="1"),
|
|
||||||
)
|
|
||||||
|
|
||||||
node = init_http_node(
|
|
||||||
config={
|
|
||||||
"id": "1",
|
|
||||||
"data": {
|
|
||||||
"title": "http",
|
|
||||||
"desc": "",
|
|
||||||
"method": "get",
|
|
||||||
"url": "https://cloud.dify.ai/logo/logo-site.png",
|
|
||||||
"authorization": {
|
|
||||||
"type": "no-auth",
|
|
||||||
"config": None,
|
|
||||||
},
|
|
||||||
"params": "",
|
|
||||||
"headers": "",
|
|
||||||
"body": None,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
result = node._run()
|
|
||||||
assert result.process_data is not None
|
|
||||||
assert result.outputs is not None
|
|
||||||
resp = result.outputs
|
|
||||||
assert len(resp.get("files", [])) == 1
|
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
from core.app.app_config.features.file_upload.manager import FileUploadConfigManager
|
||||||
|
from core.file.models import FileTransferMethod, FileUploadConfig, ImageConfig
|
||||||
|
from core.model_runtime.entities.message_entities import ImagePromptMessageContent
|
||||||
|
|
||||||
|
|
||||||
|
def test_convert_with_vision():
|
||||||
|
config = {
|
||||||
|
"file_upload": {
|
||||||
|
"enabled": True,
|
||||||
|
"number_limits": 5,
|
||||||
|
"allowed_file_upload_methods": [FileTransferMethod.REMOTE_URL],
|
||||||
|
"image": {"detail": "high"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = FileUploadConfigManager.convert(config, is_vision=True)
|
||||||
|
expected = FileUploadConfig(
|
||||||
|
image_config=ImageConfig(
|
||||||
|
number_limits=5,
|
||||||
|
transfer_methods=[FileTransferMethod.REMOTE_URL],
|
||||||
|
detail=ImagePromptMessageContent.DETAIL.HIGH,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assert result == expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_convert_without_vision():
|
||||||
|
config = {
|
||||||
|
"file_upload": {
|
||||||
|
"enabled": True,
|
||||||
|
"number_limits": 5,
|
||||||
|
"allowed_file_upload_methods": [FileTransferMethod.REMOTE_URL],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = FileUploadConfigManager.convert(config, is_vision=False)
|
||||||
|
expected = FileUploadConfig(
|
||||||
|
image_config=ImageConfig(number_limits=5, transfer_methods=[FileTransferMethod.REMOTE_URL])
|
||||||
|
)
|
||||||
|
assert result == expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_validate_and_set_defaults():
|
||||||
|
config = {}
|
||||||
|
result, keys = FileUploadConfigManager.validate_and_set_defaults(config)
|
||||||
|
assert "file_upload" in result
|
||||||
|
assert keys == ["file_upload"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_validate_and_set_defaults_with_existing_config():
|
||||||
|
config = {
|
||||||
|
"file_upload": {
|
||||||
|
"enabled": True,
|
||||||
|
"number_limits": 5,
|
||||||
|
"allowed_file_upload_methods": [FileTransferMethod.REMOTE_URL],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result, keys = FileUploadConfigManager.validate_and_set_defaults(config)
|
||||||
|
assert "file_upload" in result
|
||||||
|
assert keys == ["file_upload"]
|
||||||
|
assert result["file_upload"]["enabled"] is True
|
||||||
|
assert result["file_upload"]["number_limits"] == 5
|
||||||
|
assert result["file_upload"]["allowed_file_upload_methods"] == [FileTransferMethod.REMOTE_URL]
|
|
@ -3,7 +3,7 @@ from unittest.mock import MagicMock, patch
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from core.app.app_config.entities import ModelConfigEntity
|
from core.app.app_config.entities import ModelConfigEntity
|
||||||
from core.file import File, FileExtraConfig, FileTransferMethod, FileType, ImageConfig
|
from core.file import File, FileTransferMethod, FileType, FileUploadConfig, ImageConfig
|
||||||
from core.memory.token_buffer_memory import TokenBufferMemory
|
from core.memory.token_buffer_memory import TokenBufferMemory
|
||||||
from core.model_runtime.entities.message_entities import (
|
from core.model_runtime.entities.message_entities import (
|
||||||
AssistantPromptMessage,
|
AssistantPromptMessage,
|
||||||
|
@ -134,7 +134,6 @@ def test__get_chat_model_prompt_messages_with_files_no_memory(get_chat_model_arg
|
||||||
type=FileType.IMAGE,
|
type=FileType.IMAGE,
|
||||||
transfer_method=FileTransferMethod.REMOTE_URL,
|
transfer_method=FileTransferMethod.REMOTE_URL,
|
||||||
remote_url="https://example.com/image1.jpg",
|
remote_url="https://example.com/image1.jpg",
|
||||||
_extra_config=FileExtraConfig(image_config=ImageConfig(detail=ImagePromptMessageContent.DETAIL.HIGH)),
|
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -384,6 +384,7 @@ services:
|
||||||
NOTION_INTERNAL_SECRET: you-internal-secret
|
NOTION_INTERNAL_SECRET: you-internal-secret
|
||||||
# Indexing configuration
|
# Indexing configuration
|
||||||
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: 1000
|
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: 1000
|
||||||
|
CREATE_TIDB_SERVICE_JOB_ENABLED: false
|
||||||
depends_on:
|
depends_on:
|
||||||
- db
|
- db
|
||||||
- redis
|
- redis
|
||||||
|
|
|
@ -54,6 +54,10 @@ LOG_FILE=
|
||||||
LOG_FILE_MAX_SIZE=20
|
LOG_FILE_MAX_SIZE=20
|
||||||
# Log file max backup count
|
# Log file max backup count
|
||||||
LOG_FILE_BACKUP_COUNT=5
|
LOG_FILE_BACKUP_COUNT=5
|
||||||
|
# Log dateformat
|
||||||
|
LOG_DATEFORMAT=%Y-%m-%d %H:%M:%S
|
||||||
|
# Log Timezone
|
||||||
|
LOG_TZ=UTC
|
||||||
|
|
||||||
# Debug mode, default is false.
|
# Debug mode, default is false.
|
||||||
# It is recommended to turn on this configuration for local development
|
# It is recommended to turn on this configuration for local development
|
||||||
|
@ -583,12 +587,13 @@ CODE_GENERATION_MAX_TOKENS=1024
|
||||||
# Multi-modal Configuration
|
# Multi-modal Configuration
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
|
|
||||||
# The format of the image sent when the multi-modal model is input,
|
# The format of the image/video sent when the multi-modal model is input,
|
||||||
# the default is base64, optional url.
|
# the default is base64, optional url.
|
||||||
# The delay of the call in url mode will be lower than that in base64 mode.
|
# The delay of the call in url mode will be lower than that in base64 mode.
|
||||||
# It is generally recommended to use the more compatible base64 mode.
|
# It is generally recommended to use the more compatible base64 mode.
|
||||||
# If configured as url, you need to configure FILES_URL as an externally accessible address so that the multi-modal model can access the image.
|
# If configured as url, you need to configure FILES_URL as an externally accessible address so that the multi-modal model can access the image/video.
|
||||||
MULTIMODAL_SEND_IMAGE_FORMAT=base64
|
MULTIMODAL_SEND_IMAGE_FORMAT=base64
|
||||||
|
MULTIMODAL_SEND_VIDEO_FORMAT=base64
|
||||||
|
|
||||||
# Upload image file size limit, default 10M.
|
# Upload image file size limit, default 10M.
|
||||||
UPLOAD_IMAGE_FILE_SIZE_LIMIT=10
|
UPLOAD_IMAGE_FILE_SIZE_LIMIT=10
|
||||||
|
@ -906,3 +911,6 @@ POSITION_PROVIDER_EXCLUDES=
|
||||||
|
|
||||||
# CSP https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
|
# CSP https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
|
||||||
CSP_WHITELIST=
|
CSP_WHITELIST=
|
||||||
|
|
||||||
|
# Enable or disable create tidb service job
|
||||||
|
CREATE_TIDB_SERVICE_JOB_ENABLED=false
|
|
@ -4,6 +4,10 @@ x-shared-env: &shared-api-worker-env
|
||||||
LOG_FILE: ${LOG_FILE:-}
|
LOG_FILE: ${LOG_FILE:-}
|
||||||
LOG_FILE_MAX_SIZE: ${LOG_FILE_MAX_SIZE:-20}
|
LOG_FILE_MAX_SIZE: ${LOG_FILE_MAX_SIZE:-20}
|
||||||
LOG_FILE_BACKUP_COUNT: ${LOG_FILE_BACKUP_COUNT:-5}
|
LOG_FILE_BACKUP_COUNT: ${LOG_FILE_BACKUP_COUNT:-5}
|
||||||
|
# Log dateformat
|
||||||
|
LOG_DATEFORMAT: ${LOG_DATEFORMAT:-%Y-%m-%d %H:%M:%S}
|
||||||
|
# Log Timezone
|
||||||
|
LOG_TZ: ${LOG_TZ:-UTC}
|
||||||
DEBUG: ${DEBUG:-false}
|
DEBUG: ${DEBUG:-false}
|
||||||
FLASK_DEBUG: ${FLASK_DEBUG:-false}
|
FLASK_DEBUG: ${FLASK_DEBUG:-false}
|
||||||
SECRET_KEY: ${SECRET_KEY:-sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U}
|
SECRET_KEY: ${SECRET_KEY:-sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U}
|
||||||
|
@ -214,6 +218,7 @@ x-shared-env: &shared-api-worker-env
|
||||||
PROMPT_GENERATION_MAX_TOKENS: ${PROMPT_GENERATION_MAX_TOKENS:-512}
|
PROMPT_GENERATION_MAX_TOKENS: ${PROMPT_GENERATION_MAX_TOKENS:-512}
|
||||||
CODE_GENERATION_MAX_TOKENS: ${CODE_GENERATION_MAX_TOKENS:-1024}
|
CODE_GENERATION_MAX_TOKENS: ${CODE_GENERATION_MAX_TOKENS:-1024}
|
||||||
MULTIMODAL_SEND_IMAGE_FORMAT: ${MULTIMODAL_SEND_IMAGE_FORMAT:-base64}
|
MULTIMODAL_SEND_IMAGE_FORMAT: ${MULTIMODAL_SEND_IMAGE_FORMAT:-base64}
|
||||||
|
MULTIMODAL_SEND_VIDEO_FORMAT: ${MULTIMODAL_SEND_VIDEO_FORMAT:-base64}
|
||||||
UPLOAD_IMAGE_FILE_SIZE_LIMIT: ${UPLOAD_IMAGE_FILE_SIZE_LIMIT:-10}
|
UPLOAD_IMAGE_FILE_SIZE_LIMIT: ${UPLOAD_IMAGE_FILE_SIZE_LIMIT:-10}
|
||||||
UPLOAD_VIDEO_FILE_SIZE_LIMIT: ${UPLOAD_VIDEO_FILE_SIZE_LIMIT:-100}
|
UPLOAD_VIDEO_FILE_SIZE_LIMIT: ${UPLOAD_VIDEO_FILE_SIZE_LIMIT:-100}
|
||||||
UPLOAD_AUDIO_FILE_SIZE_LIMIT: ${UPLOAD_AUDIO_FILE_SIZE_LIMIT:-50}
|
UPLOAD_AUDIO_FILE_SIZE_LIMIT: ${UPLOAD_AUDIO_FILE_SIZE_LIMIT:-50}
|
||||||
|
@ -270,6 +275,7 @@ x-shared-env: &shared-api-worker-env
|
||||||
OCEANBASE_VECTOR_DATABASE: ${OCEANBASE_VECTOR_DATABASE:-test}
|
OCEANBASE_VECTOR_DATABASE: ${OCEANBASE_VECTOR_DATABASE:-test}
|
||||||
OCEANBASE_CLUSTER_NAME: ${OCEANBASE_CLUSTER_NAME:-difyai}
|
OCEANBASE_CLUSTER_NAME: ${OCEANBASE_CLUSTER_NAME:-difyai}
|
||||||
OCEANBASE_MEMORY_LIMIT: ${OCEANBASE_MEMORY_LIMIT:-6G}
|
OCEANBASE_MEMORY_LIMIT: ${OCEANBASE_MEMORY_LIMIT:-6G}
|
||||||
|
CREATE_TIDB_SERVICE_JOB_ENABLED: ${CREATE_TIDB_SERVICE_JOB_ENABLED:-false}
|
||||||
|
|
||||||
services:
|
services:
|
||||||
# API service
|
# API service
|
||||||
|
|
|
@ -321,7 +321,9 @@ const baseFetch = <T>(
|
||||||
}
|
}
|
||||||
|
|
||||||
const urlPrefix = isPublicAPI ? PUBLIC_API_PREFIX : API_PREFIX
|
const urlPrefix = isPublicAPI ? PUBLIC_API_PREFIX : API_PREFIX
|
||||||
let urlWithPrefix = `${urlPrefix}${url.startsWith('/') ? url : `/${url}`}`
|
let urlWithPrefix = (url.startsWith('http://') || url.startsWith('https://'))
|
||||||
|
? url
|
||||||
|
: `${urlPrefix}${url.startsWith('/') ? url : `/${url}`}`
|
||||||
|
|
||||||
const { method, params, body } = options
|
const { method, params, body } = options
|
||||||
// handle query
|
// handle query
|
||||||
|
@ -494,7 +496,9 @@ export const ssePost = (
|
||||||
getAbortController?.(abortController)
|
getAbortController?.(abortController)
|
||||||
|
|
||||||
const urlPrefix = isPublicAPI ? PUBLIC_API_PREFIX : API_PREFIX
|
const urlPrefix = isPublicAPI ? PUBLIC_API_PREFIX : API_PREFIX
|
||||||
const urlWithPrefix = `${urlPrefix}${url.startsWith('/') ? url : `/${url}`}`
|
const urlWithPrefix = (url.startsWith('http://') || url.startsWith('https://'))
|
||||||
|
? url
|
||||||
|
: `${urlPrefix}${url.startsWith('/') ? url : `/${url}`}`
|
||||||
|
|
||||||
const { body } = options
|
const { body } = options
|
||||||
if (body)
|
if (body)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user