Skip to content

Commit c18ee48

Browse files
authored
fix(angular): Do not require a component for frontend tools (#27)
1 parent 32260b3 commit c18ee48

File tree

2 files changed

+33
-65
lines changed

2 files changed

+33
-65
lines changed

packages/angular/src/lib/render-tool-calls.ts

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,7 @@ type HumanInTheLoopToolCallHandler = {
2525
config: HumanInTheLoopConfig;
2626
};
2727

28-
type ToolCallHandler =
29-
| RendererToolCallHandler
30-
| ClientToolCallHandler
31-
| HumanInTheLoopToolCallHandler;
28+
type ToolCallHandler = RendererToolCallHandler | ClientToolCallHandler | HumanInTheLoopToolCallHandler;
3229

3330
@Component({
3431
selector: "copilot-render-tool-calls",
@@ -37,12 +34,9 @@ type ToolCallHandler =
3734
template: `
3835
@for (toolCall of message().toolCalls ?? []; track toolCall.id) {
3936
@let renderConfig = pickRenderer(toolCall.function.name);
40-
@if (renderConfig && renderConfig.type !== "humanInTheLoopTool") {
37+
@if (renderConfig && renderConfig.type !== "humanInTheLoopTool" && renderConfig.config.component) {
4138
<ng-container
42-
*ngComponentOutlet="
43-
renderConfig.config.component;
44-
inputs: { toolCall: buildToolCall(toolCall) }
45-
"
39+
*ngComponentOutlet="renderConfig.config.component; inputs: { toolCall: buildToolCall(toolCall) }"
4640
/>
4741
}
4842
}
@@ -59,48 +53,37 @@ export class RenderToolCalls {
5953
type AssistantMessageWithAgent = AssistantMessage & {
6054
agentId?: string;
6155
};
62-
const messageAgentId = (this.message() as AssistantMessageWithAgent)
63-
.agentId;
56+
const messageAgentId = (this.message() as AssistantMessageWithAgent).agentId;
6457
const renderers = this.#copilotKit.toolCallRenderConfigs();
6558
const clientTools = this.#copilotKit.clientToolCallRenderConfigs();
66-
const humanInTheLoopTools =
67-
this.#copilotKit.humanInTheLoopToolRenderConfigs();
59+
const humanInTheLoopTools = this.#copilotKit.humanInTheLoopToolRenderConfigs();
6860

6961
const renderer = renderers.find(
7062
(candidate) =>
71-
candidate.name === name &&
72-
(candidate.agentId === undefined ||
73-
candidate.agentId === messageAgentId)
63+
candidate.name === name && (candidate.agentId === undefined || candidate.agentId === messageAgentId),
7464
);
7565

7666
if (renderer) return { type: "renderer", config: renderer };
7767

7868
const clientTool = clientTools.find(
7969
(candidate) =>
80-
candidate.name === name &&
81-
(candidate.agentId === undefined ||
82-
candidate.agentId === messageAgentId)
70+
candidate.name === name && (candidate.agentId === undefined || candidate.agentId === messageAgentId),
8371
);
8472
if (clientTool) return { type: "clientTool", config: clientTool };
8573

8674
const humanInTheLoopTool = humanInTheLoopTools.find(
8775
(candidate) =>
88-
candidate.name === name &&
89-
(candidate.agentId === undefined ||
90-
candidate.agentId === messageAgentId)
76+
candidate.name === name && (candidate.agentId === undefined || candidate.agentId === messageAgentId),
9177
);
92-
if (humanInTheLoopTool)
93-
return { type: "humanInTheLoopTool", config: humanInTheLoopTool };
78+
if (humanInTheLoopTool) return { type: "humanInTheLoopTool", config: humanInTheLoopTool };
9479

9580
const starRenderer = renderers.find((candidate) => candidate.name === "*");
9681
if (starRenderer) return { type: "renderer", config: starRenderer };
9782

9883
return undefined;
9984
}
10085

101-
protected buildToolCall<Args extends Record<string, unknown>>(
102-
toolCall: ToolCall
103-
): AngularToolCall<Args> {
86+
protected buildToolCall<Args extends Record<string, unknown>>(toolCall: ToolCall): AngularToolCall<Args> {
10487
const args = partialJSONParse(toolCall.function.arguments);
10588
const message = this.#getToolMessage(toolCall.id);
10689

@@ -126,7 +109,7 @@ export class RenderToolCalls {
126109
}
127110

128111
protected buildHumanInTheLoopToolCall<Args extends Record<string, unknown>>(
129-
toolCall: ToolCall
112+
toolCall: ToolCall,
130113
): HumanInTheLoopToolCall<Args> {
131114
const args = partialJSONParse(toolCall.function.arguments);
132115
const message = this.#getToolMessage(toolCall.id);
@@ -156,8 +139,6 @@ export class RenderToolCalls {
156139
}
157140

158141
#getToolMessage(toolCallId: string): Message | undefined {
159-
return this.messages().find(
160-
(m) => m.role === "tool" && m.toolCallId === toolCallId
161-
);
142+
return this.messages().find((m) => m.role === "tool" && m.toolCallId === toolCallId);
162143
}
163144
}

packages/angular/src/lib/tools.ts

Lines changed: 21 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ import { FrontendTool } from "@copilotkitnext/core";
33
import { z } from "zod";
44
import { CopilotKit } from "./copilotkit";
55

6-
export type AngularToolCall<
7-
Args extends Record<string, unknown> = Record<string, unknown>,
8-
> =
6+
export type AngularToolCall<Args extends Record<string, unknown> = Record<string, unknown>> =
97
| {
108
args: Partial<Args>;
119
status: "in-progress";
@@ -22,9 +20,7 @@ export type AngularToolCall<
2220
result: string;
2321
};
2422

25-
export type HumanInTheLoopToolCall<
26-
Args extends Record<string, unknown> = Record<string, unknown>,
27-
> =
23+
export type HumanInTheLoopToolCall<Args extends Record<string, unknown> = Record<string, unknown>> =
2824
| {
2925
args: Partial<Args>;
3026
status: "in-progress";
@@ -42,57 +38,48 @@ export type HumanInTheLoopToolCall<
4238
result: string;
4339
};
4440

45-
export interface ToolRenderer<
46-
Args extends Record<string, unknown> = Record<string, unknown>,
47-
> {
41+
export interface ToolRenderer<Args extends Record<string, unknown> = Record<string, unknown>> {
4842
toolCall: Signal<AngularToolCall<Args>>;
4943
}
5044

51-
export interface HumanInTheLoopToolRenderer<
52-
Args extends Record<string, unknown> = Record<string, unknown>,
53-
> {
45+
export interface HumanInTheLoopToolRenderer<Args extends Record<string, unknown> = Record<string, unknown>> {
5446
toolCall: Signal<HumanInTheLoopToolCall<Args>>;
5547
}
5648

57-
export type ClientTool<
58-
Args extends Record<string, unknown> = Record<string, unknown>,
59-
> = Omit<FrontendTool<Args>, "handler"> & {
49+
export type ClientTool<Args extends Record<string, unknown> = Record<string, unknown>> = Omit<
50+
FrontendTool<Args>,
51+
"handler"
52+
> & {
6053
renderer?: Type<ToolRenderer<Args>>;
6154
};
6255

63-
export interface RenderToolCallConfig<
64-
Args extends Record<string, unknown> = Record<string, unknown>,
65-
> {
56+
export interface RenderToolCallConfig<Args extends Record<string, unknown> = Record<string, unknown>> {
6657
name: string;
6758
args: z.ZodType<Args>;
6859
component: Type<ToolRenderer<Args>>;
6960
agentId?: string;
7061
}
7162

72-
export interface FrontendToolConfig<
73-
Args extends Record<string, unknown> = Record<string, unknown>,
74-
> {
63+
export interface FrontendToolConfig<Args extends Record<string, unknown> = Record<string, unknown>> {
7564
name: string;
7665
description: string;
7766
args: z.ZodType<Args>;
78-
component: Type<ToolRenderer<Args>>;
67+
component?: Type<ToolRenderer<Args>>;
7968
handler: (args: Args) => Promise<unknown>;
8069
agentId?: string;
8170
}
8271

83-
export interface HumanInTheLoopConfig<
84-
Args extends Record<string, unknown> = Record<string, unknown>,
85-
> {
72+
export interface HumanInTheLoopConfig<Args extends Record<string, unknown> = Record<string, unknown>> {
8673
name: string;
8774
args: z.ZodType<Args>;
8875
component: Type<HumanInTheLoopToolRenderer<Args>>;
8976
toolCall: Signal<HumanInTheLoopToolCall<Args>>;
9077
agentId?: string;
9178
}
9279

93-
export function registerRenderToolCall<
94-
Args extends Record<string, unknown> = Record<string, unknown>,
95-
>(renderToolCall: RenderToolCallConfig<Args>): void {
80+
export function registerRenderToolCall<Args extends Record<string, unknown> = Record<string, unknown>>(
81+
renderToolCall: RenderToolCallConfig<Args>,
82+
): void {
9683
const copilotKit = inject(CopilotKit);
9784
const destroyRef = inject(DestroyRef);
9885

@@ -103,9 +90,9 @@ export function registerRenderToolCall<
10390
});
10491
}
10592

106-
export function registerFrontendTool<
107-
Args extends Record<string, unknown> = Record<string, unknown>,
108-
>(frontendTool: FrontendToolConfig<Args>): void {
93+
export function registerFrontendTool<Args extends Record<string, unknown> = Record<string, unknown>>(
94+
frontendTool: FrontendToolConfig<Args>,
95+
): void {
10996
const injector = inject(Injector);
11097
const destroyRef = inject(DestroyRef);
11198
const copilotKit = inject(CopilotKit);
@@ -120,9 +107,9 @@ export function registerFrontendTool<
120107
});
121108
}
122109

123-
export function registerHumanInTheLoop<
124-
Args extends Record<string, unknown> = Record<string, unknown>,
125-
>(humanInTheLoop: HumanInTheLoopConfig<Args>): void {
110+
export function registerHumanInTheLoop<Args extends Record<string, unknown> = Record<string, unknown>>(
111+
humanInTheLoop: HumanInTheLoopConfig<Args>,
112+
): void {
126113
const destroyRef = inject(DestroyRef);
127114
const copilotKit = inject(CopilotKit);
128115

0 commit comments

Comments
 (0)