14 Commits

Author SHA1 Message Date
ly c4cf09a28f Merge branch 'dev' into dev-web 2024-09-05 10:11:35 +08:00
ly 75fde3598b Merge branch 'dev' of https://git.97id.com/ly/zjdataai-app into dev 2024-09-05 10:11:10 +08:00
wanyaokun aba6475c5a 将事件名称转义成中文及优化关键字检索 2024-09-05 09:24:35 +08:00
wanyaokun ae19725d72 修改模型参数 2024-09-05 09:01:27 +08:00
wanyaokun 97a486e631 优化模型初始化代码 2024-09-04 15:00:38 +08:00
wanyaokun 728ee06c5a 支持节点元数据输出及代码优化,减少事件重复添加 2024-09-02 19:58:18 +08:00
wanyaokun a4dd385368 修改缺陷:获取会话时未记录选择的工程信息 2024-09-02 09:26:26 +08:00
wanyaokun 24c808d66d 修改反馈取消时异常问题 2024-09-02 08:49:32 +08:00
wanyaokun ced3199550 新增工程数据 2024-08-30 19:12:40 +08:00
wanyaokun c4088fe963 提交配置文件 2024-08-30 16:45:39 +08:00
wanyaokun e7628809ad 新增工程信息、检索的知识片段节点回传、下一轮建议问题列表 2024-08-30 16:42:36 +08:00
wanyaokun 73565b26e4 合并Dev分支代码 2024-08-30 10:49:05 +08:00
wanyaokun e9ccd7db35 合并代码 2024-08-28 20:02:15 +08:00
wanyaokun 4020b603b1 合并代码 2024-08-28 19:58:37 +08:00
64 changed files with 6220 additions and 2193 deletions
+39 -23
View File
@@ -4,34 +4,48 @@ SQL_DATABASE_URL=mysql+pymysql://zjinfo1:Dy2Bcr53Hm5xRkba@110.42.234.166:3306/zj
#SQL_DATABASE_URL=mysql+pymysql://zjinfo2:GSKcziSdBixDXwcd@110.42.234.166:3306/zjinfo2 #SQL_DATABASE_URL=mysql+pymysql://zjinfo2:GSKcziSdBixDXwcd@110.42.234.166:3306/zjinfo2
SQLITE_DATABASE_URL=sqlite:///./source.db SQLITE_DATABASE_URL=sqlite:///./source.db
DASHSCOPE_API_KEY=sk-02c8540e86d84b7ca0e6f4f51bac6e60 # The number of similar embeddings to return when retrieving documents.
# The provider for the AI models to use. TOP_K=10
MODEL_PROVIDER=dashscope #--------------------------
# The name of LLM model to use. # 是否启用混合检索
MODEL=qwen-max HYBRID_ENABLED = true
# 混合检索阈值
HYBRID_ALPHA = 0.6
# 是否启用检索重排功能 # 是否启用检索重排功能
ENABLE_RERANK=true RERANK_ENABLED=true
# Name of the embedding model to use.
EMBEDDING_MODEL=text-embedding-v2
# Dimension of the embedding model to use. #---------- rerank- Xinference ----------------
RERANK_PROVIDER=xinference
RERANK_MODEL=bge-reranker-v2-m3
RERANK_BASE_URL=http://10.1.16.39:9995
RERANK_TOP_N=5
RERANK_THRESHOLD=0.3
#---------- model - Xinference ----------------
#MODEL_PROVIDER=xinference
#OPENAI_API_KEY=xinference
#BASE_URL=http://172.20.0.145:9995
#MODEL=Qwen2-72B-Instruct-GPTQ-Int8
## Temperature for sampling from the model.
#LLM_TEMPERATURE=0.1
#---------- model - dashscope ----------------
MODEL_PROVIDER=dashscope
DASHSCOPE_API_KEY=sk-221d2d202e104618a56002ce2e7dc0d0
MODEL=qwen-max
#---------- embedding - Xinference ----------------
EMBEDDING_PROVIDER=xinference
EMBEDDING_MODEL=bge-m3
EMBEDDING_BASE_URL=http://10.1.16.39:9995
EMBEDDING_DIM=1024 EMBEDDING_DIM=1024
# The questions to help users get started (multi-line). # The questions to help users get started (multi-line).
CONVERSATION_STARTERS=本工程指什么?\n总算表有哪些费用?\n项目划分哪些内容构成?\n其他费用表有哪些内容? CONVERSATION_STARTERS=本工程指什么?\n总算表有哪些费用?\n项目划分哪些内容构成?\n其他费用表有哪些内容?
# The OpenAI API key to use.
# OPENAI_API_KEY=
# Temperature for sampling from the model.
# LLM_TEMPERATURE=
# Maximum number of tokens to generate.
# LLM_MAX_TOKENS=
# The number of similar embeddings to return when retrieving documents.
TOP_K=5
# The time in milliseconds to wait for the stream to return a response. # The time in milliseconds to wait for the stream to return a response.
STREAM_TIMEOUT=60000 STREAM_TIMEOUT=60000
@@ -53,9 +67,8 @@ VECTOR_STORE_PATH=./storage_vector
BM_RETRIEVER_PATH =./storage_bm BM_RETRIEVER_PATH =./storage_bm
PHOENIX_API_KEY=123456 PHOENIX_API_KEY=123456
PHOENIX_URL=http://localhost:6006/v1/traces PHOENIX_URL=http://10.1.6.103:6006/v1/traces
PHOENIX_PROJECT_NAME=ly_zjapp PHOENIX_PROJECT_NAME=ly_zjapp
#OTEL_SERVICE_NAME=ly_zjapp #OTEL_SERVICE_NAME=ly_zjapp
#OTEL_RESOURCE_ATTRIBUTES=openinference.project.name=ly_zjapp #OTEL_RESOURCE_ATTRIBUTES=openinference.project.name=ly_zjapp
@@ -80,4 +93,7 @@ SYSTEM_PROMPT="You are a weather forecast agent. You help users to get the weath
- You can install any pip package (if it exists) by running a cell with pip install. - You can install any pip package (if it exists) by running a cell with pip install.
" "
PRJTOJSON_URL = 'http://10.1.6.60:8092'
PROJECT_TITLE = "您好,我是博微工程理解小助手,您可以问我有关[线路工程]工程数据的相关问题!" PROJECT_TITLE = "您好,我是博微工程理解小助手,您可以问我有关[线路工程]工程数据的相关问题!"
CHAT_UPLOAD_FILECACHE = "./output/uploaded"
+17 -13
View File
@@ -14,27 +14,28 @@ HYBRID_ALPHA = 0.6
#-------------------------- #--------------------------
# 是否启用检索重排功能 # 是否启用检索重排功能
RERANK_ENABLED=true RERANK_ENABLED=true
# Rerank model
#---------- rerank- Xinference ----------------
RERANK_PROVIDER=xinference
RERANK_MODEL=bge-reranker-v2-m3 RERANK_MODEL=bge-reranker-v2-m3
RERANK_BASE_URL=http://10.1.16.39:9995 RERANK_BASE_URL=http://10.1.16.39:9995
RERANK_TOP_N=5 RERANK_TOP_N=5
RERANK_THRESHOLD=0.3 RERANK_THRESHOLD=0.3
#---------- Xinference ----------------
# The provider for the AI models to use. #---------- model - Xinference ----------------
MODEL_PROVIDER=xinference MODEL_PROVIDER=xinference # The provider for the AI models to use.
# The OpenAI API key to use. OPENAI_API_KEY=xinference # The OpenAI API key to use.
OPENAI_API_KEY=xinference
BASE_URL=http://10.1.0.142:9995 BASE_URL=http://10.1.0.142:9995
MODEL=Qwen2-72B-Instruct-GPTQ-Int8 MODEL=Qwen2-72B-Instruct-GPTQ-Int8
# Temperature for sampling from the model. LLM_TEMPERATURE=0.1 # Temperature for sampling from the model.
LLM_TEMPERATURE=0.1 #LLM_MAX_TOKENS= # Maximum number of tokens to generate.
# Maximum number of tokens to generate.
#LLM_MAX_TOKENS=
# Name of the embedding model to use. #---------- embedding - Xinference ----------------
EMBEDDING_PROVIDER=xinference
EMBEDDING_MODEL=bge-m3 EMBEDDING_MODEL=bge-m3
EMBEDDING_BASE_URL=http://10.1.16.39:9995 EMBEDDING_BASE_URL=http://10.1.16.39:9995
# Dimension of the embedding model to use. EMBEDDING_DIM=1024 # Dimension of the embedding model to use.
EMBEDDING_DIM=1024
##---------- OpenAI ---------------- ##---------- OpenAI ----------------
## The provider for the AI models to use. ## The provider for the AI models to use.
@@ -111,4 +112,7 @@ SYSTEM_PROMPT="You are a weather forecast agent. You help users to get the weath
- You can install any pip package (if it exists) by running a cell with pip install. - You can install any pip package (if it exists) by running a cell with pip install.
" "
PRJTOJSON_URL = 'http://10.1.6.60:8092'
PROJECT_TITLE = "您好,我是博微工程理解小助手,您可以问我有关[线路工程]工程数据的相关问题!" PROJECT_TITLE = "您好,我是博微工程理解小助手,您可以问我有关[线路工程]工程数据的相关问题!"
CHAT_UPLOAD_FILECACHE = "./output/uploaded"
+194 -68
View File
@@ -1,37 +1,64 @@
import asyncio import asyncio
import json import json
import logging import logging
import time import time
from typing import Dict, List, Any, Optional, AsyncGenerator from typing import Dict, List, Any, Optional, AsyncGenerator
from collections import deque
from aiostream import stream from aiostream import stream
from fastapi import APIRouter, Request from fastapi import APIRouter, Request,HTTPException
from fastapi.responses import StreamingResponse from fastapi.responses import StreamingResponse
from llama_index.core import BaseCallbackHandler from llama_index.core import BaseCallbackHandler
from llama_index.core.base.llms.types import ChatMessage from llama_index.core.base.llms.types import ChatMessage
from llama_index.core.callbacks import CBEventType from llama_index.core.callbacks import CBEventType
from llama_index.core.chat_engine.types import StreamingAgentChatResponse from llama_index.core.chat_engine.types import StreamingAgentChatResponse
from llama_index.core.tools import ToolOutput from llama_index.core.tools import ToolOutput
from llama_index.core.schema import NodeWithScore
from pydantic import BaseModel from pydantic import BaseModel
from app.api.routers.request.base import userMng, conversations,message,parameter,feedback from app.api.routers.request.base import userMng, conversations,message,ProjectInfo,feedback
from app.api.routers.request.baseConfig import * from app.api.routers.request.baseConfig import *
from app.api.routers.request.models import ChatRequestData,ChatFileUploadRequest from app.api.routers.request.models import ChatRequestData,ChatFileUploadRequest
from app.engine import get_chat_engine from app.engine import get_chat_engine
import uuid import uuid
from app.api.routers.services.fileServices import PrjFileLoadService,ChatFileService
from app.api.routers.services.suggestion import NextQuestionSuggestion
import time
from llama_index.core.settings import Settings
logger = logging.getLogger("uvicorn") logger = logging.getLogger("uvicorn")
api_router = r = APIRouter()
v1_router = v = APIRouter() v1_router = v = APIRouter()
gEvent_handler = None
CH_Event_map={
'CHUNKING':'文本切片',
'NODE_PARSING':'节点解析',
'EMBEDDING':'生成向量',
'LLM':'知识问答',
'QUERY':'查询',
'RETRIEVE':'检索',
'SYNTHESIZE':'答案合成',
'TREE':'总结',
'SUB_QUESTION':'问题分解',
'TEMPLATING':'生成提示词模板',
'FUNCTION_CALL':'函数调用',
'RERANKING':'节点重排',
'EXCEPTION':'执行异常',
'AGENT_STEP':'单步执行'
}
class ChatCallbackEvent(BaseModel): class ChatCallbackEvent(BaseModel):
event_type: ChatEventType event_type: ChatEventType
payload: Optional[Dict[str, Any]] = None payload: Optional[Dict[str, Any]] = None
def get_common_param(self)-> dict: def get_common_param(self)-> dict:
return { return {
'event': self.event_type.name, 'event': self.event_type.value,
'conversation_id':self.payload.get("conversation_id"), 'conversation_id':self.payload.get("conversation_id"),
'message_id': self.payload.get("message_id"), 'message_id': self.payload.get("message_id"),
'created_at': int(time.time()), 'created_at': int(time.time()),
@@ -47,7 +74,7 @@ class ChatCallbackEvent(BaseModel):
"workflow_id": self.payload.get('workflow_id'), "workflow_id": self.payload.get('workflow_id'),
"sequence_number": 1709, "sequence_number": 1709,
"inputs": { "inputs": {
"sys.query": self.payload.get('query'), "sys.query": f"开始查询 {self.payload.get('query')}",
"sys.files": [], "sys.files": [],
"sys.conversation_id": self.payload.get('conversation_id'), "sys.conversation_id": self.payload.get('conversation_id'),
"sys.user_id": self.payload.get('use_id') "sys.user_id": self.payload.get('use_id')
@@ -92,7 +119,7 @@ class ChatCallbackEvent(BaseModel):
"id": self.payload.get('nodeid'), "id": self.payload.get('nodeid'),
"node_id": self.payload.get('nodeid'), "node_id": self.payload.get('nodeid'),
"node_type": "http-request", "node_type": "http-request",
"title": self.payload.get('title'), "title": CH_Event_map[self.payload.get('title')],
"index": self.payload.get('index'), "index": self.payload.get('index'),
"predecessor_node_id": self.payload.get('predecessor_node_id'), "predecessor_node_id": self.payload.get('predecessor_node_id'),
"inputs": '', "inputs": '',
@@ -110,7 +137,7 @@ class ChatCallbackEvent(BaseModel):
"id": self.payload.get('nodeid'), "id": self.payload.get('nodeid'),
"node_id": self.payload.get('nodeid'), "node_id": self.payload.get('nodeid'),
"node_type": "http-request", "node_type": "http-request",
"title": self.payload.get('title'), "title": CH_Event_map[self.payload.get('title')],
"index": self.payload.get('index'), "index": self.payload.get('index'),
"predecessor_node_id": self.payload.get('predecessor_node_id'), "predecessor_node_id": self.payload.get('predecessor_node_id'),
"inputs": '', "inputs": '',
@@ -137,15 +164,54 @@ class ChatCallbackEvent(BaseModel):
def get_MessageEnd_param(self) -> dict: def get_MessageEnd_param(self) -> dict:
params = self.get_common_param() params = self.get_common_param()
nodeInfos = []
source_nodes = self.payload.get('source_node')
if source_nodes is not None:
for i in range(len(source_nodes)):
source_node:NodeWithScore = source_nodes[i]
metadata:dict = source_node.node.metadata
nodeInfo = {
"position": i,
"dataset_id": metadata.get("pipeline_id"),
"dataset_name": metadata.get("file_name"),
"document_id": source_node.node_id,
"document_name": metadata.get("file_name"),
"data_source_type": "upload_file",
"segment_id": source_node.node_id,
"retriever_from": "workflow",
"score": source_node.score,
"hit_count": 1,
"word_count": 632,
"segment_position": i,
"index_node_hash": "",
"content": source_node.text
}
nodeInfos.append(nodeInfo)
params.update({ params.update({
'id':self.payload.get('message_id'), 'id':self.payload.get('message_id'),
'metadata':self.payload.get('metadata') 'metadata':{
"retriever_resources":nodeInfos,
"usage":{
"prompt_tokens": 4972,
"prompt_unit_price": "0.0",
"prompt_price_unit": "0.0",
"prompt_price": "0.0",
"completion_tokens": 332,
"completion_unit_price": "0.0",
"completion_price_unit": "0.0",
"completion_price": "0.0",
"total_tokens": 5304,
"total_price": "0.0",
"currency": "USD",
"latency": 4.897703120019287
}
}
}) })
return params return params
def to_response(self)-> dict|None: def to_response(self)-> dict|None:
try: try:
match self.event_type: match self.event_type.value:
case "workflow_started": case "workflow_started":
return self.get_WorkflowStart_param() return self.get_WorkflowStart_param()
case "workflow_finished": case "workflow_finished":
@@ -168,7 +234,7 @@ class ChatEventCallbackHandler(BaseCallbackHandler):
_aqueue: asyncio.Queue _aqueue: asyncio.Queue
is_done: bool = False is_done: bool = False
def __init__(self,**params): def __init__(self):
"""Initialize the base callback handler.""" """Initialize the base callback handler."""
ignored_events = [ ignored_events = [
# CBEventType.CHUNKING, # CBEventType.CHUNKING,
@@ -179,23 +245,19 @@ class ChatEventCallbackHandler(BaseCallbackHandler):
] ]
super().__init__(ignored_events, ignored_events) super().__init__(ignored_events, ignored_events)
self._aqueue = asyncio.Queue() self._aqueue = asyncio.Queue()
self._response:str = '' self._response: StreamingAgentChatResponse = None
self._params:Dict[str,Any] = params self._ids:Dict[str,Any] = {}
self._nodeStack:deque = deque() self._chatData:ChatRequestData = None
self._nodeStack:List[str] = []
self._firstEventID:str = None
#添加工作流开始事件 def setInitParams(self,ids:dict,data:ChatRequestData):
data:ChatRequestData = self._params['data'] self._ids = ids
args:Dict[str,Any] = self._params['ids'] self._chatData = data
args.update( self._firstEventID = None
{
'use_id': data.user, def setResponse(self,response: StreamingAgentChatResponse):
'query': data.query, self._response = response
'conversation_id': data.conversation_id
}
)
wf_event = ChatCallbackEvent(event_type = ChatEventType.WORKFLOW_START,payload = args)
if wf_event.to_response() is not None:
self._aqueue.put_nowait(wf_event)
def on_event_start( def on_event_start(
self, self,
@@ -204,11 +266,15 @@ class ChatEventCallbackHandler(BaseCallbackHandler):
event_id: str = "", event_id: str = "",
**kwargs: Any, **kwargs: Any,
) -> str: ) -> str:
if self._firstEventID is None:
self._firstEventID = event_id
self.start()
logger.info("event_start:{} type:{} payload:{}\n".format(event_id, event_type, payload)) logger.info("event_start:{} type:{} payload:{}\n".format(event_id, event_type, payload))
self._nodeStack.append(event_id) self._nodeStack.append(event_id)
nindex = self._nodeStack.count() - 1 nindex = len(self._nodeStack) - 1
args:Dict[str,Any] = self._params['ids'] args:Dict[str,Any] = self._ids
args.update( args.update(
{ {
'nodeid':event_id, 'nodeid':event_id,
@@ -221,7 +287,6 @@ class ChatEventCallbackHandler(BaseCallbackHandler):
if nd_event.to_response() is not None: if nd_event.to_response() is not None:
self._aqueue.put_nowait(nd_event) self._aqueue.put_nowait(nd_event)
def on_event_end( def on_event_end(
self, self,
event_type: CBEventType, event_type: CBEventType,
@@ -232,10 +297,10 @@ class ChatEventCallbackHandler(BaseCallbackHandler):
logger.info("event_end:{} type:{} payload:{}\n".format(event_id, event_type, payload)) logger.info("event_end:{} type:{} payload:{}\n".format(event_id, event_type, payload))
#self.response = payload.get("response","") #self.response = payload.get("response","")
args:Dict[str,Any] = self._params['ids'] args:Dict[str,Any] = self._ids
nodeID = self._nodeStack[-1] nodeID = self._nodeStack[-1]
if nodeID == event_id: if nodeID == event_id:
nindex = self._nodeStack.count() - 1 nindex = len(self._nodeStack) - 1
args.update( args.update(
{ {
'nodeid':event_id, 'nodeid':event_id,
@@ -249,6 +314,8 @@ class ChatEventCallbackHandler(BaseCallbackHandler):
self._aqueue.put_nowait(nd_event) self._aqueue.put_nowait(nd_event)
self._nodeStack.pop() self._nodeStack.pop()
if self._firstEventID is not None and self._firstEventID == event_id:
self.finished()
def start_trace(self, trace_id: Optional[str] = None) -> None: def start_trace(self, trace_id: Optional[str] = None) -> None:
"""No-op.""" """No-op."""
@@ -261,23 +328,6 @@ class ChatEventCallbackHandler(BaseCallbackHandler):
) -> None: ) -> None:
"""No-op.""" """No-op."""
logger.info("trace_end:{} trace_map:{}\n".format(trace_id, trace_map)) logger.info("trace_end:{} trace_map:{}\n".format(trace_id, trace_map))
data:ChatRequestData = self._params['data']
args:Dict[str,Any] = self._params['ids']
args.update(
{
'response':self._response,
'conversation_id': data.conversation_id
}
)
wf_event = ChatCallbackEvent(event_type = ChatEventType.WORKFLOW_FINISHED,payload = args)
if wf_event.to_response() is not None:
self._aqueue.put_nowait(wf_event)
args:Dict[str,Any] = self._params['ids']
msgEnt_event = ChatCallbackEvent(event_type = ChatEventType.MESSAGE_END,payload = args)
if msgEnt_event.to_response() is not None:
self._aqueue.put_nowait(msgEnt_event)
async def async_event_gen(self) -> AsyncGenerator[ChatCallbackEvent, None]: async def async_event_gen(self) -> AsyncGenerator[ChatCallbackEvent, None]:
while not self._aqueue.empty() or not self.is_done: while not self._aqueue.empty() or not self.is_done:
@@ -286,6 +336,51 @@ class ChatEventCallbackHandler(BaseCallbackHandler):
except asyncio.TimeoutError: except asyncio.TimeoutError:
pass pass
def makeWorkflow_startEvent(self)->ChatCallbackEvent:
args:Dict[str,Any] = self._ids
args.update(
{
'use_id': self._chatData.user,
'query': self._chatData.query,
'conversation_id': self._chatData.conversation_id
}
)
return ChatCallbackEvent(event_type = ChatEventType.WORKFLOW_START,payload = args)
def makeWorkflow_finishedEvent(self)->ChatCallbackEvent:
args:Dict[str,Any] = self._ids
args.update(
{
'response': '',
'conversation_id': self._chatData.conversation_id
}
)
return ChatCallbackEvent(event_type = ChatEventType.WORKFLOW_FINISHED,payload = args)
def makeMessage_EndEvent(self)->ChatCallbackEvent:
args:Dict[str,Any] = self._ids
if self._response is not None:
args.update({
'source_node': self._response.source_nodes
})
msgEnt_event = ChatCallbackEvent(event_type = ChatEventType.MESSAGE_END,payload = args)
return msgEnt_event
def start(self):
#添加工作流开始事件
wf_event = self.makeWorkflow_startEvent()
if wf_event.to_response() is not None:
self._aqueue.put_nowait(wf_event)
def finished(self):
wf_event = self.makeWorkflow_finishedEvent()
if wf_event.to_response() is not None:
self._aqueue.put_nowait(wf_event)
msgEnt_event = self.makeMessage_EndEvent()
if msgEnt_event.to_response() is not None:
self._aqueue.put_nowait(msgEnt_event)
class IDManager: class IDManager:
def createID(self): def createID(self):
return { return {
@@ -353,6 +448,7 @@ class ChatStreamResponse(StreamingResponse):
# the text_generator is the leading stream, once it's finished, also finish the event stream # the text_generator is the leading stream, once it's finished, also finish the event stream
event_handler.is_done = True event_handler.is_done = True
event_handler.setResponse(response)
# Yield the events from the event handler # Yield the events from the event handler
async def _event_generator(): async def _event_generator():
@@ -374,33 +470,36 @@ class ChatStreamResponse(StreamingResponse):
break break
@v.post("/chat-messages") @v.post("/chat-messages")
async def post_conversations(request: Request, data: ChatRequestData): async def post_chatmessages(request: Request, data: ChatRequestData):
global gEvent_handler
userMng.findNoExistCreate(data.user) userMng.findNoExistCreate(data.user)
data.conversation_id = data.conversation_id if data.conversation_id else str(uuid.uuid4()) data.conversation_id = data.conversation_id if data.conversation_id else str(uuid.uuid4())
conversaObj = conversations() conversaObj = conversations()
conversationinfo = conversaObj.get(data.conversation_id) conversationinfo = conversaObj.get(data.conversation_id)
if conversationinfo is None: if conversationinfo is None:
conversationinfo = conversaObj.add(data.conversation_id, data.user, "新建会话") conversationinfo = conversaObj.add(data.conversation_id, data.user, "新建会话",inputs= data.inputs)
# 生成聊天参数 # 生成聊天参数
last_message_content = ChatMessage.from_str(data.query) last_message_content = ChatMessage.from_str(data.query)
filters = None filters = None
params = data.inputs or {} params = data.inputs or {}
# 获取聊天引擎对象
chat_engine = get_chat_engine(filters=filters, params=params)
# 启动聊天事件监听 # 启动聊天事件监听
ids = IDManager().createID() ids = IDManager().createID()
event_handler = ChatEventCallbackHandler(ids = ids,data = data) if gEvent_handler is None:
chat_engine.callback_manager.handlers.append(event_handler) # type: ignore gEvent_handler = ChatEventCallbackHandler()
Settings.llm.callback_manager.handlers.append(gEvent_handler)
if gEvent_handler is not None:
gEvent_handler.setInitParams(ids = ids,data = data)
# 获取聊天引擎对象
chat_engine = get_chat_engine(filters=filters, params=params)
# 执行异步聊天 # 执行异步聊天
response = await chat_engine.astream_chat(data.query) response = await chat_engine.astream_chat(data.query)
# 返回异步消息回应 # 返回异步消息回应
return ChatStreamResponse(request, event_handler, response, data,ids) return ChatStreamResponse(request, gEvent_handler, response, data,ids)
@v.get("/messages") @v.get("/messages")
async def query_messages(user:str, conversation_id:str): async def query_messages(user:str, conversation_id:str):
@@ -467,24 +566,51 @@ async def query_conversations(user:str, first_id:str = None, limit:str = None, p
@v.get("/parameters") @v.get("/parameters")
async def query_parameters(user:str): async def query_parameters(user:str):
params = parameter().get(user) prjObj = ProjectInfo()
if len(params) == 0: return BaseConfig().ParamterCfg(projectInfo = prjObj.projectNames())
params = BaseConfig().ParamterCfg()
return params
@v.post("/messages/{message_id}/feedbacks") @v.post("/messages/{message_id}/feedbacks")
async def post_feedbacks(request: Request,message_id:str,params:Dict[str,Any]): async def post_feedbacks(request: Request,message_id:str,params:Dict[str,Any]):
if params['rating'] =='null': if params['rating'] is None:
feedback().delete(message_id) feedback().delete(message_id)
else: else:
condition = {'id':message_id} results = message().query(message_id)
results = message().query(**condition)
if len(results) > 0: if len(results) > 0:
result = results[0] result = results[0]
feedback().add(message_id=message_id,query=result['query'], feedback().add(message_id=message_id,query=result['query'],
answer=result['answer'],rating=params['rating']) answer=result['answer'],rating=params['rating'])
@r.post("") @v.post("/files/upload")
def upload_file(request: ChatFileUploadRequest) -> List[str]: def upload_file(request: ChatFileUploadRequest):
pass try:
logger.info("Processing file")
resluts = ChatFileService.process_file(request.base64)
return {
'id':resluts.get('id'),
'name': resluts.get('name'),
'size': resluts.get('size'),
'extension':resluts.get('extension'),
'mime_type':resluts.get('mime_type'),
'created_by':str(uuid.uuid4()),
'created_at':int(time.time())
}
except Exception as e:
logger.error(f"Error processing file: {e}", exc_info=True)
raise HTTPException(status_code=500, detail="Error processing file")
@v.post("/project")
def upload_file(request: ChatFileUploadRequest):
try:
logger.info("Processing file")
return PrjFileLoadService.process_file(request.base64)
except Exception as e:
logger.error(f"Error processing file: {e}", exc_info=True)
raise HTTPException(status_code=500, detail="Error processing file")
@v.post("/messages/{message_id}/suggested")
async def post_suggested(request: Request,message_id:str,user:str):
questions = await NextQuestionSuggestion.suggest_next_questions(message_id)
return {
"result": "success",
"data":questions
}
+37 -3
View File
@@ -2,7 +2,7 @@ from datetime import datetime
import uuid import uuid
from app.api.routers.request.baseConfig import BaseConfig from app.api.routers.request.baseConfig import BaseConfig
from app.api.routers.request.dbOrm import DBManager from app.api.routers.request.dbOrm import DBManager
from typing import List
dbManage = DBManager() dbManage = DBManager()
class conversations: class conversations:
@@ -24,12 +24,13 @@ class conversations:
return records[0] return records[0]
return None return None
def add(self,id:str, user_id:str, name:str): def add(self,id:str, user_id:str, name:str,inputs:dict):
template = BaseConfig().ConversationCfg() template = BaseConfig().ConversationCfg()
template['id'] = id template['id'] = id
template['user_id'] = user_id template['user_id'] = user_id
template['name'] = name template['name'] = name
template['created_at'] = 1724399038 template['created_at'] = 1724399038
template['inputs'] = inputs
dbManage.addRecord(self._tableName,template) dbManage.addRecord(self._tableName,template)
def delete(self,id:str): def delete(self,id:str):
@@ -122,8 +123,9 @@ class message:
def delete(self,user_id:str): def delete(self,user_id:str):
dbManage.delete(self._tableName,user_id = user_id) dbManage.delete(self._tableName,user_id = user_id)
def query(self,**condition): def query(self,id:str):
results = [] results = []
condition = {'id':id}
records = dbManage.query(self._tableName,**condition) records = dbManage.query(self._tableName,**condition)
for record in records: for record in records:
results.append(record.dict()) results.append(record.dict())
@@ -153,3 +155,35 @@ class feedback:
if len(records) > 0: if len(records) > 0:
return records[0].dict() return records[0].dict()
return None return None
class ProjectInfo:
def __init__(self) -> None:
self._tableName = 'projectInfos'
dbManage.createTable(self._tableName)
def add(self,name:str,flag:str):
info = dbManage.query(self._tableName,prjFlag = flag)
if len(info) == 0:
record = {
'prjectName': name,
'prjFlag': flag
}
dbManage.addRecord(self._tableName,record)
def projectNames(self)->List[str]:
records = dbManage.query(self._tableName)
names = []
for record in records:
data:dict = record.dict()
name = data.get('prjectName')
if name !='':
names.append(name)
return names
def prjFalg(self,name:str):
records = dbManage.query(self._tableName)
for record in records:
data:dict = record.dict()
if data.get('prjectName') == name:
return data['prjFlag']
return ''
@@ -2,6 +2,22 @@ from pydantic import BaseModel
import os import os
from enum import Enum from enum import Enum
class BaseConfig(BaseModel):
projectInfo:str = os.getenv("PROJECT_TITLE","您好,我是博微工程理解小助手,您可以问我有关[线路工程]工程数据的相关问题!")
def ParamterCfg(self,**args):
projectInfo = args.get('projectInfo')
questions = os.getenv("CONVERSATION_STARTERS", "dev")
return{
"opening_statement": self.projectInfo,
"suggested_questions": questions.split('\n'),
"suggested_questions_after_answer": {
"enabled": False
},
"speech_to_text": {
"enabled": False
},
"text_to_speech": {
class BaseConfig(BaseModel): class BaseConfig(BaseModel):
projectInfo:str = os.getenv("PROJECT_TITLE","您好,我是博微工程理解小助手,您可以问我有关[线路工程]工程数据的相关问题!") projectInfo:str = os.getenv("PROJECT_TITLE","您好,我是博微工程理解小助手,您可以问我有关[线路工程]工程数据的相关问题!")
@@ -30,6 +46,44 @@ class BaseConfig(BaseModel):
"more_like_this": { "more_like_this": {
"enabled": False "enabled": False
}, },
"user_input_form": [
{
"select": {
"variable": "projectname",
"label": "\u5de5\u7a0b\u540d\u79f0",
"type": "select",
"max_length": 48,
"required": True,
"options": projectInfo
}
}
],
"sensitive_word_avoidance": {
"enabled": False
},
"file_upload": {
"image": {
"enabled": False,
"number_limits": 3,
"transfer_methods": [
"remote_url"
]
}
},
"system_parameters": {
"image_file_size_limit": "10"
"language": "",
"voice": ""
},
"retriever_resource": {
"enabled": True
},
"annotation_reply": {
"enabled": False
},
"more_like_this": {
"enabled": False
},
"user_input_form": [], "user_input_form": [],
"sensitive_word_avoidance": { "sensitive_word_avoidance": {
"enabled": False "enabled": False
+20 -1
View File
@@ -55,6 +55,13 @@ class FeedBackOrm(Base):
answer = Column(String) answer = Column(String)
rating = Column(String) rating = Column(String)
class ProjectInfoOrm(Base):
__tablename__ = "projectInfos"
prjFlag = Column(String,primary_key=True)
prjectName = Column(String)
#数据结构 #数据结构
class ConversationModel(BaseModel): class ConversationModel(BaseModel):
id: str id: str
@@ -121,6 +128,17 @@ class FeedBackModel(BaseModel):
def orm(cls): def orm(cls):
return FeedBackOrm return FeedBackOrm
class ProjectInfoModel(BaseModel):
prjectName:str
prjFlag:str
class Config:
from_attributes=True
@classmethod
def orm(cls):
return ProjectInfoOrm
class DBManager: class DBManager:
def __init__(self) -> None: def __init__(self) -> None:
DATABASE_URL = os.getenv("SQLITE_DATABASE_URL") DATABASE_URL = os.getenv("SQLITE_DATABASE_URL")
@@ -160,7 +178,8 @@ class DBManager:
return return
records = session.query(ormCls).filter_by(**filter).all() records = session.query(ormCls).filter_by(**filter).all()
if records is not None: if records is not None:
session.delete(records) for record in records:
session.delete(record)
session.commit() session.commit()
def update(self,tableName:str,data:Dict[str,Any],**filter): def update(self,tableName:str,data:Dict[str,Any],**filter):
@@ -0,0 +1,134 @@
import base64,os,mimetypes,requests,tempfile
from typing import List,Dict,Any
from uuid import uuid4
from app.settings import init_settings
from app.engine.loaders import get_document_Types, get_documents,getFileCacahePath
from app.engine.vectordb import get_vector_store
from app.engine.generate import get_doc_store,run_pipeline,persist_storage
from llama_index.core.schema import Document
from pathlib import Path
from llama_index.core.readers.file.base import (
_try_loading_included_file_formats as get_file_loaders_map,
)
from llama_index.readers.file import FlatReader
from llama_index.core.ingestion import IngestionPipeline
from llama_index.core import VectorStoreIndex
from app.engine.index import get_index
STORAGE_DIR = os.getenv("STORAGE_DIR", "storage")
class PrjFileLoadService:
@staticmethod
def store_and_parse_file(file_data):
prjtoJson_url = os.getenv('PRJTOJSON_URL')
convert_url = prjtoJson_url +'/prj_convert_clt2json'
files ={'file':file_data}
response1 = requests.post(
url = convert_url,
files=files
)
if response1.text is None or response1.text=='':
return None
load_url = prjtoJson_url +'/file_download'
response2 = requests.post(
url = load_url,
data=response1.text
)
if response2.text is None or response2.content=='':
return None
try:
tempFilePath:str = tempfile.gettempdir() + f"\\{uuid4().hex}.zip"
with open(tempFilePath,'wb') as file:
file.write(response2.content)
prjID = str(uuid4())
filePath = getFileCacahePath() + f'/Projects/{prjID}'
os.makedirs(filePath)
import zipfile
with zipfile.ZipFile(tempFilePath,'r') as zip_File:
for zip_info in zip_File.infolist():
zip_info.filename = zip_info.filename.encode('cp437').decode('gbk')
zip_File.extract(zip_info,filePath)
os.remove(tempFilePath)
return f'Projects_{prjID}'
except Exception as e:
return None
@staticmethod
def process_file(base64_content: str) -> str:
prjFlag = PrjFileLoadService.store_and_parse_file(base64_content)
if prjFlag is None:
return None
#生成向量并持久化至本地
documents = get_documents(prjFlag)
for doc in documents:
doc.metadata["private"] = "false"
docstore = get_doc_store(prjFlag)
vector_store = get_vector_store(prjFlag)
_ = run_pipeline(docstore, vector_store, documents)
persist_storage(docstore, vector_store)
return prjFlag
class ChatFileService:
PRIVATE_STORE_PATH = os.getenv('CHAT_UPLOAD_FILECACHE','output/uploaded')
resluts:Dict[str,Any] = {}
@staticmethod
def process_file(base64_content: str) -> dict:
file_data, extension = ChatFileService.preprocess_base64_file(base64_content)
documents = ChatFileService.store_and_parse_file(file_data, extension)
pipeline = IngestionPipeline()
nodes = pipeline.run(documents=documents)
current_index = get_index()
pipeline = IngestionPipeline()
nodes = pipeline.run(documents=documents)
if current_index is None:
current_index = VectorStoreIndex(nodes=nodes)
else:
current_index.insert_nodes(nodes=nodes)
current_index.storage_context.persist(
persist_dir=os.environ.get("STORAGE_DIR", "storage")
)
return ChatFileService.resluts
@staticmethod
def preprocess_base64_file(base64_content: str) -> tuple:
header, data = base64_content.split(",", 1)
mime_type = header.split(";")[0].split(":", 1)[1]
extension = mimetypes.guess_extension(mime_type)
ChatFileService.resluts['mime_type'] = mime_type
ChatFileService.resluts['extension'] = extension
return base64.b64decode(data), extension
@staticmethod
def store_and_parse_file(file_data, extension) -> List[Document]:
os.makedirs(ChatFileService.PRIVATE_STORE_PATH, exist_ok=True)
fileID = uuid4().hex
file_name = f"{fileID}{extension}"
file_path = Path(os.path.join(ChatFileService.PRIVATE_STORE_PATH, file_name))
ChatFileService.resluts['id'] = fileID
ChatFileService.resluts['file_name'] = file_name
with open(file_path, "wb") as f:
f.write(file_data)
ChatFileService.resluts['size'] = os.path.getsize(file_path)
reader_cls = ChatFileService.default_file_loaders_map().get(extension)
if reader_cls is None:
raise ValueError(f"File extension {extension} is not supported")
reader = reader_cls()
documents = reader.load_data(file_path)
for doc in documents:
doc.metadata["file_name"] = file_name
doc.metadata["private"] = "true"
return documents
@staticmethod
def default_file_loaders_map():
default_loaders = get_file_loaders_map()
default_loaders[".txt"] = FlatReader
return default_loaders
@@ -0,0 +1,43 @@
from typing import List
from app.api.routers.request.base import message
from llama_index.core.prompts import PromptTemplate
from llama_index.core.settings import Settings
from pydantic import BaseModel
NEXT_QUESTIONS_SUGGESTION_PROMPT = PromptTemplate(
"你是一个乐于助人的助手!你的任务是对用户可能会问的下一个问题给出建议。 "
"\n这是对话历史记录"
"\n---------------------\n{conversation}\n---------------------"
"考虑到对话历史记录,仅限于现在知识库已有内容, 请给我 $number_of_questions 个你接下来可能会问题的问题!"
)
N_QUESTION_TO_GENERATE = 3
class NextQuestions(BaseModel):
"""A list of questions that user might ask next"""
questions: List[str]
class NextQuestionSuggestion:
@staticmethod
async def suggest_next_questions(
message_id: str,
number_of_questions: int = N_QUESTION_TO_GENERATE,
) -> List[str]:
last_user_message = None
last_assistant_message = None
results = message().query(message_id)
if len(results) > 0:
last_user_message = results[0]['query']
last_assistant_message = results[0]['answer']
conversation: str = f"{last_user_message}\n{last_assistant_message}"
output: NextQuestions = await Settings.llm.astructured_predict(
NextQuestions,
prompt=NEXT_QUESTIONS_SUGGESTION_PROMPT,
conversation=conversation,
nun_questions=number_of_questions,
)
return output.questions
return []
+10 -3
View File
@@ -8,14 +8,20 @@ from app.engine.engine import create_query_engine, create_summary_query_engine
from app.engine.index import get_index from app.engine.index import get_index
#from app.engine.loaders.db import makeDescriptionByEngine #from app.engine.loaders.db import makeDescriptionByEngine
from app.engine.tools import ToolFactory from app.engine.tools import ToolFactory
from app.api.routers.request.base import ProjectInfo
def getPrjFalg(params:dict=None)->str:
prjFlag = ''
if params is not None:
prjFlag = ProjectInfo().prjFalg(params.get('projectname'))
return prjFlag
def get_chat_engine(filters=None, params=None): def get_chat_engine(filters=None, params:dict=None):
system_prompt = os.getenv("SYSTEM_PROMPT") system_prompt = os.getenv("SYSTEM_PROMPT")
top_k = int(os.getenv("TOP_K", "3")) top_k = int(os.getenv("TOP_K", "3"))
use_reranker = os.getenv("RERANK_ENABLED") use_reranker = os.getenv("RERANK_ENABLED")
tools = [] tools = []
# 创建SQL查询工具 # 创建SQL查询工具
# sql_query_engine = create_summary_query_engine(index) # sql_query_engine = create_summary_query_engine(index)
# sql_query_tool = QueryEngineTool.from_defaults(query_engine=sql_query_engine, # sql_query_tool = QueryEngineTool.from_defaults(query_engine=sql_query_engine,
@@ -25,7 +31,7 @@ def get_chat_engine(filters=None, params=None):
#tools.append(sql_query_tool) #tools.append(sql_query_tool)
# Add query tool if index exists # Add query tool if index exists
index = get_index() index = get_index(getPrjFalg(params))
if index is not None: if index is not None:
summary_query_engine = create_summary_query_engine(index,top_k,use_reranker,filters) summary_query_engine = create_summary_query_engine(index,top_k,use_reranker,filters)
summary_query_tool = QueryEngineTool.from_defaults( query_engine=summary_query_engine, name="summary_query_tool", summary_query_tool = QueryEngineTool.from_defaults( query_engine=summary_query_engine, name="summary_query_tool",
@@ -58,6 +64,7 @@ def get_chat_engine(filters=None, params=None):
verbose=True, verbose=True,
) )
return agentrunner return agentrunner
# create the function calling worker for reasoning # create the function calling worker for reasoning
# worker = FunctionCallingAgentWorker.from_tools( # worker = FunctionCallingAgentWorker.from_tools(
# tools, verbose=True # tools, verbose=True
+1 -1
View File
@@ -102,7 +102,7 @@ def create_query_engine(index, top_k=3, use_reranker=False, filters=None, respon
simple_template = simple_template, simple_template = simple_template,
node_postprocessors=postprocess, node_postprocessors=postprocess,
use_async=True, use_async=True,
streaming=True, streaming=False,
ResponseMode = response_mode ResponseMode = response_mode
) )
+10 -8
View File
@@ -5,7 +5,7 @@ load_dotenv()
import logging import logging
import os import os
from app.engine.loaders import get_documents from app.engine.loaders import get_document_Types, get_documents
from app.engine.vectordb import get_vector_store from app.engine.vectordb import get_vector_store
from app.settings import init_settings from app.settings import init_settings
from app.engine.retriever.CHBM25Retriever import CHBM25Retriever from app.engine.retriever.CHBM25Retriever import CHBM25Retriever
@@ -21,12 +21,13 @@ logger = logging.getLogger()
STORAGE_DIR = os.getenv("STORAGE_DIR", "storage") STORAGE_DIR = os.getenv("STORAGE_DIR", "storage")
def get_doc_store(): def get_doc_store(docType:str):
# If the storage directory is there, load the document store from it. # If the storage directory is there, load the document store from it.
# If not, set up an in-memory document store since we can't load from a directory that doesn't exist. # If not, set up an in-memory document store since we can't load from a directory that doesn't exist.
if os.path.exists(STORAGE_DIR): storeDir = os.path.join(STORAGE_DIR,docType)
return SimpleDocumentStore.from_persist_dir(STORAGE_DIR) if os.path.exists(storeDir):
return SimpleDocumentStore.from_persist_dir(storeDir)
else: else:
return SimpleDocumentStore() return SimpleDocumentStore()
@@ -71,19 +72,20 @@ def generate_datasource():
logger.info("Generate index for the provided data") logger.info("Generate index for the provided data")
# Get the stores and documents or create new ones # Get the stores and documents or create new ones
documents = get_documents() docTypes = get_document_Types()
for docType in docTypes:
documents = get_documents(docType)
# Set private=false to mark the document as public (required for filtering) # Set private=false to mark the document as public (required for filtering)
for doc in documents: for doc in documents:
doc.metadata["private"] = "false" doc.metadata["private"] = "false"
docstore = get_doc_store() docstore = get_doc_store(docType)
vector_store = get_vector_store() vector_store = get_vector_store(docType)
# Run the ingestion pipeline # Run the ingestion pipeline
_ = run_pipeline(docstore, vector_store, documents) _ = run_pipeline(docstore, vector_store, documents)
# Build the index and persist storage # Build the index and persist storage
persist_storage(docstore, vector_store) persist_storage(docstore, vector_store)
persist_BMRetriever(vector_store)
logger.info("Finished generating the index") logger.info("Finished generating the index")
+6 -13
View File
@@ -1,22 +1,15 @@
import logging import logging
from llama_index.core.indices import VectorStoreIndex from llama_index.core.indices import VectorStoreIndex
from app.engine.vectordb import get_vector_store from app.engine.vectordb import get_vector_store
from app.engine.loaders import get_document_Types
from typing import Dict,Any
logger = logging.getLogger("uvicorn") logger = logging.getLogger("uvicorn")
index = None def get_index(prjFlag:str):
if prjFlag is None or prjFlag == '':
def get_index(params=None): raise ValueError('无效的工程标识')
global index
if index is None:
logger.info("Connecting vector store...") logger.info("Connecting vector store...")
store = get_vector_store(prjFlag)
store = get_vector_store()
# Load the index from the vector store
# If you are using a vector store that doesn't store text,
# you must load the index from both the vector store and the document store
index = VectorStoreIndex.from_vector_store(store) index = VectorStoreIndex.from_vector_store(store)
logger.info("Finished load index from vector store.") logger.info("Finished load index from vector store.")
return index return index
+76 -5
View File
@@ -3,17 +3,87 @@ import yaml
from app.engine.loaders.db import DBLoaderConfig, get_db_documents from app.engine.loaders.db import DBLoaderConfig, get_db_documents
from app.engine.loaders.file import FileLoaderConfig, get_file_documents from app.engine.loaders.file import FileLoaderConfig, get_file_documents
from app.engine.loaders.web import WebLoaderConfig, get_web_documents from app.engine.loaders.web import WebLoaderConfig, get_web_documents
from app.engine.loaders.projectJson import getProjectName
import os
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def load_configs(): def load_configs():
with open("config/loaders.yaml",encoding='UTF-8') as f:
with open("config/loaders.yaml",encoding='utf-8') as f:
configs = yaml.safe_load(f) configs = yaml.safe_load(f)
return configs return configs
def path_difference(path1:str, path2:str):
import os
path1 = os.path.abspath(path1)
path2 = os.path.abspath(path2)
def get_documents(): path1_parts = path1.split(os.path.sep)
path2_parts = path2.split(os.path.sep)
for i, part in enumerate(path1_parts):
if part != path2_parts[i]:
break
else:
i += 1
pathKey = ''
for j in range(i,len(path2_parts)):
pathKey+=path2_parts[j] + '_'
return pathKey[0:-1]
def getFileCacahePath():
rootPath = 'data'
configs = load_configs()
if configs is not None and len(configs.items()) > 0:
for loader_type, loader_config in configs.items():
if loader_type == "file":
rootPath = FileLoaderConfig(**loader_config).data_dir
break
return rootPath
def get_document_Types():
rootPath = getFileCacahePath()
types = []
dirStack = [rootPath]
while len(dirStack) > 0:
curDir = dirStack.pop()
dirs = [os.path.join(curDir, d) for d in os.listdir(curDir) if os.path.isdir(os.path.join(curDir, d))]
if len(dirs) > 0:
for dir in dirs:
dirStack.append(dir)
else:
types.append(path_difference(rootPath,curDir))
return types
def getProjectInfos():
config = load_configs()
if config is None or len(config.items()) == 0:
return None
prjDir = None
for loader_type, loader_config in config.items():
if loader_config.get('enable', True):
loader_config = loader_config or []
config = FileLoaderConfig(**loader_config)
prjDir = config.data_dir
break
if prjDir is None:
return None
prjInfos = []
prjFlags = get_document_Types()
for prjFlag in prjFlags:
fileDir = os.path.join(config.data_dir,prjFlag.replace('_','\\'))
prjInfo = {}
prjInfo['flag'] = prjFlag
prjInfo['name'] = getProjectName(fileDir)
prjInfos.append(prjInfo)
return prjInfos
def get_documents(docType:str):
documents = [] documents = []
config = load_configs() config = load_configs()
@@ -29,7 +99,8 @@ def get_documents():
loader_config = loader_config or [] loader_config = loader_config or []
match loader_type: match loader_type:
case "file": case "file":
document = get_file_documents(FileLoaderConfig(**loader_config))
document = get_file_documents(FileLoaderConfig(**loader_config),docType)
case "web": case "web":
document = get_web_documents(WebLoaderConfig(**loader_config)) document = get_web_documents(WebLoaderConfig(**loader_config))
case "db": case "db":
@@ -38,4 +109,4 @@ def get_documents():
raise ValueError(f"Invalid loader type: {loader_type}") raise ValueError(f"Invalid loader type: {loader_type}")
documents.extend(document) documents.extend(document)
return documents
+2 -2
View File
@@ -46,7 +46,7 @@ def llama_local_extractor() -> Dict[str, BaseReader]:
return {".json" : JSONReader(clean_json=False,levels_back=0)} return {".json" : JSONReader(clean_json=False,levels_back=0)}
def get_file_documents(config: FileLoaderConfig): def get_file_documents(config: FileLoaderConfig,childPath: str):
from llama_index.core.readers import SimpleDirectoryReader from llama_index.core.readers import SimpleDirectoryReader
try: try:
@@ -63,7 +63,7 @@ def get_file_documents(config: FileLoaderConfig):
file_extractor = llama_local_extractor() file_extractor = llama_local_extractor()
reader = SimpleDirectoryReader( reader = SimpleDirectoryReader(
config.data_dir, os.path.join(config.data_dir,childPath.replace('_','\\')),
recursive=True, recursive=True,
filename_as_id=True, filename_as_id=True,
raise_on_error=True, raise_on_error=True,
+73
View File
@@ -0,0 +1,73 @@
from typing import Dict,List,Any
import json,os
class Record:
def __init__(self,datas:Dict[str,Any]) -> None:
self._datas:Dict[str,Any] = datas
def value(self,key:str):
if key in self._datas:
return self._datas.get(key)
return ''
class Field:
def __init__(self,datas:Dict[str,Any]) -> None:
self._datas:Dict[str,Any] = datas
def value(self,key:str):
if key in self._datas:
return self._datas.get(key)
return ''
class JsonTable:
def __init__(self,filePth:str) -> None:
self._filePth = filePth
self._fields:Dict[str,Field] = {}
self._records:List[Record] = []
self._name = ''
def parse(self):
with open(self._filePth, 'r',encoding='utf-8') as file:
jsObj = json.load(file)
data:dict = jsObj.get('table')
self._name = data.get('name')
Jsfields = data.get('fields')
for jsfiled in Jsfields:
field = Field(jsfiled)
self._fields[field.value('name')] =field
JsRecords = data.get('records')
for jsRecord in JsRecords:
self._records.append(Record(jsRecord))
def records(self):
return self._records
class ProjectJson:
def __init__(self,dir:str) -> None:
self._dir = dir
self._tables:Dict[str,JsonTable] = {}
def parse(self):
json_files = [f for f in os.listdir(self._dir) if f.endswith('.json')]
for json_file in json_files:
prjPath = os.path.join(self._dir, json_file)
tb = JsonTable(prjPath)
tb.parse()
basename = os.path.splitext(json_file)[0]
self._tables[basename] = tb
def table(self,tableName:str):
return self._tables[tableName]
def getProjectName(dir:str):
prjJson = ProjectJson(dir)
prjJson.parse()
tb:JsonTable = prjJson.table('工程属性')
records = tb.records()
for record in records:
name = record.value('名称')
if name == '工程名称':
return record.value('')
return ''
@@ -43,6 +43,16 @@ class HybridRetriever(BaseRetriever):
for node in bmNodes: for node in bmNodes:
bmDic[node.node_id] = node bmDic[node.node_id] = node
vecScores = [node_with_score.score for node_with_score in vecNodes]
bmSores = [node_with_score.score for node_with_score in bmNodes]
vec_min_score = min(vecScores)
vec_max_score = max(vecScores)
bm_min_score = min(bmSores)
bm_max_score = max(bmSores)
result_tups = [] result_tups = []
for i in range(len(vecNodes)): for i in range(len(vecNodes)):
node = vecNodes[i] node = vecNodes[i]
@@ -52,7 +62,11 @@ class HybridRetriever(BaseRetriever):
bmDic.pop(node.node_id) bmDic.pop(node.node_id)
else: else:
bmScore = 0.0 bmScore = 0.0
full_similarity = (self._alpha * node.score) + (
bmScore = self.normal_score(bmScore,bm_min_score,bm_max_score)
vecScore = self.normal_score(node.score,vec_min_score,vec_max_score)
full_similarity = (self._alpha * vecScore) + (
(1 - self._alpha) * bmScore (1 - self._alpha) * bmScore
) )
result_tups.append((full_similarity, node)) result_tups.append((full_similarity, node))
@@ -65,3 +79,9 @@ class HybridRetriever(BaseRetriever):
for full_score, node in result_tups: for full_score, node in result_tups:
node.score = full_score node.score = full_score
return [n for _, n in result_tups][:self._out_top_k] return [n for _, n in result_tups][:self._out_top_k]
def normal_score(self,score,min,max):
if min == max:
return 1.0 if score > 0 else 0.0
else:
return (score - min) / (max - min)
+9 -8
View File
@@ -5,12 +5,13 @@ from qdrant_client import qdrant_client
qclient = None qclient = None
def get_qdrant_vector_store(): def get_qdrant_vector_store(docType:str):
collection_name = os.getenv("VECTOR_STORE_COLLECTION", "default") collection_name = docType
vector_store_path = os.getenv("VECTOR_STORE_PATH") vector_store_path = os.getenv("VECTOR_STORE_PATH")
host=os.getenv("VECTOR_STORE_HOST", "127.0.0.1"), host=os.getenv("VECTOR_STORE_HOST", "127.0.0.1"),
port=int(os.getenv("VECTOR_STORE_PORT", "6333")), port=int(os.getenv("VECTOR_STORE_PORT", "6333")),
vector_store_path =os.path.join(vector_store_path,docType)
if not vector_store_path or not host: if not vector_store_path or not host:
raise ValueError( raise ValueError(
"Please provide either VECTOR_STORE_PATH or VECTOR_STORE_HOST and VECTOR_STORE_PORT" "Please provide either VECTOR_STORE_PATH or VECTOR_STORE_HOST and VECTOR_STORE_PORT"
@@ -32,9 +33,9 @@ def get_qdrant_vector_store():
vector_store = QdrantVectorStore(client=qclient, collection_name=collection_name) vector_store = QdrantVectorStore(client=qclient, collection_name=collection_name)
return vector_store return vector_store
def get_chroma_vector_store(): def get_chroma_vector_store(docType:str):
collection_name = os.getenv("VECTOR_STORE_COLLECTION", "default") collection_name = docType
vector_store_path = os.getenv("VECTOR_STORE_PATH") vector_store_path =os.path.join(os.getenv("VECTOR_STORE_PATH"),docType)
# if VECTOR_STORE_PATH is set, use a local ChromaVectorStore from the path # if VECTOR_STORE_PATH is set, use a local ChromaVectorStore from the path
# otherwise, use a remote ChromaVectorStore (ChromaDB Cloud is not supported yet) # otherwise, use a remote ChromaVectorStore (ChromaDB Cloud is not supported yet)
if vector_store_path: if vector_store_path:
@@ -55,16 +56,16 @@ def get_chroma_vector_store():
) )
return store return store
def get_vector_store(): def get_vector_store(docType:str):
store_type=os.getenv("VECTOR_STORE_TYPE") store_type=os.getenv("VECTOR_STORE_TYPE")
store = None store = None
match store_type: match store_type:
case "chroma": case "chroma":
store = get_chroma_vector_store() store = get_chroma_vector_store(docType)
case "qdrant": case "qdrant":
store = get_qdrant_vector_store() store = get_qdrant_vector_store(docType)
case _: case _:
raise ValueError(f"Invalid vector store type: {store_type}") raise ValueError(f"Invalid vector store type: {store_type}")
+210 -109
View File
@@ -1,19 +1,115 @@
import os import os
from typing import Dict from typing import Dict
from abc import abstractmethod
from llama_index.core.constants import DEFAULT_TEMPERATURE from llama_index.core.constants import DEFAULT_TEMPERATURE
from llama_index.core.settings import Settings from llama_index.core.settings import Settings
from llama_index.llms.xinference import Xinference from llama_index.llms.xinference import Xinference
from llama_index.llms.xinference.base import DEFAULT_XINFERENCE_TEMP from llama_index.llms.xinference.base import DEFAULT_XINFERENCE_TEMP
from app.xinference.base import XinferenceEmbedding, XinferenceRerank from app.xinference.base import XinferenceEmbedding, XinferenceRerank
from app.engine.loaders import getProjectInfos
from app.api.routers.request.base import ProjectInfo
from util.register import *
from llama_index.core.callbacks import CallbackManager
from modelProvide.customDashScope import CustomDashScope
ModelPlateCategory = '模型平台'
def get_node_postprocessors(): def get_node_postprocessors():
rerank_enabled = os.getenv("RERANK_ENABLED").title() rerank_enabled = os.getenv("RERANK_ENABLED").title()
if rerank_enabled is None or rerank_enabled == 'False': if rerank_enabled is None or rerank_enabled == 'False':
return [] return []
Rerank_provider = os.getenv("RERANK_PROVIDER")
modelPaltCls:ModelPlatform = ClsRegister.get(ModelPlateCategory,Rerank_provider)
postprocess = None
if modelPaltCls is not None:
modelPalt:ModelPlatform = modelPaltCls()
postprocess = modelPalt.rerank()
else:
raise ValueError(f"Invalid rerank provider: {Rerank_provider}")
return postprocess
def init_settings():
model_provider = os.getenv("MODEL_PROVIDER")
modelPaltCls:ModelPlatform = ClsRegister.get(ModelPlateCategory,model_provider)
if modelPaltCls is not None:
modelPalt:ModelPlatform = modelPaltCls()
Settings.llm = modelPalt.model()
else:
raise ValueError(f"Invalid model provider: {model_provider}")
embedding_provider = os.getenv("EMBEDDING_PROVIDER")
modelPaltCls:ModelPlatform = ClsRegister.get(ModelPlateCategory,embedding_provider)
if modelPalt is not None:
modelPalt:ModelPlatform = modelPaltCls()
Settings.embed_model = modelPalt.embedding()
else:
raise ValueError(f"Invalid embedding provider: {embedding_provider}")
Settings.llm.callback_manager = CallbackManager()
Settings.chunk_size = int(os.getenv("CHUNK_SIZE", "1024"))
Settings.chunk_overlap = int(os.getenv("CHUNK_OVERLAP", "20"))
class ModelPlatform:
@abstractmethod
def model(self):
pass
@abstractmethod
def embedding(self):
pass
@abstractmethod
def rerank(self):
pass
@register(ModelPlateCategory,'ollama')
class OllamaPlatform(ModelPlatform):
def model(self):
from llama_index.llms.ollama.base import DEFAULT_REQUEST_TIMEOUT, Ollama
base_url = os.getenv("OLLAMA_BASE_URL") or "http://127.0.0.1:11434"
request_timeout = float(
os.getenv("OLLAMA_REQUEST_TIMEOUT", DEFAULT_REQUEST_TIMEOUT)
)
Settings.llm = Ollama(
base_url=base_url, model=os.getenv("MODEL"), request_timeout=request_timeout
)
pass
def embedding(self):
#from llama_index.embeddings.ollama import OllamaEmbedding
# base_url = os.getenv("OLLAMA_BASE_URL") or "http://127.0.0.1:11434"
# Settings.embed_model = OllamaEmbedding(
# base_url=base_url,
# model_name=os.getenv("EMBEDDING_MODEL"),
# )
pass
def rerank(self):
pass
@register(ModelPlateCategory,'xinference')
class XinferencePlatform(ModelPlatform):
def model(self):
base_url = os.getenv("BASE_URL")
model = os.getenv("MODEL")
max_tokens = int(os.getenv("LLM_MAX_TOKENS")) if os.getenv("LLM_MAX_TOKENS") is not None else None
temperature = float(os.getenv("LLM_TEMPERATURE", DEFAULT_XINFERENCE_TEMP))
return Xinference(model, base_url, temperature, max_tokens)
def embedding(self):
base_url = os.getenv("BASE_URL")
embedding_base_url = os.getenv("EMBEDDING_BASE_URL")
embedding_base_url = embedding_base_url if embedding_base_url != None and embedding_base_url != "" else base_url
embed_model_name = os.getenv("EMBEDDING_MODEL")
dimensions = os.getenv("EMBEDDING_DIM")
dimensions = int(dimensions) if dimensions is not None else None
return XinferenceEmbedding(embed_model_name, embedding_base_url, dimensions=dimensions)
def rerank(self):
rerank_model = os.getenv("RERANK_MODEL") rerank_model = os.getenv("RERANK_MODEL")
rerank_url = os.getenv("RERANK_BASE_URL") rerank_url = os.getenv("RERANK_BASE_URL")
rerank_top_n = os.getenv("RERANK_TOP_N") rerank_top_n = os.getenv("RERANK_TOP_N")
@@ -23,73 +119,10 @@ def get_node_postprocessors():
postprocess = [XinferenceRerank(rerank_model, rerank_url, top_n=rerank_top_n, threshold=rerank_threshold)] postprocess = [XinferenceRerank(rerank_model, rerank_url, top_n=rerank_top_n, threshold=rerank_threshold)]
return postprocess return postprocess
def init_settings(): @register(ModelPlateCategory,'openai')
model_provider = os.getenv("MODEL_PROVIDER") class OpenAIPlatform(ModelPlatform):
match model_provider: def model(self):
case "openai":
init_openai()
case "dashscope":
init_dashscope()
case "groq":
init_groq()
case "ollama":
init_ollama()
case "anthropic":
init_anthropic()
case "gemini":
init_gemini()
case "mistral":
init_mistral()
case "azure-openai":
init_azure_openai()
case "t-systems":
from .llmhub import init_llmhub
init_llmhub()
case "xinference":
init_xinference()
case _:
raise ValueError(f"Invalid model provider: {model_provider}")
Settings.chunk_size = int(os.getenv("CHUNK_SIZE", "1024"))
Settings.chunk_overlap = int(os.getenv("CHUNK_OVERLAP", "20"))
def init_ollama():
# from llama_index.embeddings.ollama import OllamaEmbedding
# from llama_index.llms.ollama.base import DEFAULT_REQUEST_TIMEOUT, Ollama
#
# base_url = os.getenv("OLLAMA_BASE_URL") or "http://127.0.0.1:11434"
# request_timeout = float(
# os.getenv("OLLAMA_REQUEST_TIMEOUT", DEFAULT_REQUEST_TIMEOUT)
# )
# Settings.embed_model = OllamaEmbedding(
# base_url=base_url,
# model_name=os.getenv("EMBEDDING_MODEL"),
# )
# Settings.llm = Ollama(
# base_url=base_url, model=os.getenv("MODEL"), request_timeout=request_timeout
# )
pass
def init_xinference():
base_url = os.getenv("BASE_URL")
model = os.getenv("MODEL")
max_tokens = int(os.getenv("LLM_MAX_TOKENS")) if os.getenv("LLM_MAX_TOKENS") is not None else None
temperature = float(os.getenv("LLM_TEMPERATURE", DEFAULT_XINFERENCE_TEMP))
Settings.llm = Xinference(model, base_url, temperature, max_tokens)
embedding_base_url = os.getenv("EMBEDDING_BASE_URL")
embedding_base_url = embedding_base_url if embedding_base_url != None and embedding_base_url != "" else base_url
embed_model_name = os.getenv("EMBEDDING_MODEL")
dimensions = os.getenv("EMBEDDING_DIM")
dimensions = int(dimensions) if dimensions is not None else None
Settings.embed_model = XinferenceEmbedding(embed_model_name, embedding_base_url, dimensions=dimensions)
def init_openai():
from llama_index.core.constants import DEFAULT_TEMPERATURE from llama_index.core.constants import DEFAULT_TEMPERATURE
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.llms.openai import OpenAI from llama_index.llms.openai import OpenAI
max_tokens = os.getenv("LLM_MAX_TOKENS") max_tokens = os.getenv("LLM_MAX_TOKENS")
@@ -98,39 +131,41 @@ def init_openai():
"temperature": float(os.getenv("LLM_TEMPERATURE", DEFAULT_TEMPERATURE)), "temperature": float(os.getenv("LLM_TEMPERATURE", DEFAULT_TEMPERATURE)),
"max_tokens": int(max_tokens) if max_tokens is not None else None, "max_tokens": int(max_tokens) if max_tokens is not None else None,
} }
Settings.llm = OpenAI(**config) return OpenAI(**config)
def embedding(self):
from llama_index.embeddings.openai import OpenAIEmbedding
dimensions = os.getenv("EMBEDDING_DIM") dimensions = os.getenv("EMBEDDING_DIM")
config = { config = {
"model": os.getenv("EMBEDDING_MODEL"), "model": os.getenv("EMBEDDING_MODEL"),
"dimensions": int(dimensions) if dimensions is not None else None, "dimensions": int(dimensions) if dimensions is not None else None,
} }
Settings.embed_model = OpenAIEmbedding(**config) return OpenAIEmbedding(**config)
def init_dashscope(): def rerank(self):
from llama_index.llms.dashscope import DashScope,DashScopeGenerationModels pass
from llama_index.embeddings.dashscope import DashScopeEmbedding,DashScopeBatchTextEmbeddingModels,DashScopeTextEmbeddingType,DashScopeTextEmbeddingModels
max_tokens = os.getenv("LLM_MAX_TOKENS") @register(ModelPlateCategory,'dashscope')
config = { class DashscopePlatform(ModelPlatform):
"model": os.getenv("MODEL"), def model(self):
"temperature": float(os.getenv("LLM_TEMPERATURE", DEFAULT_TEMPERATURE)), apikey = os.getenv('DASHSCOPE_API_KEY')
"max_tokens": int(max_tokens) if max_tokens is not None else None, modelName = os.getenv('MODEL')
} return CustomDashScope(model_name=modelName,api_key = apikey)
Settings.llm = llm = DashScope(model_name=DashScopeGenerationModels.QWEN_MAX)
dimensions = os.getenv("EMBEDDING_DIM") def embedding(self):
config = { from llama_index.embeddings.dashscope import DashScopeEmbedding,DashScopeTextEmbeddingType,DashScopeTextEmbeddingModels
"model": os.getenv("EMBEDDING_MODEL"), api_key = os.getenv('DASHSCOPE_API_KEY')
"dimensions": int(dimensions) if dimensions is not None else None, modelName = os.getenv('EMBEDDING_MODEL')
} return DashScopeEmbedding(model_name=modelName,
Settings.embed_model = DashScopeEmbedding(model_name=DashScopeTextEmbeddingModels.TEXT_EMBEDDING_V2, text_type=DashScopeTextEmbeddingType.TEXT_TYPE_QUERY,api_key = api_key)
text_type=DashScopeTextEmbeddingType.TEXT_TYPE_QUERY)
def rerank(self):
pass
def init_azure_openai(): @register(ModelPlateCategory,'azure-openai')
class AzureOpenaiPlatform(ModelPlatform):
def model(self):
# from llama_index.core.constants import DEFAULT_TEMPERATURE # from llama_index.core.constants import DEFAULT_TEMPERATURE
# from llama_index.embeddings.azure_openai import AzureOpenAIEmbedding
# from llama_index.llms.azure_openai import AzureOpenAI # from llama_index.llms.azure_openai import AzureOpenAI
# #
# llm_deployment = os.environ["AZURE_OPENAI_LLM_DEPLOYMENT"] # llm_deployment = os.environ["AZURE_OPENAI_LLM_DEPLOYMENT"]
@@ -146,15 +181,32 @@ def init_azure_openai():
# or os.getenv("OPENAI_API_VERSION"), # or os.getenv("OPENAI_API_VERSION"),
# } # }
# #
# Settings.llm = AzureOpenAI( # return AzureOpenAI(
# model=os.getenv("MODEL"), # model=os.getenv("MODEL"),
# max_tokens=int(max_tokens) if max_tokens is not None else None, # max_tokens=int(max_tokens) if max_tokens is not None else None,
# temperature=float(temperature), # temperature=float(temperature),
# deployment_name=llm_deployment, # deployment_name=llm_deployment,
# **azure_config, # **azure_config,
# ) # )
pass
def embedding(self):
# from llama_index.core.constants import DEFAULT_TEMPERATURE
# from llama_index.embeddings.azure_openai import AzureOpenAIEmbedding
# #
# Settings.embed_model = AzureOpenAIEmbedding( # llm_deployment = os.environ["AZURE_OPENAI_LLM_DEPLOYMENT"]
# embedding_deployment = os.environ["AZURE_OPENAI_EMBEDDING_DEPLOYMENT"]
# max_tokens = os.getenv("LLM_MAX_TOKENS")
# temperature = os.getenv("LLM_TEMPERATURE", DEFAULT_TEMPERATURE)
# dimensions = os.getenv("EMBEDDING_DIM")
#
# azure_config = {
# "api_key": os.environ["AZURE_OPENAI_KEY"],
# "azure_endpoint": os.environ["AZURE_OPENAI_ENDPOINT"],
# "api_version": os.getenv("AZURE_OPENAI_API_VERSION")
# or os.getenv("OPENAI_API_VERSION"),
# }
# return AzureOpenAIEmbedding(
# model=os.getenv("EMBEDDING_MODEL"), # model=os.getenv("EMBEDDING_MODEL"),
# dimensions=int(dimensions) if dimensions is not None else None, # dimensions=int(dimensions) if dimensions is not None else None,
# deployment_name=embedding_deployment, # deployment_name=embedding_deployment,
@@ -162,11 +214,17 @@ def init_azure_openai():
# ) # )
pass pass
def rerank(self):
pass
def init_fastembed(): @register(ModelPlateCategory,'fastembed')
""" class FastembedPlatform(ModelPlatform):
Use Qdrant Fastembed as the local embedding provider. @abstractmethod
""" def model(self):
pass
@abstractmethod
def embedding(self):
# from llama_index.embeddings.fastembed import FastEmbedEmbedding # from llama_index.embeddings.fastembed import FastEmbedEmbedding
# #
# embed_model_map: Dict[str, str] = { # embed_model_map: Dict[str, str] = {
@@ -182,8 +240,14 @@ def init_fastembed():
# ) # )
pass pass
@abstractmethod
def rerank(self):
pass
def init_groq(): @register(ModelPlateCategory,'groq')
class GroqPlatform(ModelPlatform):
@abstractmethod
def model(self):
# from llama_index.llms.groq import Groq # from llama_index.llms.groq import Groq
# #
# model_map: Dict[str, str] = { # model_map: Dict[str, str] = {
@@ -197,8 +261,17 @@ def init_groq():
# init_fastembed() # init_fastembed()
pass pass
@abstractmethod
def embedding(self):
pass
def init_anthropic(): @abstractmethod
def rerank(self):
pass
@register(ModelPlateCategory,'anthropic')
class AnthropicPlatform(ModelPlatform):
def model(self):
# from llama_index.llms.anthropic import Anthropic # from llama_index.llms.anthropic import Anthropic
# #
# model_map: Dict[str, str] = { # model_map: Dict[str, str] = {
@@ -214,22 +287,50 @@ def init_anthropic():
# init_fastembed() # init_fastembed()
pass pass
def embedding(self):
pass
def init_gemini(): def rerank(self):
# from llama_index.embeddings.gemini import GeminiEmbedding pass
@register(ModelPlateCategory,'gemini')
class GeminiPlatform(ModelPlatform):
def model(self):
# from llama_index.llms.gemini import Gemini # from llama_index.llms.gemini import Gemini
#
# model_name = f"models/{os.getenv('MODEL')}" # model_name = f"models/{os.getenv('MODEL')}"
# embed_model_name = f"models/{os.getenv('EMBEDDING_MODEL')}" # return Gemini(model=model_name)
#
# Settings.llm = Gemini(model=model_name)
# Settings.embed_model = GeminiEmbedding(model_name=embed_model_name)
pass pass
def init_mistral(): def embedding(self):
# from llama_index.embeddings.mistralai import MistralAIEmbedding # from llama_index.embeddings.gemini import GeminiEmbedding
# from llama_index.llms.mistralai import MistralAI # embed_model_name = f"models/{os.getenv('EMBEDDING_MODEL')}"
# # return GeminiEmbedding(model_name=embed_model_name)
# Settings.llm = MistralAI(model=os.getenv("MODEL"))
# Settings.embed_model = MistralAIEmbedding(model_name=os.getenv("EMBEDDING_MODEL"))
pass pass
def rerank(self):
pass
@register(ModelPlateCategory,'mistral')
class MistralPlatform(ModelPlatform):
def model(self):
# from llama_index.llms.mistralai import MistralAI
# return MistralAI(model=os.getenv("MODEL"))
pass
def embedding(self):
# from llama_index.embeddings.mistralai import MistralAIEmbedding
# return MistralAIEmbedding(model_name=os.getenv("EMBEDDING_MODEL"))
pass
def rerank(self):
pass
def init_ProjectInfo():
prjObj = ProjectInfo()
prjInfos:list[tuple] = getProjectInfos()
for prjInfo in prjInfos:
prjObj.add(prjInfo['name'],prjInfo['flag'])
+32 -32
View File
@@ -3,46 +3,46 @@ file:
# use_llama_parse: Use LlamaParse if `true`. Needs a `LLAMA_CLOUD_API_KEY` from https://cloud.llamaindex.ai set as environment variable # use_llama_parse: Use LlamaParse if `true`. Needs a `LLAMA_CLOUD_API_KEY` from https://cloud.llamaindex.ai set as environment variable
use_llama_parse: false use_llama_parse: false
db: #db:
# The configuration for the database loader, only supports MySQL and PostgreSQL databases for now. # The configuration for the database loader, only supports MySQL and PostgreSQL databases for now.
# uri: The URI for the database. E.g.: mysql+pymysql://user:password@localhost:3306/db or postgresql+psycopg2://user:password@localhost:5432/db # uri: The URI for the database. E.g.: mysql+pymysql://user:password@localhost:3306/db or postgresql+psycopg2://user:password@localhost:5432/db
# query: The query to fetch data from the database. E.g.: SELECT * FROM table # query: The query to fetch data from the database. E.g.: SELECT * FROM table
- uri: mysql+pymysql://zjinfo1:Dy2Bcr53Hm5xRkba@110.42.234.166:3306/zjinfo1 #- uri: mysql+pymysql://zjinfo1:Dy2Bcr53Hm5xRkba@110.42.234.166:3306/zjinfo1
enable: true # 添加 enable 字段 #enable: false # 添加 enable 字段
queries: #queries:
- sql: select * from ProjectProperties; #- sql: select * from ProjectProperties;
explanation: "工程属性表数据,层级关系包含在博微电力造价工程文件格式_ProjectProperties.json文件中。" #explanation: "工程属性表数据,层级关系包含在博微电力造价工程文件格式_ProjectProperties.json文件中。"
- sql: select Id, ParentId, Level, Name, Code, Amount, Amount_Total from TotalCalculateTable; #- sql: select Id, ParentId, Level, Name, Code, Amount, Amount_Total from TotalCalculateTable;
explanation: "总算表数据,层级关系包含在博微电力造价工程文件格式_TotalCalculateTable.json文件中。" #explanation: "总算表数据,层级关系包含在博微电力造价工程文件格式_TotalCalculateTable.json文件中。"
- sql: select Id, ParentId, Level, SerialNumber, Name, Quantity, Rate, Sum_Price from ProjectDivision where ProfessionalType = '线路'; #- sql: select Id, ParentId, Level, SerialNumber, Name, Quantity, Rate, Sum_Price from ProjectDivision where ProfessionalType = '线路';
explanation: "专业类型为线路的项目划分表数据,层级关系包含在博微电力造价工程文件格式_ProjectDivision.json文件中。" #explanation: "专业类型为线路的项目划分表数据,层级关系包含在博微电力造价工程文件格式_ProjectDivision.json文件中。"
- sql: select Id, ParentId, Level, SerialNumber, Name, Quantity, Rate, Sum_Price from ProjectDivision where ProfessionalType = '余物清理'; #- sql: select Id, ParentId, Level, SerialNumber, Name, Quantity, Rate, Sum_Price from ProjectDivision where ProfessionalType = '余物清理';
explanation: "专业类型为余物清理的项目划分表数据,层级关系包含在博微电力造价工程文件格式_ProjectDivision.json文件中。" #explanation: "专业类型为余物清理的项目划分表数据,层级关系包含在博微电力造价工程文件格式_ProjectDivision.json文件中。"
- sql: select Id, ParentId, Level, SerialNumber, Name, Quantity, Rate, Sum_Price from ProjectDivision where ProfessionalType = '拆除线路'; #- sql: select Id, ParentId, Level, SerialNumber, Name, Quantity, Rate, Sum_Price from ProjectDivision where ProfessionalType = '拆除线路';
explanation: "专业类型为拆除线路的项目划分表数据,层级关系包含在博微电力造价工程文件格式_ProjectDivision.json文件中。" #explanation: "专业类型为拆除线路的项目划分表数据,层级关系包含在博微电力造价工程文件格式_ProjectDivision.json文件中。"
- sql: select Id, ParentId, Level, Name, Code, Rate, Amount from OtherFee; #- sql: select Id, ParentId, Level, Name, Code, Rate, Amount from OtherFee;
explanation: "其他费用表数据,层级关系包含在博微电力造价工程文件格式_OtherFee.json文件中" #explanation: "其他费用表数据,层级关系包含在博微电力造价工程文件格式_OtherFee.json文件中"
- sql: select Name, Code, Calculation_Formula, Rate, from FeeCollectionTable where FeeCollection_Table_Name = '线路取费表' #- sql: select Name, Code, Calculation_Formula, Rate, from FeeCollectionTable where FeeCollection_Table_Name = '线路取费表'
explanation: "取费表名称为线路取费表的取费表数据,层级关系包含在博微电力造价工程文件格式_FeeCollectionTable.json文件中" #explanation: "取费表名称为线路取费表的取费表数据,层级关系包含在博微电力造价工程文件格式_FeeCollectionTable.json文件中"
- sql: select Name, Code, Calculation_Formula, Rate, from FeeCollectionTable where FeeCollection_Table_Name = '线路取费表(调试工程)aa' #- sql: select Name, Code, Calculation_Formula, Rate, from FeeCollectionTable where FeeCollection_Table_Name = '线路取费表(调试工程)aa'
explanation: "取费表名称为线路取费表的取费表数据,层级关系包含在博微电力造价工程文件格式_FeeCollectionTable.json文件中" #explanation: "取费表名称为线路取费表的取费表数据,层级关系包含在博微电力造价工程文件格式_FeeCollectionTable.json文件中"
- sql: select Name, Code, Calculation_Formula, Rate, from FeeCollectionTable where FeeCollection_Table_Name = '大型土石方取费表' #- sql: select Name, Code, Calculation_Formula, Rate, from FeeCollectionTable where FeeCollection_Table_Name = '大型土石方取费表'
explanation: "取费表名称为线路取费表的取费表数据,层级关系包含在博微电力造价工程文件格式_FeeCollectionTable.json文件中" #explanation: "取费表名称为线路取费表的取费表数据,层级关系包含在博微电力造价工程文件格式_FeeCollectionTable.json文件中"
- sql: select Name, Code, Calculation_Formula, Rate, from FeeCollectionTable where FeeCollection_Table_Name = '线路取费表(余物清理)' #- sql: select Name, Code, Calculation_Formula, Rate, from FeeCollectionTable where FeeCollection_Table_Name = '线路取费表(余物清理)'
explanation: "取费表名称为线路取费表的取费表数据,层级关系包含在博微电力造价工程文件格式_FeeCollectionTable.json文件中" #explanation: "取费表名称为线路取费表的取费表数据,层级关系包含在博微电力造价工程文件格式_FeeCollectionTable.json文件中"
- sql: select Name, Code, Calculation_Formula, Rate, from FeeCollectionTable where FeeCollection_Table_Name = '线路取费表(余物清理)(1)' #- sql: select Name, Code, Calculation_Formula, Rate, from FeeCollectionTable where FeeCollection_Table_Name = '线路取费表(余物清理)(1)'
explanation: "取费表名称为线路取费表的取费表数据,层级关系包含在博微电力造价工程文件格式_FeeCollectionTable.json文件中" #explanation: "取费表名称为线路取费表的取费表数据,层级关系包含在博微电力造价工程文件格式_FeeCollectionTable.json文件中"
- sql: select Name, Code, Calculation_Formula, Rate, from FeeCollectionTable where FeeCollection_Table_Name = '线路取费表(拆除)' #- sql: select Name, Code, Calculation_Formula, Rate, from FeeCollectionTable where FeeCollection_Table_Name = '线路取费表(拆除)'
explanation: "取费表名称为线路取费表的取费表数据,层级关系包含在博微电力造价工程文件格式_FeeCollectionTable.json文件中" #explanation: "取费表名称为线路取费表的取费表数据,层级关系包含在博微电力造价工程文件格式_FeeCollectionTable.json文件中"
- sql: select Name, Code, Calculation_Formula, Rate, from ProjectQuantities where Professional_Type = '线路' #- sql: select Name, Code, Calculation_Formula, Rate, from ProjectQuantities where Professional_Type = '线路'
explanation: "专业类型为线路的工程量表数据,层级关系包含在博微电力造价工程文件格式_ProjectQuantities.json文件中" #explanation: "专业类型为线路的工程量表数据,层级关系包含在博微电力造价工程文件格式_ProjectQuantities.json文件中"
- sql: select Name, Code, Calculation_Formula, Rate, from ProjectQuantities where Professional_Type = '余物清理' #- sql: select Name, Code, Calculation_Formula, Rate, from ProjectQuantities where Professional_Type = '余物清理'
explanation: "专业类型为余物清理的工程量表数据,层级关系包含在博微电力造价工程文件格式_ProjectQuantities.json文件中" #explanation: "专业类型为余物清理的工程量表数据,层级关系包含在博微电力造价工程文件格式_ProjectQuantities.json文件中"
#web: #web:
# driver_arguments: # driver_arguments:
# # The arguments to pass to the webdriver. E.g.: add --headless to run in headless mode # # The arguments to pass to the webdriver. E.g.: add --headless to run in headless mode
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"table":{"alias":"","comment":"取费表是取费设置中各取费表明细。查询示例: SELECT Rate FROM FeeCollectionTable WHERE Name = 'findname'。","fields":[{"alias":"","comment":"","name":"_id","type":"VARCHAR"},{"alias":"编号,代码,代号","comment":"费用代码","name":"Code","type":"VARCHAR"},{"alias":"公式,计算式,表达式","comment":"取费基数","name":"CalculationFormula","type":"VARCHAR"},{"alias":"备注,说明","comment":"费用项备注说明","name":"Remarks","type":"VARCHAR"},{"alias":"费用序号,序号,序列号","comment":"费用表序号","name":"SerialNumber","type":"VARCHAR"},{"alias":"","comment":"","name":"是否隐藏","type":"VARCHAR"},{"alias":"费用利率,费率","comment":"取费费率","name":"Rate","type":"REAL"},{"alias":"项目名,费用名,名称","comment":"费用名称,项目名称","name":"Name","type":"VARCHAR"},{"alias":"","comment":"","name":"nodeType","type":"VARCHAR"},{"alias":"","comment":"","name":"parentId","type":"VARCHAR"},{"alias":"","comment":"","name":"relTbId","type":"VARCHAR"}],"name":"FeeCollectionTable","records":[{"_id":"{AC732533-7DF2-4AE5-B7E5-F44567D78364}","nodeType":"取费表","parentId":"","relTbId":"{6C5274C1-2091-440D-8E3F-94FA30CE65A2}","代码":"FFZ","取费基数":"","备注":"","序号":"一","是否隐藏":"否","费率":"100","费用名称":"直接费"},{"_id":"{634B13BE-3DD0-451B-A6C9-0C9A317CEDA8}","nodeType":"取费表","parentId":"{AC732533-7DF2-4AE5-B7E5-F44567D78364}","relTbId":"{6C5274C1-2091-440D-8E3F-94FA30CE65A2}","代码":"FFZ1","取费基数":"","备注":"","序号":"1","是否隐藏":"否","费率":"100","费用名称":"直接工程费"},{"_id":"{A5043C5F-A326-42D0-8EA7-D8ED1D64495E}","nodeType":"取费表","parentId":"{634B13BE-3DD0-451B-A6C9-0C9A317CEDA8}","relTbId":"{6C5274C1-2091-440D-8E3F-94FA30CE65A2}","代码":"DZF","取费基数":"","备注":"","序号":"1.1","是否隐藏":"否","费率":"100","费用名称":"定额直接费"},{"_id":"{6CE02AA1-5AF2-415C-8120-87B69633E7A6}","nodeType":"取费表","parentId":"{A5043C5F-A326-42D0-8EA7-D8ED1D64495E}","relTbId":"{6C5274C1-2091-440D-8E3F-94FA30CE65A2}","代码":"RGF","取费基数":"取费定额人工费","备注":"","序号":"1.1.1","是否隐藏":"否","费率":"100","费用名称":"人工费"},{"_id":"{D06FC2F6-D089-430F-9898-F222D85FF87C}","nodeType":"取费表","parentId":"{A5043C5F-A326-42D0-8EA7-D8ED1D64495E}","relTbId":"{6C5274C1-2091-440D-8E3F-94FA30CE65A2}","代码":"CLF","取费基数":"取费定额乙供材料费不含税+取费定额甲供材料费含税","备注":"","序号":"1.1.2","是否隐藏":"否","费率":"100","费用名称":"材料费"},{"_id":"{A5BAAA84-B337-43F1-BD8B-4C13F1B15A04}","nodeType":"取费表","parentId":"{A5043C5F-A326-42D0-8EA7-D8ED1D64495E}","relTbId":"{6C5274C1-2091-440D-8E3F-94FA30CE65A2}","代码":"JXF","取费基数":"取费定额机械费","备注":"","序号":"1.1.3","是否隐藏":"否","费率":"100","费用名称":"施工机械使用费"},{"_id":"{3A5715D5-42FB-41A5-937A-D231277D9916}","nodeType":"取费表","parentId":"{AC732533-7DF2-4AE5-B7E5-F44567D78364}","relTbId":"{6C5274C1-2091-440D-8E3F-94FA30CE65A2}","代码":"FFZ2","取费基数":"","备注":"","序号":"2","是否隐藏":"否","费率":"100","费用名称":"措施费"},{"_id":"{AB35557D-593C-4D66-AD1B-17359227B6B5}","nodeType":"取费表","parentId":"{3A5715D5-42FB-41A5-937A-D231277D9916}","relTbId":"{6C5274C1-2091-440D-8E3F-94FA30CE65A2}","代码":"BZF","取费基数":"FFZ1-甲供消材进项税额","备注":"","序号":"2.1","是否隐藏":"否","费率":"2.93","费用名称":"安全文明施工费"},{"_id":"{15CC6A96-C81A-4AAE-A212-B3DCF573443D}","nodeType":"取费表","parentId":"","relTbId":"{6C5274C1-2091-440D-8E3F-94FA30CE65A2}","代码":"HJ","取费基数":"FFZ+一笔性费用","备注":"","序号":"二","是否隐藏":"否","费率":"100","费用名称":"合计"}]}}
@@ -0,0 +1 @@
{"table":{"alias":"","comment":"取费表是取费设置中各取费表明细。查询示例: SELECT Rate FROM FeeCollectionTable WHERE Name = 'findname'。","fields":[{"alias":"","comment":"","name":"_id","type":"VARCHAR"},{"alias":"编号,代码,代号","comment":"费用代码","name":"Code","type":"VARCHAR"},{"alias":"公式,计算式,表达式","comment":"取费基数","name":"CalculationFormula","type":"VARCHAR"},{"alias":"备注,说明","comment":"费用项备注说明","name":"Remarks","type":"VARCHAR"},{"alias":"费用序号,序号,序列号","comment":"费用表序号","name":"SerialNumber","type":"VARCHAR"},{"alias":"","comment":"","name":"是否隐藏","type":"VARCHAR"},{"alias":"费用利率,费率","comment":"取费费率","name":"Rate","type":"REAL"},{"alias":"项目名,费用名,名称","comment":"费用名称,项目名称","name":"Name","type":"VARCHAR"},{"alias":"","comment":"","name":"nodeType","type":"VARCHAR"},{"alias":"","comment":"","name":"parentId","type":"VARCHAR"},{"alias":"","comment":"","name":"relTbId","type":"VARCHAR"}],"name":"FeeCollectionTable","records":[{"_id":"{1C15B4B2-3B33-40F9-8C1A-F16A585894B4}","nodeType":"取费表","parentId":"","relTbId":"{96A61AA6-7110-477F-BD0B-CC0F56658DFE}","代码":"FFZ","取费基数":"","备注":"","序号":"一","是否隐藏":"否","费率":"100","费用名称":"直接费"},{"_id":"{5E7ADB7A-9C41-4813-89D3-8915182FD91E}","nodeType":"取费表","parentId":"{1C15B4B2-3B33-40F9-8C1A-F16A585894B4}","relTbId":"{96A61AA6-7110-477F-BD0B-CC0F56658DFE}","代码":"FFZ1","取费基数":"","备注":"","序号":"1","是否隐藏":"否","费率":"100","费用名称":"直接工程费"},{"_id":"{80745DAE-6C80-497B-B46A-9B0AD665847A}","nodeType":"取费表","parentId":"{5E7ADB7A-9C41-4813-89D3-8915182FD91E}","relTbId":"{96A61AA6-7110-477F-BD0B-CC0F56658DFE}","代码":"RGF","取费基数":"取费定额人工费","备注":"","序号":"1.1","是否隐藏":"否","费率":"100","费用名称":"人工费"},{"_id":"{A7D785CA-D360-4D17-9740-436534F84150}","nodeType":"取费表","parentId":"{5E7ADB7A-9C41-4813-89D3-8915182FD91E}","relTbId":"{96A61AA6-7110-477F-BD0B-CC0F56658DFE}","代码":"CLF","取费基数":"取费定额乙供材料费不含税+取费定额甲供材料费含税","备注":"","序号":"1.2","是否隐藏":"否","费率":"100","费用名称":"材料费"},{"_id":"{2680555F-1FC1-4AFE-BC80-12A16587675B}","nodeType":"取费表","parentId":"{5E7ADB7A-9C41-4813-89D3-8915182FD91E}","relTbId":"{96A61AA6-7110-477F-BD0B-CC0F56658DFE}","代码":"JXF","取费基数":"取费定额机械费","备注":"","序号":"1.3","是否隐藏":"否","费率":"100","费用名称":"施工机械使用费"},{"_id":"{1CDC9898-AD38-4B46-BDAC-870F4AC6BE52}","nodeType":"取费表","parentId":"{1C15B4B2-3B33-40F9-8C1A-F16A585894B4}","relTbId":"{96A61AA6-7110-477F-BD0B-CC0F56658DFE}","代码":"FFZ2","取费基数":"","备注":"","序号":"2","是否隐藏":"否","费率":"100","费用名称":"措施费"},{"_id":"{B3C816DB-A50E-49B9-B861-98F358A8AD11}","nodeType":"取费表","parentId":"{1CDC9898-AD38-4B46-BDAC-870F4AC6BE52}","relTbId":"{96A61AA6-7110-477F-BD0B-CC0F56658DFE}","代码":"BZF","取费基数":"FFZ1-甲供消材进项税额","备注":"","序号":"2.1","是否隐藏":"否","费率":"2.93","费用名称":"安全文明施工费"},{"_id":"{A74D1DBF-FA60-4C00-9F2C-659CAB97AD3C}","nodeType":"取费表","parentId":"","relTbId":"{96A61AA6-7110-477F-BD0B-CC0F56658DFE}","代码":"HJ","取费基数":"FFZ+一笔性费用","备注":"","序号":"二","是否隐藏":"否","费率":"100","费用名称":"合计"}]}}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"table":{"alias":"","comment":"取费表是取费设置中各取费表明细。查询示例: SELECT Rate FROM FeeCollectionTable WHERE Name = 'findname'。","fields":[{"alias":"","comment":"","name":"_id","type":"VARCHAR"},{"alias":"编号,代码,代号","comment":"费用代码","name":"Code","type":"VARCHAR"},{"alias":"公式,计算式,表达式","comment":"取费基数","name":"CalculationFormula","type":"VARCHAR"},{"alias":"备注,说明","comment":"费用项备注说明","name":"Remarks","type":"VARCHAR"},{"alias":"费用序号,序号,序列号","comment":"费用表序号","name":"SerialNumber","type":"VARCHAR"},{"alias":"","comment":"","name":"是否隐藏","type":"VARCHAR"},{"alias":"费用利率,费率","comment":"取费费率","name":"Rate","type":"REAL"},{"alias":"项目名,费用名,名称","comment":"费用名称,项目名称","name":"Name","type":"VARCHAR"},{"alias":"","comment":"","name":"nodeType","type":"VARCHAR"},{"alias":"","comment":"","name":"parentId","type":"VARCHAR"},{"alias":"","comment":"","name":"relTbId","type":"VARCHAR"}],"name":"FeeCollectionTable","records":[{"_id":"{F68A4F69-59D3-4184-96BE-7B6F662BC60E}","nodeType":"取费表","parentId":"","relTbId":"{D8E27F1A-75C4-4005-B49F-BD3402874FB4}","代码":"FFZ1","取费基数":"","备注":"","序号":"一","是否隐藏":"否","费率":"100","费用名称":"直接工程费"},{"_id":"{12EB546B-D14C-4FFA-9029-54ACEE399D6E}","nodeType":"取费表","parentId":"{F68A4F69-59D3-4184-96BE-7B6F662BC60E}","relTbId":"{D8E27F1A-75C4-4005-B49F-BD3402874FB4}","代码":"RGF","取费基数":"取费定额人工费","备注":"","序号":"1","是否隐藏":"否","费率":"100","费用名称":"人工费"},{"_id":"{19E92F99-E1E9-4745-8EA2-F525AF331FB0}","nodeType":"取费表","parentId":"{F68A4F69-59D3-4184-96BE-7B6F662BC60E}","relTbId":"{D8E27F1A-75C4-4005-B49F-BD3402874FB4}","代码":"CLF","取费基数":"取费定额乙供材料费不含税+取费定额甲供材料费含税+乙供取费主材费不含税+甲供取费主材费含税","备注":"","序号":"2","是否隐藏":"否","费率":"100","费用名称":"材料费"},{"_id":"{05F2241D-8919-4A1C-96D0-1091DD079E3B}","nodeType":"取费表","parentId":"{F68A4F69-59D3-4184-96BE-7B6F662BC60E}","relTbId":"{D8E27F1A-75C4-4005-B49F-BD3402874FB4}","代码":"JXF","取费基数":"取费定额机械费","备注":"","序号":"3","是否隐藏":"否","费率":"100","费用名称":"施工机械使用费"},{"_id":"{EB338420-823E-47B7-B8DE-640935812A5B}","nodeType":"取费表","parentId":"","relTbId":"{D8E27F1A-75C4-4005-B49F-BD3402874FB4}","代码":"TZHQF","取费基数":"FFZ1-甲供消材进项税额-甲供主材进项税额","备注":"综合取费费用额(包含措施费、间接费、利润)","序号":"二","是否隐藏":"否","费率":"16.59","费用名称":"综合取费费用额"},{"_id":"{C5834D3B-A4FB-4AEC-812E-B2069F136041}","nodeType":"取费表","parentId":"","relTbId":"{D8E27F1A-75C4-4005-B49F-BD3402874FB4}","代码":"TFFS","取费基数":"FFZ1+TZHQF-取费定额甲供材料费含税-甲供取费主材费含税+不取费定额费不含税-不取费甲供材料费不含税+不取费乙供主材费不含税","备注":"","序号":"三","是否隐藏":"否","费率":"9","费用名称":"税金"},{"_id":"{71DECC0F-AB3D-4230-9A30-7FC4096BF99C}","nodeType":"取费表","parentId":"","relTbId":"{D8E27F1A-75C4-4005-B49F-BD3402874FB4}","代码":"THJ","取费基数":"FFZ1+TZHQF+TFFS+一笔性费用+不取费定额费不含税+不取费乙供主材费不含税+不取费甲供材料进项税额+不取费甲供主材费含税","备注":"","序号":"四","是否隐藏":"否","费率":"100","费用名称":"合计"}]}}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"table":{"alias":"","comment":"取费表是取费设置中各取费表明细。查询示例: SELECT Rate FROM FeeCollectionTable WHERE Name = 'findname'。","fields":[{"alias":"","comment":"","name":"_id","type":"VARCHAR"},{"alias":"编号,代码,代号","comment":"费用代码","name":"Code","type":"VARCHAR"},{"alias":"公式,计算式,表达式","comment":"取费基数","name":"CalculationFormula","type":"VARCHAR"},{"alias":"备注,说明","comment":"费用项备注说明","name":"Remarks","type":"VARCHAR"},{"alias":"费用序号,序号,序列号","comment":"费用表序号","name":"SerialNumber","type":"VARCHAR"},{"alias":"","comment":"","name":"是否隐藏","type":"VARCHAR"},{"alias":"费用利率,费率","comment":"取费费率","name":"Rate","type":"REAL"},{"alias":"项目名,费用名,名称","comment":"费用名称,项目名称","name":"Name","type":"VARCHAR"},{"alias":"","comment":"","name":"nodeType","type":"VARCHAR"},{"alias":"","comment":"","name":"parentId","type":"VARCHAR"},{"alias":"","comment":"","name":"relTbId","type":"VARCHAR"}],"name":"FeeCollectionTable","records":[{"_id":"{42DAB3FC-51DF-47E9-8991-7642C6EE885C}","nodeType":"取费表","parentId":"","relTbId":"{02A4F179-28A3-476E-9697-CD560E240F7A}","代码":"FFZ","取费基数":"","备注":"","序号":"一","是否隐藏":"否","费率":"100","费用名称":"直接费"},{"_id":"{80FF74E3-2DA7-46FE-8298-B7A6EE2D0703}","nodeType":"取费表","parentId":"{42DAB3FC-51DF-47E9-8991-7642C6EE885C}","relTbId":"{02A4F179-28A3-476E-9697-CD560E240F7A}","代码":"FFZ1","取费基数":"","备注":"","序号":"1","是否隐藏":"否","费率":"100","费用名称":"直接工程费"},{"_id":"{6ABF558C-0DB4-47C3-9BB6-7ABCBEA910C2}","nodeType":"取费表","parentId":"{80FF74E3-2DA7-46FE-8298-B7A6EE2D0703}","relTbId":"{02A4F179-28A3-476E-9697-CD560E240F7A}","代码":"DZF","取费基数":"","备注":"","序号":"1.1","是否隐藏":"否","费率":"100","费用名称":"定额直接费"},{"_id":"{DDC61D9C-A38B-4D90-90C4-3266EBDE4D77}","nodeType":"取费表","parentId":"{6ABF558C-0DB4-47C3-9BB6-7ABCBEA910C2}","relTbId":"{02A4F179-28A3-476E-9697-CD560E240F7A}","代码":"RGF","取费基数":"取费定额人工费","备注":"","序号":"1.1.1","是否隐藏":"否","费率":"100","费用名称":"人工费"},{"_id":"{51CF5ACE-E686-4522-9879-32595AE23830}","nodeType":"取费表","parentId":"{6ABF558C-0DB4-47C3-9BB6-7ABCBEA910C2}","relTbId":"{02A4F179-28A3-476E-9697-CD560E240F7A}","代码":"CLF","取费基数":"取费定额乙供材料费不含税","备注":"","序号":"1.1.2","是否隐藏":"否","费率":"100","费用名称":"材料费"},{"_id":"{A2B54828-4789-4C20-AD42-4DE7F6176747}","nodeType":"取费表","parentId":"{6ABF558C-0DB4-47C3-9BB6-7ABCBEA910C2}","relTbId":"{02A4F179-28A3-476E-9697-CD560E240F7A}","代码":"JXF","取费基数":"取费定额机械费","备注":"","序号":"1.1.3","是否隐藏":"否","费率":"100","费用名称":"施工机械使用费"},{"_id":"{02AC3342-44E9-4B16-A718-67A56F6619FF}","nodeType":"取费表","parentId":"{42DAB3FC-51DF-47E9-8991-7642C6EE885C}","relTbId":"{02A4F179-28A3-476E-9697-CD560E240F7A}","代码":"FFZ2","取费基数":"","备注":"","序号":"2","是否隐藏":"否","费率":"100","费用名称":"措施费"},{"_id":"{30CFC3DF-FF64-4870-9A93-9EA9F344213A}","nodeType":"取费表","parentId":"{02AC3342-44E9-4B16-A718-67A56F6619FF}","relTbId":"{02A4F179-28A3-476E-9697-CD560E240F7A}","代码":"BZF","取费基数":"FFZ1","备注":"","序号":"2.1","是否隐藏":"否","费率":"3.25","费用名称":"安全文明施工费"},{"_id":"{E78003F1-AA06-4BF1-BA05-23CBBB4367A0}","nodeType":"取费表","parentId":"","relTbId":"{02A4F179-28A3-476E-9697-CD560E240F7A}","代码":"HJ","取费基数":"FFZ+一笔性费用","备注":"","序号":"二","是否隐藏":"否","费率":"100","费用名称":"合计"}]}}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"table":{"alias":"","comment":"取费表是取费设置中各取费表明细。查询示例: SELECT Rate FROM FeeCollectionTable WHERE Name = 'findname'。","fields":[{"alias":"","comment":"","name":"_id","type":"VARCHAR"},{"alias":"编号,代码,代号","comment":"费用代码","name":"Code","type":"VARCHAR"},{"alias":"公式,计算式,表达式","comment":"取费基数","name":"CalculationFormula","type":"VARCHAR"},{"alias":"备注,说明","comment":"费用项备注说明","name":"Remarks","type":"VARCHAR"},{"alias":"费用序号,序号,序列号","comment":"费用表序号","name":"SerialNumber","type":"VARCHAR"},{"alias":"","comment":"","name":"是否隐藏","type":"VARCHAR"},{"alias":"费用利率,费率","comment":"取费费率","name":"Rate","type":"REAL"},{"alias":"项目名,费用名,名称","comment":"费用名称,项目名称","name":"Name","type":"VARCHAR"},{"alias":"","comment":"","name":"nodeType","type":"VARCHAR"},{"alias":"","comment":"","name":"parentId","type":"VARCHAR"},{"alias":"","comment":"","name":"relTbId","type":"VARCHAR"}],"name":"FeeCollectionTable","records":[{"_id":"{D762E40C-F7C1-4A8E-B091-B4BD26454476}","nodeType":"取费表","parentId":"","relTbId":"{DCBA7CA2-95BA-458A-BF34-7163010FFEAA}","代码":"FFZ1","取费基数":"","备注":"","序号":"一","是否隐藏":"否","费率":"100","费用名称":"直接工程费"},{"_id":"{82C58340-54B2-4EDB-A62F-A7F786D59B78}","nodeType":"取费表","parentId":"{D762E40C-F7C1-4A8E-B091-B4BD26454476}","relTbId":"{DCBA7CA2-95BA-458A-BF34-7163010FFEAA}","代码":"RGF","取费基数":"取费定额人工费","备注":"","序号":"1","是否隐藏":"否","费率":"100","费用名称":"人工费"},{"_id":"{DE1DDC41-13C3-416B-AD08-253EFAF7FF40}","nodeType":"取费表","parentId":"{D762E40C-F7C1-4A8E-B091-B4BD26454476}","relTbId":"{DCBA7CA2-95BA-458A-BF34-7163010FFEAA}","代码":"CLF","取费基数":"取费定额乙供材料费不含税+乙供取费主材费不含税+甲供取费主材费含税","备注":"","序号":"2","是否隐藏":"否","费率":"100","费用名称":"材料费"},{"_id":"{28A95C2F-5516-429E-BAB3-36B6DD9390FC}","nodeType":"取费表","parentId":"{D762E40C-F7C1-4A8E-B091-B4BD26454476}","relTbId":"{DCBA7CA2-95BA-458A-BF34-7163010FFEAA}","代码":"JXF","取费基数":"取费定额机械费","备注":"","序号":"3","是否隐藏":"否","费率":"100","费用名称":"施工机械使用费"},{"_id":"{D27F3977-1185-4DAD-A041-186036503DAF}","nodeType":"取费表","parentId":"","relTbId":"{DCBA7CA2-95BA-458A-BF34-7163010FFEAA}","代码":"TZHQF","取费基数":"FFZ1-甲供主材进项税额","备注":"综合取费费用额(包含措施费、间接费、利润)","序号":"二","是否隐藏":"否","费率":"17.79","费用名称":"综合取费费用额"},{"_id":"{695C2D0E-F688-489C-BA71-EABF73E98E41}","nodeType":"取费表","parentId":"","relTbId":"{DCBA7CA2-95BA-458A-BF34-7163010FFEAA}","代码":"TFFS","取费基数":"FFZ1+TZHQF-甲供取费主材费含税+不取费定额费不含税+不取费乙供主材费不含税","备注":"","序号":"三","是否隐藏":"否","费率":"9","费用名称":"税金"},{"_id":"{C91A22B6-896A-4040-948D-DFC25A8D0C77}","nodeType":"取费表","parentId":"","relTbId":"{DCBA7CA2-95BA-458A-BF34-7163010FFEAA}","代码":"THJ","取费基数":"FFZ1+TZHQF+TFFS+一笔性费用+不取费定额费不含税+不取费乙供主材费不含税+不取费甲供主材费含税","备注":"","序号":"四","是否隐藏":"否","费率":"100","费用名称":"合计"}]}}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"table":{"alias":"","comment":"取费表是取费设置中各取费表明细。查询示例: SELECT Rate FROM FeeCollectionTable WHERE Name = 'findname'。","fields":[{"alias":"","comment":"","name":"_id","type":"VARCHAR"},{"alias":"编号,代码,代号","comment":"费用代码","name":"Code","type":"VARCHAR"},{"alias":"公式,计算式,表达式","comment":"取费基数","name":"CalculationFormula","type":"VARCHAR"},{"alias":"备注,说明","comment":"费用项备注说明","name":"Remarks","type":"VARCHAR"},{"alias":"费用序号,序号,序列号","comment":"费用表序号","name":"SerialNumber","type":"VARCHAR"},{"alias":"","comment":"","name":"是否隐藏","type":"VARCHAR"},{"alias":"费用利率,费率","comment":"取费费率","name":"Rate","type":"REAL"},{"alias":"项目名,费用名,名称","comment":"费用名称,项目名称","name":"Name","type":"VARCHAR"},{"alias":"","comment":"","name":"nodeType","type":"VARCHAR"},{"alias":"","comment":"","name":"parentId","type":"VARCHAR"},{"alias":"","comment":"","name":"relTbId","type":"VARCHAR"}],"name":"FeeCollectionTable","records":[{"_id":"{AE260A6F-EF67-4F66-9AA2-742A11A39C78}","nodeType":"取费表","parentId":"","relTbId":"{DE579B44-20F0-4A84-A620-3C8D211C8F16}","代码":"FFZ","取费基数":"","备注":"","序号":"一","是否隐藏":"否","费率":"100","费用名称":"直接费"},{"_id":"{2EA0D884-AB7F-478B-BCCE-212BF1A5AC87}","nodeType":"取费表","parentId":"{AE260A6F-EF67-4F66-9AA2-742A11A39C78}","relTbId":"{DE579B44-20F0-4A84-A620-3C8D211C8F16}","代码":"FFZ1","取费基数":"","备注":"","序号":"1","是否隐藏":"否","费率":"100","费用名称":"直接工程费"},{"_id":"{62F8641B-D629-40CD-AB49-34B7FB702E98}","nodeType":"取费表","parentId":"{2EA0D884-AB7F-478B-BCCE-212BF1A5AC87}","relTbId":"{DE579B44-20F0-4A84-A620-3C8D211C8F16}","代码":"DZF","取费基数":"","备注":"","序号":"1.1","是否隐藏":"否","费率":"100","费用名称":"定额直接费"},{"_id":"{B9DB9995-8BF9-4769-AB7B-E989B4907A08}","nodeType":"取费表","parentId":"{62F8641B-D629-40CD-AB49-34B7FB702E98}","relTbId":"{DE579B44-20F0-4A84-A620-3C8D211C8F16}","代码":"RGF","取费基数":"取费定额人工费","备注":"","序号":"1.1.1","是否隐藏":"否","费率":"100","费用名称":"人工费"},{"_id":"{6F2D0FFB-CAF5-43CD-90EB-2C64A21E6127}","nodeType":"取费表","parentId":"{62F8641B-D629-40CD-AB49-34B7FB702E98}","relTbId":"{DE579B44-20F0-4A84-A620-3C8D211C8F16}","代码":"CLF","取费基数":"取费定额乙供材料费不含税","备注":"","序号":"1.1.2","是否隐藏":"否","费率":"100","费用名称":"材料费"},{"_id":"{4C54B793-5D91-4762-8813-115218DC72F8}","nodeType":"取费表","parentId":"{62F8641B-D629-40CD-AB49-34B7FB702E98}","relTbId":"{DE579B44-20F0-4A84-A620-3C8D211C8F16}","代码":"JXF","取费基数":"取费定额机械费","备注":"","序号":"1.1.3","是否隐藏":"否","费率":"100","费用名称":"施工机械使用费"},{"_id":"{DBF98998-59F5-4BD6-8575-51CDD2F3EF65}","nodeType":"取费表","parentId":"{AE260A6F-EF67-4F66-9AA2-742A11A39C78}","relTbId":"{DE579B44-20F0-4A84-A620-3C8D211C8F16}","代码":"FFZ2","取费基数":"","备注":"","序号":"2","是否隐藏":"否","费率":"100","费用名称":"措施费"},{"_id":"{1A6B97A1-F64F-4062-9344-92F9DBFEA27C}","nodeType":"取费表","parentId":"{DBF98998-59F5-4BD6-8575-51CDD2F3EF65}","relTbId":"{DE579B44-20F0-4A84-A620-3C8D211C8F16}","代码":"BZF","取费基数":"FFZ1","备注":"","序号":"2.1","是否隐藏":"否","费率":"3.55","费用名称":"安全文明施工费"},{"_id":"{61FE5B00-8DA5-4FA5-A6B5-67A506CABBAC}","nodeType":"取费表","parentId":"","relTbId":"{DE579B44-20F0-4A84-A620-3C8D211C8F16}","代码":"HJ","取费基数":"FFZ+一笔性费用","备注":"","序号":"二","是否隐藏":"否","费率":"100","费用名称":"合计"}]}}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"table":{"alias":"","comment":"取费表是取费设置中各取费表明细。查询示例: SELECT Rate FROM FeeCollectionTable WHERE Name = 'findname'。","fields":[{"alias":"","comment":"","name":"_id","type":"VARCHAR"},{"alias":"编号,代码,代号","comment":"费用代码","name":"Code","type":"VARCHAR"},{"alias":"公式,计算式,表达式","comment":"取费基数","name":"CalculationFormula","type":"VARCHAR"},{"alias":"备注,说明","comment":"费用项备注说明","name":"Remarks","type":"VARCHAR"},{"alias":"费用序号,序号,序列号","comment":"费用表序号","name":"SerialNumber","type":"VARCHAR"},{"alias":"","comment":"","name":"是否隐藏","type":"VARCHAR"},{"alias":"费用利率,费率","comment":"取费费率","name":"Rate","type":"REAL"},{"alias":"项目名,费用名,名称","comment":"费用名称,项目名称","name":"Name","type":"VARCHAR"},{"alias":"","comment":"","name":"nodeType","type":"VARCHAR"},{"alias":"","comment":"","name":"parentId","type":"VARCHAR"},{"alias":"","comment":"","name":"relTbId","type":"VARCHAR"}],"name":"FeeCollectionTable","records":[{"_id":"{ECA21A14-0907-4136-8DCC-B517973334C2}","nodeType":"取费表","parentId":"","relTbId":"{0256D22B-7007-4520-B09E-928BB6A8D16A}","代码":"FFZ1","取费基数":"","备注":"","序号":"一","是否隐藏":"否","费率":"100","费用名称":"直接工程费"},{"_id":"{740AA893-1750-4ECB-B39F-281A67A1E535}","nodeType":"取费表","parentId":"{ECA21A14-0907-4136-8DCC-B517973334C2}","relTbId":"{0256D22B-7007-4520-B09E-928BB6A8D16A}","代码":"RGF","取费基数":"取费定额人工费","备注":"","序号":"1","是否隐藏":"否","费率":"100","费用名称":"人工费"},{"_id":"{D5ED3338-0D3C-40C6-9578-7664DF58DFE0}","nodeType":"取费表","parentId":"{ECA21A14-0907-4136-8DCC-B517973334C2}","relTbId":"{0256D22B-7007-4520-B09E-928BB6A8D16A}","代码":"CLF","取费基数":"取费定额乙供材料费不含税+乙供取费主材费不含税+甲供取费主材费含税","备注":"","序号":"2","是否隐藏":"否","费率":"100","费用名称":"材料费"},{"_id":"{EF4424BB-6DA4-4C71-AA3F-0B3A32C2F57D}","nodeType":"取费表","parentId":"{ECA21A14-0907-4136-8DCC-B517973334C2}","relTbId":"{0256D22B-7007-4520-B09E-928BB6A8D16A}","代码":"JXF","取费基数":"取费定额机械费","备注":"","序号":"3","是否隐藏":"否","费率":"100","费用名称":"施工机械使用费"},{"_id":"{9BEB4BE3-56A4-4E59-B0F9-912856B078A5}","nodeType":"取费表","parentId":"","relTbId":"{0256D22B-7007-4520-B09E-928BB6A8D16A}","代码":"TZHQF","取费基数":"FFZ1-甲供主材进项税额","备注":"综合取费费用额(包含措施费、间接费、利润)","序号":"二","是否隐藏":"否","费率":"17.79","费用名称":"综合取费费用额"},{"_id":"{463D4D32-D1F0-4A43-B912-5C9B83B4083E}","nodeType":"取费表","parentId":"","relTbId":"{0256D22B-7007-4520-B09E-928BB6A8D16A}","代码":"JC","取费基数":"","备注":"","序号":"三","是否隐藏":"否","费率":"100","费用名称":"编制基准期价差"},{"_id":"{26405AAE-BE51-42E1-8A3A-8E0162C48364}","nodeType":"取费表","parentId":"{463D4D32-D1F0-4A43-B912-5C9B83B4083E}","relTbId":"{0256D22B-7007-4520-B09E-928BB6A8D16A}","代码":"RJC","取费基数":"人工价差","备注":"","序号":"1","是否隐藏":"否","费率":"100","费用名称":"人工价差"},{"_id":"{E65ED1F7-384E-4047-891E-79B7A668B42C}","nodeType":"取费表","parentId":"{463D4D32-D1F0-4A43-B912-5C9B83B4083E}","relTbId":"{0256D22B-7007-4520-B09E-928BB6A8D16A}","代码":"CJC","取费基数":"乙供材料价差不含税+乙供主材价差不含税+甲供主材价差含税","备注":"","序号":"2","是否隐藏":"否","费率":"100","费用名称":"材料价差"},{"_id":"{A0CD4285-8D60-435A-9CD7-AAF3E249347D}","nodeType":"取费表","parentId":"{463D4D32-D1F0-4A43-B912-5C9B83B4083E}","relTbId":"{0256D22B-7007-4520-B09E-928BB6A8D16A}","代码":"JJC","取费基数":"机械价差","备注":"","序号":"3","是否隐藏":"否","费率":"100","费用名称":"机械价差"},{"_id":"{8AF46722-7815-4A79-A6AA-2AA7D37848CD}","nodeType":"取费表","parentId":"","relTbId":"{0256D22B-7007-4520-B09E-928BB6A8D16A}","代码":"TFFS","取费基数":"FFZ1+TZHQF+JC-甲供取费主材费含税-甲供主材价差含税+不取费定额费不含税+不取费乙供主材费不含税","备注":"","序号":"四","是否隐藏":"否","费率":"9","费用名称":"税金"},{"_id":"{881D2F8E-691E-4D29-88C3-C19AD425AECB}","nodeType":"取费表","parentId":"","relTbId":"{0256D22B-7007-4520-B09E-928BB6A8D16A}","代码":"THJ","取费基数":"FFZ1+TZHQF+TFFS+JC+一笔性费用+不取费定额费不含税+不取费乙供主材费不含税+不取费甲供主材费含税","备注":"","序号":"五","是否隐藏":"否","费率":"100","费用名称":"合计"}]}}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,71 +0,0 @@
{
"Table": [
{
"name": "FeeCollectionTable",
"alias": "",
"comment": "取费表是取费设置中各取费表明细。查询示例: SELECT Rate FROM FeeCollectionTable WHERE Name = 'findname'。",
"fields": [
{
"name": "FeeCollectionTableName",
"alias": "取费表名称,取费名称,取费名",
"comment": "取费表名称",
"type": "VARCHAR"
},
{
"name": "Name",
"alias": "名称,费用名,项目名",
"comment": "费用名称,项目名称",
"type": "VARCHAR"
},
{
"name": "SerialNumber",
"alias": "序号,序列号,费用序号",
"comment": "费用表序号",
"type": "VARCHAR"
},
{
"name": "Code",
"alias": "编号,代号,代码",
"comment": "费用代码",
"type": "VARCHAR"
},
{
"name": "CalculationFormula",
"alias": "公式,表达式,计算式",
"comment": "取费基数",
"type": "VARCHAR"
},
{
"name": "Rate",
"alias": "费用利率,费率",
"comment": "取费费率",
"type": "REAL"
},
{
"name": "Remarks",
"alias": "说明,备注",
"comment": "费用项备注说明",
"type": "VARCHAR"
},
{
"name": "Major",
"alias": "专业",
"comment": "取费表专业",
"type": "VARCHAR"
},
{
"name": "Type",
"alias": "类型,取费类型",
"comment": "取费表类型",
"type": "VARCHAR"
},
{
"name": "Path",
"alias": "路径,费用全路径",
"comment": "费用项层级全路径",
"type": "VARCHAR"
}
]
}
]
}
@@ -1,89 +0,0 @@
{
"Table": [
{
"name": "OtherFee",
"alias": "",
"comment": "其他费用表被称为“工程费用中其他费用明细”。其他费用是指为完成工程项目建设所必需的,但不属于建筑工程费、安装工程费、设备购置费、基本预备费的其他相关费用。包括建设场地征用及清理费、项目建设管理费、项目建设技术服务费、生产准备费、大件运输措施费、专业爆破服务费等。查询示例: SELECT Rate FROM OtherFee WHERE Name = 'findname'。",
"fields": [
{
"name": "Id",
"alias": "项目idid,费用id",
"comment": "费用项目id",
"type": "INT"
},
{
"name": "ParentId",
"alias": "父级id,父id",
"comment": "费用项目父级id",
"type": "INT"
},
{
"name": "Level",
"alias": "层号,层级,层编号",
"comment": "层级编号,从1开始",
"type": "INT"
},
{
"name": "Name",
"alias": "名称,费用名,项目名",
"comment": "费用名称,项目名称",
"type": "VARCHAR"
},
{
"name": "SerialNumber",
"alias": "序号,序列号",
"comment": "费用表序号",
"type": "VARCHAR"
},
{
"name": "Code",
"alias": "编号,代号,代码",
"comment": "费用代码",
"type": "VARCHAR"
},
{
"name": "CalculationFormula",
"alias": "公式,表达式,计算式",
"comment": "取费基数",
"type": "VARCHAR"
},
{
"name": "Rate",
"alias": "费用利率,费率",
"comment": "取费费率",
"type": "REAL"
},
{
"name": "Amount",
"alias": "金额,价格",
"comment": "金额、合计、费用,\n单位为元",
"type": "REAL"
},
{
"name": "Remarks",
"alias": "说明,备注",
"comment": "费用项备注说明",
"type": "VARCHAR"
},
{
"name": "Compilation_Basis",
"alias": "编制依据,编制来源",
"comment": "费用项编制依据",
"type": "VARCHAR"
},
{
"name": "WBS_Code",
"alias": "WBS编号,WBS编码",
"comment": "费用项WBS编码",
"type": "VARCHAR"
},
{
"name": "Path",
"alias": "路径,费用全路径",
"comment": "费用项层级全路径",
"type": "VARCHAR"
}
]
}
]
}
@@ -1,149 +0,0 @@
{
"Table": [
{
"name": "ProjectDivision",
"alias": "",
"comment": "项目划分表是用于存储工程项目划分树状数据。内部包含安装工程项目划分,建筑工程项目划分,线路项目划分,工程分部分项。查询示例: SELECT Sum_Price FROM ProjectDivision WHERE Name = 'findname'。",
"fields": [
{
"name": "Id",
"alias": "项目idid,费用id",
"comment": "项目划分id",
"type": "INT"
},
{
"name": "ParentId",
"alias": "父级id,父id",
"comment": "项目划分父级id",
"type": "INT"
},
{
"name": "Level",
"alias": "层号,层级,层编号",
"comment": "层级编号,从1开始",
"type": "INT"
},
{
"name": "Quantity",
"alias": "个数,数量,数目",
"comment": "项目划分数量",
"type": "REAL"
},
{
"name": "SerialNumber",
"alias": "序号,序列号,项目序号",
"comment": "项目划分序号",
"type": "VARCHAR"
},
{
"name": "Name",
"alias": "名称,项目名",
"comment": "项目名称",
"type": "VARCHAR"
},
{
"name": "Encoding",
"alias": "编码,译码",
"comment": "项目划分编码",
"type": "VARCHAR"
},
{
"name": "Sum_Price",
"alias": "合计,合价",
"comment": "项目划分合价,分部分项费用",
"type": "REAL"
},
{
"name": "FeeCollectionTableName",
"alias": "取费表",
"comment": "项目划分的取费表,此项目划分选用的取费表",
"type": "VARCHAR"
},
{
"name": "Remarks",
"alias": "说明,备注",
"comment": "备注",
"type": "VARCHAR"
},
{
"name": "WBS_Code",
"alias": "WBS编号,WBS编码",
"comment": "WBS编码",
"type": "VARCHAR"
},
{
"name": "Manual_Adjustment_Coefficient",
"alias": "人工调差系数",
"comment": "此项目划分下人工调差系数",
"type": "REAL"
},
{
"name": "Material_Adjustment_Coefficient",
"alias": "材料调差系数",
"comment": "此项目划分下材料调差系数",
"type": "REAL"
},
{
"name": "Mechanical_Adjustment_Coefficient",
"alias": "机械调差系数",
"comment": "此项目划分下机械调差系数",
"type": "REAL"
},
{
"name": "Demolition_Manual_Adjustment_Coefficient",
"alias": "拆除人工调差系数",
"comment": "此项目划分下拆除人工调差系数",
"type": "REAL"
},
{
"name": "Demolition_Material_Adjustment_Coefficient",
"alias": "拆除材料调差系数",
"comment": "此项目划分下拆除材料调差系数",
"type": "REAL"
},
{
"name": "Demolition_Mechanical_Adjustment_Coefficient",
"alias": "拆除机械调差系数",
"comment": "此项目划分下拆除机械调差系数",
"type": "REAL"
},
{
"name": "ProfessionalType",
"alias": "专业类型",
"comment": "专业类型,字段值有变电安装、变电建筑、线路等。变电安装等于安装工程,变电建筑等于建筑工程,线路等于安装工程。",
"type": "VARCHAR"
},
{
"name": "Unit",
"alias": "单位",
"comment": "项目划分单位",
"type": "VARCHAR"
},
{
"name": "CalculationFormula",
"alias": "公式,表达式,计算式",
"comment": "项目划分计算式",
"type": "VARCHAR"
},
{
"name": "Rate",
"alias": "费用利率,费率",
"comment": "项目划分费率",
"type": "REAL"
},
{
"name": "Code",
"alias": "编号,代号,代码",
"comment": "项目划分代码",
"type": "VARCHAR"
},
{
"name": "Path",
"alias": "路径,项目全路径",
"comment": "项目划分层级全路径",
"type": "VARCHAR"
}
]
}
]
}
@@ -1,239 +0,0 @@
{
"Table": [
{
"name": "ProjectDivisions_CostPreview",
"alias": "",
"comment": "项目划分_费用预览表也被称为“项目划分费用预览”、“项目划分取费费用”。其中包含项目划分合价、直接费、间接费、利润、税金、主材费等。查询示例: SELECT Total FROM ProjectDivisions_CostPreview WHERE Id = '15'。",
"fields": [
{
"name": "Id",
"alias": "id,项目id",
"comment": "项目划分id",
"type": "INT"
},
{
"name": "ParentId",
"alias": "父级id,父id",
"comment": "项目划分父级id",
"type": "INT"
},
{
"name": "Level",
"alias": "层号,层级,层编号",
"comment": "层级编号,从1开始",
"type": "INT"
},
{
"name": "ProfessionalType",
"alias": "专业类型",
"comment": "专业类型,字段值有变电安装、变电建筑、线路等。变电安装等于安装工程,变电建筑等于建筑工程,线路等于安装工程。",
"type": "VARCHAR"
},
{
"name": "FeeCollectionTableName",
"alias": "取费表",
"comment": "项目划分的取费表,此项目划分选用的取费表",
"type": "VARCHAR"
},
{
"name": "Direct_Cost",
"alias": "直接费",
"comment": "直接费是指施工过程中直接耗用于建筑、安装工程产品的各项费用的总和。包括直接工程费和措施费。",
"type": "REAL"
},
{
"name": "Direct_Project_Cost",
"alias": "直接工程费",
"comment": "直接工程费是指按照正常的施工条件,在施工过程中耗费的构成工程实体的各项费用。包括人工费、材料费和施工机械使用费。",
"type": "REAL"
},
{
"name": "Quota_Direct_Cost",
"alias": "定额直接费",
"comment": "定额直接费,包含人工费、材料费中已进入定额基价的消耗性材料费和施工机械使用费。",
"type": "REAL"
},
{
"name": "Labor_Cost",
"alias": "人工费",
"comment": "人工费是指支付给直接从事建筑安装工程施工作业的生产人员的各项费用。包括基本工资、工资性补贴、辅助工资、职工福利费、生产人员劳动保护费。",
"type": "REAL"
},
{
"name": "Material_Cost",
"alias": "材料费",
"comment": "材料费是指施工过程中一次性消耗材料及摊销材料的费用。指已进入定额基价的消耗性材料费。",
"type": "REAL"
},
{
"name": "Construction_Machinery_Cost",
"alias": "施工机械使用费",
"comment": "施工机械使用费是指施工机械作业所发生的机械使用费以及机械的现场安拆费和场外运费。包括折旧费、检修费、维护费、安装及拆卸费、场外运费、操作人员人工费、燃料动力费、其他费等。",
"type": "REAL"
},
{
"name": "Installation_Material_Cost",
"alias": "装置性材料费",
"comment": "装置性材料费是指建设工程中构成工艺系统实体的工艺性材料,也称主要材料费。装置性材料通常在概算或预算定额中未计价,也称未计价材料,也称主材。",
"type": "REAL"
},
{
"name": "A_Supply_Installation_Material_Cost",
"alias": "甲供装置性材料费",
"comment": "供货方为甲供的装置性材料费。",
"type": "REAL"
},
{
"name": "B_Supply_Installation_Material_Cost",
"alias": "乙供装置性材料费",
"comment": "供货方为乙供的装置性材料费。",
"type": "REAL"
},
{
"name": "Measure_Cost",
"alias": "措施费",
"comment": "措施费是指为完成工程项目施工而进行施工准备、克服自然条件的不利影响和辅助施工所发生的不构成工程实体的各项费用。包括冬雨季施工增加费、夜间施工增加费、施工工具用具使用费、特殊地区施工增加费、临时设施费、施工机构迁移费、安全文明施工费。",
"type": "REAL"
},
{
"name": "WinterRainySeasons_Additional_Construction_Cost",
"alias": "冬雨季施工增加费",
"comment": "冬雨季施工增加费是指按照合理的工期要求,建筑、安装工程必须在冬季、雨季期间连续施工而需要增加的费用。",
"type": "REAL"
},
{
"name": "Night_Additional_Construction_Cost",
"alias": "夜间施工增加费",
"comment": "夜间施工增加费是指按照规程要求,工程必须在夜间连续施工所发生的夜班补助、夜间施工降效、夜间施工照明设备摊销及照明用电等费用。",
"type": "REAL"
},
{
"name": "Construction_Tool_Usage_Cost",
"alias": "施工工具用具使用费",
"comment": "施工工具用具使用费是指施工企业的生产、检验、试验部门使用的不属于固定资产的工具用具和仪器仪表的购置、摊销和维护费用。",
"type": "REAL"
},
{
"name": "Special_Areas_Additional_Construction_Cost",
"alias": "特殊地区施工增加费",
"comment": "特殊地区施工增加费是指在高海拔、酷热、严寒等地区施工:因特殊自然条件影响而需额外增加的施工费用。",
"type": "REAL"
},
{
"name": "Temporary_Facility_Cost",
"alias": "临时设施费",
"comment": "临时设施费是指施工企业为满足现场正常生产、生活需要在现场必须搭设的生产、生活用临时建筑物、构筑物和其他临时设施所发生的费用,以及维修、拆除、折旧及摊销费,或临时设施的租赁费等。",
"type": "REAL"
},
{
"name": "Construction_Organization_Relocation_Cost",
"alias": "施工机构迁移费",
"comment": "施工机构迁移费是指施工企业派遣施工队伍到所承建工程现场所发生的搬迁费用。包括职工调遣差旅费和调遣期间的工资,以及办公设备、工器具、家具、材料用品和施工机械等的搬迁费用。",
"type": "REAL"
},
{
"name": "Safe_Civilized_Construction_Cost",
"alias": "安全文明施工费",
"comment": "安全文明施工费,包括安全生产费、文明施工费、环境保护费。",
"type": "REAL"
},
{
"name": "Indirect_Cost",
"alias": "间接费",
"comment": "间接费是指建筑安装工程的施工过程中,为全工程项目服务而不直接消耗在特定产品对象上的费用。包括规费、企业管理费和施工企业配合调试费。",
"type": "REAL"
},
{
"name": "Regulatory_Cost",
"alias": "规费",
"comment": "规费是指按照国家行政主管部门或省级政府和省级有关权力部门规定必须缴纳并计入建筑安装工程造价的费用。包括社会保险费和住房公积金。",
"type": "REAL"
},
{
"name": "Social_Insurance_Premiums",
"alias": "社会保险费",
"comment": "社会保险费包括养老保险费、失业保险费、医疗保险费、生育保险费和工伤保险费。",
"type": "REAL"
},
{
"name": "Housing_Provident_Fund",
"alias": "住房公积金",
"comment": "住房公积金是指企业按照规定标准为职工缴纳的住房公积金。",
"type": "REAL"
},
{
"name": "Enterprise_Management_Cost",
"alias": "企业管理费",
"comment": "企业管理费是指建筑安装施工企业为组织施工生产和经营管理所发生的费用。",
"type": "REAL"
},
{
"name": "Construction_Enterprise_Cooperation_Debugging_Cost",
"alias": "施工企业配合调试费",
"comment": "施工企业配合调试费是指在工程整套启动试运阶段,施工企业安装专业配合调试所发生的费用。",
"type": "REAL"
},
{
"name": "Profit",
"alias": "利润",
"comment": "利润是指施工企业完成所承包工程获得的盈利。",
"type": "REAL"
},
{
"name": "Taxes",
"alias": "税金",
"comment": "税金是指按照国家税法规定应计入建筑安装工程造价内的销项税额。",
"type": "REAL"
},
{
"name": "Equipment_Cost",
"alias": "设备费",
"comment": "设备购置费是指为项目建设而购置或自制各种设备,并将设备运至施工现场指定位置所支出的费用。包括设备费和设备运杂费。",
"type": "REAL"
},
{
"name": "B_Supply_Equipment_Excluding_Tax_Price",
"alias": "乙供设备不含税价",
"comment": "设备费中,供货方为乙供设备,不含税价",
"type": "REAL"
},
{
"name": "A_Supply_Equipment_Tax_Price",
"alias": "甲供设备含税价",
"comment": "设备费中,供货方为甲供设备,含税价",
"type": "REAL"
},
{
"name": "Installation_Cost",
"alias": "安装费",
"comment": "安装费包含定额直接费、措施费、间接费、利润、税金和一笔性费用。",
"type": "REAL"
},
{
"name": "Main_Material_Cost",
"alias": "主材费",
"comment": "主材费指装置性材料费",
"type": "REAL"
},
{
"name": "Total",
"alias": "总价,总计,总体费用,总的费用",
"comment": "总计包含安装费、主材费、设备费。",
"type": "REAL"
},
{
"name": "Sum",
"alias": "合计,合价",
"comment": "项目划分合价,分部分项费用,项目划分费用。合计包含安装费和主材费。",
"type": "REAL"
},
{
"name": "Path",
"alias": "路径,项目划分全路径",
"comment": "项目划分层级全路径",
"type": "VARCHAR"
}
]
}
]
}
@@ -1,35 +0,0 @@
{
"Table": [
{
"name": "ProjectProperties",
"alias": "",
"comment": "工程属性表是用于存储整个工程的重要属性,访问该表都是为了通过属性名查找属性值。通常属性值有工程信息、工程属性、技经参数,表中包含工程总投资、工程总费用,工程主要费用,工程技经参数等。查询示例: SELECT Value FROM ProjectProperties WHERE Name = 'findname'。",
"fields": [
{
"name": "Name\n",
"alias": "名称、属性、属性名称、字段、字段名称、变量、参数,属性名",
"comment": "属性的唯一标识",
"type": "VARCHAR"
},
{
"name": "Value",
"alias": "值、变量值、参数值、数值,属性值",
"comment": "属性对应的实际值",
"type": "VARCHAR"
},
{
"name": "Type",
"alias": "类型、变量类型、数值类型,属性类型",
"comment": "属性变量的类型",
"type": "VARCHAR"
},
{
"name": "Unit",
"alias": "单位",
"comment": "单位",
"type": "VARCHAR"
}
]
}
]
}
@@ -1,335 +0,0 @@
{
"Table": [
{
"name": "ProjectQuantities",
"alias": "",
"comment": "工程量表是项目划分下工程量,包含定额、主材、设备、一笔性费用。查询示例: SELECT BudgetPrice FROM ProjectQuantities WHERE Name = 'findname'。",
"fields": [
{
"name": "Id",
"alias": "id",
"comment": "消耗量id,工程量id",
"type": "INT"
},
{
"name": "ParentId",
"alias": "父级id,父id",
"comment": "父级id",
"type": "INT"
},
{
"name": "ProjectDivisionId",
"alias": "项目划分id,项目id",
"comment": "父级项目划分id",
"type": "INT"
},
{
"name": "Quantity",
"alias": "个数,数量,数目",
"comment": "数量,消耗量数量,工程量数量,主材数量,定额数量,设备数量,项目划分单位",
"type": "REAL"
},
{
"name": "FeatureSegment",
"alias": "特征段",
"comment": "线路特征段",
"type": "VARCHAR"
},
{
"name": "ParentQuantity",
"alias": "父级个数,父级数量",
"comment": "父级id的数量",
"type": "REAL"
},
{
"name": "Name",
"alias": "名称",
"comment": "项目名称,工程量名称,消耗量名称,主材名称,定额名称,设备名称,材料名称",
"type": "VARCHAR"
},
{
"name": "Encoding",
"alias": "编码,译码",
"comment": "编码,定额编码,主材编码,设备编码",
"type": "VARCHAR"
},
{
"name": "SpecificationModel",
"alias": "规格型号",
"comment": "规格型号,主材规格型号,设备规格型号",
"type": "VARCHAR"
},
{
"name": "Unit",
"alias": "单位",
"comment": "单位,主材单位,定额单位,设备单位,项目划分单位",
"type": "VARCHAR"
},
{
"name": "BasePrice",
"alias": "基价",
"comment": "定额基价",
"type": "REAL"
},
{
"name": "LaborCost",
"alias": "人工费",
"comment": "定额人工费",
"type": "REAL"
},
{
"name": "MaterialCost",
"alias": "材料费",
"comment": "定额材料费",
"type": "REAL"
},
{
"name": "MachineryCost",
"alias": "机械费",
"comment": "定额机械费",
"type": "REAL"
},
{
"name": "QuotaCoefficient",
"alias": "定额系数",
"comment": "定额系数",
"type": "REAL"
},
{
"name": "LaborCoefficient",
"alias": "人工系数",
"comment": "定额人工系数",
"type": "REAL"
},
{
"name": "MaterialCoefficient",
"alias": "材料系数",
"comment": "定额材料系数",
"type": "REAL"
},
{
"name": "MechanicalCoefficient",
"alias": "机械系数",
"comment": "定额机械系数",
"type": "REAL"
},
{
"name": "ExpenseType",
"alias": "费用类型",
"comment": "费用类型,取值为取费、不取费",
"type": "VARCHAR"
},
{
"name": "BudgetPrice",
"alias": "预算价",
"comment": "预算价",
"type": "REAL"
},
{
"name": "MarketPrice",
"alias": "市场价",
"comment": "间接费是指建筑安装工程的施工过程中,为全工程项目服务而不直接消耗在特定产品对象上的费用。包括规费、企业管理费和施工企业配合调试费。",
"type": "REAL"
},
{
"name": "Supplier",
"alias": "供货方",
"comment": "供货方,设备供货方,主材供货方,取值为甲供、乙供",
"type": "VARCHAR"
},
{
"name": "Type",
"alias": "类型",
"comment": "工程量类型,取值定额、主材、设备、一笔性费用",
"type": "VARCHAR"
},
{
"name": "QuotaRange",
"alias": "定额范围",
"comment": "定额范围,取值概算、预算",
"type": "VARCHAR"
},
{
"name": "A_Supply_Material_Cost_Excluding_Tax",
"alias": "甲供材料费不含税",
"comment": "甲供材料费不含税",
"type": "REAL"
},
{
"name": "A_Supply_Material_Cost_Including_Tax",
"alias": "甲供材料费含税",
"comment": "甲供材料费含税",
"type": "REAL"
},
{
"name": "B_Supply_Material_Cost_Excluding_Tax",
"alias": "乙供材料费不含税",
"comment": "乙供材料费不含税",
"type": "REAL"
},
{
"name": "B_Supply_Material_Cost_Including_Tax",
"alias": "乙供材料费含税",
"comment": "乙供材料费含税",
"type": "REAL"
},
{
"name": "ScaffoldCalculation",
"alias": "脚手架计取",
"comment": "脚手架计取,取值计取、不计取",
"type": "VARCHAR"
},
{
"name": "Remarks",
"alias": "说明,备注",
"comment": "备注,说明",
"type": "VARCHAR"
},
{
"name": "FeeCollectionTableName",
"alias": "取费表",
"comment": "项目划分的取费表,工程量的取费表",
"type": "VARCHAR"
},
{
"name": "Quota_Section_Name",
"alias": "定额章节名称",
"comment": "定额章节名称",
"type": "VARCHAR"
},
{
"name": "ProfessionalType",
"alias": "专业类型",
"comment": "专业类型,字段值有变电安装、变电建筑、线路等。变电安装等于安装工程,变电建筑等于建筑工程,线路等于安装工程。",
"type": "VARCHAR"
},
{
"name": "split",
"alias": "拆分",
"comment": "是否为拆分材料,取值1为拆分,取值0为不拆分",
"type": "INT"
},
{
"name": "Loss",
"alias": "损耗",
"comment": "损耗率,主材损耗率",
"type": "REAL"
},
{
"name": "SingleWeight",
"alias": "单重",
"comment": "单重,主材单重",
"type": "REAL"
},
{
"name": "LineWeight",
"alias": "线重",
"comment": "线重,主材线重",
"type": "REAL"
},
{
"name": "SupervisedMaterials",
"alias": "监造物料",
"comment": "监造物料,取值1为监造物料,取值0为非监造物料",
"type": "INT"
},
{
"name": "EquipmentMaterials",
"alias": "设备性材料",
"comment": "设备性材料,取值1为设备性材料,取值0为主材",
"type": "INT"
},
{
"name": "GrossWeight",
"alias": "毛重",
"comment": "毛重,主材毛重",
"type": "VARCHAR"
},
{
"name": "TransportationType",
"alias": "运输类型",
"comment": "运输类型,主材运输类型",
"type": "VARCHAR"
},
{
"name": "TransportationMiscellaneous",
"alias": "运杂费率",
"comment": "运杂费率,设备运杂费率",
"type": "REAL"
},
{
"name": "EquipmentType",
"alias": "设备类型",
"comment": "设备类型,取值为主要设备、普通设备",
"type": "VARCHAR"
},
{
"name": "UnitPrice",
"alias": "单价",
"comment": "单价",
"type": "REAL"
},
{
"name": "Market_Price_Excluding_Tax",
"alias": "市场价不含税",
"comment": "市场价不含税",
"type": "REAL"
},
{
"name": "Market_Price_Including_Tax",
"alias": "市场价含税",
"comment": "市场价含税,设备含税价",
"type": "REAL"
},
{
"name": "Budget_Price_Excluding_Tax",
"alias": "预算价不含税",
"comment": "预算价不含税",
"type": "REAL"
},
{
"name": "Budget_Price_Including_Tax",
"alias": "预算价含税",
"comment": "预算价含税",
"type": "REAL"
},
{
"name": "Unit_Price_Excluding_Tax",
"alias": "单价不含税",
"comment": "单价不含税,设备不含税价",
"type": "REAL"
},
{
"name": "GroupPrice",
"alias": "分组合价",
"comment": "分组合价",
"type": "REAL"
},
{
"name": "Pump_Truck_Pouring",
"alias": "泵车浇制",
"comment": "泵车浇制,取值1为泵车浇制,取值0为非泵车浇制",
"type": "INT"
},
{
"name": "On_Site_Preparation",
"alias": "现场制备",
"comment": "现场制备,取值1为现场制备,取值0为非现场制备",
"type": "INT"
},
{
"name": "Clear_Water_Concrete",
"alias": "清水混凝土",
"comment": "清水混凝土,取值1为清水混凝土,取值0为非清水混凝土",
"type": "INT"
},
{
"name": "Debugging_Fee_Calculation",
"alias": "调试费计取",
"comment": "调试费计取,取值计取、不计取",
"type": "VARCHAR"
}
]
}
]
}
@@ -1,101 +0,0 @@
{
"Table": [
{
"name": "TotalCalculateTable",
"alias": "",
"comment": "总算表也被称为“工程总费用”、“工程费用”。其中包含本地工程、辅助设施工程、编制基准期价差、设备购置费、其他费用、基本预备费、特殊费用、工程静态投资、动态费用、价差预备费、建设期贷款利息、工程动态投资、可抵扣增值税额。查询示例: SELECT Amount FROM TotalCalculateTable WHERE Name = 'findname'。",
"fields": [
{
"name": "Id",
"alias": "项目idid,费用id",
"comment": "费用项目id",
"type": "INT"
},
{
"name": "ParentId",
"alias": "父级id,父id",
"comment": "费用项目父级id",
"type": "INT"
},
{
"name": "Level",
"alias": "层号,层级,层编号",
"comment": "层级编号,从1开始",
"type": "INT"
},
{
"name": "Name",
"alias": "名称,费用名,项目名",
"comment": "费用名称,项目名称",
"type": "VARCHAR"
},
{
"name": "SerialNumber",
"alias": "序号",
"comment": "工程费用序号",
"type": "VARCHAR"
},
{
"name": "Code",
"alias": "编号,代号,代码",
"comment": "费用代码",
"type": "VARCHAR"
},
{
"name": "Rate",
"alias": "费用利率,费率",
"comment": "费率",
"type": "REAL"
},
{
"name": "Amount",
"alias": "金额,价格",
"comment": "合计费",
"type": "REAL"
},
{
"name": "WBS_Code",
"alias": "WBS编号,WBS编码",
"comment": "费用编码",
"type": "VARCHAR"
},
{
"name": "Path",
"alias": "路径,费用全路径",
"comment": "费用名称全路径",
"type": "VARCHAR"
},
{
"name": "Amount_InstallationCost",
"alias": "安装金额,金额_安装费,安装价格",
"comment": "安装费金额",
"type": "REAL"
},
{
"name": "Amount_EquipmentCost",
"alias": "金额_设备费,设备金额,设备价格",
"comment": "设备费金额",
"type": "REAL"
},
{
"name": "Amount_OtherCost",
"alias": "其他费用金额,金额_其他费,其他费用价格",
"comment": "其他费金额",
"type": "REAL"
},
{
"name": "Amount_Total",
"alias": "总的金额,金额_占总计,总体金额",
"comment": "合计费占总计",
"type": "REAL"
},
{
"name": "Amount_UnitInvestment",
"alias": "金额_单位投资,合计投资金额",
"comment": "合计费单位投资",
"type": "REAL"
}
]
}
]
}
Binary file not shown.
Binary file not shown.
+4 -3
View File
@@ -13,22 +13,23 @@ from fastapi.responses import RedirectResponse
from app.api.routers.chat import chat_router from app.api.routers.chat import chat_router
from app.api.routers.upload import file_upload_router from app.api.routers.upload import file_upload_router
from app.api.routers.app import v1_router from app.api.routers.app import v1_router
from app.settings import init_settings from app.settings import init_settings,init_ProjectInfo
from app.observability import init_observability from app.observability import init_observability
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
from phoenix.trace import using_project from phoenix.trace import using_project
logger = logging.getLogger("uvicorn") logger = logging.getLogger("uvicorn")
usPrj = using_project(os.getenv("PHOENIX_PROJECT_NAME")) usPrj = using_project(os.getenv("PHOENIX_PROJECT_NAME"))
usPrj.__enter__() usPrj.__enter__()
import nest_asyncio
nest_asyncio.apply()
init_settings() init_settings()
init_observability() init_observability()
init_ProjectInfo()
app = FastAPI() app = FastAPI()
environment = os.getenv("ENVIRONMENT", "dev") # Default to 'development' if not set environment = os.getenv("ENVIRONMENT", "dev") # Default to 'development' if not set
+58
View File
@@ -0,0 +1,58 @@
from llama_index.llms.dashscope import DashScope
from llama_index.core.base.llms.types import LLMMetadata
class DashScopeGenerationModels:
"""DashScope Qwen serial models."""
QWEN_TURBO = "qwen-turbo"
QWEN_PLUS = "qwen-plus"
QWEN_MAX = "qwen-max"
QWEN_MAX_1201 = "qwen-max-1201"
QWEN_MAX_LONGCONTEXT = "qwen-max-longcontext"
QWEN2_MATH_72B_INSTRUCT = 'qwen2-math-72b-instruct'
DASHSCOPE_MODEL_META = {
DashScopeGenerationModels.QWEN_TURBO: {
"context_window": 1024 * 8,
"num_output": 1024 * 8,
"is_chat_model": True,
},
DashScopeGenerationModels.QWEN_PLUS: {
"context_window": 1024 * 32,
"num_output": 1024 * 32,
"is_chat_model": True,
},
DashScopeGenerationModels.QWEN_MAX: {
"context_window": 1024 * 8,
"num_output": 1024 * 8,
"is_chat_model": True,
},
DashScopeGenerationModels.QWEN_MAX_1201: {
"context_window": 1024 * 8,
"num_output": 1024 * 8,
"is_chat_model": True,
},
DashScopeGenerationModels.QWEN_MAX_LONGCONTEXT: {
"context_window": 1024 * 30,
"num_output": 1024 * 30,
"is_chat_model": True,
},
DashScopeGenerationModels.QWEN2_MATH_72B_INSTRUCT: {
"context_window": 1024 * 2,
"num_output": 1024 * 8,
"is_chat_model": True,
},
}
class CustomDashScope(DashScope):
@property
def metadata(self) -> LLMMetadata:
DASHSCOPE_MODEL_META[self.model_name]["num_output"] = (
self.max_tokens or DASHSCOPE_MODEL_META[self.model_name]["num_output"]
)
return LLMMetadata(
model_name=self.model_name, **DASHSCOPE_MODEL_META[self.model_name]
)
+4974 -771
View File
File diff suppressed because it is too large Load Diff
+17 -4
View File
@@ -35,7 +35,9 @@ chroma="^0.2.0"
llama-index-vector-stores-chroma = "^0.1.10" llama-index-vector-stores-chroma = "^0.1.10"
llama-index-readers-json = "^0.1.5" llama-index-readers-json = "^0.1.5"
llama-index-retrievers-bm25 = "^0.2.2" llama-index-retrievers-bm25 = "^0.2.2"
llama-index-experimental = "^0.2.0" llama-index-experimental = "^0.1.4"
llama-index-llms-ollama = "^0.1.6"
llama-index-embeddings-ollama = "^0.1.3"
duckduckgo_search = "^6.2.6" duckduckgo_search = "^6.2.6"
@@ -63,11 +65,22 @@ version = "^0.8"
version = "0.0.7" version = "0.0.7"
[[tool.poetry.source]]
name = "ali"
url = "https://mirrors.aliyun.com/pypi/simple/"
priority = "primary"
[[tool.poetry.source]] [[tool.poetry.source]]
name = "mirrors" name = "tencent"
url = "https://pypi.tuna.tsinghua.edu.cn/simple/" url = "https://mirrors.cloud.tencent.com/pypi/simple/"
priority = "default" priority = "primary"
[[tool.poetry.source]]
name = "tsinghua"
url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple/"
priority = "primary"
[build-system] [build-system]
requires = [ "poetry-core" ] requires = [ "poetry-core" ]
+2 -1
View File
@@ -8,7 +8,8 @@ from llama_index.core import VectorStoreIndex, SQLDatabase
from llama_index.core.indices.struct_store import SQLTableRetrieverQueryEngine from llama_index.core.indices.struct_store import SQLTableRetrieverQueryEngine
from llama_index.core.objects import SQLTableNodeMapping, ObjectIndex from llama_index.core.objects import SQLTableNodeMapping, ObjectIndex
from app.api.routers.chat import generate_filters from app.api.routers.chat import generate_filters
from app.engine import get_index, makeDescriptionByEngine from app.engine import get_index
from app.engine.engine import makeDescriptionByEngine
from app.engine.loaders.db import CustomDatabaseReader from app.engine.loaders.db import CustomDatabaseReader
from app.engine.vectordb import get_vector_store from app.engine.vectordb import get_vector_store
from app.observability import init_observability from app.observability import init_observability
+2 -1
View File
@@ -7,7 +7,8 @@ from llama_index.core.objects import SQLTableNodeMapping, ObjectIndex
from sqlalchemy import create_engine from sqlalchemy import create_engine
from app.api.routers.chat import generate_filters from app.api.routers.chat import generate_filters
from app.engine import get_index, makeDescriptionByEngine from app.engine import get_index
from app.engine.engine import makeDescriptionByEngine
from app.engine.vectordb import get_vector_store from app.engine.vectordb import get_vector_store
from app.observability import init_observability from app.observability import init_observability
from app.settings import init_settings from app.settings import init_settings
+43
View File
@@ -0,0 +1,43 @@
from typing import Dict, List
class ClsRegister:
clsLst:Dict[str,Dict[str,str]] = {}
@classmethod
def add(cls,catalog,name,obj) -> None:
if catalog in cls.clsLst:
registry = cls.clsLst[catalog]
registry[name] = obj
else:
registry:Dict[str,str] = {}
registry[name] = obj
cls.clsLst[catalog] = registry
@classmethod
def get(cls,catalog,name,fuzzy:bool=False) -> None:
if catalog in cls.clsLst:
registry = cls.clsLst[catalog]
for key,value in registry.items():
if fuzzy:
if key in name:
return value
else:
if key == name:
return value
return None
@classmethod
def getClsList(cls,catalog) -> None:
res_Lst = []
if catalog in cls.clsLst:
registry = cls.clsLst[catalog]
for key,value in registry.items():
res_Lst.append(value)
return res_Lst
def register(catalog,name):
def decorator(className):
ClsRegister.add(catalog,name,className)
return className
return decorator