codex-telegram 0.4.9__tar.gz → 0.4.10__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.
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/PKG-INFO +14 -2
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/README.md +13 -1
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex_telegram/__init__.py +1 -1
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex_telegram.egg-info/PKG-INFO +14 -2
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex_telegram.egg-info/SOURCES.txt +2 -2
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/tests/test_web_server_local_command.py +100 -1
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/web/routes.py +25 -6
- codex-telegram-0.4.10/web/static/dist/assets/index-BbpBsR8Z.js +53 -0
- codex-telegram-0.4.10/web/static/dist/assets/index-BfBVFmNi.css +1 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/web/static/dist/index.html +2 -2
- codex-telegram-0.4.9/web/static/dist/assets/index-B6IQl7AZ.js +0 -53
- codex-telegram-0.4.9/web/static/dist/assets/index-Czx9yv3Y.css +0 -1
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/LICENSE +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/MANIFEST.in +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/TELEGRAM.md +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/WEB.md +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/app_runtime/__init__.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/app_runtime/bootstrap.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/app_runtime/telegram_app.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/app_runtime/web_server.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/bot/__init__.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/bot/callbacks.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/bot/features_ui.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/bot/handlers.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/bot/keyboard.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/bot/projects_ui.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/bot/skills_ui.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/bot/thread_ui.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex/__init__.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex/approval_flow.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex/approval_guardian.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex/client.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex/collaboration_mode.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex/command_router/__init__.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex/command_router/common.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex/command_router/context.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex/command_router/contracts.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex/command_router/core.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex/command_router/projects.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex/command_router/review.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex/command_router/system.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex/command_router/threads.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex/commands.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex/event_forwarding.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex/events.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex/protocol.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex_telegram/cli.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex_telegram.egg-info/dependency_links.txt +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex_telegram.egg-info/entry_points.txt +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex_telegram.egg-info/requires.txt +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/codex_telegram.egg-info/top_level.txt +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/conf.toml.example +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/main.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/models/__init__.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/models/state.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/models/thread.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/models/user.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/pyproject.toml +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/setup.cfg +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/tests/test_approval_guardian.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/tests/test_approval_policy.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/tests/test_callbacks_results.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/tests/test_cli_entrypoint.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/tests/test_codex_client.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/tests/test_command_router.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/tests/test_guardian_config.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/tests/test_handlers_results.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/tests/test_keyboard.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/tests/test_main_approval_flow.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/tests/test_normalize.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/tests/test_pypi_check.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/tests/test_single_instance.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/tests/test_telegram_bot_config.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/tests/test_thread_history.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/tests/test_web_runtime.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/utils/__init__.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/utils/approval_policy.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/utils/config.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/utils/local_command.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/utils/logger.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/utils/normalize.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/utils/pypi_check.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/utils/single_instance.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/utils/web_config.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/web/__init__.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/web/dependencies.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/web/runtime.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/web/server.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/web/static/dist/icons-tab-add.svg +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/web/static/dist/icons-tab-close.svg +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/web/thread_history.py +0 -0
- {codex-telegram-0.4.9 → codex-telegram-0.4.10}/web/workspace.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: codex-telegram
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.10
|
|
4
4
|
Summary: Bridge for controlling the Codex App Server from Telegram and Web UI
|
|
5
5
|
Author: heungtae
|
|
6
6
|
License: Apache License
|
|
@@ -320,6 +320,18 @@ export CODEX_WEB_PASSWORD="your_password"
|
|
|
320
320
|
codex-telegram
|
|
321
321
|
```
|
|
322
322
|
|
|
323
|
+
If you want to rebuild the web UI before launching the app, use:
|
|
324
|
+
|
|
325
|
+
```bash
|
|
326
|
+
./run_build_and_main.sh
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Or:
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
make run
|
|
333
|
+
```
|
|
334
|
+
|
|
323
335
|
### 4. Open Web UI
|
|
324
336
|
|
|
325
337
|
```text
|
|
@@ -335,7 +347,7 @@ pip install -e .
|
|
|
335
347
|
cd web/frontend && npm install && npm run build && cd ../..
|
|
336
348
|
cp conf.toml.example ~/.config/codex-telegram/conf.toml
|
|
337
349
|
# Edit config, then run:
|
|
338
|
-
|
|
350
|
+
./run_build_and_main.sh
|
|
339
351
|
```
|
|
340
352
|
|
|
341
353
|
## Documentation
|
|
@@ -99,6 +99,18 @@ export CODEX_WEB_PASSWORD="your_password"
|
|
|
99
99
|
codex-telegram
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
+
If you want to rebuild the web UI before launching the app, use:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
./run_build_and_main.sh
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Or:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
make run
|
|
112
|
+
```
|
|
113
|
+
|
|
102
114
|
### 4. Open Web UI
|
|
103
115
|
|
|
104
116
|
```text
|
|
@@ -114,7 +126,7 @@ pip install -e .
|
|
|
114
126
|
cd web/frontend && npm install && npm run build && cd ../..
|
|
115
127
|
cp conf.toml.example ~/.config/codex-telegram/conf.toml
|
|
116
128
|
# Edit config, then run:
|
|
117
|
-
|
|
129
|
+
./run_build_and_main.sh
|
|
118
130
|
```
|
|
119
131
|
|
|
120
132
|
## Documentation
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: codex-telegram
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.10
|
|
4
4
|
Summary: Bridge for controlling the Codex App Server from Telegram and Web UI
|
|
5
5
|
Author: heungtae
|
|
6
6
|
License: Apache License
|
|
@@ -320,6 +320,18 @@ export CODEX_WEB_PASSWORD="your_password"
|
|
|
320
320
|
codex-telegram
|
|
321
321
|
```
|
|
322
322
|
|
|
323
|
+
If you want to rebuild the web UI before launching the app, use:
|
|
324
|
+
|
|
325
|
+
```bash
|
|
326
|
+
./run_build_and_main.sh
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Or:
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
make run
|
|
333
|
+
```
|
|
334
|
+
|
|
323
335
|
### 4. Open Web UI
|
|
324
336
|
|
|
325
337
|
```text
|
|
@@ -335,7 +347,7 @@ pip install -e .
|
|
|
335
347
|
cd web/frontend && npm install && npm run build && cd ../..
|
|
336
348
|
cp conf.toml.example ~/.config/codex-telegram/conf.toml
|
|
337
349
|
# Edit config, then run:
|
|
338
|
-
|
|
350
|
+
./run_build_and_main.sh
|
|
339
351
|
```
|
|
340
352
|
|
|
341
353
|
## Documentation
|
|
@@ -84,5 +84,5 @@ web/workspace.py
|
|
|
84
84
|
web/static/dist/icons-tab-add.svg
|
|
85
85
|
web/static/dist/icons-tab-close.svg
|
|
86
86
|
web/static/dist/index.html
|
|
87
|
-
web/static/dist/assets/index-
|
|
88
|
-
web/static/dist/assets/index-
|
|
87
|
+
web/static/dist/assets/index-BbpBsR8Z.js
|
|
88
|
+
web/static/dist/assets/index-BfBVFmNi.css
|
|
@@ -4,7 +4,7 @@ import os
|
|
|
4
4
|
import subprocess
|
|
5
5
|
import tempfile
|
|
6
6
|
from types import SimpleNamespace
|
|
7
|
-
from unittest.mock import AsyncMock, patch
|
|
7
|
+
from unittest.mock import AsyncMock, call, patch
|
|
8
8
|
|
|
9
9
|
from fastapi import HTTPException
|
|
10
10
|
|
|
@@ -660,6 +660,42 @@ path_glob_any = ["helm/**"]
|
|
|
660
660
|
asyncio.run(endpoint(request, "thread-sub"))
|
|
661
661
|
|
|
662
662
|
self.assertIn(self.session.user_id, user_manager.find_user_ids_by_thread("thread-sub"))
|
|
663
|
+
self.assertEqual("thread-sub", user_manager.get(self.session.user_id).active_thread_id)
|
|
664
|
+
|
|
665
|
+
def test_chat_messages_uses_active_thread_when_payload_thread_id_is_missing(self):
|
|
666
|
+
app = create_web_app()
|
|
667
|
+
endpoint = next(
|
|
668
|
+
route.endpoint
|
|
669
|
+
for route in app.routes
|
|
670
|
+
if getattr(route, "path", None) == "/api/chat/messages"
|
|
671
|
+
)
|
|
672
|
+
request = SimpleNamespace(cookies={COOKIE_NAME: self.session.token})
|
|
673
|
+
state_user = user_manager.get(self.session.user_id)
|
|
674
|
+
state_user.active_thread_id = "thread-active"
|
|
675
|
+
state_user.set_collaboration_mode_mask(
|
|
676
|
+
{"name": "build", "mode": "default", "model": "gpt-5.3-codex", "reasoning_effort": "medium"}
|
|
677
|
+
)
|
|
678
|
+
state.codex_client.call = AsyncMock(return_value={"turn": {"id": "turn-new"}})
|
|
679
|
+
|
|
680
|
+
body = asyncio.run(endpoint({"text": "hello"}, request))
|
|
681
|
+
|
|
682
|
+
self.assertTrue(body["ok"])
|
|
683
|
+
self.assertEqual("thread-active", body["thread_id"])
|
|
684
|
+
state.codex_client.call.assert_awaited_once_with(
|
|
685
|
+
"turn/start",
|
|
686
|
+
{
|
|
687
|
+
"threadId": "thread-active",
|
|
688
|
+
"collaborationMode": {
|
|
689
|
+
"mode": "default",
|
|
690
|
+
"settings": {
|
|
691
|
+
"model": "gpt-5.3-codex",
|
|
692
|
+
"reasoning_effort": "medium",
|
|
693
|
+
"developer_instructions": None,
|
|
694
|
+
},
|
|
695
|
+
},
|
|
696
|
+
"input": [{"type": "text", "text": "hello"}],
|
|
697
|
+
},
|
|
698
|
+
)
|
|
663
699
|
|
|
664
700
|
def test_thread_read_marks_non_default_assistant_messages_as_subagent(self):
|
|
665
701
|
app = create_web_app()
|
|
@@ -922,6 +958,7 @@ path_glob_any = ["helm/**"]
|
|
|
922
958
|
)
|
|
923
959
|
state.codex_client.call = AsyncMock(
|
|
924
960
|
side_effect=[
|
|
961
|
+
CodexError(-32600, "thread not found: stale-thread"),
|
|
925
962
|
CodexError(-32600, "thread not found: stale-thread"),
|
|
926
963
|
{"thread": {"id": "thread-new"}},
|
|
927
964
|
{"turn": {"id": "turn-new"}},
|
|
@@ -936,6 +973,68 @@ path_glob_any = ["helm/**"]
|
|
|
936
973
|
self.assertEqual(self.session.user_id, user_manager.find_user_id_by_turn("turn-new"))
|
|
937
974
|
self.assertEqual("thread-new", user_manager.get_turn_thread("turn-new"))
|
|
938
975
|
|
|
976
|
+
def test_chat_messages_retries_requested_thread_by_resuming_before_creating_new_thread(self):
|
|
977
|
+
app = create_web_app()
|
|
978
|
+
endpoint = next(
|
|
979
|
+
route.endpoint
|
|
980
|
+
for route in app.routes
|
|
981
|
+
if getattr(route, "path", None) == "/api/chat/messages"
|
|
982
|
+
)
|
|
983
|
+
request = SimpleNamespace(cookies={COOKIE_NAME: self.session.token})
|
|
984
|
+
state_user = user_manager.get(self.session.user_id)
|
|
985
|
+
state_user.set_collaboration_mode_mask(
|
|
986
|
+
{"name": "build", "mode": "default", "model": "gpt-5.3-codex", "reasoning_effort": "medium"}
|
|
987
|
+
)
|
|
988
|
+
state.codex_client.call = AsyncMock(
|
|
989
|
+
side_effect=[
|
|
990
|
+
CodexError(-32600, "thread not found: thread-existing"),
|
|
991
|
+
{},
|
|
992
|
+
{"turn": {"id": "turn-existing"}},
|
|
993
|
+
]
|
|
994
|
+
)
|
|
995
|
+
|
|
996
|
+
body = asyncio.run(endpoint({"text": "hello", "thread_id": "thread-existing"}, request))
|
|
997
|
+
|
|
998
|
+
self.assertTrue(body["ok"])
|
|
999
|
+
self.assertEqual("thread-existing", body["thread_id"])
|
|
1000
|
+
self.assertEqual("turn-existing", body["turn_id"])
|
|
1001
|
+
self.assertEqual(
|
|
1002
|
+
[
|
|
1003
|
+
call(
|
|
1004
|
+
"turn/start",
|
|
1005
|
+
{
|
|
1006
|
+
"threadId": "thread-existing",
|
|
1007
|
+
"collaborationMode": {
|
|
1008
|
+
"mode": "default",
|
|
1009
|
+
"settings": {
|
|
1010
|
+
"model": "gpt-5.3-codex",
|
|
1011
|
+
"reasoning_effort": "medium",
|
|
1012
|
+
"developer_instructions": None,
|
|
1013
|
+
},
|
|
1014
|
+
},
|
|
1015
|
+
"input": [{"type": "text", "text": "hello"}],
|
|
1016
|
+
},
|
|
1017
|
+
),
|
|
1018
|
+
call("thread/resume", {"threadId": "thread-existing"}),
|
|
1019
|
+
call(
|
|
1020
|
+
"turn/start",
|
|
1021
|
+
{
|
|
1022
|
+
"threadId": "thread-existing",
|
|
1023
|
+
"collaborationMode": {
|
|
1024
|
+
"mode": "default",
|
|
1025
|
+
"settings": {
|
|
1026
|
+
"model": "gpt-5.3-codex",
|
|
1027
|
+
"reasoning_effort": "medium",
|
|
1028
|
+
"developer_instructions": None,
|
|
1029
|
+
},
|
|
1030
|
+
},
|
|
1031
|
+
"input": [{"type": "text", "text": "hello"}],
|
|
1032
|
+
},
|
|
1033
|
+
),
|
|
1034
|
+
],
|
|
1035
|
+
state.codex_client.call.await_args_list,
|
|
1036
|
+
)
|
|
1037
|
+
|
|
939
1038
|
def test_workspace_tree_status_file_and_diff_endpoints(self):
|
|
940
1039
|
with tempfile.TemporaryDirectory(prefix="codex-web-workspace-") as workspace:
|
|
941
1040
|
subprocess.run(["git", "init"], cwd=workspace, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
@@ -478,12 +478,26 @@ def register_thread_routes(app: FastAPI) -> None:
|
|
|
478
478
|
and "thread not found" in str(exc.message or "").lower()
|
|
479
479
|
and payload_thread_id
|
|
480
480
|
):
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
481
|
+
resumed_existing_thread = False
|
|
482
|
+
try:
|
|
483
|
+
await state.codex_client.call("thread/resume", {"threadId": payload_thread_id})
|
|
484
|
+
thread_id = payload_thread_id
|
|
485
|
+
user_manager.set_active_thread(session.user_id, thread_id, project_key=payload_project_key or None)
|
|
486
|
+
if payload_project_key:
|
|
487
|
+
user_manager.bind_thread_project(thread_id, payload_project_key)
|
|
488
|
+
user_manager.bind_thread_owner(session.user_id, thread_id)
|
|
489
|
+
params["threadId"] = thread_id
|
|
490
|
+
result = await state.codex_client.call("turn/start", params)
|
|
491
|
+
resumed_existing_thread = True
|
|
492
|
+
except CodexError:
|
|
493
|
+
resumed_existing_thread = False
|
|
494
|
+
if not resumed_existing_thread:
|
|
495
|
+
thread_id = await start_thread_for_context()
|
|
496
|
+
if payload_project_key:
|
|
497
|
+
user_manager.bind_thread_project(thread_id, payload_project_key)
|
|
498
|
+
user_manager.bind_thread_owner(session.user_id, thread_id)
|
|
499
|
+
params["threadId"] = thread_id
|
|
500
|
+
result = await state.codex_client.call("turn/start", params)
|
|
487
501
|
else:
|
|
488
502
|
raise
|
|
489
503
|
turn = result.get("turn", {}) if isinstance(result, dict) else {}
|
|
@@ -513,6 +527,11 @@ def register_thread_routes(app: FastAPI) -> None:
|
|
|
513
527
|
if not normalized_thread_id:
|
|
514
528
|
raise HTTPException(status_code=400, detail="thread_id is required")
|
|
515
529
|
user_manager.bind_thread_subscriber(session.user_id, normalized_thread_id)
|
|
530
|
+
user_manager.set_active_thread(
|
|
531
|
+
session.user_id,
|
|
532
|
+
normalized_thread_id,
|
|
533
|
+
project_key=user_manager.get_thread_project(normalized_thread_id),
|
|
534
|
+
)
|
|
516
535
|
await wait_for_codex()
|
|
517
536
|
try:
|
|
518
537
|
result = await state.codex_client.call(
|