@apo-ai/sdk 0.11.0 → 0.12.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/agent-task/integrations/ai-sdk.d.ts +1 -1
- package/dist/agent-task/integrations/anthropic.d.ts +1 -1
- package/dist/agent-task/integrations/anthropic.js +2 -2
- package/dist/agent-task/integrations/openai.d.ts +1 -1
- package/dist/agent-task/integrations/openai.js +2 -2
- package/dist/agent-task/public.d.ts +10 -3
- package/dist/agent-task/public.js +235 -24
- package/dist/agent-task/public.js.map +1 -1
- package/dist/{chunk-P43KL5AR.js → chunk-A3UYQ7M4.js} +3 -2
- package/dist/{chunk-P43KL5AR.js.map → chunk-A3UYQ7M4.js.map} +1 -1
- package/dist/{chunk-Z64A566W.js → chunk-JTWQD27M.js} +2 -1
- package/dist/chunk-JTWQD27M.js.map +1 -0
- package/dist/{chunk-LO343UZO.js → chunk-P24ECOI3.js} +4 -2
- package/dist/chunk-P24ECOI3.js.map +1 -0
- package/dist/{chunk-6H2GACBG.js → chunk-X73JGMK3.js} +3 -2
- package/dist/{chunk-6H2GACBG.js.map → chunk-X73JGMK3.js.map} +1 -1
- package/dist/otel/index.js +1 -1
- package/dist/{tracing-DoIGvJW1.d.ts → tracing-FqFObrmt.d.ts} +5 -0
- package/package.json +1 -1
- package/dist/chunk-LO343UZO.js.map +0 -1
- package/dist/chunk-Z64A566W.js.map +0 -1
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// Do not edit by hand — edit the src/ originals and rebuild.
|
|
3
3
|
import {
|
|
4
4
|
createApoAnthropic
|
|
5
|
-
} from "../../chunk-
|
|
6
|
-
import "../../chunk-
|
|
5
|
+
} from "../../chunk-X73JGMK3.js";
|
|
6
|
+
import "../../chunk-JTWQD27M.js";
|
|
7
7
|
export {
|
|
8
8
|
createApoAnthropic
|
|
9
9
|
};
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// Do not edit by hand — edit the src/ originals and rebuild.
|
|
3
3
|
import {
|
|
4
4
|
createApoOpenAI
|
|
5
|
-
} from "../../chunk-
|
|
6
|
-
import "../../chunk-
|
|
5
|
+
} from "../../chunk-A3UYQ7M4.js";
|
|
6
|
+
import "../../chunk-JTWQD27M.js";
|
|
7
7
|
export {
|
|
8
8
|
createApoOpenAI
|
|
9
9
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as AgentTaskTraceContext, a as AgentTaskTraceOptions } from '../tracing-
|
|
1
|
+
import { A as AgentTaskTraceContext, a as AgentTaskTraceOptions } from '../tracing-FqFObrmt.js';
|
|
2
2
|
export { CreateApoTracerOptions, createApoTracer } from './integrations/ai-sdk.js';
|
|
3
3
|
export { CreateApoOpenAIOptions, createApoOpenAI } from './integrations/openai.js';
|
|
4
4
|
export { CreateApoAnthropicOptions, createApoAnthropic } from './integrations/anthropic.js';
|
|
@@ -673,6 +673,13 @@ type JudgeMetadata = {
|
|
|
673
673
|
* the decision model, and `response` carries its typed verdict.
|
|
674
674
|
*/
|
|
675
675
|
verdict_by?: "second-judge";
|
|
676
|
+
/**
|
|
677
|
+
* How many attempts of this call were cut because the judge's stream fell
|
|
678
|
+
* into a repetition loop (`t.judge` only). Absent = none. 1 with a verdict:
|
|
679
|
+
* the first draw looped and the retry answered. A call whose last draw
|
|
680
|
+
* looped has no verdict and is recorded as a judge error.
|
|
681
|
+
*/
|
|
682
|
+
reasoning_loops?: number;
|
|
676
683
|
};
|
|
677
684
|
/**
|
|
678
685
|
* Evidence from the second grader. `error` is set when the decisions
|
|
@@ -2318,8 +2325,8 @@ declare function getActiveApoRun(): ApoRunContext | undefined;
|
|
|
2318
2325
|
*
|
|
2319
2326
|
* Pure, dependency-free canonicalizer. Both this module and its Python twin
|
|
2320
2327
|
* (`backend/apo/execution/task_revision_manifest.py`) MUST produce
|
|
2321
|
-
* byte-identical canonical JSON and digests for
|
|
2322
|
-
*
|
|
2328
|
+
* byte-identical canonical JSON and digests for any given file tree — the
|
|
2329
|
+
* task-revision identity is content-addressed on both sides of the wire.
|
|
2323
2330
|
*
|
|
2324
2331
|
* Canonicalization rules:
|
|
2325
2332
|
* - `/` path separators (caller `\` normalized to `/`);
|
|
@@ -9,20 +9,20 @@ import {
|
|
|
9
9
|
resolveApoAuthHeaders,
|
|
10
10
|
withApoRun,
|
|
11
11
|
withApoRunSync
|
|
12
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-P24ECOI3.js";
|
|
13
13
|
import {
|
|
14
14
|
createApoTracer
|
|
15
15
|
} from "../chunk-OZWOLCJ5.js";
|
|
16
16
|
import "../chunk-HRYXLRXJ.js";
|
|
17
17
|
import {
|
|
18
18
|
createApoOpenAI
|
|
19
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-A3UYQ7M4.js";
|
|
20
20
|
import {
|
|
21
21
|
createApoAnthropic
|
|
22
|
-
} from "../chunk-
|
|
22
|
+
} from "../chunk-X73JGMK3.js";
|
|
23
23
|
import {
|
|
24
24
|
servingHostFromBaseURL
|
|
25
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-JTWQD27M.js";
|
|
26
26
|
|
|
27
27
|
// src/agent-task/run/steer-scheduler.ts
|
|
28
28
|
var TASK_STEER_SPAN_NAME = "task.steer";
|
|
@@ -644,6 +644,158 @@ function levenshtein(a, b) {
|
|
|
644
644
|
// src/agent-task/checks/judge.ts
|
|
645
645
|
import { createHash } from "crypto";
|
|
646
646
|
|
|
647
|
+
// src/agent-task/checks/reasoning-loop.ts
|
|
648
|
+
var MAX_UNIT_CHARS = 64;
|
|
649
|
+
var MIN_UNIT_COPIES = 100;
|
|
650
|
+
var MIN_REPEAT_CHARS = 1e3;
|
|
651
|
+
var MAX_CHAR_RUN = 3;
|
|
652
|
+
var GRAM = 24;
|
|
653
|
+
var DIVERSITY_WINDOW = 3e3;
|
|
654
|
+
var MIN_DIVERSITY = 0.1;
|
|
655
|
+
var DIVERSITY_STRIDE = 256;
|
|
656
|
+
var MAX_DIVERSITY_LINE_CHARS = 2e3;
|
|
657
|
+
var RECYCLE_GRAM = 32;
|
|
658
|
+
var RECYCLE_WINDOW = 5e3;
|
|
659
|
+
var MAX_RECYCLED = 0.95;
|
|
660
|
+
var isFoldable = (ch) => /[\p{L}\p{N}]/u.test(ch);
|
|
661
|
+
function foldForRepetition(text) {
|
|
662
|
+
let out = "";
|
|
663
|
+
let last = "";
|
|
664
|
+
let run = 0;
|
|
665
|
+
for (const raw of text) {
|
|
666
|
+
if (!isFoldable(raw)) continue;
|
|
667
|
+
const ch = raw.toLowerCase();
|
|
668
|
+
run = ch === last ? run + 1 : 1;
|
|
669
|
+
last = ch;
|
|
670
|
+
if (run <= MAX_CHAR_RUN) out += ch;
|
|
671
|
+
}
|
|
672
|
+
return out;
|
|
673
|
+
}
|
|
674
|
+
function isTableLine(line) {
|
|
675
|
+
const trimmed = line.trim();
|
|
676
|
+
if (trimmed.startsWith("|")) return true;
|
|
677
|
+
return (trimmed.match(/\|/g)?.length ?? 0) >= 3;
|
|
678
|
+
}
|
|
679
|
+
function diversity(folded) {
|
|
680
|
+
const total = folded.length - GRAM + 1;
|
|
681
|
+
if (total <= 0) return 1;
|
|
682
|
+
const grams = /* @__PURE__ */ new Set();
|
|
683
|
+
for (let i = 0; i < total; i++) grams.add(folded.slice(i, i + GRAM));
|
|
684
|
+
return grams.size / total;
|
|
685
|
+
}
|
|
686
|
+
var RepetitionGuard = class {
|
|
687
|
+
constructor(opts) {
|
|
688
|
+
this.rawChars = 0;
|
|
689
|
+
// Repeated-unit state: the folded tail, and for each period p the number
|
|
690
|
+
// of consecutive folded chars equal to the char p before them.
|
|
691
|
+
this.tail = "";
|
|
692
|
+
this.lastChar = "";
|
|
693
|
+
this.charRun = 0;
|
|
694
|
+
this.periodRuns = new Array(MAX_UNIT_CHARS + 1).fill(0);
|
|
695
|
+
// Low-diversity state: the current raw line, and the folded window built
|
|
696
|
+
// from finished lines that are not tables.
|
|
697
|
+
this.line = "";
|
|
698
|
+
this.window = "";
|
|
699
|
+
this.sinceMeasured = 0;
|
|
700
|
+
// Recycled state: every gram of the filtered folded stream so far, and for
|
|
701
|
+
// the window's grams whether each had been seen when it arrived.
|
|
702
|
+
this.seenGrams = /* @__PURE__ */ new Set();
|
|
703
|
+
this.gramTail = "";
|
|
704
|
+
this.windowFlags = [];
|
|
705
|
+
this.flagHead = 0;
|
|
706
|
+
this.recycledInWindow = 0;
|
|
707
|
+
this.checkDiversity = opts.diversity;
|
|
708
|
+
}
|
|
709
|
+
get tripped() {
|
|
710
|
+
return this.trip;
|
|
711
|
+
}
|
|
712
|
+
push(delta) {
|
|
713
|
+
if (this.trip || !delta) return this.trip;
|
|
714
|
+
for (const raw of delta) {
|
|
715
|
+
this.rawChars++;
|
|
716
|
+
if (this.checkDiversity) this.pushLineChar(raw);
|
|
717
|
+
if (isFoldable(raw)) this.pushFolded(raw.toLowerCase());
|
|
718
|
+
if (this.trip) break;
|
|
719
|
+
}
|
|
720
|
+
return this.trip;
|
|
721
|
+
}
|
|
722
|
+
pushFolded(ch) {
|
|
723
|
+
this.charRun = ch === this.lastChar ? this.charRun + 1 : 1;
|
|
724
|
+
this.lastChar = ch;
|
|
725
|
+
if (this.charRun > MAX_CHAR_RUN) return;
|
|
726
|
+
this.tail += ch;
|
|
727
|
+
const n = this.tail.length - 1;
|
|
728
|
+
for (let p = 1; p <= MAX_UNIT_CHARS; p++) {
|
|
729
|
+
this.periodRuns[p] = n >= p && this.tail[n - p] === ch ? this.periodRuns[p] + 1 : 0;
|
|
730
|
+
const span = this.periodRuns[p] + p;
|
|
731
|
+
if (span >= MIN_REPEAT_CHARS && span / p >= MIN_UNIT_COPIES) {
|
|
732
|
+
this.trip = {
|
|
733
|
+
rule: "repeated-unit",
|
|
734
|
+
atChar: this.rawChars,
|
|
735
|
+
unit: this.tail.slice(-p),
|
|
736
|
+
copies: Math.floor(span / p)
|
|
737
|
+
};
|
|
738
|
+
return;
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
if (this.tail.length > MAX_UNIT_CHARS * 2) this.tail = this.tail.slice(-MAX_UNIT_CHARS);
|
|
742
|
+
}
|
|
743
|
+
pushLineChar(raw) {
|
|
744
|
+
if (raw !== "\n") {
|
|
745
|
+
if (this.line.length <= MAX_DIVERSITY_LINE_CHARS) this.line += raw;
|
|
746
|
+
return;
|
|
747
|
+
}
|
|
748
|
+
const line = this.line;
|
|
749
|
+
this.line = "";
|
|
750
|
+
if (line.length > MAX_DIVERSITY_LINE_CHARS || isTableLine(line)) return;
|
|
751
|
+
const folded = foldForRepetition(line);
|
|
752
|
+
if (!folded) return;
|
|
753
|
+
this.pushRecycled(folded);
|
|
754
|
+
this.window = (this.window + folded).slice(-DIVERSITY_WINDOW);
|
|
755
|
+
this.sinceMeasured += folded.length;
|
|
756
|
+
if (this.window.length < DIVERSITY_WINDOW || this.sinceMeasured < DIVERSITY_STRIDE) return;
|
|
757
|
+
this.sinceMeasured = 0;
|
|
758
|
+
const ratio = diversity(this.window);
|
|
759
|
+
if (ratio < MIN_DIVERSITY) {
|
|
760
|
+
this.trip = { rule: "low-diversity", atChar: this.rawChars, diversity: ratio };
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
763
|
+
const windowGrams = this.windowFlags.length - this.flagHead;
|
|
764
|
+
if (windowGrams < RECYCLE_WINDOW) return;
|
|
765
|
+
const recycled = this.recycledInWindow / windowGrams;
|
|
766
|
+
if (recycled >= MAX_RECYCLED) {
|
|
767
|
+
this.trip = { rule: "recycled", atChar: this.rawChars, recycled };
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
pushRecycled(folded) {
|
|
771
|
+
for (const ch of folded) {
|
|
772
|
+
this.gramTail = (this.gramTail + ch).slice(-RECYCLE_GRAM);
|
|
773
|
+
if (this.gramTail.length < RECYCLE_GRAM) continue;
|
|
774
|
+
const seen = this.seenGrams.has(this.gramTail);
|
|
775
|
+
if (!seen) this.seenGrams.add(this.gramTail);
|
|
776
|
+
this.windowFlags.push(seen);
|
|
777
|
+
if (seen) this.recycledInWindow++;
|
|
778
|
+
if (this.windowFlags.length - this.flagHead > RECYCLE_WINDOW) {
|
|
779
|
+
if (this.windowFlags[this.flagHead++]) this.recycledInWindow--;
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
if (this.flagHead > RECYCLE_WINDOW * 4) {
|
|
783
|
+
this.windowFlags.splice(0, this.flagHead);
|
|
784
|
+
this.flagHead = 0;
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
};
|
|
788
|
+
function describeTrip(trip) {
|
|
789
|
+
switch (trip.rule) {
|
|
790
|
+
case "repeated-unit":
|
|
791
|
+
return `"${trip.unit}" repeated ${trip.copies}\xD7 at char ${trip.atChar}`;
|
|
792
|
+
case "low-diversity":
|
|
793
|
+
return `distinct-${GRAM}-gram ratio ${trip.diversity.toFixed(3)} at char ${trip.atChar}`;
|
|
794
|
+
case "recycled":
|
|
795
|
+
return `${Math.round(trip.recycled * 100)}% of the last ${RECYCLE_WINDOW} chars replay earlier reasoning, at char ${trip.atChar}`;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
|
|
647
799
|
// src/agent-task/checks/second-judge.ts
|
|
648
800
|
function secondJudgeFacts(check) {
|
|
649
801
|
const sj = check.judge?.secondJudge;
|
|
@@ -828,6 +980,16 @@ var JudgeUnavailableError = class extends Error {
|
|
|
828
980
|
this.name = "JudgeUnavailableError";
|
|
829
981
|
}
|
|
830
982
|
};
|
|
983
|
+
var JudgeReasoningLoopError = class extends JudgeUnavailableError {
|
|
984
|
+
constructor(trip, channel) {
|
|
985
|
+
super(`judge reasoning loop: ${channel} ${describeTrip(trip)}`);
|
|
986
|
+
this.name = "JudgeReasoningLoopError";
|
|
987
|
+
}
|
|
988
|
+
};
|
|
989
|
+
function isJudgeLoopGuardEnabled() {
|
|
990
|
+
const value = process.env.APO_JUDGE_LOOP_GUARD?.trim().toLowerCase();
|
|
991
|
+
return value !== "0" && value !== "false" && value !== "off";
|
|
992
|
+
}
|
|
831
993
|
var QUOTE_RULE = " Inside the reasoning, quote the output with single quotes, never with unescaped double quotes.";
|
|
832
994
|
var VERDICT_FIRST_CONTRACT = 'Respond with ONLY a JSON object: {"pass": true/false, "reasoning": "your reasoning"}.' + QUOTE_RULE;
|
|
833
995
|
var REASONING_FIRST_CONTRACT = 'Respond with ONLY a JSON object: {"reasoning": "your reasoning", "pass": true/false}.' + QUOTE_RULE;
|
|
@@ -952,7 +1114,7 @@ function retryDelayMs(retryAfter) {
|
|
|
952
1114
|
if (!Number.isFinite(ms)) return JUDGE_RETRY_DELAY_MS;
|
|
953
1115
|
return Math.min(Math.max(ms, JUDGE_RETRY_DELAY_MS), JUDGE_RETRY_AFTER_CAP_MS);
|
|
954
1116
|
}
|
|
955
|
-
async function readCompletion(response, onData) {
|
|
1117
|
+
async function readCompletion(response, onData, guards) {
|
|
956
1118
|
const contentType = response.headers.get("content-type") ?? "";
|
|
957
1119
|
if (!contentType.includes("text/event-stream")) {
|
|
958
1120
|
const data = await response.json();
|
|
@@ -989,7 +1151,15 @@ async function readCompletion(response, onData) {
|
|
|
989
1151
|
}
|
|
990
1152
|
if (!chunk) return;
|
|
991
1153
|
const choice = chunk.choices?.[0];
|
|
992
|
-
|
|
1154
|
+
const content = choice?.delta?.content ?? "";
|
|
1155
|
+
text += content;
|
|
1156
|
+
if (guards) {
|
|
1157
|
+
const thinking = choice?.delta?.reasoning_content ?? choice?.delta?.reasoning ?? "";
|
|
1158
|
+
const reasoningTrip = guards.reasoning.push(thinking);
|
|
1159
|
+
if (reasoningTrip) throw new JudgeReasoningLoopError(reasoningTrip, "reasoning");
|
|
1160
|
+
const contentTrip = guards.content.push(content);
|
|
1161
|
+
if (contentTrip) throw new JudgeReasoningLoopError(contentTrip, "content");
|
|
1162
|
+
}
|
|
993
1163
|
if (choice?.finish_reason) finishReason = choice.finish_reason;
|
|
994
1164
|
if (chunk.usage) usage = chunk.usage;
|
|
995
1165
|
};
|
|
@@ -1166,9 +1336,16 @@ async function callJudge(args) {
|
|
|
1166
1336
|
...schema && response.status === 400 && /json_schema|response_format/.test(body) ? { schemaRejected: true } : {}
|
|
1167
1337
|
};
|
|
1168
1338
|
}
|
|
1339
|
+
const guards = isJudgeLoopGuardEnabled() ? {
|
|
1340
|
+
reasoning: new RepetitionGuard({ diversity: true }),
|
|
1341
|
+
content: new RepetitionGuard({ diversity: false })
|
|
1342
|
+
} : void 0;
|
|
1169
1343
|
try {
|
|
1170
|
-
return { kind: "completion", completion: await readCompletion(response, onData) };
|
|
1344
|
+
return { kind: "completion", completion: await readCompletion(response, onData, guards) };
|
|
1171
1345
|
} catch (error) {
|
|
1346
|
+
if (error instanceof JudgeReasoningLoopError) {
|
|
1347
|
+
return { kind: "unavailable", error, retryable: true, loop: true };
|
|
1348
|
+
}
|
|
1172
1349
|
return transportFailure("Judge response failed", controller.signal.reason ?? error);
|
|
1173
1350
|
}
|
|
1174
1351
|
} finally {
|
|
@@ -1202,6 +1379,7 @@ async function callJudge(args) {
|
|
|
1202
1379
|
if (result.schemaRejected) schema = false;
|
|
1203
1380
|
result = await attempt(stream, schema, deadline);
|
|
1204
1381
|
}
|
|
1382
|
+
let loops = result.kind === "unavailable" && result.loop ? 1 : 0;
|
|
1205
1383
|
const noVerdict = (r) => r.kind === "completion" && (isTruncated(r.completion) || judgeVerdict(r.completion.text) === void 0);
|
|
1206
1384
|
const retryable = result.kind === "unavailable" && result.retryable;
|
|
1207
1385
|
if (noVerdict(result) || retryable) {
|
|
@@ -1210,6 +1388,7 @@ async function callJudge(args) {
|
|
|
1210
1388
|
await new Promise((resolve5) => setTimeout(resolve5, delay));
|
|
1211
1389
|
const first = result;
|
|
1212
1390
|
result = await attempt(stream, schema, deadline);
|
|
1391
|
+
if (result.kind === "unavailable" && result.loop) loops++;
|
|
1213
1392
|
if (result.kind === "unavailable" && first.kind === "unavailable") {
|
|
1214
1393
|
result = {
|
|
1215
1394
|
...result,
|
|
@@ -1220,17 +1399,25 @@ async function callJudge(args) {
|
|
|
1220
1399
|
}
|
|
1221
1400
|
}
|
|
1222
1401
|
}
|
|
1223
|
-
|
|
1224
|
-
const { text, usage } = result.completion;
|
|
1225
|
-
const judge = {
|
|
1402
|
+
const judgeMetadata = async (completion) => ({
|
|
1226
1403
|
model: args.model,
|
|
1227
1404
|
contract: judgeContractInUse(),
|
|
1228
1405
|
prompt: { system: systemPromptText, user: instructionText },
|
|
1229
|
-
response: text,
|
|
1230
|
-
tokens: parseJudgeUsage(usage),
|
|
1406
|
+
...completion ? { response: completion.text, tokens: parseJudgeUsage(completion.usage) } : {},
|
|
1231
1407
|
latency_ms: Date.now() - startedAt,
|
|
1232
|
-
secondJudge: await secondJudgePromise
|
|
1233
|
-
|
|
1408
|
+
secondJudge: await secondJudgePromise,
|
|
1409
|
+
...loops > 0 ? { reasoning_loops: loops } : {}
|
|
1410
|
+
});
|
|
1411
|
+
if (result.kind === "unavailable" && result.loop) {
|
|
1412
|
+
return {
|
|
1413
|
+
pass: false,
|
|
1414
|
+
reasoning: `Judge reasoning loop \u2014 the judge's stream degenerated into repetition and was cut${loops > 1 ? ", on the retry too" : ""} (${result.error.message}). The verdict is unknown, so this check is recorded as a judge error, not a verdict.`,
|
|
1415
|
+
judge: await judgeMetadata(),
|
|
1416
|
+
unavailable: true
|
|
1417
|
+
};
|
|
1418
|
+
}
|
|
1419
|
+
if (result.kind === "unavailable") throw result.error;
|
|
1420
|
+
const judge = await judgeMetadata(result.completion);
|
|
1234
1421
|
if (isTruncated(result.completion)) {
|
|
1235
1422
|
return {
|
|
1236
1423
|
pass: false,
|
|
@@ -1239,11 +1426,11 @@ async function callJudge(args) {
|
|
|
1239
1426
|
unavailable: true
|
|
1240
1427
|
};
|
|
1241
1428
|
}
|
|
1242
|
-
const verdict = judgeVerdict(text);
|
|
1429
|
+
const verdict = judgeVerdict(result.completion.text);
|
|
1243
1430
|
if (verdict === void 0) {
|
|
1244
1431
|
return {
|
|
1245
1432
|
pass: false,
|
|
1246
|
-
reasoning: "Judge reply carried no verdict (no boolean `pass`)
|
|
1433
|
+
reasoning: "Judge reply carried no verdict (no boolean `pass`). The verdict is unknown, so this check is recorded as a judge error, not a verdict. The raw reply is on the judge metadata.",
|
|
1247
1434
|
judge,
|
|
1248
1435
|
unavailable: true
|
|
1249
1436
|
};
|
|
@@ -1886,10 +2073,15 @@ function buildEvidenceTools(args) {
|
|
|
1886
2073
|
}
|
|
1887
2074
|
const unsupported = rejectUnsupportedPcreConstructs(pattern);
|
|
1888
2075
|
if (unsupported) return { error: unsupported };
|
|
2076
|
+
let translated;
|
|
2077
|
+
try {
|
|
2078
|
+
translated = stripLeadingPcreFlags(pattern);
|
|
2079
|
+
} catch (error) {
|
|
2080
|
+
return { error: `invalid regex: ${error instanceof Error ? error.message : String(error)}` };
|
|
2081
|
+
}
|
|
1889
2082
|
let re;
|
|
1890
2083
|
try {
|
|
1891
|
-
|
|
1892
|
-
re = new RegExp(stripped.pattern, stripped.flags);
|
|
2084
|
+
re = new RegExp(translated.pattern, translated.flags);
|
|
1893
2085
|
} catch (error) {
|
|
1894
2086
|
return {
|
|
1895
2087
|
error: `invalid regex: ${error instanceof Error ? error.message : String(error)} \u2014 patterns compile as case-insensitive multiline; leading PCRE flags like (?i) are stripped automatically`
|
|
@@ -4410,12 +4602,13 @@ function sleep(ms) {
|
|
|
4410
4602
|
|
|
4411
4603
|
// src/agent-task/checks/agent-history.ts
|
|
4412
4604
|
function createBackendReaderFromEnv(env = process.env) {
|
|
4605
|
+
const apiKey = env.APO_API_KEY;
|
|
4413
4606
|
const token = env.APO_AUTH_TOKEN;
|
|
4414
4607
|
const publicKey = env.APO_PUBLIC_KEY;
|
|
4415
4608
|
const secretKey = env.APO_SECRET_KEY;
|
|
4416
|
-
const headers = token ? { Authorization: `Bearer ${token}` } : publicKey && secretKey ? { Authorization: `Basic ${Buffer.from(`${publicKey}:${secretKey}`).toString("base64")}` } : void 0;
|
|
4609
|
+
const headers = apiKey ? { Authorization: `Bearer ${apiKey}` } : token ? { Authorization: `Bearer ${token}` } : publicKey && secretKey ? { Authorization: `Basic ${Buffer.from(`${publicKey}:${secretKey}`).toString("base64")}` } : void 0;
|
|
4417
4610
|
if (!headers) return void 0;
|
|
4418
|
-
const endpoint = env.APO_BACKEND_URL ??
|
|
4611
|
+
const endpoint = env.APO_BACKEND_URL ?? "http://127.0.0.1:8000";
|
|
4419
4612
|
return {
|
|
4420
4613
|
async get(path) {
|
|
4421
4614
|
const res = await fetch(`${endpoint.replace(/\/$/, "")}/v1${path}`, { headers });
|
|
@@ -4429,10 +4622,23 @@ function createBackendReaderFromEnv(env = process.env) {
|
|
|
4429
4622
|
function freezeHistoryPlane(args) {
|
|
4430
4623
|
const { reader, taskId, selfRunId } = args;
|
|
4431
4624
|
const detailCache = /* @__PURE__ */ new Map();
|
|
4625
|
+
const listByTaskId = async (id) => await reader.get(
|
|
4626
|
+
`/agent-task-runs?task_id=${encodeURIComponent(id)}&limit=50`
|
|
4627
|
+
);
|
|
4432
4628
|
const loadRuns = (async () => {
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4629
|
+
let raw = await listByTaskId(taskId);
|
|
4630
|
+
if ((raw ?? []).length === 0 && selfRunId) {
|
|
4631
|
+
try {
|
|
4632
|
+
const self = await reader.get(
|
|
4633
|
+
`/agent-task-runs/${encodeURIComponent(selfRunId)}`
|
|
4634
|
+
);
|
|
4635
|
+
const canonical = self?.task_id;
|
|
4636
|
+
if (typeof canonical === "string" && canonical !== taskId) {
|
|
4637
|
+
raw = await listByTaskId(canonical);
|
|
4638
|
+
}
|
|
4639
|
+
} catch {
|
|
4640
|
+
}
|
|
4641
|
+
}
|
|
4436
4642
|
return (raw ?? []).map(
|
|
4437
4643
|
(r) => ({
|
|
4438
4644
|
id: String(r.id),
|
|
@@ -4496,7 +4702,9 @@ async function freezeHistoryPlaneFromEnv(taskId, env = process.env) {
|
|
|
4496
4702
|
taskId,
|
|
4497
4703
|
...env.AGENT_TASK_RUN_ID ? { selfRunId: env.AGENT_TASK_RUN_ID } : {}
|
|
4498
4704
|
});
|
|
4499
|
-
} catch {
|
|
4705
|
+
} catch (error) {
|
|
4706
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
4707
|
+
console.warn(`apo: judge history plane unavailable \u2014 ${reason}`);
|
|
4500
4708
|
return void 0;
|
|
4501
4709
|
}
|
|
4502
4710
|
}
|
|
@@ -6365,6 +6573,9 @@ function createOtelAgentTaskTraceClient(config) {
|
|
|
6365
6573
|
params.reasoning_tokens
|
|
6366
6574
|
);
|
|
6367
6575
|
}
|
|
6576
|
+
if (params.served_model) {
|
|
6577
|
+
active.span.setAttribute("gen_ai.response.model", params.served_model);
|
|
6578
|
+
}
|
|
6368
6579
|
if (params.status_message) {
|
|
6369
6580
|
active.span.setAttribute("apo.status_message", params.status_message);
|
|
6370
6581
|
}
|