You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Tech Debt][API][ReActAgent] Support Skills directly in Java and Python constructors #1193
ReActAgent constructors accept a chat-model descriptor, prompt, and output schema, but do not expose Skills as a first-class constructor option. Users have to know the chat-model descriptor configuration to attach Skills to the built-in agent.
Proposed direction
Add equivalent Java/Python skills constructor support. Agree whether the argument accepts registered resource names, resource declarations, or both, and document how those resources become available to the agent.
Define how constructor Skills interact with Skills already configured on the chat-model descriptor: merge/override behavior, ordering, duplicate/conflicting declarations, and whether the supplied descriptor is copied or modified. Clarify ownership and precedence of allowed_commands so the new convenience API does not silently change command permissions.
Acceptance criteria
Java/Python expose equivalent Skills configuration on ReActAgent.
Constructor and descriptor settings have deterministic, documented combination rules.
Tests cover constructor-only, descriptor-only, combined/conflicting declarations, and command-policy behavior, including actual Skill availability in the ReAct execution path.
Examples and applicable YAML-facing semantics remain consistent with the resource model.
hi @wenjin272 If no one has taken this on yet, I'd be happy to finish it.
Regarding adding skills via constructor parameters, there are two entry points for adding skills, so both may be configured at the same time. Here is my proposed approach:
Merge the skills from the constructor parameters with the skills from the descriptor.
If they have the same name, just deduplicate them.
For ordering, the descriptor skills can come first, and the constructor-parameter skills can be appended as a supplement.
All of the above rules will be clearly documented in comments and documentation. WDYT
Thanks for picking this up @da-daken! Merging the two lists with descriptor skills first and constructor skills appended sounds reasonable. Repeated skill names can be deduplicated while preserving that order.
For the constructor API, I suggest supporting both:
A list of skill names, referencing skills from sources registered through the existing APIs.
A Skills object, with the constructor registering its sources and making all skills from those sources available to the agent.
Please merge skills into a copy of the chat-model descriptor’s configuration rather than modifying the supplied descriptor or its skills list in place. Users may reuse the same descriptor across multiple agents; adding skills to one agent should not affect another agent or change the caller’s original configuration.
@wenjin272 Thanks for the clarification. Before implementing the Skills-object form, I'd like to confirm two points.
1. Approach A or B?
There are two ways to resolve "all skills from these sources" at runtime:
A: Record "source → skill names" at plan time, expand at open time. The descriptor stores a marker meaning "all skills from these sources." During open(), SkillManager loads the actual skill names from the sources and appends them to the descriptor's skill list (de-duplicated, keeping order).
The agent only gets skills from the sources the user passed. Requires changes to the ResourceContext interface and SkillManager in both Java and Python.
B: "Passed a Skills object" means "expose all skills the agent can see." Simpler: when the constructor receives a Skills object, the descriptor calls SkillManager.getAllSkillNames() at open() time. Every skill loaded from any source becomes available to the agent.
The agent gets skills from all registered sources, not just the ones the user passed. Skills also carry bash execution capability, which could unintentionally expose privileged skills (e.g. a db-admin registered at the environment level by another team member).
Which approach do you prefer?
2. If A: Java and Python currently resolve duplicate skill names differently. OK to align Java with Python?
When two sources define a skill with the same name, SkillManager.registerRepo simply overwrites (with a WARN log). The question is which one wins. Java and Python currently differ:
Python:_add_skills iterates skills_objects in insertion order. The effective order is @Skills methods → environment → agent.add_resource (including the constructor). The last one wins, so agent-level skills override environment-level ones. This matches the existing precedence for resources with the same name (env | agent.resources[type]).
Java:Agent.resources is a HashMap, and addResourcesIfAbsent merges environment resources into the same map, losing the level information. AgentPlan.addSkills then sorts resources by name (for determinism across JDKs, not as a precedence rule) before merging sources. The winner is simply the one whose resource name sorts last.
Under approach A this matters more, because "skills from these sources" is part of the semantic contract — a skill from the constructor's Skills object that gets silently overwritten would disappear from the expanded name list entirely. I'd propose making Java follow a level-aware order (@Skills methods sorted by name for determinism → environment → agent level), aligning with Python.
Thanks for outlining the options @da-daken. I prefer A: passing a Skills object should expose skills from those specific sources, while preserving any skill names explicitly configured on the chat-model descriptor.
One clarification on timing: with cross-language repositories in #1214, skill discovery must happen at runtime, using the job’s classloader and initialized Python bridge/interpreter. At plan time, please only record the source declarations and the selection marker, not the actual skill names. At runtime, resolve the names through SkillManager, then merge them with the descriptor’s explicit names, keeping descriptor names first and deduplicating while preserving order. That final list can feed the existing prompt-generation and script-directory lookup paths.
For the second point, aligning Java with Python’s level-aware precedence sounds reasonable: @Skills declarations → environment → agent, with later entries winning. Please document this behavior change and cover same-name conflicts across these levels in both languages.
Activity
da-daken commentedon Oct 8, 2026
hi @wenjin272 If no one has taken this on yet, I'd be happy to finish it.
Regarding adding skills via constructor parameters, there are two entry points for adding skills, so both may be configured at the same time. Here is my proposed approach:
Merge the skills from the constructor parameters with the skills from the descriptor.
If they have the same name, just deduplicate them.
For ordering, the descriptor skills can come first, and the constructor-parameter skills can be appended as a supplement.
All of the above rules will be clearly documented in comments and documentation. WDYT
wenjin272 commentedon Oct 8, 2026
Thanks for picking this up @da-daken! Merging the two lists with descriptor skills first and constructor skills appended sounds reasonable. Repeated skill names can be deduplicated while preserving that order.
For the constructor API, I suggest supporting both:
Skillsobject, with the constructor registering its sources and making all skills from those sources available to the agent.Please merge skills into a copy of the chat-model descriptor’s configuration rather than modifying the supplied descriptor or its skills list in place. Users may reuse the same descriptor across multiple agents; adding skills to one agent should not affect another agent or change the caller’s original configuration.
da-daken commentedon Oct 9, 2026
@wenjin272 Thanks for the clarification. Before implementing the
Skills-object form, I'd like to confirm two points.1. Approach A or B?
There are two ways to resolve "all skills from these sources" at runtime:
A: Record "source → skill names" at plan time, expand at open time. The descriptor stores a marker meaning "all skills from these sources." During
open(),SkillManagerloads the actual skill names from the sources and appends them to the descriptor's skill list (de-duplicated, keeping order).The agent only gets skills from the sources the user passed. Requires changes to the
ResourceContextinterface andSkillManagerin both Java and Python.B: "Passed a
Skillsobject" means "expose all skills the agent can see." Simpler: when the constructor receives aSkillsobject, the descriptor callsSkillManager.getAllSkillNames()atopen()time. Every skill loaded from any source becomes available to the agent.The agent gets skills from all registered sources, not just the ones the user passed. Skills also carry bash execution capability, which could unintentionally expose privileged skills (e.g. a
db-adminregistered at the environment level by another team member).Which approach do you prefer?
2. If A: Java and Python currently resolve duplicate skill names differently. OK to align Java with Python?
When two sources define a skill with the same name,
SkillManager.registerReposimply overwrites (with a WARN log). The question is which one wins. Java and Python currently differ:_add_skillsiteratesskills_objectsin insertion order. The effective order is@Skillsmethods → environment →agent.add_resource(including the constructor). The last one wins, so agent-level skills override environment-level ones. This matches the existing precedence for resources with the same name (env | agent.resources[type]).Agent.resourcesis aHashMap, andaddResourcesIfAbsentmerges environment resources into the same map, losing the level information.AgentPlan.addSkillsthen sorts resources by name (for determinism across JDKs, not as a precedence rule) before merging sources. The winner is simply the one whose resource name sorts last.Under approach A this matters more, because "skills from these sources" is part of the semantic contract — a skill from the constructor's
Skillsobject that gets silently overwritten would disappear from the expanded name list entirely. I'd propose making Java follow a level-aware order (@Skillsmethods sorted by name for determinism → environment → agent level), aligning with Python.wenjin272 commentedon Oct 9, 2026
Thanks for outlining the options @da-daken. I prefer A: passing a
Skillsobject should expose skills from those specific sources, while preserving any skill names explicitly configured on the chat-model descriptor.One clarification on timing: with cross-language repositories in #1214, skill discovery must happen at runtime, using the job’s classloader and initialized Python bridge/interpreter. At plan time, please only record the source declarations and the selection marker, not the actual skill names. At runtime, resolve the names through
SkillManager, then merge them with the descriptor’s explicit names, keeping descriptor names first and deduplicating while preserving order. That final list can feed the existing prompt-generation and script-directory lookup paths.For the second point, aligning Java with Python’s level-aware precedence sounds reasonable:
@Skillsdeclarations → environment → agent, with later entries winning. Please document this behavior change and cover same-name conflicts across these levels in both languages.[api][plan][runtime][java][python][docs] Support Skills directly in …
[api][plan][runtime][java][python][docs] Support Skills directly in …
[api][plan][runtime][java][python][docs] Support Skills directly in …