Skip to content

Commit 3f3f7cc

Browse files
fix: normalize empty tool results for LlamaIndex to prevent loop
Adapts AG-UI tool result messages for LlamaIndex by converting empty results to a canonical value ("ok"). Prevents unnecessary re-invocation of tools in LlamaIndex workflows when tools return no meaningful payload.
1 parent e94630b commit 3f3f7cc

File tree

1 file changed

+37
-1
lines changed
  • typescript-sdk/integrations/llamaindex/src

1 file changed

+37
-1
lines changed

typescript-sdk/integrations/llamaindex/src/index.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,41 @@
44
*/
55

66
import { HttpAgent } from "@ag-ui/client";
7+
import type { BaseEvent, Message, RunAgentInput } from "@ag-ui/core";
8+
import { Observable } from "rxjs";
79

8-
export class LlamaIndexAgent extends HttpAgent {}
10+
/**
11+
* Normalizes AG-UI tool result messages before sending them to the LlamaIndex server.
12+
*
13+
* Context: When a frontend tool returns `undefined`, upstream encoders serialize the
14+
* result as an empty string (""). Some LlamaIndex workflows treat an empty tool
15+
* result as insufficient evidence and immediately re-plan the same tool call,
16+
* which can produce repeated frontend tool invocations (e.g., duplicate alerts).
17+
*
18+
* This integration adapts those messages for LlamaIndex by converting empty tool
19+
* results into a non-empty canonical value ("ok"). This preserves semantics for
20+
* tools that return no meaningful payload while preventing the planner from
21+
* needlessly re-invoking the same tool.
22+
*/
23+
function normalizeEmptyToolResults(messages: Message[]): Message[] {
24+
return messages.map((message: Message): Message => {
25+
if (message.role === "tool") {
26+
const content: string | undefined = message.content;
27+
const isEmpty: boolean = (content ?? "").trim().length === 0;
28+
if (isEmpty) {
29+
return { ...message, content: "ok" };
30+
}
31+
}
32+
return message;
33+
});
34+
}
35+
36+
export class LlamaIndexAgent extends HttpAgent {
37+
public override run(input: RunAgentInput): Observable<BaseEvent> {
38+
const sanitizedInput: RunAgentInput = {
39+
...input,
40+
messages: normalizeEmptyToolResults(input.messages),
41+
};
42+
return super.run(sanitizedInput);
43+
}
44+
}

0 commit comments

Comments
 (0)