@ggui-ai/ui-gen 0.12.0 → 0.14.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/adapters/generation-dispatch.d.ts +2 -2
- package/dist/adapters/generation-dispatch.js +190 -57
- package/dist/adapters/generation-dispatch.js.map +1 -1
- package/dist/adapters/index.js +5 -8
- package/dist/adapters/index.js.map +1 -1
- package/dist/advanced/index.d.ts +3 -3
- package/dist/advanced/index.js +190 -57
- package/dist/advanced/index.js.map +1 -1
- package/dist/blueprint-validator.js +2 -7
- package/dist/blueprint-validator.js.map +1 -1
- package/dist/boilerplate.js +4 -4
- package/dist/boilerplate.js.map +1 -1
- package/dist/check/index.d.ts +1 -1
- package/dist/check/index.js +55 -15
- package/dist/check/index.js.map +1 -1
- package/dist/{create-ui-generator-CF0EL0Li.d.ts → create-ui-generator-D6TKuv9V.d.ts} +2 -2
- package/dist/{dispatch-D75M-OfZ.d.ts → dispatch-BuZfTh9r.d.ts} +1 -1
- package/dist/evaluation/axis-checks/index.d.ts +3 -3
- package/dist/evaluation/axis-checks/index.js.map +1 -1
- package/dist/evaluation/axis-checks/registry.d.ts +1 -1
- package/dist/evaluation/index.d.ts +3 -3
- package/dist/evaluation/index.js +79 -16
- package/dist/evaluation/index.js.map +1 -1
- package/dist/harness/check/runtime-render/index.d.ts +1 -1
- package/dist/harness/check/runtime-render/index.js +2 -7
- package/dist/harness/check/runtime-render/index.js.map +1 -1
- package/dist/harness/index.d.ts +2 -2
- package/dist/harness/index.js +64 -19
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/prompts.js +2 -0
- package/dist/harness/prompts.js.map +1 -1
- package/dist/harness/result-types.d.ts +1 -1
- package/dist/harness/runtime.d.ts +2 -2
- package/dist/harness/runtime.js +5 -5
- package/dist/harness/runtime.js.map +1 -1
- package/dist/harness/types-public.d.ts +1 -1
- package/dist/harness/types-public.js +4 -4
- package/dist/harness/types-public.js.map +1 -1
- package/dist/harness/validator-trace-sink.d.ts +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +190 -57
- package/dist/index.js.map +1 -1
- package/dist/{llm-router-BEVtbAb9.d.ts → llm-router-D7fjBhtr.d.ts} +39 -0
- package/dist/patch.d.ts +1 -1
- package/dist/provider-adapter-contract.js +1017 -731
- package/dist/provider-adapter-contract.js.map +1 -1
- package/dist/{types-public-DIpjC-OA.d.ts → types-public-CkNWEov9.d.ts} +64 -1
- package/dist/validation/index.d.ts +1 -1
- package/dist/validation/index.js +1 -1
- package/dist/validation/index.js.map +1 -1
- package/dist/workflows.d.ts +1 -1
- package/package.json +22 -22
- package/src/adapters/provider-router.ts +9 -0
- package/src/boilerplate/system-prompt.ts +4 -4
- package/src/check/run-tier0.ts +109 -22
- package/src/evaluation/index.ts +4 -0
- package/src/evaluation/llm-evaluator.ts +52 -8
- package/src/evaluation/types-public.ts +79 -0
- package/src/evaluation/visual-evaluator.ts +27 -5
- package/src/harness/coding/run-eval-round.ts +32 -6
- package/src/harness/llm-router.ts +128 -2
- package/src/validation/primitives.ts +1 -1
|
@@ -23,6 +23,7 @@ import type { Classification } from "../../classifier/index.js";
|
|
|
23
23
|
import type { AgentWorkspace } from "../../coding-agent/workspace.js";
|
|
24
24
|
import type { CostTracker } from "../../evaluation/cost-tracker.js";
|
|
25
25
|
import type { EvalIssue, EvalResult, RuntimeProbeMeta } from "../../evaluation/types-public.js";
|
|
26
|
+
import { notApplicableCoverage } from "../../evaluation/types-public.js";
|
|
26
27
|
import { mapProviderForEvaluator } from "../enforced-coding.js";
|
|
27
28
|
import { runCheck } from "../index.js";
|
|
28
29
|
import { isRecoverableRenderCrash } from "../check/runtime-render/index.js";
|
|
@@ -121,6 +122,15 @@ export interface EvalRoundResult {
|
|
|
121
122
|
/** Cap feedback to N issues per eval-fix turn so the LLM stays surgical. */
|
|
122
123
|
const MAX_FEEDBACK_ISSUES = 3;
|
|
123
124
|
|
|
125
|
+
/**
|
|
126
|
+
* `criteriaCoverage` reason stamped on the same-image low-risk bypass
|
|
127
|
+
* exits: tier-1/2 evaluation is never invoked there BY DESIGN, so every
|
|
128
|
+
* criterion is `not-applicable` (excluded from coverage denominators),
|
|
129
|
+
* not `skipped` (which would count as silent absence).
|
|
130
|
+
*/
|
|
131
|
+
const LOW_RISK_BYPASS_REASON =
|
|
132
|
+
"same-image low-risk bypass: axis checks clean, tier-1/2 evaluation not invoked";
|
|
133
|
+
|
|
124
134
|
/**
|
|
125
135
|
* Pick the ≤{@link MAX_FEEDBACK_ISSUES} issues an eval-fix turn feeds
|
|
126
136
|
* back. Provenance-aware (Exp 54 P1 addendum): ONE slot is reserved
|
|
@@ -375,7 +385,12 @@ export async function runEvalRound(
|
|
|
375
385
|
);
|
|
376
386
|
const lines = runtimeFails.slice(0, MAX_FEEDBACK_ISSUES).map(formatRuntimeProbeFeedback);
|
|
377
387
|
const allIssues = [...modeIssues, ...exitProbe.probeIssues];
|
|
378
|
-
evalResult = {
|
|
388
|
+
evalResult = {
|
|
389
|
+
issues: allIssues,
|
|
390
|
+
pass: ["axis.low-risk"],
|
|
391
|
+
criteriaCoverage: notApplicableCoverage(LOW_RISK_BYPASS_REASON),
|
|
392
|
+
runtimeProbe: exitProbe.meta,
|
|
393
|
+
};
|
|
379
394
|
console.log(
|
|
380
395
|
`[simple] eval round ${evalRoundsUsed}: low-risk bypass clean BUT ` +
|
|
381
396
|
`runtime probe fail (recoverable) — granting +1 turn`,
|
|
@@ -398,6 +413,7 @@ export async function runEvalRound(
|
|
|
398
413
|
evalResult = {
|
|
399
414
|
issues: [...modeIssues, ...exitProbe.probeIssues],
|
|
400
415
|
pass: ["axis.low-risk"],
|
|
416
|
+
criteriaCoverage: notApplicableCoverage(LOW_RISK_BYPASS_REASON),
|
|
401
417
|
runtimeProbe: exitProbe.meta,
|
|
402
418
|
};
|
|
403
419
|
console.log(
|
|
@@ -499,7 +515,16 @@ export async function runEvalRound(
|
|
|
499
515
|
...modeIssues,
|
|
500
516
|
];
|
|
501
517
|
const allPass: string[] = [...(llmResult?.pass ?? [])];
|
|
502
|
-
|
|
518
|
+
// Carry the per-criterion coverage stamp from the evaluator; every
|
|
519
|
+
// later re-stamp of evalResult below spreads this base so the field
|
|
520
|
+
// survives to the assembled result (benchmark reads it per run).
|
|
521
|
+
evalResult = {
|
|
522
|
+
issues: allIssues,
|
|
523
|
+
pass: allPass,
|
|
524
|
+
...(llmResult?.criteriaCoverage !== undefined
|
|
525
|
+
? { criteriaCoverage: llmResult.criteriaCoverage }
|
|
526
|
+
: {}),
|
|
527
|
+
};
|
|
503
528
|
|
|
504
529
|
// ── Log merged results, with mode-check subcategory breakdown ──
|
|
505
530
|
const fails = allIssues.filter((i) => i.result === "fail");
|
|
@@ -570,7 +595,7 @@ export async function runEvalRound(
|
|
|
570
595
|
);
|
|
571
596
|
const lines = runtimeFails.slice(0, MAX_FEEDBACK_ISSUES).map(formatRuntimeProbeFeedback);
|
|
572
597
|
const enrichedIssues = [...allIssues, ...exitProbe.probeIssues];
|
|
573
|
-
evalResult = { issues: enrichedIssues, pass: allPass, runtimeProbe: exitProbe.meta };
|
|
598
|
+
evalResult = { ...evalResult, issues: enrichedIssues, pass: allPass, runtimeProbe: exitProbe.meta };
|
|
574
599
|
const enrichedFingerprints = new Set([
|
|
575
600
|
...currFailFingerprints,
|
|
576
601
|
...runtimeFails.map(fingerprintFail),
|
|
@@ -598,6 +623,7 @@ export async function runEvalRound(
|
|
|
598
623
|
// into the merged result and ALWAYS stamp its execution meta, so a
|
|
599
624
|
// did-not-run probe is visible downstream even on this clean exit.
|
|
600
625
|
evalResult = {
|
|
626
|
+
...evalResult,
|
|
601
627
|
issues: [...allIssues, ...exitProbe.probeIssues],
|
|
602
628
|
pass: allPass,
|
|
603
629
|
runtimeProbe: exitProbe.meta,
|
|
@@ -659,8 +685,8 @@ export async function runEvalRound(
|
|
|
659
685
|
fixtureProps,
|
|
660
686
|
});
|
|
661
687
|
evalResult = {
|
|
688
|
+
...evalResult,
|
|
662
689
|
issues: [...evalResult.issues, ...stuckExitProbe.probeIssues],
|
|
663
|
-
pass: evalResult.pass,
|
|
664
690
|
runtimeProbe: stuckExitProbe.meta,
|
|
665
691
|
};
|
|
666
692
|
return {
|
|
@@ -718,8 +744,8 @@ export async function runEvalRound(
|
|
|
718
744
|
// ALWAYS stamp the probe's execution meta, even though we're not
|
|
719
745
|
// granting an extension — a did-not-run probe must stay visible.
|
|
720
746
|
evalResult = {
|
|
747
|
+
...evalResult,
|
|
721
748
|
issues: [...evalResult.issues, ...exitProbe.probeIssues],
|
|
722
|
-
pass: evalResult.pass,
|
|
723
749
|
runtimeProbe: exitProbe.meta,
|
|
724
750
|
};
|
|
725
751
|
console.log(`[simple] eval round ${evalRoundsUsed}: max eval rounds reached — stopping`);
|
|
@@ -748,7 +774,7 @@ export async function runEvalRound(
|
|
|
748
774
|
.slice(0, MAX_FEEDBACK_ISSUES)
|
|
749
775
|
.map(formatRuntimeProbeFeedback);
|
|
750
776
|
const enrichedIssues = [...evalResult.issues, ...exitProbe.probeIssues];
|
|
751
|
-
evalResult = { issues: enrichedIssues,
|
|
777
|
+
evalResult = { ...evalResult, issues: enrichedIssues, runtimeProbe: exitProbe.meta };
|
|
752
778
|
console.log(
|
|
753
779
|
`[simple] eval round ${evalRoundsUsed}: runtime-probe fail active at cap — granting +1 retry (${maxEvalRounds + RUNTIME_EXTENSION_BONUS - evalRoundsUsed} of ${RUNTIME_EXTENSION_BONUS} bonus rounds remain)`,
|
|
754
780
|
);
|
|
@@ -52,6 +52,14 @@ export interface AgentConfig {
|
|
|
52
52
|
* Sampling temperature. When defined it is threaded into the provider
|
|
53
53
|
* request; when undefined the provider default is used (unchanged
|
|
54
54
|
* behavior for all existing callers).
|
|
55
|
+
*
|
|
56
|
+
* Capability is the ROUTER's: Anthropic Opus 4.7+ and the 5-family
|
|
57
|
+
* (`claude-opus-4-7*`, `claude-fable-5*`, `claude-opus-5*`,
|
|
58
|
+
* `claude-sonnet-5*`, incl. Bedrock ids) return HTTP 400 on a
|
|
59
|
+
* non-default `temperature`/`top_p`/`top_k`, so the Anthropic adapter
|
|
60
|
+
* STRIPS the value for those ids (one log line naming model + param)
|
|
61
|
+
* and reports the effective sampling on `LLMResponse.sampling`. Callers
|
|
62
|
+
* keep expressing intent; disclosure reads the applied value.
|
|
55
63
|
*/
|
|
56
64
|
temperature?: number;
|
|
57
65
|
/**
|
|
@@ -101,10 +109,32 @@ export interface ProviderRetryInfo {
|
|
|
101
109
|
readonly message: string;
|
|
102
110
|
}
|
|
103
111
|
|
|
112
|
+
/**
|
|
113
|
+
* What sampling the provider ACTUALLY received for a text call — so a
|
|
114
|
+
* caller that asked for `temperature: 0` (a disclosed reproducibility
|
|
115
|
+
* property, e.g. the benchmark judge panel) can record the effective
|
|
116
|
+
* value instead of the requested one. `'provider-default'` means no
|
|
117
|
+
* temperature reached the provider: either the caller passed none, or
|
|
118
|
+
* the adapter stripped it because the model rejects sampling params
|
|
119
|
+
* (Anthropic Opus 4.7+ / 5-family → HTTP 400 on non-default
|
|
120
|
+
* `temperature`/`top_p`/`top_k`); `strippedReason` names the second case.
|
|
121
|
+
*/
|
|
122
|
+
export interface AppliedSampling {
|
|
123
|
+
readonly temperature: number | 'provider-default';
|
|
124
|
+
readonly strippedReason?: string;
|
|
125
|
+
}
|
|
126
|
+
|
|
104
127
|
export interface LLMResponse {
|
|
105
128
|
text: string;
|
|
106
129
|
inputTokens: number;
|
|
107
130
|
outputTokens: number;
|
|
131
|
+
/**
|
|
132
|
+
* Effective sampling for this call (see {@link AppliedSampling}).
|
|
133
|
+
* Every provider's `callText` sets it; absent only on paths that
|
|
134
|
+
* predate the field — treat absence as unknown, never as "as
|
|
135
|
+
* requested".
|
|
136
|
+
*/
|
|
137
|
+
sampling?: AppliedSampling;
|
|
108
138
|
}
|
|
109
139
|
|
|
110
140
|
/**
|
|
@@ -163,6 +193,16 @@ export interface LLMToolCallResponse {
|
|
|
163
193
|
toolCalls: LLMToolCall[];
|
|
164
194
|
inputTokens: number;
|
|
165
195
|
outputTokens: number;
|
|
196
|
+
/**
|
|
197
|
+
* The tool-choice mode the provider ACTUALLY received. Callers ask
|
|
198
|
+
* for `'required'` (Anthropic `tool_choice: any`); Claude Fable 5.1
|
|
199
|
+
* rejects forced tool choice with HTTP 400, so the Anthropic adapter
|
|
200
|
+
* downgrades to `'auto'` for that family and reports it here. A
|
|
201
|
+
* downgraded call may legitimately return zero tool calls — the
|
|
202
|
+
* evaluator's `criteriaCoverage` records that as `skipped`, never as
|
|
203
|
+
* a pass. Absent = predates the field (treat as unknown).
|
|
204
|
+
*/
|
|
205
|
+
appliedToolChoice?: 'required' | 'auto';
|
|
166
206
|
/**
|
|
167
207
|
* Tokens read from / written to the prompt cache, when the provider
|
|
168
208
|
* reports them. Optional because not every provider exposes
|
|
@@ -506,6 +546,65 @@ export abstract class LLMAgent {
|
|
|
506
546
|
// AnthropicAgent
|
|
507
547
|
// =============================================================================
|
|
508
548
|
|
|
549
|
+
/**
|
|
550
|
+
* Strip every routing spelling down to the bare Claude API id so the
|
|
551
|
+
* family predicates below see one form: `anthropic/claude-x`,
|
|
552
|
+
* `anthropic.claude-x`, `us.anthropic.claude-x[-vN:M]` and the bare
|
|
553
|
+
* `claude-x` all normalize to `claude-x…`. ARNs are left as-is (they
|
|
554
|
+
* name a profile, not a family) and match no predicate.
|
|
555
|
+
*/
|
|
556
|
+
export function normalizeAnthropicModelId(model: string): string {
|
|
557
|
+
return model
|
|
558
|
+
.replace(/^anthropic\//, '')
|
|
559
|
+
.replace(/^(?:[a-z]{2}\.)?anthropic\./, '');
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
/**
|
|
563
|
+
* Models that reject non-default sampling parameters with HTTP 400:
|
|
564
|
+
* Opus 4.7 and everything after it (Fable 5, Fable 5.1, Opus 5,
|
|
565
|
+
* Sonnet 5). Haiku 4.5 (`claude-haiku-4-5*`) still accepts them.
|
|
566
|
+
* Strings per ggui#706 (platform.claude.com, verified 2026-09-02).
|
|
567
|
+
*/
|
|
568
|
+
export function anthropicRejectsSamplingParams(model: string): boolean {
|
|
569
|
+
return /^claude-(?:opus-4-7|opus-5|sonnet-5|fable-5)(?:-|$)/.test(
|
|
570
|
+
normalizeAnthropicModelId(model),
|
|
571
|
+
);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* Models that reject a FORCED tool choice (`tool_choice: any` / a named
|
|
576
|
+
* tool) with HTTP 400: Claude Fable 5.1 (ggui#706). `auto` is accepted.
|
|
577
|
+
*/
|
|
578
|
+
export function anthropicRejectsForcedToolChoice(model: string): boolean {
|
|
579
|
+
return /^claude-fable-5-1(?:-|$)/.test(normalizeAnthropicModelId(model));
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* Decide what sampling reaches Anthropic for `model` given the caller's
|
|
584
|
+
* `temperature`: pass it through on models that accept it, strip it on
|
|
585
|
+
* the 4.7+/5-family and say so. Pure — the caller logs and spreads.
|
|
586
|
+
*/
|
|
587
|
+
export function resolveAnthropicSampling(
|
|
588
|
+
model: string,
|
|
589
|
+
temperature: number | undefined,
|
|
590
|
+
): { readonly request: { temperature?: number }; readonly applied: AppliedSampling } {
|
|
591
|
+
if (temperature === undefined) {
|
|
592
|
+
return { request: {}, applied: { temperature: 'provider-default' } };
|
|
593
|
+
}
|
|
594
|
+
if (anthropicRejectsSamplingParams(model)) {
|
|
595
|
+
return {
|
|
596
|
+
request: {},
|
|
597
|
+
applied: {
|
|
598
|
+
temperature: 'provider-default',
|
|
599
|
+
strippedReason:
|
|
600
|
+
`${normalizeAnthropicModelId(model)} rejects non-default sampling params (HTTP 400 on Opus 4.7+/5-family); ` +
|
|
601
|
+
`caller's temperature=${temperature} was not sent`,
|
|
602
|
+
},
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
return { request: { temperature }, applied: { temperature } };
|
|
606
|
+
}
|
|
607
|
+
|
|
509
608
|
export class AnthropicAgent extends LLMAgent {
|
|
510
609
|
readonly provider = 'anthropic' as const;
|
|
511
610
|
|
|
@@ -568,6 +667,14 @@ export class AnthropicAgent extends LLMAgent {
|
|
|
568
667
|
},
|
|
569
668
|
];
|
|
570
669
|
|
|
670
|
+
// Capability is the router's: the 4.7+/5-family rejects sampling
|
|
671
|
+
// params with 400, so strip (and disclose) rather than fail the call
|
|
672
|
+
// or make callers stop expressing intent (ggui#710 / #706).
|
|
673
|
+
const sampling = resolveAnthropicSampling(resolvedModel, temperature);
|
|
674
|
+
if (sampling.applied.strippedReason !== undefined) {
|
|
675
|
+
console.warn(`[anthropic] callText: ${sampling.applied.strippedReason}`);
|
|
676
|
+
}
|
|
677
|
+
|
|
571
678
|
try {
|
|
572
679
|
const response = await this.apiCall(() =>
|
|
573
680
|
client.messages.create({
|
|
@@ -575,7 +682,7 @@ export class AnthropicAgent extends LLMAgent {
|
|
|
575
682
|
max_tokens: maxTokens ?? 4096,
|
|
576
683
|
system,
|
|
577
684
|
messages: [{ role: 'user', content: userPrompt }],
|
|
578
|
-
...
|
|
685
|
+
...sampling.request,
|
|
579
686
|
}),
|
|
580
687
|
);
|
|
581
688
|
|
|
@@ -618,6 +725,7 @@ export class AnthropicAgent extends LLMAgent {
|
|
|
618
725
|
text,
|
|
619
726
|
inputTokens: response.usage.input_tokens,
|
|
620
727
|
outputTokens: response.usage.output_tokens,
|
|
728
|
+
sampling: sampling.applied,
|
|
621
729
|
};
|
|
622
730
|
} catch (e) {
|
|
623
731
|
const endedAt = Date.now();
|
|
@@ -761,6 +869,20 @@ export class AnthropicAgent extends LLMAgent {
|
|
|
761
869
|
// want the final-message shape downstream, so use the stream
|
|
762
870
|
// helper's `finalMessage()` which folds the events back to the
|
|
763
871
|
// same `Message` Type the non-streaming path returned.
|
|
872
|
+
// Fable 5.1 rejects a forced tool choice (400); downgrade to
|
|
873
|
+
// `auto` for that family and disclose it on the response so a
|
|
874
|
+
// resulting zero-tool-call reply is never mistaken for a verdict
|
|
875
|
+
// (ggui#710 / #706).
|
|
876
|
+
const appliedToolChoice: 'required' | 'auto' =
|
|
877
|
+
toolChoice === 'required' && anthropicRejectsForcedToolChoice(resolvedModel)
|
|
878
|
+
? 'auto'
|
|
879
|
+
: toolChoice;
|
|
880
|
+
if (appliedToolChoice !== toolChoice) {
|
|
881
|
+
console.warn(
|
|
882
|
+
`[anthropic] callTools: ${normalizeAnthropicModelId(resolvedModel)} rejects forced tool_choice (HTTP 400); ` +
|
|
883
|
+
`caller's 'required' downgraded to 'auto'`,
|
|
884
|
+
);
|
|
885
|
+
}
|
|
764
886
|
const response = await this.apiCall(() =>
|
|
765
887
|
client.messages
|
|
766
888
|
.stream({
|
|
@@ -769,7 +891,7 @@ export class AnthropicAgent extends LLMAgent {
|
|
|
769
891
|
system,
|
|
770
892
|
messages: [{ role: 'user', content: userPrompt }],
|
|
771
893
|
tools: cachedTools,
|
|
772
|
-
tool_choice: { type:
|
|
894
|
+
tool_choice: { type: appliedToolChoice === 'required' ? 'any' : 'auto' },
|
|
773
895
|
})
|
|
774
896
|
.finalMessage(),
|
|
775
897
|
);
|
|
@@ -821,6 +943,7 @@ export class AnthropicAgent extends LLMAgent {
|
|
|
821
943
|
outputTokens: response.usage.output_tokens,
|
|
822
944
|
cacheReadTokens: cacheRead,
|
|
823
945
|
cacheCreationTokens: cacheCreated,
|
|
946
|
+
appliedToolChoice,
|
|
824
947
|
};
|
|
825
948
|
} catch (e) {
|
|
826
949
|
const endedAt = Date.now();
|
|
@@ -1012,6 +1135,7 @@ export class OpenAIAgent extends LLMAgent {
|
|
|
1012
1135
|
text,
|
|
1013
1136
|
inputTokens: response.usage?.input_tokens ?? 0,
|
|
1014
1137
|
outputTokens: response.usage?.output_tokens ?? 0,
|
|
1138
|
+
sampling: { temperature: temperature ?? 'provider-default' },
|
|
1015
1139
|
};
|
|
1016
1140
|
}
|
|
1017
1141
|
|
|
@@ -1270,6 +1394,7 @@ export class GoogleAgent extends LLMAgent {
|
|
|
1270
1394
|
text: interactionText(interaction),
|
|
1271
1395
|
inputTokens: interaction.usage?.total_input_tokens ?? 0,
|
|
1272
1396
|
outputTokens: interaction.usage?.total_output_tokens ?? 0,
|
|
1397
|
+
sampling: { temperature: temperature ?? 'provider-default' },
|
|
1273
1398
|
};
|
|
1274
1399
|
}
|
|
1275
1400
|
|
|
@@ -1669,6 +1794,7 @@ export class OpenRouterAgent extends LLMAgent {
|
|
|
1669
1794
|
text,
|
|
1670
1795
|
inputTokens: response.usage.prompt_tokens,
|
|
1671
1796
|
outputTokens: response.usage.completion_tokens,
|
|
1797
|
+
sampling: { temperature: temperature ?? 'provider-default' },
|
|
1672
1798
|
};
|
|
1673
1799
|
}
|
|
1674
1800
|
|