@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 +6 -0
- package/dist/types/utils/schema/wire.d.ts +17 -0
- package/package.json +4 -3
- package/src/utils/schema/wire.ts +85 -0
package/CHANGELOG.md
CHANGED
|
@@ -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
|
|
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
|
|
42
|
-
"@oh-my-pi/pi-utils": "16.0
|
|
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"
|
package/src/utils/schema/wire.ts
CHANGED
|
@@ -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
|
+
}
|