monkeybot 2.1.1__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 (178) hide show
  1. monkeybot/__init__.py +3 -0
  2. monkeybot/cli/__init__.py +3 -0
  3. monkeybot/cli/__main__.py +8 -0
  4. monkeybot/cli/audio_io.py +8 -0
  5. monkeybot/cli/gateway_manager.py +17 -0
  6. monkeybot/cli/main.py +22 -0
  7. monkeybot/cli/push_to_talk.py +12 -0
  8. monkeybot/cli/realtime_client.py +13 -0
  9. monkeybot/core/__init__.py +19 -0
  10. monkeybot/core/attachments/__init__.py +22 -0
  11. monkeybot/core/attachments/catalog.py +62 -0
  12. monkeybot/core/attachments/config.py +52 -0
  13. monkeybot/core/attachments/freeze.py +158 -0
  14. monkeybot/core/attachments/resolve.py +70 -0
  15. monkeybot/core/attachments/store.py +180 -0
  16. monkeybot/core/attachments/text.py +72 -0
  17. monkeybot/core/attachments/tools.py +54 -0
  18. monkeybot/core/bootstrap.py +242 -0
  19. monkeybot/core/config/__init__.py +71 -0
  20. monkeybot/core/config/realtime_config.py +150 -0
  21. monkeybot/core/config/runtime_env.py +262 -0
  22. monkeybot/core/config/settings.py +341 -0
  23. monkeybot/core/config/validation.py +249 -0
  24. monkeybot/core/config/yaml_loader.py +45 -0
  25. monkeybot/core/context/__init__.py +781 -0
  26. monkeybot/core/context/campaign_context.py +8 -0
  27. monkeybot/core/context/common.py +14 -0
  28. monkeybot/core/context/curator.py +255 -0
  29. monkeybot/core/context/epoch.py +226 -0
  30. monkeybot/core/context/memory_prompt.py +222 -0
  31. monkeybot/core/context/tool_output_policy.py +270 -0
  32. monkeybot/core/context/tool_result_ingress.py +290 -0
  33. monkeybot/core/context/tool_shapers.py +361 -0
  34. monkeybot/core/hooks/__init__.py +261 -0
  35. monkeybot/core/llm/__init__.py +4 -0
  36. monkeybot/core/llm/provider.py +296 -0
  37. monkeybot/core/llm/realtime_provider.py +203 -0
  38. monkeybot/core/llm/usage.py +57 -0
  39. monkeybot/core/logging_utils.py +24 -0
  40. monkeybot/core/mcp/__init__.py +1 -0
  41. monkeybot/core/mcp/mcp_client.py +1215 -0
  42. monkeybot/core/mcp/ports_mcp.py +109 -0
  43. monkeybot/core/memory/__init__.py +24 -0
  44. monkeybot/core/memory/hook.py +413 -0
  45. monkeybot/core/memory/index_format.py +104 -0
  46. monkeybot/core/memory/integrity.py +180 -0
  47. monkeybot/core/memory/organizer.py +270 -0
  48. monkeybot/core/memory/storage_ops.py +139 -0
  49. monkeybot/core/memory/subsystem.py +91 -0
  50. monkeybot/core/messages/__init__.py +16 -0
  51. monkeybot/core/messages/convert_provider.py +41 -0
  52. monkeybot/core/messages/tool_integrity.py +262 -0
  53. monkeybot/core/messages/transform_context.py +84 -0
  54. monkeybot/core/path_safety.py +11 -0
  55. monkeybot/core/persistence/__init__.py +17 -0
  56. monkeybot/core/persistence/backends.py +236 -0
  57. monkeybot/core/persistence/db.py +28 -0
  58. monkeybot/core/persistence/durable_runs.py +286 -0
  59. monkeybot/core/persistence/firestore.py +658 -0
  60. monkeybot/core/persistence/firestore_scheduled_loops.py +336 -0
  61. monkeybot/core/persistence/history.py +156 -0
  62. monkeybot/core/persistence/postgres.py +895 -0
  63. monkeybot/core/persistence/runs.py +76 -0
  64. monkeybot/core/persistence/scheduled_loops.py +435 -0
  65. monkeybot/core/persistence/session_turn_locks.py +94 -0
  66. monkeybot/core/persistence/sqlite.py +218 -0
  67. monkeybot/core/persistence/sqlite_backend.py +74 -0
  68. monkeybot/core/persistence/thread_summary.py +61 -0
  69. monkeybot/core/persistence/transcript.py +194 -0
  70. monkeybot/core/persistence/usage.py +149 -0
  71. monkeybot/core/prompts/__init__.py +1 -0
  72. monkeybot/core/prompts/harness_prompt.py +197 -0
  73. monkeybot/core/prompts/prompt.py +215 -0
  74. monkeybot/core/runtime/__init__.py +1 -0
  75. monkeybot/core/runtime/context_budget.py +267 -0
  76. monkeybot/core/runtime/events.py +819 -0
  77. monkeybot/core/runtime/input_admission.py +154 -0
  78. monkeybot/core/runtime/loop.py +2374 -0
  79. monkeybot/core/runtime/provider_stream_mapper.py +159 -0
  80. monkeybot/core/runtime/realtime_loop.py +654 -0
  81. monkeybot/core/runtime/utterance_buffer.py +179 -0
  82. monkeybot/core/subagents/__init__.py +1 -0
  83. monkeybot/core/subagents/subagent_proto.py +331 -0
  84. monkeybot/core/subagents/subagent_worker.py +441 -0
  85. monkeybot/core/subagents/worker_pool.py +403 -0
  86. monkeybot/core/testing/__init__.py +1 -0
  87. monkeybot/core/testing/mocks_provider.py +86 -0
  88. monkeybot/core/testing/mocks_realtime_provider.py +137 -0
  89. monkeybot/core/tools/__init__.py +1 -0
  90. monkeybot/core/tools/core_tool_executor.py +1548 -0
  91. monkeybot/core/tools/inspector.py +226 -0
  92. monkeybot/core/tools/loop_inspector.py +45 -0
  93. monkeybot/core/tools/patch.py +480 -0
  94. monkeybot/core/tools/permission.py +284 -0
  95. monkeybot/core/tools/sandbox_executor.py +255 -0
  96. monkeybot/core/tools/spill_inventory.py +35 -0
  97. monkeybot/core/tools/terminal.py +381 -0
  98. monkeybot/core/tools/text_normalize.py +25 -0
  99. monkeybot/core/tools/types.py +33 -0
  100. monkeybot/core/tools/workspace_service.py +710 -0
  101. monkeybot/core/tools/workspace_tools.py +116 -0
  102. monkeybot/core/types/__init__.py +1 -0
  103. monkeybot/core/types/content_blocks.py +644 -0
  104. monkeybot/core/types/interfaces.py +156 -0
  105. monkeybot/core/types/types_tools.py +29 -0
  106. monkeybot/core/workspace/__init__.py +8 -0
  107. monkeybot/core/workspace/factory.py +45 -0
  108. monkeybot/core/workspace/gcs.py +130 -0
  109. monkeybot/core/workspace/local.py +162 -0
  110. monkeybot/core/workspace/protocol.py +45 -0
  111. monkeybot/core/workspace/s3.py +151 -0
  112. monkeybot/core/workspace_layout.py +27 -0
  113. monkeybot/gateway/__init__.py +1 -0
  114. monkeybot/gateway/bootstrap.py +18 -0
  115. monkeybot/gateway/main.py +47 -0
  116. monkeybot/gateway/realtime/__init__.py +31 -0
  117. monkeybot/gateway/realtime/app.py +321 -0
  118. monkeybot/gateway/realtime/deps.py +52 -0
  119. monkeybot/gateway/realtime/errors.py +81 -0
  120. monkeybot/gateway/realtime/guardrails.py +88 -0
  121. monkeybot/gateway/realtime/manager.py +77 -0
  122. monkeybot/gateway/realtime/metrics.py +144 -0
  123. monkeybot/gateway/realtime/routes.py +864 -0
  124. monkeybot/gateway/realtime/session.py +232 -0
  125. monkeybot/gateway/realtime/wire.py +412 -0
  126. monkeybot/gateway/realtime_main.py +49 -0
  127. monkeybot/gateway/sse/__init__.py +1 -0
  128. monkeybot/gateway/sse/app.py +733 -0
  129. monkeybot/gateway/sse/loop_port.py +31 -0
  130. monkeybot/gateway/sse/models.py +177 -0
  131. monkeybot/gateway/sse/reply_body.py +91 -0
  132. monkeybot/gateway/sse/routes.py +1101 -0
  133. monkeybot/gateway/sse/scheduler_routes.py +200 -0
  134. monkeybot/gateway/sse/scheduler_wiring.py +96 -0
  135. monkeybot/gateway/sse/session_bus.py +226 -0
  136. monkeybot/gateway/sse/sse.py +46 -0
  137. monkeybot/gateway/sse/workspace_layout.py +7 -0
  138. monkeybot/observability/__init__.py +220 -0
  139. monkeybot/observability/_state.py +10 -0
  140. monkeybot/observability/instrumentation.py +153 -0
  141. monkeybot/observability/propagation.py +65 -0
  142. monkeybot/observability/spans.py +455 -0
  143. monkeybot/providers/__init__.py +19 -0
  144. monkeybot/providers/_openai_compat.py +450 -0
  145. monkeybot/providers/_utils.py +473 -0
  146. monkeybot/providers/bedrock.py +145 -0
  147. monkeybot/providers/claude.py +125 -0
  148. monkeybot/providers/gemini.py +677 -0
  149. monkeybot/providers/gemini_live.py +398 -0
  150. monkeybot/providers/huggingface.py +129 -0
  151. monkeybot/providers/nvidia.py +104 -0
  152. monkeybot/providers/ollama.py +152 -0
  153. monkeybot/providers/openai.py +127 -0
  154. monkeybot/providers/pricing.py +60 -0
  155. monkeybot/providers/sampling.py +44 -0
  156. monkeybot/providers/vertex_claude.py +148 -0
  157. monkeybot/scaffold/__init__.py +33 -0
  158. monkeybot/scheduler/__init__.py +13 -0
  159. monkeybot/scheduler/__main__.py +4 -0
  160. monkeybot/scheduler/engine.py +333 -0
  161. monkeybot/scheduler/http_invoker.py +61 -0
  162. monkeybot/scheduler/interval.py +77 -0
  163. monkeybot/scheduler/tick_result.py +34 -0
  164. monkeybot/scheduler/worker.py +87 -0
  165. monkeybot/subagents/__init__.py +1 -0
  166. monkeybot/subagents/worker/__init__.py +1 -0
  167. monkeybot/subagents/worker/__main__.py +22 -0
  168. monkeybot/web_search/__init__.py +82 -0
  169. monkeybot/web_search/backends/__init__.py +5 -0
  170. monkeybot/web_search/backends/duckduckgo.py +32 -0
  171. monkeybot/web_search/backends/firecrawl.py +43 -0
  172. monkeybot/web_search/backends/tavily.py +45 -0
  173. monkeybot/web_search/protocol.py +25 -0
  174. monkeybot/web_search/tool.py +56 -0
  175. monkeybot-2.1.1.dist-info/METADATA +318 -0
  176. monkeybot-2.1.1.dist-info/RECORD +178 -0
  177. monkeybot-2.1.1.dist-info/WHEEL +4 -0
  178. monkeybot-2.1.1.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,159 @@
