induscode 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.
Files changed (167) hide show
  1. induscode/__init__.py +56 -0
  2. induscode/addons/__init__.py +176 -0
  3. induscode/addons/contract.py +923 -0
  4. induscode/addons/dispatch/__init__.py +43 -0
  5. induscode/addons/dispatch/event_dispatcher.py +348 -0
  6. induscode/addons/dispatch/tool_interceptor.py +349 -0
  7. induscode/addons/host.py +469 -0
  8. induscode/addons/loader.py +314 -0
  9. induscode/addons/manifest.py +232 -0
  10. induscode/addons/surface.py +199 -0
  11. induscode/boot/__init__.py +108 -0
  12. induscode/boot/auth_vault.py +323 -0
  13. induscode/boot/boot.py +210 -0
  14. induscode/boot/contract.py +223 -0
  15. induscode/boot/invocation.py +117 -0
  16. induscode/boot/runners/__init__.py +42 -0
  17. induscode/boot/runners/link_runner.py +82 -0
  18. induscode/boot/runners/oneshot_runner.py +85 -0
  19. induscode/boot/runners/registry.py +46 -0
  20. induscode/boot/runners/repl_runner.py +340 -0
  21. induscode/boot/runners/session.py +549 -0
  22. induscode/boot/stages.py +198 -0
  23. induscode/boot/upgrade/__init__.py +36 -0
  24. induscode/boot/upgrade/apply.py +125 -0
  25. induscode/boot/upgrade/upgrades.py +136 -0
  26. induscode/briefing/__init__.py +115 -0
  27. induscode/briefing/compose.py +414 -0
  28. induscode/briefing/contract.py +528 -0
  29. induscode/briefing/macros.py +721 -0
  30. induscode/briefing/skills.py +417 -0
  31. induscode/capability_deck/__init__.py +233 -0
  32. induscode/capability_deck/bridge_ledger/__init__.py +66 -0
  33. induscode/capability_deck/bridge_ledger/key.py +181 -0
  34. induscode/capability_deck/bridge_ledger/ledger.py +276 -0
  35. induscode/capability_deck/bridge_ledger/network.py +336 -0
  36. induscode/capability_deck/builtin_bridge.py +358 -0
  37. induscode/capability_deck/cards/__init__.py +116 -0
  38. induscode/capability_deck/cards/bg_process.py +482 -0
  39. induscode/capability_deck/cards/memory.py +226 -0
  40. induscode/capability_deck/cards/saas.py +280 -0
  41. induscode/capability_deck/cards/task.py +256 -0
  42. induscode/capability_deck/cards/todo.py +312 -0
  43. induscode/capability_deck/contract.py +450 -0
  44. induscode/capability_deck/manifest.py +126 -0
  45. induscode/capability_deck/provision.py +217 -0
  46. induscode/channels/__init__.py +146 -0
  47. induscode/channels/contract.py +585 -0
  48. induscode/channels/framer.py +132 -0
  49. induscode/channels/link/__init__.py +50 -0
  50. induscode/channels/link/dialog.py +246 -0
  51. induscode/channels/link/driver.py +308 -0
  52. induscode/channels/link/server.py +217 -0
  53. induscode/channels/oneshot.py +178 -0
  54. induscode/channels/ops.py +140 -0
  55. induscode/channels/session_ops.py +172 -0
  56. induscode/conductor/__init__.py +240 -0
  57. induscode/conductor/catalog.py +309 -0
  58. induscode/conductor/conductor.py +1084 -0
  59. induscode/conductor/contract.py +1035 -0
  60. induscode/conductor/matcher.py +291 -0
  61. induscode/conductor/serialize.py +575 -0
  62. induscode/conductor/signal_hub.py +382 -0
  63. induscode/conductor/skill_parse.py +294 -0
  64. induscode/conductor/transcript_store.py +449 -0
  65. induscode/console/__init__.py +236 -0
  66. induscode/console/app.py +1677 -0
  67. induscode/console/components/__init__.py +62 -0
  68. induscode/console/components/banner.py +499 -0
  69. induscode/console/components/banner_sweep.py +188 -0
  70. induscode/console/components/emblem.py +181 -0
  71. induscode/console/components/status_bar.py +102 -0
  72. induscode/console/contract.py +836 -0
  73. induscode/console/input/__init__.py +107 -0
  74. induscode/console/input/chord.py +197 -0
  75. induscode/console/input/dir_reader.py +113 -0
  76. induscode/console/input/intents.py +258 -0
  77. induscode/console/input/providers.py +469 -0
  78. induscode/console/mount.py +137 -0
  79. induscode/console/overlays/__init__.py +94 -0
  80. induscode/console/overlays/auth.py +503 -0
  81. induscode/console/overlays/pickers.py +526 -0
  82. induscode/console/overlays/router.py +129 -0
  83. induscode/console/overlays/sessions.py +232 -0
  84. induscode/console/reducer.py +145 -0
  85. induscode/console/resume_picker.py +156 -0
  86. induscode/console/slash_commands/__init__.py +78 -0
  87. induscode/console/slash_commands/builtins.py +254 -0
  88. induscode/console/slash_commands/dynamic.py +217 -0
  89. induscode/console/slash_commands/integrations.py +949 -0
  90. induscode/console/slash_commands/transcript.py +404 -0
  91. induscode/console/slash_commands/workbench.py +430 -0
  92. induscode/console/startup.py +434 -0
  93. induscode/console/theme/__init__.py +44 -0
  94. induscode/console/theme/adapter.py +168 -0
  95. induscode/console/theme/palette.py +128 -0
  96. induscode/console/theme/resolve.py +123 -0
  97. induscode/console/theme/tokens.py +185 -0
  98. induscode/console_slash/__init__.py +111 -0
  99. induscode/console_slash/contract.py +185 -0
  100. induscode/console_slash/registry.py +140 -0
  101. induscode/console_slash/resolve.py +194 -0
  102. induscode/console_slash/shared.py +172 -0
  103. induscode/entry.py +108 -0
  104. induscode/insight/__init__.py +153 -0
  105. induscode/insight/collector.py +73 -0
  106. induscode/insight/replay.py +305 -0
  107. induscode/insight/wrapper.py +1115 -0
  108. induscode/kit/__init__.py +82 -0
  109. induscode/kit/clipboard_image.py +215 -0
  110. induscode/kit/external_editor.py +120 -0
  111. induscode/kit/image.py +188 -0
  112. induscode/kit/shell.py +89 -0
  113. induscode/kit/tool_fetch.py +288 -0
  114. induscode/launch/__init__.py +224 -0
  115. induscode/launch/catalog.py +310 -0
  116. induscode/launch/contract.py +569 -0
  117. induscode/launch/credentials.py +852 -0
  118. induscode/launch/invocation/__init__.py +39 -0
  119. induscode/launch/invocation/attachments.py +281 -0
  120. induscode/launch/invocation/flags.py +210 -0
  121. induscode/launch/invocation/read.py +369 -0
  122. induscode/launch/invocation/usage.py +110 -0
  123. induscode/launch/oauth.py +808 -0
  124. induscode/launch/packages.py +299 -0
  125. induscode/launch/pickers.py +291 -0
  126. induscode/py.typed +0 -0
  127. induscode/runtime_bridge/__init__.py +166 -0
  128. induscode/runtime_bridge/bridges/__init__.py +66 -0
  129. induscode/runtime_bridge/bridges/_drive.py +268 -0
  130. induscode/runtime_bridge/bridges/builtins.py +177 -0
  131. induscode/runtime_bridge/bridges/claude_cli.py +198 -0
  132. induscode/runtime_bridge/bridges/codex_cli.py +203 -0
  133. induscode/runtime_bridge/bridges/indusagi_cli.py +217 -0
  134. induscode/runtime_bridge/broker.py +397 -0
  135. induscode/runtime_bridge/contract.py +734 -0
  136. induscode/runtime_bridge/sink.py +351 -0
  137. induscode/sessions/__init__.py +25 -0
  138. induscode/sessions/contract.py +119 -0
  139. induscode/sessions/library.py +350 -0
  140. induscode/settings/__init__.py +47 -0
  141. induscode/settings/contract.py +313 -0
  142. induscode/settings/manager.py +268 -0
  143. induscode/transcript_export/__init__.py +109 -0
  144. induscode/transcript_export/contract.py +522 -0
  145. induscode/transcript_export/publish.py +455 -0
  146. induscode/transcript_export/sgr.py +566 -0
  147. induscode/transcript_export/template.py +319 -0
  148. induscode/transcript_export/theme_bridge.py +325 -0
  149. induscode/window_budget/__init__.py +76 -0
  150. induscode/window_budget/budget/__init__.py +26 -0
  151. induscode/window_budget/budget/estimate.py +273 -0
  152. induscode/window_budget/budget/gate.py +60 -0
  153. induscode/window_budget/budget/slice.py +145 -0
  154. induscode/window_budget/condenser.py +170 -0
  155. induscode/window_budget/contract.py +329 -0
  156. induscode/window_budget/summarize/__init__.py +33 -0
  157. induscode/window_budget/summarize/condense.py +212 -0
  158. induscode/window_budget/summarize/prompt.py +241 -0
  159. induscode/workspace/__init__.py +30 -0
  160. induscode/workspace/brand.py +96 -0
  161. induscode/workspace/locator.py +269 -0
  162. induscode-0.1.0.dist-info/METADATA +97 -0
  163. induscode-0.1.0.dist-info/RECORD +167 -0
  164. induscode-0.1.0.dist-info/WHEEL +4 -0
  165. induscode-0.1.0.dist-info/entry_points.txt +3 -0
  166. induscode-0.1.0.dist-info/licenses/CREDITS.md +22 -0
  167. induscode-0.1.0.dist-info/licenses/NOTICE +7 -0
