Merge branch 'main' into dev-docker-compose
This commit is contained in:
commit
1736ff56bd
16 changed files with 1095 additions and 1278 deletions
|
|
@ -62,8 +62,7 @@ LANGFLOW_CHAT_FLOW_ID=your_chat_flow_id
|
||||||
LANGFLOW_INGEST_FLOW_ID=your_ingest_flow_id
|
LANGFLOW_INGEST_FLOW_ID=your_ingest_flow_id
|
||||||
NUDGES_FLOW_ID=your_nudges_flow_id
|
NUDGES_FLOW_ID=your_nudges_flow_id
|
||||||
```
|
```
|
||||||
ee extended configuration, including ingestion and optional variables: [docs/configuration.md](docs/
|
See extended configuration, including ingestion and optional variables: [docs/configuration.md](docs/configuration.md)
|
||||||
configuration.md)
|
|
||||||
### 3. Start OpenRAG
|
### 3. Start OpenRAG
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ services:
|
||||||
langflow:
|
langflow:
|
||||||
volumes:
|
volumes:
|
||||||
- ./flows:/app/flows:Z
|
- ./flows:/app/flows:Z
|
||||||
image: phact/langflow:${LANGFLOW_VERSION:-responses}
|
image: phact/openrag-langflow:${LANGFLOW_VERSION:-latest}
|
||||||
container_name: langflow
|
container_name: langflow
|
||||||
ports:
|
ports:
|
||||||
- "7860:7860"
|
- "7860:7860"
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { EllipsisVertical } from "lucide-react";
|
|
||||||
import {
|
import {
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
DropdownMenuContent,
|
DropdownMenuContent,
|
||||||
DropdownMenuItem,
|
DropdownMenuItem,
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from "@/components/ui/dropdown-menu";
|
} from "@/components/ui/dropdown-menu";
|
||||||
|
import { EllipsisVertical } from "lucide-react";
|
||||||
import { Button } from "./ui/button";
|
import { Button } from "./ui/button";
|
||||||
|
|
||||||
export function KnowledgeActionsDropdown() {
|
export function KnowledgeActionsDropdown() {
|
||||||
|
|
@ -18,7 +18,9 @@ export function KnowledgeActionsDropdown() {
|
||||||
</Button>
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent side="right" sideOffset={-10}>
|
<DropdownMenuContent side="right" sideOffset={-10}>
|
||||||
<DropdownMenuItem variant="destructive">Delete</DropdownMenuItem>
|
<DropdownMenuItem className="text-destructive focus:text-destructive-foreground focus:bg-destructive">
|
||||||
|
Delete
|
||||||
|
</DropdownMenuItem>
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ export const MarkdownRenderer = ({ chatMessage }: MarkdownRendererProps) => {
|
||||||
<Markdown
|
<Markdown
|
||||||
remarkPlugins={[remarkGfm]}
|
remarkPlugins={[remarkGfm]}
|
||||||
rehypePlugins={[rehypeMathjax, rehypeRaw]}
|
rehypePlugins={[rehypeMathjax, rehypeRaw]}
|
||||||
linkTarget="_blank"
|
urlTransform={(url) => url}
|
||||||
components={{
|
components={{
|
||||||
p({ node, ...props }) {
|
p({ node, ...props }) {
|
||||||
return <p className="w-fit max-w-full">{props.children}</p>;
|
return <p className="w-fit max-w-full">{props.children}</p>;
|
||||||
|
|
@ -79,7 +79,7 @@ export const MarkdownRenderer = ({ chatMessage }: MarkdownRendererProps) => {
|
||||||
h3({ node, ...props }) {
|
h3({ node, ...props }) {
|
||||||
return <h3 className="mb-2 mt-4">{props.children}</h3>;
|
return <h3 className="mb-2 mt-4">{props.children}</h3>;
|
||||||
},
|
},
|
||||||
hr({ node, ...props }) {
|
hr() {
|
||||||
return <hr className="w-full mt-4 mb-8" />;
|
return <hr className="w-full mt-4 mb-8" />;
|
||||||
},
|
},
|
||||||
ul({ node, ...props }) {
|
ul({ node, ...props }) {
|
||||||
|
|
@ -97,8 +97,12 @@ export const MarkdownRenderer = ({ chatMessage }: MarkdownRendererProps) => {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
a({ node, ...props }) {
|
||||||
|
return <a {...props} target="_blank" rel="noopener noreferrer">{props.children}</a>;
|
||||||
|
},
|
||||||
|
|
||||||
code: ({ node, className, inline, children, ...props }) => {
|
code(props) {
|
||||||
|
const { children, className, ...rest } = props;
|
||||||
let content = children as string;
|
let content = children as string;
|
||||||
if (
|
if (
|
||||||
Array.isArray(children) &&
|
Array.isArray(children) &&
|
||||||
|
|
@ -120,14 +124,15 @@ export const MarkdownRenderer = ({ chatMessage }: MarkdownRendererProps) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const match = /language-(\w+)/.exec(className || "");
|
const match = /language-(\w+)/.exec(className || "");
|
||||||
|
const isInline = !className?.startsWith("language-");
|
||||||
|
|
||||||
return !inline ? (
|
return !isInline ? (
|
||||||
<CodeComponent
|
<CodeComponent
|
||||||
language={(match && match[1]) || ""}
|
language={(match && match[1]) || ""}
|
||||||
code={String(content).replace(/\n$/, "")}
|
code={String(content).replace(/\n$/, "")}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<code className={className} {...props}>
|
<code className={className} {...rest}>
|
||||||
{content}
|
{content}
|
||||||
</code>
|
</code>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
2240
frontend/package-lock.json
generated
2240
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -38,11 +38,11 @@
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
"react-icons": "^5.5.0",
|
"react-icons": "^5.5.0",
|
||||||
"react-markdown": "^8.0.7",
|
"react-markdown": "^10.1.0",
|
||||||
"react-syntax-highlighter": "^15.6.1",
|
"react-syntax-highlighter": "^15.6.1",
|
||||||
"rehype-mathjax": "^4.0.3",
|
"rehype-mathjax": "^7.1.0",
|
||||||
"rehype-raw": "^6.1.1",
|
"rehype-raw": "^7.0.0",
|
||||||
"remark-gfm": "3.0.1",
|
"remark-gfm": "^4.0.1",
|
||||||
"sonner": "^2.0.6",
|
"sonner": "^2.0.6",
|
||||||
"tailwind-merge": "^3.3.1",
|
"tailwind-merge": "^3.3.1",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
|
|
@ -53,6 +53,7 @@
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
"@types/react": "^19",
|
"@types/react": "^19",
|
||||||
"@types/react-dom": "^19",
|
"@types/react-dom": "^19",
|
||||||
|
"@types/react-syntax-highlighter": "^15.5.13",
|
||||||
"autoprefixer": "^10.4.21",
|
"autoprefixer": "^10.4.21",
|
||||||
"eslint": "^9",
|
"eslint": "^9",
|
||||||
"eslint-config-next": "15.3.5",
|
"eslint-config-next": "15.3.5",
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,7 @@ async def chat_endpoint(request: Request, chat_service, session_manager):
|
||||||
user = request.state.user
|
user = request.state.user
|
||||||
user_id = user.user_id
|
user_id = user.user_id
|
||||||
|
|
||||||
# Get JWT token from auth middleware
|
jwt_token = session_manager.get_effective_jwt_token(user_id, request.state.jwt_token)
|
||||||
jwt_token = request.state.jwt_token
|
|
||||||
|
|
||||||
if not prompt:
|
if not prompt:
|
||||||
return JSONResponse({"error": "Prompt is required"}, status_code=400)
|
return JSONResponse({"error": "Prompt is required"}, status_code=400)
|
||||||
|
|
@ -76,8 +75,7 @@ async def langflow_endpoint(request: Request, chat_service, session_manager):
|
||||||
user = request.state.user
|
user = request.state.user
|
||||||
user_id = user.user_id
|
user_id = user.user_id
|
||||||
|
|
||||||
# Get JWT token from auth middleware
|
jwt_token = session_manager.get_effective_jwt_token(user_id, request.state.jwt_token)
|
||||||
jwt_token = request.state.jwt_token
|
|
||||||
|
|
||||||
if not prompt:
|
if not prompt:
|
||||||
return JSONResponse({"error": "Prompt is required"}, status_code=400)
|
return JSONResponse({"error": "Prompt is required"}, status_code=400)
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ async def list_connectors(request: Request, connector_service, session_manager):
|
||||||
)
|
)
|
||||||
return JSONResponse({"connectors": connector_types})
|
return JSONResponse({"connectors": connector_types})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("Error listing connectors", error=str(e))
|
logger.info("Error listing connectors", error=str(e))
|
||||||
return JSONResponse({"error": str(e)}, status_code=500)
|
return JSONResponse({"connectors": []})
|
||||||
|
|
||||||
|
|
||||||
async def connector_sync(request: Request, connector_service, session_manager):
|
async def connector_sync(request: Request, connector_service, session_manager):
|
||||||
|
|
@ -31,7 +31,7 @@ async def connector_sync(request: Request, connector_service, session_manager):
|
||||||
max_files=max_files,
|
max_files=max_files,
|
||||||
)
|
)
|
||||||
user = request.state.user
|
user = request.state.user
|
||||||
jwt_token = request.state.jwt_token
|
jwt_token = session_manager.get_effective_jwt_token(user.user_id, request.state.jwt_token)
|
||||||
|
|
||||||
# Get all active connections for this connector type and user
|
# Get all active connections for this connector type and user
|
||||||
connections = await connector_service.connection_manager.list_connections(
|
connections = await connector_service.connection_manager.list_connections(
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ async def create_knowledge_filter(
|
||||||
return JSONResponse({"error": "Query data is required"}, status_code=400)
|
return JSONResponse({"error": "Query data is required"}, status_code=400)
|
||||||
|
|
||||||
user = request.state.user
|
user = request.state.user
|
||||||
jwt_token = request.state.jwt_token
|
jwt_token = session_manager.get_effective_jwt_token(user.user_id, request.state.jwt_token)
|
||||||
|
|
||||||
# Create knowledge filter document
|
# Create knowledge filter document
|
||||||
filter_id = str(uuid.uuid4())
|
filter_id = str(uuid.uuid4())
|
||||||
|
|
@ -70,7 +70,7 @@ async def search_knowledge_filters(
|
||||||
limit = payload.get("limit", 20)
|
limit = payload.get("limit", 20)
|
||||||
|
|
||||||
user = request.state.user
|
user = request.state.user
|
||||||
jwt_token = request.state.jwt_token
|
jwt_token = session_manager.get_effective_jwt_token(user.user_id, request.state.jwt_token)
|
||||||
|
|
||||||
result = await knowledge_filter_service.search_knowledge_filters(
|
result = await knowledge_filter_service.search_knowledge_filters(
|
||||||
query, user_id=user.user_id, jwt_token=jwt_token, limit=limit
|
query, user_id=user.user_id, jwt_token=jwt_token, limit=limit
|
||||||
|
|
@ -101,7 +101,7 @@ async def get_knowledge_filter(
|
||||||
)
|
)
|
||||||
|
|
||||||
user = request.state.user
|
user = request.state.user
|
||||||
jwt_token = request.state.jwt_token
|
jwt_token = session_manager.get_effective_jwt_token(user.user_id, request.state.jwt_token)
|
||||||
|
|
||||||
result = await knowledge_filter_service.get_knowledge_filter(
|
result = await knowledge_filter_service.get_knowledge_filter(
|
||||||
filter_id, user_id=user.user_id, jwt_token=jwt_token
|
filter_id, user_id=user.user_id, jwt_token=jwt_token
|
||||||
|
|
@ -136,7 +136,7 @@ async def update_knowledge_filter(
|
||||||
payload = await request.json()
|
payload = await request.json()
|
||||||
|
|
||||||
user = request.state.user
|
user = request.state.user
|
||||||
jwt_token = request.state.jwt_token
|
jwt_token = session_manager.get_effective_jwt_token(user.user_id, request.state.jwt_token)
|
||||||
|
|
||||||
# First, get the existing knowledge filter
|
# First, get the existing knowledge filter
|
||||||
existing_result = await knowledge_filter_service.get_knowledge_filter(
|
existing_result = await knowledge_filter_service.get_knowledge_filter(
|
||||||
|
|
@ -205,7 +205,7 @@ async def delete_knowledge_filter(
|
||||||
)
|
)
|
||||||
|
|
||||||
user = request.state.user
|
user = request.state.user
|
||||||
jwt_token = request.state.jwt_token
|
jwt_token = session_manager.get_effective_jwt_token(user.user_id, request.state.jwt_token)
|
||||||
|
|
||||||
result = await knowledge_filter_service.delete_knowledge_filter(
|
result = await knowledge_filter_service.delete_knowledge_filter(
|
||||||
filter_id, user_id=user.user_id, jwt_token=jwt_token
|
filter_id, user_id=user.user_id, jwt_token=jwt_token
|
||||||
|
|
@ -239,7 +239,7 @@ async def subscribe_to_knowledge_filter(
|
||||||
|
|
||||||
payload = await request.json()
|
payload = await request.json()
|
||||||
user = request.state.user
|
user = request.state.user
|
||||||
jwt_token = request.state.jwt_token
|
jwt_token = session_manager.get_effective_jwt_token(user.user_id, request.state.jwt_token)
|
||||||
|
|
||||||
# Get the knowledge filter to validate it exists and get its details
|
# Get the knowledge filter to validate it exists and get its details
|
||||||
filter_result = await knowledge_filter_service.get_knowledge_filter(
|
filter_result = await knowledge_filter_service.get_knowledge_filter(
|
||||||
|
|
@ -309,7 +309,7 @@ async def list_knowledge_filter_subscriptions(
|
||||||
)
|
)
|
||||||
|
|
||||||
user = request.state.user
|
user = request.state.user
|
||||||
jwt_token = request.state.jwt_token
|
jwt_token = session_manager.get_effective_jwt_token(user.user_id, request.state.jwt_token)
|
||||||
|
|
||||||
result = await knowledge_filter_service.get_filter_subscriptions(
|
result = await knowledge_filter_service.get_filter_subscriptions(
|
||||||
filter_id, user_id=user.user_id, jwt_token=jwt_token
|
filter_id, user_id=user.user_id, jwt_token=jwt_token
|
||||||
|
|
@ -341,7 +341,7 @@ async def cancel_knowledge_filter_subscription(
|
||||||
)
|
)
|
||||||
|
|
||||||
user = request.state.user
|
user = request.state.user
|
||||||
jwt_token = request.state.jwt_token
|
jwt_token = session_manager.get_effective_jwt_token(user.user_id, request.state.jwt_token)
|
||||||
|
|
||||||
# Get subscription details to find the monitor ID
|
# Get subscription details to find the monitor ID
|
||||||
subscriptions_result = await knowledge_filter_service.get_filter_subscriptions(
|
subscriptions_result = await knowledge_filter_service.get_filter_subscriptions(
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ async def nudges_from_kb_endpoint(request: Request, chat_service, session_manage
|
||||||
"""Get nudges for a user"""
|
"""Get nudges for a user"""
|
||||||
user = request.state.user
|
user = request.state.user
|
||||||
user_id = user.user_id
|
user_id = user.user_id
|
||||||
jwt_token = request.state.jwt_token
|
jwt_token = session_manager.get_effective_jwt_token(user_id, request.state.jwt_token)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result = await chat_service.langflow_nudges_chat(
|
result = await chat_service.langflow_nudges_chat(
|
||||||
|
|
@ -28,7 +28,8 @@ async def nudges_from_chat_id_endpoint(request: Request, chat_service, session_m
|
||||||
user = request.state.user
|
user = request.state.user
|
||||||
user_id = user.user_id
|
user_id = user.user_id
|
||||||
chat_id = request.path_params["chat_id"]
|
chat_id = request.path_params["chat_id"]
|
||||||
jwt_token = request.state.jwt_token
|
|
||||||
|
jwt_token = session_manager.get_effective_jwt_token(user_id, request.state.jwt_token)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result = await chat_service.langflow_nudges_chat(
|
result = await chat_service.langflow_nudges_chat(
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,7 @@ async def search(request: Request, search_service, session_manager):
|
||||||
) # Optional score threshold, defaults to 0
|
) # Optional score threshold, defaults to 0
|
||||||
|
|
||||||
user = request.state.user
|
user = request.state.user
|
||||||
# Extract JWT token from auth middleware
|
jwt_token = session_manager.get_effective_jwt_token(user.user_id, request.state.jwt_token)
|
||||||
jwt_token = request.state.jwt_token
|
|
||||||
|
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Search API request",
|
"Search API request",
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ async def upload(request: Request, document_service, session_manager):
|
||||||
form = await request.form()
|
form = await request.form()
|
||||||
upload_file = form["file"]
|
upload_file = form["file"]
|
||||||
user = request.state.user
|
user = request.state.user
|
||||||
jwt_token = request.state.jwt_token
|
jwt_token = session_manager.get_effective_jwt_token(user.user_id, request.state.jwt_token)
|
||||||
|
|
||||||
from config.settings import is_no_auth_mode
|
from config.settings import is_no_auth_mode
|
||||||
|
|
||||||
|
|
@ -60,7 +60,7 @@ async def upload_path(request: Request, task_service, session_manager):
|
||||||
return JSONResponse({"error": "No files found in directory"}, status_code=400)
|
return JSONResponse({"error": "No files found in directory"}, status_code=400)
|
||||||
|
|
||||||
user = request.state.user
|
user = request.state.user
|
||||||
jwt_token = request.state.jwt_token
|
jwt_token = session_manager.get_effective_jwt_token(user.user_id, request.state.jwt_token)
|
||||||
|
|
||||||
from config.settings import is_no_auth_mode
|
from config.settings import is_no_auth_mode
|
||||||
|
|
||||||
|
|
@ -100,8 +100,7 @@ async def upload_context(
|
||||||
previous_response_id = form.get("previous_response_id")
|
previous_response_id = form.get("previous_response_id")
|
||||||
endpoint = form.get("endpoint", "langflow")
|
endpoint = form.get("endpoint", "langflow")
|
||||||
|
|
||||||
# Get JWT token from auth middleware
|
jwt_token = session_manager.get_effective_jwt_token(user_id, request.state.jwt_token)
|
||||||
jwt_token = request.state.jwt_token
|
|
||||||
|
|
||||||
# Get user info from request state (set by auth middleware)
|
# Get user info from request state (set by auth middleware)
|
||||||
user = request.state.user
|
user = request.state.user
|
||||||
|
|
@ -169,7 +168,7 @@ async def upload_bucket(request: Request, task_service, session_manager):
|
||||||
return JSONResponse({"error": "No files found in bucket"}, status_code=400)
|
return JSONResponse({"error": "No files found in bucket"}, status_code=400)
|
||||||
|
|
||||||
user = request.state.user
|
user = request.state.user
|
||||||
jwt_token = request.state.jwt_token
|
jwt_token = session_manager.get_effective_jwt_token(user.user_id, request.state.jwt_token)
|
||||||
|
|
||||||
from models.processors import S3FileProcessor
|
from models.processors import S3FileProcessor
|
||||||
from config.settings import is_no_auth_mode
|
from config.settings import is_no_auth_mode
|
||||||
|
|
|
||||||
|
|
@ -321,7 +321,7 @@ class ConnectionManager:
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_available_connector_types(self) -> Dict[str, Dict[str, str]]:
|
def get_available_connector_types(self) -> Dict[str, Dict[str, Any]]:
|
||||||
"""Get available connector types with their metadata"""
|
"""Get available connector types with their metadata"""
|
||||||
return {
|
return {
|
||||||
"google_drive": {
|
"google_drive": {
|
||||||
|
|
|
||||||
|
|
@ -191,26 +191,8 @@ class SessionManager:
|
||||||
|
|
||||||
def get_user_opensearch_client(self, user_id: str, jwt_token: str):
|
def get_user_opensearch_client(self, user_id: str, jwt_token: str):
|
||||||
"""Get or create OpenSearch client for user with their JWT"""
|
"""Get or create OpenSearch client for user with their JWT"""
|
||||||
from config.settings import is_no_auth_mode
|
# Get the effective JWT token (handles anonymous JWT creation)
|
||||||
|
jwt_token = self.get_effective_jwt_token(user_id, jwt_token)
|
||||||
logger.debug(
|
|
||||||
"get_user_opensearch_client",
|
|
||||||
user_id=user_id,
|
|
||||||
jwt_token_present=(jwt_token is not None),
|
|
||||||
no_auth_mode=is_no_auth_mode(),
|
|
||||||
)
|
|
||||||
|
|
||||||
# In no-auth mode, create anonymous JWT for OpenSearch DLS
|
|
||||||
if jwt_token is None and (is_no_auth_mode() or user_id in (None, AnonymousUser().user_id)):
|
|
||||||
if not hasattr(self, "_anonymous_jwt"):
|
|
||||||
# Create anonymous JWT token for OpenSearch OIDC
|
|
||||||
logger.debug("Creating anonymous JWT")
|
|
||||||
self._anonymous_jwt = self._create_anonymous_jwt()
|
|
||||||
logger.debug(
|
|
||||||
"Anonymous JWT created", jwt_prefix=self._anonymous_jwt[:50]
|
|
||||||
)
|
|
||||||
jwt_token = self._anonymous_jwt
|
|
||||||
logger.debug("Using anonymous JWT for OpenSearch")
|
|
||||||
|
|
||||||
# Check if we have a cached client for this user
|
# Check if we have a cached client for this user
|
||||||
if user_id not in self.user_opensearch_clients:
|
if user_id not in self.user_opensearch_clients:
|
||||||
|
|
@ -222,6 +204,31 @@ class SessionManager:
|
||||||
|
|
||||||
return self.user_opensearch_clients[user_id]
|
return self.user_opensearch_clients[user_id]
|
||||||
|
|
||||||
|
def get_effective_jwt_token(self, user_id: str, jwt_token: str) -> str:
|
||||||
|
"""Get the effective JWT token, creating anonymous JWT if needed in no-auth mode"""
|
||||||
|
from config.settings import is_no_auth_mode
|
||||||
|
|
||||||
|
logger.debug(
|
||||||
|
"get_effective_jwt_token",
|
||||||
|
user_id=user_id,
|
||||||
|
jwt_token_present=(jwt_token is not None),
|
||||||
|
no_auth_mode=is_no_auth_mode(),
|
||||||
|
)
|
||||||
|
|
||||||
|
# In no-auth mode, create anonymous JWT if needed
|
||||||
|
if jwt_token is None and (is_no_auth_mode() or user_id in (None, AnonymousUser().user_id)):
|
||||||
|
if not hasattr(self, "_anonymous_jwt"):
|
||||||
|
# Create anonymous JWT token for OpenSearch OIDC
|
||||||
|
logger.debug("Creating anonymous JWT")
|
||||||
|
self._anonymous_jwt = self._create_anonymous_jwt()
|
||||||
|
logger.debug(
|
||||||
|
"Anonymous JWT created", jwt_prefix=self._anonymous_jwt[:50]
|
||||||
|
)
|
||||||
|
jwt_token = self._anonymous_jwt
|
||||||
|
logger.debug("Using anonymous JWT")
|
||||||
|
|
||||||
|
return jwt_token
|
||||||
|
|
||||||
def _create_anonymous_jwt(self) -> str:
|
def _create_anonymous_jwt(self) -> str:
|
||||||
"""Create JWT token for anonymous user in no-auth mode"""
|
"""Create JWT token for anonymous user in no-auth mode"""
|
||||||
anonymous_user = AnonymousUser()
|
anonymous_user = AnonymousUser()
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ services:
|
||||||
langflow:
|
langflow:
|
||||||
volumes:
|
volumes:
|
||||||
- ./flows:/app/flows:Z
|
- ./flows:/app/flows:Z
|
||||||
image: phact/langflow:${LANGFLOW_VERSION:-responses}
|
image: phact/openrag-langflow:${LANGFLOW_VERSION:-latest}
|
||||||
container_name: langflow
|
container_name: langflow
|
||||||
ports:
|
ports:
|
||||||
- "7860:7860"
|
- "7860:7860"
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ services:
|
||||||
langflow:
|
langflow:
|
||||||
volumes:
|
volumes:
|
||||||
- ./flows:/app/flows:Z
|
- ./flows:/app/flows:Z
|
||||||
image: phact/langflow:${LANGFLOW_VERSION:-responses}
|
image: phact/openrag-langflow:${LANGFLOW_VERSION:-latest}
|
||||||
container_name: langflow
|
container_name: langflow
|
||||||
ports:
|
ports:
|
||||||
- "7860:7860"
|
- "7860:7860"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue