This commit is contained in:
Rob Colbert 2026-05-07 00:59:15 -04:00
parent 3e31d4d501
commit 86c7c4d457
4 changed files with 43 additions and 65 deletions

4
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,4 @@
{
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": false
}

View File

@ -16,7 +16,6 @@ import {
import {
IChatSession,
IChatTurn,
IProject,
IUser,
ServerToClientEvents,
ClientToServerEvents,
@ -26,15 +25,7 @@ import {
import AiService from "./ai.ts";
import { GadgetService } from "../lib/service.ts";
import { AiToolbox } from "../../../packages/ai/dist/toolbox.js";
export interface IToolCall {
name: string;
params: string;
call_id?: string;
response?: string;
error?: Error;
}
import { AiToolbox } from "@gadget/ai";
export interface IAgentWorkOrder {
createdAt: Date;
@ -50,8 +41,6 @@ interface IAgentWorkflow {
type DroneSocket = Socket<ServerToClientEvents, ClientToServerEvents>;
class AgentService extends GadgetService {
private toolbox: AiToolbox | undefined;
get name(): string {
return "AgentService";
}
@ -60,7 +49,6 @@ class AgentService extends GadgetService {
}
async start(): Promise<void> {
this.createAgentToolbox();
this.log.info("started");
}
@ -72,18 +60,12 @@ class AgentService extends GadgetService {
workOrder: IAgentWorkOrder,
socket: DroneSocket,
): Promise<void> {
assert(this.toolbox, "service uninitialized");
const { turn } = workOrder;
const task: IAgentWorkflow = {
chatOptions: {},
context: [],
};
async function aiCallTool(name: string, args: string) {
return "[all tool calls are stubbed out]";
}
const onStreamChunk = async (chunk: IAiStreamChunk): Promise<void> => {
this.log.debug("stream chunk received", { chunk });
};
@ -94,7 +76,7 @@ class AgentService extends GadgetService {
systemPrompt: turn.prompts.system,
context: task.context,
userPrompt: turn.prompts.user,
tools: Array.from(this.toolbox.getModeSet(turn.mode) || []),
tools: this.getToolsForMode(turn.mode),
};
} catch (cause) {
socket.emit(
@ -108,8 +90,6 @@ class AgentService extends GadgetService {
}
try {
let keepProcessing = true;
do {
const response = await AiService.chat(
turn.provider,
{
@ -135,29 +115,18 @@ class AgentService extends GadgetService {
socket.emit("response", response.response);
}
keepProcessing = (response.toolCalls?.length ?? 0) > 0;
for (const toolCall of response.toolCalls ?? []) {
const result = await aiCallTool(
toolCall.function.name,
toolCall.function.arguments,
);
task.context.push({
createdAt: new Date(),
role: "tool",
callId: toolCall.callId,
content: result,
});
// Emit tool call event
// Emit tool calls if present
if (response.toolCalls && response.toolCalls.length > 0) {
for (const toolCall of response.toolCalls) {
socket.emit(
"toolCall",
toolCall.callId,
toolCall.function.name,
toolCall.function.arguments,
result,
response.toolCallResults?.find(r => r.callId === toolCall.callId)?.result || "",
);
}
} while (keepProcessing);
}
} catch (cause) {
socket.emit(
"workOrderComplete",
@ -248,7 +217,7 @@ class AgentService extends GadgetService {
// TODO
}
createAgentToolbox(): void {
private getToolsForMode(mode: ChatSessionMode): any[] {
const aiEnv: IAiEnvironment = {
NODE_ENV: env.NODE_ENV || "develop",
services: {
@ -260,16 +229,16 @@ class AgentService extends GadgetService {
},
},
};
this.toolbox = new AiToolbox(aiEnv);
let tool = new GoogleSearchTool(this.toolbox);
this.toolbox.register(tool, [
const toolbox = new AiToolbox(aiEnv);
const googleSearchTool = new GoogleSearchTool(toolbox);
toolbox.register(googleSearchTool, [
ChatSessionMode.Plan,
ChatSessionMode.Build,
ChatSessionMode.Test,
ChatSessionMode.Ship,
ChatSessionMode.Develop,
]);
return Array.from(toolbox.getModeSet(mode) || []);
}
}

View File

@ -1 +1,5 @@
dist
*.js
*.js.map
*.d.ts
*.d.ts.map

View File

@ -24,6 +24,7 @@ export {
} from "./api.js";
export * from "./tools/search/google.ts";
export { AiToolbox } from "./toolbox.js";
export { OllamaAiApi } from "./ollama.js";
export { OpenAiApi } from "./openai.js";