-
Notifications
You must be signed in to change notification settings - Fork 7
移除 runtime 的 max_loops 限制并同步 compact 语义 #292
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,6 +20,8 @@ import ( | |
| // Run 执行一次完整的 ReAct 闭环:保存用户输入、驱动模型、执行工具并发出事件。 | ||
| // 已有会话会先加锁再加载/更新,确保同一会话并发 Run 不会出现状态覆盖; | ||
| // 新会话在创建后再绑定会话锁,不同会话可并行执行。 | ||
| // 当前实现不再设置内部轮数上限,因此 Run 仅在拿到最终 assistant 回复、遇到错误或收到外部取消时结束。 | ||
| // 这也意味着同一 session 的锁会覆盖整个运行周期,调用方需要依赖模型终止条件或取消机制兜底。 | ||
| func (s *Service) Run(ctx context.Context, input UserInput) error { | ||
| if strings.TrimSpace(input.Content) == "" { | ||
| return errors.New("runtime: input content is empty") | ||
|
|
@@ -68,28 +70,7 @@ func (s *Service) Run(ctx context.Context, input UserInput) error { | |
| return s.handleRunError(ctx, state.runID, state.session.ID, err) | ||
| } | ||
|
|
||
| for turn := 0; ; turn++ { | ||
| maxLoops := resolveMaxLoops(s.configManager.Get()) | ||
| if turn >= maxLoops { | ||
| errMessage := "runtime: max loop reached" | ||
| applied, compactErr := s.applyCompactForState( | ||
| ctx, | ||
| &state, | ||
| s.configManager.Get(), | ||
| contextcompact.ModeLoopLimit, | ||
| compactErrorBestEffort, | ||
| ) | ||
| if compactErr != nil { | ||
| return s.handleRunError(ctx, state.runID, state.session.ID, compactErr) | ||
| } | ||
| if applied { | ||
| errMessage = "runtime: max loop reached after saving continuation checkpoint" | ||
| } | ||
| err := errors.New(errMessage) | ||
| s.emit(ctx, EventError, state.runID, state.session.ID, err.Error()) | ||
| return err | ||
| } | ||
|
|
||
| for { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removing the loop budget turns the run loop into an unbounded execution path. If the model keeps returning |
||
| for { | ||
| if err := ctx.Err(); err != nil { | ||
| return s.handleRunError(ctx, state.runID, state.session.ID, err) | ||
|
|
@@ -298,14 +279,6 @@ func (s *Service) applyCompactForState( | |
| return false, nil | ||
| } | ||
|
|
||
| // resolveMaxLoops 收敛运行时最大推理轮数的默认值逻辑。 | ||
| func resolveMaxLoops(cfg config.Config) int { | ||
| if cfg.MaxLoops <= 0 { | ||
| return defaultMaxLoops | ||
| } | ||
| return cfg.MaxLoops | ||
| } | ||
|
|
||
| // autoCompactThreshold 返回当前配置下的自动 compact 触发阈值。 | ||
| func autoCompactThreshold(cfg config.Config) int { | ||
| if cfg.Context.AutoCompact.Enabled && cfg.Context.AutoCompact.InputTokenThreshold > 0 { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
max_loopswas removed from persisted config while strict YAML known-fields decoding is still enforced, so existing user configs containingmax_loopsnow hard-fail to load. If this breaking change is intentional, consider adding a temporary compatibility shim (accept+ignore legacy key) or an explicit migration path in docs/release notes to avoid upgrade-time boot failures.