Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explore removing agent shims #11

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 17 additions & 22 deletions demo/inngest.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import {
anthropic,
createAgent,
createNetwork,
createTool,
defaultRoutingAgent,
openai,
} from "../src/index";
import { EventSchemas, Inngest } from "inngest";
} from "@inngest/agent-kit";
import { EventSchemas, Inngest, openai } from "inngest";
import { z } from "zod";

export const inngest = new Inngest({
Expand All @@ -24,26 +22,12 @@ export const inngest = new Inngest({
export const fn = inngest.createFunction(
{ id: "agent" },
{ event: "agent/run" },
async ({ event, step }) => {
const model = openai({ model: "gpt-4", step });

async ({ event }) => {
// 1. Single agent

// Run a single agent as a prompt without a network.
await codeWritingAgent.run(event.data.input, {
model,
});
await codeWritingAgent.run(event.data.input, { model });

// 2. A network of agents that works together
const network = createNetwork({
agents: [
codeWritingAgent.withModel(model),
executingAgent.withModel(model),
],
defaultModel: model,
maxIter: 4,
});

// This uses the defaut agentic router to determine which agent to handle first. You can
// optionally specifiy the agent that should execute first, and provide your own logic for
// handling logic in between agent calls.
Expand All @@ -57,9 +41,11 @@ export const fn = inngest.createFunction(
});

return result;
},
}
);

const model = openai({ model: "gpt-4" });

const systemPrompt =
"You are an expert TypeScript programmer. You can create files with idiomatic TypeScript code, with comments and associated tests.";

Expand Down Expand Up @@ -109,7 +95,7 @@ const codeWritingAgent = createAgent({
filename: z.string(),
content: z.string(),
})
.required(),
.required()
),
})
.required(),
Expand Down Expand Up @@ -157,3 +143,12 @@ Think carefully about the request that the user is asking for. Do not respond wi
</command>
`,
});

const network = createNetwork({
agents: [
codeWritingAgent.withModel(model),
executingAgent.withModel(model),
],
defaultModel: model,
maxIter: 4,
});
10 changes: 6 additions & 4 deletions demo/mw.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
import { agenticOpenai, createAgent, createNetwork } from "@inngest/agent-kit";
import { InngestMiddleware, type OpenAi } from "inngest";
import { createAgent, createNetwork } from "@inngest/agent-kit";
import { InngestMiddleware, openai, type OpenAi } from "inngest";

export const codeWritingNetworkMiddleware = (
defaultModelOptions: OpenAi.AiModelOptions,
) => {
return new InngestMiddleware({
name: "Code Writing Agent Middleware",
init() {
const model = openai({ ...defaultModelOptions });

return {
onFunctionRun() {
return {
transformInput({ ctx: { step } }) {
transformInput() {
const codeWritingNetwork = createNetwork({
agents: [codeWritingAgent, executingAgent],
maxIter: 4,
defaultModel: agenticOpenai({ ...defaultModelOptions, step }),
defaultModel: model,
});

return {
Expand Down
4 changes: 2 additions & 2 deletions demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
"license": "ISC",
"description": "",
"dependencies": {
"@inngest/agent-kit": "~0.0.1",
"@inngest/agent-kit": "file:../inngest-agent-kit-0.0.3.tgz",
"express": "^4.21.1",
"inngest": "^3.27.3"
"inngest": "^3.27.6-pr-776.2"
},
"devDependencies": {
"@types/express": "^5.0.0",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@
}
},
"dependencies": {
"inngest": "^3.27.4",
"express": "^4.21.1",
"inngest": "3.27.6-pr-776.2",
"openai-zod-to-json-schema": "^1.0.3",
"zod": "^3.23.8"
},
Expand Down
10 changes: 5 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions src/adapters/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { type AiAdapter, type AiAdapters } from "inngest";
import { type AgenticModel } from "../model";
import * as openai from "./openai";
import * as anthropic from "./anthropic";

export type Adapters = {
[Format in AiAdapter.Format]: {
request: AgenticModel.RequestParser<AiAdapters[Format]>;
response: AgenticModel.ResponseParser<AiAdapters[Format]>;
};
};

export const adapters: Adapters = {
"openai-chat": {
request: openai.requestParser,
response: openai.responseParser,
},
anthropic: {
request: anthropic.requestParser,
response: anthropic.responseParser,
},
};
23 changes: 14 additions & 9 deletions src/agent.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type AgenticModel } from "./model";
import { type AiAdapter } from "inngest";
import { createAgenticModelFromAiAdapter, type AgenticModel } from "./model";
import { type Network } from "./network";
import {
type State,
Expand All @@ -11,7 +12,7 @@ import {
type ResultLifecycleArgs,
type Tool,
} from "./types";
import { type AnyZodType, type MaybePromise } from "./util";
import { getStepTools, type AnyZodType, type MaybePromise } from "./util";

/**
* createTool is a helper that properly types the input argument for a handler
Expand Down Expand Up @@ -72,15 +73,15 @@ export class Agent {
this.assistant = opts.assistant || "";
this.tools = new Map();
this.lifecycles = opts.lifecycle;
this.model = opts.model;
this.model = opts.model && createAgenticModelFromAiAdapter(opts.model);

for (const tool of opts.tools || []) {
this.tools.set(tool.name, tool);
}
}

withModel(model: AgenticModel.Any): Agent {
this.model = model;
withModel(model: AiAdapter.Any): Agent {
this.model = createAgenticModelFromAiAdapter(model);
return this; // for chaining
}

Expand All @@ -97,7 +98,11 @@ export class Agent {
maxIter = 0,
}: Agent.RunOptions | undefined = {},
): Promise<InferenceResult> {
const p = model || this.model || network?.defaultModel;
const p =
(model && createAgenticModelFromAiAdapter(model)) ||
this.model ||
(network?.defaultModel &&
createAgenticModelFromAiAdapter(network.defaultModel));
if (!p) {
throw new Error("No step caller provided to agent");
}
Expand Down Expand Up @@ -226,7 +231,7 @@ export class Agent {
const result = await found.handler(tool.input, {
agent: this,
network,
step: p.step,
step: await getStepTools(),
});

// TODO: handle error and send them back to the LLM
Expand Down Expand Up @@ -288,11 +293,11 @@ export namespace Agent {
assistant?: string;
tools?: Tool.Any[];
lifecycle?: Lifecycle;
model?: AgenticModel.Any;
model?: AiAdapter.Any;
}

export interface RunOptions {
model?: AgenticModel.Any;
model?: AiAdapter.Any;
network?: Network;
/**
* State allows you to pass custom state into a single agent run call. This should only
Expand Down
6 changes: 6 additions & 0 deletions src/error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export class AIGatewayError extends Error {
constructor(message: string) {
super(message);
this.name = "AIGatewayError";
}
}
5 changes: 0 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,3 @@ export * from "./network";
export * from "./state";
export * from "./types";
export * from "./util";

// Models
export * from "./models/gemini";
export * from "./models/openai";
export * from "./models/anthropic";
29 changes: 22 additions & 7 deletions src/model.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,36 @@
import { type AiAdapter, type GetStepTools, type Inngest } from "inngest";
import { type AiAdapter } from "inngest";
import { type InternalNetworkMessage } from "./state";
import { type Tool } from "./types";
import { getStepTools } from "./util";
import { adapters } from "./adapters";

export const createAgenticModelFromAiAdapter = <
TAiAdapter extends AiAdapter.Any,
>(
adapter: TAiAdapter,
): AgenticModel<TAiAdapter> => {
const opts = adapters[adapter.format as AiAdapter.Format];

return new AgenticModel({
model: adapter,
requestParser:
opts.request as unknown as AgenticModel.RequestParser<TAiAdapter>,
responseParser:
opts.response as unknown as AgenticModel.ResponseParser<TAiAdapter>,
});
};

export class AgenticModel<TAiAdapter extends AiAdapter.Any> {
#model: TAiAdapter;

step: GetStepTools<Inngest.Any>;
requestParser: AgenticModel.RequestParser<TAiAdapter>;
responseParser: AgenticModel.ResponseParser<TAiAdapter>;

constructor({
model,
step,
requestParser,
responseParser,
}: AgenticModel.Constructor<TAiAdapter>) {
this.#model = model;
this.step = step;
this.requestParser = requestParser;
this.responseParser = responseParser;
}
Expand All @@ -26,7 +40,9 @@ export class AgenticModel<TAiAdapter extends AiAdapter.Any> {
input: InternalNetworkMessage[],
tools: Tool.Any[],
): Promise<AgenticModel.InferenceResponse> {
const result = (await this.step.ai.infer(stepID, {
const step = await getStepTools();

const result = (await step.ai.infer(stepID, {
model: this.#model,
body: this.requestParser(this.#model, input, tools),
})) as AiAdapter.Input<TAiAdapter>;
Expand All @@ -50,7 +66,6 @@ export namespace AgenticModel {

export interface Constructor<TAiAdapter extends AiAdapter.Any> {
model: TAiAdapter;
step: GetStepTools<Inngest.Any>;
requestParser: RequestParser<TAiAdapter>;
responseParser: ResponseParser<TAiAdapter>;
}
Expand Down
4 changes: 0 additions & 4 deletions src/models/README.md

This file was deleted.

43 changes: 0 additions & 43 deletions src/models/anthropic.ts

This file was deleted.

Loading
Loading