agentscope-ai / agentscope-ai/agentscope-java

[Bug]: Tool groups activated at build time are lost on first call for new sessions

Aperta
#2,200 5 commenti 0 reazioni 0 assegnatari Vedi su GitHub
area/core/agent area/core/tool bug
Lingua principale
Java
Stelle
5.6k
Fork
1.3k
Merge medio
4g 12h
PR unite (30g)
77

Descrizione

**Describe the bug**

When creating a `ReActAgent` with a `Toolkit` that has tool groups activated at build time (via `toolkit.createToolGroup(name, desc, true)`), the activated groups are silently lost on the **first call** for any new session. This results in an empty `tools` array being sent to the LLM — the model cannot call any tools.

**To Reproduce**

Steps to reproduce the behavior:

1. Create a `Toolkit` and register a tool group with `active=true`:

```java
Toolkit toolkit = new Toolkit();
toolkit.createToolGroup("myTools", "My tool group", true);
toolkit.registration().tool(myToolObject).group("myTools").apply();

// At this point, toolkit.getActiveGroups() returns ["myTools"] ✓
```

2. Build a `ReActAgent` with this toolkit and an `AgentStateStore`:

```java
ReActAgent agent = ReActAgent.builder()
.name("testAgent")
.sysPrompt("You are a helpful assistant.")
.model(someModel)
.toolkit(toolkit)
.maxIters(10)
.stateStore(agentStateStore) // ← key: stateStore is configured
.build();
```

3. Call the agent with a **new** session (no prior state in the store):

```java
RuntimeContext ctx = RuntimeContext.builder()
.sessionId("new-session-001")
.userId("user-001")
.build();

agent.call("Please use myTool to do something", ctx);
```

4. Observe that the LLM request body has an empty `tools` array — the model cannot call any tools.

**What happens internally:**

Inside `ReActAgent.activateSlotForContext()` (line 479-481):

```java
if (toolkit != null) {
toolkit.setActiveGroups(loaded.getToolContext().getActivatedGroups());
}
```

For a new session, `loadOrCreateAgentStateForSlot()` returns a `freshState()` where `ToolContextState.activatedGroups` defaults to an **empty list**. This empty list then **overwrites** the toolkit's build-time active groups via `setActiveGroups([])`.

Then in `reasoning()` (line 1947-1949):

```java
List tools = toolkit.getToolSchemas(
state.getToolContext().getActivatedGroups() // ← empty list
);
// → all grouped tools are filtered out → tools = []
```

The LLM receives a request with no `tools` field, so it cannot invoke any tool.

**Expected behavior**

Tool groups activated at build time (`active=true`) should remain active for new sessions. The initial activation state should be treated as a template, similar to how `initialPermissionContext` is handled.

**Error messages**

No exception is thrown. The bug manifests as:

- The LLM request body has an empty (or missing) `tools` array
- The model responds without calling any tools, often saying it doesn't have access to tools

**Environment (please complete the following information):**

- AgentScope-Java Version: 2.0.0-SNAPSHOT (master branch)
- Java Version: 21
- OS: Windows

**Additional context**

**Root cause:**

The constructor saves `initialPermissionContext` as a template for new sessions, but does **not** save the toolkit's initial active groups:

```java
// ReActAgent constructor (line 315):
this.initialPermissionContext = builder.permissionContext; // ✓ saved
// ⚠️ No equivalent for toolkit active groups
```

When `freshState()` creates a new `AgentState`, it builds a default `ToolContextState` with an empty `activatedGroups` list. Then `activateSlotForContext()` uses this empty list to call `toolkit.setActiveGroups([])`, clearing all build-time activations.

**Suggested fix:**

1. Save the toolkit's initial active groups in the constructor:

```java
// In constructor:
this.initialActiveGroups = agentToolkit != null
? List.copyOf(agentToolkit.getActiveGroups())
: List.of();
```

2. Use them when creating fresh state:

```java
// In freshState():
ToolContextState toolCtx = ToolContextState.builder().build();
if (!initialActiveGroups.isEmpty()) {
toolCtx.setActivatedGroups(new ArrayList<>(initialActiveGroups));
}
asb.toolContext(toolCtx);
```

This ensures that new sessions inherit the build-time tool group activation, and `activateSlotForContext()` will correctly restore the toolkit's active groups instead of clearing them.

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.