kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
chore: minor refactors
rodzic
a1bd7ef101
commit
673aa18d25
|
@ -1,5 +1,5 @@
|
|||
import * as types from '@/types'
|
||||
import { defaultOpenAIModel } from '@/constants'
|
||||
import { DEFAULT_OPENAI_MODEL } from '@/constants'
|
||||
import { OpenAIChatModel } from '@/llms/openai'
|
||||
|
||||
import {
|
||||
|
@ -20,7 +20,6 @@ export class Agentic {
|
|||
'provider' | 'model' | 'modelParams' | 'timeoutMs' | 'retryConfig'
|
||||
>
|
||||
protected _defaultHumanFeedbackMechamism?: HumanFeedbackMechanism
|
||||
|
||||
protected _idGeneratorFn: types.IDGeneratorFunction
|
||||
|
||||
constructor(opts: {
|
||||
|
@ -41,7 +40,7 @@ export class Agentic {
|
|||
|
||||
this._openaiModelDefaults = {
|
||||
provider: 'openai',
|
||||
model: defaultOpenAIModel,
|
||||
model: DEFAULT_OPENAI_MODEL,
|
||||
modelParams: {},
|
||||
timeoutMs: 2 * 60000,
|
||||
retryConfig: {
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
export const defaultOpenAIModel = 'gpt-3.5-turbo'
|
||||
export const defaultAnthropicModel = 'claude-instant-v1'
|
||||
export const BOT_NAME = 'Agentic Bot'
|
||||
export const DEFAULT_OPENAI_MODEL = 'gpt-3.5-turbo'
|
||||
export const DEFAULT_ANTHROPIC_MODEL = 'claude-instant-v1'
|
||||
export const DEFAULT_BOT_NAME = 'Agentic Bot'
|
||||
|
|
|
@ -2,7 +2,7 @@ import * as anthropic from '@anthropic-ai/sdk'
|
|||
import { type SetOptional } from 'type-fest'
|
||||
|
||||
import * as types from '@/types'
|
||||
import { defaultAnthropicModel } from '@/constants'
|
||||
import { DEFAULT_ANTHROPIC_MODEL } from '@/constants'
|
||||
|
||||
import { BaseChatModel } from './llm'
|
||||
|
||||
|
@ -34,7 +34,7 @@ export class AnthropicChatModel<
|
|||
) {
|
||||
super({
|
||||
provider: 'anthropic',
|
||||
model: options.modelParams?.model || defaultAnthropicModel,
|
||||
model: options.modelParams?.model || DEFAULT_ANTHROPIC_MODEL,
|
||||
...options
|
||||
})
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { type SetOptional } from 'type-fest'
|
||||
|
||||
import * as types from '@/types'
|
||||
import { defaultOpenAIModel } from '@/constants'
|
||||
import { DEFAULT_OPENAI_MODEL } from '@/constants'
|
||||
|
||||
import { BaseChatModel } from './llm'
|
||||
|
||||
|
@ -25,7 +25,7 @@ export class OpenAIChatModel<
|
|||
) {
|
||||
super({
|
||||
provider: 'openai',
|
||||
model: options.modelParams?.model || defaultOpenAIModel,
|
||||
model: options.modelParams?.model || DEFAULT_OPENAI_MODEL,
|
||||
...options
|
||||
})
|
||||
|
||||
|
|
|
@ -1,18 +1,36 @@
|
|||
import ky from 'ky'
|
||||
import { z } from 'zod'
|
||||
|
||||
export const METAPHOR_BASE_URL = 'https://api.metaphor.systems'
|
||||
|
||||
export type MetaphorSearchResult = {
|
||||
author: string | null
|
||||
dateCreated: string | null
|
||||
title: string | null
|
||||
score: number
|
||||
url: string
|
||||
}
|
||||
// https://metaphorapi.readme.io/reference/search
|
||||
export const MetaphorSearchInputSchema = z.object({
|
||||
query: z.string(),
|
||||
numResults: z.number().optional(),
|
||||
useQueryExpansion: z.boolean().optional(),
|
||||
includeDomains: z.array(z.string()).optional(),
|
||||
excludeDomains: z.array(z.string()).optional(),
|
||||
startCrawlDate: z.string().optional(),
|
||||
endCrawlDate: z.string().optional(),
|
||||
startPublishedDate: z.string().optional(),
|
||||
endPublishedDate: z.string().optional()
|
||||
})
|
||||
|
||||
export type MetaphorSearchResponse = {
|
||||
results: MetaphorSearchResult[]
|
||||
}
|
||||
export type MetaphorSearchInput = z.infer<typeof MetaphorSearchInputSchema>
|
||||
|
||||
export const MetaphorSearchOutputSchema = z.object({
|
||||
results: z.array(
|
||||
z.object({
|
||||
author: z.string().nullable(),
|
||||
publishedDate: z.string().nullable(),
|
||||
title: z.string().nullable(),
|
||||
score: z.number(),
|
||||
url: z.string()
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
export type MetaphorSearchOutput = z.infer<typeof MetaphorSearchOutputSchema>
|
||||
|
||||
export class MetaphorClient {
|
||||
apiKey: string
|
||||
|
@ -33,23 +51,14 @@ export class MetaphorClient {
|
|||
this.baseUrl = baseUrl
|
||||
}
|
||||
|
||||
async search({
|
||||
query,
|
||||
numResults = 10
|
||||
}: {
|
||||
query: string
|
||||
numResults?: number
|
||||
}) {
|
||||
async search(params: MetaphorSearchInput) {
|
||||
return ky
|
||||
.post(`${this.baseUrl}/search`, {
|
||||
headers: {
|
||||
'x-api-key': this.apiKey
|
||||
},
|
||||
json: {
|
||||
query,
|
||||
numResults
|
||||
}
|
||||
json: params
|
||||
})
|
||||
.json<MetaphorSearchResponse>()
|
||||
.json<MetaphorSearchOutput>()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import ky, { KyResponse } from 'ky'
|
||||
import ky, { type KyResponse } from 'ky'
|
||||
|
||||
import { BOT_NAME } from '@/constants'
|
||||
import { DEFAULT_BOT_NAME } from '@/constants'
|
||||
import { sleep } from '@/utils'
|
||||
|
||||
export const TWILIO_CONVERSATION_BASE_URL =
|
||||
|
@ -131,17 +131,20 @@ export type TwilioSendAndWaitOptions = {
|
|||
export class TwilioConversationClient {
|
||||
api: typeof ky
|
||||
phoneNumber: string
|
||||
botName: string
|
||||
|
||||
constructor({
|
||||
accountSid = process.env.TWILIO_ACCOUNT_SID,
|
||||
authToken = process.env.TWILIO_AUTH_TOKEN,
|
||||
phoneNumber = process.env.TWILIO_PHONE_NUMBER,
|
||||
baseUrl = TWILIO_CONVERSATION_BASE_URL
|
||||
baseUrl = TWILIO_CONVERSATION_BASE_URL,
|
||||
botName = DEFAULT_BOT_NAME
|
||||
}: {
|
||||
accountSid?: string
|
||||
authToken?: string
|
||||
phoneNumber?: string
|
||||
baseUrl?: string
|
||||
botName?: string
|
||||
} = {}) {
|
||||
if (!accountSid || !authToken) {
|
||||
throw new Error(
|
||||
|
@ -155,7 +158,9 @@ export class TwilioConversationClient {
|
|||
)
|
||||
}
|
||||
|
||||
this.botName = botName
|
||||
this.phoneNumber = phoneNumber
|
||||
|
||||
this.api = ky.create({
|
||||
prefixUrl: baseUrl,
|
||||
headers: {
|
||||
|
@ -219,7 +224,7 @@ export class TwilioConversationClient {
|
|||
}) {
|
||||
const params = new URLSearchParams()
|
||||
params.set('Body', text)
|
||||
params.set('Author', BOT_NAME)
|
||||
params.set('Author', this.botName)
|
||||
return this.api
|
||||
.post(`Conversations/${conversationSid}/Messages`, {
|
||||
body: params
|
||||
|
@ -284,7 +289,7 @@ export class TwilioConversationClient {
|
|||
|
||||
if (response.messages.length > 1) {
|
||||
const candidates = response.messages.filter(
|
||||
(message) => message.author !== BOT_NAME
|
||||
(message) => message.author !== this.botName
|
||||
)
|
||||
const candidate = candidates[candidates.length - 1]
|
||||
|
||||
|
@ -307,6 +312,6 @@ export class TwilioConversationClient {
|
|||
} while (Date.now() - start < timeoutMs)
|
||||
|
||||
await this.deleteConversation(conversationSid)
|
||||
throw new Error('Reached timeout waiting for reply')
|
||||
throw new Error('Twilio timeout waiting for reply')
|
||||
}
|
||||
}
|
||||
|
|
12
src/task.ts
12
src/task.ts
|
@ -48,18 +48,6 @@ export abstract class BaseTask<TInput = void, TOutput = string> {
|
|||
|
||||
public abstract get name(): string
|
||||
|
||||
public serialize(): types.SerializedTask {
|
||||
return {
|
||||
_taskName: this.name
|
||||
// inputSchema: this.inputSchema.serialize()
|
||||
}
|
||||
}
|
||||
|
||||
// public abstract deserialize<
|
||||
// TInput extends ZodTypeAny = ZodTypeAny,
|
||||
// TOutput extends ZodTypeAny = ZodTypeAny
|
||||
// >(data: types.SerializedTask): BaseTask<TInput, TOutput>
|
||||
|
||||
// TODO: is this really necessary?
|
||||
public clone(): BaseTask<TInput, TOutput> {
|
||||
// TODO: override in subclass if needed
|
||||
|
|
|
@ -1,48 +1,21 @@
|
|||
import { z } from 'zod'
|
||||
|
||||
import * as metaphor from '@/services/metaphor'
|
||||
import * as types from '@/types'
|
||||
import { Agentic } from '@/agentic'
|
||||
import { MetaphorClient } from '@/services/metaphor'
|
||||
import { BaseTask } from '@/task'
|
||||
|
||||
export const MetaphorSearchToolInputSchema = z.object({
|
||||
query: z.string(),
|
||||
numResults: z.number().optional()
|
||||
})
|
||||
|
||||
export type MetaphorSearchToolInput = z.infer<
|
||||
typeof MetaphorSearchToolInputSchema
|
||||
>
|
||||
|
||||
export const MetaphorSearchToolOutputSchema = z.object({
|
||||
results: z.array(
|
||||
z.object({
|
||||
author: z.string().nullable(),
|
||||
dateCreated: z.string().nullable(),
|
||||
title: z.string().nullable(),
|
||||
score: z.number(),
|
||||
url: z.string()
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
export type MetaphorSearchToolOutput = z.infer<
|
||||
typeof MetaphorSearchToolOutputSchema
|
||||
>
|
||||
|
||||
export class MetaphorSearchTool extends BaseTask<
|
||||
MetaphorSearchToolInput,
|
||||
MetaphorSearchToolOutput
|
||||
metaphor.MetaphorSearchInput,
|
||||
metaphor.MetaphorSearchOutput
|
||||
> {
|
||||
_metaphorClient: MetaphorClient
|
||||
_metaphorClient: metaphor.MetaphorClient
|
||||
|
||||
constructor({
|
||||
agentic,
|
||||
metaphorClient = new MetaphorClient(),
|
||||
metaphorClient = new metaphor.MetaphorClient(),
|
||||
...rest
|
||||
}: {
|
||||
agentic: Agentic
|
||||
metaphorClient?: MetaphorClient
|
||||
metaphorClient?: metaphor.MetaphorClient
|
||||
} & types.BaseTaskOptions) {
|
||||
super({
|
||||
agentic,
|
||||
|
@ -53,11 +26,11 @@ export class MetaphorSearchTool extends BaseTask<
|
|||
}
|
||||
|
||||
public override get inputSchema() {
|
||||
return MetaphorSearchToolInputSchema
|
||||
return metaphor.MetaphorSearchInputSchema
|
||||
}
|
||||
|
||||
public override get outputSchema() {
|
||||
return MetaphorSearchToolOutputSchema
|
||||
return metaphor.MetaphorSearchOutputSchema
|
||||
}
|
||||
|
||||
public override get name(): string {
|
||||
|
@ -65,12 +38,9 @@ export class MetaphorSearchTool extends BaseTask<
|
|||
}
|
||||
|
||||
protected override async _call(
|
||||
ctx: types.TaskCallContext<MetaphorSearchToolInput>
|
||||
): Promise<MetaphorSearchToolOutput> {
|
||||
ctx: types.TaskCallContext<metaphor.MetaphorSearchInput>
|
||||
): Promise<metaphor.MetaphorSearchOutput> {
|
||||
// TODO: test required inputs
|
||||
return this._metaphorClient.search({
|
||||
query: ctx.input!.query,
|
||||
numResults: ctx.input!.numResults
|
||||
})
|
||||
return this._metaphorClient.search(ctx.input!)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,13 +95,6 @@ export interface RetryConfig extends RetryOptions {
|
|||
strategy?: string
|
||||
}
|
||||
|
||||
export type TaskError =
|
||||
| 'timeout'
|
||||
| 'provider'
|
||||
| 'validation'
|
||||
| 'unknown'
|
||||
| string
|
||||
|
||||
export interface TaskResponseMetadata extends Record<string, any> {
|
||||
// task info
|
||||
taskName: string
|
||||
|
|
Ładowanie…
Reference in New Issue