2023-06-09 17:44:02 +00:00
|
|
|
import pRetry from 'p-retry'
|
2023-06-06 19:46:07 +00:00
|
|
|
import { ZodRawShape, ZodTypeAny } from 'zod'
|
2023-05-26 19:06:39 +00:00
|
|
|
|
2023-06-09 17:44:02 +00:00
|
|
|
import * as errors from '@/errors'
|
2023-06-09 01:41:28 +00:00
|
|
|
import * as types from '@/types'
|
|
|
|
import { Agentic } from '@/agentic'
|
2023-05-26 19:06:39 +00:00
|
|
|
|
2023-05-27 00:36:52 +00:00
|
|
|
/**
|
|
|
|
* A `Task` is a typed, async function call that may be non-deterministic.
|
|
|
|
*
|
2023-06-06 22:20:20 +00:00
|
|
|
* Invoking a task is equivalent to sampling from a probability distribution.
|
|
|
|
*
|
2023-05-27 00:36:52 +00:00
|
|
|
* Examples of tasks include:
|
2023-06-02 06:26:22 +00:00
|
|
|
* - LLM calls
|
2023-06-06 22:20:20 +00:00
|
|
|
* - Chain of LLM calls
|
|
|
|
* - Retrieval task
|
2023-05-27 00:36:52 +00:00
|
|
|
* - API calls
|
2023-06-01 06:03:27 +00:00
|
|
|
* - Native function calls
|
2023-05-27 00:36:52 +00:00
|
|
|
* - Invoking sub-agents
|
|
|
|
*/
|
2023-06-02 06:26:22 +00:00
|
|
|
export abstract class BaseTask<
|
2023-05-26 19:06:39 +00:00
|
|
|
TInput extends ZodRawShape | ZodTypeAny = ZodTypeAny,
|
2023-06-06 19:46:07 +00:00
|
|
|
TOutput extends ZodRawShape | ZodTypeAny = ZodTypeAny
|
2023-05-26 19:06:39 +00:00
|
|
|
> {
|
2023-06-06 19:46:07 +00:00
|
|
|
protected _agentic: Agentic
|
2023-06-06 22:20:20 +00:00
|
|
|
|
|
|
|
protected _timeoutMs?: number
|
2023-06-09 17:44:02 +00:00
|
|
|
protected _retryConfig: types.RetryConfig
|
2023-06-01 01:53:09 +00:00
|
|
|
|
2023-06-06 19:46:07 +00:00
|
|
|
constructor(options: types.BaseTaskOptions) {
|
|
|
|
this._agentic = options.agentic
|
2023-05-26 19:16:13 +00:00
|
|
|
this._timeoutMs = options.timeoutMs
|
2023-06-09 17:44:02 +00:00
|
|
|
this._retryConfig = options.retryConfig ?? {
|
|
|
|
retries: 3,
|
|
|
|
strategy: 'default'
|
|
|
|
}
|
2023-05-26 19:06:39 +00:00
|
|
|
}
|
|
|
|
|
2023-06-06 19:46:07 +00:00
|
|
|
public get agentic(): Agentic {
|
|
|
|
return this._agentic
|
|
|
|
}
|
|
|
|
|
2023-06-01 01:53:09 +00:00
|
|
|
public abstract get inputSchema(): TInput
|
|
|
|
public abstract get outputSchema(): TOutput
|
2023-05-26 19:06:39 +00:00
|
|
|
|
2023-06-02 06:26:22 +00:00
|
|
|
// TODO
|
|
|
|
// public abstract get nameForModel(): string
|
|
|
|
// public abstract get nameForHuman(): string
|
|
|
|
|
|
|
|
// public abstract get descForModel(): string
|
|
|
|
// public abstract get descForHuman(): string
|
|
|
|
|
2023-06-01 01:53:09 +00:00
|
|
|
public retryConfig(retryConfig: types.RetryConfig) {
|
2023-05-26 19:16:13 +00:00
|
|
|
this._retryConfig = retryConfig
|
2023-05-26 19:06:39 +00:00
|
|
|
return this
|
|
|
|
}
|
|
|
|
|
2023-06-06 22:20:20 +00:00
|
|
|
public async call(
|
|
|
|
input?: types.ParsedData<TInput>
|
|
|
|
): Promise<types.ParsedData<TOutput>> {
|
2023-06-07 06:43:15 +00:00
|
|
|
const res = await this.callWithMetadata(input)
|
|
|
|
return res.result
|
2023-06-06 22:20:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public async callWithMetadata(
|
|
|
|
input?: types.ParsedData<TInput>
|
|
|
|
): Promise<types.TaskResponse<TOutput>> {
|
2023-06-09 17:44:02 +00:00
|
|
|
const metadata: types.TaskResponseMetadata = {
|
|
|
|
input,
|
|
|
|
numRetries: 0
|
|
|
|
}
|
|
|
|
|
|
|
|
do {
|
|
|
|
try {
|
|
|
|
const response = await this._call(input)
|
|
|
|
return response
|
|
|
|
} catch (err: any) {
|
|
|
|
if (err instanceof errors.ZodOutputValidationError) {
|
|
|
|
// TODO
|
|
|
|
} else {
|
|
|
|
throw err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: handle errors, retry logic, and self-healing
|
|
|
|
metadata.numRetries = (metadata.numRetries ?? 0) + 1
|
|
|
|
if (metadata.numRetries > this._retryConfig.retries) {
|
|
|
|
}
|
|
|
|
|
|
|
|
// eslint-disable-next-line no-constant-condition
|
|
|
|
} while (true)
|
2023-06-06 22:20:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
protected abstract _call(
|
2023-05-26 19:06:39 +00:00
|
|
|
input?: types.ParsedData<TInput>
|
2023-06-06 22:20:20 +00:00
|
|
|
): Promise<types.TaskResponse<TOutput>>
|
2023-05-26 19:06:39 +00:00
|
|
|
|
|
|
|
// TODO
|
|
|
|
// abstract stream({
|
|
|
|
// input: TInput,
|
|
|
|
// onProgress: types.ProgressFunction
|
|
|
|
// }): Promise<TOutput>
|
|
|
|
}
|