jvserve 2.0.11__py3-none-any.whl → 2.0.13__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of jvserve might be problematic. Click here for more details.
- jvserve/__init__.py +1 -1
- jvserve/cli.py +47 -17
- jvserve/lib/agent_interface.py +28 -5
- {jvserve-2.0.11.dist-info → jvserve-2.0.13.dist-info}/METADATA +1 -1
- jvserve-2.0.13.dist-info/RECORD +13 -0
- {jvserve-2.0.11.dist-info → jvserve-2.0.13.dist-info}/WHEEL +1 -1
- jvserve-2.0.11.dist-info/RECORD +0 -13
- {jvserve-2.0.11.dist-info → jvserve-2.0.13.dist-info}/entry_points.txt +0 -0
- {jvserve-2.0.11.dist-info → jvserve-2.0.13.dist-info}/licenses/LICENSE +0 -0
- {jvserve-2.0.11.dist-info → jvserve-2.0.13.dist-info}/top_level.txt +0 -0
jvserve/__init__.py
CHANGED
jvserve/cli.py
CHANGED
|
@@ -7,14 +7,13 @@ from contextlib import asynccontextmanager
|
|
|
7
7
|
from typing import AsyncIterator, Optional
|
|
8
8
|
|
|
9
9
|
from dotenv import load_dotenv
|
|
10
|
-
from fastapi.responses import FileResponse, StreamingResponse
|
|
10
|
+
from fastapi.responses import FileResponse, Response, StreamingResponse
|
|
11
11
|
from jac_cloud.jaseci.security import authenticator
|
|
12
12
|
from jac_cloud.plugin.jaseci import NodeAnchor
|
|
13
13
|
from jaclang.cli.cmdreg import cmd_registry
|
|
14
14
|
from jaclang.plugin.default import hookimpl
|
|
15
15
|
from jaclang.runtimelib.context import ExecutionContext
|
|
16
16
|
from jaclang.runtimelib.machine import JacMachine
|
|
17
|
-
from requests import Response
|
|
18
17
|
from uvicorn import run as _run
|
|
19
18
|
|
|
20
19
|
from jvserve.lib.agent_interface import AgentInterface
|
|
@@ -176,7 +175,7 @@ class JacCmd:
|
|
|
176
175
|
def jvfileserve(
|
|
177
176
|
directory: str, host: str = "0.0.0.0", port: int = 9000
|
|
178
177
|
) -> None:
|
|
179
|
-
"""Launch the file server."""
|
|
178
|
+
"""Launch the file server for local files."""
|
|
180
179
|
# load FastAPI
|
|
181
180
|
from fastapi import FastAPI
|
|
182
181
|
from fastapi.middleware.cors import CORSMiddleware
|
|
@@ -194,33 +193,60 @@ class JacCmd:
|
|
|
194
193
|
allow_headers=["*"],
|
|
195
194
|
)
|
|
196
195
|
|
|
197
|
-
if
|
|
198
|
-
|
|
199
|
-
os.environ["JIVAS_FILES_ROOT_PATH"] = directory
|
|
196
|
+
if not os.path.exists(directory):
|
|
197
|
+
os.makedirs(directory)
|
|
200
198
|
|
|
201
|
-
|
|
202
|
-
|
|
199
|
+
# Set the environment variable for the file root path
|
|
200
|
+
os.environ["JIVAS_FILES_ROOT_PATH"] = directory
|
|
203
201
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
202
|
+
# Mount the static files directory
|
|
203
|
+
app.mount(
|
|
204
|
+
"/files",
|
|
205
|
+
StaticFiles(directory=directory),
|
|
206
|
+
name="files",
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
# run the app
|
|
210
|
+
_run(app, host=host, port=port)
|
|
211
|
+
|
|
212
|
+
@cmd_registry.register
|
|
213
|
+
def jvproxyserve(
|
|
214
|
+
directory: str, host: str = "0.0.0.0", port: int = 9000
|
|
215
|
+
) -> None:
|
|
216
|
+
"""Launch the file proxy server for remote files."""
|
|
217
|
+
# load FastAPI
|
|
218
|
+
from fastapi import FastAPI
|
|
219
|
+
from fastapi.middleware.cors import CORSMiddleware
|
|
220
|
+
|
|
221
|
+
# Setup custom routes
|
|
222
|
+
app = FastAPI()
|
|
211
223
|
|
|
224
|
+
# Add CORS middleware
|
|
225
|
+
app.add_middleware(
|
|
226
|
+
CORSMiddleware,
|
|
227
|
+
allow_origins=["*"],
|
|
228
|
+
allow_credentials=True,
|
|
229
|
+
allow_methods=["*"],
|
|
230
|
+
allow_headers=["*"],
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
# Add proxy routes only if using S3
|
|
212
234
|
if FILE_INTERFACE == "s3":
|
|
213
235
|
|
|
214
236
|
@app.get("/files/{file_path:path}", response_model=None)
|
|
215
237
|
async def serve_file(
|
|
216
238
|
file_path: str,
|
|
217
|
-
) -> Response:
|
|
239
|
+
) -> FileResponse | StreamingResponse | Response:
|
|
240
|
+
descriptor_path = os.environ["JIVAS_DESCRIPTOR_ROOT_PATH"]
|
|
241
|
+
if descriptor_path and descriptor_path in file_path:
|
|
242
|
+
return Response(status_code=403)
|
|
243
|
+
|
|
218
244
|
return serve_proxied_file(file_path)
|
|
219
245
|
|
|
220
246
|
@app.get("/f/{file_id:path}", response_model=None)
|
|
221
247
|
async def get_proxied_file(
|
|
222
248
|
file_id: str,
|
|
223
|
-
) -> Response:
|
|
249
|
+
) -> FileResponse | StreamingResponse | Response:
|
|
224
250
|
from bson import ObjectId
|
|
225
251
|
from fastapi import HTTPException
|
|
226
252
|
|
|
@@ -230,8 +256,12 @@ class JacCmd:
|
|
|
230
256
|
# mongo db collection
|
|
231
257
|
collection = NodeAnchor.Collection.get_collection("url_proxies")
|
|
232
258
|
file_details = collection.find_one({"_id": ObjectId(object_id)})
|
|
259
|
+
descriptor_path = os.environ["JIVAS_DESCRIPTOR_ROOT_PATH"]
|
|
233
260
|
|
|
234
261
|
if file_details:
|
|
262
|
+
if descriptor_path and descriptor_path in file_details["path"]:
|
|
263
|
+
return Response(status_code=403)
|
|
264
|
+
|
|
235
265
|
return serve_proxied_file(file_details["path"])
|
|
236
266
|
|
|
237
267
|
raise HTTPException(status_code=404, detail="File not found")
|
jvserve/lib/agent_interface.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""Agent Interface class and methods for interaction with Jivas."""
|
|
2
2
|
|
|
3
|
+
import asyncio
|
|
3
4
|
import json
|
|
4
5
|
import logging
|
|
5
6
|
import os
|
|
@@ -243,7 +244,7 @@ class AgentInterface:
|
|
|
243
244
|
streaming: Optional[bool] = None
|
|
244
245
|
|
|
245
246
|
@staticmethod
|
|
246
|
-
def interact(payload: InteractPayload) -> dict:
|
|
247
|
+
def interact(payload: InteractPayload, request: Request) -> dict:
|
|
247
248
|
"""Interact with the agent."""
|
|
248
249
|
response = None
|
|
249
250
|
ctx = AgentInterface.load_context()
|
|
@@ -291,7 +292,7 @@ class AgentInterface:
|
|
|
291
292
|
interaction_node = response.interaction_node
|
|
292
293
|
|
|
293
294
|
async def generate(
|
|
294
|
-
generator: Iterator,
|
|
295
|
+
generator: Iterator, request: Request
|
|
295
296
|
) -> AsyncGenerator[str, None]:
|
|
296
297
|
"""
|
|
297
298
|
Asynchronously yield data chunks from a response generator in Server-Sent Events (SSE) format.
|
|
@@ -304,11 +305,11 @@ class AgentInterface:
|
|
|
304
305
|
"""
|
|
305
306
|
full_text = ""
|
|
306
307
|
total_tokens = 0
|
|
308
|
+
|
|
307
309
|
try:
|
|
308
310
|
for chunk in generator:
|
|
309
311
|
full_text += chunk.content
|
|
310
312
|
total_tokens += 1 # each chunk is a token, let's tally
|
|
311
|
-
await sleep(0.025)
|
|
312
313
|
yield (
|
|
313
314
|
"data: "
|
|
314
315
|
+ json.dumps(
|
|
@@ -324,6 +325,7 @@ class AgentInterface:
|
|
|
324
325
|
)
|
|
325
326
|
+ "\n\n"
|
|
326
327
|
)
|
|
328
|
+
await sleep(0.025)
|
|
327
329
|
# Update the interaction node with the fully generated text
|
|
328
330
|
actx = await AgentInterface.load_context_async()
|
|
329
331
|
try:
|
|
@@ -336,7 +338,7 @@ class AgentInterface:
|
|
|
336
338
|
attributes={
|
|
337
339
|
"interaction_data": interaction_node.export(),
|
|
338
340
|
},
|
|
339
|
-
module_name="jivas.agent.
|
|
341
|
+
module_name="jivas.agent.memory.update_interaction",
|
|
340
342
|
),
|
|
341
343
|
)
|
|
342
344
|
finally:
|
|
@@ -347,9 +349,30 @@ class AgentInterface:
|
|
|
347
349
|
AgentInterface.LOGGER.error(
|
|
348
350
|
f"Exception in streaming generator: {e}, {traceback.format_exc()}"
|
|
349
351
|
)
|
|
352
|
+
except asyncio.CancelledError:
|
|
353
|
+
AgentInterface.LOGGER.error(
|
|
354
|
+
"Client disconnected. Aborting stream."
|
|
355
|
+
)
|
|
356
|
+
actx = await AgentInterface.load_context_async()
|
|
357
|
+
try:
|
|
358
|
+
interaction_node.set_text_message(message=full_text)
|
|
359
|
+
interaction_node.add_tokens(total_tokens)
|
|
360
|
+
_Jac.spawn_call(
|
|
361
|
+
NodeAnchor.ref(interaction_node.id).architype,
|
|
362
|
+
AgentInterface.spawn_walker(
|
|
363
|
+
walker_name="update_interaction",
|
|
364
|
+
attributes={
|
|
365
|
+
"interaction_data": interaction_node.export(),
|
|
366
|
+
},
|
|
367
|
+
module_name="jivas.agent.memory.update_interaction",
|
|
368
|
+
),
|
|
369
|
+
)
|
|
370
|
+
finally:
|
|
371
|
+
if actx:
|
|
372
|
+
actx.close()
|
|
350
373
|
|
|
351
374
|
return StreamingResponse(
|
|
352
|
-
generate(response.generator),
|
|
375
|
+
generate(response.generator, request),
|
|
353
376
|
media_type="text/event-stream",
|
|
354
377
|
)
|
|
355
378
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
jvserve/__init__.py,sha256=AHR-iejuKB2C8u25HZ1ccXlh6tCaB3MuKVTJz-LZzig,191
|
|
2
|
+
jvserve/cli.py,sha256=NJD4ehtKnhOvsz-vrFh9lz3P4bnxqz-uqTr8QItljZc,8897
|
|
3
|
+
jvserve/lib/__init__.py,sha256=cnzfSHLoTWG9Ygut2nOpDys5aPlQz-m0BSkB-nd7OMs,31
|
|
4
|
+
jvserve/lib/agent_interface.py,sha256=4SHqvySxu08dK2cPoe2TjMKlm11VqM0qDalOKp-tma4,32347
|
|
5
|
+
jvserve/lib/agent_pulse.py,sha256=6hBF6KQYr6Z9Mi_yoWKGfdnW7gg84kK20Slu-bLR_m8,2067
|
|
6
|
+
jvserve/lib/file_interface.py,sha256=sqwTmBnZsVFQUGt7mE1EWA-jHnZlRtBAFeb4Rb_QgQ8,6079
|
|
7
|
+
jvserve/lib/jvlogger.py,sha256=RNiB9PHuBzTvNIQWhxoDgrDlNYA0PYm1SVpvzlqu8mE,4180
|
|
8
|
+
jvserve-2.0.13.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
9
|
+
jvserve-2.0.13.dist-info/METADATA,sha256=8gyJ1EnRbjZDZnOU3F-Y4lq9loXHIGLNCXn3YpPiUzg,4791
|
|
10
|
+
jvserve-2.0.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
11
|
+
jvserve-2.0.13.dist-info/entry_points.txt,sha256=HYyg1QXoLs0JRb004L300VeLOZyDLY27ynD1tnTnEN4,35
|
|
12
|
+
jvserve-2.0.13.dist-info/top_level.txt,sha256=afoCXZv-zXNBuhVIvfJGjafXKEiJl_ooy4BtgQwAG4Q,8
|
|
13
|
+
jvserve-2.0.13.dist-info/RECORD,,
|
jvserve-2.0.11.dist-info/RECORD
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
jvserve/__init__.py,sha256=sJ_mBKN30rjktWYox9bigWcSsNjhSIbEq-EWFvhYAAc,191
|
|
2
|
-
jvserve/cli.py,sha256=ptbu2_u6fZHXyIPPYRt5xKJL_l0OVhq8hETGkAGuvqk,7699
|
|
3
|
-
jvserve/lib/__init__.py,sha256=cnzfSHLoTWG9Ygut2nOpDys5aPlQz-m0BSkB-nd7OMs,31
|
|
4
|
-
jvserve/lib/agent_interface.py,sha256=vGJQ9A_9kWfa6YoW7BiidZO6Huf-0XSlunMLMNGqgws,31053
|
|
5
|
-
jvserve/lib/agent_pulse.py,sha256=6hBF6KQYr6Z9Mi_yoWKGfdnW7gg84kK20Slu-bLR_m8,2067
|
|
6
|
-
jvserve/lib/file_interface.py,sha256=sqwTmBnZsVFQUGt7mE1EWA-jHnZlRtBAFeb4Rb_QgQ8,6079
|
|
7
|
-
jvserve/lib/jvlogger.py,sha256=RNiB9PHuBzTvNIQWhxoDgrDlNYA0PYm1SVpvzlqu8mE,4180
|
|
8
|
-
jvserve-2.0.11.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
9
|
-
jvserve-2.0.11.dist-info/METADATA,sha256=avBB2xIYh266s2UxgR9MF3hVK4dUzWBxgYPJr0Fn2qc,4791
|
|
10
|
-
jvserve-2.0.11.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
|
|
11
|
-
jvserve-2.0.11.dist-info/entry_points.txt,sha256=HYyg1QXoLs0JRb004L300VeLOZyDLY27ynD1tnTnEN4,35
|
|
12
|
-
jvserve-2.0.11.dist-info/top_level.txt,sha256=afoCXZv-zXNBuhVIvfJGjafXKEiJl_ooy4BtgQwAG4Q,8
|
|
13
|
-
jvserve-2.0.11.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|