@popcraft/cli 0.34.0 → 0.34.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.
Files changed (2) hide show
  1. package/dist/popcraft.mjs +52 -21
  2. package/package.json +2 -2
package/dist/popcraft.mjs CHANGED
@@ -1196,7 +1196,7 @@ function operations(spec = openapi) {
1196
1196
  }
1197
1197
  async function call(target2, method, path, opts = {}) {
1198
1198
  const qs = new URLSearchParams(opts.query ?? {}).toString();
1199
- const headers = { "user-agent": `popcraft-cli/${"0.34.0"}`, ...opts.headers };
1199
+ const headers = { "user-agent": `popcraft-cli/${"0.34.1"}`, ...opts.headers };
1200
1200
  if (target2.token) headers.authorization = `Bearer ${target2.token}`;
1201
1201
  if (opts.contentType) headers["content-type"] = opts.contentType;
1202
1202
  try {
@@ -310353,7 +310353,6 @@ function downloadBlob(blob, filename) {
310353
310353
  }
310354
310354
  var init_download = __esm({
310355
310355
  "lib/io/download.ts"() {
310356
- "use strict";
310357
310356
  }
310358
310357
  });
310359
310358
 
@@ -310573,7 +310572,6 @@ function creditLine(c2) {
310573
310572
  var MAX_PHOTO_PAGE, MAX_PHOTO_QUERY, UUID, isPhotoId, photoImagePath;
310574
310573
  var init_stock = __esm({
310575
310574
  "lib/photos/stock.ts"() {
310576
- "use strict";
310577
310575
  MAX_PHOTO_PAGE = 12;
310578
310576
  MAX_PHOTO_QUERY = 200;
310579
310577
  UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
@@ -316498,7 +316496,7 @@ async function renderDocument(doc2, nodeIds, options) {
316498
316496
  if (frame2) doc2 = { ...doc2, nodes: bakeMotion3(doc2.nodes, frame2.id, options.at) };
316499
316497
  }
316500
316498
  }
316501
- return selectionReferenceImages2(doc2, [...nodeIds], { maxEdge: options?.maxEdge, max: 8, format: "WEBP", ...options?.bands ? { bands: options.bands } : {} });
316499
+ return selectionReferenceImages2(doc2, [...nodeIds], { maxEdge: options?.maxEdge, max: 8, format: "JPG", ...options?.bands ? { bands: options.bands } : {} });
316502
316500
  }
316503
316501
  function generateCapability(ctx2) {
316504
316502
  return async (prompt2, options = {}) => {
@@ -326484,7 +326482,7 @@ var init_package = __esm({
326484
326482
  "packages/runtime/package.json"() {
326485
326483
  package_default = {
326486
326484
  name: "@popcraft/runtime",
326487
- version: "0.34.0",
326485
+ version: "0.34.1",
326488
326486
  description: "What code exported from PopCraft shares: the meaning of expressions (operators and functions) and, as it grows, the parts of a design's behaviour that are common code rather than generated React.",
326489
326487
  license: "MIT",
326490
326488
  homepage: "https://popcraft.app/docs/exporting/nextjs",
@@ -351150,7 +351148,6 @@ function exportsOf(source3) {
351150
351148
  var CODE_LIMITS, packageOf;
351151
351149
  var init_source2 = __esm({
351152
351150
  "lib/code/source.ts"() {
351153
- "use strict";
351154
351151
  CODE_LIMITS = { modules: 100, sourceLength: 2e5, packages: 12 };
351155
351152
  packageOf = (spec) => spec.split("/").slice(0, spec.startsWith("@") ? 2 : 1).join("/");
351156
351153
  }
@@ -351193,7 +351190,6 @@ function compileModule(module2) {
351193
351190
  var import_sucrase, BUILT_IN, memo4;
351194
351191
  var init_compile2 = __esm({
351195
351192
  "lib/code/compile.ts"() {
351196
- "use strict";
351197
351193
  import_sucrase = __toESM(require_dist2());
351198
351194
  init_source2();
351199
351195
  init_source2();
@@ -363367,27 +363363,35 @@ async function authHeaders2() {
363367
363363
  };
363368
363364
  }
363369
363365
  async function streamChat(opts, handlers = {}, signal) {
363366
+ const body = JSON.stringify({
363367
+ model: opts.model,
363368
+ messages: opts.messages,
363369
+ stream: true,
363370
+ max_tokens: opts.maxTokens ?? (opts.tools?.length ? 16384 : 4096),
363371
+ ...opts.temperature !== void 0 ? { temperature: opts.temperature } : {},
363372
+ ...opts.tools?.length ? { tools: opts.tools, tool_choice: opts.toolChoice ?? "auto" } : {}
363373
+ });
363374
+ if (body.length > MAX_REQUEST_BYTES) {
363375
+ throw new StreamError(
363376
+ `This message is too large to send (${(body.length / 1e6).toFixed(1)} MB with its images). Attach fewer or smaller images.`,
363377
+ "too_large",
363378
+ 413
363379
+ );
363380
+ }
363370
363381
  const res = await fetch(`${HYPERY_GATEWAY_URL}/api/v1/chat/completions`, {
363371
363382
  method: "POST",
363372
363383
  headers: await authHeaders2(),
363373
363384
  signal,
363374
- body: JSON.stringify({
363375
- model: opts.model,
363376
- messages: opts.messages,
363377
- stream: true,
363378
- max_tokens: opts.maxTokens ?? (opts.tools?.length ? 16384 : 4096),
363379
- ...opts.temperature !== void 0 ? { temperature: opts.temperature } : {},
363380
- ...opts.tools?.length ? { tools: opts.tools, tool_choice: opts.toolChoice ?? "auto" } : {}
363381
- })
363385
+ body
363382
363386
  }).catch((err2) => {
363383
363387
  if (err2.name === "AbortError") throw err2;
363384
363388
  throw new StreamError("Could not reach Hypery. Check your connection.", "network", 0);
363385
363389
  });
363386
363390
  if (!res.ok || !res.body) {
363387
- const body = await res.text().catch(() => "");
363388
- let payload = body;
363391
+ const body2 = await res.text().catch(() => "");
363392
+ let payload = body2;
363389
363393
  try {
363390
- payload = JSON.parse(body);
363394
+ payload = JSON.parse(body2);
363391
363395
  } catch {
363392
363396
  }
363393
363397
  throw new StreamError(streamErrorMessage(payload, `The AI request failed (${res.status}).`), errorCodeFor(res.status, payload), res.status);
@@ -363436,7 +363440,7 @@ function errorCodeFor(status3, payload) {
363436
363440
  if (status3 === 429) return "ai_rate_limited";
363437
363441
  return "ai_upstream";
363438
363442
  }
363439
- var IDLE_TIMEOUT_MS;
363443
+ var IDLE_TIMEOUT_MS, MAX_REQUEST_BYTES;
363440
363444
  var init_gateway = __esm({
363441
363445
  "lib/agent/gateway.ts"() {
363442
363446
  "use strict";
@@ -363446,6 +363450,7 @@ var init_gateway = __esm({
363446
363450
  init_shared();
363447
363451
  init_stream_parse();
363448
363452
  IDLE_TIMEOUT_MS = 18e4;
363453
+ MAX_REQUEST_BYTES = 44e5;
363449
363454
  }
363450
363455
  });
363451
363456
 
@@ -363477,6 +363482,28 @@ function pruneOldImages(messages, keep = KEEP_IMAGE_TURNS) {
363477
363482
  messages[i2] = { ...m, content: `${text} [${images === 1 ? "image" : `${images} images`} omitted: superseded by a later render \u2014 render again if you need to look.]`.trim() };
363478
363483
  }
363479
363484
  }
363485
+ function fitImagesToBudget(messages, budget) {
363486
+ if (sizeOf2(messages) <= budget) return;
363487
+ const renderTurns = messages.map((m, i2) => ({ m, i: i2 })).filter(({ m }) => m.role === "user" && Array.isArray(m.content) && m.content[0]?.type === "text" && !!m.content[0].text?.startsWith(RENDER_TURN_PREFIX)).map(({ i: i2 }) => i2);
363488
+ for (const i2 of renderTurns) {
363489
+ if (sizeOf2(messages) <= budget) return;
363490
+ const m = messages[i2];
363491
+ if (!Array.isArray(m.content)) continue;
363492
+ const parts = [...m.content];
363493
+ let dropped = 0;
363494
+ for (let j = parts.length - 1; j >= 0 && sizeOf2(messages) > budget; j--) {
363495
+ if (parts[j].type !== "image_url") continue;
363496
+ parts.splice(j, 1);
363497
+ dropped++;
363498
+ messages[i2] = { ...m, content: [...parts] };
363499
+ }
363500
+ if (dropped) {
363501
+ const note2 = `[${dropped === 1 ? "1 image" : `${dropped} images`} omitted to keep the request under the size limit \u2014 look at fewer layers at once, or pass a smaller maxEdge.]`;
363502
+ const rest = messages[i2].content;
363503
+ messages[i2] = { ...m, content: rest.some((p2) => p2.type === "image_url") ? [...rest, { type: "text", text: note2 }] : `${rest.flatMap((p2) => p2.type === "text" ? [p2.text] : []).join(" ")} ${note2}`.trim() };
363504
+ }
363505
+ }
363506
+ }
363480
363507
  async function runAgentLoop(opts) {
363481
363508
  const maxRounds = opts.maxRounds ?? DEFAULT_MAX_ROUNDS;
363482
363509
  const maxResultChars = opts.maxResultChars ?? 8e3;
@@ -363488,6 +363515,7 @@ async function runAgentLoop(opts) {
363488
363515
  if (opts.stopped?.()) return { messages, text, rounds, exhausted: false, stopped: true };
363489
363516
  for (const note2 of opts.drainNotifications?.() ?? []) messages.push({ role: "user", content: note2 });
363490
363517
  pruneOldImages(messages);
363518
+ fitImagesToBudget(messages, MAX_REQUEST_BYTES - JSON.stringify(specs).length - REQUEST_MARGIN_BYTES);
363491
363519
  opts.hooks?.onAssistantStart?.(rounds);
363492
363520
  const turn = await opts.callModel(messages, specs, {
363493
363521
  onTextDelta: opts.hooks?.onTextDelta,
@@ -363546,14 +363574,17 @@ async function runAgentLoop(opts) {
363546
363574
  messages.push({ role: "assistant", content: final.text });
363547
363575
  return { messages, text: final.text, rounds, exhausted: true, stopped: false };
363548
363576
  }
363549
- var DEFAULT_MAX_ROUNDS, DEFAULT_MAX_PARALLEL, KEEP_IMAGE_TURNS, RENDER_TURN_PREFIX;
363577
+ var DEFAULT_MAX_ROUNDS, DEFAULT_MAX_PARALLEL, KEEP_IMAGE_TURNS, RENDER_TURN_PREFIX, REQUEST_MARGIN_BYTES, sizeOf2;
363550
363578
  var init_loop = __esm({
363551
363579
  "lib/agent/loop.ts"() {
363552
363580
  "use strict";
363581
+ init_gateway();
363553
363582
  DEFAULT_MAX_ROUNDS = 12;
363554
363583
  DEFAULT_MAX_PARALLEL = 4;
363555
363584
  KEEP_IMAGE_TURNS = 2;
363556
363585
  RENDER_TURN_PREFIX = "Result of ";
363586
+ REQUEST_MARGIN_BYTES = 64e3;
363587
+ sizeOf2 = (messages) => JSON.stringify(messages).length;
363557
363588
  }
363558
363589
  });
363559
363590
 
@@ -409896,7 +409927,7 @@ init_resources();
409896
409927
  init_desktop();
409897
409928
  init_hypery();
409898
409929
  import { createInterface } from "node:readline";
409899
- var VERSION2 = "0.34.0";
409930
+ var VERSION2 = "0.34.1";
409900
409931
  var HELP = `popcraft ${VERSION2} \u2014 the PopCraft command line
409901
409932
 
409902
409933
  Files (headless, on .popcraft files):
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@popcraft/cli",
3
- "version": "0.34.0",
3
+ "version": "0.34.1",
4
4
  "description": "The PopCraft command line: edit .popcraft files headlessly, call the REST API, publish to the marketplace and manage the desktop app's local plugins, themes, fonts, skills and agents.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://popcraft.app/docs/api/cli",
@@ -34,7 +34,7 @@
34
34
  "esbuild": "0.28.2"
35
35
  },
36
36
  "dependencies": {
37
- "@popcraft/kit": "0.34.0"
37
+ "@popcraft/kit": "0.34.1"
38
38
  },
39
39
  "scripts": {
40
40
  "build": "node build.mjs",