aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author苏向夜 <fu050409@163.com>2024-01-26 13:56:24 +0800
committer苏向夜 <fu050409@163.com>2024-01-26 13:56:24 +0800
commit0e8be9de58454de079d772dec6c0ef9c1774a775 (patch)
tree9e0d4863d87524c15c232bf5cbd555d98a90aa70 /src
parent796455df18b87515a4f8a4933dd92d79bea58adf (diff)
downloadinfini-0e8be9de58454de079d772dec6c0ef9c1774a775.tar.gz
infini-0e8be9de58454de079d772dec6c0ef9c1774a775.zip
:recycle: refactor(infini): refacted infini as version 2.0.0-alpha.1
Diffstat (limited to 'src')
-rw-r--r--src/infini/__init__.py28
-rw-r--r--src/infini/const.py3
-rw-r--r--src/infini/core.py39
-rw-r--r--src/infini/event.py98
-rw-r--r--src/infini/exceptions.py43
-rw-r--r--src/infini/generator.py2
-rw-r--r--src/infini/handler.py62
-rw-r--r--src/infini/input.py21
-rw-r--r--src/infini/interceptor.py35
-rw-r--r--src/infini/internal.py18
-rw-r--r--src/infini/logging.py33
-rw-r--r--src/infini/matcher.py34
-rw-r--r--src/infini/output.py19
-rw-r--r--src/infini/queue.py47
-rw-r--r--src/infini/register.py163
-rw-r--r--src/infini/router.py21
-rw-r--r--src/infini/settings.py1
-rw-r--r--src/infini/typing.py28
-rw-r--r--src/infini/utils/cli.py28
-rw-r--r--src/infini/utils/gui.py5
20 files changed, 248 insertions, 480 deletions
diff --git a/src/infini/__init__.py b/src/infini/__init__.py
index af9b8fa1..e69de29b 100644
--- a/src/infini/__init__.py
+++ b/src/infini/__init__.py
@@ -1,28 +0,0 @@
-"""Infini
-
-Core of HydroRoll, python version of GRPS-1.
-
-
-本模块从子模块导入了以下内容:
-- `Handler` => [`infini.handler`](./handler#Handler)
-- `MessageEvent` => [`infini.event.MessageEvent`](./event#MessageEvent)
-- `MatcherEvent` => [`infini.event.MatcherEvent`](./event#MatcherEvent)
-- `WorkflowEvent` => [`infini.event.WorkflowEvent`](./event#WorkflowEvent)
-- `Matcher` => [`infini.matcher.Matcher`](./matcher/#Matcher)
-- `Register` => [`infini.register.Register`](./register#Register)
-"""
-
-
-from infini.handler import Handler
-from infini.event import MessageEvent, MatcherEvent, WorkflowEvent
-from infini.matcher import Matcher
-from infini.register import Register
-
-__all__ = [
- "Handler",
- "MessageEvent",
- "Matcher",
- "Register",
- "MatcherEvent",
- "WorkflowEvent",
-]
diff --git a/src/infini/const.py b/src/infini/const.py
new file mode 100644
index 00000000..2ec42488
--- /dev/null
+++ b/src/infini/const.py
@@ -0,0 +1,3 @@
+from pathlib import Path
+
+SRC_HOME = Path.home() / ".ipm" / "src" \ No newline at end of file
diff --git a/src/infini/core.py b/src/infini/core.py
new file mode 100644
index 00000000..2bb3e7da
--- /dev/null
+++ b/src/infini/core.py
@@ -0,0 +1,39 @@
+from infini.input import Input
+from infini.interceptor import Interceptor
+from infini.generator import Generator
+from infini.handler import Handler
+from infini.output import Output
+
+
+class Core:
+ pre_interceptor: Interceptor
+ handler: Handler
+ generator: Generator
+ interceptor: Interceptor
+
+ def input(self, input: Input):
+ if isinstance(pre_intercepted_stream := self.pre_intercept(input), Output):
+ yield self.generate(pre_intercepted_stream)
+ return
+ for handled_stream in self.handle(pre_intercepted_stream):
+ if handled_stream.is_empty():
+ return # TODO 处理未找到 Handler
+ yield self.intercept(self.generate(handled_stream))
+
+ def pre_intercept(self, input: Input) -> Input | Output:
+ return self.pre_interceptor.input(input)
+
+ def handle(self, input: Input):
+ iterator = self.handler.input(input)
+ for output in iterator:
+ yield output
+
+ def generate(self, output: Output) -> str:
+ return output.name # TODO 生成器实现
+
+ def intercept(self, output: str) -> str:
+ return (
+ self.generate(callback)
+ if isinstance(callback := self.interceptor.output(output), Output)
+ else callback
+ )
diff --git a/src/infini/event.py b/src/infini/event.py
deleted file mode 100644
index 5ef9444e..00000000
--- a/src/infini/event.py
+++ /dev/null
@@ -1,98 +0,0 @@
-"""Infini 事件模块
-
-此模块定义了 Infini 的事件类,包括 InfiniEvent, MessageEvent, WorkflowEvent 和 MatcherEvent。
-这些事件类用于在 Infini 框架中处理各种事件。
-"""
-
-from abc import ABCMeta, abstractmethod
-from .typing import Dict, Any
-
-__all__ = [
- "InfiniEvent",
- "MessageEvent",
- "WorkflowEvent",
- "MatcherEvent",
-]
-
-
-class InfiniEvent(metaclass=ABCMeta):
- """Infini 事件基类"""
-
- name: str
- kwargs: Dict[str, Any]
-
- @abstractmethod
- def __repr__(self) -> str:
- raise NotImplementedError
-
- def get_event_name(self) -> str:
- return self.name
-
-
-class MessageEvent(InfiniEvent):
- """Message 事件"""
-
- name: str
- output: str
- kwargs: Dict[str, Any]
-
- def __init__(self, name: str, **kwargs) -> None:
- self.name = name
- self.kwargs = kwargs
-
- def __str__(self) -> str:
- return f"<MessageEvent [{self.name}]>"
-
- def __repr__(self) -> str:
- return self.__str__()
-
-
-class WorkflowEvent(InfiniEvent):
- """Workflow 事件"""
-
- name: str
- kwargs: Dict[str, Any]
-
- def __init__(self, name: str, **kwargs) -> None:
- self.name = name
- self.kwargs = kwargs
-
- def __repr__(self) -> str:
- return f"<WorkflowEvent [{self.name}]>"
-
- def __eq__(self, __value: object) -> bool:
- if __value is str:
- return self.name == __value
- if isinstance(__value, WorkflowEvent):
- return self.name == __value.name and self.kwargs == __value.kwargs
- return False
-
-
-class MatcherEvent(InfiniEvent):
- """Matcher 事件"""
-
- name: str
- prefix: str
- string: str
- kwargs: Dict[str, Any]
-
- def __init__(
- self,
- event_name: str,
- prefix: str | None = None,
- string: str | None = None,
- **kwargs,
- ):
- self.name = event_name
- self.prefix = prefix or ""
- self.string = string or ""
- self.kwargs = kwargs
-
- def __repr__(self) -> str:
- return f"<MatcherEvent [{self.name}]>"
-
- def get_prefix(self):
- return self.prefix
-
- def get_plain_text(self):
- return self.string
diff --git a/src/infini/exceptions.py b/src/infini/exceptions.py
index 2038efcd..cb0a9e41 100644
--- a/src/infini/exceptions.py
+++ b/src/infini/exceptions.py
@@ -1,45 +1,6 @@
-"""Infini 异常处理模块
-
-此模块定义了 Infini 项目中所有的自定义异常类。
-规则包作者后续实现的每个异常类都应该继承自 InfiniException。
-"""
-
-
class InfiniException(Exception):
"""Infini 异常基类"""
-class RulePackageException(InfiniException):
- """由规则包抛出的异常基类, 所有规则包抛出的异常都应该继承此类。"""
-
-
-class LoadError(InfiniException):
- """加载规则包错误, 找不到指定的规则包或事件声明有误导致运行时错误时抛出。"""
-
-
-class PackageNotFound(LoadError):
- """规则包不存在时错误"""
-
-
-class EventLoadError(LoadError, RuntimeError):
- """事件声明导入失败"""
-
-
-class HandlerLoadError(LoadError, RuntimeError):
- """业务函数导入失败"""
-
-
-class EventException(InfiniException):
- """事件异常基类"""
-
-
-class UnknownMatcherEvent(EventException):
- """未知的给入实现"""
-
-
-class UnknownMessageEvent(EventException):
- """未知的给出实现"""
-
-
-class UnsupportedError(EventException, RuntimeError):
- """方法未被支持"""
+class KeyError(InfiniException):
+ """键值错误"""
diff --git a/src/infini/generator.py b/src/infini/generator.py
new file mode 100644
index 00000000..a4d60e27
--- /dev/null
+++ b/src/infini/generator.py
@@ -0,0 +1,2 @@
+class Generator:
+ ...
diff --git a/src/infini/handler.py b/src/infini/handler.py
index 0f72eccf..ae3561f8 100644
--- a/src/infini/handler.py
+++ b/src/infini/handler.py
@@ -1,34 +1,28 @@
-"""Infini Handler
-
-此类是所有规则包业务类的基类。
-每个规则包业务类都需要定义一个名为 process 的抽象方法, 用于接收和处理传入的 MatcherEvent 事件,并返回一个 InfiniEvent 事件。
-此外,每个规则包业务类还可以定义一个名为 priority 的类属性,用于指定该业务类的优先级。优先级越高,该业务类处理事件的顺序越靠前。
-"""
-
-from abc import ABC, abstractmethod
-from enum import Enum
-from .typing import StateT, ClassVar, Generic
-from .event import MatcherEvent, InfiniEvent
-
-__all__ = ["Handler", "HandlerLoadType"]
-
-
-class HandlerLoadType(Enum):
- """规则包加载类型。"""
-
- DIR = "dir"
- NAME = "name"
- FILE = "file"
- CLASS = "class"
-
-
-class Handler(ABC, Generic[StateT]):
- """规则包业务基类"""
-
- name: str
- priority: ClassVar[int] = 0
- block: ClassVar[bool] = False
-
- @abstractmethod
- def process(self, event: MatcherEvent) -> InfiniEvent:
- raise NotImplementedError
+from infini.input import Input
+from infini.output import Output
+from infini.typing import List, RouterType, Callable
+from infini.queue import EventQueue
+
+
+class Handler:
+ handlers: List[RouterType]
+
+ def input(self, input: Input):
+ queue = self.match(input.get_plain_text())
+ if queue.is_empty():
+ yield Output.empty()
+ return
+ while not queue.is_empty():
+ output = queue.pop()(input)
+ yield output
+ if output.block:
+ return
+
+ def match(self, text: str) -> EventQueue[Callable[[Input], Output]]:
+ queue = EventQueue()
+
+ for handler in self.handlers:
+ if handler["router"].match(text):
+ queue.push(handler["priority"], handler["handler"])
+
+ return queue
diff --git a/src/infini/input.py b/src/infini/input.py
new file mode 100644
index 00000000..21c12a2f
--- /dev/null
+++ b/src/infini/input.py
@@ -0,0 +1,21 @@
+from infini.typing import Dict, Any, Generic, T
+
+
+class Input(Generic[T]):
+ plain_data: T
+ variables: Dict[str, Any]
+
+ def __init__(self, plain_data: Any, variables: Dict[str, Any] | None = None) -> None:
+ self.plain_data = plain_data
+ self.variables = variables or {}
+
+ def get_session_id(self) -> str:
+ if session_id := self.variables.get("session_id"):
+ return session_id
+
+ user_id = self.variables.get("user_id", "unknown")
+ group_id = self.variables.get("group_id", "unknown")
+ return f"session_{group_id}_{user_id}"
+
+ def get_plain_text(self) -> str:
+ return str(self.plain_data)
diff --git a/src/infini/interceptor.py b/src/infini/interceptor.py
new file mode 100644
index 00000000..54387281
--- /dev/null
+++ b/src/infini/interceptor.py
@@ -0,0 +1,35 @@
+from infini.input import Input
+from infini.output import Output
+from infini.typing import List, RouterType, Callable, Generic, T, overload
+from infini.queue import EventQueue
+
+
+class Interceptor:
+ interceptors: List[RouterType]
+
+ def input(self, input: Input) -> Input | Output:
+ queue = self.match(input.get_plain_text())
+ while not queue.is_empty():
+ if isinstance(intercepted := queue.pop()(input), Output):
+ return intercepted # TODO 允许拦截器产出文本
+ else:
+ input = intercepted
+ return input
+
+ def output(self, output_text: str) -> str | Output:
+ queue = self.match(output_text)
+ while not queue.is_empty():
+ if isinstance(intercepted := queue.pop()(input), Output):
+ return intercepted
+ else:
+ input = intercepted
+ return output_text
+
+ def match(self, text: str) -> EventQueue[Callable[[Input], Input | Output]]:
+ queue = EventQueue()
+
+ for interceptor in self.interceptors:
+ if interceptor["router"].match(text):
+ queue.push(interceptor["priority"], interceptor["handler"])
+
+ return queue
diff --git a/src/infini/internal.py b/src/infini/internal.py
new file mode 100644
index 00000000..4f800297
--- /dev/null
+++ b/src/infini/internal.py
@@ -0,0 +1,18 @@
+from infini.typing import List, ModuleType
+from infini.const import SRC_HOME
+
+import importlib
+import sys
+
+
+def require(name: str, paths: List | None = None) -> ModuleType:
+ paths = [
+ str(path)
+ for path in (
+ (list(paths) + [str(SRC_HOME / name)]) if paths else [str(SRC_HOME / name)]
+ )
+ ]
+ sys.path.extend(paths)
+ module = importlib.import_module(name)
+ (sys.path.remove(path) for path in paths)
+ return module
diff --git a/src/infini/logging.py b/src/infini/logging.py
deleted file mode 100644
index 979fee7d..00000000
--- a/src/infini/logging.py
+++ /dev/null
@@ -1,33 +0,0 @@
-"""Infini 日志。
-
-Infini 使用 [loguru](https://github.com/Delgan/loguru) 来记录日志信息。
-自定义 logger 请参考 [loguru](https://github.com/Delgan/loguru) 文档。
-"""
-from datetime import datetime
-from multilogging import multilogger
-from pathlib import Path
-from .settings import DEBUG
-
-
-__all__ = ["logger", "error_or_exception"]
-
-logger = multilogger(name="Infini", payload="Core",
- level="DEBUG" if DEBUG else "INFO")
-CURRENT_PATH = Path(__file__).resolve().parent
-DATA_PATH = Path.home() / ".infini"
-LOG_PATH = DATA_PATH / "logs"
-if not LOG_PATH.exists():
- LOG_PATH.mkdir(parents=True, exist_ok=True)
-logger.add(
- sink=LOG_PATH / (datetime.now().strftime("%Y-%m-%d") + ".log"),
- level="INFO",
- rotation="10 MB",
-) # 每个日志文件最大为 10MB
-
-
-def error_or_exception(message: str, exception: Exception, verbose: bool = True):
- if verbose:
- logger.exception(exception)
- logger.critical(message)
- else:
- logger.critical(f"{message} {exception!r}")
diff --git a/src/infini/matcher.py b/src/infini/matcher.py
deleted file mode 100644
index 8c11ff29..00000000
--- a/src/infini/matcher.py
+++ /dev/null
@@ -1,34 +0,0 @@
-"""Infini Matcher
-
-用于处理和匹配事件。
-"""
-
-from .register import Register, register
-from .event import MatcherEvent
-from .handler import Handler
-from .exceptions import UnknownMatcherEvent
-
-
-class Matcher:
- """事件处理单元"""
-
- register: Register
-
- def __init__(self, _register: Register | None = None) -> None:
- self.register = _register or register
-
- def match(self, name: str) -> Handler:
- if handler := self.register.handlers.match(name):
- return handler if isinstance(handler, Handler) else handler()
- else:
- raise UnknownMatcherEvent(f"未知的规则包: {name}")
-
- def run(self, event: MatcherEvent) -> str:
- callback_event = self.match(event.name).process(event)
- return self.register.events.process(
- callback_event.name,
- **callback_event.kwargs or callback_event.kwargs,
- )
-
-
-matcher = Matcher()
diff --git a/src/infini/output.py b/src/infini/output.py
new file mode 100644
index 00000000..ddb7f0a5
--- /dev/null
+++ b/src/infini/output.py
@@ -0,0 +1,19 @@
+from infini.typing import Literal
+
+
+class Output:
+ type: Literal["null", "text", "workflow"]
+ name: str
+ status: int
+ block: bool
+
+ @classmethod
+ def empty(cls) -> "Output":
+ output = cls()
+ output.type = "null"
+ output.status = 0
+ output.block = True
+ return output
+
+ def is_empty(self) -> bool:
+ return self.type == "null"
diff --git a/src/infini/queue.py b/src/infini/queue.py
new file mode 100644
index 00000000..9dd441ee
--- /dev/null
+++ b/src/infini/queue.py
@@ -0,0 +1,47 @@
+from infini.exceptions import KeyError
+from infini.typing import Generic, T
+from collections import deque
+
+import heapq
+
+
+class EventQueue(Generic[T]):
+ heap: list
+ entry_finder: dict
+ counter: int
+ order_queue: deque
+
+ def __init__(self) -> None:
+ self.heap = []
+ self.entry_finder = {}
+ self.counter = 0
+ self.order_queue = deque()
+
+ def push(self, priority: int, item: T) -> None:
+ if item in self.entry_finder:
+ self.remove(item)
+ entry = [priority, self.counter, item]
+ self.counter += 1
+ self.entry_finder[item] = entry
+ heapq.heappush(self.heap, entry)
+ self.order_queue.appendleft(item)
+
+ def pop(self) -> T:
+ while self.heap:
+ _, _, item = heapq.heappop(self.heap)
+ if self.entry_finder[item] is not None:
+ del self.entry_finder[item]
+ self.order_queue.remove(item)
+ return item
+ raise KeyError("事件队列为空.")
+
+ def remove(self, item) -> None:
+ entry = self.entry_finder.pop(item)
+ entry[-1] = None
+
+ def is_empty(self) -> bool:
+ return not bool(self.heap)
+
+ def generate(self):
+ while not self.is_empty():
+ yield self.pop()
diff --git a/src/infini/register.py b/src/infini/register.py
deleted file mode 100644
index 55677152..00000000
--- a/src/infini/register.py
+++ /dev/null
@@ -1,163 +0,0 @@
-"""Infini 注册模块
-
-包含了 Infini 事件和处理器的注册和加载功能。
-"""
-
-from pathlib import Path
-from .exceptions import UnknownMatcherEvent, UnsupportedError
-from .handler import Handler
-from .event import InfiniEvent, MessageEvent, WorkflowEvent
-from .typing import Dict, Type
-from .exceptions import LoadError, EventLoadError, HandlerLoadError
-
-import re
-import sys
-import importlib
-import inspect
-
-
-class Loader:
- """Infini 事件加载器
-
- Raises:
- LoadError: 规则包导入错误
- EventLoadError: 规则包事件导入错误
- HandlerLoadError: 规则包业务函数导入错误
- """
-
- name: str
- meta_path: Path
- events: dict
- handlers: dict
-
- def __init__(self, meta_path: Path | str) -> None:
- if isinstance(meta_path, str):
- self.meta_path = Path(meta_path).resolve()
- else:
- self.meta_path = meta_path.resolve()
- self.name = self.meta_path.name
- self.events = {}
- self.handlers = {}
-
- def load(self) -> None:
- sys.path.append(str(self.meta_path))
- try:
- importlib.import_module(f"{self.name}")
- except Exception as error:
- raise LoadError(f"规则包[{self.name}]导入失败: {error}") from error
-
- try:
- event_module = importlib.import_module(f"{self.name}.event")
- events = [
- cls[1]
- for cls in inspect.getmembers(event_module, inspect.isclass)
- if issubclass(cls[1], InfiniEvent)
- and not cls[1].__module__.startswith("infini")
- ]
- for event in events:
- self.events[f"{self.name}.{event.__dict__['name']}"] = event
- except Exception as error:
- raise EventLoadError(f"规则包[{self.name}]事件导入失败: {error}") from error
-
- try:
- handler_module = importlib.import_module(f"{self.name}.handler")
- handlers = [
- cls[1]
- for cls in inspect.getmembers(handler_module, inspect.isclass)
- if issubclass(cls[1], Handler)
- and not cls[1].__module__.startswith("infini")
- ]
- for handler in handlers:
- self.handlers[f"{self.name}.{handler.__dict__['name']}"] = handler
- except Exception as error:
- raise HandlerLoadError(f"规则包[{self.name}]业务函数导入失败: {error}") from error
-
- sys.path.remove(str(self.meta_path))
-
-
-class Events:
- """规则包事件集合
-
- Raises:
- UnsupportedError: 事件尚未被支持
- UnknownMatcherEvent: 事件不存在
-
- Returns:
- _type_: _description_
- """
-
- _events: Dict[str, Type[InfiniEvent]]
-
- def __init__(self) -> None:
- self._events = {}
-
- def register(self, name: str, event: Type[InfiniEvent]) -> None:
- self._events[name.lower()] = event
-
- def update(self, _events: dict) -> None:
- self._events.update(_events)
-
- def _process(self, event: Type[InfiniEvent], **kwargs) -> str:
- # sourcery skip: merge-duplicate-blocks
- if issubclass(event, MessageEvent):
- return self._format(event.__dict__["output"], **kwargs)
- elif issubclass(event, WorkflowEvent):
- # TODO: handle workflow events
- raise UnsupportedError
- else:
- raise UnsupportedError
-
- def process(self, name: str, **kwargs) -> str:
- if event := self._events.get(name.lower()):
- return self._process(event, **kwargs)
- raise UnknownMatcherEvent(f"事件[{name.lower()}]不存在!")
-
- def _format(self, string: str, **kwargs):
- pattern = r"{(.*?)}"
- values = re.findall(pattern, string)
- for value in values:
- kwarg = kwargs.get(value)
- value = kwarg or ""
- string = re.sub(pattern, value, string)
- return string
-
-
-class Handlers:
- """规则包业务集合
-
- Returns:
- _type_: _description_
- """
-
- _handlers: Dict[str, Handler] = {}
-
- def register(self, name: str, handler: Handler) -> None:
- self._handlers[name.lower()] = handler
-
- def update(self, _events: dict) -> None:
- self._handlers.update(_events)
-
- def match(self, name: str) -> Handler | None:
- return self._handlers.get(name.lower())
-
-
-class Register:
- """注册器"""
-
- events: Events
- handlers: Handlers
-
- def __init__(self) -> None:
- self.events = Events()
- self.handlers = Handlers()
-
- def register(
- self, meta_path: Path | str | None = None, loader: Type[Loader] | None = None
- ):
- _loader = Loader(meta_path or ".") if not loader else loader(meta_path or ".")
- _loader.load()
- self.events.update(_loader.events)
- self.handlers.update(_loader.handlers)
-
-
-register = Register()
diff --git a/src/infini/router.py b/src/infini/router.py
new file mode 100644
index 00000000..a520a456
--- /dev/null
+++ b/src/infini/router.py
@@ -0,0 +1,21 @@
+from infini.typing import overload
+
+
+class Router:
+ sign: str
+
+ def __init__(self, sign: str) -> None:
+ self.sign = sign
+
+ def match(self, input: str) -> bool:
+ return self.sign == input.strip()
+
+
+class StartswithRouter(Router):
+ def match(self, input: str) -> bool:
+ return input.strip().startswith(self.sign)
+
+
+class ContainsRouter(Router):
+ def match(self, input: str) -> bool:
+ return self.sign in input.strip()
diff --git a/src/infini/settings.py b/src/infini/settings.py
deleted file mode 100644
index 51c64dd2..00000000
--- a/src/infini/settings.py
+++ /dev/null
@@ -1 +0,0 @@
-DEBUG = True
diff --git a/src/infini/typing.py b/src/infini/typing.py
index 0da72385..0a0d3292 100644
--- a/src/infini/typing.py
+++ b/src/infini/typing.py
@@ -1,24 +1,22 @@
-"""Infini 类型提示支持。
-
-此模块定义了部分 Infini 使用的类型。
-"""
-
from typing import (
Dict as Dict,
+ List as List,
Any as Any,
- Type as Type,
- ClassVar as ClassVar,
Generic as Generic,
- TYPE_CHECKING as TYPE_CHECKING,
- TypeVar as TypeVar,
Callable as Callable,
- NoReturn as NoReturn,
- Awaitable as Awaitable,
+ Literal as Literal,
+ overload as overload,
+ TypeVar,
+ TypedDict,
+ Union,
)
+from types import ModuleType as ModuleType
+from . import router, input, output
-if TYPE_CHECKING:
- from typing import Any
+T = TypeVar("T")
-__all__ = ["StateT"]
-StateT = TypeVar("StateT")
+class RouterType(TypedDict):
+ priority: int
+ router: router.Router
+ handler: Callable[["input.Input"], Union["input.Input", "output.Output"]]
diff --git a/src/infini/utils/cli.py b/src/infini/utils/cli.py
deleted file mode 100644
index 3d30f839..00000000
--- a/src/infini/utils/cli.py
+++ /dev/null
@@ -1,28 +0,0 @@
-"""
-Infini 终端命令解析模块
-"""
-
-import argparse
-import sys
-
-
-def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
- # sourcery skip: extract-duplicate-method
- parser = argparse.ArgumentParser(prog="Infini CLI", description="Infini 命令行工具")
-
- parser.add_argument("--gui", action="store_true", help="启用 GUI 模式")
-
- subparsers = parser.add_subparsers(title="功能件", dest="operate")
-
- # 子命令 `new`
- new_parser = subparsers.add_parser("new", help="创建一个 Infini 规则包模板")
- new_parser.add_argument("path", help="目标位置")
- new_parser.add_argument("-v", "--verbose", action="store_true", help="异常追踪")
- new_parser.add_argument("-f", "--force", action="store_true", help="强制创建")
-
- # 子命令 `test`
- test_parser = subparsers.add_parser("test", help="测试 Infini 规则包")
- test_parser.add_argument("path", help="目标位置")
- test_parser.add_argument("-v", "--verbose", action="store_true", help="异常追踪")
-
- return parser.parse_args(sys.argv[1:] or argv or ["--help"])
diff --git a/src/infini/utils/gui.py b/src/infini/utils/gui.py
deleted file mode 100644
index 5e8c91c4..00000000
--- a/src/infini/utils/gui.py
+++ /dev/null
@@ -1,5 +0,0 @@
-"""
-Infini 图形用户界面模块
-"""
-
-# TODO