@oxagen/cli 2.1.4-494 → 2.1.4-495
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/oxagen.mjs +190 -43
- package/package.json +1 -1
package/oxagen.mjs
CHANGED
|
@@ -4839,6 +4839,16 @@ var init_envelope = __esm({
|
|
|
4839
4839
|
]).optional(),
|
|
4840
4840
|
tool_denial_kind: short.optional(),
|
|
4841
4841
|
tool_result_tokens: u32.optional(),
|
|
4842
|
+
/**
|
|
4843
|
+
* How `tool_result_tokens` is known (#5339). `reported` is Claude Code's own
|
|
4844
|
+
* count on its OTel tool span. `estimated` is the recorder's: the result's
|
|
4845
|
+
* UTF-8 bytes over four, from the hook that saw the result. A count with no
|
|
4846
|
+
* basis was written before the member existed, and only the OTel span wrote
|
|
4847
|
+
* a count then, so a reader takes it as `reported`. The recorder writes the
|
|
4848
|
+
* two together. The envelope does not require the pair, so a frame from a
|
|
4849
|
+
* host older than the member still parses.
|
|
4850
|
+
*/
|
|
4851
|
+
tool_result_tokens_basis: external_exports.enum(TOKEN_SOURCE_BASES).optional(),
|
|
4842
4852
|
batch_size: u8.optional(),
|
|
4843
4853
|
batch_index: u8.optional(),
|
|
4844
4854
|
attribution_skill: short.optional(),
|
|
@@ -11529,7 +11539,10 @@ function normalizeHook(raw, env, options) {
|
|
|
11529
11539
|
body2["tool_output_digest"] = digestJcs(
|
|
11530
11540
|
input.tool_response
|
|
11531
11541
|
);
|
|
11532
|
-
|
|
11542
|
+
const bytes = jsonByteLength(input.tool_response);
|
|
11543
|
+
body2["tool_output_bytes"] = bytes;
|
|
11544
|
+
body2["tool_result_tokens"] = Math.ceil(bytes / 4);
|
|
11545
|
+
body2["tool_result_tokens_basis"] = "estimated";
|
|
11533
11546
|
}
|
|
11534
11547
|
if (failed3) {
|
|
11535
11548
|
const error = input.error ?? input["error_type"];
|
|
@@ -14513,7 +14526,24 @@ function steeringFactsOf(steering) {
|
|
|
14513
14526
|
steering_tokens_basis: "estimated"
|
|
14514
14527
|
};
|
|
14515
14528
|
}
|
|
14516
|
-
|
|
14529
|
+
function contextFactsOf(tokens) {
|
|
14530
|
+
if (tokens <= 0) return {};
|
|
14531
|
+
return {
|
|
14532
|
+
context_frame_tokens: tokens,
|
|
14533
|
+
context_frame_tokens_basis: "estimated"
|
|
14534
|
+
};
|
|
14535
|
+
}
|
|
14536
|
+
function injectedMarksOf(value) {
|
|
14537
|
+
if (!Array.isArray(value)) return [];
|
|
14538
|
+
return value.flatMap((mark) => {
|
|
14539
|
+
if (typeof mark !== "object" || mark === null) return [];
|
|
14540
|
+
const { at, tokens } = mark;
|
|
14541
|
+
if (typeof at !== "string" || typeof tokens !== "number") return [];
|
|
14542
|
+
if (!Number.isFinite(tokens)) return [];
|
|
14543
|
+
return [{ at, tokens: clampU32(tokens) }];
|
|
14544
|
+
});
|
|
14545
|
+
}
|
|
14546
|
+
var REQUEST_FULL_DIGEST_ATTR, SYSTEM_CONTEXT_PARTS_OMITTED_ATTR, MEMORY_REQUESTS, LISTED_PER_TURN, INJECTED_MARKS_MAX, U32_MAX, NAME_MAX, tokenSourceFacts, SystemContextMemory, SHARED_SYSTEM_CONTEXT_MEMORY, CONVERSATION_FIELDS2, STEERING_ASSEMBLY_PART, SystemContextTracker;
|
|
14517
14547
|
var init_system_context = __esm({
|
|
14518
14548
|
"../../packages/tacho/src/claude-code/system-context.ts"() {
|
|
14519
14549
|
"use strict";
|
|
@@ -14525,6 +14555,7 @@ var init_system_context = __esm({
|
|
|
14525
14555
|
SYSTEM_CONTEXT_PARTS_OMITTED_ATTR = "oxagen.system_context_parts_omitted";
|
|
14526
14556
|
MEMORY_REQUESTS = 512;
|
|
14527
14557
|
LISTED_PER_TURN = 16;
|
|
14558
|
+
INJECTED_MARKS_MAX = 32;
|
|
14528
14559
|
U32_MAX = 4294967295;
|
|
14529
14560
|
NAME_MAX = 512;
|
|
14530
14561
|
tokenSourceFacts = modelFacts.pick({
|
|
@@ -14581,11 +14612,16 @@ var init_system_context = __esm({
|
|
|
14581
14612
|
this.steering = parts === void 0 ? void 0 : { parts, tokens: state?.steeringTokens ?? sum(parts) };
|
|
14582
14613
|
this.listedTurn = state?.listedTurn;
|
|
14583
14614
|
this.listed = [...state?.listed ?? []];
|
|
14615
|
+
this.injected = injectedMarksOf(state?.injected);
|
|
14616
|
+
const floor = state?.injectedFloor;
|
|
14617
|
+
this.injectedFloor = typeof floor === "number" && Number.isFinite(floor) ? clampU32(floor) : 0;
|
|
14584
14618
|
}
|
|
14585
14619
|
memory;
|
|
14586
14620
|
steering;
|
|
14587
14621
|
listedTurn;
|
|
14588
14622
|
listed;
|
|
14623
|
+
injected;
|
|
14624
|
+
injectedFloor;
|
|
14589
14625
|
state() {
|
|
14590
14626
|
const state = {};
|
|
14591
14627
|
if (this.steering !== void 0) {
|
|
@@ -14594,6 +14630,9 @@ var init_system_context = __esm({
|
|
|
14594
14630
|
}
|
|
14595
14631
|
if (this.listedTurn !== void 0) state.listedTurn = this.listedTurn;
|
|
14596
14632
|
if (this.listed.length > 0) state.listed = [...this.listed];
|
|
14633
|
+
if (this.injected.length > 0)
|
|
14634
|
+
state.injected = this.injected.map((mark) => ({ ...mark }));
|
|
14635
|
+
if (this.injectedFloor > 0) state.injectedFloor = this.injectedFloor;
|
|
14597
14636
|
return state;
|
|
14598
14637
|
}
|
|
14599
14638
|
/** Take the steering a sealed `steering.manifest` frame names. */
|
|
@@ -14601,21 +14640,84 @@ var init_system_context = __esm({
|
|
|
14601
14640
|
const steering = steeringContext(body2);
|
|
14602
14641
|
if (steering !== void 0) this.steering = steering;
|
|
14603
14642
|
}
|
|
14643
|
+
/**
|
|
14644
|
+
* Note text an Oxagen hook answer handed the agent after its start, at
|
|
14645
|
+
* `at`, when the answer left (#5339). The text joins the conversation, so
|
|
14646
|
+
* every call made from `at` on carries it. Empty text notes nothing.
|
|
14647
|
+
*
|
|
14648
|
+
* The caller passes only text the session's own conversation reads. The
|
|
14649
|
+
* start's text is the steering manifest's to count, and a subagent's text
|
|
14650
|
+
* stays in the subagent's conversation.
|
|
14651
|
+
*/
|
|
14652
|
+
noteInjectedContext(text4, at) {
|
|
14653
|
+
const tokens = clampU32(budgetTokens(text4));
|
|
14654
|
+
if (tokens === 0) return;
|
|
14655
|
+
this.markInjected(at, this.injectedTotal() + tokens);
|
|
14656
|
+
}
|
|
14657
|
+
/**
|
|
14658
|
+
* Empty the running total at `at`: a compaction or a `/clear` took the
|
|
14659
|
+
* text out of the conversation. A call made before `at` still reads the
|
|
14660
|
+
* total it was made with.
|
|
14661
|
+
*/
|
|
14662
|
+
clearInjectedContext(at) {
|
|
14663
|
+
if (this.injected.length === 0 && this.injectedFloor === 0) return;
|
|
14664
|
+
this.markInjected(at, 0);
|
|
14665
|
+
}
|
|
14666
|
+
injectedTotal() {
|
|
14667
|
+
return this.injected.at(-1)?.tokens ?? this.injectedFloor;
|
|
14668
|
+
}
|
|
14669
|
+
markInjected(at, tokens) {
|
|
14670
|
+
this.injected.push({ at, tokens: clampU32(tokens) });
|
|
14671
|
+
while (this.injected.length > INJECTED_MARKS_MAX) {
|
|
14672
|
+
const oldest = this.injected.shift();
|
|
14673
|
+
if (oldest !== void 0) this.injectedFloor = oldest.tokens;
|
|
14674
|
+
}
|
|
14675
|
+
}
|
|
14676
|
+
/**
|
|
14677
|
+
* The context Oxagen's hooks had handed the session when a call was made
|
|
14678
|
+
* at `at`: the latest mark at or before it. A record can arrive after
|
|
14679
|
+
* later answers left, since OTel exports in batches and the transcript is
|
|
14680
|
+
* read behind the session. A call with no readable time reads the latest
|
|
14681
|
+
* total. A call older than every mark kept reads the total before them.
|
|
14682
|
+
*/
|
|
14683
|
+
injectedAt(at) {
|
|
14684
|
+
const when = at === void 0 ? Number.NaN : Date.parse(at);
|
|
14685
|
+
if (Number.isNaN(when)) return this.injectedTotal();
|
|
14686
|
+
for (let index = this.injected.length - 1; index >= 0; index -= 1) {
|
|
14687
|
+
const mark = this.injected[index];
|
|
14688
|
+
if (mark === void 0) continue;
|
|
14689
|
+
const markAt = Date.parse(mark.at);
|
|
14690
|
+
if (Number.isNaN(markAt) || markAt <= when) return mark.tokens;
|
|
14691
|
+
}
|
|
14692
|
+
return this.injectedFloor;
|
|
14693
|
+
}
|
|
14604
14694
|
/**
|
|
14605
14695
|
* Measure one model call. `content` is the proxy's exchange body, `attrs`
|
|
14606
|
-
* the frame's attrs,
|
|
14696
|
+
* the frame's attrs, `turn` a key that changes when the turn does, and
|
|
14697
|
+
* `at` when the call was made.
|
|
14607
14698
|
*/
|
|
14608
|
-
measure(content, attrs2, turn) {
|
|
14699
|
+
measure(content, attrs2, turn, at) {
|
|
14609
14700
|
const recorded = requestOf(content);
|
|
14610
14701
|
const resolved = recorded === void 0 ? void 0 : resolveRequest(recorded.request, this.memory);
|
|
14611
14702
|
if (recorded === void 0 || resolved === void 0)
|
|
14612
|
-
return this.checked(
|
|
14613
|
-
|
|
14703
|
+
return this.checked(
|
|
14704
|
+
{
|
|
14705
|
+
...steeringFactsOf(this.steering),
|
|
14706
|
+
...contextFactsOf(this.injectedAt(at))
|
|
14707
|
+
},
|
|
14708
|
+
{},
|
|
14709
|
+
() => {
|
|
14710
|
+
}
|
|
14711
|
+
);
|
|
14614
14712
|
const fullDigest = attrs2?.[REQUEST_FULL_DIGEST_ATTR];
|
|
14615
14713
|
const key = isSha256Digest(fullDigest) ? fullDigest : recorded.request[PRIOR_MEMBER] === void 0 ? digestBytes(recorded.text) : void 0;
|
|
14616
14714
|
if (key !== void 0) this.memory.set(key, resolved);
|
|
14617
|
-
const
|
|
14618
|
-
const
|
|
14715
|
+
const main3 = resolved.tools.length > 0;
|
|
14716
|
+
const steering = main3 ? this.steering : void 0;
|
|
14717
|
+
const facts = {
|
|
14718
|
+
...steeringFactsOf(steering),
|
|
14719
|
+
...main3 ? contextFactsOf(this.injectedAt(at)) : {}
|
|
14720
|
+
};
|
|
14619
14721
|
const parts = [
|
|
14620
14722
|
...resolved.system,
|
|
14621
14723
|
...resolved.instructions,
|
|
@@ -14648,15 +14750,23 @@ var init_system_context = __esm({
|
|
|
14648
14750
|
/**
|
|
14649
14751
|
* The token sources of a model call whose request the recorder never saw:
|
|
14650
14752
|
* the counted OTel or transcript row of a call the proxy did not carry
|
|
14651
|
-
* (#4493).
|
|
14652
|
-
*
|
|
14653
|
-
*
|
|
14654
|
-
*
|
|
14655
|
-
*
|
|
14656
|
-
|
|
14657
|
-
|
|
14658
|
-
|
|
14659
|
-
|
|
14753
|
+
* (#4493). Two counts are known without the request: the steering, from
|
|
14754
|
+
* the manifest, and the context frames, from the hook answers noted before
|
|
14755
|
+
* `at`, when the call was made (#5339). The tool definition count and the
|
|
14756
|
+
* system context stay absent, never zero. Nothing changes on the tracker,
|
|
14757
|
+
* so there is nothing to commit. The caller asks only for a call that
|
|
14758
|
+
* carries the session's conversation, since a side call carries neither.
|
|
14759
|
+
*/
|
|
14760
|
+
measureUnseen(at) {
|
|
14761
|
+
return this.checked(
|
|
14762
|
+
{
|
|
14763
|
+
...steeringFactsOf(this.steering),
|
|
14764
|
+
...contextFactsOf(this.injectedAt(at))
|
|
14765
|
+
},
|
|
14766
|
+
{},
|
|
14767
|
+
() => {
|
|
14768
|
+
}
|
|
14769
|
+
).facts;
|
|
14660
14770
|
}
|
|
14661
14771
|
/**
|
|
14662
14772
|
* Hand back facts the envelope accepts, or none. A body the envelope
|
|
@@ -15296,7 +15406,12 @@ function spanDraft(span, resource) {
|
|
|
15296
15406
|
...s(attrs2, "tool_name") !== void 0 ? { tool_name: s(attrs2, "tool_name") } : {},
|
|
15297
15407
|
...s(attrs2, "tool_use_id") !== void 0 ? { tool_use_id: s(attrs2, "tool_use_id") } : {},
|
|
15298
15408
|
...n(attrs2, "duration_ms") !== void 0 ? { tool_duration_ms: n(attrs2, "duration_ms") } : {},
|
|
15299
|
-
|
|
15409
|
+
// Claude Code's own count, so it is `reported`. A reader prefers it
|
|
15410
|
+
// to the hook's estimate of the same call (#5339).
|
|
15411
|
+
...n(attrs2, "result_tokens") !== void 0 ? {
|
|
15412
|
+
tool_result_tokens: n(attrs2, "result_tokens"),
|
|
15413
|
+
tool_result_tokens_basis: "reported"
|
|
15414
|
+
} : {},
|
|
15300
15415
|
...s(attrs2, "file_path") !== void 0 ? { tool_target: s(attrs2, "file_path") } : {},
|
|
15301
15416
|
...s(attrs2, "full_command") !== void 0 ? { tool_target: (s(attrs2, "full_command") ?? "").slice(0, 512) } : {},
|
|
15302
15417
|
...s(attrs2, "skill_name") !== void 0 ? { attribution_skill: s(attrs2, "skill_name") } : {},
|
|
@@ -16544,16 +16659,18 @@ var init_recorder = __esm({
|
|
|
16544
16659
|
if (kind === "agent_stop") this.turnOpen = false;
|
|
16545
16660
|
const sighting = kind === "llm_call" ? this.llmCallSighting(body2, fields.source ?? "collector") : NO_SIGHTING;
|
|
16546
16661
|
const duplicate = sighting.attrs ?? {};
|
|
16662
|
+
const ts2 = fields.ts ?? this.now();
|
|
16547
16663
|
const measured = kind === "llm_call" ? this.systemContext.measure(
|
|
16548
16664
|
fields.content,
|
|
16549
16665
|
fields.attrs,
|
|
16550
|
-
this.turnOpen ? `turn:${this.turnSeq}` : `idle:${this.turnSeq}
|
|
16666
|
+
this.turnOpen ? `turn:${this.turnSeq}` : `idle:${this.turnSeq}`,
|
|
16667
|
+
ts2
|
|
16551
16668
|
) : void 0;
|
|
16552
16669
|
const event = this.seal(
|
|
16553
16670
|
kind,
|
|
16554
16671
|
measured !== void 0 ? { ...measured.facts, ...body2 } : body2,
|
|
16555
16672
|
{
|
|
16556
|
-
ts:
|
|
16673
|
+
ts: ts2,
|
|
16557
16674
|
source: fields.source ?? "collector",
|
|
16558
16675
|
...fields.hook_event_name !== void 0 ? { hook_event_name: fields.hook_event_name } : {},
|
|
16559
16676
|
attrs: { ...fields.attrs, ...measured?.attrs, ...duplicate },
|
|
@@ -16967,19 +17084,32 @@ var init_recorder = __esm({
|
|
|
16967
17084
|
* recorder knows without the call's request (#4493). Only the counted row,
|
|
16968
17085
|
* the first sighting of its call, takes them. A stamped duplicate is never
|
|
16969
17086
|
* summed, and the rollup joins a stamped proxy row back for the members the
|
|
16970
|
-
* counted row lacks.
|
|
16971
|
-
*
|
|
16972
|
-
*
|
|
16973
|
-
*
|
|
16974
|
-
*
|
|
16975
|
-
*
|
|
16976
|
-
*
|
|
16977
|
-
|
|
16978
|
-
|
|
17087
|
+
* counted row lacks. Two sources are known without the request: the
|
|
17088
|
+
* steering count, and the context frames Oxagen's hooks handed the session
|
|
17089
|
+
* before `ts`, when the call was made (#5339). The tool definitions and the
|
|
17090
|
+
* system context stay absent (ADR-062, amendments of 2026-10-02 and
|
|
17091
|
+
* 2026-10-03). A member the producer set itself wins, as on a proxied call.
|
|
17092
|
+
* Only a call on the session's own conversation comes here: an OTel record
|
|
17093
|
+
* whose `query_source` says so ({@link onSessionConversation}), or a
|
|
17094
|
+
* transcript `assistant` record, since Claude Code writes no side call to
|
|
17095
|
+
* the transcript.
|
|
17096
|
+
*/
|
|
17097
|
+
withUnseenRequestSources(body2, attrs2, ts2) {
|
|
16979
17098
|
if (attrs2[LLM_CALL_DUPLICATE_OF_ATTR] !== void 0) return body2;
|
|
16980
|
-
const facts = this.systemContext.measureUnseen();
|
|
17099
|
+
const facts = this.systemContext.measureUnseen(ts2);
|
|
16981
17100
|
return Object.keys(facts).length === 0 ? body2 : { ...facts, ...body2 };
|
|
16982
17101
|
}
|
|
17102
|
+
/**
|
|
17103
|
+
* Note text an Oxagen hook answer handed this session's agent after its
|
|
17104
|
+
* start, at `at`, when the answer left (#5339). Every model call on the
|
|
17105
|
+
* session's own conversation from then on carries the running total as
|
|
17106
|
+
* `context_frame_tokens`. The hook handler calls this only for a live
|
|
17107
|
+
* answer, since a replay's answer reaches no harness. A rollback of the
|
|
17108
|
+
* chain takes the note back with everything else the hook changed.
|
|
17109
|
+
*/
|
|
17110
|
+
noteInjectedContext(text4, at) {
|
|
17111
|
+
this.systemContext.noteInjectedContext(text4, at);
|
|
17112
|
+
}
|
|
16983
17113
|
/**
|
|
16984
17114
|
* The attrs a `tool_call` carries, or undefined when the chain already
|
|
16985
17115
|
* holds this call and the row must not be sealed at all.
|
|
@@ -17113,6 +17243,9 @@ var init_recorder = __esm({
|
|
|
17113
17243
|
this.started = true;
|
|
17114
17244
|
this.stopped = false;
|
|
17115
17245
|
body2 = { ...body2, env_snapshot: this.envSnapshot };
|
|
17246
|
+
const source = body2["session_start_source"];
|
|
17247
|
+
if (source === "compact" || source === "clear")
|
|
17248
|
+
this.systemContext.clearInjectedContext(ts2);
|
|
17116
17249
|
}
|
|
17117
17250
|
if (draft.kind === "turn_start") {
|
|
17118
17251
|
if (this.turnOpen) {
|
|
@@ -17389,7 +17522,7 @@ var init_recorder = __esm({
|
|
|
17389
17522
|
}
|
|
17390
17523
|
const event = this.seal(
|
|
17391
17524
|
draft.kind,
|
|
17392
|
-
draft.kind === "llm_call" && draft.source === "otel_log" && onSessionConversation(draft.standard.context.query_source) ? this.withUnseenRequestSources(draft.body, duplicate) : draft.body,
|
|
17525
|
+
draft.kind === "llm_call" && draft.source === "otel_log" && onSessionConversation(draft.standard.context.query_source) ? this.withUnseenRequestSources(draft.body, duplicate, draft.ts) : draft.body,
|
|
17393
17526
|
{
|
|
17394
17527
|
ts: draft.ts,
|
|
17395
17528
|
source: draft.source,
|
|
@@ -17472,7 +17605,7 @@ var init_recorder = __esm({
|
|
|
17472
17605
|
duplicate = { [LLM_CALL_DUPLICATE_OF_ATTR]: "transcript" };
|
|
17473
17606
|
}
|
|
17474
17607
|
if (draft.kind === "llm_call")
|
|
17475
|
-
body2 = this.withUnseenRequestSources(body2, duplicate);
|
|
17608
|
+
body2 = this.withUnseenRequestSources(body2, duplicate, draft.ts);
|
|
17476
17609
|
let content = draft.content;
|
|
17477
17610
|
if (this.isSealedPrompt(draft.kind, body2)) {
|
|
17478
17611
|
content = void 0;
|
|
@@ -23364,7 +23497,7 @@ import { readFileSync as readFileSync11 } from "node:fs";
|
|
|
23364
23497
|
import { dirname as dirname8, resolve as resolve2 } from "node:path";
|
|
23365
23498
|
import { fileURLToPath } from "node:url";
|
|
23366
23499
|
function readVersion() {
|
|
23367
|
-
if (true) return "2.1.4-
|
|
23500
|
+
if (true) return "2.1.4-495";
|
|
23368
23501
|
try {
|
|
23369
23502
|
const here = dirname8(fileURLToPath(import.meta.url));
|
|
23370
23503
|
const pkg = JSON.parse(
|
|
@@ -38458,6 +38591,11 @@ function drainMidTurn(input, record, deps, events, replay, used = 0) {
|
|
|
38458
38591
|
if (continuation !== void 0) texts.push(continuation);
|
|
38459
38592
|
return texts;
|
|
38460
38593
|
}
|
|
38594
|
+
function noteHandedContext(record, input, replay, text4, at) {
|
|
38595
|
+
if (replay !== void 0 || input.agent_id !== void 0) return;
|
|
38596
|
+
if (text4.length === 0) return;
|
|
38597
|
+
record.recorder.noteInjectedContext(text4, at);
|
|
38598
|
+
}
|
|
38461
38599
|
function hookLedgerKey(raw, harness, hookId) {
|
|
38462
38600
|
if (hookId !== void 0) return hookId;
|
|
38463
38601
|
if (harness === "stella" || typeof raw !== "object" || raw === null)
|
|
@@ -38760,6 +38898,11 @@ async function routeHook(raw, env, deps, replay, harness, agent, hookId) {
|
|
|
38760
38898
|
) : void 0;
|
|
38761
38899
|
if (block === void 0) record.control.resumeOwed = void 0;
|
|
38762
38900
|
if (block === void 0) notePrompt(record, promptText(input));
|
|
38901
|
+
const handed = [
|
|
38902
|
+
...delivered,
|
|
38903
|
+
...recalled !== void 0 ? [recalled.text] : []
|
|
38904
|
+
];
|
|
38905
|
+
const context = handed.join(CONTEXT_JOINER);
|
|
38763
38906
|
events.push(
|
|
38764
38907
|
...record.recorder.ingestHook(
|
|
38765
38908
|
payload,
|
|
@@ -38767,11 +38910,16 @@ async function routeHook(raw, env, deps, replay, harness, agent, hookId) {
|
|
|
38767
38910
|
at,
|
|
38768
38911
|
(draft) => withReplay({
|
|
38769
38912
|
...draft,
|
|
38770
|
-
...recalled !== void 0 ? {
|
|
38913
|
+
...recalled !== void 0 || handed.length > 0 ? {
|
|
38771
38914
|
attrs: {
|
|
38772
38915
|
...draft.attrs,
|
|
38773
|
-
|
|
38774
|
-
|
|
38916
|
+
...recalled !== void 0 ? {
|
|
38917
|
+
"oxagen.recall_digest": digestText(recalled.text),
|
|
38918
|
+
"oxagen.recalled_memories": String(recalled.count)
|
|
38919
|
+
} : {},
|
|
38920
|
+
// How much text the answer hands the agent, as the start
|
|
38921
|
+
// records it (#5339).
|
|
38922
|
+
...handed.length > 0 ? { "oxagen.delivered_chars": String(context.length) } : {}
|
|
38775
38923
|
}
|
|
38776
38924
|
} : {},
|
|
38777
38925
|
body: {
|
|
@@ -38792,16 +38940,13 @@ async function routeHook(raw, env, deps, replay, harness, agent, hookId) {
|
|
|
38792
38940
|
record
|
|
38793
38941
|
};
|
|
38794
38942
|
}
|
|
38795
|
-
|
|
38796
|
-
...delivered,
|
|
38797
|
-
...recalled !== void 0 ? [recalled.text] : []
|
|
38798
|
-
];
|
|
38943
|
+
noteHandedContext(record, input, replay, context, at);
|
|
38799
38944
|
return {
|
|
38800
38945
|
events,
|
|
38801
|
-
response:
|
|
38946
|
+
response: handed.length > 0 ? {
|
|
38802
38947
|
hookSpecificOutput: {
|
|
38803
38948
|
hookEventName: "UserPromptSubmit",
|
|
38804
|
-
additionalContext: context
|
|
38949
|
+
additionalContext: context
|
|
38805
38950
|
}
|
|
38806
38951
|
} : {},
|
|
38807
38952
|
record
|
|
@@ -39070,6 +39215,7 @@ async function routeHook(raw, env, deps, replay, harness, agent, hookId) {
|
|
|
39070
39215
|
if (operatorBlock(view, record) !== void 0)
|
|
39071
39216
|
return { events, response: {}, record };
|
|
39072
39217
|
const texts = drainMidTurn(input, record, deps, events, replay);
|
|
39218
|
+
noteHandedContext(record, input, replay, texts.join(CONTEXT_JOINER), at);
|
|
39073
39219
|
return {
|
|
39074
39220
|
events,
|
|
39075
39221
|
response: texts.length > 0 ? {
|
|
@@ -39104,6 +39250,7 @@ async function routeHook(raw, env, deps, replay, harness, agent, hookId) {
|
|
|
39104
39250
|
...drainMidTurn(input, record, deps, events, replay, ask?.length ?? 0),
|
|
39105
39251
|
...ask !== void 0 ? [ask] : []
|
|
39106
39252
|
];
|
|
39253
|
+
noteHandedContext(record, input, replay, texts.join(CONTEXT_JOINER), at);
|
|
39107
39254
|
return {
|
|
39108
39255
|
events,
|
|
39109
39256
|
response: texts.length > 0 ? { decision: "block", reason: texts.join(CONTEXT_JOINER) } : {},
|
|
@@ -52121,7 +52268,7 @@ var init_package = __esm({
|
|
|
52121
52268
|
"package.json"() {
|
|
52122
52269
|
package_default = {
|
|
52123
52270
|
name: "@oxagen/cli",
|
|
52124
|
-
version: "2.1.4-
|
|
52271
|
+
version: "2.1.4-495",
|
|
52125
52272
|
description: "Oxagen governance CLI \u2014 spend, lineage, grounding, credentials, and audit (agentic coding lives in the stella CLI)",
|
|
52126
52273
|
type: "module",
|
|
52127
52274
|
main: "./dist/index.js",
|
package/package.json
CHANGED