@orkestrel/agent 0.0.12 → 0.0.13

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.
@@ -583,6 +583,61 @@ var ConversationManager = class {
583
583
  //#endregion
584
584
  //#region src/core/helpers.ts
585
585
  /**
586
+ * Project an unknown value onto the canonical JSON representation of an
587
+ * {@link AgentResult}.
588
+ *
589
+ * @remarks
590
+ * This is a total hostile-boundary projection. Each structural field is captured once
591
+ * through Contract's sanctioned exception boundary, so conforming accessors and inherited
592
+ * properties are supported while a throwing getter or revoked proxy returns `undefined`.
593
+ * Present usage counts must be finite numbers; negative and fractional values are preserved,
594
+ * not normalized. Extra input properties are dropped while a fresh exact plain object is rebuilt
595
+ * and deep-gated through
596
+ * {@link import('@orkestrel/contract').parseJSONValue}.
597
+ *
598
+ * @param value - The unknown value to project
599
+ * @returns A fresh JSON value containing only AgentResult fields, or `undefined` when invalid
600
+ *
601
+ * @example
602
+ * ```ts
603
+ * import { agentResultToJSON } from '@orkestrel/agent'
604
+ *
605
+ * agentResultToJSON({ content: 'done', usage: { prompt: 2, completion: 1, total: 3 }, partial: false })
606
+ * // { content: 'done', usage: { prompt: 2, completion: 1, total: 3 }, partial: false }
607
+ * ```
608
+ */
609
+ function agentResultToJSON(value) {
610
+ const captured = (0, _orkestrel_contract.attempt)(() => {
611
+ if (!(0, _orkestrel_contract.isObject)(value)) return void 0;
612
+ const content = Reflect.get(value, "content");
613
+ const thinking = Reflect.get(value, "thinking");
614
+ const usage = Reflect.get(value, "usage");
615
+ const partial = Reflect.get(value, "partial");
616
+ if (!(0, _orkestrel_contract.isString)(content) || !(0, _orkestrel_contract.isBoolean)(partial)) return void 0;
617
+ if (thinking !== void 0 && !(0, _orkestrel_contract.isString)(thinking)) return void 0;
618
+ let projectedUsage;
619
+ if (usage !== void 0) {
620
+ if (!(0, _orkestrel_contract.isObject)(usage)) return void 0;
621
+ const prompt = Reflect.get(usage, "prompt");
622
+ const completion = Reflect.get(usage, "completion");
623
+ const total = Reflect.get(usage, "total");
624
+ if (!(0, _orkestrel_contract.isFiniteNumber)(prompt) || !(0, _orkestrel_contract.isFiniteNumber)(completion) || !(0, _orkestrel_contract.isFiniteNumber)(total)) return;
625
+ projectedUsage = {
626
+ prompt,
627
+ completion,
628
+ total
629
+ };
630
+ }
631
+ return {
632
+ content,
633
+ ...thinking === void 0 ? {} : { thinking },
634
+ ...projectedUsage === void 0 ? {} : { usage: projectedUsage },
635
+ partial
636
+ };
637
+ });
638
+ return captured.success ? (0, _orkestrel_contract.parseJSONValue)(captured.value) : void 0;
639
+ }
640
+ /**
586
641
  * Filter a list of items by a {@link import('./types.js').ScopeInterface} allow-list of
587
642
  * keys — the pure, total set-membership primitive the context's build step and the agent
588
643
  * loop's tool-advertise step apply a scope through.
@@ -2771,6 +2826,7 @@ exports.THINK_CLOSE = THINK_CLOSE;
2771
2826
  exports.THINK_OPEN = THINK_OPEN;
2772
2827
  exports.ThinkSplitter = ThinkSplitter;
2773
2828
  exports.WORKSPACE_SECTION_HEADER = WORKSPACE_SECTION_HEADER;
2829
+ exports.agentResultToJSON = agentResultToJSON;
2774
2830
  exports.createAgent = createAgent;
2775
2831
  exports.createAgentContext = createAgentContext;
2776
2832
  exports.createAgentQueue = createAgentQueue;