Files
OpenCode 68a9071cf1 feat: reconcile local master with origin (exa/hot-platform hunters, leaks ledger, latest results)
Local branch had diverged from origin/master (sibling commits on the same base). Rewrote local history linearly on top of origin/master, folding in all local content: exa/hot-platform discovery hunters, leaks ledger, nightly sweep orchestrator, updated .gitignore and skill docs, plus the latest hunt output and vault state. Remote-only files (vault keys, channel scripts) were restored rather than dropped, so the resulting tree is a full union of both sides.
2026-08-07 12:53:47 +08:00

1 line
26 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"repo": "castlecry/teka", "files": {"database_init.sql": {"e17337723a0e6516350f703e0202a31a3c33b80f": {"t": 1785746545.0112488, "n": 14720, "h": "e0795ad6b83039f0", "c": "-- ============================================================\n-- 智汇办公 AI 智能平台 - 数据库初始化脚本\n-- 数据库类型: PostgreSQL\n-- 包含: 建表语句 + 示例数据\n-- ============================================================\n\n-- ============================================================\n-- 第一部分: 建表语句\n-- ============================================================\n\n-- 角色表\nCREATE TABLE IF NOT EXISTS roles (\n id SERIAL PRIMARY KEY,\n name VARCHAR(50) NOT NULL UNIQUE,\n description TEXT,\n permissions JSONB DEFAULT '[]'::jsonb,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\n\n-- 用户表\nCREATE TABLE IF NOT EXISTS users (\n id SERIAL PRIMARY KEY,\n username VARCHAR(50) NOT NULL UNIQUE,\n email VARCHAR(100) NOT NULL UNIQUE,\n password_hash VARCHAR(255) NOT NULL,\n full_name VARCHAR(100),\n department VARCHAR(50),\n role_id INTEGER REFERENCES roles(id),\n status BOOLEAN DEFAULT TRUE,\n avatar VARCHAR(500),\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\n\n-- 知识库表\nCREATE TABLE IF NOT EXISTS knowledge_bases (\n id SERIAL PRIMARY KEY,\n name VARCHAR(100) NOT NULL,\n description TEXT,\n department VARCHAR(50),\n owner_id INTEGER REFERENCES users(id),\n embedding_model VARCHAR(100) DEFAULT 'qwen3-embedding:0.6b',\n is_personal BOOLEAN DEFAULT FALSE,\n module VARCHAR(50) DEFAULT 'general',\n is_shared BOOLEAN DEFAULT FALSE,\n is_locked BOOLEAN DEFAULT FALSE,\n status BOOLEAN DEFAULT TRUE,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\n\n-- 文档表\nCREATE TYPE document_status AS ENUM ('pending', 'processing', 'completed', 'failed', 'rejected', 'pending_review');\n\nCREATE TABLE IF NOT EXISTS documents (\n id SERIAL PRIMARY KEY,\n knowledge_base_id INTEGER REFERENCES knowledge_bases(id),\n filename VARCHAR(255) NOT NULL,\n file_path VARCHAR(500),\n file_type VARCHAR(50),\n size INTEGER,\n chunk_count INTEGER DEFAULT 0,\n status document_status DEFAULT 'pending',\n uploaded_by INTEGER REFERENCES users(id),\n uploaded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n audit_id INTEGER,\n audit_status VARCHAR(20) DEFAULT 'pending',\n rejection_reason TEXT\n);\n\n-- 内容审核日志表\nCREATE TABLE IF NOT EXISTS content_audit_logs (\n id SERIAL PRIMARY KEY,\n document_id INTEGER REFERENCES documents(id),\n filename VARCHAR(300) NOT NULL,\n knowledge_base_id INTEGER REFERENCES knowledge_bases(id),\n user_id INTEGER NOT NULL REFERENCES users(id),\n verdict VARCHAR(20) NOT NULL, -- PASS / REVIEW / BLOCK\n confidence REAL DEFAULT 0.5,\n categories JSONB DEFAULT '[]'::jsonb,\n reasons JSONB DEFAULT '[]'::jsonb,\n summary TEXT,\n raw_result TEXT,\n status VARCHAR(20) DEFAULT 'pending',\n reviewer_id INTEGER REFERENCES users(id),\n reviewer_comment TEXT,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n reviewed_at TIMESTAMP\n);\n\n-- 对话记录表\nCREATE TABLE IF NOT EXISTS conversation_logs (\n id SERIAL PRIMARY KEY,\n conversation_id VARCHAR(50),\n user_id INTEGER REFERENCES users(id),\n query TEXT,\n answer TEXT,\n sources JSONB DEFAULT '[]'::jsonb,\n knowledge_base_ids JSONB DEFAULT '[]'::jsonb,\n module VARCHAR(50) DEFAULT 'general',\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\n\n-- 系统配置表\nCREATE TABLE IF NOT EXISTS system_config (\n id SERIAL PRIMARY KEY,\n key VARCHAR(100) NOT NULL UNIQUE,\n value TEXT,\n description TEXT,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\n\n-- 用户反馈表\nCREATE TABLE IF NOT EXISTS feedback (\n id SERIAL PRIMARY KEY,\n conversation_id VARCHAR(50),\n message_id VARCHAR(50),\n user_id INTEGER REFERENCES users(id),\n rating INTEGER,\n correction TEXT,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\n\n-- 对话收藏表\nCREATE TABLE IF NOT EXISTS conversation_favorites (\n id SERIAL PRIMARY KEY,\n conversation_id VARCHAR(50) NOT NULL,\n message_id VARCHAR(100),\n user_id INTEGER NOT NULL REFERENCES users(id),\n title VARCHAR(200),\n query TEXT,\n answer TEXT,\n module VARCHAR(50) DEFAULT 'general',\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\n\n-- 索引\nCREATE INDEX IF NOT EXISTS idx_users_username ON users(username);\nCREATE INDEX IF NOT EXISTS idx_users_email ON users(email);\nCREATE INDEX IF NOT EXISTS idx_users_role_id ON users(role_id);\nCREATE INDEX IF NOT EXISTS idx_knowledge_bases_owner_id ON knowledge_bases(owner_id);\nCREATE INDEX IF NOT EXISTS idx_knowledge_bases_module ON knowledge_bases(module);\nCREATE INDEX IF NOT EXISTS idx_documents_kb_id ON documents(knowledge_base_id);\nCREATE INDEX IF NOT EXISTS idx_documents_uploaded_by ON documents(uploaded_by);\nCREATE INDEX IF NOT EXISTS idx_conversation_logs_user_id ON conversation_logs(user_id);\nCREATE INDEX IF NOT EXISTS idx_conversation_logs_conv_id ON conversation_logs(conversation_id);\nCREATE INDEX IF NOT EXISTS idx_conversation_logs_module ON conversation_logs(module);\nCREATE INDEX IF NOT EXISTS idx_content_audit_user_id ON content_audit_logs(user_id);\nCREATE INDEX IF NOT EXISTS idx_content_audit_verdict ON content_audit_logs(verdict);\nCREATE INDEX IF NOT EXISTS idx_feedback_user_id ON feedback(user_id);\nCREATE INDEX IF NOT EXISTS idx_favorites_user_id ON conversation_favorites(user_id);\n\n-- ============================================================\n-- 第二部分: 示例数据\n-- ============================================================\n\n-- 角色数据\nINSERT INTO roles (name, description, permissions) VALUES\n ('admin', '管理员,拥有全部权限', '[\"user.create\",\"user.read\",\"user.update\",\"user.delete\",\"kb.create\",\"kb.read\",\"kb.update\",\"kb.delete\",\"doc.upload\",\"doc.delete\",\"audit.review\",\"config.manage\",\"feedback.read\"]'::jsonb),\n ('user', '普通用户,基础使用权限', '[\"user.read\",\"kb.read\",\"doc.upload\",\"feedback.create\",\"feedback.read\"]'::jsonb);\n\n-- 用户数据(密码均为 bcrypt 加密,明文为 \"123456\")\nINSERT INTO users (username, email, password_hash, full_name, department, role_id, status) VALUES\n ('admin', 'admin@company.com', '$2b$12$LJ3m4ys3Lk0pKZxKxKxKxOqJ5qZ5qZ5qZ5qZ5qZ5qZ5qZ5qZ5qZ5', '系统管理员', '技术部', 1, TRUE),\n ('zhangsan', 'zhangsan@company.com', '$2b$12$LJ3m4ys3Lk0pKZxKxKxKxOqJ5qZ5qZ5qZ5qZ5qZ5qZ5qZ5qZ5qZ5', '张三', '人力资源部', 2, TRUE),\n ('lisi', 'lisi@company.com', '$2b$12$LJ3m4ys3Lk0pKZxKxKxKxOqJ5qZ5qZ5qZ5qZ5qZ5qZ5qZ5qZ5qZ5', '李四', '财务部', 2, TRUE),\n ('wangwu', 'wangwu@company.com', '$2b$12$LJ3m4ys3Lk0pKZxKxKxKxOqJ5qZ5qZ5qZ5qZ5qZ5qZ5qZ5qZ5qZ5', '王五', '技术部', 2, TRUE),\n ('zhaoliu', 'zhaoliu@company.com', '$2b$12$LJ3m4ys3Lk0pKZxKxKxKxOqJ5qZ5qZ5qZ5qZ5qZ5qZ5qZ5qZ5qZ5', '赵六', '行政部', 2, FALSE);\n\n-- 知识库数据\nINSERT INTO knowledge_bases (name, description, department, owner_id, is_personal, module, is_shared, is_locked) VALUES\n ('规章制度', '公司规章制度,包含考勤、薪酬、绩效、请假等制度文件', NULL, 1, FALSE, 'policy', TRUE, TRUE),\n ('产品技术', '产品技术文档,包含API文档、架构说明、运维手册等', NULL, 1, FALSE, 'tech', TRUE, TRUE),\n ('行政服务', '行政服务指南,包含场地预约、IT设备、员工福利等', NULL, 1, FALSE, 'admin', TRUE, TRUE),\n ('通用知识库', '通用知识问答库', NULL, 1, FALSE, 'general', TRUE, FALSE),\n ('张三的个人笔记', '张三个人整理的学习笔记', '人力资源部', 2, TRUE, 'general', FALSE, FALSE),\n ('李四的财务备忘', '李四个人的财务工作备忘', '财务部', 3, TRUE, 'general', FALSE, FALSE);\n\n-- 文档数据\nINSERT INTO documents (knowledge_base_id, filename, file_path, file_type, size, chunk_count, status, uploaded_by, audit_status) VALUES\n (1, '员工手册.pdf', '/uploads/employee_handbook.pdf', 'pdf', 2048576, 120, 'completed', 1, 'passed'),\n (1, '考勤管理制度.docx', '/uploads/attendance_policy.docx', 'docx', 524288, 35, 'completed', 1, 'passed'),\n (1, '薪酬福利制度.pdf', '/uploads/compensation_policy.pdf', 'pdf', 1048576, 60, 'completed', 1, 'passed'),\n (2, 'API接口文档.pdf', '/uploads/api_docs.pdf', 'pdf', 3145728, 200, 'completed', 1, 'passed'),\n (2, '系统架构说明.docx', '/uploads/architecture.docx', 'docx', 1572864, 80, 'completed', 1, 'passed'),\n (3, '场地预约指南.pdf', '/uploads/venue_guide.pdf', 'pdf', 786432, 25, 'completed', 1, 'passed'),\n (3, 'IT设备申领流程.docx', '/uploads/it_equipment.docx', 'docx', 262144, 15, 'completed', 1, 'passed'),\n (4, '公司简介.pdf', '/uploads/company_intro.pdf', 'pdf', 524288, 30, 'completed', 1, 'passed'),\n (5, 'Python学习笔记.pdf', '/uploads/python_notes.pdf', 'pdf', 1048576, 50, 'completed', 2, 'passed'),\n (1, '违规文档.docx', '/uploads/violation.docx', 'docx', 102400, 0, 'rejected', 2, 'rejected');\n\n-- 内容审核日志数据\nINSERT INTO content_audit_logs (document_id, filename, knowledge_base_id, user_id, verdict, confidence, categories, reasons, summary, status) VALUES\n (1, '员工手册.pdf', 1, 1, 'PASS', 0.85, '[]'::jsonb, '[]'::jsonb, '文档内容合规,未发现敏感信息', 'auto_processed'),\n (2, '考勤管理制度.docx', 1, 1, 'PASS', 0.90, '[]'::jsonb, '[]'::jsonb, '文档内容合规,未发现敏感信息', 'auto_processed'),\n (3, '薪酬福利制度.pdf', 1, 1, 'PASS', 0.88, '[]'::jsonb, '[]'::jsonb, '文档内容合规,未发现敏感信息', 'auto_processed'),\n (4, 'API接口文档.pdf', 2, 1, 'PASS', 0.92, '[]'::jsonb, '[]'::jsonb, '文档内容合规,未发现敏感信息', 'auto_processed'),\n (5, '系统架构说明.docx', 2, 1, 'PASS', 0.87, '[]'::jsonb, '[]'::jsonb, '文档内容合规,未发现敏感信息', 'auto_processed'),\n (6, '场地预约指南.pdf', 3, 1, 'PASS', 0.91, '[]'::jsonb, '[]'::jsonb, '文档内容合规,未发现敏感信息', 'auto_processed'),\n (7, 'IT设备申领流程.docx', 3, 1, 'PASS', 0.89, '[]'::jsonb, '[]'::jsonb, '文档内容合规,未发现敏感信息', 'auto_processed'),\n (8, '公司简介.pdf', 4, 1, 'PASS', 0.93, '[]'::jsonb, '[]'::jsonb, '文档内容合规,未发现敏感信息', 'auto_processed'),\n (9, 'Python学习笔记.pdf', 5, 2, 'PASS', 0.86, '[]'::jsonb, '[]'::jsonb, '文档内容合规,未发现敏感信息', 'auto_processed'),\n (10, '违规文档.docx', 1, 2, 'BLOCK', 0.95, '[\"商业机密\",\"个人隐私\"]'::jsonb, '[\"包含公司内部源代码\",\"包含员工身份证号\"]'::jsonb, '文档包含商业机密和个人隐私信息,已被拒绝', 'auto_processed');\n\n-- 对话记录数据\nINSERT INTO conversation_logs (conversation_id, user_id, query, answer, sources, knowledge_base_ids, module) VALUES\n ('conv-001', 2, '公司年假有多少天?', '根据公司《员工手册》规定:\n\n- 工作满1年不满10年:5天年假\n- 工作满10年不满20年:10天年假\n- 工作满20年以上:15天年假\n\n年假需在当年使用完毕,特殊情况可申请跨年度使用。', '[{\"title\":\"员工手册.pdf\",\"page\":15,\"snippet\":\"年假天数根据工龄计算...\"}]'::jsonb, '[1]'::jsonb, 'policy'),\n ('conv-001', 2, '怎么申请年假?', '年假申请流程如下:\n\n1. 登录OA系统,进入\"请假申请\"模块\n2. 选择\"年假\"类型,填写起止日期\n3. 提交后由直属领导审批\n4. 审批通过后自动同步到考勤系统\n\n注意:需提前3个工作日申请。', '[{\"title\":\"员工手册.pdf\",\"page\":16,\"snippet\":\"年假申请需提前3个工作日...\"}]'::jsonb, '[1]'::jsonb, 'policy'),\n ('conv-002', 3, '报销流程是什么?', '报销流程如下:\n\n1. 收集发票和消费凭证\n2. 填写报销单(OA系统-财务模块)\n3. 直属领导审批\n4. 财务部审核\n5. 每月15日和30日统一打款\n\n报销时限:消费发生后30天内。', '[{\"title\":\"员工手册.pdf\",\"page\":28,\"snippet\":\"报销流程及注意事项...\"}]'::jsonb, '[1]'::jsonb, 'policy'),\n ('conv-003', 4, 'API认证方式是什么?', '我们的API采用JWT Token认证方式:\n\n1. 调用 /api/auth/login 获取Token\n2. 在请求头中添加 Authorization: Bearer <token>\n3. Token有效期30分钟,过期需重新登录\n\n详细文档请参考《API接口文档》第3章。', '[{\"title\":\"API接口文档.pdf\",\"page\":12,\"snippet\":\"JWT认证机制说明...\"}]'::jsonb, '[2]'::jsonb, 'tech'),\n ('conv-004', 2, '今天天气怎么样?', '抱歉,我无法直接获取天气信息。但我可以帮您搜索一下。\n\n根据搜索结果,今天北京天气:晴转多云,气温18℃~28℃,空气质量良好。适合户外活动。', '[]'::jsonb, '[4]'::jsonb, 'general'),\n ('conv-005', 3, '帮我写一份会议纪要模板', '以下是一份标准的会议纪要模板:\n\n---\n# 会议纪要\n\n**会议主题:**\n**会议时间:**\n**会议地点:**\n**参会人员:**\n**记录人:**\n\n## 会议议程\n1.\n2.\n\n## 讨论内容\n...\n\n## 决议事项\n| 序号 | 事项 | 负责人 | 完成时间 |\n|------|------|--------|----------|\n\n---\n\n需要我帮您生成Word文档吗?', '[]'::jsonb, '[4]'::jsonb, 'general');\n\n-- 系统配置数据\nINSERT INTO system_config (key, value, description) VALUES\n ('llm_model', 'deepseek-chat', '默认使用的LLM模型'),\n ('llm_api_base', 'https://api.deepseek.com/v1', 'LLM API地址'),\n ('llm_api_key', 'sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'LLM API密钥(已脱敏)'),\n ('embedding_model', 'qwen3-embedding:0.6b', '向量嵌入模型'),\n ('opensearch_host', 'http://localhost:9200', 'OpenSearch地址'),\n ('redis_host', 'localhost', 'Redis地址'),\n ('redis_port', '6379', 'Redis端口'),\n ('jwt_secret_key', 'your-secret-key-change-in-production', 'JWT签名密钥'),\n ('jwt_algorithm', 'HS256', 'JWT签名算法'),\n ('jwt_expire_minutes', '30', 'JWT Token有效期(分钟)'),\n ('chunk_size', '500', '文本切片大小'),\n ('chunk_overlap', '50', '文本切片重叠大小'),\n ('top_k', '5', 'RAG检索返回的文档数量'),\n ('rerank_model', 'bge-reranker-v2-m3', 'Rerank精排模型'),\n ('max_iterations', '10', 'LangGraph最大迭代次数'),\n ('content_moderation_enabled', 'true', '是否启用内容审核'),\n ('web_search_enabled', 'true', '是否启用联网搜索'),\n ('tavily_api_key', 'tvly-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'Tavily搜索API密钥(已脱敏)');\n\n-- 用户反馈数据\nINSERT INTO feedback (conversation_id, message_id, user_id, rating, correction) VALUES\n ('conv-001', 'msg-001', 2, 5, NULL),\n ('conv-001', 'msg-002', 2, 5, NULL),\n ('conv-002', 'msg-003', 3, 4, '报销时限应该是60天而不是30天'),\n ('conv-003', 'msg-004', 4, 5, NULL),\n ('conv-004', 'msg-005', 2, 3, '天气信息不够准确,建议接入实时天气API'),\n ('conv-005', 'msg-006', 3, 5, '会议纪要模板很实用');\n\n-- 对话收藏数据\nINSERT INTO conversation_favorites (conversation_id, message_id, user_id, title, query, answer, module) VALUES\n ('conv-001', 'msg-001', 2, '年假天数查询', '公司年假有多少天?', '根据公司《员工手册》规定:工作满1年不满10年5天,满10年不满20年10天,满20年以上15天。', 'policy'),\n ('conv-003', 'msg-004', 4, 'API认证方式', 'API认证方式是什么?', 'API采用JWT Token认证,调用/login获取Token,有效期30分钟。', 'tech'),\n ('conv-005', 'msg-006', 3, '会议纪要模板', '帮我写一份会议纪要模板', '标准会议纪要模板,包含会议主题、时间、地点、参会人员、议程、讨论内容、决议事项等。', 'general');\n\n-- ============================================================\n-- 第三部分: 常用查询示例\n-- ============================================================\n\n-- 查询所有知识库及其文档数量\n-- SELECT kb.name, kb.module, COUNT(d.id) AS doc_count\n-- FROM knowledge_bases kb\n-- LEFT JOIN documents d ON kb.id = d.knowledge_base_id AND d.status = 'completed'\n-- GROUP BY kb.id;\n\n-- 查询用户的对话记录\n-- SELECT cl.query, cl.answer, cl.module, cl.created_at\n-- FROM conversation_logs cl\n-- WHERE cl.user_id = 2\n-- ORDER BY cl.created_at DESC;\n\n-- 查询审核被拒绝的文档\n-- SELECT d.filename, d.rejection_reason, cal.verdict, cal.confidence, cal.reasons\n-- FROM documents d\n-- JOIN content_audit_logs cal ON d.audit_id = cal.id\n-- WHERE cal.verdict = 'BLOCK';\n\n-- 查询各模块的对话统计\n-- SELECT module, COUNT(*) AS total_queries, AVG(LENGTH(answer)) AS avg_answer_length\n-- FROM conversation_logs\n-- GROUP BY module;\n\n-- 查询用户收藏的对话\n-- SELECT cf.title, cf.query, cf.module, cf.created_at\n-- FROM conversation_favorites cf\n-- WHERE cf.user_id = 2\n-- ORDER BY cf.created_at DESC;"}}, "backend/.env.example": {"e17337723a0e6516350f703e0202a31a3c33b80f": {"t": 1785746736.7755864, "n": 890, "h": "7d7d03c3a7e1a441", "c": "# LLM 配置\nLLM_MODE=local\nOLLAMA_MODEL=qwen3.5:9b\nOLLAMA_BASE_URL=http://localhost:11434\n\n# DeepSeek API 配置\nDEEPSEEK_API_KEY=your-deepseek-api-key-here\nDEEPSEEK_BASE_URL=https://api.deepseek.com\n\n# JWT 密钥\nJWT_SECRET_KEY=your-jwt-secret-key-change-in-production\n\n# Embedding 模型\nEMBED_MODEL=qwen3-embedding:0.6b\n\n# PostgreSQL 配置\nPOSTGRES_HOST=localhost\nPOSTGRES_PORT=5432\nPOSTGRES_DB=rag_db\nPOSTGRES_USER=postgres\nPOSTGRES_PASSWORD=MyPassword123!\n\n# OpenSearch 配置\nOPENSEARCH_HOST=https://localhost:9200\nOPENSEARCH_USER=admin\nOPENSEARCH_PASSWORD=MyPassword123!\n\n# Redis 配置\nREDIS_HOST=localhost\nREDIS_PORT=6379\n\n# SearXNG 配置\nSEARXNG_HOST=http://localhost:18080\nSEARXNG_SECRET=your-random-secret-key-change-this\n\n# MinerU API 配置\nMINERU_HOST=http://127.0.0.1:8000\n\n# 文本切片配置\nCHUNK_SIZE=500\nCHUNK_OVERLAP=100\n\n# 检索配置\nTOP_K=5\nWEB_SEARCH_COUNT=3\n\n# 对话历史\nHISTORY_TURNS=10\n\n# LLM 推理超时(秒)\nLLM_TIMEOUT=600\n"}, "aa39b74bc6403d764d5d18f91ae97cbdb35dbb66": {"t": 1785765494.9310665, "n": 890, "h": "7d7d03c3a7e1a441", "c": "# LLM 配置\nLLM_MODE=local\nOLLAMA_MODEL=qwen3.5:9b\nOLLAMA_BASE_URL=http://localhost:11434\n\n# DeepSeek API 配置\nDEEPSEEK_API_KEY=your-deepseek-api-key-here\nDEEPSEEK_BASE_URL=https://api.deepseek.com\n\n# JWT 密钥\nJWT_SECRET_KEY=your-jwt-secret-key-change-in-production\n\n# Embedding 模型\nEMBED_MODEL=qwen3-embedding:0.6b\n\n# PostgreSQL 配置\nPOSTGRES_HOST=localhost\nPOSTGRES_PORT=5432\nPOSTGRES_DB=rag_db\nPOSTGRES_USER=postgres\nPOSTGRES_PASSWORD=MyPassword123!\n\n# OpenSearch 配置\nOPENSEARCH_HOST=https://localhost:9200\nOPENSEARCH_USER=admin\nOPENSEARCH_PASSWORD=MyPassword123!\n\n# Redis 配置\nREDIS_HOST=localhost\nREDIS_PORT=6379\n\n# SearXNG 配置\nSEARXNG_HOST=http://localhost:18080\nSEARXNG_SECRET=your-random-secret-key-change-this\n\n# MinerU API 配置\nMINERU_HOST=http://127.0.0.1:8000\n\n# 文本切片配置\nCHUNK_SIZE=500\nCHUNK_OVERLAP=100\n\n# 检索配置\nTOP_K=5\nWEB_SEARCH_COUNT=3\n\n# 对话历史\nHISTORY_TURNS=10\n\n# LLM 推理超时(秒)\nLLM_TIMEOUT=600\n"}, "2facdc1348d3e8f5a5b339a72dee42436cce2da1": {"t": 1785765496.2861958, "n": 888, "h": "b89d2f07e4a8f845", "c": "# LLM 配置\nLLM_MODE=local\nOLLAMA_MODEL=qwen3.5:9b\nOLLAMA_BASE_URL=http://localhost:11434\n\n# DeepSeek API 配置\nDEEPSEEK_API_KEY=your-deepseek-api-key-here\nDEEPSEEK_BASE_URL=https://api.deepseek.com\n\n# JWT 密钥\nJWT_SECRET_KEY=your-jwt-secret-key-change-in-production\n\n# Embedding 模型\nEMBED_MODEL=qwen3-embedding:4b\n\n# PostgreSQL 配置\nPOSTGRES_HOST=localhost\nPOSTGRES_PORT=5432\nPOSTGRES_DB=rag_db\nPOSTGRES_USER=postgres\nPOSTGRES_PASSWORD=MyPassword123!\n\n# OpenSearch 配置\nOPENSEARCH_HOST=https://localhost:9200\nOPENSEARCH_USER=admin\nOPENSEARCH_PASSWORD=MyPassword123!\n\n# Redis 配置\nREDIS_HOST=localhost\nREDIS_PORT=6379\n\n# SearXNG 配置\nSEARXNG_HOST=http://localhost:18080\nSEARXNG_SECRET=your-random-secret-key-change-this\n\n# MinerU API 配置\nMINERU_HOST=http://127.0.0.1:8000\n\n# 文本切片配置\nCHUNK_SIZE=500\nCHUNK_OVERLAP=100\n\n# 检索配置\nTOP_K=5\nWEB_SEARCH_COUNT=3\n\n# 对话历史\nHISTORY_TURNS=10\n\n# LLM 推理超时(秒)\nLLM_TIMEOUT=600\n"}, "d444073f37ba283a997bb4c308a8176880a92f5d": {"t": 1785765497.590361, "n": 896, "h": "2af842898f2da630", "c": "# LLM 配置\nLLM_MODE=local\nOLLAMA_MODEL=qwen3.5:9b\nOLLAMA_BASE_URL=http://localhost:11434\n\n# DeepSeek API 配置\nDEEPSEEK_API_KEY=your-deepseek-api-key-here\nDEEPSEEK_BASE_URL=https://api.deepseek.com\n\n# JWT 密钥\nJWT_SECRET_KEY=your-jwt-secret-key-change-in-production\n\n# Embedding 模型\nEMBEDDING_MODEL=BAAI/bge-small-zh-v1.5\n\n# PostgreSQL 配置\nPOSTGRES_HOST=localhost\nPOSTGRES_PORT=5432\nPOSTGRES_DB=rag_db\nPOSTGRES_USER=postgres\nPOSTGRES_PASSWORD=MyPassword123!\n\n# OpenSearch 配置\nOPENSEARCH_HOST=https://localhost:9200\nOPENSEARCH_USER=admin\nOPENSEARCH_PASSWORD=MyPassword123!\n\n# Redis 配置\nREDIS_HOST=localhost\nREDIS_PORT=6379\n\n# SearXNG 配置\nSEARXNG_HOST=http://localhost:18080\nSEARXNG_SECRET=your-random-secret-key-change-this\n\n# MinerU API 配置\nMINERU_HOST=http://127.0.0.1:8000\n\n# 文本切片配置\nCHUNK_SIZE=500\nCHUNK_OVERLAP=100\n\n# 检索配置\nTOP_K=5\nWEB_SEARCH_COUNT=3\n\n# 对话历史\nHISTORY_TURNS=10\n\n# LLM 推理超时(秒)\nLLM_TIMEOUT=600\n"}}, "backend/docker-compose.yml": {"e17337723a0e6516350f703e0202a31a3c33b80f": {"t": 1786068533.1997807, "n": 3031, "h": "f77c7b73a8e4a329", "c": "version: '3.8'\n\nservices:\n postgres:\n image: pgvector/pgvector:pg17\n container_name: pg-vector\n environment:\n - POSTGRES_PASSWORD=MyPassword123!\n - POSTGRES_DB=rag_db\n - POSTGRES_USER=postgres\n ports:\n - \"5432:5432\"\n volumes:\n - postgres-data:/var/lib/postgresql/data\n networks:\n - rag-network\n healthcheck:\n test: [\"CMD-SHELL\", \"pg_isready -U postgres -d rag_db\"]\n interval: 10s\n timeout: 5s\n retries: 3\n\n opensearch:\n image: opensearchproject/opensearch:2.15.0\n container_name: opensearch\n environment:\n - discovery.type=single-node\n - plugins.security.disabled=true\n - OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m\n ports:\n - \"9200:9200\"\n - \"9600:9600\"\n volumes:\n - opensearch-data:/usr/share/opensearch/data\n networks:\n - rag-network\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:9200/_cluster/health\"]\n interval: 30s\n timeout: 10s\n retries: 3\n\n redis:\n image: redis:7-alpine\n container_name: redis\n ports:\n - \"6379:6379\"\n volumes:\n - redis-data:/data\n networks:\n - rag-network\n healthcheck:\n test: [\"CMD\", \"redis-cli\", \"ping\"]\n interval: 10s\n timeout: 5s\n retries: 3\n\n searxng:\n image: searxng/searxng:latest\n container_name: searxng\n ports:\n - \"18080:8080\"\n volumes:\n - ./searxng-settings.yml:/etc/searxng/settings.yml:ro\n - searxng-data:/etc/searxng\n - searxng-log:/var/log/searxng\n networks:\n - rag-network\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:8080/\"]\n interval: 30s\n timeout: 10s\n retries: 3\n\n rag-app:\n build: .\n container_name: rag-app\n ports:\n - \"8888:8888\"\n environment:\n - POSTGRES_HOST=postgres\n - POSTGRES_PORT=5432\n - POSTGRES_DB=rag_db\n - POSTGRES_USER=postgres\n - POSTGRES_PASSWORD=MyPassword123!\n - OPENSEARCH_HOST=http://opensearch:9200\n - OPENSEARCH_USER=admin\n - OPENSEARCH_PASSWORD=\n - OLLAMA_HOST=http://host.docker.internal:11434\n - DEEPSEEK_API_KEY=your-deepseek-api-key\n - DEEPSEEK_BASE_URL=https://api.deepseek.com\n - SEARXNG_HOST=http://searxng:8080\n - SEARXNG_SECRET=your-random-secret-key-change-this\n - MINERU_HOST=http://host.docker.internal:8000\n - REDIS_HOST=redis\n - REDIS_PORT=6379\n volumes:\n - ./knowledge_base:/app/knowledge_base\n - ./uploads:/app/uploads\n extra_hosts:\n - \"host.docker.internal:host-gateway\"\n depends_on:\n postgres:\n condition: service_healthy\n opensearch:\n condition: service_healthy\n redis:\n condition: service_healthy\n searxng:\n condition: service_healthy\n networks:\n - rag-network\n command: [\"uvicorn\", \"main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8888\"]\n\nvolumes:\n postgres-data:\n opensearch-data:\n redis-data:\n searxng-data:\n searxng-log:\n\nnetworks:\n rag-network:\n driver: bridge\n"}}}}