jvcli 2.0.30__py3-none-any.whl → 2.1.1__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.1}/project/README.md +4 -40
- jvcli/templates/{2.0.0 → 2.1.1}/project/actions/README.md +1 -1
- jvcli/templates/{2.0.0 → 2.1.1}/project/daf/README.md +1 -1
- jvcli/templates/{2.0.0 → 2.1.1}/project/env.example +7 -4
- jvcli/templates/2.1.1/project/main.jac +2 -0
- jvcli/templates/2.1.1/sourcefiles/action_app.py +23 -0
- jvcli/templates/2.1.1/sourcefiles/action_archetype.jac +49 -0
- jvcli/templates/{2.0.0 → 2.1.1/sourcefiles}/action_info.yaml +1 -1
- jvcli/templates/2.1.1/sourcefiles/action_lib.jac +3 -0
- jvcli/templates/{2.0.0 → 2.1.1/sourcefiles}/agent_descriptor.yaml +4 -4
- jvcli/templates/2.1.1/sourcefiles/interact_action_archetype.jac +58 -0
- jvcli/utils.py +1 -1
- {jvcli-2.0.30.dist-info → jvcli-2.1.1.dist-info}/METADATA +8 -47
- jvcli-2.1.1.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 -291
- 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.30.dist-info/RECORD +0 -61
- /jvcli/templates/{2.0.0 → 2.1.1}/project/gitignore.example +0 -0
- /jvcli/templates/{2.0.0 → 2.1.1}/project/globals.jac +0 -0
- /jvcli/templates/{2.0.0 → 2.1.1}/project/tests/README.md +0 -0
- /jvcli/templates/{CHANGELOG.md → 2.1.1/sourcefiles/CHANGELOG.md} +0 -0
- /jvcli/templates/{README.md → 2.1.1/sourcefiles/README.md} +0 -0
- /jvcli/templates/{2.0.0 → 2.1.1/sourcefiles}/agent_info.yaml +0 -0
- /jvcli/templates/{2.0.0 → 2.1.1/sourcefiles}/agent_knowledge.yaml +0 -0
- /jvcli/templates/{2.0.0 → 2.1.1/sourcefiles}/agent_memory.yaml +0 -0
- {jvcli-2.0.30.dist-info → jvcli-2.1.1.dist-info}/WHEEL +0 -0
- {jvcli-2.0.30.dist-info → jvcli-2.1.1.dist-info}/entry_points.txt +0 -0
- {jvcli-2.0.30.dist-info → jvcli-2.1.1.dist-info}/licenses/LICENSE +0 -0
- {jvcli-2.0.30.dist-info → jvcli-2.1.1.dist-info}/top_level.txt +0 -0
@@ -1,120 +0,0 @@
|
|
1
|
-
"""Render the action_dashboard page of the jvclient with actions data."""
|
2
|
-
|
3
|
-
import streamlit as st
|
4
|
-
from streamlit_elements import dashboard, elements, mui
|
5
|
-
from streamlit_router import StreamlitRouter
|
6
|
-
|
7
|
-
from jvcli.client.lib.page import Page
|
8
|
-
|
9
|
-
|
10
|
-
def render(router: StreamlitRouter) -> None:
|
11
|
-
"""Render the dashboard page."""
|
12
|
-
if actions_data := st.session_state.get("actions_data"):
|
13
|
-
with elements("action_dashboard"):
|
14
|
-
columns = 4
|
15
|
-
layout = []
|
16
|
-
|
17
|
-
# Compute the position of each card component in the layout
|
18
|
-
for idx, _ in enumerate(actions_data):
|
19
|
-
x = (idx % columns) * 3
|
20
|
-
y = (idx // columns) * 2
|
21
|
-
width = 3
|
22
|
-
height = 2
|
23
|
-
# Add an item to the action_dashboard manually without using `with` if it's not a context manager
|
24
|
-
layout.append(
|
25
|
-
dashboard.Item(
|
26
|
-
f"card_{idx}",
|
27
|
-
x,
|
28
|
-
y,
|
29
|
-
width,
|
30
|
-
height,
|
31
|
-
isDraggable=False,
|
32
|
-
isResizable=False,
|
33
|
-
)
|
34
|
-
)
|
35
|
-
|
36
|
-
# now populate the actual cards with content
|
37
|
-
with dashboard.Grid(layout):
|
38
|
-
for idx, action in enumerate(actions_data):
|
39
|
-
|
40
|
-
package = action.get("_package", {})
|
41
|
-
title = package.get("meta", {}).get("title", action.get("label"))
|
42
|
-
description = action.get("description", "")
|
43
|
-
version = package.get("version", "0.0.0")
|
44
|
-
action_type = package.get("meta", {}).get("type", "action")
|
45
|
-
key = Page.normalize_label(title)
|
46
|
-
enabled_color = "red"
|
47
|
-
enabled_text = "(disabled)"
|
48
|
-
avatar_text = "A"
|
49
|
-
|
50
|
-
if action_type == "interact_action":
|
51
|
-
avatar_text = "I"
|
52
|
-
|
53
|
-
if action.get("enabled", False):
|
54
|
-
enabled_color = "green"
|
55
|
-
enabled_text = ""
|
56
|
-
|
57
|
-
# create the card
|
58
|
-
with mui.Card(
|
59
|
-
key=f"card_{idx}",
|
60
|
-
sx={
|
61
|
-
"display": "flex",
|
62
|
-
"flexDirection": "column",
|
63
|
-
"borderRadius": 2,
|
64
|
-
"overflow": "scroll",
|
65
|
-
},
|
66
|
-
elevation=2,
|
67
|
-
):
|
68
|
-
# Card header with title
|
69
|
-
mui.CardHeader(
|
70
|
-
title=f"{title} {enabled_text}",
|
71
|
-
subheader=f"{version}",
|
72
|
-
avatar=mui.Avatar(
|
73
|
-
avatar_text, sx={"bgcolor": enabled_color}
|
74
|
-
),
|
75
|
-
action=mui.IconButton(mui.icon.MoreVert),
|
76
|
-
)
|
77
|
-
|
78
|
-
# Card body
|
79
|
-
with mui.CardContent(sx={"flex": 1}):
|
80
|
-
mui.Typography(description, variant="body2")
|
81
|
-
|
82
|
-
# Card footer with action buttons
|
83
|
-
with mui.CardActions(disableSpacing=True):
|
84
|
-
query = st.query_params.to_dict()
|
85
|
-
query_str = ""
|
86
|
-
for k, v in query.items():
|
87
|
-
if k != "request":
|
88
|
-
query_str += f"{k}={v}&"
|
89
|
-
|
90
|
-
if package.get("config", {}).get("app", False):
|
91
|
-
with mui.Stack(
|
92
|
-
direction="row",
|
93
|
-
spacing=2,
|
94
|
-
alignItems="center",
|
95
|
-
sx={"padding": "10px"},
|
96
|
-
):
|
97
|
-
mui.Button(
|
98
|
-
"Configure",
|
99
|
-
variant="outlined",
|
100
|
-
href=(
|
101
|
-
(
|
102
|
-
f"/?request=GET:/{key}&${query_str.rstrip('&')}"
|
103
|
-
if query_str
|
104
|
-
else f"/?request=GET:/{key}"
|
105
|
-
)
|
106
|
-
+ f"&token={st.session_state.TOKEN}"
|
107
|
-
),
|
108
|
-
target="_blank",
|
109
|
-
)
|
110
|
-
|
111
|
-
|
112
|
-
def logout() -> None:
|
113
|
-
"""Logout the user by clearing the session token."""
|
114
|
-
del st.session_state["TOKEN"]
|
115
|
-
token_query = st.query_params.get("token")
|
116
|
-
|
117
|
-
if token_query:
|
118
|
-
query_params = st.query_params.to_dict()
|
119
|
-
del query_params["token"]
|
120
|
-
st.query_params.from_dict(query_params)
|
@@ -1,245 +0,0 @@
|
|
1
|
-
"""Renders the analytics page of the JVCLI client."""
|
2
|
-
|
3
|
-
import calendar
|
4
|
-
import datetime
|
5
|
-
import os
|
6
|
-
from typing import Optional
|
7
|
-
|
8
|
-
import pandas as pd
|
9
|
-
import requests
|
10
|
-
import streamlit as st
|
11
|
-
from streamlit.delta_generator import DeltaGenerator
|
12
|
-
from streamlit_javascript import st_javascript
|
13
|
-
from streamlit_router import StreamlitRouter
|
14
|
-
|
15
|
-
from jvcli.client.lib.utils import call_healthcheck, get_user_info
|
16
|
-
|
17
|
-
JIVAS_BASE_URL = os.environ.get("JIVAS_BASE_URL", "http://localhost:8000")
|
18
|
-
|
19
|
-
|
20
|
-
def render(router: StreamlitRouter) -> None:
|
21
|
-
"""Render the analytics page."""
|
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
|
-
st.rerun()
|
83
|
-
|
84
|
-
else:
|
85
|
-
st.error("Failed to fetch healthcheck data.")
|
86
|
-
except Exception as e:
|
87
|
-
st.error("An error occurred while fetching healthcheck data.")
|
88
|
-
print(e)
|
89
|
-
|
90
|
-
st.header("Analytics", divider=True)
|
91
|
-
today = datetime.date.today()
|
92
|
-
last_day = calendar.monthrange(today.year, today.month)[1]
|
93
|
-
|
94
|
-
date_range = st.date_input(
|
95
|
-
"Period",
|
96
|
-
(
|
97
|
-
datetime.date(today.year, today.month, 1),
|
98
|
-
datetime.date(today.year, today.month, last_day),
|
99
|
-
),
|
100
|
-
)
|
101
|
-
|
102
|
-
(start_date, end_date) = date_range
|
103
|
-
|
104
|
-
# rerender_metrics = render_metrics()
|
105
|
-
col1, col2, col3 = st.columns(3)
|
106
|
-
timezone = st_javascript(
|
107
|
-
"""await (async () => {
|
108
|
-
const userTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
109
|
-
console.log(userTimezone)
|
110
|
-
return userTimezone
|
111
|
-
})().then(returnValue => returnValue)"""
|
112
|
-
)
|
113
|
-
|
114
|
-
try:
|
115
|
-
ctx = get_user_info()
|
116
|
-
if selected_agent and end_date > start_date:
|
117
|
-
interactions_chart(
|
118
|
-
token=ctx["token"],
|
119
|
-
agent_id=selected_agent["id"],
|
120
|
-
start_date=start_date,
|
121
|
-
end_date=end_date,
|
122
|
-
metric_col=col1,
|
123
|
-
timezone=timezone,
|
124
|
-
)
|
125
|
-
users_chart(
|
126
|
-
token=ctx["token"],
|
127
|
-
agent_id=selected_agent["id"],
|
128
|
-
start_date=start_date,
|
129
|
-
end_date=end_date,
|
130
|
-
metric_col=col2,
|
131
|
-
timezone=timezone,
|
132
|
-
)
|
133
|
-
channels_chart(
|
134
|
-
token=ctx["token"],
|
135
|
-
agent_id=selected_agent["id"],
|
136
|
-
start_date=start_date,
|
137
|
-
end_date=end_date,
|
138
|
-
metric_col=col3,
|
139
|
-
timezone=timezone,
|
140
|
-
)
|
141
|
-
else:
|
142
|
-
st.text("Invalid date range")
|
143
|
-
except Exception as e:
|
144
|
-
st.text("Unable to render charts")
|
145
|
-
print(e)
|
146
|
-
|
147
|
-
|
148
|
-
def interactions_chart(
|
149
|
-
start_date: datetime.date,
|
150
|
-
end_date: datetime.date,
|
151
|
-
agent_id: str,
|
152
|
-
token: str,
|
153
|
-
metric_col: DeltaGenerator,
|
154
|
-
timezone: str,
|
155
|
-
) -> None:
|
156
|
-
"""Render the interactions chart."""
|
157
|
-
url = f"{JIVAS_BASE_URL}/walker/get_interactions_by_date"
|
158
|
-
|
159
|
-
with st.container(border=True):
|
160
|
-
st.subheader("Interactions by Date")
|
161
|
-
response = requests.post(
|
162
|
-
url=url,
|
163
|
-
json={
|
164
|
-
"agent_id": agent_id,
|
165
|
-
"reporting": True,
|
166
|
-
"start_date": start_date.isoformat(),
|
167
|
-
"end_date": end_date.isoformat(),
|
168
|
-
"timezone": timezone,
|
169
|
-
},
|
170
|
-
headers={"Authorization": f"Bearer {token}"},
|
171
|
-
)
|
172
|
-
if response.status_code == 200:
|
173
|
-
if response_data := response.json():
|
174
|
-
chart_data = pd.DataFrame(
|
175
|
-
data=response_data["reports"][0]["data"],
|
176
|
-
)
|
177
|
-
st.line_chart(chart_data, x="date", y="count")
|
178
|
-
total = response_data["reports"][0]["total"]
|
179
|
-
metric_col.metric("Interactions", total)
|
180
|
-
|
181
|
-
|
182
|
-
def users_chart(
|
183
|
-
start_date: datetime.date,
|
184
|
-
end_date: datetime.date,
|
185
|
-
agent_id: str,
|
186
|
-
token: str,
|
187
|
-
metric_col: DeltaGenerator,
|
188
|
-
timezone: str,
|
189
|
-
) -> None:
|
190
|
-
"""Render the users chart."""
|
191
|
-
url = f"{JIVAS_BASE_URL}/walker/get_users_by_date"
|
192
|
-
with st.container(border=True):
|
193
|
-
st.subheader("Users by Date")
|
194
|
-
response = requests.post(
|
195
|
-
url=url,
|
196
|
-
json={
|
197
|
-
"agent_id": agent_id,
|
198
|
-
"reporting": True,
|
199
|
-
"start_date": start_date.isoformat(),
|
200
|
-
"end_date": end_date.isoformat(),
|
201
|
-
"timezone": timezone,
|
202
|
-
},
|
203
|
-
headers={"Authorization": f"Bearer {token}"},
|
204
|
-
)
|
205
|
-
if response.status_code == 200:
|
206
|
-
if response_data := response.json():
|
207
|
-
chart_data = pd.DataFrame(
|
208
|
-
data=response_data["reports"][0]["data"],
|
209
|
-
)
|
210
|
-
st.line_chart(chart_data, x="date", y="count")
|
211
|
-
total = response_data["reports"][0]["total"]
|
212
|
-
metric_col.metric("Users", total)
|
213
|
-
|
214
|
-
|
215
|
-
def channels_chart(
|
216
|
-
start_date: datetime.date,
|
217
|
-
end_date: datetime.date,
|
218
|
-
agent_id: str,
|
219
|
-
token: str,
|
220
|
-
metric_col: DeltaGenerator,
|
221
|
-
timezone: str,
|
222
|
-
) -> None:
|
223
|
-
"""Render the channels chart."""
|
224
|
-
url = f"{JIVAS_BASE_URL}/walker/get_channels_by_date"
|
225
|
-
with st.container(border=True):
|
226
|
-
st.subheader("Channels by Date")
|
227
|
-
response = requests.post(
|
228
|
-
url=url,
|
229
|
-
json={
|
230
|
-
"agent_id": agent_id,
|
231
|
-
"reporting": True,
|
232
|
-
"start_date": start_date.isoformat(),
|
233
|
-
"end_date": end_date.isoformat(),
|
234
|
-
"timezone": timezone,
|
235
|
-
},
|
236
|
-
headers={"Authorization": f"Bearer {token}"},
|
237
|
-
)
|
238
|
-
if response.status_code == 200:
|
239
|
-
if response_data := response.json():
|
240
|
-
chart_data = pd.DataFrame(
|
241
|
-
data=response_data["reports"][0]["data"],
|
242
|
-
)
|
243
|
-
st.line_chart(chart_data, x="date", y="count")
|
244
|
-
total = response_data["reports"][0]["total"]
|
245
|
-
metric_col.metric("Channels", total)
|
jvcli/client/pages/chat_page.py
DELETED
@@ -1,150 +0,0 @@
|
|
1
|
-
"""Renders the chat page for the JVCLI client."""
|
2
|
-
|
3
|
-
import os
|
4
|
-
from typing import Optional
|
5
|
-
|
6
|
-
import requests
|
7
|
-
import streamlit as st
|
8
|
-
from streamlit_router import StreamlitRouter
|
9
|
-
|
10
|
-
from jvcli.client.lib.utils import get_user_info
|
11
|
-
|
12
|
-
JIVAS_BASE_URL = os.environ.get("JIVAS_BASE_URL", "http://localhost:8000")
|
13
|
-
|
14
|
-
|
15
|
-
def transcribe_audio(token: str, agent_id: str, file: bytes) -> dict:
|
16
|
-
"""Transcribe audio using the walker API."""
|
17
|
-
action_walker_url = f"{JIVAS_BASE_URL}/action/walker"
|
18
|
-
|
19
|
-
# Create form data
|
20
|
-
files = {"attachments": ("audio.wav", file, "audio/wav")}
|
21
|
-
|
22
|
-
data = {
|
23
|
-
"args": "{}",
|
24
|
-
"module_root": "jivas.agent.action",
|
25
|
-
"agent_id": agent_id,
|
26
|
-
"walker": "invoke_stt_action",
|
27
|
-
}
|
28
|
-
|
29
|
-
headers = {"Authorization": f"Bearer {token}"}
|
30
|
-
|
31
|
-
# Make the POST request
|
32
|
-
response = requests.post(
|
33
|
-
f"{action_walker_url}", headers=headers, data=data, files=files
|
34
|
-
)
|
35
|
-
|
36
|
-
# Parse JSON response
|
37
|
-
result = response.json()
|
38
|
-
return result
|
39
|
-
|
40
|
-
|
41
|
-
def render(router: StreamlitRouter) -> None:
|
42
|
-
"""Render the chat page."""
|
43
|
-
url = f"{JIVAS_BASE_URL}/interact"
|
44
|
-
ctx = get_user_info()
|
45
|
-
|
46
|
-
st.header("Chat", divider=True)
|
47
|
-
tts_on = st.toggle("TTS")
|
48
|
-
|
49
|
-
message = ""
|
50
|
-
# Handle audio input first
|
51
|
-
audio_value = st.audio_input("Record a voice message")
|
52
|
-
# Get selected agent from query params
|
53
|
-
selected_agent = st.query_params.get("agent")
|
54
|
-
|
55
|
-
if selected_agent:
|
56
|
-
chat_messages = st.session_state.messages.get(selected_agent, [])
|
57
|
-
|
58
|
-
# Display chat messages from history on app rerun
|
59
|
-
for item in chat_messages:
|
60
|
-
role = item.get("role", "user")
|
61
|
-
content = item.get("content", "")
|
62
|
-
with st.chat_message(role):
|
63
|
-
st.markdown(content)
|
64
|
-
if payload := item.get("payload"):
|
65
|
-
with st.expander("...", False):
|
66
|
-
st.json(payload)
|
67
|
-
|
68
|
-
# Process audio input if available
|
69
|
-
if audio_value and selected_agent:
|
70
|
-
result = transcribe_audio(ctx["token"], selected_agent, audio_value)
|
71
|
-
if result and result.get("success", False):
|
72
|
-
message = result["transcript"]
|
73
|
-
|
74
|
-
# Otherwise handle text input
|
75
|
-
if input := st.chat_input("Type your message here"):
|
76
|
-
message = input
|
77
|
-
|
78
|
-
if message:
|
79
|
-
send_message(message, url, ctx["token"], selected_agent, tts_on)
|
80
|
-
|
81
|
-
|
82
|
-
def send_message(
|
83
|
-
prompt: str,
|
84
|
-
url: str,
|
85
|
-
token: str,
|
86
|
-
selected_agent: Optional[str] = None,
|
87
|
-
tts_on: bool = False,
|
88
|
-
) -> None:
|
89
|
-
"""Send a message to the walker API and display the response."""
|
90
|
-
# Add user message to chat history
|
91
|
-
add_agent_message(selected_agent, {"role": "user", "content": prompt})
|
92
|
-
|
93
|
-
# Display user message in chat message container
|
94
|
-
with st.chat_message("user"):
|
95
|
-
st.markdown(prompt)
|
96
|
-
|
97
|
-
with st.chat_message("assistant"):
|
98
|
-
# Call walker API
|
99
|
-
response = requests.post(
|
100
|
-
url=url,
|
101
|
-
json={
|
102
|
-
"utterance": prompt,
|
103
|
-
"session_id": st.session_state.session_id,
|
104
|
-
"agent_id": selected_agent,
|
105
|
-
"tts": tts_on,
|
106
|
-
"verbose": True,
|
107
|
-
},
|
108
|
-
headers={"Authorization": f"Bearer {token}"},
|
109
|
-
)
|
110
|
-
if response.status_code == 200:
|
111
|
-
if response_data := response.json():
|
112
|
-
st.markdown(
|
113
|
-
response_data.get("response", {})
|
114
|
-
.get("message", {})
|
115
|
-
.get("content", "...")
|
116
|
-
)
|
117
|
-
if "audio_url" in response_data.get("response", {}) and tts_on:
|
118
|
-
audio_url = response_data.get("response", {}).get(
|
119
|
-
"audio_url", "..."
|
120
|
-
)
|
121
|
-
st.audio(audio_url, autoplay=True)
|
122
|
-
with st.expander("...", False):
|
123
|
-
st.json(response_data)
|
124
|
-
|
125
|
-
# Add assistant response to chat history
|
126
|
-
add_agent_message(
|
127
|
-
selected_agent,
|
128
|
-
{
|
129
|
-
"role": "assistant",
|
130
|
-
"content": response_data.get("response", {})
|
131
|
-
.get("message", {})
|
132
|
-
.get("content", "..."),
|
133
|
-
"payload": response_data,
|
134
|
-
},
|
135
|
-
)
|
136
|
-
if "session_id" in response_data.get("response", {}):
|
137
|
-
st.session_state.session_id = response_data["response"]["session_id"]
|
138
|
-
|
139
|
-
|
140
|
-
def add_agent_message(agent_id: Optional[str], message: dict) -> None:
|
141
|
-
"""Add a message to the chat history for a specific agent."""
|
142
|
-
all_messages = st.session_state.messages
|
143
|
-
agent_messages = all_messages.get(agent_id, [])
|
144
|
-
agent_messages.append(message)
|
145
|
-
st.session_state.messages[agent_id] = agent_messages
|
146
|
-
|
147
|
-
|
148
|
-
def clear_messages() -> None:
|
149
|
-
"""Clear all chat messages."""
|
150
|
-
st.session_state.messages = {}
|
jvcli/client/pages/graph_page.py
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
"""Render the Jivas Studio page in an iframe."""
|
2
|
-
|
3
|
-
import os
|
4
|
-
|
5
|
-
import streamlit as st
|
6
|
-
from streamlit_router import StreamlitRouter
|
7
|
-
|
8
|
-
JIVAS_STUDIO_URL = os.environ.get("JIVAS_STUDIO_URL", "http://localhost:8989")
|
9
|
-
|
10
|
-
|
11
|
-
def render(router: StreamlitRouter) -> None:
|
12
|
-
"""
|
13
|
-
Render the Jivas Studio page in an iframe.
|
14
|
-
|
15
|
-
args:
|
16
|
-
router: StreamlitRouter
|
17
|
-
The StreamlitRouter instance
|
18
|
-
"""
|
19
|
-
|
20
|
-
st.components.v1.iframe(JIVAS_STUDIO_URL, width=None, height=800, scrolling=False)
|
jvcli/commands/clean.py
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
"""Runs the jac clean command"""
|
2
|
-
|
3
|
-
import subprocess
|
4
|
-
|
5
|
-
import click
|
6
|
-
|
7
|
-
|
8
|
-
@click.command(
|
9
|
-
help="Clean the Jac files in the current directory and subdirectories. This command executes 'jac clean', which removes compiled Jac artifacts and temporary files. "
|
10
|
-
"Use this command to ensure a clean state before rebuilding your Jac project."
|
11
|
-
)
|
12
|
-
@click.pass_context
|
13
|
-
def clean(ctx: click.Context) -> None:
|
14
|
-
"""Clean the Jac files in directory."""
|
15
|
-
try:
|
16
|
-
click.echo("Running jac clean in actions directory...")
|
17
|
-
result = subprocess.run(["jac", "clean"], check=True)
|
18
|
-
if result.returncode == 0:
|
19
|
-
click.echo("Successfully cleaned directory.")
|
20
|
-
|
21
|
-
else:
|
22
|
-
click.secho("Failed to clean directory.", fg="red")
|
23
|
-
ctx.exit(1)
|
24
|
-
except subprocess.CalledProcessError as e:
|
25
|
-
click.secho(f"Error running jac clean: {e}", fg="red")
|
26
|
-
ctx.exit(1)
|
27
|
-
except Exception as e:
|
28
|
-
click.secho(f"Unexpected error: {e}", fg="red")
|
29
|
-
ctx.exit(1)
|