1
+ """Map provider stream events to agent events with text/thinking block bounds."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from monkeybot.core.llm.provider import (
6
+ Done,
7
+ GroundingEvent as ProviderGroundingEvent,
8
+ ProviderEvent,
9
+ TextDelta,
10
+ ThinkingDelta,
11
+ ToolCall,
12
+ ToolInputDelta,
13
+ UsageEvent,
14
+ )
15
+ from monkeybot.core.runtime.events import (
16
+ AgentEvent,
17
+ AssistantDelta,
18
+ AssistantTextEnded,
19
+ AssistantTextStarted,
20
+ GroundingEvent,
21
+ ThinkingBlockComplete,
22
+ ThinkingBlockDelta,
23
+ ThinkingBlockStarted,
24
+ ToolInputDeltaEvent,
25
+ )
26
+
27
+
28
+ class ProviderStreamMapper:
29
+ """Stateful mapper: provider deltas → additive agent streaming events.
30
+
31
+ Accumulates assistant/thinking text and pending tool calls. Callers handle
32
+ ``UsageEvent`` cost accounting themselves.
33
+
34
+ Text and thinking blocks are mutually exclusive and LIFO: starting one
35
+ closes the other if open. Blocks may re-enter after being closed (OpenAI-
36
+ compatible adapters can emit ``TextDelta`` then ``ThinkingDelta`` from the
37
+ same chunk, and later resume text).
38
+ """
39
+
40
+ def __init__(self, request_id: str) -> None:
41
+ self.request_id = request_id
42
+ self.assistant_text = ""
43
+ self.thinking_text = ""
44
+ self.thinking_signature: str | None = None
45
+ self.thinking_streamed = False
46
+ self.pending: dict[str, ToolCall] = {}
47
+ self.stream_truncated = False
48
+ self._text_open = False
49
+ self._thinking_open = False
50
+
51
+ def map(self, ev: ProviderEvent) -> list[AgentEvent]:
52
+ """Map one provider event. ``Done`` sets ``stream_truncated`` and returns ``[]``."""
53
+ if isinstance(ev, TextDelta):
54
+ return self._on_text_delta(ev)
55
+ if isinstance(ev, ThinkingDelta):
56
+ return self._on_thinking_delta(ev)
57
+ if isinstance(ev, ToolInputDelta):
58
+ return [
59
+ ToolInputDeltaEvent(
60
+ request_id=self.request_id,
61
+ call_id=ev.call_id,
62
+ tool=ev.name,
63
+ delta=ev.delta,
64
+ )
65
+ ]
66
+ if isinstance(ev, ToolCall):
67
+ out = self._close_open_blocks()
68
+ self.pending[ev.call_id] = ev
69
+ return out
70
+ if isinstance(ev, ProviderGroundingEvent):
71
+ return [
72
+ GroundingEvent(
73
+ request_id=self.request_id,
74
+ sources=[dict(s) for s in ev.sources],
75
+ search_queries=list(ev.search_queries),
76
+ )
77
+ ]
78
+ if isinstance(ev, Done):
79
+ self.stream_truncated = ev.truncated
80
+ return []
81
+ if isinstance(ev, UsageEvent):
82
+ return []
83
+ return []
84
+
85
+ def finish(self) -> list[AgentEvent]:
86
+ """Close any open text/thinking blocks at end of stream."""
87
+ return self._close_open_blocks()
88
+
89
+ def _close_open_blocks(self) -> list[AgentEvent]:
90
+ out: list[AgentEvent] = []
91
+ ended = self._ensure_text_ended()
92
+ if ended is not None:
93
+ out.append(ended)
94
+ closed = self._close_thinking_block()
95
+ if closed is not None:
96
+ out.append(closed)
97
+ return out
98
+
99
+ def _on_text_delta(self, ev: TextDelta) -> list[AgentEvent]:
100
+ out: list[AgentEvent] = []
101
+ closed = self._close_thinking_block()
102
+ if closed is not None:
103
+ out.append(closed)
104
+ started = self._ensure_text_started()
105
+ if started is not None:
106
+ out.append(started)
107
+ self.assistant_text += ev.text
108
+ if ev.text:
109
+ out.append(AssistantDelta(request_id=self.request_id, delta=ev.text))
110
+ return out
111
+
112
+ def _on_thinking_delta(self, ev: ThinkingDelta) -> list[AgentEvent]:
113
+ out: list[AgentEvent] = []
114
+ ended = self._ensure_text_ended()
115
+ if ended is not None:
116
+ out.append(ended)
117
+ started = self._ensure_thinking_started()
118
+ if started is not None:
119
+ out.append(started)
120
+ self.thinking_text += ev.text
121
+ if ev.signature:
122
+ self.thinking_signature = ev.signature
123
+ if ev.text:
124
+ self.thinking_streamed = True
125
+ out.append(
126
+ ThinkingBlockDelta(
127
+ request_id=self.request_id,
128
+ text=ev.text,
129
+ signature=ev.signature,
130
+ )
131
+ )
132
+ return out
133
+
134
+ def _ensure_text_started(self) -> AssistantTextStarted | None:
135
+ if self._text_open:
136
+ return None
137
+ self._text_open = True
138
+ return AssistantTextStarted(request_id=self.request_id)
139
+
140
+ def _ensure_text_ended(self) -> AssistantTextEnded | None:
141
+ if not self._text_open:
142
+ return None
143
+ self._text_open = False
144
+ return AssistantTextEnded(request_id=self.request_id, text=self.assistant_text)
145
+
146
+ def _ensure_thinking_started(self) -> ThinkingBlockStarted | None:
147
+ if self._thinking_open:
148
+ return None
149
+ self._thinking_open = True
150
+ return ThinkingBlockStarted(request_id=self.request_id)
151
+
152
+ def _close_thinking_block(self) -> ThinkingBlockComplete | None:
153
+ if not self._thinking_open:
154
+ return None
155
+ self._thinking_open = False
156
+ return ThinkingBlockComplete(
157
+ request_id=self.request_id,
158
+ signature=self.thinking_signature or "",
159
+ )