jvcli 2.0.16__py3-none-any.whl → 2.0.17__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 +1 -1
- jvcli/client/app.py +15 -8
- jvcli/client/lib/utils.py +146 -171
- jvcli/client/pages/{dashboard_page.py → action_dashboard_page.py} +5 -4
- jvcli/client/pages/analytics_page.py +73 -7
- jvcli/client/pages/chat_page.py +3 -3
- jvcli/commands/client.py +2 -2
- jvcli/commands/create.py +1 -1
- jvcli/commands/download.py +1 -1
- jvcli/templates/2.0.0/project/daf/README.md +1 -1
- jvcli/templates/2.0.0/project/env.example +5 -1
- jvcli/templates/2.0.0/project/gitignore.example +2 -1
- jvcli/templates/2.0.0/project/sh/initagents.sh +3 -0
- jvcli/templates/2.0.0/project/sh/jacclean.sh +11 -0
- {jvcli-2.0.16.dist-info → jvcli-2.0.17.dist-info}/METADATA +1 -1
- {jvcli-2.0.16.dist-info → jvcli-2.0.17.dist-info}/RECORD +20 -19
- {jvcli-2.0.16.dist-info → jvcli-2.0.17.dist-info}/WHEEL +0 -0
- {jvcli-2.0.16.dist-info → jvcli-2.0.17.dist-info}/entry_points.txt +0 -0
- {jvcli-2.0.16.dist-info → jvcli-2.0.17.dist-info}/licenses/LICENSE +0 -0
- {jvcli-2.0.16.dist-info → jvcli-2.0.17.dist-info}/top_level.txt +0 -0
jvcli/__init__.py
CHANGED
jvcli/client/app.py
CHANGED
@@ -8,10 +8,14 @@ from streamlit_router import StreamlitRouter
|
|
8
8
|
|
9
9
|
from jvcli.client.lib.page import Page
|
10
10
|
from jvcli.client.lib.utils import call_list_actions, call_list_agents, load_function
|
11
|
-
from jvcli.client.pages import
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
from jvcli.client.pages import (
|
12
|
+
action_dashboard_page,
|
13
|
+
analytics_page,
|
14
|
+
chat_page,
|
15
|
+
graph_page,
|
16
|
+
)
|
17
|
+
|
18
|
+
JIVAS_BASE_URL = os.environ.get("JIVAS_BASE_URL", "http://localhost:8000")
|
15
19
|
JIVAS_STUDIO_URL = os.environ.get("JIVAS_STUDIO_URL", "http://localhost:8989")
|
16
20
|
|
17
21
|
|
@@ -24,7 +28,7 @@ def handle_agent_selection() -> None:
|
|
24
28
|
|
25
29
|
def login_form() -> None:
|
26
30
|
"""Render the login form and handle login logic."""
|
27
|
-
login_url = f"{
|
31
|
+
login_url = f"{JIVAS_BASE_URL}/user/login"
|
28
32
|
|
29
33
|
if os.environ.get("JIVAS_ENVIRONMENT") == "development":
|
30
34
|
email = os.environ.get("JIVAS_USER", "admin@jivas.com")
|
@@ -67,7 +71,6 @@ def main() -> None:
|
|
67
71
|
for key in [
|
68
72
|
"messages",
|
69
73
|
"session_id",
|
70
|
-
"EXPIRATION",
|
71
74
|
"agents",
|
72
75
|
"actions_data",
|
73
76
|
"TOKEN",
|
@@ -127,10 +130,14 @@ def main() -> None:
|
|
127
130
|
with st.expander("Menu", True):
|
128
131
|
Page(router).item(analytics_page.render, "Dashboard", "/").st_button()
|
129
132
|
Page(router).item(chat_page.render, "Chat", "/chat").st_button()
|
130
|
-
Page(router).item(
|
133
|
+
Page(router).item(
|
134
|
+
action_dashboard_page.render, "Actions", "/actions"
|
135
|
+
).st_button()
|
131
136
|
Page(router).item(graph_page.render, "Graph", "/graph").st_button()
|
132
137
|
st.button(
|
133
|
-
"Logout",
|
138
|
+
"Logout",
|
139
|
+
on_click=action_dashboard_page.logout,
|
140
|
+
use_container_width=True,
|
134
141
|
)
|
135
142
|
|
136
143
|
with st.expander("Action Apps", False):
|
jvcli/client/lib/utils.py
CHANGED
@@ -12,7 +12,7 @@ import streamlit as st
|
|
12
12
|
import yaml
|
13
13
|
from PIL import Image
|
14
14
|
|
15
|
-
|
15
|
+
JIVAS_BASE_URL = os.environ.get("JIVAS_BASE_URL", "http://localhost:8000")
|
16
16
|
|
17
17
|
|
18
18
|
def load_function(file_path: str, function_name: str, **kwargs: Any) -> Callable:
|
@@ -50,227 +50,202 @@ def load_function(file_path: str, function_name: str, **kwargs: Any) -> Callable
|
|
50
50
|
return wrapped_func
|
51
51
|
|
52
52
|
|
53
|
-
def
|
54
|
-
|
53
|
+
def call_api(
|
54
|
+
endpoint: str,
|
55
|
+
method: str = "POST",
|
56
|
+
headers: Optional[Dict] = None,
|
57
|
+
json_data: Optional[Dict] = None,
|
58
|
+
files: Optional[List] = None,
|
59
|
+
data: Optional[Dict] = None,
|
60
|
+
) -> Optional[requests.Response]:
|
61
|
+
"""Generic function to call an API endpoint."""
|
55
62
|
|
56
|
-
|
63
|
+
if not endpoint.startswith("http"):
|
64
|
+
endpoint = f"{JIVAS_BASE_URL}/{endpoint}"
|
57
65
|
|
58
|
-
|
66
|
+
ctx = get_user_info() # Assumes a function that fetches user info
|
59
67
|
|
60
|
-
if ctx
|
68
|
+
if ctx.get("token"):
|
61
69
|
try:
|
62
|
-
headers =
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
]
|
70
|
+
headers = headers or {}
|
71
|
+
headers["Authorization"] = f"Bearer {ctx['token']}"
|
72
|
+
|
73
|
+
response = requests.request(
|
74
|
+
method=method,
|
75
|
+
url=endpoint,
|
76
|
+
headers=headers,
|
77
|
+
json=json_data,
|
78
|
+
files=files,
|
79
|
+
data=data,
|
80
|
+
)
|
74
81
|
|
75
82
|
if response.status_code == 401:
|
76
83
|
st.session_state.EXPIRATION = ""
|
77
|
-
return
|
84
|
+
return None
|
85
|
+
|
86
|
+
return response
|
78
87
|
|
79
88
|
except Exception as e:
|
80
89
|
st.session_state.EXPIRATION = ""
|
81
|
-
|
90
|
+
st.write(e)
|
82
91
|
|
83
|
-
return
|
92
|
+
return None
|
84
93
|
|
85
94
|
|
86
|
-
def
|
87
|
-
|
95
|
+
def call_action_walker_exec(
|
96
|
+
agent_id: str,
|
97
|
+
module_root: str,
|
98
|
+
walker: str,
|
99
|
+
args: Optional[Dict] = None,
|
100
|
+
files: Optional[List] = None,
|
101
|
+
headers: Optional[Dict] = None,
|
102
|
+
) -> list:
|
103
|
+
"""Call the API to execute a walker action for a given agent."""
|
88
104
|
|
89
|
-
|
105
|
+
endpoint = f"{JIVAS_BASE_URL}/action/walker"
|
90
106
|
|
91
|
-
|
107
|
+
# Create form data
|
108
|
+
data = {"agent_id": agent_id, "module_root": module_root, "walker": walker}
|
92
109
|
|
93
|
-
if
|
94
|
-
|
95
|
-
headers = {"Authorization": "Bearer " + ctx["token"]}
|
96
|
-
json = {"agent_id": agent_id}
|
110
|
+
if args:
|
111
|
+
data["args"] = json.dumps(args)
|
97
112
|
|
98
|
-
|
99
|
-
response = requests.post(endpoint, json=json, headers=headers)
|
113
|
+
file_list = []
|
100
114
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
return result[0]
|
105
|
-
else:
|
106
|
-
return []
|
115
|
+
if files:
|
116
|
+
for file in files:
|
117
|
+
file_list.append(("attachments", (file[0], file[1], file[2])))
|
107
118
|
|
108
|
-
|
109
|
-
st.session_state.EXPIRATION = ""
|
110
|
-
return []
|
119
|
+
response = call_api(endpoint, headers=headers, data=data, files=file_list)
|
111
120
|
|
112
|
-
|
113
|
-
|
114
|
-
|
121
|
+
if response and response.status_code == 200:
|
122
|
+
result = response.json()
|
123
|
+
return result if result else []
|
115
124
|
|
116
125
|
return []
|
117
126
|
|
118
127
|
|
119
|
-
def
|
120
|
-
"""Call the API to
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
endpoint = f"{JIVAS_URL}/walker/get_action"
|
128
|
+
def call_healthcheck(agent_id: str, headers: Optional[Dict] = None) -> Optional[dict]:
|
129
|
+
"""Call the API to check the health of an agent."""
|
130
|
+
endpoint = "walker/healthcheck"
|
131
|
+
json_data = {"agent_id": agent_id}
|
132
|
+
response = call_api(endpoint, headers=headers, json_data=json_data)
|
125
133
|
|
126
|
-
if
|
127
|
-
|
128
|
-
|
129
|
-
|
134
|
+
if response and response.status_code in [200, 501, 503]:
|
135
|
+
result = response.json()
|
136
|
+
reports = result.get("reports", [])
|
137
|
+
return reports[0] if reports else {}
|
130
138
|
|
131
|
-
|
132
|
-
response = requests.post(endpoint, json=json, headers=headers)
|
139
|
+
return {}
|
133
140
|
|
134
|
-
if response.status_code == 200:
|
135
|
-
result = (response.json()).get("reports", [])
|
136
|
-
if len(result) > 0:
|
137
|
-
return result[0]
|
138
|
-
else:
|
139
|
-
return []
|
140
141
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
142
|
+
def call_list_agents(headers: Optional[Dict] = None) -> list:
|
143
|
+
"""Call the API to list agents."""
|
144
|
+
endpoint = "walker/list_agents"
|
145
|
+
json_data = {"reporting": True}
|
146
|
+
response = call_api(endpoint, headers=headers, json_data=json_data)
|
147
|
+
|
148
|
+
if response and response.status_code == 200:
|
149
|
+
result = response.json()
|
150
|
+
reports = result.get("reports", [])
|
151
|
+
return [
|
152
|
+
{"id": agent.get("id", ""), "label": agent.get("name", "")}
|
153
|
+
for agent in reports
|
154
|
+
]
|
148
155
|
|
149
156
|
return []
|
150
157
|
|
151
158
|
|
152
|
-
def
|
153
|
-
"""Call the API to
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
endpoint = f"{JIVAS_URL}/walker/update_action"
|
159
|
+
def call_get_agent(agent_id: str, headers: Optional[Dict] = None) -> dict:
|
160
|
+
"""Call the API to get details of a specific agent."""
|
161
|
+
endpoint = "walker/get_agent"
|
162
|
+
json_data = {"agent_id": agent_id}
|
163
|
+
response = call_api(endpoint, headers=headers, json_data=json_data)
|
158
164
|
|
159
|
-
if
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
"agent_id": agent_id,
|
164
|
-
"action_id": action_id,
|
165
|
-
"action_data": action_data,
|
166
|
-
}
|
167
|
-
|
168
|
-
# call interact
|
169
|
-
response = requests.post(endpoint, json=json, headers=headers)
|
170
|
-
|
171
|
-
if response.status_code == 200:
|
172
|
-
result = (response.json()).get("reports", [])
|
173
|
-
if len(result) > 0:
|
174
|
-
return result[0]
|
175
|
-
else:
|
176
|
-
return {}
|
177
|
-
|
178
|
-
if response.status_code == 401:
|
179
|
-
st.session_state.EXPIRATION = ""
|
180
|
-
return {}
|
181
|
-
|
182
|
-
except Exception as e:
|
183
|
-
st.session_state.EXPIRATION = ""
|
184
|
-
print("Exception occurred: ", e)
|
165
|
+
if response and response.status_code == 200:
|
166
|
+
result = response.json()
|
167
|
+
reports = result.get("reports", [])
|
168
|
+
return reports[0] if reports else {}
|
185
169
|
|
186
170
|
return {}
|
187
171
|
|
188
172
|
|
189
|
-
def
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
files: Optional[List] = None,
|
195
|
-
headers: Optional[Dict] = None,
|
196
|
-
) -> list:
|
197
|
-
"""Call the API to execute a walker action for a given agent."""
|
198
|
-
|
199
|
-
ctx = get_user_info()
|
200
|
-
|
201
|
-
endpoint = f"{JIVAS_URL}/action/walker"
|
202
|
-
|
203
|
-
if ctx.get("token"):
|
204
|
-
try:
|
205
|
-
headers = headers if headers else {}
|
206
|
-
headers["Authorization"] = "Bearer " + ctx["token"]
|
207
|
-
|
208
|
-
# Create form data
|
209
|
-
data = {"agent_id": agent_id, "module_root": module_root, "walker": walker}
|
210
|
-
|
211
|
-
if args:
|
212
|
-
data["args"] = json.dumps(args)
|
173
|
+
def call_list_actions(agent_id: str, headers: Optional[Dict] = None) -> list:
|
174
|
+
"""Call the API to list actions for a given agent."""
|
175
|
+
endpoint = "walker/list_actions"
|
176
|
+
json_data = {"agent_id": agent_id}
|
177
|
+
response = call_api(endpoint, headers=headers, json_data=json_data)
|
213
178
|
|
214
|
-
|
179
|
+
if response and response.status_code == 200:
|
180
|
+
result = response.json()
|
181
|
+
reports = result.get("reports", [])
|
182
|
+
return reports[0] if reports else []
|
215
183
|
|
216
|
-
|
184
|
+
return []
|
217
185
|
|
218
|
-
for file in files:
|
219
|
-
file_list.append(("attachments", (file[0], file[1], file[2])))
|
220
186
|
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
return result if result else []
|
187
|
+
def call_get_action(
|
188
|
+
agent_id: str, action_id: str, headers: Optional[Dict] = None
|
189
|
+
) -> dict:
|
190
|
+
"""Call the API to get a specific action for a given agent."""
|
191
|
+
endpoint = "walker/get_action"
|
192
|
+
json_data = {"agent_id": agent_id, "action_id": action_id}
|
193
|
+
response = call_api(endpoint, headers=headers, json_data=json_data)
|
229
194
|
|
230
|
-
|
231
|
-
|
232
|
-
|
195
|
+
if response and response.status_code == 200:
|
196
|
+
result = response.json()
|
197
|
+
reports = result.get("reports", [])
|
198
|
+
return reports[0] if reports else {}
|
233
199
|
|
234
|
-
|
235
|
-
st.session_state.EXPIRATION = ""
|
236
|
-
st.write(e)
|
200
|
+
return {}
|
237
201
|
|
238
|
-
return []
|
239
202
|
|
203
|
+
def call_update_action(
|
204
|
+
agent_id: str, action_id: str, action_data: dict, headers: Optional[Dict] = None
|
205
|
+
) -> dict:
|
206
|
+
"""Call the API to update a specific action for a given agent."""
|
207
|
+
endpoint = "walker/update_action"
|
208
|
+
json_data = {
|
209
|
+
"agent_id": agent_id,
|
210
|
+
"action_id": action_id,
|
211
|
+
"action_data": action_data,
|
212
|
+
}
|
213
|
+
response = call_api(endpoint, headers=headers, json_data=json_data)
|
240
214
|
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
"""Call the API to import an agent."""
|
215
|
+
if response and response.status_code == 200:
|
216
|
+
result = response.json()
|
217
|
+
reports = result.get("reports", [])
|
218
|
+
return reports[0] if reports else {}
|
246
219
|
|
247
|
-
|
220
|
+
return {}
|
248
221
|
|
249
|
-
endpoint = f"{JIVAS_URL}/walker/import_agent"
|
250
222
|
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
223
|
+
def call_update_agent(
|
224
|
+
agent_id: str, agent_data: dict, headers: Optional[Dict] = None
|
225
|
+
) -> dict:
|
226
|
+
"""Call the API to update a specific agent."""
|
227
|
+
endpoint = "walker/update_agent"
|
228
|
+
json_data = {"agent_id": agent_id, "agent_data": agent_data}
|
229
|
+
response = call_api(endpoint, headers=headers, json_data=json_data)
|
257
230
|
|
258
|
-
|
231
|
+
if response and response.status_code == 200:
|
232
|
+
result = response.json()
|
233
|
+
reports = result.get("reports", [])
|
234
|
+
return reports[0] if reports else {}
|
259
235
|
|
260
|
-
|
261
|
-
response = requests.post(endpoint, headers=headers, json=data)
|
236
|
+
return {}
|
262
237
|
|
263
|
-
if response.status_code == 200:
|
264
|
-
result = response.json()
|
265
|
-
return result if result else []
|
266
238
|
|
267
|
-
|
268
|
-
|
269
|
-
|
239
|
+
def call_import_agent(descriptor: str, headers: Optional[Dict] = None) -> list:
|
240
|
+
"""Call the API to import an agent."""
|
241
|
+
endpoint = "walker/import_agent"
|
242
|
+
json_data = {"descriptor": descriptor}
|
243
|
+
response = call_api(endpoint, headers=headers, json_data=json_data)
|
270
244
|
|
271
|
-
|
272
|
-
|
273
|
-
|
245
|
+
if response and response.status_code == 200:
|
246
|
+
result = response.json()
|
247
|
+
reports = result.get("reports", [])
|
248
|
+
return reports[0] if reports else []
|
274
249
|
|
275
250
|
return []
|
276
251
|
|
@@ -278,9 +253,9 @@ def call_import_agent(
|
|
278
253
|
def get_user_info() -> dict:
|
279
254
|
"""Get user information from the session state."""
|
280
255
|
return {
|
281
|
-
"root_id": st.session_state.ROOT_ID,
|
282
|
-
"token": st.session_state.TOKEN,
|
283
|
-
"expiration": st.session_state.EXPIRATION,
|
256
|
+
"root_id": st.session_state.get("ROOT_ID", ""),
|
257
|
+
"token": st.session_state.get("TOKEN", ""),
|
258
|
+
"expiration": st.session_state.get("EXPIRATION", ""),
|
284
259
|
}
|
285
260
|
|
286
261
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
"""Render the
|
1
|
+
"""Render the action_dashboard page of the jvclient with actions data."""
|
2
2
|
|
3
3
|
import streamlit as st
|
4
4
|
from streamlit_elements import dashboard, elements, mui
|
@@ -10,7 +10,7 @@ from jvcli.client.lib.page import Page
|
|
10
10
|
def render(router: StreamlitRouter) -> None:
|
11
11
|
"""Render the dashboard page."""
|
12
12
|
if actions_data := st.session_state.get("actions_data"):
|
13
|
-
with elements("
|
13
|
+
with elements("action_dashboard"):
|
14
14
|
columns = 4
|
15
15
|
layout = []
|
16
16
|
|
@@ -20,7 +20,7 @@ def render(router: StreamlitRouter) -> None:
|
|
20
20
|
y = (idx // columns) * 2
|
21
21
|
width = 3
|
22
22
|
height = 2
|
23
|
-
# Add an item to the
|
23
|
+
# Add an item to the action_dashboard manually without using `with` if it's not a context manager
|
24
24
|
layout.append(
|
25
25
|
dashboard.Item(
|
26
26
|
f"card_{idx}",
|
@@ -36,10 +36,11 @@ def render(router: StreamlitRouter) -> None:
|
|
36
36
|
# now populate the actual cards with content
|
37
37
|
with dashboard.Grid(layout):
|
38
38
|
for idx, action in enumerate(actions_data):
|
39
|
+
|
39
40
|
package = action.get("_package", {})
|
40
41
|
title = package.get("meta", {}).get("title", action.get("label"))
|
41
42
|
description = action.get("description", "")
|
42
|
-
version =
|
43
|
+
version = package.get("version", "0.0.0")
|
43
44
|
action_type = package.get("meta", {}).get("type", "action")
|
44
45
|
key = Page.normalize_label(title)
|
45
46
|
enabled_color = "red"
|
@@ -3,6 +3,7 @@
|
|
3
3
|
import calendar
|
4
4
|
import datetime
|
5
5
|
import os
|
6
|
+
from typing import Optional
|
6
7
|
|
7
8
|
import pandas as pd
|
8
9
|
import requests
|
@@ -11,14 +12,79 @@ from streamlit.delta_generator import DeltaGenerator
|
|
11
12
|
from streamlit_javascript import st_javascript
|
12
13
|
from streamlit_router import StreamlitRouter
|
13
14
|
|
14
|
-
from jvcli.client.lib.utils import get_user_info
|
15
|
+
from jvcli.client.lib.utils import call_healthcheck, get_user_info
|
15
16
|
|
16
|
-
|
17
|
+
JIVAS_BASE_URL = os.environ.get("JIVAS_BASE_URL", "http://localhost:8000")
|
17
18
|
|
18
19
|
|
19
20
|
def render(router: StreamlitRouter) -> None:
|
20
21
|
"""Render the analytics page."""
|
21
|
-
|
22
|
+
|
23
|
+
selected_agent = st.session_state.get("selected_agent")
|
24
|
+
|
25
|
+
# Call the healthcheck endpoint and render the collapsible section
|
26
|
+
@st.cache_data(show_spinner=True)
|
27
|
+
def fetch_healthcheck(agent_id: str) -> Optional[dict]:
|
28
|
+
return call_healthcheck(agent_id)
|
29
|
+
|
30
|
+
health_data = None
|
31
|
+
|
32
|
+
if selected_agent:
|
33
|
+
# Clear the cache and fetch fresh data if the button is clicked
|
34
|
+
if st.session_state.get("recheck_health_clicked", False):
|
35
|
+
fetch_healthcheck.clear()
|
36
|
+
health_data = call_healthcheck(selected_agent["id"])
|
37
|
+
st.session_state["recheck_health_clicked"] = False
|
38
|
+
else:
|
39
|
+
# Use cached data
|
40
|
+
health_data = fetch_healthcheck(selected_agent["id"])
|
41
|
+
|
42
|
+
try:
|
43
|
+
if health_data:
|
44
|
+
trace = health_data.get("trace", {})
|
45
|
+
errors = [
|
46
|
+
f"{key}: {value['message']}"
|
47
|
+
for key, value in trace.items()
|
48
|
+
if value.get("severity") == "error"
|
49
|
+
]
|
50
|
+
warnings = [
|
51
|
+
f"{key}: {value['message']}"
|
52
|
+
for key, value in trace.items()
|
53
|
+
if value.get("severity") == "warning"
|
54
|
+
]
|
55
|
+
|
56
|
+
if errors:
|
57
|
+
section_label = "Agent health needs ATTENTION!"
|
58
|
+
section_color = "red"
|
59
|
+
expanded = True
|
60
|
+
elif warnings:
|
61
|
+
section_label = "Agent health is OK (with warnings)"
|
62
|
+
section_color = "orange"
|
63
|
+
expanded = True
|
64
|
+
else:
|
65
|
+
section_label = "Agent health is OK"
|
66
|
+
section_color = "green"
|
67
|
+
expanded = False
|
68
|
+
|
69
|
+
with st.expander(
|
70
|
+
f":{section_color}[{section_label}]", expanded=expanded
|
71
|
+
):
|
72
|
+
if errors:
|
73
|
+
st.error("Errors")
|
74
|
+
for error in errors:
|
75
|
+
st.text(f"- {error}")
|
76
|
+
if warnings:
|
77
|
+
st.warning("Warnings")
|
78
|
+
for warning in warnings:
|
79
|
+
st.text(f"- {warning}")
|
80
|
+
if st.button("Recheck Health", key="recheck_inside_expander"):
|
81
|
+
st.session_state["recheck_health_clicked"] = True
|
82
|
+
|
83
|
+
else:
|
84
|
+
st.error("Failed to fetch healthcheck data.")
|
85
|
+
except Exception as e:
|
86
|
+
st.error("An error occurred while fetching healthcheck data.")
|
87
|
+
print(e)
|
22
88
|
|
23
89
|
st.header("Analytics", divider=True)
|
24
90
|
today = datetime.date.today()
|
@@ -45,7 +111,7 @@ def render(router: StreamlitRouter) -> None:
|
|
45
111
|
)
|
46
112
|
|
47
113
|
try:
|
48
|
-
|
114
|
+
ctx = get_user_info()
|
49
115
|
if selected_agent and end_date > start_date:
|
50
116
|
interactions_chart(
|
51
117
|
token=ctx["token"],
|
@@ -87,7 +153,7 @@ def interactions_chart(
|
|
87
153
|
timezone: str,
|
88
154
|
) -> None:
|
89
155
|
"""Render the interactions chart."""
|
90
|
-
url = f"{
|
156
|
+
url = f"{JIVAS_BASE_URL}/walker/get_interactions_by_date"
|
91
157
|
|
92
158
|
with st.container(border=True):
|
93
159
|
st.subheader("Interactions by Date")
|
@@ -121,7 +187,7 @@ def users_chart(
|
|
121
187
|
timezone: str,
|
122
188
|
) -> None:
|
123
189
|
"""Render the users chart."""
|
124
|
-
url = f"{
|
190
|
+
url = f"{JIVAS_BASE_URL}/walker/get_users_by_date"
|
125
191
|
with st.container(border=True):
|
126
192
|
st.subheader("Users by Date")
|
127
193
|
response = requests.post(
|
@@ -154,7 +220,7 @@ def channels_chart(
|
|
154
220
|
timezone: str,
|
155
221
|
) -> None:
|
156
222
|
"""Render the channels chart."""
|
157
|
-
url = f"{
|
223
|
+
url = f"{JIVAS_BASE_URL}/walker/get_channels_by_date"
|
158
224
|
with st.container(border=True):
|
159
225
|
st.subheader("Channels by Date")
|
160
226
|
response = requests.post(
|
jvcli/client/pages/chat_page.py
CHANGED
@@ -9,12 +9,12 @@ from streamlit_router import StreamlitRouter
|
|
9
9
|
|
10
10
|
from jvcli.client.lib.utils import get_user_info
|
11
11
|
|
12
|
-
|
12
|
+
JIVAS_BASE_URL = os.environ.get("JIVAS_BASE_URL", "http://localhost:8000")
|
13
13
|
|
14
14
|
|
15
15
|
def transcribe_audio(token: str, agent_id: str, file: bytes) -> dict:
|
16
16
|
"""Transcribe audio using the walker API."""
|
17
|
-
action_walker_url = f"{
|
17
|
+
action_walker_url = f"{JIVAS_BASE_URL}/action/walker"
|
18
18
|
|
19
19
|
# Create form data
|
20
20
|
files = {"attachments": ("audio.wav", file, "audio/wav")}
|
@@ -41,7 +41,7 @@ def transcribe_audio(token: str, agent_id: str, file: bytes) -> dict:
|
|
41
41
|
|
42
42
|
def render(router: StreamlitRouter) -> None:
|
43
43
|
"""Render the chat page."""
|
44
|
-
url = f"{
|
44
|
+
url = f"{JIVAS_BASE_URL}/interact"
|
45
45
|
ctx = get_user_info()
|
46
46
|
|
47
47
|
st.header("Chat", divider=True)
|
jvcli/commands/client.py
CHANGED
@@ -17,7 +17,7 @@ def client() -> None:
|
|
17
17
|
@click.option("--port", default=8501, help="Port for the client to launch on.")
|
18
18
|
@click.option(
|
19
19
|
"--jivas_url",
|
20
|
-
default=os.environ.get("
|
20
|
+
default=os.environ.get("JIVAS_BASE_URL", "http://localhost:8000"),
|
21
21
|
help="URL for the Jivas API.",
|
22
22
|
)
|
23
23
|
@click.option(
|
@@ -30,7 +30,7 @@ def launch(port: int, jivas_url: str, studio_url: str) -> None:
|
|
30
30
|
click.echo(
|
31
31
|
f"Launching Jivas Client on port {port}, loading action apps from {jivas_url}..."
|
32
32
|
)
|
33
|
-
os.environ["
|
33
|
+
os.environ["JIVAS_BASE_URL"] = jivas_url
|
34
34
|
os.environ["JIVAS_STUDIO_URL"] = studio_url
|
35
35
|
subprocess.call(
|
36
36
|
[
|
jvcli/commands/create.py
CHANGED
jvcli/commands/download.py
CHANGED
@@ -87,7 +87,7 @@ def _download_package(name: str, version: str, path: str, pkg_type: str) -> None
|
|
87
87
|
|
88
88
|
# checking for both daf and agent to maintain backward compatibility
|
89
89
|
if pkg_type == "agent" and package_type in ["agent", "daf"]:
|
90
|
-
base_dir = "
|
90
|
+
base_dir = "daf"
|
91
91
|
elif pkg_type == "action" and package_type.endswith("action"):
|
92
92
|
base_dir = "actions"
|
93
93
|
else:
|
@@ -21,7 +21,7 @@ To create a new DAF package using `jvcli`, follow these steps:
|
|
21
21
|
2. **Options**: You can customize the creation process with various options:
|
22
22
|
- `--version`: Specify the version of the agent. Default is `0.0.1`.
|
23
23
|
- `--jivas_version`: Specify the version of Jivas. Default is `2.0.0`.
|
24
|
-
- `--path`: Directory to create the agent folder in. Default is `./
|
24
|
+
- `--path`: Directory to create the agent folder in. Default is `./daf`.
|
25
25
|
- `--namespace`: Namespace for the agent. Defaults to the username in the token.
|
26
26
|
|
27
27
|
3. **Example**:
|
@@ -35,4 +35,8 @@ TOKEN_SECRET=s3cr3t
|
|
35
35
|
# TYPESENSE_PORT=8108
|
36
36
|
# TYPESENSE_PROTOCOL=http
|
37
37
|
# TYPESENSE_API_KEY=abcd
|
38
|
-
# TYPESENSE_CONNECTION_TIMEOUT_SECONDS=2
|
38
|
+
# TYPESENSE_CONNECTION_TIMEOUT_SECONDS=2
|
39
|
+
|
40
|
+
# WPP Config
|
41
|
+
# WPP_API_URL="http://localhost:21465"
|
42
|
+
# WPP_MASTER_KEY="wpp_secret"
|
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
# perform a jac_clean on the actions folder
|
4
|
+
# Navigate to the ./actions subdirectory and execute jac clean
|
5
|
+
if cd ./actions; then
|
6
|
+
jac clean
|
7
|
+
cd - > /dev/null
|
8
|
+
else
|
9
|
+
echo "Failed to navigate to ./actions directory. Exiting..."
|
10
|
+
exit 1
|
11
|
+
fi
|
@@ -1,24 +1,24 @@
|
|
1
|
-
jvcli/__init__.py,sha256=
|
1
|
+
jvcli/__init__.py,sha256=OeC4EUAVWqVouNBryA-pk95IyKTI81XNGBSJlCnhjiU,171
|
2
2
|
jvcli/api.py,sha256=gd-EP1e75e7HijyrP-EF6i_jjCo6YUeSbm1l5daKLfQ,10352
|
3
3
|
jvcli/auth.py,sha256=p04T02ufqbENx_93oDPg3xsq7sv-Nabeq3YR1kLXfSg,1215
|
4
4
|
jvcli/cli.py,sha256=VM_QGPiYfSdqOZ4n0YLZbrOwXm0d5lHmzv47MqTyBMc,1060
|
5
5
|
jvcli/utils.py,sha256=sdVMBNPSI4985OdspmCxj0BVL61c6dwEQNwhvPJIiAU,7648
|
6
6
|
jvcli/client/__init__.py,sha256=WGP05OBzZHReqENYs1qYqMnYvgAaNVW6KvGQvyB3NGs,85
|
7
|
-
jvcli/client/app.py,sha256=
|
7
|
+
jvcli/client/app.py,sha256=bjdGY9J43qymdmODt0BgzN66Aolyo1653ZuCj_gNdKA,6184
|
8
8
|
jvcli/client/lib/__init__.py,sha256=_Wv8CNIxeIle_x0U9T6w9s5mPuOY9-0u69BvTEPXLUw,38
|
9
9
|
jvcli/client/lib/page.py,sha256=QF53ffO4A2P9QTdPFfi0baCpKyEMmfkLyhJNxm7pTb0,2225
|
10
|
-
jvcli/client/lib/utils.py,sha256
|
10
|
+
jvcli/client/lib/utils.py,sha256=-IKM3iqNwRCaR8FuTzqFpk9Jr-R3HGw3LvBgdYth5OA,9584
|
11
11
|
jvcli/client/lib/widgets.py,sha256=kGI_bHbqUFZCFctNOwIKOL5ZdelQo9Gx_n5Ju2x3PQU,9555
|
12
12
|
jvcli/client/pages/__init__.py,sha256=sXsBV8cGItWhXtYg8PkfCd1Vi5ibd-rv5LABnPC_St4,51
|
13
|
-
jvcli/client/pages/
|
14
|
-
jvcli/client/pages/
|
15
|
-
jvcli/client/pages/
|
13
|
+
jvcli/client/pages/action_dashboard_page.py,sha256=LvDFUt2-hNSmHTHyN1tDSPaE1sV-m_uyId1sGWuoMsw,5029
|
14
|
+
jvcli/client/pages/analytics_page.py,sha256=N6iA5GSVc4QyjUZASHDd16M8IpJWpt9hm-k5RgDTD_A,8273
|
15
|
+
jvcli/client/pages/chat_page.py,sha256=HJC2GxqFQhaCyv-3GmrxY6hPsR-i3BjaJyZfxAEwIk4,4769
|
16
16
|
jvcli/client/pages/graph_page.py,sha256=2ZN-C9eskqICgnZhfP1zc6YOPPsGib_WZw3xHXcA63k,491
|
17
17
|
jvcli/commands/__init__.py,sha256=bjZvM55MC2NugvRlxkEU9CDDP9NnsygcsGZewj1gQcg,57
|
18
18
|
jvcli/commands/auth.py,sha256=lO5G1_TCbxhOfy7xH9EULwvCLqf7iQTF9Q3MrpAtHPY,1611
|
19
|
-
jvcli/commands/client.py,sha256=
|
20
|
-
jvcli/commands/create.py,sha256
|
21
|
-
jvcli/commands/download.py,sha256=
|
19
|
+
jvcli/commands/client.py,sha256=yIp0wCmoxgxImJrpl0dH9qURGMcVKTxonVd1d-BdsxI,1432
|
20
|
+
jvcli/commands/create.py,sha256=HIL01nTcyEEXk4yLMwnPsRtj_cbhsuz2AEN2BwWeI-o,13393
|
21
|
+
jvcli/commands/download.py,sha256=GiLX_43CQOW9d5vF04fAszOWh3AB-7Mgote4tJ9RVng,3416
|
22
22
|
jvcli/commands/info.py,sha256=NyIDpR_AGMMSFPE0tFZv4dIuv_gwqrfd589zQAA_Q3s,2685
|
23
23
|
jvcli/commands/publish.py,sha256=q1ihoL42GmEsU5ggHN3bcg8QD26kjRUZGfQpRzI2GMo,6630
|
24
24
|
jvcli/commands/startproject.py,sha256=yLJO3MDnC5g7qyCSMLzwZomx4y0sC983G_wHjUWrdUM,3393
|
@@ -44,22 +44,23 @@ jvcli/templates/2.0.0/agent_info.yaml,sha256=3olXRQDQG-543o7zSWWT23kJsK29QGhdx6-
|
|
44
44
|
jvcli/templates/2.0.0/agent_knowledge.yaml,sha256=hI0ifr0ICiZGce-oUFovBOmDWxGU1Z2M10WyZH_wS2g,284
|
45
45
|
jvcli/templates/2.0.0/agent_memory.yaml,sha256=_MBgObZcW1UzwWuYQVJiPZ_7TvYbGrDgd-xMuzJEkVo,9
|
46
46
|
jvcli/templates/2.0.0/project/README.md,sha256=cr6yHG1qEzO7xDFchEDpl8tKawVvF0tsUVTrWyxjiG4,1077
|
47
|
-
jvcli/templates/2.0.0/project/env.example,sha256
|
48
|
-
jvcli/templates/2.0.0/project/gitignore.example,sha256=
|
47
|
+
jvcli/templates/2.0.0/project/env.example,sha256=-BqkgF6jR1FLXRyh6esdWqtd1UUFzH6aKt3ZDa4r2Bk,1051
|
48
|
+
jvcli/templates/2.0.0/project/gitignore.example,sha256=KG1wl-o8ltNs4d8qCVgok5F2waUYqCJ5-HJq58Kh79I,530
|
49
49
|
jvcli/templates/2.0.0/project/globals.jac,sha256=CEt7L25wEZfE6TupqpM1ilHbtJMQQWExDQ5GJlkHPts,56
|
50
50
|
jvcli/templates/2.0.0/project/main.jac,sha256=r37jsaGq-85YvDbHP3bQvBXk0u8w0rtRTZTNxZOjTW0,48
|
51
51
|
jvcli/templates/2.0.0/project/actions/README.md,sha256=TU1t-rOBH5WQP_HUWaEBLq5BbPv4jejtjIrwTW4hZwM,1742
|
52
|
-
jvcli/templates/2.0.0/project/daf/README.md,sha256=
|
52
|
+
jvcli/templates/2.0.0/project/daf/README.md,sha256=fO-dcc3j-1E6sFagIvvJsISAth11N-2d64G0yHi7JrY,1682
|
53
53
|
jvcli/templates/2.0.0/project/sh/exportenv.sh,sha256=keFEu6HAROE8F9cOa5FxdIb2pryd22fED66rhaAvAuU,164
|
54
54
|
jvcli/templates/2.0.0/project/sh/importagent.sh,sha256=isDMHR8ZEJEuwAAfJRc0xWhw8xHWetQNMeUqxCDOqx8,1174
|
55
|
-
jvcli/templates/2.0.0/project/sh/initagents.sh,sha256=
|
55
|
+
jvcli/templates/2.0.0/project/sh/initagents.sh,sha256=ZTgVT37Gkw-YOgesTOIUKC1fN_6omAJRvkbGRdbvtZA,983
|
56
56
|
jvcli/templates/2.0.0/project/sh/inituser.sh,sha256=BYvLfFZdL0n7AGmjmoTQQcb236f5wG68RMeVJiUyhFQ,1893
|
57
|
+
jvcli/templates/2.0.0/project/sh/jacclean.sh,sha256=xkC7KLjvvxz5YLdDBT8Js06nr6ru_9G8kYmp_3-kXks,260
|
57
58
|
jvcli/templates/2.0.0/project/sh/serve.sh,sha256=EsXOqszYD5xa8fjAEwyYCz8mSTX-v5VfiTZeKUpOKYw,105
|
58
59
|
jvcli/templates/2.0.0/project/sh/startclient.sh,sha256=3GbJtTxycLBUJGfX2_b3cfQoAPFzhvcJpWRtS2sSsRM,119
|
59
60
|
jvcli/templates/2.0.0/project/tests/README.md,sha256=-1ZXkxuUKa6tMw_jlF3rpCvUFq8ijW2L-nSuAkbCANo,917
|
60
|
-
jvcli-2.0.
|
61
|
-
jvcli-2.0.
|
62
|
-
jvcli-2.0.
|
63
|
-
jvcli-2.0.
|
64
|
-
jvcli-2.0.
|
65
|
-
jvcli-2.0.
|
61
|
+
jvcli-2.0.17.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
62
|
+
jvcli-2.0.17.dist-info/METADATA,sha256=YJXIovjMLhLkkQptmzJdpobrrB56gZpGawxLE0DrTao,4202
|
63
|
+
jvcli-2.0.17.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
64
|
+
jvcli-2.0.17.dist-info/entry_points.txt,sha256=XunGcL0LWmIMIytaUckUA27czEf8M2Y4aTOfYIpOgrQ,42
|
65
|
+
jvcli-2.0.17.dist-info/top_level.txt,sha256=akZnN9Zy1dFT93N0ms-C8ZXUn-xlhq37nO3jSRp0Y6o,6
|
66
|
+
jvcli-2.0.17.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|