Skip to content

[Feature] Support tool parameter injection#854

Open
GreatEugenius wants to merge 5 commits into
apache:mainfrom
GreatEugenius:codex/tool-parameter-injection
Open

[Feature] Support tool parameter injection#854
GreatEugenius wants to merge 5 commits into
apache:mainfrom
GreatEugenius:codex/tool-parameter-injection

Conversation

@GreatEugenius

@GreatEugenius GreatEugenius commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

Linked issue: #853

Purpose of change

Support declarative tool parameter injection for function tools.

This change lets framework-owned arguments, such as tenant id or request context, be injected at tool execution time without exposing them to the model-facing tool schema. The injection source is declared together with the hidden tool parameter, and values are resolved by the built-in tool_call_action immediately before invoking the tool.

Main changes:

  • Add Python API support:

    • @tool(injected_args={"tenant_id": InjectedArg.from_config("tenant_id")})
    • explicit injection sources for config, sensory memory, and short-term memory
  • Add Java API support:

    • @ToolParam(injected = true, source = ToolParameterSource.CONFIG, key = "tenant_id")
    • explicit injection sources for config, sensory memory, and short-term memory
  • Add YAML API support:

    • tools[].injected_args as an object mapping parameter names to injection specs
  • Inject parameters in the built-in tool_call_action, after reading model arguments and before invoking the tool.

  • Preserve injected argument metadata in the plan/runtime representation while filtering injected parameters from model-facing tool metadata.

  • Keep cross-language tool calls supported by resolving injection before dispatching to the target tool implementation.

Tests

UT & E2E Test

API

Yes

Documentation

  • doc-needed
  • doc-not-needed
  • doc-included

@GreatEugenius GreatEugenius marked this pull request as draft June 18, 2026 09:17
@github-actions github-actions Bot added doc-included Your PR already contains the necessary documentation updates. fixVersion/0.3.0 The feature or bug should be implemented/fixed in the 0.3.0 version. priority/major Default priority of the PR or issue. labels Jun 18, 2026
@GreatEugenius GreatEugenius force-pushed the codex/tool-parameter-injection branch from b2f9753 to 0a18129 Compare June 18, 2026 09:28
@GreatEugenius GreatEugenius added fixVersion/0.4.0 and removed fixVersion/0.3.0 The feature or bug should be implemented/fixed in the 0.3.0 version. labels Jun 18, 2026
@GreatEugenius GreatEugenius force-pushed the codex/tool-parameter-injection branch from 0a18129 to 17b0f9a Compare June 22, 2026 01:59
@GreatEugenius GreatEugenius marked this pull request as ready for review June 22, 2026 02:02
@GreatEugenius GreatEugenius force-pushed the codex/tool-parameter-injection branch 2 times, most recently from 53f537c to 28ab27d Compare June 22, 2026 03:33
@GreatEugenius

Copy link
Copy Markdown
Collaborator Author

Hi, @Sxnan and @wenjin272. Could you please review this PR? Thank you!

@GreatEugenius GreatEugenius requested review from Sxnan and wenjin272 and removed request for wenjin272 June 22, 2026 03:37
@Sxnan

Sxnan commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Thanks for the work — the schema-hiding part (injected_args / @ToolParam(injected=true)) is clean and useful.

A step back on the API shape before line details: #853 asks for one narrow thing — inject a model-hidden, framework-owned arg at execution time. This PR does it via a general before/after hook mechanism (hook slots on Agent, plan fields, serializers, YAML keys, new ToolCallContext/ToolCallResult). That's a lot of machinery, and the generality makes injection harder, not easier:

  • Two decoupled declarations (injected_args + a separate global hook matching on tool_name), no plan-time link — forget/typo the hook → silent crash.
  • One hook per agent → a manual if tool_name == ... dispatch table as tools grow.
  • after_tool_call (result rewriting) is unrelated to injection — a separate capability bundled in.

Suggestion:

  1. Keep injected_args for schema hiding.
  2. Make the value source declarative and co-located with the param, e.g. @tool(inject={"tenant_id": lambda ctx: ctx.tenant_id}), resolved right before the call — drops the decoupling, the dispatch table, and the "declared but never filled" gap.
  3. Defer before_tool_call / after_tool_call to a separate issue if a real cross-cutting need shows up — and there, consider the existing event/action model over a parallel mechanism.

If there's a concrete need behind the general hooks that isn't in #853, worth surfacing here.

@GreatEugenius GreatEugenius force-pushed the codex/tool-parameter-injection branch 3 times, most recently from d3295ca to d71b52f Compare June 23, 2026 11:54
@GreatEugenius

Copy link
Copy Markdown
Collaborator Author

Thanks for the work — the schema-hiding part (injected_args / @ToolParam(injected=true)) is clean and useful.

A step back on the API shape before line details: #853 asks for one narrow thing — inject a model-hidden, framework-owned arg at execution time. This PR does it via a general before/after hook mechanism (hook slots on Agent, plan fields, serializers, YAML keys, new ToolCallContext/ToolCallResult). That's a lot of machinery, and the generality makes injection harder, not easier:

  • Two decoupled declarations (injected_args + a separate global hook matching on tool_name), no plan-time link — forget/typo the hook → silent crash.
  • One hook per agent → a manual if tool_name == ... dispatch table as tools grow.
  • after_tool_call (result rewriting) is unrelated to injection — a separate capability bundled in.

