@deepblend/dsh-blender-tool 0.2.0 → 0.2.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/lib/index.js CHANGED
@@ -78,7 +78,11 @@ export const Config = undefined
78
78
  * rule reachable only through a real render is a rule nobody has checked (the same reasoning
79
79
  * `host/lib/frame-ledger.js` records for `sampleFrame`). `contract/render-job.test.mjs` drives it.
80
80
  */
81
- export { describeJobLines } from './render-tools.js'
81
+ export {
82
+ describeJobLines,
83
+ REFERENCE_SECONDS_PER_FRAME,
84
+ describeRenderCost,
85
+ } from './render-tools.js'
82
86
 
83
87
  /**
84
88
  * The per-review prose block, re-exported for the same reason and with the same narrow scope.
@@ -1,3 +1,32 @@
1
+ /**
2
+ * What one frame of a delivery render costs on the reference machine, in seconds.
3
+ *
4
+ * ONE DEFINITION, because three places quote it: the approval prompt (twice, in the reason and in the
5
+ * refusal) and the tool description the model reads. It was a string in the prompt and a sentence in
6
+ * the description, which is two copies of one measurement.
7
+ */
8
+ export const REFERENCE_SECONDS_PER_FRAME = Object.freeze({ low: 19.6, high: 41.4 })
9
+
10
+ /**
11
+ * A frame count as a duration, in the words a person deciding would use.
12
+ *
13
+ * Deliberately a RANGE and deliberately coarse: the rate is a range measured on one machine, and a
14
+ * single number here would read as a promise. `null` frames is answered with the rate alone rather
15
+ * than a guess — the caller that does not know how many frames it is asking for gets no estimate.
16
+ *
17
+ * @param {number|null|undefined} frames
18
+ * @returns {string}
19
+ */
20
+ export function describeRenderCost(frames) {
21
+ if (!Number.isFinite(frames) || frames <= 0) return 'an unknown amount of machine time'
22
+ const lowMinutes = (frames * REFERENCE_SECONDS_PER_FRAME.low) / 60
23
+ const highMinutes = (frames * REFERENCE_SECONDS_PER_FRAME.high) / 60
24
+ const asDuration = minutes => minutes < 90
25
+ ? `${Math.round(minutes)} minute${Math.round(minutes) === 1 ? '' : 's'}`
26
+ : `${(minutes / 60).toFixed(1)} hours`
27
+ return `${asDuration(lowMinutes)} to ${asDuration(highMinutes)} of machine time`
28
+ }
29
+
1
30
  /**
2
31
  * M3 model-visible tools: the persistent delivery render (SPEC §11, §20 M3).
3
32
  *
@@ -313,8 +342,13 @@ function finalRender(ctx) {
313
342
  ? ` (${cause.detail.frameStart}..${cause.detail.frameEnd})`
314
343
  : ''}${cause.detail?.revision == null ? '' : ` of revision ${cause.detail.revision}`}` +
315
344
  `, above the configured approval threshold of ${cause.detail?.threshold ?? '?'}. ` +
316
- 'Measured cost on the reference machine: 19.6-41.4 s per frame at 1920x1080 / Cycles / 256 ' +
317
- 'samples, so this is hours of machine time.',
345
+ // WHAT IT WILL COST, IN THE UNIT THE PERSON DECIDING THINKS IN. This used to say "so this
346
+ // is hours of machine time" — a true sentence that leaves the reader to do the
347
+ // arithmetic. The rate is the same measured range; the estimate is that rate applied to
348
+ // the number of frames THIS request asked for, which is the number the decision is about
349
+ // (ledger C17: a user should know what they are about to spend before they spend it).
350
+ `Measured cost on the reference machine: ${REFERENCE_SECONDS_PER_FRAME.low}-${REFERENCE_SECONDS_PER_FRAME.high} s per frame ` +
351
+ `at 1920x1080 / Cycles / 256 samples, so this request is about ${describeRenderCost(cause.detail?.frames)}.`,
318
352
  refusal:
319
353
  `Nothing was started — no job, no frames. The request was for ${cause.detail?.frames ?? '?'} ` +
320
354
  `frame(s), above the threshold of ${cause.detail?.threshold ?? '?'}. Options: ask the operator ` +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deepblend/dsh-blender-tool",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "description": "Agent-preset tool consumer: registers the model-visible DeepBlend Blender tools. Publishes no service.",
6
6
  "main": "lib/index.js",
@@ -11,7 +11,7 @@
11
11
  "./package.json": "./package.json"
12
12
  },
13
13
  "dependencies": {
14
- "@deepblend/dsh-blender-contracts": "0.2.0"
14
+ "@deepblend/dsh-blender-contracts": "0.2.2"
15
15
  },
16
16
  "license": "MIT",
17
17
  "repository": {