bazaar-compute-node 0.1.15__tar.gz → 0.1.17__tar.gz
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.
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/PKG-INFO +1 -1
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/pyproject.toml +1 -1
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/pyproject.toml.orig +1 -1
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/bcc.py +4 -16
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/codex/runtime.py +10 -26
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/telegram/channel.py +27 -11
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/wecom/channel.py +1 -1
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/instruction.py +6 -6
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/orchestration/session.py +85 -26
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/LICENSE +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/README.md +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/__init__.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/app/__init__.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/app/agent.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/app/agent_management.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/app/application.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/app/attachments.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/app/command.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/app/config.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/app/registry.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/app/reminder_dispatch.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/app/system_service.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/app/transport.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/app/windows_pipe.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/app/wrapper.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/cli.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/__init__.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/codex/__init__.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/codex/approval.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/codex/client.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/codex/events.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/codex/plugin.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/codex/process.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/codex/protocol.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/logging/__init__.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/logging/audit.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/logging/plugin.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/sqlite/__init__.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/sqlite/agent_migration.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/sqlite/codec.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/sqlite/database.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/sqlite/migrations.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/sqlite/plugin.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/sqlite/reminder_codec.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/sqlite/reminder_database.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/sqlite/reminder_migration.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/sqlite/reminder_repository.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/sqlite/repository.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/sqlite/scoped_repository.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/telegram/__init__.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/telegram/api.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/telegram/approval.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/telegram/attachments.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/telegram/identity.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/telegram/markdown.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/telegram/outbound.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/telegram/plugin.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/wecom/__init__.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/wecom/markdown.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/wecom/outbound.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/contrib/wecom/plugin.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/__init__.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/approval.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/audit.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/channel.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/client.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/command.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/concurrency.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/correlation.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/lifecycle.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/models/__init__.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/models/entities.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/models/reminder.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/models/reminder_owner.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/models/states.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/observability.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/orchestration/__init__.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/orchestration/command.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/orchestration/delivery.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/orchestration/error_feedback.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/orchestration/reminder.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/orchestration/reminder_command.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/orchestration/services.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/orchestration/turn.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/outcomes.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/paths.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/reminder.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/reminder_schedule.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/runtime.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/storage.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/timerwheel.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/i18n/__init__.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/i18n/catalog.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/i18n/english.py +0 -0
- {bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/i18n/schinese.py +0 -0
|
@@ -483,24 +483,12 @@ def _message_header_fields(
|
|
|
483
483
|
sender_value = message.get("sender")
|
|
484
484
|
sender: str | None = None
|
|
485
485
|
if sender_value is not None:
|
|
486
|
-
if isinstance(sender_value,
|
|
487
|
-
sender = sender_value
|
|
488
|
-
elif not isinstance(sender_value, Mapping):
|
|
486
|
+
if not isinstance(sender_value, Mapping):
|
|
489
487
|
_invalid_response("command response contains an invalid message sender")
|
|
490
488
|
else:
|
|
491
489
|
sender_id = sender_value.get("id")
|
|
492
490
|
sender_name = sender_value.get("name")
|
|
493
|
-
|
|
494
|
-
not isinstance(sender_id, str) or not sender_id
|
|
495
|
-
):
|
|
496
|
-
_invalid_response("command response contains an invalid sender id")
|
|
497
|
-
if sender_name is not None and (
|
|
498
|
-
not isinstance(sender_name, str) or not sender_name
|
|
499
|
-
):
|
|
500
|
-
_invalid_response("command response contains an invalid sender name")
|
|
501
|
-
sender = sender_name or sender_id
|
|
502
|
-
if sender is None:
|
|
503
|
-
_invalid_response("command response contains an empty message sender")
|
|
491
|
+
sender = f"@{sender_id}({sender_name})" if sender_name else f"@{sender_id}"
|
|
504
492
|
return (
|
|
505
493
|
target,
|
|
506
494
|
message_id,
|
|
@@ -553,7 +541,7 @@ def _format_check_message(message: Mapping[str, object]) -> str:
|
|
|
553
541
|
line += f" reply_to={reply_to_message_id}"
|
|
554
542
|
line += "] "
|
|
555
543
|
if sender is not None:
|
|
556
|
-
line += f"
|
|
544
|
+
line += f"{sender} "
|
|
557
545
|
return line + body + _attachment_suffix(message)
|
|
558
546
|
|
|
559
547
|
|
|
@@ -583,7 +571,7 @@ def _format_read_message(
|
|
|
583
571
|
fields.append(f"replyTo={reply_to_message_id}")
|
|
584
572
|
line = f"[{index}/{count} {' '.join(fields)}] "
|
|
585
573
|
if sender is not None:
|
|
586
|
-
line += f"
|
|
574
|
+
line += f"{sender} "
|
|
587
575
|
return line + body + _attachment_suffix(message)
|
|
588
576
|
|
|
589
577
|
|
|
@@ -104,7 +104,6 @@ class Runtime(IRuntime, IAsyncLifecycle):
|
|
|
104
104
|
self._model = model
|
|
105
105
|
self._effort = effort
|
|
106
106
|
self._connections: dict[str, _Connection] = {}
|
|
107
|
-
self._teardown_tasks: set[asyncio.Task[None]] = set()
|
|
108
107
|
self._expire_events: asyncio.Queue[RuntimeExpire] = asyncio.Queue()
|
|
109
108
|
self._logger = logging.getLogger("bazaar_compute_node.runtime.codex")
|
|
110
109
|
self._started = False
|
|
@@ -114,6 +113,11 @@ class Runtime(IRuntime, IAsyncLifecycle):
|
|
|
114
113
|
del timeout
|
|
115
114
|
if self._stopping:
|
|
116
115
|
raise RuntimeError("Codex App Server runtime is stopping")
|
|
116
|
+
if os.name == "nt":
|
|
117
|
+
self._logger.warning(
|
|
118
|
+
"Codex idle timeout is not supported on Windows; "
|
|
119
|
+
"see openai/codex#15461."
|
|
120
|
+
)
|
|
117
121
|
self._started = True
|
|
118
122
|
|
|
119
123
|
async def stop(self, *, timeout: float) -> None:
|
|
@@ -524,6 +528,9 @@ class Runtime(IRuntime, IAsyncLifecycle):
|
|
|
524
528
|
*,
|
|
525
529
|
timeout: float,
|
|
526
530
|
) -> bool:
|
|
531
|
+
if os.name == "nt":
|
|
532
|
+
# Detached OS processes are not exposed by the Windows Codex provider.
|
|
533
|
+
return True
|
|
527
534
|
connection = self._connections.get(session.id)
|
|
528
535
|
provider_thread_id = session.provider_thread_id
|
|
529
536
|
if connection is None or not provider_thread_id:
|
|
@@ -549,11 +556,10 @@ class Runtime(IRuntime, IAsyncLifecycle):
|
|
|
549
556
|
status=ProviderCallStatus.CONFIRMED,
|
|
550
557
|
value=session,
|
|
551
558
|
)
|
|
552
|
-
self.
|
|
559
|
+
await self._stop_connection(connection, timeout=timeout)
|
|
553
560
|
return ProviderCallResult(
|
|
554
|
-
status=ProviderCallStatus.
|
|
561
|
+
status=ProviderCallStatus.CONFIRMED,
|
|
555
562
|
value=session,
|
|
556
|
-
receipt={"teardown": "scheduled"},
|
|
557
563
|
)
|
|
558
564
|
|
|
559
565
|
async def _open_connection(
|
|
@@ -660,28 +666,6 @@ class Runtime(IRuntime, IAsyncLifecycle):
|
|
|
660
666
|
except OSError, TimeoutError, JsonlTransportError:
|
|
661
667
|
return
|
|
662
668
|
|
|
663
|
-
def _schedule_connection_teardown(
|
|
664
|
-
self,
|
|
665
|
-
connection: _Connection,
|
|
666
|
-
*,
|
|
667
|
-
timeout: float,
|
|
668
|
-
) -> None:
|
|
669
|
-
task = asyncio.create_task(
|
|
670
|
-
self._stop_connection(connection, timeout=timeout),
|
|
671
|
-
name=f"bcn-codex-teardown-{connection.provider_thread_id}",
|
|
672
|
-
)
|
|
673
|
-
self._teardown_tasks.add(task)
|
|
674
|
-
task.add_done_callback(self._forget_teardown_task)
|
|
675
|
-
|
|
676
|
-
def _forget_teardown_task(self, task: asyncio.Task[None]) -> None:
|
|
677
|
-
self._teardown_tasks.discard(task)
|
|
678
|
-
if task.cancelled():
|
|
679
|
-
return
|
|
680
|
-
try:
|
|
681
|
-
task.result()
|
|
682
|
-
except Exception:
|
|
683
|
-
self._logger.exception("Codex runtime connection teardown failed")
|
|
684
|
-
|
|
685
669
|
def _clear_active_turn(self, session_id: str, turn_id: str) -> None:
|
|
686
670
|
connection = self._connections.get(session_id)
|
|
687
671
|
if connection is not None and connection.active_turn_id == turn_id:
|
|
@@ -67,6 +67,7 @@ class TelegramChannel(IChannel):
|
|
|
67
67
|
self._api: TelegramBotApi | None = None
|
|
68
68
|
self._bot_id: int | None = None
|
|
69
69
|
self._bot_username: str | None = None
|
|
70
|
+
self._bot_first_name: str | None = None
|
|
70
71
|
self._state = "stopped"
|
|
71
72
|
self._poll_attempts = 0
|
|
72
73
|
self._last_poll_at_ms: int | None = None
|
|
@@ -102,6 +103,7 @@ class TelegramChannel(IChannel):
|
|
|
102
103
|
"started_at_s": self._started_at_s,
|
|
103
104
|
"bot_id": self._bot_id,
|
|
104
105
|
"bot_username": self._bot_username,
|
|
106
|
+
"bot_first_name": self._bot_first_name,
|
|
105
107
|
"poll_timeout_seconds": 50,
|
|
106
108
|
"poll_attempts": self._poll_attempts,
|
|
107
109
|
"last_poll_at_ms": self._last_poll_at_ms,
|
|
@@ -127,9 +129,15 @@ class TelegramChannel(IChannel):
|
|
|
127
129
|
def get_identity(self) -> ChannelIdentity | None:
|
|
128
130
|
bot_id = self._bot_id
|
|
129
131
|
bot_username = self._bot_username
|
|
130
|
-
|
|
132
|
+
bot_first_name = self._bot_first_name
|
|
133
|
+
if bot_id is None or bot_first_name is None:
|
|
131
134
|
return None
|
|
132
|
-
return ChannelIdentity(
|
|
135
|
+
return ChannelIdentity(
|
|
136
|
+
id=str(bot_id),
|
|
137
|
+
name=(
|
|
138
|
+
f"{bot_username}({bot_first_name})" if bot_username else bot_first_name
|
|
139
|
+
),
|
|
140
|
+
)
|
|
133
141
|
|
|
134
142
|
async def start(self, *, timeout: float) -> None:
|
|
135
143
|
if self._runner is not None:
|
|
@@ -156,16 +164,22 @@ class TelegramChannel(IChannel):
|
|
|
156
164
|
bot_id = bot.get("id")
|
|
157
165
|
is_bot = bot.get("is_bot")
|
|
158
166
|
username = bot.get("username")
|
|
167
|
+
first_name = bot.get("first_name")
|
|
159
168
|
if (
|
|
160
169
|
not isinstance(bot_id, int)
|
|
161
170
|
or isinstance(bot_id, bool)
|
|
162
171
|
or is_bot is not True
|
|
163
|
-
or
|
|
164
|
-
|
|
172
|
+
or (
|
|
173
|
+
username is not None
|
|
174
|
+
and (not isinstance(username, str) or not username)
|
|
175
|
+
)
|
|
176
|
+
or not isinstance(first_name, str)
|
|
177
|
+
or not first_name
|
|
165
178
|
):
|
|
166
179
|
raise ValueError("Telegram getMe returned an invalid bot identity")
|
|
167
180
|
self._bot_id = bot_id
|
|
168
|
-
self._bot_username = username
|
|
181
|
+
self._bot_username = username if isinstance(username, str) else None
|
|
182
|
+
self._bot_first_name = first_name
|
|
169
183
|
self._typing_runner = asyncio.create_task(
|
|
170
184
|
self._run_typing_dispatcher(),
|
|
171
185
|
name="bcn-telegram-typing",
|
|
@@ -195,6 +209,7 @@ class TelegramChannel(IChannel):
|
|
|
195
209
|
self._session = None
|
|
196
210
|
self._bot_id = None
|
|
197
211
|
self._bot_username = None
|
|
212
|
+
self._bot_first_name = None
|
|
198
213
|
self._typing_leases.clear()
|
|
199
214
|
await session.close()
|
|
200
215
|
self._state = "stopped"
|
|
@@ -227,6 +242,7 @@ class TelegramChannel(IChannel):
|
|
|
227
242
|
self._session = None
|
|
228
243
|
self._bot_id = None
|
|
229
244
|
self._bot_username = None
|
|
245
|
+
self._bot_first_name = None
|
|
230
246
|
if session is not None and not session.closed:
|
|
231
247
|
await session.close()
|
|
232
248
|
self._ready.clear()
|
|
@@ -462,8 +478,8 @@ class TelegramChannel(IChannel):
|
|
|
462
478
|
update_id: int,
|
|
463
479
|
) -> None:
|
|
464
480
|
bot_id = self._bot_id
|
|
465
|
-
bot_username = self._bot_username
|
|
466
|
-
if bot_id is None
|
|
481
|
+
bot_username = self._bot_username or ""
|
|
482
|
+
if bot_id is None:
|
|
467
483
|
raise RuntimeError("Telegram bot identity is not initialized")
|
|
468
484
|
|
|
469
485
|
provider_sender = message.get("from")
|
|
@@ -631,8 +647,8 @@ class TelegramChannel(IChannel):
|
|
|
631
647
|
if topic_id is None or topic_id != identity.topic_id:
|
|
632
648
|
return None
|
|
633
649
|
bot_id = self._bot_id
|
|
634
|
-
bot_username = self._bot_username
|
|
635
|
-
if bot_id is None
|
|
650
|
+
bot_username = self._bot_username or ""
|
|
651
|
+
if bot_id is None:
|
|
636
652
|
raise RuntimeError("Telegram bot identity is not initialized")
|
|
637
653
|
content = await self._content(
|
|
638
654
|
reply,
|
|
@@ -826,11 +842,11 @@ class TelegramChannel(IChannel):
|
|
|
826
842
|
if entity_text is None:
|
|
827
843
|
continue
|
|
828
844
|
if entity_type == "mention":
|
|
829
|
-
if entity_text.casefold() == f"@{username}":
|
|
845
|
+
if username and entity_text.casefold() == f"@{username}":
|
|
830
846
|
return True
|
|
831
847
|
continue
|
|
832
848
|
_, separator, target = entity_text.rpartition("@")
|
|
833
|
-
if separator and target.casefold() == username:
|
|
849
|
+
if separator and username and target.casefold() == username:
|
|
834
850
|
return True
|
|
835
851
|
return False
|
|
836
852
|
|
|
@@ -71,10 +71,10 @@ Do not obstruct a human-directed use of a credential: use or send it on the requ
|
|
|
71
71
|
Messages you receive have a single RFC 5424-style structured data header followed by the sender and content:
|
|
72
72
|
|
|
73
73
|
```
|
|
74
|
-
[target=<thread-target> msg=00000000 time=2026-03-15T01:00:00 type=human] @
|
|
75
|
-
[target=<thread-target> msg=11111111 time=2026-03-15T01:00:01 type=agent] @Alice
|
|
76
|
-
[target=dm:@
|
|
77
|
-
[target=<thread-target> msg=33333333 time=2026-03-15T01:00:03 type=human] @
|
|
74
|
+
[target=<thread-target> msg=00000000 time=2026-03-15T01:00:00 type=human] @yuchanns(Hanchin Hsieh) hello everyone
|
|
75
|
+
[target=<thread-target> msg=11111111 time=2026-03-15T01:00:01 type=agent] @Alice(Aeris) hi there
|
|
76
|
+
[target=dm:@yuchanss msg=22222222 time=2026-03-15T01:00:02 type=human] @yuchanns(Hanchin Hsieh) hey, can you help?
|
|
77
|
+
[target=<thread-target> msg=33333333 time=2026-03-15T01:00:03 type=human] @yuchanns(Hanchin Hsieh) thread reply
|
|
78
78
|
```
|
|
79
79
|
|
|
80
80
|
Prompt examples use obvious placeholder IDs such as `00000000`, `11111111`, and `22222222`. They show the shape of a real message ID but are not actual messages. Do not cite them as evidence; use only IDs from messages you actually received or read.
|
|
@@ -257,9 +257,9 @@ class DeveloperInstructionContext:
|
|
|
257
257
|
def render(self) -> str:
|
|
258
258
|
rendered = DEVELOPER_INSTRUCTIONS
|
|
259
259
|
identity_statement = (
|
|
260
|
-
f
|
|
260
|
+
f"You're {self.bot_name}, A.K.A {self.agent_name}"
|
|
261
261
|
if self.bot_name is not None
|
|
262
|
-
else f
|
|
262
|
+
else f"You're {self.agent_name}"
|
|
263
263
|
)
|
|
264
264
|
for placeholder, value in (
|
|
265
265
|
("{{identity_statement}}", identity_statement),
|
|
@@ -204,6 +204,7 @@ class SessionOrchestrator(IAsyncLifecycle):
|
|
|
204
204
|
clock=self._clock,
|
|
205
205
|
)
|
|
206
206
|
self._active_tasks: set[asyncio.Task[RuntimeTurn | None]] = set()
|
|
207
|
+
self._runtime_teardown_tasks: set[asyncio.Task[None]] = set()
|
|
207
208
|
self._ingress_queues: dict[tuple[str, str], asyncio.Queue[_IngressItem]] = {}
|
|
208
209
|
self._ingress_workers: dict[tuple[str, str], asyncio.Task[None]] = {}
|
|
209
210
|
self._runtime_queues: dict[str, asyncio.Queue[_RuntimeQueueItem]] = {}
|
|
@@ -408,7 +409,7 @@ class SessionOrchestrator(IAsyncLifecycle):
|
|
|
408
409
|
)
|
|
409
410
|
except BaseException:
|
|
410
411
|
try:
|
|
411
|
-
await self.
|
|
412
|
+
await self._stop_runtime_session(
|
|
412
413
|
context.runtime_session,
|
|
413
414
|
timeout=self._timeout_budget.provider_call_seconds,
|
|
414
415
|
)
|
|
@@ -497,6 +498,8 @@ class SessionOrchestrator(IAsyncLifecycle):
|
|
|
497
498
|
for runtime_session in tuple(self._runtime_sessions.values()):
|
|
498
499
|
await self._stop_runtime_session(runtime_session, timeout=timeout)
|
|
499
500
|
|
|
501
|
+
await self._wait_for_runtime_teardown_tasks(timeout=timeout)
|
|
502
|
+
|
|
500
503
|
try:
|
|
501
504
|
await self._runtime.stop(timeout=timeout)
|
|
502
505
|
except asyncio.CancelledError:
|
|
@@ -1515,38 +1518,45 @@ class SessionOrchestrator(IAsyncLifecycle):
|
|
|
1515
1518
|
async with self._concurrency.for_session(runtime_session.bcn_session_id):
|
|
1516
1519
|
await self._stop_runtime_session_locked(runtime_session, timeout=timeout)
|
|
1517
1520
|
|
|
1518
|
-
async def
|
|
1521
|
+
async def _wait_for_runtime_teardown_tasks(self, *, timeout: float) -> None:
|
|
1522
|
+
tasks = tuple(self._runtime_teardown_tasks)
|
|
1523
|
+
if not tasks:
|
|
1524
|
+
return
|
|
1525
|
+
gathered = asyncio.gather(*tasks, return_exceptions=True)
|
|
1526
|
+
try:
|
|
1527
|
+
await asyncio.wait_for(asyncio.shield(gathered), timeout=timeout)
|
|
1528
|
+
except TimeoutError:
|
|
1529
|
+
self._shutdown_errors.append("runtime session teardown: shutdown timeout")
|
|
1530
|
+
|
|
1531
|
+
def _schedule_runtime_session_teardown(
|
|
1519
1532
|
self,
|
|
1520
1533
|
runtime_session: RuntimeSession,
|
|
1521
1534
|
*,
|
|
1535
|
+
correlation: CorrelationContext,
|
|
1522
1536
|
timeout: float,
|
|
1523
1537
|
) -> None:
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
provider_thread_id=runtime_session.provider_thread_id,
|
|
1530
|
-
)
|
|
1531
|
-
await self._audit.append(
|
|
1532
|
-
event_name="runtime.process.stop.requested",
|
|
1533
|
-
state=RuntimeEventState.STARTED,
|
|
1534
|
-
correlation=process_correlation,
|
|
1535
|
-
metadata={
|
|
1536
|
-
"runtime": runtime_session.runtime,
|
|
1537
|
-
"workspace_id": runtime_session.workspace_id,
|
|
1538
|
-
},
|
|
1539
|
-
)
|
|
1540
|
-
await self._state_machine.apply_locked(
|
|
1541
|
-
runtime_session.bcn_session_id,
|
|
1542
|
-
SessionRuntimeObservation(
|
|
1543
|
-
source=SessionRuntimeObservationSource.SESSION,
|
|
1544
|
-
signal=SessionRuntimeSignal.STOP_REQUESTED,
|
|
1545
|
-
observed_at_ms=self._clock(),
|
|
1538
|
+
task = asyncio.create_task(
|
|
1539
|
+
self._complete_runtime_session_teardown(
|
|
1540
|
+
runtime_session,
|
|
1541
|
+
correlation=correlation,
|
|
1542
|
+
timeout=timeout,
|
|
1546
1543
|
),
|
|
1544
|
+
name=f"bcn-runtime-teardown-{runtime_session.id}",
|
|
1547
1545
|
)
|
|
1546
|
+
self._runtime_teardown_tasks.add(task)
|
|
1547
|
+
task.add_done_callback(self._forget_runtime_teardown_task)
|
|
1548
|
+
|
|
1549
|
+
async def _complete_runtime_session_teardown(
|
|
1550
|
+
self,
|
|
1551
|
+
runtime_session: RuntimeSession,
|
|
1552
|
+
*,
|
|
1553
|
+
correlation: CorrelationContext,
|
|
1554
|
+
timeout: float,
|
|
1555
|
+
) -> None:
|
|
1548
1556
|
try:
|
|
1549
1557
|
result = await self._runtime.stop_session(runtime_session, timeout=timeout)
|
|
1558
|
+
except asyncio.CancelledError:
|
|
1559
|
+
raise
|
|
1550
1560
|
except Exception as error: # noqa: BLE001
|
|
1551
1561
|
result = None
|
|
1552
1562
|
stop_error = error
|
|
@@ -1563,7 +1573,6 @@ class SessionOrchestrator(IAsyncLifecycle):
|
|
|
1563
1573
|
else ErrorKind.PROVIDER_UNKNOWN.value
|
|
1564
1574
|
)
|
|
1565
1575
|
error_message = result.error_message if result is not None else str(stop_error)
|
|
1566
|
-
await self._discard_runtime_session(runtime_session)
|
|
1567
1576
|
await self._audit.append(
|
|
1568
1577
|
event_name=(
|
|
1569
1578
|
"runtime.process.stop.completed"
|
|
@@ -1579,7 +1588,7 @@ class SessionOrchestrator(IAsyncLifecycle):
|
|
|
1579
1588
|
if unknown
|
|
1580
1589
|
else RuntimeEventState.FAILED
|
|
1581
1590
|
),
|
|
1582
|
-
correlation=
|
|
1591
|
+
correlation=correlation,
|
|
1583
1592
|
error_kind=(
|
|
1584
1593
|
ErrorKind(error_kind)
|
|
1585
1594
|
if error_kind in ErrorKind._value2member_map_
|
|
@@ -1595,3 +1604,53 @@ class SessionOrchestrator(IAsyncLifecycle):
|
|
|
1595
1604
|
"workspace_id": runtime_session.workspace_id,
|
|
1596
1605
|
},
|
|
1597
1606
|
)
|
|
1607
|
+
|
|
1608
|
+
def _forget_runtime_teardown_task(self, task: asyncio.Task[None]) -> None:
|
|
1609
|
+
self._runtime_teardown_tasks.discard(task)
|
|
1610
|
+
if task.cancelled():
|
|
1611
|
+
return
|
|
1612
|
+
error = task.exception()
|
|
1613
|
+
if error is None:
|
|
1614
|
+
return
|
|
1615
|
+
self._logger.error(
|
|
1616
|
+
"runtime session teardown failed: %s",
|
|
1617
|
+
error,
|
|
1618
|
+
exc_info=(type(error), error, error.__traceback__),
|
|
1619
|
+
)
|
|
1620
|
+
|
|
1621
|
+
async def _stop_runtime_session_locked(
|
|
1622
|
+
self,
|
|
1623
|
+
runtime_session: RuntimeSession,
|
|
1624
|
+
*,
|
|
1625
|
+
timeout: float,
|
|
1626
|
+
) -> None:
|
|
1627
|
+
process_correlation = CorrelationContext(
|
|
1628
|
+
node_id=self.agent_id,
|
|
1629
|
+
channel_session_id=runtime_session.channel_session_id,
|
|
1630
|
+
bcn_session_id=runtime_session.bcn_session_id,
|
|
1631
|
+
runtime_session_id=runtime_session.id,
|
|
1632
|
+
provider_thread_id=runtime_session.provider_thread_id,
|
|
1633
|
+
)
|
|
1634
|
+
await self._audit.append(
|
|
1635
|
+
event_name="runtime.process.stop.requested",
|
|
1636
|
+
state=RuntimeEventState.STARTED,
|
|
1637
|
+
correlation=process_correlation,
|
|
1638
|
+
metadata={
|
|
1639
|
+
"runtime": runtime_session.runtime,
|
|
1640
|
+
"workspace_id": runtime_session.workspace_id,
|
|
1641
|
+
},
|
|
1642
|
+
)
|
|
1643
|
+
await self._state_machine.apply_locked(
|
|
1644
|
+
runtime_session.bcn_session_id,
|
|
1645
|
+
SessionRuntimeObservation(
|
|
1646
|
+
source=SessionRuntimeObservationSource.SESSION,
|
|
1647
|
+
signal=SessionRuntimeSignal.STOP_REQUESTED,
|
|
1648
|
+
observed_at_ms=self._clock(),
|
|
1649
|
+
),
|
|
1650
|
+
)
|
|
1651
|
+
self._schedule_runtime_session_teardown(
|
|
1652
|
+
runtime_session,
|
|
1653
|
+
correlation=process_correlation,
|
|
1654
|
+
timeout=timeout,
|
|
1655
|
+
)
|
|
1656
|
+
await self._discard_runtime_session(runtime_session)
|
|
File without changes
|
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/__init__.py
RENAMED
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/app/__init__.py
RENAMED
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/app/agent.py
RENAMED
|
File without changes
|
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/app/application.py
RENAMED
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/app/attachments.py
RENAMED
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/app/command.py
RENAMED
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/app/config.py
RENAMED
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/app/registry.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/app/transport.py
RENAMED
|
File without changes
|
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/app/wrapper.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/__init__.py
RENAMED
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/approval.py
RENAMED
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/audit.py
RENAMED
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/channel.py
RENAMED
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/client.py
RENAMED
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/command.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/lifecycle.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/outcomes.py
RENAMED
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/paths.py
RENAMED
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/reminder.py
RENAMED
|
File without changes
|
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/runtime.py
RENAMED
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/storage.py
RENAMED
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/core/timerwheel.py
RENAMED
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/i18n/__init__.py
RENAMED
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/i18n/catalog.py
RENAMED
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/i18n/english.py
RENAMED
|
File without changes
|
{bazaar_compute_node-0.1.15 → bazaar_compute_node-0.1.17}/src/bazaar_compute_node/i18n/schinese.py
RENAMED
|
File without changes
|