@@ -0,0 +1,140 @@
1
+ """Operation registry — the single declarative source both halves of the link
2
+ consume (port of TS ``src/channels/ops.ts``).
3
+
4
+ The contract defines :func:`~induscode.channels.contract.define_ops` (freeze a
5
+ record of :class:`~induscode.channels.contract.Op` declarations into an
6
+ :data:`~induscode.channels.contract.OpRegistry`). This module adds the runtime
7
+ face the server needs and the driver leans on: a built registry carries its
8
+ ``methods`` list (so a link client can be generated by walking the keys, never
9
+ hand-written) and a ``dispatch`` seam that looks an op up by ``method`` and
10
+ runs its ``handle`` — the data-driven replacement for a copied command switch.
11
+
12
+ Nothing here knows about transport or framing: dispatch takes the already
13
+ parsed ``method``/``params`` and the shared
14
+ :class:`~induscode.channels.contract.ChannelContext`, runs the op, and returns
15
+ its resolved result (or raises :class:`UnknownOpError` when no op is
16
+ registered). The server frames the outcome into a reply; the driver uses
17
+ ``methods`` to build its thunks. One frozen registry drives both.
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ from collections.abc import Mapping
23
+ from dataclasses import dataclass, field
24
+ from typing import Any, Callable, Coroutine
25
+
26
+ from induscode.channels.contract import (
27
+ OP_ERROR,
28
+ ChannelContext,
29
+ Op,
30
+ OpRegistry,
31
+ define_ops,
32
+ )
33
+
34
+ __all__ = [
35
+ "OpRegistryHandle",
36
+ "UnknownOpError",
37
+ "build_ops",
38
+ "define_ops",
39
+ "dispatch",
40
+ "has_op",
41
+ "methods_of",
42
+ ]
43
+
44
+
45
+ class UnknownOpError(Exception):
46
+ """Raised by :func:`dispatch` (and :meth:`OpRegistryHandle.dispatch`) when
47
+ the requested ``method`` has no registered :class:`Op`.
48
+
49
+ Carries the frozen ``OP_ERROR["unknownOp"]`` code so the server can frame
50
+ it into an error reply without re-deriving the category, and records the
51
+ offending ``method`` for logging.
52
+ """
53
+
54
+ def __init__(self, method: str) -> None:
55
+ super().__init__(f"Unknown op: {method}")
56
+ #: The JSON-RPC error category for an unregistered method.
57
+ self.code: int = OP_ERROR["unknownOp"]
58
+ #: The method name that resolved to no operation.
59
+ self.method: str = method
60
+
61
+
62
+ async def dispatch(
63
+ registry: OpRegistry,
64
+ method: str,
65
+ params: Any,
66
+ ctx: ChannelContext,
67
+ ) -> Any:
68
+ """Run one operation by name against the shared context.
69
+
70
+ Looks ``method`` up in ``registry``, then awaits its
71
+ ``handle(params, ctx)``. The lone dispatch path for the server: there is
72
+ no per-method branch, only a map lookup. Raises :class:`UnknownOpError`
73
+ when the method is not registered and propagates whatever the handler
74
+ raises (the server maps that to an error reply).
75
+
76
+ :param registry: the frozen :data:`OpRegistry` to dispatch within
77
+ :param method: the wire method name to invoke
78
+ :param params: the already-parsed request payload (passed through verbatim)
79
+ :param ctx: the shared :class:`ChannelContext`
80
+ :returns: the operation result
81
+ """
82
+ op = registry.get(method)
83
+ if op is None:
84
+ raise UnknownOpError(method)
85
+ return await op.handle(params, ctx)
86
+
87
+
88
+ def has_op(registry: OpRegistry, method: str) -> bool:
89
+ """Whether ``method`` resolves to a registered :class:`Op` in ``registry``."""
90
+ return method in registry
91
+
92
+
93
+ def methods_of(registry: OpRegistry) -> tuple[str, ...]:
94
+ """The sorted wire method names a registry exposes — the driver's method
95
+ set."""
96
+ return tuple(sorted(registry.keys()))
97
+
98
+
99
+ @dataclass(frozen=True, slots=True)
100
+ class OpRegistryHandle:
101
+ """A built registry plus its runtime face: the method list and a bound
102
+ ``dispatch``.
103
+
104
+ ``methods`` is what a generated link client walks to build its thunks;
105
+ ``dispatch`` is what the server calls per request. Both are bound to the
106
+ one frozen ``registry``, so the server-side dispatch and the client-side
107
+ method set can never drift from each other.
108
+ """
109
+
110
+ #: The frozen registry — the single source of truth.
111
+ registry: OpRegistry
112
+ #: The sorted method names this registry exposes.
113
+ methods: tuple[str, ...]
114
+ #: Invoke an op by name against a context; see :func:`dispatch`.
115
+ dispatch: Callable[[str, Any, ChannelContext], Coroutine[Any, Any, Any]] = field(repr=False)
116
+
117
+
118
+ def build_ops(ops: Mapping[str, Op]) -> OpRegistryHandle:
119
+ """Build an :class:`OpRegistryHandle` from a record of operation
120
+ declarations.
121
+
122
+ Freezes the input with :func:`define_ops`, then bundles it with its
123
+ derived method list and a ``dispatch`` bound to that frozen registry. This
124
+ is the lone sanctioned way to produce the object the server and the driver
125
+ both consume, so the dispatch map and the driver method set always derive
126
+ from one source.
127
+
128
+ :param ops: a record of method-name → :class:`Op`
129
+ :returns: the frozen registry handle
130
+ """
131
+ registry = define_ops(ops)
132
+
133
+ async def bound_dispatch(method: str, params: Any, ctx: ChannelContext) -> Any:
134
+ return await dispatch(registry, method, params, ctx)
135
+
136
+ return OpRegistryHandle(
137
+ registry=registry,
138
+ methods=methods_of(registry),
139
+ dispatch=bound_dispatch,
140
+ )
@@ -0,0 +1,172 @@
1
+ """Session ops — the concrete operation registry that drives the link
2
+ (port of TS ``src/channels/session-ops.ts``).
3
+
4
+ This is the single declarative source of every operation the link server
5
+ dispatches and the generated link client is built from. Each op binds a wire
6
+ ``method`` name to a ``handle`` that delegates to the
7
+ :class:`~induscode.conductor.contract.SessionConductor` carried on the
8
+ :class:`~induscode.channels.contract.ChannelContext`; there is no per-method
9
+ dispatch ladder and no hand-written parallel client method. Adding a row here
10
+ adds both a server-handled method and a callable driver method.
11
+
12
+ The ops also own the :data:`~induscode.channels.contract.LinkSnapshot`
13
+ projection: the conductor exposes its internal
14
+ :class:`~induscode.conductor.contract.ConductorState`, and
15
+ :func:`project_snapshot` reshapes that into the flat, serializable wire
16
+ vocabulary a remote driver mirrors without holding a live conductor.
17
+
18
+ Port notes
19
+ ----------
20
+ - Wire method names (``submit`` / ``abort`` / ``snapshot`` / ``resume`` /
21
+ ``listModels`` / ``cycleModel``) and the snapshot field names/casing are
22
+ kept **verbatim** from TS for cross-host compatibility.
23
+ - TS param interfaces (``SubmitParams`` etc.) typed the registry statically;
24
+ the Python handlers index the decoded wire dict directly
25
+ (``params["input"]``, ``params["sessionId"]``, ``params["modelId"]``).
26
+ - TS ``ctx.conductor.cycleModel?.(…)`` (optional method) becomes a ``getattr``
27
+ probe for the Python conductor's ``cycle_model`` — same as the conductor
28
+ contract's own port note for optional members.
29
+ - ``usage`` rides the snapshot through the one app-wide codec
30
+ (:func:`~induscode.conductor.serialize.message_to_dict`, plan rule 2).
31
+ """
32
+
33
+ from __future__ import annotations
34
+
35
+ from typing import Any
36
+
37
+ from induscode.channels.contract import (
38
+ ChannelContext,
39
+ ConductorState,
40
+ LinkSnapshot,
41
+ Op,
42
+ OpRegistry,
43
+ ThinkingLevel,
44
+ define_ops,
45
+ )
46
+ from induscode.conductor.serialize import message_to_dict
47
+
48
+ __all__ = [
49
+ "DEFAULT_THINKING",
50
+ "SESSION_OPS",
51
+ "project_snapshot",
52
+ ]
53
+
54
+ #: The reasoning effort reported when a snapshot carries none of its own.
55
+ DEFAULT_THINKING: ThinkingLevel = "off"
56
+
57
+
58
+ # ---------------------------------------------------------------------------
59
+ # Snapshot projection
60
+ # ---------------------------------------------------------------------------
61
+
62
+
63
+ def project_snapshot(
64
+ state: ConductorState,
65
+ *,
66
+ thinking: ThinkingLevel | None = None,
67
+ sessionFile: str | None = None,
68
+ autoCondense: bool | None = None,
69
+ messageCount: int | None = None,
70
+ queuedCount: int | None = None,
71
+ ) -> LinkSnapshot:
72
+ """Project a conductor :class:`ConductorState` onto the wire
73
+ :data:`LinkSnapshot`.
74
+
75
+ The snapshot is the link vocabulary: flat, serializable, and derived from
76
+ — not a passthrough of — the conductor state. Busy flags are read off the
77
+ coarse phase, the model and session identity off the state and its head,
78
+ and the cumulative usage carried straight through (as its codec dict).
79
+ Field names/casing are the verbatim TS wire vocabulary; ``sessionFile`` is
80
+ omitted (not nulled) when absent, exactly as ``JSON.stringify`` dropped
81
+ the undefined TS field.
82
+
83
+ :param state: the immutable conductor state
84
+ :param thinking: reasoning effort the conductor does not surface on state
85
+ :param sessionFile: on-disk transcript file backing the session
86
+ :param autoCondense: whether auto-condense is engaged (default ``True``)
87
+ :param messageCount: nodes on the active transcript branch (default 0)
88
+ :param queuedCount: inputs queued behind the in-flight turn (default 0)
89
+ """
90
+ snapshot: LinkSnapshot = {
91
+ "model": state.modelId,
92
+ "thinking": thinking if thinking is not None else DEFAULT_THINKING,
93
+ "streaming": state.phase == "streaming" or state.phase == "tooling",
94
+ "condensing": state.phase == "condensing",
95
+ "faulted": state.phase == "faulted",
96
+ "sessionId": state.head.sessionId,
97
+ "autoCondense": autoCondense if autoCondense is not None else True,
98
+ "messageCount": messageCount if messageCount is not None else 0,
99
+ "queuedCount": queuedCount if queuedCount is not None else 0,
100
+ "usage": message_to_dict(state.usage),
101
+ }
102
+ if sessionFile is not None:
103
+ snapshot["sessionFile"] = sessionFile
104
+ return snapshot
105
+
106
+
107
+ # ---------------------------------------------------------------------------
108
+ # The op set
109
+ # ---------------------------------------------------------------------------
110
+
111
+
112
+ async def _submit(params: Any, ctx: ChannelContext) -> LinkSnapshot:
113
+ """Run a user turn to settlement and reply with a snapshot."""
114
+ state = await ctx.conductor.submit(params["input"])
115
+ return project_snapshot(state)
116
+
117
+
118
+ async def _abort(params: Any, ctx: ChannelContext) -> LinkSnapshot:
119
+ """Cancel the in-flight turn and reply with a snapshot."""
120
+ ctx.conductor.abort()
121
+ return project_snapshot(ctx.conductor.snapshot())
122
+
123
+
124
+ async def _snapshot(params: Any, ctx: ChannelContext) -> LinkSnapshot:
125
+ """Read the current state, projected to a :data:`LinkSnapshot`."""
126
+ return project_snapshot(ctx.conductor.snapshot())
127
+
128
+
129
+ async def _resume(params: Any, ctx: ChannelContext) -> LinkSnapshot:
130
+ """Restore a persisted session and reply with a snapshot."""
131
+ await ctx.conductor.resume(params["sessionId"])
132
+ return project_snapshot(ctx.conductor.snapshot())
133
+
134
+
135
+ async def _list_models(params: Any, ctx: ChannelContext) -> list[dict[str, Any]]:
136
+ """List the model bound to the session (the active entry). Each row is the
137
+ wire ``ModelEntry`` shape ``{"id", "active"}``."""
138
+ active = ctx.conductor.snapshot().modelId
139
+ return [{"id": active, "active": True}]
140
+
141
+
142
+ async def _cycle_model(params: Any, ctx: ChannelContext) -> LinkSnapshot:
143
+ """Rotate the active model and reply with a snapshot. Probes for the
144
+ conductor's optional ``cycle_model`` (TS ``cycleModel?.()``)."""
145
+ cycle = getattr(ctx.conductor, "cycle_model", None)
146
+ if callable(cycle):
147
+ cycle(params["modelId"])
148
+ return project_snapshot(ctx.conductor.snapshot())
149
+
150
+
151
+ #: The frozen link op set: every operation a driver can invoke, each
152
+ #: delegating to the conductor on the context.
153
+ #:
154
+ #: - ``submit`` — run a user turn to settlement and reply with a snapshot.
155
+ #: - ``abort`` — cancel the in-flight turn and reply with a snapshot.
156
+ #: - ``snapshot`` — read the current state, projected to a snapshot.
157
+ #: - ``resume`` — restore a persisted session and reply with a snapshot.
158
+ #: - ``listModels`` — list the model bound to the session (the active entry).
159
+ #: - ``cycleModel`` — rotate the active model and reply with a snapshot.
160
+ #:
161
+ #: The map is consumed verbatim by the server (data-driven dispatch) and by
162
+ #: the generated link client (its method set is exactly these keys).
163
+ SESSION_OPS: OpRegistry = define_ops(
164
+ {
165
+ "submit": Op(method="submit", handle=_submit),
166
+ "abort": Op(method="abort", handle=_abort),
167
+ "snapshot": Op(method="snapshot", handle=_snapshot),
168
+ "resume": Op(method="resume", handle=_resume),
169
+ "listModels": Op(method="listModels", handle=_list_models),
170
+ "cycleModel": Op(method="cycleModel", handle=_cycle_model),
171
+ }
172
+ )
@@ -0,0 +1,240 @@
1
+ """Conductor — the product-level session orchestration layer (public barrel).
2
+
3
+ The framework ``Agent`` (:mod:`indusagi.agent`) is a raw LLM conversation
4
+ loop; the conductor wraps exactly one such agent and turns it into a
5
+ *coding-agent session*: a stable product signal stream
6
+ (:data:`SessionSignal`), typed faults (:class:`ConductorFault`), an
7
+ immutable state snapshot (:class:`ConductorState`) maintained by the pure
8
+ :func:`reduce_state` reducer, a branchable on-disk transcript vocabulary
9
+ (:class:`TranscriptEntry` / :class:`SessionHead` /
10
+ :data:`TRANSCRIPT_SCHEMA`), and the :class:`SessionConductor` Protocol the
11
+ interactive console, oneshot/print mode, and JSON-RPC link all drive.
12
+
13
+ M2 wave-1 surface (this barrel today):
14
+
15
+ - :mod:`.contract` — the FROZEN type seam: signals, faults, transcript
16
+ schema, catalog refs/queries, state + reducer, queue/stats/bash shapes,
17
+ and the :class:`SessionConductor` / :class:`AgentLike` /
18
+ :class:`CondenseFn` / :class:`RetryPolicy` seams.
19
+ - :mod:`.signal_hub` — the :class:`SignalHub` fan-out bus plus the
20
+ framework-event → product-signal projector
21
+ (:func:`translate_agent_event` / :data:`TRANSLATOR_TABLE`).
22
+ - :mod:`.skill_parse` — the re-derived ``<skill …>body</skill>`` block
23
+ scanner (:func:`parse_skill_invocation`).
24
+ - :mod:`.catalog` / :mod:`.matcher` — the normalized model catalog over the
25
+ framework registry and the scored-candidate matcher
26
+ (:class:`ModelCatalog` / :class:`ModelMatcher` / :func:`canonical_id` /
27
+ :func:`to_card_ref`).
28
+ - :mod:`.transcript_store` / :mod:`.serialize` — the branchable transcript
29
+ tree store, NDJSON envelope + the one app-wide message⇄dict codec, and the
30
+ legacy framework-session import (:class:`TranscriptStore` /
31
+ :func:`memory_backend` / :func:`fs_backend` / :func:`replay` /
32
+ :func:`message_to_dict` / :func:`message_from_dict`).
33
+
34
+ M2 wave-2 surface (landed):
35
+
36
+ - :mod:`.conductor` — the :class:`SessionConductorImpl` turn loop +
37
+ :func:`create_session_conductor` factory (queue drain, transient-fault
38
+ retry with injectable sleep, per-message persist tail, condense seam,
39
+ fork/navigate, ``execute_bash`` on asyncio subprocess, thinking ladder,
40
+ :func:`noop_condense`, :class:`ConductorDeps`, :data:`DEFAULT_RETRY`, and
41
+ the lazy live-agent assembly :class:`LazyAgent`).
42
+ """
43
+
44
+ from __future__ import annotations
45
+
46
+ from .contract import (
47
+ FAULT_KINDS,
48
+ QUEUE_MODES,
49
+ SIGNAL_KINDS,
50
+ TRANSCRIPT_ROLES,
51
+ TRANSCRIPT_SCHEMA,
52
+ AgentLike,
53
+ AgentMessage,
54
+ AgentStateLike,
55
+ AgentTool,
56
+ BashOutcome,
57
+ CompactedSignal,
58
+ CondenseFn,
59
+ ConductorFault,
60
+ ConductorPhase,
61
+ ConductorState,
62
+ ExecuteBashOptions,
63
+ FaultAction,
64
+ FaultKind,
65
+ FaultSignal,
66
+ HeadAction,
67
+ IdleSignal,
68
+ KnownProvider,
69
+ MatchQuery,
70
+ Model,
71
+ ModelAction,
72
+ ModelCardRef,
73
+ PersistedSignal,
74
+ PhaseAction,
75
+ PromptSignal,
76
+ QueuedInput,
77
+ QueueMode,
78
+ QueueSignal,
79
+ RetryPolicy,
80
+ SessionConductor,
81
+ SessionConductorOptions,
82
+ SessionHead,
83
+ SessionSignal,
84
+ SessionStats,
85
+ SettledAction,
86
+ SignalHandler,
87
+ SignalKind,
88
+ StateAction,
89
+ TextSignal,
90
+ ThinkingLevel,
91
+ ThinkingSignal,
92
+ TokenTally,
93
+ ToolEndSignal,
94
+ ToolStartSignal,
95
+ TranscriptEntry,
96
+ TranscriptRole,
97
+ TranscriptSchema,
98
+ TurnEndSignal,
99
+ Usage,
100
+ UsageAction,
101
+ conductor_fault,
102
+ reduce_state,
103
+ )
104
+ from .catalog import (
105
+ CatalogCard,
106
+ CatalogSource,
107
+ ModelCatalog,
108
+ canonical_id,
109
+ to_card_ref,
110
+ )
111
+ from .conductor import (
112
+ DEFAULT_RETRY,
113
+ ConductorDeps,
114
+ LazyAgent,
115
+ SessionConductorImpl,
116
+ create_session_conductor,
117
+ noop_condense,
118
+ )
119
+ from .matcher import ModelMatcher, ResolveInput
120
+ from .serialize import (
121
+ ParsedSessionFile,
122
+ branch_to_llm_messages,
123
+ branch_to_messages,
124
+ encode_entry,
125
+ encode_head,
126
+ import_legacy_file,
127
+ import_legacy_text,
128
+ message_from_dict,
129
+ message_to_dict,
130
+ parse_session_text,
131
+ resolve_legacy_messages,
132
+ role_for_message,
133
+ )
134
+ from .signal_hub import TRANSLATOR_TABLE, SignalHub, translate_agent_event
135
+ from .skill_parse import SkillInvocation, parse_skill_invocation
136
+ from .transcript_store import (
137
+ TranscriptBackend,
138
+ TranscriptClock,
139
+ TranscriptState,
140
+ TranscriptStore,
141
+ fs_backend,
142
+ memory_backend,
143
+ replay,
144
+ )
145
+
146
+ __all__ = [
147
+ "AgentLike",
148
+ "AgentMessage",
149
+ "AgentStateLike",
150
+ "AgentTool",
151
+ "BashOutcome",
152
+ "CatalogCard",
153
+ "CatalogSource",
154
+ "CompactedSignal",
155
+ "CondenseFn",
156
+ "ConductorDeps",
157
+ "ConductorFault",
158
+ "ConductorPhase",
159
+ "ConductorState",
160
+ "DEFAULT_RETRY",
161
+ "ExecuteBashOptions",
162
+ "FAULT_KINDS",
163
+ "FaultAction",
164
+ "FaultKind",
165
+ "FaultSignal",
166
+ "HeadAction",
167
+ "IdleSignal",
168
+ "KnownProvider",
169
+ "LazyAgent",
170
+ "MatchQuery",
171
+ "Model",
172
+ "ModelAction",
173
+ "ModelCardRef",
174
+ "ModelCatalog",
175
+ "ModelMatcher",
176
+ "ParsedSessionFile",
177
+ "PersistedSignal",
178
+ "PhaseAction",
179
+ "PromptSignal",
180
+ "QUEUE_MODES",
181
+ "QueueMode",
182
+ "QueueSignal",
183
+ "QueuedInput",
184
+ "ResolveInput",
185
+ "RetryPolicy",
186
+ "SIGNAL_KINDS",
187
+ "SessionConductor",
188
+ "SessionConductorImpl",
189
+ "SessionConductorOptions",
190
+ "SessionHead",
191
+ "SessionSignal",
192
+ "SessionStats",
193
+ "SettledAction",
194
+ "SignalHandler",
195
+ "SignalHub",
196
+ "SignalKind",
197
+ "SkillInvocation",
198
+ "StateAction",
199
+ "TRANSCRIPT_ROLES",
200
+ "TRANSCRIPT_SCHEMA",
201
+ "TRANSLATOR_TABLE",
202
+ "TextSignal",
203
+ "ThinkingLevel",
204
+ "ThinkingSignal",
205
+ "TokenTally",
206
+ "ToolEndSignal",
207
+ "ToolStartSignal",
208
+ "TranscriptBackend",
209
+ "TranscriptClock",
210
+ "TranscriptEntry",
211
+ "TranscriptRole",
212
+ "TranscriptSchema",
213
+ "TranscriptState",
214
+ "TranscriptStore",
215
+ "TurnEndSignal",
216
+ "Usage",
217
+ "UsageAction",
218
+ "branch_to_llm_messages",
219
+ "branch_to_messages",
220
+ "canonical_id",
221
+ "conductor_fault",
222
+ "create_session_conductor",
223
+ "encode_entry",
224
+ "encode_head",
225
+ "fs_backend",
226
+ "import_legacy_file",
227
+ "import_legacy_text",
228
+ "memory_backend",
229
+ "message_from_dict",
230
+ "message_to_dict",
231
+ "noop_condense",
232
+ "parse_session_text",
233
+ "parse_skill_invocation",
234
+ "reduce_state",
235
+ "replay",
236
+ "resolve_legacy_messages",
237
+ "role_for_message",
238
+ "to_card_ref",
239
+ "translate_agent_event",
240
+ ]