tool description and rag update

This commit is contained in:
admin 2026-01-22 16:58:37 +01:00
parent 4c29600553
commit 483f54164c

88
app.py
View File

@ -1943,6 +1943,37 @@ def _collection_effective(name: str) -> str:
return name return name
return _collection_versioned(name) return _collection_versioned(name)
async def t_run_shell(args: dict) -> dict:
cmd = args["command"]; timeout = int(args.get("timeout", 600))
BAN_RM=False
if BAN_RM and re.search(r"\brm\s+-", cmd):
return {"exit_code": 1, "stdout": "", "stderr": "rm is verboden", "duration": 0.0, "log_path": ""}
start = time.time()
proc = await asyncio.create_subprocess_shell(cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
try:
#out, err = await asyncio.wait_for(proc.communicate(), timeout=timeout)
# Lees stdout en stderr apart (in bytes)
out_bytes = await asyncio.wait_for(proc.stdout.read(), timeout=timeout)
err_bytes = await asyncio.wait_for(proc.stderr.read(), timeout=timeout)
# Splits stdout en stderr naar regels
stdout_lines = out_bytes.decode(errors="ignore").splitlines()
stderr_lines = err_bytes.decode(errors="ignore").splitlines()
return {
"exit_code": proc.returncode,
"stdout_lines": stdout_lines,
"stderr_lines": stderr_lines,
"duration": time.time() - start,
"log_path": "",
"merge_stderr_used": False
}
except asyncio.TimeoutError:
try: proc.kill()
except Exception: pass
return {"exit_code": -1, "stdout": "", "stderr": "timeout", "duration": time.time()-start, "log_path": ""}
#return {"exit_code": proc.returncode, "stdout": out.decode(errors="ignore"), "stderr": err.decode(errors="ignore"), "duration": time.time()-start, "log_path": ""}
async def _execute_tool(name: str, args: dict) -> dict: async def _execute_tool(name: str, args: dict) -> dict:
logger.info("toolcall: "+str(name)+" ("+str(args)+")") logger.info("toolcall: "+str(name)+" ("+str(args)+")")
if name == "repo_grep": if name == "repo_grep":
@ -2019,6 +2050,17 @@ async def _execute_tool(name: str, args: dict) -> dict:
}) })
return out return out
if name == "rag_query": if name == "rag_query":
out= await run_in_threadpool(_rag_index_repo_sync, **{
"repo_url": args.get("repo",""),
"branch": "main",
"profile": "auto",
"include": "",
"exclude_dirs": "",
"chunk_chars": 3000,
"overlap": 400,
"collection_name": "code_docs",
"force": False,
})
out = await rag_query_api( out = await rag_query_api(
query=args.get("query",""), query=args.get("query",""),
n_results=int(args.get("n_results",5)), n_results=int(args.get("n_results",5)),
@ -2029,6 +2071,18 @@ async def _execute_tool(name: str, args: dict) -> dict:
) )
return out return out
# Console tools
if name == "run_shell":
# Search the web using SearXNG and get the content of the relevant pages.
out=json.dumps(await t_run_shell(args), ensure_ascii=False)
return out
# Repo
if name == "repo_qa":
# High-level QA over een specifieke repo.
out=json.dumps(await repo_qa_answer(repo_hint=args.get("repo_hint"),question=args.get("question"),branch=args.get("branch","main"),n_ctx=10), ensure_ascii=False)
return out
# Web tools # Web tools
if name == "web_search_xng": if name == "web_search_xng":
# Search the web using SearXNG and get the content of the relevant pages. # Search the web using SearXNG and get the content of the relevant pages.
@ -2136,9 +2190,13 @@ async def _execute_tool(name: str, args: dict) -> dict:
raise HTTPException(status_code=400, detail=f"Unknown tool: {name}") raise HTTPException(status_code=400, detail=f"Unknown tool: {name}")
"""
"""
TOOLS_REGISTRY = { TOOLS_REGISTRY = {
"repo_grep": { "repo_grep": {
"description": "Zoek exact(e) tekst in een git repo (fast grep-achtig).", "description": "Zoek een specifieke exacte tekst in een file in een git repo (fast grep-achtig).",
"parameters": { "parameters": {
"type":"object", "type":"object",
"properties":{ "properties":{
@ -2181,7 +2239,7 @@ TOOLS_REGISTRY = {
} }
}, },
"rag_query": { "rag_query": {
"description": "Zoek in de RAG-collectie en geef top-N passages (hybride rerank).", "description": "Zoek korte text in de RAG-collectie en geef top-N passages (hybride rerank). (! first call rag_index_repo !)",
"parameters": { "parameters": {
"type":"object", "type":"object",
"properties":{ "properties":{
@ -2211,6 +2269,25 @@ TOOLS_REGISTRY = {
"url": {"type": "string"}, "url": {"type": "string"},
},"required":["url"]} },"required":["url"]}
}, },
"run_shell": {
"description": "Voer een shell-commando uit (stdout/stderr). (for simple commands)",
"parameters":{
"type":"object",
"properties":{
"command":{"type":"string"},
"timeout":{"type":"integer","default":600}
},"required":["command"]}
},
"repo_qa": {
"description": "High-level QA over een specifieke repo. (incl. RAG,clone,summary,context fuctionalities). Repo hint graag als full url met .git ",
"parameters":{
"type":"object",
"properties":{
"repo_hint":{"type":"string"},
"question":{"type":"string"},
"branch":{"type":"string"},
},"required":["repo_hint","question"]}
},
"summarize_text": { "summarize_text": {
"description": "Vat tekst samen in bullets met inleiding en actiepunten.", "description": "Vat tekst samen in bullets met inleiding en actiepunten.",
"parameters": {"type":"object","properties":{ "parameters": {"type":"object","properties":{
@ -2490,6 +2567,10 @@ def _normalize_tools_and_choice(body: dict) -> None:
body["tool_choice"] = {"type": "function", "function": {"name": fc["name"]}} body["tool_choice"] = {"type": "function", "function": {"name": fc["name"]}}
body.pop("function_call", None) body.pop("function_call", None)
@app.post("/v1/completions")
async def openai_completions(body: dict = Body(...), request: Request = None):
out = await openai_chat_completions(body,request)
return out
@app.post("/v1/chat/completions") @app.post("/v1/chat/completions")
async def openai_chat_completions(body: dict = Body(...), request: Request = None): async def openai_chat_completions(body: dict = Body(...), request: Request = None):
@ -3730,8 +3811,7 @@ async def rag_query_api(
if repo: if repo:
# Accepteer zowel 'repo' (basename) als 'repo_full' (owner/repo) # Accepteer zowel 'repo' (basename) als 'repo_full' (owner/repo)
base = repo.rsplit("/", 1)[-1] base = repo.rsplit("/", 1)[-1]
where = {"$or": [ where = {"$and": [
{"repo": {"$eq": base}},
{"repo_full": {"$eq": repo}} {"repo_full": {"$eq": repo}}
]} ]}
if profile: where["profile"] = {"$eq": profile} if profile: where["profile"] = {"$eq": profile}