jvserve 2.1.16__py3-none-any.whl → 2.1.18__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/cli.py +38 -2
- jvserve/lib/agent_interface.py +63 -3
- jvserve/lib/jac_interface.py +10 -4
- {jvserve-2.1.16.dist-info → jvserve-2.1.18.dist-info}/METADATA +1 -1
- jvserve-2.1.18.dist-info/RECORD +14 -0
- jvserve-2.1.16.dist-info/RECORD +0 -14
- {jvserve-2.1.16.dist-info → jvserve-2.1.18.dist-info}/WHEEL +0 -0
- {jvserve-2.1.16.dist-info → jvserve-2.1.18.dist-info}/entry_points.txt +0 -0
- {jvserve-2.1.16.dist-info → jvserve-2.1.18.dist-info}/licenses/LICENSE +0 -0
- {jvserve-2.1.16.dist-info → jvserve-2.1.18.dist-info}/top_level.txt +0 -0
jvserve/cli.py
CHANGED
|
@@ -18,9 +18,9 @@ import pymongo
|
|
|
18
18
|
import requests
|
|
19
19
|
from bson import ObjectId
|
|
20
20
|
from dotenv import load_dotenv
|
|
21
|
-
from fastapi import FastAPI, HTTPException, Response
|
|
21
|
+
from fastapi import FastAPI, HTTPException, Request, Response
|
|
22
22
|
from fastapi.middleware.cors import CORSMiddleware
|
|
23
|
-
from fastapi.responses import FileResponse, StreamingResponse
|
|
23
|
+
from fastapi.responses import FileResponse, JSONResponse, StreamingResponse
|
|
24
24
|
from jac_cloud.core.context import JaseciContext
|
|
25
25
|
from jac_cloud.jaseci.main import FastAPI as JaseciFastAPI # type: ignore
|
|
26
26
|
from jac_cloud.jaseci.utils import logger
|
|
@@ -244,6 +244,42 @@ def run_jivas(filename: str, host: str = "localhost", port: int = 8000) -> None:
|
|
|
244
244
|
allow_headers=["*"],
|
|
245
245
|
)
|
|
246
246
|
|
|
247
|
+
@app.get("/action/webhook/{namespace}/{action}/{walker}/{agent_id}/{key}")
|
|
248
|
+
async def webhook_exec_get(
|
|
249
|
+
namespace: str,
|
|
250
|
+
action: str,
|
|
251
|
+
walker: str,
|
|
252
|
+
agent_id: str,
|
|
253
|
+
key: str,
|
|
254
|
+
request: Request,
|
|
255
|
+
) -> JSONResponse:
|
|
256
|
+
return await agent_interface.webhook_exec(
|
|
257
|
+
namespace=namespace,
|
|
258
|
+
action=action,
|
|
259
|
+
walker=walker,
|
|
260
|
+
agent_id=agent_id,
|
|
261
|
+
key=key,
|
|
262
|
+
request=request,
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
@app.post("/action/webhook/{namespace}/{action}/{walker}/{agent_id}/{key}")
|
|
266
|
+
async def webhook_exec_post(
|
|
267
|
+
namespace: str,
|
|
268
|
+
action: str,
|
|
269
|
+
walker: str,
|
|
270
|
+
agent_id: str,
|
|
271
|
+
key: str,
|
|
272
|
+
request: Request,
|
|
273
|
+
) -> JSONResponse:
|
|
274
|
+
return await agent_interface.webhook_exec(
|
|
275
|
+
namespace=namespace,
|
|
276
|
+
action=action,
|
|
277
|
+
walker=walker,
|
|
278
|
+
agent_id=agent_id,
|
|
279
|
+
key=key,
|
|
280
|
+
request=request,
|
|
281
|
+
)
|
|
282
|
+
|
|
247
283
|
# Ensure the local file directory exists if that's the interface
|
|
248
284
|
if FILE_INTERFACE == "local":
|
|
249
285
|
directory = os.environ.get("JIVAS_FILES_ROOT_PATH", DEFAULT_FILES_ROOT)
|
jvserve/lib/agent_interface.py
CHANGED
|
@@ -6,6 +6,8 @@ import traceback
|
|
|
6
6
|
from typing import Any
|
|
7
7
|
|
|
8
8
|
import requests
|
|
9
|
+
from fastapi import Request
|
|
10
|
+
from fastapi.responses import JSONResponse
|
|
9
11
|
|
|
10
12
|
from jvserve.lib.jac_interface import JacInterface
|
|
11
13
|
|
|
@@ -15,6 +17,7 @@ class AgentInterface:
|
|
|
15
17
|
|
|
16
18
|
_instance = None
|
|
17
19
|
logger = logging.getLogger(__name__)
|
|
20
|
+
timeout = int(os.environ.get("JIVAS_REQUEST_TIMEOUT", 30))
|
|
18
21
|
|
|
19
22
|
def __init__(self, host: str = "localhost", port: int = 8000) -> None:
|
|
20
23
|
"""Initialize the AgentInterface with JacInterface."""
|
|
@@ -46,11 +49,68 @@ class AgentInterface:
|
|
|
46
49
|
self._jac.reset()
|
|
47
50
|
self.logger.error(f"Init error: {e}\n{traceback.format_exc()}")
|
|
48
51
|
|
|
52
|
+
async def webhook_exec(
|
|
53
|
+
self,
|
|
54
|
+
agent_id: str,
|
|
55
|
+
key: str,
|
|
56
|
+
namespace: str,
|
|
57
|
+
action: str,
|
|
58
|
+
walker: str,
|
|
59
|
+
request: Request,
|
|
60
|
+
) -> JSONResponse:
|
|
61
|
+
"""Trigger webhook execution - async compatible"""
|
|
62
|
+
try:
|
|
63
|
+
|
|
64
|
+
if not self._jac.is_valid():
|
|
65
|
+
self.logger.warning(
|
|
66
|
+
"Invalid API state for webhook, attempting to reinstate it..."
|
|
67
|
+
)
|
|
68
|
+
self._jac._authenticate()
|
|
69
|
+
|
|
70
|
+
header = dict(request.headers)
|
|
71
|
+
try:
|
|
72
|
+
payload = await request.json()
|
|
73
|
+
if not payload:
|
|
74
|
+
payload = {}
|
|
75
|
+
except Exception:
|
|
76
|
+
payload = {}
|
|
77
|
+
|
|
78
|
+
walker_obj = await self._jac.spawn_walker_async(
|
|
79
|
+
walker_name=walker,
|
|
80
|
+
module_name=f"actions.{namespace}.{action}.{walker}",
|
|
81
|
+
attributes={
|
|
82
|
+
"agent_id": agent_id,
|
|
83
|
+
"key": key,
|
|
84
|
+
"header": header,
|
|
85
|
+
"payload": payload,
|
|
86
|
+
},
|
|
87
|
+
)
|
|
88
|
+
if not walker_obj:
|
|
89
|
+
self.logger.error("Webhook execution failed")
|
|
90
|
+
return JSONResponse(
|
|
91
|
+
content={"error": "Webhook execution failed"}, status_code=500
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
result = walker_obj.response
|
|
95
|
+
return JSONResponse(
|
|
96
|
+
status_code=result.get("status", 200),
|
|
97
|
+
content=result.get("message", "200 OK"),
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
except Exception as e:
|
|
101
|
+
self._jac.reset()
|
|
102
|
+
self.logger.error(f"Webhook callback error: {e}\n{traceback.format_exc()}")
|
|
103
|
+
return JSONResponse(
|
|
104
|
+
content={"error": "Internal server error"}, status_code=500
|
|
105
|
+
)
|
|
106
|
+
|
|
49
107
|
def api_pulse(self, action_label: str, agent_id: str) -> dict:
|
|
50
108
|
"""Synchronous pulse API call"""
|
|
51
109
|
if not self._jac.is_valid():
|
|
52
|
-
self.logger.warning(
|
|
53
|
-
|
|
110
|
+
self.logger.warning(
|
|
111
|
+
"Invalid API state for pulse, attempting to reinstate it..."
|
|
112
|
+
)
|
|
113
|
+
self._jac._authenticate()
|
|
54
114
|
|
|
55
115
|
# Clean parameters
|
|
56
116
|
action_label = action_label.replace("action_label=", "")
|
|
@@ -62,7 +122,7 @@ class AgentInterface:
|
|
|
62
122
|
|
|
63
123
|
try:
|
|
64
124
|
response = requests.post(
|
|
65
|
-
endpoint, json=payload, headers=headers, timeout=
|
|
125
|
+
endpoint, json=payload, headers=headers, timeout=self.timeout
|
|
66
126
|
)
|
|
67
127
|
if response.status_code == 200:
|
|
68
128
|
return response.json().get("reports", {})
|
jvserve/lib/jac_interface.py
CHANGED
|
@@ -25,6 +25,8 @@ from jaclang.runtimelib.machine import JacMachine
|
|
|
25
25
|
class JacInterface:
|
|
26
26
|
"""Thread-safe connection and context state provider for Jac Runtime with auto-authentication."""
|
|
27
27
|
|
|
28
|
+
timeout = int(os.environ.get("JIVAS_REQUEST_TIMEOUT", 30))
|
|
29
|
+
|
|
28
30
|
def __init__(self, host: str = "localhost", port: int = 8000) -> None:
|
|
29
31
|
"""Initialize JacInterface with host and port."""
|
|
30
32
|
self.host = host
|
|
@@ -122,7 +124,7 @@ class JacInterface:
|
|
|
122
124
|
|
|
123
125
|
try:
|
|
124
126
|
if module_name not in JacMachine.list_modules():
|
|
125
|
-
self.logger.error(f"Module {module_name} not
|
|
127
|
+
self.logger.error(f"Module {module_name} not found")
|
|
126
128
|
return None
|
|
127
129
|
|
|
128
130
|
entry_node = ctx.entry_node.archetype
|
|
@@ -155,7 +157,9 @@ class JacInterface:
|
|
|
155
157
|
try:
|
|
156
158
|
# Try login first
|
|
157
159
|
response = requests.post(
|
|
158
|
-
login_url,
|
|
160
|
+
login_url,
|
|
161
|
+
json={"email": user, "password": password},
|
|
162
|
+
timeout=self.timeout,
|
|
159
163
|
)
|
|
160
164
|
self.logger.info(f"Login response status: {response.status_code}")
|
|
161
165
|
if response.status_code == 200:
|
|
@@ -164,7 +168,9 @@ class JacInterface:
|
|
|
164
168
|
|
|
165
169
|
# Register if login fails
|
|
166
170
|
reg_response = requests.post(
|
|
167
|
-
register_url,
|
|
171
|
+
register_url,
|
|
172
|
+
json={"email": user, "password": password},
|
|
173
|
+
timeout=self.timeout,
|
|
168
174
|
)
|
|
169
175
|
self.logger.info(
|
|
170
176
|
f"Register response status: {reg_response.status_code}"
|
|
@@ -174,7 +180,7 @@ class JacInterface:
|
|
|
174
180
|
login_response = requests.post(
|
|
175
181
|
login_url,
|
|
176
182
|
json={"email": user, "password": password},
|
|
177
|
-
timeout=
|
|
183
|
+
timeout=self.timeout,
|
|
178
184
|
)
|
|
179
185
|
self.logger.info(
|
|
180
186
|
f"Retry login response status: {login_response.status_code}"
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
jvserve/__init__.py,sha256=Jd0pamSDn2wGTZkNk8I9qNYTFBHp7rasdYO0_Dvad_k,245
|
|
2
|
+
jvserve/cli.py,sha256=FdZ5Zht7d5lDr2rOtAqgB_lw7o9TfyyhfDIC2noc46s,14929
|
|
3
|
+
jvserve/lib/__init__.py,sha256=cnzfSHLoTWG9Ygut2nOpDys5aPlQz-m0BSkB-nd7OMs,31
|
|
4
|
+
jvserve/lib/agent_interface.py,sha256=cO2ZgII33YU6m2zU_qTThAPoHcfg8V3dAMPFGaZAun4,5511
|
|
5
|
+
jvserve/lib/agent_pulse.py,sha256=6hBF6KQYr6Z9Mi_yoWKGfdnW7gg84kK20Slu-bLR_m8,2067
|
|
6
|
+
jvserve/lib/file_interface.py,sha256=VO9RBCtJwaBxu5eZjc57-uRbsVXXZt86wVRVq9R3KXY,6079
|
|
7
|
+
jvserve/lib/jac_interface.py,sha256=hugcHF6by6_fIFfmvW7fgRMVpKe471oEWEZEA53MtEQ,8148
|
|
8
|
+
jvserve/lib/jvlogger.py,sha256=RNiB9PHuBzTvNIQWhxoDgrDlNYA0PYm1SVpvzlqu8mE,4180
|
|
9
|
+
jvserve-2.1.18.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
10
|
+
jvserve-2.1.18.dist-info/METADATA,sha256=qFDC-jP9juZ9-j49j536aQYIErjgssTRLm3N1nZHH94,4821
|
|
11
|
+
jvserve-2.1.18.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
12
|
+
jvserve-2.1.18.dist-info/entry_points.txt,sha256=HYyg1QXoLs0JRb004L300VeLOZyDLY27ynD1tnTnEN4,35
|
|
13
|
+
jvserve-2.1.18.dist-info/top_level.txt,sha256=afoCXZv-zXNBuhVIvfJGjafXKEiJl_ooy4BtgQwAG4Q,8
|
|
14
|
+
jvserve-2.1.18.dist-info/RECORD,,
|
jvserve-2.1.16.dist-info/RECORD
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
jvserve/__init__.py,sha256=Jd0pamSDn2wGTZkNk8I9qNYTFBHp7rasdYO0_Dvad_k,245
|
|
2
|
-
jvserve/cli.py,sha256=b1AHsiJUsMVHZ7ZOKhrOJSvISPh5O5O020aoDJQJ0Rk,13910
|
|
3
|
-
jvserve/lib/__init__.py,sha256=cnzfSHLoTWG9Ygut2nOpDys5aPlQz-m0BSkB-nd7OMs,31
|
|
4
|
-
jvserve/lib/agent_interface.py,sha256=Igv5Jb7i9Aq_7IbLDZ6jnldGKssAWKeb6iXoolX8u4k,3478
|
|
5
|
-
jvserve/lib/agent_pulse.py,sha256=6hBF6KQYr6Z9Mi_yoWKGfdnW7gg84kK20Slu-bLR_m8,2067
|
|
6
|
-
jvserve/lib/file_interface.py,sha256=VO9RBCtJwaBxu5eZjc57-uRbsVXXZt86wVRVq9R3KXY,6079
|
|
7
|
-
jvserve/lib/jac_interface.py,sha256=ydhXfYTsrhdvMXBTAd_vnAXJSSVBydQ3qavPU1-oodU,7973
|
|
8
|
-
jvserve/lib/jvlogger.py,sha256=RNiB9PHuBzTvNIQWhxoDgrDlNYA0PYm1SVpvzlqu8mE,4180
|
|
9
|
-
jvserve-2.1.16.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
10
|
-
jvserve-2.1.16.dist-info/METADATA,sha256=NY8quNVWCkDnV-zbXAfRunwL4WQ7PDxvs9JBQziSgW8,4821
|
|
11
|
-
jvserve-2.1.16.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
12
|
-
jvserve-2.1.16.dist-info/entry_points.txt,sha256=HYyg1QXoLs0JRb004L300VeLOZyDLY27ynD1tnTnEN4,35
|
|
13
|
-
jvserve-2.1.16.dist-info/top_level.txt,sha256=afoCXZv-zXNBuhVIvfJGjafXKEiJl_ooy4BtgQwAG4Q,8
|
|
14
|
-
jvserve-2.1.16.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|