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

Attempting to add support for anthropic #53

Open
wants to merge 31 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
caa92c4
Add build step before typecheck in CI workflow
rileytomasek Oct 13, 2024
82fe6d2
Catch tokenizer error without console output
rileytomasek Oct 13, 2024
53ede7e
Update `openai-fetch` to 3.3.1 and handle refusals
rileytomasek Oct 13, 2024
fd8e4d0
Delete documentation website
rileytomasek Oct 13, 2024
a3fea3b
Remove Datastore classes & add Knip to clean up
rileytomasek Oct 13, 2024
f2f1690
Remove unused code and exports
rileytomasek Oct 13, 2024
799a342
Refactor to remove top-level exports
rileytomasek Oct 13, 2024
788170f
Remove remnants of deleted Datastore class
rileytomasek Oct 13, 2024
2213098
Refactor telemetry file structure and imports
rileytomasek Oct 13, 2024
5234eaa
Refactor: Move utils to `model/utils` directory
rileytomasek Oct 13, 2024
80f3efe
Refactor error handling into `model/utils/errors.ts`
rileytomasek Oct 13, 2024
7f86124
Refactor `Msg` to `MsgUtil` and update related imports
rileytomasek Oct 13, 2024
b7ea3fa
Refactor `prompt` directory to `ai-function`
rileytomasek Oct 13, 2024
d4cb343
Move `@dexaai/dexter/model` exports to package root
rileytomasek Oct 13, 2024
8681798
Update readme
rileytomasek Oct 13, 2024
3eb2fa8
Remove unused exports
rileytomasek Oct 13, 2024
9a26060
Add `createExtractFunction` for data extraction
rileytomasek Oct 13, 2024
93b038d
Add rough Swarm implementation
rileytomasek Oct 14, 2024
c334720
4.0.0-0
rileytomasek Oct 14, 2024
e3b290e
Rename `Runner` to `AIRunner` for consistency
rileytomasek Oct 17, 2024
7947e4b
Add optional strict validation to extract function
rileytomasek Oct 17, 2024
d419fd0
Replace legacy `Model.Message` type with `Msg`
rileytomasek Oct 17, 2024
9f4dd77
Enhance `readme.md` based on feedback
rileytomasek Oct 17, 2024
0874859
Upgrade `openai-zod-to-json-schema` to v1.0.3
rileytomasek Oct 17, 2024
4513b78
Refactor imports and simplify module exports
rileytomasek Oct 17, 2024
9529196
4.0.0-1
rileytomasek Oct 17, 2024
33255ac
Adding aifetch, anthropic fetch
cfortuner Oct 25, 2024
42ba106
prettier
cfortuner Oct 25, 2024
554c398
working on getting types to align
cfortuner Oct 28, 2024
ad185f4
merge
cfortuner Oct 28, 2024
bdc3fcf
fix merge
cfortuner Oct 28, 2024
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
2 changes: 1 addition & 1 deletion examples/abort-chat-completion.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'dotenv/config';

import { ChatModel, type Msg, MsgUtil } from '@dexaai/dexter';
import { ChatModel, type Msg, MsgUtil } from '../src/index.js';

/**
* npx tsx examples/abort-chat-completion.ts
Expand Down
8 changes: 7 additions & 1 deletion examples/ai-function.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import 'dotenv/config';

import { ChatModel, createAIFunction, type Msg, MsgUtil } from '@dexaai/dexter';
import { z } from 'zod';

import {
ChatModel,
createAIFunction,
type Msg,
MsgUtil,
} from '../src/index.js';

/**
* npx tsx examples/ai-function.ts
*/
Expand Down
6 changes: 6 additions & 0 deletions examples/ai-runner-with-error.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import 'dotenv/config';

import { z } from 'zod';

import {
ChatModel,
createAIFunction,
createAIRunner,
MsgUtil,
<<<<<<< HEAD
} from '../src/index.js';
=======
} from '@dexaai/dexter';
import { z } from 'zod';
>>>>>>> origin/master

