gini-toolkit 6.0.1.dev0__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.
- gini/__init__.py +12 -0
- gini/__main__.py +107 -0
- gini/_version.py +24 -0
- gini/agent/__init__.py +17 -0
- gini/agent/agent_gamemaster.py +140 -0
- gini/agent/api.py +291 -0
- gini/agent/ask.py +123 -0
- gini/agent/authoring.py +72 -0
- gini/agent/blackboard.py +114 -0
- gini/agent/contracts.py +142 -0
- gini/agent/domains.py +91 -0
- gini/agent/embed.py +123 -0
- gini/agent/gamemaster.py +256 -0
- gini/agent/kb.py +148 -0
- gini/agent/lesson_resolver.py +261 -0
- gini/agent/llm/__init__.py +5 -0
- gini/agent/llm/backend.py +43 -0
- gini/agent/llm/fake.py +25 -0
- gini/agent/llm/ollama.py +206 -0
- gini/agent/loop.py +258 -0
- gini/agent/mcp_server.py +86 -0
- gini/agent/meaning.py +225 -0
- gini/agent/mission.py +210 -0
- gini/agent/mission_controller.py +208 -0
- gini/agent/narration.py +116 -0
- gini/agent/notifier.py +86 -0
- gini/agent/personas.py +79 -0
- gini/agent/reasoning.py +172 -0
- gini/agent/recall.py +248 -0
- gini/agent/session.py +79 -0
- gini/agent/teaching_center.py +482 -0
- gini/agent/tools/__init__.py +3 -0
- gini/agent/tools/registry.py +193 -0
- gini/agent/twin/__init__.py +28 -0
- gini/agent/twin/authoring.py +71 -0
- gini/agent/twin/contracts.py +54 -0
- gini/agent/twin/dialectic.py +189 -0
- gini/agent/twin/harness.py +93 -0
- gini/agent/twin/justify.py +156 -0
- gini/agent/twin/learner.py +64 -0
- gini/agent/twin/mission.py +60 -0
- gini/agent/twin/os_coach.py +79 -0
- gini/agent/twin/salience.py +30 -0
- gini/agent/understand.py +250 -0
- gini/agent/verifiers.py +106 -0
- gini/agent/wizard.py +178 -0
- gini/agent/xv6_pack.py +74 -0
- gini/app/__init__.py +3 -0
- gini/app/context.py +368 -0
- gini/app/paths.py +121 -0
- gini/data/README.md +21 -0
- gini/domain/__init__.py +9 -0
- gini/domain/assembly.py +209 -0
- gini/domain/authoring.py +353 -0
- gini/domain/blueprints.py +5 -0
- gini/domain/capabilities.py +177 -0
- gini/domain/catalog.py +85 -0
- gini/domain/certify.py +201 -0
- gini/domain/compose.py +413 -0
- gini/domain/composition.py +88 -0
- gini/domain/concepts.py +383 -0
- gini/domain/connection_rules.py +269 -0
- gini/domain/constraints.py +153 -0
- gini/domain/content.py +59 -0
- gini/domain/cpu_journey.py +89 -0
- gini/domain/devices.py +747 -0
- gini/domain/diagnose.py +201 -0
- gini/domain/element_guide.py +327 -0
- gini/domain/explain.py +90 -0
- gini/domain/fingerprint.py +201 -0
- gini/domain/firewall.py +34 -0
- gini/domain/flowlog.py +61 -0
- gini/domain/flowtable.py +179 -0
- gini/domain/fragment_yaml.py +230 -0
- gini/domain/fragments.py +169 -0
- gini/domain/games/__init__.py +2 -0
- gini/domain/games/paging_games.py +119 -0
- gini/domain/games/policy_game.py +86 -0
- gini/domain/games/process_game.py +48 -0
- gini/domain/games/thrash_game.py +75 -0
- gini/domain/games/translate_game.py +60 -0
- gini/domain/games/trap_game.py +86 -0
- gini/domain/grader.py +155 -0
- gini/domain/grouping.py +67 -0
- gini/domain/legality.py +103 -0
- gini/domain/lesson.py +241 -0
- gini/domain/lexicon.py +150 -0
- gini/domain/machine_state.py +410 -0
- gini/domain/missions/networking/basic-lan.yaml +32 -0
- gini/domain/missions/networking/cache-in-front.yaml +23 -0
- gini/domain/missions/networking/decouple-with-queue.yaml +31 -0
- gini/domain/missions/networking/drive-load.yaml +20 -0
- gini/domain/missions/networking/fix-the-address.yaml +75 -0
- gini/domain/missions/networking/fix-the-lan.yaml +43 -0
- gini/domain/missions/networking/inspect-flows.yaml +16 -0
- gini/domain/missions/networking/k8s-autoscale.yaml +27 -0
- gini/domain/missions/networking/least-privilege.yaml +21 -0
- gini/domain/missions/networking/load-balanced-web.yaml +29 -0
- gini/domain/missions/networking/observe-it.yaml +24 -0
- gini/domain/missions/networking/put-in-vpc.yaml +30 -0
- gini/domain/missions/networking/reachability-boundary.yaml +56 -0
- gini/domain/missions/networking/sdn-reactive.yaml +35 -0
- gini/domain/missions/networking/send-request.yaml +19 -0
- gini/domain/missions/networking/serverless-api.yaml +25 -0
- gini/domain/missions/networking/service-chain.yaml +33 -0
- gini/domain/missions/os/lottery-fix.yaml +19 -0
- gini/domain/missions/os/priority-fix.yaml +24 -0
- gini/domain/missions.py +111 -0
- gini/domain/modulechain.py +36 -0
- gini/domain/objectives.py +488 -0
- gini/domain/os_zoo.py +79 -0
- gini/domain/paging_sim.py +141 -0
- gini/domain/pricing.py +199 -0
- gini/domain/probes.py +226 -0
- gini/domain/profile.py +142 -0
- gini/domain/recipes.py +738 -0
- gini/domain/riders.py +309 -0
- gini/domain/router_modules.py +224 -0
- gini/domain/routetable.py +67 -0
- gini/domain/scoring.py +76 -0
- gini/domain/staging.py +122 -0
- gini/domain/syscall_builder.py +144 -0
- gini/domain/topic_cloud.py +62 -0
- gini/domain/topology.py +213 -0
- gini/domain/vocabulary.py +51 -0
- gini/domain/xv6.py +808 -0
- gini/domain/xv6_fs.py +250 -0
- gini/domain/xv6_runner.py +113 -0
- gini/domain/xv6_vm.py +385 -0
- gini/gloader.py +17 -0
- gini/runtime/__init__.py +18 -0
- gini/runtime/cloudfabric_agent.py +370 -0
- gini/runtime/console.py +68 -0
- gini/runtime/control.py +70 -0
- gini/runtime/frame.py +138 -0
- gini/runtime/gbridge.py +638 -0
- gini/runtime/grouter.py +223 -0
- gini/runtime/hostsim.py +90 -0
- gini/runtime/shuttle.py +348 -0
- gini/runtime/switch.py +109 -0
- gini/runtime/transport.py +77 -0
- gini/runtime/xv6_bridge.py +312 -0
- gini/server/__init__.py +22 -0
- gini/server/__main__.py +74 -0
- gini/server/app.py +140 -0
- gini/server/auth.py +82 -0
- gini/server/policy.py +57 -0
- gini/server/session.py +23 -0
- gini/services/__init__.py +15 -0
- gini/services/boardflash.py +248 -0
- gini/services/boardsetup.py +374 -0
- gini/services/cloud_catalog.py +143 -0
- gini/services/compiler.py +1858 -0
- gini/services/discovery.py +324 -0
- gini/services/gloader.py +183 -0
- gini/services/orchestrator.py +1460 -0
- gini/services/persistence.py +28 -0
- gini/services/probe_runner.py +149 -0
- gini/services/project.py +217 -0
- gini/services/remote.py +93 -0
- gini/services/rider_runner.py +96 -0
- gini/services/rider_session.py +171 -0
- gini/services/shadow_store.py +52 -0
- gini/services/terminal.py +45 -0
- gini/setup/__init__.py +17 -0
- gini/setup/cli.py +109 -0
- gini/setup/images.py +33 -0
- gini/setup/marker.py +43 -0
- gini/setup/runtime.py +69 -0
- gini/ui/__init__.py +3 -0
- gini/ui/assets/app_icon.icns +0 -0
- gini/ui/assets/app_icon.ico +0 -0
- gini/ui/assets/app_icon.png +0 -0
- gini/ui/assets/app_icon_1024.png +0 -0
- gini/ui/assets/cue/_w.txt +1 -0
- gini/ui/assets/cue/ai.png +0 -0
- gini/ui/assets/cue/canvas.png +0 -0
- gini/ui/assets/cue/cloud.png +0 -0
- gini/ui/assets/cue/cost.png +0 -0
- gini/ui/assets/cue/dark/ai.png +0 -0
- gini/ui/assets/cue/dark/canvas.png +0 -0
- gini/ui/assets/cue/dark/cloud.png +0 -0
- gini/ui/assets/cue/dark/cost.png +0 -0
- gini/ui/assets/cue/dark/metrics.png +0 -0
- gini/ui/assets/cue/dark/router.png +0 -0
- gini/ui/assets/cue/dark/run.png +0 -0
- gini/ui/assets/cue/dark/serverless.png +0 -0
- gini/ui/assets/cue/dark/settings.png +0 -0
- gini/ui/assets/cue/dark/welcome.png +0 -0
- gini/ui/assets/cue/dark/wizard.png +0 -0
- gini/ui/assets/cue/ginibrand/ai.png +0 -0
- gini/ui/assets/cue/ginibrand/canvas.png +0 -0
- gini/ui/assets/cue/ginibrand/cloud.png +0 -0
- gini/ui/assets/cue/ginibrand/cost.png +0 -0
- gini/ui/assets/cue/ginibrand/metrics.png +0 -0
- gini/ui/assets/cue/ginibrand/router.png +0 -0
- gini/ui/assets/cue/ginibrand/run.png +0 -0
- gini/ui/assets/cue/ginibrand/serverless.png +0 -0
- gini/ui/assets/cue/ginibrand/settings.png +0 -0
- gini/ui/assets/cue/ginibrand/welcome.png +0 -0
- gini/ui/assets/cue/ginibrand/wizard.png +0 -0
- gini/ui/assets/cue/highcontrast/ai.png +0 -0
- gini/ui/assets/cue/highcontrast/canvas.png +0 -0
- gini/ui/assets/cue/highcontrast/cloud.png +0 -0
- gini/ui/assets/cue/highcontrast/cost.png +0 -0
- gini/ui/assets/cue/highcontrast/metrics.png +0 -0
- gini/ui/assets/cue/highcontrast/router.png +0 -0
- gini/ui/assets/cue/highcontrast/run.png +0 -0
- gini/ui/assets/cue/highcontrast/serverless.png +0 -0
- gini/ui/assets/cue/highcontrast/settings.png +0 -0
- gini/ui/assets/cue/highcontrast/welcome.png +0 -0
- gini/ui/assets/cue/highcontrast/wizard.png +0 -0
- gini/ui/assets/cue/light/ai.png +0 -0
- gini/ui/assets/cue/light/canvas.png +0 -0
- gini/ui/assets/cue/light/cloud.png +0 -0
- gini/ui/assets/cue/light/cost.png +0 -0
- gini/ui/assets/cue/light/metrics.png +0 -0
- gini/ui/assets/cue/light/router.png +0 -0
- gini/ui/assets/cue/light/run.png +0 -0
- gini/ui/assets/cue/light/serverless.png +0 -0
- gini/ui/assets/cue/light/settings.png +0 -0
- gini/ui/assets/cue/light/welcome.png +0 -0
- gini/ui/assets/cue/light/wizard.png +0 -0
- gini/ui/assets/cue/metrics.png +0 -0
- gini/ui/assets/cue/router.png +0 -0
- gini/ui/assets/cue/run.png +0 -0
- gini/ui/assets/cue/serverless.png +0 -0
- gini/ui/assets/cue/settings.png +0 -0
- gini/ui/assets/cue/welcome.png +0 -0
- gini/ui/assets/cue/wizard.png +0 -0
- gini/ui/assistant.py +2111 -0
- gini/ui/author_dialog.py +184 -0
- gini/ui/board_dialog.py +247 -0
- gini/ui/branding.py +21 -0
- gini/ui/canvas.py +2007 -0
- gini/ui/chat_panel.py +7 -0
- gini/ui/cpu_journey.py +212 -0
- gini/ui/cpu_lab.py +306 -0
- gini/ui/cue_cards.py +214 -0
- gini/ui/dashboard.py +222 -0
- gini/ui/diagnose_game.py +336 -0
- gini/ui/fingerprint_lab.py +219 -0
- gini/ui/flash_dialog.py +244 -0
- gini/ui/flow_layout.py +63 -0
- gini/ui/fragment_manager.py +1415 -0
- gini/ui/game_catalog.py +184 -0
- gini/ui/game_renderers.py +340 -0
- gini/ui/games_lab.py +90 -0
- gini/ui/inspector.py +1055 -0
- gini/ui/live_metrics.py +130 -0
- gini/ui/machine_lab.py +1412 -0
- gini/ui/main_window.py +3153 -0
- gini/ui/memory_lab.py +371 -0
- gini/ui/mission_panel.py +302 -0
- gini/ui/mode_indicator.py +227 -0
- gini/ui/palette.py +112 -0
- gini/ui/peripherals.py +218 -0
- gini/ui/process_tree.py +130 -0
- gini/ui/reset_dialog.py +179 -0
- gini/ui/router_lab.py +776 -0
- gini/ui/run_button.py +183 -0
- gini/ui/settings_dialog.py +234 -0
- gini/ui/signin_dialog.py +111 -0
- gini/ui/storage_lab.py +219 -0
- gini/ui/syscall_builder.py +235 -0
- gini/ui/syscall_lab.py +152 -0
- gini/ui/theme/__init__.py +5 -0
- gini/ui/theme/icons.py +145 -0
- gini/ui/theme/manager.py +291 -0
- gini/ui/theme/tokens.py +194 -0
- gini/ui/trap_lab.py +270 -0
- gini/ui/worker_host.py +102 -0
- gini/ui/zoo_lab.py +112 -0
- gini_toolkit-6.0.1.dev0.dist-info/METADATA +77 -0
- gini_toolkit-6.0.1.dev0.dist-info/RECORD +278 -0
- gini_toolkit-6.0.1.dev0.dist-info/WHEEL +5 -0
- gini_toolkit-6.0.1.dev0.dist-info/entry_points.txt +3 -0
- gini_toolkit-6.0.1.dev0.dist-info/top_level.txt +1 -0
gini/ui/live_metrics.py
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"""LiveMetrics — real-time charts for the Inspector's Live tab.
|
|
2
|
+
|
|
3
|
+
Two stacked chart boxes, each holding two coloured, independently-scaled series:
|
|
4
|
+
• CPU (%) + Memory (MiB) — from `docker stats`, every container
|
|
5
|
+
• Throughput (KB/s) + Latency (ms) — network from docker stats; latency from the
|
|
6
|
+
cloud fabric (proxies/LBs; blank otherwise)
|
|
7
|
+
Each series autoscales to its own range so trends are readable even at different
|
|
8
|
+
magnitudes; the current value is labelled in the series colour. Pure QPainter.
|
|
9
|
+
"""
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from collections import deque
|
|
13
|
+
|
|
14
|
+
from PySide6.QtCore import QRectF, Qt
|
|
15
|
+
from PySide6.QtGui import QColor, QFont, QPainter, QPainterPath, QPen
|
|
16
|
+
from PySide6.QtWidgets import QWidget
|
|
17
|
+
from .theme.manager import sp as _sp
|
|
18
|
+
|
|
19
|
+
# a layout = list of chart boxes; each box = up to two (key, label, unit, color-token)
|
|
20
|
+
# series. Colors resolve against the theme (accent / accent2 / success / warning).
|
|
21
|
+
CLOUD_LAYOUT = [
|
|
22
|
+
[("cpu", "CPU", "%", "accent"), ("mem", "Memory", " MiB", "accent2")],
|
|
23
|
+
[("thru", "Throughput", " KB/s", "success"), ("lat", "Latency", " ms", "warning")],
|
|
24
|
+
]
|
|
25
|
+
K8S_LAYOUT = [
|
|
26
|
+
[("cpu_pct", "CPU", "%", "accent"), ("target_pct", "Target", "%", "warning")],
|
|
27
|
+
[("replicas", "Replicas", "", "success")],
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class LiveMetrics(QWidget):
|
|
32
|
+
WINDOW = 90 # samples kept (~135s at a 1.5s poll)
|
|
33
|
+
|
|
34
|
+
def __init__(self, theme) -> None:
|
|
35
|
+
super().__init__()
|
|
36
|
+
self.theme = theme # ThemeManager
|
|
37
|
+
self._layout = CLOUD_LAYOUT
|
|
38
|
+
self._d = {k: deque(maxlen=self.WINDOW) for k in ("cpu", "mem", "thru", "lat")}
|
|
39
|
+
self.setMinimumHeight(260)
|
|
40
|
+
|
|
41
|
+
def set_layout(self, layout) -> None:
|
|
42
|
+
"""Choose which series go in which chart box (cloud vs kubernetes view)."""
|
|
43
|
+
self._layout = layout
|
|
44
|
+
self.update()
|
|
45
|
+
|
|
46
|
+
def set_series(self, series: dict) -> None:
|
|
47
|
+
"""Point the chart at an external set of deques (the inspector keeps one per
|
|
48
|
+
element, so each element's history survives selection changes)."""
|
|
49
|
+
self._d = series
|
|
50
|
+
self.update()
|
|
51
|
+
|
|
52
|
+
def reset(self) -> None:
|
|
53
|
+
for q in self._d.values():
|
|
54
|
+
q.clear()
|
|
55
|
+
self.update()
|
|
56
|
+
|
|
57
|
+
def push(self, cpu, mem, thru=0.0, lat=None) -> None:
|
|
58
|
+
self._d["cpu"].append(_f(cpu))
|
|
59
|
+
self._d["mem"].append(_f(mem))
|
|
60
|
+
self._d["thru"].append(_f(thru))
|
|
61
|
+
self._d["lat"].append(None if lat is None else _f(lat))
|
|
62
|
+
self.update()
|
|
63
|
+
|
|
64
|
+
# -- painting ----------------------------------------------------------- #
|
|
65
|
+
def paintEvent(self, _e) -> None:
|
|
66
|
+
p = QPainter(self)
|
|
67
|
+
p.setRenderHint(QPainter.Antialiasing, True)
|
|
68
|
+
t = self.theme.theme
|
|
69
|
+
w = self.width()
|
|
70
|
+
n = max(1, len(self._layout))
|
|
71
|
+
gap = 14
|
|
72
|
+
ch = (self.height() - gap * (n - 1)) / n
|
|
73
|
+
for i, box in enumerate(self._layout):
|
|
74
|
+
rect = QRectF(4, 4 + i * (ch + gap), w - 8, ch - 6)
|
|
75
|
+
series = [(label, unit, self._d.get(key, ()), QColor(getattr(t, token)))
|
|
76
|
+
for key, label, unit, token in box]
|
|
77
|
+
self._chart(p, rect, t, series)
|
|
78
|
+
|
|
79
|
+
def _chart(self, p: QPainter, rect: QRectF, t, series) -> None:
|
|
80
|
+
p.setBrush(QColor(t.panel2)); p.setPen(QPen(QColor(t.line), 1))
|
|
81
|
+
p.drawRoundedRect(rect, 8, 8)
|
|
82
|
+
|
|
83
|
+
# two header labels: series[0] left, series[1] right
|
|
84
|
+
for i, (label, unit, data, col) in enumerate(series):
|
|
85
|
+
vals = [v for v in data if v is not None]
|
|
86
|
+
cur = vals[-1] if vals else None
|
|
87
|
+
align = Qt.AlignLeft if i == 0 else Qt.AlignRight
|
|
88
|
+
p.setPen(QColor(t.faint))
|
|
89
|
+
f = QFont(); f.setPointSize(_sp(9)); f.setBold(True); p.setFont(f)
|
|
90
|
+
p.drawText(rect.adjusted(11, 7, -11, 0), Qt.AlignTop | align, label.upper())
|
|
91
|
+
p.setPen(col)
|
|
92
|
+
fb = QFont(); fb.setPointSize(_sp(13)); fb.setBold(True); p.setFont(fb)
|
|
93
|
+
txt = f"{cur:,.1f}{unit}" if cur is not None else "—"
|
|
94
|
+
p.drawText(rect.adjusted(11, 22, -11, 0), Qt.AlignTop | align, txt)
|
|
95
|
+
|
|
96
|
+
plot = rect.adjusted(11, 44, -11, -10)
|
|
97
|
+
if all(len([v for v in data if v is not None]) < 2 for _, _, data, _ in series):
|
|
98
|
+
p.setPen(QColor(t.faint))
|
|
99
|
+
fs = QFont(); fs.setPointSize(_sp(9)); p.setFont(fs)
|
|
100
|
+
p.drawText(plot, Qt.AlignCenter, "sampling…")
|
|
101
|
+
return
|
|
102
|
+
for _label, _unit, data, col in series:
|
|
103
|
+
self._line(p, plot, list(data), col)
|
|
104
|
+
|
|
105
|
+
def _line(self, p: QPainter, plot: QRectF, data, col: QColor) -> None:
|
|
106
|
+
vals = [v for v in data if v is not None]
|
|
107
|
+
if len(vals) < 2:
|
|
108
|
+
return
|
|
109
|
+
ymax = max(max(vals) * 1.2, 1e-6)
|
|
110
|
+
n = len(data)
|
|
111
|
+
step = plot.width() / (self.WINDOW - 1)
|
|
112
|
+
path = QPainterPath()
|
|
113
|
+
started = False
|
|
114
|
+
for i, v in enumerate(data):
|
|
115
|
+
if v is None:
|
|
116
|
+
continue
|
|
117
|
+
x = plot.right() - (n - 1 - i) * step
|
|
118
|
+
y = plot.bottom() - (v / ymax) * plot.height()
|
|
119
|
+
if not started:
|
|
120
|
+
path.moveTo(x, y); started = True
|
|
121
|
+
else:
|
|
122
|
+
path.lineTo(x, y)
|
|
123
|
+
p.setBrush(Qt.NoBrush); p.setPen(QPen(col, 2)); p.drawPath(path)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def _f(v) -> float:
|
|
127
|
+
try:
|
|
128
|
+
return max(0.0, float(v))
|
|
129
|
+
except (TypeError, ValueError):
|
|
130
|
+
return 0.0
|