sigrank 0.14.3 → 0.15.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/README.md +4 -0
- package/package.json +1 -1
- package/tools.mjs +136 -0
package/README.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
> **🏆 SigRank is live: [signalaf.com](https://signalaf.com)** — the leaderboard for how
|
|
2
|
+
> efficiently you use AI, not how much. See your projected rank in 60 seconds at
|
|
3
|
+
> [signalaf.com/score](https://signalaf.com/score). *Token counts only. Never your prompts.*
|
|
4
|
+
|
|
1
5
|
<div align="center">
|
|
2
6
|
|
|
3
7
|
<p><img src="./.github/assets/og-card.png" alt="SigRank — the new standard in AI evaluation & benchmarks" width="800"></p>
|
package/package.json
CHANGED
package/tools.mjs
CHANGED
|
@@ -295,6 +295,31 @@ export const TOOLS = [
|
|
|
295
295
|
},
|
|
296
296
|
},
|
|
297
297
|
},
|
|
298
|
+
{
|
|
299
|
+
name: 'simulate_change',
|
|
300
|
+
description:
|
|
301
|
+
"The first PRESCRIPTIVE SigRank tool — 'what if I changed my token mix?' Takes your current 4 pillars (input/output/cacheCreate/cacheRead) and one or more proposed changes, runs the canonical cascade on BOTH the current and simulated values, and returns the exact Υ Yield delta, class change, and per-metric diffs. This is the 'show me the payoff before I do the work' primitive: no network, no submission, pure local math. Use it to answer 'would increasing my cache-read by 50k tokens actually move my class?' before you change your workflow. Accepts the current pillars as JSON or 4 numbers (same as rank_paste) plus a `changes` object with any of the 4 pillar names mapped to new absolute values OR relative deltas (e.g. {cacheRead: '+50000'} or {input: 800000}).",
|
|
302
|
+
inputSchema: {
|
|
303
|
+
type: 'object',
|
|
304
|
+
properties: {
|
|
305
|
+
text: {
|
|
306
|
+
type: 'string',
|
|
307
|
+
description: 'Current token pillars — ccusage JSON or "input output cacheCreate cacheRead" (same format as rank_paste).',
|
|
308
|
+
},
|
|
309
|
+
changes: {
|
|
310
|
+
type: 'object',
|
|
311
|
+
description: 'Proposed changes to apply. Keys: input, output, cacheCreate, cacheRead. Values are either absolute numbers (replace) or strings starting with +/- for relative deltas (add/subtract). Omitted pillars are unchanged.',
|
|
312
|
+
properties: {
|
|
313
|
+
input: { type: ['number', 'string'], description: 'new input token count (absolute) or "+/-N" for a relative delta' },
|
|
314
|
+
output: { type: ['number', 'string'], description: 'new output token count (absolute) or "+/-N" for a relative delta' },
|
|
315
|
+
cacheCreate: { type: ['number', 'string'], description: 'new cache-create token count (absolute) or "+/-N" for a relative delta' },
|
|
316
|
+
cacheRead: { type: ['number', 'string'], description: 'new cache-read token count (absolute) or "+/-N" for a relative delta' },
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
},
|
|
320
|
+
required: ['text', 'changes'],
|
|
321
|
+
},
|
|
322
|
+
},
|
|
298
323
|
]
|
|
299
324
|
|
|
300
325
|
// tokenpull window key → the board's window_type enum.
|
|
@@ -718,5 +743,116 @@ export async function callTool(name, args, opts = {}) {
|
|
|
718
743
|
}
|
|
719
744
|
}
|
|
720
745
|
|
|
746
|
+
if (name === 'simulate_change') {
|
|
747
|
+
// The first prescriptive tool — "what if I changed my token mix?"
|
|
748
|
+
// Pure local math: parse current pillars, apply proposed changes, run the
|
|
749
|
+
// cascade on both, return the delta. No network, no submission.
|
|
750
|
+
if (!args?.text) throw new Error('simulate_change requires a non-empty `text` argument (current pillars).')
|
|
751
|
+
if (typeof args.text === 'string' && args.text.length > MAX_INPUT) {
|
|
752
|
+
return { status: 'error', reason: 'input_too_large', detail: `text exceeds ${MAX_INPUT} chars.` }
|
|
753
|
+
}
|
|
754
|
+
if (!args?.changes || typeof args.changes !== 'object') {
|
|
755
|
+
throw new Error('simulate_change requires a `changes` object with at least one pillar change.')
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
const currentPillars = parsePillars(args.text)
|
|
759
|
+
const current = withParseWarnings(currentPillars, cascade(currentPillars))
|
|
760
|
+
|
|
761
|
+
// Apply changes: each pillar is either an absolute number (replace) or a
|
|
762
|
+
// string starting with +/- (relative delta). Omitted pillars are unchanged.
|
|
763
|
+
const PILLAR_KEYS = ['input', 'output', 'cacheCreate', 'cacheRead']
|
|
764
|
+
const simulated = { ...currentPillars }
|
|
765
|
+
const appliedChanges = {}
|
|
766
|
+
|
|
767
|
+
for (const key of PILLAR_KEYS) {
|
|
768
|
+
if (args.changes[key] == null) continue
|
|
769
|
+
const raw = args.changes[key]
|
|
770
|
+
let newVal
|
|
771
|
+
|
|
772
|
+
if (typeof raw === 'number') {
|
|
773
|
+
newVal = raw
|
|
774
|
+
} else if (typeof raw === 'string') {
|
|
775
|
+
const trimmed = raw.trim()
|
|
776
|
+
if (trimmed.startsWith('+') || trimmed.startsWith('-')) {
|
|
777
|
+
// Relative delta: add/subtract from current value
|
|
778
|
+
const delta = Number(trimmed)
|
|
779
|
+
if (!Number.isFinite(delta)) {
|
|
780
|
+
return { status: 'error', reason: 'invalid_change', detail: `changes.${key}: "${raw}" is not a valid relative delta.` }
|
|
781
|
+
}
|
|
782
|
+
newVal = currentPillars[key] + delta
|
|
783
|
+
} else {
|
|
784
|
+
// Absolute value as a string
|
|
785
|
+
newVal = Number(trimmed)
|
|
786
|
+
}
|
|
787
|
+
} else {
|
|
788
|
+
return { status: 'error', reason: 'invalid_change', detail: `changes.${key}: expected number or string, got ${typeof raw}.` }
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
if (!Number.isFinite(newVal)) {
|
|
792
|
+
return { status: 'error', reason: 'invalid_change', detail: `changes.${key}: result is not a finite number.` }
|
|
793
|
+
}
|
|
794
|
+
// Clamp to non-negative — token counts can't be negative
|
|
795
|
+
if (newVal < 0) {
|
|
796
|
+
return { status: 'error', reason: 'invalid_change', detail: `changes.${key}: result ${newVal} is negative — token counts must be >= 0.` }
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
simulated[key] = newVal
|
|
800
|
+
appliedChanges[key] = {
|
|
801
|
+
from: currentPillars[key],
|
|
802
|
+
to: newVal,
|
|
803
|
+
delta: newVal - currentPillars[key],
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
if (Object.keys(appliedChanges).length === 0) {
|
|
808
|
+
return { status: 'error', reason: 'no_changes', detail: 'No pillar changes specified in the `changes` object.' }
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
const simulatedResult = cascade(simulated)
|
|
812
|
+
|
|
813
|
+
// Compute deltas for every cascade metric
|
|
814
|
+
const metricDelta = (curr, sim) => {
|
|
815
|
+
if (curr == null && sim == null) return null
|
|
816
|
+
if (curr == null) return { from: null, to: sim, delta: null }
|
|
817
|
+
if (sim == null) return { from: curr, to: null, delta: null }
|
|
818
|
+
return { from: curr, to: sim, delta: Number((sim - curr).toFixed(4)) }
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
const classChanged = current.class !== simulatedResult.class
|
|
822
|
+
|
|
823
|
+
return {
|
|
824
|
+
current: {
|
|
825
|
+
pillars: currentPillars,
|
|
826
|
+
yield: current.yield,
|
|
827
|
+
snr: current.snr,
|
|
828
|
+
leverage: current.leverage,
|
|
829
|
+
velocity: current.velocity,
|
|
830
|
+
dev10x: current.dev10x,
|
|
831
|
+
class: current.class,
|
|
832
|
+
},
|
|
833
|
+
simulated: {
|
|
834
|
+
pillars: { input: simulated.input, output: simulated.output, cacheCreate: simulated.cacheCreate, cacheRead: simulated.cacheRead },
|
|
835
|
+
yield: simulatedResult.yield,
|
|
836
|
+
snr: simulatedResult.snr,
|
|
837
|
+
leverage: simulatedResult.leverage,
|
|
838
|
+
velocity: simulatedResult.velocity,
|
|
839
|
+
dev10x: simulatedResult.dev10x,
|
|
840
|
+
class: simulatedResult.class,
|
|
841
|
+
},
|
|
842
|
+
changes: appliedChanges,
|
|
843
|
+
deltas: {
|
|
844
|
+
yield: metricDelta(current.yield, simulatedResult.yield),
|
|
845
|
+
snr: metricDelta(current.snr, simulatedResult.snr),
|
|
846
|
+
leverage: metricDelta(current.leverage, simulatedResult.leverage),
|
|
847
|
+
velocity: metricDelta(current.velocity, simulatedResult.velocity),
|
|
848
|
+
dev10x: metricDelta(current.dev10x, simulatedResult.dev10x),
|
|
849
|
+
},
|
|
850
|
+
class_changed: classChanged,
|
|
851
|
+
...(classChanged ? { class_transition: `${current.class} → ${simulatedResult.class}` } : {}),
|
|
852
|
+
...(simulatedResult.warnings ? { simulated_warnings: simulatedResult.warnings } : {}),
|
|
853
|
+
note: 'Local simulation only — no submission. The actual score depends on server-side RS.xx weights and class thresholds.',
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
|
|
721
857
|
throw new Error(`Unknown tool: ${name}`)
|
|
722
858
|
}
|