@zimtsui/brainswitch 0.0.56 → 0.0.59
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 +109 -54
- package/assets/verbatim/declarations.handlebars +11 -0
- package/assets/verbatim/instruction.md +49 -0
- package/build/adaptor.d.ts +40 -9
- package/build/adaptor.js +36 -38
- package/build/adaptor.js.map +1 -1
- package/build/api-types/anthropic/billing.d.ts +5 -5
- package/build/api-types/anthropic/billing.js +1 -2
- package/build/api-types/anthropic/billing.js.map +1 -1
- package/build/api-types/anthropic/tool-codec.d.ts +11 -12
- package/build/api-types/anthropic/tool-codec.js +27 -42
- package/build/api-types/anthropic/tool-codec.js.map +1 -1
- package/build/api-types/google/billing.d.ts +5 -5
- package/build/api-types/google/billing.js +2 -3
- package/build/api-types/google/billing.js.map +1 -1
- package/build/api-types/google/restful-request.d.ts +1 -1
- package/build/api-types/google/restful-request.js +0 -1
- package/build/api-types/google/restful-request.js.map +1 -1
- package/build/api-types/google/tool-codec.d.ts +11 -11
- package/build/api-types/google/tool-codec.js +21 -19
- package/build/api-types/google/tool-codec.js.map +1 -1
- package/build/api-types/{openai-chatcompletion → openai-chatcompletions}/billing.d.ts +2 -3
- package/build/api-types/{openai-chatcompletion → openai-chatcompletions}/billing.js +0 -2
- package/build/api-types/openai-chatcompletions/billing.js.map +1 -0
- package/build/api-types/openai-chatcompletions/tool-codec.d.ts +17 -0
- package/build/api-types/{openai-chatcompletion → openai-chatcompletions}/tool-codec.js +26 -32
- package/build/api-types/openai-chatcompletions/tool-codec.js.map +1 -0
- package/build/api-types/openai-responses/billing.d.ts +5 -5
- package/build/api-types/openai-responses/billing.js +1 -2
- package/build/api-types/openai-responses/billing.js.map +1 -1
- package/build/api-types/openai-responses/tool-codec.d.ts +11 -11
- package/build/api-types/openai-responses/tool-codec.js +36 -32
- package/build/api-types/openai-responses/tool-codec.js.map +1 -1
- package/build/assets.d.ts +7 -0
- package/build/assets.js +8 -0
- package/build/assets.js.map +1 -0
- package/build/compatible-engine/session.d.ts +67 -0
- package/build/compatible-engine/session.js +92 -0
- package/build/compatible-engine/session.js.map +1 -0
- package/build/compatible-engine/structuring.d.ts +36 -0
- package/build/compatible-engine/structuring.js +34 -0
- package/build/compatible-engine/structuring.js.map +1 -0
- package/build/compatible-engine/validation.d.ts +21 -0
- package/build/compatible-engine/validation.js +82 -0
- package/build/compatible-engine/validation.js.map +1 -0
- package/build/compatible-engine.d/agentloop.d.ts +12 -0
- package/build/compatible-engine.d/agentloop.js +52 -0
- package/build/compatible-engine.d/agentloop.js.map +1 -0
- package/build/compatible-engine.d/aliyun/transport.d.ts +12 -0
- package/build/compatible-engine.d/aliyun/transport.js +7 -0
- package/build/compatible-engine.d/aliyun/transport.js.map +1 -0
- package/build/compatible-engine.d/aliyun.d.ts +24 -0
- package/build/compatible-engine.d/aliyun.js +46 -0
- package/build/compatible-engine.d/aliyun.js.map +1 -0
- package/build/compatible-engine.d/anthropic/choice-codec.d.ts +5 -0
- package/build/compatible-engine.d/anthropic/choice-codec.js +26 -0
- package/build/compatible-engine.d/anthropic/choice-codec.js.map +1 -0
- package/build/compatible-engine.d/anthropic/message-codec.d.ts +36 -0
- package/build/compatible-engine.d/anthropic/message-codec.js +86 -0
- package/build/compatible-engine.d/anthropic/message-codec.js.map +1 -0
- package/build/compatible-engine.d/anthropic/transport.d.ts +34 -0
- package/build/compatible-engine.d/anthropic/transport.js +150 -0
- package/build/compatible-engine.d/anthropic/transport.js.map +1 -0
- package/build/compatible-engine.d/anthropic.d.ts +26 -0
- package/build/compatible-engine.d/anthropic.js +46 -0
- package/build/compatible-engine.d/anthropic.js.map +1 -0
- package/build/compatible-engine.d/google/choice-codec.d.ts +5 -0
- package/build/compatible-engine.d/google/choice-codec.js +27 -0
- package/build/compatible-engine.d/google/choice-codec.js.map +1 -0
- package/build/compatible-engine.d/google/message-codec.d.ts +36 -0
- package/build/compatible-engine.d/google/message-codec.js +94 -0
- package/build/compatible-engine.d/google/message-codec.js.map +1 -0
- package/build/compatible-engine.d/google/transport.d.ts +30 -0
- package/build/{compatible.d → compatible-engine.d}/google/transport.js +22 -18
- package/build/compatible-engine.d/google/transport.js.map +1 -0
- package/build/compatible-engine.d/google.d.ts +26 -0
- package/build/compatible-engine.d/google.js +50 -0
- package/build/compatible-engine.d/google.js.map +1 -0
- package/build/compatible-engine.d/openai-chatcompletions/choice-codec.d.ts +5 -0
- package/build/compatible-engine.d/openai-chatcompletions/choice-codec.js +31 -0
- package/build/compatible-engine.d/openai-chatcompletions/choice-codec.js.map +1 -0
- package/build/compatible-engine.d/openai-chatcompletions/message-codec.d.ts +24 -0
- package/build/compatible-engine.d/openai-chatcompletions/message-codec.js +71 -0
- package/build/compatible-engine.d/openai-chatcompletions/message-codec.js.map +1 -0
- package/build/compatible-engine.d/openai-chatcompletions/transport.d/monolith.d.ts +38 -0
- package/build/{compatible.d/openai-chatcompletions.d → compatible-engine.d/openai-chatcompletions/transport.d}/monolith.js +25 -22
- package/build/compatible-engine.d/openai-chatcompletions/transport.d/monolith.js.map +1 -0
- package/build/compatible-engine.d/openai-chatcompletions/transport.d/stream.d.ts +37 -0
- package/build/compatible-engine.d/openai-chatcompletions/transport.d/stream.js +190 -0
- package/build/compatible-engine.d/openai-chatcompletions/transport.d/stream.js.map +1 -0
- package/build/compatible-engine.d/openai-chatcompletions/transport.d.ts +10 -0
- package/build/compatible-engine.d/openai-chatcompletions/transport.js +11 -0
- package/build/compatible-engine.d/openai-chatcompletions/transport.js.map +1 -0
- package/build/compatible-engine.d/openai-chatcompletions.d.ts +17 -0
- package/build/compatible-engine.d/openai-chatcompletions.js +14 -0
- package/build/compatible-engine.d/openai-chatcompletions.js.map +1 -0
- package/build/compatible-engine.d/openai-responses/choice-codec.d.ts +5 -0
- package/build/compatible-engine.d/openai-responses/choice-codec.js +30 -0
- package/build/compatible-engine.d/openai-responses/choice-codec.js.map +1 -0
- package/build/compatible-engine.d/openai-responses/message-codec.d.ts +36 -0
- package/build/compatible-engine.d/openai-responses/message-codec.js +96 -0
- package/build/compatible-engine.d/openai-responses/message-codec.js.map +1 -0
- package/build/compatible-engine.d/openai-responses/transport.d.ts +35 -0
- package/build/{compatible.d → compatible-engine.d}/openai-responses/transport.js +21 -29
- package/build/compatible-engine.d/openai-responses/transport.js.map +1 -0
- package/build/compatible-engine.d/openai-responses.d.ts +26 -0
- package/build/compatible-engine.d/openai-responses.js +46 -0
- package/build/compatible-engine.d/openai-responses.js.map +1 -0
- package/build/compatible-engine.d.ts +22 -0
- package/build/compatible-engine.js +29 -0
- package/build/compatible-engine.js.map +1 -0
- package/build/config.d.ts +1 -0
- package/build/config.js +1 -2
- package/build/config.js.map +1 -1
- package/build/endpoint-spec.d.ts +1 -0
- package/build/endpoint-spec.js +2 -1
- package/build/endpoint-spec.js.map +1 -1
- package/build/engine/session.d.ts +7 -0
- package/build/{session.js.map → engine/session.js.map} +1 -1
- package/build/engine/transport.d.ts +5 -0
- package/build/engine/transport.js +1 -0
- package/build/engine/transport.js.map +1 -0
- package/build/engine/validation.d.ts +9 -0
- package/build/engine/validation.js +1 -0
- package/build/engine/validation.js.map +1 -0
- package/build/engine.d.ts +49 -40
- package/build/engine.js +88 -70
- package/build/engine.js.map +1 -1
- package/build/exports.d.ts +14 -14
- package/build/exports.js +14 -14
- package/build/exports.js.map +1 -1
- package/build/function.d.ts +79 -66
- package/build/function.js +30 -47
- package/build/function.js.map +1 -1
- package/build/inference-context.d.ts +2 -2
- package/build/inference-context.js +0 -1
- package/build/inference-context.js.map +1 -1
- package/build/native-engines.d/google/message-codec.d.ts +18 -16
- package/build/native-engines.d/google/message-codec.js +31 -33
- package/build/native-engines.d/google/message-codec.js.map +1 -1
- package/build/native-engines.d/google/session.d.ts +44 -51
- package/build/native-engines.d/google/session.js +85 -81
- package/build/native-engines.d/google/session.js.map +1 -1
- package/build/native-engines.d/google/transport.d.ts +22 -19
- package/build/native-engines.d/google/transport.js +13 -13
- package/build/native-engines.d/google/transport.js.map +1 -1
- package/build/native-engines.d/google/validation.d.ts +22 -0
- package/build/native-engines.d/google/validation.js +20 -0
- package/build/native-engines.d/google/validation.js.map +1 -0
- package/build/native-engines.d/google.d/agentloop.d.ts +12 -0
- package/build/native-engines.d/google.d/agentloop.js +57 -0
- package/build/native-engines.d/google.d/agentloop.js.map +1 -0
- package/build/native-engines.d/google.d/exports.d.ts +3 -0
- package/build/native-engines.d/google.d/exports.js +4 -0
- package/build/native-engines.d/google.d/exports.js.map +1 -0
- package/build/native-engines.d/google.d.ts +42 -0
- package/build/native-engines.d/google.js +83 -0
- package/build/native-engines.d/google.js.map +1 -0
- package/build/native-engines.d/openai-responses/choice-codec.d.ts +5 -0
- package/build/native-engines.d/openai-responses/choice-codec.js +30 -0
- package/build/native-engines.d/openai-responses/choice-codec.js.map +1 -0
- package/build/native-engines.d/openai-responses/message-codec.d.ts +19 -17
- package/build/native-engines.d/openai-responses/message-codec.js +31 -25
- package/build/native-engines.d/openai-responses/message-codec.js.map +1 -1
- package/build/native-engines.d/openai-responses/session.d.ts +47 -45
- package/build/native-engines.d/openai-responses/session.js +75 -105
- package/build/native-engines.d/openai-responses/session.js.map +1 -1
- package/build/native-engines.d/openai-responses/structuring.d.ts +19 -0
- package/build/native-engines.d/openai-responses/structuring.js +19 -0
- package/build/native-engines.d/openai-responses/structuring.js.map +1 -0
- package/build/native-engines.d/openai-responses/tool.d.ts +15 -12
- package/build/native-engines.d/openai-responses/tool.js +1 -12
- package/build/native-engines.d/openai-responses/tool.js.map +1 -1
- package/build/native-engines.d/openai-responses/transport.d.ts +24 -25
- package/build/native-engines.d/openai-responses/transport.js +21 -41
- package/build/native-engines.d/openai-responses/transport.js.map +1 -1
- package/build/native-engines.d/openai-responses/validation.d.ts +20 -0
- package/build/native-engines.d/openai-responses/validation.js +80 -0
- package/build/native-engines.d/openai-responses/validation.js.map +1 -0
- package/build/native-engines.d/openai-responses.d/agentloop.d.ts +12 -0
- package/build/native-engines.d/openai-responses.d/agentloop.js +61 -0
- package/build/native-engines.d/openai-responses.d/agentloop.js.map +1 -0
- package/build/native-engines.d/openai-responses.d/exports.d.ts +4 -0
- package/build/native-engines.d/openai-responses.d/exports.js +5 -0
- package/build/native-engines.d/openai-responses.d/exports.js.map +1 -0
- package/build/native-engines.d/openai-responses.d.ts +44 -0
- package/build/native-engines.d/openai-responses.js +78 -0
- package/build/native-engines.d/openai-responses.js.map +1 -0
- package/build/throttle.d.ts +6 -5
- package/build/throttle.js +17 -14
- package/build/throttle.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/verbatim/codec/declarations.d.ts +2 -0
- package/build/verbatim/codec/declarations.js +22 -0
- package/build/verbatim/codec/declarations.js.map +1 -0
- package/build/verbatim/codec/request.d.ts +7 -0
- package/build/verbatim/codec/request.js +53 -0
- package/build/verbatim/codec/request.js.map +1 -0
- package/build/verbatim/codec.d.ts +2 -0
- package/build/verbatim/codec.js +3 -0
- package/build/verbatim/codec.js.map +1 -0
- package/build/verbatim.d.ts +74 -0
- package/build/verbatim.js +17 -0
- package/build/verbatim.js.map +1 -0
- package/examples/agent.ts +65 -0
- package/examples/chat.ts +24 -0
- package/examples/config.ts +24 -0
- package/{test/src → examples}/tsconfig.json +6 -2
- package/examples/verbatim.ts +44 -0
- package/package.json +15 -13
- package/build/agentloop.d.ts +0 -12
- package/build/agentloop.js +0 -43
- package/build/agentloop.js.map +0 -1
- package/build/api-types/openai-chatcompletion/billing.js.map +0 -1
- package/build/api-types/openai-chatcompletion/tool-codec.d.ts +0 -18
- package/build/api-types/openai-chatcompletion/tool-codec.js.map +0 -1
- package/build/compatible/engine.d/aliyun.d.ts +0 -23
- package/build/compatible/engine.d/aliyun.js +0 -44
- package/build/compatible/engine.d/aliyun.js.map +0 -1
- package/build/compatible/engine.d/anthropic.d.ts +0 -23
- package/build/compatible/engine.d/anthropic.js +0 -41
- package/build/compatible/engine.d/anthropic.js.map +0 -1
- package/build/compatible/engine.d/google.d.ts +0 -23
- package/build/compatible/engine.d/google.js +0 -45
- package/build/compatible/engine.d/google.js.map +0 -1
- package/build/compatible/engine.d/openai-responses.d.ts +0 -23
- package/build/compatible/engine.d/openai-responses.js +0 -41
- package/build/compatible/engine.d/openai-responses.js.map +0 -1
- package/build/compatible/engine.d.ts +0 -18
- package/build/compatible/engine.js +0 -21
- package/build/compatible/engine.js.map +0 -1
- package/build/compatible/session.d.ts +0 -78
- package/build/compatible/session.js +0 -138
- package/build/compatible/session.js.map +0 -1
- package/build/compatible/tool-call-validator.d.ts +0 -11
- package/build/compatible/tool-call-validator.js +0 -12
- package/build/compatible/tool-call-validator.js.map +0 -1
- package/build/compatible.d/aliyun/transport.d.ts +0 -11
- package/build/compatible.d/aliyun/transport.js +0 -9
- package/build/compatible.d/aliyun/transport.js.map +0 -1
- package/build/compatible.d/anthropic/message-codec.d.ts +0 -31
- package/build/compatible.d/anthropic/message-codec.js +0 -88
- package/build/compatible.d/anthropic/message-codec.js.map +0 -1
- package/build/compatible.d/anthropic/transport.d.ts +0 -31
- package/build/compatible.d/anthropic/transport.js +0 -137
- package/build/compatible.d/anthropic/transport.js.map +0 -1
- package/build/compatible.d/google/message-codec.d.ts +0 -31
- package/build/compatible.d/google/message-codec.js +0 -98
- package/build/compatible.d/google/message-codec.js.map +0 -1
- package/build/compatible.d/google/transport.d.ts +0 -28
- package/build/compatible.d/google/transport.js.map +0 -1
- package/build/compatible.d/openai-chatcompletions/message-codec.d.ts +0 -19
- package/build/compatible.d/openai-chatcompletions/message-codec.js +0 -66
- package/build/compatible.d/openai-chatcompletions/message-codec.js.map +0 -1
- package/build/compatible.d/openai-chatcompletions/transport.d.ts +0 -9
- package/build/compatible.d/openai-chatcompletions/transport.js +0 -25
- package/build/compatible.d/openai-chatcompletions/transport.js.map +0 -1
- package/build/compatible.d/openai-chatcompletions.d/monolith.d.ts +0 -36
- package/build/compatible.d/openai-chatcompletions.d/monolith.js.map +0 -1
- package/build/compatible.d/openai-chatcompletions.d/stream.d.ts +0 -35
- package/build/compatible.d/openai-chatcompletions.d/stream.js +0 -196
- package/build/compatible.d/openai-chatcompletions.d/stream.js.map +0 -1
- package/build/compatible.d/openai-responses/message-codec.d.ts +0 -32
- package/build/compatible.d/openai-responses/message-codec.js +0 -105
- package/build/compatible.d/openai-responses/message-codec.js.map +0 -1
- package/build/compatible.d/openai-responses/transport.d.ts +0 -33
- package/build/compatible.d/openai-responses/transport.js.map +0 -1
- package/build/frontmatter.d.ts +0 -5
- package/build/frontmatter.js +0 -13
- package/build/frontmatter.js.map +0 -1
- package/build/native-engines.d/google/agentloop.d.ts +0 -12
- package/build/native-engines.d/google/agentloop.js +0 -42
- package/build/native-engines.d/google/agentloop.js.map +0 -1
- package/build/native-engines.d/google/engine.d.ts +0 -35
- package/build/native-engines.d/google/engine.js +0 -73
- package/build/native-engines.d/google/engine.js.map +0 -1
- package/build/native-engines.d/google/exports.d.ts +0 -5
- package/build/native-engines.d/google/exports.js +0 -6
- package/build/native-engines.d/google/exports.js.map +0 -1
- package/build/native-engines.d/openai-responses/agentloop.d.ts +0 -13
- package/build/native-engines.d/openai-responses/agentloop.js +0 -53
- package/build/native-engines.d/openai-responses/agentloop.js.map +0 -1
- package/build/native-engines.d/openai-responses/engine.d.ts +0 -32
- package/build/native-engines.d/openai-responses/engine.js +0 -63
- package/build/native-engines.d/openai-responses/engine.js.map +0 -1
- package/build/native-engines.d/openai-responses/exports.d.ts +0 -6
- package/build/native-engines.d/openai-responses/exports.js +0 -7
- package/build/native-engines.d/openai-responses/exports.js.map +0 -1
- package/build/native-engines.d/openai-responses/tool-call-validator.d.ts +0 -12
- package/build/native-engines.d/openai-responses/tool-call-validator.js +0 -33
- package/build/native-engines.d/openai-responses/tool-call-validator.js.map +0 -1
- package/build/session.d.ts +0 -7
- package/test/build/test-codecs.d.ts +0 -1
- package/test/build/test-codecs.js +0 -230
- package/test/build/test-codecs.js.map +0 -1
- package/test/build/test-compatible-engine.d.ts +0 -1
- package/test/build/test-compatible-engine.js +0 -27
- package/test/build/test-compatible-engine.js.map +0 -1
- package/test/build/test-compatible-engines.d.ts +0 -1
- package/test/build/test-compatible-engines.js +0 -112
- package/test/build/test-compatible-engines.js.map +0 -1
- package/test/build/test-engine.d.ts +0 -1
- package/test/build/test-engine.js +0 -97
- package/test/build/test-engine.js.map +0 -1
- package/test/build/test-helpers.d.ts +0 -46
- package/test/build/test-helpers.js +0 -45
- package/test/build/test-helpers.js.map +0 -1
- package/test/build/test-native-engines.d.ts +0 -1
- package/test/build/test-native-engines.js +0 -64
- package/test/build/test-native-engines.js.map +0 -1
- package/test/build/test.d.ts +0 -5
- package/test/build/test.js +0 -6
- package/test/build/test.js.map +0 -1
- package/test/build/tsconfig.tsbuildinfo +0 -1
- package/test/src/test-codecs.ts +0 -256
- package/test/src/test-compatible-engine.ts +0 -45
- package/test/src/test-compatible-engines.ts +0 -129
- package/test/src/test-engine.ts +0 -144
- package/test/src/test-helpers.ts +0 -53
- package/test/src/test-native-engines.ts +0 -75
- package/test/src/test.ts +0 -5
- /package/build/{session.js → engine/session.js} +0 -0
package/test/src/test-codecs.ts
DELETED
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
import test from 'ava';
|
|
2
|
-
import { Function } from '#@/function.ts';
|
|
3
|
-
import { ResponseInvalid } from '#@/engine.ts';
|
|
4
|
-
import { ToolCallValidator } from '#@/compatible/tool-call-validator.ts';
|
|
5
|
-
import { GoogleToolCodec } from '#@/api-types/google/tool-codec.ts';
|
|
6
|
-
import { GoogleCompatibleMessageCodec } from '#@/compatible.d/google/message-codec.ts';
|
|
7
|
-
import { GoogleNativeMessageCodec } from '#@/native-engines.d/google/message-codec.ts';
|
|
8
|
-
import { OpenAIResponsesToolCodec } from '#@/api-types/openai-responses/tool-codec.ts';
|
|
9
|
-
import { OpenAIResponsesCompatibleMessageCodec } from '#@/compatible.d/openai-responses/message-codec.ts';
|
|
10
|
-
import { OpenAIResponsesNativeMessageCodec } from '#@/native-engines.d/openai-responses/message-codec.ts';
|
|
11
|
-
import { OpenAIResponsesNativeToolCallValidator } from '#@/native-engines.d/openai-responses/tool-call-validator.ts';
|
|
12
|
-
import { Tool } from '#@/native-engines.d/openai-responses/tool.ts';
|
|
13
|
-
import { GoogleBilling } from '#@/api-types/google/billing.ts';
|
|
14
|
-
import { OpenAIResponsesBilling } from '#@/api-types/openai-responses/billing.ts';
|
|
15
|
-
import { AnthropicBilling } from '#@/api-types/anthropic/billing.ts';
|
|
16
|
-
import { RoleMessage } from '#@/compatible/session.ts';
|
|
17
|
-
import * as Google from '@google/genai';
|
|
18
|
-
import * as OpenAIResponsesNative from '#@/native-engines.d/openai-responses/session.ts';
|
|
19
|
-
import { fdm } from './test-helpers.ts';
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
function makeFooCall() {
|
|
23
|
-
return Function.Call.create<fdm>({
|
|
24
|
-
id: 'fc-1',
|
|
25
|
-
name: 'foo',
|
|
26
|
-
args: { x: 1 },
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function makeBarCall() {
|
|
31
|
-
return Function.Call.create<fdm>({
|
|
32
|
-
id: 'fc-2',
|
|
33
|
-
name: 'bar',
|
|
34
|
-
args: { y: 'x' },
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
test('ToolCallValidator enforces REQUIRED / allowlist / NONE', t => {
|
|
40
|
-
const validator = new ToolCallValidator<fdm>({ toolChoice: Function.ToolChoice.REQUIRED });
|
|
41
|
-
const fooCall = makeFooCall();
|
|
42
|
-
const barCall = makeBarCall();
|
|
43
|
-
|
|
44
|
-
t.throws(() => validator.validate([]), { instanceOf: ResponseInvalid });
|
|
45
|
-
t.notThrows(() => validator.validate([fooCall]));
|
|
46
|
-
|
|
47
|
-
validator['ctx'].toolChoice = ['foo'];
|
|
48
|
-
t.notThrows(() => validator.validate([fooCall]));
|
|
49
|
-
t.throws(() => validator.validate([barCall]), { instanceOf: ResponseInvalid });
|
|
50
|
-
|
|
51
|
-
validator['ctx'].toolChoice = Function.ToolChoice.NONE;
|
|
52
|
-
t.notThrows(() => validator.validate([]));
|
|
53
|
-
t.throws(() => validator.validate([fooCall]), { instanceOf: ResponseInvalid });
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
test('OpenAIResponsesNativeToolCallValidator enforces apply_patch allowlist', t => {
|
|
57
|
-
const fooCall = makeFooCall();
|
|
58
|
-
const applyPatchCall = Tool.ApplyPatch.Call.create({
|
|
59
|
-
id: 'patch-1',
|
|
60
|
-
call_id: 'call-1',
|
|
61
|
-
operation: {
|
|
62
|
-
type: 'update_file',
|
|
63
|
-
path: 'a.ts',
|
|
64
|
-
diff: 'diff',
|
|
65
|
-
},
|
|
66
|
-
status: 'completed',
|
|
67
|
-
type: 'apply_patch_call',
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
const validator = new OpenAIResponsesNativeToolCallValidator<fdm>({
|
|
71
|
-
toolChoice: ['foo', Tool.Choice.APPLY_PATCH],
|
|
72
|
-
});
|
|
73
|
-
t.notThrows(() => validator.validate([fooCall, applyPatchCall]));
|
|
74
|
-
|
|
75
|
-
const validatorWithoutPatch = new OpenAIResponsesNativeToolCallValidator<fdm>({
|
|
76
|
-
toolChoice: ['foo'],
|
|
77
|
-
});
|
|
78
|
-
t.throws(() => validatorWithoutPatch.validate([applyPatchCall]), { instanceOf: ResponseInvalid });
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
test('GoogleCompatibleMessageCodec converts user and ai messages', t => {
|
|
82
|
-
const toolCodec = new GoogleToolCodec({ fdm });
|
|
83
|
-
const codec = new GoogleCompatibleMessageCodec({ toolCodec });
|
|
84
|
-
|
|
85
|
-
const userMessage = RoleMessage.User.create<fdm>([
|
|
86
|
-
RoleMessage.Part.Text.create('hello'),
|
|
87
|
-
Function.Response.create<fdm>({
|
|
88
|
-
id: 'fc-1',
|
|
89
|
-
name: 'foo',
|
|
90
|
-
text: '{"ok":true}',
|
|
91
|
-
}),
|
|
92
|
-
]);
|
|
93
|
-
const userContent = codec.convertFromUserMessage(userMessage);
|
|
94
|
-
t.is(userContent.role, 'user');
|
|
95
|
-
t.is(userContent.parts?.[0]?.text, 'hello');
|
|
96
|
-
t.truthy(userContent.parts?.[1]?.functionResponse);
|
|
97
|
-
|
|
98
|
-
const aiContent = {
|
|
99
|
-
role: 'model',
|
|
100
|
-
parts: [
|
|
101
|
-
{ text: 'hi' },
|
|
102
|
-
{ functionCall: { id: 'fc-1', name: 'foo', args: { x: 1 } } },
|
|
103
|
-
],
|
|
104
|
-
};
|
|
105
|
-
const aiMessage = codec.convertToAiMessage(aiContent);
|
|
106
|
-
t.is(aiMessage.getText(), 'hi');
|
|
107
|
-
t.is(aiMessage.getFunctionCalls()[0]?.name, 'foo');
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
test('GoogleNativeMessageCodec reuses compatible message codec and decodes code execution parts', t => {
|
|
111
|
-
const toolCodec = new GoogleToolCodec({ fdm });
|
|
112
|
-
const compatibleMessageCodec = new GoogleCompatibleMessageCodec({ toolCodec });
|
|
113
|
-
const codec = new GoogleNativeMessageCodec({
|
|
114
|
-
toolCodec,
|
|
115
|
-
compatibleMessageCodec,
|
|
116
|
-
codeExecution: true,
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
const userContent = codec.convertFromUserMessage(RoleMessage.User.create<fdm>([
|
|
120
|
-
RoleMessage.Part.Text.create('hello'),
|
|
121
|
-
]));
|
|
122
|
-
t.is(userContent.role, 'user');
|
|
123
|
-
|
|
124
|
-
const aiMessage = codec.convertToAiMessage({
|
|
125
|
-
role: 'model',
|
|
126
|
-
parts: [
|
|
127
|
-
{ text: 'hi' },
|
|
128
|
-
{ functionCall: { id: 'fc-1', name: 'foo', args: { x: 1 } } },
|
|
129
|
-
{ executableCode: { code: 'print(1)', language: Google.Language.PYTHON } },
|
|
130
|
-
{ codeExecutionResult: { outcome: Google.Outcome.OUTCOME_OK, output: '1' } },
|
|
131
|
-
],
|
|
132
|
-
});
|
|
133
|
-
t.is(aiMessage.getText(), 'hi');
|
|
134
|
-
t.is(aiMessage.getFunctionCalls()[0]?.name, 'foo');
|
|
135
|
-
t.is(aiMessage.getParts().length, 4);
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
test('OpenAIResponsesCompatibleMessageCodec converts user and ai messages', t => {
|
|
139
|
-
const toolCodec = new OpenAIResponsesToolCodec({ fdm });
|
|
140
|
-
const codec = new OpenAIResponsesCompatibleMessageCodec({ toolCodec });
|
|
141
|
-
|
|
142
|
-
const userMessage = RoleMessage.User.create<fdm>([
|
|
143
|
-
RoleMessage.Part.Text.create('hello'),
|
|
144
|
-
Function.Response.create<fdm>({
|
|
145
|
-
id: 'fc-1',
|
|
146
|
-
name: 'foo',
|
|
147
|
-
text: '{"ok":true}',
|
|
148
|
-
}),
|
|
149
|
-
]);
|
|
150
|
-
const input = codec.convertFromUserMessage(userMessage);
|
|
151
|
-
t.is(input[0]?.type, 'message');
|
|
152
|
-
t.is(input[1]?.type, 'function_call_output');
|
|
153
|
-
|
|
154
|
-
const aiMessage = codec.convertToAiMessage([
|
|
155
|
-
{
|
|
156
|
-
id: 'msg_1',
|
|
157
|
-
type: 'message',
|
|
158
|
-
role: 'assistant',
|
|
159
|
-
status: 'completed',
|
|
160
|
-
content: [{ type: 'output_text', text: 'hi', annotations: [] }],
|
|
161
|
-
},
|
|
162
|
-
{
|
|
163
|
-
id: 'fc_1',
|
|
164
|
-
type: 'function_call',
|
|
165
|
-
call_id: 'call_1',
|
|
166
|
-
name: 'foo',
|
|
167
|
-
arguments: '{"x":1}',
|
|
168
|
-
status: 'completed',
|
|
169
|
-
},
|
|
170
|
-
]);
|
|
171
|
-
t.is(aiMessage.getText(), 'hi');
|
|
172
|
-
t.is(aiMessage.getFunctionCalls()[0]?.name, 'foo');
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
test('OpenAIResponsesNativeMessageCodec converts apply_patch response', t => {
|
|
176
|
-
const toolCodec = new OpenAIResponsesToolCodec({ fdm });
|
|
177
|
-
const compatibleMessageCodec = new OpenAIResponsesCompatibleMessageCodec({ toolCodec });
|
|
178
|
-
const codec = new OpenAIResponsesNativeMessageCodec({
|
|
179
|
-
toolCodec,
|
|
180
|
-
compatibleMessageCodec,
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
const input = codec.convertFromUserMessage(OpenAIResponsesNative.RoleMessage.User.create<
|
|
184
|
-
fdm
|
|
185
|
-
>([
|
|
186
|
-
OpenAIResponsesNative.RoleMessage.Part.Text.create('hello'),
|
|
187
|
-
Function.Response.create<fdm>({
|
|
188
|
-
id: 'fc-1',
|
|
189
|
-
name: 'foo',
|
|
190
|
-
text: '{"ok":true}',
|
|
191
|
-
}),
|
|
192
|
-
Tool.ApplyPatch.Response.create({
|
|
193
|
-
id: 'patch-1',
|
|
194
|
-
failure: 'failure',
|
|
195
|
-
}),
|
|
196
|
-
]));
|
|
197
|
-
t.is(input[0]?.type, 'message');
|
|
198
|
-
t.is(input[1]?.type, 'function_call_output');
|
|
199
|
-
t.is(input[2]?.type, 'apply_patch_call_output');
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
test('GoogleBilling calculates cache hit / miss / thinking cost', t => {
|
|
203
|
-
const billing = new GoogleBilling({
|
|
204
|
-
pricing: {
|
|
205
|
-
inputPrice: 1,
|
|
206
|
-
cachePrice: 2,
|
|
207
|
-
outputPrice: 3,
|
|
208
|
-
},
|
|
209
|
-
});
|
|
210
|
-
const charge = billing.charge({
|
|
211
|
-
promptTokenCount: 100,
|
|
212
|
-
cachedContentTokenCount: 25,
|
|
213
|
-
candidatesTokenCount: 10,
|
|
214
|
-
thoughtsTokenCount: 5,
|
|
215
|
-
});
|
|
216
|
-
t.is(charge, (75 + 50 + 30 + 15) / 1e6);
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
test('OpenAIResponsesBilling calculates cache hit / miss cost', t => {
|
|
220
|
-
const billing = new OpenAIResponsesBilling({
|
|
221
|
-
pricing: {
|
|
222
|
-
inputPrice: 1,
|
|
223
|
-
cachePrice: 2,
|
|
224
|
-
outputPrice: 3,
|
|
225
|
-
},
|
|
226
|
-
});
|
|
227
|
-
const charge = billing.charge({
|
|
228
|
-
input_tokens: 100,
|
|
229
|
-
input_tokens_details: { cached_tokens: 20 },
|
|
230
|
-
output_tokens: 10,
|
|
231
|
-
output_tokens_details: { reasoning_tokens: 0 },
|
|
232
|
-
total_tokens: 110,
|
|
233
|
-
});
|
|
234
|
-
t.true(Math.abs(charge - (80 + 40 + 30) / 1e6) < 1e-12);
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
test('AnthropicBilling calculates cache hit / miss cost', t => {
|
|
238
|
-
const billing = new AnthropicBilling({
|
|
239
|
-
pricing: {
|
|
240
|
-
inputPrice: 1,
|
|
241
|
-
cachePrice: 2,
|
|
242
|
-
outputPrice: 3,
|
|
243
|
-
},
|
|
244
|
-
});
|
|
245
|
-
const charge = billing.charge({
|
|
246
|
-
input_tokens: 100,
|
|
247
|
-
output_tokens: 10,
|
|
248
|
-
cache_read_input_tokens: 20,
|
|
249
|
-
cache_creation_input_tokens: 0,
|
|
250
|
-
cache_creation: { ephemeral_5m_input_tokens: 0, ephemeral_1h_input_tokens: 0 },
|
|
251
|
-
inference_geo: 'unknown',
|
|
252
|
-
server_tool_use: { web_fetch_requests: 0, web_search_requests: 0 },
|
|
253
|
-
service_tier: 'standard',
|
|
254
|
-
});
|
|
255
|
-
t.true(Math.abs(charge - (80 + 40 + 30) / 1e6) < 1e-12);
|
|
256
|
-
});
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import test from 'ava';
|
|
2
|
-
import { CompatibleEngine } from '#@/compatible/engine.ts';
|
|
3
|
-
import { RoleMessage, type Session } from '#@/compatible/session.ts';
|
|
4
|
-
import { Function } from '#@/function.ts';
|
|
5
|
-
import { type InferenceContext } from '#@/inference-context.ts';
|
|
6
|
-
import {
|
|
7
|
-
fdm,
|
|
8
|
-
makeAiMessage,
|
|
9
|
-
makeBaseOptions,
|
|
10
|
-
} from './test-helpers.ts';
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class StubCompatibleEngine extends CompatibleEngine<fdm> {
|
|
14
|
-
protected override parallelToolCall = false;
|
|
15
|
-
public responder: (
|
|
16
|
-
wfctx: InferenceContext,
|
|
17
|
-
session: Session<fdm>,
|
|
18
|
-
signal?: AbortSignal,
|
|
19
|
-
) => Promise<RoleMessage.Ai<fdm>> = async () => makeAiMessage();
|
|
20
|
-
|
|
21
|
-
public getToolChoice(): Function.ToolChoice<fdm> {
|
|
22
|
-
return this.toolChoice;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
public setToolChoice(toolChoice: Function.ToolChoice<fdm>): void {
|
|
26
|
-
this.toolChoice = toolChoice;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
public override infer(
|
|
30
|
-
wfctx: InferenceContext,
|
|
31
|
-
session: Session<fdm>,
|
|
32
|
-
signal?: AbortSignal,
|
|
33
|
-
): Promise<RoleMessage.Ai<fdm>> {
|
|
34
|
-
return this.responder(wfctx, session, signal);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
test('CompatibleEngine stores default tool choice', t => {
|
|
40
|
-
const engine = new StubCompatibleEngine({
|
|
41
|
-
...makeBaseOptions(),
|
|
42
|
-
apiType: 'google',
|
|
43
|
-
});
|
|
44
|
-
t.is(engine.getToolChoice(), Function.ToolChoice.AUTO);
|
|
45
|
-
});
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import test from 'ava';
|
|
2
|
-
import { Adaptor } from '#@/adaptor.ts';
|
|
3
|
-
import { Function } from '#@/function.ts';
|
|
4
|
-
import { OpenAIResponsesCompatibleEngine } from '#@/compatible/engine.d/openai-responses.ts';
|
|
5
|
-
import { GoogleCompatibleEngine } from '#@/compatible/engine.d/google.ts';
|
|
6
|
-
import { AnthropicCompatibleEngine } from '#@/compatible/engine.d/anthropic.ts';
|
|
7
|
-
import { AliyunEngine } from '#@/compatible/engine.d/aliyun.ts';
|
|
8
|
-
import { fdm, makeBaseOptions } from './test-helpers.ts';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class OpenAIResponsesCompatibleEngineProbe extends OpenAIResponsesCompatibleEngine<fdm> {
|
|
12
|
-
public getToolChoice(): Function.ToolChoice<fdm> {
|
|
13
|
-
return this.toolChoice;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
public getParallelToolCall(): boolean {
|
|
17
|
-
return this.parallelToolCall;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
class GoogleCompatibleEngineProbe extends GoogleCompatibleEngine<fdm> {
|
|
22
|
-
public getToolChoice(): Function.ToolChoice<fdm> {
|
|
23
|
-
return this.toolChoice;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
public getParallelToolCall(): boolean {
|
|
27
|
-
return this.parallelToolCall;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
class AnthropicCompatibleEngineProbe extends AnthropicCompatibleEngine<fdm> {
|
|
32
|
-
public getToolChoice(): Function.ToolChoice<fdm> {
|
|
33
|
-
return this.toolChoice;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
public getParallelToolCall(): boolean {
|
|
37
|
-
return this.parallelToolCall;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
class AliyunEngineProbe extends AliyunEngine<fdm> {
|
|
42
|
-
public getToolChoice(): Function.ToolChoice<fdm> {
|
|
43
|
-
return this.toolChoice;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
public getParallelToolCall(): boolean {
|
|
47
|
-
return this.parallelToolCall;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
test('compatible engines preserve aggregated defaults', t => {
|
|
53
|
-
const openaiEngine = new OpenAIResponsesCompatibleEngineProbe({
|
|
54
|
-
...makeBaseOptions(),
|
|
55
|
-
apiType: 'openai-responses',
|
|
56
|
-
});
|
|
57
|
-
const googleEngine = new GoogleCompatibleEngineProbe({
|
|
58
|
-
...makeBaseOptions(),
|
|
59
|
-
apiType: 'google',
|
|
60
|
-
});
|
|
61
|
-
const anthropicEngine = new AnthropicCompatibleEngineProbe({
|
|
62
|
-
...makeBaseOptions(),
|
|
63
|
-
apiType: 'anthropic',
|
|
64
|
-
});
|
|
65
|
-
const aliyunEngine = new AliyunEngineProbe({
|
|
66
|
-
...makeBaseOptions(),
|
|
67
|
-
apiType: 'aliyun',
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
t.is(openaiEngine.fdm, fdm);
|
|
71
|
-
t.is(openaiEngine.getToolChoice(), Function.ToolChoice.AUTO);
|
|
72
|
-
t.false(openaiEngine.getParallelToolCall());
|
|
73
|
-
|
|
74
|
-
t.is(googleEngine.getToolChoice(), Function.ToolChoice.AUTO);
|
|
75
|
-
t.true(googleEngine.getParallelToolCall());
|
|
76
|
-
|
|
77
|
-
t.is(anthropicEngine.getToolChoice(), Function.ToolChoice.AUTO);
|
|
78
|
-
t.false(anthropicEngine.getParallelToolCall());
|
|
79
|
-
|
|
80
|
-
t.is(aliyunEngine.getToolChoice(), Function.ToolChoice.AUTO);
|
|
81
|
-
t.false(aliyunEngine.getParallelToolCall());
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
test('Adaptor.makeEngine returns each compatible implementation', t => {
|
|
85
|
-
const adaptor = Adaptor.create({
|
|
86
|
-
brainswitch: {
|
|
87
|
-
endpoints: {
|
|
88
|
-
oa: {
|
|
89
|
-
baseUrl: 'https://example.com/v1',
|
|
90
|
-
apiKey: 'k',
|
|
91
|
-
model: 'm',
|
|
92
|
-
name: 'oa',
|
|
93
|
-
apiType: 'openai-responses',
|
|
94
|
-
},
|
|
95
|
-
gg: {
|
|
96
|
-
baseUrl: 'https://generativelanguage.googleapis.com',
|
|
97
|
-
apiKey: 'k',
|
|
98
|
-
model: 'gemini-test',
|
|
99
|
-
name: 'gg',
|
|
100
|
-
apiType: 'google',
|
|
101
|
-
},
|
|
102
|
-
an: {
|
|
103
|
-
baseUrl: 'https://api.anthropic.com',
|
|
104
|
-
apiKey: 'k',
|
|
105
|
-
model: 'claude-test',
|
|
106
|
-
name: 'an',
|
|
107
|
-
apiType: 'anthropic',
|
|
108
|
-
},
|
|
109
|
-
al: {
|
|
110
|
-
baseUrl: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
|
|
111
|
-
apiKey: 'k',
|
|
112
|
-
model: 'qwen-test',
|
|
113
|
-
name: 'al',
|
|
114
|
-
apiType: 'aliyun',
|
|
115
|
-
},
|
|
116
|
-
},
|
|
117
|
-
},
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
const openaiEngine = adaptor.makeEngine('oa', fdm);
|
|
121
|
-
const googleEngine = adaptor.makeEngine('gg', fdm);
|
|
122
|
-
const anthropicEngine = adaptor.makeEngine('an', fdm);
|
|
123
|
-
const aliyunEngine = adaptor.makeEngine('al', fdm);
|
|
124
|
-
|
|
125
|
-
t.true(openaiEngine instanceof OpenAIResponsesCompatibleEngine);
|
|
126
|
-
t.true(googleEngine instanceof GoogleCompatibleEngine);
|
|
127
|
-
t.true(anthropicEngine instanceof AnthropicCompatibleEngine);
|
|
128
|
-
t.true(aliyunEngine instanceof AliyunEngine);
|
|
129
|
-
});
|
package/test/src/test-engine.ts
DELETED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import test from 'ava';
|
|
2
|
-
import { Engine, InferenceTimeout, ResponseInvalid, UserAbortion } from '#@/engine.ts';
|
|
3
|
-
import { type GenericSession } from '#@/session.ts';
|
|
4
|
-
import { type InferenceContext } from '#@/inference-context.ts';
|
|
5
|
-
import { type RoleMessage } from '#@/compatible/session.ts';
|
|
6
|
-
import {
|
|
7
|
-
fdm,
|
|
8
|
-
makeBaseOptions,
|
|
9
|
-
makeInferenceContext,
|
|
10
|
-
makeUserMessage,
|
|
11
|
-
} from './test-helpers.ts';
|
|
12
|
-
|
|
13
|
-
type StubSession = GenericSession<RoleMessage.User<fdm>, string, never>;
|
|
14
|
-
|
|
15
|
-
class StubEngine extends Engine<
|
|
16
|
-
fdm,
|
|
17
|
-
RoleMessage.User<fdm>,
|
|
18
|
-
string,
|
|
19
|
-
never,
|
|
20
|
-
StubSession
|
|
21
|
-
> {
|
|
22
|
-
protected override parallelToolCall = false;
|
|
23
|
-
public responder: (
|
|
24
|
-
wfctx: InferenceContext,
|
|
25
|
-
session: StubSession,
|
|
26
|
-
signal?: AbortSignal,
|
|
27
|
-
) => Promise<string> = async () => 'ok';
|
|
28
|
-
|
|
29
|
-
protected override infer(
|
|
30
|
-
wfctx: InferenceContext,
|
|
31
|
-
session: StubSession,
|
|
32
|
-
signal?: AbortSignal,
|
|
33
|
-
): Promise<string> {
|
|
34
|
-
return this.responder(wfctx, session, signal);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
public override appendUserMessage(
|
|
38
|
-
session: StubSession,
|
|
39
|
-
message: RoleMessage.User<fdm>,
|
|
40
|
-
): StubSession {
|
|
41
|
-
return {
|
|
42
|
-
...session,
|
|
43
|
-
chatMessages: [...session.chatMessages, message],
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
public override pushUserMessage(
|
|
48
|
-
session: StubSession,
|
|
49
|
-
message: RoleMessage.User<fdm>,
|
|
50
|
-
): StubSession {
|
|
51
|
-
session.chatMessages.push(message);
|
|
52
|
-
return session;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function makeStringSession(): StubSession {
|
|
57
|
-
return { chatMessages: [] };
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
test('Engine stores function declaration map', t => {
|
|
62
|
-
const engine = new StubEngine({
|
|
63
|
-
...makeBaseOptions(),
|
|
64
|
-
apiType: 'google',
|
|
65
|
-
});
|
|
66
|
-
t.is(engine.fdm, fdm);
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
test('Engine.stateless retries ResponseInvalid and succeeds', async t => {
|
|
70
|
-
const engine = new StubEngine({
|
|
71
|
-
...makeBaseOptions(),
|
|
72
|
-
apiType: 'google',
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
let attempts = 0;
|
|
76
|
-
engine.responder = async () => {
|
|
77
|
-
attempts += 1;
|
|
78
|
-
if (attempts < 3) throw new ResponseInvalid('temporary');
|
|
79
|
-
return 'retry-ok';
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
const response = await engine.stateless(makeInferenceContext(), makeStringSession());
|
|
83
|
-
|
|
84
|
-
t.is(attempts, 3);
|
|
85
|
-
t.is(response, 'retry-ok');
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
test('Engine.stateless converts aborted workflow signal to UserAbortion', async t => {
|
|
89
|
-
const engine = new StubEngine({
|
|
90
|
-
...makeBaseOptions(),
|
|
91
|
-
apiType: 'google',
|
|
92
|
-
});
|
|
93
|
-
const controller = new AbortController();
|
|
94
|
-
|
|
95
|
-
engine.responder = async () => {
|
|
96
|
-
controller.abort();
|
|
97
|
-
throw new TypeError('aborted');
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
const e = await engine.stateless(makeInferenceContext(controller.signal), makeStringSession()).catch((e: unknown) => e);
|
|
101
|
-
t.true(e instanceof UserAbortion);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
test('Engine.stateless converts timeout abort to InferenceTimeout', async t => {
|
|
105
|
-
const engine = new StubEngine({
|
|
106
|
-
...makeBaseOptions(),
|
|
107
|
-
apiType: 'google',
|
|
108
|
-
timeout: 1,
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
engine.responder = async (_wfctx: InferenceContext, _session: StubSession, signal?: AbortSignal) => {
|
|
112
|
-
await new Promise(resolve => setTimeout(resolve, 10));
|
|
113
|
-
if (signal?.aborted) throw new TypeError('timed out');
|
|
114
|
-
return 'late';
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
const e = await t.throwsAsync(
|
|
118
|
-
engine.stateless(makeInferenceContext(), makeStringSession()),
|
|
119
|
-
);
|
|
120
|
-
t.true(e instanceof InferenceTimeout);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
test('Engine stateful/append/push message semantics are correct', async t => {
|
|
124
|
-
const engine = new StubEngine({
|
|
125
|
-
...makeBaseOptions(),
|
|
126
|
-
apiType: 'google',
|
|
127
|
-
});
|
|
128
|
-
engine.responder = async () => 'stateful-ok';
|
|
129
|
-
|
|
130
|
-
const session = makeStringSession();
|
|
131
|
-
const response = await engine.stateful(makeInferenceContext(), session);
|
|
132
|
-
t.is(response, 'stateful-ok');
|
|
133
|
-
t.deepEqual(session.chatMessages, ['stateful-ok']);
|
|
134
|
-
|
|
135
|
-
const user = makeUserMessage();
|
|
136
|
-
const appended = engine.appendUserMessage(session, user);
|
|
137
|
-
t.not(appended, session);
|
|
138
|
-
t.deepEqual(appended.chatMessages, ['stateful-ok', user]);
|
|
139
|
-
t.deepEqual(session.chatMessages, ['stateful-ok']);
|
|
140
|
-
|
|
141
|
-
const pushed = engine.pushUserMessage(session, user);
|
|
142
|
-
t.is(pushed, session);
|
|
143
|
-
t.deepEqual(session.chatMessages, ['stateful-ok', user]);
|
|
144
|
-
});
|
package/test/src/test-helpers.ts
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { Type } from '@sinclair/typebox';
|
|
2
|
-
import { Function } from '#@/function.ts';
|
|
3
|
-
import { type InferenceContext } from '#@/inference-context.ts';
|
|
4
|
-
import { RoleMessage, type Session } from '#@/compatible/session.ts';
|
|
5
|
-
import { Throttle } from '#@/throttle.ts';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export const fdm = {
|
|
9
|
-
foo: {
|
|
10
|
-
description: 'foo tool',
|
|
11
|
-
paraschema: Type.Object({ x: Type.Number() }),
|
|
12
|
-
},
|
|
13
|
-
bar: {
|
|
14
|
-
description: 'bar tool',
|
|
15
|
-
paraschema: Type.Object({ y: Type.String() }),
|
|
16
|
-
},
|
|
17
|
-
} satisfies Function.Declaration.Map;
|
|
18
|
-
|
|
19
|
-
export type fdm = typeof fdm;
|
|
20
|
-
|
|
21
|
-
export function makeBaseOptions() {
|
|
22
|
-
return {
|
|
23
|
-
baseUrl: 'https://example.com/v1',
|
|
24
|
-
apiKey: 'test-key',
|
|
25
|
-
model: 'test-model',
|
|
26
|
-
name: 'Test Endpoint',
|
|
27
|
-
functionDeclarationMap: fdm,
|
|
28
|
-
throttle: new Throttle(60),
|
|
29
|
-
inputPrice: 1,
|
|
30
|
-
outputPrice: 2,
|
|
31
|
-
cachePrice: 3,
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function makeSession(): Session<fdm> {
|
|
36
|
-
return { chatMessages: [] };
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function makeUserMessage(): RoleMessage.User<fdm> {
|
|
40
|
-
return RoleMessage.User.create<fdm>([RoleMessage.Part.Text.create('hello')]);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export function makeAiMessage(text = 'ok'): RoleMessage.Ai<fdm> {
|
|
44
|
-
return RoleMessage.Ai.create<fdm>([RoleMessage.Part.Text.create(text)]);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export function makeInferenceContext(signal: AbortSignal | null = null): InferenceContext {
|
|
48
|
-
return {
|
|
49
|
-
busy: null,
|
|
50
|
-
signal,
|
|
51
|
-
cost() {},
|
|
52
|
-
};
|
|
53
|
-
}
|