glaip-sdk 0.0.2__py3-none-any.whl → 0.0.4__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.
- glaip_sdk/__init__.py +2 -2
- glaip_sdk/_version.py +51 -0
- glaip_sdk/branding.py +145 -0
- glaip_sdk/cli/commands/agents.py +876 -166
- glaip_sdk/cli/commands/configure.py +46 -104
- glaip_sdk/cli/commands/init.py +43 -118
- glaip_sdk/cli/commands/mcps.py +86 -161
- glaip_sdk/cli/commands/tools.py +196 -57
- glaip_sdk/cli/main.py +43 -29
- glaip_sdk/cli/utils.py +258 -27
- glaip_sdk/client/__init__.py +54 -2
- glaip_sdk/client/agents.py +196 -237
- glaip_sdk/client/base.py +62 -2
- glaip_sdk/client/mcps.py +63 -20
- glaip_sdk/client/tools.py +236 -81
- glaip_sdk/config/constants.py +10 -3
- glaip_sdk/exceptions.py +13 -0
- glaip_sdk/models.py +21 -5
- glaip_sdk/utils/__init__.py +116 -18
- glaip_sdk/utils/client_utils.py +284 -0
- glaip_sdk/utils/rendering/__init__.py +1 -0
- glaip_sdk/utils/rendering/formatting.py +211 -0
- glaip_sdk/utils/rendering/models.py +53 -0
- glaip_sdk/utils/rendering/renderer/__init__.py +38 -0
- glaip_sdk/utils/rendering/renderer/base.py +827 -0
- glaip_sdk/utils/rendering/renderer/config.py +33 -0
- glaip_sdk/utils/rendering/renderer/console.py +54 -0
- glaip_sdk/utils/rendering/renderer/debug.py +82 -0
- glaip_sdk/utils/rendering/renderer/panels.py +123 -0
- glaip_sdk/utils/rendering/renderer/progress.py +118 -0
- glaip_sdk/utils/rendering/renderer/stream.py +198 -0
- glaip_sdk/utils/rendering/steps.py +168 -0
- glaip_sdk/utils/run_renderer.py +22 -1086
- {glaip_sdk-0.0.2.dist-info → glaip_sdk-0.0.4.dist-info}/METADATA +8 -36
- glaip_sdk-0.0.4.dist-info/RECORD +41 -0
- glaip_sdk/cli/config.py +0 -592
- glaip_sdk/utils.py +0 -167
- glaip_sdk-0.0.2.dist-info/RECORD +0 -28
- {glaip_sdk-0.0.2.dist-info → glaip_sdk-0.0.4.dist-info}/WHEEL +0 -0
- {glaip_sdk-0.0.2.dist-info → glaip_sdk-0.0.4.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"""Rendering utilities.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Raymond Christopher (raymond.christopher@gdplabs.id)
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from collections.abc import Iterator
|
|
10
|
+
|
|
11
|
+
from .models import Step
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class StepManager:
|
|
15
|
+
def __init__(self, max_steps: int = 200):
|
|
16
|
+
self.by_id: dict[str, Step] = {}
|
|
17
|
+
self.order: list[str] = []
|
|
18
|
+
self.children: dict[str, list[str]] = {}
|
|
19
|
+
self.key_index: dict[tuple, str] = {}
|
|
20
|
+
self.slot_counter: dict[tuple, int] = {}
|
|
21
|
+
self.max_steps = max_steps
|
|
22
|
+
self._last_running: dict[tuple, str] = {}
|
|
23
|
+
|
|
24
|
+
def _alloc_slot(self, task_id, context_id, kind, name) -> int:
|
|
25
|
+
k = (task_id, context_id, kind, name)
|
|
26
|
+
self.slot_counter[k] = self.slot_counter.get(k, 0) + 1
|
|
27
|
+
return self.slot_counter[k]
|
|
28
|
+
|
|
29
|
+
def _key(self, task_id, context_id, kind, name, slot) -> tuple:
|
|
30
|
+
return (task_id, context_id, kind, name, slot)
|
|
31
|
+
|
|
32
|
+
def _make_id(self, task_id, context_id, kind, name, slot) -> str:
|
|
33
|
+
return f"{task_id or 't'}::{context_id or 'c'}::{kind}::{name}::{slot}"
|
|
34
|
+
|
|
35
|
+
def start_or_get(
|
|
36
|
+
self, *, task_id, context_id, kind, name, parent_id=None, args=None
|
|
37
|
+
) -> Step:
|
|
38
|
+
existing = self.find_running(
|
|
39
|
+
task_id=task_id, context_id=context_id, kind=kind, name=name
|
|
40
|
+
)
|
|
41
|
+
if existing:
|
|
42
|
+
if args and existing.args != args:
|
|
43
|
+
existing.args = args
|
|
44
|
+
return existing
|
|
45
|
+
slot = self._alloc_slot(task_id, context_id, kind, name)
|
|
46
|
+
key = self._key(task_id, context_id, kind, name, slot)
|
|
47
|
+
step_id = self._make_id(task_id, context_id, kind, name, slot)
|
|
48
|
+
st = Step(
|
|
49
|
+
step_id=step_id,
|
|
50
|
+
kind=kind,
|
|
51
|
+
name=name,
|
|
52
|
+
parent_id=parent_id,
|
|
53
|
+
task_id=task_id,
|
|
54
|
+
context_id=context_id,
|
|
55
|
+
args=args or {},
|
|
56
|
+
)
|
|
57
|
+
self.by_id[step_id] = st
|
|
58
|
+
if parent_id:
|
|
59
|
+
self.children.setdefault(parent_id, []).append(step_id)
|
|
60
|
+
else:
|
|
61
|
+
self.order.append(step_id)
|
|
62
|
+
self.key_index[key] = step_id
|
|
63
|
+
self._prune_steps()
|
|
64
|
+
self._last_running[(task_id, context_id, kind, name)] = step_id
|
|
65
|
+
return st
|
|
66
|
+
|
|
67
|
+
def _prune_steps(self):
|
|
68
|
+
total = len(self.order) + sum(len(v) for v in self.children.values())
|
|
69
|
+
if total <= self.max_steps:
|
|
70
|
+
return
|
|
71
|
+
|
|
72
|
+
def remove_subtree(root_id: str):
|
|
73
|
+
stack = [root_id]
|
|
74
|
+
to_remove = []
|
|
75
|
+
while stack:
|
|
76
|
+
sid = stack.pop()
|
|
77
|
+
to_remove.append(sid)
|
|
78
|
+
stack.extend(self.children.pop(sid, []))
|
|
79
|
+
for sid in to_remove:
|
|
80
|
+
st = self.by_id.pop(sid, None)
|
|
81
|
+
if st:
|
|
82
|
+
key = (st.task_id, st.context_id, st.kind, st.name)
|
|
83
|
+
self._last_running.pop(key, None)
|
|
84
|
+
for _parent, kids in list(self.children.items()):
|
|
85
|
+
if sid in kids:
|
|
86
|
+
kids.remove(sid)
|
|
87
|
+
if sid in self.order:
|
|
88
|
+
self.order.remove(sid)
|
|
89
|
+
|
|
90
|
+
while total > self.max_steps and self.order:
|
|
91
|
+
sid = self.order[0]
|
|
92
|
+
subtree = [sid]
|
|
93
|
+
stack = list(self.children.get(sid, []))
|
|
94
|
+
while stack:
|
|
95
|
+
x = stack.pop()
|
|
96
|
+
subtree.append(x)
|
|
97
|
+
stack.extend(self.children.get(x, []))
|
|
98
|
+
total -= len(subtree)
|
|
99
|
+
remove_subtree(sid)
|
|
100
|
+
|
|
101
|
+
def get_child_count(self, step_id: str) -> int:
|
|
102
|
+
return len(self.children.get(step_id, []))
|
|
103
|
+
|
|
104
|
+
def find_running(self, *, task_id, context_id, kind, name) -> Step | None:
|
|
105
|
+
key = (task_id, context_id, kind, name)
|
|
106
|
+
step_id = self._last_running.get(key)
|
|
107
|
+
if step_id:
|
|
108
|
+
st = self.by_id.get(step_id)
|
|
109
|
+
if st and st.status != "finished":
|
|
110
|
+
return st
|
|
111
|
+
for sid in reversed(list(self._iter_all_steps())):
|
|
112
|
+
st = self.by_id.get(sid)
|
|
113
|
+
if (
|
|
114
|
+
st
|
|
115
|
+
and (st.task_id, st.context_id, st.kind, st.name)
|
|
116
|
+
== (
|
|
117
|
+
task_id,
|
|
118
|
+
context_id,
|
|
119
|
+
kind,
|
|
120
|
+
name,
|
|
121
|
+
)
|
|
122
|
+
and st.status != "finished"
|
|
123
|
+
):
|
|
124
|
+
return st
|
|
125
|
+
return None
|
|
126
|
+
|
|
127
|
+
def finish(
|
|
128
|
+
self, *, task_id, context_id, kind, name, output=None, duration_raw=None
|
|
129
|
+
):
|
|
130
|
+
st = self.find_running(
|
|
131
|
+
task_id=task_id, context_id=context_id, kind=kind, name=name
|
|
132
|
+
)
|
|
133
|
+
if not st:
|
|
134
|
+
# Try to find any existing step with matching parameters, even if not running
|
|
135
|
+
for sid in reversed(list(self._iter_all_steps())):
|
|
136
|
+
st_check = self.by_id.get(sid)
|
|
137
|
+
if (
|
|
138
|
+
st_check
|
|
139
|
+
and st_check.task_id == task_id
|
|
140
|
+
and st_check.context_id == context_id
|
|
141
|
+
and st_check.kind == kind
|
|
142
|
+
and st_check.name == name
|
|
143
|
+
):
|
|
144
|
+
st = st_check
|
|
145
|
+
break
|
|
146
|
+
|
|
147
|
+
# If still no step found, create a new one
|
|
148
|
+
if not st:
|
|
149
|
+
st = self.start_or_get(
|
|
150
|
+
task_id=task_id, context_id=context_id, kind=kind, name=name
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
if output:
|
|
154
|
+
st.output = output
|
|
155
|
+
st.finish(duration_raw)
|
|
156
|
+
key = (task_id, context_id, kind, name)
|
|
157
|
+
if self._last_running.get(key) == st.step_id:
|
|
158
|
+
self._last_running.pop(key, None)
|
|
159
|
+
return st
|
|
160
|
+
|
|
161
|
+
def _iter_all_steps(self) -> Iterator[str]:
|
|
162
|
+
for root in self.order:
|
|
163
|
+
yield root
|
|
164
|
+
stack = list(self.children.get(root, []))
|
|
165
|
+
while stack:
|
|
166
|
+
sid = stack.pop()
|
|
167
|
+
yield sid
|
|
168
|
+
stack.extend(self.children.get(sid, []))
|