jvcli 2.0.31__py3-none-any.whl → 2.1.2__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.
- jvcli/__init__.py +4 -2
- jvcli/cli.py +2 -6
- jvcli/commands/client.py +14 -38
- jvcli/commands/create.py +91 -86
- jvcli/commands/server.py +0 -6
- jvcli/commands/startproject.py +1 -1
- jvcli/templates/{2.0.0 → 2.1.2}/project/README.md +4 -40
- jvcli/templates/{2.0.0 → 2.1.2}/project/actions/README.md +1 -1
- jvcli/templates/{2.0.0 → 2.1.2}/project/daf/README.md +1 -1
- jvcli/templates/{2.0.0 → 2.1.2}/project/env.example +7 -4
- jvcli/templates/2.1.2/project/main.jac +2 -0
- jvcli/templates/2.1.2/sourcefiles/action_app.py +23 -0
- jvcli/templates/2.1.2/sourcefiles/action_archetype.jac +49 -0
- jvcli/templates/{2.0.0 → 2.1.2/sourcefiles}/action_info.yaml +1 -1
- jvcli/templates/2.1.2/sourcefiles/action_lib.jac +3 -0
- jvcli/templates/{2.0.0 → 2.1.2/sourcefiles}/agent_descriptor.yaml +4 -4
- jvcli/templates/2.1.2/sourcefiles/interact_action_archetype.jac +58 -0
- jvcli/utils.py +1 -1
- {jvcli-2.0.31.dist-info → jvcli-2.1.2.dist-info}/METADATA +8 -47
- jvcli-2.1.2.dist-info/RECORD +40 -0
- jvcli/client/__init__.py +0 -1
- jvcli/client/app.py +0 -188
- jvcli/client/lib/__init__.py +0 -1
- jvcli/client/lib/page.py +0 -68
- jvcli/client/lib/utils.py +0 -312
- jvcli/client/lib/widgets.py +0 -295
- jvcli/client/pages/__init__.py +0 -1
- jvcli/client/pages/action_dashboard_page.py +0 -120
- jvcli/client/pages/analytics_page.py +0 -245
- jvcli/client/pages/chat_page.py +0 -150
- jvcli/client/pages/graph_page.py +0 -20
- jvcli/commands/clean.py +0 -29
- jvcli/commands/studio.py +0 -258
- jvcli/studio/assets/index-DDV79SDu.js +0 -213
- jvcli/studio/assets/index-DdMMONxd.css +0 -1
- jvcli/studio/index.html +0 -15
- jvcli/studio/jac_logo.png +0 -0
- jvcli/studio/tauri.svg +0 -6
- jvcli/studio/vite.svg +0 -1
- jvcli/studio-auth/assets/index-Bh6lyeXA.js +0 -218
- jvcli/studio-auth/assets/index-DdMMONxd.css +0 -1
- jvcli/studio-auth/index.html +0 -15
- jvcli/studio-auth/jac_logo.png +0 -0
- jvcli/studio-auth/tauri.svg +0 -6
- jvcli/studio-auth/vite.svg +0 -1
- jvcli/templates/2.0.0/project/main.jac +0 -2
- jvcli-2.0.31.dist-info/RECORD +0 -61
- /jvcli/templates/{2.0.0 → 2.1.2}/project/gitignore.example +0 -0
- /jvcli/templates/{2.0.0 → 2.1.2}/project/globals.jac +0 -0
- /jvcli/templates/{2.0.0 → 2.1.2}/project/tests/README.md +0 -0
- /jvcli/templates/{CHANGELOG.md → 2.1.2/sourcefiles/CHANGELOG.md} +0 -0
- /jvcli/templates/{README.md → 2.1.2/sourcefiles/README.md} +0 -0
- /jvcli/templates/{2.0.0 → 2.1.2/sourcefiles}/agent_info.yaml +0 -0
- /jvcli/templates/{2.0.0 → 2.1.2/sourcefiles}/agent_knowledge.yaml +0 -0
- /jvcli/templates/{2.0.0 → 2.1.2/sourcefiles}/agent_memory.yaml +0 -0
- {jvcli-2.0.31.dist-info → jvcli-2.1.2.dist-info}/WHEEL +0 -0
- {jvcli-2.0.31.dist-info → jvcli-2.1.2.dist-info}/entry_points.txt +0 -0
- {jvcli-2.0.31.dist-info → jvcli-2.1.2.dist-info}/licenses/LICENSE +0 -0
- {jvcli-2.0.31.dist-info → jvcli-2.1.2.dist-info}/top_level.txt +0 -0
jvcli/commands/studio.py
DELETED
@@ -1,258 +0,0 @@
|
|
1
|
-
"""Studio command group for deploying and interfacing with the Jivas Studio."""
|
2
|
-
|
3
|
-
import json
|
4
|
-
from pathlib import Path
|
5
|
-
from typing import Annotated
|
6
|
-
|
7
|
-
import click
|
8
|
-
import jaclang # noqa: F401
|
9
|
-
from bson import ObjectId
|
10
|
-
from fastapi import Depends, FastAPI, HTTPException
|
11
|
-
from fastapi.middleware.cors import CORSMiddleware
|
12
|
-
from fastapi.responses import JSONResponse
|
13
|
-
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
14
|
-
from fastapi.staticfiles import StaticFiles
|
15
|
-
from jac_cloud.core.architype import NodeAnchor
|
16
|
-
from jac_cloud.jaseci.security import decrypt
|
17
|
-
from uvicorn import run
|
18
|
-
|
19
|
-
|
20
|
-
def get_nodes_and_edges(
|
21
|
-
nid: str,
|
22
|
-
current_depth: int,
|
23
|
-
depth: int,
|
24
|
-
nodes: list,
|
25
|
-
edges: list,
|
26
|
-
node_collection: NodeAnchor.Collection,
|
27
|
-
edge_collection: NodeAnchor.Collection,
|
28
|
-
) -> None:
|
29
|
-
"""Get nodes and edges recursively."""
|
30
|
-
if current_depth >= depth:
|
31
|
-
return
|
32
|
-
|
33
|
-
outgoing_edges = edge_collection.find(
|
34
|
-
{
|
35
|
-
"$or": [
|
36
|
-
{"source": nid},
|
37
|
-
{"source": {"$regex": f"{nid}$"}},
|
38
|
-
]
|
39
|
-
}
|
40
|
-
)
|
41
|
-
|
42
|
-
for edge in outgoing_edges:
|
43
|
-
edges.append(
|
44
|
-
{
|
45
|
-
"id": edge["_id"],
|
46
|
-
"name": edge["name"],
|
47
|
-
"source": edge["source"],
|
48
|
-
"target": edge["target"],
|
49
|
-
"data": edge["architype"],
|
50
|
-
}
|
51
|
-
)
|
52
|
-
|
53
|
-
node_id = edge["target"].split(":")[-1]
|
54
|
-
connected_nodes = node_collection.find({"_id": ObjectId(node_id)})
|
55
|
-
|
56
|
-
for node in connected_nodes:
|
57
|
-
nodes.append(
|
58
|
-
{
|
59
|
-
"id": node["_id"],
|
60
|
-
"data": node["architype"],
|
61
|
-
"name": node["name"],
|
62
|
-
}
|
63
|
-
)
|
64
|
-
|
65
|
-
get_nodes_and_edges(
|
66
|
-
node["_id"],
|
67
|
-
current_depth + 1,
|
68
|
-
depth,
|
69
|
-
nodes,
|
70
|
-
edges,
|
71
|
-
node_collection,
|
72
|
-
edge_collection,
|
73
|
-
)
|
74
|
-
|
75
|
-
|
76
|
-
# need this because endpoint annotation differs depending on require auth flag
|
77
|
-
class EndpointFactory:
|
78
|
-
"""Factory for creating endpoints based on require_auth flag."""
|
79
|
-
|
80
|
-
@staticmethod
|
81
|
-
def create_endpoints(require_auth: bool, security: HTTPBearer | None) -> tuple:
|
82
|
-
"""Create endpoints based on require_auth flag."""
|
83
|
-
|
84
|
-
def validate_auth(credentials: HTTPAuthorizationCredentials) -> None:
|
85
|
-
"""Validate authentication token."""
|
86
|
-
token = credentials.credentials
|
87
|
-
if not token or not decrypt(token):
|
88
|
-
raise HTTPException(status_code=401, detail="Invalid token")
|
89
|
-
|
90
|
-
def get_graph_data(root: str) -> dict:
|
91
|
-
"""Get graph nodes and edges data."""
|
92
|
-
edge_collection = NodeAnchor.Collection.get_collection("edge")
|
93
|
-
node_collection = NodeAnchor.Collection.get_collection("node")
|
94
|
-
|
95
|
-
nodes = [
|
96
|
-
{
|
97
|
-
"id": node["_id"],
|
98
|
-
"data": node["architype"],
|
99
|
-
"name": node["name"],
|
100
|
-
}
|
101
|
-
for node in node_collection.find({"root": ObjectId(root)})
|
102
|
-
]
|
103
|
-
|
104
|
-
edges = [
|
105
|
-
{
|
106
|
-
"id": edge["_id"],
|
107
|
-
"name": edge["name"],
|
108
|
-
"source": edge["source"],
|
109
|
-
"target": edge["target"],
|
110
|
-
"data": edge["architype"],
|
111
|
-
}
|
112
|
-
for edge in edge_collection.find({"root": ObjectId(root)})
|
113
|
-
]
|
114
|
-
|
115
|
-
return {"nodes": nodes, "edges": edges}
|
116
|
-
|
117
|
-
def get_users_data() -> list:
|
118
|
-
"""Get users data."""
|
119
|
-
user_collection = NodeAnchor.Collection.get_collection("user")
|
120
|
-
return [
|
121
|
-
{
|
122
|
-
"id": user["_id"],
|
123
|
-
"root_id": user["root_id"],
|
124
|
-
"email": user["email"],
|
125
|
-
}
|
126
|
-
for user in user_collection.find()
|
127
|
-
]
|
128
|
-
|
129
|
-
def get_node_connections(node_id: str, depth: int) -> dict:
|
130
|
-
nid = node_id.split(":")[-1]
|
131
|
-
current_depth = 0
|
132
|
-
nodes: list = []
|
133
|
-
edges: list = []
|
134
|
-
|
135
|
-
edge_collection = NodeAnchor.Collection.get_collection("edge")
|
136
|
-
node_collection = NodeAnchor.Collection.get_collection("node")
|
137
|
-
|
138
|
-
get_nodes_and_edges(
|
139
|
-
nid,
|
140
|
-
current_depth,
|
141
|
-
depth,
|
142
|
-
nodes,
|
143
|
-
edges,
|
144
|
-
node_collection,
|
145
|
-
edge_collection,
|
146
|
-
)
|
147
|
-
|
148
|
-
return {"nodes": nodes, "edges": edges}
|
149
|
-
|
150
|
-
if not require_auth:
|
151
|
-
|
152
|
-
async def graph_endpoint(root: str) -> JSONResponse:
|
153
|
-
return JSONResponse(
|
154
|
-
content=json.loads(json.dumps(get_graph_data(root), default=str))
|
155
|
-
)
|
156
|
-
|
157
|
-
async def users_endpoint() -> JSONResponse:
|
158
|
-
return JSONResponse(
|
159
|
-
content=json.loads(json.dumps(get_users_data(), default=str))
|
160
|
-
)
|
161
|
-
|
162
|
-
async def node_endpoint(node_id: str, depth: int) -> JSONResponse:
|
163
|
-
return JSONResponse(
|
164
|
-
content=json.loads(
|
165
|
-
json.dumps(get_node_connections(node_id, depth), default=str)
|
166
|
-
)
|
167
|
-
)
|
168
|
-
|
169
|
-
return graph_endpoint, users_endpoint, node_endpoint
|
170
|
-
|
171
|
-
else:
|
172
|
-
|
173
|
-
async def guarded_graph_endpoint(
|
174
|
-
root: str,
|
175
|
-
credentials: Annotated[HTTPAuthorizationCredentials, Depends(security)],
|
176
|
-
) -> JSONResponse:
|
177
|
-
validate_auth(credentials)
|
178
|
-
return JSONResponse(
|
179
|
-
content=json.loads(json.dumps(get_graph_data(root), default=str))
|
180
|
-
)
|
181
|
-
|
182
|
-
async def guarded_users_endpoint(
|
183
|
-
credentials: Annotated[HTTPAuthorizationCredentials, Depends(security)],
|
184
|
-
) -> JSONResponse:
|
185
|
-
validate_auth(credentials)
|
186
|
-
return JSONResponse(
|
187
|
-
content=json.loads(json.dumps(get_users_data(), default=str))
|
188
|
-
)
|
189
|
-
|
190
|
-
async def guarded_node_endpoint(
|
191
|
-
node_id: str,
|
192
|
-
depth: int,
|
193
|
-
credentials: Annotated[HTTPAuthorizationCredentials, Depends(security)],
|
194
|
-
) -> JSONResponse:
|
195
|
-
validate_auth(credentials)
|
196
|
-
return JSONResponse(
|
197
|
-
content=json.loads(
|
198
|
-
json.dumps(get_node_connections(node_id, depth), default=str)
|
199
|
-
)
|
200
|
-
)
|
201
|
-
|
202
|
-
return guarded_graph_endpoint, guarded_users_endpoint, guarded_node_endpoint
|
203
|
-
|
204
|
-
|
205
|
-
@click.group()
|
206
|
-
def studio() -> None:
|
207
|
-
"""Group for managing Jivas Studio resources."""
|
208
|
-
pass # pragma: no cover
|
209
|
-
|
210
|
-
|
211
|
-
@studio.command()
|
212
|
-
@click.option("--port", default=8989, help="Port for the studio to launch on.")
|
213
|
-
@click.option(
|
214
|
-
"--require-auth", default=False, help="Require authentication for studio api."
|
215
|
-
)
|
216
|
-
def launch(port: int, require_auth: bool) -> None:
|
217
|
-
"""Launch the Jivas Studio on the specified port."""
|
218
|
-
click.echo(f"Launching Jivas Studio on port {port}...")
|
219
|
-
|
220
|
-
security = HTTPBearer() if require_auth else None
|
221
|
-
|
222
|
-
get_graph, get_users, get_node = EndpointFactory.create_endpoints(
|
223
|
-
require_auth, security
|
224
|
-
)
|
225
|
-
|
226
|
-
app = FastAPI(title="Jivas Studio API")
|
227
|
-
|
228
|
-
app.add_middleware(
|
229
|
-
CORSMiddleware,
|
230
|
-
allow_origins=["*"],
|
231
|
-
allow_credentials=True,
|
232
|
-
allow_methods=["*"],
|
233
|
-
allow_headers=["*"],
|
234
|
-
)
|
235
|
-
|
236
|
-
app.add_api_route("/graph", endpoint=get_graph, methods=["GET"])
|
237
|
-
app.add_api_route("/users", endpoint=get_users, methods=["GET"])
|
238
|
-
app.add_api_route("/graph/node", endpoint=get_node, methods=["GET"])
|
239
|
-
|
240
|
-
client_dir = (
|
241
|
-
Path(__file__)
|
242
|
-
.resolve()
|
243
|
-
.parent.parent.joinpath("studio-auth" if require_auth else "studio")
|
244
|
-
)
|
245
|
-
|
246
|
-
app.mount(
|
247
|
-
"/",
|
248
|
-
StaticFiles(directory=client_dir, html=True),
|
249
|
-
name="studio",
|
250
|
-
)
|
251
|
-
|
252
|
-
app.mount(
|
253
|
-
"/graph",
|
254
|
-
StaticFiles(directory=client_dir, html=True),
|
255
|
-
name="studio_graph",
|
256
|
-
)
|
257
|
-
|
258
|
-
run(app, host="0.0.0.0", port=port)
|