@oh-my-pi/pi-ai 16.0.10 → 16.1.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/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [16.1.0] - 2026-06-19
6
+
7
+ ### Added
8
+
9
+ - Added utility functions to strip schema descriptions for optimized LLM context usage
10
+
5
11
  ## [16.0.10] - 2026-06-18
6
12
 
7
13
  ### Added
@@ -73,3 +73,20 @@ export declare function arkToWireSchema(schema: Type): Record<string, unknown>;
73
73
  * schema-valued positions and nullable scalar unions.
74
74
  */
75
75
  export declare function toolWireSchema(tool: Tool): Record<string, unknown>;
76
+ /**
77
+ * Return a deep clone of `schema` with every `description` annotation removed.
78
+ * The result is memoized on the input via a non-enumerable symbol (`stamp`) so
79
+ * repeated provider requests reuse the same stripped object; the input is never
80
+ * mutated, so the stamped `toolWireSchema` cache stays intact for
81
+ * system-prompt/UI rendering.
82
+ */
83
+ export declare function stripSchemaDescriptions(schema: Record<string, unknown>): Record<string, unknown>;
84
+ /**
85
+ * Strip a tool's human-readable text from its provider-bound spec: empties the
86
+ * top-level `description` and removes nested schema `description` annotations.
87
+ * Used when the full tool catalog is rendered into the system prompt instead, so
88
+ * the descriptions ride the wire once (in the prompt) rather than duplicated on
89
+ * every tool definition. Parameters are resolved to wire JSON Schema and cloned,
90
+ * leaving the original tool objects and the stamped schema cache untouched.
91
+ */
92
+ export declare function stripToolDescriptions(tools: readonly Tool[]): Tool[];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/pi-ai",
4
- "version": "16.0.10",
4
+ "version": "16.1.0",
5
5
  "description": "Unified LLM API with automatic model discovery and provider configuration",
6
6
  "homepage": "https://omp.sh",
7
7
  "author": "Can Boluk",
@@ -38,8 +38,9 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "@bufbuild/protobuf": "^2.12.0",
41
- "@oh-my-pi/pi-catalog": "16.0.10",
42
- "@oh-my-pi/pi-utils": "16.0.10",
41
+ "@oh-my-pi/pi-catalog": "16.1.0",
42
+ "@oh-my-pi/pi-utils": "16.1.0",
43
+ "@oh-my-pi/pi-wire": "16.1.0",
43
44
  "arktype": "^2.2.0",
44
45
  "partial-json": "^0.1.7",
45
46
  "zod": "^4"
@@ -152,6 +152,7 @@ function arkJsonAstToWire(value: unknown): unknown {
152
152
  const kZodWireSchema = Symbol("pi.schema.zod.wire");
153
153
  const kJsonWireSchema = Symbol("pi.schema.json.wire");
154
154
  const kArkWireSchema = Symbol("pi.schema.ark.wire");
155
+ const kStrippedSchema = Symbol("pi.schema.descriptions.stripped");
155
156
 
156
157
  /**
157
158
  * Post-process Zod-emitted JSON Schema so it matches the wire shape providers
@@ -634,3 +635,87 @@ export function toolWireSchema(tool: Tool): Record<string, unknown> {
634
635
  return postProcessJsonSchema(upgraded);
635
636
  });
636
637
  }
638
+
639
+ /**
640
+ * Schema-valued keywords whose value is a single subschema (or an array of
641
+ * subschemas — the recursion dispatches on array-ness, so tuple forms like
642
+ * draft-07 `items: []` are handled too). Covers the draft 2020-12 surface plus
643
+ * the legacy `additionalItems` that may survive an incomplete upgrade.
644
+ */
645
+ const STRIP_SCHEMA_VALUE_KEYS = [
646
+ "additionalProperties",
647
+ "unevaluatedProperties",
648
+ "unevaluatedItems",
649
+ "items",
650
+ "additionalItems",
651
+ "contains",
652
+ "propertyNames",
653
+ "contentSchema",
654
+ "if",
655
+ "then",
656
+ "else",
657
+ "not",
658
+ "anyOf",
659
+ "oneOf",
660
+ "allOf",
661
+ "prefixItems",
662
+ ] as const;
663
+
664
+ /** Keywords whose value is a `{ name: Schema }` map — names are NOT annotations. */
665
+ const STRIP_SCHEMA_MAP_KEYS = ["properties", "patternProperties", "$defs", "definitions", "dependentSchemas"] as const;
666
+
667
+ /**
668
+ * Recursively strip human-readable `description` annotations from a JSON Schema,
669
+ * descending only through schema-valued keywords so a property literally named
670
+ * `"description"` inside a `properties`/`$defs` map keeps its schema (only its own
671
+ * annotation is dropped), and data-bearing keywords (`default`/`const`/`examples`)
672
+ * are never traversed. Mutates `node` in place — callers pass a clone.
673
+ */
674
+ function stripSchemaDescriptionsInPlace(node: unknown): void {
675
+ if (Array.isArray(node)) {
676
+ for (const child of node) stripSchemaDescriptionsInPlace(child);
677
+ return;
678
+ }
679
+ if (!isSchemaRecord(node)) return;
680
+ delete node.description;
681
+ for (const key of STRIP_SCHEMA_VALUE_KEYS) {
682
+ if (Object.hasOwn(node, key)) stripSchemaDescriptionsInPlace(node[key]);
683
+ }
684
+ for (const mapKey of STRIP_SCHEMA_MAP_KEYS) {
685
+ const map = node[mapKey];
686
+ if (isSchemaRecord(map)) {
687
+ for (const key in map) stripSchemaDescriptionsInPlace(map[key]);
688
+ }
689
+ }
690
+ }
691
+
692
+ /**
693
+ * Return a deep clone of `schema` with every `description` annotation removed.
694
+ * The result is memoized on the input via a non-enumerable symbol (`stamp`) so
695
+ * repeated provider requests reuse the same stripped object; the input is never
696
+ * mutated, so the stamped `toolWireSchema` cache stays intact for
697
+ * system-prompt/UI rendering.
698
+ */
699
+ export function stripSchemaDescriptions(schema: Record<string, unknown>): Record<string, unknown> {
700
+ return stamp(schema, kStrippedSchema, source => {
701
+ const clone = structuredClone(source);
702
+ stripSchemaDescriptionsInPlace(clone);
703
+ return clone;
704
+ });
705
+ }
706
+
707
+ /**
708
+ * Strip a tool's human-readable text from its provider-bound spec: empties the
709
+ * top-level `description` and removes nested schema `description` annotations.
710
+ * Used when the full tool catalog is rendered into the system prompt instead, so
711
+ * the descriptions ride the wire once (in the prompt) rather than duplicated on
712
+ * every tool definition. Parameters are resolved to wire JSON Schema and cloned,
713
+ * leaving the original tool objects and the stamped schema cache untouched.
714
+ */
715
+ export function stripToolDescriptions(tools: readonly Tool[]): Tool[] {
716
+ return tools.map(tool => ({
717
+ ...tool,
718
+ description: "",
719
+ parameters: stripSchemaDescriptions(toolWireSchema(tool)),
720
+ }));
721
+ }