Repository navigation
Labels
enhancementNew feature or requestNew feature or requestpriority/important-soon高优先级:近期应安排处理的重要问题高优先级:近期应安排处理的重要问题
Description
目标与优先级
不需要再造摘要器;需要组合既有压缩能力并在最终请求组装后判断是否真的满足模型窗口。
- 优先级:P1;责任仓库:
agentic-ai-java/argi;补充任务:T34。 - 总览:https://github.com/agentic-ai-java/argi/issues/117。
当前证据与判断边界
- SummarizationHook/ContextEditingInterceptor 已有 message token threshold;LargeResultEvictionInterceptor 已有大工具结果外置。
- 这些组件各自触发;SummarizationHook 在无 safe cutoff 时保留原消息,未对最终 system/tools/schema/预留输出组成的完整请求设置统一硬门。
以上是源码观察;能力补充结论是基于这些路径的推断,不等同生产故障或漏洞已经复现。框架已有ReAct/Hook、摘要、Todo、Schema声明、工具拦截及可选Sandbox,本任务是在其基础上补齐边界。
范围与落地方案
- 明确模型 contextWindow/input/output reserve,统计最终system、messages、工具Schema、模板、RAG及多模态估算;区分准确计数与保守估算。
- 复用既有摘要、编辑和结果外置,定义顺序、可保护内容和压缩后重新计数;请求仍过大则明示失败/缩小工具集合,不继续冒险调用。
- 保护可信指令、当前计划、最近未完成 toolCall/result 配对、approval/input identity;摘要失败不得用错误字符串替代可靠上下文继续执行。
- 结果外置只有写入确认才返回可读引用;失败不能伪称文件已保存。durable模式引用可恢复性复用 [P1A][T07] 增加版本固定的运行定义解析与恢复能力校验 #123/[P1C][T14] 持久化模型调用结果与稳定工具执行计划 #125 和存储任务能力检查。
前置依赖
- 无前置Task,可独立交付基础契约和reference tests。
已有任务与去重边界
- [P1A][T07] 增加版本固定的运行定义解析与恢复能力校验 #123 (T07)
- [P1C][T14] 持久化模型调用结果与稳定工具执行计划 #125 (T14)
- [P1C][T17] 增加持久化重试、deadline 与恢复预算记账 #127 (T17)
- [P0][T33] 保留上下文来源与信任级别,防止检索或工具内容提升为指令 #136 (T33)
这些是关联/集成位置,不是额外硬阻塞。仅前置依赖要求先交付;持久化和跨实例能力继续由原任务承担。
验收条件
- 最终请求预算包含toolSchema/system/RAG/output reserve,而不只消息列表。
- 压缩后再次验证预算;所有内容不可压缩或摘要失败时无超预算 provider dispatch。
- 跨多个消息的工具配对、审批参数和当前计划不被误删;重复压缩结果稳定可读。
- 外置写失败不返回成功文件指针;计数器替换/模型窗口差异有模型无关测试,旧压缩默认行为不变。
非目标
- 不重建已有 SummarizationHook,不重复 [P1C][T17] 增加持久化重试、deadline 与恢复预算记账 #127 的调用次数/金额预算,也不建设新对象存储服务。
兼容与验证
- Java 17,新增路径opt-in;保留现有公开API、默认行为与历史state/checkpoint格式。不引入MQ或节点级分片。
- Core不导入Redis/Extensions;优先复用已有API、reducer和组件,不直接添加新依赖。
- 先模型无关单测,再按本任务范围运行模块测试/API与格式fixture;跨adapter路径用stub contract tests,真实Docker测试注明环境要求。
- 当前main的兼容文档/CI曾调整,新任务不引用已删除文档或自行恢复CI;遵循实施时实际有效门禁,保留兼容回归目标。
源码依据(固定版本)
- Existing summarization trigger
- Existing context editing
- Large-result persistence response
- Schema augmentation
分析基线:Core f3bcbef24aa79e1e265a7d0d2011274982ac2978、Extensions 1ba3048f16d48c9f41dab171eed9a91148b45758。只读compare确认相对上次分析没有生产Java变更,主要是release/build/docs更新;本Issue不表示能力已实现。
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or requestpriority/important-soon高优先级:近期应安排处理的重要问题高优先级:近期应安排处理的重要问题
Activity
Carl-Zhou-CN commentedon Oct 23, 2026
assigne me @Aias00
konlue commentedon Nov 2, 2026
您好,我想认领 #137。
基于 main
738354633确认:TokenCounter.countTokens(List<ChatMessage>)只累计消息正文与 assistant 的 tool call arguments(chars/4 近似),不计 system 消息、工具 schema 与输出预留;而最终派发的是ReActAgent.invokeModel里的new ChatRequest(composeMessages(request), effective.definitions(), request.getOptions(), request.getAttributes())——composeMessages把 system 拼进消息,effective.definitions()是ToolDefinition(name, description, inputSchema)。GenerationOptions只有maxTokens(输出上限),全仓没有 contextWindow / input budget / reserve 的概念。SummarizationHook.beforeModel只按 previousMessages 计数并与阈值比较;findSafeCutoff找不到安全切点时log.warn("Cannot find safe cutoff point for summarization")后原样返回原消息继续,摘要抛异常时也「保留原历史继续」;ContextEditingInterceptor.interceptModel找不到可清候选时原样放行。两处都没有「最终请求仍然超预算 → 不得调用 provider」的收口。LargeResultEvictionInterceptor.processLargeResult在backend.write(...)返回错误或backend == null时只log.warn,随后仍返回TOO_LARGE_TOOL_MSG(「was saved in the filesystem at this path: …」)并置status=evicted_to_filesystem——伪称文件已保存。方案(单 PR,只做预算契约与硬门,不动既有默认行为)
argi-agent-api新增io.github.agentic.ai.agent.budget包,定义ContextWindowBudget(输入窗口 + 输出预留)、RequestTokenEstimate(system / 消息 / 工具 schema / 输出预留的分解估算,区分准确计数与保守估算)、RequestTokenEstimator(可替换的计数口径)与默认近似实现、BudgetComponent与BudgetViolation(稳定越界分类)、ContextWindowBudgetExceededException(明确失败,不静默截断)。ContextBudgetInterceptor(中立层ModelInterceptor,opt-in 挂进既有interceptors(...)链):估算 → 超限则调RequestCompactor→ 重新估算 → 仍超限则抛异常且不调用 provider;未超限才放行。中立 ReAct 与框架 ReactAgent 两条路径共用同一个闸门,不需要改任何引擎。RequestCompactor接缝,框架侧用适配器接既有SummarizationHook(不改其默认阈值与默认行为);配对保护用ToolCallPairingValidator校验「assistant toolCall ↔ tool 结果」一一配对,压缩破坏配对即拒绝派发。LargeResultEvictionInterceptor写失败或未配置 backend 时不再返回声称已落盘的指针,改为显式失败状态并保留原 metadata;不动装配形态(迁移到生命周期插件属于 [Refactor][P1] 将摘要、上下文编辑与大结果处理接入生命周期插件 #302 的范围)。测试(离线,模型无关)
ContextWindowBudgetExceededException,handler 调用次数为 0。evicted_to_filesystem;压缩适配器在摘要成功时返回压缩后的请求、摘要失败时原样返回。konlue commentedon Nov 2, 2026
补充一处测试口径:
LargeResultEvictionInterceptor.Builder.build()在启用驱逐时会自动补一个默认LocalFilesystemBackend,所以「未配置 backend」的分支只有防御意义、无法经 builder 构造;测试覆盖的是写失败这一条真实路径——backend 返回错误时,结果不含文件指针、不含 “saved in the filesystem” 文案,状态为error,原 response 的 metadata 保留。其余测试清单不变。fix(agent): position-aware tool result pairing and documented budget …
fix(agent): account for an explicit maxTokens output demand in the bu…
fix(agent): estimate the tool schemas the dispatch actually sends (is…