Vibe Coding: textfx 若干 issue 更新
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@ -23,7 +23,7 @@ class TextHandleResult:
|
||||
|
||||
|
||||
class TextHandler(ABC):
|
||||
name: str = ''
|
||||
name: str = ""
|
||||
keywords: list[str] = []
|
||||
|
||||
@abstractmethod
|
||||
@ -37,12 +37,16 @@ class TextHandler(ABC):
|
||||
|
||||
class TextHandlerSync(TextHandler):
|
||||
@abstractmethod
|
||||
def handle_sync(self, env: TextHandlerEnvironment, istream: str | None, args: list[str]) -> TextHandleResult:
|
||||
...
|
||||
def handle_sync(
|
||||
self, env: TextHandlerEnvironment, istream: str | None, args: list[str]
|
||||
) -> TextHandleResult: ...
|
||||
|
||||
async def handle(self, env: TextHandlerEnvironment, istream: str | None, args: list[str]) -> TextHandleResult:
|
||||
async def handle(
|
||||
self, env: TextHandlerEnvironment, istream: str | None, args: list[str]
|
||||
) -> TextHandleResult:
|
||||
def _hs():
|
||||
return self.handle_sync(env, istream, args)
|
||||
|
||||
return await asyncio.to_thread(_hs)
|
||||
|
||||
|
||||
@ -99,6 +103,7 @@ class PipelineRunner:
|
||||
current_string = ""
|
||||
current_string_raw = ""
|
||||
status_in_string_pair = ""
|
||||
has_token = False # 是否正在构建一个 token(区分空字符串和无 token)
|
||||
|
||||
# 重定向解析状态
|
||||
is_parsing_redirect_filename = False
|
||||
@ -111,8 +116,9 @@ class PipelineRunner:
|
||||
current_string, \
|
||||
current_string_raw, \
|
||||
is_parsing_redirect_filename, \
|
||||
current_redirect_target
|
||||
if not current_string:
|
||||
current_redirect_target, \
|
||||
has_token
|
||||
if not has_token:
|
||||
return
|
||||
|
||||
if is_parsing_redirect_filename:
|
||||
@ -123,6 +129,7 @@ class PipelineRunner:
|
||||
|
||||
current_string = ""
|
||||
current_string_raw = ""
|
||||
has_token = False
|
||||
|
||||
# 辅助函数:将当前指令 flush 到当前组
|
||||
def _flush_command() -> str | None:
|
||||
@ -176,6 +183,7 @@ class PipelineRunner:
|
||||
status_in_string_pair = c
|
||||
status = PipelineParseStatus.in_string
|
||||
current_string_raw = ""
|
||||
has_token = True
|
||||
|
||||
elif c == "|":
|
||||
_flush_token()
|
||||
@ -206,6 +214,7 @@ class PipelineRunner:
|
||||
|
||||
else:
|
||||
current_string += c
|
||||
has_token = True
|
||||
|
||||
case PipelineParseStatus.in_string:
|
||||
current_string_raw += c
|
||||
@ -217,7 +226,18 @@ class PipelineRunner:
|
||||
current_string += c
|
||||
|
||||
case PipelineParseStatus.in_string_to_escape:
|
||||
current_string += c
|
||||
escape_map = {
|
||||
"n": "\n",
|
||||
"r": "\r",
|
||||
"t": "\t",
|
||||
"0": "\0",
|
||||
"a": "\a",
|
||||
"b": "\b",
|
||||
"f": "\f",
|
||||
"v": "\v",
|
||||
"\\": "\\",
|
||||
}
|
||||
current_string += escape_map.get(c, c)
|
||||
status = PipelineParseStatus.in_string
|
||||
|
||||
case PipelineParseStatus.off_string:
|
||||
@ -265,24 +285,19 @@ class PipelineRunner:
|
||||
pipeline: Pipeline,
|
||||
istream: str | None,
|
||||
env: TextHandlerEnvironment | None = None,
|
||||
) -> TextHandleResult:
|
||||
) -> list[TextHandleResult]:
|
||||
if env is None:
|
||||
# 默认环境
|
||||
env = TextHandlerEnvironment(is_trusted=False, buffers={})
|
||||
|
||||
final_result = TextHandleResult(code=0, ostream=istream)
|
||||
results: list[TextHandleResult] = []
|
||||
|
||||
# 遍历执行指令组 (分号分隔)
|
||||
# 遍历执行指令组 (分号分隔),每个组独立产生输出
|
||||
for group in pipeline.command_groups:
|
||||
# 每个组开始时,使用原始输入(或者根据需求设为 None,这里假设每个组独立处理 istream)
|
||||
# 通常分号分隔的命令组,第一条命令如果没有 pipe 输入,它接收的 istream 取决于整体输入
|
||||
current_stream = istream
|
||||
group_result = TextHandleResult(code=0, ostream=None)
|
||||
|
||||
# 遍历组内指令 (管道分隔)
|
||||
for cmd in group:
|
||||
if final_result.code != 0:
|
||||
break
|
||||
|
||||
try:
|
||||
logger.debug(
|
||||
f"Executing: {cmd.handler.name} args={cmd.args} redirect={cmd.redirect_target}"
|
||||
@ -290,8 +305,9 @@ class PipelineRunner:
|
||||
result = await cmd.handler.handle(env, current_stream, cmd.args)
|
||||
|
||||
if result.code != 0:
|
||||
final_result = result
|
||||
break
|
||||
# 组内出错,整条流水线中止
|
||||
results.append(result)
|
||||
return results
|
||||
|
||||
# 处理重定向逻辑
|
||||
if cmd.redirect_target:
|
||||
@ -304,29 +320,27 @@ class PipelineRunner:
|
||||
else:
|
||||
env.buffers[target_buffer] = content_to_write
|
||||
|
||||
# 重定向后,标准输出通常被消耗,后续管道接收到的流为空 (或 None)
|
||||
# 除非实现 tee 逻辑,否则视为流已终止
|
||||
current_stream = None
|
||||
|
||||
# 更新最终结果,但 ostream 设为 None 因为被重定向了
|
||||
final_result = TextHandleResult(
|
||||
group_result = TextHandleResult(
|
||||
code=0, ostream=None, attachment=result.attachment
|
||||
)
|
||||
else:
|
||||
current_stream = result.ostream
|
||||
final_result = result
|
||||
group_result = result
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Pipeline execution failed at {cmd.handler.name}")
|
||||
logger.exception(e)
|
||||
return TextHandleResult(code=-1, ostream="处理流水线时出现 python 错误")
|
||||
results.append(
|
||||
TextHandleResult(
|
||||
code=-1, ostream="处理流水线时出现 python 错误"
|
||||
)
|
||||
)
|
||||
return results
|
||||
|
||||
# 一个组执行完,final_result保留该组最后的状态。
|
||||
# 如果还有下一个组,final_result.code 如果是 0 则继续执行下一个组
|
||||
if final_result.code != 0:
|
||||
break
|
||||
results.append(group_result)
|
||||
|
||||
return final_result
|
||||
return results
|
||||
|
||||
|
||||
def register_text_handlers(*handlers: TextHandler):
|
||||
|
||||
Reference in New Issue
Block a user