Suggestion:

  1. Keep injected_args for schema hiding.
  2. Make the value source declarative and co-located with the param, e.g. @tool(inject={"tenant_id": lambda ctx: ctx.tenant_id}), resolved right before the call — drops the decoupling, the dispatch table, and the "declared but never filled" gap.
  3. Defer before_tool_call / after_tool_call to a separate issue if a real cross-cutting need shows up — and there, consider the existing event/action model over a parallel mechanism.

If there's a concrete need behind the general hooks that isn't in #853, worth surfacing here.

Thanks, agreed with the direction here. Stepping back, #853 should stay focused on model-hidden framework-owned argument injection, and the generic before/after hook mechanism was too broad for that scope.

I’ve updated the PR accordingly:

  • Removed the before/after tool-call hook API and the related Agent/Plan/YAML/serializer fields.
  • Kept injected_args / @ToolParam(injected = true) for schema hiding.
  • Made the injection source declarative and co-located with the parameter instead of relying on a separate global hook. The current API supports explicit sources such as config, sensory memory, and short-term memory.
  • Kept resolution in the built-in tool_call_action, right before invoking the tool, so the injected value remains hidden from the model and is not written back to the tool request.

So the PR now covers only the narrow injection use case from #853. Any general before_tool_call / after_tool_call capability can be discussed separately if a concrete cross-cutting need shows up.

@github-actions github-actions Bot added doc-included Your PR already contains the necessary documentation updates. and removed doc-included Your PR already contains the necessary documentation updates. labels Jun 23, 2026
@GreatEugenius GreatEugenius force-pushed the codex/tool-parameter-injection branch from d71b52f to 3369917 Compare June 24, 2026 01:20
Comment thread python/flink_agents/plan/actions/tool_call_action.py Outdated
Comment thread api/src/main/java/org/apache/flink/agents/api/tools/ToolParameterSource.java Outdated
Comment thread python/flink_agents/api/tools/tool_parameter_injection.py
Comment thread plan/src/test/java/org/apache/flink/agents/plan/actions/ToolCallActionTest.java Outdated
Comment thread python/flink_agents/plan/tests/resources/agent_plan.json Outdated
@GreatEugenius GreatEugenius force-pushed the codex/tool-parameter-injection branch 2 times, most recently from e73d1fd to 74d5ea3 Compare June 24, 2026 08:24
@GreatEugenius

Copy link
Copy Markdown
Collaborator Author

Hi @Sxnan and @weiqingy, thank you for your comments. I have addressed all of them. Please take a look.

@GreatEugenius GreatEugenius requested a review from weiqingy June 24, 2026 08:54

@wenjin272 wenjin272 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GreatEugenius, thanks for taking this on. Overall looks good to me, I left two comments.

Besides, I think we also need add e2e case for YAML API.

Comment thread plan/src/main/java/org/apache/flink/agents/plan/tools/SchemaUtils.java Outdated

@Sxnan Sxnan left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two follow-ups, verified against the implementations. Neither blocks the common scalar-injection path.

Comment thread plan/src/main/java/org/apache/flink/agents/plan/actions/ToolCallAction.java Outdated
Comment thread python/flink_agents/plan/actions/tool_call_action.py Outdated
Comment thread python/flink_agents/plan/actions/chat_model_action.py Outdated
@GreatEugenius GreatEugenius force-pushed the codex/tool-parameter-injection branch from 74d5ea3 to 17ac568 Compare June 30, 2026 08:40
@GreatEugenius

Copy link
Copy Markdown
Collaborator Author

Hi @wenjin272 and @Sxnan, I have addressed your comment. Please review it once more.

@GreatEugenius GreatEugenius requested review from Sxnan and wenjin272 June 30, 2026 11:02
@GreatEugenius GreatEugenius force-pushed the codex/tool-parameter-injection branch 2 times, most recently from 1bc213e to f78f835 Compare July 2, 2026 02:18

@Sxnan Sxnan left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more cross-language gap, verified against the implementations: injected-arg declarations don't travel across the language bridge — schema hiding and injection only honor the host-language declaration.

Comment thread python/flink_agents/plan/tools/function_tool.py
Comment thread python/flink_agents/runtime/python_java_utils.py
Comment thread python/flink_agents/runtime/python_java_utils.py Outdated
@GreatEugenius GreatEugenius force-pushed the codex/tool-parameter-injection branch from f78f835 to 0b5bf5a Compare July 2, 2026 10:59
@GreatEugenius

Copy link
Copy Markdown
Collaborator Author

Hi @Sxnan and @wenjin272. Thanks for pointing this out. I fixed this by carrying injected tool args through the cross-language metadata bridge in both directions.

For Python host -> Java tool, FunctionTool.set_java_resource_adapter() now passes the descriptor-declared injected arg names into JavaResourceAdapter.getJavaToolMetadata(...). The Java side uses those names when generating the model-facing schema, and also returns annotation-declared injected args from @ToolParam(injected = true). The Python FunctionTool then merges the descriptor declarations and Java annotation declarations, so tool_call_action can see the complete injected_args set at execution time.

For Java host -> Python tool, get_python_tool_metadata(...) now reads the callable’s _injected_args, hides those params from the schema together with any Java/YAML-declared injected args, and returns the callable-declared injected args back to Java. Java FunctionTool.setPythonResourceAdapter() merges them into the tool descriptor before execution.

So the cross-language behavior is now aligned: injected params are hidden from the model schema and are also available to the host-language tool_call_action for runtime injection, regardless of whether they were declared in YAML/API or on the tool annotation/decorator.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

doc-included Your PR already contains the necessary documentation updates. fixVersion/0.4.0 priority/major Default priority of the PR or issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants