axel-protocol 2.3.7__tar.gz → 2.3.8__tar.gz
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.
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/PKG-INFO +1 -1
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/cli.py +4 -1
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/static/monitor.html +81 -70
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/pyproject.toml +1 -1
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/.github/workflows/ci.yml +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/.github/workflows/publish.yml +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/.gitignore +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/CHANGELOG.md +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/CONTRIBUTING.md +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/Dockerfile +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/LICENSE +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/README.md +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/__init__.py +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/adapters/__init__.py +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/adapters/bedrock.py +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/adapters/cohere.py +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/adapters/gemini.py +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/adapters/groq.py +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/adapters/litellm.py +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/adapters/mistral.py +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/adapters/together.py +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/client.py +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/core.py +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/learning.py +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/persistence.py +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/server.py +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/testing.py +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/universal.py +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/docker-compose.yml +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/docs/message-schemas.md +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/examples/demo_live.py +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/install.sh +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/tests/__init__.py +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/tests/test_adapters.py +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/tests/test_client.py +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/tests/test_core.py +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/tests/test_new_features.py +0 -0
- {axel_protocol-2.3.7 → axel_protocol-2.3.8}/tests/test_server.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: axel-protocol
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.8
|
|
4
4
|
Summary: AXEL — Agent eXchange Language: a universal protocol for multi-LLM networks
|
|
5
5
|
Project-URL: Homepage, https://github.com/sectorx/axel-protocol
|
|
6
6
|
Project-URL: Repository, https://github.com/sectorx/axel-protocol
|
|
@@ -454,13 +454,16 @@ def _fire_run_complete(server: str, run: int, topic: str,
|
|
|
454
454
|
import json as _json
|
|
455
455
|
import urllib.request as _ur
|
|
456
456
|
import uuid as _uuid
|
|
457
|
+
# Strip "[X skipped]" placeholders produced when all fallbacks exhaust
|
|
458
|
+
def _ok(s: str) -> str:
|
|
459
|
+
return (s or '') if not ('[' in (s or '') and 'skipped' in (s or '')) else ''
|
|
457
460
|
msg = {
|
|
458
461
|
"t": "RC", "v": "2.1",
|
|
459
462
|
"id": str(_uuid.uuid4()),
|
|
460
463
|
"fr": "axel-demo", "to": "dashboard",
|
|
461
464
|
"body": {
|
|
462
465
|
"run": run, "topic": topic,
|
|
463
|
-
"summary": summary, "draft": draft, "review": review,
|
|
466
|
+
"summary": _ok(summary), "draft": _ok(draft), "review": _ok(review),
|
|
464
467
|
},
|
|
465
468
|
}
|
|
466
469
|
data = _json.dumps(msg).encode()
|
|
@@ -63,29 +63,53 @@ header {
|
|
|
63
63
|
.stat-val { font-size: 20px; font-weight: 700; color: var(--accent); line-height: 1; }
|
|
64
64
|
.stat-lbl { font-size: 9px; text-transform: uppercase; letter-spacing: .8px; color: var(--muted); margin-top: 2px; }
|
|
65
65
|
|
|
66
|
-
/* ──
|
|
67
|
-
.
|
|
68
|
-
display: flex; align-items:
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
66
|
+
/* ── Combined control bar (mission left, topics right) ── */
|
|
67
|
+
.ctrl-bar {
|
|
68
|
+
display: flex; align-items: stretch; flex-shrink: 0;
|
|
69
|
+
border-bottom: 1px solid var(--border); min-height: 46px;
|
|
70
|
+
}
|
|
71
|
+
.ctrl-mission {
|
|
72
|
+
flex: 1; display: flex; align-items: center; gap: 8px;
|
|
73
|
+
padding: 7px 14px; background: rgba(129,140,248,.03);
|
|
74
|
+
}
|
|
75
|
+
.ctrl-input {
|
|
76
|
+
flex: 1; min-width: 0; background: var(--bg); border: 1px solid var(--border);
|
|
77
|
+
color: var(--text); padding: 6px 10px; border-radius: 6px; font-size: 12px;
|
|
75
78
|
transition: border-color .2s;
|
|
76
79
|
}
|
|
77
|
-
.
|
|
78
|
-
.
|
|
79
|
-
.
|
|
80
|
+
.ctrl-input:focus { outline: none; border-color: var(--accent); }
|
|
81
|
+
.ctrl-input::placeholder { color: var(--muted); }
|
|
82
|
+
.ctrl-send-btn {
|
|
80
83
|
background: var(--accent); color: #fff; border: none;
|
|
81
|
-
padding:
|
|
82
|
-
white-space: nowrap; transition: opacity .2s;
|
|
83
|
-
}
|
|
84
|
-
.
|
|
85
|
-
.
|
|
86
|
-
.
|
|
87
|
-
.
|
|
88
|
-
.
|
|
84
|
+
padding: 6px 13px; border-radius: 6px; font-size: 12px; font-weight: 600;
|
|
85
|
+
cursor: pointer; white-space: nowrap; transition: opacity .2s; flex-shrink: 0;
|
|
86
|
+
}
|
|
87
|
+
.ctrl-send-btn:hover { opacity: .85; }
|
|
88
|
+
.ctrl-send-btn:disabled { opacity: .4; cursor: default; }
|
|
89
|
+
.ctrl-status { font-size: 10px; color: var(--muted); white-space: nowrap; flex-shrink: 0; min-width: 55px; }
|
|
90
|
+
.ctrl-status.sent { color: var(--green); }
|
|
91
|
+
.ctrl-status.waiting { color: var(--yellow); }
|
|
92
|
+
.ctrl-topics {
|
|
93
|
+
width: 300px; flex-shrink: 0; display: flex; flex-direction: column; justify-content: center;
|
|
94
|
+
gap: 4px; padding: 5px 12px; border-left: 1px solid var(--border);
|
|
95
|
+
background: rgba(251,191,36,.02);
|
|
96
|
+
}
|
|
97
|
+
.ctrl-topics-top { display: flex; align-items: center; gap: 6px; }
|
|
98
|
+
.ctrl-topics-lbl {
|
|
99
|
+
font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .6px;
|
|
100
|
+
color: var(--yellow); white-space: nowrap; flex-shrink: 0;
|
|
101
|
+
}
|
|
102
|
+
.ctrl-topic-input {
|
|
103
|
+
flex: 1; min-width: 0; background: var(--bg); border: 1px solid var(--border);
|
|
104
|
+
color: var(--text); padding: 4px 7px; border-radius: 5px; font-size: 11px;
|
|
105
|
+
}
|
|
106
|
+
.ctrl-topic-input:focus { outline: none; border-color: var(--yellow); }
|
|
107
|
+
.ctrl-topic-btn {
|
|
108
|
+
padding: 3px 9px; border-radius: 5px; border: 1px solid rgba(251,191,36,.4);
|
|
109
|
+
background: rgba(251,191,36,.08); color: var(--yellow); font-size: 15px; font-weight: 300;
|
|
110
|
+
cursor: pointer; flex-shrink: 0; line-height: 1.3; transition: background .15s;
|
|
111
|
+
}
|
|
112
|
+
.ctrl-topic-btn:hover { background: rgba(251,191,36,.18); }
|
|
89
113
|
|
|
90
114
|
/* ── Progress strip ── */
|
|
91
115
|
.progress-strip {
|
|
@@ -223,27 +247,8 @@ header {
|
|
|
223
247
|
.conf-bar { height: 2px; background: var(--border); border-radius: 2px; margin-top: 5px; }
|
|
224
248
|
.conf-fill { height: 100%; background: var(--green); border-radius: 2px; transition: width .5s; }
|
|
225
249
|
|
|
226
|
-
/* ── Topic
|
|
227
|
-
.topic-
|
|
228
|
-
display: flex; align-items: flex-start; gap: 10px;
|
|
229
|
-
padding: 8px 18px; background: rgba(251,191,36,.03);
|
|
230
|
-
border-bottom: 1px solid var(--border); flex-shrink: 0;
|
|
231
|
-
}
|
|
232
|
-
.topic-bar-label { font-size: 10px; text-transform: uppercase; letter-spacing: .7px; color: var(--yellow); font-weight: 700; }
|
|
233
|
-
.topic-bar-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
|
|
234
|
-
.topic-bar-row { display: flex; align-items: center; gap: 8px; }
|
|
235
|
-
.topic-input {
|
|
236
|
-
flex: 1; background: var(--bg); border: 1px solid var(--border); color: var(--text);
|
|
237
|
-
padding: 5px 10px; border-radius: 6px; font-size: 12px; min-width: 0;
|
|
238
|
-
}
|
|
239
|
-
.topic-input:focus { outline: none; border-color: var(--yellow); }
|
|
240
|
-
.topic-add-btn {
|
|
241
|
-
padding: 5px 12px; border-radius: 6px; border: 1px solid rgba(251,191,36,.4);
|
|
242
|
-
background: rgba(251,191,36,.08); color: var(--yellow); font-size: 12px; cursor: pointer;
|
|
243
|
-
white-space: nowrap; transition: background .15s;
|
|
244
|
-
}
|
|
245
|
-
.topic-add-btn:hover { background: rgba(251,191,36,.18); }
|
|
246
|
-
.topic-chips { display: flex; flex-wrap: wrap; gap: 5px; }
|
|
250
|
+
/* ── Topic chips (used inside .ctrl-topics) ── */
|
|
251
|
+
.topic-chips { display: flex; flex-wrap: wrap; gap: 4px; }
|
|
247
252
|
.topic-chip {
|
|
248
253
|
display: inline-flex; align-items: center; gap: 5px;
|
|
249
254
|
background: rgba(251,191,36,.1); border: 1px solid rgba(251,191,36,.25);
|
|
@@ -389,23 +394,22 @@ header {
|
|
|
389
394
|
<div class="stat"><div class="stat-val" id="sUptime">–</div><div class="stat-lbl">Uptime</div></div>
|
|
390
395
|
</div>
|
|
391
396
|
|
|
392
|
-
<div class="
|
|
393
|
-
<
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
<
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
<
|
|
405
|
-
<button class="topic-add-btn" onclick="addTopic()">+ Add Topic</button>
|
|
397
|
+
<div class="ctrl-bar">
|
|
398
|
+
<div class="ctrl-mission">
|
|
399
|
+
<span style="font-size:12px;flex-shrink:0">🎯</span>
|
|
400
|
+
<input class="ctrl-input" id="missionInput"
|
|
401
|
+
placeholder="Give agents a one-off task… e.g. 'Will AI replace software engineers in 10 years?'" />
|
|
402
|
+
<button class="ctrl-send-btn" id="missionBtn" onclick="submitMission()">Send to Agents →</button>
|
|
403
|
+
<span class="ctrl-status" id="missionStatus"></span>
|
|
404
|
+
</div>
|
|
405
|
+
<div class="ctrl-topics">
|
|
406
|
+
<div class="ctrl-topics-top">
|
|
407
|
+
<span class="ctrl-topics-lbl">📚 Topics</span>
|
|
408
|
+
<input class="ctrl-topic-input" id="topicInput" placeholder="Add recurring topic…" />
|
|
409
|
+
<button class="ctrl-topic-btn" onclick="addTopic()">+</button>
|
|
406
410
|
</div>
|
|
407
411
|
<div class="topic-chips" id="topicChips">
|
|
408
|
-
<span class="topic-empty">
|
|
412
|
+
<span class="topic-empty">built-in rotation</span>
|
|
409
413
|
</div>
|
|
410
414
|
</div>
|
|
411
415
|
</div>
|
|
@@ -698,7 +702,7 @@ function onEvent(d) {
|
|
|
698
702
|
const task = p.task || p.data?.task || '';
|
|
699
703
|
addFeed('announce', '🎯', `<b>User</b> sent a mission: <i>${esc(task.slice(0,80))}${task.length>80?'…':''}</i>`, 'Agents will pick this up on the next run', { rawType:'USER', fullPrompt: task });
|
|
700
704
|
const status = document.getElementById('missionStatus');
|
|
701
|
-
if (status) { status.textContent = '⏳
|
|
705
|
+
if (status) { status.textContent = '⏳ queued'; status.className = 'ctrl-status waiting'; }
|
|
702
706
|
|
|
703
707
|
} else if (p.t === 'PROG' || type.includes('progress')) {
|
|
704
708
|
const b = p.body || p;
|
|
@@ -1084,7 +1088,7 @@ function submitMission() {
|
|
|
1084
1088
|
|
|
1085
1089
|
btn.disabled = true;
|
|
1086
1090
|
status.textContent = 'sending…';
|
|
1087
|
-
status.className = '
|
|
1091
|
+
status.className = 'ctrl-status';
|
|
1088
1092
|
|
|
1089
1093
|
fetch(serverUrl + '/queue', {
|
|
1090
1094
|
method: 'POST',
|
|
@@ -1094,12 +1098,12 @@ function submitMission() {
|
|
|
1094
1098
|
.then(r => r.json())
|
|
1095
1099
|
.then(d => {
|
|
1096
1100
|
if (d.ok) {
|
|
1097
|
-
status.textContent = '✓ queued
|
|
1098
|
-
status.className = '
|
|
1101
|
+
status.textContent = '✓ queued';
|
|
1102
|
+
status.className = 'ctrl-status sent';
|
|
1099
1103
|
input.value = '';
|
|
1100
1104
|
setTimeout(() => {
|
|
1101
|
-
status.textContent = '
|
|
1102
|
-
status.className = '
|
|
1105
|
+
status.textContent = '';
|
|
1106
|
+
status.className = 'ctrl-status';
|
|
1103
1107
|
btn.disabled = false;
|
|
1104
1108
|
}, 4000);
|
|
1105
1109
|
} else {
|
|
@@ -1180,22 +1184,29 @@ function loadTopics() {
|
|
|
1180
1184
|
|
|
1181
1185
|
// ─── Run Output panel ──────────────────────────────────────────
|
|
1182
1186
|
function showRunOutput(run, topic, summary, draft, review) {
|
|
1187
|
+
// Strip any [X skipped] placeholders that slipped through
|
|
1188
|
+
const clean = s => (s && s.includes('skipped')) ? '' : (s || '');
|
|
1189
|
+
summary = clean(summary); draft = clean(draft); review = clean(review);
|
|
1190
|
+
|
|
1183
1191
|
const panel = document.getElementById('outputPanel');
|
|
1184
1192
|
panel.style.display = 'block';
|
|
1185
|
-
panel.classList.add('open');
|
|
1186
1193
|
document.getElementById('outputBadge').textContent = `Run #${run} complete ✓`;
|
|
1187
1194
|
document.getElementById('outputTopic').textContent = '📝 ' + (topic || 'unknown topic');
|
|
1188
|
-
document.getElementById('outputSummary').textContent = summary || '(no summary)';
|
|
1189
1195
|
|
|
1190
|
-
|
|
1196
|
+
const hasContent = summary || draft || review;
|
|
1197
|
+
if (hasContent) panel.classList.add('open');
|
|
1198
|
+
|
|
1199
|
+
document.getElementById('outputSummary').textContent =
|
|
1200
|
+
summary || '(summarizer did not return output this run)';
|
|
1201
|
+
|
|
1191
1202
|
const scoreMatch = (review || '').match(/(\d{1,2})\/10/);
|
|
1192
|
-
const scoreHtml = scoreMatch
|
|
1193
|
-
? `<span class="output-score">${scoreMatch[0]}</span>`
|
|
1194
|
-
: '';
|
|
1203
|
+
const scoreHtml = scoreMatch ? `<span class="output-score">${scoreMatch[0]}</span>` : '';
|
|
1195
1204
|
document.getElementById('outputDraft').textContent =
|
|
1196
|
-
|
|
1205
|
+
draft ? (draft.slice(0, 300) + (draft.length > 300 ? '…' : ''))
|
|
1206
|
+
: '(writer did not return output this run)';
|
|
1197
1207
|
document.getElementById('outputReview').innerHTML =
|
|
1198
|
-
scoreHtml + esc(review
|
|
1208
|
+
review ? scoreHtml + esc(review).slice(0, 280) + (review.length > 280 ? '…' : '')
|
|
1209
|
+
: '(reviewer did not return output this run)';
|
|
1199
1210
|
|
|
1200
1211
|
// Flash green to draw attention
|
|
1201
1212
|
panel.classList.remove('flash');
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|