@pstdio/pocketcoder-cli 0.7.0 → 0.7.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/index.js +74 -21
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -5214,7 +5214,7 @@ function isYargsInstance(y) {
5214
5214
  var Yargs = YargsFactory(esm_default);
5215
5215
  var yargs_default = Yargs;
5216
5216
  // package.json
5217
- var version = "0.7.0";
5217
+ var version = "0.7.1";
5218
5218
 
5219
5219
  // src/cli-context.ts
5220
5220
  import { existsSync as existsSync3, readFileSync as readFileSync3, statSync as statSync3 } from "fs";
@@ -40111,6 +40111,17 @@ ${tail}`] : []
40111
40111
  this.workspace = workspace;
40112
40112
  }
40113
40113
  }
40114
+
40115
+ class AgentNotReadyError extends Error {
40116
+ workspaceId;
40117
+ agentState;
40118
+ constructor(workspaceId, agentState, timeoutMs2) {
40119
+ super(`agent in workspace ${workspaceId} was still ${agentState} after ${timeoutMs2}ms and cannot accept a message`);
40120
+ this.name = "AgentNotReadyError";
40121
+ this.workspaceId = workspaceId;
40122
+ this.agentState = agentState;
40123
+ }
40124
+ }
40114
40125
  function responseError(response, body) {
40115
40126
  const parsed = ErrorEnvelopeSchema.safeParse(body);
40116
40127
  if (!parsed.success) {
@@ -40126,6 +40137,7 @@ function responseError(response, body) {
40126
40137
  }
40127
40138
 
40128
40139
  // ../sdk/src/attachments.ts
40140
+ var DEFAULT_READY_TIMEOUT_MS = 120000;
40129
40141
  function contentDisposition(name2) {
40130
40142
  const clean = name2.replace(/[\r\n]/g, "");
40131
40143
  if (/^[ -~]*$/.test(clean)) {
@@ -40170,10 +40182,13 @@ class AttachmentsApi {
40170
40182
 
40171
40183
  class AgentApi {
40172
40184
  transport;
40173
- constructor(transport) {
40185
+ workspaces;
40186
+ constructor(transport, workspaces3) {
40174
40187
  this.transport = transport;
40188
+ this.workspaces = workspaces3;
40175
40189
  }
40176
40190
  async sendMessage(workspaceId, input) {
40191
+ await this.workspaces.waitForAgentInput(workspaceId, input.readyTimeoutMs ?? DEFAULT_READY_TIMEOUT_MS, input.signal ? { signal: input.signal } : {});
40177
40192
  const response = await this.transport.raw(`/v1/workspaces/${encodeURIComponent(workspaceId)}/agent/message`, {
40178
40193
  method: "POST",
40179
40194
  ...input.signal ? { signal: input.signal } : {},
@@ -40622,6 +40637,21 @@ class WorkspacesApi {
40622
40637
  }
40623
40638
  return workspace;
40624
40639
  }
40640
+ async waitForAgentInput(id, timeoutMs2, options = {}) {
40641
+ const deadline = Date.now() + timeoutMs2;
40642
+ let workspace = await this.get(id, options);
40643
+ while (workspace.agent_state !== "stable") {
40644
+ if (TERMINAL_STATES.includes(workspace.state))
40645
+ throw new WorkspaceTerminalError(workspace);
40646
+ const remainingMs = deadline - Date.now();
40647
+ if (remainingMs <= 0) {
40648
+ throw new AgentNotReadyError(workspace.id, workspace.agent_state, timeoutMs2);
40649
+ }
40650
+ const change = await this.change(workspace.id, workspace.change_cursor, Math.max(1, Math.min(30, Math.ceil(remainingMs / 1000))), options);
40651
+ workspace = change.workspace;
40652
+ }
40653
+ return workspace;
40654
+ }
40625
40655
  preserve(id, input, key, options = {}) {
40626
40656
  return this.jsonOperation(`/v1/workspaces/${encodeURIComponent(id)}/preserve`, input, key, PreserveResponseSchema, options);
40627
40657
  }
@@ -40661,7 +40691,7 @@ class PocketCoderClient {
40661
40691
  this.templates = new TemplatesApi(this.transport);
40662
40692
  this.workspaces = new WorkspacesApi(this.transport);
40663
40693
  this.attachments = new AttachmentsApi(this.transport);
40664
- this.agent = new AgentApi(this.transport);
40694
+ this.agent = new AgentApi(this.transport, this.workspaces);
40665
40695
  this.conversations = new ConversationsApi(this.transport);
40666
40696
  this.checkpoints = new CheckpointsApi(this.transport);
40667
40697
  this.operations = new OperationsApi(this.transport);
@@ -41053,7 +41083,7 @@ function addDoctorCommand(parser2) {
41053
41083
  }).option("turn-timeout-seconds", {
41054
41084
  type: "number",
41055
41085
  default: 60,
41056
- description: "Maximum time to wait for the correlated diagnostic response"
41086
+ description: "Maximum wait for agent input readiness and, separately, its diagnostic response"
41057
41087
  }), runDoctor);
41058
41088
  }
41059
41089
  async function runDoctor(flags) {
@@ -41069,8 +41099,10 @@ async function runDoctor(flags) {
41069
41099
  console.log(`doctor: workspace ${workspace.id} queued; waiting for ready`);
41070
41100
  await waitUntilReady(workspace.id);
41071
41101
  console.log("doctor: workspace ready; probing agent status through the relay");
41102
+ const timeoutSeconds = turnTimeout(flags);
41072
41103
  await verifyStatus(workspace.id);
41073
- await runTurn(workspace.id, turnTimeout(flags));
41104
+ await waitForInput(workspace.id, timeoutSeconds);
41105
+ await runTurn(workspace.id, timeoutSeconds);
41074
41106
  console.log("doctor: correlated agent response received");
41075
41107
  } catch (error51) {
41076
41108
  failure = error51 instanceof Error ? error51 : new Error(String(error51));
@@ -41103,6 +41135,10 @@ async function waitUntilReady(workspaceId) {
41103
41135
  }
41104
41136
  throw new Error("workspace did not become ready within 5 minutes");
41105
41137
  }
41138
+ async function waitForInput(workspaceId, timeoutSeconds) {
41139
+ console.log("doctor: waiting for the agent to be ready for input");
41140
+ await controlPlaneClient().workspaces.waitForAgentInput(workspaceId, timeoutSeconds * 1000);
41141
+ }
41106
41142
  async function verifyStatus(workspaceId) {
41107
41143
  const response = await api2(`/v1/workspaces/${workspaceId}/agent/status`);
41108
41144
  const text6 = await response.text();
@@ -52359,6 +52395,31 @@ function addTemplateCommands(parser2) {
52359
52395
  // src/commands/workspaces/chat-session.ts
52360
52396
  import { createInterface } from "readline";
52361
52397
 
52398
+ // src/commands/workspaces/agent-readiness.ts
52399
+ async function readWorkspaceAgentState(id, { api: api3, fail: fail2 }) {
52400
+ const response = await api3(`/v1/workspaces/${id}`);
52401
+ const body = await response.json();
52402
+ if (!response.ok) {
52403
+ fail2(`workspace lookup failed (${response.status}): ${JSON.stringify(body)}`);
52404
+ }
52405
+ if (body.state !== "ready") {
52406
+ fail2(`workspace is ${String(body.state ?? "unavailable")}; it is not live`);
52407
+ }
52408
+ if (body.agent_state !== "unknown" && body.agent_state !== "running" && body.agent_state !== "stable") {
52409
+ fail2(`workspace returned unknown agent state: ${JSON.stringify(body.agent_state)}`);
52410
+ }
52411
+ return typeof body.agent_state === "string" ? body.agent_state : "unknown";
52412
+ }
52413
+ async function waitForAgentInput(id, options, deps) {
52414
+ const deadline = Date.now() + options.timeoutSeconds * 1000;
52415
+ while (await readWorkspaceAgentState(id, deps) !== "stable") {
52416
+ if (Date.now() >= deadline) {
52417
+ deps.fail(`agent was not ready for input within ${options.timeoutSeconds} seconds`);
52418
+ }
52419
+ await Bun.sleep(options.pollIntervalMs);
52420
+ }
52421
+ }
52422
+
52362
52423
  // src/commands/workspaces/attachments.ts
52363
52424
  import { randomUUID as randomUUID27 } from "crypto";
52364
52425
  import { readFileSync as readFileSync5, statSync as statSync4 } from "fs";
@@ -52542,6 +52603,7 @@ function setCursor(id, cursor, value) {
52542
52603
  }
52543
52604
 
52544
52605
  // src/commands/workspaces/chat-session.ts
52606
+ var DEFAULT_READINESS = { timeoutSeconds: 120, pollIntervalMs: 500 };
52545
52607
  function need2(flags, key, fail2) {
52546
52608
  const value = flags[key];
52547
52609
  if (typeof value !== "string" || value === "")
@@ -52566,9 +52628,11 @@ async function assertWorkspaceAttachable(id, { api: api3, fail: fail2 }) {
52566
52628
  const restore = workspace.persistence?.latest_checkpoint_id ? ` Restore with: pcd workspaces restore --checkpoint ${workspace.persistence.latest_checkpoint_id} --external-id <new-id>` : "";
52567
52629
  fail2(`workspace is ${workspace.state ?? "unavailable"}; it is not live.${restore}`);
52568
52630
  }
52569
- async function sendWorkspaceMessage(id, message, { api: api3, fail: fail2 }, attachmentIds = []) {
52631
+ async function sendWorkspaceMessage(id, message, deps, attachmentIds = [], readiness = DEFAULT_READINESS) {
52570
52632
  if (typeof message !== "string")
52571
52633
  return;
52634
+ const { api: api3, fail: fail2 } = deps;
52635
+ await waitForAgentInput(id, readiness, deps);
52572
52636
  const response = await api3(`/v1/workspaces/${id}/agent/message`, {
52573
52637
  method: "POST",
52574
52638
  body: JSON.stringify({
@@ -52652,20 +52716,6 @@ async function readChatMessages(id, deps) {
52652
52716
  }
52653
52717
  return body.messages ?? [];
52654
52718
  }
52655
- async function readWorkspaceAgentState(id, deps) {
52656
- const response = await deps.api(`/v1/workspaces/${id}`);
52657
- const body = await response.json();
52658
- if (!response.ok) {
52659
- deps.fail(`workspace lookup failed (${response.status}): ${JSON.stringify(body)}`);
52660
- }
52661
- if (body.state !== "ready") {
52662
- deps.fail(`workspace is ${String(body.state ?? "unavailable")}; it is not live`);
52663
- }
52664
- if (body.agent_state !== "unknown" && body.agent_state !== "running" && body.agent_state !== "stable") {
52665
- deps.fail(`workspace returned unknown agent state: ${JSON.stringify(body.agent_state)}`);
52666
- }
52667
- return typeof body.agent_state === "string" ? body.agent_state : "unknown";
52668
- }
52669
52719
  async function pollTurnResponse(id, baseline, cursor, options, deps) {
52670
52720
  const deadline = Date.now() + options.timeoutSeconds * 1000;
52671
52721
  while (!options.interrupted()) {
@@ -52736,7 +52786,10 @@ async function chatWorkspace(flags, deps) {
52736
52786
  const before = await readChatMessages(id, deps);
52737
52787
  const baseline = messageBaseline(before);
52738
52788
  advanceCursor(id, cursor, before);
52739
- await sendWorkspaceMessage(id, message, deps, attachmentIds);
52789
+ await sendWorkspaceMessage(id, message, deps, attachmentIds, {
52790
+ timeoutSeconds: responseTimeoutSeconds,
52791
+ pollIntervalMs
52792
+ });
52740
52793
  await pollTurnResponse(id, baseline, cursor, {
52741
52794
  json: flags.json === true,
52742
52795
  pollIntervalMs,
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "type:app"
7
7
  ]
8
8
  },
9
- "version": "0.7.0",
9
+ "version": "0.7.1",
10
10
  "private": false,
11
11
  "description": "Operator and diagnostics CLI for PocketCoder.",
12
12
  "type": "module",