@atlasharness/atlascode 0.1.64 → 0.1.65

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/cli.js +139 -18
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -37092,9 +37092,9 @@ function formatAgentLine(agent) {
37092
37092
  function getPrompt(agents) {
37093
37093
  const list = agents.length > 0 ? agents.map(formatAgentLine).join(`
37094
37094
  `) : "- general-purpose: General-purpose agent for researching and executing multi-step tasks.";
37095
- return "Launch a subagent to run a self-contained task in an isolated context. " + "Provide a short description (3-5 words) and a fully self-contained prompt " + "(the subagent cannot see this conversation). " + "Be cost-aware about delegating: prefer to do the work inline in this " + "conversation for a small task with a known, bounded target (a single-file " + "edit, a quick lookup, a change you can finish without broad exploration) — " + "spawning a subagent has overhead. Delegate when the task is genuinely " + "parallelizable or would otherwise flood this context with material you do " + "not need to keep (a broad multi-file search, an isolated multi-step " + "implementation, or independent work that can run alongside your own). Keep " + "each delegated brief narrow and evidence-focused: name the exact goal, the " + "files or area, and the expected deliverable rather than a broad " + '"figure this out." Because the subagent cannot see this conversation, its ' + "prompt must be fully self-contained — state every constraint, file, and " + "reporting requirement it needs. " + `Available agent types and the tools they have access to:
37095
+ return "Launch a subagent to run a self-contained task in an isolated context. " + "Provide a short description (3-5 words) and a fully self-contained prompt " + "(the subagent cannot see this conversation). " + "Be cost-aware about delegating: prefer to do the work inline in this " + "conversation for a small task with a known, bounded target (a single-file " + "edit, a quick lookup, a change you can finish without broad exploration) — " + "spawning a subagent has overhead. Delegate when the task is genuinely " + "parallelizable or would otherwise flood this context with material you do " + "not need to keep (a broad multi-file search, an isolated multi-step " + "implementation, or independent work that can run alongside your own). Keep " + "each delegated brief narrow and evidence-focused: name the exact goal, the " + "files or area, and the expected deliverable rather than a broad " + '"figure this out." Because the subagent cannot see this conversation, its ' + "prompt must be fully self-contained — state every constraint, file, and " + "reporting requirement it needs. " + "Set run_in_background to true to launch a subagent that runs while you " + "continue working in this conversation; you will receive a task-notification " + "when it completes. Use this only for genuinely parallel work, not to defer " + "a result you need before you can proceed. " + `Available agent types and the tools they have access to:
37096
37096
  ${list}
37097
- ` + `The ${AGENT_TOOL_NAME} tool runs the subagent and returns its final result ` + "when it completes; act on that result once it is returned.";
37097
+ ` + `The ${AGENT_TOOL_NAME} tool runs the subagent and returns its final result ` + "when it completes; act on that result once it is returned. " + "Do not predict or assume what the subagent will find — wait for its " + "returned result and act on what it actually reports.";
37098
37098
  }
37099
37099
  var init_prompt = () => {};
37100
37100
 
@@ -37136,9 +37136,72 @@ async function runAgent(args) {
37136
37136
  turns: loopResult.turns
37137
37137
  };
37138
37138
  }
