@ggui-ai/ui-gen 0.27.0 → 0.29.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/dist/{adapter-h4_V69LI.d.ts → adapter-DLQ-5COm.d.ts} +1 -1
- package/dist/adapters/base.js +2 -27
- package/dist/adapters/base.js.map +1 -1
- package/dist/adapters/generation-dispatch.d.ts +14 -6
- package/dist/adapters/generation-dispatch.js +40 -19095
- package/dist/adapters/generation-dispatch.js.map +1 -1
- package/dist/adapters/index.d.ts +1 -1
- package/dist/adapters/index.js +25 -3561
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/types.js +2 -9
- package/dist/adapters/types.js.map +1 -1
- package/dist/advanced/index.d.ts +13 -12
- package/dist/advanced/index.js +63 -21789
- package/dist/advanced/index.js.map +1 -1
- package/dist/{bank-Ctdp3FUA.d.ts → bank-LWaiAtaA.d.ts} +1 -1
- package/dist/blueprint-validator.js +6 -2301
- package/dist/blueprint-validator.js.map +1 -1
- package/dist/boilerplate.d.ts +3 -2
- package/dist/boilerplate.js +6 -1867
- package/dist/boilerplate.js.map +1 -1
- package/dist/check/index.d.ts +3 -2
- package/dist/check/index.js +6 -1923
- package/dist/check/index.js.map +1 -1
- package/dist/chunk-33B3BAWS.js +24 -0
- package/dist/chunk-33B3BAWS.js.map +1 -0
- package/dist/chunk-3HSGA6NI.js +591 -0
- package/dist/chunk-3HSGA6NI.js.map +1 -0
- package/dist/chunk-3NNNGNTO.js +1707 -0
- package/dist/chunk-3NNNGNTO.js.map +1 -0
- package/dist/chunk-3T2HMTON.js +79 -0
- package/dist/chunk-3T2HMTON.js.map +1 -0
- package/dist/chunk-3ZSSDV3L.js +123 -0
- package/dist/chunk-3ZSSDV3L.js.map +1 -0
- package/dist/chunk-4MBR5GA3.js +99 -0
- package/dist/chunk-4MBR5GA3.js.map +1 -0
- package/dist/chunk-56NJFD55.js +337 -0
- package/dist/chunk-56NJFD55.js.map +1 -0
- package/dist/chunk-5AGTY555.js +26 -0
- package/dist/chunk-5AGTY555.js.map +1 -0
- package/dist/chunk-5EJM7EGY.js +115 -0
- package/dist/chunk-5EJM7EGY.js.map +1 -0
- package/dist/chunk-5KXCQLLR.js +529 -0
- package/dist/chunk-5KXCQLLR.js.map +1 -0
- package/dist/chunk-5VBXHVEH.js +171 -0
- package/dist/chunk-5VBXHVEH.js.map +1 -0
- package/dist/chunk-6KDDEING.js +515 -0
- package/dist/chunk-6KDDEING.js.map +1 -0
- package/dist/chunk-6VDRWAP6.js +123 -0
- package/dist/chunk-6VDRWAP6.js.map +1 -0
- package/dist/chunk-732IBFEJ.js +2400 -0
- package/dist/chunk-732IBFEJ.js.map +1 -0
- package/dist/chunk-73AURS3I.js +46 -0
- package/dist/chunk-73AURS3I.js.map +1 -0
- package/dist/chunk-77H5SKLX.js +8 -0
- package/dist/chunk-77H5SKLX.js.map +1 -0
- package/dist/chunk-7QE3AHLE.js +35 -0
- package/dist/chunk-7QE3AHLE.js.map +1 -0
- package/dist/chunk-A375NNWN.js +11 -0
- package/dist/chunk-A375NNWN.js.map +1 -0
- package/dist/chunk-AOU33EFS.js +140 -0
- package/dist/chunk-AOU33EFS.js.map +1 -0
- package/dist/chunk-BA4QYA6E.js +461 -0
- package/dist/chunk-BA4QYA6E.js.map +1 -0
- package/dist/chunk-DBP764GL.js +3 -0
- package/dist/chunk-DBP764GL.js.map +1 -0
- package/dist/chunk-DUU3ZJDQ.js +41 -0
- package/dist/chunk-DUU3ZJDQ.js.map +1 -0
- package/dist/chunk-DXKRBXNU.js +30 -0
- package/dist/chunk-DXKRBXNU.js.map +1 -0
- package/dist/chunk-FB7OEEAH.js +1467 -0
- package/dist/chunk-FB7OEEAH.js.map +1 -0
- package/dist/chunk-FLRNMZV2.js +18 -0
- package/dist/chunk-FLRNMZV2.js.map +1 -0
- package/dist/chunk-FWJIMKFZ.js +2032 -0
- package/dist/chunk-FWJIMKFZ.js.map +1 -0
- package/dist/chunk-FXRHWYIQ.js +163 -0
- package/dist/chunk-FXRHWYIQ.js.map +1 -0
- package/dist/chunk-G3PMV62Z.js +33 -0
- package/dist/chunk-G3PMV62Z.js.map +1 -0
- package/dist/chunk-GAJI7Y3P.js +13 -0
- package/dist/chunk-GAJI7Y3P.js.map +1 -0
- package/dist/chunk-GYINWMPR.js +2052 -0
- package/dist/chunk-GYINWMPR.js.map +1 -0
- package/dist/chunk-HD6ABIK7.js +484 -0
- package/dist/chunk-HD6ABIK7.js.map +1 -0
- package/dist/chunk-HDQVHYO6.js +100 -0
- package/dist/chunk-HDQVHYO6.js.map +1 -0
- package/dist/chunk-IHUT3SIW.js +7 -0
- package/dist/chunk-IHUT3SIW.js.map +1 -0
- package/dist/chunk-JDH5EGNZ.js +126 -0
- package/dist/chunk-JDH5EGNZ.js.map +1 -0
- package/dist/chunk-JMD4RGSV.js +37 -0
- package/dist/chunk-JMD4RGSV.js.map +1 -0
- package/dist/chunk-KJWGZL5B.js +33 -0
- package/dist/chunk-KJWGZL5B.js.map +1 -0
- package/dist/chunk-MKMDQFZ7.js +86 -0
- package/dist/chunk-MKMDQFZ7.js.map +1 -0
- package/dist/chunk-NF6JUZWF.js +85 -0
- package/dist/chunk-NF6JUZWF.js.map +1 -0
- package/dist/chunk-O2YC6XDC.js +1933 -0
- package/dist/chunk-O2YC6XDC.js.map +1 -0
- package/dist/chunk-OVLH5ICV.js +29 -0
- package/dist/chunk-OVLH5ICV.js.map +1 -0
- package/dist/chunk-PBOYHGSD.js +106 -0
- package/dist/chunk-PBOYHGSD.js.map +1 -0
- package/dist/chunk-PJFH7QWA.js +81 -0
- package/dist/chunk-PJFH7QWA.js.map +1 -0
- package/dist/chunk-PUH4CXGZ.js +284 -0
- package/dist/chunk-PUH4CXGZ.js.map +1 -0
- package/dist/chunk-QLXXPGTV.js +18 -0
- package/dist/chunk-QLXXPGTV.js.map +1 -0
- package/dist/chunk-R5GIGPW2.js +2845 -0
- package/dist/chunk-R5GIGPW2.js.map +1 -0
- package/dist/chunk-RH4IUSTO.js +83 -0
- package/dist/chunk-RH4IUSTO.js.map +1 -0
- package/dist/chunk-S2GVXKKY.js +153 -0
- package/dist/chunk-S2GVXKKY.js.map +1 -0
- package/dist/chunk-TVHGKFJS.js +58 -0
- package/dist/chunk-TVHGKFJS.js.map +1 -0
- package/dist/chunk-U7GALWLG.js +66 -0
- package/dist/chunk-U7GALWLG.js.map +1 -0
- package/dist/chunk-VTC263LT.js +256 -0
- package/dist/chunk-VTC263LT.js.map +1 -0
- package/dist/chunk-WEOXFEVE.js +739 -0
- package/dist/chunk-WEOXFEVE.js.map +1 -0
- package/dist/chunk-WYHP46LT.js +28 -0
- package/dist/chunk-WYHP46LT.js.map +1 -0
- package/dist/chunk-XGLO5LGG.js +274 -0
- package/dist/chunk-XGLO5LGG.js.map +1 -0
- package/dist/chunk-XRBCRKA2.js +29 -0
- package/dist/chunk-XRBCRKA2.js.map +1 -0
- package/dist/chunk-XW7ADFFV.js +340 -0
- package/dist/chunk-XW7ADFFV.js.map +1 -0
- package/dist/chunk-YIQ42IUX.js +34 -0
- package/dist/chunk-YIQ42IUX.js.map +1 -0
- package/dist/chunk-YJZTUY7B.js +101 -0
- package/dist/chunk-YJZTUY7B.js.map +1 -0
- package/dist/chunk-Z3CXME3K.js +107 -0
- package/dist/chunk-Z3CXME3K.js.map +1 -0
- package/dist/classifier/index.js +2 -527
- package/dist/classifier/index.js.map +1 -1
- package/dist/client-JBPCXU7W.js +4 -0
- package/dist/client-JBPCXU7W.js.map +1 -0
- package/dist/compose.js +3 -367
- package/dist/compose.js.map +1 -1
- package/dist/cost-tracker-HHGQ4FTW.js +67 -0
- package/dist/cost-tracker-HHGQ4FTW.js.map +1 -0
- package/dist/{create-ui-generator-BrZHF0cf.d.ts → create-ui-generator-BY-WeaPi.d.ts} +3 -3
- package/dist/{design-mode-DGWN_Gkm.d.ts → design-mode-XyOQmzE0.d.ts} +4 -3
- package/dist/{dispatch-B07TI30d.d.ts → dispatch-8LzTddKw.d.ts} +3 -2
- package/dist/dist-UALN6ZVB.js +543 -0
- package/dist/dist-UALN6ZVB.js.map +1 -0
- package/dist/dupe-break-X6K7QFIS.js +4 -0
- package/dist/dupe-break-X6K7QFIS.js.map +1 -0
- package/dist/evaluation/axis-checks/index.d.ts +5 -4
- package/dist/evaluation/axis-checks/index.js +6 -1818
- package/dist/evaluation/axis-checks/index.js.map +1 -1
- package/dist/evaluation/axis-checks/registry.d.ts +3 -2
- package/dist/evaluation/axis-checks/registry.js +3 -1748
- package/dist/evaluation/axis-checks/registry.js.map +1 -1
- package/dist/evaluation/index.d.ts +49 -132
- package/dist/evaluation/index.js +302 -6368
- package/dist/evaluation/index.js.map +1 -1
- package/dist/evaluation/types.d.ts +3 -2
- package/dist/evaluation/types.js +2 -5
- package/dist/evaluation/types.js.map +1 -1
- package/dist/fragments/index.js +2 -338
- package/dist/fragments/index.js.map +1 -1
- package/dist/{generate-tSO_shQ0.d.ts → generate-DQ4ci90s.d.ts} +1 -1
- package/dist/harness/check/runtime-render/index.d.ts +35 -15
- package/dist/harness/check/runtime-render/index.js +6 -2390
- package/dist/harness/check/runtime-render/index.js.map +1 -1
- package/dist/harness/check/runtime-render/render-check-worker.js +4 -1739
- package/dist/harness/check/runtime-render/render-check-worker.js.map +1 -1
- package/dist/harness/index.d.ts +3 -2
- package/dist/harness/index.js +23 -5124
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/llm-trace-sink.js +2 -24
- package/dist/harness/llm-trace-sink.js.map +1 -1
- package/dist/harness/prompts.d.ts +2 -2
- package/dist/harness/prompts.js +8 -324
- package/dist/harness/prompts.js.map +1 -1
- package/dist/harness/result-types.d.ts +18 -6
- package/dist/harness/result-types.js +2 -0
- package/dist/harness/result-types.js.map +1 -1
- package/dist/harness/runtime.d.ts +22 -5
- package/dist/harness/runtime.js +10 -2313
- package/dist/harness/runtime.js.map +1 -1
- package/dist/harness/types-public.d.ts +3 -2
- package/dist/harness/types-public.js +16 -2954
- package/dist/harness/types-public.js.map +1 -1
- package/dist/harness/validator-trace-sink.d.ts +3 -2
- package/dist/harness/validator-trace-sink.js +2 -26
- package/dist/harness/validator-trace-sink.js.map +1 -1
- package/dist/hash.js +2 -39
- package/dist/hash.js.map +1 -1
- package/dist/hashline-5OKREIRM.js +4 -0
- package/dist/hashline-5OKREIRM.js.map +1 -0
- package/dist/index.d.ts +51 -12
- package/dist/index.js +57 -21850
- package/dist/index.js.map +1 -1
- package/dist/llm-evaluator-PN3WFCS4.js +653 -0
- package/dist/llm-evaluator-PN3WFCS4.js.map +1 -0
- package/dist/magic-string.es-2NZTC4GZ.js +1307 -0
- package/dist/magic-string.es-2NZTC4GZ.js.map +1 -0
- package/dist/patch.d.ts +3 -2
- package/dist/patch.js +2 -56
- package/dist/patch.js.map +1 -1
- package/dist/policy-VCYKGSAC.js +5 -0
- package/dist/policy-VCYKGSAC.js.map +1 -0
- package/dist/policy.js +2 -35
- package/dist/policy.js.map +1 -1
- package/dist/primitive-index-2OF6F4TZ.js +131 -0
- package/dist/primitive-index-2OF6F4TZ.js.map +1 -0
- package/dist/primitive-slice-WTMBLYFJ.js +235 -0
- package/dist/primitive-slice-WTMBLYFJ.js.map +1 -0
- package/dist/{prompts-BhNUuRoZ.d.ts → prompts-CLZGywMP.d.ts} +1 -1
- package/dist/provider-adapter-contract.js +10407 -14204
- package/dist/provider-adapter-contract.js.map +1 -1
- package/dist/provider-adapter.js +2 -44
- package/dist/provider-adapter.js.map +1 -1
- package/dist/providers/index.d.ts +89 -1
- package/dist/providers/index.js +115 -44
- package/dist/providers/index.js.map +1 -1
- package/dist/raw-C6KBH5I3.js +141 -0
- package/dist/raw-C6KBH5I3.js.map +1 -0
- package/dist/raw-FXSBXQTZ.js +7 -0
- package/dist/raw-FXSBXQTZ.js.map +1 -0
- package/dist/raw-MURDUPGK.js +8 -0
- package/dist/raw-MURDUPGK.js.map +1 -0
- package/dist/raw-T3GW3UVX.js +8 -0
- package/dist/raw-T3GW3UVX.js.map +1 -0
- package/dist/render-check-host-ZNIS6BJ5.js +5 -0
- package/dist/render-check-host-ZNIS6BJ5.js.map +1 -0
- package/dist/sdk-4JNSDNSR.js +6 -0
- package/dist/sdk-4JNSDNSR.js.map +1 -0
- package/dist/sdk-DIVJMHCX.js +7 -0
- package/dist/sdk-DIVJMHCX.js.map +1 -0
- package/dist/sdk-QRJOCRTS.js +7 -0
- package/dist/sdk-QRJOCRTS.js.map +1 -0
- package/dist/tag-balance-CTHCTRJ7.js +123 -0
- package/dist/tag-balance-CTHCTRJ7.js.map +1 -0
- package/dist/tools/get-primitives-ts.d.ts +1 -1
- package/dist/tools/get-primitives-ts.js +3 -1
- package/dist/tools/get-primitives-ts.js.map +1 -1
- package/dist/tools/render-check-worker.js +3 -40
- package/dist/tools/render-check-worker.js.map +1 -1
- package/dist/{types-public-h8IMnYuh.d.ts → types-public-hYlrerZh.d.ts} +35 -2
- package/dist/validation/index.d.ts +2 -2
- package/dist/validation/index.js +3 -498
- package/dist/validation/index.js.map +1 -1
- package/dist/{visual-evaluator-C2strxqD.d.ts → visual-evaluator-KskajxD5.d.ts} +14 -4
- package/dist/visual-evaluator-TGEXYQTP.js +12 -0
- package/dist/visual-evaluator-TGEXYQTP.js.map +1 -0
- package/dist/workflows.d.ts +3 -2
- package/dist/workflows.js +2 -151
- package/dist/workflows.js.map +1 -1
- package/package.json +21 -17
- package/src/adapters/claude/sdk.ts +4 -2
- package/src/adapters/claude/tool-bridge.ts +2 -1
- package/src/adapters/generation-dispatch.ts +9 -0
- package/src/adapters/openai/raw.ts +4 -0
- package/src/adapters/openai/sdk.ts +6 -1
- package/src/adapters/openai/tokens.ts +21 -7
- package/src/adapters/provider-router.ts +1 -0
- package/src/adapters/tool-bridge.ts +1 -1
- package/src/adapters/tools.ts +1 -1
- package/src/advanced/feedback.ts +1 -2
- package/src/advanced/generator.ts +4 -3
- package/src/boilerplate/free-design-prompt.ts +7 -0
- package/src/boilerplate/generate.ts +18 -5
- package/src/boilerplate/hard-sections.ts +8 -3
- package/src/boilerplate/react-hooks.ts +56 -0
- package/src/boilerplate/system-prompt.ts +12 -3
- package/src/check/run-tier0.ts +233 -8
- package/src/check/type-checker.ts +128 -16
- package/src/coding-agent/tools.ts +26 -3
- package/src/create-ui-generator.ts +4 -2
- package/src/design-mode.ts +4 -9
- package/src/evaluation/axis-checks/checks/state-merge.ts +3 -5
- package/src/evaluation/axis-checks/checks/state-payload.ts +1 -28
- package/src/evaluation/axis-checks/checks/tint.ts +197 -0
- package/src/evaluation/axis-checks/helpers.ts +246 -0
- package/src/evaluation/axis-checks/registry.ts +2 -0
- package/src/evaluation/criteria/__fixtures__/edge-v2-draw2.json +4629 -0
- package/src/evaluation/criteria/bank.ts +1 -1
- package/src/evaluation/criteria/edge-instruments.ts +14 -0
- package/src/evaluation/criteria/edge-probe-v2.ts +352 -0
- package/src/evaluation/criteria/edge-v2.ts +242 -0
- package/src/evaluation/criteria/resolve.ts +24 -5
- package/src/evaluation/evaluator.ts +2 -2
- package/src/evaluation/index.ts +3 -5
- package/src/evaluation/llm-evaluator.ts +2 -2
- package/src/evaluation/mcp-server.ts +0 -50
- package/src/evaluation/types-public.ts +6 -1
- package/src/evaluation/visual-evaluator.ts +162 -31
- package/src/harness/check/runtime-render/index.ts +28 -4
- package/src/harness/check/runtime-render/render-check.ts +20 -21
- package/src/harness/claude-agent-sdk-loader.ts +93 -0
- package/src/harness/claude-code-login-query.ts +1 -1
- package/src/harness/coding/assemble-result.ts +1 -0
- package/src/harness/coding/dupe-break.ts +70 -0
- package/src/harness/coding/generate-task-runner.ts +6 -1
- package/src/harness/coding/run-coding-turn.ts +59 -1
- package/src/harness/coding/run-eval-round.ts +9 -0
- package/src/harness/llm-router.ts +50 -2
- package/src/harness/result-types.ts +12 -0
- package/src/harness/runtime.ts +17 -0
- package/src/index.ts +10 -1
- package/src/providers/anthropic-tool-call.ts +263 -0
- package/src/providers/index.ts +13 -0
- package/src/tools/get-primitives-ts.ts +1 -1
- package/src/tools/render-check.ts +4 -4
- package/src/validation/primitives.ts +2 -1
- package/src/evaluation/loop.ts +0 -218
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one Anthropic structured call: a single `/v1/messages` request
|
|
3
|
+
* that asks for one tool call and returns that tool's input.
|
|
4
|
+
*
|
|
5
|
+
* Every structured caller that speaks to Anthropic goes through
|
|
6
|
+
* {@link anthropicToolCall}, so the request shape and the failure
|
|
7
|
+
* names live in one place (ggui#1271): the negotiator's LLM seam in
|
|
8
|
+
* `@ggui-ai/mcp-server` (rerank judge + contract synthesizer), the
|
|
9
|
+
* judge the live match probes drive in `@ggui-ai/mcp-server-handlers`,
|
|
10
|
+
* and the negotiator's dev benches.
|
|
11
|
+
*
|
|
12
|
+
* It lives here because every production caller already depends on
|
|
13
|
+
* `@ggui-ai/ui-gen`. The day a production caller lives in a package that
|
|
14
|
+
* does not (`@ggui-ai/negotiator`, `@ggui-ai/protocol`), the home becomes
|
|
15
|
+
* `@ggui-ai/mcp-server-core`, which every one of them reaches.
|
|
16
|
+
*
|
|
17
|
+
* It is a standalone function rather than a `ProviderAdapter`
|
|
18
|
+
* method on purpose. Adapters return a result union and never throw;
|
|
19
|
+
* every structured caller here wants the throw, because its consumers
|
|
20
|
+
* (the rerank judge, the synthesizer) already collapse a throw to
|
|
21
|
+
* their null-decision fallback and carry the message into their
|
|
22
|
+
* reason. A transport failure keeps its own type: a network failure
|
|
23
|
+
* rejects with `fetch`'s `TypeError`, an abort with the signal's
|
|
24
|
+
* `AbortError`, and a 2xx body that is not JSON with `SyntaxError`.
|
|
25
|
+
*
|
|
26
|
+
* Two request shapes, chosen by the shared model rule
|
|
27
|
+
* (`@ggui-ai/protocol` `anthropicRejectsForcedToolChoice`, the same list
|
|
28
|
+
* the generation router reads):
|
|
29
|
+
*
|
|
30
|
+
* - A model that accepts a forced tool gets
|
|
31
|
+
* `tool_choice: {type: 'tool', name}` and the caller's budget.
|
|
32
|
+
* - A model that refuses one (the always-thinking family answers a
|
|
33
|
+
* forced tool with HTTP 400) gets `tool_choice: auto` with at most
|
|
34
|
+
* one call, an instruction naming the tool appended to the system
|
|
35
|
+
* prompt, and {@link ALWAYS_THINKING_HEADROOM_TOKENS} added to the
|
|
36
|
+
* caller's budget. `strict: true` is not sent: the callers' schemas
|
|
37
|
+
* carry keywords strict tool use rejects (`minimum`/`maximum`,
|
|
38
|
+
* map-shaped `additionalProperties`), and every caller validates
|
|
39
|
+
* the input it gets back.
|
|
40
|
+
*
|
|
41
|
+
* No `temperature` is sent: newer tool-use models reject it with
|
|
42
|
+
* HTTP 400, so callers tolerate paraphrase in field values instead.
|
|
43
|
+
*/
|
|
44
|
+
import { anthropicRejectsForcedToolChoice, isRecord } from '@ggui-ai/protocol';
|
|
45
|
+
|
|
46
|
+
const DEFAULT_ENDPOINT = 'https://api.anthropic.com/v1/messages';
|
|
47
|
+
const DEFAULT_API_VERSION = '2023-06-01';
|
|
48
|
+
const DEFAULT_ANSWER_BUDGET = 1024;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Thinking budget added to the caller's ANSWER budget when the model
|
|
52
|
+
* refuses a forced tool. Those models always think, their thinking
|
|
53
|
+
* counts against `max_tokens`, and it comes before the tool call, so a
|
|
54
|
+
* small answer budget (the rerank judge asks for 512) would be spent
|
|
55
|
+
* before the `tool_use` block exists. `max_tokens` is a ceiling, not
|
|
56
|
+
* spend.
|
|
57
|
+
*/
|
|
58
|
+
export const ALWAYS_THINKING_HEADROOM_TOKENS = 16_000;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The one tool the call asks for: the Messages API's own wire shape for a
|
|
62
|
+
* tool (`name`, `description`, `input_schema`), sent as-is under a raw
|
|
63
|
+
* `fetch`. It is not an SDK type and does not stand in for one; this
|
|
64
|
+
* package takes no Anthropic SDK dependency.
|
|
65
|
+
*/
|
|
66
|
+
export interface AnthropicTool {
|
|
67
|
+
readonly name: string;
|
|
68
|
+
readonly description: string;
|
|
69
|
+
/** The tool's input JSON Schema, sent verbatim. */
|
|
70
|
+
readonly input_schema: Readonly<Record<string, unknown>>;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface AnthropicToolCallRequest {
|
|
74
|
+
readonly apiKey: string;
|
|
75
|
+
/** The wire model id, sent verbatim. */
|
|
76
|
+
readonly model: string;
|
|
77
|
+
readonly systemPrompt: string;
|
|
78
|
+
readonly userPrompt: string;
|
|
79
|
+
readonly tool: AnthropicTool;
|
|
80
|
+
/** The answer budget. Absent ⇒ 1024. Headroom is added on top where the model needs it. */
|
|
81
|
+
readonly maxTokens?: number;
|
|
82
|
+
/** Cancels the request. */
|
|
83
|
+
readonly signal?: AbortSignal;
|
|
84
|
+
/** Override for tests and instrumentation. Absent ⇒ the global `fetch` at call time. */
|
|
85
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
86
|
+
/** Override for a proxy endpoint. */
|
|
87
|
+
readonly endpoint?: string;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** The tool input, with the response's token usage when it reported one. */
|
|
91
|
+
export interface AnthropicToolCallResult {
|
|
92
|
+
readonly input: unknown;
|
|
93
|
+
/**
|
|
94
|
+
* `usage.input_tokens` / `usage.output_tokens` when both are numbers;
|
|
95
|
+
* absent otherwise. An unmetered response reports no usage, never
|
|
96
|
+
* zeros. No `cache_control` is sent, so there are no cache counts.
|
|
97
|
+
*/
|
|
98
|
+
readonly usage?: { readonly input: number; readonly output: number };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* How a structured call ended without the tool input it asked for:
|
|
103
|
+
*
|
|
104
|
+
* - `max_tokens`: the budget ran out (`stop_reason: max_tokens`) before
|
|
105
|
+
* the tool call.
|
|
106
|
+
* - `no_tool_call`: the model finished without calling the tool
|
|
107
|
+
* (possible under `auto`).
|
|
108
|
+
* - `refusal`: the model declined (`stop_reason: refusal`).
|
|
109
|
+
* - `http`: the API answered non-2xx.
|
|
110
|
+
* - `malformed`: the body was JSON but not a Messages response.
|
|
111
|
+
*/
|
|
112
|
+
export const ANTHROPIC_STRUCTURED_CALL_FAILURE_KINDS = [
|
|
113
|
+
'max_tokens',
|
|
114
|
+
'no_tool_call',
|
|
115
|
+
'refusal',
|
|
116
|
+
'http',
|
|
117
|
+
'malformed',
|
|
118
|
+
] as const;
|
|
119
|
+
|
|
120
|
+
export type AnthropicStructuredCallFailureKind =
|
|
121
|
+
(typeof ANTHROPIC_STRUCTURED_CALL_FAILURE_KINDS)[number];
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* A structured call that returned no tool input, NAMED by why. The kind
|
|
125
|
+
* is in the message too (`[max_tokens]` …), so a consumer that only
|
|
126
|
+
* surfaces the message (the rerank judge's `reason`) still reports
|
|
127
|
+
* which failure it was.
|
|
128
|
+
*/
|
|
129
|
+
export class AnthropicStructuredCallError extends Error {
|
|
130
|
+
readonly kind: AnthropicStructuredCallFailureKind;
|
|
131
|
+
readonly status: number | undefined;
|
|
132
|
+
readonly stopReason: string | undefined;
|
|
133
|
+
constructor(
|
|
134
|
+
kind: AnthropicStructuredCallFailureKind,
|
|
135
|
+
detail: string,
|
|
136
|
+
extra: { readonly status?: number; readonly stopReason?: string } = {},
|
|
137
|
+
) {
|
|
138
|
+
super(`anthropic structured call [${kind}]: ${detail}`);
|
|
139
|
+
this.name = 'AnthropicStructuredCallError';
|
|
140
|
+
this.kind = kind;
|
|
141
|
+
this.status = extra.status;
|
|
142
|
+
this.stopReason = extra.stopReason;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Whether `err` is an {@link AnthropicStructuredCallError}, by its shape:
|
|
148
|
+
* an `Error` named `AnthropicStructuredCallError` whose `kind` is one of
|
|
149
|
+
* {@link ANTHROPIC_STRUCTURED_CALL_FAILURE_KINDS}.
|
|
150
|
+
*
|
|
151
|
+
* Prefer this to `instanceof`. An `instanceof` check holds only while one
|
|
152
|
+
* copy of this package is installed: a consumer that resolves a second
|
|
153
|
+
* copy (its own `@ggui-ai/ui-gen` at a different version from the one
|
|
154
|
+
* `@ggui-ai/mcp-server` depends on) gets errors from a class it did not
|
|
155
|
+
* import, and every one of them fails the check.
|
|
156
|
+
*/
|
|
157
|
+
export function isAnthropicStructuredCallError(
|
|
158
|
+
err: unknown,
|
|
159
|
+
): err is AnthropicStructuredCallError {
|
|
160
|
+
if (!(err instanceof Error) || err.name !== 'AnthropicStructuredCallError') {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
const kind: unknown = Reflect.get(err, 'kind');
|
|
164
|
+
return ANTHROPIC_STRUCTURED_CALL_FAILURE_KINDS.some((known) => known === kind);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Send one structured call and return the named tool's input. Every way
|
|
169
|
+
* the turn ends without that input throws an
|
|
170
|
+
* {@link AnthropicStructuredCallError} whose kind says which.
|
|
171
|
+
*/
|
|
172
|
+
export async function anthropicToolCall(
|
|
173
|
+
request: AnthropicToolCallRequest,
|
|
174
|
+
): Promise<AnthropicToolCallResult> {
|
|
175
|
+
const answerBudget = request.maxTokens ?? DEFAULT_ANSWER_BUDGET;
|
|
176
|
+
const refusesForcedTool = anthropicRejectsForcedToolChoice(request.model);
|
|
177
|
+
const maxTokens = refusesForcedTool
|
|
178
|
+
? answerBudget + ALWAYS_THINKING_HEADROOM_TOKENS
|
|
179
|
+
: answerBudget;
|
|
180
|
+
const toolName = request.tool.name;
|
|
181
|
+
const body = {
|
|
182
|
+
model: request.model,
|
|
183
|
+
max_tokens: maxTokens,
|
|
184
|
+
system: refusesForcedTool
|
|
185
|
+
? `${request.systemPrompt}\n\nAnswer by calling the \`${toolName}\` tool exactly once. Do not answer in text.`
|
|
186
|
+
: request.systemPrompt,
|
|
187
|
+
messages: [{ role: 'user', content: request.userPrompt }],
|
|
188
|
+
tools: [
|
|
189
|
+
{
|
|
190
|
+
name: toolName,
|
|
191
|
+
description: request.tool.description,
|
|
192
|
+
input_schema: request.tool.input_schema,
|
|
193
|
+
},
|
|
194
|
+
],
|
|
195
|
+
tool_choice: refusesForcedTool
|
|
196
|
+
? { type: 'auto', disable_parallel_tool_use: true }
|
|
197
|
+
: { type: 'tool', name: toolName },
|
|
198
|
+
};
|
|
199
|
+
const fetchImpl = request.fetch ?? globalThis.fetch;
|
|
200
|
+
const response = await fetchImpl(request.endpoint ?? DEFAULT_ENDPOINT, {
|
|
201
|
+
method: 'POST',
|
|
202
|
+
headers: {
|
|
203
|
+
'x-api-key': request.apiKey,
|
|
204
|
+
'anthropic-version': DEFAULT_API_VERSION,
|
|
205
|
+
'content-type': 'application/json',
|
|
206
|
+
},
|
|
207
|
+
body: JSON.stringify(body),
|
|
208
|
+
...(request.signal !== undefined ? { signal: request.signal } : {}),
|
|
209
|
+
});
|
|
210
|
+
if (!response.ok) {
|
|
211
|
+
const text = await response.text();
|
|
212
|
+
throw new AnthropicStructuredCallError(
|
|
213
|
+
'http',
|
|
214
|
+
`HTTP ${response.status}: ${text.slice(0, 500)}`,
|
|
215
|
+
{ status: response.status },
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
const json: unknown = await response.json();
|
|
219
|
+
if (!isRecord(json) || !Array.isArray(json['content'])) {
|
|
220
|
+
throw new AnthropicStructuredCallError(
|
|
221
|
+
'malformed',
|
|
222
|
+
'response body is not a Messages response',
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
const stopReason =
|
|
226
|
+
typeof json['stop_reason'] === 'string' ? json['stop_reason'] : undefined;
|
|
227
|
+
const toolUse = json['content'].find(
|
|
228
|
+
(block: unknown): block is Record<string, unknown> =>
|
|
229
|
+
isRecord(block) && block['type'] === 'tool_use' && block['name'] === toolName,
|
|
230
|
+
);
|
|
231
|
+
if (toolUse !== undefined && toolUse['input'] !== undefined) {
|
|
232
|
+
const usage = readUsage(json['usage']);
|
|
233
|
+
return { input: toolUse['input'], ...(usage !== undefined ? { usage } : {}) };
|
|
234
|
+
}
|
|
235
|
+
if (stopReason === 'max_tokens') {
|
|
236
|
+
throw new AnthropicStructuredCallError(
|
|
237
|
+
'max_tokens',
|
|
238
|
+
`stop_reason=max_tokens before the "${toolName}" tool_use block (max_tokens=${maxTokens})`,
|
|
239
|
+
{ stopReason },
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
if (stopReason === 'refusal') {
|
|
243
|
+
throw new AnthropicStructuredCallError(
|
|
244
|
+
'refusal',
|
|
245
|
+
'the model declined (stop_reason=refusal)',
|
|
246
|
+
{ stopReason },
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
throw new AnthropicStructuredCallError(
|
|
250
|
+
'no_tool_call',
|
|
251
|
+
`the turn ended (stop_reason=${stopReason ?? 'absent'}) without a "${toolName}" tool_use block`,
|
|
252
|
+
stopReason !== undefined ? { stopReason } : {},
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function readUsage(usage: unknown): AnthropicToolCallResult['usage'] {
|
|
257
|
+
if (!isRecord(usage)) return undefined;
|
|
258
|
+
const input = usage['input_tokens'];
|
|
259
|
+
const output = usage['output_tokens'];
|
|
260
|
+
return typeof input === 'number' && typeof output === 'number'
|
|
261
|
+
? { input, output }
|
|
262
|
+
: undefined;
|
|
263
|
+
}
|
package/src/providers/index.ts
CHANGED
|
@@ -62,6 +62,19 @@ export type { OpenRouterAdapterOptions } from './openrouter.js';
|
|
|
62
62
|
export { createBedrockAdapter } from './bedrock.js';
|
|
63
63
|
export type { BedrockAdapterOptions } from './bedrock.js';
|
|
64
64
|
|
|
65
|
+
export {
|
|
66
|
+
ANTHROPIC_STRUCTURED_CALL_FAILURE_KINDS,
|
|
67
|
+
AnthropicStructuredCallError,
|
|
68
|
+
anthropicToolCall,
|
|
69
|
+
isAnthropicStructuredCallError,
|
|
70
|
+
} from './anthropic-tool-call.js';
|
|
71
|
+
export type {
|
|
72
|
+
AnthropicStructuredCallFailureKind,
|
|
73
|
+
AnthropicTool,
|
|
74
|
+
AnthropicToolCallRequest,
|
|
75
|
+
AnthropicToolCallResult,
|
|
76
|
+
} from './anthropic-tool-call.js';
|
|
77
|
+
|
|
65
78
|
import type { LlmProvider } from '@ggui-ai/mcp-server-core';
|
|
66
79
|
import type { ProviderAdapter } from '../provider-adapter.js';
|
|
67
80
|
import { createAnthropicAdapter } from './anthropic.js';
|