Skip to content

Commit 1a5dfaf

Browse files
osom8979claude
andcommitted
refactor(agent): Improve app with logging and args
- Add agent_logger for dedicated logging - Add --ws-uri argument with env var support - Use aio_run for event loop management - Add logging configuration (colored, simple, severity) - Translate Korean messages to English - Remove deprecated worker app module Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 94389c3 commit 1a5dfaf

11 files changed

Lines changed: 112 additions & 185 deletions

File tree

cvp/apps/__init__.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
from cvp.apps.cli import cli_main
1010
from cvp.apps.player import player_main
1111
from cvp.apps.tester import tester_main
12-
from cvp.apps.worker import worker_main
13-
from cvp.arguments import CMD_AGENT, CMD_CLI, CMD_PLAYER, CMD_TESTER, CMD_WORKER
12+
from cvp.arguments import CMD_AGENT, CMD_CLI, CMD_PLAYER, CMD_TESTER
1413
from cvp.context.autofixer import AutoFixerError
1514
from cvp.logging.loggers import logger
1615

@@ -22,7 +21,6 @@ def cmd_apps() -> Dict[str, Callable[[Namespace], None]]:
2221
CMD_CLI: cli_main,
2322
CMD_PLAYER: player_main,
2423
CMD_TESTER: tester_main,
25-
CMD_WORKER: worker_main,
2624
}
2725

2826

cvp/apps/agent/__init__.py

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,67 @@
33
from argparse import Namespace
44

55
from cvp.context.context import Context
6+
from cvp.logging.loggers import agent_logger as logger
7+
from cvp.logging.logging import (
8+
SEVERITY_NAME_DEBUG,
9+
SEVERITY_NAME_WARNING,
10+
add_default_colored_logging,
11+
add_simple_logging,
12+
convert_level_number,
13+
set_asyncio_level,
14+
)
15+
from cvp.variables import SLOW_CALLBACK_DURATION
616

717

818
def agent_main(args: Namespace) -> None:
919
assert isinstance(args.home, str)
20+
assert isinstance(args.ws_uri, str)
21+
assert isinstance(args.colored_logging, bool)
22+
assert isinstance(args.simple_logging, bool)
23+
assert isinstance(args.logging_step, int)
24+
assert isinstance(args.logging_severity, str)
25+
assert isinstance(args.use_uvloop, bool)
26+
assert isinstance(args.debug, bool)
27+
assert isinstance(args.verbose, int)
28+
assert isinstance(args.D, bool)
29+
assert isinstance(args.opts, list)
1030

11-
context = Context(args.home)
31+
if args.D:
32+
args.colored_logging = True
33+
args.simple_logging = False
34+
args.debug = True
35+
args.verbose = 2
36+
37+
if args.debug:
38+
args.logging_severity = SEVERITY_NAME_DEBUG
39+
40+
level = convert_level_number(args.logging_severity)
41+
logger.setLevel(level)
42+
43+
if args.colored_logging:
44+
assert not args.simple_logging
45+
add_default_colored_logging(logger.name)
46+
elif args.simple_logging:
47+
assert not args.colored_logging
48+
add_simple_logging(logger.name)
49+
50+
asyncio_severity = SEVERITY_NAME_DEBUG if args.debug else SEVERITY_NAME_WARNING
51+
asyncio_level = convert_level_number(asyncio_severity)
52+
set_asyncio_level(asyncio_level)
53+
54+
context = Context(args.home, detect_opengl=False)
1255

1356
# [IMPORTANT]
1457
# Do not change the import order!
1558
from cvp.apps.agent.app import AgentApplication
1659

17-
app = AgentApplication(context)
60+
app = AgentApplication(
61+
context=context,
62+
ws_uri=args.ws_uri,
63+
logging_step=args.logging_step,
64+
slow_callback_duration=SLOW_CALLBACK_DURATION,
65+
use_uvloop=args.use_uvloop,
66+
debug=args.debug,
67+
verbose=args.verbose,
68+
)
1869
app.start()

cvp/apps/agent/app.py

Lines changed: 33 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,51 @@
11
# -*- coding: utf-8 -*-
22

3-
import asyncio
4-
from typing import Optional
3+
from asyncio import get_running_loop
54

