craterview 0.4.24 → 0.4.27

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.
Files changed (3) hide show
  1. package/README.md +6 -6
  2. package/index.ts +46 -30
  3. package/package.json +4 -4
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # craterview
2
2
 
3
- TypeScript client for the [CraterView](https://craterview.ai) image enhancement and
3
+ TypeScript client for the [CraterView.ai](https://craterview.ai) image enhancement and
4
4
  restoration API.
5
5
 
6
6
  ```bash
@@ -45,7 +45,7 @@ reimplement.
45
45
  Build against `echo` first. It costs no credits, needs no GPU and returns a real result — a
46
46
  plain upscale — so the request, the parameters and the response are the ones a paid model
47
47
  gives, and your integration needs no change when you switch. When you are ready, swap the
48
- model name for the one you want.
48
+ model id for the one you want.
49
49
 
50
50
  ```ts
51
51
  const job = await cv.run(file, {
@@ -57,7 +57,7 @@ const job = await cv.run(file, {
57
57
  const blob = await job.blob();
58
58
  ```
59
59
 
60
- A parameter one model publishes is not one another accepts — `cv.models()` says which — and
60
+ A parameter one model publishes is not necessarily one another accepts — `cv.models()` says which — and
61
61
  a value a model does not publish is refused at submit rather than ignored.
62
62
 
63
63
  ## An API key
@@ -109,7 +109,7 @@ a presigned URL and `blob()` GETs the result the same way; the API moves keys, n
109
109
 
110
110
  ## Retries are yours to write
111
111
 
112
- **Outside `run()` and `waitFor()`, this client does not retry.** `run()` asks its submission
112
+ **Outside `run()` and `waitFor()`, this client does not retry.** `run()` sends its submission
113
113
  once more, under one idempotency key, when the first got no answer or a failure on the
114
114
  platform's side, and `waitFor()` reads on through the same until its timeout; neither can make a
115
115
  second job. Every other call is sent once. That is deliberate: only the caller knows where one
@@ -327,7 +327,7 @@ to storage and have five minutes.
327
327
  ## From Claude Code
328
328
 
329
329
  This repository is also a Claude Code marketplace. Two plugins: `craterview` connects
330
- CraterView's hosted tools so the assistant enhances images in the conversation, and
330
+ CraterView.ai's hosted tools so the assistant enhances images in the conversation, and
331
331
  `craterview-api` teaches an agent to call the API from code with this client. See
332
332
  [`plugins/`](plugins/) for what each does and how it finds a key.
333
333
 
@@ -340,7 +340,7 @@ CraterView's hosted tools so the assistant enhances images in the conversation,
340
340
  ## Versioning
341
341
 
342
342
  Semver, from `0.1.0` on. A release that removes an exported member, renames a field on `Job`
343
- or `ModelInfo`, or changes the type of one, gets a minor bump while this is `0.x` and a major
343
+ or `ModelInfo`, or changes the type of one gets a minor bump while this is `0.x` and a major
344
344
  bump after `1.0.0`; anything purely additive gets a patch. Pin what you depend on.
345
345
 
346
346
  The API this wraps adds fields to its responses without warning, so treat an unfamiliar key in
package/index.ts CHANGED
@@ -18,7 +18,7 @@ import { imageSize } from "image-size";
18
18
  // Mirrored from package.json, which is the number a release bumps. It cannot be imported
19
19
  // from there — this ships as TypeScript, so the import would have to resolve in the
20
20
  // consumer's toolchain — so test/version.test.ts asserts the two agree.
21
- export const VERSION = "0.4.24";
21
+ export const VERSION = "0.4.27";
22
22
  const DEFAULT_BASE_URL = "https://api.craterview.ai";
23
23
  // The server rejects a longer wait outright, so asking for one costs a 422 rather than the
24
24
  // wait you asked for. `run()` clamps to this rather than letting that happen.
@@ -336,11 +336,19 @@ function timingSafeEqual(a: string, b: string): boolean {
336
336
  * with `JobData` — there is no wrapper class here because there is no behavior to add.
337
337
  */
338
338
  export interface ModelInfo {
339
- /** The public name, and what you pass as `model` when submitting. */
340
- name: string;
341
- version: string;
339
+ /** What you pass as `model` when submitting. Not for showing to a person; that is `title`. */
340
+ id: string;
341
+ /**
342
+ * Which revision of this model is in service. It changes when the same input gives a
343
+ * different result, while the id stays the same; record it to explain an old result later.
344
+ */
345
+ revision: string;
346
+ /** What to call this model when talking to a person. */
342
347
  title: string;
348
+ /** What this model is for and when to choose it over another; for a program or an agent. */
343
349
  description: string;
350
+ /** What this model does, in one short line for a person choosing it in an app. */
351
+ help: string;
344
352
  accepts: string[];
345
353
  /**
346
354
  * The media type a result usually comes back as, and advisory: a model that keeps the
@@ -365,6 +373,12 @@ export interface ModelInfo {
365
373
  * utility or fun experiment.
366
374
  */
367
375
  tenure?: "fixed" | "comet";
376
+ /**
377
+ * Whether this is a model for testing an integration rather than for use: free, and it
378
+ * returns a result of the right size without improving the picture. `echo` is one.
379
+ * CraterView's apps do not offer it; an app built on this catalog should leave it out too.
380
+ */
381
+ test_model?: boolean;
368
382
  max_input_bytes: number;
369
383
  /**
370
384
  * The ceilings **your key** is held to, not the model's widest. Community work is bounded
@@ -372,16 +386,16 @@ export interface ModelInfo {
372
386
  * before uploading rather than learning them from a rejected job.
373
387
  *
374
388
  * `max_frame_megapixels` bounds one frame you send, and applies to images too since a
375
- * still is one frame. `max_frames` bounds how many frames one job may carry. Zero means
376
- * that axis is unbounded for you.
389
+ * still is one frame. `max_frames` bounds how many frames one job may carry. Null means
390
+ * nothing bounds that axis for you; a limit is never 0.
377
391
  *
378
392
  * For a duration, divide: `max_frames / reference_fps` is the longest clip you may send, in
379
393
  * seconds. It is not published as its own field on purpose — one limit with two spellings
380
394
  * is one that can disagree with itself, and frames are what the platform counts, enforces
381
395
  * and bills on.
382
396
  */
383
- max_frame_megapixels: number;
384
- max_frames: number;
397
+ max_frame_megapixels: number | null;
398
+ max_frames: number | null;
385
399
  /**
386
400
  * The largest frame you may get **back**, in megapixels, and for a model that enlarges it
387
401
  * is the ceiling that decides whether a job runs: what returns is the frame you send
@@ -392,42 +406,36 @@ export interface ModelInfo {
392
406
  *
393
407
  * ```ts
394
408
  * const result = megapixels * scale ** 2;
395
- * if (model.max_output_megapixels && result > model.max_output_megapixels) {
409
+ * if (model.max_output_megapixels !== null && result > model.max_output_megapixels) {
396
410
  * // send a smaller region of the image, or ask for less enlargement
397
411
  * }
398
412
  * ```
399
413
  *
400
414
  * Sending a smaller region keeps every pixel of what it covers; asking for less
401
- * enlargement keeps the whole picture. Zero means this axis is unbounded for you.
415
+ * enlargement keeps the whole picture. Null means nothing bounds it for you.
402
416
  */
403
- max_output_megapixels: number;
417
+ max_output_megapixels: number | null;
404
418
  /**
405
- * The most of a picture this model works on in one job, in megapixels: the region you
419
+ * The most of a picture one job may work on for you, in megapixels: the region you
406
420
  * name with `roi`, or the whole image. Where it is set it binds at every enlargement, so
407
421
  * the largest frame you may send is the smaller of this and `max_output_megapixels`
408
422
  * divided by the square of the enlargement — and asking for less enlargement does not
409
- * help with it, where a smaller region does. Zero means this axis is unbounded for you.
410
- */
411
- max_input_megapixels: number;
412
- /**
413
- * The most of a picture this model works on in one job with `denoise` sent as true, in
414
- * megapixels; `max_input_megapixels` applies otherwise. Null for a model that takes no
415
- * `denoise`. Zero means this axis is unbounded for you.
423
+ * help with it, where a smaller region does. Null means nothing bounds it for you.
416
424
  */
417
- max_denoise_input_megapixels?: number | null;
425
+ max_input_megapixels: number | null;
418
426
  /**
419
- * The most of a picture this model works on in one job with `tiled` sent as true, in
420
- * megapixels: the region you name with `roi`, or the whole image, worked on at its own
421
- * resolution and returned at its own size. Without `tiled`, a larger picture is reduced
422
- * rather than refused: see `working_megapixels`. Null for a model that takes no `tiled`.
427
+ * The most of a picture one job may work on for you at each `binning` value, in megapixels,
428
+ * keyed by the value ("2x2", "3x3", ...); `max_input_megapixels` applies with binning off.
429
+ * Each is `max_output_megapixels` divided by the square of the largest scale that binning
430
+ * allows. Null for a model that takes no `binning`, or when nothing bounds it for you.
423
431
  */
424
- max_tiled_input_megapixels?: number | null;
432
+ max_input_megapixels_by_binning?: Record<string, number> | null;
425
433
  /**
426
- * The most this model works on at a picture's own resolution, in megapixels: a larger
427
- * picture or region is reduced to about this area first and comes back at about this size,
428
- * unless `tiled` is sent as true. Null for a model that works at the size it is given.
434
+ * The shortest side, in pixels, of the part of a picture this model works on: the region
435
+ * you name with `roi`, or the whole image. A job with a shorter one fails before the model
436
+ * runs, as `input_too_small`, and is not charged. The same for every key.
429
437
  */
430
- working_megapixels?: number | null;
438
+ min_input_side: number;
431
439
  /** Whole credits. The price is flat and knowable before you send anything. */
432
440
  credits_per_image: number;
433
441
  /** Whole credits. Null means this model takes stills only. */
@@ -439,6 +447,12 @@ export interface ModelInfo {
439
447
  * not order an object's keys, so a form drawn from the schema reads its order from here.
440
448
  */
441
449
  params_order: string[];
450
+ /**
451
+ * A short line for a person choosing each setting in a form, keyed by parameter name: every
452
+ * parameter in `params_schema` that one control can set. Show it under the control. For what
453
+ * a value may be and what may be sent together, read `params_schema`.
454
+ */
455
+ params_help: Record<string, string>;
442
456
  /**
443
457
  * JSON Schema for the fields a finished job of this model states under `result`, beside
444
458
  * any files it links. Empty for a model whose whole answer is its file.
@@ -1023,7 +1037,9 @@ export class CraterView {
1023
1037
  * charged when it succeeds, so queued and running work is not in the figures yet, and a
1024
1038
  * failed job costs nothing.
1025
1039
  *
1026
- * `credits_remaining` is always a number, floored at zero. A balance of zero never stops a
1040
+ * The balance is `credits_remaining`; `credits_spent` is what the account has spent, all
1041
+ * time, and `credits_granted` what it has been given. `credits_remaining` is always a
1042
+ * number, floored at zero. A balance of zero never stops a
1027
1043
  * submission: `community` says whether your next job runs on the community queue, which is
1028
1044
  * free and can wait longer at busy times, or on paid compute. `jobs_in_flight` and
1029
1045
  * `max_jobs_in_flight` are the state of the queue and are what a 429 on submit is about.
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "craterview",
3
- "version": "0.4.24",
3
+ "version": "0.4.27",
4
4
  "dependencies": {
5
5
  "image-size": "^2.0.4"
6
6
  },
7
- "description": "TypeScript client for the CraterView image enhancement API",
7
+ "description": "TypeScript client for the CraterView.ai image enhancement API",
8
8
  "type": "module",
9
9
  "main": "index.ts",
10
10
  "types": "index.ts",
@@ -25,10 +25,10 @@
25
25
  "test": "vitest run"
26
26
  },
27
27
  "devDependencies": {
28
- "@types/node": "^26.6.3",
28
+ "@types/node": "^26.6.6",
29
29
  "esbuild": "^0.28.2",
30
30
  "tsx": "^4.23.15",
31
31
  "typescript": "^7.0.2",
32
- "vitest": "^5.0.2"
32
+ "vitest": "^5.0.5"
33
33
  }
34
34
  }