Showing preview only (3,006K chars total). Download the full file or copy to clipboard to get everything.
Repository: cloudwego/eino
Branch: main
Commit: e2eea8eaf360
Files: 312
Total size: 2.8 MB
Directory structure:
gitextract_0ddnn1r5/
├── .github/
│ ├── .codedev.yml
│ ├── .commit-rules.json
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ ├── PULL_REQUEST_TEMPLATE.md
│ └── workflows/
│ ├── pr-check.yml
│ ├── tag-notification.yml
│ └── tests.yml
├── .gitignore
├── .golangci.yaml
├── .licenserc.yaml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE-APACHE
├── README.md
├── README.zh_CN.md
├── _typos.toml
├── adk/
│ ├── agent_tool.go
│ ├── agent_tool_test.go
│ ├── call_option.go
│ ├── call_option_test.go
│ ├── callback.go
│ ├── callback_integration_test.go
│ ├── callback_test.go
│ ├── chatmodel.go
│ ├── chatmodel_retry_test.go
│ ├── chatmodel_test.go
│ ├── config.go
│ ├── deterministic_transfer.go
│ ├── deterministic_transfer_test.go
│ ├── filesystem/
│ │ ├── backend.go
│ │ ├── backend_inmemory.go
│ │ └── backend_inmemory_test.go
│ ├── flow.go
│ ├── flow_test.go
│ ├── handler.go
│ ├── handler_test.go
│ ├── instruction.go
│ ├── interface.go
│ ├── internal/
│ │ └── config.go
│ ├── interrupt.go
│ ├── interrupt_test.go
│ ├── middlewares/
│ │ ├── dynamictool/
│ │ │ └── toolsearch/
│ │ │ ├── toolsearch.go
│ │ │ └── toolsearch_test.go
│ │ ├── filesystem/
│ │ │ ├── backend.go
│ │ │ ├── filesystem.go
│ │ │ ├── filesystem_test.go
│ │ │ ├── large_tool_result.go
│ │ │ ├── large_tool_result_test.go
│ │ │ └── prompt.go
│ │ ├── patchtoolcalls/
│ │ │ ├── patchtoolcalls.go
│ │ │ └── patchtoolcalls_test.go
│ │ ├── plantask/
│ │ │ ├── backend_test.go
│ │ │ ├── plantask.go
│ │ │ ├── plantask_test.go
│ │ │ ├── task.go
│ │ │ ├── task_create.go
│ │ │ ├── task_create_test.go
│ │ │ ├── task_get.go
│ │ │ ├── task_get_test.go
│ │ │ ├── task_list.go
│ │ │ ├── task_list_test.go
│ │ │ ├── task_update.go
│ │ │ └── task_update_test.go
│ │ ├── reduction/
│ │ │ ├── consts.go
│ │ │ ├── internal/
│ │ │ │ ├── clear_tool_result.go
│ │ │ │ ├── clear_tool_result_test.go
│ │ │ │ ├── large_tool_result.go
│ │ │ │ ├── large_tool_result_test.go
│ │ │ │ └── tool_result.go
│ │ │ ├── legacy.go
│ │ │ ├── reduction.go
│ │ │ └── reduction_test.go
│ │ ├── skill/
│ │ │ ├── filesystem_backend.go
│ │ │ ├── filesystem_backend_test.go
│ │ │ ├── prompt.go
│ │ │ ├── skill.go
│ │ │ └── skill_test.go
│ │ └── summarization/
│ │ ├── consts.go
│ │ ├── customized_action.go
│ │ ├── prompt.go
│ │ ├── summarization.go
│ │ └── summarization_test.go
│ ├── prebuilt/
│ │ ├── deep/
│ │ │ ├── checkpoint_compat_resume_test.go
│ │ │ ├── deep.go
│ │ │ ├── deep_test.go
│ │ │ ├── prompt.go
│ │ │ ├── task_tool.go
│ │ │ ├── task_tool_test.go
│ │ │ ├── testdata/
│ │ │ │ └── _gen/
│ │ │ │ └── generate_test.go
│ │ │ └── types.go
│ │ ├── integration_test.go
│ │ ├── planexecute/
│ │ │ ├── plan_execute.go
│ │ │ ├── plan_execute_test.go
│ │ │ └── utils.go
│ │ └── supervisor/
│ │ ├── supervisor.go
│ │ └── supervisor_test.go
│ ├── react.go
│ ├── react_test.go
│ ├── retry_chatmodel.go
│ ├── runctx.go
│ ├── runctx_test.go
│ ├── runner.go
│ ├── runner_test.go
│ ├── utils.go
│ ├── utils_test.go
│ ├── workflow.go
│ ├── workflow_test.go
│ ├── wrappers.go
│ └── wrappers_test.go
├── callbacks/
│ ├── aspect_inject.go
│ ├── aspect_inject_test.go
│ ├── doc.go
│ ├── handler_builder.go
│ ├── interface.go
│ └── interface_test.go
├── components/
│ ├── document/
│ │ ├── callback_extra_loader.go
│ │ ├── callback_extra_transformer.go
│ │ ├── doc.go
│ │ ├── interface.go
│ │ ├── option.go
│ │ ├── option_test.go
│ │ └── parser/
│ │ ├── doc.go
│ │ ├── ext_parser.go
│ │ ├── interface.go
│ │ ├── option.go
│ │ ├── option_test.go
│ │ ├── parser_test.go
│ │ ├── testdata/
│ │ │ └── test.md
│ │ └── text_parser.go
│ ├── embedding/
│ │ ├── callback_extra.go
│ │ ├── callback_extra_test.go
│ │ ├── doc.go
│ │ ├── interface.go
│ │ ├── option.go
│ │ └── option_test.go
│ ├── indexer/
│ │ ├── callback_extra.go
│ │ ├── callback_extra_test.go
│ │ ├── doc.go
│ │ ├── interface.go
│ │ ├── option.go
│ │ └── option_test.go
│ ├── model/
│ │ ├── callback_extra.go
│ │ ├── callback_extra_test.go
│ │ ├── doc.go
│ │ ├── interface.go
│ │ ├── option.go
│ │ └── option_test.go
│ ├── prompt/
│ │ ├── callback_extra.go
│ │ ├── callback_extra_test.go
│ │ ├── chat_template.go
│ │ ├── chat_template_test.go
│ │ ├── doc.go
│ │ ├── interface.go
│ │ ├── option.go
│ │ └── option_test.go
│ ├── retriever/
│ │ ├── callback_extra.go
│ │ ├── callback_extra_test.go
│ │ ├── doc.go
│ │ ├── interface.go
│ │ ├── option.go
│ │ └── option_test.go
│ ├── tool/
│ │ ├── callback_extra.go
│ │ ├── callback_extra_test.go
│ │ ├── doc.go
│ │ ├── interface.go
│ │ ├── interrupt.go
│ │ ├── interrupt_test.go
│ │ ├── option.go
│ │ ├── option_test.go
│ │ └── utils/
│ │ ├── common.go
│ │ ├── common_test.go
│ │ ├── create_options.go
│ │ ├── doc.go
│ │ ├── error_handler.go
│ │ ├── error_handler_test.go
│ │ ├── invokable_func.go
│ │ ├── invokable_func_test.go
│ │ ├── streamable_func.go
│ │ └── streamable_func_test.go
│ └── types.go
├── compose/
│ ├── branch.go
│ ├── branch_test.go
│ ├── chain.go
│ ├── chain_branch.go
│ ├── chain_branch_test.go
│ ├── chain_parallel.go
│ ├── chain_test.go
│ ├── checkpoint.go
│ ├── checkpoint_migrate_test.go
│ ├── checkpoint_test.go
│ ├── component_to_graph_node.go
│ ├── dag.go
│ ├── dag_test.go
│ ├── doc.go
│ ├── error.go
│ ├── error_test.go
│ ├── field_mapping.go
│ ├── generic_graph.go
│ ├── generic_helper.go
│ ├── graph.go
│ ├── graph_add_node_options.go
│ ├── graph_call_options.go
│ ├── graph_call_options_test.go
│ ├── graph_compile_options.go
│ ├── graph_manager.go
│ ├── graph_node.go
│ ├── graph_run.go
│ ├── graph_test.go
│ ├── interrupt.go
│ ├── introspect.go
│ ├── pregel.go
│ ├── resume.go
│ ├── resume_test.go
│ ├── runnable.go
│ ├── runnable_test.go
│ ├── state.go
│ ├── state_test.go
│ ├── stream_concat.go
│ ├── stream_concat_test.go
│ ├── stream_reader.go
│ ├── stream_reader_test.go
│ ├── tool_node.go
│ ├── tool_node_test.go
│ ├── types.go
│ ├── types_composable.go
│ ├── types_lambda.go
│ ├── types_lambda_test.go
│ ├── utils.go
│ ├── utils_test.go
│ ├── values_merge.go
│ ├── values_merge_test.go
│ ├── workflow.go
│ └── workflow_test.go
├── doc.go
├── flow/
│ ├── agent/
│ │ ├── agent_option.go
│ │ ├── multiagent/
│ │ │ └── host/
│ │ │ ├── callback.go
│ │ │ ├── compose.go
│ │ │ ├── compose_test.go
│ │ │ ├── doc.go
│ │ │ ├── options.go
│ │ │ └── types.go
│ │ ├── react/
│ │ │ ├── callback.go
│ │ │ ├── doc.go
│ │ │ ├── option.go
│ │ │ ├── option_test.go
│ │ │ ├── react.go
│ │ │ └── react_test.go
│ │ └── utils.go
│ ├── indexer/
│ │ └── parent/
│ │ ├── parent.go
│ │ └── parent_test.go
│ └── retriever/
│ ├── multiquery/
│ │ ├── multi_query.go
│ │ └── multi_query_test.go
│ ├── parent/
│ │ ├── doc.go
│ │ ├── parent.go
│ │ └── parent_test.go
│ ├── router/
│ │ ├── router.go
│ │ └── router_test.go
│ └── utils/
│ └── utils.go
├── go.mod
├── go.sum
├── internal/
│ ├── callbacks/
│ │ ├── inject.go
│ │ ├── interface.go
│ │ └── manager.go
│ ├── channel.go
│ ├── channel_test.go
│ ├── concat.go
│ ├── concat_test.go
│ ├── core/
│ │ ├── address.go
│ │ ├── interrupt.go
│ │ ├── interrupt_test.go
│ │ └── resume.go
│ ├── generic/
│ │ ├── generic.go
│ │ ├── generic_test.go
│ │ ├── type_name.go
│ │ └── type_name_test.go
│ ├── gmap/
│ │ ├── gmap.go
│ │ └── gmap_test.go
│ ├── gslice/
│ │ ├── gslice.go
│ │ └── gslice_test.go
│ ├── merge.go
│ ├── mock/
│ │ ├── adk/
│ │ │ └── Agent_mock.go
│ │ ├── components/
│ │ │ ├── document/
│ │ │ │ └── document_mock.go
│ │ │ ├── embedding/
│ │ │ │ └── Embedding_mock.go
│ │ │ ├── indexer/
│ │ │ │ └── indexer_mock.go
│ │ │ ├── model/
│ │ │ │ └── ChatModel_mock.go
│ │ │ └── retriever/
│ │ │ └── retriever_mock.go
│ │ └── doc.go
│ ├── safe/
│ │ ├── panic.go
│ │ └── panic_test.go
│ └── serialization/
│ ├── serialization.go
│ └── serialization_test.go
├── llms.txt
├── schema/
│ ├── doc.go
│ ├── document.go
│ ├── document_test.go
│ ├── message.go
│ ├── message_parser.go
│ ├── message_parser_test.go
│ ├── message_test.go
│ ├── select.go
│ ├── serialization.go
│ ├── serialization_test.go
│ ├── stream.go
│ ├── stream_copy_external_test.go
│ ├── stream_test.go
│ ├── tool.go
│ └── tool_test.go
├── scripts/
│ ├── dev_setup.sh
│ └── eino_setup.sh
└── utils/
└── callbacks/
├── template.go
└── template_test.go
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/.codedev.yml
================================================
coverage:
status:
project: #add everything under here, more options at https://docs.codecov.com/docs/commit-status
default: # default is the status check's name, not default settings
target: auto #default
threshold: 1% #allow coverage to drop by 1%
base: auto
if_ci_failed: error #success, failure, error, ignore
patch:
default:
target: 82% #default
threshold: 1% #allow coverage to drop by 1%
base: auto
if_ci_failed: error #success, failure, error, ignore
comment: #this is a top-level key
layout: " diff, flags, files"
behavior: default
require_changes: false # if true: only post the comment if coverage changes
require_base: false # [true :: must have a base report to post]
require_head: true # [true :: must have a head report to post]
hide_project_coverage: false # [true :: only show coverage on the git diff aka patch coverage]
# sample regex patterns
ignore:
- "tests"
- "examples/"
- "mock/"
- "callbacks/interface.go"
- "utils/safe"
- "components/tool/utils/create_options.go"
================================================
FILE: .github/.commit-rules.json
================================================
{
"allowedTypes": [
"feat",
"fix",
"docs",
"style",
"refactor",
"perf",
"test",
"build",
"ci",
"chore",
"revert"
],
"allowedScopes": [
"adk",
"adk/filesystem",
"callbacks",
"components",
"compose",
"deep",
"dynamictool",
"filesystem",
"flow",
"internal",
"middlewares",
"planexecute",
"plantask",
"prebuilt",
"reduction",
"schema",
"skill",
"summarization",
"supervisor",
"toolsearch",
"utils",
"docs",
"ci",
"serialization"
]
}
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Version:**
Please provide the version of {project_name} you are using.
**Environment:**
The output of `go env`.
**Additional context**
Add any other context about the problem here.
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
#### What type of PR is this?
<!--
Add one of the following kinds:
build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
docs: Documentation only changes
feat: A new feature
optimize: A new optimization
fix: A bug fix
perf: A code change that improves performance
refactor: A code change that neither fixes a bug nor adds a feature
style: Changes that do not affect the meaning of the code (white space, formatting, missing semi-colons, etc)
test: Adding missing tests or correcting existing tests
chore: Changes to the build process or auxiliary tools and libraries such as documentation generation
-->
#### Check the PR title.
<!--
The description of the title will be attached in Release Notes,
so please describe it from user-oriented, what this PR does / why we need it.
Please check your PR title with the below requirements:
-->
- [ ] This PR title match the format: \<type\>(optional scope): \<description\>
- [ ] The description of this PR title is user-oriented and clear enough for others to understand.
- [ ] Attach the PR updating the user documentation if the current PR requires user awareness at the usage level. [User docs repo](https://github.com/cloudwego/cloudwego.github.io)
#### (Optional) Translate the PR title into Chinese.
#### (Optional) More detailed description for this PR(en: English/zh: Chinese).
<!--
Provide more detailed info for review(e.g., it's recommended to provide perf data if this is a perf type PR).
-->
en:
zh(optional):
#### (Optional) Which issue(s) this PR fixes:
<!--
Automatically closes linked issue when PR is merged.
Eg: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
-->
#### (optional) The PR that updates user documentation:
<!--
If the current PR requires user awareness at the usage level, please submit a PR to update user docs. [User docs repo](https://github.com/cloudwego/cloudwego.github.io)
-->
================================================
FILE: .github/workflows/pr-check.yml
================================================
name: Pull Request Check
on: [ pull_request ]
jobs:
compliant:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check License Header
uses: apache/skywalking-eyes/header@v0.4.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check Spell
uses: crate-ci/typos@v1.42.3
golangci-lint:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
repository-projects: write
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 1.18
# for self-hosted, the cache path is shared across projects,
# and it works well without the cache of GitHub actions
# Enable it if we're going to use GitHub only
cache: true
- name: Golang CI Lint
# https://golangci-lint.run/
uses: golangci/golangci-lint-action@v9.2.0
with:
version: v2.8.0
args: --timeout 5m
commit-msg-check:
name: Commit Message Check
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
steps:
- uses: actions/checkout@v4
- name: Validate commit messages format and scope
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const fs = require('fs');
const pr = context.payload.pull_request;
if (!pr) {
core.setFailed('This workflow must run on pull_request events.');
return;
}
let allowedTypes = [];
let allowedScopes = [];
try {
const raw = fs.readFileSync('.github/.commit-rules.json', 'utf8');
const cfg = JSON.parse(raw);
allowedTypes = Array.isArray(cfg.allowedTypes) ? cfg.allowedTypes : [];
allowedScopes = Array.isArray(cfg.allowedScopes) ? cfg.allowedScopes : [];
} catch (e) {
core.setFailed('Cannot read .github/.commit-rules.json: ' + e.message);
return;
}
if (!allowedTypes.length) {
core.setFailed('allowedTypes is empty in .github/.commit-rules.json');
return;
}
const { owner, repo } = context.repo;
const pull_number = pr.number;
const commits = await github.paginate(
github.rest.pulls.listCommits,
{ owner, repo, pull_number, per_page: 100 }
);
let errors = [];
for (const c of commits) {
const sha = c.sha.slice(0, 7);
const subject = (c.commit.message || '').split('\n')[0];
const m = subject.match(/^([a-z]+)(\(([a-z0-9\-\/]+)\))?:\s(.+)$/);
if (!m) {
errors.push(`(${sha}) invalid format: "${subject}"`);
continue;
}
const type = m[1];
const scope = m[3]; // may be undefined
const desc = m[4];
if (!allowedTypes.includes(type)) {
errors.push(`(${sha}) invalid type "${type}"`);
}
if (!desc || !desc.trim()) {
errors.push(`(${sha}) description must be non-empty`);
}
if (scope) {
const topScope = scope.split('/')[0];
if (allowedScopes.length && !allowedScopes.includes(topScope)) {
errors.push(`(${sha}) invalid scope "${scope}"`);
}
}
}
if (errors.length) {
core.setFailed('Commit message check failed:\n' + errors.join('\n'));
} else {
core.info('All commit messages conform to "<type>(optional scope): <description>" and scope rules.');
}
pr-title-check:
name: PR Title Check
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
steps:
- uses: actions/checkout@v4
- name: Read commit rules
id: rules
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const fs = require('fs');
let cfg;
try {
const raw = fs.readFileSync('.github/.commit-rules.json', 'utf8');
cfg = JSON.parse(raw);
} catch (e) {
core.setFailed('Cannot read .github/.commit-rules.json: ' + e.message);
return;
}
const toMultiline = (list) => Array.isArray(list) ? list.join('\n') : '';
core.setOutput('types', toMultiline(cfg.allowedTypes));
core.setOutput('scopes', toMultiline(cfg.allowedScopes));
- name: Validate PR title
uses: amannn/action-semantic-pull-request@v6.1.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
types: ${{ steps.rules.outputs.types }}
scopes: ${{ steps.rules.outputs.scopes }}
requireScope: false
================================================
FILE: .github/workflows/tag-notification.yml
================================================
name: Tag Notification
on:
push:
tags:
- 'v*'
jobs:
notify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
- name: Fetch tag info
run: |
git fetch --tags -f
- name: Get tag info and send notification
run: |
# Get the tag name
TAG_NAME="${{ github.ref_name }}"
echo "Processing tag: $TAG_NAME"
# Get tag message
echo "Getting tag message..."
TAG_MESSAGE=$(git tag -l --format='%(contents)' "$TAG_NAME")
echo "Tag message:"
echo "$TAG_MESSAGE"
echo "---"
# Create base content parts
HEADER="### 🏷️ Eino New Tag Created: \`$TAG_NAME\`"
VERSION_INFO="📦 Version: \`$TAG_NAME\`"
# Prepare the message parts for jq
if [ ! -z "$TAG_MESSAGE" ]; then
# Pass all parts to jq and let it handle the formatting
jq -n \
--arg header "$HEADER" \
--arg version "$VERSION_INFO" \
--arg notes "$TAG_MESSAGE" \
--arg repo_url "https://github.com/${{ github.repository }}/releases/tag/$TAG_NAME" \
'{
"msg_type": "interactive",
"card": {
"elements": [
{
"tag": "markdown",
"content": ($header + "\n\n" + $version + "\n\n### 📝 Release Notes:\n" + $notes)
},
{
"tag": "action",
"actions": [
{
"tag": "button",
"text": {
"tag": "plain_text",
"content": "🔗 View Tag"
},
"url": $repo_url,
"type": "default"
}
]
}
],
"header": {
"title": {
"tag": "plain_text",
"content": "🏷️ Eino New Tag Created"
}
}
}
}' > webhook_payload.json
else
# Without release notes
jq -n \
--arg header "$HEADER" \
--arg version "$VERSION_INFO" \
--arg repo_url "https://github.com/${{ github.repository }}/releases/tag/$TAG_NAME" \
'{
"msg_type": "interactive",
"card": {
"elements": [
{
"tag": "markdown",
"content": ($header + "\n\n" + $version)
},
{
"tag": "action",
"actions": [
{
"tag": "button",
"text": {
"tag": "plain_text",
"content": "🔗 View Tag"
},
"url": $repo_url,
"type": "default"
}
]
}
],
"header": {
"title": {
"tag": "plain_text",
"content": "🏷️ Eino New Tag Created"
}
}
}
}' > webhook_payload.json
fi
# Send webhook
curl -X POST \
-H "Content-Type: application/json" \
-d @webhook_payload.json \
"${{ secrets.FEISHU_WEBHOOK_URL }}"
================================================
FILE: .github/workflows/tests.yml
================================================
name: Eino Tests
on:
pull_request:
push:
branches:
- main
env:
DEFAULT_GO_VERSION: "1.18"
jobs:
unit-test:
name: eino-unit-test
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
repository-projects: write
env:
COVERAGE_FILE: coverage.out
BREAKDOWN_FILE: main.breakdown
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.DEFAULT_GO_VERSION }}
- name: Exec Go Test
run: |
modules=`find . -name "go.mod" -exec dirname {} \;`
echo $modules
list=""
coverpkg=""
if [[ ! -f "go.work" ]];then go work init;fi
for module in $modules; do go work use $module; list=$module"/... "$list; coverpkg=$module"/...,"$coverpkg; done
go work sync
go test -race -v -coverprofile=${{ env.COVERAGE_FILE }} -gcflags="all=-l -N" -coverpkg=$coverpkg $list
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
name: eino-unit-test
env_vars: GOLANG,EINO
files: ${{ env.COVERAGE_FILE }}
token: ${{ secrets.CODECOV_TOKEN }}
codecov_yml_path: ./github/.codecov.yml
benchmark-test:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
repository-projects: write
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.DEFAULT_GO_VERSION }}
- name: Run Benchmark Tests
run: go test -bench=. -benchmem -run=none ./...
compatibility-test:
strategy:
matrix:
go: [ "1.19", "1.20", "1.21", "1.22", "1.23", "1.24" ]
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
repository-projects: write
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go }}
cache: true
- name: Compatibility Test
run: |
# just basic unit test, no coverage report
go test -race ./...
api-compatibility:
name: api-compatibility-check
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
repository-projects: write
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.22"
- name: Install go-apidiff
run: go install github.com/joelanford/go-apidiff@v0.8.2
- name: Check API compatibility
id: apidiff
run: |
BASE_SHA=${{ github.event.pull_request.base.sha }}
HEAD_SHA=${{ github.event.pull_request.head.sha }}
echo "Checking API compatibility between $BASE_SHA and $HEAD_SHA"
go mod tidy
if ! DIFF_OUTPUT=$(go-apidiff $BASE_SHA $HEAD_SHA 2>&1); then
echo "go-apidiff output: $DIFF_OUTPUT"
fi
echo "diff_output<<EOF" >> $GITHUB_ENV
echo "$DIFF_OUTPUT" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
if echo "$DIFF_OUTPUT" | grep -q "Incompatible changes:"; then
echo "has_breaking_changes=true" >> $GITHUB_OUTPUT
else
echo "has_breaking_changes=false" >> $GITHUB_OUTPUT
fi
- name: Create Review Thread
if: steps.apidiff.outputs.has_breaking_changes == 'true'
continue-on-error: true
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const reviewComments = await github.rest.pulls.listReviewComments({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number
});
const existingPackageComments = new Map();
for (const comment of reviewComments.data) {
if (comment.body.includes('Breaking API Changes Detected')) {
const packageMatch = comment.body.match(/Package: `([^`]+)`/);
if (packageMatch) {
const pkg = packageMatch[1];
if (!existingPackageComments.has(pkg)) {
existingPackageComments.set(pkg, new Set());
}
existingPackageComments.get(pkg).add(comment.path);
}
}
}
const files = await github.rest.pulls.listFiles({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number
});
const diffOutput = process.env.diff_output || '';
const breakingChanges = new Map();
let currentPackage = '';
let isInIncompatibleSection = false;
const lines = diffOutput.split('\n');
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
if (line.startsWith('github.com/')) {
currentPackage = line;
if (!breakingChanges.has(currentPackage)) {
breakingChanges.set(currentPackage, []);
}
continue;
}
if (line === 'Incompatible changes:') {
isInIncompatibleSection = true;
continue;
}
if (line === '') {
isInIncompatibleSection = false;
continue;
}
if (isInIncompatibleSection && line.startsWith('- ')) {
const change = line.substring(2);
if (currentPackage) {
breakingChanges.get(currentPackage).push(change);
}
}
}
const changedFiles = files.data;
for (const [pkg, changes] of breakingChanges) {
if (changes.length === 0) continue;
const pkgPath = pkg.split('/').slice(3).join('/');
const matchingFile = changedFiles.find(file =>
file.filename.includes(pkgPath)
) || changedFiles[0];
const hasCommentForPackage = existingPackageComments.has(pkg) &&
existingPackageComments.get(pkg).has(matchingFile.filename);
if (matchingFile && !hasCommentForPackage) {
const changesList = changes.map(change => {
const [name, desc] = change.split(':').map(s => s.trim());
return `- **${name}:** ${desc}`;
}).join('\n');
const commentBody = [
'🚨 **Breaking API Changes Detected**',
'',
`Package: \`${pkg}\``,
'',
'Incompatible changes:',
changesList,
'',
'<details>',
'<summary>Review Guidelines</summary>',
'',
'Please ensure that:',
'- The changes are absolutely necessary',
'- They are properly documented',
'- Migration guides are provided if needed',
'</details>',
'',
'⚠️ Please resolve this thread after reviewing the breaking changes.'
].join('\n');
await github.rest.pulls.createReview({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number,
event: 'COMMENT',
comments: [{
path: matchingFile.filename,
position: matchingFile.patch ? matchingFile.patch.split('\n').findIndex(line => line.startsWith('+')) + 1 : 1,
body: commentBody
}]
});
if (!existingPackageComments.has(pkg)) {
existingPackageComments.set(pkg, new Set());
}
existingPackageComments.get(pkg).add(matchingFile.filename);
}
}
================================================
FILE: .gitignore
================================================
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/
# Go workspace file
go.work
go.work.sum
# env file
.env
# the result of the go build
output*
output/*
# Files generated by IDEs
.idea/
*.iml
# Vim swap files
*.swp
# Vscode files
.vscode
/patches
/vendor
# Trae files
.trae
# Specs files (internal documentation)
**/specs/
# Reports (generated analysis files)
reports/
.DS_Store
*.log
CLAUDE.md
# Specs directories
*/specs
/todos
/.claude/
# Internal dev setup (not for public repo)
/scripts/dev_setup_internal.sh
================================================
FILE: .golangci.yaml
================================================
# output configuration options
version: "2"
# All available settings of specific linters.
# Refer to https://golangci-lint.run/usage/linters
linters:
default: standard
enable:
- revive
- godoclint
- funlen
- cyclop
disable:
- errcheck
- staticcheck
- unused
- ineffassign
exclusions:
generated: lax
paths:
- ".*_test.go"
- ".*_mock.go"
rules:
- path: "^internal/.*"
linters:
- revive
- text: "var-naming: don't use underscores in Go names"
linters:
- revive
- path: "/utils/"
text: "var-naming: avoid meaningless package names"
linters:
- revive
- text: "exported: type name will be used as agent.AgentOption by other packages"
linters:
- revive
- path: "adk/prebuilt/deep/task_tool.go"
text: "argument-limit: maximum number of arguments per function exceeded"
linters:
- revive
- path: "compose/component_to_graph_node.go"
text: "argument-limit: maximum number of arguments per function exceeded"
linters:
- revive
- path: "compose/graph_run.go"
text: "argument-limit: maximum number of arguments per function exceeded"
linters:
- revive
- path: "adk/workflow.go"
text: "argument-limit: maximum number of arguments per function exceeded"
linters:
- revive
- path: "compose/graph.go"
linters:
- cyclop
text: "calculated cyclomatic complexity for function compile"
- path: "schema/message.go"
linters:
- cyclop
text: "calculated cyclomatic complexity for function ConcatMessages"
- path: "compose/graph_run.go"
linters:
- cyclop
text: "calculated cyclomatic complexity for function run"
- path: "compose/graph.go"
linters:
- funlen
text: "Function 'compile' is too long"
- path: "compose/graph_run.go"
linters:
- funlen
text: "Function 'run' is too long"
settings:
govet:
enable-all: true
# Disable analyzers by name.
# Run `go tool vet help` to see all analyzers.
disable:
- fieldalignment
revive:
# Sets the default failure confidence.
# This means that linting errors with less than 0.8 confidence will be ignored.
# Default: 0.8
confidence: 0.8
rules:
# Exported function and methods should have comments.
- name: exported
severity: error
exclude:
- "^internal/.*"
arguments:
- "disable-checks-on-constants"
- "disable-checks-on-variables"
- "disable-checks-on-types"
- "disable-checks-on-methods"
- name: package-comments
disabled: false
- name: var-naming
disabled: false
arguments:
# AllowList
- [ "utils", "s_", "err_", "err__", "plan_", "userInput_", "executedSteps_", "executedStep_", "iterator_", "in_", "out_" ]
# DenyList
- [ ]
- - extra-bad-package-names:
- helpers
- models
- name: argument-limit
arguments: [ 6 ]
- name: function-length
arguments: [ 120, 0 ]
godoclint:
check-exported: true
require-package-documentation: true
funlen:
lines: 200
statements: 120
cyclop:
max-complexity: 40
package-average: 20
formatters:
enable:
- gci
- gofmt
settings:
gofmt:
# Simplify code: gofmt with `-s` option.
# Default: true
simplify: true
# Apply the rewrite rules to the source before reformatting.
# https://pkg.go.dev/cmd/gofmt
# Default: []
rewrite-rules:
- pattern: 'interface{}'
replacement: 'any'
- pattern: 'a[b:len(a)]'
replacement: 'a[b:]'
gci:
# Section configuration to compare against.
# Section names are case-insensitive and may contain parameters in ().
# The default order of sections is `standard > default > custom > blank > dot > alias > localmodule`.
# If `custom-order` is `true`, it follows the order of `sections` option.
# Default: ["standard", "default"]
sections:
- standard
- default
- localmodule
custom-order: true
================================================
FILE: .licenserc.yaml
================================================
header:
license:
spdx-id: Apache-2.0
copyright-owner: CloudWeGo Authors
template: |
/*
* Copyright {{ .Year }} CloudWeGo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
paths:
- '**/*.go'
- '**/*.s'
comment: on-failure
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
conduct@cloudwego.io.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
================================================
FILE: CONTRIBUTING.md
================================================
# How to Contribute
## Your First Pull Request
We use GitHub for our codebase. You can start by reading [How To Pull Request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests).
## Branch Organization
We use [git-flow](https://nvie.com/posts/a-successful-git-branching-model/) as our branch organization, as known as [FDD](https://en.wikipedia.org/wiki/Feature-driven_development)
## Bugs
### 1. How to Find Known Issues
We are using [Github Issues](https://github.com/cloudwego/{project_name}/issues) for our public bugs. We keep a close eye on this and try to make it clear when we have an internal fix in progress. Before filing a new task, try to make sure your problem doesn’t already exist.
### 2. Reporting New Issues
Providing a reduced test code is a recommended way for reporting issues. Then can place in:
- Just in issues
- [Golang Playground](https://play.golang.org/)
### 3. Security Bugs
Please do not report the safe disclosure of bugs to public issues. Contact us by [Support Email](mailto:conduct@cloudwego.io)
## How to Get in Touch
- [Email](mailto:conduct@cloudwego.io)
## Submit a Pull Request
Before you submit your Pull Request (PR) consider the following guidelines:
1. Search [GitHub](https://github.com/cloudwego/{project_name}/pulls) for an open or closed PR that relates to your submission. You don't want to duplicate existing efforts.
2. Be sure that an issue describes the problem you're fixing, or documents the design for the feature you'd like to add. Discussing the design upfront helps to ensure that we're ready to accept your work.
3. [Fork](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo) the cloudwego {project_name} repo.
4. In your forked repository, make your changes in a new git branch:
```
git checkout -b my-fix-branch develop
```
5. Create your patch, including appropriate test cases.
6. Follow our [Style Guides](#code-style-guides).
7. Commit your changes using a descriptive commit message that follows [AngularJS Git Commit Message Conventions](https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit).
Adherence to these conventions is necessary because release notes are automatically generated from these messages.
8. Push your branch to GitHub:
```
git push origin my-fix-branch
```
9. In GitHub, send a pull request to `{project_name}:develop`
## Contribution Prerequisites
- Our development environment keeps up with [Go Official](https://golang.org/project/).
- You need fully checking with lint tools before submit your pull request. [gofmt](https://golang.org/pkg/cmd/gofmt/) and [golangci-lint](https://github.com/golangci/golangci-lint)
- You are familiar with [GitHub](https://github.com)
- Maybe you need familiar with [Actions](https://github.com/features/actions)(our default workflow tool).
## Code Style Guides
- [Effective Go](https://golang.org/doc/effective_go)
- [Go Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments)
================================================
FILE: LICENSE-APACHE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
================================================
FILE: README.md
================================================
# Eino

[](https://github.com/cloudwego/eino/releases)
[](https://www.cloudwego.io/)
[](https://github.com/cloudwego/eino/blob/main/LICENSE)
[](https://goreportcard.com/report/github.com/cloudwego/eino)
[](https://github.com/cloudwego/kitex/eino)
[](https://github.com/cloudwego/eino/issues?q=is%3Aissue+is%3Aclosed)


English | [中文](README.zh_CN.md)
# Overview
**Eino['aino]** is an LLM application development framework in Golang. It draws from LangChain, Google ADK, and other open-source frameworks, and is designed to follow Golang conventions.
Eino provides:
- **[Components](https://github.com/cloudwego/eino-ext)**: reusable building blocks like `ChatModel`, `Tool`, `Retriever`, and `ChatTemplate`, with official implementations for OpenAI, Ollama, and more.
- **Agent Development Kit (ADK)**: build AI agents with tool use, multi-agent coordination, context management, interrupt/resume for human-in-the-loop, and ready-to-use agent patterns.
- **Composition**: connect components into graphs and workflows that can run standalone or be exposed as tools for agents.
- **[Examples](https://github.com/cloudwego/eino-examples)**: working code for common patterns and real-world use cases.

# Quick Start
## ChatModelAgent
Configure a ChatModel, optionally add tools, and you have a working agent:
```Go
chatModel, _ := openai.NewChatModel(ctx, &openai.ChatModelConfig{
Model: "gpt-4o",
APIKey: os.Getenv("OPENAI_API_KEY"),
})
agent, _ := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
Model: chatModel,
})
runner := adk.NewRunner(ctx, adk.RunnerConfig{Agent: agent})
iter := runner.Query(ctx, "Hello, who are you?")
for {
event, ok := iter.Next()
if !ok {
break
}
fmt.Println(event.Message.Content)
}
```
Add tools to give the agent capabilities:
```Go
agent, _ := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
Model: chatModel,
ToolsConfig: adk.ToolsConfig{
ToolsNodeConfig: compose.ToolsNodeConfig{
Tools: []tool.BaseTool{weatherTool, calculatorTool},
},
},
})
```
The agent handles the ReAct loop internally — it decides when to call tools and when to respond.
→ [ChatModelAgent examples](https://github.com/cloudwego/eino-examples/tree/main/adk/intro) · [docs](https://www.cloudwego.io/docs/eino/core_modules/eino_adk/agent_implementation/chat_model/)
## DeepAgent
For complex tasks, use DeepAgent. It breaks down problems into steps, delegates to sub-agents, and tracks progress:
```Go
deepAgent, _ := deep.New(ctx, &deep.Config{
ChatModel: chatModel,
SubAgents: []adk.Agent{researchAgent, codeAgent},
ToolsConfig: adk.ToolsConfig{
ToolsNodeConfig: compose.ToolsNodeConfig{
Tools: []tool.BaseTool{shellTool, pythonTool, webSearchTool},
},
},
})
runner := adk.NewRunner(ctx, adk.RunnerConfig{Agent: deepAgent})
iter := runner.Query(ctx, "Analyze the sales data in report.csv and generate a summary chart")
```
DeepAgent can be configured to coordinate multiple specialized agents, run shell commands, execute Python code, and search the web.
→ [DeepAgent example](https://github.com/cloudwego/eino-examples/tree/main/adk/multiagent/deep) · [docs](https://www.cloudwego.io/docs/eino/core_modules/eino_adk/agent_implementation/deepagents/)
## Composition
When you need precise control over execution flow, use `compose` to build graphs and workflows:
```Go
graph := compose.NewGraph[*Input, *Output]()
graph.AddLambdaNode("validate", validateFn)
graph.AddChatModelNode("generate", chatModel)
graph.AddLambdaNode("format", formatFn)
graph.AddEdge(compose.START, "validate")
graph.AddEdge("validate", "generate")
graph.AddEdge("generate", "format")
graph.AddEdge("format", compose.END)
runnable, _ := graph.Compile(ctx)
result, _ := runnable.Invoke(ctx, input)
```
Compositions can be exposed as tools for agents, bridging deterministic workflows with autonomous behavior:
```Go
tool, _ := graphtool.NewInvokableGraphTool(graph, "data_pipeline", "Process and validate data")
agent, _ := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
Model: chatModel,
ToolsConfig: adk.ToolsConfig{
ToolsNodeConfig: compose.ToolsNodeConfig{
Tools: []tool.BaseTool{tool},
},
},
})
```
This lets you build domain-specific pipelines with exact control, then let agents decide when to use them.
→ [GraphTool examples](https://github.com/cloudwego/eino-examples/tree/main/adk/common/tool/graphtool) · [compose docs](https://www.cloudwego.io/docs/eino/core_modules/chain_and_graph_orchestration/)
# Key Features
## Component Ecosystem
Eino defines component abstractions (ChatModel, Tool, Retriever, Embedding, etc.) with official implementations for OpenAI, Claude, Gemini, Ark, Ollama, Elasticsearch, and more.
→ [eino-ext](https://github.com/cloudwego/eino-ext)
## Stream Processing
Eino automatically handles streaming throughout orchestration: concatenating, boxing, merging, and copying streams as data flows between nodes. Components only implement the streaming paradigms that make sense for them; the framework handles the rest.
→ [docs](https://www.cloudwego.io/docs/eino/core_modules/chain_and_graph_orchestration/stream_programming_essentials/)
## Callback Aspects
Inject logging, tracing, and metrics at fixed points (OnStart, OnEnd, OnError, OnStartWithStreamInput, OnEndWithStreamOutput) across components, graphs, and agents.
→ [docs](https://www.cloudwego.io/docs/eino/core_modules/chain_and_graph_orchestration/callback_manual/)
## Interrupt/Resume
Any agent or tool can pause execution for human input and resume from checkpoint. The framework handles state persistence and routing.
→ [docs](https://www.cloudwego.io/docs/eino/core_modules/eino_adk/agent_hitl/) · [examples](https://github.com/cloudwego/eino-examples/tree/main/adk/human-in-the-loop)
# Framework Structure

The Eino framework consists of:
- Eino (this repo): Type definitions, streaming mechanism, component abstractions, orchestration, agent implementations, aspect mechanisms
- [EinoExt](https://github.com/cloudwego/eino-ext): Component implementations, callback handlers, usage examples, evaluators, prompt optimizers
- [Eino Devops](https://github.com/cloudwego/eino-ext/tree/main/devops): Visualized development and debugging
- [EinoExamples](https://github.com/cloudwego/eino-examples): Example applications and best practices
## Documentation
- [Eino User Manual](https://www.cloudwego.io/zh/docs/eino/)
- [Eino: Quick Start](https://www.cloudwego.io/zh/docs/eino/quick_start/)
## Dependencies
- Go 1.18 and above.
## Code Style
This repo uses `golangci-lint`. Check locally with:
```bash
golangci-lint run ./...
```
Rules enforced:
- Exported functions, interfaces, packages, etc. should have GoDoc comments
- Code should be formatted with `gofmt -s`
- Import order should follow `goimports` (std -> third party -> local)
## Security
If you discover a potential security issue, notify Bytedance Security via the [security center](https://security.bytedance.com/src) or [vulnerability reporting email](sec@bytedance.com).
Do **not** create a public GitHub issue.
## Contact
- Membership: [COMMUNITY MEMBERSHIP](https://github.com/cloudwego/community/blob/main/COMMUNITY_MEMBERSHIP.md)
- Issues: [Issues](https://github.com/cloudwego/eino/issues)
- Lark: Scan the QR code below with [Feishu](https://www.feishu.cn/en/) to join the CloudWeGo/eino user group.
    <img src=".github/static/img/eino/lark_group_zh.png" alt="LarkGroup" width="200"/>
## License
This project is licensed under the [Apache-2.0 License](LICENSE-APACHE).
================================================
FILE: README.zh_CN.md
================================================
# Eino

[](https://github.com/cloudwego/eino/releases)
[](https://www.cloudwego.io/)
[](https://github.com/cloudwego/eino/blob/main/LICENSE)
[](https://goreportcard.com/report/github.com/cloudwego/eino)
[](https://github.com/cloudwego/kitex/eino)
[](https://github.com/cloudwego/eino/issues?q=is%3Aissue+is%3Aclosed)


[English](README.md) | 中文
# 简介
**Eino['aino]** 是一个 Go 语言的 LLM 应用开发框架,借鉴了 LangChain、Google ADK 等开源项目,按照 Go 的惯例设计。
Eino 提供:
- **[组件](https://github.com/cloudwego/eino-ext)**:`ChatModel`、`Tool`、`Retriever`、`ChatTemplate` 等可复用模块,官方实现覆盖 OpenAI、Ollama 等
- **智能体开发套件(ADK)**:支持工具调用、多智能体协同、上下文管理、中断/恢复等人机交互,以及开箱即用的智能体模式
- **编排**:把组件组装成图或工作流,既能独立运行,也能作为工具给智能体调用
- **[示例](https://github.com/cloudwego/eino-examples)**:常见模式和实际场景的可运行代码

# 快速上手
## ChatModelAgent
配置好 ChatModel,加上工具(可选),就能跑起来:
```Go
chatModel, _ := openai.NewChatModel(ctx, &openai.ChatModelConfig{
Model: "gpt-4o",
APIKey: os.Getenv("OPENAI_API_KEY"),
})
agent, _ := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
Model: chatModel,
})
runner := adk.NewRunner(ctx, adk.RunnerConfig{Agent: agent})
iter := runner.Query(ctx, "Hello, who are you?")
for {
event, ok := iter.Next()
if !ok {
break
}
fmt.Println(event.Message.Content)
}
```
加工具让智能体有更多能力:
```Go
agent, _ := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
Model: chatModel,
ToolsConfig: adk.ToolsConfig{
ToolsNodeConfig: compose.ToolsNodeConfig{
Tools: []tool.BaseTool{weatherTool, calculatorTool},
},
},
})
```
智能体内部自动处理 ReAct 循环,自己判断什么时候调工具、什么时候回复。
→ [ChatModelAgent 示例](https://github.com/cloudwego/eino-examples/tree/main/adk/intro) · [文档](https://www.cloudwego.io/zh/docs/eino/core_modules/eino_adk/agent_implementation/chat_model/)
## DeepAgent
复杂任务用 DeepAgent,它会把问题拆成步骤,分派给子智能体,并追踪进度:
```Go
deepAgent, _ := deep.New(ctx, &deep.Config{
ChatModel: chatModel,
SubAgents: []adk.Agent{researchAgent, codeAgent},
ToolsConfig: adk.ToolsConfig{
ToolsNodeConfig: compose.ToolsNodeConfig{
Tools: []tool.BaseTool{shellTool, pythonTool, webSearchTool},
},
},
})
runner := adk.NewRunner(ctx, adk.RunnerConfig{Agent: deepAgent})
iter := runner.Query(ctx, "Analyze the sales data in report.csv and generate a summary chart")
```
DeepAgent 可以配置成:协调多个专业智能体、跑 shell 命令、执行 Python、搜索网络。
→ [DeepAgent 示例](https://github.com/cloudwego/eino-examples/tree/main/adk/multiagent/deep) · [文档](https://www.cloudwego.io/zh/docs/eino/core_modules/eino_adk/agent_implementation/deepagents/)
## 编排
需要精确控制执行流程时,用 `compose` 搭图或工作流:
```Go
graph := compose.NewGraph[*Input, *Output]()
graph.AddLambdaNode("validate", validateFn)
graph.AddChatModelNode("generate", chatModel)
graph.AddLambdaNode("format", formatFn)
graph.AddEdge(compose.START, "validate")
graph.AddEdge("validate", "generate")
graph.AddEdge("generate", "format")
graph.AddEdge("format", compose.END)
runnable, _ := graph.Compile(ctx)
result, _ := runnable.Invoke(ctx, input)
```
编排出来的流程可以包装成工具给智能体用,把确定性流程和自主决策结合起来:
```Go
tool, _ := graphtool.NewInvokableGraphTool(graph, "data_pipeline", "Process and validate data")
agent, _ := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
Model: chatModel,
ToolsConfig: adk.ToolsConfig{
ToolsNodeConfig: compose.ToolsNodeConfig{
Tools: []tool.BaseTool{tool},
},
},
})
```
这样你可以写出精确可控的业务流程,再让智能体决定什么时候调用。
→ [GraphTool 示例](https://github.com/cloudwego/eino-examples/tree/main/adk/common/tool/graphtool) · [编排文档](https://www.cloudwego.io/zh/docs/eino/core_modules/chain_and_graph_orchestration/)
# 主要特性
## 组件生态
Eino 定义了组件抽象(ChatModel、Tool、Retriever、Embedding 等),官方实现覆盖 OpenAI、Claude、Gemini、Ark、Ollama、Elasticsearch 等。
→ [eino-ext](https://github.com/cloudwego/eino-ext)
## 流式处理
Eino 在编排中自动处理流式:拼接、装箱、合并、复制。组件只需实现有业务意义的流式范式,框架处理剩下的。
→ [文档](https://www.cloudwego.io/zh/docs/eino/core_modules/chain_and_graph_orchestration/stream_programming_essentials/)
## 回调切面
在固定切点(OnStart、OnEnd、OnError、OnStartWithStreamInput、OnEndWithStreamOutput)注入日志、追踪、指标,适用于组件、图、智能体。
→ [文档](https://www.cloudwego.io/zh/docs/eino/core_modules/chain_and_graph_orchestration/callback_manual/)
## 中断/恢复
任何智能体或工具都能暂停等待人工输入,从检查点恢复。框架处理状态持久化和路由。
→ [文档](https://www.cloudwego.io/zh/docs/eino/core_modules/eino_adk/agent_hitl/) · [示例](https://github.com/cloudwego/eino-examples/tree/main/adk/human-in-the-loop)
# 框架结构

Eino 框架包含:
- Eino(本仓库):类型定义、流处理机制、组件抽象、编排、智能体实现、切面机制
- [EinoExt](https://github.com/cloudwego/eino-ext):组件实现、回调处理器、使用示例、评估器、提示优化器
- [Eino Devops](https://github.com/cloudwego/eino-ext/tree/main/devops):可视化开发和调试
- [EinoExamples](https://github.com/cloudwego/eino-examples):示例应用和最佳实践
## 文档
- [Eino 用户手册](https://www.cloudwego.io/zh/docs/eino/)
- [Eino: 快速开始](https://www.cloudwego.io/zh/docs/eino/quick_start/)
## 依赖
- Go 1.18 及以上
## 代码规范
本仓库使用 `golangci-lint`,本地检查:
```bash
golangci-lint run ./...
```
规则:
- 导出的函数、接口、package 等需要 GoDoc 注释
- 代码格式符合 `gofmt -s`
- import 顺序符合 `goimports`(std -> third party -> local)
## 安全
发现安全问题请通过[安全中心](https://security.bytedance.com/src)或[漏洞报告邮箱](sec@bytedance.com)联系字节跳动安全团队。
请**不要**创建公开的 GitHub Issue。
## 联系我们
- 成为 member:[COMMUNITY MEMBERSHIP](https://github.com/cloudwego/community/blob/main/COMMUNITY_MEMBERSHIP.md)
- Issues:[Issues](https://github.com/cloudwego/eino/issues)
- 飞书:扫码加入 CloudWeGo/eino 用户群
    <img src=".github/static/img/eino/lark_group_zh.png" alt="LarkGroup" width="200"/>
## 开源许可证
本项目基于 [Apache-2.0 许可证](LICENSE-APACHE) 开源。
================================================
FILE: _typos.toml
================================================
# Typo check: https://github.com/crate-ci/typos
[default]
[default.extend-words]
Invokable = "Invokable"
invokable = "invokable"
InvokableLambda = "InvokableLambda"
InvokableRun = "InvokableRun"
typ = "typ"
byted = "byted"
cpy = "cpy"
mak = "mak"
[files]
extend-exclude = ["go.mod", "go.sum", "check_branch_name.sh"]
================================================
FILE: adk/agent_tool.go
================================================
/*
* Copyright 2025 CloudWeGo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Package adk provides core agent development kit utilities and types.
package adk
import (
"context"
"errors"
"fmt"
"github.com/bytedance/sonic"
"github.com/cloudwego/eino/components/tool"
"github.com/cloudwego/eino/compose"
"github.com/cloudwego/eino/schema"
)
var (
defaultAgentToolParam = schema.NewParamsOneOfByParams(map[string]*schema.ParameterInfo{
"request": {
Desc: "request to be processed",
Required: true,
Type: schema.String,
},
})
)
type AgentToolOptions struct {
fullChatHistoryAsInput bool
agentInputSchema *schema.ParamsOneOf
}
type AgentToolOption func(*AgentToolOptions)
// WithFullChatHistoryAsInput enables using the full chat history as input.
func WithFullChatHistoryAsInput() AgentToolOption {
return func(options *AgentToolOptions) {
options.fullChatHistoryAsInput = true
}
}
// WithAgentInputSchema sets a custom input schema for the agent tool.
func WithAgentInputSchema(schema *schema.ParamsOneOf) AgentToolOption {
return func(options *AgentToolOptions) {
options.agentInputSchema = schema
}
}
func withAgentToolEnableStreaming(enabled bool) tool.Option {
return tool.WrapImplSpecificOptFn(func(opt *agentToolOptions) {
opt.enableStreaming = enabled
})
}
// NewAgentTool creates a tool that wraps an agent for invocation.
//
// Event Streaming:
// When EmitInternalEvents is enabled in ToolsConfig, the agent tool will emit AgentEvent
// from the inner agent to the parent agent's AsyncGenerator, allowing real-time streaming
// of the inner agent's output to the end-user via Runner.
//
// Note that these forwarded events are NOT recorded in the parent agent's runSession.
// They are only emitted to the end-user and have no effect on the parent agent's state
// or checkpoint. The only exception is Interrupted action, which is propagated via
// CompositeInterrupt to enable proper interrupt/resume across agent boundaries.
//
// Action Scoping:
// Actions emitted by the inner agent are scoped to the agent tool boundary:
// - Interrupted: Propagated via CompositeInterrupt to allow proper interrupt/resume across boundaries
// - Exit, TransferToAgent, BreakLoop: Ignored outside the agent tool; these actions only affect
// the inner agent's execution and do not propagate to the parent agent
//
// This scoping ensures that nested agents cannot unexpectedly terminate or transfer control
// of their parent agent's execution flow.
func NewAgentTool(_ context.Context, agent Agent, options ...AgentToolOption) tool.BaseTool {
opts := &AgentToolOptions{}
for _, opt := range options {
opt(opts)
}
return &agentTool{
agent: agent,
fullChatHistoryAsInput: opts.fullChatHistoryAsInput,
inputSchema: opts.agentInputSchema,
}
}
type agentTool struct {
agent Agent
fullChatHistoryAsInput bool
inputSchema *schema.ParamsOneOf
}
func (at *agentTool) Info(ctx context.Context) (*schema.ToolInfo, error) {
param := at.inputSchema
if param == nil {
param = defaultAgentToolParam
}
return &schema.ToolInfo{
Name: at.agent.Name(ctx),
Desc: at.agent.Description(ctx),
ParamsOneOf: param,
}, nil
}
func (at *agentTool) InvokableRun(ctx context.Context, argumentsInJSON string, opts ...tool.Option) (string, error) {
gen, enableStreaming := getEmitGeneratorAndEnableStreaming(opts)
var ms *bridgeStore
var iter *AsyncIterator[*AgentEvent]
var err error
wasInterrupted, hasState, state := tool.GetInterruptState[[]byte](ctx)
if !wasInterrupted {
ms = newBridgeStore()
var input []Message
if at.fullChatHistoryAsInput {
input, err = getReactChatHistory(ctx, at.agent.Name(ctx))
if err != nil {
return "", err
}
} else {
if at.inputSchema == nil {
// default input schema
type request struct {
Request string `json:"request"`
}
req := &request{}
err = sonic.UnmarshalString(argumentsInJSON, req)
if err != nil {
return "", err
}
argumentsInJSON = req.Request
}
input = []Message{
schema.UserMessage(argumentsInJSON),
}
}
iter = newInvokableAgentToolRunner(at.agent, ms, enableStreaming).Run(ctx, input,
append(getOptionsByAgentName(at.agent.Name(ctx), opts), WithCheckPointID(bridgeCheckpointID), withSharedParentSession())...)
} else {
if !hasState {
return "", fmt.Errorf("agent tool '%s' interrupt has happened, but cannot find interrupt state", at.agent.Name(ctx))
}
ms = newResumeBridgeStore(state)
iter, err = newInvokableAgentToolRunner(at.agent, ms, enableStreaming).
Resume(ctx, bridgeCheckpointID, append(getOptionsByAgentName(at.agent.Name(ctx), opts), withSharedParentSession())...)
if err != nil {
return "", err
}
}
var lastEvent *AgentEvent
for {
event, ok := iter.Next()
if !ok {
break
}
if lastEvent != nil &&
lastEvent.Output != nil &&
lastEvent.Output.MessageOutput != nil &&
lastEvent.Output.MessageOutput.MessageStream != nil {
lastEvent.Output.MessageOutput.MessageStream.Close()
}
if event.Err != nil {
return "", event.Err
}
if gen != nil {
if event.Action == nil || event.Action.Interrupted == nil {
if parentRunCtx := getRunCtx(ctx); parentRunCtx != nil && len(parentRunCtx.RunPath) > 0 {
rp := make([]RunStep, 0, len(parentRunCtx.RunPath)+len(event.RunPath))
rp = append(rp, parentRunCtx.RunPath...)
rp = append(rp, event.RunPath...)
event.RunPath = rp
}
tmp := copyAgentEvent(event)
gen.Send(event)
event = tmp
}
}
lastEvent = event
}
if lastEvent != nil && lastEvent.Action != nil && lastEvent.Action.Interrupted != nil {
data, existed, err_ := ms.Get(ctx, bridgeCheckpointID)
if err_ != nil {
return "", fmt.Errorf("failed to get interrupt info: %w", err_)
}
if !existed {
return "", fmt.Errorf("interrupt has happened, but cannot find interrupt info")
}
return "", tool.CompositeInterrupt(ctx, "agent tool interrupt", data,
lastEvent.Action.internalInterrupted)
}
if lastEvent == nil {
return "", errors.New("no event returned")
}
var ret string
if lastEvent.Output != nil {
if output := lastEvent.Output.MessageOutput; output != nil {
msg, err := output.GetMessage()
if err != nil {
return "", err
}
ret = msg.Content
}
}
return ret, nil
}
// agentToolOptions is a wrapper structure used to convert AgentRunOption slices to tool.Option.
// It stores the agent name and corresponding run options for tool-specific processing.
type agentToolOptions struct {
agentName string
opts []AgentRunOption
generator *AsyncGenerator[*AgentEvent]
enableStreaming bool
}
func withAgentToolOptions(agentName string, opts []AgentRunOption) tool.Option {
return tool.WrapImplSpecificOptFn(func(opt *agentToolOptions) {
opt.agentName = agentName
opt.opts = opts
})
}
func withAgentToolEventGenerator(gen *AsyncGenerator[*AgentEvent]) tool.Option {
return tool.WrapImplSpecificOptFn(func(o *agentToolOptions) {
o.generator = gen
})
}
func getOptionsByAgentName(agentName string, opts []tool.Option) []AgentRunOption {
var ret []AgentRunOption
for _, opt := range opts {
o := tool.GetImplSpecificOptions[agentToolOptions](nil, opt)
if o != nil && o.agentName == agentName {
ret = append(ret, o.opts...)
}
}
return ret
}
func getEmitGeneratorAndEnableStreaming(opts []tool.Option) (*AsyncGenerator[*AgentEvent], bool) {
o := tool.GetImplSpecificOptions[agentToolOptions](nil, opts...)
if o == nil {
return nil, false
}
return o.generator, o.enableStreaming
}
func getReactChatHistory(ctx context.Context, destAgentName string) ([]Message, error) {
var messages []Message
err := compose.ProcessState(ctx, func(ctx context.Context, st *State) error {
messages = make([]Message, len(st.Messages)-1)
copy(messages, st.Messages[:len(st.Messages)-1]) // remove the last assistant message, which is the tool call message
return nil
})
if err != nil {
return nil, fmt.Errorf("failed to get chat history from state: %w", err)
}
var agentName string
if runCtx := getRunCtx(ctx); runCtx != nil && len(runCtx.RunPath) > 0 {
agentName = runCtx.RunPath[len(runCtx.RunPath)-1].agentName
}
a, t := GenTransferMessages(ctx, destAgentName)
messages = append(messages, a, t)
history := make([]Message, 0, len(messages))
for _, msg := range messages {
if msg.Role == schema.System {
continue
}
if msg.Role == schema.Assistant || msg.Role == schema.Tool {
msg = rewriteMessage(msg, agentName)
}
history = append(history, msg)
}
return history, nil
}
func newInvokableAgentToolRunner(agent Agent, store compose.CheckPointStore, enableStreaming bool) *Runner {
return &Runner{
a: agent,
enableStreaming: enableStreaming,
store: store,
}
}
================================================
FILE: adk/agent_tool_test.go
================================================
/*
* Copyright 2025 CloudWeGo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package adk
import (
"context"
"fmt"
"strings"
"sync"
"testing"
"github.com/stretchr/testify/assert"
"github.com/cloudwego/eino/components/model"
"github.com/cloudwego/eino/components/tool"
"github.com/cloudwego/eino/compose"
"github.com/cloudwego/eino/schema"
)
// mockAgent implements the Agent interface for testing
type mockAgentForTool struct {
name string
description string
responses []*AgentEvent
}
func (a *mockAgentForTool) Name(_ context.Context) string {
return a.name
}
func (a *mockAgentForTool) Description(_ context.Context) string {
return a.description
}
func (a *mockAgentForTool) Run(_ context.Context, _ *AgentInput, _ ...AgentRunOption) *AsyncIterator[*AgentEvent] {
iterator, generator := NewAsyncIteratorPair[*AgentEvent]()
go func() {
defer generator.Close()
for _, event := range a.responses {
generator.Send(event)
// If the event has an Exit action, stop sending events
if event.Action != nil && event.Action.Exit {
break
}
}
}()
return iterator
}
func newMockAgentForTool(name, description string, responses []*AgentEvent) *mockAgentForTool {
return &mockAgentForTool{
name: name,
description: description,
responses: responses,
}
}
func TestAgentTool_Info(t *testing.T) {
// Create a mock agent
mockAgent_ := newMockAgentForTool("TestAgent", "Test agent description", nil)
// Create an agentTool with the mock agent
agentTool_ := NewAgentTool(context.Background(), mockAgent_)
// Test the Info method
ctx := context.Background()
info, err := agentTool_.Info(ctx)
// Verify results
assert.NoError(t, err)
assert.NotNil(t, info)
assert.Equal(t, "TestAgent", info.Name)
assert.Equal(t, "Test agent description", info.Desc)
assert.NotNil(t, info.ParamsOneOf)
}
func TestAgentTool_SharedParentSessionValues(t *testing.T) {
ctx := context.Background()
inner := &sessionValuesAgent{name: "inner"}
innerTool := NewAgentTool(ctx, inner).(tool.InvokableTool)
input := &AgentInput{Messages: []Message{schema.UserMessage("q")}}
ctx, _ = initRunCtx(ctx, "outer", input)
AddSessionValue(ctx, "parent_key", "parent_val")
parentSession := getRunCtx(ctx).Session
_, err := innerTool.InvokableRun(ctx, `{"request":"hello"}`)
assert.NoError(t, err)
assert.Equal(t, "parent_val", inner.seenParentValue)
assert.NotNil(t, inner.capturedSession)
assert.NotSame(t, parentSession, inner.capturedSession)
assert.NotNil(t, parentSession.valuesMtx)
assert.Same(t, parentSession.valuesMtx, inner.capturedSession.valuesMtx)
mtx := parentSession.valuesMtx
mtx.Lock()
inner.capturedSession.Values["direct_child_key"] = "direct_child_val"
mtx.Unlock()
mtx.Lock()
v2, ok2 := parentSession.Values["direct_child_key"]
mtx.Unlock()
assert.True(t, ok2)
assert.Equal(t, "direct_child_val", v2)
mtx.Lock()
parentSession.Values["direct_parent_key"] = "direct_parent_val"
mtx.Unlock()
mtx.Lock()
v3, ok3 := inner.capturedSession.Values["direct_parent_key"]
mtx.Unlock()
assert.True(t, ok3)
assert.Equal(t, "direct_parent_val", v3)
v, ok := GetSessionValue(ctx, "child_key")
assert.True(t, ok)
assert.Equal(t, "child_val", v)
}
type sessionValuesAgent struct {
name string
seenParentValue any
capturedSession *runSession
}
func (a *sessionValuesAgent) Name(context.Context) string { return a.name }
func (a *sessionValuesAgent) Description(context.Context) string { return "test" }
func (a *sessionValuesAgent) Run(ctx context.Context, _ *AgentInput, _ ...AgentRunOption) *AsyncIterator[*AgentEvent] {
if rc := getRunCtx(ctx); rc != nil {
a.capturedSession = rc.Session
}
a.seenParentValue, _ = GetSessionValue(ctx, "parent_key")
AddSessionValue(ctx, "child_key", "child_val")
it, gen := NewAsyncIteratorPair[*AgentEvent]()
gen.Send(&AgentEvent{
AgentName: a.name,
Output: &AgentOutput{
MessageOutput: &MessageVariant{
IsStreaming: false,
Message: schema.AssistantMessage("ok", nil),
Role: schema.Assistant,
},
},
})
gen.Close()
return it
}
func TestAgentTool_InvokableRun(t *testing.T) {
// Create a context
ctx := context.Background()
// Test cases
tests := []struct {
name string
agentResponses []*AgentEvent
request string
expectedOutput string
expectError bool
}{
{
name: "successful model response",
agentResponses: []*AgentEvent{
{
AgentName: "TestAgent",
Output: &AgentOutput{
MessageOutput: &MessageVariant{
IsStreaming: false,
Message: schema.AssistantMessage("Test response", nil),
Role: schema.Assistant,
},
},
},
},
request: `{"request":"Test request"}`,
expectedOutput: "Test response",
expectError: false,
},
{
name: "successful tool call response",
agentResponses: []*AgentEvent{
{
AgentName: "TestAgent",
Output: &AgentOutput{
MessageOutput: &MessageVariant{
IsStreaming: false,
Message: schema.ToolMessage("Tool response", "test-id"),
Role: schema.Tool,
},
},
},
},
request: `{"request":"Test tool request"}`,
expectedOutput: "Tool response",
expectError: false,
},
{
name: "invalid request JSON",
agentResponses: nil,
request: `invalid json`,
expectedOutput: "",
expectError: true,
},
{
name: "no events returned",
agentResponses: []*AgentEvent{},
request: `{"request":"Test request"}`,
expectedOutput: "",
expectError: true,
},
{
name: "error in event",
agentResponses: []*AgentEvent{
{
AgentName: "TestAgent",
Err: assert.AnError,
},
},
request: `{"request":"Test request"}`,
expectedOutput: "",
expectError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Create a mock agent with the test responses
mockAgent_ := newMockAgentForTool("TestAgent", "Test agent description", tt.agentResponses)
// Create an agentTool with the mock agent
agentTool_ := NewAgentTool(ctx, mockAgent_)
// Call InvokableRun
output, err := agentTool_.(tool.InvokableTool).InvokableRun(ctx, tt.request)
// Verify results
if tt.expectError {
assert.Error(t, err)
} else {
assert.NoError(t, err)
assert.Equal(t, tt.expectedOutput, output)
}
})
}
}
func TestGetReactHistory(t *testing.T) {
g := compose.NewGraph[string, []Message](compose.WithGenLocalState(func(ctx context.Context) (state *State) {
return &State{
Messages: []Message{
schema.UserMessage("user query"),
schema.AssistantMessage("", []schema.ToolCall{{ID: "tool call id 1", Function: schema.FunctionCall{Name: "tool1", Arguments: "arguments1"}}}),
schema.ToolMessage("tool result 1", "tool call id 1", schema.WithToolName("tool1")),
schema.AssistantMessage("", []schema.ToolCall{{ID: "tool call id 2", Function: schema.FunctionCall{Name: "tool2", Arguments: "arguments2"}}}),
},
}
}))
assert.NoError(t, g.AddLambdaNode("1", compose.InvokableLambda(func(ctx context.Context, input string) (output []Message, err error) {
return getReactChatHistory(ctx, "DestAgentName")
})))
assert.NoError(t, g.AddEdge(compose.START, "1"))
assert.NoError(t, g.AddEdge("1", compose.END))
ctx := context.Background()
ctx, _ = initRunCtx(ctx, "MyAgent", nil)
runner, err := g.Compile(ctx)
assert.NoError(t, err)
result, err := runner.Invoke(ctx, "")
assert.NoError(t, err)
assert.Equal(t, []Message{
schema.UserMessage("user query"),
schema.UserMessage("For context: [MyAgent] called tool: `tool1` with arguments: arguments1."),
schema.UserMessage("For context: [MyAgent] `tool1` tool returned result: tool result 1."),
schema.UserMessage("For context: [MyAgent] called tool: `transfer_to_agent` with arguments: DestAgentName."),
schema.UserMessage("For context: [MyAgent] `transfer_to_agent` tool returned result: successfully transferred to agent [DestAgentName]."),
}, result)
}
// mockAgentWithInputCapture implements the Agent interface for testing and captures the input it receives
type mockAgentWithInputCapture struct {
name string
description string
capturedInput []Message
responses []*AgentEvent
}
func (a *mockAgentWithInputCapture) Name(_ context.Context) string {
return a.name
}
func (a *mockAgentWithInputCapture) Description(_ context.Context) string {
return a.description
}
func (a *mockAgentWithInputCapture) Run(_ context.Context, input *AgentInput, _ ...AgentRunOption) *AsyncIterator[*AgentEvent] {
a.capturedInput = input.Messages
iterator, generator := NewAsyncIteratorPair[*AgentEvent]()
go func() {
defer generator.Close()
for _, event := range a.responses {
generator.Send(event)
// If the event has an Exit action, stop sending events
if event.Action != nil && event.Action.Exit {
break
}
}
}()
return iterator
}
func newMockAgentWithInputCapture(name, description string, responses []*AgentEvent) *mockAgentWithInputCapture {
return &mockAgentWithInputCapture{
name: name,
description: description,
responses: responses,
}
}
func TestAgentToolWithOptions(t *testing.T) {
// Test Case 1: WithFullChatHistoryAsInput
t.Run("WithFullChatHistoryAsInput", func(t *testing.T) {
ctx := context.Background()
// 1. Set up a mock agent that will capture the input it receives
mockAgent := newMockAgentWithInputCapture("test-agent", "a test agent", []*AgentEvent{
{
AgentName: "test-agent",
Output: &AgentOutput{
MessageOutput: &MessageVariant{
IsStreaming: false,
Message: schema.AssistantMessage("done", nil),
Role: schema.Assistant,
},
},
},
})
// 2. Create an agentTool with the option
agentTool := NewAgentTool(ctx, mockAgent, WithFullChatHistoryAsInput())
// 3. Set up a context with a chat history using a graph
history := []Message{
schema.UserMessage("first user message"),
schema.AssistantMessage("first assistant response", nil),
}
g := compose.NewGraph[string, string](compose.WithGenLocalState(func(ctx context.Context) (state *State) {
return &State{
Messages: append(history, schema.AssistantMessage("tool call msg", nil)),
}
}))
assert.NoError(t, g.AddLambdaNode("1", compose.InvokableLambda(func(ctx context.Context, input string) (output string, err error) {
// Run the tool within the graph context that has the state
_, err = agentTool.(tool.InvokableTool).InvokableRun(ctx, `{"request":"some ignored input"}`)
return "done", err
})))
assert.NoError(t, g.AddEdge(compose.START, "1"))
assert.NoError(t, g.AddEdge("1", compose.END))
ctx, _ = initRunCtx(ctx, "react-agent", nil)
runner, err := g.Compile(ctx)
assert.NoError(t, err)
// 4. Run the graph which will execute the tool with the state
_, err = runner.Invoke(ctx, "")
assert.NoError(t, err)
// 5. Assert that the agent received the full history
// The agent should receive: history (minus last assistant message) + transfer messages
assert.Len(t, mockAgent.capturedInput, 4) // 2 from history + 2 transfer messages
assert.Equal(t, "first user message", mockAgent.capturedInput[0].Content)
assert.Equal(t, "For context: [react-agent] said: first assistant response.", mockAgent.capturedInput[1].Content)
assert.Equal(t, "For context: [react-agent] called tool: `transfer_to_agent` with arguments: test-agent.", mockAgent.capturedInput[2].Content)
assert.Equal(t, "For context: [react-agent] `transfer_to_agent` tool returned result: successfully transferred to agent [test-agent].", mockAgent.capturedInput[3].Content)
})
// Test Case 2: WithAgentInputSchema
t.Run("WithAgentInputSchema", func(t *testing.T) {
ctx := context.Background()
// 1. Define a custom schema
customSchema := schema.NewParamsOneOfByParams(map[string]*schema.ParameterInfo{
"custom_arg": {
Desc: "a custom argument",
Required: true,
Type: schema.String,
},
})
// 2. Set up a mock agent to capture input
mockAgent := newMockAgentWithInputCapture("schema-agent", "agent with custom schema", []*AgentEvent{
{
AgentName: "schema-agent",
Output: &AgentOutput{
MessageOutput: &MessageVariant{
IsStreaming: false,
Message: schema.AssistantMessage("schema processed", nil),
Role: schema.Assistant,
},
},
},
})
// 3. Create agentTool with the custom schema option
agentTool := NewAgentTool(ctx, mockAgent, WithAgentInputSchema(customSchema))
// 4. Verify the Info() method returns the custom schema
info, err := agentTool.Info(ctx)
assert.NoError(t, err)
assert.Equal(t, customSchema, info.ParamsOneOf)
// 5. Run the tool with arguments matching the custom schema
_, err = agentTool.(tool.InvokableTool).InvokableRun(ctx, `{"custom_arg":"hello world"}`)
assert.NoError(t, err)
// 6. Assert that the agent received the correctly parsed argument
// With custom schema, the agent should receive the raw JSON as input
assert.Len(t, mockAgent.capturedInput, 1)
assert.Equal(t, `{"custom_arg":"hello world"}`, mockAgent.capturedInput[0].Content)
})
// Test Case 3: WithAgentInputSchema with complex schema
t.Run("WithAgentInputSchema_ComplexSchema", func(t *testing.T) {
ctx := context.Background()
// 1. Define a complex custom schema with multiple parameters
complexSchema := schema.NewParamsOneOfByParams(map[string]*schema.ParameterInfo{
"name": {
Desc: "user name",
Required: true,
Type: schema.String,
},
"age": {
Desc: "user age",
Required: false,
Type: schema.Integer,
},
"active": {
Desc: "user status",
Required: false,
Type: schema.Boolean,
},
})
// 2. Set up a mock agent
mockAgent := newMockAgentWithInputCapture("complex-agent", "agent with complex schema", []*AgentEvent{
{
AgentName: "complex-agent",
Output: &AgentOutput{
MessageOutput: &MessageVariant{
IsStreaming: false,
Message: schema.AssistantMessage("complex processed", nil),
Role: schema.Assistant,
},
},
},
})
// 3. Create agentTool with the complex schema option
agentTool := NewAgentTool(ctx, mockAgent, WithAgentInputSchema(complexSchema))
// 4. Verify the Info() method returns the complex schema
info, err := agentTool.Info(ctx)
assert.NoError(t, err)
assert.Equal(t, complexSchema, info.ParamsOneOf)
// 5. Run the tool with complex arguments
_, err = agentTool.(tool.InvokableTool).InvokableRun(ctx, `{"name":"John","age":30,"active":true}`)
assert.NoError(t, err)
// 6. Assert that the agent received the complex JSON
assert.Len(t, mockAgent.capturedInput, 1)
assert.Equal(t, `{"name":"John","age":30,"active":true}`, mockAgent.capturedInput[0].Content)
})
// Test Case 4: Both options together
t.Run("BothOptionsTogether", func(t *testing.T) {
ctx := context.Background()
// 1. Define a custom schema
customSchema := schema.NewParamsOneOfByParams(map[string]*schema.ParameterInfo{
"query": {
Desc: "search query",
Required: true,
Type: schema.String,
},
})
// 2. Set up a mock agent
mockAgent := newMockAgentWithInputCapture("combined-agent", "agent with both options", []*AgentEvent{
{
AgentName: "combined-agent",
Output: &AgentOutput{
MessageOutput: &MessageVariant{
IsStreaming: false,
Message: schema.AssistantMessage("combined processed", nil),
Role: schema.Assistant,
},
},
},
})
// 3. Create agentTool with both options
agentTool := NewAgentTool(ctx, mockAgent, WithAgentInputSchema(customSchema), WithFullChatHistoryAsInput())
// 4. Set up a context with chat history using a graph
history := []Message{
schema.UserMessage("previous conversation"),
schema.AssistantMessage("previous response", nil),
}
g := compose.NewGraph[string, string](compose.WithGenLocalState(func(ctx context.Context) (state *State) {
return &State{
Messages: append(history, schema.AssistantMessage("tool call", nil)),
}
}))
assert.NoError(t, g.AddLambdaNode("1", compose.InvokableLambda(func(ctx context.Context, input string) (output string, err error) {
// Run the tool within the graph context that has the state
_, err = agentTool.(tool.InvokableTool).InvokableRun(ctx, `{"query":"current query"}`)
return "done", err
})))
assert.NoError(t, g.AddEdge(compose.START, "1"))
assert.NoError(t, g.AddEdge("1", compose.END))
ctx, _ = initRunCtx(ctx, "react-agent", nil)
runner, err := g.Compile(ctx)
assert.NoError(t, err)
// 5. Run the graph which will execute the tool with the state
_, err = runner.Invoke(ctx, "")
assert.NoError(t, err)
// 6. Verify both options work together
info, err := agentTool.Info(ctx)
assert.NoError(t, err)
assert.Equal(t, customSchema, info.ParamsOneOf)
// The agent should receive full history + the custom query
assert.Len(t, mockAgent.capturedInput, 4) // 2 history + 2 transfer messages
assert.Equal(t, "previous conversation", mockAgent.capturedInput[0].Content)
assert.Equal(t, "For context: [react-agent] said: previous response.", mockAgent.capturedInput[1].Content)
assert.Equal(t, "For context: [react-agent] called tool: `transfer_to_agent` with arguments: combined-agent.", mockAgent.capturedInput[2].Content)
assert.Equal(t, "For context: [react-agent] `transfer_to_agent` tool returned result: successfully transferred to agent [combined-agent].", mockAgent.capturedInput[3].Content)
})
}
type fakeTCM struct{}
func (f *fakeTCM) Generate(ctx context.Context, input []*schema.Message, opts ...model.Option) (*schema.Message, error) {
o := model.GetCommonOptions(&model.Options{}, opts...)
tc := schema.ToolCall{ID: "id-1", Type: "function"}
if len(o.Tools) > 0 {
tc.Function.Name = o.Tools[0].Name
}
tc.Function.Arguments = `{"request":"hello"}`
return schema.AssistantMessage("", []schema.ToolCall{tc}), nil
}
func (f *fakeTCM) Stream(ctx context.Context, input []*schema.Message, opts ...model.Option) (*schema.StreamReader[*schema.Message], error) {
msg, _ := f.Generate(ctx, input, opts...)
return schema.StreamReaderFromArray([]*schema.Message{msg}), nil
}
func (f *fakeTCM) WithTools(tools []*schema.ToolInfo) (model.ToolCallingChatModel, error) {
return f, nil
}
type emitOnceModel struct{}
func (e *emitOnceModel) Generate(ctx context.Context, input []*schema.Message, _ ...model.Option) (*schema.Message, error) {
return schema.AssistantMessage("inner2", nil), nil
}
func (e *emitOnceModel) Stream(ctx context.Context, input []*schema.Message, _ ...model.Option) (*schema.StreamReader[*schema.Message], error) {
m, _ := e.Generate(ctx, input)
return schema.StreamReaderFromArray([]*schema.Message{m}), nil
}
func (e *emitOnceModel) WithTools(tools []*schema.ToolInfo) (model.ToolCallingChatModel, error) {
return e, nil
}
type emitEventsAgent struct{ events []*AgentEvent }
func (e *emitEventsAgent) Name(context.Context) string { return "emit" }
func (e *emitEventsAgent) Description(context.Context) string { return "test" }
func (e *emitEventsAgent) Run(context.Context, *AgentInput, ...AgentRunOption) *AsyncIterator[*AgentEvent] {
it, gen := NewAsyncIteratorPair[*AgentEvent]()
go func() {
for _, ev := range e.events {
gen.Send(ev)
}
gen.Close()
}()
return it
}
// spyAgent captures runSession from ctx in a single nested run
type spyAgent struct {
a Agent
mu sync.Mutex
captured *runSession
}
func (s *spyAgent) Name(ctx context.Context) string { return s.a.Name(ctx) }
func (s *spyAgent) Description(ctx context.Context) string { return s.a.Description(ctx) }
func (s *spyAgent) Run(ctx context.Context, input *AgentInput, options ...AgentRunOption) *AsyncIterator[*AgentEvent] {
if rc := getRunCtx(ctx); rc != nil {
s.mu.Lock()
s.captured = rc.Session
s.mu.Unlock()
}
return s.a.Run(ctx, input, options...)
}
func (s *spyAgent) getCaptured() *runSession {
s.mu.Lock()
defer s.mu.Unlock()
return s.captured
}
func TestNestedAgentTool_RunPath(t *testing.T) {
ctx := context.Background()
inner2, _ := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "inner2",
Description: "leaf",
Model: &emitOnceModel{},
ToolsConfig: ToolsConfig{EmitInternalEvents: true},
})
inner2Spy := &spyAgent{a: inner2}
inner2Tool := NewAgentTool(ctx, inner2Spy)
inner, _ := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "inner",
Description: "mid",
Model: &fakeTCM{},
ToolsConfig: ToolsConfig{EmitInternalEvents: true, ToolsNodeConfig: compose.ToolsNodeConfig{Tools: []tool.BaseTool{inner2Tool}}},
})
innerSpy := &spyAgent{a: inner}
innerTool := NewAgentTool(ctx, innerSpy)
outer, _ := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "outer",
Description: "top",
Model: &fakeTCM{},
ToolsConfig: ToolsConfig{EmitInternalEvents: true, ToolsNodeConfig: compose.ToolsNodeConfig{Tools: []tool.BaseTool{innerTool}}},
})
input := &AgentInput{Messages: []Message{schema.UserMessage("q")}}
ctx, outerRunCtx := initRunCtx(ctx, "outer", input)
r := NewRunner(ctx, RunnerConfig{Agent: outer, EnableStreaming: false, CheckPointStore: newBridgeStore()})
it := r.Run(ctx, []Message{schema.UserMessage("q")})
var target *AgentEvent
for {
ev, ok := it.Next()
if !ok {
break
}
if ev.Output != nil && ev.Output.MessageOutput != nil && !ev.Output.MessageOutput.IsStreaming {
if ev.Output.MessageOutput.Message != nil && ev.Output.MessageOutput.Message.Content == "inner2" {
target = ev
break
}
}
}
if target == nil {
t.Fatalf("no inner2 event found in ephemerals")
}
got := make([]string, len(target.RunPath))
for i := range target.RunPath {
got[i] = target.RunPath[i].agentName
}
want := []string{"outer", "inner", "inner2"}
if len(got) != len(want) {
t.Fatalf("unexpected runPath len: got %d want %d: %+v", len(got), len(want), got)
}
for i := range want {
if got[i] != want[i] {
t.Fatalf("runPath mismatch at %d: got %s want %s; full: %+v", i, got[i], want[i], got)
}
}
for _, w := range outerRunCtx.Session.getEvents() {
if w.AgentName != "outer" {
t.Fatalf("outer session contains non-outer event: %s", w.AgentName)
}
}
if innerSpy.getCaptured() == nil {
t.Fatalf("inner spy did not capture session")
}
for _, w := range innerSpy.getCaptured().getEvents() {
if w.AgentName != "inner" {
t.Fatalf("inner session contains non-inner event: %s", w.AgentName)
}
}
if inner2Spy.getCaptured() == nil {
t.Fatalf("inner2 spy did not capture session")
}
for _, w := range inner2Spy.getCaptured().getEvents() {
if w.AgentName != "inner2" {
t.Fatalf("inner2 session contains non-inner2 event: %s", w.AgentName)
}
}
}
func TestNestedAgentTool_NoInternalEventsWhenDisabled(t *testing.T) {
ctx := context.Background()
inner2, _ := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "inner2",
Description: "leaf",
Model: &emitOnceModel{},
ToolsConfig: ToolsConfig{EmitInternalEvents: false},
})
inner2Tool := NewAgentTool(ctx, inner2)
inner, _ := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "inner",
Description: "mid",
Model: &fakeTCM{},
ToolsConfig: ToolsConfig{EmitInternalEvents: false, ToolsNodeConfig: compose.ToolsNodeConfig{Tools: []tool.BaseTool{inner2Tool}}},
})
innerTool := NewAgentTool(ctx, inner)
outer, _ := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "outer",
Description: "top",
Model: &fakeTCM{},
ToolsConfig: ToolsConfig{EmitInternalEvents: false, ToolsNodeConfig: compose.ToolsNodeConfig{Tools: []tool.BaseTool{innerTool}}},
})
r := NewRunner(ctx, RunnerConfig{Agent: outer, EnableStreaming: false, CheckPointStore: newBridgeStore()})
it := r.Run(ctx, []Message{schema.UserMessage("q")})
for {
ev, ok := it.Next()
if !ok {
break
}
if ev.AgentName == "inner2" {
t.Fatalf("inner2 internal event should not be emitted when disabled")
}
}
}
func TestNestedAgentTool_InnerToolResultNotEmittedToOuter(t *testing.T) {
ctx := context.Background()
innerTool := &simpleTool{name: "inner_tool", result: "inner_tool_result"}
inner, _ := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "inner",
Description: "inner agent with tool",
Model: &fakeTCM{},
ToolsConfig: ToolsConfig{ToolsNodeConfig: compose.ToolsNodeConfig{Tools: []tool.BaseTool{innerTool}}},
})
innerAgentTool := NewAgentTool(ctx, inner)
outer, _ := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "outer",
Description: "outer agent",
Model: &fakeTCM{},
ToolsConfig: ToolsConfig{ToolsNodeConfig: compose.ToolsNodeConfig{Tools: []tool.BaseTool{innerAgentTool}}},
})
r := NewRunner(ctx, RunnerConfig{Agent: outer, EnableStreaming: false, CheckPointStore: newBridgeStore()})
it := r.Run(ctx, []Message{schema.UserMessage("q")})
var allEvents []*AgentEvent
for {
ev, ok := it.Next()
if !ok {
break
}
allEvents = append(allEvents, ev)
}
for _, ev := range allEvents {
if ev.Output != nil && ev.Output.MessageOutput != nil &&
ev.Output.MessageOutput.Message != nil &&
ev.Output.MessageOutput.Message.Role == schema.Tool &&
ev.AgentName == "outer" &&
ev.Output.MessageOutput.Message.Content == "inner_tool_result" {
t.Fatalf("inner agent's tool result (inner_tool_result) should not be emitted as outer agent's event, but got event with AgentName=%s, Content=%s",
ev.AgentName, ev.Output.MessageOutput.Message.Content)
}
}
}
type simpleTool struct {
name string
result string
}
func (s *simpleTool) Info(context.Context) (*schema.ToolInfo, error) {
return &schema.ToolInfo{Name: s.name, Desc: "simple tool"}, nil
}
func (s *simpleTool) InvokableRun(ctx context.Context, argumentsInJSON string, opts ...tool.Option) (string, error) {
return s.result, nil
}
func TestAgentTool_InterruptWithoutCheckpoint(t *testing.T) {
ctx := context.Background()
ctx, _ = initRunCtx(ctx, "TestAgent", &AgentInput{Messages: []Message{}})
interrupted := &AgentEvent{AgentName: "TestAgent"}
interrupted.Action = StatefulInterrupt(ctx, "info", "state").Action
err := compositeInterruptFromLast(ctx, &bridgeStore{}, interrupted)
if err == nil {
t.Fatalf("expected error for interrupt without checkpoint")
}
if !strings.Contains(err.Error(), "interrupt occurred but checkpoint data is missing") {
t.Fatalf("unexpected error: %v", err)
}
}
func compositeInterruptFromLast(ctx context.Context, ms *bridgeStore, lastEvent *AgentEvent) error {
if lastEvent == nil || lastEvent.Action == nil || lastEvent.Action.Interrupted == nil {
return nil
}
data, existed, err := ms.Get(ctx, bridgeCheckpointID)
if err != nil {
return fmt.Errorf("failed to get interrupt info: %w", err)
}
if !existed {
return fmt.Errorf("interrupt occurred but checkpoint data is missing")
}
return tool.CompositeInterrupt(ctx, "agent tool interrupt", data, lastEvent.Action.internalInterrupted)
}
func TestAgentTool_InvokableRun_FinalOnly(t *testing.T) {
ctx := context.Background()
inner2, _ := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "inner2",
Description: "leaf",
Model: &emitOnceModel{},
ToolsConfig: ToolsConfig{EmitInternalEvents: true},
})
invTool := NewAgentTool(ctx, inner2)
out, err := invTool.(tool.InvokableTool).InvokableRun(ctx, `{"request":"q"}`)
if err != nil {
t.Fatalf("invokable run error: %v", err)
}
if out != "inner2" {
t.Fatalf("unexpected output: %s", out)
}
}
type streamingAgent struct{}
func (s *streamingAgent) Name(context.Context) string { return "stream" }
func (s *streamingAgent) Description(context.Context) string { return "test" }
func (s *streamingAgent) Run(context.Context, *AgentInput, ...AgentRunOption) *AsyncIterator[*AgentEvent] {
it, gen := NewAsyncIteratorPair[*AgentEvent]()
go func() {
mv := &MessageVariant{IsStreaming: true, MessageStream: schema.StreamReaderFromArray([]Message{schema.AssistantMessage("1", nil), schema.AssistantMessage("2", nil)})}
gen.Send(&AgentEvent{AgentName: "stream", Output: &AgentOutput{MessageOutput: mv}})
mv = &MessageVariant{IsStreaming: true, MessageStream: schema.StreamReaderFromArray([]Message{schema.AssistantMessage("a", nil), schema.AssistantMessage("b", nil)})}
gen.Send(&AgentEvent{AgentName: "stream", Output: &AgentOutput{MessageOutput: mv}})
gen.Close()
}()
return it
}
func TestAgentTool_InvokableRun_StreamingVariant(t *testing.T) {
ctx := context.Background()
agent := &streamingAgent{}
it := NewAgentTool(ctx, agent)
out, err := it.(tool.InvokableTool).InvokableRun(ctx, `{"request":"q"}`)
if err != nil {
t.Fatalf("invokable run error: %v", err)
}
if out != "ab" {
t.Fatalf("unexpected output: %s", out)
}
}
func TestSequentialWorkflow_WithChatModelAgentTool_NestedRunPathAndSessions(t *testing.T) {
ctx := context.Background()
inner2, _ := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "inner2",
Description: "leaf",
Model: &emitOnceModel{},
ToolsConfig: ToolsConfig{EmitInternalEvents: true},
})
inner2Spy := &spyAgent{a: inner2}
inner2ToolSpy := NewAgentTool(ctx, inner2Spy)
innerWithSpy, _ := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "inner",
Description: "mid",
Model: &fakeTCM{},
ToolsConfig: ToolsConfig{EmitInternalEvents: true, ToolsNodeConfig: compose.ToolsNodeConfig{Tools: []tool.BaseTool{inner2ToolSpy}}},
})
innerSpy := &spyAgent{a: innerWithSpy}
outer, err := NewSequentialAgent(ctx, &SequentialAgentConfig{
Name: "outer-seq",
Description: "workflow",
SubAgents: []Agent{innerSpy},
})
if err != nil {
t.Fatalf("new sequential agent err: %v", err)
}
input := &AgentInput{Messages: []Message{schema.UserMessage("q")}}
ctx, outerRunCtx := initRunCtx(ctx, "outer-seq", input)
r := NewRunner(ctx, RunnerConfig{Agent: outer, EnableStreaming: false, CheckPointStore: newBridgeStore()})
it := r.Run(ctx, []Message{schema.UserMessage("q")})
var target *AgentEvent
for {
ev, ok := it.Next()
if !ok {
break
}
if ev.Output != nil && ev.Output.MessageOutput != nil && !ev.Output.MessageOutput.IsStreaming {
if ev.Output.MessageOutput.Message != nil && ev.Output.MessageOutput.Message.Content == "inner2" {
target = ev
break
}
}
}
if target == nil {
t.Fatalf("no inner2 event found")
}
got := make([]string, len(target.RunPath))
for i := range target.RunPath {
got[i] = target.RunPath[i].agentName
}
want := []string{"outer-seq", "inner", "inner2"}
if len(got) != len(want) {
t.Fatalf("unexpected runPath len: got %d want %d: %+v", len(got), len(want), got)
}
for i := range want {
if got[i] != want[i] {
t.Fatalf("runPath mismatch at %d: got %s want %s; full: %+v", i, got[i], want[i], got)
}
}
for _, w := range outerRunCtx.Session.getEvents() {
if w.AgentName != "outer-seq" {
t.Fatalf("outer session contains non-outer event: %s", w.AgentName)
}
}
if innerSpy.getCaptured() == nil {
t.Fatalf("inner spy did not capture session")
}
for _, w := range innerSpy.getCaptured().getEvents() {
if w.AgentName != "inner" {
t.Fatalf("inner session contains non-inner event: %s", w.AgentName)
}
}
if inner2Spy.getCaptured() == nil {
t.Fatalf("inner2 spy did not capture session")
}
for _, w := range inner2Spy.getCaptured().getEvents() {
if w.AgentName != "inner2" {
t.Fatalf("inner2 session contains non-inner2 event: %s", w.AgentName)
}
}
}
func TestRunPathGating_IgnoresInnerExitAndAllowsOutput(t *testing.T) {
ctx := context.Background()
innerExit := &AgentEvent{Action: &AgentAction{Exit: true}, RunPath: []RunStep{{agentName: "inner"}}}
finalOut := EventFromMessage(schema.AssistantMessage("ok", nil), nil, schema.Assistant, "")
sub := &emitEventsAgent{events: []*AgentEvent{innerExit, finalOut}}
fa := toFlowAgent(ctx, sub)
it := fa.Run(ctx, &AgentInput{Messages: []Message{schema.UserMessage("q")}})
var sawFinal bool
for {
ev, ok := it.Next()
if !ok {
break
}
if ev.Output != nil && ev.Output.MessageOutput != nil && !ev.Output.MessageOutput.IsStreaming {
if ev.Output.MessageOutput.Message != nil && ev.Output.MessageOutput.Message.Content == "ok" {
sawFinal = true
}
}
}
if !sawFinal {
t.Fatalf("final output not observed; parent may have exited on inner Exit action")
}
}
func TestRunPathGating_IgnoresInnerTransfer(t *testing.T) {
ctx := context.Background()
innerTransfer := &AgentEvent{Action: NewTransferToAgentAction("ghost"), RunPath: []RunStep{{agentName: "inner"}}}
finalOut := EventFromMessage(schema.AssistantMessage("done", nil), nil, schema.Assistant, "")
sub := &emitEventsAgent{events: []*AgentEvent{innerTransfer, finalOut}}
fa := toFlowAgent(ctx, sub)
it := fa.Run(ctx, &AgentInput{Messages: []Message{schema.UserMessage("q")}})
var outputs int
for {
ev, ok := it.Next()
if !ok {
break
}
if ev.Output != nil && ev.Output.MessageOutput != nil && !ev.Output.MessageOutput.IsStreaming {
if ev.Output.MessageOutput.Message != nil {
outputs++
}
}
}
if outputs == 0 {
t.Fatalf("no outputs observed; parent may have transferred on inner transfer action")
}
}
type streamAgent struct{}
func (s *streamAgent) Name(context.Context) string { return "s" }
func (s *streamAgent) Description(context.Context) string { return "s" }
func (s *streamAgent) Run(context.Context, *AgentInput, ...AgentRunOption) *AsyncIterator[*AgentEvent] {
it, gen := NewAsyncIteratorPair[*AgentEvent]()
go func() {
frames := []*schema.Message{
schema.AssistantMessage("hello ", nil),
schema.AssistantMessage("world", nil),
}
stream := schema.StreamReaderFromArray(frames)
gen.Send(EventFromMessage(nil, stream, schema.Assistant, ""))
gen.Close()
}()
return it
}
func TestInvokableAgentTool_InfoAndRun(t *testing.T) {
ctx := context.Background()
at := NewAgentTool(ctx, &streamAgent{})
info, err := at.Info(ctx)
assert.NoError(t, err)
assert.Equal(t, "s", info.Name)
assert.Equal(t, "s", info.Desc)
js, err := info.ParamsOneOf.ToJSONSchema()
assert.NoError(t, err)
found := false
for _, r := range js.Required {
if r == "request" {
found = true
break
}
}
assert.True(t, found)
prop, ok := js.Properties.Get("request")
assert.True(t, ok)
assert.Equal(t, string(schema.String), prop.Type)
custom := schema.NewParamsOneOfByParams(map[string]*schema.ParameterInfo{
"x": {Desc: "arg", Required: true, Type: schema.String},
})
at2 := NewAgentTool(ctx, &streamAgent{}, WithAgentInputSchema(custom))
info2, err := at2.Info(ctx)
assert.NoError(t, err)
assert.Equal(t, custom, info2.ParamsOneOf)
out, err := at.(tool.InvokableTool).InvokableRun(ctx, `{"request":"x"}`)
assert.NoError(t, err)
assert.Equal(t, "hello world", out)
}
type emptyAgent struct{}
func (e *emptyAgent) Name(context.Context) string { return "empty" }
func (e *emptyAgent) Description(context.Context) string { return "empty" }
func (e *emptyAgent) Run(context.Context, *AgentInput, ...AgentRunOption) *AsyncIterator[*AgentEvent] {
it, gen := NewAsyncIteratorPair[*AgentEvent]()
go func() { gen.Close() }()
return it
}
type noOutputAgent struct{}
func (n *noOutputAgent) Name(context.Context) string { return "no" }
func (n *noOutputAgent) Description(context.Context) string { return "no" }
func (n *noOutputAgent) Run(context.Context, *AgentInput, ...AgentRunOption) *AsyncIterator[*AgentEvent] {
it, gen := NewAsyncIteratorPair[*AgentEvent]()
go func() { gen.Send(&AgentEvent{}); gen.Close() }()
return it
}
func TestInvokableAgentTool_ErrorCases(t *testing.T) {
ctx := context.Background()
atEmpty := NewAgentTool(ctx, &emptyAgent{})
out, err := atEmpty.(tool.InvokableTool).InvokableRun(ctx, `{"request":"x"}`)
assert.Equal(t, "", out)
assert.Error(t, err)
atNo := NewAgentTool(ctx, &noOutputAgent{})
out2, err := atNo.(tool.InvokableTool).InvokableRun(ctx, `{"request":"x"}`)
assert.NoError(t, err)
assert.Equal(t, "", out2)
}
================================================
FILE: adk/call_option.go
================================================
/*
* Copyright 2025 CloudWeGo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package adk
import "github.com/cloudwego/eino/callbacks"
type options struct {
sharedParentSession bool
sessionValues map[string]any
checkPointID *string
skipTransferMessages bool
handlers []callbacks.Handler
}
// AgentRunOption is the call option for adk Agent.
type AgentRunOption struct {
implSpecificOptFn any
// specify which Agent can see this AgentRunOption, if empty, all Agents can see this AgentRunOption
agentNames []string
}
func (o AgentRunOption) DesignateAgent(name ...string) AgentRunOption {
o.agentNames = append(o.agentNames, name...)
return o
}
func getCommonOptions(base *options, opts ...AgentRunOption) *options {
if base == nil {
base = &options{}
}
return GetImplSpecificOptions(base, opts...)
}
// WithSessionValues sets session-scoped values for the agent run.
func WithSessionValues(v map[string]any) AgentRunOption {
return WrapImplSpecificOptFn(func(o *options) {
o.sessionValues = v
})
}
// WithSkipTransferMessages disables forwarding transfer messages during execution.
func WithSkipTransferMessages() AgentRunOption {
return WrapImplSpecificOptFn(func(t *options) {
t.skipTransferMessages = true
})
}
func withSharedParentSession() AgentRunOption {
return WrapImplSpecificOptFn(func(o *options) {
o.sharedParentSession = true
})
}
// WithCallbacks adds callback handlers to receive agent lifecycle events.
// Handlers receive OnStart with AgentCallbackInput and OnEnd with AgentCallbackOutput.
// Multiple handlers can be added; each receives an independent copy of the event stream.
func WithCallbacks(handlers ...callbacks.Handler) AgentRunOption {
return WrapImplSpecificOptFn(func(o *options) {
o.handlers = append(o.handlers, handlers...)
})
}
// WrapImplSpecificOptFn is the option to wrap the implementation specific option function.
func WrapImplSpecificOptFn[T any](optFn func(*T)) AgentRunOption {
return AgentRunOption{
implSpecificOptFn: optFn,
}
}
// GetImplSpecificOptions extract the implementation specific options from AgentRunOption list, optionally providing a base options with default values.
// e.g.
//
// myOption := &MyOption{
// Field1: "default_value",
// }
//
// myOption := model.GetImplSpecificOptions(myOption, opts...)
func GetImplSpecificOptions[T any](base *T, opts ...AgentRunOption) *T {
if base == nil {
base = new(T)
}
for i := range opts {
opt := opts[i]
if opt.implSpecificOptFn != nil {
optFn, ok := opt.implSpecificOptFn.(func(*T))
if ok {
optFn(base)
}
}
}
return base
}
// filterCallbackHandlersForNestedAgents removes callback handlers that have already been applied
// to the current agent before passing opts to nested inner agents.
//
// This is necessary for workflow agents (LoopAgent, SequentialAgent, ParallelAgent) because:
// 1. Callback handlers designated for the current agent are applied via initAgentCallbacks(),
// which stores them in the context.
// 2. Nested inner agents inherit this context, so they automatically receive these callbacks.
// 3. If we also pass these handlers in opts to inner agents, they would be applied twice,
// causing duplicate callback invocations.
//
// Note: This only applies to workflow agents where inner agents inherit context from the parent.
// For flowAgent's sub-agents (which are peer agents that transfer to each other), the full opts
// are passed since they don't inherit the parent's callback context.
func filterCallbackHandlersForNestedAgents(currentAgentName string, opts []AgentRunOption) []AgentRunOption {
if len(opts) == 0 {
return nil
}
var filteredOpts []AgentRunOption
for i := range opts {
opt := opts[i]
if opt.implSpecificOptFn == nil {
filteredOpts = append(filteredOpts, opt)
continue
}
if _, isCallbackOpt := opt.implSpecificOptFn.(func(*options)); isCallbackOpt {
testOpt := &options{}
opt.implSpecificOptFn.(func(*options))(testOpt)
if len(testOpt.handlers) > 0 {
if len(opt.agentNames) == 0 {
continue
}
matched := false
for _, name := range opt.agentNames {
if name == currentAgentName {
matched = true
break
}
}
if matched {
continue
}
}
}
filteredOpts = append(filteredOpts, opt)
}
return filteredOpts
}
func filterOptions(agentName string, opts []AgentRunOption) []AgentRunOption {
if len(opts) == 0 {
return nil
}
var filteredOpts []AgentRunOption
for i := range opts {
opt := opts[i]
if len(opt.agentNames) == 0 {
filteredOpts = append(filteredOpts, opt)
continue
}
for j := range opt.agentNames {
if opt.agentNames[j] == agentName {
filteredOpts = append(filteredOpts, opt)
break
}
}
}
return filteredOpts
}
================================================
FILE: adk/call_option_test.go
================================================
/*
* Copyright 2025 CloudWeGo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package adk
import (
"context"
)
type mockAgentForOption struct {
opts []AgentRunOption
options *options
}
func (m *mockAgentForOption) Name(ctx context.Context) string {
return "agent_1"
}
func (m *mockAgentForOption) Description(ctx context.Context) string {
return ""
}
func (m *mockAgentForOption) Run(ctx context.Context, input *AgentInput, opts ...AgentRunOption) *AsyncIterator[*AgentEvent] {
m.opts = opts
m.options = getCommonOptions(&options{}, opts...)
return nil
}
================================================
FILE: adk/callback.go
================================================
/*
* Copyright 2026 CloudWeGo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package adk
import (
"context"
"github.com/cloudwego/eino/callbacks"
"github.com/cloudwego/eino/components"
icb "github.com/cloudwego/eino/internal/callbacks"
)
// AgentCallbackInput represents the input passed to agent callbacks during OnStart.
// Use ConvAgentCallbackInput to safely convert from callbacks.CallbackInput.
type AgentCallbackInput struct {
// Input contains the agent input for a new run. Nil when resuming.
Input *AgentInput
// ResumeInfo contains resume information when resuming from an interrupt. Nil for new runs.
ResumeInfo *ResumeInfo
}
// AgentCallbackOutput represents the output passed to agent callbacks during OnEnd.
// Use ConvAgentCallbackOutput to safely convert from callbacks.CallbackOutput.
//
// Important: The Events iterator should be consumed asynchronously to avoid blocking
// the agent execution. Each callback handler receives an independent copy of the iterator.
type AgentCallbackOutput struct {
// Events provides a stream of agent events. Each handler receives its own copy.
Events *AsyncIterator[*AgentEvent]
}
func copyEventIterator(iter *AsyncIterator[*AgentEvent], n int) []*AsyncIterator[*AgentEvent] {
if n <= 0 {
return nil
}
if n == 1 {
return []*AsyncIterator[*AgentEvent]{iter}
}
iterators := make([]*AsyncIterator[*AgentEvent], n)
generators := make([]*AsyncGenerator[*AgentEvent], n)
for i := 0; i < n; i++ {
iterators[i], generators[i] = NewAsyncIteratorPair[*AgentEvent]()
}
go func() {
defer func() {
for _, g := range generators {
g.Close()
}
}()
for {
event, ok := iter.Next()
if !ok {
break
}
for i := 0; i < n-1; i++ {
generators[i].Send(copyAgentEvent(event))
}
generators[n-1].Send(event)
}
}()
return iterators
}
func copyAgentCallbackOutput(out *AgentCallbackOutput, n int) []*AgentCallbackOutput {
if out == nil || out.Events == nil {
result := make([]*AgentCallbackOutput, n)
for i := 0; i < n; i++ {
result[i] = out
}
return result
}
iters := copyEventIterator(out.Events, n)
result := make([]*AgentCallbackOutput, n)
for i, iter := range iters {
result[i] = &AgentCallbackOutput{Events: iter}
}
return result
}
// ConvAgentCallbackInput converts a generic CallbackInput to AgentCallbackInput.
// Returns nil if the input is not an AgentCallbackInput.
func ConvAgentCallbackInput(input callbacks.CallbackInput) *AgentCallbackInput {
if v, ok := input.(*AgentCallbackInput); ok {
return v
}
return nil
}
// ConvAgentCallbackOutput converts a generic CallbackOutput to AgentCallbackOutput.
// Returns nil if the output is not an AgentCallbackOutput.
func ConvAgentCallbackOutput(output callbacks.CallbackOutput) *AgentCallbackOutput {
if v, ok := output.(*AgentCallbackOutput); ok {
return v
}
return nil
}
func initAgentCallbacks(ctx context.Context, agentName, agentType string, opts ...AgentRunOption) context.Context {
ri := &callbacks.RunInfo{
Name: agentName,
Type: agentType,
Component: ComponentOfAgent,
}
o := getCommonOptions(nil, opts...)
if len(o.handlers) == 0 {
return icb.ReuseHandlers(ctx, ri)
}
return icb.AppendHandlers(ctx, ri, o.handlers...)
}
func getAgentType(agent Agent) string {
if typer, ok := agent.(components.Typer); ok {
return typer.GetType()
}
return ""
}
================================================
FILE: adk/callback_integration_test.go
================================================
/*
* Copyright 2026 CloudWeGo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package adk
import (
"context"
"sync"
"testing"
"github.com/stretchr/testify/assert"
"go.uber.org/mock/gomock"
"github.com/cloudwego/eino/callbacks"
mockModel "github.com/cloudwego/eino/internal/mock/components/model"
"github.com/cloudwego/eino/schema"
)
type callbackRecorder struct {
mu sync.Mutex
onStartCalled bool
onEndCalled bool
runInfo *callbacks.RunInfo
inputReceived *AgentCallbackInput
eventsReceived []*AgentEvent
eventsDone chan struct{}
closeOnce sync.Once
}
func (r *callbackRecorder) getOnStartCalled() bool {
r.mu.Lock()
defer r.mu.Unlock()
return r.onStartCalled
}
func (r *callbackRecorder) getOnEndCalled() bool {
r.mu.Lock()
defer r.mu.Unlock()
return r.onEndCalled
}
func (r *callbackRecorder) getEventsReceived() []*AgentEvent {
r.mu.Lock()
defer r.mu.Unlock()
result := make([]*AgentEvent, len(r.eventsReceived))
copy(result, r.eventsReceived)
return result
}
func newRecordingHandler(recorder *callbackRecorder) callbacks.Handler {
recorder.eventsDone = make(chan struct{})
return callbacks.NewHandlerBuilder().
OnStartFn(func(ctx context.Context, info *callbacks.RunInfo, input callbacks.CallbackInput) context.Context {
if info.Component != ComponentOfAgent {
return ctx
}
recorder.mu.Lock()
defer recorder.mu.Unlock()
recorder.onStartCalled = true
recorder.runInfo = info
if agentInput := ConvAgentCallbackInput(input); agentInput != nil {
recorder.inputReceived = agentInput
}
return ctx
}).
OnEndFn(func(ctx context.Context, info *callbacks.RunInfo, output callbacks.CallbackOutput) context.Context {
if info.Component != ComponentOfAgent {
return ctx
}
recorder.mu.Lock()
recorder.onEndCalled = true
recorder.runInfo = info
recorder.mu.Unlock()
if agentOutput := ConvAgentCallbackOutput(output); agentOutput != nil {
if agentOutput.Events != nil {
go func() {
defer recorder.closeOnce.Do(func() { close(recorder.eventsDone) })
for {
event, ok := agentOutput.Events.Next()
if !ok {
break
}
recorder.mu.Lock()
recorder.eventsReceived = append(recorder.eventsReceived, event)
recorder.mu.Unlock()
}
}()
return ctx
}
}
recorder.closeOnce.Do(func() { close(recorder.eventsDone) })
return ctx
}).
Build()
}
func TestCallbackOnStartInvocation(t *testing.T) {
ctx := context.Background()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
cm := mockModel.NewMockToolCallingChatModel(ctrl)
cm.EXPECT().Generate(gomock.Any(), gomock.Any(), gomock.Any()).
Return(schema.AssistantMessage("test response", nil), nil).
Times(1)
cm.EXPECT().WithTools(gomock.Any()).Return(cm, nil).AnyTimes()
agent, err := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "TestAgent",
Description: "Test agent for callback",
Instruction: "You are a test agent",
Model: cm,
})
assert.NoError(t, err)
recorder := &callbackRecorder{}
handler := newRecordingHandler(recorder)
runner := NewRunner(ctx, RunnerConfig{Agent: agent})
iter := runner.Query(ctx, "hello", WithCallbacks(handler))
for {
_, ok := iter.Next()
if !ok {
break
}
}
<-recorder.eventsDone
assert.True(t, recorder.onStartCalled, "OnStart should be called")
assert.NotNil(t, recorder.inputReceived, "Input should be received")
assert.NotNil(t, recorder.inputReceived.Input, "AgentInput should be set")
assert.Len(t, recorder.inputReceived.Input.Messages, 1)
}
func TestCallbackOnEndInvocation(t *testing.T) {
ctx := context.Background()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
cm := mockModel.NewMockToolCallingChatModel(ctrl)
cm.EXPECT().Generate(gomock.Any(), gomock.Any(), gomock.Any()).
Return(schema.AssistantMessage("test response", nil), nil).
Times(1)
cm.EXPECT().WithTools(gomock.Any()).Return(cm, nil).AnyTimes()
agent, err := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "TestAgent",
Description: "Test agent for callback",
Instruction: "You are a test agent",
Model: cm,
})
assert.NoError(t, err)
recorder := &callbackRecorder{}
handler := newRecordingHandler(recorder)
runner := NewRunner(ctx, RunnerConfig{Agent: agent})
iter := runner.Query(ctx, "hello", WithCallbacks(handler))
for {
_, ok := iter.Next()
if !ok {
break
}
}
<-recorder.eventsDone
assert.True(t, recorder.onEndCalled, "OnEnd should be called")
assert.NotEmpty(t, recorder.eventsReceived, "Events should be received")
}
func TestCallbackRunInfoForChatModelAgent(t *testing.T) {
ctx := context.Background()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
cm := mockModel.NewMockToolCallingChatModel(ctrl)
cm.EXPECT().Generate(gomock.Any(), gomock.Any(), gomock.Any()).
Return(schema.AssistantMessage("test response", nil), nil).
Times(1)
cm.EXPECT().WithTools(gomock.Any()).Return(cm, nil).AnyTimes()
agent, err := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "TestChatAgent",
Description: "Test chat agent",
Instruction: "You are a test agent",
Model: cm,
})
assert.NoError(t, err)
recorder := &callbackRecorder{}
handler := newRecordingHandler(recorder)
runner := NewRunner(ctx, RunnerConfig{Agent: agent})
iter := runner.Query(ctx, "hello", WithCallbacks(handler))
for {
_, ok := iter.Next()
if !ok {
break
}
}
<-recorder.eventsDone
assert.NotNil(t, recorder.runInfo)
assert.Equal(t, "TestChatAgent", recorder.runInfo.Name)
assert.Equal(t, "ChatModel", recorder.runInfo.Type)
assert.Equal(t, ComponentOfAgent, recorder.runInfo.Component)
}
func TestMultipleCallbackHandlers(t *testing.T) {
ctx := context.Background()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
cm := mockModel.NewMockToolCallingChatModel(ctrl)
cm.EXPECT().Generate(gomock.Any(), gomock.Any(), gomock.Any()).
Return(schema.AssistantMessage("test response", nil), nil).
Times(1)
cm.EXPECT().WithTools(gomock.Any()).Return(cm, nil).AnyTimes()
agent, err := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "TestAgent",
Description: "Test agent",
Instruction: "You are a test agent",
Model: cm,
})
assert.NoError(t, err)
recorder1 := &callbackRecorder{}
recorder2 := &callbackRecorder{}
handler1 := newRecordingHandler(recorder1)
handler2 := newRecordingHandler(recorder2)
runner := NewRunner(ctx, RunnerConfig{Agent: agent})
iter := runner.Query(ctx, "hello", WithCallbacks(handler1, handler2))
for {
_, ok := iter.Next()
if !ok {
break
}
}
<-recorder1.eventsDone
<-recorder2.eventsDone
assert.True(t, recorder1.onStartCalled, "Handler1 OnStart should be called")
assert.True(t, recorder2.onStartCalled, "Handler2 OnStart should be called")
assert.True(t, recorder1.onEndCalled, "Handler1 OnEnd should be called")
assert.True(t, recorder2.onEndCalled, "Handler2 OnEnd should be called")
assert.NotEmpty(t, recorder1.eventsReceived, "Handler1 should receive events")
assert.NotEmpty(t, recorder2.eventsReceived, "Handler2 should receive events")
}
func TestCallbackWithWorkflowAgent(t *testing.T) {
ctx := context.Background()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
cm1 := mockModel.NewMockToolCallingChatModel(ctrl)
cm1.EXPECT().Generate(gomock.Any(), gomock.Any(), gomock.Any()).
Return(schema.AssistantMessage("response 1", nil), nil).
Times(1)
cm1.EXPECT().WithTools(gomock.Any()).Return(cm1, nil).AnyTimes()
cm2 := mockModel.NewMockToolCallingChatModel(ctrl)
cm2.EXPECT().Generate(gomock.Any(), gomock.Any(), gomock.Any()).
Return(schema.AssistantMessage("response 2", nil), nil).
Times(1)
cm2.EXPECT().WithTools(gomock.Any()).Return(cm2, nil).AnyTimes()
agent1, err := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "Agent1",
Description: "First agent",
Instruction: "You are agent 1",
Model: cm1,
})
assert.NoError(t, err)
agent2, err := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "Agent2",
Description: "Second agent",
Instruction: "You are agent 2",
Model: cm2,
})
assert.NoError(t, err)
seqAgent, err := NewSequentialAgent(ctx, &SequentialAgentConfig{
Name: "SequentialAgent",
Description: "Sequential workflow",
SubAgents: []Agent{agent1, agent2},
})
assert.NoError(t, err)
var callbackInfos []*callbacks.RunInfo
handler := callbacks.NewHandlerBuilder().
OnStartFn(func(ctx context.Context, info *callbacks.RunInfo, input callbacks.CallbackInput) context.Context {
if info.Component == ComponentOfAgent {
callbackInfos = append(callbackInfos, info)
}
return ctx
}).
Build()
runner := NewRunner(ctx, RunnerConfig{Agent: seqAgent})
iter := runner.Query(ctx, "hello", WithCallbacks(handler))
for {
_, ok := iter.Next()
if !ok {
break
}
}
assert.NotEmpty(t, callbackInfos, "OnStart should be called for agents")
foundAgent1 := false
foundAgent2 := false
for _, info := range callbackInfos {
if info.Name == "Agent1" && info.Type == "ChatModel" {
foundAgent1 = true
}
if info.Name == "Agent2" && info.Type == "ChatModel" {
foundAgent2 = true
}
}
assert.True(t, foundAgent1, "Agent1 callback should be invoked")
assert.True(t, foundAgent2, "Agent2 callback should be invoked")
}
func TestCallbackEventsMatchAgentOutput(t *testing.T) {
ctx := context.Background()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
expectedContent := "This is the test response content"
cm := mockModel.NewMockToolCallingChatModel(ctrl)
cm.EXPECT().Generate(gomock.Any(), gomock.Any(), gomock.Any()).
Return(schema.AssistantMessage(expectedContent, nil), nil).
Times(1)
cm.EXPECT().WithTools(gomock.Any()).Return(cm, nil).AnyTimes()
agent, err := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "TestAgent",
Description: "Test agent",
Instruction: "You are a test agent",
Model: cm,
})
assert.NoError(t, err)
recorder := &callbackRecorder{}
handler := newRecordingHandler(recorder)
var agentEvents []*AgentEvent
runner := NewRunner(ctx, RunnerConfig{Agent: agent})
iter := runner.Query(ctx, "hello", WithCallbacks(handler))
for {
event, ok := iter.Next()
if !ok {
break
}
agentEvents = append(agentEvents, event)
}
<-recorder.eventsDone
assert.NotEmpty(t, agentEvents, "Agent should emit events")
assert.NotEmpty(t, recorder.eventsReceived, "Callback should receive events")
foundExpectedContent := false
for _, event := range recorder.eventsReceived {
if event.Output != nil && event.Output.MessageOutput != nil {
msg := event.Output.MessageOutput.Message
if msg != nil && msg.Content == expectedContent {
foundExpectedContent = true
break
}
}
}
assert.True(t, foundExpectedContent, "Callback events should contain the expected content")
}
func TestCallbackOnEndForWorkflowAgent(t *testing.T) {
ctx := context.Background()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
cm1 := mockModel.NewMockToolCallingChatModel(ctrl)
cm1.EXPECT().Generate(gomock.Any(), gomock.Any(), gomock.Any()).
Return(schema.AssistantMessage("response 1", nil), nil).
Times(1)
cm1.EXPECT().WithTools(gomock.Any()).Return(cm1, nil).AnyTimes()
cm2 := mockModel.NewMockToolCallingChatModel(ctrl)
cm2.EXPECT().Generate(gomock.Any(), gomock.Any(), gomock.Any()).
Return(schema.AssistantMessage("response 2", nil), nil).
Times(1)
cm2.EXPECT().WithTools(gomock.Any()).Return(cm2, nil).AnyTimes()
agent1, err := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "Agent1",
Description: "First agent",
Instruction: "You are agent 1",
Model: cm1,
})
assert.NoError(t, err)
agent2, err := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "Agent2",
Description: "Second agent",
Instruction: "You are agent 2",
Model: cm2,
})
assert.NoError(t, err)
seqAgent, err := NewSequentialAgent(ctx, &SequentialAgentConfig{
Name: "SequentialAgent",
Description: "Sequential workflow",
SubAgents: []Agent{agent1, agent2},
})
assert.NoError(t, err)
recorder := &callbackRecorder{}
handler := newRecordingHandler(recorder)
runner := NewRunner(ctx, RunnerConfig{Agent: seqAgent})
iter := runner.Query(ctx, "hello", WithCallbacks(handler))
for {
_, ok := iter.Next()
if !ok {
break
}
}
<-recorder.eventsDone
assert.True(t, recorder.getOnStartCalled(), "OnStart should be called for workflow agent")
assert.True(t, recorder.getOnEndCalled(), "OnEnd should be called for workflow agent")
assert.NotEmpty(t, recorder.getEventsReceived(), "Events should be received for workflow agent")
}
type ctxKeyForTest string
const testOnStartMarkerKey ctxKeyForTest = "onStartMarker"
func TestSubAgentContextIsolation(t *testing.T) {
ctx := context.Background()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
cm1 := mockModel.NewMockToolCallingChatModel(ctrl)
cm1.EXPECT().Generate(gomock.Any(), gomock.Any(), gomock.Any()).
Return(schema.AssistantMessage("transferring to Agent2",
[]schema.ToolCall{
{
ID: "transfer_1",
Function: schema.FunctionCall{
Name: TransferToAgentToolName,
Arguments: `{"agent_name": "Agent2"}`,
},
},
}), nil).
Times(1)
cm1.EXPECT().WithTools(gomock.Any()).Return(cm1, nil).AnyTimes()
cm2 := mockModel.NewMockToolCallingChatModel(ctrl)
cm2.EXPECT().Generate(gomock.Any(), gomock.Any(), gomock.Any()).
Return(schema.AssistantMessage("final response from Agent2", nil), nil).
Times(1)
cm2.EXPECT().WithTools(gomock.Any()).Return(cm2, nil).AnyTimes()
agent1, err := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "Agent1",
Description: "First agent that transfers to Agent2",
Instruction: "You are agent 1",
Model: cm1,
})
assert.NoError(t, err)
agent2, err := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "Agent2",
Description: "Second agent",
Instruction: "You are agent 2",
Model: cm2,
})
assert.NoError(t, err)
agentWithSubAgents, err := SetSubAgents(ctx, agent1, []Agent{agent2})
assert.NoError(t, err)
runner := NewRunner(ctx, RunnerConfig{Agent: agentWithSubAgents})
var mu sync.Mutex
onStartContextMarkers := make(map[string][]string)
handler := callbacks.NewHandlerBuilder().
OnStartFn(func(ctx context.Context, info *callbacks.RunInfo, input callbacks.CallbackInput) context.Context {
if info.Component != ComponentOfAgent {
return ctx
}
mu.Lock()
marker, _ := ctx.Value(testOnStartMarkerKey).(string)
onStartContextMarkers[info.Name] = append(onStartContextMarkers[info.Name], marker)
mu.Unlock()
return context.WithValue(ctx, testOnStartMarkerKey, info.Name+"_marker")
}).
OnEndFn(func(ctx context.Context, info *callbacks.RunInfo, output callbacks.CallbackOutput) context.Context {
if info.Component != ComponentOfAgent {
return ctx
}
if agentOutput := ConvAgentCallbackOutput(output); agentOutput != nil && agentOutput.Events != nil {
go func() {
for {
_, ok := agentOutput.Events.Next()
if !ok {
break
}
}
}()
}
return ctx
}).
Build()
iter := runner.Query(ctx, "hello", WithCallbacks(handler))
for {
_, ok := iter.Next()
if !ok {
break
}
}
mu.Lock()
defer mu.Unlock()
assert.NotEmpty(t, onStartContextMarkers["Agent1"], "Agent1's OnStart should be called")
assert.NotEmpty(t, onStartContextMarkers["Agent2"], "Agent2's OnStart should be called")
if len(onStartContextMarkers["Agent1"]) > 0 {
assert.Equal(t, "", onStartContextMarkers["Agent1"][0],
"Agent1's OnStart should receive context without marker (initial context)")
}
if len(onStartContextMarkers["Agent2"]) > 0 {
assert.Equal(t, "", onStartContextMarkers["Agent2"][0],
"Agent2's first OnStart should NOT inherit Agent1's marker - context should be isolated")
}
}
func TestCallbackDesignatedToSpecificAgent(t *testing.T) {
ctx := context.Background()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
cm1 := mockModel.NewMockToolCallingChatModel(ctrl)
cm1.EXPECT().Generate(gomock.Any(), gomock.Any(), gomock.Any()).
Return(schema.AssistantMessage("transferring to Agent2",
[]schema.ToolCall{
{
ID: "transfer_1",
Function: schema.FunctionCall{
Name: TransferToAgentToolName,
Arguments: `{"agent_name": "Agent2"}`,
},
},
}), nil).
Times(1)
cm1.EXPECT().WithTools(gomock.Any()).Return(cm1, nil).AnyTimes()
cm2 := mockModel.NewMockToolCallingChatModel(ctrl)
cm2.EXPECT().Generate(gomock.Any(), gomock.Any(), gomock.Any()).
Return(schema.AssistantMessage("final response from Agent2", nil), nil).
Times(1)
cm2.EXPECT().WithTools(gomock.Any()).Return(cm2, nil).AnyTimes()
agent1, err := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "Agent1",
Description: "First agent that transfers to Agent2",
Instruction: "You are agent 1",
Model: cm1,
})
assert.NoError(t, err)
agent2, err := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "Agent2",
Description: "Second agent",
Instruction: "You are agent 2",
Model: cm2,
})
assert.NoError(t, err)
agentWithSubAgents, err := SetSubAgents(ctx, agent1, []Agent{agent2})
assert.NoError(t, err)
runner := NewRunner(ctx, RunnerConfig{Agent: agentWithSubAgents})
var mu sync.Mutex
onStartCalls := make(map[string]int)
agent2OnlyHandler := callbacks.NewHandlerBuilder().
OnStartFn(func(ctx context.Context, info *callbacks.RunInfo, input callbacks.CallbackInput) context.Context {
if info.Component != ComponentOfAgent {
return ctx
}
mu.Lock()
onStartCalls[info.Name]++
mu.Unlock()
return ctx
}).
OnEndFn(func(ctx context.Context, info *callbacks.RunInfo, output callbacks.CallbackOutput) context.Context {
if info.Component != ComponentOfAgent {
return ctx
}
if agentOutput := ConvAgentCallbackOutput(output); agentOutput != nil && agentOutput.Events != nil {
go func() {
for {
_, ok := agentOutput.Events.Next()
if !ok {
break
}
}
}()
}
return ctx
}).
Build()
iter := runner.Query(ctx, "hello", WithCallbacks(agent2OnlyHandler).DesignateAgent("Agent2"))
for {
_, ok := iter.Next()
if !ok {
break
}
}
mu.Lock()
defer mu.Unlock()
assert.Equal(t, 0, onStartCalls["Agent1"], "Agent1's OnStart should NOT be called when handler is designated to Agent2")
assert.Equal(t, 1, onStartCalls["Agent2"], "Agent2's OnStart should be called exactly once")
}
func TestCallbackDesignatedToMultipleAgents(t *testing.T) {
ctx := context.Background()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
cm1 := mockModel.NewMockToolCallingChatModel(ctrl)
cm1.EXPECT().Generate(gomock.Any(), gomock.Any(), gomock.Any()).
Return(schema.AssistantMessage("transferring to Agent2",
[]schema.ToolCall{
{
ID: "transfer_1",
Function: schema.FunctionCall{
Name: TransferToAgentToolName,
Arguments: `{"agent_name": "Agent2"}`,
},
},
}), nil).
Times(1)
cm1.EXPECT().WithTools(gomock.Any()).Return(cm1, nil).AnyTimes()
cm2 := mockModel.NewMockToolCallingChatModel(ctrl)
cm2.EXPECT().Generate(gomock.Any(), gomock.Any(), gomock.Any()).
Return(schema.AssistantMessage("final response from Agent2", nil), nil).
Times(1)
cm2.EXPECT().WithTools(gomock.Any()).Return(cm2, nil).AnyTimes()
agent1, err := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "Agent1",
Description: "First agent",
Instruction: "You are agent 1",
Model: cm1,
})
assert.NoError(t, err)
agent2, err := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "Agent2",
Description: "Second agent",
Instruction: "You are agent 2",
Model: cm2,
})
assert.NoError(t, err)
agentWithSubAgents, err := SetSubAgents(ctx, agent1, []Agent{agent2})
assert.NoError(t, err)
runner := NewRunner(ctx, RunnerConfig{Agent: agentWithSubAgents})
var mu sync.Mutex
onStartCalls := make(map[string]int)
agent1And2Handler := callbacks.NewHandlerBuilder().
OnStartFn(func(ctx context.Context, info *callbacks.RunInfo, input callbacks.CallbackInput) context.Context {
if info.Component != ComponentOfAgent {
return ctx
}
mu.Lock()
onStartCalls[info.Name]++
mu.Unlock()
return ctx
}).
OnEndFn(func(ctx context.Context, info *callbacks.RunInfo, output callbacks.CallbackOutput) context.Context {
if info.Component != ComponentOfAgent {
return ctx
}
if agentOutput := ConvAgentCallbackOutput(output); agentOutput != nil && agentOutput.Events != nil {
go func() {
for {
_, ok := agentOutput.Events.Next()
if !ok {
break
}
}
}()
}
return ctx
}).
Build()
iter := runner.Query(ctx, "hello", WithCallbacks(agent1And2Handler).DesignateAgent("Agent1", "Agent2"))
for {
_, ok := iter.Next()
if !ok {
break
}
}
mu.Lock()
defer mu.Unlock()
assert.Equal(t, 1, onStartCalls["Agent1"], "Agent1's OnStart should be called exactly once")
assert.Equal(t, 1, onStartCalls["Agent2"], "Agent2's OnStart should be called exactly once")
}
func TestCallbackDesignatedExcludesNonMatchingAgents(t *testing.T) {
ctx := context.Background()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
cm1 := mockModel.NewMockToolCallingChatModel(ctrl)
cm1.EXPECT().Generate(gomock.Any(), gomock.Any(), gomock.Any()).
Return(schema.AssistantMessage("transferring to Agent2",
[]schema.ToolCall{
{
ID: "transfer_1",
Function: schema.FunctionCall{
Name: TransferToAgentToolName,
Arguments: `{"agent_name": "Agent2"}`,
},
},
}), nil).
Times(1)
cm1.EXPECT().WithTools(gomock.Any()).Return(cm1, nil).AnyTimes()
cm2 := mockModel.NewMockToolCallingChatModel(ctrl)
cm2.EXPECT().Generate(gomock.Any(), gomock.Any(), gomock.Any()).
Return(schema.AssistantMessage("final response from Agent2", nil), nil).
Times(1)
cm2.EXPECT().WithTools(gomock.Any()).Return(cm2, nil).AnyTimes()
agent1, err := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "Agent1",
Description: "First agent",
Instruction: "You are agent 1",
Model: cm1,
})
assert.NoError(t, err)
agent2, err := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "Agent2",
Description: "Second agent",
Instruction: "You are agent 2",
Model: cm2,
})
assert.NoError(t, err)
agentWithSubAgents, err := SetSubAgents(ctx, agent1, []Agent{agent2})
assert.NoError(t, err)
runner := NewRunner(ctx, RunnerConfig{Agent: agentWithSubAgents})
var mu sync.Mutex
onStartCalls := make(map[string]int)
agent1OnlyHandler := callbacks.NewHandlerBuilder().
OnStartFn(func(ctx context.Context, info *callbacks.RunInfo, input callbacks.CallbackInput) context.Context {
if info.Component != ComponentOfAgent {
return ctx
}
mu.Lock()
onStartCalls[info.Name]++
mu.Unlock()
return ctx
}).
OnEndFn(func(ctx context.Context, info *callbacks.RunInfo, output callbacks.CallbackOutput) context.Context {
if info.Component != ComponentOfAgent {
return ctx
}
if agentOutput := ConvAgentCallbackOutput(output); agentOutput != nil && agentOutput.Events != nil {
go func() {
for {
_, ok := agentOutput.Events.Next()
if !ok {
break
}
}
}()
}
return ctx
}).
Build()
iter := runner.Query(ctx, "hello", WithCallbacks(agent1OnlyHandler).DesignateAgent("Agent1"))
for {
_, ok := iter.Next()
if !ok {
break
}
}
mu.Lock()
defer mu.Unlock()
assert.Equal(t, 1, onStartCalls["Agent1"], "Agent1's OnStart should be called exactly once")
assert.Equal(t, 0, onStartCalls["Agent2"], "Agent2's OnStart should NOT be called when handler is designated only to Agent1")
}
func TestMixedDesignatedAndGlobalCallbacks(t *testing.T) {
ctx := context.Background()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
cm1 := mockModel.NewMockToolCallingChatModel(ctrl)
cm1.EXPECT().Generate(gomock.Any(), gomock.Any(), gomock.Any()).
Return(schema.AssistantMessage("transferring to Agent2",
[]schema.ToolCall{
{
ID: "transfer_1",
Function: schema.FunctionCall{
Name: TransferToAgentToolName,
Arguments: `{"agent_name": "Agent2"}`,
},
},
}), nil).
Times(1)
cm1.EXPECT().WithTools(gomock.Any()).Return(cm1, nil).AnyTimes()
cm2 := mockModel.NewMockToolCallingChatModel(ctrl)
cm2.EXPECT().Generate(gomock.Any(), gomock.Any(), gomock.Any()).
Return(schema.AssistantMessage("final response from Agent2", nil), nil).
Times(1)
cm2.EXPECT().WithTools(gomock.Any()).Return(cm2, nil).AnyTimes()
agent1, err := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "Agent1",
Description: "First agent that transfers to Agent2",
Instruction: "You are agent 1",
Model: cm1,
})
assert.NoError(t, err)
agent2, err := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "Agent2",
Description: "Second agent",
Instruction: "You are agent 2",
Model: cm2,
})
assert.NoError(t, err)
agentWithSubAgents, err := SetSubAgents(ctx, agent1, []Agent{agent2})
assert.NoError(t, err)
runner := NewRunner(ctx, RunnerConfig{Agent: agentWithSubAgents})
var mu sync.Mutex
globalHandlerCalls := make(map[string]int)
agent2OnlyHandlerCalls := make(map[string]int)
globalHandler := callbacks.NewHandlerBuilder().
OnStartFn(func(ctx context.Context, info *callbacks.RunInfo, input callbacks.CallbackInput) context.Context {
if info.Component != ComponentOfAgent {
return ctx
}
mu.Lock()
globalHandlerCalls[info.Name]++
mu.Unlock()
return ctx
}).
OnEndFn(func(ctx context.Context, info *callbacks.RunInfo, output callbacks.CallbackOutput) context.Context {
if info.Component != ComponentOfAgent {
return ctx
}
if agentOutput := ConvAgentCallbackOutput(output); agentOutput != nil && agentOutput.Events != nil {
go func() {
for {
_, ok := agentOutput.Events.Next()
if !ok {
break
}
}
}()
}
return ctx
}).
Build()
agent2OnlyHandler := callbacks.NewHandlerBuilder().
OnStartFn(func(ctx context.Context, info *callbacks.RunInfo, input callbacks.CallbackInput) context.Context {
if info.Component != ComponentOfAgent {
return ctx
}
mu.Lock()
agent2OnlyHandlerCalls[info.Name]++
mu.Unlock()
return ctx
}).
OnEndFn(func(ctx context.Context, info *callbacks.RunInfo, output callbacks.CallbackOutput) context.Context {
if info.Component != ComponentOfAgent {
return ctx
}
if agentOutput := ConvAgentCallbackOutput(output); agentOutput != nil && agentOutput.Events != nil {
go func() {
for {
_, ok := agentOutput.Events.Next()
if !ok {
break
}
}
}()
}
return ctx
}).
Build()
iter := runner.Query(ctx, "hello",
WithCallbacks(globalHandler),
WithCallbacks(agent2OnlyHandler).DesignateAgent("Agent2"),
)
for {
_, ok := iter.Next()
if !ok {
break
}
}
mu.Lock()
defer mu.Unlock()
assert.Equal(t, 1, globalHandlerCalls["Agent1"], "Global handler should fire for Agent1")
assert.Equal(t, 1, globalHandlerCalls["Agent2"], "Global handler should fire for Agent2")
assert.Equal(t, 0, agent2OnlyHandlerCalls["Agent1"], "Agent2-only handler should NOT fire for Agent1")
assert.Equal(t, 1, agent2OnlyHandlerCalls["Agent2"], "Agent2-only handler should fire for Agent2")
}
func TestOnStartCalledOncePerAgentWithDesignation(t *testing.T) {
ctx := context.Background()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
cm1 := mockModel.NewMockToolCallingChatModel(ctrl)
cm1.EXPECT().Generate(gomock.Any(), gomock.Any(), gomock.Any()).
Return(schema.AssistantMessage("transferring to Agent2",
[]schema.ToolCall{
{
ID: "transfer_1",
Function: schema.FunctionCall{
Name: TransferToAgentToolName,
Arguments: `{"agent_name": "Agent2"}`,
},
},
}), nil).
Times(1)
cm1.EXPECT().WithTools(gomock.Any()).Return(cm1, nil).AnyTimes()
cm2 := mockModel.NewMockToolCallingChatModel(ctrl)
cm2.EXPECT().Generate(gomock.Any(), gomock.Any(), gomock.Any()).
Return(schema.AssistantMessage("final response from Agent2", nil), nil).
Times(1)
cm2.EXPECT().WithTools(gomock.Any()).Return(cm2, nil).AnyTimes()
agent1, err := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "Agent1",
Description: "First agent that transfers to Agent2",
Instruction: "You are agent 1",
Model: cm1,
})
assert.NoError(t, err)
agent2, err := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "Agent2",
Description: "Second agent",
Instruction: "You are agent 2",
Model: cm2,
})
assert.NoError(t, err)
agentWithSubAgents, err := SetSubAgents(ctx, agent1, []Agent{agent2})
assert.NoError(t, err)
runner := NewRunner(ctx, RunnerConfig{Agent: agentWithSubAgents})
var mu sync.Mutex
onStartCalls := make(map[string]int)
handler := callbacks.NewHandlerBuilder().
OnStartFn(func(ctx context.Context, info *callbacks.RunInfo, input callbacks.CallbackInput) context.Context {
if info.Component != ComponentOfAgent {
return ctx
}
mu.Lock()
onStartCalls[info.Name]++
mu.Unlock()
return ctx
}).
OnEndFn(func(ctx context.Context, info *callbacks.RunInfo, output callbacks.CallbackOutput) context.Context {
if info.Component != ComponentOfAgent {
return ctx
}
if agentOutput := ConvAgentCallbackOutput(output); agentOutput != nil && agentOutput.Events != nil {
go func() {
for {
_, ok := agentOutput.Events.Next()
if !ok {
break
}
}
}()
}
return ctx
}).
Build()
iter := runner.Query(ctx, "hello", WithCallbacks(handler))
for {
_, ok := iter.Next()
if !ok {
break
}
}
mu.Lock()
defer mu.Unlock()
assert.Equal(t, 1, onStartCalls["Agent1"], "Agent1's OnStart should be called exactly once")
assert.Equal(t, 1, onStartCalls["Agent2"], "Agent2's OnStart should be called exactly once")
}
================================================
FILE: adk/callback_test.go
================================================
/*
* Copyright 2026 CloudWeGo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package adk
import (
"context"
"sync"
"testing"
"github.com/stretchr/testify/assert"
"github.com/cloudwego/eino/callbacks"
"github.com/cloudwego/eino/schema"
)
func TestCopyEventIterator(t *testing.T) {
t.Run("n=0 returns nil", func(t *testing.T) {
iter, gen := NewAsyncIteratorPair[*AgentEvent]()
go func() {
gen.Send(&AgentEvent{AgentName: "test"})
gen.Close()
}()
result := copyEventIterator(iter, 0)
assert.Nil(t, result)
})
t.Run("n=1 returns original iterator", func(t *testing.T) {
iter, gen := NewAsyncIteratorPair[*AgentEvent]()
go func() {
gen.Send(&AgentEvent{AgentName: "test"})
gen.Close()
}()
result := copyEventIterator(iter, 1)
assert.Len(t, result, 1)
assert.Equal(t, iter, result[0])
})
t.Run("n>1 creates n independent copies", func(t *testing.T) {
iter, gen := NewAsyncIteratorPair[*AgentEvent]()
events := []*AgentEvent{
{AgentName: "agent1", Output: &AgentOutput{MessageOutput: &MessageVariant{Message: schema.AssistantMessage("msg1", nil)}}},
{AgentName: "agent2", Output: &AgentOutput{MessageOutput: &MessageVariant{Message: schema.AssistantMessage("msg2", nil)}}},
}
go func() {
for _, e := range events {
gen.Send(e)
}
gen.Close()
}()
n := 3
copies := copyEventIterator(iter, n)
assert.Len(t, copies, n)
var wg sync.WaitGroup
receivedEvents := make([][]*AgentEvent, n)
for i := 0; i < n; i++ {
wg.Add(1)
go func(idx int) {
defer wg.Done()
for {
event, ok := copies[idx].Next()
if !ok {
break
}
receivedEvents[idx] = append(receivedEvents[idx], event)
}
}(i)
}
wg.Wait()
for i := 0; i < n; i++ {
assert.Len(t, receivedEvents[i], len(events), "iterator %d should receive all events", i)
for j, e := range receivedEvents[i] {
assert.Equal(t, events[j].AgentName, e.AgentName)
}
}
})
}
func TestCopyAgentCallbackOutput(t *testing.T) {
t.Run("nil output", func(t *testing.T) {
result := copyAgentCallbackOutput(nil, 3)
assert.Len(t, result, 3)
for _, r := range result {
assert.Nil(t, r)
}
})
t.Run("output with nil Events", func(t *testing.T) {
out := &AgentCallbackOutput{Events: nil}
result := copyAgentCallbackOutput(out, 3)
assert.Len(t, result, 3)
for _, r := range result {
assert.Equal(t, out, r)
}
})
t.Run("valid output with events", func(t *testing.T) {
iter, gen := NewAsyncIteratorPair[*AgentEvent]()
go func() {
gen.Send(&AgentEvent{AgentName: "test"})
gen.Close()
}()
out := &AgentCallbackOutput{Events: iter}
result := copyAgentCallbackOutput(out, 2)
assert.Len(t, result, 2)
for i, r := range result {
assert.NotNil(t, r, "result[%d] should not be nil", i)
assert.NotNil(t, r.Events, "result[%d].Events should not be nil", i)
}
})
}
func TestConvAgentCallbackInput(t *testing.T) {
t.Run("valid AgentCallbackInput", func(t *testing.T) {
input := &AgentCallbackInput{
Input: &AgentInput{Messages: []Message{schema.UserMessage("test")}},
}
result := ConvAgentCallbackInput(input)
assert.Equal(t, input, result)
})
t.Run("invalid type returns nil", func(t *testing.T) {
result := ConvAgentCallbackInput("invalid")
assert.Nil(t, result)
})
t.Run("nil returns nil", func(t *testing.T) {
result := ConvAgentCallbackInput(nil)
assert.Nil(t, result)
})
}
func TestConvAgentCallbackOutput(t *testing.T) {
t.Run("valid AgentCallbackOutput", func(t *testing.T) {
iter, _ := NewAsyncIteratorPair[*AgentEvent]()
output := &AgentCallbackOutput{Events: iter}
result := ConvAgentCallbackOutput(output)
assert.Equal(t, output, result)
})
t.Run("invalid type returns nil", func(t *testing.T) {
result := ConvAgentCallbackOutput("invalid")
assert.Nil(t, result)
})
t.Run("nil returns nil", func(t *testing.T) {
result := ConvAgentCallbackOutput(nil)
assert.Nil(t, result)
})
}
type mockTyperAgent struct {
name string
agentType string
}
func (a *mockTyperAgent) Name(_ context.Context) string { return a.name }
func (a *mockTyperAgent) Description(_ context.Context) string { return "mock agent" }
func (a *mockTyperAgent) GetType() string { return a.agentType }
func (a *mockTyperAgent) Run(_ context.Context, _ *AgentInput, _ ...AgentRunOption) *AsyncIterator[*AgentEvent] {
iter, gen := NewAsyncIteratorPair[*AgentEvent]()
gen.Close()
return iter
}
type mockNonTyperAgent struct {
name string
}
func (a *mockNonTyperAgent) Name(_ context.Context) string { return a.name }
func (a *mockNonTyperAgent) Description(_ context.Context) string { return "mock agent" }
func (a *mockNonTyperAgent) Run(_ context.Context, _ *AgentInput, _ ...AgentRunOption) *AsyncIterator[*AgentEvent] {
iter, gen := NewAsyncIteratorPair[*AgentEvent]()
gen.Close()
return iter
}
func TestGetAgentType(t *testing.T) {
t.Run("agent implementing Typer", func(t *testing.T) {
agent := &mockTyperAgent{name: "test", agentType: "CustomType"}
result := getAgentType(agent)
assert.Equal(t, "CustomType", result)
})
t.Run("agent not implementing Typer", func(t *testing.T) {
agent := &mockNonTyperAgent{name: "test"}
result := getAgentType(agent)
assert.Equal(t, "", result)
})
}
func TestWithCallbacksOption(t *testing.T) {
handler := callbacks.NewHandlerBuilder().
OnStartFn(func(ctx context.Context, info *callbacks.RunInfo, input callbacks.CallbackInput) context.Context {
return ctx
}).
Build()
opt := WithCallbacks(handler)
opts := getCommonOptions(nil, opt)
assert.Len(t, opts.handlers, 1)
}
func TestWithMultipleCallbacksOption(t *testing.T) {
handler1 := callbacks.NewHandlerBuilder().Build()
handler2 := callbacks.NewHandlerBuilder().Build()
opt := WithCallbacks(handler1, handler2)
opts := getCommonOptions(nil, opt)
assert.Len(t, opts.handlers, 2)
}
================================================
FILE: adk/chatmodel.go
================================================
/*
* Copyright 2025 CloudWeGo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package adk
import (
"bytes"
"context"
"encoding/gob"
"errors"
"fmt"
"math"
"runtime/debug"
"sync"
"sync/atomic"
"github.com/bytedance/sonic"
"github.com/cloudwego/eino/adk/internal"
"github.com/cloudwego/eino/components/model"
"github.com/cloudwego/eino/components/prompt"
"github.com/cloudwego/eino/components/tool"
"github.com/cloudwego/eino/compose"
"github.com/cloudwego/eino/internal/safe"
"github.com/cloudwego/eino/schema"
)
type chatModelAgentExecCtx struct {
runtimeReturnDirectly map[string]bool
generator *AsyncGenerator[*AgentEvent]
}
func (e *chatModelAgentExecCtx) send(event *AgentEvent) {
if e != nil && e.generator != nil {
e.generator.Send(event)
}
}
type chatModelAgentExecCtxKey struct{}
func withChatModelAgentExecCtx(ctx context.Context, execCtx *chatModelAgentExecCtx) context.Context {
return context.WithValue(ctx, chatModelAgentExecCtxKey{}, execCtx)
}
func getChatModelAgentExecCtx(ctx context.Context) *chatModelAgentExecCtx {
if v := ctx.Value(chatModelAgentExecCtxKey{}); v != nil {
return v.(*chatModelAgentExecCtx)
}
return nil
}
type chatModelAgentRunOptions struct {
chatModelOptions []model.Option
toolOptions []tool.Option
agentToolOptions map[string][]AgentRunOption
historyModifier func(context.Context, []Message) []Message
}
// WithChatModelOptions sets options for the underlying chat model.
func WithChatModelOptions(opts []model.Option) AgentRunOption {
return WrapImplSpecificOptFn(func(t *chatModelAgentRunOptions) {
t.chatModelOptions = opts
})
}
// WithToolOptions sets options for tools used by the chat model agent.
func WithToolOptions(opts []tool.Option) AgentRunOption {
return WrapImplSpecificOptFn(func(t *chatModelAgentRunOptions) {
t.toolOptions = opts
})
}
// WithAgentToolRunOptions specifies per-tool run options for the agent.
func WithAgentToolRunOptions(opts map[string][]AgentRunOption) AgentRunOption {
return WrapImplSpecificOptFn(func(t *chatModelAgentRunOptions) {
t.agentToolOptions = opts
})
}
// WithHistoryModifier sets a function to modify history during resume.
// Deprecated: use ResumeWithData and ChatModelAgentResumeData instead.
func WithHistoryModifier(f func(context.Context, []Message) []Message) AgentRunOption {
return WrapImplSpecificOptFn(func(t *chatModelAgentRunOptions) {
t.historyModifier = f
})
}
type ToolsConfig struct {
compose.ToolsNodeConfig
// ReturnDirectly specifies tools that cause the agent to return immediately when called.
// If multiple listed tools are called simultaneously, only the first one triggers the return.
// The map keys are tool names indicate whether the tool should trigger immediate return.
ReturnDirectly map[string]bool
// EmitInternalEvents indicates whether internal events from agentTool should be emitted
// to the parent agent's AsyncGenerator, allowing real-time streaming of nested agent output
// to the end-user via Runner.
//
// Note that these forwarded events are NOT recorded in the parent agent's runSession.
// They are only emitted to the end-user and have no effect on the parent agent's state
// or checkpoint.
//
// Action Scoping:
// Actions emitted by the inner agent are scoped to the agent tool boundary:
// - Interrupted: Propagated via CompositeInterrupt to allow proper interrupt/resume
// - Exit, TransferToAgent, BreakLoop: Ignored outside the agent tool
EmitInternalEvents bool
}
// GenModelInput transforms agent instructions and input into a format suitable for the model.
type GenModelInput func(ctx context.Context, instruction string, input *AgentInput) ([]Message, error)
func defaultGenModelInput(ctx context.Context, instruction string, input *AgentInput) ([]Message, error) {
msgs := make([]Message, 0, len(input.Messages)+1)
if instruction != "" {
sp := schema.SystemMessage(instruction)
vs := GetSessionValues(ctx)
if len(vs) > 0 {
ct := prompt.FromMessages(schema.FString, sp)
ms, err := ct.Format(ctx, vs)
if err != nil {
return nil, fmt.Errorf("defaultGenModelInput: failed to format instruction using FString template. "+
"This formatting is triggered automatically when SessionValues are present. "+
"If your instruction contains literal curly braces (e.g., JSON), provide a custom GenModelInput that uses another format. If you are using "+
"SessionValues for purposes other than instruction formatting, provide a custom GenModelInput that does no formatting at all: %w", err)
}
sp = ms[0]
}
msgs = append(msgs, sp)
}
msgs = append(msgs, input.Messages...)
return msgs, nil
}
// ChatModelAgentState represents the state of a chat model agent during conversation.
// This is the primary state type for both ChatModelAgentMiddleware and AgentMiddleware callbacks.
type ChatModelAgentState struct {
// Messages contains all messages in the current conversation session.
Messages []Message
}
// AgentMiddleware provides hooks to customize agent behavior at various stages of execution.
//
// Limitations of AgentMiddleware (struct-based):
// - Struct types are closed: users cannot add new methods
// - Callbacks only return error, cannot return modified context
// - Configuration is scattered across closures when using factory functions
//
// For new code requiring extensibility, consider using ChatModelAgentMiddleware (interface-based) instead.
// AgentMiddleware is kept for backward compatibility and remains suitable for simple,
// static additions like extra instruction or tools.
//
// See ChatModelAgentMiddleware documentation for detailed comparison.
type AgentMiddleware struct {
// AdditionalInstruction adds supplementary text to the agent's system instruction.
// This instruction is concatenated with the base instruction before each chat model call.
AdditionalInstruction string
// AdditionalTools adds supplementary tools to the agent's available toolset.
// These tools are combined with the tools configured for the agent.
AdditionalTools []tool.BaseTool
// BeforeChatModel is called before each ChatModel invocation, allowing modification of the agent state.
BeforeChatModel func(context.Context, *ChatModelAgentState) error
// AfterChatModel is called after each ChatModel invocation, allowing modification of the agent state.
AfterChatModel func(context.Context, *ChatModelAgentState) error
// WrapToolCall wraps tool calls with custom middleware logic.
// Each middleware contains Invokable and/or Streamable functions for tool calls.
WrapToolCall compose.ToolMiddleware
}
type ChatModelAgentConfig struct {
// Name of the agent. Better be unique across all agents.
Name string
// Description of the agent's capabilities.
// Helps other agents determine whether to transfer tasks to this agent.
Description string
// Instruction used as the system prompt for this agent.
// Optional. If empty, no system prompt will be used.
// Supports f-string placeholders for session values in default GenModelInput, for example:
// "You are a helpful assistant. The current time is {Time}. The current user is {User}."
// These placeholders will be replaced with session values for "Time" and "User".
Instruction string
// Model is the chat model used by the agent.
// If your ChatModelAgent uses any tools, this model must support the model.WithTools
// call option, as that's how ChatModelAgent configures the model with tool information.
Model model.BaseChatModel
ToolsConfig ToolsConfig
// GenModelInput transforms instructions and input messages into the model's input format.
// Optional. Defaults to defaultGenModelInput which combines instruction and messages.
GenModelInput GenModelInput
// Exit defines the tool used to terminate the agent process.
// Optional. If nil, no Exit Action will be generated.
// You can use the provided 'ExitTool' implementation directly.
Exit tool.BaseTool
// OutputKey stores the agent's response in the session.
// Optional. When set, stores output via AddSessionValue(ctx, outputKey, msg.Content).
OutputKey string
// MaxIterations defines the upper limit of ChatModel generation cycles.
// The agent will terminate with an error if this limit is exceeded.
// Optional. Defaults to 20.
MaxIterations int
// Middlewares configures agent middleware for extending functionality.
// Use for simple, static additions like extra instruction or tools.
// Kept for backward compatibility; for new code, consider using Handlers instead.
Middlewares []AgentMiddleware
// Handlers configures interface-based handlers for extending agent behavior.
// Unlike Middlewares (struct-based), Handlers allow users to:
// - Add custom methods to their handler implementations
// - Return modified context from handler methods
// - Centralize configuration in struct fields instead of closures
//
// Handlers are processed after Middlewares, in registration order.
// See ChatModelAgentMiddleware documentation for when to use Handlers vs Middlewares.
//
// Execution Order (relative to AgentMiddleware and ToolsConfig):
//
// Model call lifecycle (outermost to innermost wrapper chain):
// 1. AgentMiddleware.BeforeChatModel (hook, runs before model call)
// 2. ChatModelAgentMiddleware.BeforeModelRewriteState (hook, can modify state before model call)
// 3. retryModelWrapper (internal - retries on failure, if configured)
// 4. eventSenderModelWrapper (internal - sends model response events)
// 5. ChatModelAgentMiddleware.WrapModel (wrapper, first registered is outermost)
// 6. callbackInjectionModelWrapper (internal - injects callbacks if not enabled)
// 7. Model.Generate/Stream
// 8. ChatModelAgentMiddleware.AfterModelRewriteState (hook, can modify state after model call)
// 9. AgentMiddleware.AfterChatModel (hook, runs after model call)
//
// Custom Event Sender Position:
// By default, events are sent after all user middlewares (WrapModel) have processed the output,
// containing the modified messages. To send events with original (unmodified) output, pass
// NewEventSenderModelWrapper as a Handler after the modifying middleware:
//
// agent, _ := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
// Handlers: []adk.ChatModelAgentMiddleware{
// myCustomHandler, // First registered = outermost wrapper
// adk.NewEventSenderModelWrapper(), // Last registered = innermost, events sent with original output
// },
// })
//
// Handler order: first registered is outermost. So [A, B, C] becomes A(B(C(model))).
// EventSenderModelWrapper sends events in post-processing, so placing it innermost
// means it receives the original model output before outer handlers modify it.
//
// When EventSenderModelWrapper is detected in Handlers, the framework skips
// the default event sender to avoid duplicate events.
//
// Tool call lifecycle (outermost to innermost):
// 1. eventSenderToolHandler (internal ToolMiddleware - sends tool result events after all processing)
// 2. ToolsConfig.ToolCallMiddlewares (ToolMiddleware)
// 3. AgentMiddleware.WrapToolCall (ToolMiddleware)
// 4. ChatModelAgentMiddleware.WrapToolCall (wrapper, first registered is outermost)
// 5. callbackInjectedToolCall (internal - injects callbacks if tool doesn't handle them)
// 6. Tool.InvokableRun/StreamableRun
//
// Tool List Modification:
//
// There are two ways to modify the tool list:
//
// 1. In BeforeAgent: Modify ChatModelAgentContext.Tools ([]tool.BaseTool) directly. This affects
// both the tool info list passed to ChatModel AND the actual tools available for
// execution. Changes persist for the entire agent run.
//
// 2. In WrapModel: Create a model wrapper that modifies the tool info list per model
// request using model.WithTools(toolInfos). This ONLY affects the tool info list
// passed to ChatModel, NOT the actual tools available for execution. Use this for
// dynamic tool filtering/selection based on conversation context. The modification
// is scoped to this model request only.
Handlers []ChatModelAgentMiddleware
// ModelRetryConfig configures retry behavior for the ChatModel.
// When set, the agent will automatically retry failed ChatModel calls
// based on the configured policy.
// Optional. If nil, no retry will be performed.
ModelRetryConfig *ModelRetryConfig
}
type ChatModelAgent struct {
name string
description string
instruction string
model model.BaseChatModel
toolsConfig ToolsConfig
genModelInput GenModelInput
outputKey string
maxIterations int
subAgents []Agent
parentAgent Agent
disallowTransferToParent bool
exit tool.BaseTool
handlers []ChatModelAgentMiddleware
middlewares []AgentMiddleware
modelRetryConfig *ModelRetryConfig
once sync.Once
run runFunc
frozen uint32
exeCtx *execContext
}
type runFunc func(ctx context.Context, input *AgentInput, generator *AsyncGenerator[*AgentEvent], store *bridgeStore, instruction string, returnDirectly map[string]bool, opts ...compose.Option)
// NewChatModelAgent constructs a chat model-backed agent with the provided config.
func NewChatModelAgent(ctx context.Context, config *ChatModelAgentConfig) (*ChatModelAgent, error) {
if config.Name == "" {
return nil, errors.New("agent 'Name' is required")
}
if config.Description == "" {
return nil, errors.New("agent 'Description' is required")
}
if config.Model == nil {
return nil, errors.New("agent 'Model' is required")
}
genInput := defaultGenModelInput
if config.GenModelInput != nil {
genInput = config.GenModelInput
}
tc := config.ToolsConfig
// Tool call middleware execution order (outermost to innermost):
// 1. eventSenderToolHandler (internal - sends tool result events after all modifications)
// 2. User-provided ToolsConfig.ToolCallMiddlewares (original order preserved)
// 3. Middlewares' WrapToolCall (in registration order)
// 4. ChatModelAgentMiddleware.WrapToolCall (in registration order)
// 5. callbackInjectedToolCall (internal - injects callbacks if tool doesn't handle them)
eventSender := &eventSenderToolHandler{}
tc.ToolCallMiddlewares = append(
[]compose.ToolMiddleware{{Invokable: eventSender.WrapInvokableToolCall,
Streamable: eventSender.WrapStreamableToolCall,
EnhancedInvokable: eventSender.WrapEnhancedInvokableToolCall,
EnhancedStreamable: eventSender.WrapEnhancedStreamableToolCall,
}},
tc.ToolCallMiddlewares...,
)
tc.ToolCallMiddlewares = append(tc.ToolCallMiddlewares, collectToolMiddlewaresFromMiddlewares(config.Middlewares)...)
return &ChatModelAgent{
name: config.Name,
description: config.Description,
instruction: config.Instruction,
model: config.Model,
toolsConfig: tc,
genModelInput: genInput,
exit: config.Exit,
outputKey: config.OutputKey,
maxIterations: config.MaxIterations,
handlers: config.Handlers,
middlewares: config.Middlewares,
modelRetryConfig: config.ModelRetryConfig,
}, nil
}
func collectToolMiddlewaresFromMiddlewares(mws []AgentMiddleware) []compose.ToolMiddleware {
var middlewares []compose.ToolMiddleware
for _, m := range mws {
if m.WrapToolCall.Invokable == nil && m.WrapToolCall.Streamable == nil {
continue
}
middlewares = append(middlewares, m.WrapToolCall)
}
return middlewares
}
const (
TransferToAgentToolName = "transfer_to_agent"
TransferToAgentToolDesc = "Transfer the question to another agent."
TransferToAgentToolDescChinese = "将问题移交给其他 Agent。"
)
var (
toolInfoTransferToAgent = &schema.ToolInfo{
Name: TransferToAgentToolName,
ParamsOneOf: schema.NewParamsOneOfByParams(map[string]*schema.ParameterInfo{
"agent_name": {
Desc: "the name of the agent to transfer to",
Required: true,
Type: schema.String,
},
}),
}
ToolInfoExit = &schema.ToolInfo{
Name: "exit",
Desc: "Exit the agent process and return the final result.",
ParamsOneOf: schema.NewParamsOneOfByParams(map[string]*schema.ParameterInfo{
"final_result": {
Desc: "the final result to return",
Required: true,
Type: schema.String,
},
}),
}
)
type ExitTool struct{}
func (et ExitTool) Info(_ context.Context) (*schema.ToolInfo, error) {
return ToolInfoExit, nil
}
func (et ExitTool) InvokableRun(ctx context.Context, argumentsInJSON string, _ ...tool.Option) (string, error) {
type exitParams struct {
FinalResult string `json:"final_result"`
}
params := &exitParams{}
err := sonic.UnmarshalString(argumentsInJSON, params)
if err != nil {
return "", err
}
err = SendToolGenAction(ctx, "exit", NewExitAction())
if err != nil {
return "", err
}
return params.FinalResult, nil
}
type transferToAgent struct{}
func (tta transferToAgent) Info(_ context.Context) (*schema.ToolInfo, error) {
desc := internal.SelectPrompt(internal.I18nPrompts{
English: TransferToAgentToolDesc,
Chinese: TransferToAgentToolDescChinese,
})
info := *toolInfoTransferToAgent
info.Desc = desc
return &info, nil
}
func transferToAgentToolOutput(destName string) string {
tpl := internal.SelectPrompt(internal.I18nPrompts{
English: "successfully transferred to agent [%s]",
Chinese: "成功移交任务至 agent [%s]",
})
return fmt.Sprintf(tpl, destName)
}
func (tta transferToAgent) InvokableRun(ctx context.Context, argumentsInJSON string, _ ...tool.Option) (string, error) {
type transferParams struct {
AgentName string `json:"agent_name"`
}
params := &transferParams{}
err := sonic.UnmarshalString(argumentsInJSON, params)
if err != nil {
return "", err
}
err = SendToolGenAction(ctx, TransferToAgentToolName, NewTransferToAgentAction(params.AgentName))
if err != nil {
return "", err
}
return transferToAgentToolOutput(params.AgentName), nil
}
func (a *ChatModelAgent) Name(_ context.Context) string {
return a.name
}
func (a *ChatModelAgent) Description(_ context.Context) string {
return a.description
}
func (a *ChatModelAgent) GetType() string {
return "ChatModel"
}
func (a *ChatModelAgent) OnSetSubAgents(_ context.Context, subAgents []Agent) error {
if atomic.LoadUint32(&a.frozen) == 1 {
return errors.New("agent has been frozen after run")
}
if len(a.subAgents) > 0 {
return errors.New("agent's sub-agents has already been set")
}
a.subAgents = subAgents
return nil
}
func (a *ChatModelAgent) OnSetAsSubAgent(_ context.Context, parent Agent) error {
if atomic.LoadUint32(&a.frozen) == 1 {
return errors.New("agent has been frozen after run")
}
if a.parentAgent != nil {
return errors.New("agent has already been set as a sub-agent of another agent")
}
a.parentAgent = parent
return nil
}
func (a *ChatModelAgent) OnDisallowTransferToParent(_ context.Context) error {
if atomic.LoadUint32(&a.frozen) == 1 {
return errors.New("agent has been frozen after run")
}
a.disallowTransferToParent = true
return nil
}
type ChatModelAgentInterruptInfo struct {
Info *compose.InterruptInfo
Data []byte
}
func init() {
schema.RegisterName[*ChatModelAgentInterruptInfo]("_eino_adk_chat_model_agent_interrupt_info")
}
func setOutputToSession(ctx context.Context, msg Message, msgStream MessageStream, outputKey string) error {
if msg != nil {
AddSessionValue(ctx, outputKey, msg.Content)
return nil
}
concatenated, err := schema.ConcatMessageStream(msgStream)
if err != nil {
return err
}
AddSessionValue(ctx, outputKey, concatenated.Content)
return nil
}
func errFunc(err error) runFunc {
return func(ctx context.Context, input *AgentInput, generator *AsyncGenerator[*AgentEvent], store *bridgeStore, _ string, _ map[string]bool, _ ...compose.Option) {
generator.Send(&AgentEvent{Err: err})
}
}
// ChatModelAgentResumeData holds data that can be provided to a ChatModelAgent during a resume operation
// to modify its behavior. It is provided via the adk.ResumeWithData function.
type ChatModelAgentResumeData struct {
// HistoryModifier is a function that can transform the agent's message history before it is sent to the model.
// This allows for adding new information or context upon resumption.
HistoryModifier func(ctx context.Context, history []Message) []Message
}
type execContext struct {
instruction string
toolsNodeConf compose.ToolsNodeConfig
returnDirectly map[string]bool
toolInfos []*schema.ToolInfo
unwrappedTools []tool.BaseTool
rebuildGraph bool // whether needs to instantiate a new graph because of topology changes due to tool modifications
toolUpdated bool // whether needs to pass a compose.WithToolList option to ToolsNode due to tool list change
}
func (a *ChatModelAgent) applyBeforeAgent(ctx context.Context, ec *execContext) (context.Context, *execContext, error) {
runCtx := &ChatModelAgentContext{
Instruction: ec.instruction,
Tools: cloneSlice(ec.unwrappedTools),
ReturnDirectly: copyMap(ec.returnDirectly),
}
var err error
for i, handler := range a.handlers {
ctx, runCtx, err = handler.BeforeAgent(ctx, runCtx)
if err != nil {
return ctx, nil, fmt.Errorf("handler[%d] (%T) BeforeAgent failed: %w", i, handler, err)
}
}
runtimeEC := &execContext{
instruction: runCtx.Instruction,
toolsNodeConf: compose.ToolsNodeConfig{
Tools: runCtx.Tools,
ToolCallMiddlewares: cloneSlice(ec.toolsNodeConf.ToolCallMiddlewares),
},
returnDirectly: runCtx.ReturnDirectly,
toolUpdated: true,
rebuildGraph: (len(ec.toolsNodeConf.Tools) == 0 && len(runCtx.Tools) > 0) ||
(len(ec.returnDirectly) == 0 && len(runCtx.ReturnDirectly) > 0),
}
toolInfos, err := genToolInfos(ctx, &runtimeEC.toolsNodeConf)
if err != nil {
return ctx, nil, err
}
runtimeEC.toolInfos = toolInfos
return ctx, runtimeEC, nil
}
func (a *ChatModelAgent) prepareExecContext(ctx context.Context) (*execContext, error) {
instruction := a.instruction
toolsNodeConf := compose.ToolsNodeConfig{
Tools: cloneSlice(a.toolsConfig.Tools),
ToolCallMiddlewares: cloneSlice(a.toolsConfig.ToolCallMiddlewares),
UnknownToolsHandler: a.toolsConfig.UnknownToolsHandler,
ExecuteSequentially: a.toolsConfig.ExecuteSequentially,
ToolArgumentsHandler: a.toolsConfig.ToolArgumentsHandler,
}
returnDirectly := copyMap(a.toolsConfig.ReturnDirectly)
transferToAgents := a.subAgents
if a.parentAgent != nil && !a.disallowTransferToParent {
transferToAgents = append(transferToAgents, a.parentAgent)
}
if len(transferToAgents) > 0 {
transferInstruction := genTransferToAgentInstruction(ctx, transferToAgents)
instruction = concatInstructions(instruction, transferInstruction)
toolsNodeConf.Tools = append(toolsNodeConf.Tools, &transferToAgent{})
returnDirectly[TransferToAgentToolName] = true
}
if a.exit != nil {
toolsNodeConf.Tools = append(toolsNodeConf.Tools, a.exit)
exitInfo, err := a.exit.Info(ctx)
if err != nil {
return nil, err
}
returnDirectly[exitInfo.Name] = true
}
for _, m := range a.middlewares {
if m.AdditionalInstruction != "" {
instruction = concatInstructions(instruction, m.AdditionalInstruction)
}
toolsNodeConf.Tools = append(toolsNodeConf.Tools, m.AdditionalTools...)
}
unwrappedTools := cloneSlice(toolsNodeConf.Tools)
handlerMiddlewares := handlersToToolMiddlewares(a.handlers)
toolsNodeConf.ToolCallMiddlewares = append(toolsNodeConf.ToolCallMiddlewares, handlerMiddlewares...)
toolInfos, err := genToolInfos(ctx, &toolsNodeConf)
if err != nil {
return nil, err
}
return &execContext{
instruction: instruction,
toolsNodeConf: toolsNodeConf,
returnDirectly: returnDirectly,
toolInfos: toolInfos,
unwrappedTools: unwrappedTools,
}, nil
}
func (a *ChatModelAgent) buildNoToolsRunFunc(_ context.Context) runFunc {
wrappedModel := buildModelWrappers(a.model, &modelWrapperConfig{
handlers: a.handlers,
middlewares: a.middlewares,
retryConfig: a.modelRetryConfig,
})
type noToolsInput struct {
input *AgentInput
instruction string
}
return func(ctx context.Context, input *AgentInput, generator *AsyncGenerator[*AgentEvent],
store *bridgeStore, instruction string, _ map[string]bool, opts ...compose.Option) {
chain := compose.NewChain[noToolsInput, Message](
compose.WithGenLocalState(func(ctx context.Context) (state *State) {
return &State{}
})).
AppendLambda(compose.InvokableLambda(func(ctx context.Context, in noToolsInput) ([]Message, error) {
messages, err := a.genModelInput(ctx, in.instruction, in.input)
if err != nil {
return nil, err
}
return messages, nil
})).
AppendChatModel(wrappedModel)
r, err := chain.Compile(ctx, compose.WithGraphName(a.name),
compose.WithCheckPointStore(store),
compose.WithSerializer(&gobSerializer{}))
if err != nil {
generator.Send(&AgentEvent{Err: err})
return
}
ctx = withChatModelAgentExecCtx(ctx, &chatModelAgentExecCtx{
generator: generator,
})
in := noToolsInput{input: input, instruction: instruction}
var msg Message
var msgStream MessageStream
if input.EnableStreaming {
msgStream, err = r.Stream(ctx, in, opts...)
} else {
msg, err = r.Invoke(ctx, in, opts...)
}
if err == nil {
if a.outputKey != "" {
err = setOutputToSession(ctx, msg, msgStream, a.outputKey)
if err != nil {
generator.Send(&AgentEvent{Err: err})
}
} else if msgStream != nil {
msgStream.Close()
}
} else {
generator.Send(&AgentEvent{Err: err})
}
}
}
func (a *ChatModelAgent) buildReactRunFunc(ctx context.Context, bc *execContext) (runFunc, error) {
conf := &reactConfig{
model: a.model,
toolsConfig: &bc.toolsNodeConf,
modelWrapperConf: &modelWrapperConfig{
handlers: a.handlers,
middlewares: a.middlewares,
retryConfig: a.modelRetryConfig,
toolInfos: bc.toolInfos,
},
toolsReturnDirectly: bc.returnDirectly,
agentName: a.name,
maxIterations: a.maxIterations,
}
type reactRunInput struct {
input *AgentInput
instruction string
}
return func(ctx context.Context, input *AgentInput, generator *AsyncGenerator[*AgentEvent], store *bridgeStore,
instruction string, returnDirectly map[string]bool, opts ...compose.Option) {
g, err := newReact(ctx, conf)
if err != nil {
generator.Send(&AgentEvent{Err: err})
return
}
chain := compose.NewChain[reactRunInput, Message]().
AppendLambda(
compose.InvokableLambda(func(ctx context.Context, in reactRunInput) (*reactInput, error) {
messages, genErr := a.genModelInput(ctx, in.instruction, in.input)
if genErr != nil {
return nil, genErr
}
return &reactInput{
messages: messages,
}, nil
}),
).
AppendGraph(g, compose.WithNodeName("ReAct"), compose.WithGraphCompileOptions(compose.WithMaxRunSteps(math.MaxInt)))
var compileOptions []compose.GraphCompileOption
compileOptions = append(compileOptions,
compose.WithGraphName(a.name),
compose.WithCheckPointStore(store),
compose.WithSerializer(&gobSerializer{}),
compose.WithMaxRunSteps(math.MaxInt))
runnable, err_ := chain.Compile(ctx, compileOptions...)
if err_ != nil {
generator.Send(&AgentEvent{Err: err_})
return
}
ctx = withChatModelAgentExecCtx(ctx, &chatModelAgentExecCtx{
runtimeReturnDirectly: returnDirectly,
generator: generator,
})
in := reactRunInput{
input: input,
instruction: instruction,
}
var runOpts []compose.Option
runOpts = append(runOpts, opts...)
if a.toolsConfig.EmitInternalEvents {
runOpts = append(runOpts, compose.WithToolsNodeOption(compose.WithToolOption(withAgentToolEventGenerator(generator))))
}
if input.EnableStreaming {
runOpts = append(runOpts, compose.WithToolsNodeOption(compose.WithToolOption(withAgentToolEnableStreaming(true))))
}
var msg Message
var msgStream MessageStream
if input.EnableStreaming {
msgStream, err_ = runnable.Stream(ctx, in, runOpts...)
} else {
msg, err_ = runnable.Invoke(ctx, in, runOpts...)
}
if err_ == nil {
if a.outputKey != "" {
err_ = setOutputToSession(ctx, msg, msgStream, a.outputKey)
if err_ != nil {
generator.Send(&AgentEvent{Err: err_})
}
} else if msgStream != nil {
msgStream.Close()
}
return
}
info, ok := compose.ExtractInterruptInfo(err_)
if !ok {
generator.Send(&AgentEvent{Err: err_})
return
}
data, existed, err := store.Get(ctx, bridgeCheckpointID)
if err != nil {
generator.Send(&AgentEvent{AgentName: a.name, Err: fmt.Errorf("failed to get interrupt info: %w", err)})
return
}
if !existed {
generator.Send(&AgentEvent{AgentName: a.name, Err: fmt.Errorf("interrupt occurred but checkpoint data is missing")})
return
}
is := FromInterruptContexts(info.InterruptContexts)
event := CompositeInterrupt(ctx, info, data, is)
event.Action.Interrupted.Data = &ChatModelAgentInterruptInfo{
Info: info,
Data: data,
}
event.AgentName = a.name
generator.Send(event)
}, nil
}
func (a *ChatModelAgent) buildRunFunc(ctx context.Context) runFunc {
a.once.Do(func() {
ec, err := a.prepareExecContext(ctx)
if err != nil {
a.run = errFunc(err)
return
}
a.exeCtx = ec
if len(ec.toolsNodeConf.Tools) == 0 {
a.run = a.buildNoToolsRunFunc(ctx)
return
}
run, err := a.buildReactRunFunc(ctx, ec)
if err != nil {
a.run = errFunc(err)
return
}
a.run = run
})
atomic.StoreUint32(&a.frozen, 1)
return a.run
}
func (a *ChatModelAgent) getRunFunc(ctx context.Context) (context.Context, runFunc, *execContext, error) {
defaultRun := a.buildRunFunc(ctx)
bc := a.exeCtx
if bc == nil {
return ctx, defaultRun, bc, nil
}
if len(a.handlers) == 0 {
runtimeBC := &execContext{
instruction: bc.instruction,
toolsNodeConf: bc.toolsNodeConf,
returnDirectly: bc.returnDirectly,
toolInfos: bc.toolInfos,
}
return ctx, defaultRun, runtimeBC, nil
}
ctx, runtimeBC, err := a.applyBeforeAgent(ctx, bc)
if err != nil {
return ctx, nil, nil, err
}
if !runtimeBC.rebuildGraph {
return ctx, defaultRun, runtimeBC, nil
}
var tempRun runFunc
if len(runtimeBC.toolsNodeConf.Tools) == 0 {
tempRun = a.buildNoToolsRunFunc(ctx)
} else {
tempRun, err = a.buildReactRunFunc(ctx, runtimeBC)
if err != nil {
return ctx, nil, nil, err
}
}
return ctx, tempRun, runtimeBC, nil
}
func (a *ChatModelAgent) Run(ctx context.Context, input *AgentInput, opts ...AgentRunOption) *AsyncIterator[*AgentEvent] {
iterator, generator := NewAsyncIteratorPair[*AgentEvent]()
ctx, run, bc, err := a.getRunFunc(ctx)
if err != nil {
go func() {
generator.Send(&AgentEvent{Err: err})
generator.Close()
}()
return iterator
}
co := getComposeOptions(opts)
co = append(co, compose.WithCheckPointID(bridgeCheckpointID))
if bc != nil {
co = append(co, compose.WithChatModelOption(model.WithTools(bc.toolInfos)))
if bc.toolUpdated {
co = append(co, compose.WithToolsNodeOption(compose.WithToolList(bc.toolsNodeConf.Tools...)))
}
}
go func() {
defer func() {
panicErr := recover()
if panicErr != nil {
e := safe.NewPanicErr(panicErr, debug.Stack())
generator.Send(&AgentEvent{Err: e})
}
generator.Close()
}()
var (
instruction string
returnDirectly map[string]bool
)
if bc != nil {
instruction = bc.instruction
returnDirectly = bc.returnDirectly
}
run(ctx, input, generator, newBridgeStore(), instruction, returnDirectly, co...)
}()
return iterator
}
func (a *ChatModelAgent) Resume(ctx context.Context, info *ResumeInfo, opts ...AgentRunOption) *AsyncIterator[*AgentEvent] {
iterator, generator := NewAsyncIteratorPair[*AgentEvent]()
ctx, run, bc, err := a.getRunFunc(ctx)
if err != nil {
go func() {
generator.Send(&AgentEvent{Err: err})
generator.Close()
}()
return iterator
}
co := getComposeOptions(opts)
co = append(co, compose.WithCheckPointID(bridgeCheckpointID))
if bc != nil {
co = append(co, compose.WithChatModelOption(model.WithTools(bc.toolInfos)))
if bc.toolUpdated {
co = append(co, compose.WithToolsNodeOption(compose.WithToolList(bc.toolsNodeConf.Tools...)))
}
}
if info.InterruptState == nil {
panic(fmt.Sprintf("ChatModelAgent.Resume: agent '%s' was asked to resume but has no state", a.Name(ctx)))
}
stateByte, ok := info.InterruptState.([]byte)
if !ok {
panic(fmt.Sprintf("ChatModelAgent.Resume: agent '%s' was asked to resume but has invalid interrupt state type: %T",
a.Name(ctx), info.InterruptState))
}
// Migrate legacy checkpoints before resume.
// This covers both:
// - v0.7.*: state is stored as a struct wire type (stateV07) under the legacy name.
// - v0.8.0-v0.8.3: state is stored as a GobEncoder payload under the same legacy name and must
// be routed to a GobDecode-compatible compat type via byte-patching.
// The result is re-encoded so the resume path always operates on the current *State.
stateByte, err = preprocessComposeCheckpoint(stateByte)
if err != nil {
go func() {
generator.Send(&AgentEvent{Err: err})
generator.Close()
}()
return iterator
}
var historyModifier func(ctx context.Context, history []Message) []Message
if info.ResumeData != nil {
resumeData, ok := info.ResumeData.(*ChatModelAgentResumeData)
if !ok {
panic(fmt.Sprintf("ChatModelAgent.Resume: agent '%s' was asked to resume but has invalid resume data type: %T",
a.Name(ctx), info.ResumeData))
}
historyModifier = resumeData.HistoryModifier
}
if historyModifier != nil {
co = append(co, compose.WithStateModifier(func(ctx context.Context, path compose.NodePath, state any) error {
s, ok := state.(*State)
if !ok {
return nil
}
s.Messages = historyModifier(ctx, s.Messages)
return nil
}))
}
go func() {
defer func() {
panicErr := recover()
if panicErr != nil {
e := safe.NewPanicErr(panicErr, debug.Stack())
generator.Send(&AgentEvent{Err: e})
}
generator.Close()
}()
var (
instruction string
returnDirectly map[string]bool
)
if bc != nil {
instruction = bc.instruction
returnDirectly = bc.returnDirectly
}
run(ctx, &AgentInput{EnableStreaming: info.EnableStreaming}, generator,
newResumeBridgeStore(stateByte), instruction, returnDirectly, co...)
}()
return iterator
}
func getComposeOptions(opts []AgentRunOption) []compose.Option {
o := GetImplSpecificOptions[chatModelAgentRunOptions](nil, opts...)
var co []compose.Option
if len(o.chatModelOptions) > 0 {
co = append(co, compose.WithChatModelOption(o.chatModelOptions...))
}
var to []tool.Option
if len(o.toolOptions) > 0 {
to = append(to, o.toolOptions...)
}
for toolName, atos := range o.agentToolOptions {
to = append(to, withAgentToolOptions(toolName, atos))
}
if len(to) > 0 {
co = append(co, compose.WithToolsNodeOption(compose.WithToolOption(to...)))
}
if o.historyModifier != nil {
co = append(co, compose.WithStateModifier(func(ctx context.Context, path compose.NodePath, state any) error {
s, ok := state.(*State)
if !ok {
return fmt.Errorf("unexpected state type: %T, expected: %T", state, &State{})
}
s.Messages = o.historyModifier(ctx, s.Messages)
return nil
}))
}
return co
}
type gobSerializer struct{}
func (g *gobSerializer) Marshal(v any) ([]byte, error) {
buf := new(bytes.Buffer)
err := gob.NewEncoder(buf).Encode(v)
if err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func (g *gobSerializer) Unmarshal(data []byte, v any) error {
buf := bytes.NewBuffer(data)
return gob.NewDecoder(buf).Decode(v)
}
// preprocessComposeCheckpoint migrates legacy compose checkpoints to the current format.
// It handles the v0.8.0-v0.8.3 format:
// - gob name "_eino_adk_state_v080_" (already byte-patched by preprocessADKCheckpoint
// from "_eino_adk_react_state"), opaque-bytes wire format → decoded as *stateV080
//
// v0.7 checkpoints need no migration — State is now a plain struct registered under the
// same gob name, and gob handles missing fields gracefully.
//
// Fast path: if the legacy name is not present, skip entirely.
func preprocessComposeCheckpoint(data []byte) ([]byte, error) {
const lenPrefixedCompatName = "\x15" + stateGobNameV080
if bytes.Contains(data, []byte(lenPrefixedCompatName)) {
// v0.8.0-v0.8.3: already byte-patched by preprocessADKCheckpoint; decode as *stateV080.
migrated, err := compose.MigrateCheckpointState(data, &gobSerializer{}, func(state any) (any, bool, error) {
sc, ok := state.(*stateV080)
if !ok {
return state, false, nil
}
return stateV080ToState(sc), true, nil
})
if err != nil {
return nil, fmt.Errorf("failed to migrate v0.8.0-v0.8.3 compose checkpoint: %w", err)
}
return migrated, nil
}
return data, nil
}
================================================
FILE: adk/chatmodel_retry_test.go
================================================
/*
* Copyright 2025 CloudWeGo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package adk
import (
"context"
"errors"
"io"
"strings"
"sync/atomic"
"testing"
"time"
"github.com/stretchr/testify/assert"
"go.uber.org/mock/gomock"
"github.com/cloudwego/eino/components/model"
"github.com/cloudwego/eino/components/tool"
"github.com/cloudwego/eino/compose"
mockModel "github.com/cloudwego/eino/internal/mock/components/model"
"github.com/cloudwego/eino/schema"
)
var errRetryAble = errors.New("retry-able error")
var errNonRetryAble = errors.New("non-retry-able error")
func TestChatModelAgentRetry_NoTools_DirectError_Generate(t *testing.T) {
ctx := context.Background()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
cm := mockModel.NewMockToolCallingChatModel(ctrl)
var callCount int32
cm.EXPECT().Generate(gomock.Any(), gomock.Any(), gomock.Any()).
DoAndReturn(func(ctx context.Context, input []*schema.Message, opts ...model.Option) (*schema.Message, error) {
count := atomic.AddInt32(&callCount, 1)
if count < 3 {
return nil, errRetryAble
}
return schema.AssistantMessage("Success after retry", nil), nil
}).Times(3)
agent, err := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "RetryTestAgent",
Description: "Test agent for retry functionality",
Instruction: "You are a helpful assistant.",
Model: cm,
ModelRetryConfig: &ModelRetryConfig{
MaxRetries: 3,
IsRetryAble: func(ctx context.Context, err error) bool { return errors.Is(err, errRetryAble) },
},
})
assert.NoError(t, err)
input := &AgentInput{
Messages: []Message{schema.UserMessage("Hello")},
}
iterator := agent.Run(ctx, input)
event, ok := iterator.Next()
assert.True(t, ok)
assert.NotNil(t, event)
assert.Nil(t, event.Err)
assert.NotNil(t, event.Output)
assert.Equal(t, "Success after retry", event.Output.MessageOutput.Message.Content)
_, ok = iterator.Next()
assert.False(t, ok)
assert.Equal(t, int32(3), atomic.LoadInt32(&callCount))
}
func TestChatModelAgentRetry_NoTools_DirectError_Stream(t *testing.T) {
ctx := context.Background()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
cm := mockModel.NewMockToolCallingChatModel(ctrl)
var callCount int32
cm.EXPECT().Stream(gomock.Any(), gomock.Any(), gomock.Any()).
DoAndReturn(func(ctx context.Context, input []*schema.Message, opts ...model.Option) (*schema.StreamReader[*schema.Message], error) {
count := atomic.AddInt32(&callCount, 1)
if count < 2 {
return nil, errRetryAble
}
return schema.StreamReaderFromArray([]*schema.Message{
schema.AssistantMessage("Success", nil),
}), nil
}).Times(2)
agent, err := NewChatModelAgent(ctx, &ChatModelAgentConfig{
Name: "RetryTestAgent",
Description:
gitextract_0ddnn1r5/
├── .github/
│ ├── .codedev.yml
│ ├── .commit-rules.json
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ ├── PULL_REQUEST_TEMPLATE.md
│ └── workflows/
│ ├── pr-check.yml
│ ├── tag-notification.yml
│ └── tests.yml
├── .gitignore
├── .golangci.yaml
├── .licenserc.yaml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE-APACHE
├── README.md
├── README.zh_CN.md
├── _typos.toml
├── adk/
│ ├── agent_tool.go
│ ├── agent_tool_test.go
│ ├── call_option.go
│ ├── call_option_test.go
│ ├── callback.go
│ ├── callback_integration_test.go
│ ├── callback_test.go
│ ├── chatmodel.go
│ ├── chatmodel_retry_test.go
│ ├── chatmodel_test.go
│ ├── config.go
│ ├── deterministic_transfer.go
│ ├── deterministic_transfer_test.go
│ ├── filesystem/
│ │ ├── backend.go
│ │ ├── backend_inmemory.go
│ │ └── backend_inmemory_test.go
│ ├── flow.go
│ ├── flow_test.go
│ ├── handler.go
│ ├── handler_test.go
│ ├── instruction.go
│ ├── interface.go
│ ├── internal/
│ │ └── config.go
│ ├── interrupt.go
│ ├── interrupt_test.go
│ ├── middlewares/
│ │ ├── dynamictool/
│ │ │ └── toolsearch/
│ │ │ ├── toolsearch.go
│ │ │ └── toolsearch_test.go
│ │ ├── filesystem/
│ │ │ ├── backend.go
│ │ │ ├── filesystem.go
│ │ │ ├── filesystem_test.go
│ │ │ ├── large_tool_result.go
│ │ │ ├── large_tool_result_test.go
│ │ │ └── prompt.go
│ │ ├── patchtoolcalls/
│ │ │ ├── patchtoolcalls.go
│ │ │ └── patchtoolcalls_test.go
│ │ ├── plantask/
│ │ │ ├── backend_test.go
│ │ │ ├── plantask.go
│ │ │ ├── plantask_test.go
│ │ │ ├── task.go
│ │ │ ├── task_create.go
│ │ │ ├── task_create_test.go
│ │ │ ├── task_get.go
│ │ │ ├── task_get_test.go
│ │ │ ├── task_list.go
│ │ │ ├── task_list_test.go
│ │ │ ├── task_update.go
│ │ │ └── task_update_test.go
│ │ ├── reduction/
│ │ │ ├── consts.go
│ │ │ ├── internal/
│ │ │ │ ├── clear_tool_result.go
│ │ │ │ ├── clear_tool_result_test.go
│ │ │ │ ├── large_tool_result.go
│ │ │ │ ├── large_tool_result_test.go
│ │ │ │ └── tool_result.go
│ │ │ ├── legacy.go
│ │ │ ├── reduction.go
│ │ │ └── reduction_test.go
│ │ ├── skill/
│ │ │ ├── filesystem_backend.go
│ │ │ ├── filesystem_backend_test.go
│ │ │ ├── prompt.go
│ │ │ ├── skill.go
│ │ │ └── skill_test.go
│ │ └── summarization/
│ │ ├── consts.go
│ │ ├── customized_action.go
│ │ ├── prompt.go
│ │ ├── summarization.go
│ │ └── summarization_test.go
│ ├── prebuilt/
│ │ ├── deep/
│ │ │ ├── checkpoint_compat_resume_test.go
│ │ │ ├── deep.go
│ │ │ ├── deep_test.go
│ │ │ ├── prompt.go
│ │ │ ├── task_tool.go
│ │ │ ├── task_tool_test.go
│ │ │ ├── testdata/
│ │ │ │ └── _gen/
│ │ │ │ └── generate_test.go
│ │ │ └── types.go
│ │ ├── integration_test.go
│ │ ├── planexecute/
│ │ │ ├── plan_execute.go
│ │ │ ├── plan_execute_test.go
│ │ │ └── utils.go
│ │ └── supervisor/
│ │ ├── supervisor.go
│ │ └── supervisor_test.go
│ ├── react.go
│ ├── react_test.go
│ ├── retry_chatmodel.go
│ ├── runctx.go
│ ├── runctx_test.go
│ ├── runner.go
│ ├── runner_test.go
│ ├── utils.go
│ ├── utils_test.go
│ ├── workflow.go
│ ├── workflow_test.go
│ ├── wrappers.go
│ └── wrappers_test.go
├── callbacks/
│ ├── aspect_inject.go
│ ├── aspect_inject_test.go
│ ├── doc.go
│ ├── handler_builder.go
│ ├── interface.go
│ └── interface_test.go
├── components/
│ ├── document/
│ │ ├── callback_extra_loader.go
│ │ ├── callback_extra_transformer.go
│ │ ├── doc.go
│ │ ├── interface.go
│ │ ├── option.go
│ │ ├── option_test.go
│ │ └── parser/
│ │ ├── doc.go
│ │ ├── ext_parser.go
│ │ ├── interface.go
│ │ ├── option.go
│ │ ├── option_test.go
│ │ ├── parser_test.go
│ │ ├── testdata/
│ │ │ └── test.md
│ │ └── text_parser.go
│ ├── embedding/
│ │ ├── callback_extra.go
│ │ ├── callback_extra_test.go
│ │ ├── doc.go
│ │ ├── interface.go
│ │ ├── option.go
│ │ └── option_test.go
│ ├── indexer/
│ │ ├── callback_extra.go
│ │ ├── callback_extra_test.go
│ │ ├── doc.go
│ │ ├── interface.go
│ │ ├── option.go
│ │ └── option_test.go
│ ├── model/
│ │ ├── callback_extra.go
│ │ ├── callback_extra_test.go
│ │ ├── doc.go
│ │ ├── interface.go
│ │ ├── option.go
│ │ └── option_test.go
│ ├── prompt/
│ │ ├── callback_extra.go
│ │ ├── callback_extra_test.go
│ │ ├── chat_template.go
│ │ ├── chat_template_test.go
│ │ ├── doc.go
│ │ ├── interface.go
│ │ ├── option.go
│ │ └── option_test.go
│ ├── retriever/
│ │ ├── callback_extra.go
│ │ ├── callback_extra_test.go
│ │ ├── doc.go
│ │ ├── interface.go
│ │ ├── option.go
│ │ └── option_test.go
│ ├── tool/
│ │ ├── callback_extra.go
│ │ ├── callback_extra_test.go
│ │ ├── doc.go
│ │ ├── interface.go
│ │ ├── interrupt.go
│ │ ├── interrupt_test.go
│ │ ├── option.go
│ │ ├── option_test.go
│ │ └── utils/
│ │ ├── common.go
│ │ ├── common_test.go
│ │ ├── create_options.go
│ │ ├── doc.go
│ │ ├── error_handler.go
│ │ ├── error_handler_test.go
│ │ ├── invokable_func.go
│ │ ├── invokable_func_test.go
│ │ ├── streamable_func.go
│ │ └── streamable_func_test.go
│ └── types.go
├── compose/
│ ├── branch.go
│ ├── branch_test.go
│ ├── chain.go
│ ├── chain_branch.go
│ ├── chain_branch_test.go
│ ├── chain_parallel.go
│ ├── chain_test.go
│ ├── checkpoint.go
│ ├── checkpoint_migrate_test.go
│ ├── checkpoint_test.go
│ ├── component_to_graph_node.go
│ ├── dag.go
│ ├── dag_test.go
│ ├── doc.go
│ ├── error.go
│ ├── error_test.go
│ ├── field_mapping.go
│ ├── generic_graph.go
│ ├── generic_helper.go
│ ├── graph.go
│ ├── graph_add_node_options.go
│ ├── graph_call_options.go
│ ├── graph_call_options_test.go
│ ├── graph_compile_options.go
│ ├── graph_manager.go
│ ├── graph_node.go
│ ├── graph_run.go
│ ├── graph_test.go
│ ├── interrupt.go
│ ├── introspect.go
│ ├── pregel.go
│ ├── resume.go
│ ├── resume_test.go
│ ├── runnable.go
│ ├── runnable_test.go
│ ├── state.go
│ ├── state_test.go
│ ├── stream_concat.go
│ ├── stream_concat_test.go
│ ├── stream_reader.go
│ ├── stream_reader_test.go
│ ├── tool_node.go
│ ├── tool_node_test.go
│ ├── types.go
│ ├── types_composable.go
│ ├── types_lambda.go
│ ├── types_lambda_test.go
│ ├── utils.go
│ ├── utils_test.go
│ ├── values_merge.go
│ ├── values_merge_test.go
│ ├── workflow.go
│ └── workflow_test.go
├── doc.go
├── flow/
│ ├── agent/
│ │ ├── agent_option.go
│ │ ├── multiagent/
│ │ │ └── host/
│ │ │ ├── callback.go
│ │ │ ├── compose.go
│ │ │ ├── compose_test.go
│ │ │ ├── doc.go
│ │ │ ├── options.go
│ │ │ └── types.go
│ │ ├── react/
│ │ │ ├── callback.go
│ │ │ ├── doc.go
│ │ │ ├── option.go
│ │ │ ├── option_test.go
│ │ │ ├── react.go
│ │ │ └── react_test.go
│ │ └── utils.go
│ ├── indexer/
│ │ └── parent/
│ │ ├── parent.go
│ │ └── parent_test.go
│ └── retriever/
│ ├── multiquery/
│ │ ├── multi_query.go
│ │ └── multi_query_test.go
│ ├── parent/
│ │ ├── doc.go
│ │ ├── parent.go
│ │ └── parent_test.go
│ ├── router/
│ │ ├── router.go
│ │ └── router_test.go
│ └── utils/
│ └── utils.go
├── go.mod
├── go.sum
├── internal/
│ ├── callbacks/
│ │ ├── inject.go
│ │ ├── interface.go
│ │ └── manager.go
│ ├── channel.go
│ ├── channel_test.go
│ ├── concat.go
│ ├── concat_test.go
│ ├── core/
│ │ ├── address.go
│ │ ├── interrupt.go
│ │ ├── interrupt_test.go
│ │ └── resume.go
│ ├── generic/
│ │ ├── generic.go
│ │ ├── generic_test.go
│ │ ├── type_name.go
│ │ └── type_name_test.go
│ ├── gmap/
│ │ ├── gmap.go
│ │ └── gmap_test.go
│ ├── gslice/
│ │ ├── gslice.go
│ │ └── gslice_test.go
│ ├── merge.go
│ ├── mock/
│ │ ├── adk/
│ │ │ └── Agent_mock.go
│ │ ├── components/
│ │ │ ├── document/
│ │ │ │ └── document_mock.go
│ │ │ ├── embedding/
│ │ │ │ └── Embedding_mock.go
│ │ │ ├── indexer/
│ │ │ │ └── indexer_mock.go
│ │ │ ├── model/
│ │ │ │ └── ChatModel_mock.go
│ │ │ └── retriever/
│ │ │ └── retriever_mock.go
│ │ └── doc.go
│ ├── safe/
│ │ ├── panic.go
│ │ └── panic_test.go
│ └── serialization/
│ ├── serialization.go
│ └── serialization_test.go
├── llms.txt
├── schema/
│ ├── doc.go
│ ├── document.go
│ ├── document_test.go
│ ├── message.go
│ ├── message_parser.go
│ ├── message_parser_test.go
│ ├── message_test.go
│ ├── select.go
│ ├── serialization.go
│ ├── serialization_test.go
│ ├── stream.go
│ ├── stream_copy_external_test.go
│ ├── stream_test.go
│ ├── tool.go
│ └── tool_test.go
├── scripts/
│ ├── dev_setup.sh
│ └── eino_setup.sh
└── utils/
└── callbacks/
├── template.go
└── template_test.go
Showing preview only (340K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (3577 symbols across 270 files)
FILE: adk/agent_tool.go
type AgentToolOptions (line 42) | type AgentToolOptions struct
type AgentToolOption (line 47) | type AgentToolOption
function WithFullChatHistoryAsInput (line 50) | func WithFullChatHistoryAsInput() AgentToolOption {
function WithAgentInputSchema (line 57) | func WithAgentInputSchema(schema *schema.ParamsOneOf) AgentToolOption {
function withAgentToolEnableStreaming (line 63) | func withAgentToolEnableStreaming(enabled bool) tool.Option {
function NewAgentTool (line 89) | func NewAgentTool(_ context.Context, agent Agent, options ...AgentToolOp...
type agentTool (line 102) | type agentTool struct
method Info (line 109) | func (at *agentTool) Info(ctx context.Context) (*schema.ToolInfo, erro...
method InvokableRun (line 122) | func (at *agentTool) InvokableRun(ctx context.Context, argumentsInJSON...
type agentToolOptions (line 240) | type agentToolOptions struct
function withAgentToolOptions (line 247) | func withAgentToolOptions(agentName string, opts []AgentRunOption) tool....
function withAgentToolEventGenerator (line 254) | func withAgentToolEventGenerator(gen *AsyncGenerator[*AgentEvent]) tool....
function getOptionsByAgentName (line 260) | func getOptionsByAgentName(agentName string, opts []tool.Option) []Agent...
function getEmitGeneratorAndEnableStreaming (line 271) | func getEmitGeneratorAndEnableStreaming(opts []tool.Option) (*AsyncGener...
function getReactChatHistory (line 280) | func getReactChatHistory(ctx context.Context, destAgentName string) ([]M...
function newInvokableAgentToolRunner (line 314) | func newInvokableAgentToolRunner(agent Agent, store compose.CheckPointSt...
FILE: adk/agent_tool_test.go
type mockAgentForTool (line 35) | type mockAgentForTool struct
method Name (line 41) | func (a *mockAgentForTool) Name(_ context.Context) string {
method Description (line 45) | func (a *mockAgentForTool) Description(_ context.Context) string {
method Run (line 49) | func (a *mockAgentForTool) Run(_ context.Context, _ *AgentInput, _ ......
function newMockAgentForTool (line 68) | func newMockAgentForTool(name, description string, responses []*AgentEve...
function TestAgentTool_Info (line 76) | func TestAgentTool_Info(t *testing.T) {
function TestAgentTool_SharedParentSessionValues (line 95) | func TestAgentTool_SharedParentSessionValues(t *testing.T) {
type sessionValuesAgent (line 141) | type sessionValuesAgent struct
method Name (line 147) | func (a *sessionValuesAgent) Name(context.Context) string { ret...
method Description (line 148) | func (a *sessionValuesAgent) Description(context.Context) string { ret...
method Run (line 149) | func (a *sessionValuesAgent) Run(ctx context.Context, _ *AgentInput, _...
function TestAgentTool_InvokableRun (line 171) | func TestAgentTool_InvokableRun(t *testing.T) {
function TestGetReactHistory (line 269) | func TestGetReactHistory(t *testing.T) {
type mockAgentWithInputCapture (line 302) | type mockAgentWithInputCapture struct
method Name (line 309) | func (a *mockAgentWithInputCapture) Name(_ context.Context) string {
method Description (line 313) | func (a *mockAgentWithInputCapture) Description(_ context.Context) str...
method Run (line 317) | func (a *mockAgentWithInputCapture) Run(_ context.Context, input *Agen...
function newMockAgentWithInputCapture (line 338) | func newMockAgentWithInputCapture(name, description string, responses []...
function TestAgentToolWithOptions (line 346) | func TestAgentToolWithOptions(t *testing.T) {
type fakeTCM (line 576) | type fakeTCM struct
method Generate (line 578) | func (f *fakeTCM) Generate(ctx context.Context, input []*schema.Messag...
method Stream (line 587) | func (f *fakeTCM) Stream(ctx context.Context, input []*schema.Message,...
method WithTools (line 591) | func (f *fakeTCM) WithTools(tools []*schema.ToolInfo) (model.ToolCalli...
type emitOnceModel (line 595) | type emitOnceModel struct
method Generate (line 597) | func (e *emitOnceModel) Generate(ctx context.Context, input []*schema....
method Stream (line 600) | func (e *emitOnceModel) Stream(ctx context.Context, input []*schema.Me...
method WithTools (line 604) | func (e *emitOnceModel) WithTools(tools []*schema.ToolInfo) (model.Too...
type emitEventsAgent (line 608) | type emitEventsAgent struct
method Name (line 610) | func (e *emitEventsAgent) Name(context.Context) string { return...
method Description (line 611) | func (e *emitEventsAgent) Description(context.Context) string { return...
method Run (line 612) | func (e *emitEventsAgent) Run(context.Context, *AgentInput, ...AgentRu...
type spyAgent (line 624) | type spyAgent struct
method Name (line 630) | func (s *spyAgent) Name(ctx context.Context) string { return s....
method Description (line 631) | func (s *spyAgent) Description(ctx context.Context) string { return s....
method Run (line 632) | func (s *spyAgent) Run(ctx context.Context, input *AgentInput, options...
method getCaptured (line 641) | func (s *spyAgent) getCaptured() *runSession {
function TestNestedAgentTool_RunPath (line 647) | func TestNestedAgentTool_RunPath(t *testing.T) {
function TestNestedAgentTool_NoInternalEventsWhenDisabled (line 734) | func TestNestedAgentTool_NoInternalEventsWhenDisabled(t *testing.T) {
function TestNestedAgentTool_InnerToolResultNotEmittedToOuter (line 774) | func TestNestedAgentTool_InnerToolResultNotEmittedToOuter(t *testing.T) {
type simpleTool (line 817) | type simpleTool struct
method Info (line 822) | func (s *simpleTool) Info(context.Context) (*schema.ToolInfo, error) {
method InvokableRun (line 826) | func (s *simpleTool) InvokableRun(ctx context.Context, argumentsInJSON...
function TestAgentTool_InterruptWithoutCheckpoint (line 830) | func TestAgentTool_InterruptWithoutCheckpoint(t *testing.T) {
function compositeInterruptFromLast (line 846) | func compositeInterruptFromLast(ctx context.Context, ms *bridgeStore, la...
function TestAgentTool_InvokableRun_FinalOnly (line 860) | func TestAgentTool_InvokableRun_FinalOnly(t *testing.T) {
type streamingAgent (line 879) | type streamingAgent struct
method Name (line 881) | func (s *streamingAgent) Name(context.Context) string { return ...
method Description (line 882) | func (s *streamingAgent) Description(context.Context) string { return ...
method Run (line 883) | func (s *streamingAgent) Run(context.Context, *AgentInput, ...AgentRun...
function TestAgentTool_InvokableRun_StreamingVariant (line 895) | func TestAgentTool_InvokableRun_StreamingVariant(t *testing.T) {
function TestSequentialWorkflow_WithChatModelAgentTool_NestedRunPathAndSessions (line 908) | func TestSequentialWorkflow_WithChatModelAgentTool_NestedRunPathAndSessi...
function TestRunPathGating_IgnoresInnerExitAndAllowsOutput (line 996) | func TestRunPathGating_IgnoresInnerExitAndAllowsOutput(t *testing.T) {
function TestRunPathGating_IgnoresInnerTransfer (line 1024) | func TestRunPathGating_IgnoresInnerTransfer(t *testing.T) {
type streamAgent (line 1052) | type streamAgent struct
method Name (line 1054) | func (s *streamAgent) Name(context.Context) string { return "s" }
method Description (line 1055) | func (s *streamAgent) Description(context.Context) string { return "s" }
method Run (line 1056) | func (s *streamAgent) Run(context.Context, *AgentInput, ...AgentRunOpt...
function TestInvokableAgentTool_InfoAndRun (line 1070) | func TestInvokableAgentTool_InfoAndRun(t *testing.T) {
type emptyAgent (line 1104) | type emptyAgent struct
method Name (line 1106) | func (e *emptyAgent) Name(context.Context) string { return "emp...
method Description (line 1107) | func (e *emptyAgent) Description(context.Context) string { return "emp...
method Run (line 1108) | func (e *emptyAgent) Run(context.Context, *AgentInput, ...AgentRunOpti...
type noOutputAgent (line 1114) | type noOutputAgent struct
method Name (line 1116) | func (n *noOutputAgent) Name(context.Context) string { return "...
method Description (line 1117) | func (n *noOutputAgent) Description(context.Context) string { return "...
method Run (line 1118) | func (n *noOutputAgent) Run(context.Context, *AgentInput, ...AgentRunO...
function TestInvokableAgentTool_ErrorCases (line 1124) | func TestInvokableAgentTool_ErrorCases(t *testing.T) {
FILE: adk/call_option.go
type options (line 21) | type options struct
type AgentRunOption (line 30) | type AgentRunOption struct
method DesignateAgent (line 37) | func (o AgentRunOption) DesignateAgent(name ...string) AgentRunOption {
function getCommonOptions (line 42) | func getCommonOptions(base *options, opts ...AgentRunOption) *options {
function WithSessionValues (line 51) | func WithSessionValues(v map[string]any) AgentRunOption {
function WithSkipTransferMessages (line 58) | func WithSkipTransferMessages() AgentRunOption {
function withSharedParentSession (line 64) | func withSharedParentSession() AgentRunOption {
function WithCallbacks (line 73) | func WithCallbacks(handlers ...callbacks.Handler) AgentRunOption {
function WrapImplSpecificOptFn (line 80) | func WrapImplSpecificOptFn[T any](optFn func(*T)) AgentRunOption {
function GetImplSpecificOptions (line 94) | func GetImplSpecificOptions[T any](base *T, opts ...AgentRunOption) *T {
function filterCallbackHandlersForNestedAgents (line 125) | func filterCallbackHandlersForNestedAgents(currentAgentName string, opts...
function filterOptions (line 160) | func filterOptions(agentName string, opts []AgentRunOption) []AgentRunOp...
FILE: adk/call_option_test.go
type mockAgentForOption (line 23) | type mockAgentForOption struct
method Name (line 29) | func (m *mockAgentForOption) Name(ctx context.Context) string {
method Description (line 33) | func (m *mockAgentForOption) Description(ctx context.Context) string {
method Run (line 37) | func (m *mockAgentForOption) Run(ctx context.Context, input *AgentInpu...
FILE: adk/callback.go
type AgentCallbackInput (line 29) | type AgentCallbackInput struct
type AgentCallbackOutput (line 41) | type AgentCallbackOutput struct
function copyEventIterator (line 46) | func copyEventIterator(iter *AsyncIterator[*AgentEvent], n int) []*Async...
function copyAgentCallbackOutput (line 82) | func copyAgentCallbackOutput(out *AgentCallbackOutput, n int) []*AgentCa...
function ConvAgentCallbackInput (line 100) | func ConvAgentCallbackInput(input callbacks.CallbackInput) *AgentCallbac...
function ConvAgentCallbackOutput (line 109) | func ConvAgentCallbackOutput(output callbacks.CallbackOutput) *AgentCall...
function initAgentCallbacks (line 116) | func initAgentCallbacks(ctx context.Context, agentName, agentType string...
function getAgentType (line 130) | func getAgentType(agent Agent) string {
FILE: adk/callback_integration_test.go
type callbackRecorder (line 32) | type callbackRecorder struct
method getOnStartCalled (line 43) | func (r *callbackRecorder) getOnStartCalled() bool {
method getOnEndCalled (line 49) | func (r *callbackRecorder) getOnEndCalled() bool {
method getEventsReceived (line 55) | func (r *callbackRecorder) getEventsReceived() []*AgentEvent {
function newRecordingHandler (line 63) | func newRecordingHandler(recorder *callbackRecorder) callbacks.Handler {
function TestCallbackOnStartInvocation (line 111) | func TestCallbackOnStartInvocation(t *testing.T) {
function TestCallbackOnEndInvocation (line 150) | func TestCallbackOnEndInvocation(t *testing.T) {
function TestCallbackRunInfoForChatModelAgent (line 187) | func TestCallbackRunInfoForChatModelAgent(t *testing.T) {
function TestMultipleCallbackHandlers (line 226) | func TestMultipleCallbackHandlers(t *testing.T) {
function TestCallbackWithWorkflowAgent (line 271) | func TestCallbackWithWorkflowAgent(t *testing.T) {
function TestCallbackEventsMatchAgentOutput (line 345) | func TestCallbackEventsMatchAgentOutput(t *testing.T) {
function TestCallbackOnEndForWorkflowAgent (line 397) | func TestCallbackOnEndForWorkflowAgent(t *testing.T) {
type ctxKeyForTest (line 456) | type ctxKeyForTest
constant testOnStartMarkerKey (line 458) | testOnStartMarkerKey ctxKeyForTest = "onStartMarker"
function TestSubAgentContextIsolation (line 460) | func TestSubAgentContextIsolation(t *testing.T) {
function TestCallbackDesignatedToSpecificAgent (line 564) | func TestCallbackDesignatedToSpecificAgent(t *testing.T) {
function TestCallbackDesignatedToMultipleAgents (line 657) | func TestCallbackDesignatedToMultipleAgents(t *testing.T) {
function TestCallbackDesignatedExcludesNonMatchingAgents (line 750) | func TestCallbackDesignatedExcludesNonMatchingAgents(t *testing.T) {
function TestMixedDesignatedAndGlobalCallbacks (line 843) | func TestMixedDesignatedAndGlobalCallbacks(t *testing.T) {
function TestOnStartCalledOncePerAgentWithDesignation (line 971) | func TestOnStartCalledOncePerAgentWithDesignation(t *testing.T) {
FILE: adk/callback_test.go
function TestCopyEventIterator (line 30) | func TestCopyEventIterator(t *testing.T) {
function TestCopyAgentCallbackOutput (line 100) | func TestCopyAgentCallbackOutput(t *testing.T) {
function TestConvAgentCallbackInput (line 136) | func TestConvAgentCallbackInput(t *testing.T) {
function TestConvAgentCallbackOutput (line 156) | func TestConvAgentCallbackOutput(t *testing.T) {
type mockTyperAgent (line 175) | type mockTyperAgent struct
method Name (line 180) | func (a *mockTyperAgent) Name(_ context.Context) string { retur...
method Description (line 181) | func (a *mockTyperAgent) Description(_ context.Context) string { retur...
method GetType (line 182) | func (a *mockTyperAgent) GetType() string { retur...
method Run (line 183) | func (a *mockTyperAgent) Run(_ context.Context, _ *AgentInput, _ ...Ag...
type mockNonTyperAgent (line 189) | type mockNonTyperAgent struct
method Name (line 193) | func (a *mockNonTyperAgent) Name(_ context.Context) string { re...
method Description (line 194) | func (a *mockNonTyperAgent) Description(_ context.Context) string { re...
method Run (line 195) | func (a *mockNonTyperAgent) Run(_ context.Context, _ *AgentInput, _ .....
function TestGetAgentType (line 201) | func TestGetAgentType(t *testing.T) {
function TestWithCallbacksOption (line 215) | func TestWithCallbacksOption(t *testing.T) {
function TestWithMultipleCallbacksOption (line 228) | func TestWithMultipleCallbacksOption(t *testing.T) {
FILE: adk/chatmodel.go
type chatModelAgentExecCtx (line 41) | type chatModelAgentExecCtx struct
method send (line 46) | func (e *chatModelAgentExecCtx) send(event *AgentEvent) {
type chatModelAgentExecCtxKey (line 52) | type chatModelAgentExecCtxKey struct
function withChatModelAgentExecCtx (line 54) | func withChatModelAgentExecCtx(ctx context.Context, execCtx *chatModelAg...
function getChatModelAgentExecCtx (line 58) | func getChatModelAgentExecCtx(ctx context.Context) *chatModelAgentExecCtx {
type chatModelAgentRunOptions (line 65) | type chatModelAgentRunOptions struct
function WithChatModelOptions (line 74) | func WithChatModelOptions(opts []model.Option) AgentRunOption {
function WithToolOptions (line 81) | func WithToolOptions(opts []tool.Option) AgentRunOption {
function WithAgentToolRunOptions (line 88) | func WithAgentToolRunOptions(opts map[string][]AgentRunOption) AgentRunO...
function WithHistoryModifier (line 96) | func WithHistoryModifier(f func(context.Context, []Message) []Message) A...
type ToolsConfig (line 102) | type ToolsConfig struct
type GenModelInput (line 126) | type GenModelInput
function defaultGenModelInput (line 128) | func defaultGenModelInput(ctx context.Context, instruction string, input...
type ChatModelAgentState (line 158) | type ChatModelAgentState struct
type AgentMiddleware (line 175) | type AgentMiddleware struct
type ChatModelAgentConfig (line 195) | type ChatModelAgentConfig struct
type ChatModelAgent (line 309) | type ChatModelAgent struct
method Name (line 502) | func (a *ChatModelAgent) Name(_ context.Context) string {
method Description (line 506) | func (a *ChatModelAgent) Description(_ context.Context) string {
method GetType (line 510) | func (a *ChatModelAgent) GetType() string {
method OnSetSubAgents (line 514) | func (a *ChatModelAgent) OnSetSubAgents(_ context.Context, subAgents [...
method OnSetAsSubAgent (line 527) | func (a *ChatModelAgent) OnSetAsSubAgent(_ context.Context, parent Age...
method OnDisallowTransferToParent (line 540) | func (a *ChatModelAgent) OnDisallowTransferToParent(_ context.Context)...
method applyBeforeAgent (line 600) | func (a *ChatModelAgent) applyBeforeAgent(ctx context.Context, ec *exe...
method prepareExecContext (line 637) | func (a *ChatModelAgent) prepareExecContext(ctx context.Context) (*exe...
method buildNoToolsRunFunc (line 696) | func (a *ChatModelAgent) buildNoToolsRunFunc(_ context.Context) runFunc {
method buildReactRunFunc (line 761) | func (a *ChatModelAgent) buildReactRunFunc(ctx context.Context, bc *ex...
method buildRunFunc (line 884) | func (a *ChatModelAgent) buildRunFunc(ctx context.Context) runFunc {
method getRunFunc (line 912) | func (a *ChatModelAgent) getRunFunc(ctx context.Context) (context.Cont...
method Run (line 952) | func (a *ChatModelAgent) Run(ctx context.Context, input *AgentInput, o...
method Resume (line 1001) | func (a *ChatModelAgent) Resume(ctx context.Context, info *ResumeInfo,...
type runFunc (line 340) | type runFunc
function NewChatModelAgent (line 343) | func NewChatModelAgent(ctx context.Context, config *ChatModelAgentConfig...
function collectToolMiddlewaresFromMiddlewares (line 394) | func collectToolMiddlewaresFromMiddlewares(mws []AgentMiddleware) []comp...
constant TransferToAgentToolName (line 406) | TransferToAgentToolName = "transfer_to_agent"
constant TransferToAgentToolDesc (line 407) | TransferToAgentToolDesc = "Transfer the question to another agent."
constant TransferToAgentToolDescChinese (line 408) | TransferToAgentToolDescChinese = "将问题移交给其他 Agent。"
type ExitTool (line 438) | type ExitTool struct
method Info (line 440) | func (et ExitTool) Info(_ context.Context) (*schema.ToolInfo, error) {
method InvokableRun (line 444) | func (et ExitTool) InvokableRun(ctx context.Context, argumentsInJSON s...
type transferToAgent (line 463) | type transferToAgent struct
method Info (line 465) | func (tta transferToAgent) Info(_ context.Context) (*schema.ToolInfo, ...
method InvokableRun (line 483) | func (tta transferToAgent) InvokableRun(ctx context.Context, arguments...
function transferToAgentToolOutput (line 475) | func transferToAgentToolOutput(destName string) string {
type ChatModelAgentInterruptInfo (line 550) | type ChatModelAgentInterruptInfo struct
function init (line 555) | func init() {
function setOutputToSession (line 559) | func setOutputToSession(ctx context.Context, msg Message, msgStream Mess...
function errFunc (line 574) | func errFunc(err error) runFunc {
type ChatModelAgentResumeData (line 582) | type ChatModelAgentResumeData struct
type execContext (line 588) | type execContext struct
function getComposeOptions (line 1097) | func getComposeOptions(opts []AgentRunOption) []compose.Option {
type gobSerializer (line 1126) | type gobSerializer struct
method Marshal (line 1128) | func (g *gobSerializer) Marshal(v any) ([]byte, error) {
method Unmarshal (line 1137) | func (g *gobSerializer) Unmarshal(data []byte, v any) error {
function preprocessComposeCheckpoint (line 1151) | func preprocessComposeCheckpoint(data []byte) ([]byte, error) {
FILE: adk/chatmodel_retry_test.go
function TestChatModelAgentRetry_NoTools_DirectError_Generate (line 41) | func TestChatModelAgentRetry_NoTools_DirectError_Generate(t *testing.T) {
function TestChatModelAgentRetry_NoTools_DirectError_Stream (line 87) | func TestChatModelAgentRetry_NoTools_DirectError_Stream(t *testing.T) {
type streamErrorModel (line 136) | type streamErrorModel struct
method Generate (line 144) | func (m *streamErrorModel) Generate(_ context.Context, _ []*schema.Mes...
method Stream (line 148) | func (m *streamErrorModel) Stream(_ context.Context, _ []*schema.Messa...
method WithTools (line 172) | func (m *streamErrorModel) WithTools(tools []*schema.ToolInfo) (model....
function TestChatModelAgentRetry_StreamError (line 177) | func TestChatModelAgentRetry_StreamError(t *testing.T) {
function TestChatModelAgentRetry_WithTools_DirectError_Generate (line 322) | func TestChatModelAgentRetry_WithTools_DirectError_Generate(t *testing.T) {
function TestChatModelAgentRetry_NonRetryableError (line 376) | func TestChatModelAgentRetry_NonRetryableError(t *testing.T) {
type inputCapturingModel (line 413) | type inputCapturingModel struct
method Generate (line 417) | func (m *inputCapturingModel) Generate(_ context.Context, input []*sch...
method Stream (line 422) | func (m *inputCapturingModel) Stream(_ context.Context, input []*schem...
method WithTools (line 429) | func (m *inputCapturingModel) WithTools(_ []*schema.ToolInfo) (model.T...
function TestChatModelAgentRetry_MaxRetriesExhausted (line 433) | func TestChatModelAgentRetry_MaxRetriesExhausted(t *testing.T) {
function TestChatModelAgentRetry_BackoffFunction (line 473) | func TestChatModelAgentRetry_BackoffFunction(t *testing.T) {
function TestChatModelAgentRetry_NoRetryConfig (line 522) | func TestChatModelAgentRetry_NoRetryConfig(t *testing.T) {
function TestChatModelAgentRetry_WithTools_NonRetryAbleStreamError (line 555) | func TestChatModelAgentRetry_WithTools_NonRetryAbleStreamError(t *testin...
type nonRetryAbleStreamErrorModel (line 601) | type nonRetryAbleStreamErrorModel struct
method Generate (line 605) | func (m *nonRetryAbleStreamErrorModel) Generate(_ context.Context, _ [...
method Stream (line 609) | func (m *nonRetryAbleStreamErrorModel) Stream(_ context.Context, _ []*...
method WithTools (line 619) | func (m *nonRetryAbleStreamErrorModel) WithTools(tools []*schema.ToolI...
function TestChatModelAgentRetry_NoTools_NonRetryAbleStreamError (line 624) | func TestChatModelAgentRetry_NoTools_NonRetryAbleStreamError(t *testing....
function TestDefaultBackoff (line 682) | func TestDefaultBackoff(t *testing.T) {
function TestRetryExhaustedError_ErrorString (line 709) | func TestRetryExhaustedError_ErrorString(t *testing.T) {
function TestWillRetryError_ErrorString (line 724) | func TestWillRetryError_ErrorString(t *testing.T) {
type customError (line 729) | type customError struct
method Error (line 734) | func (e *customError) Error() string {
function TestWillRetryError_Unwrap (line 738) | func TestWillRetryError_Unwrap(t *testing.T) {
function TestChatModelAgentRetry_DefaultIsRetryAble (line 750) | func TestChatModelAgentRetry_DefaultIsRetryAble(t *testing.T) {
function TestSequentialWorkflow_RetryAbleStreamError_SuccessfulRetry (line 794) | func TestSequentialWorkflow_RetryAbleStreamError_SuccessfulRetry(t *test...
type streamErrorModelNoRetry (line 881) | type streamErrorModelNoRetry struct
method Generate (line 885) | func (m *streamErrorModelNoRetry) Generate(_ context.Context, _ []*sch...
method Stream (line 889) | func (m *streamErrorModelNoRetry) Stream(_ context.Context, _ []*schem...
method WithTools (line 901) | func (m *streamErrorModelNoRetry) WithTools(_ []*schema.ToolInfo) (mod...
function TestSequentialWorkflow_NonRetryAbleStreamError_StopsFlow (line 905) | func TestSequentialWorkflow_NonRetryAbleStreamError_StopsFlow(t *testing...
function TestSequentialWorkflow_NoRetryConfig_StreamError_StopsFlow (line 979) | func TestSequentialWorkflow_NoRetryConfig_StreamError_StopsFlow(t *testi...
FILE: adk/chatmodel_test.go
function TestChatModelAgentRun (line 36) | func TestChatModelAgentRun(t *testing.T) {
function TestExitTool (line 535) | func TestExitTool(t *testing.T) {
function TestParallelReturnDirectlyToolCall (line 612) | func TestParallelReturnDirectlyToolCall(t *testing.T) {
function TestConcurrentSameToolSendToolGenActionUsesToolCallID (line 684) | func TestConcurrentSameToolSendToolGenActionUsesToolCallID(t *testing.T) {
type myTool (line 732) | type myTool struct
method Info (line 738) | func (m *myTool) Info(ctx context.Context) (*schema.ToolInfo, error) {
method InvokableRun (line 745) | func (m *myTool) InvokableRun(ctx context.Context, argumentsInJSON str...
type actionTool (line 750) | type actionTool struct
method Info (line 752) | func (a actionTool) Info(ctx context.Context) (*schema.ToolInfo, error) {
method InvokableRun (line 756) | func (a actionTool) InvokableRun(ctx context.Context, argumentsInJSON ...
type streamActionTool (line 761) | type streamActionTool struct
method Info (line 763) | func (s streamActionTool) Info(ctx context.Context) (*schema.ToolInfo,...
method StreamableRun (line 767) | func (s streamActionTool) StreamableRun(ctx context.Context, arguments...
type legacyStreamActionTool (line 778) | type legacyStreamActionTool struct
method Info (line 780) | func (s legacyStreamActionTool) Info(ctx context.Context) (*schema.Too...
method StreamableRun (line 784) | func (s legacyStreamActionTool) StreamableRun(ctx context.Context, arg...
function TestChatModelAgentOutputKey (line 799) | func TestChatModelAgentOutputKey(t *testing.T) {
function TestConcurrentSameStreamToolSendToolGenActionUsesToolCallID (line 1083) | func TestConcurrentSameStreamToolSendToolGenActionUsesToolCallID(t *test...
function TestStreamToolLegacyNameKeyFallback (line 1133) | func TestStreamToolLegacyNameKeyFallback(t *testing.T) {
function TestChatModelAgent_ToolResultMiddleware_EmitsFinalResult (line 1178) | func TestChatModelAgent_ToolResultMiddleware_EmitsFinalResult(t *testing...
type simpleToolForMiddlewareTest (line 1358) | type simpleToolForMiddlewareTest struct
method Info (line 1363) | func (s *simpleToolForMiddlewareTest) Info(_ context.Context) (*schema...
method InvokableRun (line 1378) | func (s *simpleToolForMiddlewareTest) InvokableRun(_ context.Context, ...
method StreamableRun (line 1382) | func (s *simpleToolForMiddlewareTest) StreamableRun(_ context.Context,...
function TestGetComposeOptions (line 1386) | func TestGetComposeOptions(t *testing.T) {
type toolOptionCapturingTool (line 1472) | type toolOptionCapturingTool struct
method Info (line 1477) | func (t *toolOptionCapturingTool) Info(_ context.Context) (*schema.Too...
method InvokableRun (line 1481) | func (t *toolOptionCapturingTool) InvokableRun(_ context.Context, _ st...
type testToolOptions (line 1488) | type testToolOptions struct
function testToolOption (line 1492) | func testToolOption(value string) tool.Option {
type errorTool (line 1498) | type errorTool struct
method Info (line 1502) | func (e *errorTool) Info(_ context.Context) (*schema.ToolInfo, error) {
method InvokableRun (line 1506) | func (e *errorTool) InvokableRun(_ context.Context, _ string, _ ...too...
function TestChatModelAgent_PrepareExecContextError (line 1510) | func TestChatModelAgent_PrepareExecContextError(t *testing.T) {
function TestPreprocessComposeCheckpoint_MigrateErrorIsReturned (line 1579) | func TestPreprocessComposeCheckpoint_MigrateErrorIsReturned(t *testing.T) {
FILE: adk/config.go
constant LanguageEnglish (line 26) | LanguageEnglish Language = internal.LanguageEnglish
constant LanguageChinese (line 28) | LanguageChinese Language = internal.LanguageChinese
function SetLanguage (line 33) | func SetLanguage(lang Language) error {
FILE: adk/deterministic_transfer.go
function init (line 30) | func init() {
type deterministicTransferState (line 34) | type deterministicTransferState struct
function AgentWithDeterministicTransferTo (line 39) | func AgentWithDeterministicTransferTo(_ context.Context, config *Determi...
type agentWithDeterministicTransferTo (line 52) | type agentWithDeterministicTransferTo struct
method Description (line 57) | func (a *agentWithDeterministicTransferTo) Description(ctx context.Con...
method Name (line 61) | func (a *agentWithDeterministicTransferTo) Name(ctx context.Context) s...
method GetType (line 65) | func (a *agentWithDeterministicTransferTo) GetType() string {
method Run (line 72) | func (a *agentWithDeterministicTransferTo) Run(ctx context.Context,
type resumableAgentWithDeterministicTransferTo (line 87) | type resumableAgentWithDeterministicTransferTo struct
method Description (line 92) | func (a *resumableAgentWithDeterministicTransferTo) Description(ctx co...
method Name (line 96) | func (a *resumableAgentWithDeterministicTransferTo) Name(ctx context.C...
method GetType (line 100) | func (a *resumableAgentWithDeterministicTransferTo) GetType() string {
method Run (line 107) | func (a *resumableAgentWithDeterministicTransferTo) Run(ctx context.Co...
method Resume (line 122) | func (a *resumableAgentWithDeterministicTransferTo) Resume(ctx context...
function forwardEventsAndAppendTransfer (line 135) | func forwardEventsAndAppendTransfer(iter *AsyncIterator[*AgentEvent],
function runFlowAgentWithIsolatedSession (line 162) | func runFlowAgentWithIsolatedSession(ctx context.Context, fa *flowAgent,...
function resumeFlowAgentWithIsolatedSession (line 193) | func resumeFlowAgentWithIsolatedSession(ctx context.Context, fa *flowAge...
function handleFlowAgentEvents (line 230) | func handleFlowAgentEvents(ctx context.Context, iter *AsyncIterator[*Age...
function sendTransferEvents (line 282) | func sendTransferEvents(generator *AsyncGenerator[*AgentEvent], toAgentN...
FILE: adk/deterministic_transfer_test.go
type dtTestStore (line 28) | type dtTestStore struct
method Set (line 36) | func (s *dtTestStore) Set(_ context.Context, key string, value []byte)...
method Get (line 41) | func (s *dtTestStore) Get(_ context.Context, key string) ([]byte, bool...
function newDTTestStore (line 32) | func newDTTestStore() *dtTestStore {
type dtTestAgent (line 46) | type dtTestAgent struct
method Name (line 52) | func (a *dtTestAgent) Name(_ context.Context) string {
method Description (line 56) | func (a *dtTestAgent) Description(_ context.Context) string {
method Run (line 60) | func (a *dtTestAgent) Run(ctx context.Context, input *AgentInput, opti...
method Resume (line 64) | func (a *dtTestAgent) Resume(ctx context.Context, info *ResumeInfo, op...
function TestDeterministicTransferFlowAgentInterruptResume (line 71) | func TestDeterministicTransferFlowAgentInterruptResume(t *testing.T) {
function TestDeterministicTransferRunPathPreserved (line 264) | func TestDeterministicTransferRunPathPreserved(t *testing.T) {
function TestDeterministicTransferExitSkipsTransfer (line 337) | func TestDeterministicTransferExitSkipsTransfer(t *testing.T) {
type nonFlowTestAgent (line 411) | type nonFlowTestAgent struct
method Name (line 417) | func (a *nonFlowTestAgent) Name(_ context.Context) string {
method Description (line 421) | func (a *nonFlowTestAgent) Description(_ context.Context) string {
method Run (line 425) | func (a *nonFlowTestAgent) Run(ctx context.Context, input *AgentInput,...
method Resume (line 429) | func (a *nonFlowTestAgent) Resume(ctx context.Context, info *ResumeInf...
type nonResumableTestAgent (line 436) | type nonResumableTestAgent struct
method Name (line 441) | func (a *nonResumableTestAgent) Name(_ context.Context) string {
method Description (line 445) | func (a *nonResumableTestAgent) Description(_ context.Context) string {
method Run (line 449) | func (a *nonResumableTestAgent) Run(ctx context.Context, input *AgentI...
function TestDeterministicTransferNonFlowAgent_ExitSkipsTransfer (line 453) | func TestDeterministicTransferNonFlowAgent_ExitSkipsTransfer(t *testing....
function TestDeterministicTransferNonFlowAgent_AppendsTransfer (line 499) | func TestDeterministicTransferNonFlowAgent_AppendsTransfer(t *testing.T) {
function TestDeterministicTransferNonFlowAgent_InterruptSkipsTransfer (line 542) | func TestDeterministicTransferNonFlowAgent_InterruptSkipsTransfer(t *tes...
function TestDeterministicTransferNonFlowAgent_Resume (line 591) | func TestDeterministicTransferNonFlowAgent_Resume(t *testing.T) {
function TestDeterministicTransferFlowAgent_ResumeWithInvalidState (line 645) | func TestDeterministicTransferFlowAgent_ResumeWithInvalidState(t *testin...
function TestDeterministicTransferNonResumableAgent (line 692) | func TestDeterministicTransferNonResumableAgent(t *testing.T) {
FILE: adk/filesystem/backend.go
type FileInfo (line 27) | type FileInfo struct
type GrepMatch (line 45) | type GrepMatch struct
type LsInfoRequest (line 56) | type LsInfoRequest struct
type ReadRequest (line 62) | type ReadRequest struct
type GrepRequest (line 80) | type GrepRequest struct
type GlobInfoRequest (line 131) | type GlobInfoRequest struct
type WriteRequest (line 145) | type WriteRequest struct
type EditRequest (line 154) | type EditRequest struct
type FileContent (line 172) | type FileContent struct
type Backend (line 180) | type Backend interface
type ExecuteRequest (line 223) | type ExecuteRequest struct
type ExecuteResponse (line 229) | type ExecuteResponse struct
type Shell (line 235) | type Shell interface
type StreamingShell (line 239) | type StreamingShell interface
FILE: adk/filesystem/backend_inmemory.go
type fileEntry (line 31) | type fileEntry struct
type InMemoryBackend (line 38) | type InMemoryBackend struct
method LsInfo (line 51) | func (b *InMemoryBackend) LsInfo(ctx context.Context, req *LsInfoReque...
method Read (line 136) | func (b *InMemoryBackend) Read(ctx context.Context, req *ReadRequest) ...
method GrepRaw (line 194) | func (b *InMemoryBackend) GrepRaw(ctx context.Context, req *GrepReques...
method grepFilesInParallel (line 240) | func (b *InMemoryBackend) grepFilesInParallel(filteredFiles []string, ...
method compilePattern (line 322) | func (b *InMemoryBackend) compilePattern(req *GrepRequest) (*regexp.Re...
method filterFiles (line 334) | func (b *InMemoryBackend) filterFiles(searchPath string, req *GrepRequ...
method filterByGlob (line 362) | func (b *InMemoryBackend) filterByGlob(files []string, searchPath stri...
method filterByFileType (line 389) | func (b *InMemoryBackend) filterByFileType(files []string, fileType st...
method applyContext (line 492) | func (b *InMemoryBackend) applyContext(matches []GrepMatch, req *GrepR...
method GlobInfo (line 573) | func (b *InMemoryBackend) GlobInfo(ctx context.Context, req *GlobInfoR...
method Write (line 623) | func (b *InMemoryBackend) Write(ctx context.Context, req *WriteRequest...
method Edit (line 637) | func (b *InMemoryBackend) Edit(ctx context.Context, req *EditRequest) ...
function NewInMemoryBackend (line 44) | func NewInMemoryBackend() *InMemoryBackend {
function mustParseTime (line 130) | func mustParseTime(s string) time.Time {
function matchFileType (line 403) | func matchFileType(ext, fileType string) bool {
function normalizePath (line 683) | func normalizePath(path string) string {
type grepCollector (line 696) | type grepCollector struct
method processFile (line 706) | func (c *grepCollector) processFile(filePath, content string, re *rege...
method findMatches (line 713) | func (c *grepCollector) findMatches(filePath, content string, re *rege...
method findMultilineMatches (line 720) | func (c *grepCollector) findMultilineMatches(filePath, content string,...
method findSingleLineMatches (line 742) | func (c *grepCollector) findSingleLineMatches(filePath, content string...
method buildResults (line 757) | func (c *grepCollector) buildResults(b *InMemoryBackend, req *GrepRequ...
method buildContentResult (line 761) | func (c *grepCollector) buildContentResult(b *InMemoryBackend, req *Gr...
function newGrepCollector (line 700) | func newGrepCollector() *grepCollector {
FILE: adk/filesystem/backend_inmemory_test.go
function TestInMemoryBackend_WriteAndRead (line 28) | func TestInMemoryBackend_WriteAndRead(t *testing.T) {
function TestInMemoryBackend_LsInfo (line 78) | func TestInMemoryBackend_LsInfo(t *testing.T) {
function TestInMemoryBackend_Edit (line 123) | func TestInMemoryBackend_Edit(t *testing.T) {
function TestInMemoryBackend_LsInfo_PathIsFilename (line 191) | func TestInMemoryBackend_LsInfo_PathIsFilename(t *testing.T) {
function TestInMemoryBackend_GlobInfo (line 276) | func TestInMemoryBackend_GlobInfo(t *testing.T) {
function TestInMemoryBackend_GlobInfo_RelativePath (line 329) | func TestInMemoryBackend_GlobInfo_RelativePath(t *testing.T) {
function TestInMemoryBackend_GlobInfo_RecursivePattern (line 478) | func TestInMemoryBackend_GlobInfo_RecursivePattern(t *testing.T) {
function TestInMemoryBackend_Concurrent (line 640) | func TestInMemoryBackend_Concurrent(t *testing.T) {
function TestInMemoryBackend_LsInfo_FileInfoMetadata (line 665) | func TestInMemoryBackend_LsInfo_FileInfoMetadata(t *testing.T) {
function TestInMemoryBackend_GlobInfo_FileInfoMetadata (line 875) | func TestInMemoryBackend_GlobInfo_FileInfoMetadata(t *testing.T) {
function TestInMemoryBackend_WriteAndEdit_ModifiedAt (line 954) | func TestInMemoryBackend_WriteAndEdit_ModifiedAt(t *testing.T) {
function TestInMemoryBackend_Read_EdgeCases (line 1138) | func TestInMemoryBackend_Read_EdgeCases(t *testing.T) {
function TestInMemoryBackend_Edit_EdgeCases (line 1207) | func TestInMemoryBackend_Edit_EdgeCases(t *testing.T) {
function TestInMemoryBackend_NormalizePath (line 1338) | func TestInMemoryBackend_NormalizePath(t *testing.T) {
function TestInMemoryBackend_MatchFileType (line 1374) | func TestInMemoryBackend_MatchFileType(t *testing.T) {
function TestInMemoryBackend_GrepRaw (line 1406) | func TestInMemoryBackend_GrepRaw(t *testing.T) {
function TestInMemoryBackend_GrepRaw_WithContext (line 1617) | func TestInMemoryBackend_GrepRaw_WithContext(t *testing.T) {
function TestInMemoryBackend_GrepRaw_Multiline (line 1714) | func TestInMemoryBackend_GrepRaw_Multiline(t *testing.T) {
function TestInMemoryBackend_GrepRaw_EmptyFiles (line 1822) | func TestInMemoryBackend_GrepRaw_EmptyFiles(t *testing.T) {
function TestInMemoryBackend_GrepRaw_SpecialCharacters (line 1856) | func TestInMemoryBackend_GrepRaw_SpecialCharacters(t *testing.T) {
function TestInMemoryBackend_GrepRaw_Concurrent (line 1926) | func TestInMemoryBackend_GrepRaw_Concurrent(t *testing.T) {
function BenchmarkInMemoryBackend_GrepRaw (line 2036) | func BenchmarkInMemoryBackend_GrepRaw(b *testing.B) {
function TestInMemoryBackend_GrepRaw_ComplexScenarios (line 2101) | func TestInMemoryBackend_GrepRaw_ComplexScenarios(t *testing.T) {
function TestInMemoryBackend_Read_Scenarios (line 2218) | func TestInMemoryBackend_Read_Scenarios(t *testing.T) {
FILE: adk/flow.go
type HistoryEntry (line 34) | type HistoryEntry struct
type HistoryRewriter (line 40) | type HistoryRewriter
type flowAgent (line 42) | type flowAgent struct
method deepCopy (line 54) | func (a *flowAgent) deepCopy() *flowAgent {
method getAgent (line 157) | func (a *flowAgent) getAgent(ctx context.Context, name string) *flowAg...
method genAgentInput (line 258) | func (a *flowAgent) genAgentInput(ctx context.Context, runCtx *runCont...
method Run (line 335) | func (a *flowAgent) Run(ctx context.Context, input *AgentInput, opts ....
method Resume (line 373) | func (a *flowAgent) Resume(ctx context.Context, info *ResumeInfo, opts...
method run (line 435) | func (a *flowAgent) run(
function SetSubAgents (line 71) | func SetSubAgents(ctx context.Context, agent Agent, subAgents []Agent) (...
type AgentOption (line 75) | type AgentOption
function WithDisallowTransferToParent (line 78) | func WithDisallowTransferToParent() AgentOption {
function WithHistoryRewriter (line 85) | func WithHistoryRewriter(h HistoryRewriter) AgentOption {
function toFlowAgent (line 91) | func toFlowAgent(ctx context.Context, agent Agent, opts ...AgentOption) ...
function AgentWithOptions (line 111) | func AgentWithOptions(ctx context.Context, agent Agent, opts ...AgentOpt...
function setSubAgents (line 115) | func setSubAgents(ctx context.Context, agent Agent, subAgents []Agent) (...
function rewriteMessage (line 171) | func rewriteMessage(msg Message, agentName string) Message {
function genMsg (line 238) | func genMsg(entry *HistoryEntry, agentName string) (Message, error) {
method deepCopy (line 247) | func (ai *AgentInput) deepCopy() *AgentInput {
function buildDefaultHistoryRewriter (line 313) | func buildDefaultHistoryRewriter(agentName string) HistoryRewriter {
type DeterministicTransferConfig (line 430) | type DeterministicTransferConfig struct
function exactRunPathMatch (line 536) | func exactRunPathMatch(aPath, bPath []RunStep) bool {
function wrapIterWithOnEnd (line 548) | func wrapIterWithOnEnd(ctx context.Context, iter *AsyncIterator[*AgentEv...
FILE: adk/flow_test.go
function strPtr (line 32) | func strPtr(s string) *string { return &s }
function TestRewriteMessage (line 34) | func TestRewriteMessage(t *testing.T) {
function TestTransferToAgent (line 95) | func TestTransferToAgent(t *testing.T) {
function TestTransferToAgentWithDesignatedCallback (line 211) | func TestTransferToAgentWithDesignatedCallback(t *testing.T) {
FILE: adk/handler.go
type InvokableToolCallEndpoint (line 31) | type InvokableToolCallEndpoint
type StreamableToolCallEndpoint (line 35) | type StreamableToolCallEndpoint
type EnhancedInvokableToolCallEndpoint (line 37) | type EnhancedInvokableToolCallEndpoint
type EnhancedStreamableToolCallEndpoint (line 39) | type EnhancedStreamableToolCallEndpoint
type ToolContext (line 42) | type ToolContext struct
type ModelContext (line 48) | type ModelContext struct
type ChatModelAgentContext (line 63) | type ChatModelAgentContext struct
type ChatModelAgentMiddleware (line 111) | type ChatModelAgentMiddleware interface
type BaseChatModelAgentMiddleware (line 213) | type BaseChatModelAgentMiddleware struct
method WrapInvokableToolCall (line 215) | func (b *BaseChatModelAgentMiddleware) WrapInvokableToolCall(_ context...
method WrapStreamableToolCall (line 219) | func (b *BaseChatModelAgentMiddleware) WrapStreamableToolCall(_ contex...
method WrapEnhancedInvokableToolCall (line 223) | func (b *BaseChatModelAgentMiddleware) WrapEnhancedInvokableToolCall(_...
method WrapEnhancedStreamableToolCall (line 227) | func (b *BaseChatModelAgentMiddleware) WrapEnhancedStreamableToolCall(...
method WrapModel (line 231) | func (b *BaseChatModelAgentMiddleware) WrapModel(_ context.Context, m ...
method BeforeAgent (line 235) | func (b *BaseChatModelAgentMiddleware) BeforeAgent(ctx context.Context...
method BeforeModelRewriteState (line 239) | func (b *BaseChatModelAgentMiddleware) BeforeModelRewriteState(ctx con...
method AfterModelRewriteState (line 243) | func (b *BaseChatModelAgentMiddleware) AfterModelRewriteState(ctx cont...
function SetRunLocalValue (line 256) | func SetRunLocalValue(ctx context.Context, key string, value any) error {
function GetRunLocalValue (line 279) | func GetRunLocalValue(ctx context.Context, key string) (any, bool, error) {
function DeleteRunLocalValue (line 298) | func DeleteRunLocalValue(ctx context.Context, key string) error {
function SendEvent (line 317) | func SendEvent(ctx context.Context, event *AgentEvent) error {
FILE: adk/handler_test.go
type testInstructionHandler (line 34) | type testInstructionHandler struct
method BeforeAgent (line 39) | func (h *testInstructionHandler) BeforeAgent(ctx context.Context, runC...
type testInstructionFuncHandler (line 48) | type testInstructionFuncHandler struct
method BeforeAgent (line 53) | func (h *testInstructionFuncHandler) BeforeAgent(ctx context.Context, ...
type testToolsHandler (line 62) | type testToolsHandler struct
method BeforeAgent (line 67) | func (h *testToolsHandler) BeforeAgent(ctx context.Context, runCtx *Ch...
type testToolsFuncHandler (line 72) | type testToolsFuncHandler struct
method BeforeAgent (line 77) | func (h *testToolsFuncHandler) BeforeAgent(ctx context.Context, runCtx...
type testBeforeAgentHandler (line 87) | type testBeforeAgentHandler struct
method BeforeAgent (line 92) | func (h *testBeforeAgentHandler) BeforeAgent(ctx context.Context, runC...
type testBeforeModelRewriteStateHandler (line 96) | type testBeforeModelRewriteStateHandler struct
method BeforeModelRewriteState (line 101) | func (h *testBeforeModelRewriteStateHandler) BeforeModelRewriteState(c...
type testAfterModelRewriteStateHandler (line 105) | type testAfterModelRewriteStateHandler struct
method AfterModelRewriteState (line 110) | func (h *testAfterModelRewriteStateHandler) AfterModelRewriteState(ctx...
type testToolWrapperHandler (line 114) | type testToolWrapperHandler struct
method WrapInvokableToolCall (line 120) | func (h *testToolWrapperHandler) WrapInvokableToolCall(ctx context.Con...
method WrapStreamableToolCall (line 127) | func (h *testToolWrapperHandler) WrapStreamableToolCall(ctx context.Co...
type testModelWrapperHandler (line 134) | type testModelWrapperHandler struct
method WrapModel (line 139) | func (h *testModelWrapperHandler) WrapModel(ctx context.Context, m mod...
function newTestInvokableToolCallWrapper (line 143) | func newTestInvokableToolCallWrapper(beforeFn, afterFn func()) func(cont...
function newResultModifyingInvokableToolCallWrapper (line 158) | func newResultModifyingInvokableToolCallWrapper(modifyFn func(string) st...
function newTestStreamableToolCallWrapper (line 170) | func newTestStreamableToolCallWrapper(beforeFn, afterFn func()) func(con...
function TestHandlerExecutionOrder (line 185) | func TestHandlerExecutionOrder(t *testing.T) {
function TestToolsHandlerCombinations (line 271) | func TestToolsHandlerCombinations(t *testing.T) {
function TestMessageRewriteHandlers (line 473) | func TestMessageRewriteHandlers(t *testing.T) {
function TestToolCallWrapperHandlers (line 552) | func TestToolCallWrapperHandlers(t *testing.T) {
function TestToolContextFunctions (line 757) | func TestToolContextFunctions(t *testing.T) {
type toolChainingTestModel (line 812) | type toolChainingTestModel struct
method Generate (line 818) | func (m *toolChainingTestModel) Generate(ctx context.Context, msgs []*...
method Stream (line 825) | func (m *toolChainingTestModel) Stream(ctx context.Context, msgs []*sc...
method BindTools (line 832) | func (m *toolChainingTestModel) BindTools(tools []*schema.ToolInfo) er...
function TestContextPropagation (line 836) | func TestContextPropagation(t *testing.T) {
function TestCustomHandler (line 919) | func TestCustomHandler(t *testing.T) {
function TestHandlerErrorHandling (line 952) | func TestHandlerErrorHandling(t *testing.T) {
type namedTool (line 990) | type namedTool struct
method Info (line 994) | func (t *namedTool) Info(_ context.Context) (*schema.ToolInfo, error) {
method InvokableRun (line 998) | func (t *namedTool) InvokableRun(_ context.Context, _ string, _ ...too...
type streamingNamedTool (line 1002) | type streamingNamedTool struct
method Info (line 1006) | func (t *streamingNamedTool) Info(_ context.Context) (*schema.ToolInfo...
method InvokableRun (line 1010) | func (t *streamingNamedTool) InvokableRun(_ context.Context, _ string,...
method StreamableRun (line 1014) | func (t *streamingNamedTool) StreamableRun(_ context.Context, _ string...
type callableTool (line 1018) | type callableTool struct
method Info (line 1023) | func (t *callableTool) Info(_ context.Context) (*schema.ToolInfo, erro...
method InvokableRun (line 1027) | func (t *callableTool) InvokableRun(_ context.Context, _ string, _ ......
type countingHandler (line 1034) | type countingHandler struct
method BeforeAgent (line 1042) | func (h *countingHandler) BeforeAgent(ctx context.Context, runCtx *Cha...
method BeforeModelRewriteState (line 1049) | func (h *countingHandler) BeforeModelRewriteState(ctx context.Context,...
method AfterModelRewriteState (line 1056) | func (h *countingHandler) AfterModelRewriteState(ctx context.Context, ...
function newTestModelWrapperFn (line 1063) | func newTestModelWrapperFn(beforeFn, afterFn func()) func(context.Contex...
type testWrappedModel (line 1073) | type testWrappedModel struct
method Generate (line 1079) | func (m *testWrappedModel) Generate(ctx context.Context, input []*sche...
method Stream (line 1090) | func (m *testWrappedModel) Stream(ctx context.Context, input []*schema...
function TestModelWrapperHandlers (line 1101) | func TestModelWrapperHandlers(t *testing.T) {
type simpleChatModelWithoutCallbacks (line 1275) | type simpleChatModelWithoutCallbacks struct
method Generate (line 1280) | func (m *simpleChatModelWithoutCallbacks) Generate(ctx context.Context...
method Stream (line 1287) | func (m *simpleChatModelWithoutCallbacks) Stream(ctx context.Context, ...
method WithTools (line 1294) | func (m *simpleChatModelWithoutCallbacks) WithTools(tools []*schema.To...
function newInputModifyingWrapperFn (line 1298) | func newInputModifyingWrapperFn(inputPrefix string) func(context.Context...
type inputOutputModifyingModel (line 1307) | type inputOutputModifyingModel struct
method Generate (line 1312) | func (m *inputOutputModifyingModel) Generate(ctx context.Context, inpu...
method Stream (line 1324) | func (m *inputOutputModifyingModel) Stream(ctx context.Context, input ...
function TestModelWrapper_InputModification (line 1336) | func TestModelWrapper_InputModification(t *testing.T) {
function TestRunLocalValueFunctions (line 1437) | func TestRunLocalValueFunctions(t *testing.T) {
function TestHandlerErrorPropagation (line 1644) | func TestHandlerErrorPropagation(t *testing.T) {
function TestToolContextInWrappers (line 1749) | func TestToolContextInWrappers(t *testing.T) {
FILE: adk/instruction.go
constant TransferToAgentInstruction (line 28) | TransferToAgentInstruction = `Available other agents: %s
constant TransferToAgentInstructionChinese (line 36) | TransferToAgentInstructionChinese = `可用的其他 agent:%s
constant agentDescriptionTpl (line 44) | agentDescriptionTpl = "\n- Agent name: %s\n Agent description: %s"
constant agentDescriptionTplChinese (line 45) | agentDescriptionTplChinese = "\n- Agent 名字: %s\n Agent 描述: %s"
function genTransferToAgentInstruction (line 48) | func genTransferToAgentInstruction(ctx context.Context, agents []Agent) ...
FILE: adk/interface.go
constant ComponentOfAgent (line 33) | ComponentOfAgent components.Component = "Agent"
type MessageVariant (line 38) | type MessageVariant struct
method GobEncode (line 73) | func (mv *MessageVariant) GobEncode() ([]byte, error) {
method GobDecode (line 106) | func (mv *MessageVariant) GobDecode(b []byte) error {
method GetMessage (line 122) | func (mv *MessageVariant) GetMessage() (Message, error) {
function EventFromMessage (line 50) | func EventFromMessage(msg Message, msgStream MessageStream,
type messageVariantSerialization (line 65) | type messageVariantSerialization struct
type TransferToAgentAction (line 137) | type TransferToAgentAction struct
type AgentOutput (line 141) | type AgentOutput struct
function NewTransferToAgentAction (line 148) | func NewTransferToAgentAction(destAgentName string) *AgentAction {
function NewExitAction (line 153) | func NewExitAction() *AgentAction {
type AgentAction (line 168) | type AgentAction struct
type RunStep (line 183) | type RunStep struct
method String (line 191) | func (r *RunStep) String() string {
method Equals (line 195) | func (r *RunStep) Equals(r1 RunStep) bool {
method GobEncode (line 199) | func (r *RunStep) GobEncode() ([]byte, error) {
method GobDecode (line 209) | func (r *RunStep) GobDecode(b []byte) error {
function init (line 187) | func init() {
type runStepSerialization (line 219) | type runStepSerialization struct
type AgentEvent (line 224) | type AgentEvent struct
type AgentInput (line 241) | type AgentInput struct
type Agent (line 247) | type Agent interface
type OnSubAgents (line 260) | type OnSubAgents interface
type ResumableAgent (line 267) | type ResumableAgent interface
FILE: adk/internal/config.go
type Language (line 26) | type Language
constant LanguageEnglish (line 30) | LanguageEnglish Language = iota
constant LanguageChinese (line 32) | LanguageChinese
function SetLanguage (line 39) | func SetLanguage(lang Language) error {
function getLanguage (line 50) | func getLanguage() Language {
type I18nPrompts (line 58) | type I18nPrompts struct
function SelectPrompt (line 65) | func SelectPrompt(prompts I18nPrompts) string {
FILE: adk/interrupt.go
type ResumeInfo (line 32) | type ResumeInfo struct
type InterruptInfo (line 48) | type InterruptInfo struct
function Interrupt (line 60) | func Interrupt(ctx context.Context, info any) *AgentEvent {
function StatefulInterrupt (line 89) | func StatefulInterrupt(ctx context.Context, info any, state any) *AgentE...
function CompositeInterrupt (line 120) | func CompositeInterrupt(ctx context.Context, info any, state any,
constant AddressSegmentAgent (line 154) | AddressSegmentAgent AddressSegmentType = "agent"
constant AddressSegmentTool (line 155) | AddressSegmentTool AddressSegmentType = "tool"
function AppendAddressSegment (line 161) | func AppendAddressSegment(ctx context.Context, segType AddressSegmentTyp...
function FromInterruptContexts (line 172) | func FromInterruptContexts(contexts []*InterruptCtx) *InterruptSignal {
function WithCheckPointID (line 177) | func WithCheckPointID(id string) AgentRunOption {
function init (line 183) | func init() {
type serialization (line 190) | type serialization struct
method loadCheckPoint (line 199) | func (r *Runner) loadCheckPoint(ctx context.Context, checkpointID string) (
function preprocessADKCheckpoint (line 247) | func preprocessADKCheckpoint(data []byte) []byte {
method saveCheckPoint (line 263) | func (r *Runner) saveCheckPoint(
constant bridgeCheckpointID (line 287) | bridgeCheckpointID = "adk_react_mock_key"
function newBridgeStore (line 289) | func newBridgeStore() *bridgeStore {
function newResumeBridgeStore (line 293) | func newResumeBridgeStore(data []byte) *bridgeStore {
type bridgeStore (line 300) | type bridgeStore struct
method Get (line 305) | func (m *bridgeStore) Get(_ context.Context, _ string) ([]byte, bool, ...
method Set (line 312) | func (m *bridgeStore) Set(_ context.Context, _ string, checkPoint []by...
function getNextResumeAgent (line 318) | func getNextResumeAgent(ctx context.Context, info *ResumeInfo) (string, ...
function getNextResumeAgents (line 343) | func getNextResumeAgents(ctx context.Context, info *ResumeInfo) (map[str...
function buildResumeInfo (line 356) | func buildResumeInfo(ctx context.Context, nextAgentID string, info *Resu...
FILE: adk/interrupt_test.go
type interruptTestToolsHandler (line 35) | type interruptTestToolsHandler struct
method BeforeAgent (line 61) | func (h *interruptTestToolsHandler) BeforeAgent(ctx context.Context, r...
function TestPreprocessADKCheckpoint (line 40) | func TestPreprocessADKCheckpoint(t *testing.T) {
function TestSaveAgentEventWrapper (line 66) | func TestSaveAgentEventWrapper(t *testing.T) {
function TestInterruptFunctionsPopulateInterruptContextsImmediately (line 105) | func TestInterruptFunctionsPopulateInterruptContextsImmediately(t *testi...
function TestSimpleInterrupt (line 167) | func TestSimpleInterrupt(t *testing.T) {
function TestMultiAgentInterrupt (line 233) | func TestMultiAgentInterrupt(t *testing.T) {
function TestWorkflowInterrupt (line 324) | func TestWorkflowInterrupt(t *testing.T) {
function TestChatModelInterrupt (line 1052) | func TestChatModelInterrupt(t *testing.T) {
function TestChatModelAgentToolInterrupt (line 1142) | func TestChatModelAgentToolInterrupt(t *testing.T) {
function newMyStore (line 1263) | func newMyStore() *myStore {
type myStore (line 1269) | type myStore struct
method Set (line 1273) | func (m *myStore) Set(_ context.Context, key string, value []byte) err...
method Get (line 1278) | func (m *myStore) Get(_ context.Context, key string) ([]byte, bool, er...
type myAgentOptions (line 1283) | type myAgentOptions struct
function withValue (line 1289) | func withValue(value string) AgentRunOption {
type myAgent (line 1295) | type myAgent struct
method Name (line 1301) | func (m *myAgent) Name(_ context.Context) string {
method Description (line 1308) | func (m *myAgent) Description(_ context.Context) string {
method Run (line 1312) | func (m *myAgent) Run(ctx context.Context, input *AgentInput, options ...
method Resume (line 1316) | func (m *myAgent) Resume(ctx context.Context, info *ResumeInfo, opts ....
type myModel (line 1320) | type myModel struct
method Generate (line 1326) | func (m *myModel) Generate(_ context.Context, input []*schema.Message,...
method Stream (line 1338) | func (m *myModel) Stream(_ context.Context, _ []*schema.Message, _ ......
method WithTools (line 1342) | func (m *myModel) WithTools(_ []*schema.ToolInfo) (model.ToolCallingCh...
type myTool1 (line 1346) | type myTool1 struct
method Info (line 1348) | func (m *myTool1) Info(_ context.Context) (*schema.ToolInfo, error) {
method InvokableRun (line 1355) | func (m *myTool1) InvokableRun(ctx context.Context, _ string, _ ...too...
function TestCyclicalAgentInterrupt (line 1369) | func TestCyclicalAgentInterrupt(t *testing.T) {
type myStatefulTool (line 1511) | type myStatefulTool struct
method Info (line 1516) | func (m *myStatefulTool) Info(_ context.Context) (*schema.ToolInfo, er...
method InvokableRun (line 1531) | func (m *myStatefulTool) InvokableRun(ctx context.Context, _ string, _...
type myStatefulToolState (line 1523) | type myStatefulToolState struct
function init (line 1527) | func init() {
function TestChatModelParallelToolInterruptAndResume (line 1546) | func TestChatModelParallelToolInterruptAndResume(t *testing.T) {
function TestNestedChatModelAgentWithAgentTool (line 1651) | func TestNestedChatModelAgentWithAgentTool(t *testing.T) {
function consumeUntilInterrupt (line 1807) | func consumeUntilInterrupt(iter *AsyncIterator[*AgentEvent]) (normalEven...
type returnDirectlyTool (line 1822) | type returnDirectlyTool struct
method Info (line 1826) | func (t *returnDirectlyTool) Info(_ context.Context) (*schema.ToolInfo...
method InvokableRun (line 1833) | func (t *returnDirectlyTool) InvokableRun(_ context.Context, _ string,...
type interruptingTool (line 1837) | type interruptingTool struct
method Info (line 1841) | func (i *interruptingTool) Info(_ context.Context) (*schema.ToolInfo, ...
method InvokableRun (line 1848) | func (i *interruptingTool) InvokableRun(ctx context.Context, _ string,...
type twoToolCallModel (line 1860) | type twoToolCallModel struct
method Generate (line 1868) | func (m *twoToolCallModel) Generate(_ context.Context, _ []*schema.Mes...
method Stream (line 1905) | func (m *twoToolCallModel) Stream(_ context.Context, _ []*schema.Messa...
method WithTools (line 1909) | func (m *twoToolCallModel) WithTools(_ []*schema.ToolInfo) (model.Tool...
method GetReceivedTools (line 1913) | func (m *twoToolCallModel) GetReceivedTools() []*schema.ToolInfo {
type dynamicTool (line 1919) | type dynamicTool struct
method Info (line 1923) | func (t *dynamicTool) Info(_ context.Context) (*schema.ToolInfo, error) {
method InvokableRun (line 1930) | func (t *dynamicTool) InvokableRun(_ context.Context, _ string, _ ...t...
function TestReturnDirectlyEventSentAfterResume (line 1934) | func TestReturnDirectlyEventSentAfterResume(t *testing.T) {
FILE: adk/middlewares/dynamictool/toolsearch/toolsearch.go
type Config (line 33) | type Config struct
function New (line 57) | func New(ctx context.Context, config *Config) (adk.ChatModelAgentMiddlew...
type middleware (line 70) | type middleware struct
method BeforeAgent (line 75) | func (m *middleware) BeforeAgent(ctx context.Context, runCtx *adk.Chat...
method WrapModel (line 90) | func (m *middleware) WrapModel(_ context.Context, cm model.BaseChatMod...
type wrapper (line 94) | type wrapper struct
method Generate (line 101) | func (w *wrapper) Generate(ctx context.Context, input []*schema.Messag...
method Stream (line 109) | func (w *wrapper) Stream(ctx context.Context, input []*schema.Message,...
function newToolSearchTool (line 117) | func newToolSearchTool(toolNames []string) *toolSearchTool {
type toolSearchTool (line 121) | type toolSearchTool struct
method Info (line 129) | func (t *toolSearchTool) Info(ctx context.Context) (*schema.ToolInfo, ...
method InvokableRun (line 151) | func (t *toolSearchTool) InvokableRun(ctx context.Context, argumentsIn...
constant toolSearchToolName (line 126) | toolSearchToolName = "tool_search"
type toolSearchArgs (line 143) | type toolSearchArgs struct
type toolSearchResult (line 147) | type toolSearchResult struct
function getToolNames (line 185) | func getToolNames(ctx context.Context, tools []tool.BaseTool) ([]string,...
function extractSelectedTools (line 197) | func extractSelectedTools(ctx context.Context, messages []*schema.Messag...
function invertSelect (line 214) | func invertSelect[T comparable](all []T, selected []T) map[T]struct{} {
function removeTools (line 229) | func removeTools(ctx context.Context, all []*schema.ToolInfo, dynamicToo...
FILE: adk/middlewares/dynamictool/toolsearch/toolsearch_test.go
type mockTool (line 33) | type mockTool struct
method Info (line 38) | func (m *mockTool) Info(ctx context.Context) (*schema.ToolInfo, error) {
function newMockTool (line 45) | func newMockTool(name, desc string) *mockTool {
function TestNew (line 49) | func TestNew(t *testing.T) {
function TestMiddleware_BeforeAgent (line 77) | func TestMiddleware_BeforeAgent(t *testing.T) {
function TestToolSearchTool_Info (line 111) | func TestToolSearchTool_Info(t *testing.T) {
function TestToolSearchTool_InvokableRun (line 123) | func TestToolSearchTool_InvokableRun(t *testing.T) {
function TestGetToolNames (line 197) | func TestGetToolNames(t *testing.T) {
function TestExtractSelectedTools (line 218) | func TestExtractSelectedTools(t *testing.T) {
function TestInvertSelect (line 275) | func TestInvertSelect(t *testing.T) {
function TestRemoveTools (line 319) | func TestRemoveTools(t *testing.T) {
type mockChatModel (line 388) | type mockChatModel struct
method Generate (line 393) | func (m *mockChatModel) Generate(ctx context.Context, input []*schema....
method Stream (line 400) | func (m *mockChatModel) Stream(ctx context.Context, input []*schema.Me...
function TestWrapper_Generate (line 407) | func TestWrapper_Generate(t *testing.T) {
function TestWrapper_Stream (line 449) | func TestWrapper_Stream(t *testing.T) {
FILE: adk/middlewares/filesystem/filesystem.go
constant ToolNameLs (line 40) | ToolNameLs = "ls"
constant ToolNameReadFile (line 41) | ToolNameReadFile = "read_file"
constant ToolNameWriteFile (line 42) | ToolNameWriteFile = "write_file"
constant ToolNameEditFile (line 43) | ToolNameEditFile = "edit_file"
constant ToolNameGlob (line 44) | ToolNameGlob = "glob"
constant ToolNameGrep (line 45) | ToolNameGrep = "grep"
constant ToolNameExecute (line 46) | ToolNameExecute = "execute"
constant noFilesFound (line 48) | noFilesFound = "No files found"
constant noMatchesFound (line 49) | noMatchesFound = "No matches found"
type ToolConfig (line 53) | type ToolConfig struct
type Config (line 75) | type Config struct
method Validate (line 151) | func (c *Config) Validate() error {
function NewMiddleware (line 170) | func NewMiddleware(ctx context.Context, config *Config) (adk.AgentMiddle...
type MiddlewareConfig (line 219) | type MiddlewareConfig struct
method Validate (line 282) | func (c *MiddlewareConfig) Validate() error {
method mergeToolConfigWithDesc (line 298) | func (c *MiddlewareConfig) mergeToolConfigWithDesc(
function New (line 340) | func New(ctx context.Context, config *MiddlewareConfig) (adk.ChatModelAg...
type filesystemMiddleware (line 362) | type filesystemMiddleware struct
method BeforeAgent (line 368) | func (m *filesystemMiddleware) BeforeAgent(ctx context.Context, runCtx...
type toolSpec (line 384) | type toolSpec struct
function getFilesystemTools (line 390) | func getFilesystemTools(_ context.Context, middlewareConfig *MiddlewareC...
function createToolFromSpec (line 497) | func createToolFromSpec(middlewareConfig *MiddlewareConfig, spec toolSpe...
function getOrCreateTool (line 513) | func getOrCreateTool(customTool tool.BaseTool, createFunc func() (tool.B...
type lsArgs (line 520) | type lsArgs struct
function newLsTool (line 524) | func newLsTool(fs filesystem.Backend, name string, desc string) (tool.Ba...
type readFileArgs (line 546) | type readFileArgs struct
function newReadFileTool (line 557) | func newReadFileTool(fs filesystem.Backend, name string, desc string) (t...
type writeFileArgs (line 592) | type writeFileArgs struct
function newWriteFileTool (line 600) | func newWriteFileTool(fs filesystem.Backend, name string, desc string) (...
type editFileArgs (line 618) | type editFileArgs struct
function newEditFileTool (line 632) | func newEditFileTool(fs filesystem.Backend, name string, desc string) (t...
type globArgs (line 652) | type globArgs struct
function newGlobTool (line 660) | func newGlobTool(fs filesystem.Backend, name string, desc string) (tool....
type grepArgs (line 685) | type grepArgs struct
function newGrepTool (line 739) | func newGrepTool(fs filesystem.Backend, name string, desc string) (tool....
type executeArgs (line 804) | type executeArgs struct
function newExecuteTool (line 808) | func newExecuteTool(sb filesystem.Shell, name string, desc string) (tool...
function newStreamingExecuteTool (line 826) | func newStreamingExecuteTool(sb filesystem.StreamingShell, name string, ...
function convExecuteResponse (line 893) | func convExecuteResponse(response *filesystem.ExecuteResponse) string {
function valueOrDefault (line 913) | func valueOrDefault[T any](ptr *T, defaultValue T) T {
function applyPagination (line 920) | func applyPagination[T any](items []T, offset, headLimit int) []T {
function formatFileMatches (line 935) | func formatFileMatches(matches []filesystem.GrepMatch, offset, headLimit...
function formatContentMatches (line 957) | func formatContentMatches(matches []filesystem.GrepMatch, showLineNum bo...
function formatCountMatches (line 975) | func formatCountMatches(matches []filesystem.GrepMatch, offset, headLimi...
function selectToolDesc (line 1018) | func selectToolDesc(customDesc string, defaultEnglish, defaultChinese st...
function selectToolName (line 1029) | func selectToolName(customName string, defaultName string) string {
FILE: adk/middlewares/filesystem/filesystem_test.go
function setupTestBackend (line 36) | func setupTestBackend() *filesystem.InMemoryBackend {
function invokeTool (line 66) | func invokeTool(_ *testing.T, bt tool.BaseTool, input string) (string, e...
function TestLsTool (line 75) | func TestLsTool(t *testing.T) {
function TestReadFileTool (line 120) | func TestReadFileTool(t *testing.T) {
function TestWriteFileTool (line 179) | func TestWriteFileTool(t *testing.T) {
function TestEditFileTool (line 238) | func TestEditFileTool(t *testing.T) {
function TestGlobTool (line 319) | func TestGlobTool(t *testing.T) {
function TestGrepTool (line 381) | func TestGrepTool(t *testing.T) {
function TestExecuteTool (line 443) | func TestExecuteTool(t *testing.T) {
function ptrOf (line 521) | func ptrOf[T any](t T) *T {
type mockShellBackend (line 525) | type mockShellBackend struct
method Execute (line 530) | func (m *mockShellBackend) Execute(ctx context.Context, req *filesyste...
function TestGetFilesystemTools (line 534) | func TestGetFilesystemTools(t *testing.T) {
function TestNew (line 600) | func TestNew(t *testing.T) {
function TestFilesystemMiddleware_BeforeAgent (line 653) | func TestFilesystemMiddleware_BeforeAgent(t *testing.T) {
function TestFilesystemMiddleware_WrapInvokableToolCall (line 685) | func TestFilesystemMiddleware_WrapInvokableToolCall(t *testing.T) {
function TestGrepToolWithSortingAndPagination (line 708) | func TestGrepToolWithSortingAndPagination(t *testing.T) {
function TestApplyPagination (line 817) | func TestApplyPagination(t *testing.T) {
function TestCustomToolNames (line 849) | func TestCustomToolNames(t *testing.T) {
function TestSelectToolName (line 991) | func TestSelectToolName(t *testing.T) {
function TestGetOrCreateTool (line 1004) | func TestGetOrCreateTool(t *testing.T) {
function TestCustomTools (line 1057) | func TestCustomTools(t *testing.T) {
function TestToolConfig (line 1217) | func TestToolConfig(t *testing.T) {
function TestToolConfigEdgeCases (line 1360) | func TestToolConfigEdgeCases(t *testing.T) {
function TestGetFilesystemTools_DisableAllTools (line 1513) | func TestGetFilesystemTools_DisableAllTools(t *testing.T) {
function TestGetFilesystemTools_StreamingShell (line 1532) | func TestGetFilesystemTools_StreamingShell(t *testing.T) {
function TestGetFilesystemTools_NilBackend (line 1572) | func TestGetFilesystemTools_NilBackend(t *testing.T) {
function TestGetFilesystemTools_PartialDisable (line 1617) | func TestGetFilesystemTools_PartialDisable(t *testing.T) {
type mockStreamingShell (line 1644) | type mockStreamingShell struct
method ExecuteStreaming (line 1646) | func (m *mockStreamingShell) ExecuteStreaming(ctx context.Context, inp...
type mockStreamingShellWithError (line 1658) | type mockStreamingShellWithError struct
method ExecuteStreaming (line 1660) | func (m *mockStreamingShellWithError) ExecuteStreaming(ctx context.Con...
type mockStreamingShellWithRecvError (line 1664) | type mockStreamingShellWithRecvError struct
method ExecuteStreaming (line 1666) | func (m *mockStreamingShellWithRecvError) ExecuteStreaming(ctx context...
type mockStreamingShellWithExitCode (line 1675) | type mockStreamingShellWithExitCode struct
method ExecuteStreaming (line 1679) | func (m *mockStreamingShellWithExitCode) ExecuteStreaming(ctx context....
type mockStreamingShellNoOutput (line 1691) | type mockStreamingShellNoOutput struct
method ExecuteStreaming (line 1693) | func (m *mockStreamingShellNoOutput) ExecuteStreaming(ctx context.Cont...
type mockStreamingShellTruncated (line 1704) | type mockStreamingShellTruncated struct
method ExecuteStreaming (line 1706) | func (m *mockStreamingShellTruncated) ExecuteStreaming(ctx context.Con...
type mockStreamingShellNilChunk (line 1719) | type mockStreamingShellNilChunk struct
method ExecuteStreaming (line 1721) | func (m *mockStreamingShellNilChunk) ExecuteStreaming(ctx context.Cont...
function TestNewStreamingExecuteTool (line 1734) | func TestNewStreamingExecuteTool(t *testing.T) {
function TestNew_StreamingShell (line 1892) | func TestNew_StreamingShell(t *testing.T) {
function TestNewMiddleware_Validation (line 1919) | func TestNewMiddleware_Validation(t *testing.T) {
function TestMiddlewareConfig_Validate (line 1946) | func TestMiddlewareConfig_Validate(t *testing.T) {
function TestNewStreamingExecuteTool_MultipleChunks (line 1981) | func TestNewStreamingExecuteTool_MultipleChunks(t *testing.T) {
type mockStreamingShellMultiChunk (line 2008) | type mockStreamingShellMultiChunk struct
method ExecuteStreaming (line 2010) | func (m *mockStreamingShellMultiChunk) ExecuteStreaming(ctx context.Co...
function TestNewStreamingExecuteTool_ExitCodeOnlyInLastChunk (line 2021) | func TestNewStreamingExecuteTool_ExitCodeOnlyInLastChunk(t *testing.T) {
type mockStreamingShellExitCodeLast (line 2045) | type mockStreamingShellExitCodeLast struct
method ExecuteStreaming (line 2049) | func (m *mockStreamingShellExitCodeLast) ExecuteStreaming(ctx context....
function TestConvExecuteResponse_NilResponse (line 2059) | func TestConvExecuteResponse_NilResponse(t *testing.T) {
function TestConvExecuteResponse_NilExitCode (line 2064) | func TestConvExecuteResponse_NilExitCode(t *testing.T) {
function TestConfig_Validate (line 2071) | func TestConfig_Validate(t *testing.T) {
function TestGetFilesystemTools_CustomToolWithShell (line 2104) | func TestGetFilesystemTools_CustomToolWithShell(t *testing.T) {
function TestMergeToolConfigWithDesc (line 2133) | func TestMergeToolConfigWithDesc(t *testing.T) {
function TestNewMiddleware_WithShell (line 2175) | func TestNewMiddleware_WithShell(t *testing.T) {
function TestNewExecuteTool_ShellError (line 2202) | func TestNewExecuteTool_ShellError(t *testing.T) {
type mockShellBackendWithError (line 2213) | type mockShellBackendWithError struct
method Execute (line 2215) | func (m *mockShellBackendWithError) Execute(ctx context.Context, req *...
FILE: adk/middlewares/filesystem/large_tool_result.go
type toolResultOffloadingConfig (line 36) | type toolResultOffloadingConfig struct
function newToolResultOffloading (line 42) | func newToolResultOffloading(ctx context.Context, config *toolResultOffl...
type toolResultOffloading (line 65) | type toolResultOffloading struct
method invoke (line 71) | func (t *toolResultOffloading) invoke(endpoint compose.InvokableToolEn...
method stream (line 85) | func (t *toolResultOffloading) stream(endpoint compose.StreamableToolE...
method handleResult (line 103) | func (t *toolResultOffloading) handleResult(ctx context.Context, resul...
function concatString (line 138) | func concatString(sr *schema.StreamReader[string]) (string, error) {
function formatToolMessage (line 155) | func formatToolMessage(s string) string {
FILE: adk/middlewares/filesystem/large_tool_result_test.go
type mockBackend (line 32) | type mockBackend struct
method Write (line 42) | func (m *mockBackend) Write(ctx context.Context, req *WriteRequest) er...
method Read (line 47) | func (m *mockBackend) Read(ctx context.Context, req *ReadRequest) (*Fi...
method LsInfo (line 55) | func (m *mockBackend) LsInfo(ctx context.Context, _ *LsInfoRequest) ([...
method GrepRaw (line 59) | func (m *mockBackend) GrepRaw(ctx context.Context, _ *GrepRequest) ([]...
method GlobInfo (line 63) | func (m *mockBackend) GlobInfo(ctx context.Context, _ *GlobInfoRequest...
method Edit (line 67) | func (m *mockBackend) Edit(ctx context.Context, _ *EditRequest) error {
function newMockBackend (line 36) | func newMockBackend() *mockBackend {
function TestToolResultOffloading_SmallResult (line 71) | func TestToolResultOffloading_SmallResult(t *testing.T) {
function TestToolResultOffloading_LargeResult (line 113) | func TestToolResultOffloading_LargeResult(t *testing.T) {
function TestToolResultOffloading_CustomPathGenerator (line 170) | func TestToolResultOffloading_CustomPathGenerator(t *testing.T) {
function TestToolResultOffloading_PathGeneratorError (line 218) | func TestToolResultOffloading_PathGeneratorError(t *testing.T) {
function TestToolResultOffloading_EndpointError (line 255) | func TestToolResultOffloading_EndpointError(t *testing.T) {
function TestToolResultOffloading_DefaultTokenLimit (line 288) | func TestToolResultOffloading_DefaultTokenLimit(t *testing.T) {
function TestToolResultOffloading_Stream (line 328) | func TestToolResultOffloading_Stream(t *testing.T) {
function TestToolResultOffloading_StreamError (line 400) | func TestToolResultOffloading_StreamError(t *testing.T) {
function TestFormatToolMessage (line 433) | func TestFormatToolMessage(t *testing.T) {
function TestConcatString (line 481) | func TestConcatString(t *testing.T) {
function TestToolResultOffloading_BackendWriteError (line 544) | func TestToolResultOffloading_BackendWriteError(t *testing.T) {
type failingBackend (line 582) | type failingBackend struct
method Write (line 586) | func (f *failingBackend) Write(ctx context.Context, req *WriteRequest)...
method Read (line 593) | func (f *failingBackend) Read(ctx context.Context, req *ReadRequest) (...
method LsInfo (line 597) | func (f *failingBackend) LsInfo(ctx context.Context, _ *LsInfoRequest)...
method GrepRaw (line 601) | func (f *failingBackend) GrepRaw(ctx context.Context, _ *GrepRequest) ...
method GlobInfo (line 605) | func (f *failingBackend) GlobInfo(ctx context.Context, _ *GlobInfoRequ...
method Edit (line 609) | func (f *failingBackend) Edit(ctx context.Context, _ *EditRequest) err...
FILE: adk/middlewares/filesystem/prompt.go
constant tooLargeToolMessage (line 28) | tooLargeToolMessage = `Tool result too large, the result of this tool ca...
constant tooLargeToolMessageChinese (line 36) | tooLargeToolMessageChinese = `工具结果过大,此工具调用 {tool_call_id} 的结果已保存到文件系统的以下...
constant ListFilesToolDesc (line 44) | ListFilesToolDesc = `Lists all files in the filesystem, filtering by dir...
constant ListFilesToolDescChinese (line 52) | ListFilesToolDescChinese = `列出文件系统中的所有文件,按目录过滤。
constant ReadFileToolDesc (line 60) | ReadFileToolDesc = `Reads a file from the filesystem. You can access any...
constant ReadFileToolDescChinese (line 76) | ReadFileToolDescChinese = `从文件系统读取文件。你可以使用此工具直接访问任何文件。
constant EditFileToolDesc (line 92) | EditFileToolDesc = `Performs exact string replacements in files.
constant EditFileToolDescChinese (line 102) | EditFileToolDescChinese = `在文件中执行精确的字符串替换。
constant WriteFileToolDesc (line 112) | WriteFileToolDesc = `Writes a file to the local filesystem.
constant WriteFileToolDescChinese (line 121) | WriteFileToolDescChinese = `将文件写入本地文件系统。
constant GlobToolDesc (line 130) | GlobToolDesc = `Fast file pattern matching tool that works with any code...
constant GlobToolDescChinese (line 141) | GlobToolDescChinese = `适用于任何代码库大小的快速文件模式匹配工具
constant GrepToolDesc (line 152) | GrepToolDesc = `
constant GrepToolDescChinese (line 164) | GrepToolDescChinese = `
constant ExecuteToolDesc (line 176) | ExecuteToolDesc = `
constant ExecuteToolDescChinese (line 219) | ExecuteToolDescChinese = `
FILE: adk/middlewares/patchtoolcalls/patchtoolcalls.go
type Config (line 30) | type Config struct
function New (line 49) | func New(ctx context.Context, cfg *Config) (adk.ChatModelAgentMiddleware...
type middleware (line 59) | type middleware struct
method BeforeModelRewriteState (line 64) | func (m *middleware) BeforeModelRewriteState(ctx context.Context, stat...
method createPatchedToolMessage (line 107) | func (m *middleware) createPatchedToolMessage(ctx context.Context, tc ...
function hasCorrespondingToolMessage (line 98) | func hasCorrespondingToolMessage(messages []adk.Message, toolCallID stri...
constant defaultPatchedToolMessageTemplate (line 124) | defaultPatchedToolMessageTemplate = "Tool call %s with id %s was ...
constant defaultPatchedToolMessageTemplateChinese (line 125) | defaultPatchedToolMessageTemplateChinese = "工具调用 %s(ID 为 %s)已被取消——在其完成之前...
FILE: adk/middlewares/patchtoolcalls/patchtoolcalls_test.go
function TestPatchToolCalls (line 30) | func TestPatchToolCalls(t *testing.T) {
FILE: adk/middlewares/plantask/backend_test.go
type inMemoryBackend (line 29) | type inMemoryBackend struct
method LsInfo (line 40) | func (b *inMemoryBackend) LsInfo(ctx context.Context, req *LsInfoReque...
method Read (line 55) | func (b *inMemoryBackend) Read(ctx context.Context, req *ReadRequest) ...
method Write (line 66) | func (b *inMemoryBackend) Write(ctx context.Context, req *WriteRequest...
method Delete (line 74) | func (b *inMemoryBackend) Delete(ctx context.Context, req *DeleteReque...
function newInMemoryBackend (line 34) | func newInMemoryBackend() *inMemoryBackend {
FILE: adk/middlewares/plantask/plantask.go
type Config (line 28) | type Config struct
function New (line 36) | func New(ctx context.Context, config *Config) (adk.ChatModelAgentMiddlew...
type middleware (line 50) | type middleware struct
method BeforeAgent (line 56) | func (m *middleware) BeforeAgent(ctx context.Context, runCtx *adk.Chat...
FILE: adk/middlewares/plantask/plantask_test.go
function TestNew (line 30) | func TestNew(t *testing.T) {
function TestMiddlewareBeforeAgent (line 50) | func TestMiddlewareBeforeAgent(t *testing.T) {
function TestIntegration (line 83) | func TestIntegration(t *testing.T) {
FILE: adk/middlewares/plantask/task.go
constant highWatermarkFileName (line 28) | highWatermarkFileName = ".highwatermark"
type task (line 30) | type task struct
type taskOut (line 42) | type taskOut struct
constant taskStatusPending (line 47) | taskStatusPending = "pending"
constant taskStatusInProgress (line 48) | taskStatusInProgress = "in_progress"
constant taskStatusCompleted (line 49) | taskStatusCompleted = "completed"
constant taskStatusDeleted (line 50) | taskStatusDeleted = "deleted"
type DeleteRequest (line 58) | type DeleteRequest struct
type Backend (line 64) | type Backend interface
function isValidTaskID (line 75) | func isValidTaskID(taskID string) bool {
function appendUnique (line 79) | func appendUnique(slice []string, items ...string) []string {
function hasCyclicDependency (line 93) | func hasCyclicDependency(taskMap map[string]*task, blockerID, blockedID ...
function canReach (line 102) | func canReach(taskMap map[string]*task, fromID, toID string, visited map...
FILE: adk/middlewares/plantask/task_create.go
function newTaskCreateTool (line 32) | func newTaskCreateTool(backend Backend, baseDir string, lock *sync.Mutex...
type taskCreateTool (line 36) | type taskCreateTool struct
method Info (line 49) | func (t *taskCreateTool) Info(ctx context.Context) (*schema.ToolInfo, ...
method InvokableRun (line 88) | func (t *taskCreateTool) InvokableRun(ctx context.Context, argumentsIn...
type taskCreateArgs (line 42) | type taskCreateArgs struct
constant TaskCreateToolName (line 182) | TaskCreateToolName = "TaskCreate"
constant taskCreateToolDesc (line 183) | taskCreateToolDesc = `Use this tool to create a structured task list for...
constant taskCreateToolDescChinese (line 225) | taskCreateToolDescChinese = `使用此工具为当前编码会话创建结构化的任务列表。这有助于跟踪进度、组织复杂任务,并向用户...
FILE: adk/middlewares/plantask/task_create_test.go
function TestTaskCreateTool (line 29) | func TestTaskCreateTool(t *testing.T) {
function TestTaskCreateToolWithMetadata (line 71) | func TestTaskCreateToolWithMetadata(t *testing.T) {
FILE: adk/middlewares/plantask/task_get.go
function newTaskGetTool (line 33) | func newTaskGetTool(backend Backend, baseDir string, lock *sync.Mutex) *...
type taskGetTool (line 37) | type taskGetTool struct
method Info (line 43) | func (t *taskGetTool) Info(ctx context.Context) (*schema.ToolInfo, err...
method InvokableRun (line 66) | func (t *taskGetTool) InvokableRun(ctx context.Context, argumentsInJSO...
type taskGetArgs (line 62) | type taskGetArgs struct
constant TaskGetToolName (line 131) | TaskGetToolName = "TaskGet"
constant taskGetToolDesc (line 132) | taskGetToolDesc = `Use this tool to retrieve a task by its ID from the t...
constant taskGetToolDescChinese (line 155) | taskGetToolDescChinese = `使用此工具通过任务 ID 从任务列表中获取任务。
FILE: adk/middlewares/plantask/task_get_test.go
function TestTaskGetTool (line 29) | func TestTaskGetTool(t *testing.T) {
function TestTaskGetToolInvalidTaskID (line 65) | func TestTaskGetToolInvalidTaskID(t *testing.T) {
FILE: adk/middlewares/plantask/task_list.go
function newTaskListTool (line 34) | func newTaskListTool(backend Backend, baseDir string, lock *sync.Mutex) ...
type taskListTool (line 38) | type taskListTool struct
method Info (line 44) | func (t *taskListTool) Info(ctx context.Context) (*schema.ToolInfo, er...
method InvokableRun (line 101) | func (t *taskListTool) InvokableRun(ctx context.Context, argumentsInJS...
function listTasks (line 57) | func listTasks(ctx context.Context, backend Backend, baseDir string) ([]...
constant TaskListToolName (line 151) | TaskListToolName = "TaskList"
constant taskListToolDesc (line 152) | taskListToolDesc = `Use this tool to list all tasks in the task list.
constant taskListToolDescChinese (line 174) | taskListToolDescChinese = `使用此工具列出任务列表中的所有任务。
FILE: adk/middlewares/plantask/task_list_test.go
function TestTaskListTool (line 29) | func TestTaskListTool(t *testing.T) {
FILE: adk/middlewares/plantask/task_update.go
function newTaskUpdateTool (line 33) | func newTaskUpdateTool(backend Backend, baseDir string, lock *sync.Mutex...
type taskUpdateTool (line 37) | type taskUpdateTool struct
method Info (line 55) | func (t *taskUpdateTool) Info(ctx context.Context) (*schema.ToolInfo, ...
method InvokableRun (line 122) | func (t *taskUpdateTool) InvokableRun(ctx context.Context, argumentsIn...
method removeTaskFromDependencies (line 286) | func (t *taskUpdateTool) removeTaskFromDependencies(ctx context.Contex...
method addBlockedByToTask (line 335) | func (t *taskUpdateTool) addBlockedByToTask(ctx context.Context, targe...
method addBlocksToTask (line 362) | func (t *taskUpdateTool) addBlocksToTask(ctx context.Context, targetTa...
method checkIfNeedDeleteAllTasks (line 390) | func (t *taskUpdateTool) checkIfNeedDeleteAllTasks(ctx context.Context...
type taskUpdateArgs (line 43) | type taskUpdateArgs struct
constant TaskUpdateToolName (line 414) | TaskUpdateToolName = "TaskUpdate"
constant taskUpdateToolDesc (line 415) | taskUpdateToolDesc = `Use this tool to update a task in the task list.
constant taskUpdateToolDescChinese (line 491) | taskUpdateToolDescChinese = `使用此工具更新任务列表中的任务。
FILE: adk/middlewares/plantask/task_update_test.go
function TestTaskUpdateTool (line 29) | func TestTaskUpdateTool(t *testing.T) {
function TestTaskUpdateToolOwnerAndMetadata (line 75) | func TestTaskUpdateToolOwnerAndMetadata(t *testing.T) {
function TestTaskUpdateToolBlocks (line 124) | func TestTaskUpdateToolBlocks(t *testing.T) {
function TestTaskUpdateToolDelete (line 194) | func TestTaskUpdateToolDelete(t *testing.T) {
function TestTaskUpdateToolInvalidTaskID (line 219) | func TestTaskUpdateToolInvalidTaskID(t *testing.T) {
function TestTaskUpdateToolBlocksDeduplication (line 259) | func TestTaskUpdateToolBlocksDeduplication(t *testing.T) {
function TestTaskUpdateToolBidirectionalBlocks (line 338) | func TestTaskUpdateToolBidirectionalBlocks(t *testing.T) {
function TestTaskUpdateToolBidirectionalBlockedBy (line 401) | func TestTaskUpdateToolBidirectionalBlockedBy(t *testing.T) {
function TestTaskUpdateToolBidirectionalWithNonExistentTask (line 464) | func TestTaskUpdateToolBidirectionalWithNonExistentTask(t *testing.T) {
function TestTaskUpdateToolCyclicDependencyDetection (line 492) | func TestTaskUpdateToolCyclicDependencyDetection(t *testing.T) {
function TestTaskUpdateToolDeleteCleansDependencies (line 582) | func TestTaskUpdateToolDeleteCleansDependencies(t *testing.T) {
function TestTaskUpdateToolAutoDeleteAllTasksWhenAllCompleted (line 645) | func TestTaskUpdateToolAutoDeleteAllTasksWhenAllCompleted(t *testing.T) {
function TestTaskUpdateToolNoDeleteWhenNotAllCompleted (line 697) | func TestTaskUpdateToolNoDeleteWhenNotAllCompleted(t *testing.T) {
FILE: adk/middlewares/reduction/consts.go
constant truncFmt (line 23) | truncFmt = `<persisted-output>
constant truncFmtZh (line 32) | truncFmtZh = `<persisted-output>
constant clearWithOffloadingFmt (line 44) | clearWithOffloadingFmt = `<persisted-output>Tool result saved to: {file_...
constant clearWithOffloadingFmtZh (line 46) | clearWithOffloadingFmtZh = `<persisted-output>工具结果已保存至: {file_path}
constant clearWithoutOffloadingFmt (line 49) | clearWithoutOffloadingFmt = `[Old tool result content cleared]`
constant clearWithoutOffloadingFmtZh (line 50) | clearWithoutOffloadingFmtZh = `[工具输出结果已清理]`
constant msgReducedFlag (line 54) | msgReducedFlag = "_reduction_mw_processed"
constant msgReducedTokens (line 55) | msgReducedTokens = "_reduction_mw_tokens"
function getTruncFmt (line 58) | func getTruncFmt() string {
function getClearWithOffloadingFmt (line 65) | func getClearWithOffloadingFmt() string {
function getClearWithoutOffloadingFmt (line 72) | func getClearWithoutOffloadingFmt() string {
type scene (line 79) | type scene
constant sceneTruncation (line 82) | sceneTruncation scene = 1
constant sceneClear (line 83) | sceneClear scene = 2
FILE: adk/middlewares/reduction/internal/clear_tool_result.go
type ClearToolResultConfig (line 30) | type ClearToolResultConfig struct
function NewClearToolResult (line 58) | func NewClearToolResult(ctx context.Context, config *ClearToolResultConf...
function newClearToolResult (line 64) | func newClearToolResult(ctx context.Context, config *ClearToolResultConf...
function defaultTokenCounter (line 97) | func defaultTokenCounter(msg *schema.Message) int {
function reduceByTokens (line 113) | func reduceByTokens(state *adk.ChatModelAgentState, toolResultTokenThres...
function excluded (line 158) | func excluded(name string, exclude []string) bool {
FILE: adk/middlewares/reduction/internal/clear_tool_result_test.go
function Test_reduceByTokens (line 31) | func Test_reduceByTokens(t *testing.T) {
function Test_newClearToolResult (line 268) | func Test_newClearToolResult(t *testing.T) {
FILE: adk/middlewares/reduction/internal/large_tool_result.go
constant tooLargeToolMessage (line 37) | tooLargeToolMessage = `Tool result too large, the result of this tool ca...
constant tooLargeToolMessageChinese (line 45) | tooLargeToolMessageChinese = `工具结果过大,此工具调用 {tool_call_id} 的结果已保存到文件系统的以下...
type toolResultOffloadingConfig (line 54) | type toolResultOffloadingConfig struct
function newToolResultOffloading (line 62) | func newToolResultOffloading(_ context.Context, config *toolResultOffloa...
type toolResultOffloading (line 95) | type toolResultOffloading struct
method invoke (line 103) | func (t *toolResultOffloading) invoke(endpoint compose.InvokableToolEn...
method stream (line 117) | func (t *toolResultOffloading) stream(endpoint compose.StreamableToolE...
method handleResult (line 135) | func (t *toolResultOffloading) handleResult(ctx context.Context, resul...
function concatString (line 171) | func concatString(sr *schema.StreamReader[string]) (string, error) {
function formatToolMessage (line 188) | func formatToolMessage(s string) string {
FILE: adk/middlewares/reduction/internal/large_tool_result_test.go
type mockBackend (line 33) | type mockBackend struct
method Write (line 43) | func (m *mockBackend) Write(_ context.Context, wr *filesystem.WriteReq...
function newMockBackend (line 37) | func newMockBackend() *mockBackend {
function TestToolResultOffloading_SmallResult (line 48) | func TestToolResultOffloading_SmallResult(t *testing.T) {
function TestToolResultOffloading_LargeResult (line 90) | func TestToolResultOffloading_LargeResult(t *testing.T) {
function TestToolResultOffloading_CustomPathGenerator (line 147) | func TestToolResultOffloading_CustomPathGenerator(t *testing.T) {
function TestToolResultOffloading_PathGeneratorError (line 195) | func TestToolResultOffloading_PathGeneratorError(t *testing.T) {
function TestToolResultOffloading_EndpointError (line 232) | func TestToolResultOffloading_EndpointError(t *testing.T) {
function TestToolResultOffloading_DefaultTokenLimit (line 265) | func TestToolResultOffloading_DefaultTokenLimit(t *testing.T) {
function TestToolResultOffloading_Stream (line 305) | func TestToolResultOffloading_Stream(t *testing.T) {
function TestToolResultOffloading_StreamError (line 377) | func TestToolResultOffloading_StreamError(t *testing.T) {
function TestFormatToolMessage (line 410) | func TestFormatToolMessage(t *testing.T) {
function TestConcatString (line 458) | func TestConcatString(t *testing.T) {
function TestToolResultOffloading_BackendWriteError (line 521) | func TestToolResultOffloading_BackendWriteError(t *testing.T) {
type failingBackend (line 559) | type failingBackend struct
method Write (line 563) | func (f *failingBackend) Write(context.Context, *filesystem.WriteReque...
FILE: adk/middlewares/reduction/internal/tool_result.go
type Backend (line 30) | type Backend interface
type ToolResultConfig (line 35) | type ToolResultConfig struct
function NewToolResultMiddleware (line 103) | func NewToolResultMiddleware(ctx context.Context, cfg *ToolResultConfig)...
FILE: adk/middlewares/reduction/reduction.go
type Config (line 51) | type Config struct
method copyAndFillDefaults (line 179) | func (t *Config) copyAndFillDefaults() (*Config, error) {
type ToolReductionConfig (line 101) | type ToolReductionConfig struct
type ToolDetail (line 121) | type ToolDetail struct
type TruncResult (line 132) | type TruncResult struct
type ClearResult (line 154) | type ClearResult struct
function New (line 225) | func New(_ context.Context, config *Config) (adk.ChatModelAgentMiddlewar...
type toolReductionMiddleware (line 256) | type toolReductionMiddleware struct
method getToolConfig (line 263) | func (t *toolReductionMiddleware) getToolConfig(toolName string, sc sc...
method WrapInvokableToolCall (line 276) | func (t *toolReductionMiddleware) WrapInvokableToolCall(_ context.Cont...
method WrapStreamableToolCall (line 320) | func (t *toolReductionMiddleware) WrapStreamableToolCall(_ context.Con...
method BeforeModelRewriteState (line 386) | func (t *toolReductionMiddleware) BeforeModelRewriteState(ctx context....
function defaultTokenCounter (line 522) | func defaultTokenCounter(_ context.Context, msgs []*schema.Message, tool...
function defaultTruncHandler (line 567) | func defaultTruncHandler(rootDir string, truncMaxLength int) func(ctx co...
function defaultClearHandler (line 601) | func defaultClearHandler(rootDir string, needOffload bool, readFileToolN...
function getMsgOffloadedFlag (line 654) | func getMsgOffloadedFlag(msg *schema.Message) (offloaded bool) {
function setMsgOffloadedFlag (line 665) | func setMsgOffloadedFlag(msg *schema.Message) {
function getMsgCachedToken (line 672) | func getMsgCachedToken(msg *schema.Message) (int64, bool) {
function setMsgCachedToken (line 680) | func setMsgCachedToken(msg *schema.Message, tokens int64) {
function toolResultFromMessage (line 687) | func toolResultFromMessage(msg *schema.Message) (result *schema.ToolResu...
function convMessageInputPartToToolOutputPart (line 705) | func convMessageInputPartToToolOutputPart(msgPart schema.MessageInputPar...
FILE: adk/middlewares/reduction/reduction_test.go
function TestReductionMiddlewareTrunc (line 35) | func TestReductionMiddlewareTrunc(t *testing.T) {
function TestReductionMiddlewareClear (line 109) | func TestReductionMiddlewareClear(t *testing.T) {
function TestDefaultOffloadHandler (line 446) | func TestDefaultOffloadHandler(t *testing.T) {
function mockInvokableTool (line 476) | func mockInvokableTool() tool.InvokableTool {
function mockStreamableTool (line 489) | func mockStreamableTool() tool.StreamableTool {
function splitStrings (line 507) | func splitStrings(s string, n int) []string {
function toJson (line 536) | func toJson(v any) string {
function TestToolResultFromMessage (line 541) | func TestToolResultFromMessage(t *testing.T) {
function TestConvMessageInputPartToToolOutputPart (line 578) | func TestConvMessageInputPartToToolOutputPart(t *testing.T) {
function TestGetSetMsgOffloadedFlag (line 644) | func TestGetSetMsgOffloadedFlag(t *testing.T) {
function TestGetSetMsgCachedToken (line 671) | func TestGetSetMsgCachedToken(t *testing.T) {
function TestNewErrors (line 706) | func TestNewErrors(t *testing.T) {
function TestGetToolConfig (line 726) | func TestGetToolConfig(t *testing.T) {
function TestCopyAndFillDefaults (line 788) | func TestCopyAndFillDefaults(t *testing.T) {
function TestDefaultTokenCounter (line 816) | func TestDefaultTokenCounter(t *testing.T) {
function TestDefaultClearHandler (line 837) | func TestDefaultClearHandler(t *testing.T) {
FILE: adk/middlewares/skill/filesystem_backend.go
constant skillFileName (line 30) | skillFileName = "SKILL.md"
type filesystemBackend (line 32) | type filesystemBackend struct
method List (line 66) | func (b *filesystemBackend) List(ctx context.Context) ([]FrontMatter, ...
method Get (line 80) | func (b *filesystemBackend) Get(ctx context.Context, name string) (Ski...
method list (line 95) | func (b *filesystemBackend) list(ctx context.Context) ([]Skill, error) {
method loadSkillFromFile (line 123) | func (b *filesystemBackend) loadSkillFromFile(ctx context.Context, pat...
type BackendFromFilesystemConfig (line 38) | type BackendFromFilesystemConfig struct
function NewBackendFromFilesystem (line 49) | func NewBackendFromFilesystem(_ context.Context, config *BackendFromFile...
function stripLineNumbers (line 152) | func stripLineNumbers(data string) string {
function parseFrontmatter (line 165) | func parseFrontmatter(data string) (frontmatter string, content string, ...
FILE: adk/middlewares/skill/filesystem_backend_test.go
function TestNewBackendFromFilesystem (line 29) | func TestNewBackendFromFilesystem(t *testing.T) {
function TestFilesystemBackend_List (line 71) | func TestFilesystemBackend_List(t *testing.T) {
function TestFilesystemBackend_Get (line 259) | func TestFilesystemBackend_Get(t *testing.T) {
function TestParseFrontmatter (line 332) | func TestParseFrontmatter(t *testing.T) {
function TestLoadSkillFromFile (line 432) | func TestLoadSkillFromFile(t *testing.T) {
FILE: adk/middlewares/skill/prompt.go
constant systemPrompt (line 20) | systemPrompt = `
constant systemPromptChinese (line 52) | systemPromptChinese = `
constant toolDescriptionBase (line 84) | toolDescriptionBase = `Execute a skill within the main conversation
constant toolDescriptionBaseChinese (line 106) | toolDescriptionBaseChinese = `在主对话中执行 Skill(技能)
constant toolDescriptionTemplate (line 128) | toolDescriptionTemplate = `
constant toolResult (line 142) | toolResult = "Launching skill: %s\n"
constant toolResultChinese (line 143) | toolResultChinese = "正在启动 Skill:%s\n"
constant userContent (line 144) | userContent = `Base directory for this skill: %s
constant userContentChinese (line 147) | userContentChinese = `此 Skill 的目录:%s
constant toolName (line 150) | toolName = "skill"
constant subAgentResultFormat (line 152) | subAgentResultFormat = "Skill \"%s\" completed (sub-agent executi...
constant subAgentResultFormatChinese (line 153) | subAgentResultFormatChinese = "Skill \"%s\" 已完成(子 Agent 执行)。\n\n结果:\n%s"
FILE: adk/middlewares/skill/skill.go
type ContextMode (line 38) | type ContextMode
constant ContextModeForkWithContext (line 43) | ContextModeForkWithContext ContextMode = "fork_with_context"
constant ContextModeFork (line 46) | ContextModeFork ContextMode = "fork"
type FrontMatter (line 49) | type FrontMatter struct
type Skill (line 57) | type Skill struct
type Backend (line 63) | type Backend interface
type AgentHubOptions (line 69) | type AgentHubOptions struct
type AgentHub (line 76) | type AgentHub interface
type ModelHub (line 83) | type ModelHub interface
type SystemPromptFunc (line 89) | type SystemPromptFunc
type ToolDescriptionFunc (line 93) | type ToolDescriptionFunc
type Config (line 96) | type Config struct
function NewMiddleware (line 153) | func NewMiddleware(ctx context.Context, config *Config) (adk.ChatModelAg...
type skillHandler (line 190) | type skillHandler struct
method BeforeAgent (line 196) | func (h *skillHandler) BeforeAgent(ctx context.Context, runCtx *adk.Ch...
method WrapModel (line 202) | func (h *skillHandler) WrapModel(ctx context.Context, m model.BaseChat...
constant activeModelKey (line 224) | activeModelKey = "__skill_active_model__"
function New (line 231) | func New(ctx context.Context, config *Config) (adk.AgentMiddleware, erro...
function buildSystemPrompt (line 266) | func buildSystemPrompt(skillToolName string, useChinese bool) (string, e...
type skillTool (line 281) | type skillTool struct
method Info (line 294) | func (s *skillTool) Info(ctx context.Context) (*schema.ToolInfo, error) {
method InvokableRun (line 338) | func (s *skillTool) InvokableRun(ctx context.Context, argumentsInJSON ...
method setActiveModel (line 362) | func (s *skillTool) setActiveModel(ctx context.Context, modelName stri...
method buildSkillResult (line 366) | func (s *skillTool) buildSkillResult(skill Skill) (string, error) {
method runAgentMode (line 379) | func (s *skillTool) runAgentMode(ctx context.Context, skill Skill, for...
method getMessagesFromState (line 458) | func (s *skillTool) getMessagesFromState(ctx context.Context) ([]adk.M...
type descriptionTemplateHelper (line 290) | type descriptionTemplateHelper struct
type inputArguments (line 334) | type inputArguments struct
function renderToolDescription (line 471) | func renderToolDescription(matters []FrontMatter) (string, error) {
FILE: adk/middlewares/skill/skill_test.go
type inMemoryBackend (line 36) | type inMemoryBackend struct
method List (line 40) | func (i *inMemoryBackend) List(ctx context.Context) ([]FrontMatter, er...
method Get (line 48) | func (i *inMemoryBackend) Get(ctx context.Context, name string) (Skill...
function TestTool (line 57) | func TestTool(t *testing.T) {
function TestSkillToolName (line 158) | func TestSkillToolName(t *testing.T) {
type mockModel (line 183) | type mockModel struct
type mockModelHub (line 188) | type mockModelHub struct
method Get (line 192) | func (h *mockModelHub) Get(_ context.Context, name string) (model.Tool...
type mockAgent (line 200) | type mockAgent struct
method Name (line 204) | func (a *mockAgent) Name(_ context.Context) string { return "mo...
method Description (line 205) | func (a *mockAgent) Description(_ context.Context) string { return "m...
method Run (line 206) | func (a *mockAgent) Run(_ context.Context, _ *adk.AgentInput, _ ...adk...
type mockAgentHub (line 217) | type mockAgentHub struct
method Get (line 223) | func (h *mockAgentHub) Get(_ context.Context, name string, opts *Agent...
type errorBackend (line 235) | type errorBackend struct
method List (line 240) | func (b *errorBackend) List(_ context.Context) ([]FrontMatter, error) {
method Get (line 243) | func (b *errorBackend) Get(_ context.Context, _ string) (Skill, error) {
function TestNewMiddleware (line 249) | func TestNewMiddleware(t *testing.T) {
function TestBeforeAgent (line 319) | func TestBeforeAgent(t *testing.T) {
function TestSkillToolInfo (line 343) | func TestSkillToolInfo(t *testing.T) {
function TestInvokableRun_InlineMode (line 374) | func TestInvokableRun_InlineMode(t *testing.T) {
function TestInvokableRun_AgentMode (line 416) | func TestInvokableRun_AgentMode(t *testing.T) {
FILE: adk/middlewares/summarization/consts.go
constant extraKeyContentType (line 20) | extraKeyContentType = "_eino_summarization_content_type"
type summarizationContentType (line 23) | type summarizationContentType
constant contentTypeSummary (line 26) | contentTypeSummary summarizationContentType = "summary"
type ActionType (line 29) | type ActionType
constant ActionTypeBeforeSummarize (line 32) | ActionTypeBeforeSummarize ActionType = "before_summarize"
constant ActionTypeAfterSummarize (line 33) | ActionTypeAfterSummarize ActionType = "after_summarize"
FILE: adk/middlewares/summarization/customized_action.go
type CustomizedAction (line 23) | type CustomizedAction struct
type BeforeSummarizeAction (line 36) | type BeforeSummarizeAction struct
type AfterSummarizeAction (line 41) | type AfterSummarizeAction struct
FILE: adk/middlewares/summarization/prompt.go
function getSystemInstruction (line 27) | func getSystemInstruction() string {
function getUserSummaryInstruction (line 34) | func getUserSummaryInstruction() string {
function getSummaryPreamble (line 41) | func getSummaryPreamble() string {
function getContinueInstruction (line 48) | func getContinueInstruction() string {
function getTranscriptPathInstruction (line 55) | func getTranscriptPathInstruction() string {
function getTruncatedMarkerFormat (line 62) | func getTruncatedMarkerFormat() string {
function getUserMessagesReplacedNote (line 69) | func getUserMessagesReplacedNote() string {
constant systemInstruction (line 76) | systemInstruction = `You are a helpful AI assistant tasked with summariz...
constant systemInstructionZh (line 78) | systemInstructionZh = `你是一个负责总结对话的 AI 助手。`
constant userSummaryInstruction (line 80) | userSummaryInstruction = `Your task is to create a detailed summary of t...
constant userSummaryInstructionZh (line 182) | userSummaryInstructionZh = `你的任务是对目前为止的对话创建一份详细的总结,需要密切关注用户的明确请求和你之前的操作。
constant summaryPreamble (line 284) | summaryPreamble = `This session is being continued from a previous conve...
constant summaryPreambleZh (line 286) | summaryPreambleZh = `此会话延续自此前一段因上下文耗尽而终止的对话。以下总结概述了此前对话的内容。`
constant continueInstruction (line 288) | continueInstruction = `Please continue the conversation from where we le...
constant continueInstructionZh (line 290) | continueInstructionZh = `请从我们中断的地方继续对话,无需向用户提出任何进一步的问题。继续完成先前指令中未完成的任务。`
constant transcriptPathInstruction (line 292) | transcriptPathInstruction = `If you need specific details from before co...
constant transcriptPathInstructionZh (line 294) | transcriptPathInstructionZh = `如果你需要压缩之前的具体细节(如精确的代码片段、错误消息或你生成的内容),完整的对...
constant truncatedMarkerFormat (line 296) | truncatedMarkerFormat = "…%d characters truncated…"
constant truncatedMarkerFormatZh (line 298) | truncatedMarkerFormatZh = "…已截断 %d 个字符…"
constant userMessagesReplacedNote (line 300) | userMessagesReplacedNote = "Some earlier user messages have been cleared...
constant userMessagesReplacedNoteZh (line 302) | userMessagesReplacedNoteZh = "部分较早的用户消息已被清除,以下是保留的最近用户消息:"
FILE: adk/middlewares/summarization/summarization.go
function init (line 35) | func init() {
type TokenCounterFunc (line 40) | type TokenCounterFunc
type GenModelInputFunc (line 41) | type GenModelInputFunc
type FinalizeFunc (line 42) | type FinalizeFunc
type CallbackFunc (line 43) | type CallbackFunc
type Config (line 47) | type Config struct
method check (line 559) | func (c *Config) check() error {
type TokenCounterInput (line 112) | type TokenCounterInput struct
type TriggerCondition (line 119) | type TriggerCondition struct
method check (line 575) | func (c *TriggerCondition) check() error {
type PreserveUserMessages (line 127) | type PreserveUserMessages struct
function New (line 138) | func New(ctx context.Context, cfg *Config) (adk.ChatModelAgentMiddleware...
type middleware (line 148) | type middleware struct
method BeforeModelRewriteState (line 153) | func (m *middleware) BeforeModelRewriteState(ctx context.Context, stat...
method shouldSummarize (line 236) | func (m *middleware) shouldSummarize(ctx context.Context, input *Token...
method getTriggerContextTokens (line 249) | func (m *middleware) getTriggerContextTokens() int {
method getUserMessageContextTokens (line 257) | func (m *middleware) getUserMessageContextTokens() int {
method emitEvent (line 264) | func (m *middleware) emitEvent(ctx context.Context, action *Customized...
method countTokens (line 276) | func (m *middleware) countTokens(ctx context.Context, input *TokenCoun...
method summarize (line 308) | func (m *middleware) summarize(ctx context.Context, originMsgs, contex...
method buildSummarizationModelInput (line 322) | func (m *middleware) buildSummarizationModelInput(ctx context.Context,...
method postProcessSummary (line 363) | func (m *middleware) postProcessSummary(ctx context.Context, messages ...
method replaceUserMessagesInSummary (line 395) | func (m *middleware) replaceUserMessagesInSummary(ctx context.Context,...
function defaultTokenCounter (line 283) | func defaultTokenCounter(ctx context.Context, input *TokenCounterInput) ...
function estimateTokenCount (line 304) | func estimateTokenCount(text string) int {
function newSummaryMessage (line 354) | func newSummaryMessage(content string) *schema.Message {
function findLastMatch (line 475) | func findLastMatch(re *regexp.Regexp, s string) []int {
function appendSection (line 483) | func appendSection(base, section string) string {
function defaultTrimUserMessage (line 493) | func defaultTrimUserMessage(msg adk.Message, remainingTokens int) adk.Me...
function truncateTextByChars (line 514) | func truncateTextByChars(text string) string {
function extractTextContent (line 538) | func extractTextContent(msg adk.Message) string {
function setContentType (line 588) | func setContentType(msg adk.Message, ct summarizationContentType) {
function getContentType (line 592) | func getContentType(msg adk.Message) (summarizationContentType, bool) {
function setExtra (line 600) | func setExtra(msg adk.Message, key string, value any) {
function getExtra (line 607) | func getExtra[T any](msg adk.Message, key string) (T, bool) {
FILE: adk/middlewares/summarization/summarization_test.go
function TestNew (line 33) | func TestNew(t *testing.T) {
function TestMiddlewareBeforeModelRewriteState (line 62) | func TestMiddlewareBeforeModelRewriteState(t *testing.T) {
function TestMiddlewareShouldSummarize (line 236) | func TestMiddlewareShouldSummarize(t *testing.T) {
function TestMiddlewareCountTokens (line 333) | func TestMiddlewareCountTokens(t *testing.T) {
function TestExtractTextContent (line 383) | func TestExtractTextContent(t *testing.T) {
function TestTruncateTextByChars (line 415) | func TestTruncateTextByChars(t *testing.T) {
function TestAppendSection (line 441) | func TestAppendSection(t *testing.T) {
function TestAllUserMessagesTagRegex (line 482) | func TestAllUserMessagesTagRegex(t *testing.T) {
function TestConfigCheck (line 506) | func TestConfigCheck(t *testing.T) {
function TestSetGetContentType (line 572) | func TestSetGetContentType(t *testing.T) {
function TestSetGetExtra (line 585) | func TestSetGetExtra(t *testing.T) {
function TestMiddlewareSummarize (line 617) | func TestMiddlewareSummarize(t *testing.T) {
function TestReplaceUserMessagesInSummary (line 774) | func TestReplaceUserMessagesInSummary(t *testing.T) {
function TestAllUserMessagesTagRegexMatch (line 891) | func TestAllUserMessagesTagRegexMatch(t *testing.T) {
function TestDefaultTrimUserMessage (line 903) | func TestDefaultTrimUserMessage(t *testing.T) {
function TestDefaultTokenCounter (line 925) | func TestDefaultTokenCounter(t *testing.T) {
function TestPostProcessSummary (line 941) | func TestPostProcessSummary(t *testing.T) {
FILE: adk/prebuilt/deep/checkpoint_compat_resume_test.go
type compatCheckpointStore (line 38) | type compatCheckpointStore struct
method Set (line 46) | func (s *compatCheckpointStore) Set(_ context.Context, key string, val...
method Get (line 51) | func (s *compatCheckpointStore) Get(_ context.Context, key string) ([]...
function newCompatCheckpointStore (line 42) | func newCompatCheckpointStore() *compatCheckpointStore {
type interruptingSubAgentTool (line 59) | type interruptingSubAgentTool struct
method Info (line 63) | func (t *interruptingSubAgentTool) Info(_ context.Context) (*schema.To...
method InvokableRun (line 73) | func (t *interruptingSubAgentTool) InvokableRun(ctx context.Context, a...
function readTestdataBytes (line 78) | func readTestdataBytes(t *testing.T, filename string) []byte {
function runDeepAgentCheckpointCompat (line 89) | func runDeepAgentCheckpointCompat(t *testing.T, checkpointID string, fil...
function TestDeepAgentCheckpointCompat_V0_8_Resume (line 170) | func TestDeepAgentCheckpointCompat_V0_8_Resume(t *testing.T) {
FILE: adk/prebuilt/deep/deep.go
function init (line 35) | func init() {
type Config (line 41) | type Config struct
function New (line 105) | func New(ctx context.Context, cfg *Config) (adk.ResumableAgent, error) {
function genModelInput (line 155) | func genModelInput(ctx context.Context, instruction string, input *adk.A...
function buildBuiltinAgentMiddlewares (line 167) | func buildBuiltinAgentMiddlewares(ctx context.Context, cfg *Config) ([]a...
type TODO (line 192) | type TODO struct
type writeTodosArguments (line 198) | type writeTodosArguments struct
function newWriteTodos (line 202) | func newWriteTodos() (adk.ChatModelAgentMiddleware, error) {
FILE: adk/prebuilt/deep/deep_test.go
function TestGenModelInput (line 35) | func TestGenModelInput(t *testing.T) {
function TestWriteTodos (line 69) | func TestWriteTodos(t *testing.T) {
function TestDeepSubAgentSharesSessionValues (line 83) | func TestDeepSubAgentSharesSessionValues(t *testing.T) {
function TestDeepSubAgentFollowsStreamingMode (line 130) | func TestDeepSubAgentFollowsStreamingMode(t *testing.T) {
type spySubAgent (line 185) | type spySubAgent struct
method Name (line 189) | func (s *spySubAgent) Name(context.Context) string { return "sp...
method Description (line 190) | func (s *spySubAgent) Description(context.Context) string { return "sp...
method Run (line 191) | func (s *spySubAgent) Run(ctx context.Context, _ *adk.AgentInput, _ .....
type spyStreamingSubAgent (line 199) | type spyStreamingSubAgent struct
method Name (line 203) | func (s *spyStreamingSubAgent) Name(context.Context) string { r...
method Description (line 204) | func (s *spyStreamingSubAgent) Description(context.Context) string { r...
method Run (line 205) | func (s *spyStreamingSubAgent) Run(ctx context.Context, input *adk.Age...
function TestDeepAgentWithPlanExecuteSubAgent_InternalEventsEmitted (line 215) | func TestDeepAgentWithPlanExecuteSubAgent_InternalEventsEmitted(t *testi...
type namedPlanExecuteAgent (line 384) | type namedPlanExecuteAgent struct
method Name (line 390) | func (n *namedPlanExecuteAgent) Name(_ context.Context) string {
method Description (line 394) | func (n *namedPlanExecuteAgent) Description(_ context.Context) string {
function TestDeepAgentOutputKey (line 398) | func TestDeepAgentOutputKey(t *testing.T) {
type sessionCaptureAgent (line 531) | type sessionCaptureAgent struct
method Run (line 536) | func (s *sessionCaptureAgent) Run(ctx context.Context, input *adk.Agen...
FILE: adk/prebuilt/deep/prompt.go
constant taskPrompt (line 28) | taskPrompt = `
constant baseAgentInstruction (line 59) | baseAgentInstruction = `
constant generalAgentDescription (line 111) | generalAgentDescription = `general-purpose agent for researching complex...
constant taskToolDescription (line 112) | taskToolDescription = `Launch a new agent to handle complex, multi-s...
constant writeTodosToolDescription (line 173) | writeTodosToolDescription = `Use this tool to create and manage a struct...
constant taskPromptChinese (line 357) | taskPromptChinese = `
constant baseAgentInstructionChinese (line 388) | baseAgentInstructionChinese = `
constant generalAgentDescriptionChinese (line 440) | generalAgentDescriptionChinese = `通用代理,用于研究复杂问题、搜索代码和执行多步骤任务。当你搜索关键字或文件并...
constant taskToolDescriptionChinese (line 441) | taskToolDescriptionChinese = `启动新代理以自主处理复杂的多步骤任务。
constant writeTodosToolDescriptionChinese (line 502) | writeTodosToolDescriptionChinese = `使用此工具为你当前的编码会话创建和管理结构化的任务列表。这有助于你跟踪进...
FILE: adk/prebuilt/deep/task_tool.go
function newTaskToolMiddleware (line 35) | func newTaskToolMiddleware(
function newTaskTool (line 61) | func newTaskTool(
type taskTool (line 125) | type taskTool struct
method Info (line 131) | func (t *taskTool) Info(ctx context.Context) (*schema.ToolInfo, error) {
method InvokableRun (line 155) | func (t *taskTool) InvokableRun(ctx context.Context, argumentsInJSON s...
type taskToolArgument (line 150) | type taskToolArgument struct
function defaultTaskToolDescription (line 176) | func defaultTaskToolDescription(ctx context.Context, subAgents []adk.Age...
FILE: adk/prebuilt/deep/task_tool_test.go
function TestTaskTool (line 29) | func TestTaskTool(t *testing.T) {
type myAgent (line 59) | type myAgent struct
method Name (line 64) | func (m *myAgent) Name(ctx context.Context) string {
method Description (line 68) | func (m *myAgent) Description(ctx context.Context) string {
method Run (line 72) | func (m *myAgent) Run(ctx context.Context, input *adk.AgentInput, opti...
FILE: adk/prebuilt/deep/testdata/_gen/generate_test.go
type checkpointStore (line 38) | type checkpointStore struct
method Set (line 42) | func (s *checkpointStore) Set(_ context.Context, key string, value []b...
method Get (line 50) | func (s *checkpointStore) Get(_ context.Context, key string) ([]byte, ...
type interruptTool (line 58) | type interruptTool struct
method Info (line 62) | func (t *interruptTool) Info(_ context.Context) (*schema.ToolInfo, err...
method InvokableRun (line 72) | func (t *interruptTool) InvokableRun(ctx context.Context, argumentsInJ...
type scriptedModel (line 80) | type scriptedModel struct
method Generate (line 84) | func (m *scriptedModel) Generate(_ context.Context, _ []*schema.Messag...
method Stream (line 88) | func (m *scriptedModel) Stream(_ context.Context, _ []*schema.Message,...
function TestGenerateV084CheckpointData (line 92) | func TestGenerateV084CheckpointData(t *testing.T) {
FILE: adk/prebuilt/deep/types.go
constant generalAgentName (line 28) | generalAgentName = "general-purpose"
constant taskToolName (line 29) | taskToolName = "task"
constant SessionKeyTodos (line 33) | SessionKeyTodos = "deep_agent_session_key_todos"
function assertAgentTool (line 36) | func assertAgentTool(t tool.BaseTool) (tool.InvokableTool, error) {
function buildAppendPromptTool (line 44) | func buildAppendPromptTool(prompt string, t tool.BaseTool) adk.ChatModel...
type appendPromptTool (line 52) | type appendPromptTool struct
method BeforeAgent (line 58) | func (w *appendPromptTool) BeforeAgent(ctx context.Context, runCtx *ad...
FILE: adk/prebuilt/integration_test.go
type approvalInfo (line 38) | type approvalInfo struct
method String (line 44) | func (ai *approvalInfo) String() string {
type approvalResult (line 49) | type approvalResult struct
function init (line 54) | func init() {
type approvableTool (line 59) | type approvableTool struct
method Info (line 64) | func (m *approvableTool) Info(_ context.Context) (*schema.ToolInfo, er...
method InvokableRun (line 74) | func (m *approvableTool) InvokableRun(ctx context.Context, argumentsIn...
type integrationCheckpointStore (line 108) | type integrationCheckpointStore struct
method Set (line 116) | func (s *integrationCheckpointStore) Set(_ context.Context, key string...
method Get (line 121) | func (s *integrationCheckpointStore) Get(_ context.Context, key string...
function newIntegrationCheckpointStore (line 112) | func newIntegrationCheckpointStore() *integrationCheckpointStore {
type defaultPlan (line 126) | type defaultPlan struct
method FirstStep (line 130) | func (p *defaultPlan) FirstStep() string {
method MarshalJSON (line 137) | func (p *defaultPlan) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 142) | func (p *defaultPlan) UnmarshalJSON(bytes []byte) error {
type namedAgent (line 147) | type namedAgent struct
method Name (line 153) | func (n *namedAgent) Name(_ context.Context) string {
method Description (line 157) | func (n *namedAgent) Description(_ context.Context) string {
function formatRunPath (line 161) | func formatRunPath(runPath []adk.RunStep) string {
function formatAgentEventIntegration (line 172) | func formatAgentEventIntegration(event *adk.AgentEvent) string {
function TestSupervisorWithPlanExecuteInterruptResume (line 199) | func TestSupervisorWithPlanExecuteInterruptResume(t *testing.T) {
FILE: adk/prebuilt/planexecute/plan_execute.go
function init (line 37) | func init() {
type Plan (line 45) | type Plan interface
type NewPlan (line 58) | type NewPlan
type defaultPlan (line 77) | type defaultPlan struct
method FirstStep (line 84) | func (p *defaultPlan) FirstStep() string {
method MarshalJSON (line 91) | func (p *defaultPlan) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 96) | func (p *defaultPlan) UnmarshalJSON(bytes []byte) error {
type Response (line 104) | type Response struct
constant UserInputSessionKey (line 243) | UserInputSessionKey = "UserInput"
constant PlanSessionKey (line 246) | PlanSessionKey = "Plan"
constant ExecutedStepSessionKey (line 249) | ExecutedStepSessionKey = "ExecutedStep"
constant ExecutedStepsSessionKey (line 252) | ExecutedStepsSessionKey = "ExecutedSteps"
type PlannerConfig (line 260) | type PlannerConfig struct
type GenPlannerModelInputFn (line 285) | type GenPlannerModelInputFn
function defaultNewPlan (line 287) | func defaultNewPlan(ctx context.Context) Plan {
function defaultGenPlannerInputFn (line 291) | func defaultGenPlannerInputFn(ctx context.Context, userInput []adk.Messa...
type planner (line 301) | type planner struct
method Name (line 308) | func (p *planner) Name(_ context.Context) string {
method Description (line 312) | func (p *planner) Description(_ context.Context) string {
method Run (line 324) | func (p *planner) Run(ctx context.Context, input *adk.AgentInput,
function argToContent (line 316) | func argToContent(msg adk.Message) (adk.Message, error) {
function NewPlanner (line 437) | func NewPlanner(_ context.Context, cfg *PlannerConfig) (adk.Agent, error) {
type ExecutionContext (line 475) | type ExecutionContext struct
type GenModelInputFn (line 482) | type GenModelInputFn
type ExecutorConfig (line 485) | type ExecutorConfig struct
type ExecutedStep (line 504) | type ExecutedStep struct
function NewExecutor (line 510) | func NewExecutor(ctx context.Context, cfg *ExecutorConfig) (adk.Agent, e...
function defaultGenExecutorInputFn (line 566) | func defaultGenExecutorInputFn(ctx context.Context, in *ExecutionContext...
type replanner (line 586) | type replanner struct
method Name (line 638) | func (r *replanner) Name(_ context.Context) string {
method Description (line 642) | func (r *replanner) Description(_ context.Context) string {
method genInput (line 646) | func (r *replanner) genInput(ctx context.Context) ([]adk.Message, erro...
method Run (line 696) | func (r *replanner) Run(ctx context.Context, input *adk.AgentInput, _ ...
type ReplannerConfig (line 595) | type ReplannerConfig struct
function formatInput (line 619) | func formatInput(input []adk.Message) string {
function formatExecutedSteps (line 629) | func formatExecutedSteps(results []ExecutedStep) string {
function buildGenReplannerInputFn (line 784) | func buildGenReplannerInputFn(planToolName, respondToolName string) GenM...
function NewReplanner (line 807) | func NewReplanner(_ context.Context, cfg *ReplannerConfig) (adk.Agent, e...
type Config (line 838) | type Config struct
function New (line 862) | func New(ctx context.Context, cfg *Config) (adk.ResumableAgent, error) {
FILE: adk/prebuilt/planexecute/plan_execute_test.go
function TestNewPlannerWithFormattedOutput (line 39) | func TestNewPlannerWithFormattedOutput(t *testing.T) {
function TestNewPlannerWithToolCalling (line 65) | func TestNewPlannerWithToolCalling(t *testing.T) {
function TestPlannerRunWithFormattedOutput (line 93) | func TestPlannerRunWithFormattedOutput(t *testing.T) {
function TestPlannerRunWithToolCalling (line 148) | func TestPlannerRunWithToolCalling(t *testing.T) {
function TestNewExecutor (line 219) | func TestNewExecutor(t *testing.T) {
function TestExecutorRun (line 246) | func TestExecutorRun(t *testing.T) {
function TestNewReplanner (line 309) | func TestNewReplanner(t *testing.T) {
function TestReplannerRunWithPlan (line 350) | func TestReplannerRunWithPlan(t *testing.T) {
function TestReplannerRunWithRespond (line 452) | func TestReplannerRunWithRespond(t *testing.T) {
function TestNewPlanExecuteAgent (line 538) | func TestNewPlanExecuteAgent(t *testing.T) {
function TestPlanExecuteAgentWithReplan (line 572) | func TestPlanExecuteAgentWithReplan(t *testing.T) {
type interruptibleTool (line 728) | type interruptibleTool struct
method Info (line 733) | func (m *interruptibleTool) Info(_ context.Context) (*schema.ToolInfo,...
method InvokableRun (line 747) | func (m *interruptibleTool) InvokableRun(ctx context.Context, argument...
type checkpointStore (line 764) | type checkpointStore struct
method Set (line 772) | func (s *checkpointStore) Set(_ context.Context, key string, value []b...
method Get (line 777) | func (s *checkpointStore) Get(_ context.Context, key string) ([]byte, ...
function newCheckpointStore (line 768) | func newCheckpointStore() *checkpointStore {
function formatRunPath (line 782) | func formatRunPath(runPath []adk.RunStep) string {
function formatAgentEvent (line 793) | func formatAgentEvent(event *adk.AgentEvent) string {
function TestPlanExecuteAgentInterruptResume (line 817) | func TestPlanExecuteAgentInterruptResume(t *testing.T) {
FILE: adk/prebuilt/planexecute/utils.go
type outputSessionKVsAgent (line 25) | type outputSessionKVsAgent struct
method Run (line 29) | func (o *outputSessionKVsAgent) Run(ctx context.Context, input *adk.Ag...
function agentOutputSessionKVs (line 56) | func agentOutputSessionKVs(ctx context.Context, agent adk.Agent) (adk.Ag...
FILE: adk/prebuilt/supervisor/supervisor.go
type Config (line 40) | type Config struct
type supervisorContainer (line 56) | type supervisorContainer struct
method Name (line 61) | func (s *supervisorContainer) Name(_ context.Context) string {
method Description (line 65) | func (s *supervisorContainer) Description(ctx context.Context) string {
method GetType (line 69) | func (s *supervisorContainer) GetType() string {
method Run (line 73) | func (s *supervisorContainer) Run(ctx context.Context, input *adk.Agen...
method Resume (line 77) | func (s *supervisorContainer) Resume(ctx context.Context, info *adk.Re...
function New (line 92) | func New(ctx context.Context, conf *Config) (adk.ResumableAgent, error) {
FILE: adk/prebuilt/supervisor/supervisor_test.go
function TestNewSupervisor (line 40) | func TestNewSupervisor(t *testing.T) {
type approvalInfo (line 180) | type approvalInfo struct
method String (line 186) | func (ai *approvalInfo) String() string {
type approvalResult (line 191) | type approvalResult struct
function init (line 196) | func init() {
type approvableTool (line 201) | type approvableTool struct
method Info (line 206) | func (m *approvableTool) Info(_ context.Context) (*schema.ToolInfo, er...
method InvokableRun (line 216) | func (m *approvableTool) InvokableRun(ctx context.Context, argumentsIn...
type checkpointStore (line 250) | type checkpointStore struct
method Set (line 258) | func (s *checkpointStore) Set(_ context.Context, key string, value []b...
method Get (line 263) | func (s *checkpointStore) Get(_ context.Context, key string) ([]byte, ...
function newCheckpointStore (line 254) | func newCheckpointStore() *checkpointStore {
type namedAgent (line 268) | type namedAgent struct
method Name (line 274) | func (n *namedAgent) Name(_ context.Context) string {
method Description (line 278) | func (n *namedAgent) Description(_ context.Context) string {
function TestNestedSupervisorInterruptResume (line 282) | func TestNestedSupervisorInterruptResume(t *testing.T) {
function TestSupervisorExit (line 498) | func TestSupervisorExit(t *testing.T) {
function TestNestedSupervisorExit (line 575) | func TestNestedSupervisorExit(t *testing.T) {
function TestChatModelAgentInternalEventsExit (line 682) | func TestChatModelAgentInternalEventsExit(t *testing.T) {
function TestSupervisorContainerUnifiedTracing (line 831) | func TestSupervisorContainerUnifiedTracing(t *testing.T) {
type traceContextKey (line 943) | type traceContextKey struct
function TestSupervisorContainerUnifiedTracingOnResume (line 945) | func TestSupervisorContainerUnifiedTracingOnResume(t *testing.T) {
FILE: adk/react.go
type State (line 40) | type State struct
method getReturnDirectlyEvent (line 86) | func (s *State) getReturnDirectlyEvent() *AgentEvent {
method setReturnDirectlyEvent (line 90) | func (s *State) setReturnDirectlyEvent(event *AgentEvent) {
method getRetryAttempt (line 94) | func (s *State) getRetryAttempt() int {
method setRetryAttempt (line 98) | func (s *State) setRetryAttempt(attempt int) {
method getReturnDirectlyToolCallID (line 102) | func (s *State) getReturnDirectlyToolCallID() string {
method setReturnDirectlyToolCallID (line 106) | func (s *State) setReturnDirectlyToolCallID(id string) {
method getToolGenActions (line 111) | func (s *State) getToolGenActions() map[string]*AgentAction {
method setToolGenAction (line 115) | func (s *State) setToolGenAction(key string, action *AgentAction) {
method popToolGenAction (line 122) | func (s *State) popToolGenAction(key string) *AgentAction {
method getRemainingIterations (line 131) | func (s *State) getRemainingIterations() int {
method setRemainingIterations (line 135) | func (s *State) setRemainingIterations(iterations int) {
method decrementRemainingIterations (line 139) | func (s *State) decrementRemainingIterations() {
constant stateGobNameV07 (line 56) | stateGobNameV07 = "_eino_adk_react_state"
constant stateGobNameV080 (line 62) | stateGobNameV080 = "_eino_adk_state_v080_"
function init (line 65) | func init() {
type stateV080 (line 150) | type stateV080 struct
method GobDecode (line 167) | func (sc *stateV080) GobDecode(b []byte) error {
type stateV080Serialization (line 165) | type stateV080Serialization
function stateV080ToState (line 184) | func stateV080ToState(sc *stateV080) *State {
function SendToolGenAction (line 226) | func SendToolGenAction(ctx context.Context, toolName string, action *Age...
type reactInput (line 239) | type reactInput struct
type reactConfig (line 243) | type reactConfig struct
function genToolInfos (line 258) | func genToolInfos(ctx context.Context, config *compose.ToolsNodeConfig) ...
function getReturnDirectlyToolCallID (line 276) | func getReturnDirectlyToolCallID(ctx context.Context) (string, bool) {
function genReactState (line 288) | func genReactState(config *reactConfig) func(ctx context.Context) *State {
function newReact (line 302) | func newReact(ctx context.Context, config *reactConfig) (reactGraph, err...
FILE: adk/react_test.go
type testModelWrapper (line 40) | type testModelWrapper struct
method Generate (line 81) | func (w *testModelWrapper) Generate(ctx context.Context, input []*sche...
method Stream (line 85) | func (w *testModelWrapper) Stream(ctx context.Context, input []*schema...
method WithTools (line 89) | func (w *testModelWrapper) WithTools(tools []*schema.ToolInfo) (model....
function TestStateCompatConversions_V080 (line 44) | func TestStateCompatConversions_V080(t *testing.T) {
function TestStateGetToolGenActions (line 71) | func TestStateGetToolGenActions(t *testing.T) {
function TestReact (line 98) | func TestReact(t *testing.T) {
type fakeStreamToolForTest (line 560) | type fakeStreamToolForTest struct
method StreamableRun (line 565) | func (t *fakeStreamToolForTest) StreamableRun(_ context.Context, argum...
method Info (line 602) | func (t *fakeStreamToolForTest) Info(_ context.Context) (*schema.ToolI...
type fakeToolForTest (line 582) | type fakeToolForTest struct
method Info (line 587) | func (t *fakeToolForTest) Info(_ context.Context) (*schema.ToolInfo, e...
method InvokableRun (line 617) | func (t *fakeToolForTest) InvokableRun(_ context.Context, argumentsInJ...
type fakeToolInputForTest (line 632) | type fakeToolInputForTest struct
function randStrForTest (line 636) | func randStrForTest() string {
FILE: adk/retry_chatmodel.go
type RetryExhaustedError (line 52) | type RetryExhaustedError struct
method Error (line 57) | func (e *RetryExhaustedError) Error() string {
method Unwrap (line 64) | func (e *RetryExhaustedError) Unwrap() error {
type WillRetryError (line 79) | type WillRetryError struct
method Error (line 85) | func (e *WillRetryError) Error() string {
method Unwrap (line 89) | func (e *WillRetryError) Unwrap() error {
function init (line 93) | func init() {
type ModelRetryConfig (line 99) | type ModelRetryConfig struct
function defaultIsRetryAble (line 119) | func defaultIsRetryAble(_ context.Context, err error) bool {
function defaultBackoff (line 123) | func defaultBackoff(_ context.Context, attempt int) time.Duration {
function genErrWrapper (line 144) | func genErrWrapper(ctx context.Context, maxRetries, attempt int, isRetry...
function consumeStreamForError (line 156) | func consumeStreamForError(stream *schema.StreamReader[*schema.Message])...
type retryModelWrapper (line 173) | type retryModelWrapper struct
method Generate (line 182) | func (r *retryModelWrapper) Generate(ctx context.Context, input []*sch...
method Stream (line 213) | func (r *retryModelWrapper) Stream(ctx context.Context, input []*schem...
function newRetryModelWrapper (line 178) | func newRetryModelWrapper(inner model.BaseChatModel, config *ModelRetryC...
FILE: adk/runctx.go
type runSession (line 32) | type runSession struct
method addEvent (line 131) | func (rs *runSession) addEvent(event *AgentEvent) {
method getEvents (line 146) | func (rs *runSession) getEvents() []*agentEventWrapper {
method getValues (line 183) | func (rs *runSession) getValues() map[string]any {
method addValue (line 194) | func (rs *runSession) addValue(key string, value any) {
method addValues (line 200) | func (rs *runSession) addValues(kvs map[string]any) {
method getValue (line 208) | func (rs *runSession) getValue(key string) (any, bool) {
type laneEvents (line 42) | type laneEvents struct
type agentEventWrapper (line 48) | type agentEventWrapper struct
method GobEncode (line 67) | func (a *agentEventWrapper) GobEncode() ([]byte, error) {
method GobDecode (line 80) | func (a *agentEventWrapper) GobDecode(b []byte) error {
type otherAgentEventWrapperForEncode (line 65) | type otherAgentEventWrapperForEncode
function newRunSession (line 84) | func newRunSession() *runSession {
function GetSessionValues (line 92) | func GetSessionValues(ctx context.Context) map[string]any {
function AddSessionValue (line 102) | func AddSessionValue(ctx context.Context, key string, value any) {
function AddSessionValues (line 112) | func AddSessionValues(ctx context.Context, kvs map[string]any) {
function GetSessionValue (line 122) | func GetSessionValue(ctx context.Context, key string) (any, bool) {
type runContext (line 216) | type runContext struct
method isRoot (line 223) | func (rc *runContext) isRoot() bool {
method deepCopy (line 227) | func (rc *runContext) deepCopy() *runContext {
type runCtxKey (line 239) | type runCtxKey struct
function getRunCtx (line 241) | func getRunCtx(ctx context.Context) *runContext {
function setRunCtx (line 249) | func setRunCtx(ctx context.Context, runCtx *runContext) context.Context {
function initRunCtx (line 253) | func initRunCtx(ctx context.Context, agentName string, input *AgentInput...
function joinRunCtxs (line 269) | func joinRunCtxs(parentCtx context.Context, childCtxs ...context.Context) {
function commitEvents (line 293) | func commitEvents(ctx context.Context, newEvents []*agentEventWrapper) {
function unwindLaneEvents (line 313) | func unwindLaneEvents(ctxs ...context.Context) []*agentEventWrapper {
function forkRunCtx (line 324) | func forkRunCtx(ctx context.Context) context.Context {
function updateRunPathOnly (line 359) | func updateRunPathOnly(ctx context.Context, agentNames ...string) contex...
function ClearRunCtx (line 379) | func ClearRunCtx(ctx context.Context) context.Context {
function ctxWithNewRunCtx (line 383) | func ctxWithNewRunCtx(ctx context.Context, input *AgentInput, sharedPare...
function getSession (line 399) | func getSession(ctx context.Context) *runSession {
FILE: adk/runctx_test.go
function TestSessionValues (line 29) | func TestSessionValues(t *testing.T) {
function TestForkJoinRunCtx (line 337) | func TestForkJoinRunCtx(t *testing.T) {
FILE: adk/runner.go
type Runner (line 32) | type Runner struct
method Run (line 75) | func (r *Runner) Run(ctx context.Context, messages []Message,
method Query (line 102) | func (r *Runner) Query(ctx context.Context,
method Resume (line 115) | func (r *Runner) Resume(ctx context.Context, checkPointID string, opts...
method ResumeWithParams (line 138) | func (r *Runner) ResumeWithParams(ctx context.Context, checkPointID st...
method resume (line 143) | func (r *Runner) resume(ctx context.Context, checkPointID string, resu...
method handleIter (line 189) | func (r *Runner) handleIter(ctx context.Context, aIter *AsyncIterator[...
type RunnerConfig (line 44) | type RunnerConfig struct
type ResumeParams (line 54) | type ResumeParams struct
function NewRunner (line 63) | func NewRunner(_ context.Context, conf RunnerConfig) *Runner {
FILE: adk/runner_test.go
type mockRunnerAgent (line 29) | type mockRunnerAgent struct
method Name (line 39) | func (a *mockRunnerAgent) Name(_ context.Context) string {
method Description (line 43) | func (a *mockRunnerAgent) Description(_ context.Context) string {
method Run (line 47) | func (a *mockRunnerAgent) Run(_ context.Context, input *AgentInput, _ ...
function newMockRunnerAgent (line 71) | func newMockRunnerAgent(name, description string, responses []*AgentEven...
function TestNewRunner (line 79) | func TestNewRunner(t *testing.T) {
function TestRunner_Run (line 89) | func TestRunner_Run(t *testing.T) {
function TestRunner_Run_WithStreaming (line 135) | func TestRunner_Run_WithStreaming(t *testing.T) {
function TestRunner_Query (line 181) | func TestRunner_Query(t *testing.T) {
function TestRunner_Query_WithStreaming (line 223) | func TestRunner_Query_WithStreaming(t *testing.T) {
FILE: adk/utils.go
type AsyncIterator (line 31) | type AsyncIterator struct
method Next (line 35) | func (ai *AsyncIterator[T]) Next() (T, bool) {
type AsyncGenerator (line 39) | type AsyncGenerator struct
method Send (line 43) | func (ag *AsyncGenerator[T]) Send(v T) {
method Close (line 47) | func (ag *AsyncGenerator[T]) Close() {
function NewAsyncIteratorPair (line 53) | func NewAsyncIteratorPair[T any]() (*AsyncIterator[T], *AsyncGenerator[T...
function copyMap (line 58) | func copyMap[K comparable, V any](m map[K]V) map[K]V {
function cloneSlice (line 66) | func cloneSlice[T any](s []T) []T {
function concatInstructions (line 75) | func concatInstructions(instructions ...string) string {
function GenTransferMessages (line 88) | func GenTransferMessages(_ context.Context, destAgentName string) (Messa...
function setAutomaticClose (line 98) | func setAutomaticClose(e *AgentEvent) {
function getMessageFromWrappedEvent (line 110) | func getMessageFromWrappedEvent(e *agentEventWrapper) (Message, error) {
function copyAgentEvent (line 186) | func copyAgentEvent(ae *AgentEvent) *AgentEvent {
function GetMessage (line 228) | func GetMessage(e *AgentEvent) (Message, *AgentEvent, error) {
function genErrorIter (line 246) | func genErrorIter(err error) *AsyncIterator[*AgentEvent] {
FILE: adk/utils_test.go
function TestAsyncIteratorPair_Basic (line 33) | func TestAsyncIteratorPair_Basic(t *testing.T) {
function TestAsyncIteratorPair_Close (line 68) | func TestAsyncIteratorPair_Close(t *testing.T) {
function TestAsyncIteratorPair_Concurrency (line 102) | func TestAsyncIteratorPair_Concurrency(t *testing.T) {
function TestGenErrorIter (line 165) | func TestGenErrorIter(t *testing.T) {
function TestGetMessageFromWrappedEvent_StreamError_MultipleCallsGuard (line 174) | func TestGetMessageFromWrappedEvent_StreamError_MultipleCallsGuard(t *te...
function TestGetMessageFromWrappedEvent_StreamSuccess_MultipleCallsCached (line 209) | func TestGetMessageFromWrappedEvent_StreamSuccess_MultipleCallsCached(t ...
function TestGetMessageFromWrappedEvent_StreamError_PartialMessagesPreserved (line 242) | func TestGetMessageFromWrappedEvent_StreamError_PartialMessagesPreserved...
function TestAgentEventWrapper_GobEncoding_WithWillRetryError (line 285) | func TestAgentEventWrapper_GobEncoding_WithWillRetryError(t *testing.T) {
function TestAgentEventWrapper_GobEncoding_WithUnregisteredError (line 334) | func TestAgentEventWrapper_GobEncoding_WithUnregisteredError(t *testing....
function TestAgentEventWrapper_GobEncoding_WithStreamSuccess (line 367) | func TestAgentEventWrapper_GobEncoding_WithStreamSuccess(t *testing.T) {
FILE: adk/workflow.go
type workflowAgentMode (line 30) | type workflowAgentMode
constant workflowAgentModeUnknown (line 33) | workflowAgentModeUnknown workflowAgentMode = iota
constant workflowAgentModeSequential (line 34) | workflowAgentModeSequential
constant workflowAgentModeLoop (line 35) | workflowAgentModeLoop
constant workflowAgentModeParallel (line 36) | workflowAgentModeParallel
type workflowAgent (line 39) | type workflowAgent struct
method Name (line 49) | func (a *workflowAgent) Name(_ context.Context) string {
method Description (line 53) | func (a *workflowAgent) Description(_ context.Context) string {
method GetType (line 57) | func (a *workflowAgent) GetType() string {
method Run (line 70) | func (a *workflowAgent) Run(ctx context.Context, _ *AgentInput, opts ....
method Resume (line 123) | func (a *workflowAgent) Resume(ctx context.Context, info *ResumeInfo, ...
method runSequential (line 172) | func (a *workflowAgent) runSequential(ctx context.Context,
method runLoop (line 297) | func (a *workflowAgent) runLoop(ctx context.Context, generator *AsyncG...
method runParallel (line 427) | func (a *workflowAgent) runParallel(ctx context.Context, generator *As...
type sequentialWorkflowState (line 104) | type sequentialWorkflowState struct
type parallelWorkflowState (line 108) | type parallelWorkflowState struct
type loopWorkflowState (line 112) | type loopWorkflowState struct
function init (line 117) | func init() {
type WorkflowInterruptInfo (line 161) | type WorkflowInterruptInfo struct
type BreakLoopAction (line 278) | type BreakLoopAction struct
function NewBreakLoopAction (line 291) | func NewBreakLoopAction(agentName string) *AgentAction {
type SequentialAgentConfig (line 553) | type SequentialAgentConfig struct
type ParallelAgentConfig (line 559) | type ParallelAgentConfig struct
type LoopAgentConfig (line 565) | type LoopAgentConfig struct
function newWorkflowAgent (line 573) | func newWorkflowAgent(ctx context.Context, name, desc string,
function NewSequentialAgent (line 600) | func NewSequentialAgent(ctx context.Context, config *SequentialAgentConf...
function NewParallelAgent (line 605) | func NewParallelAgent(ctx context.Context, config *ParallelAgentConfig) ...
function NewLoopAgent (line 610) | func NewLoopAgent(ctx context.Context, config *LoopAgentConfig) (Resumab...
FILE: adk/workflow_test.go
type mockAgent (line 32) | type mockAgent struct
method Name (line 38) | func (a *mockAgent) Name(_ context.Context) string {
method Description (line 42) | func (a *mockAgent) Description(_ context.Context) string {
method Run (line 46) | func (a *mockAgent) Run(_ context.Context, _ *AgentInput, _ ...AgentRu...
function newMockAgent (line 66) | func newMockAgent(name, description string, responses []*AgentEvent) *mo...
function TestSequentialAgent (line 75) | func TestSequentialAgent(t *testing.T) {
function TestSequentialAgentWithExit (line 162) | func TestSequentialAgentWithExit(t *testing.T) {
function TestParallelAgent (line 234) | func TestParallelAgent(t *testing.T) {
function TestLoopAgent (line 322) | func TestLoopAgent(t *testing.T) {
function TestLoopAgentWithBreakLoop (line 390) | func TestLoopAgentWithBreakLoop(t *testing.T) {
function TestWorkflowAgentPanicRecovery (line 463) | func TestWorkflowAgentPanicRecovery(t *testing.T) {
type panicMockAgent (line 509) | type panicMockAgent struct
method Run (line 513) | func (a *panicMockAgent) Run(_ context.Context, _ *AgentInput, _ ...Ag...
function TestParallelWorkflowResumeWithEvents (line 517) | func TestParallelWorkflowResumeWithEvents(t *testing.T) {
function TestNestedParallelWorkflow (line 733) | func TestNestedParallelWorkflow(t *testing.T) {
function TestWorkflowAgentUnsupportedMode (line 1016) | func TestWorkflowAgentUnsupportedMode(t *testing.T) {
function TestFilterOptions (line 1050) | func TestFilterOptions(t *testing.T) {
function TestLoopAgentWithError (line 1091) | func TestLoopAgentWithError(t *testing.T) {
function TestWorkflowCallbackHandlerNotDoubled (line 1150) | func TestWorkflowCallbackHandlerNotDoubled(t *testing.T) {
function TestLoopAgentWithBreakLoopFollowedByMoreEvents (line 1289) | func TestLoopAgentWithBreakLoopFollowedByMoreEvents(t *testing.T) {
FILE: adk/wrappers.go
type generateEndpoint (line 33) | type generateEndpoint
type streamEndpoint (line 34) | type streamEndpoint
type modelWrapperConfig (line 36) | type modelWrapperConfig struct
function buildModelWrappers (line 43) | func buildModelWrappers(m model.BaseChatModel, config *modelWrapperConfi...
type callbackInjectionModelWrapper (line 62) | type callbackInjectionModelWrapper struct
method WrapModel (line 64) | func (w *callbackInjectionModelWrapper) WrapModel(m model.BaseChatMode...
type callbackInjectedModel (line 68) | type callbackInjectedModel struct
method Generate (line 72) | func (m *callbackInjectedModel) Generate(ctx context.Context, input []...
method Stream (line 83) | func (m *callbackInjectedModel) Stream(ctx context.Context, input []*s...
function handlersToToolMiddlewares (line 94) | func handlersToToolMiddlewares(handlers []ChatModelAgentMiddleware) []co...
type eventSenderModelWrapper (line 239) | type eventSenderModelWrapper struct
method WrapModel (line 254) | func (w *eventSenderModelWrapper) WrapModel(_ context.Context, m model...
function NewEventSenderModelWrapper (line 248) | func NewEventSenderModelWrapper() ChatModelAgentMiddleware {
type eventSenderModel (line 262) | type eventSenderModel struct
method Generate (line 267) | func (m *eventSenderModel) Generate(ctx context.Context, input []*sche...
method Stream (line 285) | func (m *eventSenderModel) Stream(ctx context.Context, input []*schema...
function popToolGenAction (line 322) | func popToolGenAction(ctx context.Context, toolName string) *AgentAction {
type eventSenderToolHandler (line 344) | type eventSenderToolHandler struct
method WrapInvokableToolCall (line 346) | func (h *eventSenderToolHandler) WrapInvokableToolCall(next compose.In...
method WrapStreamableToolCall (line 377) | func (h *eventSenderToolHandler) WrapStreamableToolCall(next compose.S...
method WrapEnhancedInvokableToolCall (line 411) | func (h *eventSenderToolHandler) WrapEnhancedInvokableToolCall(next co...
method WrapEnhancedStreamableToolCall (line 446) | func (h *eventSenderToolHandler) WrapEnhancedStreamableToolCall(next c...
type stateModelWrapper (line 486) | type stateModelWrapper struct
method IsCallbacksEnabled (line 495) | func (w *stateModelWrapper) IsCallbacksEnabled() bool {
method GetType (line 499) | func (w *stateModelWrapper) GetType() string {
method hasUserEventSender (line 506) | func (w *stateModelWrapper) hasUserEventSender() bool {
method wrapGenerateEndpoint (line 515) | func (w *stateModelWrapper) wrapGenerateEndpoint(endpoint generateEndp...
method wrapStreamEndpoint (line 563) | func (w *stateModelWrapper) wrapStreamEndpoint(endpoint streamEndpoint...
method Generate (line 611) | func (w *stateModelWrapper) Generate(ctx context.Context, input []*sch...
method Stream (line 677) | func (w *stateModelWrapper) Stream(ctx context.Context, input []*schem...
type endpointModel (line 747) | type endpointModel struct
method Generate (line 752) | func (m *endpointModel) Generate(ctx context.Context, input []*schema....
method Stream (line 759) | func (m *endpointModel) Stream(ctx context.Context, input []*schema.Me...
FILE: adk/wrappers_test.go
type testEnhancedToolWrapperHandler (line 33) | type testEnhancedToolWrapperHandler struct
method WrapEnhancedInvokableToolCall (line 39) | func (h *testEnhancedToolWrapperHandler) WrapEnhancedInvokableToolCall...
method WrapEnhancedStreamableToolCall (line 46) | func (h *testEnhancedToolWrapperHandler) WrapEnhancedStreamableToolCal...
function newTestEnhancedInvokableToolCallWrapper (line 53) | func newTestEnhancedInvokableToolCallWrapper(beforeFn, afterFn func()) f...
function newTestEnhancedStreamableToolCallWrapper (line 68) | func newTestEnhancedStreamableToolCallWrapper(beforeFn, afterFn func()) ...
function TestHandlersToToolMiddlewaresEnhanced (line 83) | func TestHandlersToToolMiddlewaresEnhanced(t *testing.T) {
function TestEnhancedToolContextPropagation (line 396) | func TestEnhancedToolContextPropagation(t *testing.T) {
function TestBaseChatModelAgentMiddlewareEnhancedDefaults (line 456) | func TestBaseChatModelAgentMiddlewareEnhancedDefaults(t *testing.T) {
function TestEnhancedToolArgumentsPropagation (line 492) | func TestEnhancedToolArgumentsPropagation(t *testing.T) {
function TestEnhancedToolResultPropagation (line 523) | func TestEnhancedToolResultPropagation(t *testing.T) {
function TestEnhancedToolEndpointErrorFromNext (line 596) | func TestEnhancedToolEndpointErrorFromNext(t *testing.T) {
function TestWrapModelStreamChunksPreserved (line 648) | func TestWrapModelStreamChunksPreserved(t *testing.T) {
type mockStreamingModel (line 877) | type mockStreamingModel struct
method Generate (line 881) | func (m *mockStreamingModel) Generate(ctx context.Context, input []*sc...
method Stream (line 885) | func (m *mockStreamingModel) Stream(ctx context.Context, input []*sche...
type streamConsumingModelWrapper (line 896) | type streamConsumingModelWrapper struct
method Generate (line 900) | func (m *streamConsumingModelWrapper) Generate(ctx context.Context, in...
method Stream (line 904) | func (m *streamConsumingModelWrapper) Stream(ctx context.Context, inpu...
function TestEventSenderModelWrapperCustomPosition (line 916) | func TestEventSenderModelWrapperCustomPosition(t *testing.T) {
type contentModifyingModelWrapper (line 1062) | type contentModifyingModelWrapper struct
method Generate (line 1067) | func (m *contentModifyingModelWrapper) Generate(ctx context.Context, i...
method Stream (line 1076) | func (m *contentModifyingModelWrapper) Stream(ctx context.Context, inp...
FILE: callbacks/aspect_inject.go
function OnStart (line 74) | func OnStart[T any](ctx context.Context, input T) context.Context {
function OnEnd (line 86) | func OnEnd[T any](ctx context.Context, output T) context.Context {
function OnStartWithStreamInput (line 100) | func OnStartWithStreamInput[T any](ctx context.Context, input *schema.St...
function OnEndWithStreamOutput (line 113) | func OnEndWithStreamOutput[T any](ctx context.Context, output *schema.St...
function OnError (line 125) | func OnError(ctx context.Context, err error) context.Context {
function EnsureRunInfo (line 139) | func EnsureRunInfo(ctx context.Context, typ string, comp components.Comp...
function ReuseHandlers (line 156) | func ReuseHandlers(ctx context.Context, info *RunInfo) context.Context {
function InitCallbacks (line 172) | func InitCallbacks(ctx context.Context, info *RunInfo, handlers ...Handl...
FILE: callbacks/aspect_inject_test.go
function TestAspectInject (line 32) | func TestAspectInject(t *testing.T) {
function TestGlobalCallbacksRepeated (line 187) | func TestGlobalCallbacksRepeated(t *testing.T) {
function TestEnsureRunInfo (line 203) | func TestEnsureRunInfo(t *testing.T) {
function TestNesting (line 237) | func TestNesting(t *testing.T) {
function TestReuseHandlersOnEmptyCtx (line 262) | func TestReuseHandlersOnEmptyCtx(t *testing.T) {
function TestAppendHandlersTwiceOnSameCtx (line 271) | func TestAppendHandlersTwiceOnSameCtx(t *testing.T) {
type myCallback (line 286) | type myCallback struct
method OnStart (line 291) | func (m *myCallback) OnStart(ctx context.Context, info *RunInfo, input...
method OnEnd (line 306) | func (m *myCallback) OnEnd(ctx context.Context, info *RunInfo, output ...
method OnError (line 320) | func (m *myCallback) OnError(ctx context.Context, info *RunInfo, err e...
method OnStartWithStreamInput (line 324) | func (m *myCallback) OnStartWithStreamInput(ctx context.Context, info ...
method OnEndWithStreamOutput (line 328) | func (m *myCallback) OnEndWithStreamOutput(ctx context.Context, info *...
FILE: callbacks/handler_builder.go
type HandlerBuilder (line 54) | type HandlerBuilder struct
method OnStartFn (line 114) | func (hb *HandlerBuilder) OnStartFn(
method OnEndFn (line 122) | func (hb *HandlerBuilder) OnEndFn(
method OnErrorFn (line 130) | func (hb *HandlerBuilder) OnErrorFn(
method OnStartWithStreamInputFn (line 141) | func (hb *HandlerBuilder) OnStartWithStreamInputFn(
method OnEndWithStreamOutputFn (line 153) | func (hb *HandlerBuilder) OnEndWithStreamOutputFn(
method Build (line 161) | func (hb *HandlerBuilder) Build() Handler {
type handlerImpl (line 62) | type handlerImpl struct
method OnStart (line 66) | func (hb *handlerImpl) OnStart(ctx context.Context, info *RunInfo, inp...
method OnEnd (line 70) | func (hb *handlerImpl) OnEnd(ctx context.Context, info *RunInfo, outpu...
method OnError (line 74) | func (hb *handlerImpl) OnError(ctx context.Context, info *RunInfo, err...
method OnStartWithStreamInput (line 78) | func (hb *handlerImpl) OnStartWithStreamInput(ctx context.Context, inf...
method OnEndWithStreamOutput (line 84) | func (hb *handlerImpl) OnEndWithStreamOutput(ctx context.Context, info...
method Needed (line 90) | func (hb *handlerImpl) Needed(_ context.Context, _ *RunInfo, timing Ca...
function NewHandlerBuilder (line 109) | func NewHandlerBuilder() *HandlerBuilder {
FILE: callbacks/interface.go
function InitCallbackHandlers (line 91) | func InitCallbackHandlers(handlers []Handler) {
function AppendGlobalHandlers (line 103) | func AppendGlobalHandlers(handlers ...Handler) {
constant TimingOnStart (line 117) | TimingOnStart CallbackTiming = iota
constant TimingOnEnd (line 120) | TimingOnEnd
constant TimingOnError (line 124) | TimingOnError
constant TimingOnStartWithStreamInput (line 128) | TimingOnStartWithStreamInput
constant TimingOnEndWithStreamOutput (line 133) | TimingOnEndWithStreamOutput
FILE: callbacks/interface_test.go
function TestAppendGlobalHandlers (line 28) | func TestAppendGlobalHandlers(t *testing.T) {
FILE: components/document/callback_extra_loader.go
type LoaderCallbackInput (line 25) | type LoaderCallbackInput struct
type LoaderCallbackOutput (line 34) | type LoaderCallbackOutput struct
function ConvLoaderCallbackInput (line 46) | func ConvLoaderCallbackInput(src callbacks.CallbackInput) *LoaderCallbac...
function ConvLoaderCallbackOutput (line 60) | func ConvLoaderCallbackOutput(src callbacks.CallbackOutput) *LoaderCallb...
FILE: components/document/callback_extra_transformer.go
type TransformerCallbackInput (line 25) | type TransformerCallbackInput struct
type TransformerCallbackOutput (line 34) | type TransformerCallbackOutput struct
function ConvTransformerCallbackInput (line 43) | func ConvTransformerCallbackInput(src callbacks.CallbackInput) *Transfor...
function ConvTransformerCallbackOutput (line 57) | func ConvTransformerCallbackOutput(src callbacks.CallbackOutput) *Transf...
FILE: components/document/interface.go
type Source (line 27) | type Source struct
type Loader (line 43) | type Loader interface
type Transformer (line 53) | type Transformer interface
FILE: components/document/option.go
type LoaderOptions (line 22) | type LoaderOptions struct
type LoaderOption (line 29) | type LoaderOption struct
function WrapLoaderImplSpecificOptFn (line 51) | func WrapLoaderImplSpecificOptFn[T any](optFn func(*T)) LoaderOption {
function GetLoaderImplSpecificOptions (line 67) | func GetLoaderImplSpecificOptions[T any](base *T, opts ...LoaderOption) ...
function GetLoaderCommonOptions (line 86) | func GetLoaderCommonOptions(base *LoaderOptions, opts ...LoaderOption) *...
function WithParserOptions (line 102) | func WithParserOptions(opts ...parser.Option) LoaderOption {
type TransformerOption (line 113) | type TransformerOption struct
function WrapTransformerImplSpecificOptFn (line 135) | func WrapTransformerImplSpecificOptFn[T any](optFn func(*T)) Transformer...
function GetTransformerImplSpecificOptions (line 151) | func GetTransformerImplSpecificOptions[T any](base *T, opts ...Transform...
FILE: components/document/option_test.go
function TestImplSpecificOpts (line 27) | func TestImplSpecificOpts(t *testing.T) {
function TestCommonOptions (line 69) | func TestCommonOptions(t *testing.T) {
FILE: components/document/parser/ext_parser.go
type ExtParserConfig (line 29) | type ExtParserConfig struct
type ExtParser (line 55) | type ExtParser struct
method GetParsers (line 85) | func (p *ExtParser) GetParsers() map[string]Parser {
method Parse (line 95) | func (p *ExtParser) Parse(ctx context.Context, reader io.Reader, opts ...
function NewExtParser (line 62) | func NewExtParser(ctx context.Context, conf *ExtParserConfig) (*ExtParse...
FILE: components/document/parser/interface.go
type Parser (line 34) | type Parser interface
FILE: components/document/parser/option.go
type Options (line 20) | type Options struct
type Option (line 31) | type Option struct
function WithURI (line 39) | func WithURI(uri string) Option {
function WithExtraMeta (line 48) | func WithExtraMeta(meta map[string]any) Option {
function GetCommonOptions (line 57) | func GetCommonOptions(base *Options, opts ...Option) *Options {
function WrapImplSpecificOptFn (line 90) | func WrapImplSpecificOptFn[T any](optFn func(*T)) Option {
function GetImplSpecificOptions (line 100) | func GetImplSpecificOptions[T any](base *T, opts ...Option) *T {
FILE: components/document/parser/option_test.go
function TestImplSpecificOpts (line 25) | func TestImplSpecificOpts(t *testing.T) {
FILE: components/document/parser/parser_test.go
type ParserForTest (line 30) | type ParserForTest struct
method Parse (line 34) | func (p *ParserForTest) Parse(ctx context.Context, reader io.Reader, o...
function TestParser (line 38) | func TestParser(t *testing.T) {
FILE: components/document/parser/text_parser.go
constant MetaKeySource (line 28) | MetaKeySource = "_source"
type TextParser (line 36) | type TextParser struct
method Parse (line 39) | func (dp TextParser) Parse(ctx context.Context, reader io.Reader, opts...
FILE: components/embedding/callback_extra.go
type TokenUsage (line 24) | type TokenUsage struct
type Config (line 34) | type Config struct
type ComponentExtra (line 42) | type ComponentExtra struct
type CallbackInput (line 50) | type CallbackInput struct
type CallbackOutput (line 60) | type CallbackOutput struct
function ConvCallbackInput (line 72) | func ConvCallbackInput(src callbacks.CallbackInput) *CallbackInput {
function ConvCallbackOutput (line 86) | func ConvCallbackOutput(src callbacks.CallbackOutput) *CallbackOutput {
FILE: components/embedding/callback_extra_test.go
function TestConvEmbedding (line 25) | func TestConvEmbedding(t *testing.T) {
FILE: components/embedding/interface.go
type Embedder (line 37) | type Embedder interface
FILE: components/embedding/option.go
type Options (line 20) | type Options struct
type Option (line 26) | type Option struct
function WithModel (line 33) | func WithModel(model string) Option {
function GetCommonOptions (line 49) | func GetCommonOptions(base *Options, opts ...Option) *Options {
function WrapImplSpecificOptFn (line 72) | func WrapImplSpecificOptFn[T any](optFn func(*T)) Option {
function GetImplSpecificOptions (line 86) | func GetImplSpecificOptions[T any](base *T, opts ...Option) *T {
FILE: components/embedding/option_test.go
function TestOptions (line 25) | func TestOptions(t *testing.T) {
FILE: components/indexer/callback_extra.go
type CallbackInput (line 25) | type CallbackInput struct
type CallbackOutput (line 33) | type CallbackOutput struct
function ConvCallbackInput (line 41) | func ConvCallbackInput(src callbacks.CallbackInput) *CallbackInput {
function ConvCallbackOutput (line 55) | func ConvCallbackOutput(src callbacks.CallbackOutput) *CallbackOutput {
FILE: components/indexer/callback_extra_test.go
function TestConvIndexer (line 27) | func TestConvIndexer(t *testing.T) {
FILE: components/indexer/interface.go
type Indexer (line 37) | type Indexer interface
FILE: components/indexer/option.go
type Options (line 22) | type Options struct
function WithSubIndexes (line 30) | func WithSubIndexes(subIndexes []string) Option {
function WithEmbedding (line 39) | func WithEmbedding(emb embedding.Embedder) Option {
type Option (line 48) | type Option struct
function GetCommonOptions (line 61) | func GetCommonOptions(base *Options, opts ...Option) *Options {
function WrapImplSpecificOptFn (line 78) | func WrapImplSpecificOptFn[T any](optFn func(*T)) Option {
function GetImplSpecificOptions (line 86) | func GetImplSpecificOptions[T any](base *T, opts ...Option) *T {
FILE: components/indexer/option_test.go
function TestOptions (line 27) | func TestOptions(t *testing.T) {
FILE: components/model/callback_extra.go
type TokenUsage (line 25) | type TokenUsage struct
type CompletionTokensDetails (line 38) | type CompletionTokensDetails struct
type PromptTokenDetails (line 46) | type PromptTokenDetails struct
type Config (line 52) | type Config struct
type CallbackInput (line 66) | type CallbackInput struct
type CallbackOutput (line 80) | type CallbackOutput struct
function ConvCallbackInput (line 92) | func ConvCallbackInput(src callbacks.CallbackInput) *CallbackInput {
function ConvCallbackOutput (line 106) | func ConvCallbackOutput(src callbacks.CallbackOutput) *CallbackOutput {
FILE: components/model/callback_extra_test.go
function TestConvModel (line 27) | func TestConvModel(t *testing.T) {
FILE: components/model/interface.go
type BaseChatModel (line 53) | type BaseChatModel interface
type ChatModel (line 66) | type ChatModel interface
type ToolCallingChatModel (line 85) | type ToolCallingChatModel interface
FILE: components/model/option.go
type Options (line 22) | type Options struct
type Option (line 46) | type Option struct
function WithTemperature (line 53) | func WithTemperature(temperature float32) Option {
function WithMaxTokens (line 62) | func WithMaxTokens(maxTokens int) Option {
function WithModel (line 71) | func WithModel(name string) Option {
function WithTopP (line 80) | func WithTopP(topP float32) Option {
function WithStop (line 89) | func WithStop(stop []string) Option {
function WithTools (line 98) | func WithTools(tools []*schema.ToolInfo) Option {
function WithToolChoice (line 111) | func WithToolChoice(toolChoice schema.ToolChoice, allowedToolNames ...st...
function WrapImplSpecificOptFn (line 139) | func WrapImplSpecificOptFn[T any](optFn func(*T)) Option {
function GetCommonOptions (line 154) | func GetCommonOptions(base *Options, opts ...Option) *Options {
function GetImplSpecificOptions (line 182) | func GetImplSpecificOptions[T any](base *T, opts ...Option) *T {
FILE: components/model/option_test.go
function TestOptions (line 27) | func TestOptions(t *testing.T) {
type implOption (line 87) | type implOption struct
function WithUserID (line 92) | func WithUserID(uid int64) Option {
function WithName (line 98) | func WithName(n string) Option {
function TestImplSpecificOption (line 104) | func TestImplSpecificOption(t *testing.T) {
FILE: components/prompt/callback_extra.go
type CallbackInput (line 25) | type CallbackInput struct
type CallbackOutput (line 35) | type CallbackOutput struct
function ConvCallbackInput (line 45) | func ConvCallbackInput(src callbacks.CallbackInput) *CallbackInput {
function ConvCallbackOutput (line 59) | func ConvCallbackOutput(src callbacks.CallbackOutput) *CallbackOutput {
FILE: components/prompt/callback_extra_test.go
function TestConvPrompt (line 27) | func TestConvPrompt(t *testing.T) {
FILE: components/prompt/chat_template.go
type DefaultChatTemplate (line 28) | type DefaultChatTemplate struct
method Format (line 50) | func (t *DefaultChatTemplate) Format(ctx context.Context,
method GetType (line 82) | func (t *DefaultChatTemplate) GetType() string {
method IsCallbacksEnabled (line 87) | func (t *DefaultChatTemplate) IsCallbacksEnabled() bool {
function FromMessages (line 42) | func FromMessages(formatType schema.FormatType, templates ...schema.Mess...
FILE: components/prompt/chat_template_test.go
function TestFormat (line 28) | func TestFormat(t *testing.T) {
function TestDocumentFormat (line 86) | func TestDocumentFormat(t *testing.T) {
function TestMultiContentFormat (line 117) | func TestMultiContentFormat(t *testing.T) {
FILE: components/prompt/interface.go
type ChatTemplate (line 42) | type ChatTemplate interface
FILE: components/prompt/option.go
type Option (line 22) | type Option struct
function WrapImplSpecificOptFn (line 29) | func WrapImplSpecificOptFn[T any](optFn func(*T)) Option {
function GetImplSpecificOptions (line 36) | func GetImplSpecificOptions[T any](base *T, opts ...Option) *T {
FILE: components/prompt/option_test.go
type implOption (line 25) | type implOption struct
function WithUserID (line 30) | func WithUserID(uid int64) Option {
function WithName (line 36) | func WithName(n string) Option {
function TestImplSpecificOption (line 42) | func TestImplSpecificOption(t *testing.T) {
FILE: components/retriever/callback_extra.go
type CallbackInput (line 25) | type CallbackInput struct
type CallbackOutput (line 41) | type CallbackOutput struct
function ConvCallbackInput (line 49) | func ConvCallbackInput(src callbacks.CallbackInput) *CallbackInput {
function ConvCallbackOutput (line 63) | func ConvCallbackOutput(src callbacks.CallbackOutput) *CallbackOutput {
FILE: components/retriever/callback_extra_test.go
function TestConvRetriever (line 27) | func TestConvRetriever(t *testing.T) {
FILE: components/retriever/interface.go
type Retriever (line 48) | type Retriever interface
FILE: components/retriever/option.go
type Options (line 22) | type Options struct
function WithIndex (line 40) | func WithIndex(index string) Option {
function WithSubIndex (line 49) | func WithSubIndex(subIndex string) Option {
function WithTopK (line 58) | func WithTopK(topK int) Option {
function WithScoreThreshold (line 67) | func WithScoreThreshold(threshold float64) Option {
function WithEmbedding (line 76) | func WithEmbedding(emb embedding.Embedder) Option {
function WithDSLInfo (line 85) | func WithDSLInfo(dsl map[string]any) Option {
type Option (line 94) | type Option struct
function GetCommonOptions (line 107) | func GetCommonOptions(base *Options, opts ...Option) *Options {
function WrapImplSpecificOptFn (line 123) | func WrapImplSpecificOptFn[T any](optFn func(*T)) Option {
function GetImplSpecificOptions (line 131) | func GetImplSpecificOptions[T any](base *T, opts ...Option) *T {
FILE: components/retriever/option_test.go
function TestOptions (line 27) | func TestOptions(t *testing.T) {
FILE: components/tool/callback_extra.go
type CallbackInput (line 25) | type CallbackInput struct
type CallbackOutput (line 33) | type CallbackOutput struct
function ConvCallbackInput (line 43) | func ConvCallbackInput(src callbacks.CallbackInput) *CallbackInput {
function ConvCallbackOutput (line 57) | func ConvCallbackOutput(src callbacks.CallbackOutput) *CallbackOutput {
FILE: components/tool/callback_extra_test.go
function TestConvCallbackInput (line 25) | func TestConvCallbackInput(t *testing.T) {
function TestConvCallbackOutput (line 32) | func TestConvCallbackOutput(t *testing.T) {
FILE: components/tool/interface.go
type BaseTool (line 32) | type BaseTool interface
type InvokableTool (line 42) | type InvokableTool interface
type StreamableTool (line 53) | type StreamableTool interface
type EnhancedInvokableTool (line 67) | type EnhancedInvokableTool interface
type EnhancedStreamableTool (line 76) | type EnhancedStreamableTool interface
FILE: components/tool/interrupt.go
function Interrupt (line 44) | func Interrupt(ctx context.Context, info any) error {
function StatefulInterrupt (line 71) | func StatefulInterrupt(ctx context.Context, info any, state any) error {
function CompositeInterrupt (line 100) | func CompositeInterrupt(ctx context.Context, info any, state any, errs ....
function GetInterruptState (line 150) | func GetInterruptState[T any](ctx context.Context) (wasInterrupted bool,...
function GetResumeContext (line 183) | func GetResumeContext[T any](ctx context.Context) (isResumeTarget bool, ...
FILE: components/tool/interrupt_test.go
function TestInterrupt (line 29) | func TestInterrupt(t *testing.T) {
function TestStatefulInterrupt (line 43) | func TestStatefulInterrupt(t *testing.T) {
function TestCompositeInterrupt (line 63) | func TestCompositeInterrupt(t *testing.T) {
function TestGetInterruptState (line 116) | func TestGetInterruptState(t *testing.T) {
function TestGetResumeContext (line 126) | func TestGetResumeContext(t *testing.T) {
FILE: components/tool/option.go
type Option (line 22) | type Option struct
function WrapImplSpecificOptFn (line 44) | func WrapImplSpecificOptFn[T any](optFn func(*T)) Option {
function GetImplSpecificOptions (line 62) | func GetImplSpecificOptions[T any](base *T, opts ...Option) *T {
FILE: components/tool/option_test.go
function TestImplSpecificOpts (line 25) | func TestImplSpecificOpts(t *testing.T) {
FILE: components/tool/utils/common.go
function marshalString (line 23) | func marshalString(resp any) (string, error) {
FILE: components/tool/utils/common_test.go
function TestMarshalString (line 26) | func TestMarshalString(t *testing.T) {
function TestMarshalStringEdgeCases (line 145) | func TestMarshalStringEdgeCases(t *testing.T) {
function TestMarshalStringConsistency (line 175) | func TestMarshalStringConsistency(t *testing.T) {
FILE: components/tool/utils/create_options.go
type UnmarshalArguments (line 27) | type UnmarshalArguments
type MarshalOutput (line 30) | type MarshalOutput
type toolOptions (line 32) | type toolOptions struct
type Option (line 39) | type Option
function WithUnmarshalArguments (line 43) | func WithUnmarshalArguments(um UnmarshalArguments) Option {
function WithMarshalOutput (line 51) | func WithMarshalOutput(m MarshalOutput) Option {
type SchemaModifierFn (line 64) | type SchemaModifierFn
function WithSchemaModifier (line 67) | func WithSchemaModifier(modifier SchemaModifierFn) Option {
function getToolOptions (line 73) | func getToolOptions(opt ...Option) *toolOptions {
FILE: components/tool/utils/error_handler.go
type ErrorHandler (line 28) | type ErrorHandler
function WrapToolWithErrorHandler (line 42) | func WrapToolWithErrorHandler(t tool.BaseTool, h ErrorHandler) tool.Base...
function WrapInvokableToolWithErrorHandler (line 81) | func WrapInvokableToolWithErrorHandler(t tool.InvokableTool, h ErrorHand...
function WrapStreamableToolWithErrorHandler (line 102) | func WrapStreamableToolWithErrorHandler(t tool.StreamableTool, h ErrorHa...
type errorWrapper (line 112) | type errorWrapper struct
type streamErrorWrapper (line 117) | type streamErrorWrapper struct
type combinedErrorWrapper (line 122) | type combinedErrorWrapper struct
type infoHelper (line 128) | type infoHelper struct
method Info (line 132) | func (i *infoHelper) Info(ctx context.Context) (*schema.ToolInfo, erro...
type errorHelper (line 136) | type errorHelper struct
method InvokableRun (line 141) | func (s *errorHelper) InvokableRun(ctx context.Context, argumentsInJSO...
type streamErrorHelper (line 152) | type streamErrorHelper struct
method StreamableRun (line 157) | func (s *streamErrorHelper) StreamableRun(ctx context.Context, argumen...
FILE: components/tool/utils/error_handler_test.go
type testErrorTool (line 31) | type testErrorTool struct
method Info (line 33) | func (t *testErrorTool) Info(ctx context.Context) (*schema.ToolInfo, e...
method InvokableRun (line 37) | func (t *testErrorTool) InvokableRun(ctx context.Context, argumentsInJ...
method StreamableRun (line 41) | func (t *testErrorTool) StreamableRun(ctx context.Context, argumentsIn...
function TestErrorWrapper (line 45) | func TestErrorWrapper(t *testing.T) {
FILE: components/tool/utils/invokable_func.go
type InvokeFunc (line 33) | type InvokeFunc
type OptionableInvokeFunc (line 36) | type OptionableInvokeFunc
function InferTool (line 46) | func InferTool[T, D any](toolName, toolDesc string, i InvokeFunc[T, D], ...
function InferOptionableTool (line 57) | func InferOptionableTool[T, D any](toolName, toolDesc string, i Optionab...
type EnhancedInvokeFunc (line 67) | type EnhancedInvokeFunc
type OptionableEnhancedInvokeFunc (line 70) | type OptionableEnhancedInvokeFunc
function InferEnhancedTool (line 75) | func InferEnhancedTool[T any](toolName, toolDesc string, i EnhancedInvok...
function InferOptionableEnhancedTool (line 85) | func InferOptionableEnhancedTool[T any](toolName, toolDesc string, i Opt...
function GoStruct2ParamsOneOf (line 97) | func GoStruct2ParamsOneOf[T any](opts ...Option) (*schema.ParamsOneOf, e...
function GoStruct2ToolInfo (line 104) | func GoStruct2ToolInfo[T any](toolName, toolDesc string, opts ...Option)...
function goStruct2ToolInfo (line 108) | func goStruct2ToolInfo[T any](toolName, toolDesc string, opts ...Option)...
function goStruct2ParamsOneOf (line 120) | func goStruct2ParamsOneOf[T any](opts ...Option) (*schema.ParamsOneOf, e...
function NewTool (line 143) | func NewTool[T, D any](desc *schema.ToolInfo, i InvokeFunc[T, D], opts ....
function newOptionableTool (line 149) | func newOptionableTool[T, D any](desc *schema.ToolInfo, i OptionableInvo...
type invokableTool (line 160) | type invokableTool struct
method Info (line 169) | func (i *invokableTool[T, D]) Info(ctx context.Context) (*schema.ToolInf...
method InvokableRun (line 174) | func (i *invokableTool[T, D]) InvokableRun(ctx context.Context, argument...
method GetType (line 217) | func (i *invokableTool[T, D]) GetType() string {
method getToolName (line 221) | func (i *invokableTool[T, D]) getToolName() string {
function snakeToCamel (line 230) | func snakeToCamel(s string) string {
function NewEnhancedTool (line 248) | func NewEnhancedTool[T any](desc *schema.ToolInfo, i EnhancedInvokeFunc[...
function newOptionableEnhancedTool (line 254) | func newOptionableEnhancedTool[T any](desc *schema.ToolInfo, i Optionabl...
type enhancedInvokableTool (line 264) | type enhancedInvokableTool struct
method Info (line 272) | func (e *enhancedInvokableTool[T]) Info(ctx context.Context) (*schema.To...
method InvokableRun (line 276) | func (e *enhancedInvokableTool[T]) InvokableRun(ctx context.Context, too...
method GetType (line 308) | func (e *enhancedInvokableTool[T]) GetType() string {
method getToolName (line 312) | func (e *enhancedInvokableTool[T]) getToolName() string {
FILE: components/tool/utils/invokable_func_test.go
type Job (line 33) | type Job struct
type Income (line 39) | type Income struct
type User (line 46) | type User struct
type UserResult (line 55) | type UserResult struct
function updateUserInfo (line 194) | func updateUserInfo(ctx context.Context, input *User) (output *UserResul...
type UserInfoOption (line 201) | type UserInfoOption struct
function WithUserInfoOption (line 205) | func WithUserInfoOption(s string) tool.Option {
function updateUserInfoWithOption (line 211) | func updateUserInfoWithOption(_ context.Context, input *User, opts ...to...
function TestInferTool (line 223) | func TestInferTool(t *testing.T) {
function TestInferOptionableTool (line 251) | func TestInferOptionableTool(t *testing.T) {
function TestNewTool (line 265) | func TestNewTool(t *testing.T) {
function TestSnakeToCamel (line 320) | func TestSnakeToCamel(t *testing.T) {
type stringAlias (line 342) | type stringAlias
type integerAlias (line 343) | type integerAlias
type floatAlias (line 344) | type floatAlias
type boolAlias (line 345) | type boolAlias
type testEnumStruct (line 347) | type testEnumStruct struct
type testEnumStruct2 (line 358) | type testEnumStruct2 struct
type testEnumStruct3 (line 362) | type testEnumStruct3 struct
function TestEnumTag (line 366) | func TestEnumTag(t *testing.T) {
FILE: components/tool/utils/streamable_func.go
type StreamFunc (line 31) | type StreamFunc
type OptionableStreamFunc (line 34) | type OptionableStreamFunc
function InferStreamTool (line 39) | func InferStreamTool[T, D any](toolName, toolDesc string, s StreamFunc[T...
function InferOptionableStreamTool (line 50) | func InferOptionableStreamTool[T, D any](toolName, toolDesc string, s Op...
function NewStreamTool (line 61) | func NewStreamTool[T, D any](desc *schema.ToolInfo, s StreamFunc[T, D], ...
function newOptionableStreamTool (line 69) | func newOptionableStreamTool[T, D any](desc *schema.ToolInfo, s Optionab...
type streamableTool (line 82) | type streamableTool struct
method Info (line 92) | func (s *streamableTool[T, D]) Info(ctx context.Context) (*schema.ToolIn...
method StreamableRun (line 97) | func (s *streamableTool[T, D]) StreamableRun(ctx context.Context, argume...
method GetType (line 149) | func (s *streamableTool[T, D]) GetType() string {
method getToolName (line 153) | func (s *streamableTool[T, D]) getToolName() string {
type EnhancedStreamFunc (line 162) | type EnhancedStreamFunc
type OptionableEnhancedStreamFunc (line 165) | type OptionableEnhancedStreamFunc
function InferEnhancedStreamTool (line 170) | func InferEnhancedStreamTool[T any](toolName, toolDesc string, s Enhance...
function InferOptionableEnhancedStreamTool (line 180) | func InferOptionableEnhancedStreamTool[T any](toolName, toolDesc string,...
function NewEnhancedStreamTool (line 191) | func NewEnhancedStreamTool[T any](desc *schema.ToolInfo, s EnhancedStrea...
function newOptionableEnhancedStreamTool (line 199) | func newOptionableEnhancedStreamTool[T any](desc *schema.ToolInfo, s Opt...
type enhancedStreamableTool (line 209) | type enhancedStreamableTool struct
method Info (line 217) | func (s *enhancedStreamableTool[T]) Info(ctx context.Context) (*schema.T...
method StreamableRun (line 221) | func (s *enhancedStreamableTool[T]) StreamableRun(ctx context.Context, t...
method GetType (line 249) | func (s *enhancedStreamableTool[T]) GetType() string {
method getToolName (line 253) | func (s *enhancedStreamableTool[T]) getToolName() string {
FILE: components/tool/utils/streamable_func_test.go
function TestNewStreamableTool (line 33) | func TestNewStreamableTool(t *testing.T) {
type FakeStreamOption (line 117) | type FakeStreamOption struct
type FakeStreamInferToolInput (line 121) | type FakeStreamInferToolInput struct
type FakeStreamInferToolOutput (line 125) | type FakeStreamInferToolOutput struct
function FakeWithToolOption (line 129) | func FakeWithToolOption(s string) tool.Option {
function fakeStreamFunc (line 135) | func fakeStreamFunc(ctx context.Context, input FakeStreamInferToolInput,...
function TestInferStreamTool (line 148) | func TestInferStreamTool(t *testing.T) {
type EnhancedStreamInput (line 171) | type EnhancedStreamInput struct
function TestNewEnhancedStreamTool (line 175) | func TestNewEnhancedStreamTool(t *testing.T) {
type FakeEnhancedStreamOption (line 238) | type FakeEnhancedStreamOption struct
function FakeWithEnhancedStreamOption (line 242) | func FakeWithEnhancedStreamOption(prefix string) tool.Option {
function fakeEnhancedStreamFunc (line 248) | func fakeEnhancedStreamFunc(ctx context.Context, input EnhancedStreamInp...
function fakeOptionableEnhancedStreamFunc (line 258) | func fakeOptionableEnhancedStreamFunc(ctx context.Context, input Enhance...
function TestInferEnhancedStreamTool (line 273) | func TestInferEnhancedStreamTool(t *testing.T) {
function TestInferOptionableEnhancedStreamTool (line 295) | func TestInferOptionableEnhancedStreamTool(t *testing.T) {
FILE: components/types.go
type Typer (line 29) | type Typer interface
function GetType (line 34) | func GetType(component any) (string, bool) {
type Checker (line 50) | type Checker interface
function IsCallbacksEnabled (line 55) | func IsCallbacksEnabled(i any) bool {
type Component (line 64) | type Component
constant ComponentOfPrompt (line 68) | ComponentOfPrompt Component = "ChatTemplate"
constant ComponentOfChatModel (line 70) | ComponentOfChatModel Component = "ChatModel"
constant ComponentOfEmbedding (line 72) | ComponentOfEmbedding Component = "Embedding"
constant ComponentOfIndexer (line 74) | ComponentOfIndexer Component = "Indexer"
constant ComponentOfRetriever (line 76) | ComponentOfRetriever Component = "Retriever"
constant ComponentOfLoader (line 78) | ComponentOfLoader Component = "Loader"
constant ComponentOfTransformer (line 80) | ComponentOfTransformer Component = "DocumentTransformer"
constant ComponentOfTool (line 82) | ComponentOfTool Component = "Tool"
FILE: compose/branch.go
type GraphBranchCondition (line 29) | type GraphBranchCondition
type StreamGraphBranchCondition (line 32) | type StreamGraphBranchCondition
type GraphMultiBranchCondition (line 35) | type GraphMultiBranchCondition
type StreamGraphMultiBranchCondition (line 38) | type StreamGraphMultiBranchCondition
type GraphBranch (line 42) | type GraphBranch struct
method GetEndNode (line 53) | func (gb *GraphBranch) GetEndNode() map[string]bool {
function newGraphBranch (line 57) | func newGraphBranch[T any](r *runnablePacker[T, []string, any], endNodes...
function NewGraphMultiBranch (line 89) | func NewGraphMultiBranch[T any](condition GraphMultiBranchCondition[T], ...
function NewStreamGraphMultiBranch (line 111) | func NewStreamGraphMultiBranch[T any](condition StreamGraphMultiBranchCo...
function NewGraphBranch (line 145) | func NewGraphBranch[T any](condition GraphBranchCondition[T], endNodes m...
function NewStreamGraphBranch (line 168) | func NewStreamGraphBranch[T any](condition StreamGraphBranchCondition[T]...
FILE: compose/branch_test.go
function TestMultiBranch (line 29) | func TestMultiBranch(t *testing.T) {
function TestStreamMultiBranch (line 81) | func TestStreamMultiBranch(t *testing.T) {
FILE: compose/chain.go
function NewChain (line 37) | func NewChain[I, O any](opts ...NewGraphOption) *Chain[I, O] {
type Chain (line 72) | type Chain struct
method compile (line 88) | func (c *Chain[I, O]) compile(ctx context.Context, option *graphCompileO...
method addEndIfNeeded (line 98) | func (c *Chain[I, O]) addEndIfNeeded() error {
method getGenericHelper (line 123) | func (c *Chain[I, O]) getGenericHelper() *genericHelper {
method inputType (line 129) | func (c *Chain[I, O]) inputType() reflect.Type {
method outputType (line 135) | func (c *Chain[I, O]) outputType() reflect.Type {
method component (line 141) | func (c *Chain[I, O]) component() component {
method Compile (line 157) | func (c *Chain[I, O]) Compile(ctx context.Context, opts ...GraphCompileO...
method AppendChatModel (line 171) | func (c *Chain[I, O]) AppendChatModel(node model.BaseChatModel, opts ......
method AppendChatTemplate (line 186) | func (c *Chain[I, O]) AppendChatTemplate(node prompt.ChatTemplate, opts ...
method AppendToolsNode (line 200) | func (c *Chain[I, O]) AppendToolsNode(node *ToolsNode, opts ...GraphAddN...
method AppendDocumentTransformer (line 212) | func (c *Chain[I, O]) AppendDocumentTransformer(node document.Transforme...
method AppendLambda (line 228) | func (c *Chain[I, O]) AppendLambda(node *Lambda, opts ...GraphAddNodeOpt...
method AppendEmbedding (line 240) | func (c *Chain[I, O]) AppendEmbedding(node embedding.Embedder, opts ...G...
method AppendRetriever (line 259) | func (c *Chain[I, O]) AppendRetriever(node retriever.Retriever, opts ......
method AppendLoader (line 271) | func (c *Chain[I, O]) AppendLoader(node document.Loader, opts ...GraphAd...
method AppendIndexer (line 289) | func (c *Chain[I, O]) AppendIndexer(node indexer.Indexer, opts ...GraphA...
method AppendBranch (line 304) | func (c *Chain[I, O]) AppendBranch(b *ChainBranch) *Chain[I, O] {
method AppendParallel (line 421) | func (c *Chain[I, O]) AppendParallel(p *Parallel) *Chain[I, O] {
method AppendGraph (line 484) | func (c *Chain[I, O]) AppendGraph(node AnyGraph, opts ...GraphAddNodeOpt...
method AppendPassthrough (line 495) | func (c *Chain[I, O]) AppendPassthrough(opts ...GraphAddNodeOpt) *Chain[...
method nextNodeKey (line 506) | func (c *Chain[I, O]) nextNodeKey() string {
method reportError (line 514) | func (c *Chain[I, O]) reportError(err error) {
method addNode (line 522) | func (c *Chain[I, O]) addNode(node *graphNode, options *graphAddNodeOpts) {
FILE: compose/chain_branch.go
type nodeOptionsPair (line 33) | type nodeOptionsPair
type ChainBranch (line 38) | type ChainBranch struct
method AddChatModel (line 144) | func (cb *ChainBranch) AddChatModel(key string, node model.BaseChatMod...
method AddChatTemplate (line 165) | func (cb *ChainBranch) AddChatTemplate(key string, node prompt.ChatTem...
method AddToolsNode (line 178) | func (cb *ChainBranch) AddToolsNode(key string, node *ToolsNode, opts ...
method AddLambda (line 192) | func (cb *ChainBranch) AddLambda(key string, node *Lambda, opts ...Gra...
method AddEmbedding (line 205) | func (cb *ChainBranch) AddEmbedding(key string, node embedding.Embedde...
method AddRetriever (line 218) | func (cb *ChainBranch) AddRetriever(key string, node retriever.Retriev...
method AddLoader (line 232) | func (cb *ChainBranch) AddLoader(key string, node document.Loader, opt...
method AddIndexer (line 245) | func (cb *ChainBranch) AddIndexer(key string, node indexer.Indexer, op...
method AddDocumentTransformer (line 256) | func (cb *ChainBranch) AddDocumentTransformer(key string, node documen...
method AddGraph (line 267) | func (cb *ChainBranch) AddGraph(key string, node AnyGraph, opts ...Gra...
method AddPassthrough (line 276) | func (cb *ChainBranch) AddPassthrough(key string, opts ...GraphAddNode...
method addNode (line 281) | func (cb *ChainBranch) addNode(key string, node *graphNode, options *g...
function NewChainMultiBranch (line 46) | func NewChainMultiBranch[T any](cond GraphMultiBranchCondition[T]) *Chai...
function NewStreamChainMultiBranch (line 67) | func NewStreamChainMultiBranch[T any](cond StreamGraphMultiBranchConditi...
function NewChainBranch (line 100) | func NewChainBranch[T any](cond GraphBranchCondition[T]) *ChainBranch {
function NewStreamChainBranch (line 123) | func NewStreamChainBranch[T any](cond StreamGraphBranchCondition[T]) *Ch...
FILE: compose/chain_branch_test.go
function TestChainBranch (line 35) | func TestChainBranch(t *testing.T) {
function TestChainMultiBranch (line 276) | func TestChainMultiBranch(t *testing.T) {
function TestStreamChainMultiBranch (line 313) | func TestStreamChainMultiBranch(t *testing.T) {
FILE: compose/chain_parallel.go
function NewParallel (line 32) | func NewParallel() *Parallel {
type Parallel (line 49) | type Parallel struct
method AddChatModel (line 68) | func (p *Parallel) AddChatModel(outputKey string, node model.BaseChatM...
method AddChatTemplate (line 82) | func (p *Parallel) AddChatTemplate(outputKey string, node prompt.ChatT...
method AddToolsNode (line 95) | func (p *Parallel) AddToolsNode(outputKey string, node *ToolsNode, opt...
method AddLambda (line 108) | func (p *Parallel) AddLambda(outputKey string, node *Lambda, opts ...G...
method AddEmbedding (line 121) | func (p *Parallel) AddEmbedding(outputKey string, node embedding.Embed...
method AddRetriever (line 132) | func (p *Parallel) AddRetriever(outputKey string, node retriever.Retri...
method AddLoader (line 143) | func (p *Parallel) AddLoader(outputKey string, node document.Loader, o...
method AddIndexer (line 156) | func (p *Parallel) AddIndexer(outputKey string, node indexer.Indexer, ...
method AddDocumentTransformer (line 167) | func (p *Parallel) AddDocumentTransformer(outputKey string, node docum...
method AddGraph (line 179) | func (p *Parallel) AddGraph(outputKey string, node AnyGraph, opts ...G...
method AddPassthrough (line 188) | func (p *Parallel) AddPassthrough(outputKey string, opts ...GraphAddNo...
method addNode (line 193) | func (p *Parallel) addNode(outputKey string, node *graphNode, options ...
FILE: compose/chain_test.go
function TestChain (line 37) | func TestChain(t *testing.T) {
function TestChainWithException (line 112) | func TestChainWithException(t *testing.T) {
function TestEmptyList (line 219) | func TestEmptyList(t *testing.T) {
function TestChainList (line 250) | func TestChainList(t *testing.T) {
function TestChainSingleNode (line 303) | func TestChainSingleNode(t *testing.T) {
function TestParallelModels (line 340) | func TestParallelModels(t *testing.T) {
function TestChainMultiNodes (line 376) | func TestChainMultiNodes(t *testing.T) {
function TestParallelMultiNodes (line 551) | func TestParallelMultiNodes(t *testing.T) {
type FakeLambdaOptions (line 590) | type FakeLambdaOptions struct
type FakeLambdaOption (line 594) | type FakeLambdaOption
function FakeWithLambdaInfo (line 596) | func FakeWithLambdaInfo(info string) FakeLambdaOption {
function TestChainWithNodeKey (line 602) | func TestChainWithNodeKey(t *testing.T) {
FILE: compose/checkpoint.go
function init (line 28) | func init() {
function RegisterSerializableType (line 47) | func RegisterSerializableType[T any](name string) (err error) {
type Serializer (line 53) | type Serializer interface
function WithCheckPointStore (line 59) | func WithCheckPointStore(store CheckPointStore) GraphCompileOption {
function WithSerializer (line 66) | func WithSerializer(serializer Serializer) GraphCompileOption {
function WithCheckPointID (line 73) | func WithCheckPointID(checkPointID string) Option {
function WithWriteToCheckPointID (line 83) | func WithWriteToCheckPointID(checkPointID string) Option {
function WithForceNewRun (line 90) | func WithForceNewRun() Option {
type StateModifier (line 97) | type StateModifier
function WithStateModifier (line 100) | func WithStateModifier(sm StateModifier) Option {
type checkpoint (line 106) | type checkpoint struct
type stateModifierKey (line 119) | type stateModifierKey struct
type checkPointKey (line 120) | type checkPointKey struct
function getStateModifier (line 122) | func getStateModifier(ctx context.Context) StateModifier {
function setStateModifier (line 129) | func setStateModifier(ctx context.Context, modifier StateModifier) conte...
function getCheckPointFromStore (line 133) | func getCheckPointFromStore(ctx context.Context, id string, cpr *checkPo...
function setCheckPointToCtx (line 145) | func setCheckPointToCtx(ctx context.Context, cp *checkpoint) context.Con...
function getCheckPointFromCtx (line 150) | func getCheckPointFromCtx(ctx context.Context) *checkpoint {
function forwardCheckPoint (line 157) | func forwardCheckPoint(ctx context.Context, nodeKey string) context.Cont...
function newCheckPointer (line 170) | func newCheckPointer(
type checkPointer (line 185) | type checkPointer struct
method get (line 191) | func (c *checkPointer) get(ctx context.Context, id string) (*checkpoin...
method set (line 206) | func (c *checkPointer) set(ctx context.Context, id string, cp *checkpo...
method convertCheckPoint (line 272) | func (c *checkPointer) convertCheckPoint(cp *checkpoint, isStream bool...
method restoreCheckPoint (line 291) | func (c *checkPointer) restoreCheckPoint(cp *checkpoint, isStream bool...
function MigrateCheckpointState (line 231) | func MigrateCheckpointState(data []byte, serializer Serializer, migrate ...
function migrateCheckpoint (line 247) | func migrateCheckpoint(cp *checkpoint, migrate func(state any) (any, boo...
function newStreamConverter (line 309) | func newStreamConverter(inputPairs, outputPairs map[string]streamConvert...
type streamConverter (line 316) | type streamConverter struct
method convertInputs (line 320) | func (s *streamConverter) convertInputs(isStream bool, values map[stri...
method restoreInputs (line 324) | func (s *streamConverter) restoreInputs(isStream bool, values map[stri...
method convertOutputs (line 328) | func (s *streamConverter) convertOutputs(isStream bool, values map[str...
method restoreOutputs (line 332) | func (s *streamConverter) restoreOutputs(isStream bool, values map[str...
function convert (line 336) | func convert(values map[string]any, convPairs map[string]streamConvertPa...
function restore (line 358) | func restore(values map[string]any, convPairs map[string]streamConvertPa...
FILE: compose/checkpoint_migrate_test.go
type stubSerializer (line 26) | type stubSerializer struct
method Marshal (line 31) | func (s stubSerializer) Marshal(v any) ([]byte, error) {
method Unmarshal (line 35) | func (s stubSerializer) Unmarshal(data []byte, v any) error {
function TestMigrateCheckpointState_UnmarshalError (line 39) | func TestMigrateCheckpointState_UnmarshalError(t *testing.T) {
function TestMigrateCheckpointState_NoChangeReturnsOriginalBytes (line 51) | func TestMigrateCheckpointState_NoChangeReturnsOriginalBytes(t *testing....
function TestMigrateCheckpointState_ChangeTriggersMarshal (line 70) | func TestMigrateCheckpointState_ChangeTriggersMarshal(t *testing.T) {
function TestMigrateCheckpointState_MigrateErrorStops (line 92) | func TestMigrateCheckpointState_MigrateErrorStops(t *testing.T) {
FILE: compose/checkpoint_test.go
type inMemoryStore (line 37) | type inMemoryStore struct
method Get (line 41) | func (i *inMemoryStore) Get(_ context.Context, checkPointID string) ([...
method Set (line 46) | func (i *inMemoryStore) Set(_ context.Context, checkPointID string, ch...
function newInMemoryStore (line 51) | func newInMemoryStore() *inMemoryStore {
type testStruct (line 57) | type testStruct struct
function init (line 61) | func init() {
function TestSimpleCheckPoint (line 65) | func TestSimpleCheckPoint(t *testing.T) {
function TestCustomStructInAn2y (line 157) | func TestCustomStructInAn2y(t *testing.T) {
function TestSubGraph (line 248) | func TestSubGraph(t *testing.T) {
type testGraphCallback (line 389) | type testGraphCallback struct
method OnStart (line 397) | func (t *testGraphCallback) OnStart(ctx context.Context, info *callbac...
method OnEnd (line 404) | func (t *testGraphCallback) OnEnd(ctx context.Context, info *callbacks...
method OnError (line 411) | func (t *testGraphCallback) OnError(ctx context.Context, info *callbac...
method OnStartWithStreamInput (line 418) | func (t *testGraphCallback) OnStartWithStreamInput(ctx context.Context...
method OnEndWithStreamOutput (line 426) | func (t *testGraphCallback) OnEndWithStreamOutput(ctx context.Context,...
function TestNestedSubGraph (line 434) | func TestNestedSubGraph(t *testing.T) {
function TestDAGInterrupt (line 1125) | func TestDAGInterrupt(t *testing.T) {
function TestRerunNodeInterrupt (line 1165) | func TestRerunNodeInterrupt(t *testing.T) {
type myInterface (line 1221) | type myInterface interface
function TestInterfaceResume (line 1225) | func TestInterfaceResume(t *testing.T) {
function TestEarlyFailCallback (line 1251) | func TestEarlyFailCallback(t *testing.T) {
function TestGraphStartInterrupt (line 1269) | func TestGraphStartInterrupt(t *testing.T) {
function TestWithForceNewRun (line 1299) | func TestWithForceNewRun(t *testing.T) {
type failStore (line 1314) | type failStore struct
method Get (line 1318) | func (f *failStore) Get(_ context.Context, _ string) ([]byte, bool, er...
method Set (line 1323) | func (f *failStore) Set(_ context.Context, _ string, _ []byte) error {
function TestPreHandlerInterrupt (line 1328) | func TestPreHandlerInterrupt(t *testing.T) {
function TestCancelInterrupt (line 1358) | func TestCancelInterrupt(t *testing.T) {
function TestPersistRerunInputNonStream (line 1539) | func TestPersistRerunInputNonStream(t *testing.T) {
function TestPersistRerunInputStream (line 1600) | func TestPersistRerunInputStream(t *testing.T) {
type testPersistRerunInputState (line 1692) | type testPersistRerunInputState struct
function TestPersistRerunInputWithPreHandler (line 1696) | func TestPersistRerunInputWithPreHandler(t *testing.T) {
function TestPersistRerunInputBackwardCompatibility (line 1765) | func TestPersistRerunInputBackwardCompatibility(t *testing.T) {
function TestPersistRerunInputSubGraph (line 1812) | func TestPersistRerunInputSubGraph(t *testing.T) {
type longRunningToolInput (line 1891) | type longRunningToolInput struct
function TestToolsNodeWithExternalGraphInterrupt (line 1895) | func TestToolsNodeWithExternalGraphInterrupt(t *testing.T) {
type checkpointTestTool
Condensed preview — 312 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,241K chars).
[
{
"path": ".github/.codedev.yml",
"chars": 1115,
"preview": "coverage:\n status:\n project: #add everything under here, more options at https://docs.codecov.com/docs/commit-status"
},
{
"path": ".github/.commit-rules.json",
"chars": 577,
"preview": "{\n \"allowedTypes\": [\n \"feat\",\n \"fix\",\n \"docs\",\n \"style\",\n \"refactor\",\n \"perf\",\n \"test\",\n \"build"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 658,
"preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Describe the b"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 599,
"preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your fea"
},
{
"path": ".github/PULL_REQUEST_TEMPLATE.md",
"chars": 2047,
"preview": "#### What type of PR is this?\n<!--\nAdd one of the following kinds:\n\nbuild: Changes that affect the build system or exter"
},
{
"path": ".github/workflows/pr-check.yml",
"chars": 5162,
"preview": "name: Pull Request Check\n\non: [ pull_request ]\n\njobs:\n compliant:\n runs-on: ubuntu-latest\n steps:\n - uses: a"
},
{
"path": ".github/workflows/tag-notification.yml",
"chars": 3887,
"preview": "name: Tag Notification\n\non:\n push:\n tags:\n - 'v*'\n\njobs:\n notify:\n runs-on: ubuntu-latest\n steps:\n "
},
{
"path": ".github/workflows/tests.yml",
"chars": 8726,
"preview": "name: Eino Tests\n\non:\n pull_request:\n push:\n branches:\n - main\n\nenv:\n DEFAULT_GO_VERSION: \"1.18\"\n\njobs:\n uni"
},
{
"path": ".gitignore",
"chars": 746,
"preview": "# Binaries for programs and plugins\n*.exe\n*.exe~\n*.dll\n*.so\n*.dylib\n\n# Test binary, built with `go test -c`\n*.test\n\n# Ou"
},
{
"path": ".golangci.yaml",
"chars": 4479,
"preview": "# output configuration options\nversion: \"2\"\n# All available settings of specific linters.\n# Refer to https://golangci-li"
},
{
"path": ".licenserc.yaml",
"chars": 829,
"preview": "header:\n license:\n spdx-id: Apache-2.0\n copyright-owner: CloudWeGo Authors\n\n template: |\n /*\n * Copyright"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 5222,
"preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participa"
},
{
"path": "CONTRIBUTING.md",
"chars": 3058,
"preview": "# How to Contribute\n\n## Your First Pull Request\nWe use GitHub for our codebase. You can start by reading [How To Pull Re"
},
{
"path": "LICENSE-APACHE",
"chars": 10174,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 8424,
"preview": "# Eino\n\n\n[\n[;\n * you may "
},
{
"path": "adk/agent_tool_test.go",
"chars": 36767,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/call_option.go",
"chars": 5327,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/call_option_test.go",
"chars": 1094,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/callback.go",
"chars": 3906,
"preview": "/*\n * Copyright 2026 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/callback_integration_test.go",
"chars": 30690,
"preview": "/*\n * Copyright 2026 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/callback_test.go",
"chars": 6431,
"preview": "/*\n * Copyright 2026 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/chatmodel.go",
"chars": 37434,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/chatmodel_retry_test.go",
"chars": 30559,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/chatmodel_test.go",
"chars": 47847,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/config.go",
"chars": 1186,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/deterministic_transfer.go",
"chars": 8364,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/deterministic_transfer_test.go",
"chars": 22299,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/filesystem/backend.go",
"chars": 7793,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/filesystem/backend_inmemory.go",
"chars": 19715,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/filesystem/backend_inmemory_test.go",
"chars": 59699,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/flow.go",
"chars": 16755,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/flow_test.go",
"chars": 9971,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/handler.go",
"chars": 16583,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/handler_test.go",
"chars": 57523,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/instruction.go",
"chars": 1890,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/interface.go",
"chars": 7590,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/internal/config.go",
"chars": 2091,
"preview": "/*\n * Copyright 2026 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/interrupt.go",
"chars": 12632,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/interrupt_test.go",
"chars": 60167,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/dynamictool/toolsearch/toolsearch.go",
"chars": 7451,
"preview": "/*\n * Copyright 2026 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/dynamictool/toolsearch/toolsearch_test.go",
"chars": 14025,
"preview": "/*\n * Copyright 2026 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/filesystem/backend.go",
"chars": 1104,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/filesystem/filesystem.go",
"chars": 35341,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/filesystem/filesystem_test.go",
"chars": 62609,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/filesystem/large_tool_result.go",
"chars": 4414,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/filesystem/large_tool_result_test.go",
"chars": 15698,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/filesystem/prompt.go",
"chars": 12506,
"preview": "/*\n * Copyright (c) 2025 Harrison Chase\n * Copyright (c) 2025 CloudWeGo Authors\n * SPDX-License-Identifier: MIT\n *\n * Li"
},
{
"path": "adk/middlewares/patchtoolcalls/patchtoolcalls.go",
"chars": 4049,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/patchtoolcalls/patchtoolcalls_test.go",
"chars": 3030,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/plantask/backend_test.go",
"chars": 1902,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/plantask/plantask.go",
"chars": 2065,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/plantask/plantask_test.go",
"chars": 3692,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/plantask/task.go",
"chars": 3372,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/plantask/task_create.go",
"chars": 8516,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/plantask/task_create_test.go",
"chars": 3144,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/plantask/task_get.go",
"chars": 4799,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/plantask/task_get_test.go",
"chars": 2368,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/plantask/task_list.go",
"chars": 5440,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/plantask/task_list_test.go",
"chars": 2001,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/plantask/task_update.go",
"chars": 16809,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/plantask/task_update_test.go",
"chars": 24645,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/reduction/consts.go",
"chars": 2195,
"preview": "/*\n * Copyright 2026 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/reduction/internal/clear_tool_result.go",
"chars": 5707,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/reduction/internal/clear_tool_result_test.go",
"chars": 10940,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/reduction/internal/large_tool_result.go",
"chars": 5773,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/reduction/internal/large_tool_result_test.go",
"chars": 14540,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/reduction/internal/tool_result.go",
"chars": 5193,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/reduction/legacy.go",
"chars": 3421,
"preview": "/*\n * Copyright 2026 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/reduction/reduction.go",
"chars": 22306,
"preview": "/*\n * Copyright 2026 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/reduction/reduction_test.go",
"chars": 28445,
"preview": "/*\n * Copyright 2026 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/skill/filesystem_backend.go",
"chars": 5042,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/skill/filesystem_backend_test.go",
"chars": 13419,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/skill/prompt.go",
"chars": 5103,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/skill/skill.go",
"chars": 15039,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/skill/skill_test.go",
"chars": 16563,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/summarization/consts.go",
"chars": 951,
"preview": "/*\n * Copyright 2026 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/summarization/customized_action.go",
"chars": 1418,
"preview": "/*\n * Copyright 2026 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/summarization/prompt.go",
"chars": 10468,
"preview": "/*\n * Copyright 2026 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/summarization/summarization.go",
"chars": 16642,
"preview": "/*\n * Copyright 2026 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/middlewares/summarization/summarization_test.go",
"chars": 24938,
"preview": "/*\n * Copyright 2026 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/prebuilt/deep/checkpoint_compat_resume_test.go",
"chars": 5599,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/prebuilt/deep/deep.go",
"chars": 7744,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/prebuilt/deep/deep_test.go",
"chars": 17348,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/prebuilt/deep/prompt.go",
"chars": 33641,
"preview": "/*\n * Copyright (c) 2025 Harrison Chase\n * Copyright (c) 2025 CloudWeGo Authors\n * SPDX-License-Identifier: MIT\n *\n * Li"
},
{
"path": "adk/prebuilt/deep/task_tool.go",
"chars": 5342,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/prebuilt/deep/task_tool_test.go",
"chars": 1960,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/prebuilt/deep/testdata/_gen/generate_test.go",
"chars": 4896,
"preview": "//go:build gencheckpoints\n\n/*\n * Copyright 2026 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "adk/prebuilt/deep/types.go",
"chars": 1734,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/prebuilt/integration_test.go",
"chars": 14196,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/prebuilt/planexecute/plan_execute.go",
"chars": 27777,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/prebuilt/planexecute/plan_execute_test.go",
"chars": 31128,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/prebuilt/planexecute/utils.go",
"chars": 1445,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/prebuilt/supervisor/supervisor.go",
"chars": 4501,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/prebuilt/supervisor/supervisor_test.go",
"chars": 38385,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/react.go",
"chars": 13464,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/react_test.go",
"chars": 16636,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/retry_chatmodel.go",
"chars": 8427,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/runctx.go",
"chars": 12068,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/runctx_test.go",
"chars": 13030,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/runner.go",
"chars": 8666,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/runner_test.go",
"chars": 7766,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/utils.go",
"chars": 6809,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/utils_test.go",
"chars": 9685,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/workflow.go",
"chars": 17319,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/workflow_test.go",
"chars": 40336,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/wrappers.go",
"chars": 23561,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "adk/wrappers_test.go",
"chars": 39273,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "callbacks/aspect_inject.go",
"chars": 6972,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "callbacks/aspect_inject_test.go",
"chars": 7846,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "callbacks/doc.go",
"chars": 5304,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "callbacks/handler_builder.go",
"chars": 6079,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "callbacks/interface.go",
"chars": 7096,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "callbacks/interface_test.go",
"chars": 1717,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/document/callback_extra_loader.go",
"chars": 1903,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/document/callback_extra_transformer.go",
"chars": 1947,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/document/doc.go",
"chars": 1725,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/document/interface.go",
"chars": 2136,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/document/option.go",
"chars": 5464,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/document/option_test.go",
"chars": 2366,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/document/parser/doc.go",
"chars": 1923,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/document/parser/ext_parser.go",
"chars": 3029,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/document/parser/interface.go",
"chars": 1191,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/document/parser/option.go",
"chars": 3342,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/document/parser/option_test.go",
"chars": 1442,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/document/parser/parser_test.go",
"chars": 2497,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/document/parser/testdata/test.md",
"chars": 19,
"preview": "# Title\nhello world"
},
{
"path": "components/document/parser/text_parser.go",
"chars": 1578,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/embedding/callback_extra.go",
"chars": 2628,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/embedding/callback_extra_test.go",
"chars": 1022,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/embedding/doc.go",
"chars": 1719,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/embedding/interface.go",
"chars": 1539,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/embedding/option.go",
"chars": 2772,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/embedding/option_test.go",
"chars": 908,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/indexer/callback_extra.go",
"chars": 1786,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/indexer/callback_extra_test.go",
"chars": 1062,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/indexer/doc.go",
"chars": 1504,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/indexer/interface.go",
"chars": 1495,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/indexer/option.go",
"chars": 2748,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/indexer/option_test.go",
"chars": 1137,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/model/callback_extra.go",
"chars": 4311,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/model/callback_extra_test.go",
"chars": 1064,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/model/doc.go",
"chars": 2389,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/model/interface.go",
"chars": 3723,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/model/option.go",
"chars": 5955,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/model/option_test.go",
"chars": 2931,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/prompt/callback_extra.go",
"chars": 1947,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/prompt/callback_extra_test.go",
"chars": 1065,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/prompt/chat_template.go",
"chars": 2692,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/prompt/chat_template_test.go",
"chars": 5009,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/prompt/doc.go",
"chars": 2169,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/prompt/interface.go",
"chars": 1609,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/prompt/option.go",
"chars": 1597,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/prompt/option_test.go",
"chars": 1258,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/retriever/callback_extra.go",
"chars": 2091,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/retriever/callback_extra_test.go",
"chars": 1066,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/retriever/doc.go",
"chars": 1724,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/retriever/interface.go",
"chars": 1902,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/retriever/option.go",
"chars": 4033,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/retriever/option_test.go",
"chars": 1525,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/tool/callback_extra.go",
"chars": 2022,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/tool/callback_extra_test.go",
"chars": 1129,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/tool/doc.go",
"chars": 2451,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/tool/interface.go",
"chars": 3141,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/tool/interrupt.go",
"chars": 6192,
"preview": "/*\n * Copyright 2026 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/tool/interrupt_test.go",
"chars": 3925,
"preview": "/*\n * Copyright 2026 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/tool/option.go",
"chars": 2591,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/tool/option_test.go",
"chars": 1446,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/tool/utils/common.go",
"chars": 796,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/tool/utils/common_test.go",
"chars": 4507,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/tool/utils/create_options.go",
"chars": 2977,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/tool/utils/doc.go",
"chars": 2373,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/tool/utils/error_handler.go",
"chars": 5002,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/tool/utils/error_handler_test.go",
"chars": 2506,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/tool/utils/invokable_func.go",
"chars": 10214,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/tool/utils/invokable_func_test.go",
"chars": 12515,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/tool/utils/streamable_func.go",
"chars": 8395,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/tool/utils/streamable_func_test.go",
"chars": 8584,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "components/types.go",
"chars": 3088,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "compose/branch.go",
"chars": 6435,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "compose/branch_test.go",
"chars": 3613,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "compose/chain.go",
"chars": 16545,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "compose/chain_branch.go",
"chars": 10521,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "compose/chain_branch_test.go",
"chars": 9761,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "compose/chain_parallel.go",
"chars": 7399,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "compose/chain_test.go",
"chars": 28702,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "compose/checkpoint.go",
"chars": 10773,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "compose/checkpoint_migrate_test.go",
"chars": 3060,
"preview": "/*\n * Copyright 2026 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "compose/checkpoint_test.go",
"chars": 55218,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "compose/component_to_graph_node.go",
"chars": 4403,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "compose/dag.go",
"chars": 4675,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "compose/dag_test.go",
"chars": 4990,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "compose/doc.go",
"chars": 757,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "compose/error.go",
"chars": 3258,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "compose/error_test.go",
"chars": 3935,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "compose/field_mapping.go",
"chars": 22366,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "compose/generic_graph.go",
"chars": 4933,
"preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
},
{
"path": "compose/generic_helper.go",
"chars": 8649,
"preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
}
]
// ... and 112 more files (download for full content)
About this extraction
This page contains the full source code of the cloudwego/eino GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 312 files (2.8 MB), approximately 752.8k tokens, and a symbol index with 3577 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.