37139
+ function wrapPermissionGateForBackground(gate, onNeedsInput) {
37140
+ if (!gate)
37141
+ return;
37142
+ return async (tool, input, callContext) => {
37143
+ const verdict = await gate(tool, input, callContext);
37144
+ if (verdict.ask) {
37145
+ onNeedsInput({
37146
+ toolName: tool.name,
37147
+ reason: verdict.reason
37148
+ });
37149
+ }
37150
+ return verdict;
37151
+ };
37152
+ }
37153
+ async function runAsyncAgentLifecycle(args) {
37154
+ const { description, toolUseId, signal, agentId } = args;
37155
+ const wrappedCheckPermission = wrapPermissionGateForBackground(args.checkPermission, (req) => {
37156
+ enqueueAgentNotification({
37157
+ taskId: agentId,
37158
+ description,
37159
+ status: "needs_input",
37160
+ inputRequest: `Permission required for ${req.toolName}${req.reason ? `: ${req.reason}` : ""}`,
37161
+ ...toolUseId ? { toolUseId } : {}
37162
+ });
37163
+ });
37164
+ try {
37165
+ const { result } = await runAgent({
37166
+ ...args,
37167
+ checkPermission: wrappedCheckPermission
37168
+ });
37169
+ const finalMessage = result.content.map((b) => b.text).join("");
37170
+ enqueueAgentNotification({
37171
+ taskId: agentId,
37172
+ description,
37173
+ status: "completed",
37174
+ finalMessage: finalMessage || undefined,
37175
+ usage: {
37176
+ totalTokens: result.totalTokens,
37177
+ toolUses: result.totalToolUseCount,
37178
+ durationMs: result.totalDurationMs
37179
+ },
37180
+ ...toolUseId ? { toolUseId } : {}
37181
+ });
37182
+ } catch (err) {
37183
+ if (signal?.aborted) {
37184
+ enqueueAgentNotification({
37185
+ taskId: agentId,
37186
+ description,
37187
+ status: "killed",
37188
+ ...toolUseId ? { toolUseId } : {}
37189
+ });
37190
+ return;
37191
+ }
37192
+ enqueueAgentNotification({
37193
+ taskId: agentId,
37194
+ description,
37195
+ status: "failed",
37196
+ error: err instanceof Error ? err.message : String(err),
37197
+ ...toolUseId ? { toolUseId } : {}
37198
+ });
37199
+ }
37200
+ }
37139
37201
  var init_runAgent = __esm(() => {
37140
37202
  init_query2();
37141
37203
  init_agentToolUtils();
37204
+ init_localAgentTask();
37142
37205
  });
37143
37206
 
37144
37207
  // src/engine/tools/agent/AgentTool.ts
