@meridiona/meridian-darwin-arm64 1.61.0 → 1.62.0
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.
- package/VERSION +1 -1
- package/bin/meridian +0 -0
- package/package.json +1 -1
- package/scripts/install-openobserve-daemon.sh +79 -0
- package/services/agents/pm_worklog_update/config.py +1 -1
- package/services/agents/server.py +29 -3
- package/services/observability/dashboards/coding-agent-summariser.json +621 -0
- package/services/pyproject.toml +1 -1
- package/ui.tar.gz +0 -0
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.
|
|
1
|
+
1.62.0
|
package/bin/meridian
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meridiona/meridian-darwin-arm64",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.62.0",
|
|
4
4
|
"description": "Prebuilt Meridian app for macOS arm64 (daemon binary + dashboard + Python services). Installed via @meridiona/meridian.",
|
|
5
5
|
"homepage": "https://github.com/Meridiona/meridian",
|
|
6
6
|
"repository": {
|
|
@@ -221,6 +221,83 @@ _otlp_enabled() {
|
|
|
221
221
|
return 1
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
+
# Provision the bundled dashboards (services/observability/dashboards/*.json)
|
|
225
|
+
# into OpenObserve via its REST API. Idempotent: a dashboard is created only if
|
|
226
|
+
# no dashboard with the same title already exists (create endpoint always mints
|
|
227
|
+
# a fresh dashboardId, so a blind POST on every install would duplicate). Runs
|
|
228
|
+
# only once the service is up and reachable; degrades silently (never fails the
|
|
229
|
+
# install) when OpenObserve is unreachable or export is off.
|
|
230
|
+
_import_dashboards() {
|
|
231
|
+
local dash_dir
|
|
232
|
+
dash_dir="$(cd "${SCRIPT_DIR}/.." && pwd)/services/observability/dashboards"
|
|
233
|
+
[[ -d "${dash_dir}" ]] || return 0
|
|
234
|
+
OO_EMAIL="${OO_EMAIL}" OO_PASSWORD="${OO_PASSWORD}" python3 - "${dash_dir}" <<'PYEOF'
|
|
235
|
+
import base64, glob, json, os, sys, time, urllib.request, urllib.error
|
|
236
|
+
|
|
237
|
+
dash_dir = sys.argv[1]
|
|
238
|
+
base = "http://localhost:5080"
|
|
239
|
+
org = "default"
|
|
240
|
+
auth = base64.b64encode(f'{os.environ["OO_EMAIL"]}:{os.environ["OO_PASSWORD"]}'.encode()).decode()
|
|
241
|
+
|
|
242
|
+
def call(method, path, body=None):
|
|
243
|
+
data = json.dumps(body).encode() if body is not None else None
|
|
244
|
+
req = urllib.request.Request(
|
|
245
|
+
base + path, data=data, method=method,
|
|
246
|
+
headers={"Authorization": "Basic " + auth, "Content-Type": "application/json"},
|
|
247
|
+
)
|
|
248
|
+
try:
|
|
249
|
+
r = urllib.request.urlopen(req, timeout=15)
|
|
250
|
+
return r.status, r.read()
|
|
251
|
+
except urllib.error.HTTPError as e:
|
|
252
|
+
return e.code, e.read()
|
|
253
|
+
except Exception as e: # connection refused, DNS, timeout, …
|
|
254
|
+
return None, str(e).encode()
|
|
255
|
+
|
|
256
|
+
# Wait for the service to accept authenticated requests (just-kickstarted).
|
|
257
|
+
for _ in range(30):
|
|
258
|
+
st, _b = call("GET", "/config")
|
|
259
|
+
if st == 200:
|
|
260
|
+
break
|
|
261
|
+
time.sleep(1)
|
|
262
|
+
else:
|
|
263
|
+
print(" ⚠ OpenObserve not reachable — skipping dashboard import (import later by re-running this script)")
|
|
264
|
+
sys.exit(0)
|
|
265
|
+
|
|
266
|
+
st, body = call("GET", f"/api/{org}/dashboards")
|
|
267
|
+
if st != 200:
|
|
268
|
+
print(f" ⚠ could not list dashboards ({st}) — skipping dashboard import")
|
|
269
|
+
sys.exit(0)
|
|
270
|
+
existing = set()
|
|
271
|
+
for d in json.loads(body).get("dashboards", []):
|
|
272
|
+
for v in ("v1", "v2", "v3", "v4", "v5", "v6"):
|
|
273
|
+
if d.get(v) and d[v].get("title"):
|
|
274
|
+
existing.add(d[v]["title"])
|
|
275
|
+
|
|
276
|
+
created = skipped = failed = 0
|
|
277
|
+
for path in sorted(glob.glob(os.path.join(dash_dir, "*.json"))):
|
|
278
|
+
try:
|
|
279
|
+
dash = json.load(open(path))
|
|
280
|
+
except Exception as e:
|
|
281
|
+
print(f" ⚠ {os.path.basename(path)}: invalid JSON ({e}) — skipped")
|
|
282
|
+
failed += 1
|
|
283
|
+
continue
|
|
284
|
+
title = dash.get("title", "")
|
|
285
|
+
if title in existing:
|
|
286
|
+
skipped += 1
|
|
287
|
+
continue
|
|
288
|
+
st, resp = call("POST", f"/api/{org}/dashboards?folder=default", dash)
|
|
289
|
+
if st in (200, 201):
|
|
290
|
+
created += 1
|
|
291
|
+
print(f" ✓ imported dashboard: {title}")
|
|
292
|
+
else:
|
|
293
|
+
failed += 1
|
|
294
|
+
print(f" ⚠ failed to import {os.path.basename(path)} ({st}): {resp[:200].decode(errors='replace')}")
|
|
295
|
+
|
|
296
|
+
print(f"→ dashboards: {created} imported, {skipped} already present, {failed} failed")
|
|
297
|
+
PYEOF
|
|
298
|
+
return 0
|
|
299
|
+
}
|
|
300
|
+
|
|
224
301
|
if [[ "${_no_creds}" -eq 0 ]] && _otlp_enabled; then
|
|
225
302
|
echo "→ bootstrap ${LABEL} (OpenObserve Export is enabled in settings)"
|
|
226
303
|
launchctl bootstrap "${GUI_TARGET}" "${PLIST_DEST}"
|
|
@@ -228,6 +305,8 @@ if [[ "${_no_creds}" -eq 0 ]] && _otlp_enabled; then
|
|
|
228
305
|
launchctl kickstart -k "${GUI_TARGET}/${LABEL}"
|
|
229
306
|
echo
|
|
230
307
|
echo "✓ OpenObserve installed and started"
|
|
308
|
+
echo "→ importing bundled dashboards"
|
|
309
|
+
_import_dashboards || true
|
|
231
310
|
else
|
|
232
311
|
launchctl disable "${GUI_TARGET}/${LABEL}" 2>/dev/null || true
|
|
233
312
|
echo
|
|
@@ -32,7 +32,7 @@ MLX_SERVER_MODEL = os.environ.get("MLX_SERVER_MODEL", "qwen3.5-9b-instruct")
|
|
|
32
32
|
# Token caps. The MLX model exposes 128-262K context — a single Synthesise
|
|
33
33
|
# call comfortably swallows even the heaviest hour of work.
|
|
34
34
|
PM_WORKLOG_SYNTH_MAX_TOKENS = int(os.environ.get("PM_WORKLOG_SYNTH_MAX_TOKENS", "8000"))
|
|
35
|
-
PM_WORKLOG_REQUEST_TIMEOUT_S = int(os.environ.get("PM_WORKLOG_REQUEST_TIMEOUT_S", "
|
|
35
|
+
PM_WORKLOG_REQUEST_TIMEOUT_S = int(os.environ.get("PM_WORKLOG_REQUEST_TIMEOUT_S", "900"))
|
|
36
36
|
|
|
37
37
|
# Temperature tuned for each step. Lower = more deterministic.
|
|
38
38
|
PM_WORKLOG_TEMP_COLLECT = 0.0
|
|
@@ -62,6 +62,25 @@ async def _idle_evictor(mlx_module: Any) -> None:
|
|
|
62
62
|
log.warning("server: idle-evictor error: %s", exc)
|
|
63
63
|
|
|
64
64
|
|
|
65
|
+
def _model_sem() -> "asyncio.Semaphore":
|
|
66
|
+
"""Return the process-global single-slot model semaphore.
|
|
67
|
+
|
|
68
|
+
Created once in _lifespan and stored in _app_state. Every endpoint that
|
|
69
|
+
runs a model inference acquires this before calling run_in_threadpool so
|
|
70
|
+
that classify, synthesise_worklog, and summarise never compete on the GPU.
|
|
71
|
+
The synthesise path is indirectly serialised: /synthesise_worklog itself
|
|
72
|
+
does NOT hold the semaphore (agno calls /v1/chat/completions internally),
|
|
73
|
+
so /v1/chat/completions acquires it instead — no nested acquisition,
|
|
74
|
+
no deadlock.
|
|
75
|
+
"""
|
|
76
|
+
import asyncio
|
|
77
|
+
sem = _app_state.get("model_sem")
|
|
78
|
+
if sem is None: # fallback if called before lifespan (e.g. tests)
|
|
79
|
+
sem = asyncio.Semaphore(1)
|
|
80
|
+
_app_state["model_sem"] = sem
|
|
81
|
+
return sem
|
|
82
|
+
|
|
83
|
+
|
|
65
84
|
@asynccontextmanager
|
|
66
85
|
async def _lifespan(app: FastAPI) -> AsyncIterator[None]:
|
|
67
86
|
import asyncio
|
|
@@ -69,6 +88,7 @@ async def _lifespan(app: FastAPI) -> AsyncIterator[None]:
|
|
|
69
88
|
import agents.run_task_linker_mlx as _mlx
|
|
70
89
|
_app_state["mlx_module"] = _mlx
|
|
71
90
|
_app_state["loaded_at"] = datetime.datetime.now(datetime.timezone.utc).isoformat()
|
|
91
|
+
_app_state["model_sem"] = asyncio.Semaphore(1)
|
|
72
92
|
from agents.llm_selector import APPLE_INTELLIGENCE_ID
|
|
73
93
|
evictor: "asyncio.Task | None" = None
|
|
74
94
|
if _mlx._resolve_model_id() == APPLE_INTELLIGENCE_ID:
|
|
@@ -332,7 +352,8 @@ async def classify_sessions(req: ClassifySessionsRequest) -> dict:
|
|
|
332
352
|
if _tok is not None:
|
|
333
353
|
_otel_context.detach(_tok)
|
|
334
354
|
|
|
335
|
-
|
|
355
|
+
async with _model_sem():
|
|
356
|
+
results = await run_in_threadpool(_classify_all)
|
|
336
357
|
return {"results": results}
|
|
337
358
|
|
|
338
359
|
|
|
@@ -489,7 +510,8 @@ async def openai_chat_completions(req: _OAIChatRequest) -> dict:
|
|
|
489
510
|
|
|
490
511
|
t0 = _time.time()
|
|
491
512
|
try:
|
|
492
|
-
|
|
513
|
+
async with _model_sem():
|
|
514
|
+
text = await run_in_threadpool(_generate)
|
|
493
515
|
except Exception as exc: # noqa: BLE001
|
|
494
516
|
log.warning("openai_chat_completions: inference error: %s", exc)
|
|
495
517
|
raise HTTPException(status_code=500, detail=str(exc)) from exc
|
|
@@ -618,7 +640,8 @@ async def summarise(req: _SummariseRequest) -> _SummariseResponse:
|
|
|
618
640
|
)
|
|
619
641
|
|
|
620
642
|
try:
|
|
621
|
-
|
|
643
|
+
async with _model_sem():
|
|
644
|
+
raw = await run_in_threadpool(_generate)
|
|
622
645
|
obj = _SummarySchema.model_validate_json(raw)
|
|
623
646
|
except Exception as exc: # noqa: BLE001
|
|
624
647
|
log.warning("summarise: inference/parse error: %s", exc)
|
|
@@ -832,6 +855,9 @@ async def synthesise_worklog(req: _SynthWorklogRequest) -> dict:
|
|
|
832
855
|
except Exception as exc: # noqa: BLE001 — never crash the shared server
|
|
833
856
|
last_detail = f"agent run raised {type(exc).__name__}: {exc}"
|
|
834
857
|
log.warning("synthesise_worklog: attempt %d %s", attempt, last_detail)
|
|
858
|
+
if attempt < 3:
|
|
859
|
+
import time as _t
|
|
860
|
+
_t.sleep(5 * attempt) # 5s, 10s between retries
|
|
835
861
|
continue
|
|
836
862
|
raw = getattr(response, "content", response)
|
|
837
863
|
if raw is None:
|
|
@@ -0,0 +1,621 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 8,
|
|
3
|
+
"title": "Coding-Agent Summariser — Continuity",
|
|
4
|
+
"description": "Every sealed coding-agent segment turned into a prose summary, newest first. The continuity signal: `prior_present=true` means the segment was summarised WITH the previous burst's summary injected as context (a resumed session reading as one story); `prior_chars` is how much context carried over. Backed by the `summarise_segment` spans (service meridian — the Rust daemon's in-process summariser). Copy a row's trace_id and open it in Traces for the full span. Filter by session UUID or agent above; use Continuity = 'with prior' to see only resumed-session summaries.",
|
|
5
|
+
"tabs": [
|
|
6
|
+
{
|
|
7
|
+
"tabId": "default",
|
|
8
|
+
"name": "Default",
|
|
9
|
+
"panels": [
|
|
10
|
+
{
|
|
11
|
+
"id": "stat_total",
|
|
12
|
+
"type": "metric",
|
|
13
|
+
"title": "Segments summarised",
|
|
14
|
+
"description": "Total summarise_segment spans in range",
|
|
15
|
+
"config": {
|
|
16
|
+
"show_legends": false,
|
|
17
|
+
"legends_position": null,
|
|
18
|
+
"decimals": 0.0,
|
|
19
|
+
"base_map": null,
|
|
20
|
+
"map_view": null,
|
|
21
|
+
"no_value_replacement": "0"
|
|
22
|
+
},
|
|
23
|
+
"queryType": "sql",
|
|
24
|
+
"queries": [
|
|
25
|
+
{
|
|
26
|
+
"query": "SELECT count(*) as \"y_axis_1\" FROM \"default\" WHERE operation_name='summarise_segment'",
|
|
27
|
+
"vrlFunctionQuery": "",
|
|
28
|
+
"customQuery": true,
|
|
29
|
+
"fields": {
|
|
30
|
+
"stream": "default",
|
|
31
|
+
"stream_type": "traces",
|
|
32
|
+
"x": [],
|
|
33
|
+
"y": [
|
|
34
|
+
{
|
|
35
|
+
"label": "Segments",
|
|
36
|
+
"alias": "y_axis_1",
|
|
37
|
+
"column": "y_axis_1",
|
|
38
|
+
"type": "custom",
|
|
39
|
+
"color": "#5960b2",
|
|
40
|
+
"args": [],
|
|
41
|
+
"isDerived": false,
|
|
42
|
+
"havingConditions": []
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"z": [],
|
|
46
|
+
"breakdown": [],
|
|
47
|
+
"filter": {
|
|
48
|
+
"filterType": "group",
|
|
49
|
+
"logicalOperator": "AND",
|
|
50
|
+
"conditions": []
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"config": {
|
|
54
|
+
"promql_legend": "",
|
|
55
|
+
"layer_type": "scatter",
|
|
56
|
+
"weight_fixed": 1.0
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
"layout": {
|
|
61
|
+
"x": 0,
|
|
62
|
+
"y": 0,
|
|
63
|
+
"w": 32,
|
|
64
|
+
"h": 18,
|
|
65
|
+
"i": 1
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"id": "stat_with_prior",
|
|
70
|
+
"type": "metric",
|
|
71
|
+
"title": "With continuity",
|
|
72
|
+
"description": "Segments summarised with the prior burst's summary as context",
|
|
73
|
+
"config": {
|
|
74
|
+
"show_legends": false,
|
|
75
|
+
"legends_position": null,
|
|
76
|
+
"decimals": 0.0,
|
|
77
|
+
"base_map": null,
|
|
78
|
+
"map_view": null,
|
|
79
|
+
"no_value_replacement": "0"
|
|
80
|
+
},
|
|
81
|
+
"queryType": "sql",
|
|
82
|
+
"queries": [
|
|
83
|
+
{
|
|
84
|
+
"query": "SELECT count(*) as \"y_axis_1\" FROM \"default\" WHERE operation_name='summarise_segment' AND prior_present='true'",
|
|
85
|
+
"vrlFunctionQuery": "",
|
|
86
|
+
"customQuery": true,
|
|
87
|
+
"fields": {
|
|
88
|
+
"stream": "default",
|
|
89
|
+
"stream_type": "traces",
|
|
90
|
+
"x": [],
|
|
91
|
+
"y": [
|
|
92
|
+
{
|
|
93
|
+
"label": "With continuity",
|
|
94
|
+
"alias": "y_axis_1",
|
|
95
|
+
"column": "y_axis_1",
|
|
96
|
+
"type": "custom",
|
|
97
|
+
"color": "#59b27a",
|
|
98
|
+
"args": [],
|
|
99
|
+
"isDerived": false,
|
|
100
|
+
"havingConditions": []
|
|
101
|
+
}
|
|
102
|
+
],
|
|
103
|
+
"z": [],
|
|
104
|
+
"breakdown": [],
|
|
105
|
+
"filter": {
|
|
106
|
+
"filterType": "group",
|
|
107
|
+
"logicalOperator": "AND",
|
|
108
|
+
"conditions": []
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
"config": {
|
|
112
|
+
"promql_legend": "",
|
|
113
|
+
"layer_type": "scatter",
|
|
114
|
+
"weight_fixed": 1.0
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
],
|
|
118
|
+
"layout": {
|
|
119
|
+
"x": 32,
|
|
120
|
+
"y": 0,
|
|
121
|
+
"w": 32,
|
|
122
|
+
"h": 18,
|
|
123
|
+
"i": 2
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"id": "stat_continuity_rate",
|
|
128
|
+
"type": "metric",
|
|
129
|
+
"title": "Continuity rate %",
|
|
130
|
+
"description": "Share of segments that carried prior-burst context",
|
|
131
|
+
"config": {
|
|
132
|
+
"show_legends": false,
|
|
133
|
+
"legends_position": null,
|
|
134
|
+
"unit": "percent",
|
|
135
|
+
"decimals": 1.0,
|
|
136
|
+
"base_map": null,
|
|
137
|
+
"map_view": null,
|
|
138
|
+
"no_value_replacement": "0"
|
|
139
|
+
},
|
|
140
|
+
"queryType": "sql",
|
|
141
|
+
"queries": [
|
|
142
|
+
{
|
|
143
|
+
"query": "SELECT round(100.0 * sum(CASE WHEN prior_present='true' THEN 1 ELSE 0 END) / count(*), 1) as \"y_axis_1\" FROM \"default\" WHERE operation_name='summarise_segment'",
|
|
144
|
+
"vrlFunctionQuery": "",
|
|
145
|
+
"customQuery": true,
|
|
146
|
+
"fields": {
|
|
147
|
+
"stream": "default",
|
|
148
|
+
"stream_type": "traces",
|
|
149
|
+
"x": [],
|
|
150
|
+
"y": [
|
|
151
|
+
{
|
|
152
|
+
"label": "Continuity rate",
|
|
153
|
+
"alias": "y_axis_1",
|
|
154
|
+
"column": "y_axis_1",
|
|
155
|
+
"type": "custom",
|
|
156
|
+
"color": "#b29959",
|
|
157
|
+
"args": [],
|
|
158
|
+
"isDerived": false,
|
|
159
|
+
"havingConditions": []
|
|
160
|
+
}
|
|
161
|
+
],
|
|
162
|
+
"z": [],
|
|
163
|
+
"breakdown": [],
|
|
164
|
+
"filter": {
|
|
165
|
+
"filterType": "group",
|
|
166
|
+
"logicalOperator": "AND",
|
|
167
|
+
"conditions": []
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
"config": {
|
|
171
|
+
"promql_legend": "",
|
|
172
|
+
"layer_type": "scatter",
|
|
173
|
+
"weight_fixed": 1.0
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
],
|
|
177
|
+
"layout": {
|
|
178
|
+
"x": 64,
|
|
179
|
+
"y": 0,
|
|
180
|
+
"w": 32,
|
|
181
|
+
"h": 18,
|
|
182
|
+
"i": 3
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"id": "stat_fallback",
|
|
187
|
+
"type": "metric",
|
|
188
|
+
"title": "MLX fallback %",
|
|
189
|
+
"description": "Share summarised by the MLX fallback (primary agent CLI unavailable) — primary-engine health",
|
|
190
|
+
"config": {
|
|
191
|
+
"show_legends": false,
|
|
192
|
+
"legends_position": null,
|
|
193
|
+
"decimals": 1.0,
|
|
194
|
+
"base_map": null,
|
|
195
|
+
"map_view": null,
|
|
196
|
+
"no_value_replacement": "0",
|
|
197
|
+
"unit": "percent"
|
|
198
|
+
},
|
|
199
|
+
"queryType": "sql",
|
|
200
|
+
"queries": [
|
|
201
|
+
{
|
|
202
|
+
"query": "SELECT round(100.0 * sum(CASE WHEN summary_source='mlx' THEN 1 ELSE 0 END) / count(*), 1) as \"y_axis_1\" FROM \"default\" WHERE operation_name='summarise_segment'",
|
|
203
|
+
"vrlFunctionQuery": "",
|
|
204
|
+
"customQuery": true,
|
|
205
|
+
"fields": {
|
|
206
|
+
"stream": "default",
|
|
207
|
+
"stream_type": "traces",
|
|
208
|
+
"x": [],
|
|
209
|
+
"y": [
|
|
210
|
+
{
|
|
211
|
+
"label": "MLX fallback %",
|
|
212
|
+
"alias": "y_axis_1",
|
|
213
|
+
"column": "y_axis_1",
|
|
214
|
+
"type": "custom",
|
|
215
|
+
"color": "#9959b2",
|
|
216
|
+
"args": [],
|
|
217
|
+
"isDerived": false,
|
|
218
|
+
"havingConditions": []
|
|
219
|
+
}
|
|
220
|
+
],
|
|
221
|
+
"z": [],
|
|
222
|
+
"breakdown": [],
|
|
223
|
+
"filter": {
|
|
224
|
+
"filterType": "group",
|
|
225
|
+
"logicalOperator": "AND",
|
|
226
|
+
"conditions": []
|
|
227
|
+
}
|
|
228
|
+
},
|
|
229
|
+
"config": {
|
|
230
|
+
"promql_legend": "",
|
|
231
|
+
"layer_type": "scatter",
|
|
232
|
+
"weight_fixed": 1.0
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
],
|
|
236
|
+
"layout": {
|
|
237
|
+
"x": 96,
|
|
238
|
+
"y": 0,
|
|
239
|
+
"w": 32,
|
|
240
|
+
"h": 18,
|
|
241
|
+
"i": 4
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
"id": "stat_avg_summary",
|
|
246
|
+
"type": "metric",
|
|
247
|
+
"title": "Avg summary chars",
|
|
248
|
+
"description": "Mean length of produced summaries (successful only)",
|
|
249
|
+
"config": {
|
|
250
|
+
"show_legends": false,
|
|
251
|
+
"legends_position": null,
|
|
252
|
+
"decimals": 0.0,
|
|
253
|
+
"base_map": null,
|
|
254
|
+
"map_view": null,
|
|
255
|
+
"no_value_replacement": "0"
|
|
256
|
+
},
|
|
257
|
+
"queryType": "sql",
|
|
258
|
+
"queries": [
|
|
259
|
+
{
|
|
260
|
+
"query": "SELECT round(avg(CAST(summary_chars AS DOUBLE))) as \"y_axis_1\" FROM \"default\" WHERE operation_name='summarise_segment' AND is_error='false'",
|
|
261
|
+
"vrlFunctionQuery": "",
|
|
262
|
+
"customQuery": true,
|
|
263
|
+
"fields": {
|
|
264
|
+
"stream": "default",
|
|
265
|
+
"stream_type": "traces",
|
|
266
|
+
"x": [],
|
|
267
|
+
"y": [
|
|
268
|
+
{
|
|
269
|
+
"label": "Avg summary chars",
|
|
270
|
+
"alias": "y_axis_1",
|
|
271
|
+
"column": "y_axis_1",
|
|
272
|
+
"type": "custom",
|
|
273
|
+
"color": "#59a0b2",
|
|
274
|
+
"args": [],
|
|
275
|
+
"isDerived": false,
|
|
276
|
+
"havingConditions": []
|
|
277
|
+
}
|
|
278
|
+
],
|
|
279
|
+
"z": [],
|
|
280
|
+
"breakdown": [],
|
|
281
|
+
"filter": {
|
|
282
|
+
"filterType": "group",
|
|
283
|
+
"logicalOperator": "AND",
|
|
284
|
+
"conditions": []
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
"config": {
|
|
288
|
+
"promql_legend": "",
|
|
289
|
+
"layer_type": "scatter",
|
|
290
|
+
"weight_fixed": 1.0
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
],
|
|
294
|
+
"layout": {
|
|
295
|
+
"x": 128,
|
|
296
|
+
"y": 0,
|
|
297
|
+
"w": 32,
|
|
298
|
+
"h": 18,
|
|
299
|
+
"i": 5
|
|
300
|
+
}
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
"id": "stat_errors",
|
|
304
|
+
"type": "metric",
|
|
305
|
+
"title": "Errors",
|
|
306
|
+
"description": "Segments that failed to summarise (is_error=true)",
|
|
307
|
+
"config": {
|
|
308
|
+
"show_legends": false,
|
|
309
|
+
"legends_position": null,
|
|
310
|
+
"decimals": 0.0,
|
|
311
|
+
"base_map": null,
|
|
312
|
+
"map_view": null,
|
|
313
|
+
"no_value_replacement": "0"
|
|
314
|
+
},
|
|
315
|
+
"queryType": "sql",
|
|
316
|
+
"queries": [
|
|
317
|
+
{
|
|
318
|
+
"query": "SELECT count(*) as \"y_axis_1\" FROM \"default\" WHERE operation_name='summarise_segment' AND is_error='true'",
|
|
319
|
+
"vrlFunctionQuery": "",
|
|
320
|
+
"customQuery": true,
|
|
321
|
+
"fields": {
|
|
322
|
+
"stream": "default",
|
|
323
|
+
"stream_type": "traces",
|
|
324
|
+
"x": [],
|
|
325
|
+
"y": [
|
|
326
|
+
{
|
|
327
|
+
"label": "Errors",
|
|
328
|
+
"alias": "y_axis_1",
|
|
329
|
+
"column": "y_axis_1",
|
|
330
|
+
"type": "custom",
|
|
331
|
+
"color": "#b25959",
|
|
332
|
+
"args": [],
|
|
333
|
+
"isDerived": false,
|
|
334
|
+
"havingConditions": []
|
|
335
|
+
}
|
|
336
|
+
],
|
|
337
|
+
"z": [],
|
|
338
|
+
"breakdown": [],
|
|
339
|
+
"filter": {
|
|
340
|
+
"filterType": "group",
|
|
341
|
+
"logicalOperator": "AND",
|
|
342
|
+
"conditions": []
|
|
343
|
+
}
|
|
344
|
+
},
|
|
345
|
+
"config": {
|
|
346
|
+
"promql_legend": "",
|
|
347
|
+
"layer_type": "scatter",
|
|
348
|
+
"weight_fixed": 1.0
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
],
|
|
352
|
+
"layout": {
|
|
353
|
+
"x": 160,
|
|
354
|
+
"y": 0,
|
|
355
|
+
"w": 32,
|
|
356
|
+
"h": 18,
|
|
357
|
+
"i": 6
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
"id": "table_all",
|
|
362
|
+
"type": "table",
|
|
363
|
+
"title": "All segments (newest first)",
|
|
364
|
+
"description": "Filter with the Session UUID / Agent / Continuity variables above. 'Prior' = whether the previous burst's summary was injected; 'Prior chars' = how much context carried over. Click any row → opens that trace's spans.",
|
|
365
|
+
"config": {
|
|
366
|
+
"show_legends": false,
|
|
367
|
+
"legends_position": null,
|
|
368
|
+
"base_map": null,
|
|
369
|
+
"map_view": null,
|
|
370
|
+
"drilldown": [
|
|
371
|
+
{
|
|
372
|
+
"name": "Open this trace's spans",
|
|
373
|
+
"type": "byUrl",
|
|
374
|
+
"targetBlank": true,
|
|
375
|
+
"findBy": "name",
|
|
376
|
+
"data": {
|
|
377
|
+
"url": "/web/traces?org_identifier=default&stream=default&search_type=ui&search_mode=spans&period=30d&query=${row.field.trace_filter}",
|
|
378
|
+
"folder": "",
|
|
379
|
+
"dashboard": "",
|
|
380
|
+
"tab": "",
|
|
381
|
+
"passAllVariables": false,
|
|
382
|
+
"variables": []
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
],
|
|
386
|
+
"wrap_table_cells": false,
|
|
387
|
+
"table_dynamic_columns": false
|
|
388
|
+
},
|
|
389
|
+
"queryType": "sql",
|
|
390
|
+
"queries": [
|
|
391
|
+
{
|
|
392
|
+
"query": "SELECT to_char(to_timestamp_micros(_timestamp + 19800000000),'%Y-%m-%d %H:%M:%S') as \"Time\", substr(session_uuid,1,8) as \"Session\", agent as \"Agent\", prior_present as \"Prior\", prior_chars as \"Prior chars\", transcript_chars as \"Transcript chars\", prompt_chars as \"Prompt chars\", summary_chars as \"Summary chars\", summary_source as \"Engine\", is_error as \"Error\", round(CAST(duration AS DOUBLE)/1000000,2) as \"Time taken (s)\", trace_id as \"trace_id\", encode(concat('trace_id=''', trace_id, ''''),'base64') as \"trace_filter\" FROM \"default\" WHERE operation_name='summarise_segment' AND ('$session_uuid'='' OR session_uuid LIKE '%$session_uuid%') AND ('$agent'='' OR agent LIKE '%$agent%') AND ('$continuity'='' OR prior_present='$continuity') ORDER BY _timestamp DESC",
|
|
393
|
+
"vrlFunctionQuery": "",
|
|
394
|
+
"customQuery": true,
|
|
395
|
+
"fields": {
|
|
396
|
+
"stream": "default",
|
|
397
|
+
"stream_type": "traces",
|
|
398
|
+
"x": [
|
|
399
|
+
{
|
|
400
|
+
"label": "Time",
|
|
401
|
+
"alias": "Time",
|
|
402
|
+
"column": "_timestamp",
|
|
403
|
+
"type": "custom",
|
|
404
|
+
"color": null,
|
|
405
|
+
"args": [],
|
|
406
|
+
"isDerived": false,
|
|
407
|
+
"havingConditions": []
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
"label": "Session",
|
|
411
|
+
"alias": "Session",
|
|
412
|
+
"column": "session_uuid",
|
|
413
|
+
"type": "custom",
|
|
414
|
+
"color": null,
|
|
415
|
+
"args": [],
|
|
416
|
+
"isDerived": false,
|
|
417
|
+
"havingConditions": []
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
"label": "Agent",
|
|
421
|
+
"alias": "Agent",
|
|
422
|
+
"column": "agent",
|
|
423
|
+
"type": "custom",
|
|
424
|
+
"color": null,
|
|
425
|
+
"args": [],
|
|
426
|
+
"isDerived": false,
|
|
427
|
+
"havingConditions": []
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
"label": "Prior",
|
|
431
|
+
"alias": "Prior",
|
|
432
|
+
"column": "prior_present",
|
|
433
|
+
"type": "custom",
|
|
434
|
+
"color": null,
|
|
435
|
+
"args": [],
|
|
436
|
+
"isDerived": false,
|
|
437
|
+
"havingConditions": []
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
"label": "Prior chars",
|
|
441
|
+
"alias": "Prior chars",
|
|
442
|
+
"column": "prior_chars",
|
|
443
|
+
"type": "custom",
|
|
444
|
+
"color": null,
|
|
445
|
+
"args": [],
|
|
446
|
+
"isDerived": false,
|
|
447
|
+
"havingConditions": []
|
|
448
|
+
},
|
|
449
|
+
{
|
|
450
|
+
"label": "Transcript chars",
|
|
451
|
+
"alias": "Transcript chars",
|
|
452
|
+
"column": "transcript_chars",
|
|
453
|
+
"type": "custom",
|
|
454
|
+
"color": null,
|
|
455
|
+
"args": [],
|
|
456
|
+
"isDerived": false,
|
|
457
|
+
"havingConditions": []
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
"label": "Prompt chars",
|
|
461
|
+
"alias": "Prompt chars",
|
|
462
|
+
"column": "prompt_chars",
|
|
463
|
+
"type": "custom",
|
|
464
|
+
"color": null,
|
|
465
|
+
"args": [],
|
|
466
|
+
"isDerived": false,
|
|
467
|
+
"havingConditions": []
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
"label": "Summary chars",
|
|
471
|
+
"alias": "Summary chars",
|
|
472
|
+
"column": "summary_chars",
|
|
473
|
+
"type": "custom",
|
|
474
|
+
"color": null,
|
|
475
|
+
"args": [],
|
|
476
|
+
"isDerived": false,
|
|
477
|
+
"havingConditions": []
|
|
478
|
+
},
|
|
479
|
+
{
|
|
480
|
+
"label": "Engine",
|
|
481
|
+
"alias": "Engine",
|
|
482
|
+
"column": "summary_source",
|
|
483
|
+
"type": "custom",
|
|
484
|
+
"color": null,
|
|
485
|
+
"args": [],
|
|
486
|
+
"isDerived": false,
|
|
487
|
+
"havingConditions": []
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
"label": "Error",
|
|
491
|
+
"alias": "Error",
|
|
492
|
+
"column": "is_error",
|
|
493
|
+
"type": "custom",
|
|
494
|
+
"color": null,
|
|
495
|
+
"args": [],
|
|
496
|
+
"isDerived": false,
|
|
497
|
+
"havingConditions": []
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
"label": "Time taken (s)",
|
|
501
|
+
"alias": "Time taken (s)",
|
|
502
|
+
"column": "duration",
|
|
503
|
+
"type": "custom",
|
|
504
|
+
"color": null,
|
|
505
|
+
"args": [],
|
|
506
|
+
"isDerived": false,
|
|
507
|
+
"havingConditions": []
|
|
508
|
+
},
|
|
509
|
+
{
|
|
510
|
+
"label": "Trace ID",
|
|
511
|
+
"alias": "trace_id",
|
|
512
|
+
"column": "trace_id",
|
|
513
|
+
"type": "custom",
|
|
514
|
+
"color": null,
|
|
515
|
+
"args": [],
|
|
516
|
+
"isDerived": false,
|
|
517
|
+
"havingConditions": []
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
"label": "trace_filter",
|
|
521
|
+
"alias": "trace_filter",
|
|
522
|
+
"column": "trace_filter",
|
|
523
|
+
"type": "custom",
|
|
524
|
+
"color": null,
|
|
525
|
+
"args": [],
|
|
526
|
+
"isDerived": false,
|
|
527
|
+
"havingConditions": []
|
|
528
|
+
}
|
|
529
|
+
],
|
|
530
|
+
"y": [],
|
|
531
|
+
"z": [],
|
|
532
|
+
"breakdown": [],
|
|
533
|
+
"filter": {
|
|
534
|
+
"filterType": "group",
|
|
535
|
+
"logicalOperator": "AND",
|
|
536
|
+
"conditions": []
|
|
537
|
+
}
|
|
538
|
+
},
|
|
539
|
+
"config": {
|
|
540
|
+
"promql_legend": "",
|
|
541
|
+
"layer_type": "scatter",
|
|
542
|
+
"weight_fixed": 1.0
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
],
|
|
546
|
+
"layout": {
|
|
547
|
+
"x": 0,
|
|
548
|
+
"y": 18,
|
|
549
|
+
"w": 192,
|
|
550
|
+
"h": 40,
|
|
551
|
+
"i": 7
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
]
|
|
555
|
+
}
|
|
556
|
+
],
|
|
557
|
+
"variables": {
|
|
558
|
+
"list": [
|
|
559
|
+
{
|
|
560
|
+
"type": "textbox",
|
|
561
|
+
"name": "session_uuid",
|
|
562
|
+
"label": "Session UUID",
|
|
563
|
+
"query_data": null,
|
|
564
|
+
"value": "",
|
|
565
|
+
"options": [],
|
|
566
|
+
"multiSelect": false,
|
|
567
|
+
"hideOnDashboard": false,
|
|
568
|
+
"selectAllValueForMultiSelect": "custom",
|
|
569
|
+
"customMultiSelectValue": [],
|
|
570
|
+
"escapeSingleQuotes": true
|
|
571
|
+
},
|
|
572
|
+
{
|
|
573
|
+
"type": "textbox",
|
|
574
|
+
"name": "agent",
|
|
575
|
+
"label": "Agent",
|
|
576
|
+
"query_data": null,
|
|
577
|
+
"value": "",
|
|
578
|
+
"options": [],
|
|
579
|
+
"multiSelect": false,
|
|
580
|
+
"hideOnDashboard": false,
|
|
581
|
+
"selectAllValueForMultiSelect": "custom",
|
|
582
|
+
"customMultiSelectValue": [],
|
|
583
|
+
"escapeSingleQuotes": true
|
|
584
|
+
},
|
|
585
|
+
{
|
|
586
|
+
"type": "custom",
|
|
587
|
+
"name": "continuity",
|
|
588
|
+
"label": "Continuity",
|
|
589
|
+
"query_data": null,
|
|
590
|
+
"value": "",
|
|
591
|
+
"options": [
|
|
592
|
+
{
|
|
593
|
+
"label": "All",
|
|
594
|
+
"value": "",
|
|
595
|
+
"selected": true
|
|
596
|
+
},
|
|
597
|
+
{
|
|
598
|
+
"label": "With prior",
|
|
599
|
+
"value": "true",
|
|
600
|
+
"selected": false
|
|
601
|
+
},
|
|
602
|
+
{
|
|
603
|
+
"label": "Fresh burst",
|
|
604
|
+
"value": "false",
|
|
605
|
+
"selected": false
|
|
606
|
+
}
|
|
607
|
+
],
|
|
608
|
+
"multiSelect": false,
|
|
609
|
+
"hideOnDashboard": false,
|
|
610
|
+
"selectAllValueForMultiSelect": "custom",
|
|
611
|
+
"customMultiSelectValue": [],
|
|
612
|
+
"escapeSingleQuotes": true
|
|
613
|
+
}
|
|
614
|
+
],
|
|
615
|
+
"showDynamicFilters": true
|
|
616
|
+
},
|
|
617
|
+
"defaultDatetimeDuration": {
|
|
618
|
+
"type": "relative",
|
|
619
|
+
"relativeTimePeriod": "12h"
|
|
620
|
+
}
|
|
621
|
+
}
|
package/services/pyproject.toml
CHANGED
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "meridian-agents"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.62.0"
|
|
8
8
|
description = "Meridian agents — MLX classifier server and Jira worklog synthesis for meridian.db"
|
|
9
9
|
requires-python = ">=3.11"
|
|
10
10
|
authors = [{ name = "Meridiona" }]
|
package/ui.tar.gz
CHANGED
|
Binary file
|