seam-runtime 1.3.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.
Files changed (73) hide show
  1. seam.py +152 -0
  2. seam_runtime/__init__.py +29 -0
  3. seam_runtime/agent_memory.py +145 -0
  4. seam_runtime/benchmark_baseline_policy.py +116 -0
  5. seam_runtime/benchmark_integrity.py +462 -0
  6. seam_runtime/benchmarks.py +2346 -0
  7. seam_runtime/bm25.py +69 -0
  8. seam_runtime/cli.py +2168 -0
  9. seam_runtime/context_views.py +195 -0
  10. seam_runtime/dashboard.py +3157 -0
  11. seam_runtime/doctor.py +166 -0
  12. seam_runtime/dsl.py +190 -0
  13. seam_runtime/evals.py +191 -0
  14. seam_runtime/external_memory_benchmarks.py +210 -0
  15. seam_runtime/holographic.py +566 -0
  16. seam_runtime/improvement.py +114 -0
  17. seam_runtime/installer.py +386 -0
  18. seam_runtime/lossless.py +975 -0
  19. seam_runtime/lx1.py +311 -0
  20. seam_runtime/mcp.py +454 -0
  21. seam_runtime/mcp_protocol.py +288 -0
  22. seam_runtime/mirl.py +376 -0
  23. seam_runtime/models.py +213 -0
  24. seam_runtime/nl.py +322 -0
  25. seam_runtime/nl_extract.py +205 -0
  26. seam_runtime/pack.py +300 -0
  27. seam_runtime/pgvector_bootstrap.py +230 -0
  28. seam_runtime/pool.py +169 -0
  29. seam_runtime/reconcile.py +43 -0
  30. seam_runtime/retrieval.py +414 -0
  31. seam_runtime/retrieval_orchestrator/README.md +41 -0
  32. seam_runtime/retrieval_orchestrator/__init__.py +33 -0
  33. seam_runtime/retrieval_orchestrator/adapters.py +444 -0
  34. seam_runtime/retrieval_orchestrator/merger.py +22 -0
  35. seam_runtime/retrieval_orchestrator/orchestrator.py +119 -0
  36. seam_runtime/retrieval_orchestrator/planner.py +87 -0
  37. seam_runtime/retrieval_orchestrator/types.py +176 -0
  38. seam_runtime/retry.py +175 -0
  39. seam_runtime/runtime.py +396 -0
  40. seam_runtime/self_improve.py +415 -0
  41. seam_runtime/server.py +1013 -0
  42. seam_runtime/skills/__init__.py +26 -0
  43. seam_runtime/skills/factory.py +180 -0
  44. seam_runtime/skills/skill_ir.py +104 -0
  45. seam_runtime/storage.py +1621 -0
  46. seam_runtime/surface_adapters.py +152 -0
  47. seam_runtime/symbols.py +249 -0
  48. seam_runtime/temporal.py +127 -0
  49. seam_runtime/tokenization.py +33 -0
  50. seam_runtime/transpile.py +21 -0
  51. seam_runtime/ui/__init__.py +12 -0
  52. seam_runtime/ui/animations.py +483 -0
  53. seam_runtime/ui/bars.py +244 -0
  54. seam_runtime/ui/logo.py +409 -0
  55. seam_runtime/ui/theme.py +192 -0
  56. seam_runtime/vector.py +166 -0
  57. seam_runtime/vector_adapters.py +248 -0
  58. seam_runtime/verify.py +144 -0
  59. seam_runtime/webui/branding/seam-glitch.png +0 -0
  60. seam_runtime/webui/branding/seam-mark-retro.svg +25 -0
  61. seam_runtime/webui/branding/seam-mark-terminal.svg +10 -0
  62. seam_runtime/webui/dashboard.html +6504 -0
  63. seam_runtime/webui/favicon.svg +1 -0
  64. seam_runtime/webui/icons.svg +24 -0
  65. seam_runtime/webui/seam-api.js +317 -0
  66. seam_runtime/webui/tweaks-panel.jsx +426 -0
  67. seam_runtime-1.3.0.dist-info/METADATA +637 -0
  68. seam_runtime-1.3.0.dist-info/RECORD +73 -0
  69. seam_runtime-1.3.0.dist-info/WHEEL +5 -0
  70. seam_runtime-1.3.0.dist-info/entry_points.txt +6 -0
  71. seam_runtime-1.3.0.dist-info/licenses/LICENSE +201 -0
  72. seam_runtime-1.3.0.dist-info/licenses/NOTICE +13 -0
  73. seam_runtime-1.3.0.dist-info/top_level.txt +2 -0
