@botpress/evals 1.18.3
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/dist/client.d.ts +50 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +123 -0
- package/dist/client.js.map +7 -0
- package/dist/definition.d.ts +113 -0
- package/dist/definition.d.ts.map +1 -0
- package/dist/definition.js +25 -0
- package/dist/definition.js.map +7 -0
- package/dist/graders/index.d.ts +12 -0
- package/dist/graders/index.d.ts.map +1 -0
- package/dist/graders/index.js +466 -0
- package/dist/graders/index.js.map +7 -0
- package/dist/graders/llm.d.ts +23 -0
- package/dist/graders/llm.d.ts.map +1 -0
- package/dist/graders/llm.js +125 -0
- package/dist/graders/llm.js.map +7 -0
- package/dist/graders/match.d.ts +11 -0
- package/dist/graders/match.d.ts.map +1 -0
- package/dist/graders/match.js +48 -0
- package/dist/graders/match.js.map +7 -0
- package/dist/graders/outcome.d.ts +11 -0
- package/dist/graders/outcome.d.ts.map +1 -0
- package/dist/graders/outcome.js +148 -0
- package/dist/graders/outcome.js.map +7 -0
- package/dist/graders/response.d.ts +10 -0
- package/dist/graders/response.d.ts.map +1 -0
- package/dist/graders/response.js +155 -0
- package/dist/graders/response.js.map +7 -0
- package/dist/graders/state.d.ts +16 -0
- package/dist/graders/state.d.ts.map +1 -0
- package/dist/graders/state.js +101 -0
- package/dist/graders/state.js.map +7 -0
- package/dist/graders/timing.d.ts +7 -0
- package/dist/graders/timing.d.ts.map +1 -0
- package/dist/graders/timing.js +63 -0
- package/dist/graders/timing.js.map +7 -0
- package/dist/graders/tools.d.ts +7 -0
- package/dist/graders/tools.d.ts.map +1 -0
- package/dist/graders/tools.js +122 -0
- package/dist/graders/tools.js.map +7 -0
- package/dist/graders/workflow.d.ts +7 -0
- package/dist/graders/workflow.d.ts.map +1 -0
- package/dist/graders/workflow.js +34 -0
- package/dist/graders/workflow.js.map +7 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +7 -0
- package/dist/loader.d.ts +11 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +114 -0
- package/dist/loader.js.map +7 -0
- package/dist/runner.d.ts +25 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +1536 -0
- package/dist/runner.js.map +7 -0
- package/dist/sse-collector.d.ts +148 -0
- package/dist/sse-collector.d.ts.map +1 -0
- package/dist/sse-collector.js +386 -0
- package/dist/sse-collector.js.map +7 -0
- package/dist/trace.d.ts +56 -0
- package/dist/trace.d.ts.map +1 -0
- package/dist/trace.js +1 -0
- package/dist/trace.js.map +7 -0
- package/dist/transformer.d.ts +18 -0
- package/dist/transformer.d.ts.map +1 -0
- package/dist/transformer.js +101 -0
- package/dist/transformer.js.map +7 -0
- package/dist/types.d.ts +184 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +25 -0
- package/dist/types.js.map +7 -0
- package/package.json +99 -0
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chat client for eval conversations.
|
|
3
|
+
* Drives conversations against a running ADK bot via @botpress/chat.
|
|
4
|
+
*
|
|
5
|
+
* This is a send-only client. Observation (bot responses, tool calls, state)
|
|
6
|
+
* is handled by the SSECollector via trace spans — not via WebSocket listeners.
|
|
7
|
+
*/
|
|
8
|
+
import type { ChatClient } from './types';
|
|
9
|
+
export declare function setDefaultChatClient(chatClient: ChatClient | null): void;
|
|
10
|
+
/**
|
|
11
|
+
* A send-only chat session that maintains a single client connection across turns.
|
|
12
|
+
* Messages and events are fire-and-forget; the SSECollector observes results via traces.
|
|
13
|
+
*/
|
|
14
|
+
export declare class ChatSession {
|
|
15
|
+
private webhookId;
|
|
16
|
+
private chatClient?;
|
|
17
|
+
private client;
|
|
18
|
+
private conversationId;
|
|
19
|
+
constructor(webhookId: string, chatClient?: ChatClient);
|
|
20
|
+
connect(): Promise<void>;
|
|
21
|
+
get userId(): string;
|
|
22
|
+
ensureConversation(): Promise<string>;
|
|
23
|
+
/**
|
|
24
|
+
* Send a user message. Fire-and-forget — observation is via SSECollector.
|
|
25
|
+
*/
|
|
26
|
+
sendMessage(message: string): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Send an event. Fire-and-forget — observation is via SSECollector.
|
|
29
|
+
*/
|
|
30
|
+
sendEvent(type: string, payload: Record<string, unknown>): Promise<void>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Discover the chat integration's webhookId from a bot.
|
|
34
|
+
*
|
|
35
|
+
* Evals talk to the bot through the `chat` integration (via @botpress/chat).
|
|
36
|
+
* If the bot doesn't have that integration installed, evals can't run.
|
|
37
|
+
*/
|
|
38
|
+
export declare function discoverWebhookId(botId: string, token: string, apiUrl: string): Promise<string>;
|
|
39
|
+
/**
|
|
40
|
+
* Verify the bot has at least one Conversation bound to `chat.channel`.
|
|
41
|
+
*
|
|
42
|
+
* The `chat` integration can be installed without any handler listening on its
|
|
43
|
+
* channel — in that case messages sent via @botpress/chat produce no response
|
|
44
|
+
* and the caller times out silently. Fail fast with actionable guidance instead.
|
|
45
|
+
*
|
|
46
|
+
* Uses the dev server's `/api/agent` endpoint, so this is a no-op against
|
|
47
|
+
* production bots (no devServerUrl).
|
|
48
|
+
*/
|
|
49
|
+
export declare function assertChatChannelBound(devServerUrl: string, headers?: Record<string, string>): Promise<void>;
|
|
50
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAwB,MAAM,SAAS,CAAA;AAI/D,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAExE;AAcD;;;GAGG;AACH,qBAAa,WAAW;IAKpB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,UAAU,CAAC;IALrB,OAAO,CAAC,MAAM,CAAoC;IAClD,OAAO,CAAC,cAAc,CAAsB;gBAGlC,SAAS,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,UAAU;IAG3B,OAAO;IAKb,IAAI,MAAM,IAAI,MAAM,CAKnB;IAEK,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC;IAc3C;;OAEG;IACG,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASjD;;OAEG;IACG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAQ/E;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAqBrG;AAED;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,CAC1C,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACnC,OAAO,CAAC,IAAI,CAAC,CAsCf"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
import { Client as BpClient } from "@botpress/client";
|
|
3
|
+
import { createRequire } from "module";
|
|
4
|
+
var defaultChatClient = null;
|
|
5
|
+
function setDefaultChatClient(chatClient) {
|
|
6
|
+
defaultChatClient = chatClient;
|
|
7
|
+
}
|
|
8
|
+
function getDefaultChatClient() {
|
|
9
|
+
if (defaultChatClient) return defaultChatClient;
|
|
10
|
+
const require2 = createRequire(import.meta.url);
|
|
11
|
+
const mod = require2("@botpress/chat");
|
|
12
|
+
const ChatClient = mod.default?.Client ?? mod.Client;
|
|
13
|
+
if (!ChatClient) {
|
|
14
|
+
throw new Error("@botpress/chat did not expose a Client export. Pass EvalRunnerConfig.chatClient explicitly.");
|
|
15
|
+
}
|
|
16
|
+
return ChatClient;
|
|
17
|
+
}
|
|
18
|
+
var ChatSession = class {
|
|
19
|
+
constructor(webhookId, chatClient) {
|
|
20
|
+
this.webhookId = webhookId;
|
|
21
|
+
this.chatClient = chatClient;
|
|
22
|
+
}
|
|
23
|
+
client = null;
|
|
24
|
+
conversationId = null;
|
|
25
|
+
async connect() {
|
|
26
|
+
const ChatClient = this.chatClient ?? getDefaultChatClient();
|
|
27
|
+
this.client = await ChatClient.connect({ webhookId: this.webhookId });
|
|
28
|
+
}
|
|
29
|
+
get userId() {
|
|
30
|
+
if (!this.client) {
|
|
31
|
+
throw new Error("ChatSession not connected. Call connect() first.");
|
|
32
|
+
}
|
|
33
|
+
return this.client.user.id;
|
|
34
|
+
}
|
|
35
|
+
async ensureConversation() {
|
|
36
|
+
if (!this.client) {
|
|
37
|
+
throw new Error("ChatSession not connected. Call connect() first.");
|
|
38
|
+
}
|
|
39
|
+
if (!this.conversationId) {
|
|
40
|
+
const conv = await this.client.createConversation({});
|
|
41
|
+
this.conversationId = conv.conversation.id;
|
|
42
|
+
return conv.conversation.id;
|
|
43
|
+
}
|
|
44
|
+
return this.conversationId;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Send a user message. Fire-and-forget — observation is via SSECollector.
|
|
48
|
+
*/
|
|
49
|
+
async sendMessage(message) {
|
|
50
|
+
if (!this.client) {
|
|
51
|
+
throw new Error("ChatSession not connected. Call connect() first.");
|
|
52
|
+
}
|
|
53
|
+
const conversationId = await this.ensureConversation();
|
|
54
|
+
await this.client.createMessage({ conversationId, payload: { type: "text", text: message } });
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Send an event. Fire-and-forget — observation is via SSECollector.
|
|
58
|
+
*/
|
|
59
|
+
async sendEvent(type, payload) {
|
|
60
|
+
if (!this.client) {
|
|
61
|
+
throw new Error("ChatSession not connected. Call connect() first.");
|
|
62
|
+
}
|
|
63
|
+
const conversationId = await this.ensureConversation();
|
|
64
|
+
await this.client.createEvent({ type, payload, conversationId });
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
async function discoverWebhookId(botId, token, apiUrl) {
|
|
68
|
+
const client = new BpClient({ token, botId, apiUrl });
|
|
69
|
+
const { bot } = await client.getBot({ id: botId });
|
|
70
|
+
const integrations = bot.integrations || {};
|
|
71
|
+
const chat = Object.values(integrations).find((int) => int.name === "chat");
|
|
72
|
+
const webhookId = chat?.webhookId;
|
|
73
|
+
if (!webhookId || typeof webhookId !== "string") {
|
|
74
|
+
throw new Error(
|
|
75
|
+
[
|
|
76
|
+
"The `chat` integration is not installed on this bot \u2014 evals require it.",
|
|
77
|
+
"",
|
|
78
|
+
"To fix:",
|
|
79
|
+
" 1. Install it: adk add chat",
|
|
80
|
+
" 2. Redeploy: adk dev (or: adk deploy)"
|
|
81
|
+
].join("\n")
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
return webhookId;
|
|
85
|
+
}
|
|
86
|
+
async function assertChatChannelBound(devServerUrl, headers = {}) {
|
|
87
|
+
let conversations = [];
|
|
88
|
+
try {
|
|
89
|
+
const res = await fetch(`${devServerUrl}/api/agent`, { headers });
|
|
90
|
+
if (!res.ok) return;
|
|
91
|
+
const agent = await res.json();
|
|
92
|
+
conversations = agent.conversations ?? [];
|
|
93
|
+
} catch {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (conversations.length === 0) return;
|
|
97
|
+
const matchesChatChannel = (ch) => {
|
|
98
|
+
if (!ch) return false;
|
|
99
|
+
if (ch === "*" || ch === "chat.channel") return true;
|
|
100
|
+
return Array.isArray(ch) && (ch.includes("chat.channel") || ch.includes("*"));
|
|
101
|
+
};
|
|
102
|
+
const bound = conversations.some((c) => matchesChatChannel(c.channel));
|
|
103
|
+
if (bound) return;
|
|
104
|
+
throw new Error(
|
|
105
|
+
[
|
|
106
|
+
"No Conversation is bound to `chat.channel` \u2014 messages via `@botpress/chat` will time out silently.",
|
|
107
|
+
"",
|
|
108
|
+
"To fix, bind a Conversation in `src/conversations/` to `chat.channel` (or `*`):",
|
|
109
|
+
" channel: 'chat.channel', // explicit",
|
|
110
|
+
" channel: '*', // wildcard \u2014 matches every channel",
|
|
111
|
+
" channel: ['chat.channel', ...], // array form",
|
|
112
|
+
"",
|
|
113
|
+
"The `chat` integration is how evals and `adk chat --single` send messages programmatically."
|
|
114
|
+
].join("\n")
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
export {
|
|
118
|
+
ChatSession,
|
|
119
|
+
assertChatChannelBound,
|
|
120
|
+
discoverWebhookId,
|
|
121
|
+
setDefaultChatClient
|
|
122
|
+
};
|
|
123
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/client.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Chat client for eval conversations.\n * Drives conversations against a running ADK bot via @botpress/chat.\n *\n * This is a send-only client. Observation (bot responses, tool calls, state)\n * is handled by the SSECollector via trace spans \u2014 not via WebSocket listeners.\n */\n\nimport { Client as BpClient } from '@botpress/client'\nimport { createRequire } from 'module'\nimport type { ChatClient, ChatClientConnection } from './types'\n\nlet defaultChatClient: ChatClient | null = null\n\nexport function setDefaultChatClient(chatClient: ChatClient | null): void {\n defaultChatClient = chatClient\n}\n\nfunction getDefaultChatClient(): ChatClient {\n if (defaultChatClient) return defaultChatClient\n\n const require = createRequire(import.meta.url)\n const mod = require('@botpress/chat') as { Client?: ChatClient; default?: { Client?: ChatClient } }\n const ChatClient = mod.default?.Client ?? mod.Client\n if (!ChatClient) {\n throw new Error('@botpress/chat did not expose a Client export. Pass EvalRunnerConfig.chatClient explicitly.')\n }\n return ChatClient\n}\n\n/**\n * A send-only chat session that maintains a single client connection across turns.\n * Messages and events are fire-and-forget; the SSECollector observes results via traces.\n */\nexport class ChatSession {\n private client: ChatClientConnection | null = null\n private conversationId: string | null = null\n\n constructor(\n private webhookId: string,\n private chatClient?: ChatClient\n ) {}\n\n async connect() {\n const ChatClient = this.chatClient ?? getDefaultChatClient()\n this.client = await ChatClient.connect({ webhookId: this.webhookId })\n }\n\n get userId(): string {\n if (!this.client) {\n throw new Error('ChatSession not connected. Call connect() first.')\n }\n return this.client.user.id\n }\n\n async ensureConversation(): Promise<string> {\n if (!this.client) {\n throw new Error('ChatSession not connected. Call connect() first.')\n }\n\n if (!this.conversationId) {\n const conv = await this.client.createConversation({})\n this.conversationId = conv.conversation.id\n return conv.conversation.id\n }\n\n return this.conversationId\n }\n\n /**\n * Send a user message. Fire-and-forget \u2014 observation is via SSECollector.\n */\n async sendMessage(message: string): Promise<void> {\n if (!this.client) {\n throw new Error('ChatSession not connected. Call connect() first.')\n }\n\n const conversationId = await this.ensureConversation()\n await this.client.createMessage({ conversationId, payload: { type: 'text', text: message } })\n }\n\n /**\n * Send an event. Fire-and-forget \u2014 observation is via SSECollector.\n */\n async sendEvent(type: string, payload: Record<string, unknown>): Promise<void> {\n if (!this.client) {\n throw new Error('ChatSession not connected. Call connect() first.')\n }\n\n const conversationId = await this.ensureConversation()\n await this.client.createEvent({ type, payload, conversationId })\n }\n}\n\n/**\n * Discover the chat integration's webhookId from a bot.\n *\n * Evals talk to the bot through the `chat` integration (via @botpress/chat).\n * If the bot doesn't have that integration installed, evals can't run.\n */\nexport async function discoverWebhookId(botId: string, token: string, apiUrl: string): Promise<string> {\n const client = new BpClient({ token, botId, apiUrl })\n const { bot } = await client.getBot({ id: botId })\n const integrations = bot.integrations || {}\n\n const chat = Object.values(integrations).find((int) => (int as Record<string, unknown>).name === 'chat')\n const webhookId = (chat as Record<string, unknown> | undefined)?.webhookId\n\n if (!webhookId || typeof webhookId !== 'string') {\n throw new Error(\n [\n 'The `chat` integration is not installed on this bot \u2014 evals require it.',\n '',\n 'To fix:',\n ' 1. Install it: adk add chat',\n ' 2. Redeploy: adk dev (or: adk deploy)',\n ].join('\\n')\n )\n }\n\n return webhookId\n}\n\n/**\n * Verify the bot has at least one Conversation bound to `chat.channel`.\n *\n * The `chat` integration can be installed without any handler listening on its\n * channel \u2014 in that case messages sent via @botpress/chat produce no response\n * and the caller times out silently. Fail fast with actionable guidance instead.\n *\n * Uses the dev server's `/api/agent` endpoint, so this is a no-op against\n * production bots (no devServerUrl).\n */\nexport async function assertChatChannelBound(\n devServerUrl: string,\n headers: Record<string, string> = {}\n): Promise<void> {\n type ConversationSummary = { channel?: string | string[] }\n let conversations: ConversationSummary[] = []\n try {\n const res = await fetch(`${devServerUrl}/api/agent`, { headers })\n if (!res.ok) return // Dev server unreachable \u2014 skip, let downstream errors surface\n const agent = (await res.json()) as { conversations?: ConversationSummary[] }\n conversations = agent.conversations ?? []\n } catch {\n return // Network error \u2014 skip check\n }\n\n if (conversations.length === 0) return // Bot has no conversations at all \u2014 different problem\n\n // Mirrors the runtime's matchesChannel semantics: a handler matches `chat.channel`\n // if it is the wildcard '*', the literal string 'chat.channel', or an array\n // containing either.\n const matchesChatChannel = (ch: string | string[] | undefined): boolean => {\n if (!ch) return false\n if (ch === '*' || ch === 'chat.channel') return true\n return Array.isArray(ch) && (ch.includes('chat.channel') || ch.includes('*'))\n }\n\n const bound = conversations.some((c) => matchesChatChannel(c.channel))\n if (bound) return\n\n throw new Error(\n [\n 'No Conversation is bound to `chat.channel` \u2014 messages via `@botpress/chat` will time out silently.',\n '',\n 'To fix, bind a Conversation in `src/conversations/` to `chat.channel` (or `*`):',\n \" channel: 'chat.channel', // explicit\",\n \" channel: '*', // wildcard \u2014 matches every channel\",\n \" channel: ['chat.channel', ...], // array form\",\n '',\n 'The `chat` integration is how evals and `adk chat --single` send messages programmatically.',\n ].join('\\n')\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["require"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
export type MatchOperator = string | {
|
|
2
|
+
equals: unknown;
|
|
3
|
+
} | {
|
|
4
|
+
contains: string;
|
|
5
|
+
} | {
|
|
6
|
+
not_contains: string;
|
|
7
|
+
} | {
|
|
8
|
+
matches: string;
|
|
9
|
+
} | {
|
|
10
|
+
in: unknown[];
|
|
11
|
+
} | {
|
|
12
|
+
exists: boolean;
|
|
13
|
+
} | {
|
|
14
|
+
gte: number;
|
|
15
|
+
} | {
|
|
16
|
+
lte: number;
|
|
17
|
+
};
|
|
18
|
+
export type ResponseAssertion = {
|
|
19
|
+
contains: string;
|
|
20
|
+
} | {
|
|
21
|
+
not_contains: string;
|
|
22
|
+
} | {
|
|
23
|
+
matches: string;
|
|
24
|
+
} | {
|
|
25
|
+
llm_judge: string;
|
|
26
|
+
};
|
|
27
|
+
export type ToolAssertion = {
|
|
28
|
+
called: string;
|
|
29
|
+
params?: Record<string, MatchOperator>;
|
|
30
|
+
} | {
|
|
31
|
+
not_called: string;
|
|
32
|
+
} | {
|
|
33
|
+
call_order: string[];
|
|
34
|
+
};
|
|
35
|
+
export interface StateAssertion {
|
|
36
|
+
path: string;
|
|
37
|
+
equals?: unknown;
|
|
38
|
+
changed?: boolean;
|
|
39
|
+
}
|
|
40
|
+
export interface WorkflowAssertion {
|
|
41
|
+
name: string;
|
|
42
|
+
entered?: boolean;
|
|
43
|
+
completed?: boolean;
|
|
44
|
+
}
|
|
45
|
+
export type NumericOperator = {
|
|
46
|
+
equals: number;
|
|
47
|
+
} | {
|
|
48
|
+
gte: number;
|
|
49
|
+
} | {
|
|
50
|
+
lte: number;
|
|
51
|
+
};
|
|
52
|
+
export interface TimingAssertion {
|
|
53
|
+
response_time: NumericOperator;
|
|
54
|
+
}
|
|
55
|
+
export interface TurnAssertions {
|
|
56
|
+
response?: ResponseAssertion[];
|
|
57
|
+
tools?: ToolAssertion[];
|
|
58
|
+
state?: StateAssertion[];
|
|
59
|
+
workflow?: WorkflowAssertion[];
|
|
60
|
+
timing?: TimingAssertion[];
|
|
61
|
+
}
|
|
62
|
+
export interface ConversationTurn {
|
|
63
|
+
user?: string;
|
|
64
|
+
event?: {
|
|
65
|
+
type: string;
|
|
66
|
+
payload?: Record<string, unknown>;
|
|
67
|
+
};
|
|
68
|
+
expectSilence?: boolean;
|
|
69
|
+
assert?: TurnAssertions;
|
|
70
|
+
}
|
|
71
|
+
export interface OutcomeAssertions {
|
|
72
|
+
state?: StateAssertion[];
|
|
73
|
+
workflow?: WorkflowAssertion[];
|
|
74
|
+
}
|
|
75
|
+
export interface EvalSetup {
|
|
76
|
+
state?: {
|
|
77
|
+
bot?: Record<string, unknown>;
|
|
78
|
+
user?: Record<string, unknown>;
|
|
79
|
+
conversation?: Record<string, unknown>;
|
|
80
|
+
};
|
|
81
|
+
workflow?: {
|
|
82
|
+
trigger: string;
|
|
83
|
+
input?: Record<string, unknown>;
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
export interface EvalDefinition {
|
|
87
|
+
name: string;
|
|
88
|
+
description?: string;
|
|
89
|
+
tags?: string[];
|
|
90
|
+
type?: 'capability' | 'regression';
|
|
91
|
+
setup?: EvalSetup;
|
|
92
|
+
conversation: ConversationTurn[];
|
|
93
|
+
outcome?: OutcomeAssertions;
|
|
94
|
+
options?: {
|
|
95
|
+
idleTimeout?: number;
|
|
96
|
+
judgePassThreshold?: number;
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
export declare class Eval implements EvalDefinition {
|
|
100
|
+
readonly name: string;
|
|
101
|
+
readonly description?: string;
|
|
102
|
+
readonly tags?: string[];
|
|
103
|
+
readonly type?: 'capability' | 'regression';
|
|
104
|
+
readonly setup?: EvalSetup;
|
|
105
|
+
readonly conversation: ConversationTurn[];
|
|
106
|
+
readonly outcome?: OutcomeAssertions;
|
|
107
|
+
readonly options?: {
|
|
108
|
+
idleTimeout?: number;
|
|
109
|
+
judgePassThreshold?: number;
|
|
110
|
+
};
|
|
111
|
+
constructor(def: EvalDefinition);
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=definition.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../src/definition.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// src/definition.ts
|
|
2
|
+
var Eval = class {
|
|
3
|
+
name;
|
|
4
|
+
description;
|
|
5
|
+
tags;
|
|
6
|
+
type;
|
|
7
|
+
setup;
|
|
8
|
+
conversation;
|
|
9
|
+
outcome;
|
|
10
|
+
options;
|
|
11
|
+
constructor(def) {
|
|
12
|
+
this.name = def.name;
|
|
13
|
+
this.conversation = def.conversation;
|
|
14
|
+
if (def.description !== void 0) this.description = def.description;
|
|
15
|
+
if (def.tags !== void 0) this.tags = def.tags;
|
|
16
|
+
if (def.type !== void 0) this.type = def.type;
|
|
17
|
+
if (def.setup !== void 0) this.setup = def.setup;
|
|
18
|
+
if (def.outcome !== void 0) this.outcome = def.outcome;
|
|
19
|
+
if (def.options !== void 0) this.options = def.options;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
export {
|
|
23
|
+
Eval
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=definition.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/definition.ts"],
|
|
4
|
+
"sourcesContent": ["export type MatchOperator =\n | string\n | { equals: unknown }\n | { contains: string }\n | { not_contains: string }\n | { matches: string }\n | { in: unknown[] }\n | { exists: boolean }\n | { gte: number }\n | { lte: number }\n\nexport type ResponseAssertion =\n | { contains: string }\n | { not_contains: string }\n | { matches: string }\n | { llm_judge: string }\n// | { similar_to: string } TODO: uncomment this when it gets implemented\n\nexport type ToolAssertion =\n | { called: string; params?: Record<string, MatchOperator> }\n | { not_called: string }\n | { call_order: string[] }\n\nexport interface StateAssertion {\n path: string\n equals?: unknown\n changed?: boolean\n}\n\nexport interface WorkflowAssertion {\n name: string\n entered?: boolean\n completed?: boolean\n}\n\nexport type NumericOperator = { equals: number } | { gte: number } | { lte: number }\n\nexport interface TimingAssertion {\n response_time: NumericOperator\n}\n\nexport interface TurnAssertions {\n response?: ResponseAssertion[]\n tools?: ToolAssertion[]\n state?: StateAssertion[]\n workflow?: WorkflowAssertion[]\n timing?: TimingAssertion[]\n}\n\nexport interface ConversationTurn {\n user?: string\n event?: { type: string; payload?: Record<string, unknown> }\n expectSilence?: boolean\n assert?: TurnAssertions\n}\n\nexport interface OutcomeAssertions {\n state?: StateAssertion[]\n workflow?: WorkflowAssertion[]\n}\n\nexport interface EvalSetup {\n state?: {\n bot?: Record<string, unknown>\n user?: Record<string, unknown>\n conversation?: Record<string, unknown>\n }\n workflow?: {\n trigger: string\n input?: Record<string, unknown>\n }\n}\n\nexport interface EvalDefinition {\n name: string\n description?: string\n tags?: string[]\n type?: 'capability' | 'regression'\n setup?: EvalSetup\n conversation: ConversationTurn[]\n outcome?: OutcomeAssertions\n options?: {\n idleTimeout?: number\n judgePassThreshold?: number\n }\n}\n\nexport class Eval implements EvalDefinition {\n readonly name: string\n readonly description?: string\n readonly tags?: string[]\n readonly type?: 'capability' | 'regression'\n readonly setup?: EvalSetup\n readonly conversation: ConversationTurn[]\n readonly outcome?: OutcomeAssertions\n readonly options?: {\n idleTimeout?: number\n judgePassThreshold?: number\n }\n\n constructor(def: EvalDefinition) {\n this.name = def.name\n this.conversation = def.conversation\n if (def.description !== undefined) this.description = def.description\n if (def.tags !== undefined) this.tags = def.tags\n if (def.type !== undefined) this.type = def.type\n if (def.setup !== undefined) this.setup = def.setup\n if (def.outcome !== undefined) this.outcome = def.outcome\n if (def.options !== undefined) this.options = def.options\n }\n}\n"],
|
|
5
|
+
"mappings": ";AAuFO,IAAM,OAAN,MAAqC;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAKT,YAAY,KAAqB;AAC/B,SAAK,OAAO,IAAI;AAChB,SAAK,eAAe,IAAI;AACxB,QAAI,IAAI,gBAAgB,OAAW,MAAK,cAAc,IAAI;AAC1D,QAAI,IAAI,SAAS,OAAW,MAAK,OAAO,IAAI;AAC5C,QAAI,IAAI,SAAS,OAAW,MAAK,OAAO,IAAI;AAC5C,QAAI,IAAI,UAAU,OAAW,MAAK,QAAQ,IAAI;AAC9C,QAAI,IAAI,YAAY,OAAW,MAAK,UAAU,IAAI;AAClD,QAAI,IAAI,YAAY,OAAW,MAAK,UAAU,IAAI;AAAA,EACpD;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grader barrel exports.
|
|
3
|
+
*/
|
|
4
|
+
export { matchValue, operatorToString } from './match';
|
|
5
|
+
export { gradeResponse } from './response';
|
|
6
|
+
export { gradeLLMJudge, initLLMJudge } from './llm';
|
|
7
|
+
export { gradeTools } from './tools';
|
|
8
|
+
export { gradeState } from './state';
|
|
9
|
+
export { gradeWorkflows } from './workflow';
|
|
10
|
+
export { gradeTiming } from './timing';
|
|
11
|
+
export { gradeOutcome } from './outcome';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/graders/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC1C,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA"}
|