prompt-identifiers-baml 0.1.0 → 0.1.1
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/README.md +55 -47
- package/dist/index.d.mts +33 -3
- package/dist/index.d.ts +33 -3
- package/dist/index.js +48 -10
- package/dist/index.mjs +48 -10
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -11,24 +11,22 @@ npm install prompt-identifiers-baml prompt-identifiers @boundaryml/baml
|
|
|
11
11
|
## Quick Start
|
|
12
12
|
|
|
13
13
|
```typescript
|
|
14
|
-
import { wrapBamlFunction } from
|
|
15
|
-
import { b } from
|
|
14
|
+
import { wrapBamlFunction } from "prompt-identifiers-baml";
|
|
15
|
+
import { b } from "./baml_client";
|
|
16
16
|
|
|
17
17
|
// Wrap your BAML function
|
|
18
18
|
const analyzeUser = wrapBamlFunction(b.AnalyzeUser, {
|
|
19
|
-
config: { inputFormat:
|
|
19
|
+
config: { inputFormat: "UUID", outputFormat: "SafeNumeric" },
|
|
20
20
|
});
|
|
21
21
|
|
|
22
22
|
// Use normally - IDs are automatically encoded/decoded
|
|
23
23
|
const result = await analyzeUser({
|
|
24
|
-
user_id:
|
|
25
|
-
items: [
|
|
26
|
-
{ id: '987fcdeb-51a2-43f7-8d9c-0123456789ab', name: 'Order 1' },
|
|
27
|
-
],
|
|
24
|
+
user_id: "123e4567-e89b-42d3-a456-426655440000",
|
|
25
|
+
items: [{ id: "987fcdeb-51a2-43f7-8d9c-0123456789ab", name: "Order 1" }],
|
|
28
26
|
});
|
|
29
27
|
|
|
30
28
|
// The BAML function receives:
|
|
31
|
-
// { user_id: '
|
|
29
|
+
// { user_id: '~000~', items: [{ id: '~001~', name: 'Order 1' }] }
|
|
32
30
|
//
|
|
33
31
|
// You receive the response with original UUIDs restored
|
|
34
32
|
```
|
|
@@ -36,10 +34,10 @@ const result = await analyzeUser({
|
|
|
36
34
|
## How It Works
|
|
37
35
|
|
|
38
36
|
1. **Before BAML call**: Deep traverses input object and encodes all ID fields
|
|
39
|
-
- `123e4567-e89b-42d3-a456-426655440000` →
|
|
37
|
+
- `123e4567-e89b-42d3-a456-426655440000` → `~000~`
|
|
40
38
|
|
|
41
39
|
2. **After BAML call**: Deep traverses output object and decodes all placeholders
|
|
42
|
-
-
|
|
40
|
+
- `~000~` → `123e4567-e89b-42d3-a456-426655440000`
|
|
43
41
|
|
|
44
42
|
This is completely transparent - you work with real IDs, the LLM works with compact placeholders.
|
|
45
43
|
|
|
@@ -49,21 +47,29 @@ This is completely transparent - you work with real IDs, the LLM works with comp
|
|
|
49
47
|
wrapBamlFunction(fn, {
|
|
50
48
|
// Required: encoding configuration
|
|
51
49
|
config: {
|
|
52
|
-
inputFormat:
|
|
53
|
-
outputFormat:
|
|
50
|
+
inputFormat: "UUID", // or 'ULID' or custom RegExp
|
|
51
|
+
outputFormat: "SafeNumeric", // or 'Numeric', 'IdToken', { template: '...' }
|
|
54
52
|
},
|
|
55
53
|
|
|
56
54
|
// Optional: specify which fields to encode
|
|
57
55
|
// If not provided, all matching strings are encoded
|
|
58
|
-
encodeFields: [
|
|
56
|
+
encodeFields: ["user_id", "items[].id", "metadata.owner_id"],
|
|
57
|
+
|
|
58
|
+
// Optional: enable debug mode for detailed diagnostics
|
|
59
|
+
debug: true,
|
|
59
60
|
|
|
60
61
|
// Optional: callbacks for logging/debugging
|
|
61
62
|
onEncode: (result) => {
|
|
62
|
-
console.log(
|
|
63
|
-
|
|
63
|
+
console.log("Mapping:", result.mapping);
|
|
64
|
+
// debugData is only present when debug: true
|
|
65
|
+
if (result.debugData) {
|
|
66
|
+
console.log(`Encoded ${result.debugData.encodedCount} IDs in ${result.debugData.durationMs}ms`);
|
|
67
|
+
}
|
|
64
68
|
},
|
|
65
69
|
onDecode: (result) => {
|
|
66
|
-
|
|
70
|
+
if (result.debugData) {
|
|
71
|
+
console.log(`Decoded ${result.debugData.decodedCount} placeholders in ${result.debugData.durationMs}ms`);
|
|
72
|
+
}
|
|
67
73
|
},
|
|
68
74
|
});
|
|
69
75
|
```
|
|
@@ -72,40 +78,40 @@ wrapBamlFunction(fn, {
|
|
|
72
78
|
|
|
73
79
|
The `encodeFields` option supports dot notation and array wildcards:
|
|
74
80
|
|
|
75
|
-
| Pattern
|
|
76
|
-
|
|
77
|
-
| `user_id`
|
|
78
|
-
| `data.user_id`
|
|
79
|
-
| `items[].id`
|
|
80
|
-
| `data.users[].profile.id` | Deep nested
|
|
81
|
+
| Pattern | Description | Example Match |
|
|
82
|
+
| ------------------------- | ---------------- | --------------------------------------------------- |
|
|
83
|
+
| `user_id` | Top-level field | `{ user_id: '...' }` |
|
|
84
|
+
| `data.user_id` | Nested field | `{ data: { user_id: '...' } }` |
|
|
85
|
+
| `items[].id` | Array item field | `{ items: [{ id: '...' }] }` |
|
|
86
|
+
| `data.users[].profile.id` | Deep nested | `{ data: { users: [{ profile: { id: '...' } }] } }` |
|
|
81
87
|
|
|
82
88
|
### Input Formats
|
|
83
89
|
|
|
84
|
-
| Format
|
|
85
|
-
|
|
86
|
-
| `'UUID'` | RFC 4122 UUIDs
|
|
87
|
-
| `'ULID'` | Crockford Base32 ULIDs | `01ARZ3NDEKTSV4RRFFQ69G5FAV`
|
|
88
|
-
| `RegExp` | Custom pattern
|
|
90
|
+
| Format | Description | Example |
|
|
91
|
+
| -------- | ---------------------- | -------------------------------------- |
|
|
92
|
+
| `'UUID'` | RFC 4122 UUIDs | `123e4567-e89b-42d3-a456-426655440000` |
|
|
93
|
+
| `'ULID'` | Crockford Base32 ULIDs | `01ARZ3NDEKTSV4RRFFQ69G5FAV` |
|
|
94
|
+
| `RegExp` | Custom pattern | `/user-\d{6}/gi` |
|
|
89
95
|
|
|
90
96
|
### Output Formats
|
|
91
97
|
|
|
92
|
-
| Format
|
|
93
|
-
|
|
94
|
-
| `'SafeNumeric'`
|
|
95
|
-
| `'Numeric'`
|
|
96
|
-
| `'IdToken'`
|
|
97
|
-
| `{ template: '...' }` | Custom template
|
|
98
|
+
| Format | Description | Example |
|
|
99
|
+
| --------------------- | ------------------------------------------------- | ------------------------------------- |
|
|
100
|
+
| `'SafeNumeric'` | Collision-safe with tildes (recommended) | `~000~`, `~001~` |
|
|
101
|
+
| `'Numeric'` | Simple numeric with smart triplet expansion | `000`, `001` |
|
|
102
|
+
| `'IdToken'` | Base62 encoding | `0`, `A`, `z`, `10` |
|
|
103
|
+
| `{ template: '...' }` | Custom template | `{ template: '[ID:{i}]' }` → `[ID:0]` |
|
|
98
104
|
|
|
99
105
|
## Streaming Support
|
|
100
106
|
|
|
101
107
|
Use `wrapBamlStreamingFunction` for BAML streaming functions:
|
|
102
108
|
|
|
103
109
|
```typescript
|
|
104
|
-
import { wrapBamlStreamingFunction } from
|
|
105
|
-
import { b } from
|
|
110
|
+
import { wrapBamlStreamingFunction } from "prompt-identifiers-baml";
|
|
111
|
+
import { b } from "./baml_client";
|
|
106
112
|
|
|
107
113
|
const streamAnalysis = wrapBamlStreamingFunction(b.stream.AnalyzeUser, {
|
|
108
|
-
config: { inputFormat:
|
|
114
|
+
config: { inputFormat: "UUID", outputFormat: "SafeNumeric" },
|
|
109
115
|
});
|
|
110
116
|
|
|
111
117
|
// IDs are decoded in real-time as partials arrive
|
|
@@ -121,15 +127,15 @@ for await (const partial of streamAnalysis({ user_id: uuid })) {
|
|
|
121
127
|
Manually encode an object (useful for custom integrations):
|
|
122
128
|
|
|
123
129
|
```typescript
|
|
124
|
-
import { encodeObject } from
|
|
130
|
+
import { encodeObject } from "prompt-identifiers-baml";
|
|
125
131
|
|
|
126
132
|
const { encoded, mapping } = encodeObject(
|
|
127
|
-
{ user_id:
|
|
128
|
-
{ inputFormat:
|
|
133
|
+
{ user_id: "uuid-here", data: { owner: "other-uuid" } },
|
|
134
|
+
{ inputFormat: "UUID", outputFormat: "SafeNumeric" }
|
|
129
135
|
);
|
|
130
136
|
|
|
131
|
-
// encoded: { user_id: '
|
|
132
|
-
// mapping: { '
|
|
137
|
+
// encoded: { user_id: '~000~', data: { owner: '~001~' } }
|
|
138
|
+
// mapping: { '~000~': 'uuid-here', '~001~': 'other-uuid' }
|
|
133
139
|
```
|
|
134
140
|
|
|
135
141
|
### decodeObject
|
|
@@ -137,11 +143,11 @@ const { encoded, mapping } = encodeObject(
|
|
|
137
143
|
Manually decode an object:
|
|
138
144
|
|
|
139
145
|
```typescript
|
|
140
|
-
import { decodeObject } from
|
|
146
|
+
import { decodeObject } from "prompt-identifiers-baml";
|
|
141
147
|
|
|
142
148
|
const decoded = decodeObject(
|
|
143
|
-
{ user_id:
|
|
144
|
-
{
|
|
149
|
+
{ user_id: "~000~", summary: "User ~000~ is active" },
|
|
150
|
+
{ "~000~": "uuid-here" }
|
|
145
151
|
);
|
|
146
152
|
|
|
147
153
|
// decoded: { user_id: 'uuid-here', summary: 'User uuid-here is active' }
|
|
@@ -165,11 +171,13 @@ const result: AnalyzeUserOutput = await analyzeUser({
|
|
|
165
171
|
## Auto-Detection vs Explicit Fields
|
|
166
172
|
|
|
167
173
|
**Auto-detection mode** (no `encodeFields`):
|
|
174
|
+
|
|
168
175
|
- Encodes ALL string fields matching the input pattern
|
|
169
176
|
- Simple to use, works for most cases
|
|
170
177
|
- May encode fields you don't want encoded
|
|
171
178
|
|
|
172
179
|
**Explicit fields** (with `encodeFields`):
|
|
180
|
+
|
|
173
181
|
- Only encodes specified fields
|
|
174
182
|
- More precise control
|
|
175
183
|
- Recommended for production use
|
|
@@ -177,13 +185,13 @@ const result: AnalyzeUserOutput = await analyzeUser({
|
|
|
177
185
|
```typescript
|
|
178
186
|
// Auto-detection: all UUIDs encoded
|
|
179
187
|
const wrapped1 = wrapBamlFunction(fn, {
|
|
180
|
-
config: { inputFormat:
|
|
188
|
+
config: { inputFormat: "UUID", outputFormat: "SafeNumeric" },
|
|
181
189
|
});
|
|
182
190
|
|
|
183
191
|
// Explicit: only user_id and item IDs encoded
|
|
184
192
|
const wrapped2 = wrapBamlFunction(fn, {
|
|
185
|
-
config: { inputFormat:
|
|
186
|
-
encodeFields: [
|
|
193
|
+
config: { inputFormat: "UUID", outputFormat: "SafeNumeric" },
|
|
194
|
+
encodeFields: ["user_id", "items[].id"],
|
|
187
195
|
});
|
|
188
196
|
```
|
|
189
197
|
|
package/dist/index.d.mts
CHANGED
|
@@ -7,6 +7,28 @@ import { EncodeConfig } from 'prompt-identifiers';
|
|
|
7
7
|
* in inputs and decode them in outputs.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
/** Debug data included in onEncode callback when debug is true */
|
|
11
|
+
interface EncodeDebugData {
|
|
12
|
+
/** Number of unique IDs encoded */
|
|
13
|
+
encodedCount: number;
|
|
14
|
+
/** Original input object before encoding */
|
|
15
|
+
input: unknown;
|
|
16
|
+
/** Encoded input object */
|
|
17
|
+
output: unknown;
|
|
18
|
+
/** Time spent encoding in milliseconds */
|
|
19
|
+
durationMs: number;
|
|
20
|
+
}
|
|
21
|
+
/** Debug data included in onDecode callback when debug is true */
|
|
22
|
+
interface DecodeDebugData {
|
|
23
|
+
/** Number of fields containing decoded placeholders */
|
|
24
|
+
decodedCount: number;
|
|
25
|
+
/** Raw output from LLM (encoded) */
|
|
26
|
+
input: unknown;
|
|
27
|
+
/** Decoded output with original IDs restored */
|
|
28
|
+
output: unknown;
|
|
29
|
+
/** Time spent decoding in milliseconds */
|
|
30
|
+
durationMs: number;
|
|
31
|
+
}
|
|
10
32
|
/** Configuration options for the BAML wrapper */
|
|
11
33
|
interface WrapBamlFunctionOptions {
|
|
12
34
|
/** Encoding configuration (inputFormat and outputFormat) */
|
|
@@ -25,18 +47,26 @@ interface WrapBamlFunctionOptions {
|
|
|
25
47
|
* encodeFields: ['user_id', 'items[].id', 'metadata.owner_id']
|
|
26
48
|
*/
|
|
27
49
|
encodeFields?: string[];
|
|
50
|
+
/**
|
|
51
|
+
* Enable debug mode to populate debugData in callbacks with
|
|
52
|
+
* input/output snapshots, counts, and timing information.
|
|
53
|
+
*/
|
|
54
|
+
debug?: boolean;
|
|
28
55
|
/**
|
|
29
56
|
* Optional callback fired after encoding IDs in the input.
|
|
57
|
+
* Receives the placeholder→ID mapping. When debug is true,
|
|
58
|
+
* also receives debugData with input, output, counts, and timing.
|
|
30
59
|
*/
|
|
31
60
|
onEncode?: (result: {
|
|
32
61
|
mapping: Record<string, string>;
|
|
33
|
-
|
|
62
|
+
debugData?: EncodeDebugData;
|
|
34
63
|
}) => void;
|
|
35
64
|
/**
|
|
36
65
|
* Optional callback fired after decoding IDs in the output.
|
|
66
|
+
* When debug is true, receives debugData with input, output, counts, and timing.
|
|
37
67
|
*/
|
|
38
68
|
onDecode?: (result: {
|
|
39
|
-
|
|
69
|
+
debugData?: DecodeDebugData;
|
|
40
70
|
}) => void;
|
|
41
71
|
}
|
|
42
72
|
/** A BAML function type (sync or async) */
|
|
@@ -111,4 +141,4 @@ declare function encodeObject<T>(obj: T, config: EncodeConfig, encodeFields?: st
|
|
|
111
141
|
*/
|
|
112
142
|
declare function decodeObject<T>(obj: T, mapping: Record<string, string>): T;
|
|
113
143
|
|
|
114
|
-
export { type BamlFunction, type BamlStreamingFunction, type WrapBamlFunctionOptions, decodeObject, encodeObject, wrapBamlFunction, wrapBamlStreamingFunction };
|
|
144
|
+
export { type BamlFunction, type BamlStreamingFunction, type DecodeDebugData, type EncodeDebugData, type WrapBamlFunctionOptions, decodeObject, encodeObject, wrapBamlFunction, wrapBamlStreamingFunction };
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,28 @@ import { EncodeConfig } from 'prompt-identifiers';
|
|
|
7
7
|
* in inputs and decode them in outputs.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
/** Debug data included in onEncode callback when debug is true */
|
|
11
|
+
interface EncodeDebugData {
|
|
12
|
+
/** Number of unique IDs encoded */
|
|
13
|
+
encodedCount: number;
|
|
14
|
+
/** Original input object before encoding */
|
|
15
|
+
input: unknown;
|
|
16
|
+
/** Encoded input object */
|
|
17
|
+
output: unknown;
|
|
18
|
+
/** Time spent encoding in milliseconds */
|
|
19
|
+
durationMs: number;
|
|
20
|
+
}
|
|
21
|
+
/** Debug data included in onDecode callback when debug is true */
|
|
22
|
+
interface DecodeDebugData {
|
|
23
|
+
/** Number of fields containing decoded placeholders */
|
|
24
|
+
decodedCount: number;
|
|
25
|
+
/** Raw output from LLM (encoded) */
|
|
26
|
+
input: unknown;
|
|
27
|
+
/** Decoded output with original IDs restored */
|
|
28
|
+
output: unknown;
|
|
29
|
+
/** Time spent decoding in milliseconds */
|
|
30
|
+
durationMs: number;
|
|
31
|
+
}
|
|
10
32
|
/** Configuration options for the BAML wrapper */
|
|
11
33
|
interface WrapBamlFunctionOptions {
|
|
12
34
|
/** Encoding configuration (inputFormat and outputFormat) */
|
|
@@ -25,18 +47,26 @@ interface WrapBamlFunctionOptions {
|
|
|
25
47
|
* encodeFields: ['user_id', 'items[].id', 'metadata.owner_id']
|
|
26
48
|
*/
|
|
27
49
|
encodeFields?: string[];
|
|
50
|
+
/**
|
|
51
|
+
* Enable debug mode to populate debugData in callbacks with
|
|
52
|
+
* input/output snapshots, counts, and timing information.
|
|
53
|
+
*/
|
|
54
|
+
debug?: boolean;
|
|
28
55
|
/**
|
|
29
56
|
* Optional callback fired after encoding IDs in the input.
|
|
57
|
+
* Receives the placeholder→ID mapping. When debug is true,
|
|
58
|
+
* also receives debugData with input, output, counts, and timing.
|
|
30
59
|
*/
|
|
31
60
|
onEncode?: (result: {
|
|
32
61
|
mapping: Record<string, string>;
|
|
33
|
-
|
|
62
|
+
debugData?: EncodeDebugData;
|
|
34
63
|
}) => void;
|
|
35
64
|
/**
|
|
36
65
|
* Optional callback fired after decoding IDs in the output.
|
|
66
|
+
* When debug is true, receives debugData with input, output, counts, and timing.
|
|
37
67
|
*/
|
|
38
68
|
onDecode?: (result: {
|
|
39
|
-
|
|
69
|
+
debugData?: DecodeDebugData;
|
|
40
70
|
}) => void;
|
|
41
71
|
}
|
|
42
72
|
/** A BAML function type (sync or async) */
|
|
@@ -111,4 +141,4 @@ declare function encodeObject<T>(obj: T, config: EncodeConfig, encodeFields?: st
|
|
|
111
141
|
*/
|
|
112
142
|
declare function decodeObject<T>(obj: T, mapping: Record<string, string>): T;
|
|
113
143
|
|
|
114
|
-
export { type BamlFunction, type BamlStreamingFunction, type WrapBamlFunctionOptions, decodeObject, encodeObject, wrapBamlFunction, wrapBamlStreamingFunction };
|
|
144
|
+
export { type BamlFunction, type BamlStreamingFunction, type DecodeDebugData, type EncodeDebugData, type WrapBamlFunctionOptions, decodeObject, encodeObject, wrapBamlFunction, wrapBamlStreamingFunction };
|
package/dist/index.js
CHANGED
|
@@ -84,7 +84,7 @@ function formatPlaceholder(outputFormat, index) {
|
|
|
84
84
|
if (outputFormat === "SafeNumeric") {
|
|
85
85
|
const s = index.toString();
|
|
86
86
|
const width = Math.max(3, Math.ceil(s.length / 3) * 3);
|
|
87
|
-
return
|
|
87
|
+
return `~${s.padStart(width, "0")}~`;
|
|
88
88
|
}
|
|
89
89
|
if (outputFormat === "Numeric") {
|
|
90
90
|
const s = index.toString();
|
|
@@ -170,9 +170,7 @@ function deepEncode(value, ctx, path = []) {
|
|
|
170
170
|
return encodeStringWithContext(value, ctx);
|
|
171
171
|
}
|
|
172
172
|
if (Array.isArray(value)) {
|
|
173
|
-
return value.map(
|
|
174
|
-
(item, index) => deepEncode(item, ctx, [...path, String(index)])
|
|
175
|
-
);
|
|
173
|
+
return value.map((item, index) => deepEncode(item, ctx, [...path, String(index)]));
|
|
176
174
|
}
|
|
177
175
|
if (typeof value === "object") {
|
|
178
176
|
const result = {};
|
|
@@ -207,7 +205,7 @@ function deepDecode(value, mapping, countRef) {
|
|
|
207
205
|
return value;
|
|
208
206
|
}
|
|
209
207
|
function wrapBamlFunction(fn, options) {
|
|
210
|
-
const { config, encodeFields, onEncode, onDecode } = options;
|
|
208
|
+
const { config, encodeFields, onEncode, onDecode, debug } = options;
|
|
211
209
|
const fieldPaths = encodeFields ? encodeFields.map(parseFieldPath) : null;
|
|
212
210
|
return async (input) => {
|
|
213
211
|
const ctx = {
|
|
@@ -217,20 +215,40 @@ function wrapBamlFunction(fn, options) {
|
|
|
217
215
|
mapping: {},
|
|
218
216
|
nextIndex: 0
|
|
219
217
|
};
|
|
218
|
+
const startEncode = debug ? performance.now() : 0;
|
|
220
219
|
const encodedInput = deepEncode(input, ctx);
|
|
220
|
+
const encodeDurationMs = debug ? performance.now() - startEncode : 0;
|
|
221
221
|
onEncode?.({
|
|
222
222
|
mapping: ctx.mapping,
|
|
223
|
-
|
|
223
|
+
...debug && {
|
|
224
|
+
debugData: {
|
|
225
|
+
encodedCount: Object.keys(ctx.mapping).length,
|
|
226
|
+
input,
|
|
227
|
+
output: encodedInput,
|
|
228
|
+
durationMs: encodeDurationMs
|
|
229
|
+
}
|
|
230
|
+
}
|
|
224
231
|
});
|
|
225
232
|
const output = await fn(encodedInput);
|
|
226
233
|
const countRef = { count: 0 };
|
|
234
|
+
const startDecode = debug ? performance.now() : 0;
|
|
227
235
|
const decodedOutput = deepDecode(output, ctx.mapping, countRef);
|
|
228
|
-
|
|
236
|
+
const decodeDurationMs = debug ? performance.now() - startDecode : 0;
|
|
237
|
+
onDecode?.({
|
|
238
|
+
...debug && {
|
|
239
|
+
debugData: {
|
|
240
|
+
decodedCount: countRef.count,
|
|
241
|
+
input: output,
|
|
242
|
+
output: decodedOutput,
|
|
243
|
+
durationMs: decodeDurationMs
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
});
|
|
229
247
|
return decodedOutput;
|
|
230
248
|
};
|
|
231
249
|
}
|
|
232
250
|
function wrapBamlStreamingFunction(fn, options) {
|
|
233
|
-
const { config, encodeFields, onEncode, onDecode } = options;
|
|
251
|
+
const { config, encodeFields, onEncode, onDecode, debug } = options;
|
|
234
252
|
const fieldPaths = encodeFields ? encodeFields.map(parseFieldPath) : null;
|
|
235
253
|
return async function* (input) {
|
|
236
254
|
const ctx = {
|
|
@@ -240,20 +258,40 @@ function wrapBamlStreamingFunction(fn, options) {
|
|
|
240
258
|
mapping: {},
|
|
241
259
|
nextIndex: 0
|
|
242
260
|
};
|
|
261
|
+
const startEncode = debug ? performance.now() : 0;
|
|
243
262
|
const encodedInput = deepEncode(input, ctx);
|
|
263
|
+
const encodeDurationMs = debug ? performance.now() - startEncode : 0;
|
|
244
264
|
onEncode?.({
|
|
245
265
|
mapping: ctx.mapping,
|
|
246
|
-
|
|
266
|
+
...debug && {
|
|
267
|
+
debugData: {
|
|
268
|
+
encodedCount: Object.keys(ctx.mapping).length,
|
|
269
|
+
input,
|
|
270
|
+
output: encodedInput,
|
|
271
|
+
durationMs: encodeDurationMs
|
|
272
|
+
}
|
|
273
|
+
}
|
|
247
274
|
});
|
|
248
275
|
const generator = fn(encodedInput);
|
|
249
276
|
let totalDecoded = 0;
|
|
277
|
+
const startDecode = debug ? performance.now() : 0;
|
|
250
278
|
while (true) {
|
|
251
279
|
const { value, done } = await generator.next();
|
|
252
280
|
if (done) {
|
|
253
281
|
const countRef2 = { count: 0 };
|
|
254
282
|
const decodedValue2 = deepDecode(value, ctx.mapping, countRef2);
|
|
255
283
|
totalDecoded += countRef2.count;
|
|
256
|
-
|
|
284
|
+
const decodeDurationMs = debug ? performance.now() - startDecode : 0;
|
|
285
|
+
onDecode?.({
|
|
286
|
+
...debug && {
|
|
287
|
+
debugData: {
|
|
288
|
+
decodedCount: totalDecoded,
|
|
289
|
+
input: value,
|
|
290
|
+
output: decodedValue2,
|
|
291
|
+
durationMs: decodeDurationMs
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
});
|
|
257
295
|
return decodedValue2;
|
|
258
296
|
}
|
|
259
297
|
const countRef = { count: 0 };
|
package/dist/index.mjs
CHANGED
|
@@ -57,7 +57,7 @@ function formatPlaceholder(outputFormat, index) {
|
|
|
57
57
|
if (outputFormat === "SafeNumeric") {
|
|
58
58
|
const s = index.toString();
|
|
59
59
|
const width = Math.max(3, Math.ceil(s.length / 3) * 3);
|
|
60
|
-
return
|
|
60
|
+
return `~${s.padStart(width, "0")}~`;
|
|
61
61
|
}
|
|
62
62
|
if (outputFormat === "Numeric") {
|
|
63
63
|
const s = index.toString();
|
|
@@ -143,9 +143,7 @@ function deepEncode(value, ctx, path = []) {
|
|
|
143
143
|
return encodeStringWithContext(value, ctx);
|
|
144
144
|
}
|
|
145
145
|
if (Array.isArray(value)) {
|
|
146
|
-
return value.map(
|
|
147
|
-
(item, index) => deepEncode(item, ctx, [...path, String(index)])
|
|
148
|
-
);
|
|
146
|
+
return value.map((item, index) => deepEncode(item, ctx, [...path, String(index)]));
|
|
149
147
|
}
|
|
150
148
|
if (typeof value === "object") {
|
|
151
149
|
const result = {};
|
|
@@ -180,7 +178,7 @@ function deepDecode(value, mapping, countRef) {
|
|
|
180
178
|
return value;
|
|
181
179
|
}
|
|
182
180
|
function wrapBamlFunction(fn, options) {
|
|
183
|
-
const { config, encodeFields, onEncode, onDecode } = options;
|
|
181
|
+
const { config, encodeFields, onEncode, onDecode, debug } = options;
|
|
184
182
|
const fieldPaths = encodeFields ? encodeFields.map(parseFieldPath) : null;
|
|
185
183
|
return async (input) => {
|
|
186
184
|
const ctx = {
|
|
@@ -190,20 +188,40 @@ function wrapBamlFunction(fn, options) {
|
|
|
190
188
|
mapping: {},
|
|
191
189
|
nextIndex: 0
|
|
192
190
|
};
|
|
191
|
+
const startEncode = debug ? performance.now() : 0;
|
|
193
192
|
const encodedInput = deepEncode(input, ctx);
|
|
193
|
+
const encodeDurationMs = debug ? performance.now() - startEncode : 0;
|
|
194
194
|
onEncode?.({
|
|
195
195
|
mapping: ctx.mapping,
|
|
196
|
-
|
|
196
|
+
...debug && {
|
|
197
|
+
debugData: {
|
|
198
|
+
encodedCount: Object.keys(ctx.mapping).length,
|
|
199
|
+
input,
|
|
200
|
+
output: encodedInput,
|
|
201
|
+
durationMs: encodeDurationMs
|
|
202
|
+
}
|
|
203
|
+
}
|
|
197
204
|
});
|
|
198
205
|
const output = await fn(encodedInput);
|
|
199
206
|
const countRef = { count: 0 };
|
|
207
|
+
const startDecode = debug ? performance.now() : 0;
|
|
200
208
|
const decodedOutput = deepDecode(output, ctx.mapping, countRef);
|
|
201
|
-
|
|
209
|
+
const decodeDurationMs = debug ? performance.now() - startDecode : 0;
|
|
210
|
+
onDecode?.({
|
|
211
|
+
...debug && {
|
|
212
|
+
debugData: {
|
|
213
|
+
decodedCount: countRef.count,
|
|
214
|
+
input: output,
|
|
215
|
+
output: decodedOutput,
|
|
216
|
+
durationMs: decodeDurationMs
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
});
|
|
202
220
|
return decodedOutput;
|
|
203
221
|
};
|
|
204
222
|
}
|
|
205
223
|
function wrapBamlStreamingFunction(fn, options) {
|
|
206
|
-
const { config, encodeFields, onEncode, onDecode } = options;
|
|
224
|
+
const { config, encodeFields, onEncode, onDecode, debug } = options;
|
|
207
225
|
const fieldPaths = encodeFields ? encodeFields.map(parseFieldPath) : null;
|
|
208
226
|
return async function* (input) {
|
|
209
227
|
const ctx = {
|
|
@@ -213,20 +231,40 @@ function wrapBamlStreamingFunction(fn, options) {
|
|
|
213
231
|
mapping: {},
|
|
214
232
|
nextIndex: 0
|
|
215
233
|
};
|
|
234
|
+
const startEncode = debug ? performance.now() : 0;
|
|
216
235
|
const encodedInput = deepEncode(input, ctx);
|
|
236
|
+
const encodeDurationMs = debug ? performance.now() - startEncode : 0;
|
|
217
237
|
onEncode?.({
|
|
218
238
|
mapping: ctx.mapping,
|
|
219
|
-
|
|
239
|
+
...debug && {
|
|
240
|
+
debugData: {
|
|
241
|
+
encodedCount: Object.keys(ctx.mapping).length,
|
|
242
|
+
input,
|
|
243
|
+
output: encodedInput,
|
|
244
|
+
durationMs: encodeDurationMs
|
|
245
|
+
}
|
|
246
|
+
}
|
|
220
247
|
});
|
|
221
248
|
const generator = fn(encodedInput);
|
|
222
249
|
let totalDecoded = 0;
|
|
250
|
+
const startDecode = debug ? performance.now() : 0;
|
|
223
251
|
while (true) {
|
|
224
252
|
const { value, done } = await generator.next();
|
|
225
253
|
if (done) {
|
|
226
254
|
const countRef2 = { count: 0 };
|
|
227
255
|
const decodedValue2 = deepDecode(value, ctx.mapping, countRef2);
|
|
228
256
|
totalDecoded += countRef2.count;
|
|
229
|
-
|
|
257
|
+
const decodeDurationMs = debug ? performance.now() - startDecode : 0;
|
|
258
|
+
onDecode?.({
|
|
259
|
+
...debug && {
|
|
260
|
+
debugData: {
|
|
261
|
+
decodedCount: totalDecoded,
|
|
262
|
+
input: value,
|
|
263
|
+
output: decodedValue2,
|
|
264
|
+
durationMs: decodeDurationMs
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
});
|
|
230
268
|
return decodedValue2;
|
|
231
269
|
}
|
|
232
270
|
const countRef = { count: 0 };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prompt-identifiers-baml",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "BAML integration for prompt-identifiers. Efficient ID compression for token optimization.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"ts-jest": "^29.0.0",
|
|
55
55
|
"tsup": "^8.5.1",
|
|
56
56
|
"typescript": "^5.0.0",
|
|
57
|
-
"prompt-identifiers": "0.1.
|
|
57
|
+
"prompt-identifiers": "0.1.1"
|
|
58
58
|
},
|
|
59
59
|
"scripts": {
|
|
60
60
|
"build": "tsup src/index.ts --format cjs,esm --dts --clean",
|