@questionbase/deskfree 0.3.0-alpha.38 → 0.3.0-alpha.39

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/dist/index.js CHANGED
@@ -4995,28 +4995,29 @@ function enqueuePoll(client, ctx, getCursor, setCursor, log, account, getWelcome
4995
4995
  });
4996
4996
  pollChains.set(accountId, next);
4997
4997
  }
4998
- var SEED = "SEED";
4999
4998
  async function pollAndDeliver(client, ctx, cursor, log, account, alreadyWelcomed) {
5000
4999
  try {
5001
- const isFirstRun = !cursor || cursor === SEED;
5002
- const apiCursor = cursor && cursor !== SEED ? cursor : void 0;
5000
+ const isFirstRun = !cursor;
5003
5001
  const response = await client.listMessages({
5004
- ...apiCursor ? { cursor: apiCursor } : {}
5002
+ ...cursor ? { cursor } : {}
5005
5003
  });
5006
5004
  if (isFirstRun) {
5005
+ const seedCursor = response.cursor ?? (/* @__PURE__ */ new Date()).toISOString();
5007
5006
  if (response.cursor) {
5008
5007
  log.info(
5009
5008
  `First run: skipping ${response.items.length} existing message(s), seeding cursor.`
5010
5009
  );
5011
- saveCursor(ctx, response.cursor, log);
5012
5010
  } else {
5013
- log.info("First run: no messages yet (empty inbox).");
5011
+ log.info(
5012
+ "First run: no messages yet (empty inbox), seeding cursor with current time."
5013
+ );
5014
5014
  }
5015
+ saveCursor(ctx, seedCursor, log);
5015
5016
  log.info("Connected to DeskFree. Ready to receive messages and tasks.");
5016
5017
  if (alreadyWelcomed) {
5017
5018
  log.info("Welcome already sent, skipping duplicate.");
5018
5019
  return {
5019
- cursor: response.cursor ?? SEED,
5020
+ cursor: seedCursor,
5020
5021
  ok: true,
5021
5022
  welcomeSent: false
5022
5023
  };
@@ -5028,7 +5029,7 @@ async function pollAndDeliver(client, ctx, cursor, log, account, alreadyWelcomed
5028
5029
  const welcomeMessage = {
5029
5030
  messageId: `welcome-${Date.now()}`,
5030
5031
  botId: "",
5031
- humanId: "system",
5032
+ humanId: account?.userId ?? ctx.account.userId,
5032
5033
  authorType: "user",
5033
5034
  content: welcomeContent,
5034
5035
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -5040,7 +5041,7 @@ async function pollAndDeliver(client, ctx, cursor, log, account, alreadyWelcomed
5040
5041
  const msg = err instanceof Error ? err.message : String(err);
5041
5042
  log.warn(`Failed to send welcome message: ${msg}`);
5042
5043
  }
5043
- return { cursor: response.cursor ?? SEED, ok: true, welcomeSent: true };
5044
+ return { cursor: seedCursor, ok: true, welcomeSent: true };
5044
5045
  }
5045
5046
  if (response.items.length === 0) return { cursor: null, ok: true };
5046
5047
  const newItems = response.items.filter(
@@ -5348,9 +5349,11 @@ async function runWebSocketConnection(opts) {
5348
5349
  try {
5349
5350
  const raw = data.toString();
5350
5351
  if (!raw || raw.length > 65536) {
5351
- log.warn(
5352
- `Ignoring oversized or empty WS message (${raw?.length ?? 0} bytes)`
5353
- );
5352
+ if (raw && raw.length > 65536) {
5353
+ log.warn(`Ignoring oversized WS message (${raw.length} bytes)`);
5354
+ } else {
5355
+ log.debug(`Ignoring empty WS frame (${raw?.length ?? 0} bytes)`);
5356
+ }
5354
5357
  return;
5355
5358
  }
5356
5359
  const msg = JSON.parse(raw);
@@ -8206,7 +8209,7 @@ var ORCHESTRATOR_TOOLS = {
8206
8209
  }),
8207
8210
  instructions: Type.Optional(
8208
8211
  Type.String({
8209
- description: "Concise instructions in simple markdown (bold, lists, inline code \u2014 no # headers). Brief a contractor: what to do, what done looks like. Skip obvious context."
8212
+ description: "3-8 bullet points max in simple markdown (bold, lists, inline code \u2014 no # headers). What to do, what done looks like, key constraints. Under 500 words. Skip context the worker can infer from the title."
8210
8213
  })
8211
8214
  ),
8212
8215
  file: Type.Optional(
@@ -8293,11 +8296,11 @@ var SHARED_TOOLS = {
8293
8296
  Type.Object(
8294
8297
  {
8295
8298
  reasoning: Type.String({
8296
- description: "Why these updates matter \u2014 what was learned from this task"
8299
+ description: "1-2 sentences: what changed and why. No restating known context."
8297
8300
  }),
8298
8301
  globalWoW: Type.Optional(
8299
8302
  Type.String({
8300
- description: "Full updated global Ways of Working markdown content (full replacement, not diff)"
8303
+ description: "Updated global Ways of Working (full replacement). Keep surgical \u2014 only add or modify relevant sections, do not inflate with restated context."
8301
8304
  })
8302
8305
  ),
8303
8306
  initiativeId: Type.Optional(
@@ -8307,7 +8310,7 @@ var SHARED_TOOLS = {
8307
8310
  ),
8308
8311
  initiativeContent: Type.Optional(
8309
8312
  Type.String({
8310
- description: "Full updated initiative content markdown (full replacement, not diff)"
8313
+ description: "Updated initiative content (full replacement). Keep surgical \u2014 evolve what exists, do not rewrite from scratch."
8311
8314
  })
8312
8315
  )
8313
8316
  },
@@ -8324,7 +8327,7 @@ var SHARED_TOOLS = {
8324
8327
  }),
8325
8328
  instructions: Type.Optional(
8326
8329
  Type.String({
8327
- description: "Instructions for the follow-up task"
8330
+ description: "Brief handoff: 2-3 bullet points max. The next worker gets parent task context."
8328
8331
  })
8329
8332
  )
8330
8333
  }),
@@ -8394,7 +8397,7 @@ var SHARED_TOOLS = {
8394
8397
  }),
8395
8398
  instructions: Type.Optional(
8396
8399
  Type.String({
8397
- description: "Concise instructions in simple markdown (bold, lists, inline code \u2014 no # headers). Brief a contractor: what to do, what done looks like. Skip obvious context."
8400
+ description: "3-8 bullet points max in simple markdown (bold, lists, inline code \u2014 no # headers). What to do, what done looks like, key constraints. Under 500 words. Skip context the worker can infer from the title."
8398
8401
  })
8399
8402
  ),
8400
8403
  file: Type.Optional(
@@ -8935,7 +8938,7 @@ You are the orchestrator. Your job: turn human intent into approved tasks, then
8935
8938
 
8936
8939
  You do NOT claim tasks, complete tasks, or do work directly \u2014 you have no access to deskfree_start_task or deskfree_complete_task. Spawn a sub-agent for each approved task and pass it the taskId.
8937
8940
  - When a human writes in a task thread, decide: does it need bot action? If yes \u2192 reopen and spawn sub-agent. If it's just confirmation or deferred \u2014 leave it for now.
8938
- - Write task instructions as rich markdown (bold, lists, inline code \u2014 no # headers). Brief a contractor who has never seen the codebase.
8941
+ - Write task instructions as 3-8 bullet points max (bold, lists, inline code \u2014 no # headers). What to do, what done looks like, key constraints. Under 500 words \u2014 brief a contractor, not write a spec.
8939
8942
  - Estimate token cost per task \u2014 consider files to read, reasoning, output.
8940
8943
  - One initiative per proposal \u2014 make multiple calls for multiple initiatives.
8941
8944
  - Initiative titles should reflect aspirations and outcomes, not activities. "AI Thought Leadership on LinkedIn" over "LinkedIn Content."
@@ -8944,10 +8947,10 @@ var DESKFREE_WORKER_DIRECTIVE = `## DeskFree Worker
8944
8947
  You are a worker sub-agent. Call \`deskfree_start_task\` with your taskId to claim and load context.
8945
8948
  Tools: deskfree_start_task, deskfree_update_file, deskfree_complete_task, deskfree_send_message, deskfree_propose.
8946
8949
  - Claim your task first with deskfree_start_task \u2014 this loads instructions, messages, and file context.
8947
- - Save work to linked files with deskfree_update_file (incrementally).
8950
+ - Save work to linked files with deskfree_update_file. Build up incrementally \u2014 start with structure/outline, then flesh out. Send an "ask" for review before going deep. The human should see the shape before the details.
8948
8951
  - Use deskfree_send_message with type "notify" for progress updates \u2014 what you're doing, what you found. Keep it brief.
8949
8952
  - Use deskfree_send_message with type "ask" when you need human input OR when your work is done for review. This surfaces to the main thread. Terminate after sending an ask.
8950
- - When completing: pass "learnings" to deskfree_complete_task if you have knowledge updates (WoW or initiative content). Pass "followUps" if the work revealed clear next steps. Knowledge updates and proposals happen atomically with completion \u2014 no separate tool calls needed.
8953
+ - When completing: pass "learnings" only if you have genuine new knowledge. WoW updates should be surgical \u2014 add or modify only the relevant section, do not restate existing content. Reasoning should be 1-2 sentences. Pass "followUps" as brief handoffs (title + 2-3 bullets each).
8951
8954
  - Only complete when the human has confirmed or no review is needed.
8952
8955
  - Write like a senior colleague giving a status update \u2014 not a report. 1-3 sentences for messages.
8953
8956
  - On 409 or 404 errors: STOP. Do not retry the same taskId. Call deskfree_state to find available tasks.`;