/** Get the weather for a given location. */
const getWeather = createAIFunction(
Expand Down
6 changes: 6 additions & 0 deletions examples/ai-runner.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import 'dotenv/config';

import { z } from 'zod';

import {
ChatModel,
createAIFunction,
createAIRunner,
MsgUtil,
<<<<<<< HEAD
} from '../src/index.js';
=======
} from '@dexaai/dexter';
import { z } from 'zod';
>>>>>>> origin/master

/** Get the weather for a given location. */
const getWeather = createAIFunction(
Expand Down
108 changes: 108 additions & 0 deletions examples/anthropic-ai-function.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import 'dotenv/config';

import { z } from 'zod';

import {
ChatModel,
createAIFunction,
createAnthropicClient,
type Msg,
MsgUtil,
} from '../src/index.js';

/**
* npx tsx examples/ai-function.ts
*/
async function main() {
const getWeather = createAIFunction(
{
name: 'get_weather',
description: 'Gets the weather for a given location',
argsSchema: z.object({
location: z
.string()
.describe('The city and state e.g. San Francisco, CA'),
unit: z
.enum(['c', 'f'])
.optional()
.default('f')
.describe('The unit of temperature to use'),
}),
},
// Fake weather API implementation which returns a random temperature
// after a short delay
async (args: { location: string; unit?: string }) => {
await new Promise((resolve) => setTimeout(resolve, 500));

return {
location: args.location,
unit: args.unit,
temperature: (30 + Math.random() * 70) | 0,
};
}
);

const chatModel = new ChatModel({
debug: true,
client: createAnthropicClient(),
params: {
model: 'claude-2.0',
temperature: 0.5,
max_tokens: 500,
tools: [
{
type: 'function',
function: getWeather.spec,
},
],
},
});

const messages: Msg[] = [
MsgUtil.user('What is the weather in San Francisco?'),
];

{
// Invoke the chat model and have it create the args for the `get_weather` function
const { message } = await chatModel.run({
messages,
model: 'claude-2.0',
tool_choice: {
type: 'function',
function: {
name: 'get_weather',
},
},
});

if (!MsgUtil.isToolCall(message)) {
throw new Error('Expected tool call');
}
messages.push(message);

for (const toolCall of message.tool_calls) {
if (toolCall.function.name !== 'get_weather') {
throw new Error(`Invalid function name: ${toolCall.function.name}`);
}

const result = await getWeather(toolCall.function.arguments);
const toolResult = MsgUtil.toolResult(result, toolCall.id);
messages.push(toolResult);
}
}

{
// Invoke the chat model with the result
const { message } = await chatModel.run({
messages,
tool_choice: 'none',
});
if (!MsgUtil.isAssistant(message)) {
throw new Error('Expected assistant message');
}

console.log(message.content);
}
}

main();
98 changes: 98 additions & 0 deletions examples/anthropic-ai-runner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import 'dotenv/config';

import { z } from 'zod';

import {
ChatModel,
createAIFunction,
createAIRunner,
createAnthropicClient,
MsgUtil,
} from '../src/index.js';

/** Get the weather for a given location. */
const getWeather = createAIFunction(
{
name: 'get_weather',
description: 'Gets the weather for a given location',
argsSchema: z.object({
location: z
.string()
.describe('The city and state e.g. San Francisco, CA'),
unit: z
.enum(['c', 'f'])
.optional()
.default('f')
.describe('The unit of temperature to use'),
}),
},
async ({ location, unit }) => {
await new Promise((resolve) => setTimeout(resolve, 500));
const temperature = (30 + Math.random() * 70) | 0;
return { location, unit, temperature };
}
);

/** Get the capital city for a given state. */
const getCapitalCity = createAIFunction(
{
name: 'get_capital_city',
description: 'Use this to get the the capital city for a given state',
argsSchema: z.object({
state: z
.string()
.length(2)
.describe(
'The state to get the capital city for, using the two letter abbreviation e.g. CA'
),
}),
},
async ({ state }) => {
await new Promise((resolve) => setTimeout(resolve, 500));
let capitalCity = '';
switch (state) {
case 'CA':
capitalCity = 'Sacramento';
break;
case 'NY':
capitalCity = 'Albany';
break;
default:
capitalCity = 'Unknown';
}
return { capitalCity };
}
);

/** A runner that uses the weather and capital city functions. */
const weatherCapitalRunner = createAIRunner({
chatModel: new ChatModel({
client: createAnthropicClient(),
params: { model: 'claude-2.0' },
}),
functions: [getWeather, getCapitalCity],
systemMessage: `You use functions to answer questions about the weather and capital cities.`,
});

/**
* npx tsx examples/ai-runner.ts
*/
async function main() {
// Run with a string input
const rString = await weatherCapitalRunner(
`Whats the capital of California and NY and the weather for both`
);
console.log('rString', rString);

// Run with a message input
const rMessage = await weatherCapitalRunner({
messages: [
MsgUtil.user(
`Whats the capital of California and NY and the weather for both`
),
],
});
console.log('rMessage', rMessage);
}

main().catch(console.error);
5 changes: 5 additions & 0 deletions examples/caching-redis.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import 'dotenv/config';

<<<<<<< HEAD
=======
import { EmbeddingModel } from '@dexaai/dexter';
>>>>>>> origin/master
import KeyvRedis from '@keyv/redis';
import Keyv from 'keyv';

import { EmbeddingModel } from '../src/index.js';

/**
* npx tsx examples/caching-redis.ts
*/
Expand Down
25 changes: 25 additions & 0 deletions examples/embeddings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import 'dotenv/config';

import { createOpenAIClient, EmbeddingModel } from '../src/index.js';

/**
* npx tsx examples/ai-function.ts
*/
async function main() {
const embeddingModel = new EmbeddingModel({
client: createOpenAIClient(),
params: { model: 'text-embedding-3-small' },
});

{
// Invoke the chat model and have it create the args for the `get_weather` function
const response = await embeddingModel.run({
input: ['What is the weather in San Francisco?'],
model: 'text-embedding-3-small',
});

console.log(response);
}
}

main();
5 changes: 5 additions & 0 deletions examples/extract-people-names.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import 'dotenv/config';

<<<<<<< HEAD
=======
import { ChatModel, createExtractFunction } from '@dexaai/dexter';
>>>>>>> origin/master
import { z } from 'zod';

import { ChatModel, createExtractFunction } from '../src/index.js';

/** A function to extract people names from text. */
const extractPeopleNamesRunner = createExtractFunction({
chatModel: new ChatModel({ params: { model: 'gpt-4o-mini' } }),
Expand Down
3 changes: 2 additions & 1 deletion examples/with-telemetry.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import './instrument.js';
import 'dotenv/config';

import { ChatModel } from '@dexaai/dexter';
import * as Sentry from '@sentry/node';

import { ChatModel } from '../src/index.js';

const chatModel = new ChatModel({
// Send tracing data to Sentry
telemetry: Sentry,
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@
"hash-object": "^5.0.1",
"jsonrepair": "^3.8.1",
"ky": "^1.7.2",
"openai-fetch": "3.3.1",
"ai-fetch": "../ai-fetch",
"openai-fetch": "../openai-fetch",
"openai-zod-to-json-schema": "^1.0.3",
"p-map": "^7.0.2",
"p-throttle": "^6.2.0",
Expand All @@ -58,7 +59,8 @@
"tslib": "^2.7.0",
"zod": "^3.23.8",
"zod-to-json-schema": "^3.23.3",
"zod-validation-error": "^3.4.0"
"zod-validation-error": "^3.4.0",
"anthropic-fetch": "../anthropic-fetch"
},
"devDependencies": {
"@dexaai/eslint-config": "^1.3.6",
Expand Down
Loading
Loading