ai-functions 0.3.0 → 0.4.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/.turbo/turbo-build.log +5 -0
- package/.turbo/turbo-test.log +105 -0
- package/README.md +190 -86
- package/TODO.md +138 -0
- package/dist/ai-promise.d.ts +219 -0
- package/dist/ai-promise.d.ts.map +1 -0
- package/dist/ai-promise.js +610 -0
- package/dist/ai-promise.js.map +1 -0
- package/dist/ai.d.ts +285 -0
- package/dist/ai.d.ts.map +1 -0
- package/dist/ai.js +842 -0
- package/dist/ai.js.map +1 -0
- package/dist/batch/anthropic.d.ts +23 -0
- package/dist/batch/anthropic.d.ts.map +1 -0
- package/dist/batch/anthropic.js +257 -0
- package/dist/batch/anthropic.js.map +1 -0
- package/dist/batch/bedrock.d.ts +64 -0
- package/dist/batch/bedrock.d.ts.map +1 -0
- package/dist/batch/bedrock.js +586 -0
- package/dist/batch/bedrock.js.map +1 -0
- package/dist/batch/cloudflare.d.ts +37 -0
- package/dist/batch/cloudflare.d.ts.map +1 -0
- package/dist/batch/cloudflare.js +289 -0
- package/dist/batch/cloudflare.js.map +1 -0
- package/dist/batch/google.d.ts +41 -0
- package/dist/batch/google.d.ts.map +1 -0
- package/dist/batch/google.js +360 -0
- package/dist/batch/google.js.map +1 -0
- package/dist/batch/index.d.ts +31 -0
- package/dist/batch/index.d.ts.map +1 -0
- package/dist/batch/index.js +31 -0
- package/dist/batch/index.js.map +1 -0
- package/dist/batch/memory.d.ts +44 -0
- package/dist/batch/memory.d.ts.map +1 -0
- package/dist/batch/memory.js +188 -0
- package/dist/batch/memory.js.map +1 -0
- package/dist/batch/openai.d.ts +37 -0
- package/dist/batch/openai.d.ts.map +1 -0
- package/dist/batch/openai.js +403 -0
- package/dist/batch/openai.js.map +1 -0
- package/dist/batch-map.d.ts +125 -0
- package/dist/batch-map.d.ts.map +1 -0
- package/dist/batch-map.js +406 -0
- package/dist/batch-map.js.map +1 -0
- package/dist/batch-queue.d.ts +273 -0
- package/dist/batch-queue.d.ts.map +1 -0
- package/dist/batch-queue.js +271 -0
- package/dist/batch-queue.js.map +1 -0
- package/dist/context.d.ts +133 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +267 -0
- package/dist/context.js.map +1 -0
- package/dist/embeddings.d.ts +123 -0
- package/dist/embeddings.d.ts.map +1 -0
- package/dist/embeddings.js +170 -0
- package/dist/embeddings.js.map +1 -0
- package/dist/eval/index.d.ts +8 -0
- package/dist/eval/index.d.ts.map +1 -0
- package/dist/eval/index.js +8 -0
- package/dist/eval/index.js.map +1 -0
- package/dist/eval/models.d.ts +66 -0
- package/dist/eval/models.d.ts.map +1 -0
- package/dist/eval/models.js +120 -0
- package/dist/eval/models.js.map +1 -0
- package/dist/eval/runner.d.ts +64 -0
- package/dist/eval/runner.d.ts.map +1 -0
- package/dist/eval/runner.js +148 -0
- package/dist/eval/runner.js.map +1 -0
- package/dist/generate.d.ts +168 -0
- package/dist/generate.d.ts.map +1 -0
- package/dist/generate.js +174 -0
- package/dist/generate.js.map +1 -0
- package/dist/index.d.ts +29 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +53 -52
- package/dist/index.js.map +1 -1
- package/dist/primitives.d.ts +292 -0
- package/dist/primitives.d.ts.map +1 -0
- package/dist/primitives.js +471 -0
- package/dist/primitives.js.map +1 -0
- package/dist/providers/cloudflare.d.ts +9 -0
- package/dist/providers/cloudflare.d.ts.map +1 -0
- package/dist/providers/cloudflare.js +9 -0
- package/dist/providers/cloudflare.js.map +1 -0
- package/dist/providers/index.d.ts +9 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +9 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/schema.d.ts +54 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +109 -0
- package/dist/schema.js.map +1 -0
- package/dist/template.d.ts +73 -0
- package/dist/template.d.ts.map +1 -0
- package/dist/template.js +129 -0
- package/dist/template.js.map +1 -0
- package/dist/types.d.ts +474 -106
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +4 -8
- package/dist/types.js.map +1 -1
- package/evalite.config.ts +19 -0
- package/evals/README.md +212 -0
- package/evals/classification.eval.ts +108 -0
- package/evals/marketing.eval.ts +370 -0
- package/evals/math.eval.ts +94 -0
- package/evals/run-evals.ts +166 -0
- package/evals/structured-output.eval.ts +143 -0
- package/evals/writing.eval.ts +117 -0
- package/examples/batch-blog-posts.ts +160 -0
- package/package.json +57 -57
- package/src/ai-promise.ts +784 -0
- package/src/ai.ts +1183 -0
- package/src/batch/anthropic.ts +375 -0
- package/src/batch/bedrock.ts +801 -0
- package/src/batch/cloudflare.ts +421 -0
- package/src/batch/google.ts +491 -0
- package/src/batch/index.ts +31 -0
- package/src/batch/memory.ts +253 -0
- package/src/batch/openai.ts +557 -0
- package/src/batch-map.ts +534 -0
- package/src/batch-queue.ts +493 -0
- package/src/context.ts +332 -0
- package/src/embeddings.ts +244 -0
- package/src/eval/index.ts +8 -0
- package/src/eval/models.ts +158 -0
- package/src/eval/runner.ts +217 -0
- package/src/generate.ts +245 -0
- package/src/index.ts +154 -0
- package/src/primitives.ts +612 -0
- package/src/providers/cloudflare.ts +15 -0
- package/src/providers/index.ts +14 -0
- package/src/schema.ts +147 -0
- package/src/template.ts +209 -0
- package/src/types.ts +540 -0
- package/test/README.md +105 -0
- package/test/ai-proxy.test.ts +192 -0
- package/test/async-iterators.test.ts +327 -0
- package/test/batch-background.test.ts +482 -0
- package/test/batch-blog-posts.test.ts +387 -0
- package/test/blog-generation.test.ts +510 -0
- package/test/browse-read.test.ts +611 -0
- package/test/core-functions.test.ts +694 -0
- package/test/decide.test.ts +393 -0
- package/test/define.test.ts +274 -0
- package/test/e2e-bedrock-manual.ts +163 -0
- package/test/e2e-bedrock.test.ts +191 -0
- package/test/e2e-flex-gateway.ts +157 -0
- package/test/e2e-flex-manual.ts +183 -0
- package/test/e2e-flex.test.ts +209 -0
- package/test/e2e-google-manual.ts +178 -0
- package/test/e2e-google.test.ts +216 -0
- package/test/embeddings.test.ts +284 -0
- package/test/evals/define-function.eval.test.ts +379 -0
- package/test/evals/primitives.eval.test.ts +384 -0
- package/test/function-types.test.ts +492 -0
- package/test/generate-core.test.ts +319 -0
- package/test/generate.test.ts +163 -0
- package/test/implicit-batch.test.ts +422 -0
- package/test/schema.test.ts +109 -0
- package/test/tagged-templates.test.ts +302 -0
- package/tsconfig.json +10 -0
- package/vitest.config.ts +42 -0
- package/LICENSE +0 -21
- package/bin/cli.js +0 -5
- package/dist/cli/index.d.ts +0 -10
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js +0 -38
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/index.test.d.ts +0 -2
- package/dist/cli/index.test.d.ts.map +0 -1
- package/dist/cli/index.test.js +0 -35
- package/dist/cli/index.test.js.map +0 -1
- package/dist/constants/models.d.ts +0 -10
- package/dist/constants/models.d.ts.map +0 -1
- package/dist/constants/models.js +0 -12
- package/dist/constants/models.js.map +0 -1
- package/dist/converters/index.d.ts +0 -3
- package/dist/converters/index.d.ts.map +0 -1
- package/dist/converters/index.js +0 -3
- package/dist/converters/index.js.map +0 -1
- package/dist/converters/model.d.ts +0 -4
- package/dist/converters/model.d.ts.map +0 -1
- package/dist/converters/model.js +0 -19
- package/dist/converters/model.js.map +0 -1
- package/dist/converters/schema.d.ts +0 -4
- package/dist/converters/schema.d.ts.map +0 -1
- package/dist/converters/schema.js +0 -25
- package/dist/converters/schema.js.map +0 -1
- package/dist/core/responses.d.ts +0 -5
- package/dist/core/responses.d.ts.map +0 -1
- package/dist/core/responses.js +0 -16
- package/dist/core/responses.js.map +0 -1
- package/dist/core/responses.test.d.ts +0 -2
- package/dist/core/responses.test.d.ts.map +0 -1
- package/dist/core/responses.test.js +0 -31
- package/dist/core/responses.test.js.map +0 -1
- package/dist/errors.d.ts +0 -6
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js +0 -9
- package/dist/errors.js.map +0 -1
- package/dist/examples/streaming.test.d.ts +0 -2
- package/dist/examples/streaming.test.d.ts.map +0 -1
- package/dist/examples/streaming.test.js +0 -176
- package/dist/examples/streaming.test.js.map +0 -1
- package/dist/factory/__tests__/index.test.d.ts +0 -2
- package/dist/factory/__tests__/index.test.d.ts.map +0 -1
- package/dist/factory/__tests__/index.test.js +0 -430
- package/dist/factory/__tests__/index.test.js.map +0 -1
- package/dist/factory/__tests__/list.test.d.ts +0 -2
- package/dist/factory/__tests__/list.test.d.ts.map +0 -1
- package/dist/factory/__tests__/list.test.js +0 -92
- package/dist/factory/__tests__/list.test.js.map +0 -1
- package/dist/factory/index.d.ts +0 -20
- package/dist/factory/index.d.ts.map +0 -1
- package/dist/factory/index.js +0 -287
- package/dist/factory/index.js.map +0 -1
- package/dist/factory/index.test.d.ts +0 -2
- package/dist/factory/index.test.d.ts.map +0 -1
- package/dist/factory/index.test.js +0 -287
- package/dist/factory/index.test.js.map +0 -1
- package/dist/factory/list.d.ts +0 -3
- package/dist/factory/list.d.ts.map +0 -1
- package/dist/factory/list.js +0 -221
- package/dist/factory/list.js.map +0 -1
- package/dist/factory/list.test.d.ts +0 -2
- package/dist/factory/list.test.d.ts.map +0 -1
- package/dist/factory/list.test.js +0 -84
- package/dist/factory/list.test.js.map +0 -1
- package/dist/generate/index.d.ts +0 -5
- package/dist/generate/index.d.ts.map +0 -1
- package/dist/generate/index.js +0 -17
- package/dist/generate/index.js.map +0 -1
- package/dist/index.test.d.ts +0 -2
- package/dist/index.test.d.ts.map +0 -1
- package/dist/index.test.js +0 -59
- package/dist/index.test.js.map +0 -1
- package/dist/list/await.d.ts +0 -3
- package/dist/list/await.d.ts.map +0 -1
- package/dist/list/await.js +0 -28
- package/dist/list/await.js.map +0 -1
- package/dist/list/constants.d.ts +0 -4
- package/dist/list/constants.d.ts.map +0 -1
- package/dist/list/constants.js +0 -5
- package/dist/list/constants.js.map +0 -1
- package/dist/list/create-function.d.ts +0 -3
- package/dist/list/create-function.d.ts.map +0 -1
- package/dist/list/create-function.js +0 -11
- package/dist/list/create-function.js.map +0 -1
- package/dist/list/index.d.ts +0 -4
- package/dist/list/index.d.ts.map +0 -1
- package/dist/list/index.js +0 -5
- package/dist/list/index.js.map +0 -1
- package/dist/list/prompt.d.ts +0 -3
- package/dist/list/prompt.d.ts.map +0 -1
- package/dist/list/prompt.js +0 -6
- package/dist/list/prompt.js.map +0 -1
- package/dist/list/schemas.d.ts +0 -4
- package/dist/list/schemas.d.ts.map +0 -1
- package/dist/list/schemas.js +0 -8
- package/dist/list/schemas.js.map +0 -1
- package/dist/list/stream.d.ts +0 -3
- package/dist/list/stream.d.ts.map +0 -1
- package/dist/list/stream.js +0 -33
- package/dist/list/stream.js.map +0 -1
- package/dist/list/types.d.ts +0 -11
- package/dist/list/types.d.ts.map +0 -1
- package/dist/list/types.js +0 -2
- package/dist/list/types.js.map +0 -1
- package/dist/list/validation.d.ts +0 -3
- package/dist/list/validation.d.ts.map +0 -1
- package/dist/list/validation.js +0 -12
- package/dist/list/validation.js.map +0 -1
- package/dist/providers/config.d.ts +0 -4
- package/dist/providers/config.d.ts.map +0 -1
- package/dist/providers/config.js +0 -21
- package/dist/providers/config.js.map +0 -1
- package/dist/providers/config.test.d.ts +0 -2
- package/dist/providers/config.test.d.ts.map +0 -1
- package/dist/providers/config.test.js +0 -37
- package/dist/providers/config.test.js.map +0 -1
- package/dist/proxy/constants.d.ts +0 -4
- package/dist/proxy/constants.d.ts.map +0 -1
- package/dist/proxy/constants.js +0 -5
- package/dist/proxy/constants.js.map +0 -1
- package/dist/proxy/create-function.d.ts +0 -4
- package/dist/proxy/create-function.d.ts.map +0 -1
- package/dist/proxy/create-function.js +0 -24
- package/dist/proxy/create-function.js.map +0 -1
- package/dist/proxy/create-proxy.d.ts +0 -2
- package/dist/proxy/create-proxy.d.ts.map +0 -1
- package/dist/proxy/create-proxy.js +0 -11
- package/dist/proxy/create-proxy.js.map +0 -1
- package/dist/proxy/function-generator.d.ts +0 -9
- package/dist/proxy/function-generator.d.ts.map +0 -1
- package/dist/proxy/function-generator.js +0 -29
- package/dist/proxy/function-generator.js.map +0 -1
- package/dist/proxy/index.d.ts +0 -4
- package/dist/proxy/index.d.ts.map +0 -1
- package/dist/proxy/index.js +0 -4
- package/dist/proxy/index.js.map +0 -1
- package/dist/proxy/prompt.d.ts +0 -2
- package/dist/proxy/prompt.d.ts.map +0 -1
- package/dist/proxy/prompt.js +0 -6
- package/dist/proxy/prompt.js.map +0 -1
- package/dist/proxy/types.d.ts +0 -7
- package/dist/proxy/types.d.ts.map +0 -1
- package/dist/proxy/types.js +0 -2
- package/dist/proxy/types.js.map +0 -1
- package/dist/queue/manager.d.ts +0 -5
- package/dist/queue/manager.d.ts.map +0 -1
- package/dist/queue/manager.js +0 -37
- package/dist/queue/manager.js.map +0 -1
- package/dist/queue/manager.test.d.ts +0 -2
- package/dist/queue/manager.test.d.ts.map +0 -1
- package/dist/queue/manager.test.js +0 -52
- package/dist/queue/manager.test.js.map +0 -1
- package/dist/schema-converter.d.ts +0 -4
- package/dist/schema-converter.d.ts.map +0 -1
- package/dist/schema-converter.js +0 -30
- package/dist/schema-converter.js.map +0 -1
- package/dist/stream/index.d.ts +0 -7
- package/dist/stream/index.d.ts.map +0 -1
- package/dist/stream/index.js +0 -23
- package/dist/stream/index.js.map +0 -1
- package/dist/streaming/utils.d.ts +0 -4
- package/dist/streaming/utils.d.ts.map +0 -1
- package/dist/streaming/utils.js +0 -131
- package/dist/streaming/utils.js.map +0 -1
- package/dist/streaming/utils.test.d.ts +0 -2
- package/dist/streaming/utils.test.d.ts.map +0 -1
- package/dist/streaming/utils.test.js +0 -84
- package/dist/streaming/utils.test.js.map +0 -1
- package/dist/templates/result.d.ts +0 -7
- package/dist/templates/result.d.ts.map +0 -1
- package/dist/templates/result.js +0 -40
- package/dist/templates/result.js.map +0 -1
- package/dist/templates/result.test.d.ts +0 -2
- package/dist/templates/result.test.d.ts.map +0 -1
- package/dist/templates/result.test.js +0 -75
- package/dist/templates/result.test.js.map +0 -1
- package/dist/test/setup.d.ts +0 -2
- package/dist/test/setup.d.ts.map +0 -1
- package/dist/test/setup.js +0 -21
- package/dist/test/setup.js.map +0 -1
- package/dist/test-types.d.ts +0 -13
- package/dist/test-types.d.ts.map +0 -1
- package/dist/test-types.js +0 -55
- package/dist/test-types.js.map +0 -1
- package/dist/types/index.d.ts +0 -4
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -4
- package/dist/types/index.js.map +0 -1
- package/dist/types/list.d.ts +0 -10
- package/dist/types/list.d.ts.map +0 -1
- package/dist/types/list.js +0 -2
- package/dist/types/list.js.map +0 -1
- package/dist/types/model.d.ts +0 -7
- package/dist/types/model.d.ts.map +0 -1
- package/dist/types/model.js +0 -2
- package/dist/types/model.js.map +0 -1
- package/dist/types/options.d.ts +0 -25
- package/dist/types/options.d.ts.map +0 -1
- package/dist/types/options.js +0 -2
- package/dist/types/options.js.map +0 -1
- package/dist/types/schema.d.ts +0 -5
- package/dist/types/schema.d.ts.map +0 -1
- package/dist/types/schema.js +0 -2
- package/dist/types/schema.js.map +0 -1
- package/dist/utils/__tests__/request-handler.test.d.ts +0 -2
- package/dist/utils/__tests__/request-handler.test.d.ts.map +0 -1
- package/dist/utils/__tests__/request-handler.test.js +0 -134
- package/dist/utils/__tests__/request-handler.test.js.map +0 -1
- package/dist/utils/__tests__/schema.test.d.ts +0 -2
- package/dist/utils/__tests__/schema.test.d.ts.map +0 -1
- package/dist/utils/__tests__/schema.test.js +0 -49
- package/dist/utils/__tests__/schema.test.js.map +0 -1
- package/dist/utils/__tests__/stream-progress.test.d.ts +0 -2
- package/dist/utils/__tests__/stream-progress.test.d.ts.map +0 -1
- package/dist/utils/__tests__/stream-progress.test.js +0 -85
- package/dist/utils/__tests__/stream-progress.test.js.map +0 -1
- package/dist/utils/index.d.ts +0 -2
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -2
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/request-handler.d.ts +0 -17
- package/dist/utils/request-handler.d.ts.map +0 -1
- package/dist/utils/request-handler.js +0 -105
- package/dist/utils/request-handler.js.map +0 -1
- package/dist/utils/schema.d.ts +0 -11
- package/dist/utils/schema.d.ts.map +0 -1
- package/dist/utils/schema.js +0 -51
- package/dist/utils/schema.js.map +0 -1
- package/dist/utils/stream-progress.d.ts +0 -17
- package/dist/utils/stream-progress.d.ts.map +0 -1
- package/dist/utils/stream-progress.js +0 -86
- package/dist/utils/stream-progress.js.map +0 -1
- package/dist/utils/validation.d.ts +0 -3
- package/dist/utils/validation.d.ts.map +0 -1
- package/dist/utils/validation.js +0 -30
- package/dist/utils/validation.js.map +0 -1
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Primitives Eval Suite
|
|
3
|
+
*
|
|
4
|
+
* Tests the core AI functions (code, ai, list, is, etc.) with real AI calls
|
|
5
|
+
* across multiple models to ensure consistent behavior and quality.
|
|
6
|
+
*
|
|
7
|
+
* Run with: pnpm test -- test/evals/primitives.eval.test.ts
|
|
8
|
+
* Run specific model: MODEL=sonnet pnpm test -- test/evals/primitives.eval.test.ts
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { describe, it, expect, beforeAll } from 'vitest'
|
|
12
|
+
import { ai, code, list, is, summarize, extract, write, lists } from '../../src/primitives.js'
|
|
13
|
+
import { EVAL_MODELS, type EvalModel, type ModelTier } from '../../src/eval/models.js'
|
|
14
|
+
|
|
15
|
+
// Configuration
|
|
16
|
+
const EVAL_TIERS: ModelTier[] = (process.env.EVAL_TIERS?.split(',') as ModelTier[]) || ['fast']
|
|
17
|
+
const SINGLE_MODEL = process.env.MODEL
|
|
18
|
+
|
|
19
|
+
// Get models to test
|
|
20
|
+
function getTestModels(): EvalModel[] {
|
|
21
|
+
if (SINGLE_MODEL) {
|
|
22
|
+
const model = EVAL_MODELS.find(m => m.id === SINGLE_MODEL || m.name.toLowerCase().includes(SINGLE_MODEL.toLowerCase()))
|
|
23
|
+
return model ? [model] : EVAL_MODELS.filter(m => m.tier === 'fast').slice(0, 1)
|
|
24
|
+
}
|
|
25
|
+
return EVAL_MODELS.filter(m => EVAL_TIERS.includes(m.tier))
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Skip if no API access
|
|
29
|
+
const hasAPI = !!process.env.AI_GATEWAY_URL || !!process.env.ANTHROPIC_API_KEY || !!process.env.OPENAI_API_KEY
|
|
30
|
+
|
|
31
|
+
// Test timeout for AI calls
|
|
32
|
+
const AI_TIMEOUT = 30000
|
|
33
|
+
|
|
34
|
+
describe.skipIf(!hasAPI)('AI Primitives Evals', () => {
|
|
35
|
+
const models = getTestModels()
|
|
36
|
+
|
|
37
|
+
beforeAll(() => {
|
|
38
|
+
console.log(`\nRunning evals on ${models.length} models: ${models.map(m => m.name).join(', ')}\n`)
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
// ==========================================================================
|
|
42
|
+
// code() - Code Generation
|
|
43
|
+
// ==========================================================================
|
|
44
|
+
describe('code()', () => {
|
|
45
|
+
const testCases = [
|
|
46
|
+
{
|
|
47
|
+
name: 'generates email validation function',
|
|
48
|
+
prompt: 'email validation function in TypeScript',
|
|
49
|
+
validate: (result: string) => {
|
|
50
|
+
expect(typeof result).toBe('string')
|
|
51
|
+
expect(result.length).toBeGreaterThan(20)
|
|
52
|
+
// Should contain function-like syntax
|
|
53
|
+
expect(result).toMatch(/function|const|=>|def|public/)
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: 'generates a sorting algorithm',
|
|
58
|
+
prompt: 'quicksort function in JavaScript',
|
|
59
|
+
validate: (result: string) => {
|
|
60
|
+
expect(typeof result).toBe('string')
|
|
61
|
+
expect(result.toLowerCase()).toMatch(/sort|pivot|partition|array/)
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: 'generates API endpoint',
|
|
66
|
+
prompt: 'REST API endpoint for user authentication in Express.js',
|
|
67
|
+
validate: (result: string) => {
|
|
68
|
+
expect(typeof result).toBe('string')
|
|
69
|
+
expect(result).toMatch(/router|app\.|req|res|post|get/i)
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
for (const model of models) {
|
|
75
|
+
describe(`[${model.name}]`, () => {
|
|
76
|
+
for (const tc of testCases) {
|
|
77
|
+
it(tc.name, async () => {
|
|
78
|
+
const result = await code(tc.prompt, { model: model.id })
|
|
79
|
+
tc.validate(result)
|
|
80
|
+
}, AI_TIMEOUT)
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
// ==========================================================================
|
|
87
|
+
// ai() - General AI with Dynamic Schema
|
|
88
|
+
// ==========================================================================
|
|
89
|
+
describe('ai()', () => {
|
|
90
|
+
const testCases = [
|
|
91
|
+
{
|
|
92
|
+
name: 'generates text response',
|
|
93
|
+
prompt: 'explain what TypeScript is in one sentence',
|
|
94
|
+
validate: (result: unknown) => {
|
|
95
|
+
expect(result).toBeDefined()
|
|
96
|
+
// ai() returns object by default with dynamic schema
|
|
97
|
+
expect(typeof result === 'string' || typeof result === 'object').toBe(true)
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: 'handles complex prompts',
|
|
102
|
+
prompt: 'analyze the pros and cons of microservices architecture',
|
|
103
|
+
validate: (result: unknown) => {
|
|
104
|
+
expect(result).toBeDefined()
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
]
|
|
108
|
+
|
|
109
|
+
for (const model of models) {
|
|
110
|
+
describe(`[${model.name}]`, () => {
|
|
111
|
+
for (const tc of testCases) {
|
|
112
|
+
it(tc.name, async () => {
|
|
113
|
+
const result = await ai(tc.prompt, { model: model.id })
|
|
114
|
+
tc.validate(result)
|
|
115
|
+
}, AI_TIMEOUT)
|
|
116
|
+
}
|
|
117
|
+
})
|
|
118
|
+
}
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
// ==========================================================================
|
|
122
|
+
// list() - List Generation
|
|
123
|
+
// ==========================================================================
|
|
124
|
+
describe('list()', () => {
|
|
125
|
+
const testCases = [
|
|
126
|
+
{
|
|
127
|
+
name: 'generates list of programming languages',
|
|
128
|
+
prompt: '5 popular programming languages',
|
|
129
|
+
validate: (result: string[]) => {
|
|
130
|
+
expect(Array.isArray(result)).toBe(true)
|
|
131
|
+
expect(result.length).toBeGreaterThanOrEqual(3)
|
|
132
|
+
expect(result.every(item => typeof item === 'string')).toBe(true)
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
name: 'generates list of startup ideas',
|
|
137
|
+
prompt: '3 AI startup ideas',
|
|
138
|
+
validate: (result: string[]) => {
|
|
139
|
+
expect(Array.isArray(result)).toBe(true)
|
|
140
|
+
expect(result.length).toBeGreaterThanOrEqual(2)
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
name: 'generates list with specific count',
|
|
145
|
+
prompt: '7 colors of the rainbow',
|
|
146
|
+
validate: (result: string[]) => {
|
|
147
|
+
expect(Array.isArray(result)).toBe(true)
|
|
148
|
+
// Should be close to 7
|
|
149
|
+
expect(result.length).toBeGreaterThanOrEqual(5)
|
|
150
|
+
expect(result.length).toBeLessThanOrEqual(10)
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
]
|
|
154
|
+
|
|
155
|
+
for (const model of models) {
|
|
156
|
+
describe(`[${model.name}]`, () => {
|
|
157
|
+
for (const tc of testCases) {
|
|
158
|
+
it(tc.name, async () => {
|
|
159
|
+
const result = await list(tc.prompt, { model: model.id })
|
|
160
|
+
tc.validate(result)
|
|
161
|
+
}, AI_TIMEOUT)
|
|
162
|
+
}
|
|
163
|
+
})
|
|
164
|
+
}
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
// ==========================================================================
|
|
168
|
+
// is() - Boolean Classification
|
|
169
|
+
// ==========================================================================
|
|
170
|
+
describe('is()', () => {
|
|
171
|
+
const testCases = [
|
|
172
|
+
{
|
|
173
|
+
name: 'correctly identifies valid email',
|
|
174
|
+
prompt: 'hello@example.com a valid email address',
|
|
175
|
+
expected: true,
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
name: 'correctly identifies invalid email',
|
|
179
|
+
prompt: 'not-an-email a valid email address',
|
|
180
|
+
expected: false,
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
name: 'correctly identifies positive sentiment',
|
|
184
|
+
prompt: '"I love this product, it is amazing!" positive sentiment',
|
|
185
|
+
expected: true,
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
name: 'correctly identifies negative sentiment',
|
|
189
|
+
prompt: '"This is terrible, worst purchase ever" positive sentiment',
|
|
190
|
+
expected: false,
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
name: 'correctly identifies programming language',
|
|
194
|
+
prompt: 'Python a programming language',
|
|
195
|
+
expected: true,
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
name: 'correctly identifies non-programming language',
|
|
199
|
+
prompt: 'Banana a programming language',
|
|
200
|
+
expected: false,
|
|
201
|
+
},
|
|
202
|
+
]
|
|
203
|
+
|
|
204
|
+
for (const model of models) {
|
|
205
|
+
describe(`[${model.name}]`, () => {
|
|
206
|
+
for (const tc of testCases) {
|
|
207
|
+
it(tc.name, async () => {
|
|
208
|
+
const result = await is(tc.prompt, { model: model.id })
|
|
209
|
+
expect(typeof result).toBe('boolean')
|
|
210
|
+
expect(result).toBe(tc.expected)
|
|
211
|
+
}, AI_TIMEOUT)
|
|
212
|
+
}
|
|
213
|
+
})
|
|
214
|
+
}
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
// ==========================================================================
|
|
218
|
+
// summarize() - Text Summarization
|
|
219
|
+
// ==========================================================================
|
|
220
|
+
describe('summarize()', () => {
|
|
221
|
+
const longText = `
|
|
222
|
+
Artificial intelligence (AI) is intelligence demonstrated by machines, as opposed to natural intelligence displayed by animals including humans.
|
|
223
|
+
AI research has been defined as the field of study of intelligent agents, which refers to any system that perceives its environment and takes actions that maximize its chance of achieving its goals.
|
|
224
|
+
The term "artificial intelligence" had previously been used to describe machines that mimic and display "human" cognitive skills that are associated with the human mind, such as "learning" and "problem-solving".
|
|
225
|
+
This definition has since been rejected by major AI researchers who now describe AI in terms of rationality and acting rationally, which does not limit how intelligence can be articulated.
|
|
226
|
+
AI applications include advanced web search engines, recommendation systems, understanding human speech, self-driving cars, automated decision-making and competing at the highest level in strategic game systems.
|
|
227
|
+
`
|
|
228
|
+
|
|
229
|
+
const testCases = [
|
|
230
|
+
{
|
|
231
|
+
name: 'summarizes long text',
|
|
232
|
+
input: longText,
|
|
233
|
+
validate: (result: string) => {
|
|
234
|
+
expect(typeof result).toBe('string')
|
|
235
|
+
expect(result.length).toBeGreaterThan(20)
|
|
236
|
+
expect(result.length).toBeLessThan(longText.length)
|
|
237
|
+
// Should mention AI or artificial intelligence
|
|
238
|
+
expect(result.toLowerCase()).toMatch(/ai|artificial intelligence|machine|intelligence/)
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
name: 'summarizes technical content',
|
|
243
|
+
input: 'REST (Representational State Transfer) is an architectural style for distributed hypermedia systems. It was introduced by Roy Fielding in 2000. REST APIs use HTTP methods (GET, POST, PUT, DELETE) to perform CRUD operations on resources identified by URIs.',
|
|
244
|
+
validate: (result: string) => {
|
|
245
|
+
expect(typeof result).toBe('string')
|
|
246
|
+
expect(result.length).toBeGreaterThan(10)
|
|
247
|
+
expect(result.toLowerCase()).toMatch(/rest|api|http/)
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
]
|
|
251
|
+
|
|
252
|
+
for (const model of models) {
|
|
253
|
+
describe(`[${model.name}]`, () => {
|
|
254
|
+
for (const tc of testCases) {
|
|
255
|
+
it(tc.name, async () => {
|
|
256
|
+
const result = await summarize(tc.input, { model: model.id })
|
|
257
|
+
tc.validate(result)
|
|
258
|
+
}, AI_TIMEOUT)
|
|
259
|
+
}
|
|
260
|
+
})
|
|
261
|
+
}
|
|
262
|
+
})
|
|
263
|
+
|
|
264
|
+
// ==========================================================================
|
|
265
|
+
// extract() - Data Extraction
|
|
266
|
+
// ==========================================================================
|
|
267
|
+
describe('extract()', () => {
|
|
268
|
+
const testCases = [
|
|
269
|
+
{
|
|
270
|
+
name: 'extracts email addresses',
|
|
271
|
+
prompt: 'email addresses from "Contact us at support@example.com or sales@company.org for assistance"',
|
|
272
|
+
validate: (result: unknown[]) => {
|
|
273
|
+
expect(Array.isArray(result)).toBe(true)
|
|
274
|
+
expect(result.length).toBeGreaterThanOrEqual(1)
|
|
275
|
+
// Should contain email-like strings
|
|
276
|
+
const resultStr = JSON.stringify(result).toLowerCase()
|
|
277
|
+
expect(resultStr).toMatch(/@/)
|
|
278
|
+
},
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
name: 'extracts names',
|
|
282
|
+
prompt: 'person names from "The meeting was attended by John Smith, Jane Doe, and Bob Johnson"',
|
|
283
|
+
validate: (result: unknown[]) => {
|
|
284
|
+
expect(Array.isArray(result)).toBe(true)
|
|
285
|
+
expect(result.length).toBeGreaterThanOrEqual(2)
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
name: 'extracts numbers',
|
|
290
|
+
prompt: 'numbers from "The product costs $49.99 and we sold 150 units in Q3 with 23% growth"',
|
|
291
|
+
validate: (result: unknown[]) => {
|
|
292
|
+
expect(Array.isArray(result)).toBe(true)
|
|
293
|
+
expect(result.length).toBeGreaterThanOrEqual(2)
|
|
294
|
+
},
|
|
295
|
+
},
|
|
296
|
+
]
|
|
297
|
+
|
|
298
|
+
for (const model of models) {
|
|
299
|
+
describe(`[${model.name}]`, () => {
|
|
300
|
+
for (const tc of testCases) {
|
|
301
|
+
it(tc.name, async () => {
|
|
302
|
+
const result = await extract(tc.prompt, { model: model.id })
|
|
303
|
+
tc.validate(result)
|
|
304
|
+
}, AI_TIMEOUT)
|
|
305
|
+
}
|
|
306
|
+
})
|
|
307
|
+
}
|
|
308
|
+
})
|
|
309
|
+
|
|
310
|
+
// ==========================================================================
|
|
311
|
+
// write() - Text Generation
|
|
312
|
+
// ==========================================================================
|
|
313
|
+
describe('write()', () => {
|
|
314
|
+
const testCases = [
|
|
315
|
+
{
|
|
316
|
+
name: 'writes professional email',
|
|
317
|
+
prompt: 'a professional email to schedule a meeting',
|
|
318
|
+
validate: (result: string) => {
|
|
319
|
+
expect(typeof result).toBe('string')
|
|
320
|
+
expect(result.length).toBeGreaterThan(50)
|
|
321
|
+
expect(result.toLowerCase()).toMatch(/meeting|schedule|time|available/)
|
|
322
|
+
},
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
name: 'writes product description',
|
|
326
|
+
prompt: 'a short product description for a wireless bluetooth headphone',
|
|
327
|
+
validate: (result: string) => {
|
|
328
|
+
expect(typeof result).toBe('string')
|
|
329
|
+
expect(result.length).toBeGreaterThan(30)
|
|
330
|
+
expect(result.toLowerCase()).toMatch(/wireless|bluetooth|headphone|audio|sound/)
|
|
331
|
+
},
|
|
332
|
+
},
|
|
333
|
+
]
|
|
334
|
+
|
|
335
|
+
for (const model of models) {
|
|
336
|
+
describe(`[${model.name}]`, () => {
|
|
337
|
+
for (const tc of testCases) {
|
|
338
|
+
it(tc.name, async () => {
|
|
339
|
+
const result = await write(tc.prompt, { model: model.id })
|
|
340
|
+
tc.validate(result)
|
|
341
|
+
}, AI_TIMEOUT)
|
|
342
|
+
}
|
|
343
|
+
})
|
|
344
|
+
}
|
|
345
|
+
})
|
|
346
|
+
|
|
347
|
+
// ==========================================================================
|
|
348
|
+
// lists() - Multiple Named Lists
|
|
349
|
+
// ==========================================================================
|
|
350
|
+
describe('lists()', () => {
|
|
351
|
+
const testCases = [
|
|
352
|
+
{
|
|
353
|
+
name: 'generates pros and cons',
|
|
354
|
+
prompt: 'pros and cons of remote work',
|
|
355
|
+
validate: (result: Record<string, string[]>) => {
|
|
356
|
+
expect(typeof result).toBe('object')
|
|
357
|
+
// Should have categorized lists
|
|
358
|
+
const keys = Object.keys(result)
|
|
359
|
+
expect(keys.length).toBeGreaterThanOrEqual(1)
|
|
360
|
+
},
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
name: 'generates SWOT analysis',
|
|
364
|
+
prompt: 'strengths weaknesses opportunities and threats for a startup',
|
|
365
|
+
validate: (result: Record<string, string[]>) => {
|
|
366
|
+
expect(typeof result).toBe('object')
|
|
367
|
+
const keys = Object.keys(result)
|
|
368
|
+
expect(keys.length).toBeGreaterThanOrEqual(1)
|
|
369
|
+
},
|
|
370
|
+
},
|
|
371
|
+
]
|
|
372
|
+
|
|
373
|
+
for (const model of models) {
|
|
374
|
+
describe(`[${model.name}]`, () => {
|
|
375
|
+
for (const tc of testCases) {
|
|
376
|
+
it(tc.name, async () => {
|
|
377
|
+
const result = await lists(tc.prompt, { model: model.id })
|
|
378
|
+
tc.validate(result)
|
|
379
|
+
}, AI_TIMEOUT)
|
|
380
|
+
}
|
|
381
|
+
})
|
|
382
|
+
}
|
|
383
|
+
})
|
|
384
|
+
})
|