Merge pull request #226 from langflow-ai/tui-copy-flows
tui copies flows and v0.1.17 update
This commit is contained in:
commit
26018c0d37
19 changed files with 100 additions and 266 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -18,6 +18,8 @@ wheels/
|
||||||
1001*.pdf
|
1001*.pdf
|
||||||
*.json
|
*.json
|
||||||
!flows/*.json
|
!flows/*.json
|
||||||
|
!src/tui/_assets/flows/*.json
|
||||||
|
!src/tui/_assets/flows/components/*.json
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
config/
|
config/
|
||||||
|
|
|
||||||
|
|
@ -1,122 +0,0 @@
|
||||||
services:
|
|
||||||
opensearch:
|
|
||||||
image: phact/openrag-opensearch:${OPENRAG_VERSION:-latest}
|
|
||||||
#build:
|
|
||||||
# context: .
|
|
||||||
# dockerfile: Dockerfile
|
|
||||||
container_name: os
|
|
||||||
depends_on:
|
|
||||||
- openrag-backend
|
|
||||||
environment:
|
|
||||||
- discovery.type=single-node
|
|
||||||
- OPENSEARCH_INITIAL_ADMIN_PASSWORD=${OPENSEARCH_PASSWORD}
|
|
||||||
# Run security setup in background after OpenSearch starts
|
|
||||||
command: >
|
|
||||||
bash -c "
|
|
||||||
# Start OpenSearch in background
|
|
||||||
/usr/share/opensearch/opensearch-docker-entrypoint.sh opensearch &
|
|
||||||
|
|
||||||
# Wait a bit for OpenSearch to start, then apply security config
|
|
||||||
sleep 10 && /usr/share/opensearch/setup-security.sh &
|
|
||||||
|
|
||||||
# Wait for background processes
|
|
||||||
wait
|
|
||||||
"
|
|
||||||
ports:
|
|
||||||
- "9200:9200"
|
|
||||||
- "9600:9600"
|
|
||||||
|
|
||||||
dashboards:
|
|
||||||
image: opensearchproject/opensearch-dashboards:3.0.0
|
|
||||||
container_name: osdash
|
|
||||||
depends_on:
|
|
||||||
- opensearch
|
|
||||||
environment:
|
|
||||||
OPENSEARCH_HOSTS: '["https://opensearch:9200"]'
|
|
||||||
OPENSEARCH_USERNAME: "admin"
|
|
||||||
OPENSEARCH_PASSWORD: ${OPENSEARCH_PASSWORD}
|
|
||||||
ports:
|
|
||||||
- "5601:5601"
|
|
||||||
|
|
||||||
openrag-backend:
|
|
||||||
image: phact/openrag-backend:${OPENRAG_VERSION:-latest}
|
|
||||||
#build:
|
|
||||||
#context: .
|
|
||||||
#dockerfile: Dockerfile.backend
|
|
||||||
container_name: openrag-backend
|
|
||||||
depends_on:
|
|
||||||
- langflow
|
|
||||||
environment:
|
|
||||||
- OPENSEARCH_HOST=opensearch
|
|
||||||
- LANGFLOW_URL=http://langflow:7860
|
|
||||||
- LANGFLOW_PUBLIC_URL=${LANGFLOW_PUBLIC_URL}
|
|
||||||
- LANGFLOW_SECRET_KEY=${LANGFLOW_SECRET_KEY}
|
|
||||||
- LANGFLOW_SUPERUSER=${LANGFLOW_SUPERUSER}
|
|
||||||
- LANGFLOW_SUPERUSER_PASSWORD=${LANGFLOW_SUPERUSER_PASSWORD}
|
|
||||||
- LANGFLOW_CHAT_FLOW_ID=${LANGFLOW_CHAT_FLOW_ID}
|
|
||||||
- LANGFLOW_INGEST_FLOW_ID=${LANGFLOW_INGEST_FLOW_ID}
|
|
||||||
- LANGFLOW_URL_INGEST_FLOW_ID=${LANGFLOW_URL_INGEST_FLOW_ID}
|
|
||||||
- DISABLE_INGEST_WITH_LANGFLOW=${DISABLE_INGEST_WITH_LANGFLOW:-false}
|
|
||||||
- NUDGES_FLOW_ID=${NUDGES_FLOW_ID}
|
|
||||||
- OPENSEARCH_PORT=9200
|
|
||||||
- OPENSEARCH_USERNAME=admin
|
|
||||||
- OPENSEARCH_PASSWORD=${OPENSEARCH_PASSWORD}
|
|
||||||
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
|
||||||
- NVIDIA_DRIVER_CAPABILITIES=compute,utility
|
|
||||||
- NVIDIA_VISIBLE_DEVICES=all
|
|
||||||
- GOOGLE_OAUTH_CLIENT_ID=${GOOGLE_OAUTH_CLIENT_ID}
|
|
||||||
- GOOGLE_OAUTH_CLIENT_SECRET=${GOOGLE_OAUTH_CLIENT_SECRET}
|
|
||||||
- MICROSOFT_GRAPH_OAUTH_CLIENT_ID=${MICROSOFT_GRAPH_OAUTH_CLIENT_ID}
|
|
||||||
- MICROSOFT_GRAPH_OAUTH_CLIENT_SECRET=${MICROSOFT_GRAPH_OAUTH_CLIENT_SECRET}
|
|
||||||
- WEBHOOK_BASE_URL=${WEBHOOK_BASE_URL}
|
|
||||||
- AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
|
|
||||||
- AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
|
|
||||||
volumes:
|
|
||||||
- ./documents:/app/documents:Z
|
|
||||||
- ./keys:/app/keys:Z
|
|
||||||
- ./flows:/app/flows:Z
|
|
||||||
|
|
||||||
openrag-frontend:
|
|
||||||
image: phact/openrag-frontend:${OPENRAG_VERSION:-latest}
|
|
||||||
#build:
|
|
||||||
#context: .
|
|
||||||
#dockerfile: Dockerfile.frontend
|
|
||||||
container_name: openrag-frontend
|
|
||||||
depends_on:
|
|
||||||
- openrag-backend
|
|
||||||
environment:
|
|
||||||
- OPENRAG_BACKEND_HOST=openrag-backend
|
|
||||||
ports:
|
|
||||||
- "3000:3000"
|
|
||||||
|
|
||||||
langflow:
|
|
||||||
volumes:
|
|
||||||
- ./flows:/app/flows:Z
|
|
||||||
image: phact/openrag-langflow:${LANGFLOW_VERSION:-latest}
|
|
||||||
container_name: langflow
|
|
||||||
ports:
|
|
||||||
- "7860:7860"
|
|
||||||
environment:
|
|
||||||
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
|
||||||
- LANGFLOW_LOAD_FLOWS_PATH=/app/flows
|
|
||||||
- LANGFLOW_SECRET_KEY=${LANGFLOW_SECRET_KEY}
|
|
||||||
- JWT=None
|
|
||||||
- OWNER=None
|
|
||||||
- OWNER_NAME=None
|
|
||||||
- OWNER_EMAIL=None
|
|
||||||
- CONNECTOR_TYPE=system
|
|
||||||
- CONNECTOR_TYPE_URL=url
|
|
||||||
- OPENRAG-QUERY-FILTER="{}"
|
|
||||||
- OPENSEARCH_PASSWORD=${OPENSEARCH_PASSWORD}
|
|
||||||
- FILENAME=None
|
|
||||||
- MIMETYPE=None
|
|
||||||
- FILESIZE=0
|
|
||||||
- LANGFLOW_VARIABLES_TO_GET_FROM_ENVIRONMENT=JWT,OPENRAG-QUERY-FILTER,OPENSEARCH_PASSWORD,OWNER,OWNER_NAME,OWNER_EMAIL,CONNECTOR_TYPE,FILENAME,MIMETYPE,FILESIZE
|
|
||||||
- LANGFLOW_LOG_LEVEL=DEBUG
|
|
||||||
- LANGFLOW_AUTO_LOGIN=${LANGFLOW_AUTO_LOGIN}
|
|
||||||
- LANGFLOW_SUPERUSER=${LANGFLOW_SUPERUSER}
|
|
||||||
- LANGFLOW_SUPERUSER_PASSWORD=${LANGFLOW_SUPERUSER_PASSWORD}
|
|
||||||
- LANGFLOW_NEW_USER_IS_ACTIVE=${LANGFLOW_NEW_USER_IS_ACTIVE}
|
|
||||||
- LANGFLOW_ENABLE_SUPERUSER_CLI=${LANGFLOW_ENABLE_SUPERUSER_CLI}
|
|
||||||
# - DEFAULT_FOLDER_NAME=OpenRAG
|
|
||||||
- HIDE_GETTING_STARTED_PROGRESS=true
|
|
||||||
1
src/tui/_assets/docker-compose-cpu.yml
Symbolic link
1
src/tui/_assets/docker-compose-cpu.yml
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../docker-compose-cpu.yml
|
||||||
|
|
@ -1,122 +0,0 @@
|
||||||
services:
|
|
||||||
opensearch:
|
|
||||||
image: phact/openrag-opensearch:${OPENRAG_VERSION:-latest}
|
|
||||||
#build:
|
|
||||||
#context: .
|
|
||||||
#dockerfile: Dockerfile
|
|
||||||
container_name: os
|
|
||||||
depends_on:
|
|
||||||
- openrag-backend
|
|
||||||
environment:
|
|
||||||
- discovery.type=single-node
|
|
||||||
- OPENSEARCH_INITIAL_ADMIN_PASSWORD=${OPENSEARCH_PASSWORD}
|
|
||||||
# Run security setup in background after OpenSearch starts
|
|
||||||
command: >
|
|
||||||
bash -c "
|
|
||||||
# Start OpenSearch in background
|
|
||||||
/usr/share/opensearch/opensearch-docker-entrypoint.sh opensearch &
|
|
||||||
|
|
||||||
# Wait a bit for OpenSearch to start, then apply security config
|
|
||||||
sleep 10 && /usr/share/opensearch/setup-security.sh &
|
|
||||||
|
|
||||||
# Wait for background processes
|
|
||||||
wait
|
|
||||||
"
|
|
||||||
ports:
|
|
||||||
- "9200:9200"
|
|
||||||
- "9600:9600"
|
|
||||||
|
|
||||||
dashboards:
|
|
||||||
image: opensearchproject/opensearch-dashboards:3.0.0
|
|
||||||
container_name: osdash
|
|
||||||
depends_on:
|
|
||||||
- opensearch
|
|
||||||
environment:
|
|
||||||
OPENSEARCH_HOSTS: '["https://opensearch:9200"]'
|
|
||||||
OPENSEARCH_USERNAME: "admin"
|
|
||||||
OPENSEARCH_PASSWORD: ${OPENSEARCH_PASSWORD}
|
|
||||||
ports:
|
|
||||||
- "5601:5601"
|
|
||||||
|
|
||||||
openrag-backend:
|
|
||||||
image: phact/openrag-backend:${OPENRAG_VERSION:-latest}
|
|
||||||
#build:
|
|
||||||
#context: .
|
|
||||||
#dockerfile: Dockerfile.backend
|
|
||||||
container_name: openrag-backend
|
|
||||||
depends_on:
|
|
||||||
- langflow
|
|
||||||
environment:
|
|
||||||
- OPENSEARCH_HOST=opensearch
|
|
||||||
- LANGFLOW_URL=http://langflow:7860
|
|
||||||
- LANGFLOW_PUBLIC_URL=${LANGFLOW_PUBLIC_URL}
|
|
||||||
- LANGFLOW_SUPERUSER=${LANGFLOW_SUPERUSER}
|
|
||||||
- LANGFLOW_SUPERUSER_PASSWORD=${LANGFLOW_SUPERUSER_PASSWORD}
|
|
||||||
- LANGFLOW_CHAT_FLOW_ID=${LANGFLOW_CHAT_FLOW_ID}
|
|
||||||
- LANGFLOW_INGEST_FLOW_ID=${LANGFLOW_INGEST_FLOW_ID}
|
|
||||||
- LANGFLOW_URL_INGEST_FLOW_ID=${LANGFLOW_URL_INGEST_FLOW_ID}
|
|
||||||
- DISABLE_INGEST_WITH_LANGFLOW=${DISABLE_INGEST_WITH_LANGFLOW:-false}
|
|
||||||
- NUDGES_FLOW_ID=${NUDGES_FLOW_ID}
|
|
||||||
- OPENSEARCH_PORT=9200
|
|
||||||
- OPENSEARCH_USERNAME=admin
|
|
||||||
- OPENSEARCH_PASSWORD=${OPENSEARCH_PASSWORD}
|
|
||||||
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
|
||||||
- NVIDIA_DRIVER_CAPABILITIES=compute,utility
|
|
||||||
- NVIDIA_VISIBLE_DEVICES=all
|
|
||||||
- GOOGLE_OAUTH_CLIENT_ID=${GOOGLE_OAUTH_CLIENT_ID}
|
|
||||||
- GOOGLE_OAUTH_CLIENT_SECRET=${GOOGLE_OAUTH_CLIENT_SECRET}
|
|
||||||
- MICROSOFT_GRAPH_OAUTH_CLIENT_ID=${MICROSOFT_GRAPH_OAUTH_CLIENT_ID}
|
|
||||||
- MICROSOFT_GRAPH_OAUTH_CLIENT_SECRET=${MICROSOFT_GRAPH_OAUTH_CLIENT_SECRET}
|
|
||||||
- WEBHOOK_BASE_URL=${WEBHOOK_BASE_URL}
|
|
||||||
- AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
|
|
||||||
- AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
|
|
||||||
volumes:
|
|
||||||
- ./documents:/app/documents:Z
|
|
||||||
- ./keys:/app/keys:Z
|
|
||||||
- ./flows:/app/flows:Z
|
|
||||||
gpus: all
|
|
||||||
|
|
||||||
openrag-frontend:
|
|
||||||
image: phact/openrag-frontend:${OPENRAG_VERSION:-latest}
|
|
||||||
#build:
|
|
||||||
#context: .
|
|
||||||
#dockerfile: Dockerfile.frontend
|
|
||||||
container_name: openrag-frontend
|
|
||||||
depends_on:
|
|
||||||
- openrag-backend
|
|
||||||
environment:
|
|
||||||
- OPENRAG_BACKEND_HOST=openrag-backend
|
|
||||||
ports:
|
|
||||||
- "3000:3000"
|
|
||||||
|
|
||||||
langflow:
|
|
||||||
volumes:
|
|
||||||
- ./flows:/app/flows:Z
|
|
||||||
image: phact/openrag-langflow:${LANGFLOW_VERSION:-latest}
|
|
||||||
container_name: langflow
|
|
||||||
ports:
|
|
||||||
- "7860:7860"
|
|
||||||
environment:
|
|
||||||
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
|
||||||
- LANGFLOW_LOAD_FLOWS_PATH=/app/flows
|
|
||||||
- LANGFLOW_SECRET_KEY=${LANGFLOW_SECRET_KEY}
|
|
||||||
- JWT=None
|
|
||||||
- OWNER=None
|
|
||||||
- OWNER_NAME=None
|
|
||||||
- OWNER_EMAIL=None
|
|
||||||
- CONNECTOR_TYPE=system
|
|
||||||
- CONNECTOR_TYPE_URL=url
|
|
||||||
- OPENRAG-QUERY-FILTER="{}"
|
|
||||||
- OPENSEARCH_PASSWORD=${OPENSEARCH_PASSWORD}
|
|
||||||
- FILENAME=None
|
|
||||||
- MIMETYPE=None
|
|
||||||
- FILESIZE=0
|
|
||||||
- LANGFLOW_VARIABLES_TO_GET_FROM_ENVIRONMENT=JWT,OPENRAG-QUERY-FILTER,OPENSEARCH_PASSWORD,OWNER,OWNER_NAME,OWNER_EMAIL,CONNECTOR_TYPE,FILENAME,MIMETYPE,FILESIZE
|
|
||||||
- LANGFLOW_LOG_LEVEL=DEBUG
|
|
||||||
- LANGFLOW_AUTO_LOGIN=${LANGFLOW_AUTO_LOGIN}
|
|
||||||
- LANGFLOW_SUPERUSER=${LANGFLOW_SUPERUSER}
|
|
||||||
- LANGFLOW_SUPERUSER_PASSWORD=${LANGFLOW_SUPERUSER_PASSWORD}
|
|
||||||
- LANGFLOW_NEW_USER_IS_ACTIVE=${LANGFLOW_NEW_USER_IS_ACTIVE}
|
|
||||||
- LANGFLOW_ENABLE_SUPERUSER_CLI=${LANGFLOW_ENABLE_SUPERUSER_CLI}
|
|
||||||
# - DEFAULT_FOLDER_NAME="OpenRAG"
|
|
||||||
- HIDE_GETTING_STARTED_PROGRESS=true
|
|
||||||
1
src/tui/_assets/docker-compose.yml
Symbolic link
1
src/tui/_assets/docker-compose.yml
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../docker-compose.yml
|
||||||
Binary file not shown.
1
src/tui/_assets/documents/2506.08231v1.pdf
Symbolic link
1
src/tui/_assets/documents/2506.08231v1.pdf
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../../../documents/2506.08231v1.pdf
|
||||||
Binary file not shown.
1
src/tui/_assets/documents/ai-human-resources.pdf
Symbolic link
1
src/tui/_assets/documents/ai-human-resources.pdf
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../../../documents/ai-human-resources.pdf
|
||||||
Binary file not shown.
1
src/tui/_assets/documents/warmup_ocr.pdf
Symbolic link
1
src/tui/_assets/documents/warmup_ocr.pdf
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../../../documents/warmup_ocr.pdf
|
||||||
1
src/tui/_assets/flows/components/ollama_embedding.json
Symbolic link
1
src/tui/_assets/flows/components/ollama_embedding.json
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../../../../flows/components/ollama_embedding.json
|
||||||
1
src/tui/_assets/flows/components/ollama_llm.json
Symbolic link
1
src/tui/_assets/flows/components/ollama_llm.json
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../../../../flows/components/ollama_llm.json
|
||||||
1
src/tui/_assets/flows/components/ollama_llm_text.json
Symbolic link
1
src/tui/_assets/flows/components/ollama_llm_text.json
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../../../../flows/components/ollama_llm_text.json
|
||||||
1
src/tui/_assets/flows/components/watsonx_embedding.json
Symbolic link
1
src/tui/_assets/flows/components/watsonx_embedding.json
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../../../../flows/components/watsonx_embedding.json
|
||||||
1
src/tui/_assets/flows/components/watsonx_llm.json
Symbolic link
1
src/tui/_assets/flows/components/watsonx_llm.json
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../../../../flows/components/watsonx_llm.json
|
||||||
1
src/tui/_assets/flows/components/watsonx_llm_text.json
Symbolic link
1
src/tui/_assets/flows/components/watsonx_llm_text.json
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../../../../flows/components/watsonx_llm_text.json
|
||||||
1
src/tui/_assets/flows/ingestion_flow.json
Symbolic link
1
src/tui/_assets/flows/ingestion_flow.json
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../../../flows/ingestion_flow.json
|
||||||
1
src/tui/_assets/flows/openrag_agent.json
Symbolic link
1
src/tui/_assets/flows/openrag_agent.json
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../../../flows/openrag_agent.json
|
||||||
1
src/tui/_assets/flows/openrag_ingest_docling.json
Symbolic link
1
src/tui/_assets/flows/openrag_ingest_docling.json
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../../../flows/openrag_ingest_docling.json
|
||||||
1
src/tui/_assets/flows/openrag_nudges.json
Symbolic link
1
src/tui/_assets/flows/openrag_nudges.json
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../../../flows/openrag_nudges.json
|
||||||
1
src/tui/_assets/flows/openrag_url_mcp.json
Symbolic link
1
src/tui/_assets/flows/openrag_url_mcp.json
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../../../flows/openrag_url_mcp.json
|
||||||
105
src/tui/main.py
105
src/tui/main.py
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import Iterable, Optional
|
||||||
from textual.app import App, ComposeResult
|
from textual.app import App, ComposeResult
|
||||||
from utils.logging_config import get_logger
|
from utils.logging_config import get_logger
|
||||||
try:
|
try:
|
||||||
|
|
@ -305,41 +306,103 @@ class OpenRAGTUI(App):
|
||||||
return True, "Runtime requirements satisfied"
|
return True, "Runtime requirements satisfied"
|
||||||
|
|
||||||
|
|
||||||
def copy_sample_documents():
|
def _copy_assets(resource_tree, destination: Path, allowed_suffixes: Optional[Iterable[str]] = None, *, force: bool = False) -> None:
|
||||||
|
"""Copy packaged assets into destination and optionally overwrite existing files.
|
||||||
|
|
||||||
|
When ``force`` is True, files are refreshed if the packaged bytes differ.
|
||||||
|
"""
|
||||||
|
destination.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
for resource in resource_tree.iterdir():
|
||||||
|
target_path = destination / resource.name
|
||||||
|
|
||||||
|
if resource.is_dir():
|
||||||
|
_copy_assets(resource, target_path, allowed_suffixes, force=force)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if allowed_suffixes and not any(resource.name.endswith(suffix) for suffix in allowed_suffixes):
|
||||||
|
continue
|
||||||
|
resource_bytes = resource.read_bytes()
|
||||||
|
|
||||||
|
if target_path.exists():
|
||||||
|
if not force:
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
if target_path.read_bytes() == resource_bytes:
|
||||||
|
continue
|
||||||
|
except Exception as read_error:
|
||||||
|
logger.debug(f"Failed to read existing asset {target_path}: {read_error}")
|
||||||
|
|
||||||
|
target_path.write_bytes(resource_bytes)
|
||||||
|
logger.info(f"Copied bundled asset: {target_path}")
|
||||||
|
|
||||||
|
|
||||||
|
def copy_sample_documents(*, force: bool = False) -> None:
|
||||||
"""Copy sample documents from package to current directory if they don't exist."""
|
"""Copy sample documents from package to current directory if they don't exist."""
|
||||||
documents_dir = Path("documents")
|
documents_dir = Path("documents")
|
||||||
|
|
||||||
# Check if documents directory already exists and has files
|
|
||||||
if documents_dir.exists() and any(documents_dir.glob("*.pdf")):
|
|
||||||
return # Documents already exist, don't overwrite
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Get sample documents from package assets
|
|
||||||
assets_files = files("tui._assets.documents")
|
assets_files = files("tui._assets.documents")
|
||||||
|
_copy_assets(assets_files, documents_dir, allowed_suffixes=(".pdf",), force=force)
|
||||||
# Create documents directory if it doesn't exist
|
|
||||||
documents_dir.mkdir(exist_ok=True)
|
|
||||||
|
|
||||||
# Copy each sample document
|
|
||||||
for resource in assets_files.iterdir():
|
|
||||||
if resource.is_file() and resource.name.endswith('.pdf'):
|
|
||||||
dest_path = documents_dir / resource.name
|
|
||||||
if not dest_path.exists():
|
|
||||||
content = resource.read_bytes()
|
|
||||||
dest_path.write_bytes(content)
|
|
||||||
logger.info(f"Copied sample document: {resource.name}")
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.debug(f"Could not copy sample documents: {e}")
|
logger.debug(f"Could not copy sample documents: {e}")
|
||||||
# This is not a critical error - the app can work without sample documents
|
# This is not a critical error - the app can work without sample documents
|
||||||
|
|
||||||
|
|
||||||
|
def copy_sample_flows(*, force: bool = False) -> None:
|
||||||
|
"""Copy sample flows from package to current directory if they don't exist."""
|
||||||
|
flows_dir = Path("flows")
|
||||||
|
|
||||||
|
try:
|
||||||
|
assets_files = files("tui._assets.flows")
|
||||||
|
_copy_assets(assets_files, flows_dir, allowed_suffixes=(".json",), force=force)
|
||||||
|
except Exception as e:
|
||||||
|
logger.debug(f"Could not copy sample flows: {e}")
|
||||||
|
# The app can proceed without bundled flows
|
||||||
|
|
||||||
|
|
||||||
|
def copy_compose_files(*, force: bool = False) -> None:
|
||||||
|
"""Copy docker-compose templates into the workspace if they are missing."""
|
||||||
|
try:
|
||||||
|
assets_root = files("tui._assets")
|
||||||
|
except Exception as e:
|
||||||
|
logger.debug(f"Could not access compose assets: {e}")
|
||||||
|
return
|
||||||
|
|
||||||
|
for filename in ("docker-compose.yml", "docker-compose-cpu.yml"):
|
||||||
|
destination = Path(filename)
|
||||||
|
if destination.exists() and not force:
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
resource = assets_root.joinpath(filename)
|
||||||
|
if not resource.is_file():
|
||||||
|
logger.debug(f"Compose template not found in assets: {filename}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
resource_bytes = resource.read_bytes()
|
||||||
|
if destination.exists():
|
||||||
|
try:
|
||||||
|
if destination.read_bytes() == resource_bytes:
|
||||||
|
continue
|
||||||
|
except Exception as read_error:
|
||||||
|
logger.debug(f"Failed to read existing compose file {destination}: {read_error}")
|
||||||
|
|
||||||
|
destination.write_bytes(resource_bytes)
|
||||||
|
logger.info(f"Copied docker-compose template: {filename}")
|
||||||
|
except Exception as error:
|
||||||
|
logger.debug(f"Could not copy compose file {filename}: {error}")
|
||||||
|
|
||||||
|
|
||||||
def run_tui():
|
def run_tui():
|
||||||
"""Run the OpenRAG TUI application."""
|
"""Run the OpenRAG TUI application."""
|
||||||
app = None
|
app = None
|
||||||
try:
|
try:
|
||||||
# Copy sample documents on first run
|
# Keep bundled assets aligned with the packaged versions
|
||||||
copy_sample_documents()
|
copy_sample_documents(force=True)
|
||||||
|
copy_sample_flows(force=True)
|
||||||
|
copy_compose_files(force=True)
|
||||||
|
|
||||||
app = OpenRAGTUI()
|
app = OpenRAGTUI()
|
||||||
app.run()
|
app.run()
|
||||||
|
|
|
||||||
2
uv.lock
generated
2
uv.lock
generated
|
|
@ -2282,7 +2282,7 @@ wheels = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openrag"
|
name = "openrag"
|
||||||
version = "0.1.14.dev3"
|
version = "0.1.17"
|
||||||
source = { editable = "." }
|
source = { editable = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "agentd" },
|
{ name = "agentd" },
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue