@cogitator-ai/openai-compat 21.1.13 → 21.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +183 -46
- package/dist/client/openai-adapter.d.ts +35 -7
- package/dist/client/openai-adapter.d.ts.map +1 -1
- package/dist/client/openai-adapter.js +139 -57
- package/dist/client/openai-adapter.js.map +1 -1
- package/dist/client/thread-manager.d.ts +4 -3
- package/dist/client/thread-manager.d.ts.map +1 -1
- package/dist/client/thread-manager.js +7 -5
- package/dist/client/thread-manager.js.map +1 -1
- package/dist/index.d.ts +7 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/server/agents/agent-turn.d.ts +134 -0
- package/dist/server/agents/agent-turn.d.ts.map +1 -0
- package/dist/server/agents/agent-turn.js +340 -0
- package/dist/server/agents/agent-turn.js.map +1 -0
- package/dist/server/agents/shared.d.ts +62 -0
- package/dist/server/agents/shared.d.ts.map +1 -0
- package/dist/server/agents/shared.js +136 -0
- package/dist/server/agents/shared.js.map +1 -0
- package/dist/server/api-server.d.ts +50 -10
- package/dist/server/api-server.d.ts.map +1 -1
- package/dist/server/api-server.js +61 -24
- package/dist/server/api-server.js.map +1 -1
- package/dist/server/routes/chat-completions.d.ts +15 -0
- package/dist/server/routes/chat-completions.d.ts.map +1 -0
- package/dist/server/routes/chat-completions.js +305 -0
- package/dist/server/routes/chat-completions.js.map +1 -0
- package/dist/server/routes/models.d.ts +8 -0
- package/dist/server/routes/models.d.ts.map +1 -0
- package/dist/server/routes/models.js +27 -0
- package/dist/server/routes/models.js.map +1 -0
- package/dist/server/routes/responses.d.ts +229 -0
- package/dist/server/routes/responses.d.ts.map +1 -0
- package/dist/server/routes/responses.js +484 -0
- package/dist/server/routes/responses.js.map +1 -0
- package/dist/server/routes/runs.d.ts +5 -1
- package/dist/server/routes/runs.d.ts.map +1 -1
- package/dist/server/routes/runs.js +16 -6
- package/dist/server/routes/runs.js.map +1 -1
- package/dist/types/openai-types.d.ts +3 -1
- package/dist/types/openai-types.d.ts.map +1 -1
- package/package.json +11 -7
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAGtE,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAQjG,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAWjF,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AASxD,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { type Cogitator } from '@cogitator-ai/core';
|
|
2
|
+
import type { Agent, ImageInput, ResponseFormat as AgentResponseFormat } from '@cogitator-ai/types';
|
|
3
|
+
/** One entry of a conversation, as Chat Completions and Responses both describe it. */
|
|
4
|
+
export type ConversationItem = {
|
|
5
|
+
kind: 'system';
|
|
6
|
+
text: string;
|
|
7
|
+
} | {
|
|
8
|
+
kind: 'user';
|
|
9
|
+
text: string;
|
|
10
|
+
images: ImageInput[];
|
|
11
|
+
} | {
|
|
12
|
+
kind: 'assistant';
|
|
13
|
+
text: string;
|
|
14
|
+
} | {
|
|
15
|
+
kind: 'function_call';
|
|
16
|
+
callId: string;
|
|
17
|
+
name: string;
|
|
18
|
+
arguments: string;
|
|
19
|
+
} | {
|
|
20
|
+
kind: 'function_call_output';
|
|
21
|
+
callId: string;
|
|
22
|
+
output: string;
|
|
23
|
+
};
|
|
24
|
+
/** A function the API client runs itself. */
|
|
25
|
+
export interface ClientFunction {
|
|
26
|
+
name: string;
|
|
27
|
+
description?: string;
|
|
28
|
+
parameters?: Record<string, unknown>;
|
|
29
|
+
}
|
|
30
|
+
export type TurnToolChoice = 'auto' | 'none' | 'required' | {
|
|
31
|
+
name: string;
|
|
32
|
+
};
|
|
33
|
+
export interface AgentTurnRequest {
|
|
34
|
+
/** The registered agent the request's `model` names */
|
|
35
|
+
agent: Agent;
|
|
36
|
+
items: ConversationItem[];
|
|
37
|
+
functions: ClientFunction[];
|
|
38
|
+
toolChoice: TurnToolChoice;
|
|
39
|
+
parallelToolCalls?: boolean;
|
|
40
|
+
temperature?: number;
|
|
41
|
+
topP?: number;
|
|
42
|
+
maxTokens?: number;
|
|
43
|
+
stop?: string[];
|
|
44
|
+
responseFormat?: {
|
|
45
|
+
responseFormat?: AgentResponseFormat;
|
|
46
|
+
instructions?: string;
|
|
47
|
+
};
|
|
48
|
+
signal: AbortSignal;
|
|
49
|
+
/** Called with every token of the answer while the agent writes it */
|
|
50
|
+
onToken?: (token: string) => void;
|
|
51
|
+
}
|
|
52
|
+
/** A call of a client function the agent made; `callId` is what the client answers with. */
|
|
53
|
+
export interface ClientFunctionCall {
|
|
54
|
+
callId: string;
|
|
55
|
+
name: string;
|
|
56
|
+
arguments: string;
|
|
57
|
+
}
|
|
58
|
+
export interface AgentTurnUsage {
|
|
59
|
+
inputTokens: number;
|
|
60
|
+
outputTokens: number;
|
|
61
|
+
totalTokens: number;
|
|
62
|
+
cachedInputTokens: number;
|
|
63
|
+
reasoningTokens: number;
|
|
64
|
+
}
|
|
65
|
+
export interface AgentTurnResult {
|
|
66
|
+
/** The agent's answer, or what it said before it called client functions */
|
|
67
|
+
text: string;
|
|
68
|
+
/** The client functions to run before the conversation goes on */
|
|
69
|
+
functionCalls: ClientFunctionCall[];
|
|
70
|
+
/**
|
|
71
|
+
* Why the turn ended: `stop` with an answer, `tool_calls` with function calls for the client,
|
|
72
|
+
* `length` when the answer hit the token limit, `content_filter` when the provider withheld it
|
|
73
|
+
*/
|
|
74
|
+
finishReason: 'stop' | 'length' | 'content_filter' | 'tool_calls';
|
|
75
|
+
/** True when the model declined to answer; `text` is its explanation */
|
|
76
|
+
refusal: boolean;
|
|
77
|
+
usage: AgentTurnUsage;
|
|
78
|
+
}
|
|
79
|
+
export interface AgentTurnRunnerOptions {
|
|
80
|
+
/** How long a turn paused on client function calls waits for their outputs (default: 10 minutes) */
|
|
81
|
+
pausedTurnTtlMs?: number;
|
|
82
|
+
/** How many paused turns are kept at most (default: 1000) */
|
|
83
|
+
maxPausedTurns?: number;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* The input of a run that replays the conversation: the last user message, preceded by the
|
|
87
|
+
* transcript of what came before it, or the transcript ending with function results when the
|
|
88
|
+
* client answered function calls this server no longer waits on.
|
|
89
|
+
*/
|
|
90
|
+
export declare function renderConversation(items: readonly ConversationItem[]): {
|
|
91
|
+
input: string;
|
|
92
|
+
images: ImageInput[];
|
|
93
|
+
hasHistory: boolean;
|
|
94
|
+
};
|
|
95
|
+
export declare function assertToolChoice(agent: Agent, functions: readonly ClientFunction[], toolChoice: TurnToolChoice): void;
|
|
96
|
+
/**
|
|
97
|
+
* Runs one turn of a registered agent for the stateless OpenAI APIs (Chat Completions and
|
|
98
|
+
* Responses). The client sends the conversation, the agent answers with its own instructions and
|
|
99
|
+
* tools, and functions the client declares become tools whose calls end the turn with
|
|
100
|
+
* `tool_calls`. The paused run is kept for a while, so when the client sends the function
|
|
101
|
+
* outputs back, the same run goes on from where it stopped instead of replaying the conversation.
|
|
102
|
+
*/
|
|
103
|
+
export declare class AgentTurnRunner {
|
|
104
|
+
private readonly cogitator;
|
|
105
|
+
private paused;
|
|
106
|
+
private readonly ttlMs;
|
|
107
|
+
private readonly maxPaused;
|
|
108
|
+
constructor(cogitator: Cogitator, options?: AgentTurnRunnerOptions);
|
|
109
|
+
run(request: AgentTurnRequest): Promise<AgentTurnResult>;
|
|
110
|
+
private resume;
|
|
111
|
+
/**
|
|
112
|
+
* The result of a run: an answer, or the client function calls it paused on. Calls of server
|
|
113
|
+
* tools that wait for an approval nobody can give over this API are declined, and the run goes
|
|
114
|
+
* on.
|
|
115
|
+
*/
|
|
116
|
+
private settle;
|
|
117
|
+
private pause;
|
|
118
|
+
/**
|
|
119
|
+
* The agent of the turn: the registered agent with the client's instructions after its own,
|
|
120
|
+
* the request's sampling settings, and the client functions next to its tools.
|
|
121
|
+
*/
|
|
122
|
+
private turnAgent;
|
|
123
|
+
private clientTool;
|
|
124
|
+
/** Client function calls pause the run; anything else is left to the runtime's guardrails. */
|
|
125
|
+
private decideApproval;
|
|
126
|
+
/**
|
|
127
|
+
* The paused turn the conversation answers: its last items are the outputs of every call of a
|
|
128
|
+
* kept turn. The turn is taken out, so it resumes once.
|
|
129
|
+
*/
|
|
130
|
+
private takePausedTurn;
|
|
131
|
+
private keep;
|
|
132
|
+
private evictExpired;
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=agent-turn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-turn.d.ts","sourceRoot":"","sources":["../../../src/server/agents/agent-turn.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
import { isPausedRun } from '@cogitator-ai/core';
|
|
2
|
+
import { nanoid } from 'nanoid';
|
|
3
|
+
import { toZodParameters } from '../../client/openai-adapter.js';
|
|
4
|
+
import { InvalidRequestError } from '../../client/errors.js';
|
|
5
|
+
const TRANSCRIPT_HEADER = 'Conversation so far:\n\n';
|
|
6
|
+
const NO_APPROVAL_OVER_API = 'This tool needs an approval, which nobody can give through this API: it was not run.';
|
|
7
|
+
function emptyUsage() {
|
|
8
|
+
return {
|
|
9
|
+
inputTokens: 0,
|
|
10
|
+
outputTokens: 0,
|
|
11
|
+
totalTokens: 0,
|
|
12
|
+
cachedInputTokens: 0,
|
|
13
|
+
reasoningTokens: 0,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function addUsage(total, result) {
|
|
17
|
+
const usage = result.usage;
|
|
18
|
+
return {
|
|
19
|
+
inputTokens: total.inputTokens + usage.inputTokens,
|
|
20
|
+
outputTokens: total.outputTokens + usage.outputTokens,
|
|
21
|
+
totalTokens: total.totalTokens + usage.totalTokens,
|
|
22
|
+
cachedInputTokens: total.cachedInputTokens + (usage.cachedInputTokens ?? 0),
|
|
23
|
+
reasoningTokens: total.reasoningTokens + (usage.reasoningTokens ?? 0),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function renderItem(item) {
|
|
27
|
+
switch (item.kind) {
|
|
28
|
+
case 'system':
|
|
29
|
+
return '';
|
|
30
|
+
case 'user':
|
|
31
|
+
return `User: ${item.text}${item.images.length > 0 ? ` [${item.images.length} image(s)]` : ''}`;
|
|
32
|
+
case 'assistant':
|
|
33
|
+
return `Assistant: ${item.text}`;
|
|
34
|
+
case 'function_call':
|
|
35
|
+
return `Assistant called function ${item.name} (call ${item.callId}) with arguments: ${item.arguments}`;
|
|
36
|
+
case 'function_call_output':
|
|
37
|
+
return `Function result for call ${item.callId}: ${item.output}`;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The input of a run that replays the conversation: the last user message, preceded by the
|
|
42
|
+
* transcript of what came before it, or the transcript ending with function results when the
|
|
43
|
+
* client answered function calls this server no longer waits on.
|
|
44
|
+
*/
|
|
45
|
+
export function renderConversation(items) {
|
|
46
|
+
const conversation = items.filter((item) => item.kind !== 'system');
|
|
47
|
+
const last = conversation.at(-1);
|
|
48
|
+
if (!last) {
|
|
49
|
+
throw new InvalidRequestError('The conversation has no message to answer');
|
|
50
|
+
}
|
|
51
|
+
if (last.kind === 'user') {
|
|
52
|
+
const prior = conversation.slice(0, -1);
|
|
53
|
+
if (prior.length === 0)
|
|
54
|
+
return { input: last.text, images: last.images, hasHistory: false };
|
|
55
|
+
return {
|
|
56
|
+
input: `${TRANSCRIPT_HEADER}${prior.map(renderItem).join('\n\n')}\n\nUser: ${last.text}`,
|
|
57
|
+
images: last.images,
|
|
58
|
+
hasHistory: true,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
input: `${TRANSCRIPT_HEADER}${conversation.map(renderItem).join('\n\n')}\n\nContinue the conversation.`,
|
|
63
|
+
images: [],
|
|
64
|
+
hasHistory: true,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Refuses a `tool_choice` that names neither a tool of the agent nor a function of the client,
|
|
69
|
+
* so the request fails before any output is sent.
|
|
70
|
+
*/
|
|
71
|
+
/**
|
|
72
|
+
* The run's `toolChoice` for a request's `tool_choice`, when it obliges the model to call a
|
|
73
|
+
* function: `'required'` or one function by name. The run forces it until the model makes a
|
|
74
|
+
* call. `'none'` and `'auto'` need none, the tools the turn offers already say it.
|
|
75
|
+
*/
|
|
76
|
+
function mandatoryToolChoice(choice) {
|
|
77
|
+
if (choice === 'required')
|
|
78
|
+
return 'required';
|
|
79
|
+
if (typeof choice === 'object')
|
|
80
|
+
return { type: 'function', function: { name: choice.name } };
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
export function assertToolChoice(agent, functions, toolChoice) {
|
|
84
|
+
if (typeof toolChoice !== 'object')
|
|
85
|
+
return;
|
|
86
|
+
const known = agent.tools.some((tool) => tool.name === toolChoice.name) ||
|
|
87
|
+
functions.some((fn) => fn.name === toolChoice.name);
|
|
88
|
+
if (!known) {
|
|
89
|
+
throw new InvalidRequestError(`tool_choice names an unknown function: ${toolChoice.name}`, 'tool_choice');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Runs one turn of a registered agent for the stateless OpenAI APIs (Chat Completions and
|
|
94
|
+
* Responses). The client sends the conversation, the agent answers with its own instructions and
|
|
95
|
+
* tools, and functions the client declares become tools whose calls end the turn with
|
|
96
|
+
* `tool_calls`. The paused run is kept for a while, so when the client sends the function
|
|
97
|
+
* outputs back, the same run goes on from where it stopped instead of replaying the conversation.
|
|
98
|
+
*/
|
|
99
|
+
export class AgentTurnRunner {
|
|
100
|
+
cogitator;
|
|
101
|
+
paused = new Map();
|
|
102
|
+
ttlMs;
|
|
103
|
+
maxPaused;
|
|
104
|
+
constructor(cogitator, options = {}) {
|
|
105
|
+
this.cogitator = cogitator;
|
|
106
|
+
this.ttlMs = options.pausedTurnTtlMs ?? 10 * 60 * 1000;
|
|
107
|
+
this.maxPaused = options.maxPausedTurns ?? 1000;
|
|
108
|
+
}
|
|
109
|
+
async run(request) {
|
|
110
|
+
this.evictExpired();
|
|
111
|
+
const resumable = this.takePausedTurn(request.items);
|
|
112
|
+
if (resumable)
|
|
113
|
+
return this.resume(resumable, request);
|
|
114
|
+
const outputs = new Map();
|
|
115
|
+
const { agent, clientFunctions } = this.turnAgent(request, outputs);
|
|
116
|
+
const { input, images, hasHistory } = renderConversation(request.items);
|
|
117
|
+
const toolChoice = mandatoryToolChoice(request.toolChoice);
|
|
118
|
+
const result = await this.cogitator.run(agent, {
|
|
119
|
+
input,
|
|
120
|
+
...(images.length > 0 && { images }),
|
|
121
|
+
threadId: `turn_${nanoid()}`,
|
|
122
|
+
useMemory: false,
|
|
123
|
+
signal: request.signal,
|
|
124
|
+
stream: !!request.onToken,
|
|
125
|
+
onToken: request.onToken,
|
|
126
|
+
...(request.parallelToolCalls !== undefined && {
|
|
127
|
+
parallelToolCalls: request.parallelToolCalls,
|
|
128
|
+
}),
|
|
129
|
+
onApproval: (approval) => this.decideApproval(approval, clientFunctions),
|
|
130
|
+
...(hasHistory && { loadHistory: false }),
|
|
131
|
+
...(toolChoice && { toolChoice }),
|
|
132
|
+
});
|
|
133
|
+
return this.settle(agent, result, outputs, clientFunctions, request, emptyUsage());
|
|
134
|
+
}
|
|
135
|
+
async resume(turn, request) {
|
|
136
|
+
const decisions = {};
|
|
137
|
+
for (const [clientCallId, modelCallId] of turn.callIds) {
|
|
138
|
+
const output = request.items.find((item) => item.kind === 'function_call_output' && item.callId === clientCallId);
|
|
139
|
+
turn.outputs.set(modelCallId, output?.output ?? '');
|
|
140
|
+
decisions[modelCallId] = { approved: true };
|
|
141
|
+
}
|
|
142
|
+
const result = await this.cogitator.resume(turn.agent, turn.checkpoint, {
|
|
143
|
+
decisions,
|
|
144
|
+
useMemory: false,
|
|
145
|
+
signal: request.signal,
|
|
146
|
+
stream: !!request.onToken,
|
|
147
|
+
onToken: request.onToken,
|
|
148
|
+
onApproval: (approval) => this.decideApproval(approval, turn.clientFunctions),
|
|
149
|
+
});
|
|
150
|
+
return this.settle(turn.agent, result, turn.outputs, turn.clientFunctions, request, emptyUsage());
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* The result of a run: an answer, or the client function calls it paused on. Calls of server
|
|
154
|
+
* tools that wait for an approval nobody can give over this API are declined, and the run goes
|
|
155
|
+
* on.
|
|
156
|
+
*/
|
|
157
|
+
async settle(agent, initial, outputs, clientFunctions, request, initialUsage) {
|
|
158
|
+
let result = initial;
|
|
159
|
+
let usage = addUsage(initialUsage, result);
|
|
160
|
+
while (isPausedRun(result)) {
|
|
161
|
+
const serverCalls = result.pendingApprovals.filter((p) => !clientFunctions.has(p.toolName));
|
|
162
|
+
if (serverCalls.length === 0) {
|
|
163
|
+
return this.pause(agent, result, outputs, clientFunctions, usage);
|
|
164
|
+
}
|
|
165
|
+
if (!result.checkpoint) {
|
|
166
|
+
throw new Error('The run paused without a checkpoint to resume from');
|
|
167
|
+
}
|
|
168
|
+
result = await this.cogitator.resume(agent, result.checkpoint, {
|
|
169
|
+
decisions: Object.fromEntries(serverCalls.map((call) => [
|
|
170
|
+
call.toolCallId,
|
|
171
|
+
{ approved: false, reason: NO_APPROVAL_OVER_API },
|
|
172
|
+
])),
|
|
173
|
+
useMemory: false,
|
|
174
|
+
signal: request.signal,
|
|
175
|
+
stream: !!request.onToken,
|
|
176
|
+
onToken: request.onToken,
|
|
177
|
+
onApproval: (approval) => this.decideApproval(approval, clientFunctions),
|
|
178
|
+
});
|
|
179
|
+
usage = addUsage(usage, result);
|
|
180
|
+
}
|
|
181
|
+
return {
|
|
182
|
+
text: result.output,
|
|
183
|
+
functionCalls: [],
|
|
184
|
+
finishReason: result.truncated
|
|
185
|
+
? 'length'
|
|
186
|
+
: result.blocked === 'content_filter'
|
|
187
|
+
? 'content_filter'
|
|
188
|
+
: 'stop',
|
|
189
|
+
refusal: result.blocked === 'refusal',
|
|
190
|
+
usage,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
pause(agent, result, outputs, clientFunctions, usage) {
|
|
194
|
+
if (!result.checkpoint) {
|
|
195
|
+
throw new Error('The run paused without a checkpoint to resume from');
|
|
196
|
+
}
|
|
197
|
+
const callIds = new Map();
|
|
198
|
+
const functionCalls = result.pendingApprovals.map((approval) => {
|
|
199
|
+
const callId = `call_${nanoid(24)}`;
|
|
200
|
+
callIds.set(callId, approval.toolCallId);
|
|
201
|
+
return {
|
|
202
|
+
callId,
|
|
203
|
+
name: approval.toolName,
|
|
204
|
+
arguments: JSON.stringify(approval.arguments),
|
|
205
|
+
};
|
|
206
|
+
});
|
|
207
|
+
this.keep({
|
|
208
|
+
agent,
|
|
209
|
+
checkpoint: result.checkpoint,
|
|
210
|
+
callIds,
|
|
211
|
+
outputs,
|
|
212
|
+
clientFunctions,
|
|
213
|
+
expiresAt: Date.now() + this.ttlMs,
|
|
214
|
+
});
|
|
215
|
+
return {
|
|
216
|
+
text: result.output,
|
|
217
|
+
functionCalls,
|
|
218
|
+
finishReason: 'tool_calls',
|
|
219
|
+
refusal: false,
|
|
220
|
+
usage,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* The agent of the turn: the registered agent with the client's instructions after its own,
|
|
225
|
+
* the request's sampling settings, and the client functions next to its tools.
|
|
226
|
+
*/
|
|
227
|
+
turnAgent(request, outputs) {
|
|
228
|
+
const base = request.agent;
|
|
229
|
+
const serverToolNames = new Set(base.tools.map((tool) => tool.name));
|
|
230
|
+
const functions = request.functions.filter((fn) => !serverToolNames.has(fn.name));
|
|
231
|
+
let tools = [...base.tools, ...functions.map((fn) => this.clientTool(fn, outputs))];
|
|
232
|
+
if (request.toolChoice === 'none') {
|
|
233
|
+
tools = [];
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
assertToolChoice(request.agent, request.functions, request.toolChoice);
|
|
237
|
+
}
|
|
238
|
+
const clientInstructions = request.items
|
|
239
|
+
.filter((item) => item.kind === 'system')
|
|
240
|
+
.map((item) => item.text);
|
|
241
|
+
const instructions = [
|
|
242
|
+
base.instructions,
|
|
243
|
+
...clientInstructions,
|
|
244
|
+
request.responseFormat?.instructions ?? '',
|
|
245
|
+
]
|
|
246
|
+
.filter((part) => part.length > 0)
|
|
247
|
+
.join('\n\n');
|
|
248
|
+
const overrides = { instructions, tools };
|
|
249
|
+
if (request.temperature !== undefined)
|
|
250
|
+
overrides.temperature = request.temperature;
|
|
251
|
+
if (request.topP !== undefined)
|
|
252
|
+
overrides.topP = request.topP;
|
|
253
|
+
if (request.maxTokens !== undefined)
|
|
254
|
+
overrides.maxTokens = request.maxTokens;
|
|
255
|
+
if (request.stop !== undefined)
|
|
256
|
+
overrides.stopSequences = request.stop;
|
|
257
|
+
if (request.responseFormat?.responseFormat) {
|
|
258
|
+
overrides.responseFormat = request.responseFormat.responseFormat;
|
|
259
|
+
}
|
|
260
|
+
return {
|
|
261
|
+
agent: base.clone(overrides),
|
|
262
|
+
clientFunctions: new Set(functions.map((fn) => fn.name)),
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
clientTool(fn, outputs) {
|
|
266
|
+
return {
|
|
267
|
+
name: fn.name,
|
|
268
|
+
description: fn.description ?? fn.name,
|
|
269
|
+
parameters: toZodParameters(fn.parameters),
|
|
270
|
+
requiresApproval: true,
|
|
271
|
+
execute: async (_args, context) => {
|
|
272
|
+
const output = context.toolCallId !== undefined ? outputs.get(context.toolCallId) : undefined;
|
|
273
|
+
if (output === undefined) {
|
|
274
|
+
throw new Error(`Function "${fn.name}" runs on the API client, which sent no output for this call`);
|
|
275
|
+
}
|
|
276
|
+
return output;
|
|
277
|
+
},
|
|
278
|
+
toJSON: () => {
|
|
279
|
+
const schema = (fn.parameters ?? {});
|
|
280
|
+
return {
|
|
281
|
+
name: fn.name,
|
|
282
|
+
description: fn.description ?? fn.name,
|
|
283
|
+
parameters: {
|
|
284
|
+
type: 'object',
|
|
285
|
+
properties: schema.properties ?? {},
|
|
286
|
+
required: schema.required,
|
|
287
|
+
},
|
|
288
|
+
};
|
|
289
|
+
},
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
/** Client function calls pause the run; anything else is left to the runtime's guardrails. */
|
|
293
|
+
decideApproval(approval, clientFunctions) {
|
|
294
|
+
return clientFunctions.has(approval.toolName) ? 'pause' : undefined;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* The paused turn the conversation answers: its last items are the outputs of every call of a
|
|
298
|
+
* kept turn. The turn is taken out, so it resumes once.
|
|
299
|
+
*/
|
|
300
|
+
takePausedTurn(items) {
|
|
301
|
+
const trailing = [];
|
|
302
|
+
for (let i = items.length - 1; i >= 0; i--) {
|
|
303
|
+
const item = items[i];
|
|
304
|
+
if (item.kind !== 'function_call_output')
|
|
305
|
+
break;
|
|
306
|
+
trailing.push(item.callId);
|
|
307
|
+
}
|
|
308
|
+
if (trailing.length === 0)
|
|
309
|
+
return undefined;
|
|
310
|
+
const turn = this.paused.get(trailing[0]);
|
|
311
|
+
if (!turn || turn.expiresAt <= Date.now())
|
|
312
|
+
return undefined;
|
|
313
|
+
const answered = new Set(trailing);
|
|
314
|
+
for (const callId of turn.callIds.keys()) {
|
|
315
|
+
if (!answered.has(callId))
|
|
316
|
+
return undefined;
|
|
317
|
+
}
|
|
318
|
+
for (const callId of turn.callIds.keys())
|
|
319
|
+
this.paused.delete(callId);
|
|
320
|
+
return turn;
|
|
321
|
+
}
|
|
322
|
+
keep(turn) {
|
|
323
|
+
for (const callId of turn.callIds.keys())
|
|
324
|
+
this.paused.set(callId, turn);
|
|
325
|
+
while (this.paused.size > this.maxPaused) {
|
|
326
|
+
const oldest = this.paused.keys().next().value;
|
|
327
|
+
if (oldest === undefined)
|
|
328
|
+
break;
|
|
329
|
+
this.paused.delete(oldest);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
evictExpired() {
|
|
333
|
+
const now = Date.now();
|
|
334
|
+
for (const [callId, turn] of this.paused) {
|
|
335
|
+
if (turn.expiresAt <= now)
|
|
336
|
+
this.paused.delete(callId);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
//# sourceMappingURL=agent-turn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-turn.js","sourceRoot":"","sources":["../../../src/server/agents/agent-turn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAajE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAqF1D,MAAM,iBAAiB,GAAG,0BAA0B,CAAC;AACrD,MAAM,oBAAoB,GACxB,sFAAsF,CAAC;AAEzF,SAAS,UAAU;IACjB,OAAO;QACL,WAAW,EAAE,CAAC;QACd,YAAY,EAAE,CAAC;QACf,WAAW,EAAE,CAAC;QACd,iBAAiB,EAAE,CAAC;QACpB,eAAe,EAAE,CAAC;KACnB,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,KAAqB,EAAE,MAAiB;IACxD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAC3B,OAAO;QACL,WAAW,EAAE,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW;QAClD,YAAY,EAAE,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC,YAAY;QACrD,WAAW,EAAE,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW;QAClD,iBAAiB,EAAE,KAAK,CAAC,iBAAiB,GAAG,CAAC,KAAK,CAAC,iBAAiB,IAAI,CAAC,CAAC;QAC3E,eAAe,EAAE,KAAK,CAAC,eAAe,GAAG,CAAC,KAAK,CAAC,eAAe,IAAI,CAAC,CAAC;KACtE,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,IAAsB;IACxC,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,QAAQ;YACX,OAAO,EAAE,CAAC;QACZ,KAAK,MAAM;YACT,OAAO,SAAS,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,MAAM,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAClG,KAAK,WAAW;YACd,OAAO,cAAc,IAAI,CAAC,IAAI,EAAE,CAAC;QACnC,KAAK,eAAe;YAClB,OAAO,6BAA6B,IAAI,CAAC,IAAI,UAAU,IAAI,CAAC,MAAM,qBAAqB,IAAI,CAAC,SAAS,EAAE,CAAC;QAC1G,KAAK,sBAAsB;YACzB,OAAO,4BAA4B,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;IACrE,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAkC;IAKnE,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACjC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,mBAAmB,CAAC,2CAA2C,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACxC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;QAC5F,OAAO;YACL,KAAK,EAAE,GAAG,iBAAiB,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,IAAI,CAAC,IAAI,EAAE;YACxF,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,UAAU,EAAE,IAAI;SACjB,CAAC;IACJ,CAAC;IACD,OAAO;QACL,KAAK,EAAE,GAAG,iBAAiB,GAAG,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,gCAAgC;QACvG,MAAM,EAAE,EAAE;QACV,UAAU,EAAE,IAAI;KACjB,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,MAAsB;IACjD,IAAI,MAAM,KAAK,UAAU;QAAE,OAAO,UAAU,CAAC;IAC7C,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;IAC7F,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,KAAY,EACZ,SAAoC,EACpC,UAA0B;IAE1B,IAAI,OAAO,UAAU,KAAK,QAAQ;QAAE,OAAO;IAC3C,MAAM,KAAK,GACT,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC,IAAI,CAAC;QACzD,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,UAAU,CAAC,IAAI,CAAC,CAAC;IACtD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,mBAAmB,CAC3B,0CAA0C,UAAU,CAAC,IAAI,EAAE,EAC3D,aAAa,CACd,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,OAAO,eAAe;IAMP;IALX,MAAM,GAAG,IAAI,GAAG,EAAsB,CAAC;IAC9B,KAAK,CAAS;IACd,SAAS,CAAS;IAEnC,YACmB,SAAoB,EACrC,UAAkC,EAAE;QADnB,cAAS,GAAT,SAAS,CAAW;QAGrC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,eAAe,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;QACvD,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,cAAc,IAAI,IAAI,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,OAAyB;QACjC,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACrD,IAAI,SAAS;YAAE,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAEtD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC1C,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACpE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,kBAAkB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACxE,MAAM,UAAU,GAAG,mBAAmB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC3D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE;YAC7C,KAAK;YACL,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;YACpC,QAAQ,EAAE,QAAQ,MAAM,EAAE,EAAE;YAC5B,SAAS,EAAE,KAAK;YAChB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO;YACzB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,GAAG,CAAC,OAAO,CAAC,iBAAiB,KAAK,SAAS,IAAI;gBAC7C,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;aAC7C,CAAC;YACF,UAAU,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,eAAe,CAAC;YACxE,GAAG,CAAC,UAAU,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;YACzC,GAAG,CAAC,UAAU,IAAI,EAAE,UAAU,EAAE,CAAC;SAClC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;IACrF,CAAC;IAEO,KAAK,CAAC,MAAM,CAAC,IAAgB,EAAE,OAAyB;QAC9D,MAAM,SAAS,GAAyC,EAAE,CAAC;QAC3D,KAAK,MAAM,CAAC,YAAY,EAAE,WAAW,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACvD,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAC/B,CAAC,IAAI,EAAuE,EAAE,CAC5E,IAAI,CAAC,IAAI,KAAK,sBAAsB,IAAI,IAAI,CAAC,MAAM,KAAK,YAAY,CACvE,CAAC;YACF,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC;YACpD,SAAS,CAAC,WAAW,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAC9C,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE;YACtE,SAAS;YACT,SAAS,EAAE,KAAK;YAChB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO;YACzB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,UAAU,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,CAAC,eAAe,CAAC;SAC9E,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,MAAM,CAChB,IAAI,CAAC,KAAK,EACV,MAAM,EACN,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,eAAe,EACpB,OAAO,EACP,UAAU,EAAE,CACb,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,MAAM,CAClB,KAAY,EACZ,OAAkB,EAClB,OAA4B,EAC5B,eAAoC,EACpC,OAAyB,EACzB,YAA4B;QAE5B,IAAI,MAAM,GAAG,OAAO,CAAC;QACrB,IAAI,KAAK,GAAG,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QAC3C,OAAO,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,MAAM,WAAW,GAAG,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC5F,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,KAAK,CAAC,CAAC;YACpE,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;gBACvB,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;YACxE,CAAC;YACD,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,UAAU,EAAE;gBAC7D,SAAS,EAAE,MAAM,CAAC,WAAW,CAC3B,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;oBACxB,IAAI,CAAC,UAAU;oBACf,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,oBAAoB,EAAE;iBAClD,CAAC,CACH;gBACD,SAAS,EAAE,KAAK;gBAChB,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO;gBACzB,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,UAAU,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,eAAe,CAAC;aACzE,CAAC,CAAC;YACH,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAClC,CAAC;QAED,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,MAAM;YACnB,aAAa,EAAE,EAAE;YACjB,YAAY,EAAE,MAAM,CAAC,SAAS;gBAC5B,CAAC,CAAC,QAAQ;gBACV,CAAC,CAAC,MAAM,CAAC,OAAO,KAAK,gBAAgB;oBACnC,CAAC,CAAC,gBAAgB;oBAClB,CAAC,CAAC,MAAM;YACZ,OAAO,EAAE,MAAM,CAAC,OAAO,KAAK,SAAS;YACrC,KAAK;SACN,CAAC;IACJ,CAAC;IAEO,KAAK,CACX,KAAY,EACZ,MAAwE,EACxE,OAA4B,EAC5B,eAAoC,EACpC,KAAqB;QAErB,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;QACxE,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC1C,MAAM,aAAa,GAAG,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;YAC7D,MAAM,MAAM,GAAG,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;YACzC,OAAO;gBACL,MAAM;gBACN,IAAI,EAAE,QAAQ,CAAC,QAAQ;gBACvB,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;aAC9C,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,CAAC;YACR,KAAK;YACL,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,OAAO;YACP,OAAO;YACP,eAAe;YACf,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK;SACnC,CAAC,CAAC;QACH,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,MAAM;YACnB,aAAa;YACb,YAAY,EAAE,YAAY;YAC1B,OAAO,EAAE,KAAK;YACd,KAAK;SACN,CAAC;IACJ,CAAC;IAED;;;OAGG;IACK,SAAS,CACf,OAAyB,EACzB,OAA4B;QAE5B,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC;QAC3B,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACrE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;QAClF,IAAI,KAAK,GAAW,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;QAC5F,IAAI,OAAO,CAAC,UAAU,KAAK,MAAM,EAAE,CAAC;YAClC,KAAK,GAAG,EAAE,CAAC;QACb,CAAC;aAAM,CAAC;YACN,gBAAgB,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;QACzE,CAAC;QAED,MAAM,kBAAkB,GAAG,OAAO,CAAC,KAAK;aACrC,MAAM,CACL,CAAC,IAAI,EAAyD,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CACxF;aACA,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,MAAM,YAAY,GAAG;YACnB,IAAI,CAAC,YAAY;YACjB,GAAG,kBAAkB;YACrB,OAAO,CAAC,cAAc,EAAE,YAAY,IAAI,EAAE;SAC3C;aACE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;aACjC,IAAI,CAAC,MAAM,CAAC,CAAC;QAEhB,MAAM,SAAS,GAAyB,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;QAChE,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS;YAAE,SAAS,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QACnF,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS;YAAE,SAAS,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QAC9D,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS;YAAE,SAAS,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QAC7E,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS;YAAE,SAAS,CAAC,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;QACvE,IAAI,OAAO,CAAC,cAAc,EAAE,cAAc,EAAE,CAAC;YAC3C,SAAS,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,cAAc,CAAC;QACnE,CAAC;QACD,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;YAC5B,eAAe,EAAE,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;SACzD,CAAC;IACJ,CAAC;IAEO,UAAU,CAAC,EAAkB,EAAE,OAA4B;QACjE,OAAO;YACL,IAAI,EAAE,EAAE,CAAC,IAAI;YACb,WAAW,EAAE,EAAE,CAAC,WAAW,IAAI,EAAE,CAAC,IAAI;YACtC,UAAU,EAAE,eAAe,CAAC,EAAE,CAAC,UAAU,CAAC;YAC1C,gBAAgB,EAAE,IAAI;YACtB,OAAO,EAAE,KAAK,EAAE,KAAc,EAAE,OAAO,EAAE,EAAE;gBACzC,MAAM,MAAM,GACV,OAAO,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBACjF,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBACzB,MAAM,IAAI,KAAK,CACb,aAAa,EAAE,CAAC,IAAI,8DAA8D,CACnF,CAAC;gBACJ,CAAC;gBACD,OAAO,MAAM,CAAC;YAChB,CAAC;YACD,MAAM,EAAE,GAAG,EAAE;gBACX,MAAM,MAAM,GAAG,CAAC,EAAE,CAAC,UAAU,IAAI,EAAE,CAGlC,CAAC;gBACF,OAAO;oBACL,IAAI,EAAE,EAAE,CAAC,IAAI;oBACb,WAAW,EAAE,EAAE,CAAC,WAAW,IAAI,EAAE,CAAC,IAAI;oBACtC,UAAU,EAAE;wBACV,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,EAAE;wBACnC,QAAQ,EAAE,MAAM,CAAC,QAAQ;qBAC1B;iBACF,CAAC;YACJ,CAAC;SACF,CAAC;IACJ,CAAC;IAED,8FAA8F;IACtF,cAAc,CACpB,QAA6B,EAC7B,eAAoC;QAEpC,OAAO,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IACtE,CAAC;IAED;;;OAGG;IACK,cAAc,CAAC,KAAkC;QACvD,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,IAAI,IAAI,CAAC,IAAI,KAAK,sBAAsB;gBAAE,MAAM;YAChD,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC7B,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1C,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE;YAAE,OAAO,SAAS,CAAC;QAC5D,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;QACnC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YACzC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC;gBAAE,OAAO,SAAS,CAAC;QAC9C,CAAC;QACD,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;YAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACrE,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,IAAI,CAAC,IAAgB;QAC3B,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;YAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACxE,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YACzC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;YAC/C,IAAI,MAAM,KAAK,SAAS;gBAAE,MAAM;YAChC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAEO,YAAY;QAClB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,KAAK,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACzC,IAAI,IAAI,CAAC,SAAS,IAAI,GAAG;gBAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { Agent, ImageInput } from '@cogitator-ai/types';
|
|
2
|
+
import type { FastifyReply } from 'fastify';
|
|
3
|
+
import type { z } from 'zod';
|
|
4
|
+
import type { AgentTurnUsage } from './agent-turn.js';
|
|
5
|
+
/** The agents the OpenAI endpoints serve, by the model id clients send. */
|
|
6
|
+
export declare class AgentDirectory {
|
|
7
|
+
private readonly agents;
|
|
8
|
+
readonly createdAt: number;
|
|
9
|
+
constructor(agents: Readonly<Record<string, Agent>>);
|
|
10
|
+
get(model: string): Agent | undefined;
|
|
11
|
+
names(): string[];
|
|
12
|
+
}
|
|
13
|
+
/** An image of a request, as the runtime takes it: a data URL becomes base64 data. */
|
|
14
|
+
export declare function toImageInput(url: string): ImageInput;
|
|
15
|
+
/** The body parsed with `schema`, or an `InvalidRequestError` naming the parameter at fault. */
|
|
16
|
+
export declare function parseRequestBody<T extends z.ZodType>(schema: T, body: unknown): z.output<T>;
|
|
17
|
+
export declare function sendModelNotFound(reply: FastifyReply, model: string): FastifyReply;
|
|
18
|
+
/** The message a client may see for a failed run: deliberate errors as they are, others masked. */
|
|
19
|
+
export declare function clientErrorMessage(error: unknown, context: string): string;
|
|
20
|
+
/** Answer a request that failed before any output was sent, in the OpenAI error format. */
|
|
21
|
+
export declare function sendTurnError(reply: FastifyReply, error: unknown, context: string): FastifyReply;
|
|
22
|
+
/** Usage in the Chat Completions shape. */
|
|
23
|
+
export declare function chatUsage(usage: AgentTurnUsage): {
|
|
24
|
+
prompt_tokens: number;
|
|
25
|
+
completion_tokens: number;
|
|
26
|
+
total_tokens: number;
|
|
27
|
+
prompt_tokens_details: {
|
|
28
|
+
cached_tokens: number;
|
|
29
|
+
};
|
|
30
|
+
completion_tokens_details: {
|
|
31
|
+
reasoning_tokens: number;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
/** Usage in the Responses shape. */
|
|
35
|
+
export declare function responseUsage(usage: AgentTurnUsage): {
|
|
36
|
+
input_tokens: number;
|
|
37
|
+
input_tokens_details: {
|
|
38
|
+
cached_tokens: number;
|
|
39
|
+
};
|
|
40
|
+
output_tokens: number;
|
|
41
|
+
output_tokens_details: {
|
|
42
|
+
reasoning_tokens: number;
|
|
43
|
+
};
|
|
44
|
+
total_tokens: number;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* A signal that aborts when the client disconnects before the response is sent. It watches the
|
|
48
|
+
* response, since the request emits `close` as soon as its body has been read.
|
|
49
|
+
*/
|
|
50
|
+
export declare function abortOnDisconnect(reply: FastifyReply): AbortSignal;
|
|
51
|
+
export interface EventStream {
|
|
52
|
+
/** Aborted when the client disconnects */
|
|
53
|
+
signal: AbortSignal;
|
|
54
|
+
write(frame: string): void;
|
|
55
|
+
end(): void;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Take over the reply for Server-Sent Events. While it is open a heartbeat comment goes out
|
|
59
|
+
* every `heartbeatMs`, and the signal aborts when the client disconnects, so the run stops.
|
|
60
|
+
*/
|
|
61
|
+
export declare function openEventStream(reply: FastifyReply, heartbeatMs: number): EventStream;
|
|
62
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/server/agents/shared.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAE7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAG7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAUnD,2EAA2E;AAC3E,qBAAa,cAAc;IAGb,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,QAAQ,CAAC,SAAS,SAAiC;gBAEtB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAEpE,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS;IAIrC,KAAK,IAAI,MAAM,EAAE;CAGlB;AAED,sFAAsF;AACtF,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAMpD;AAED,gGAAgG;AAChG,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAS3F;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,CAWlF;AAED,mGAAmG;AACnG,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAM1E;AAED,2FAA2F;AAC3F,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,YAAY,CAWhG;AAED,2CAA2C;AAC3C,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc;;;;;;;;;;EAQ9C;AAED,oCAAoC;AACpC,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc;;;;;;;;;;EAQlD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,WAAW,CAMlE;AAED,MAAM,WAAW,WAAW;IAC1B,0CAA0C;IAC1C,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,GAAG,IAAI,IAAI,CAAC;CACb;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,GAAG,WAAW,CA6BrF"}
|