@playdrop/playdrop-cli 0.18.8 → 0.18.9

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.
@@ -1,7 +1,7 @@
1
1
  {
2
- "version": "0.18.8",
2
+ "version": "0.18.9",
3
3
  "build": 1,
4
- "runtimeSdkVersion": "0.18.8",
4
+ "runtimeSdkVersion": "0.18.9",
5
5
  "runtimeSdkBuild": 1,
6
6
  "clients": {
7
7
  "all": {
@@ -180,11 +180,24 @@ function pushPreparedArtifact(task, currentTotal, file, maxBytes, code, label) {
180
180
  }
181
181
  async function uploadSignedObject(client, creatorUsername, appName, sessionId, file, descriptor) {
182
182
  for (let attempt = 0; attempt < 2; attempt += 1) {
183
- const response = await fetch(descriptor.url, {
184
- method: descriptor.method,
185
- headers: descriptor.headers,
186
- body: file.file,
187
- });
183
+ let response;
184
+ try {
185
+ response = await fetch(descriptor.url, {
186
+ method: descriptor.method,
187
+ headers: descriptor.headers,
188
+ body: file.file,
189
+ });
190
+ }
191
+ catch (error) {
192
+ const cause = error instanceof Error ? error.cause : null;
193
+ const code = cause && typeof cause === "object" && "code" in cause &&
194
+ typeof cause.code === "string" && /^[A-Z][A-Z0-9_]{0,63}$/.test(cause.code)
195
+ ? cause.code
196
+ : "UNKNOWN";
197
+ const annotated = new Error(`direct_object_upload_network_failed:${file.relativePath}:${code}`);
198
+ Object.defineProperty(annotated, "cause", { value: error, configurable: true, writable: true });
199
+ throw annotated;
200
+ }
188
201
  if (response.ok) {
189
202
  return;
190
203
  }
@@ -418,6 +418,25 @@ export declare function buildGrokIsolationEnv(): Record<string, string>;
418
418
  export declare function resolveHostGrokAuthPath(homeDir?: string): string;
419
419
  export declare function mergeCreatorRecoveryResults(runtime: AgentRuntime, initial: LoggedProcessResult, recovery: LoggedProcessResult): LoggedProcessResult;
420
420
  export declare function mergeMissingAgentOutcomeRecoveryResults(runtime: AgentRuntime, initial: LoggedProcessResult, recovery: LoggedProcessResult): LoggedProcessResult;
421
+ export declare function recordAgentRunTelemetry(input: {
422
+ client: ApiClient;
423
+ task: {
424
+ id: number;
425
+ attempts: number;
426
+ };
427
+ assignment: WorkerTaskAssignment;
428
+ workerKey: string;
429
+ leaseToken: string;
430
+ result: LoggedProcessResult;
431
+ status: AgentTaskStatus;
432
+ resolvedRuntimeModel: string;
433
+ reasoningEffort: string | null;
434
+ availableSkillPaths: readonly string[];
435
+ observedSkillPaths?: readonly string[];
436
+ startedAt: Date;
437
+ completedAt: Date;
438
+ terminalReason?: AgentTaskTerminalReason;
439
+ }): Promise<void>;
421
440
  export declare function buildAgentFailureCode(agent: AgentRuntime, result: LoggedProcessResult, request?: {
422
441
  model: string;
423
442
  reasoningEffort?: string | null;
@@ -515,6 +534,14 @@ export declare function assertLaunchAgentPlistCompatible(input: {
515
534
  wrapperPath: string;
516
535
  canonicalPlistPath: string;
517
536
  }): void;
537
+ export declare function writeManagedWorkerWrapper(input: {
538
+ env: string;
539
+ workerName: string;
540
+ workerKey: string;
541
+ }): Promise<{
542
+ wrapperPath: string;
543
+ policyFile: string;
544
+ }>;
518
545
  export declare function launchManagedWorker(label: string, plistPath: string, options: {
519
546
  registrationChanged: boolean;
520
547
  runCommand?: typeof runShell;
@@ -70,6 +70,7 @@ exports.buildGrokIsolationEnv = buildGrokIsolationEnv;
70
70
  exports.resolveHostGrokAuthPath = resolveHostGrokAuthPath;
71
71
  exports.mergeCreatorRecoveryResults = mergeCreatorRecoveryResults;
72
72
  exports.mergeMissingAgentOutcomeRecoveryResults = mergeMissingAgentOutcomeRecoveryResults;
73
+ exports.recordAgentRunTelemetry = recordAgentRunTelemetry;
73
74
  exports.buildAgentFailureCode = buildAgentFailureCode;
74
75
  exports.classifyAgentAvailabilityFailureReason = classifyAgentAvailabilityFailureReason;
75
76
  exports.describeAgentFailureForEvent = describeAgentFailureForEvent;
@@ -100,6 +101,7 @@ exports.withTaskUploadLock = withTaskUploadLock;
100
101
  exports.readActivePersonalWorkerRuntimeState = readActivePersonalWorkerRuntimeState;
101
102
  exports.parseLaunchAgentProgramArguments = parseLaunchAgentProgramArguments;
102
103
  exports.assertLaunchAgentPlistCompatible = assertLaunchAgentPlistCompatible;
104
+ exports.writeManagedWorkerWrapper = writeManagedWorkerWrapper;
103
105
  exports.launchManagedWorker = launchManagedWorker;
104
106
  exports.showWorkerStatus = showWorkerStatus;
105
107
  exports.setupWorker = setupWorker;
@@ -191,7 +193,7 @@ const FAIL_REPORT_RETRY_DELAY_MS = 2000;
191
193
  const CLAIM_ACK_RETRY_DELAY_MS = 500;
192
194
  const CLAIM_ACK_MAX_ATTEMPTS = 4;
193
195
  exports.WORKSPACE_ARCHIVE_DOWNLOAD_TIMEOUT_MS = 5 * 60000;
194
- const WORKER_WRAPPER_CONTRACT_VERSION = 5;
196
+ const WORKER_WRAPPER_CONTRACT_VERSION = 6;
195
197
  const WORKER_SUPPORTED_KINDS = [
196
198
  "NEW_GAME",
197
199
  "STATIC_GAME",
@@ -3597,12 +3599,6 @@ function buildAgentRunResult(result) {
3597
3599
  tokensUsed: result.tokensUsed,
3598
3600
  };
3599
3601
  }
3600
- function agentFailureRawError(result) {
3601
- return ([result.stderr, result.stdout, result.outputTail]
3602
- .map((value) => value.trim())
3603
- .filter(Boolean)
3604
- .join("\n") || "agent_failure");
3605
- }
3606
3602
  function buildSupervisorFailureRunResult(message) {
3607
3603
  return {
3608
3604
  exitCode: null,
@@ -3693,7 +3689,11 @@ async function recordAgentRunTelemetry(input) {
3693
3689
  completedAt: input.completedAt.toISOString(),
3694
3690
  ...(input.status === "FAILED"
3695
3691
  ? {
3696
- terminalReason: input.terminalReason ?? (0, types_1.classifyAgentTaskTerminalReason)(agentFailureRawError(input.result), "agent"),
3692
+ terminalReason: input.terminalReason ??
3693
+ (0, types_1.classifyAgentTaskTerminalReason)(buildAgentFailureCode(input.assignment.agent.runtime, input.result, {
3694
+ model: input.assignment.agent.model,
3695
+ reasoningEffort: input.reasoningEffort,
3696
+ }), "agent"),
3697
3697
  }
3698
3698
  : {}),
3699
3699
  });
@@ -5169,6 +5169,29 @@ if [ -n "$MINIMUM_CLI_VERSION" ]; then
5169
5169
  version_meets "$CURRENT_CLI_VERSION" "$MINIMUM_CLI_VERSION" || fail_converge "$?" "worker_update_cli_below_minimum"
5170
5170
  fi
5171
5171
 
5172
+ PLAYDROP_EXECUTABLE="$(command -v playdrop)" || fail_converge "$?" "worker_update_playwright_resolve_failed"
5173
+ node - "$PLAYDROP_EXECUTABLE" <<'NODE' || fail_converge "$?" "worker_update_playwright_install_failed"
5174
+ const fs = require("fs");
5175
+ const path = require("path");
5176
+ const { createRequire } = require("module");
5177
+ const { spawnSync } = require("child_process");
5178
+ const cliRequire = createRequire(fs.realpathSync(process.argv[2]));
5179
+ const playwright = cliRequire("playwright-core");
5180
+ const executablePath = playwright.chromium.executablePath();
5181
+ if (!fs.existsSync(executablePath)) {
5182
+ const packagePath = cliRequire.resolve("playwright-core/package.json");
5183
+ const packageJson = cliRequire(packagePath);
5184
+ const installerPath = path.resolve(path.dirname(packagePath), packageJson.bin["playwright-core"]);
5185
+ const result = spawnSync(process.execPath, [installerPath, "install", "chromium"], {
5186
+ stdio: "inherit",
5187
+ env: { ...process.env, PLAYWRIGHT_SKIP_BROWSER_GC: "1" },
5188
+ });
5189
+ if (result.error) throw result.error;
5190
+ if (result.status !== 0) process.exit(result.status || 1);
5191
+ if (!fs.existsSync(executablePath)) throw new Error("worker_update_chromium_missing_after_install");
5192
+ }
5193
+ NODE
5194
+
5172
5195
  if [ "$TARGET_UPDATE_FAILED" -eq 0 ]; then
5173
5196
  rm -f "$FAILURE_FILE"
5174
5197
  fi
@@ -6852,7 +6875,7 @@ async function startWorker(options = {}) {
6852
6875
  if (refreshed && refreshed.task.status !== "RUNNING" && refreshed.task.status !== "QUEUED") {
6853
6876
  retainWorkspace = refreshed.task.status === "FAILED";
6854
6877
  console.error(`Agent task ${task.id} was finalized by the server as ${refreshed.task.status}.`);
6855
- await reportTelemetry(refreshed.task.status);
6878
+ await reportTelemetry(refreshed.task.status, undefined, refreshed.task.terminalReason ?? undefined);
6856
6879
  }
6857
6880
  else {
6858
6881
  console.error(`Agent task ${task.id} was aborted by the server; cleaning up without reporting failure.`);
@@ -6886,7 +6909,7 @@ async function startWorker(options = {}) {
6886
6909
  if (refreshed.task.status !== "RUNNING") {
6887
6910
  retainWorkspace = refreshed.task.status === "FAILED";
6888
6911
  console.error(`Agent task ${task.id} was finalized by the agent as ${refreshed.task.status}.`);
6889
- await reportTelemetry(refreshed.task.status);
6912
+ await reportTelemetry(refreshed.task.status, undefined, refreshed.task.terminalReason ?? undefined);
6890
6913
  }
6891
6914
  else if (hasAgentTaskUploadedArtifact(refreshed.task)) {
6892
6915
  console.error(`Agent task ${task.id} uploaded an artifact but exited before task completion; failing it explicitly.`);
@@ -6909,6 +6932,7 @@ async function startWorker(options = {}) {
6909
6932
  model: assignment.agent.model,
6910
6933
  reasoningEffort,
6911
6934
  });
6935
+ const terminalReason = uploadFailure?.terminalReason ?? (0, types_1.classifyAgentTaskTerminalReason)(failureCode, "agent");
6912
6936
  const availabilityReason = uploadFailure
6913
6937
  ? null
6914
6938
  : classifyAgentAvailabilityFailureReason(failureCode, task.kind === "GAME_REVIEW");
@@ -6923,7 +6947,7 @@ async function startWorker(options = {}) {
6923
6947
  });
6924
6948
  if (availabilityReason) {
6925
6949
  retainWorkspace = false;
6926
- await reportTelemetry("FAILED").catch((error) => {
6950
+ await reportTelemetry("FAILED", undefined, terminalReason).catch((error) => {
6927
6951
  console.error(`Agent task ${task.id} telemetry failed before provider handoff: ${error instanceof Error ? error.message : String(error)}`);
6928
6952
  });
6929
6953
  const unavailable = await client.workerRecordAgentTaskAttemptUnavailable(task.id, {
@@ -6942,12 +6966,10 @@ async function startWorker(options = {}) {
6942
6966
  workerKey,
6943
6967
  leaseToken,
6944
6968
  error: failureCode,
6945
- terminalReason: uploadFailure
6946
- ? uploadFailure.terminalReason
6947
- : (0, types_1.classifyAgentTaskTerminalReason)(failureCode, "agent"),
6969
+ terminalReason,
6948
6970
  result: agentRunResult,
6949
6971
  });
6950
- await reportTelemetry("FAILED");
6972
+ await reportTelemetry("FAILED", undefined, terminalReason);
6951
6973
  }
6952
6974
  }
6953
6975
  }
@@ -6956,7 +6978,7 @@ async function startWorker(options = {}) {
6956
6978
  if (refreshed.task.status !== "RUNNING") {
6957
6979
  retainWorkspace = refreshed.task.status === "FAILED";
6958
6980
  console.error(`Agent task ${task.id} was finalized by the agent as ${refreshed.task.status}.`);
6959
- await reportTelemetry(refreshed.task.status);
6981
+ await reportTelemetry(refreshed.task.status, undefined, refreshed.task.terminalReason ?? undefined);
6960
6982
  }
6961
6983
  else if (taskStillMissingAgentOutcome(refreshed) &&
6962
6984
  hasAgentTaskUploadedArtifact(refreshed.task)) {
@@ -7133,6 +7155,7 @@ async function startWorker(options = {}) {
7133
7155
  }
7134
7156
  else {
7135
7157
  const uploadFailure = readRecordedTaskUploadFailure();
7158
+ const terminalReason = uploadFailure?.terminalReason ?? (0, types_1.classifyAgentTaskTerminalReason)("agent_exited_without_task_done", "agent");
7136
7159
  await client.workerCreateAgentTaskEvent(task.id, {
7137
7160
  workerKey,
7138
7161
  leaseToken,
@@ -7145,10 +7168,10 @@ async function startWorker(options = {}) {
7145
7168
  workerKey,
7146
7169
  leaseToken,
7147
7170
  error: uploadFailure?.terminalReason.code ?? "agent_exited_without_task_done",
7148
- ...(uploadFailure ? { terminalReason: uploadFailure.terminalReason } : {}),
7171
+ terminalReason,
7149
7172
  result: agentRunResult,
7150
7173
  });
7151
- await reportTelemetry("FAILED");
7174
+ await reportTelemetry("FAILED", undefined, terminalReason);
7152
7175
  }
7153
7176
  }
7154
7177
  }
@@ -1,7 +1,7 @@
1
1
  {
2
- "version": "0.18.8",
2
+ "version": "0.18.9",
3
3
  "build": 1,
4
- "runtimeSdkVersion": "0.18.8",
4
+ "runtimeSdkVersion": "0.18.9",
5
5
  "runtimeSdkBuild": 1,
6
6
  "clients": {
7
7
  "all": {
@@ -1 +1 @@
1
- {"version":3,"file":"agent-task-terminal.d.ts","sourceRoot":"","sources":["../src/agent-task-terminal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAExD,wBAAgB,+BAA+B,CAC7C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,uBAAuB,CAAC,QAAQ,CAAC,GACxC,uBAAuB,CAoFzB;AAoCD,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,uBAAuB,CASlF;AAED,wBAAgB,uBAAuB,CAAC,IAAI,SAAc,GAAG,uBAAuB,CASnF"}
1
+ {"version":3,"file":"agent-task-terminal.d.ts","sourceRoot":"","sources":["../src/agent-task-terminal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAExD,wBAAgB,+BAA+B,CAC7C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,uBAAuB,CAAC,QAAQ,CAAC,GACxC,uBAAuB,CAwFzB;AAoCD,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,uBAAuB,CASlF;AAED,wBAAgB,uBAAuB,CAAC,IAAI,SAAc,GAAG,uBAAuB,CASnF"}
@@ -47,7 +47,7 @@ function classifyAgentTaskTerminalReason(errorText, source) {
47
47
  source: "instrument",
48
48
  message: "The required browser or capture instrument failed."
49
49
  }),
50
- matchFailure(lower, /(capacity|overloaded|rate.?limit|too many requests|quota|(?:^|\D)429(?:\D|$))/, {
50
+ matchFailure(lower, /(agent_(?:provider_)?temporarily_unavailable|capacity|overloaded|rate.?limit|too many requests|quota|(?:^|\D)429(?:\D|$))/, {
51
51
  category: "provider_capacity",
52
52
  retryable: true,
53
53
  source: "provider",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playdrop/playdrop-cli",
3
- "version": "0.18.8",
3
+ "version": "0.18.9",
4
4
  "description": "Official Playdrop CLI for publishing browser games, creator apps, and AI-generated game assets on playdrop.ai",
5
5
  "homepage": "https://www.playdrop.ai",
6
6
  "repository": {