Conversation
|
|
||
| func (a *ChatModelAgent) applyBeforeAgent(ctx context.Context, ec *execContext) (context.Context, *execContext, error) { | ||
| func (a *ChatModelAgent) applyBeforeAgent(ctx context.Context, ec *execContext, agentInput *AgentInput) (context.Context, *execContext, error) { | ||
| runCtx := &ChatModelAgentContext{ |
There was a problem hiding this comment.
🚨 Breaking API Changes Detected
Package: github.com/cloudwego/eino/adk
Incompatible changes:
- ChatModelAgentMiddleware.AfterAgent: added
Review Guidelines
Please ensure that:
- The changes are absolutely necessary
- They are properly documented
- Migration guides are provided if needed
6544882 to
7a50a8c
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #987 +/- ##
==========================================
- Coverage 82.82% 79.37% -3.46%
==========================================
Files 148 154 +6
Lines 16668 21693 +5025
==========================================
+ Hits 13806 17219 +3413
- Misses 1903 3386 +1483
- Partials 959 1088 +129 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
feat(agentic_model): - format print - support agentic chat template - support to compose agentic odel&agentic tools node - support agentic tool node - support agentic message concat
* fix(adk): skip saving checkpoint when TurnLoop is idle When Stop() is called on an idle TurnLoop (no active agent run, no unhandled items, no canceled items), the resulting checkpoint contains no meaningful state. Skip saving such checkpoints to avoid unnecessary store writes. - Add isIdle check in cleanup() before checkpoint save decision - Add TestTurnLoop_StopWhileIdle_SkipsCheckpoint test Change-Id: I6aeaff5ed5833a971cb95298193fdb96d904baf8 * fix(internal): merge id2State in PopulateInterruptState instead of replacing PopulateInterruptState merged id2Addr entries one by one but replaced id2State wholesale. In a parallel workflow resume, two goroutines share the same globalResumeInfo. If one goroutine's compose graph called PopulateInterruptState (replacing id2State with compose-only entries) before the other goroutine looked up its outer-level entry, the lookup returned a zero-value InterruptState with State=nil, triggering the 'has no state' panic in ChatModelAgent.Resume. Change id2State handling to merge entry by entry, consistent with id2Addr. Change-Id: Ia21f65289bff7beb2bc383fb033926ad9c92d7e7 * fix(adk): keep watching for cancel escalation after stopSig.done When watchStopSignal entered the stopSig.done branch, it processed the initial cancel and then blocked on <-done (turn completion), never looping back to check notify. This meant a subsequent Stop() call with a higher cancel mode (e.g. CancelImmediate) was never forwarded to the agent, causing TestTurnLoop_Stop_EscalatesCancelMode to time out. Replace the blocking <-done with an inner loop that selects on both done and notify, so escalation signals are always delivered. Also apply the generation-based dedup check consistent with the notify branch. Change-Id: Ia6a04d00a2b44625ffbcb625ff0e559c12ed145f
…r agent cancellation (#929) * fix(adk): prevent panic when orphaned tool goroutine sends event after agent cancellation When CancelAfterChatModel times out and escalates to CancelImmediate, GraphInterrupt fires with timeout=0. The compose graph returns immediately, orphaning parallel tool goroutines. When an orphaned tool completes, eventSenderToolWrapper tries to send an event via the AsyncGenerator which is already closed, causing 'send on closed channel' panic. - Add isImmediateCancelled() to cancelContext for checking immediateChan - Make chatModelAgentExecCtx.send cancel-aware: skip send when immediate cancel is active - Use trySend as safety net for the TOCTOU race window - Route SendEvent() through execCtx.send() instead of direct generator.Send() Change-Id: Ic7e0194c860e2692a3cddc559911ab379024f650 * test(adk): add test for orphaned tool goroutine panic after CancelImmediate - unit_send_after_close: directly reproduces the panic by sending to a closed generator with isImmediateCancelled=true - unit_send_after_close_without_cancel_ctx: verifies trySend safety net prevents panic even without cancelCtx - integration_cancel_escalation_orphans_tool: end-to-end test with slow tool, CancelAfterChatModel timeout escalation, and orphaned goroutine Change-Id: Ia82fa957b102ccc2ac42094d18d4b15db2a1701c * test(adk): improve coverage for orphaned tool goroutine fix Add test cases for: - nil execCtx and nil generator defensive guards - nil cancelContext in isImmediateCancelled - TOCTOU race window (isImmediateCancelled=false but generator closed) - SendEvent public API with closed generator - SendEvent without exec context Change-Id: I197c36f34675f5376cbe5f830b15db6ca873cd1f
…925) * fix(adk): keep late turn loop items Change-Id: Iabee0c25a83d5a25585d3592a41ca6a5fba35c2b * docs(adk): clarify cancel wait semantics Change-Id: Ia0a396b9cc2e43f15e85056d966f20b010dcd2b6 * feat(adk): add WithSkipCheckpoint and WithStopCause StopOptions Add two new StopOption variants for TurnLoop.Stop(): - WithSkipCheckpoint: prevents checkpoint persistence on stop, for cases where the caller does not intend to resume in the future. The flag is sticky across escalation calls. - WithStopCause: attaches a business-supplied reason string. Surfaced in TurnLoopExitState.StopCause and, after the Stopped channel closes, via TurnContext.StopCause(). Uses first-non-empty-wins semantics across multiple Stop() calls. Thread both fields through stopSignal with proper mutex protection. Update cleanup() to skip checkpoint save when skipCheckpoint is set. Change-Id: Ifeat-stop-options-skip-checkpoint-stop-cause
* fix: rebase error Change-Id: If20fa78dba82a1c177c8ec47090050ea8c1354ed * feat(adk): add failover support for ChatModel Change-Id: Ice1b513b4b509e7b540316da9119ff3d529c9bae * feat(adk): add failover support for ChatModel Change-Id: Ice1b513b4b509e7b540316da9119ff3d529c9bae * feat(adk): add failover support for ChatModel Change-Id: Id5483447b74322f6dd495bdd3b994c001094569d * feat(adk): make Name and Description optional in ChatModelAgentConfig * feat(adk): add callback lifecycle management to failoverProxyModel - Extract prepareCallbacks method to reuse callback setup logic between Generate and Stream methods - Add callbacks.ReuseHandlers with proper RunInfo (model type + component) before each failover model invocation so handlers receive correct identity - Add explicit OnStart/OnEnd/OnError callback invocations in Generate and Stream since failoverProxyModel declares IsCallbacksEnabled() = true and the outer layer skips automatic callback injection Change-Id: I0150529024125251828cf6f77c8247aa464b1f84 * fix(adk): preserve partial result in failoverProxyModel.Generate on error Return result instead of nil when target.Generate fails, so that the outer failoverModelWrapper can pass the partial output message to ShouldFailover for inspection. Change-Id: I32d86151a6e133f1a58d5e988bccf42d831a646c * refactor(adk): use EnsureRunInfo in failoverProxyModel and separate ctx for callbacks - Replace manual RunInfo construction + ReuseHandlers with callbacks.EnsureRunInfo for cleaner RunInfo setup - Use nCtx (from EnsureRunInfo) for target model invocation and original ctx for OnStart/OnEnd/OnError callback lifecycle Change-Id: I1d5982d0e1ceeaf8f6648b9c40c229b6a2b07ab8 --------- Co-authored-by: shentong.martin <shentong.martin@bytedance.com>
feat: tool search definition
…945) - Add ToolAliases to prepareExecContext when building ToolsNodeConfig - Add UnknownToolsHandler, ExecuteSequentially, ToolArgumentsHandler, and ToolAliases to applyBeforeAgent when rebuilding after BeforeAgent handlers modify tools - Add tests covering argument alias remapping, name alias dispatch, alias preservation after handler rebuild, and handler-only tool registration with pre-configured aliases
…options, add UntilIdleFor (#942)
… retry event signaling (#944)
… UntilIdleFor from canceling agent (#972)
… and clean up internal terminology (#979)
feat(adk): add MultiModalRead with custom FileContentPart types - Define FileContentPartType, FileContentPart in filesystem package to replace direct schema.ToolOutputPart dependency, supporting only Image (bytes) and File (bytes) types - Add MultiModalReader interface and MultiModalReadRequest with Pages field - Add multiModalReadFileArgs extending readFileArgs with PDF pages param - Convert FileContentPart to schema.ToolOutputPart with base64 encoding in middleware layer - Guard against nil FileContent returned from Backend.Read and MultiModalRead; return human-readable fallback instead of panicking - Reuse base64 encoding buffer across multimodal parts via base64Encoder - Add tests for image, file, unsupported type, pages passthrough, schema fields, custom desc, empty data error, nil result, and routing
…es to BeforeModelRewriteState (#984)
* feat(adk): validate pages parameter in MultiModalReadFileTool - Add validatePages function to check format (must be "N" or "N-M") - Reject invalid formats such as "1-", "-5", non-numeric values - Enforce end >= start and max 20 pages per request - Return validation error as ToolResult so the model can self-correct * test(adk): add unit tests for validatePages function - Cover valid formats: single page, range, same start/end, max boundary - Cover invalid formats: trailing dash, leading dash, non-numeric, zero - Cover logic errors: end < start, range exceeds 20 pages
…terToolCallsHook option (#985)
Replace FunctionToolResult.Result string field with Blocks
[]*FunctionToolResultBlock to uniformly represent all tool results
(text-only and multimodal) as structured content blocks.
- Add FunctionToolResultBlock type supporting text, image, audio,
video, and file content with String() method
- Remove FunctionToolResult.Result field; text results are now
wrapped as FunctionToolResultBlock{Text: ...}
- Update FunctionToolResultAgenticMessage to accept blocks parameter
- Convert MessageInputPart to FunctionToolResultBlock in compose layer
- Update concatFunctionToolResults to merge via Blocks append
- Add comprehensive tests for multimodal and streaming tool results
…xt, and DeepAgent for AgenticMessage support (#988)
…1004) refactor(adk): build ToolsNodeConfig via shallow copy + field override Replace explicit field-by-field struct literals with a shallow copy of the source ToolsNodeConfig followed by overriding only the fields that need per-run isolation (Tools and ToolCallMiddlewares). New fields added to compose.ToolsNodeConfig in the future will be forwarded automatically instead of being silently dropped. - applyBeforeAgent: reuse the already-cloned toolsNodeConf local instead of rebuilding the struct - prepareExecContext: shallow-copy a.toolsConfig.ToolsNodeConfig then cloneSlice the Tools/ToolCallMiddlewares that will be appended to No behavior change: every field is assigned the same value as before.
…base Swap handler positions in InnermostGetsOriginalOutput subtests to match the forward-iteration semantics from #1000. The tests assumed the old reverse-iteration order where handlers[0] was innermost. Change-Id: Ib319b3ea687870db9f69c4c93e1ee69369ea2fe8
…eep-copy (#1007) fix(serialization): ensure pointer-receiver MarshalJSON is invoked in InternalSerializer When InternalSerializer marshals a struct value that implements json.Marshaler via pointer receiver (e.g. *ToolInfo), rv.Interface() produces a non-addressable copy. json.Marshal then cannot call the pointer method and falls back to default struct encoding, which skips unexported fields — causing ParamsOneOf data loss after deepCopyState during interrupt/resume. Fix: pass a pointer to json.Marshal by using rv.Addr() when addressable, or copying into reflect.New() otherwise.
ba37df9 to
52a0b15
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What type of PR is this?
Check the PR title.
(Optional) Translate the PR title into Chinese.
(Optional) More detailed description for this PR(en: English/zh: Chinese).
en:
zh(optional):
(Optional) Which issue(s) this PR fixes:
(optional) The PR that updates user documentation: