Spaces:
Running
Running
Update OpenAI API compatibility layer.
Browse filesHide the .lynxkite.json extension.
Support non-streaming requests.
Disable the test box.
lynxkite-lynxscribe/src/lynxkite_lynxscribe/lynxscribe_ops.py
CHANGED
|
@@ -864,11 +864,15 @@ async def get_chat_api(ws: str):
|
|
| 864 |
from lynxkite.core import workspace
|
| 865 |
|
| 866 |
cwd = pathlib.Path()
|
| 867 |
-
path = cwd / ws
|
| 868 |
assert path.is_relative_to(cwd), f"Path '{path}' is invalid"
|
| 869 |
assert path.exists(), f"Workspace {path} does not exist"
|
| 870 |
ws = workspace.Workspace.load(path)
|
| 871 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 872 |
nodes = [op for op in ws.nodes if op.data.title == "LynxScribe RAG Graph Chatbot Backend"]
|
| 873 |
[node] = nodes
|
| 874 |
context = contexts[node.id]
|
|
@@ -879,9 +883,18 @@ async def stream_chat_api_response(request):
|
|
| 879 |
chat_api = await get_chat_api(request["model"])
|
| 880 |
request = ChatCompletionPrompt(**request)
|
| 881 |
async for chunk in await chat_api.answer(request, stream=True):
|
|
|
|
| 882 |
yield chunk.model_dump_json()
|
| 883 |
|
| 884 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 885 |
async def api_service_post(request):
|
| 886 |
"""
|
| 887 |
Serves a chat endpoint that matches LynxScribe's interface.
|
|
@@ -899,9 +912,12 @@ async def api_service_post(request):
|
|
| 899 |
path = "/".join(request.url.path.split("/")[4:])
|
| 900 |
request = await request.json()
|
| 901 |
if path == "chat/completions":
|
| 902 |
-
|
|
|
|
| 903 |
|
| 904 |
-
|
|
|
|
|
|
|
| 905 |
return {"error": "Not found"}
|
| 906 |
|
| 907 |
|
|
@@ -912,7 +928,7 @@ async def api_service_get(request):
|
|
| 912 |
"object": "list",
|
| 913 |
"data": [
|
| 914 |
{
|
| 915 |
-
"id": ws,
|
| 916 |
"object": "model",
|
| 917 |
"created": 0,
|
| 918 |
"owned_by": "lynxkite",
|
|
@@ -924,7 +940,7 @@ async def api_service_get(request):
|
|
| 924 |
return {"error": "Not found"}
|
| 925 |
|
| 926 |
|
| 927 |
-
def get_lynxscribe_workspaces():
|
| 928 |
from lynxkite.core import workspace
|
| 929 |
|
| 930 |
workspaces = []
|
|
@@ -933,7 +949,7 @@ def get_lynxscribe_workspaces():
|
|
| 933 |
try:
|
| 934 |
ws = workspace.Workspace.load(p)
|
| 935 |
if ws.env == ENV:
|
| 936 |
-
workspaces.append(p)
|
| 937 |
except Exception:
|
| 938 |
pass # Ignore files that are not valid workspaces.
|
| 939 |
workspaces.sort()
|
|
|
|
| 864 |
from lynxkite.core import workspace
|
| 865 |
|
| 866 |
cwd = pathlib.Path()
|
| 867 |
+
path = cwd / (ws + ".lynxkite.json")
|
| 868 |
assert path.is_relative_to(cwd), f"Path '{path}' is invalid"
|
| 869 |
assert path.exists(), f"Workspace {path} does not exist"
|
| 870 |
ws = workspace.Workspace.load(path)
|
| 871 |
+
# Remove any test nodes.
|
| 872 |
+
ws.nodes = [op for op in ws.nodes if op.data.title != "Test Chat API"]
|
| 873 |
+
ws.normalize()
|
| 874 |
+
executor = ops.EXECUTORS[ENV]
|
| 875 |
+
contexts = await executor(ws)
|
| 876 |
nodes = [op for op in ws.nodes if op.data.title == "LynxScribe RAG Graph Chatbot Backend"]
|
| 877 |
[node] = nodes
|
| 878 |
context = contexts[node.id]
|
|
|
|
| 883 |
chat_api = await get_chat_api(request["model"])
|
| 884 |
request = ChatCompletionPrompt(**request)
|
| 885 |
async for chunk in await chat_api.answer(request, stream=True):
|
| 886 |
+
chunk.sources = []
|
| 887 |
yield chunk.model_dump_json()
|
| 888 |
|
| 889 |
|
| 890 |
+
async def get_chat_api_response(request):
|
| 891 |
+
chat_api = await get_chat_api(request["model"])
|
| 892 |
+
request = ChatCompletionPrompt(**request)
|
| 893 |
+
response = await chat_api.answer(request, stream=False)
|
| 894 |
+
response.sources = []
|
| 895 |
+
return response.model_dump_json()
|
| 896 |
+
|
| 897 |
+
|
| 898 |
async def api_service_post(request):
|
| 899 |
"""
|
| 900 |
Serves a chat endpoint that matches LynxScribe's interface.
|
|
|
|
| 912 |
path = "/".join(request.url.path.split("/")[4:])
|
| 913 |
request = await request.json()
|
| 914 |
if path == "chat/completions":
|
| 915 |
+
if request["stream"]:
|
| 916 |
+
from sse_starlette.sse import EventSourceResponse
|
| 917 |
|
| 918 |
+
return EventSourceResponse(stream_chat_api_response(request))
|
| 919 |
+
else:
|
| 920 |
+
return await get_chat_api_response(request)
|
| 921 |
return {"error": "Not found"}
|
| 922 |
|
| 923 |
|
|
|
|
| 928 |
"object": "list",
|
| 929 |
"data": [
|
| 930 |
{
|
| 931 |
+
"id": ws.removesuffix(".lynxkite.json"),
|
| 932 |
"object": "model",
|
| 933 |
"created": 0,
|
| 934 |
"owned_by": "lynxkite",
|
|
|
|
| 940 |
return {"error": "Not found"}
|
| 941 |
|
| 942 |
|
| 943 |
+
def get_lynxscribe_workspaces() -> list[str]:
|
| 944 |
from lynxkite.core import workspace
|
| 945 |
|
| 946 |
workspaces = []
|
|
|
|
| 949 |
try:
|
| 950 |
ws = workspace.Workspace.load(p)
|
| 951 |
if ws.env == ENV:
|
| 952 |
+
workspaces.append(str(p))
|
| 953 |
except Exception:
|
| 954 |
pass # Ignore files that are not valid workspaces.
|
| 955 |
workspaces.sort()
|