promptopskit 0.8.0 → 0.8.2
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/SKILL.md +152 -2
- package/dist/cli/index.js +41 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +41 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +41 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/SKILL.md
CHANGED
|
@@ -45,7 +45,9 @@ Behavior:
|
|
|
45
45
|
- Include `provider` and `model` only if they are requested or not supplied by
|
|
46
46
|
a nearby `defaults.md`.
|
|
47
47
|
- Include `sampling`, `reasoning`, `response`, `tools`, `cache`,
|
|
48
|
-
|
|
48
|
+
`provider_options`, or `raw` only when the prompt behavior requires them.
|
|
49
|
+
- Include `compression` only when the prompt or data insertions explicitly need
|
|
50
|
+
opt-in compression or code compaction.
|
|
49
51
|
- Include `context.inputs` for every `{{ variable }}` in the body.
|
|
50
52
|
- Use object-form inputs with `non_empty: true`, `max_size`, `trim`, and
|
|
51
53
|
validation controls when the input is user-provided or unbounded.
|
|
@@ -382,12 +384,13 @@ the fields required by that specific file:
|
|
|
382
384
|
| `reasoning` | object | no | `{ effort: low|medium|high, budget_tokens: number }` |
|
|
383
385
|
| `sampling` | object | no | `{ temperature, top_p, frequency_penalty, presence_penalty, stop, max_output_tokens }` |
|
|
384
386
|
| `response` | object | no | `{ format: text|json|markdown, stream: boolean, schema?: object, schema_name?: string, schema_description?: string, schema_strict?: boolean }` |
|
|
387
|
+
| `compression` | object | no | Prompt-template compression controls: `thetokencompany`, local `heuristic`, or local `code` compaction |
|
|
385
388
|
| `cache` | object | no | Provider-specific cache controls (`openai`, `anthropic`, `gemini`/`google`) |
|
|
386
389
|
| `tools` | array | no | Tool names (strings) or inline definitions with `{ name, description, input_schema }` |
|
|
387
390
|
| `provider_options` | object | no | Provider-specific advanced options (`anthropic`, `gemini`, `openrouter`, `llmasaservice`) |
|
|
388
391
|
| `raw` | object | no | Provider-scoped request-body passthrough for unmodeled vendor fields |
|
|
389
392
|
| `mcp` | object | no | `{ servers: [string | { name, config }] }` |
|
|
390
|
-
| `context.inputs` | `Array<string | { name, optional?, warnings?, max_size?, trim?, allow_regex?, deny_regex?, non_empty?, reject_secrets? }>` | no | Declared variable names used in templates, with optionality, warning controls, size budgets,
|
|
393
|
+
| `context.inputs` | `Array<string | { name, optional?, warnings?, max_size?, trim?, allow_regex?, deny_regex?, non_empty?, reject_secrets?, compression? }>` | no | Declared variable names used in templates, with optionality, warning controls, size budgets, runtime hardening controls, and optional per-input compression |
|
|
391
394
|
| `context.history` | object | no | `{ max_items: number }`; caps rendered history by compacting older turns into one preserved message |
|
|
392
395
|
| `includes` | string[] | no | Relative paths to other prompt files to include |
|
|
393
396
|
| `environments` | object | no | Per-environment overrides (see Overrides) |
|
|
@@ -433,6 +436,9 @@ Rules:
|
|
|
433
436
|
- Escape literal braces with `\{{` and `\}}`
|
|
434
437
|
- In strict mode, missing variables throw an error
|
|
435
438
|
- In permissive mode, unresolved placeholders are left intact
|
|
439
|
+
- Compression modifiers are single-token opt-ins: `{{ text | compress }}`,
|
|
440
|
+
`{{ json_payload | toon }}`, `{{ source_code | compact }}`, or
|
|
441
|
+
`{{ source_code | code }}`
|
|
436
442
|
|
|
437
443
|
Example with a size budget:
|
|
438
444
|
|
|
@@ -451,6 +457,140 @@ If a validator declares `return_message`, `renderPrompt()` returns that message
|
|
|
451
457
|
|
|
452
458
|
Malformed `allow_regex` and `deny_regex` values fail during `validate` and `compile`, not just at render time. When regex compilation fails, the error includes the prompt id, variable name, field name, and raw configured value. Double-quoted YAML regex strings with raw backslashes fail as `POK013`; use `/pattern/i`, single-quoted `pattern: '...'`, or doubled backslashes.
|
|
453
459
|
|
|
460
|
+
### Prompt and data compression
|
|
461
|
+
|
|
462
|
+
Compression is always opt-in. Add it only when a prompt template or a specific
|
|
463
|
+
data insertion is large enough to justify changing the rendered prompt. Do not
|
|
464
|
+
compress system instructions or small inputs by default.
|
|
465
|
+
|
|
466
|
+
Use `compression.thetokencompany` when the rendered `# Prompt template` should
|
|
467
|
+
be compressed by TheTokenCompany before provider request generation:
|
|
468
|
+
|
|
469
|
+
```yaml
|
|
470
|
+
compression:
|
|
471
|
+
thetokencompany:
|
|
472
|
+
enabled: true
|
|
473
|
+
model: bear-2
|
|
474
|
+
aggressiveness: 0.2
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
Runtime callers must pass `theTokenCompany.apiKey` or provide
|
|
478
|
+
`THETOKENCOMPANY_API_KEY`/`TTC_API_KEY`. TheTokenCompany compression is the only
|
|
479
|
+
compression mode that makes a backend call.
|
|
480
|
+
|
|
481
|
+
Use local heuristic compression when the prompt template is prose or natural
|
|
482
|
+
language context and no backend call should be made:
|
|
483
|
+
|
|
484
|
+
```yaml
|
|
485
|
+
compression:
|
|
486
|
+
heuristic:
|
|
487
|
+
enabled: true
|
|
488
|
+
min_tokens: 120
|
|
489
|
+
max_sentences: 8
|
|
490
|
+
target_reduction: 0.45
|
|
491
|
+
query_variable: user_question
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
The heuristic compressor deduplicates text, ranks sentences against `query`,
|
|
495
|
+
`query_variable`, or system instructions, and keeps the highest-scoring
|
|
496
|
+
sentences inside the token budget. It is heuristic, so use it for context where
|
|
497
|
+
extractive reduction is acceptable, not for code or strict structured payloads.
|
|
498
|
+
|
|
499
|
+
Use TOON preprocessing for complete JSON object/array inputs:
|
|
500
|
+
|
|
501
|
+
```yaml
|
|
502
|
+
compression:
|
|
503
|
+
heuristic:
|
|
504
|
+
enabled: true
|
|
505
|
+
json_to_toon: true
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
For one JSON insertion, prefer the placeholder modifier:
|
|
509
|
+
|
|
510
|
+
```markdown
|
|
511
|
+
Payload:
|
|
512
|
+
{{ json_payload | toon }}
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
If `json_to_toon: true` or `{{ value | toon }}` cannot parse a complete JSON
|
|
516
|
+
object or array, PromptOpsKit preserves the original value and returns a
|
|
517
|
+
`POK031` warning instead of sentence-compressing broken JSON.
|
|
518
|
+
|
|
519
|
+
Use code compaction for code. Do not text-compress code:
|
|
520
|
+
|
|
521
|
+
```yaml
|
|
522
|
+
compression:
|
|
523
|
+
code:
|
|
524
|
+
enabled: true
|
|
525
|
+
remove_comments: true
|
|
526
|
+
trim_indentation: true
|
|
527
|
+
collapse_blank_lines: true
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
For one code insertion:
|
|
531
|
+
|
|
532
|
+
```markdown
|
|
533
|
+
Source:
|
|
534
|
+
{{ source_code | compact }}
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
Code compaction removes comments, common indentation, trailing whitespace, and
|
|
538
|
+
blank lines by default. Set `remove_comments: false` when comments carry
|
|
539
|
+
semantics, such as compiler pragmas, generated-code markers, or `@ts-ignore`.
|
|
540
|
+
When prompt-level `compression.code.enabled: true`, PromptOpsKit skips
|
|
541
|
+
TheTokenCompany compression and returns `POK033` so code is not backend
|
|
542
|
+
text-compressed.
|
|
543
|
+
|
|
544
|
+
Context inputs can opt in through schema:
|
|
545
|
+
|
|
546
|
+
```yaml
|
|
547
|
+
context:
|
|
548
|
+
inputs:
|
|
549
|
+
- name: account_context
|
|
550
|
+
compression:
|
|
551
|
+
heuristic:
|
|
552
|
+
enabled: true
|
|
553
|
+
query_variable: user_question
|
|
554
|
+
- name: payload
|
|
555
|
+
compression:
|
|
556
|
+
heuristic:
|
|
557
|
+
enabled: true
|
|
558
|
+
json_to_toon: true
|
|
559
|
+
- name: source_code
|
|
560
|
+
compression: code
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
Or at the placeholder call site:
|
|
564
|
+
|
|
565
|
+
```markdown
|
|
566
|
+
Context: {{ account_context | compress }}
|
|
567
|
+
Payload: {{ payload | toon }}
|
|
568
|
+
Source: {{ source_code | compact }}
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
Placeholder modifiers are single-token shortcuts. Use
|
|
572
|
+
`context.inputs[].compression` when a placeholder needs options such as
|
|
573
|
+
`query_variable`, `json_to_toon`, or `remove_comments: false`.
|
|
574
|
+
|
|
575
|
+
Render results may include:
|
|
576
|
+
|
|
577
|
+
```typescript
|
|
578
|
+
result.compression; // per-step details
|
|
579
|
+
result.compressionSummary; // operation-level aggregate
|
|
580
|
+
result.warnings; // includes POK031/POK032/POK033 compression warnings
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
Treat `compressionSummary.tokensSaved` as an operation-level aggregate across
|
|
584
|
+
all compression and compaction steps, not a guaranteed net request-token delta.
|
|
585
|
+
Use `result.compression` for the per-placeholder or per-provider breakdown.
|
|
586
|
+
|
|
587
|
+
Credit the source projects when documenting compression: the local
|
|
588
|
+
token-compression approach is based on Jason Kneen's
|
|
589
|
+
[open-thetokenco](https://github.com/jasonkneen/open-thetokenco/tree/main).
|
|
590
|
+
TOON preprocessing uses a local encode-only implementation inspired by the
|
|
591
|
+
MIT-licensed [TOON project](https://github.com/toon-format/toon) by Johann
|
|
592
|
+
Schopplich.
|
|
593
|
+
|
|
454
594
|
### Conversation history limits
|
|
455
595
|
|
|
456
596
|
Use `context.history.max_items` when a chat-style prompt should bound rendered conversation history:
|
|
@@ -716,6 +856,14 @@ if (!result.request) {
|
|
|
716
856
|
}
|
|
717
857
|
|
|
718
858
|
const { request } = result;
|
|
859
|
+
|
|
860
|
+
if (result.compressionSummary) {
|
|
861
|
+
console.log('Compression savings:', result.compressionSummary.tokensSaved);
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
for (const warning of result.warnings) {
|
|
865
|
+
console.warn(warning);
|
|
866
|
+
}
|
|
719
867
|
```
|
|
720
868
|
|
|
721
869
|
### Use `adapter.renderPrompt()` when:
|
|
@@ -904,3 +1052,5 @@ Hello {{ name }}
|
|
|
904
1052
|
9. **Validate before compile and compile before shipping** when prompts are part of the build
|
|
905
1053
|
10. **Variable names** should be `snake_case`
|
|
906
1054
|
11. **Prompt file names** should be `kebab-case.md`
|
|
1055
|
+
12. **Compression must stay opt-in** through `compression` config or placeholder modifiers
|
|
1056
|
+
13. **Use TOON for complete JSON payloads** and code compaction for code; do not text-compress code
|
package/dist/cli/index.js
CHANGED
|
@@ -1122,6 +1122,7 @@ var RISKY_UNBOUNDED_INPUT_NAMES = [
|
|
|
1122
1122
|
"body",
|
|
1123
1123
|
"context"
|
|
1124
1124
|
];
|
|
1125
|
+
var COMPRESS_MODIFIER_RE = /\{\{\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*\|\s*compress\s*\}\}/g;
|
|
1125
1126
|
function validateAsset(asset, frontMatterKeys, filePath) {
|
|
1126
1127
|
const errors = [];
|
|
1127
1128
|
const warnings = [];
|
|
@@ -1203,6 +1204,26 @@ function validateAsset(asset, frontMatterKeys, filePath) {
|
|
|
1203
1204
|
suggestion: "Declare context.inputs to enable input policy validation."
|
|
1204
1205
|
});
|
|
1205
1206
|
}
|
|
1207
|
+
if (asset.compression?.heuristic?.enabled === true && asset.compression.heuristic.json_to_toon !== true) {
|
|
1208
|
+
warnings.push({
|
|
1209
|
+
code: "POK055",
|
|
1210
|
+
message: "Prompt-level heuristic compression is enabled for the full prompt template.",
|
|
1211
|
+
filePath,
|
|
1212
|
+
suggestion: "Prefer per-placeholder compression for bulky context values so instructions, output constraints, and safety conditions are not sentence-selected away."
|
|
1213
|
+
});
|
|
1214
|
+
}
|
|
1215
|
+
const systemHeuristicCompressionVariables = findSystemHeuristicCompressionVariables(
|
|
1216
|
+
asset.sections?.system_instructions,
|
|
1217
|
+
declaredInputsByName
|
|
1218
|
+
);
|
|
1219
|
+
if (systemHeuristicCompressionVariables.length > 0) {
|
|
1220
|
+
warnings.push({
|
|
1221
|
+
code: "POK056",
|
|
1222
|
+
message: `System instructions use heuristic compression for ${formatQuotedList(systemHeuristicCompressionVariables)}.`,
|
|
1223
|
+
filePath,
|
|
1224
|
+
suggestion: "Avoid compressing values inside system instructions; move lossy compression to prompt-template context placeholders when possible."
|
|
1225
|
+
});
|
|
1226
|
+
}
|
|
1206
1227
|
for (const input of contextInputs) {
|
|
1207
1228
|
const lowerName = input.name.toLowerCase();
|
|
1208
1229
|
const inputWarningsEnabled = areContextInputWarningsEnabled(input);
|
|
@@ -1394,6 +1415,26 @@ function findClosestMatch(input, candidates) {
|
|
|
1394
1415
|
}
|
|
1395
1416
|
return best;
|
|
1396
1417
|
}
|
|
1418
|
+
function findSystemHeuristicCompressionVariables(systemInstructions, declaredInputsByName) {
|
|
1419
|
+
if (!systemInstructions) {
|
|
1420
|
+
return [];
|
|
1421
|
+
}
|
|
1422
|
+
const variables = /* @__PURE__ */ new Set();
|
|
1423
|
+
for (const match of systemInstructions.matchAll(COMPRESS_MODIFIER_RE)) {
|
|
1424
|
+
variables.add(match[1]);
|
|
1425
|
+
}
|
|
1426
|
+
for (const variable of extractVariables(systemInstructions)) {
|
|
1427
|
+
const input = declaredInputsByName.get(variable);
|
|
1428
|
+
const heuristic = input?.compression?.heuristic;
|
|
1429
|
+
if (heuristic?.enabled === true && heuristic.json_to_toon !== true) {
|
|
1430
|
+
variables.add(variable);
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
return [...variables].sort();
|
|
1434
|
+
}
|
|
1435
|
+
function formatQuotedList(values) {
|
|
1436
|
+
return values.map((value) => `"${value}"`).join(", ");
|
|
1437
|
+
}
|
|
1397
1438
|
function isRecord(value) {
|
|
1398
1439
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1399
1440
|
}
|