5+
from cvp.aio.run import aio_run
66
from cvp.context.context import Context
7-
from cvp.logging.loggers import logger
7+
from cvp.logging.loggers import agent_logger as logger
8+
from cvp.variables import AGENT_WS_URI, LOGGING_STEP, SLOW_CALLBACK_DURATION
89
from cvp.ws.asyncio.client import WebSocketClient
910

1011

1112
class AgentApplication:
12-
def __init__(self, context: Context):
13+
def __init__(
14+
self,
15+
context: Context,
16+
ws_uri: str = AGENT_WS_URI,
17+
logging_step=LOGGING_STEP,
18+
slow_callback_duration=SLOW_CALLBACK_DURATION,
19+
use_uvloop=False,
20+
debug=False,
21+
verbose=0,
22+
):
1323
self._context = context
14-
self._ws_client: Optional[WebSocketClient] = None
15-
self._loop: Optional[asyncio.AbstractEventLoop] = None
16-
17-
def start(self) -> None:
18-
# WebSocket URI 설정 (환경 변수나 설정 파일에서 가져올 수 있음)
19-
ws_uri = "ws://localhost:8765" # 기본값
20-
21-
# 설정에서 URI 가져오기 (있다면)
22-
if hasattr(self._context, "config"):
23-
ws_uri = getattr(self._context.config, "agent_ws_uri", ws_uri)
24-
25-
logger.info(f"Agent 애플리케이션 시작: {ws_uri}")
26-
27-
# WebSocket 클라이언트 생성
2824
self._ws_client = WebSocketClient(uri=ws_uri)
25+
self._logging_step = logging_step
26+
self._slow_callback_duration = slow_callback_duration
27+
self._use_uvloop = use_uvloop
28+
self._debug = debug
29+
self._verbose = verbose
2930

30-
# 이벤트 루프 생성 및 실행
31-
try:
32-
self._loop = asyncio.new_event_loop()
33-
asyncio.set_event_loop(self._loop)
31+
async def on_main(self) -> None:
32+
logger.info(f"Starting agent application: {self._ws_client.uri}")
3433

35-
# WebSocket 클라이언트 시작
36-
self._loop.run_until_complete(self._run())
37-
except KeyboardInterrupt:
38-
logger.info("Agent 애플리케이션 중지 요청")
39-
finally:
40-
self._cleanup()
41-
42-
async def _run(self) -> None:
43-
if not self._ws_client:
44-
logger.error("WebSocket 클라이언트가 초기화되지 않았습니다")
45-
return
34+
loop = get_running_loop()
35+
loop.slow_callback_duration = self._slow_callback_duration
36+
loop.set_debug(self._debug)
4637

4738
try:
48-
# WebSocket 클라이언트 시작
4939
await self._ws_client.start()
5040
except Exception as e:
51-
logger.error(f"Agent 실행 중 오류: {e}")
41+
logger.error(f"Agent runtime error: {e}")
5242
raise
43+
finally:
44+
await self._ws_client.stop()
45+
logger.info("Agent application stopped")
5346

54-
def _cleanup(self) -> None:
55-
if self._ws_client:
56-
# WebSocket 클라이언트 중지
57-
if self._loop and not self._loop.is_closed():
58-
self._loop.run_until_complete(self._ws_client.stop())
59-
60-
if self._loop:
61-
self._loop.close()
62-
63-
logger.info("Agent 애플리케이션 종료")
47+
def start(self) -> None:
48+
try:
49+
aio_run(self.on_main(), self._use_uvloop)
50+
except (KeyboardInterrupt, InterruptedError):
51+
logger.warning("Interrupt signal detected")

cvp/apps/worker/__init__.py

Lines changed: 0 additions & 62 deletions
This file was deleted.

cvp/apps/worker/app.py

Lines changed: 0 additions & 49 deletions
This file was deleted.