seam.py ADDED
@@ -0,0 +1,152 @@
1
+ from __future__ import annotations
2
+
3
+ import sys
4
+ from pathlib import Path
5
+
6
+ from seam_runtime.cli import run_cli
7
+ from seam_runtime.dsl import compile_dsl
8
+ from seam_runtime.lossless import (
9
+ LosslessArtifact,
10
+ LosslessBenchmarkResult,
11
+ ReadableCompressionArtifact,
12
+ ReadableQueryResult,
13
+ benchmark_text_lossless,
14
+ compress_text_lossless,
15
+ compress_text_readable,
16
+ decompress_text_lossless,
17
+ decompress_text_readable,
18
+ query_readable_compressed,
19
+ )
20
+ from seam_runtime.holographic import (
21
+ HolographicReader,
22
+ SurfaceArtifact,
23
+ SurfacePayload,
24
+ SurfaceQueryResult,
25
+ SurfaceVerification,
26
+ context_surface,
27
+ decode_surface,
28
+ encode_surface,
29
+ query_surface,
30
+ verify_surface,
31
+ )
32
+ from seam_runtime.mirl import IRBatch, MIRLRecord, Pack, RecordKind
33
+ from seam_runtime.models import HashEmbeddingModel, OpenAICompatibleEmbeddingModel
34
+ from seam_runtime.nl import compile_nl
35
+ from seam_runtime.pack import pack_records, unpack_exact_pack
36
+ from seam_runtime.runtime import SeamRuntime
37
+ from seam_runtime.verify import verify_ir
38
+
39
+
40
+ def pack_ir(records, lens: str = "general", budget: int = 512, mode: str = "context") -> Pack:
41
+ if isinstance(records, IRBatch):
42
+ batch = records
43
+ else:
44
+ batch = IRBatch(list(records))
45
+ return pack_records(batch.records, lens=lens, budget=budget, mode=mode)
46
+
47
+
48
+ def decompile_ir(records, mode: str = "expanded") -> str:
49
+ if isinstance(records, IRBatch):
50
+ batch = records
51
+ else:
52
+ batch = IRBatch(list(records))
53
+ states = [record for record in batch.records if record.kind == RecordKind.STA]
54
+ claims = [record for record in batch.records if record.kind == RecordKind.CLM]
55
+ if states:
56
+ summary = "; ".join(f"{key}={value}" for key, value in states[0].attrs.get("fields", {}).items())
57
+ elif claims:
58
+ summary = "; ".join(f"{record.attrs.get('subject')} {record.attrs.get('predicate')} {record.attrs.get('object')}" for record in claims)
59
+ else:
60
+ summary = "No MIRL records available."
61
+ return summary if mode == "minimal" else f"MIRL summary: {summary}"
62
+
63
+
64
+ def render_ir(records) -> str:
65
+ if isinstance(records, IRBatch):
66
+ return records.to_text()
67
+ return IRBatch(list(records)).to_text()
68
+
69
+
70
+ def load_ir_lines(text: str) -> list[MIRLRecord]:
71
+ return IRBatch.from_text(text).records
72
+
73
+
74
+ def unpack_pack(pack: Pack | str):
75
+ if isinstance(pack, Pack):
76
+ if pack.mode == "exact":
77
+ return unpack_exact_pack(pack).to_json()
78
+ return pack.payload
79
+ raise TypeError("unpack_pack now expects a Pack instance")
80
+
81
+
82
+ def lossless_compress(text: str, codec: str = "auto", transform: str = "auto", tokenizer: str = "auto") -> LosslessArtifact:
83
+ return compress_text_lossless(text, codec=codec, transform=transform, tokenizer=tokenizer)
84
+
85
+
86
+ def lossless_decompress(machine_text: str) -> str:
87
+ return decompress_text_lossless(machine_text)
88
+
89
+
90
+ def readable_compress(text: str, source_ref: str = "local://input", granularity: str = "auto", tokenizer: str = "auto") -> ReadableCompressionArtifact:
91
+ return compress_text_readable(text, source_ref=source_ref, granularity=granularity, tokenizer=tokenizer)
92
+
93
+
94
+ def readable_query(machine_text: str, query: str, limit: int = 5) -> ReadableQueryResult:
95
+ return query_readable_compressed(machine_text, query=query, limit=limit)
96
+
97
+
98
+ def readable_decompress(machine_text: str) -> str:
99
+ return decompress_text_readable(machine_text)
100
+
101
+
102
+ def surface_encode(payload: bytes, output_path: str | Path, mode: str = "rgb24", payload_format: str = "auto") -> SurfaceArtifact:
103
+ return encode_surface(payload, Path(output_path), mode=mode, payload_format=payload_format)
104
+
105
+
106
+ def surface_compile(text: str, output_path: str | Path, mode: str = "rgb24", source_ref: str = "local://input") -> SurfaceArtifact:
107
+ batch = compile_nl(text, source_ref=source_ref)
108
+ return encode_surface(batch.to_text().encode("utf-8"), Path(output_path), mode=mode, payload_format="MIRL", source_ref=source_ref)
109
+
110
+
111
+ def surface_decode(path: str | Path) -> SurfacePayload:
112
+ return decode_surface(Path(path))
113
+
114
+
115
+ def surface_verify(path: str | Path) -> SurfaceVerification:
116
+ return verify_surface(Path(path))
117
+
118
+
119
+ def surface_query(path: str | Path, query: str, limit: int = 5) -> SurfaceQueryResult:
120
+ return query_surface(Path(path), query=query, limit=limit)
121
+
122
+
123
+ def lossless_benchmark(
124
+ text: str,
125
+ codec: str = "auto",
126
+ transform: str = "auto",
127
+ min_token_savings: float = 0.30,
128
+ tokenizer: str = "auto",
129
+ ) -> LosslessBenchmarkResult:
130
+ return benchmark_text_lossless(text, codec=codec, transform=transform, min_token_savings=min_token_savings, tokenizer=tokenizer)
131
+
132
+
133
+ def main() -> None:
134
+ run_cli()
135
+
136
+
137
+ def benchmark_main() -> None:
138
+ argv = sys.argv[1:]
139
+ if argv and argv[0] not in {"run", "show", "verify", "diff", "gate", "-h", "--help"} and Path(argv[0]).exists():
140
+ run_cli(["lossless-benchmark", *argv])
141
+ return
142
+ if not argv:
143
+ run_cli(["benchmark", "run"])
144
+ return
145
+ if argv[0] in {"run", "show", "verify", "diff", "gate"}:
146
+ run_cli(["benchmark", *argv])
147
+ return
148
+ run_cli(["benchmark", "run", *argv])
149
+
150
+
151
+ if __name__ == "__main__":
152
+ main()
@@ -0,0 +1,29 @@
1
+ from .mirl import (
2
+ Artifact,
3
+ IRBatch,
4
+ MIRLRecord,
5
+ Pack,
6
+ PersistReport,
7
+ ReconcileReport,
8
+ RecordKind,
9
+ SearchResult,
10
+ Status,
11
+ TraceGraph,
12
+ VerifyReport,
13
+ )
14
+ from .runtime import SeamRuntime
15
+
16
+ __all__ = [
17
+ "Artifact",
18
+ "IRBatch",
19
+ "MIRLRecord",
20
+ "Pack",
21
+ "PersistReport",
22
+ "ReconcileReport",
23
+ "RecordKind",
24
+ "SearchResult",
25
+ "SeamRuntime",
26
+ "Status",
27
+ "TraceGraph",
28
+ "VerifyReport",
29
+ ]
@@ -0,0 +1,145 @@
1
+ from __future__ import annotations
2
+
3
+ import hashlib
4
+ import json
5
+ from dataclasses import dataclass
6
+ from pathlib import Path
7
+ from typing import Iterable
8
+
9
+ from .mirl import IRBatch, MIRLRecord, RecordKind
10
+
11
+
12
+ @dataclass(frozen=True)
13
+ class IngestReport:
14
+ document: dict[str, object]
15
+ stored_ids: list[str]
16
+
17
+ def to_dict(self) -> dict[str, object]:
18
+ return {"document": self.document, "stored_ids": list(self.stored_ids)}
19
+
20
+
21
+ def source_hash(text: str) -> str:
22
+ return hashlib.sha256(text.encode("utf-8")).hexdigest()
23
+
24
+
25
+ def stable_document_id(source_ref: str, text: str) -> str:
26
+ digest = hashlib.sha256(f"{source_ref}\n{source_hash(text)}".encode("utf-8")).hexdigest()[:16]
27
+ return f"doc:{digest}"
28
+
29
+
30
+ def namespace_ingest_batch(batch: IRBatch, document_id: str) -> IRBatch:
31
+ suffix = document_id.split(":", 1)[1]
32
+ id_map = {record.id: _document_record_id(record.id, suffix) for record in batch.records}
33
+ records = []
34
+ for record in batch.records:
35
+ cloned = MIRLRecord.from_dict(record.to_dict())
36
+ cloned.id = id_map[record.id]
37
+ cloned.prov = [id_map.get(item, item) for item in cloned.prov]
38
+ cloned.evidence = [id_map.get(item, item) for item in cloned.evidence]
39
+ cloned.attrs = _rewrite_refs(cloned.attrs, id_map)
40
+ records.append(cloned)
41
+ return IRBatch(records)
42
+
43
+
44
+ def compact_memory_index(records: Iterable[MIRLRecord], query: str, scores: dict[str, float] | None = None) -> dict[str, object]:
45
+ scores = scores or {}
46
+ items = []
47
+ for record in records:
48
+ items.append(
49
+ {
50
+ "id": record.id,
51
+ "kind": record.kind.value,
52
+ "score": round(float(scores.get(record.id, 0.0)), 6),
53
+ "summary": _record_summary(record),
54
+ "refs": sorted(set(record.prov + record.evidence)),
55
+ }
56
+ )
57
+ return {"query": query, "results": items, "next": "Use `seam memory get <ids>` for full records."}
58
+
59
+
60
+ def full_memory_records(records: Iterable[MIRLRecord]) -> dict[str, object]:
61
+ return {"records": [record.to_dict() for record in records]}
62
+
63
+
64
+ def neighbor_timeline(batch: IRBatch, record_ids: list[str]) -> dict[str, object]:
65
+ by_id = batch.by_id()
66
+ selected = [by_id[record_id] for record_id in record_ids if record_id in by_id]
67
+ neighbors: dict[str, list[str]] = {}
68
+ for record in selected:
69
+ refs = set(record.prov + record.evidence)
70
+ for key in ("src", "dst", "target", "raw_id", "subject"):
71
+ value = record.attrs.get(key)
72
+ if isinstance(value, str):
73
+ refs.add(value)
74
+ obj = record.attrs.get("object")
75
+ if isinstance(obj, str):
76
+ refs.add(obj)
77
+ neighbors[record.id] = sorted(ref for ref in refs if ref in by_id)
78
+ ordered = sorted(selected, key=lambda item: (item.t0 or item.created_at, item.id))
79
+ return {
80
+ "ids": list(record_ids),
81
+ "timeline": [{"id": record.id, "kind": record.kind.value, "updated_at": record.updated_at} for record in ordered],
82
+ "neighbors": neighbors,
83
+ }
84
+
85
+
86
+ def render_memory_index(payload: dict[str, object]) -> str:
87
+ lines = [f"Memory search: {payload.get('query')}"]
88
+ results = payload.get("results", [])
89
+ if not results:
90
+ lines.append("(none)")
91
+ for index, item in enumerate(results, start=1):
92
+ lines.append(f"{index}. {item['id']} [{item['kind']}] score={item['score']:.3f}")
93
+ if item.get("summary"):
94
+ lines.append(f" {item['summary']}")
95
+ refs = item.get("refs") or []
96
+ if refs:
97
+ lines.append(f" refs={', '.join(refs)}")
98
+ lines.append(str(payload.get("next", "")))
99
+ return "\n".join(line for line in lines if line)
100
+
101
+
102
+ def render_memory_records(payload: dict[str, object]) -> str:
103
+ records = payload.get("records", [])
104
+ if not records:
105
+ return "No records found."
106
+ return "\n".join(json.dumps(record, sort_keys=True) for record in records)
107
+
108
+
109
+ def read_path_text(path: str) -> tuple[str, str]:
110
+ if path == "-":
111
+ import sys
112
+
113
+ return sys.stdin.read(), "stdin://seam"
114
+ source = Path(path)
115
+ return source.read_bytes().decode("utf-8"), str(source)
116
+
117
+
118
+ def _record_summary(record: MIRLRecord) -> str:
119
+ attrs = record.attrs
120
+ if record.kind == RecordKind.CLM:
121
+ return f"{attrs.get('subject')} {attrs.get('predicate')} {attrs.get('object')}"
122
+ if record.kind == RecordKind.REL:
123
+ return f"{attrs.get('src')} {attrs.get('predicate')} {attrs.get('dst')}"
124
+ if record.kind == RecordKind.STA:
125
+ return f"{attrs.get('target')} {attrs.get('fields')}"
126
+ if record.kind == RecordKind.EVT:
127
+ return f"{attrs.get('actor')} {attrs.get('action')} {attrs.get('object')}"
128
+ return str(attrs)[:180]
129
+
130
+
131
+ def _document_record_id(record_id: str, suffix: str) -> str:
132
+ head, sep, tail = record_id.partition(":")
133
+ if not sep:
134
+ return f"{record_id}:{suffix}"
135
+ return f"{head}:{suffix}:{tail}"
136
+
137
+
138
+ def _rewrite_refs(value, id_map: dict[str, str]):
139
+ if isinstance(value, str):
140
+ return id_map.get(value, value)
141
+ if isinstance(value, list):
142
+ return [_rewrite_refs(item, id_map) for item in value]
143
+ if isinstance(value, dict):
144
+ return {key: _rewrite_refs(item, id_map) for key, item in value.items()}
145
+ return value
@@ -0,0 +1,116 @@
1
+ """CI baseline-source policy for ``seam bench gate``.
2
+
3
+ Picks the most recent benchmark run reachable from the merge-base of HEAD
4
+ and origin/main, excluding any path under ``benchmarks/runs/holdout/``.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import json
10
+ import subprocess
11
+ from pathlib import Path
12
+
13
+
14
+ BENCHMARK_RUNS_DIR = Path("benchmarks") / "runs"
15
+ HOLDOUT_PREFIX = str(BENCHMARK_RUNS_DIR / "holdout")
16
+
17
+
18
+ def resolve_baseline(
19
+ repo_root: Path | None = None,
20
+ current_run: Path | None = None,
21
+ ) -> Path | None:
22
+ """Return the best baseline bundle path, or None for a first-run.
23
+
24
+ Policy:
25
+ 1. Find the merge-base of HEAD and origin/main.
26
+ 2. List all JSON files under ``benchmarks/runs/``, newest first.
27
+ 3. Exclude any path under ``benchmarks/runs/holdout/``.
28
+ 4. Exclude *current_run* itself when provided.
29
+ 5. Return the first run whose git SHA is reachable from the merge-base.
30
+
31
+ Returns None when no baseline exists — the caller treats this as
32
+ "first run" (no regression check, exit 0 with a note).
33
+ """
34
+ root = repo_root or _git_root()
35
+ if root is None:
36
+ return None
37
+
38
+ merge_base = _merge_base(root)
39
+ if merge_base is None:
40
+ return None
41
+
42
+ runs_dir = root / BENCHMARK_RUNS_DIR
43
+ if not runs_dir.is_dir():
44
+ return None
45
+
46
+ candidates = sorted(
47
+ runs_dir.glob("**/*.json"),
48
+ key=lambda p: p.stat().st_mtime,
49
+ reverse=True,
50
+ )
51
+
52
+ for candidate in candidates:
53
+ if _is_holdout_run(candidate, root):
54
+ continue
55
+ if current_run is not None and candidate.resolve() == current_run.resolve():
56
+ continue
57
+ sha = _bundle_git_sha(candidate)
58
+ if sha is None:
59
+ continue
60
+ if _is_reachable(root, sha, merge_base):
61
+ return candidate
62
+
63
+ return None
64
+
65
+
66
+ def _is_holdout_run(path: Path, repo_root: Path) -> bool:
67
+ try:
68
+ relative = path.resolve().relative_to((repo_root / BENCHMARK_RUNS_DIR).resolve())
69
+ except ValueError:
70
+ return False
71
+ return bool(relative.parts) and relative.parts[0] == "holdout"
72
+
73
+
74
+ def _git_root() -> Path | None:
75
+ try:
76
+ result = subprocess.run(
77
+ ["git", "rev-parse", "--show-toplevel"],
78
+ capture_output=True, text=True, timeout=10,
79
+ )
80
+ except Exception:
81
+ return None
82
+ return Path(result.stdout.strip()) if result.returncode == 0 else None
83
+
84
+
85
+ def _merge_base(repo_root: Path) -> str | None:
86
+ try:
87
+ result = subprocess.run(
88
+ ["git", "merge-base", "HEAD", "origin/main"],
89
+ capture_output=True, text=True, timeout=10, cwd=str(repo_root),
90
+ )
91
+ except Exception:
92
+ return None
93
+ return result.stdout.strip() if result.returncode == 0 and result.stdout.strip() else None
94
+
95
+
96
+ def _bundle_git_sha(path: Path) -> str | None:
97
+ try:
98
+ payload = json.loads(path.read_text(encoding="utf-8"))
99
+ except Exception:
100
+ return None
101
+ if isinstance(payload, dict):
102
+ manifest = payload.get("manifest") or {}
103
+ return manifest.get("git_sha") or None
104
+ return None
105
+
106
+
107
+ def _is_reachable(repo_root: Path, sha: str, merge_base: str) -> bool:
108
+ """True if *sha* is an ancestor of *merge_base* (i.e. reachable from it)."""
109
+ try:
110
+ result = subprocess.run(
111
+ ["git", "merge-base", "--is-ancestor", sha, merge_base],
112
+ capture_output=True, timeout=10, cwd=str(repo_root),
113
+ )
114
+ except Exception:
115
+ return False
116
+ return result.returncode == 0