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.
Files changed (38) hide show
  1. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/PKG-INFO +1 -1
  2. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/cli.py +4 -1
  3. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/static/monitor.html +81 -70
  4. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/pyproject.toml +1 -1
  5. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/.github/workflows/ci.yml +0 -0
  6. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/.github/workflows/publish.yml +0 -0
  7. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/.gitignore +0 -0
  8. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/CHANGELOG.md +0 -0
  9. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/CONTRIBUTING.md +0 -0
  10. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/Dockerfile +0 -0
  11. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/LICENSE +0 -0
  12. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/README.md +0 -0
  13. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/__init__.py +0 -0
  14. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/adapters/__init__.py +0 -0
  15. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/adapters/bedrock.py +0 -0
  16. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/adapters/cohere.py +0 -0
  17. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/adapters/gemini.py +0 -0
  18. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/adapters/groq.py +0 -0
  19. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/adapters/litellm.py +0 -0
  20. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/adapters/mistral.py +0 -0
  21. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/adapters/together.py +0 -0
  22. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/client.py +0 -0
  23. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/core.py +0 -0
  24. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/learning.py +0 -0
  25. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/persistence.py +0 -0
  26. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/server.py +0 -0
  27. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/testing.py +0 -0
  28. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/axel/universal.py +0 -0
  29. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/docker-compose.yml +0 -0
  30. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/docs/message-schemas.md +0 -0
  31. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/examples/demo_live.py +0 -0
  32. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/install.sh +0 -0
  33. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/tests/__init__.py +0 -0
  34. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/tests/test_adapters.py +0 -0
  35. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/tests/test_client.py +0 -0
  36. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/tests/test_core.py +0 -0
  37. {axel_protocol-2.3.7 → axel_protocol-2.3.8}/tests/test_new_features.py +0 -0
  38. {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.7
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
- /* ── Mission input bar ── */
67
- .mission-bar {
68
- display: flex; align-items: center; gap: 10px;
69
- padding: 8px 18px; background: rgba(129,140,248,.04);
70
- border-bottom: 1px solid var(--border); flex-shrink: 0;
71
- }
72
- .mission-input {
73
- flex: 1; background: var(--bg); border: 1px solid var(--border); color: var(--text);
74
- padding: 7px 12px; border-radius: 7px; font-size: 12px;
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
- .mission-input:focus { outline: none; border-color: var(--accent); }
78
- .mission-input::placeholder { color: var(--muted); }
79
- .mission-btn {
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: 7px 16px; border-radius: 7px; font-size: 12px; font-weight: 600; cursor: pointer;
82
- white-space: nowrap; transition: opacity .2s;
83
- }
84
- .mission-btn:hover { opacity: .85; }
85
- .mission-btn:disabled { opacity: .4; cursor: default; }
86
- .mission-status { font-size: 11px; color: var(--muted); white-space: nowrap; min-width: 120px; }
87
- .mission-status.sent { color: var(--green); }
88
- .mission-status.waiting { color: var(--yellow); }
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 Library bar ── */
227
- .topic-bar {
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="mission-bar">
393
- <span style="font-size:13px">🎯</span>
394
- <input class="mission-input" id="missionInput" placeholder="Give the agents a task… e.g. 'Research the impact of AI on creative industries'" />
395
- <button class="mission-btn" id="missionBtn" onclick="submitMission()">Send to Agents →</button>
396
- <span class="mission-status" id="missionStatus">agents running autonomously</span>
397
- </div>
398
-
399
- <div class="topic-bar">
400
- <span style="font-size:15px;line-height:1;padding-top:1px">📚</span>
401
- <div class="topic-bar-body">
402
- <div class="topic-bar-label">Learning Topics <span style="font-weight:400;text-transform:none;letter-spacing:0;color:var(--muted)">— agents will cycle through these instead of built-in topics</span></div>
403
- <div class="topic-bar-row">
404
- <input class="topic-input" id="topicInput" placeholder="Add a topic… e.g. 'The ethics of autonomous AI systems'" />
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">No topics yet — agents use built-in rotation</span>
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 = '⏳ waiting for agents…'; status.className = 'mission-status waiting'; }
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 = 'mission-status';
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 — agents will pick it up next run';
1098
- status.className = 'mission-status sent';
1101
+ status.textContent = '✓ queued';
1102
+ status.className = 'ctrl-status sent';
1099
1103
  input.value = '';
1100
1104
  setTimeout(() => {
1101
- status.textContent = 'agents running autonomously';
1102
- status.className = 'mission-status';
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
- // Extract score from review if present (looks for "X/10")
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
- (draft || '').slice(0, 300) + ((draft||'').length > 300 ? '…' : '');
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 || '').slice(0, 280) + ((review||'').length > 280 ? '…' : '');
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');
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "axel-protocol"
7
- version = "2.3.7"
7
+ version = "2.3.8"
8
8
  description = "AXEL — Agent eXchange Language: a universal protocol for multi-LLM networks"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
File without changes
File without changes
File without changes
File without changes
File without changes