cvp/arguments.py

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from cvp.logging.logging import SEVERITIES, SEVERITY_NAME_INFO
1010
from cvp.system.environ import get_typed_environ_value as get_eval
1111
from cvp.system.environ_keys import (
12+
CVP_AGENT_WS_URI,
1213
CVP_COLORED_LOGGING,
1314
CVP_DEBUG,
1415
CVP_DOTENV_PATH,
@@ -23,6 +24,7 @@
2324
SDL_VIDEO_X11_FORCE_EGL,
2425
)
2526
from cvp.variables import (
27+
AGENT_WS_URI,
2628
CVP_HOME_DIRNAME,
2729
DOTENV_LOCAL_FILENAME,
2830
FONT_DEFAULT_NAME,
@@ -41,13 +43,6 @@
4143
{PROG} {CMD_PLAYER}
4244
"""
4345

44-
CMD_WORKER: Final[str] = "worker"
45-
CMD_WORKER_HELP: Final[str] = "The flow graph for worker"
46-
CMD_WORKER_EPILOG = f"""
47-
Simply usage:
48-
{PROG} {CMD_WORKER}
49-
"""
50-
5146
CMD_AGENT: Final[str] = "agent"
5247
CMD_AGENT_HELP: Final[str] = "Background agent"
5348
CMD_AGENT_EPILOG = f"""
@@ -69,7 +64,7 @@
6964
{PROG} {CMD_TESTER}
7065
"""
7166

72-
CMDS: Final[Sequence[str]] = CMD_PLAYER, CMD_WORKER, CMD_AGENT, CMD_CLI, CMD_TESTER
67+
CMDS: Final[Sequence[str]] = CMD_PLAYER, CMD_AGENT, CMD_CLI, CMD_TESTER
7368
DEFAULT_CMD: Final[str] = CMD_PLAYER
7469

7570
DEFAULT_SEVERITY: Final[str] = SEVERITY_NAME_INFO
@@ -209,16 +204,24 @@ def add_player_parser(subparsers) -> None:
209204
assert isinstance(parser, ArgumentParser)
210205

211206

212-
def add_worker_parser(subparsers) -> None:
207+
def add_agent_parser(subparsers) -> None:
213208
# noinspection SpellCheckingInspection
214209
parser = subparsers.add_parser(
215-
name=CMD_WORKER,
216-
help=CMD_WORKER_HELP,
210+
name=CMD_AGENT,
211+
help=CMD_AGENT_HELP,
217212
formatter_class=RawDescriptionHelpFormatter,
218-
epilog=CMD_WORKER_EPILOG,
213+
epilog=CMD_AGENT_EPILOG,
219214
)
220215
assert isinstance(parser, ArgumentParser)
221216

217+
parser.add_argument(
218+
"--ws-uri",
219+
type=str,
220+
default=get_eval(CVP_AGENT_WS_URI, AGENT_WS_URI),
221+
metavar="uri",
222+
help=f"WebSocket server URI (default: '{AGENT_WS_URI}')",
223+
)
224+
222225
logging_group = parser.add_mutually_exclusive_group()
223226
logging_group.add_argument(
224227
"--colored-logging",
@@ -282,17 +285,6 @@ def add_worker_parser(subparsers) -> None:
282285
)
283286

284287

285-
def add_agent_parser(subparsers) -> None:
286-
# noinspection SpellCheckingInspection
287-
parser = subparsers.add_parser(
288-
name=CMD_AGENT,
289-
help=CMD_AGENT_HELP,
290-
formatter_class=RawDescriptionHelpFormatter,
291-
epilog=CMD_AGENT_EPILOG,
292-
)
293-
assert isinstance(parser, ArgumentParser)
294-
295-
296288
def add_cli_parser(subparsers) -> None:
297289
# noinspection SpellCheckingInspection
298290
parser = subparsers.add_parser(
@@ -342,7 +334,6 @@ def default_argument_parser() -> ArgumentParser:
342334

343335
subparsers = parser.add_subparsers(dest="cmd")
344336
add_player_parser(subparsers)
345-
add_worker_parser(subparsers)
346337
add_agent_parser(subparsers)
347338
add_cli_parser(subparsers)
348339
add_tester_parser(subparsers)

cvp/logging/loggers.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
logger = getLogger(names.CVP_LOGGER_NAME)
88

9+
agent_logger = getLogger(names.CVP_AGENT_LOGGER_NAME)
910
canvas_logger = getLogger(names.CVP_CANVAS_LOGGER_NAME)
1011
chat_logger = getLogger(names.CVP_CHAT_LOGGER_NAME)
1112
download_logger = getLogger(names.CVP_DOWNLOAD_LOGGER_NAME)

0 commit comments

Comments
 (0)