@@ -37164,6 +37227,8 @@ var init_AgentTool = __esm(() => {
37164
37227
  init_prompt();
37165
37228
  init_runAgent();
37166
37229
  init_coordinator();
37230
+ init_task2();
37231
+ init_localAgentTask();
37167
37232
  AGENT_TOOL_INPUT_SCHEMA = {
37168
37233
  type: "object",
37169
37234
  properties: {
@@ -37182,6 +37247,10 @@ var init_AgentTool = __esm(() => {
37182
37247
  model: {
37183
37248
  enum: ["small", "premium", "fast"],
37184
37249
  description: "Optional model override for this agent. Takes precedence over the agent definition's model. If omitted, inherits from the parent."
37250
+ },
37251
+ run_in_background: {
37252
+ type: "boolean",
37253
+ description: "Set to true to run this agent in the background. You will be notified when it completes."
37185
37254
  }
37186
37255
  },
37187
37256
  required: ["description", "prompt"]
@@ -37218,6 +37287,13 @@ var init_AgentTool = __esm(() => {
37218
37287
  ` + text
37219
37288
  };
37220
37289
  }
37290
+ if (c && c.status === "async_launched") {
37291
+ return {
37292
+ type: "tool_result",
37293
+ tool_use_id: toolUseID,
37294
+ content: "[agent launched in background] agentId=" + (c.agentId ?? "") + " output=" + (c.outputFile ?? "")
37295
+ };
37296
+ }
37221
37297
  return {
37222
37298
  type: "tool_result",
37223
37299
  tool_use_id: toolUseID,
@@ -37235,6 +37311,38 @@ var init_AgentTool = __esm(() => {
37235
37311
  const allowFanOut = isCoordinatorMode() && childSpawnDepth < MAX_WORKER_SPAWN_DEPTH;
37236
37312
  const resolvedTools = resolveAgentTools(agentDefinition, availableTools, allowFanOut).resolvedTools;
37237
37313
  const agentId = "agent-" + randomUUID5();
37314
+ if (input.run_in_background) {
37315
+ const outputFile = getTaskOutputPath(agentId);
37316
+ runAsyncAgentLifecycle({
37317
+ agentDefinition,
37318
+ prompt: input.prompt,
37319
+ tools: resolvedTools,
37320
+ modelProvider,
37321
+ parentRole,
37322
+ overrideRole: input.model,
37323
+ agentId,
37324
+ spawnDepth: childSpawnDepth,
37325
+ signal: ctx.signal,
37326
+ checkPermission: ctx.checkPermission,
37327
+ description: input.description
37328
+ }).catch((err) => {
37329
+ enqueueAgentNotification({
37330
+ taskId: agentId,
37331
+ description: input.description,
37332
+ status: "failed",
37333
+ error: err instanceof Error ? err.message : String(err)
37334
+ });
37335
+ });
37336
+ return {
37337
+ data: {
37338
+ status: "async_launched",
37339
+ agentId,
37340
+ description: input.description,
37341
+ prompt: input.prompt,
37342
+ outputFile
37343
+ }
37344
+ };
37345
+ }
37238
37346
  const { result } = await runAgent({
37239
37347
  agentDefinition,
37240
37348
  prompt: input.prompt,
@@ -79621,24 +79729,27 @@ function enqueueAgentNotification({
79621
79729
  usage,
79622
79730
  toolUseId,
79623
79731
  worktreePath,
79624
- worktreeBranch
79732
+ worktreeBranch,
79733
+ inputRequest
79625
79734
  }) {
79626
- let shouldEnqueue = false;
79627
- updateTaskState(taskId, setAppState, (task) => {
79628
- if (task.notified) {
79629
- return task;
79735
+ if (setAppState && status !== "needs_input") {
79736
+ let shouldEnqueue = false;
79737
+ updateTaskState(taskId, setAppState, (task) => {
79738
+ if (task.notified) {
79739
+ return task;
79740
+ }
79741
+ shouldEnqueue = true;
79742
+ return {
79743
+ ...task,
79744
+ notified: true
79745
+ };
79746
+ });
79747
+ if (!shouldEnqueue) {
79748
+ return;
79630
79749
  }
79631
- shouldEnqueue = true;
79632
- return {
79633
- ...task,
79634
- notified: true
79635
- };
79636
- });
79637
- if (!shouldEnqueue) {
79638
- return;
79639
79750
  }
79640
79751
  const escapedDescription = escapeXml(description);
79641
- const summary = status === "completed" ? `Agent "${escapedDescription}" completed` : status === "failed" ? `Agent "${escapedDescription}" failed: ${escapeXml(error || "Unknown error")}` : `Agent "${escapedDescription}" was stopped`;
79752
+ const summary = status === "completed" ? `Agent "${escapedDescription}" completed` : status === "failed" ? `Agent "${escapedDescription}" failed: ${escapeXml(error || "Unknown error")}` : status === "killed" ? `Agent "${escapedDescription}" was stopped` : status === "needs_input" ? `Agent "${escapedDescription}" needs input: ${escapeXml(inputRequest || "Permission request or question pending")}` : `Agent "${escapedDescription}" ${escapeXml(status)}`;
79642
79753
  const outputPath = getTaskOutputPath(taskId);
79643
79754
  const toolUseIdLine = toolUseId ? `
79644
79755
  <${TOOL_USE_ID_TAG}>${escapeXml(toolUseId)}</${TOOL_USE_ID_TAG}>` : "";
@@ -180621,6 +180732,7 @@ __export(exports_engineCompat, {
180621
180732
  roughTokenCountEstimationForContent: () => roughTokenCountEstimationForContent,
180622
180733
  roughTokenCountEstimationForMessages: () => roughTokenCountEstimationForMessages,
180623
180734
  runAgent: () => runAgent,
180735
+ runAsyncAgentLifecycle: () => runAsyncAgentLifecycle,
180624
180736
  runCleanupFunctions: () => runCleanupFunctions2,
180625
180737
  runHooksStream: () => runHooksStream,
180626
180738
  runPostCompactCleanup: () => runPostCompactCleanup,
@@ -180712,6 +180824,7 @@ __export(exports_engineCompat, {
180712
180824
  waitForSessionMemoryExtraction: () => waitForSessionMemoryExtraction,
180713
180825
  waitForTeammatesToBecomeIdle: () => waitForTeammatesToBecomeIdle,
180714
180826
  worktreeBranchName: () => worktreeBranchName,
180827
+ wrapPermissionGateForBackground: () => wrapPermissionGateForBackground,
180715
180828
  writeCronTasks: () => writeCronTasks,
180716
180829
  writeToMailbox: () => writeToMailbox
180717
180830
  });
@@ -275861,7 +275974,7 @@ function extractPartialResult(messages) {
275861
275974
  }
275862
275975
  return;
275863
275976
  }
275864
- async function runAsyncAgentLifecycle({
275977
+ async function runAsyncAgentLifecycle2({
275865
275978
  taskId,
275866
275979
  abortController,
275867
275980
  makeStream,
@@ -311132,7 +311245,7 @@ async function resumeAgentBackground({
311132
311245
  invocationEmitted: false
311133
311246
  };
311134
311247
  const wrapWithCwd = (fn) => resumedWorktreePath ? runWithCwdOverride(resumedWorktreePath, fn) : fn();
311135
- runWithAgentContext(asyncAgentContext, () => wrapWithCwd(() => runAsyncAgentLifecycle({
311248
+ runWithAgentContext(asyncAgentContext, () => wrapWithCwd(() => runAsyncAgentLifecycle2({
311136
311249
  taskId: agentBackgroundTask.agentId,
311137
311250
  abortController: agentBackgroundTask.abortController,
311138
311251
  makeStream: (onCacheSafeParams) => runAgent2({
@@ -321060,6 +321173,10 @@ function buildAgentLoopParams(m) {
321060
321173
  toolUseContext: m.toolUseContext
321061
321174
  }),
321062
321175
  toolContext: m.toolUseContext,
321176
+ hasPendingBackgroundTasks: () => {
321177
+ const tasks = m.toolUseContext?.getAppState?.()?.tasks;
321178
+ return tasks ? hasNonTerminalTasks(tasks) : false;
321179
+ },
321063
321180
  hooks: createLoopHooks({
321064
321181
  options: {
321065
321182
  sessionId: getSessionId(),
@@ -321091,6 +321208,7 @@ function buildAgentLoopParams(m) {
321091
321208
  var init_agentLoopDeps = __esm(() => {
321092
321209
  init_modelprovider2();
321093
321210
  init_engine();
321211
+ init_Task();
321094
321212
  init_settings3();
321095
321213
  init_shared();
321096
321214
  init_bootstrap();
@@ -425283,6 +425401,9 @@ import { randomBytes as randomBytes22 } from "crypto";
425283
425401
  function isTerminalTaskStatus2(status) {
425284
425402
  return status === "completed" || status === "failed" || status === "killed";
425285
425403
  }
425404
+ function hasNonTerminalTasks(tasks) {
425405
+ return Object.values(tasks).some((t) => !isTerminalTaskStatus2(t.status));
425406
+ }
425286
425407
  function getTaskIdPrefix(type) {
425287
425408
  return TASK_ID_PREFIXES[type] ?? "x";
425288
425409
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlasharness/atlascode",
3
- "version": "0.1.64",
3
+ "version": "0.1.65",
4
4
  "description": "AtlasCode \u2014 Coding Agent for the domestic computing ecosystem (Ascend NPU + domestic LLM backends)",
5
5
  "bin": {
6
6
  "atlas": "dist/cli.js",