summitsdk 0.1.0__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.
marlsdk/__init__.py ADDED
@@ -0,0 +1,5 @@
1
+ from marlsdk.tracer import Tracer
2
+ from marlsdk.schema import InteractionTrace
3
+ from marlsdk.exporters.local import LocalExporter
4
+
5
+ __all__ = ["Tracer", "InteractionTrace", "LocalExporter"]
@@ -0,0 +1,3 @@
1
+ from marlsdk.exporters.local import LocalExporter
2
+
3
+ __all__ = ["LocalExporter"]
@@ -0,0 +1,24 @@
1
+ import json
2
+ import os
3
+ from marlsdk.schema import InteractionTrace
4
+
5
+
6
+ class LocalExporter:
7
+ def __init__(self, output_dir: str = "data/traces"):
8
+ self.output_dir = output_dir
9
+ os.makedirs(output_dir, exist_ok=True)
10
+
11
+ def export(self, trace: InteractionTrace) -> str:
12
+ filename = (
13
+ f"{trace.task_id}_{trace.from_agent}_to_{trace.to_agent}"
14
+ f"_r{trace.round_trip}_{trace.trace_id[:6]}.json"
15
+ )
16
+ filepath = os.path.join(self.output_dir, filename)
17
+ with open(filepath, "w") as f:
18
+ json.dump(trace.to_dict(), f, indent=2)
19
+ return filepath
20
+
21
+ def list_traces(self) -> list:
22
+ if not os.path.exists(self.output_dir):
23
+ return []
24
+ return sorted(f for f in os.listdir(self.output_dir) if f.endswith(".json"))
marlsdk/schema.py ADDED
@@ -0,0 +1,37 @@
1
+ from dataclasses import dataclass, field
2
+ from datetime import datetime, timezone
3
+ import uuid
4
+
5
+
6
+ @dataclass
7
+ class InteractionTrace:
8
+ task_id: str
9
+ from_agent: str
10
+ to_agent: str
11
+ content: str
12
+ model: str
13
+ input_tokens: int
14
+ output_tokens: int
15
+ round_trip: int
16
+ framework: str = "unknown"
17
+ trace_id: str = field(default_factory=lambda: str(uuid.uuid4()))
18
+ timestamp: str = field(
19
+ default_factory=lambda: datetime.now(timezone.utc).isoformat()
20
+ )
21
+ metadata: dict = field(default_factory=dict)
22
+
23
+ def to_dict(self) -> dict:
24
+ return {
25
+ "trace_id": self.trace_id,
26
+ "task_id": self.task_id,
27
+ "from_agent": self.from_agent,
28
+ "to_agent": self.to_agent,
29
+ "content": self.content,
30
+ "model": self.model,
31
+ "input_tokens": self.input_tokens,
32
+ "output_tokens": self.output_tokens,
33
+ "round_trip": self.round_trip,
34
+ "timestamp": self.timestamp,
35
+ "framework": self.framework,
36
+ "metadata": self.metadata,
37
+ }
marlsdk/tracer.py ADDED
@@ -0,0 +1,36 @@
1
+ from marlsdk.schema import InteractionTrace
2
+ from marlsdk.exporters.local import LocalExporter
3
+
4
+
5
+ class Tracer:
6
+ def __init__(self, exporter=None):
7
+ self.exporter = exporter or LocalExporter()
8
+
9
+ def record(self, trace: InteractionTrace) -> None:
10
+ try:
11
+ self.exporter.export(trace)
12
+ except Exception as e:
13
+ import sys
14
+ print(
15
+ f"[summitsdk] Warning: export failed"
16
+ f" for trace {trace.trace_id}:"
17
+ f" {type(e).__name__}: {e}",
18
+ file=sys.stderr,
19
+ )
20
+
21
+ def wrap_anthropic(self, client, from_agent, to_agent, task_id, round_trip):
22
+ from marlsdk.wrappers.anthropic_wrapper import WrappedAnthropicMessages
23
+ client.messages = WrappedAnthropicMessages(
24
+ client.messages, self, from_agent, to_agent, task_id, round_trip
25
+ )
26
+ return client
27
+
28
+ def wrap_openai(self, client, from_agent, to_agent, task_id, round_trip):
29
+ try:
30
+ from marlsdk.wrappers.openai_wrapper import WrappedOpenAICompletions
31
+ client.chat.completions = WrappedOpenAICompletions(
32
+ client.chat.completions, self, from_agent, to_agent, task_id, round_trip
33
+ )
34
+ except (ImportError, AttributeError):
35
+ pass
36
+ return client
File without changes
@@ -0,0 +1,55 @@
1
+ from marlsdk.schema import InteractionTrace
2
+
3
+
4
+ class WrappedAnthropicMessages:
5
+ def __init__(self, original, tracer, from_agent, to_agent, task_id, round_trip):
6
+ self._original = original
7
+ self._tracer = tracer
8
+ self._from_agent = from_agent
9
+ self._to_agent = to_agent
10
+ self._task_id = task_id
11
+ self._round_trip = round_trip
12
+
13
+ def create(self, *args, **kwargs):
14
+ response = self._original.create(*args, **kwargs)
15
+ try:
16
+ content = ""
17
+ if response.content:
18
+ for block in response.content:
19
+ if hasattr(block, "text"):
20
+ content = block.text
21
+ break
22
+ input_tokens = getattr(response.usage, "input_tokens", 0) or 0
23
+ output_tokens = getattr(response.usage, "output_tokens", 0) or 0
24
+ model = getattr(response, "model", "unknown")
25
+ trace = InteractionTrace(
26
+ task_id=self._task_id,
27
+ from_agent=self._from_agent,
28
+ to_agent=self._to_agent,
29
+ content=content,
30
+ model=model,
31
+ input_tokens=input_tokens,
32
+ output_tokens=output_tokens,
33
+ round_trip=self._round_trip,
34
+ framework="anthropic",
35
+ )
36
+ self._tracer.record(trace)
37
+ except Exception as e:
38
+ import sys
39
+ print(
40
+ f"[summitsdk] Warning: trace recording failed"
41
+ f" for {self._from_agent}->{self._to_agent}:"
42
+ f" {type(e).__name__}: {e}",
43
+ file=sys.stderr,
44
+ )
45
+ return response
46
+
47
+ def stream(self, *args, **kwargs):
48
+ raise NotImplementedError(
49
+ "summitsdk does not support streaming. "
50
+ "Use client.messages.create() instead. "
51
+ "Streaming calls will not produce traces."
52
+ )
53
+
54
+ def __getattr__(self, name):
55
+ return getattr(self._original, name)
@@ -0,0 +1,58 @@
1
+ try:
2
+ from marlsdk.schema import InteractionTrace
3
+
4
+ class WrappedOpenAICompletions:
5
+ def __init__(self, original, tracer, from_agent, to_agent, task_id, round_trip):
6
+ self._original = original
7
+ self._tracer = tracer
8
+ self._from_agent = from_agent
9
+ self._to_agent = to_agent
10
+ self._task_id = task_id
11
+ self._round_trip = round_trip
12
+
13
+ def create(self, *args, **kwargs):
14
+ response = self._original.create(*args, **kwargs)
15
+ try:
16
+ choices = getattr(response, "choices", None) or []
17
+ content = ""
18
+ if choices:
19
+ msg = getattr(choices[0], "message", None)
20
+ content = getattr(msg, "content", "") or ""
21
+ usage = getattr(response, "usage", None)
22
+ input_tokens = getattr(usage, "prompt_tokens", 0) or 0
23
+ output_tokens = getattr(usage, "completion_tokens", 0) or 0
24
+ model = getattr(response, "model", "unknown")
25
+ trace = InteractionTrace(
26
+ task_id=self._task_id,
27
+ from_agent=self._from_agent,
28
+ to_agent=self._to_agent,
29
+ content=content,
30
+ model=model,
31
+ input_tokens=input_tokens,
32
+ output_tokens=output_tokens,
33
+ round_trip=self._round_trip,
34
+ framework="openai",
35
+ )
36
+ self._tracer.record(trace)
37
+ except Exception as e:
38
+ import sys
39
+ print(
40
+ f"[summitsdk] Warning: trace recording failed"
41
+ f" for {self._from_agent}->{self._to_agent}:"
42
+ f" {type(e).__name__}: {e}",
43
+ file=sys.stderr,
44
+ )
45
+ return response
46
+
47
+ def stream(self, *args, **kwargs):
48
+ raise NotImplementedError(
49
+ "summitsdk does not support streaming. "
50
+ "Use client.chat.completions.create() instead. "
51
+ "Streaming calls will not produce traces."
52
+ )
53
+
54
+ def __getattr__(self, name):
55
+ return getattr(self._original, name)
56
+
57
+ except ImportError:
58
+ pass
@@ -0,0 +1,71 @@
1
+ Metadata-Version: 2.4
2
+ Name: summitsdk
3
+ Version: 0.1.0
4
+ Summary: Instrumentation layer for multi-agent AI pipelines
5
+ Home-page: https://cronys.xyz/summit
6
+ Author: Shaz Hussain
7
+ Author-email: shaz@cronys.xyz
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.8
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: anthropic
15
+ Provides-Extra: openai
16
+ Requires-Dist: openai; extra == "openai"
17
+ Dynamic: author
18
+ Dynamic: author-email
19
+ Dynamic: classifier
20
+ Dynamic: description
21
+ Dynamic: description-content-type
22
+ Dynamic: home-page
23
+ Dynamic: license-file
24
+ Dynamic: provides-extra
25
+ Dynamic: requires-dist
26
+ Dynamic: requires-python
27
+ Dynamic: summary
28
+
29
+ # MARL
30
+
31
+ Simulation and evaluation environment for
32
+ Summit by Cronys.
33
+
34
+ ## Structure
35
+
36
+ sim/ Planner, Worker, Judge agents
37
+ eval/ Reward model evaluator
38
+ improve.py Single-pass improvement loop
39
+ cycle.py Automated multi-cycle runner
40
+ marlsdk/ summitsdk package source
41
+ data/ Traces and evaluation results
42
+
43
+ ## Usage
44
+
45
+ ```python
46
+ from anthropic import Anthropic
47
+ from marlsdk.tracer import Tracer
48
+ from marlsdk.exporters.local import LocalExporter
49
+
50
+ exporter = LocalExporter(output_dir="traces/")
51
+ tracer = Tracer(exporter=exporter)
52
+
53
+ client = Anthropic()
54
+ wrapped = tracer.wrap_anthropic(
55
+ client,
56
+ from_agent="planner",
57
+ to_agent="worker",
58
+ task_id="task-001",
59
+ round_trip=1
60
+ )
61
+
62
+ response = wrapped.messages.create(
63
+ model="claude-sonnet-4-20250514",
64
+ max_tokens=1024,
65
+ messages=[{"role": "user", "content": "your prompt"}]
66
+ )
67
+ # trace written automatically to traces/
68
+ ```
69
+
70
+ OpenAI: use tracer.wrap_openai(client, ...)
71
+ with the same arguments.
@@ -0,0 +1,13 @@
1
+ marlsdk/__init__.py,sha256=MieX0EwpdtKC7LwbKbLznpdFMYYf64dA0DCxObWIQb8,187
2
+ marlsdk/schema.py,sha256=JV30B0i8XU69zq3uWIEyjp3ySdOY-eBcb17a9lmSaOA,1083
3
+ marlsdk/tracer.py,sha256=UMQRgRnzSTSNOrTaidOh_tYJ9RyI0ivVU4x39XS3h5s,1325
4
+ marlsdk/exporters/__init__.py,sha256=MexA6fnAt9kKWiyajkRxnKAD2Qlevk1SIhZoprQ6joM,79
5
+ marlsdk/exporters/local.py,sha256=rtQ_NQT-HuobGlHvYbXQ56h80MM4jYFPhcKdvsm6ga4,813
6
+ marlsdk/wrappers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ marlsdk/wrappers/anthropic_wrapper.py,sha256=lx9AIAbTcuxw6MimLk6TvOMw8M6GQZNNQqSXaGU76lE,2006
8
+ marlsdk/wrappers/openai_wrapper.py,sha256=Do59EVQkPCo9h6Y72pRtaLFZNgvdclaarsAnqJHa80I,2289
9
+ summitsdk-0.1.0.dist-info/licenses/LICENSE,sha256=-piU4bFNOw_DasMxGO6Xz2ciRrf6SCLUkEm7sKiI7UU,1069
10
+ summitsdk-0.1.0.dist-info/METADATA,sha256=TlCynx4g-79MlkuRi5rBVZsN-No8IGrsrur5GN5E8uY,1807
11
+ summitsdk-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
12
+ summitsdk-0.1.0.dist-info/top_level.txt,sha256=IxMmo2HJH49y0hDeIDvcMIvUhcFdDBBAVan0WbH4qoI,8
13
+ summitsdk-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,30 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Shaz Hussain
4
+
5
+ Permission is hereby granted, free of charge,
6
+ to any person obtaining a copy of this software
7
+ and associated documentation files (the
8
+ "Software"), to deal in the Software without
9
+ restriction, including without limitation the
10
+ rights to use, copy, modify, merge, publish,
11
+ distribute, sublicense, and/or sell copies of
12
+ the Software, and to permit persons to whom the
13
+ Software is furnished to do so, subject to the
14
+ following conditions:
15
+
16
+ The above copyright notice and this permission
17
+ notice shall be included in all copies or
18
+ substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT
21
+ WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
22
+ INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR
24
+ PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
26
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
27
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
28
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ marlsdk