chore: import upstream snapshot with attribution
CI / Shell Format Check (push) Has been cancelled
CI / Check Ruby (3.4) (push) Has been cancelled
CI / CI Config (push) Has been cancelled
CI / Test on Node ${{ matrix.node }} and ${{ matrix.os }}${{ matrix.shard && format(' (shard {0}/3)', matrix.shard) || '' }} (push) Has been cancelled
CI / Build on Node ${{ matrix.node }} (push) Has been cancelled
CI / Style Check (push) Has been cancelled
CI / Generate Assets (push) Has been cancelled
CI / Check Python (3.14) (push) Has been cancelled
CI / Check Python (3.9) (push) Has been cancelled
CI / Build Docs (push) Has been cancelled
CI / Code Scan Action (push) Has been cancelled
CI / Site tests (push) Has been cancelled
CI / webui tests (push) Has been cancelled
CI / Run Integration Tests (push) Has been cancelled
CI / Run Smoke Tests (push) Has been cancelled
CI / Go Tests (push) Has been cancelled
CI / Share Test (push) Has been cancelled
CI / Redteam (Production API) (push) Has been cancelled
CI / Redteam (Staging API) (push) Has been cancelled
CI / GitHub Actions Lint (push) Has been cancelled
CI / Check Ruby (3.0) (push) Has been cancelled
release-please / release-please (push) Has been cancelled
release-please / build (push) Has been cancelled
release-please / publish-npm (push) Has been cancelled
release-please / publish-npm-backfill (push) Has been cancelled
release-please / docker (push) Has been cancelled
release-please / publish-code-scan-action (push) Has been cancelled
release-please / attest-code-scan-action (push) Has been cancelled
Deploy local.promptfoo.app / Deploy to Cloudflare Pages (push) Has been cancelled
Test and Publish Multi-arch Docker Image / test (push) Has been cancelled
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-amd64 platform:linux/amd64 runner:ubuntu-latest]) (push) Has been cancelled
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-arm64 platform:linux/arm64 runner:ubuntu-24.04-arm]) (push) Has been cancelled
Test and Publish Multi-arch Docker Image / merge-docker-digests (push) Has been cancelled
Test and Publish Multi-arch Docker Image / Attest Multi-arch Image (push) Has been cancelled
Validate Renovate Config / Validate Renovate Configuration (push) Has been cancelled
CI / Shell Format Check (push) Has been cancelled
CI / Check Ruby (3.4) (push) Has been cancelled
CI / CI Config (push) Has been cancelled
CI / Test on Node ${{ matrix.node }} and ${{ matrix.os }}${{ matrix.shard && format(' (shard {0}/3)', matrix.shard) || '' }} (push) Has been cancelled
CI / Build on Node ${{ matrix.node }} (push) Has been cancelled
CI / Style Check (push) Has been cancelled
CI / Generate Assets (push) Has been cancelled
CI / Check Python (3.14) (push) Has been cancelled
CI / Check Python (3.9) (push) Has been cancelled
CI / Build Docs (push) Has been cancelled
CI / Code Scan Action (push) Has been cancelled
CI / Site tests (push) Has been cancelled
CI / webui tests (push) Has been cancelled
CI / Run Integration Tests (push) Has been cancelled
CI / Run Smoke Tests (push) Has been cancelled
CI / Go Tests (push) Has been cancelled
CI / Share Test (push) Has been cancelled
CI / Redteam (Production API) (push) Has been cancelled
CI / Redteam (Staging API) (push) Has been cancelled
CI / GitHub Actions Lint (push) Has been cancelled
CI / Check Ruby (3.0) (push) Has been cancelled
release-please / release-please (push) Has been cancelled
release-please / build (push) Has been cancelled
release-please / publish-npm (push) Has been cancelled
release-please / publish-npm-backfill (push) Has been cancelled
release-please / docker (push) Has been cancelled
release-please / publish-code-scan-action (push) Has been cancelled
release-please / attest-code-scan-action (push) Has been cancelled
Deploy local.promptfoo.app / Deploy to Cloudflare Pages (push) Has been cancelled
Test and Publish Multi-arch Docker Image / test (push) Has been cancelled
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-amd64 platform:linux/amd64 runner:ubuntu-latest]) (push) Has been cancelled
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-arm64 platform:linux/arm64 runner:ubuntu-24.04-arm]) (push) Has been cancelled
Test and Publish Multi-arch Docker Image / merge-docker-digests (push) Has been cancelled
Test and Publish Multi-arch Docker Image / Attest Multi-arch Image (push) Has been cancelled
Validate Renovate Config / Validate Renovate Configuration (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,505 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { createMockProvider as createFactoryProvider } from '../factories/provider';
|
||||
|
||||
import type { ApiProvider } from '../../src/types/providers';
|
||||
|
||||
// Use vi.hoisted to create mock functions that persist across clearAllMocks
|
||||
const mockEvaluate = vi.hoisted(() => vi.fn());
|
||||
const mockToEvaluateSummary = vi.hoisted(() =>
|
||||
vi.fn().mockResolvedValue({
|
||||
results: [
|
||||
{
|
||||
response: {
|
||||
output: 'Hello! How can I help you?',
|
||||
raw: 'Hello! How can I help you?',
|
||||
sessionId: 'session-123',
|
||||
metadata: { transformedRequest: { body: '{}' } },
|
||||
},
|
||||
error: undefined,
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
const mockNeverGenerateRemote = vi.hoisted(() => vi.fn().mockReturnValue(false));
|
||||
const mockFetchWithProxy = vi.hoisted(() =>
|
||||
vi.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
json: vi.fn().mockResolvedValue({
|
||||
message: 'Test completed successfully',
|
||||
error: null,
|
||||
changes_needed: false,
|
||||
}),
|
||||
}),
|
||||
);
|
||||
const mockDoRemoteGrading = vi.hoisted(() =>
|
||||
vi.fn().mockResolvedValue({
|
||||
pass: true,
|
||||
reason: 'Session is working correctly',
|
||||
}),
|
||||
);
|
||||
const mockDetermineEffectiveSessionSource = vi.hoisted(() => vi.fn().mockReturnValue('client'));
|
||||
|
||||
vi.mock('dedent', () => ({
|
||||
default: (strings: TemplateStringsArray, ...values: unknown[]) => {
|
||||
let result = '';
|
||||
strings.forEach((str, i) => {
|
||||
result += str + (values[i] ?? '');
|
||||
});
|
||||
return result;
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('../../src/evaluator', () => ({
|
||||
evaluate: mockEvaluate,
|
||||
}));
|
||||
|
||||
vi.mock('../../src/globalConfig/cloud', () => ({
|
||||
cloudConfig: {
|
||||
getApiHost: vi.fn().mockReturnValue('https://api.example.com'),
|
||||
getApiKey: vi.fn().mockReturnValue('test-api-key'),
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('../../src/logger', () => ({
|
||||
default: {
|
||||
debug: vi.fn(),
|
||||
warn: vi.fn(),
|
||||
error: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('../../src/models/eval', () => {
|
||||
return {
|
||||
default: class MockEval {
|
||||
toEvaluateSummary = mockToEvaluateSummary;
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock('../../src/redteam/remoteGeneration', () => ({
|
||||
neverGenerateRemote: mockNeverGenerateRemote,
|
||||
}));
|
||||
|
||||
vi.mock('../../src/remoteGrading', () => ({
|
||||
doRemoteGrading: mockDoRemoteGrading,
|
||||
}));
|
||||
|
||||
vi.mock('../../src/util/fetch/index', () => ({
|
||||
fetchWithProxy: mockFetchWithProxy,
|
||||
}));
|
||||
|
||||
vi.mock('../../src/util/sanitizer', () => ({
|
||||
sanitizeObject: vi.fn((obj: unknown) => obj),
|
||||
}));
|
||||
|
||||
vi.mock('../../src/validators/util', () => ({
|
||||
determineEffectiveSessionSource: mockDetermineEffectiveSessionSource,
|
||||
formatConfigBody: vi.fn().mockReturnValue('None configured'),
|
||||
formatConfigHeaders: vi.fn().mockReturnValue('None configured'),
|
||||
validateSessionConfig: vi.fn(),
|
||||
}));
|
||||
|
||||
import { testProviderConnectivity, testProviderSession } from '../../src/node/testProvider';
|
||||
|
||||
beforeEach(() => {
|
||||
// Reset call history but keep implementations from vi.hoisted
|
||||
mockEvaluate.mockReset();
|
||||
mockNeverGenerateRemote.mockReset().mockReturnValue(false);
|
||||
mockDetermineEffectiveSessionSource.mockReset().mockReturnValue('client');
|
||||
mockDoRemoteGrading.mockReset().mockResolvedValue({
|
||||
pass: true,
|
||||
reason: 'Session is working correctly',
|
||||
});
|
||||
mockToEvaluateSummary.mockReset().mockResolvedValue({
|
||||
results: [
|
||||
{
|
||||
response: {
|
||||
output: 'Hello! How can I help you?',
|
||||
raw: 'Hello! How can I help you?',
|
||||
sessionId: 'session-123',
|
||||
metadata: { transformedRequest: { body: '{}' } },
|
||||
},
|
||||
error: undefined,
|
||||
},
|
||||
],
|
||||
});
|
||||
mockFetchWithProxy.mockReset().mockResolvedValue({
|
||||
ok: true,
|
||||
json: vi.fn().mockResolvedValue({
|
||||
message: 'Test completed successfully',
|
||||
error: null,
|
||||
changes_needed: false,
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
function createMockProvider(overrides?: Record<string, unknown>): ApiProvider {
|
||||
return Object.assign(
|
||||
createFactoryProvider({
|
||||
response: {
|
||||
output: 'Hello! How can I help you?',
|
||||
sessionId: 'session-123',
|
||||
},
|
||||
config: {},
|
||||
}),
|
||||
overrides,
|
||||
) as unknown as ApiProvider;
|
||||
}
|
||||
|
||||
describe('testProviderConnectivity', () => {
|
||||
it('should return success when provider evaluation succeeds', async () => {
|
||||
const provider = createMockProvider();
|
||||
const result = await testProviderConnectivity({ provider });
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.message).toBe('Test completed successfully');
|
||||
expect(mockEvaluate).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should use custom prompt when provided', async () => {
|
||||
const provider = createMockProvider();
|
||||
await testProviderConnectivity({ provider, prompt: 'Custom prompt' });
|
||||
|
||||
expect(mockEvaluate).toHaveBeenCalled();
|
||||
const callArgs = mockEvaluate.mock.calls[0];
|
||||
expect(callArgs[0].prompts[0].raw).toBe('Custom prompt');
|
||||
});
|
||||
|
||||
it('should generate test values for input variables', async () => {
|
||||
const provider = createMockProvider();
|
||||
await testProviderConnectivity({
|
||||
provider,
|
||||
inputs: { name: 'User name', topic: 'Discussion topic' },
|
||||
});
|
||||
|
||||
expect(mockEvaluate).toHaveBeenCalled();
|
||||
const callArgs = mockEvaluate.mock.calls[0];
|
||||
const vars = callArgs[0].tests[0].vars;
|
||||
expect(vars['name']).toBe('test_name');
|
||||
expect(vars['topic']).toBe('test_topic');
|
||||
});
|
||||
|
||||
it('should return raw result when remote grading is disabled', async () => {
|
||||
mockNeverGenerateRemote.mockReturnValue(true);
|
||||
const provider = createMockProvider();
|
||||
|
||||
const result = await testProviderConnectivity({ provider });
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.message).toContain('Remote grading disabled');
|
||||
expect(mockFetchWithProxy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should return error when evaluation result has error', async () => {
|
||||
mockNeverGenerateRemote.mockReturnValue(true);
|
||||
mockToEvaluateSummary.mockResolvedValueOnce({
|
||||
results: [
|
||||
{
|
||||
response: { output: null },
|
||||
error: 'Connection refused',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const provider = createMockProvider();
|
||||
const result = await testProviderConnectivity({ provider });
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.message).toContain('Connection refused');
|
||||
});
|
||||
|
||||
it('should handle evaluation throwing an error', async () => {
|
||||
mockEvaluate.mockRejectedValueOnce(new Error('Evaluation failed'));
|
||||
|
||||
const provider = createMockProvider();
|
||||
const result = await testProviderConnectivity({ provider });
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toBe('Evaluation failed');
|
||||
});
|
||||
|
||||
it('should handle remote analysis endpoint failure', async () => {
|
||||
mockFetchWithProxy.mockResolvedValueOnce({
|
||||
ok: false,
|
||||
statusText: 'Internal Server Error',
|
||||
} as any);
|
||||
|
||||
const provider = createMockProvider();
|
||||
const result = await testProviderConnectivity({ provider });
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.message).toContain('review the provider response manually');
|
||||
});
|
||||
|
||||
it('should handle remote analysis endpoint throwing', async () => {
|
||||
mockFetchWithProxy.mockRejectedValueOnce(new Error('Network error'));
|
||||
|
||||
const provider = createMockProvider();
|
||||
const result = await testProviderConnectivity({ provider });
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toBe('Network error');
|
||||
});
|
||||
|
||||
it('should report changes_needed from analysis', async () => {
|
||||
mockFetchWithProxy.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
json: vi.fn().mockResolvedValue({
|
||||
message: 'Configuration needs changes',
|
||||
error: null,
|
||||
changes_needed: true,
|
||||
changes_needed_reason: 'Missing auth header',
|
||||
changes_needed_suggestions: ['Add Authorization header'],
|
||||
}),
|
||||
} as any);
|
||||
|
||||
const provider = createMockProvider();
|
||||
const result = await testProviderConnectivity({ provider });
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.analysis).toBeDefined();
|
||||
expect(result.analysis?.changes_needed).toBe(true);
|
||||
expect(result.analysis?.changes_needed_reason).toBe('Missing auth header');
|
||||
});
|
||||
|
||||
it('should not set sessionId var when provider has sessionParser config', async () => {
|
||||
const provider = createMockProvider({
|
||||
config: { sessionParser: 'response.headers.session' },
|
||||
});
|
||||
|
||||
await testProviderConnectivity({ provider });
|
||||
|
||||
expect(mockEvaluate).toHaveBeenCalled();
|
||||
const callArgs = mockEvaluate.mock.calls[0];
|
||||
const vars = callArgs[0].tests[0].vars;
|
||||
expect(vars).not.toHaveProperty('sessionId');
|
||||
});
|
||||
|
||||
it('should set sessionId var when provider has no sessionParser config', async () => {
|
||||
const provider = createMockProvider();
|
||||
|
||||
await testProviderConnectivity({ provider });
|
||||
|
||||
expect(mockEvaluate).toHaveBeenCalled();
|
||||
const callArgs = mockEvaluate.mock.calls[0];
|
||||
const vars = callArgs[0].tests[0].vars;
|
||||
expect(vars).toHaveProperty('sessionId');
|
||||
});
|
||||
|
||||
it('should use default prompt when none provided', async () => {
|
||||
const provider = createMockProvider();
|
||||
await testProviderConnectivity({ provider });
|
||||
|
||||
const callArgs = mockEvaluate.mock.calls[0];
|
||||
expect(callArgs[0].prompts[0].raw).toBe('Hello World!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('testProviderSession', () => {
|
||||
it('should return success when session is working', async () => {
|
||||
const provider = createMockProvider();
|
||||
const result = await testProviderSession({ provider });
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.message).toContain('working correctly');
|
||||
});
|
||||
|
||||
it('should return failure when first request fails', async () => {
|
||||
const provider = createMockProvider({
|
||||
callApi: vi.fn().mockResolvedValue({
|
||||
error: 'Connection timeout',
|
||||
output: null,
|
||||
}),
|
||||
});
|
||||
|
||||
const result = await testProviderSession({ provider });
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.message).toContain('First request failed');
|
||||
expect(result.error).toBe('Connection timeout');
|
||||
});
|
||||
|
||||
it('should return failure when second request fails', async () => {
|
||||
const callApi = vi
|
||||
.fn()
|
||||
.mockResolvedValueOnce({
|
||||
output: 'Hello! I can help with many things.',
|
||||
sessionId: 'session-123',
|
||||
})
|
||||
.mockResolvedValueOnce({
|
||||
error: 'Server error',
|
||||
output: null,
|
||||
});
|
||||
|
||||
const provider = createMockProvider({ callApi });
|
||||
const result = await testProviderSession({ provider });
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.message).toContain('Second request failed');
|
||||
});
|
||||
|
||||
it('should return manual review message when remote grading is disabled', async () => {
|
||||
mockNeverGenerateRemote.mockReturnValue(true);
|
||||
const provider = createMockProvider();
|
||||
|
||||
const result = await testProviderSession({ provider });
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.message).toContain('Remote grading is disabled');
|
||||
});
|
||||
|
||||
it('should return failure when session grading fails', async () => {
|
||||
mockDoRemoteGrading.mockRejectedValueOnce(new Error('Grading service unavailable'));
|
||||
const provider = createMockProvider();
|
||||
|
||||
const result = await testProviderSession({ provider });
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.message).toContain('Failed to evaluate session');
|
||||
});
|
||||
|
||||
it('should return failure when session is not working', async () => {
|
||||
mockDoRemoteGrading.mockResolvedValueOnce({
|
||||
pass: false,
|
||||
score: 0,
|
||||
reason: 'Provider did not remember the previous question',
|
||||
});
|
||||
const provider = createMockProvider();
|
||||
|
||||
const result = await testProviderSession({ provider });
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.message).toContain('Session is NOT working');
|
||||
});
|
||||
|
||||
it('should handle server session source with extraction failure', async () => {
|
||||
mockDetermineEffectiveSessionSource.mockReturnValue('server');
|
||||
const provider = createMockProvider({
|
||||
callApi: vi.fn().mockResolvedValue({
|
||||
output: 'Hello!',
|
||||
// No sessionId returned
|
||||
}),
|
||||
getSessionId: vi.fn().mockReturnValue(undefined),
|
||||
});
|
||||
|
||||
const result = await testProviderSession({ provider });
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.message).toContain('Session extraction failed');
|
||||
});
|
||||
|
||||
it('should handle input variables for multi-input configurations', async () => {
|
||||
const callApi = vi.fn().mockResolvedValue({
|
||||
output: 'Response',
|
||||
sessionId: 'session-123',
|
||||
});
|
||||
const provider = createMockProvider({ callApi });
|
||||
|
||||
await testProviderSession({
|
||||
provider,
|
||||
inputs: { user_message: 'Main input', context: 'Additional context' },
|
||||
mainInputVariable: 'user_message',
|
||||
});
|
||||
|
||||
expect(callApi).toHaveBeenCalledTimes(2);
|
||||
const firstContext = callApi.mock.calls[0][1];
|
||||
expect(firstContext.vars).toHaveProperty('context', 'test_context');
|
||||
expect(firstContext.vars).toHaveProperty('user_message', 'What can you help me with?');
|
||||
});
|
||||
|
||||
it('should materialize typed main input variables during session tests', async () => {
|
||||
const callApi = vi.fn().mockResolvedValue({
|
||||
output: 'Response',
|
||||
sessionId: 'session-123',
|
||||
});
|
||||
const provider = createMockProvider({ callApi });
|
||||
|
||||
await testProviderSession({
|
||||
provider,
|
||||
inputs: {
|
||||
document: {
|
||||
description: 'Uploaded document',
|
||||
type: 'docx',
|
||||
},
|
||||
question: 'Question',
|
||||
},
|
||||
mainInputVariable: 'document',
|
||||
});
|
||||
|
||||
expect(callApi).toHaveBeenCalledTimes(2);
|
||||
const firstContext = callApi.mock.calls[0][1];
|
||||
const secondContext = callApi.mock.calls[1][1];
|
||||
expect(firstContext.vars.document).toMatch(
|
||||
/^data:application\/vnd\.openxmlformats-officedocument\.wordprocessingml\.document;base64,/,
|
||||
);
|
||||
expect(secondContext.vars.document).toMatch(
|
||||
/^data:application\/vnd\.openxmlformats-officedocument\.wordprocessingml\.document;base64,/,
|
||||
);
|
||||
expect(firstContext.vars.document).not.toBe('What can you help me with?');
|
||||
expect(secondContext.vars.document).not.toBe('What was the last thing I asked you?');
|
||||
});
|
||||
|
||||
it('should handle errors thrown during session test', async () => {
|
||||
const provider = createMockProvider({
|
||||
callApi: vi.fn().mockRejectedValue(new Error('Unexpected error')),
|
||||
});
|
||||
|
||||
const result = await testProviderSession({ provider });
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toBe('Unexpected error');
|
||||
});
|
||||
|
||||
it('should include session details in successful response', async () => {
|
||||
const provider = createMockProvider();
|
||||
const result = await testProviderSession({ provider });
|
||||
|
||||
expect(result.details).toBeDefined();
|
||||
expect(result.details?.sessionSource).toBe('client');
|
||||
expect(result.details?.request1).toBeDefined();
|
||||
expect(result.details?.response1).toBeDefined();
|
||||
expect(result.details?.request2).toBeDefined();
|
||||
expect(result.details?.response2).toBeDefined();
|
||||
});
|
||||
|
||||
it('should include reason from grading judge', async () => {
|
||||
mockDoRemoteGrading.mockResolvedValueOnce({
|
||||
pass: true,
|
||||
reason: 'The model remembered the first question',
|
||||
});
|
||||
const provider = createMockProvider();
|
||||
|
||||
const result = await testProviderSession({ provider });
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.reason).toBe('The model remembered the first question');
|
||||
});
|
||||
|
||||
it('should generate dummy values for non-main input variables', async () => {
|
||||
const callApi = vi.fn().mockResolvedValue({
|
||||
output: 'Response',
|
||||
sessionId: 'session-123',
|
||||
});
|
||||
const provider = createMockProvider({ callApi });
|
||||
|
||||
await testProviderSession({
|
||||
provider,
|
||||
inputs: {
|
||||
user_message: 'Main',
|
||||
system_prompt: 'System instruction',
|
||||
language: 'Language preference',
|
||||
},
|
||||
mainInputVariable: 'user_message',
|
||||
});
|
||||
|
||||
const firstContext = callApi.mock.calls[0][1];
|
||||
expect(firstContext.vars).toHaveProperty('system_prompt', 'test_system_prompt');
|
||||
expect(firstContext.vars).toHaveProperty('language', 'test_language');
|
||||
// main input variable should have the actual prompt
|
||||
expect(firstContext.vars).toHaveProperty('user_message', 'What can you help me with?');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user