Skip to content

Commit 280f2c7

Browse files
committed
RDBC-944 Simplify handle method overloads in AiConversation by consolidating logic and removing redundant branches.
1 parent af3a293 commit 280f2c7

File tree

2 files changed

+166
-2
lines changed

2 files changed

+166
-2
lines changed

src/Documents/Operations/AI/AiConversation.ts

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,44 @@ export class AiConversation {
8080
this._userPrompt = userPrompt;
8181
}
8282

83-
public handle<TArgs = any>(actionName: string, action: (request: AiAgentActionRequest, args: TArgs) => Promise<object> | object, aiHandleError: AiHandleErrorStrategy = AiHandleErrorStrategy.SendErrorsToModel): void {
83+
public handle<TArgs = any>(
84+
actionName: string,
85+
action: (args: TArgs) => Promise<object>,
86+
aiHandleError?: AiHandleErrorStrategy
87+
): void;
88+
89+
public handle<TArgs = any>(
90+
actionName: string,
91+
action: (args: TArgs) => object,
92+
aiHandleError?: AiHandleErrorStrategy
93+
): void;
94+
95+
public handle<TArgs = any>(
96+
actionName: string,
97+
action: (request: AiAgentActionRequest, args: TArgs) => Promise<object>,
98+
aiHandleError?: AiHandleErrorStrategy
99+
): void;
100+
101+
public handle<TArgs = any>(
102+
actionName: string,
103+
action: (request: AiAgentActionRequest, args: TArgs) => object,
104+
aiHandleError?: AiHandleErrorStrategy
105+
): void
106+
107+
// Implementation
108+
public handle<TArgs = any>(
109+
actionName: string,
110+
action: ((args: TArgs) => Promise<object> | object) |
111+
((request: AiAgentActionRequest, args: TArgs) => Promise<object> | object),
112+
aiHandleError: AiHandleErrorStrategy = AiHandleErrorStrategy.SendErrorsToModel
113+
) {
114+
const wrappedAction = action.length === 1
115+
? (_request: AiAgentActionRequest, args: TArgs) =>
116+
(action as (args: TArgs) => Promise<object> | object)(args)
117+
: action as (request: AiAgentActionRequest, args: TArgs) => Promise<object> | object;
118+
84119
this.receive<TArgs>(actionName, async (req, args) => {
85-
const result = await action(req, args);
120+
const result = await wrappedAction(req, args);
86121
this.addActionResponse(req.toolId, result as any);
87122
}, aiHandleError);
88123
}

test/Ported/Documents/Operations/AiConversationTest.ts

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,4 +151,133 @@ import { AiHandleErrorStrategy } from "../../../../src/Documents/Operations/AI/A
151151
assertThat(receivedArgs.action.name).isSameAs("custom-action");
152152
assertThat(receivedArgs.action.toolId).isSameAs("tool-789");
153153
});
154+
155+
it("handle method works without request parameter (backward compat, async)", async () => {
156+
const conv = store.ai.conversation("agents/1-A", "conversations/12|") as any;
157+
158+
let handlerCalled = false;
159+
let capturedArgs: any = null;
160+
161+
// Register handler without request parameter (single arg)
162+
conv.handle("simple-action", async (args: any) => {
163+
handlerCalled = true;
164+
capturedArgs = args;
165+
return { result: "success", data: args.value };
166+
});
167+
168+
// Verify handler was registered
169+
assertThat(conv._invocations.has("simple-action")).isTrue();
170+
171+
// Simulate calling the handler via the internal invocation
172+
const invocation = conv._invocations.get("simple-action");
173+
await invocation({
174+
name: "simple-action",
175+
toolId: "tool-100",
176+
arguments: '{"value":"test-data"}'
177+
});
178+
179+
assertThat(handlerCalled).isTrue();
180+
assertThat(capturedArgs).isNotNull();
181+
assertThat(capturedArgs.value).isSameAs("test-data");
182+
183+
// Verify response was added
184+
assertThat(conv._actionResponses.length).isGreaterThan(0);
185+
});
186+
187+
it("handle method works without request parameter (backward compat, sync)", async () => {
188+
const conv = store.ai.conversation("agents/1-A", "conversations/13|") as any;
189+
190+
let handlerCalled = false;
191+
192+
// Register sync handler without request parameter
193+
conv.handle("sync-action", (args: any) => {
194+
handlerCalled = true;
195+
return { processed: true, input: args.input };
196+
});
197+
198+
assertThat(conv._invocations.has("sync-action")).isTrue();
199+
200+
const invocation = conv._invocations.get("sync-action");
201+
await invocation({
202+
name: "sync-action",
203+
toolId: "tool-101",
204+
arguments: '{"input":"test"}'
205+
});
206+
207+
assertThat(handlerCalled).isTrue();
208+
assertThat(conv._actionResponses.length).isGreaterThan(0);
209+
});
210+
211+
it("handle method works with request parameter (with metadata, async)", async () => {
212+
const conv = store.ai.conversation("agents/1-A", "conversations/14|") as any;
213+
214+
let handlerCalled = false;
215+
let capturedRequest: any = null;
216+
let capturedArgs: any = null;
217+
218+
// Register handler with request parameter (two args)
219+
conv.handle("action-with-request", async (request: any, args: any) => {
220+
handlerCalled = true;
221+
capturedRequest = request;
222+
capturedArgs = args;
223+
return { toolId: request.toolId, data: args.data };
224+
});
225+
226+
assertThat(conv._invocations.has("action-with-request")).isTrue();
227+
228+
const invocation = conv._invocations.get("action-with-request");
229+
const testRequest = {
230+
name: "action-with-request",
231+
toolId: "tool-102",
232+
arguments: '{"data":"metadata-test"}'
233+
};
234+
235+
await invocation(testRequest);
236+
237+
assertThat(handlerCalled).isTrue();
238+
assertThat(capturedRequest).isNotNull();
239+
assertThat(capturedRequest.toolId).isSameAs("tool-102");
240+
assertThat(capturedArgs.data).isSameAs("metadata-test");
241+
});
242+
243+
it("handle method works with request parameter (with metadata, sync)", async () => {
244+
const conv = store.ai.conversation("agents/1-A", "conversations/15|") as any;
245+
246+
let capturedToolId: string = null;
247+
248+
// Register sync handler with request parameter
249+
conv.handle("sync-with-request", (request: any, args: any) => {
250+
capturedToolId = request.toolId;
251+
return { success: true };
252+
});
253+
254+
const invocation = conv._invocations.get("sync-with-request");
255+
await invocation({
256+
name: "sync-with-request",
257+
toolId: "tool-103",
258+
arguments: "{}"
259+
});
260+
261+
assertThat(capturedToolId).isSameAs("tool-103");
262+
});
263+
264+
it("handle method arity detection works correctly", async () => {
265+
const conv = store.ai.conversation("agents/1-A", "conversations/16|") as any;
266+
267+
// Single parameter function (args only)
268+
const singleParamHandler = (args: any) => ({ result: args });
269+
assertThat(singleParamHandler.length).isSameAs(1);
270+
271+
// Two parameter function (request, args)
272+
const twoParamHandler = (request: any, args: any) => ({ result: args });
273+
assertThat(twoParamHandler.length).isSameAs(2);
274+
275+
// Register both
276+
conv.handle("single-param", singleParamHandler);
277+
conv.handle("two-param", twoParamHandler);
278+
279+
// Both should be registered
280+
assertThat(conv._invocations.has("single-param")).isTrue();
281+
assertThat(conv._invocations.has("two-param")).isTrue();
282+
});
154283
});

0 commit comments

Comments
 (0)