neoctl 0.2.35 → 0.2.36

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 (71) hide show
  1. package/dist/agents/agent-tool-persistence.test.d.ts +1 -0
  2. package/dist/agents/agent-tool-persistence.test.js +313 -0
  3. package/dist/agents/agent-tool-persistence.test.js.map +1 -0
  4. package/dist/agents/agent-tool.js +137 -60
  5. package/dist/agents/agent-tool.js.map +1 -1
  6. package/dist/agents/local-agent-task.d.ts +41 -0
  7. package/dist/agents/local-agent-task.js +3 -0
  8. package/dist/agents/local-agent-task.js.map +1 -1
  9. package/dist/agents/no-nested-delegation.test.d.ts +1 -0
  10. package/dist/agents/no-nested-delegation.test.js +38 -0
  11. package/dist/agents/no-nested-delegation.test.js.map +1 -0
  12. package/dist/agents/smoke-agent-lifecycle.d.ts +1 -0
  13. package/dist/agents/smoke-agent-lifecycle.js +188 -0
  14. package/dist/agents/smoke-agent-lifecycle.js.map +1 -0
  15. package/dist/core/query-engine.js +1 -1
  16. package/dist/core/query-engine.js.map +1 -1
  17. package/dist/core/query.d.ts +3 -1
  18. package/dist/core/query.js +16 -3
  19. package/dist/core/query.js.map +1 -1
  20. package/dist/core/run-agent-pause.test.d.ts +1 -0
  21. package/dist/core/run-agent-pause.test.js +52 -0
  22. package/dist/core/run-agent-pause.test.js.map +1 -0
  23. package/dist/core/run-agent-persistence.test.d.ts +1 -0
  24. package/dist/core/run-agent-persistence.test.js +222 -0
  25. package/dist/core/run-agent-persistence.test.js.map +1 -0
  26. package/dist/core/run-agent.d.ts +11 -0
  27. package/dist/core/run-agent.js +56 -11
  28. package/dist/core/run-agent.js.map +1 -1
  29. package/dist/core/smoke-core-loop.js +8 -7
  30. package/dist/core/smoke-core-loop.js.map +1 -1
  31. package/dist/model/model-metadata.json +99 -99
  32. package/dist/repl/index.js +20 -26
  33. package/dist/repl/index.js.map +1 -1
  34. package/dist/session/session-store-safety.test.d.ts +1 -0
  35. package/dist/session/session-store-safety.test.js +107 -0
  36. package/dist/session/session-store-safety.test.js.map +1 -0
  37. package/dist/session/session-store.d.ts +1 -0
  38. package/dist/session/session-store.js +64 -5
  39. package/dist/session/session-store.js.map +1 -1
  40. package/dist/session/tool-result-memory.d.ts +3 -1
  41. package/dist/session/tool-result-memory.js.map +1 -1
  42. package/dist/tasks/subagent-tools.d.ts +4 -1
  43. package/dist/tasks/subagent-tools.js +85 -24
  44. package/dist/tasks/subagent-tools.js.map +1 -1
  45. package/dist/tasks/subagent-tools.test.d.ts +1 -0
  46. package/dist/tasks/subagent-tools.test.js +158 -0
  47. package/dist/tasks/subagent-tools.test.js.map +1 -0
  48. package/dist/tasks/task-ack-size.test.d.ts +1 -0
  49. package/dist/tasks/task-ack-size.test.js +100 -0
  50. package/dist/tasks/task-ack-size.test.js.map +1 -0
  51. package/dist/tasks/task-persistence.d.ts +22 -0
  52. package/dist/tasks/task-persistence.js +194 -0
  53. package/dist/tasks/task-persistence.js.map +1 -0
  54. package/dist/tasks/task-persistence.test.d.ts +1 -0
  55. package/dist/tasks/task-persistence.test.js +331 -0
  56. package/dist/tasks/task-persistence.test.js.map +1 -0
  57. package/dist/tasks/task-store.d.ts +45 -3
  58. package/dist/tasks/task-store.js +292 -16
  59. package/dist/tasks/task-store.js.map +1 -1
  60. package/dist/tools/tool.d.ts +5 -0
  61. package/dist/tools/tool.js.map +1 -1
  62. package/dist/web/index.d.ts +99 -6
  63. package/dist/web/index.js +93 -56
  64. package/dist/web/index.js.map +1 -1
  65. package/dist/web/smoke-task-session-entrypoints.d.ts +1 -0
  66. package/dist/web/smoke-task-session-entrypoints.js +75 -0
  67. package/dist/web/smoke-task-session-entrypoints.js.map +1 -0
  68. package/dist/web/smoke-web-agent-tasks.d.ts +1 -0
  69. package/dist/web/smoke-web-agent-tasks.js +50 -0
  70. package/dist/web/smoke-web-agent-tasks.js.map +1 -0
  71. package/package.json +4 -4
@@ -1,99 +1,99 @@
1
- {
2
- "updatedAt": "2026-09-05",
3
- "notes": [
4
- "Static metadata for the supported multimodal GPT model aliases.",
5
- "MODEL_CONTEXT_WINDOW_TOKENS or OPENAI_CONTEXT_WINDOW_TOKENS overrides contextWindowTokens at runtime.",
6
- "modelIds are matched exactly."
7
- ],
8
- "sources": {
9
- "openai-models": "https://developers.openai.com/api/docs/models",
10
- "openai-reasoning": "https://developers.openai.com/api/docs/guides/reasoning"
11
- },
12
- "models": [
13
- {
14
- "id": "gpt-5.6-sol",
15
- "provider": "openai",
16
- "modelIds": [
17
- "gpt-5.6",
18
- "gpt-5.6-sol"
19
- ],
20
- "contextWindowTokens": 256000,
21
- "maxOutputTokens": 128000,
22
- "knowledgeCutoff": "2026-02-16",
23
- "reasoning": true,
24
- "imageInput": true,
25
- "source": "openai-models",
26
- "reasoningEfforts": [
27
- "none",
28
- "low",
29
- "medium",
30
- "high",
31
- "xhigh",
32
- "max"
33
- ]
34
- },
35
- {
36
- "id": "gpt-5.6-terra",
37
- "provider": "openai",
38
- "modelIds": [
39
- "gpt-5.6-terra"
40
- ],
41
- "contextWindowTokens": 256000,
42
- "maxOutputTokens": 128000,
43
- "knowledgeCutoff": "2026-02-16",
44
- "reasoning": true,
45
- "imageInput": true,
46
- "source": "openai-models",
47
- "reasoningEfforts": [
48
- "none",
49
- "low",
50
- "medium",
51
- "high",
52
- "xhigh",
53
- "max"
54
- ]
55
- },
56
- {
57
- "id": "gpt-5.6-luna",
58
- "provider": "openai",
59
- "modelIds": [
60
- "gpt-5.6-luna"
61
- ],
62
- "contextWindowTokens": 256000,
63
- "maxOutputTokens": 128000,
64
- "knowledgeCutoff": "2026-02-16",
65
- "reasoning": true,
66
- "imageInput": true,
67
- "source": "openai-models",
68
- "reasoningEfforts": [
69
- "none",
70
- "low",
71
- "medium",
72
- "high",
73
- "xhigh",
74
- "max"
75
- ]
76
- },
77
- {
78
- "id": "gpt-6-astra",
79
- "provider": "openai",
80
- "modelIds": [
81
- "gpt-6",
82
- "gpt-6-astra"
83
- ],
84
- "contextWindowTokens": 256000,
85
- "maxOutputTokens": 128000,
86
- "reasoning": true,
87
- "imageInput": true,
88
- "source": "openai-models",
89
- "reasoningEfforts": [
90
- "none",
91
- "low",
92
- "medium",
93
- "high",
94
- "xhigh",
95
- "max"
96
- ]
97
- }
98
- ]
99
- }
1
+ {
2
+ "updatedAt": "2026-09-05",
3
+ "notes": [
4
+ "Static metadata for the supported multimodal GPT model aliases.",
5
+ "MODEL_CONTEXT_WINDOW_TOKENS or OPENAI_CONTEXT_WINDOW_TOKENS overrides contextWindowTokens at runtime.",
6
+ "modelIds are matched exactly."
7
+ ],
8
+ "sources": {
9
+ "openai-models": "https://developers.openai.com/api/docs/models",
10
+ "openai-reasoning": "https://developers.openai.com/api/docs/guides/reasoning"
11
+ },
12
+ "models": [
13
+ {
14
+ "id": "gpt-5.6-sol",
15
+ "provider": "openai",
16
+ "modelIds": [
17
+ "gpt-5.6",
18
+ "gpt-5.6-sol"
19
+ ],
20
+ "contextWindowTokens": 256000,
21
+ "maxOutputTokens": 128000,
22
+ "knowledgeCutoff": "2026-02-16",
23
+ "reasoning": true,
24
+ "imageInput": true,
25
+ "source": "openai-models",
26
+ "reasoningEfforts": [
27
+ "none",
28
+ "low",
29
+ "medium",
30
+ "high",
31
+ "xhigh",
32
+ "max"
33
+ ]
34
+ },
35
+ {
36
+ "id": "gpt-5.6-terra",
37
+ "provider": "openai",
38
+ "modelIds": [
39
+ "gpt-5.6-terra"
40
+ ],
41
+ "contextWindowTokens": 256000,
42
+ "maxOutputTokens": 128000,
43
+ "knowledgeCutoff": "2026-02-16",
44
+ "reasoning": true,
45
+ "imageInput": true,
46
+ "source": "openai-models",
47
+ "reasoningEfforts": [
48
+ "none",
49
+ "low",
50
+ "medium",
51
+ "high",
52
+ "xhigh",
53
+ "max"
54
+ ]
55
+ },
56
+ {
57
+ "id": "gpt-5.6-luna",
58
+ "provider": "openai",
59
+ "modelIds": [
60
+ "gpt-5.6-luna"
61
+ ],
62
+ "contextWindowTokens": 256000,
63
+ "maxOutputTokens": 128000,
64
+ "knowledgeCutoff": "2026-02-16",
65
+ "reasoning": true,
66
+ "imageInput": true,
67
+ "source": "openai-models",
68
+ "reasoningEfforts": [
69
+ "none",
70
+ "low",
71
+ "medium",
72
+ "high",
73
+ "xhigh",
74
+ "max"
75
+ ]
76
+ },
77
+ {
78
+ "id": "gpt-6-astra",
79
+ "provider": "openai",
80
+ "modelIds": [
81
+ "gpt-6",
82
+ "gpt-6-astra"
83
+ ],
84
+ "contextWindowTokens": 256000,
85
+ "maxOutputTokens": 128000,
86
+ "reasoning": true,
87
+ "imageInput": true,
88
+ "source": "openai-models",
89
+ "reasoningEfforts": [
90
+ "none",
91
+ "low",
92
+ "medium",
93
+ "high",
94
+ "xhigh",
95
+ "max"
96
+ ]
97
+ }
98
+ ]
99
+ }
@@ -37,7 +37,7 @@ import { buildEffectiveSystemPrompt } from "../context/prompts.js";
37
37
  import { writeSessionMarkdownExport } from "../session/session-export.js";
38
38
  import { readClipboard } from "./clipboard.js";
39
39
  import { openDirectory } from "../open-directory.js";
40
- import { runWebServer } from "../web/index.js";
40
+ import { runWebServer, activateSession, sessionAgentTasks, createResumeParentContext, createTaskNotificationSource } from "../web/index.js";
41
41
  import { getNeoctlHome } from "../paths.js";
42
42
  import { FileSystemSkillCatalog } from "../skills/skill-filesystem.js";
43
43
  import { createSkillAwareCanUseTool, createSkillTool, requireSkillName } from "../skills/skill-tool.js";
@@ -230,22 +230,6 @@ async function buildSkillCatalogPromptSection(catalog) {
230
230
  ].join("\n"),
231
231
  };
232
232
  }
233
- function createTaskNotificationSource(taskStore) {
234
- return {
235
- collectUnnotifiedCompletions() {
236
- return taskStore.collectUnnotifiedCompletions().map((task) => ({
237
- taskId: task.taskId,
238
- agentId: task.agentId,
239
- status: task.status,
240
- type: task.type,
241
- content: task.result?.content ?? task.error ?? "",
242
- }));
243
- },
244
- markNotified(taskId) {
245
- taskStore.markNotified(taskId);
246
- },
247
- };
248
- }
249
233
  async function createRuntime(options = {}) {
250
234
  const envLoad = loadDefaultDotEnvFiles({ override: true });
251
235
  const modelConfig = readModelProviderConfig(process.env);
@@ -284,16 +268,14 @@ async function createRuntime(options = {}) {
284
268
  tools.register(tool);
285
269
  const agentRuntime = { modelGateway, tools, taskStore, agentActivityStore };
286
270
  tools.register(createAgentTool(agentRuntime));
271
+ let runtime;
287
272
  const resumeHandler = async (taskId, directive) => {
288
- const dummyContext = {
289
- agentId: "main",
290
- tools,
291
- appState: new (await import("../app/app-state.js")).InMemoryAppState("main"),
273
+ const parentContext = {
274
+ ...createResumeParentContext(runtime.engine, tools, process.cwd()),
292
275
  secrets: secretStore,
293
276
  secretRedactions,
294
- emit: () => undefined,
295
277
  };
296
- return resumeAgentTask(taskId, directive, agentRuntime, taskStore, dummyContext);
278
+ return resumeAgentTask(taskId, directive, agentRuntime, taskStore, parentContext);
297
279
  };
298
280
  for (const tool of createSubagentTools(taskStore, resumeHandler))
299
281
  tools.register(tool);
@@ -322,8 +304,9 @@ async function createRuntime(options = {}) {
322
304
  },
323
305
  });
324
306
  await engine.initialize();
307
+ activateSession({ engine, taskStore });
325
308
  const initialMetrics = await engine.contextMetrics();
326
- return {
309
+ runtime = {
327
310
  engine,
328
311
  communicationLogger,
329
312
  modelGateway,
@@ -340,6 +323,7 @@ async function createRuntime(options = {}) {
340
323
  envPath: process.env.NEO_ENV_FILE?.trim() ? path.resolve(process.env.NEO_ENV_FILE.trim()) : envLoad.userDotEnvPath,
341
324
  envNotice: envLoad.createdUserDotEnv ? formatCreatedEnvNotice(envLoad.userDotEnvPath) : undefined,
342
325
  };
326
+ return runtime;
343
327
  }
344
328
  function syncImageGenerationTool(runtime, provider) {
345
329
  runtime.tools.unregister("image2");
@@ -355,7 +339,7 @@ function parseResumeFlag(value) {
355
339
  return ["1", "true", "yes", "latest"].includes(value.toLowerCase());
356
340
  }
357
341
  function activeBackgroundTasks(runtime) {
358
- return runtime.taskStore.list().filter((task) => !runtime.taskStore.isTerminal(task));
342
+ return sessionAgentTasks(runtime).filter((task) => !runtime.taskStore.isTerminal(task));
359
343
  }
360
344
  function debounceVoid(callback, delayMs) {
361
345
  let timer;
@@ -378,7 +362,10 @@ function debounceVoid(callback, delayMs) {
378
362
  }
379
363
  function activeAgentActivities(runtime) {
380
364
  const now = Date.now();
365
+ const visibleTaskIds = new Set(sessionAgentTasks(runtime).map((task) => task.taskId));
381
366
  return runtime.agentActivityStore.list().filter((activity) => {
367
+ if (activity.taskId && !visibleTaskIds.has(activity.taskId))
368
+ return false;
382
369
  if (activity.status === "running" || activity.status === "pending")
383
370
  return true;
384
371
  const completedAt = activity.completedAt ? new Date(activity.completedAt).getTime() : new Date(activity.updatedAt).getTime();
@@ -598,7 +585,10 @@ function InkRepl({ runtime, initialCommandLine }) {
598
585
  return () => clearInterval(interval);
599
586
  }, [busy, backgroundTaskCount, backgroundSessionRuns.length, agentActivities.length, runtime]);
600
587
  useEffect(() => {
601
- const updateBackgroundTasks = () => setBackgroundTasks(activeBackgroundTasks(runtime));
588
+ const updateBackgroundTasks = () => {
589
+ setBackgroundTasks(activeBackgroundTasks(runtime));
590
+ setAgentActivities(activeAgentActivities(runtime));
591
+ };
602
592
  updateBackgroundTasks();
603
593
  return runtime.taskStore.subscribe(updateBackgroundTasks);
604
594
  }, [runtime]);
@@ -852,6 +842,7 @@ function InkRepl({ runtime, initialCommandLine }) {
852
842
  syncBackgroundSessionRuns();
853
843
  setSessionsBrowser((current) => current ? { ...current, runningSessionIds: runningSessionIds(backgroundSessionRunsRef.current) } : current);
854
844
  runtime.engine = run.engine;
845
+ activateSession(runtime);
855
846
  activeAbortController.current = run.abortController;
856
847
  interruptArmed.current = false;
857
848
  activePromptRunRef.current = run.promise;
@@ -1081,6 +1072,7 @@ function InkRepl({ runtime, initialCommandLine }) {
1081
1072
  }
1082
1073
  if (command.type === "reset") {
1083
1074
  runtime.engine.reset();
1075
+ activateSession(runtime);
1084
1076
  runtime.usage.reset();
1085
1077
  setStatus(await resetStatus(runtime));
1086
1078
  append(systemLine("transcript reset"));
@@ -1123,6 +1115,7 @@ function InkRepl({ runtime, initialCommandLine }) {
1123
1115
  detachRunningForeground("new session");
1124
1116
  runtime.engine = runtime.engine.forkForSession(undefined, false);
1125
1117
  await runtime.engine.initialize();
1118
+ activateSession(runtime);
1126
1119
  const snapshot = runtime.engine.snapshot().session;
1127
1120
  const metrics = await runtime.engine.contextMetrics();
1128
1121
  runtime.usage.reset();
@@ -2995,6 +2988,7 @@ async function handleResumeCommand(sessionId, runtime, append) {
2995
2988
  try {
2996
2989
  runtime.engine = runtime.engine.forkForSession(sessionId, true);
2997
2990
  await runtime.engine.initialize();
2991
+ activateSession(runtime);
2998
2992
  const snapshot = runtime.engine.snapshot().session;
2999
2993
  if (!snapshot)
3000
2994
  throw new Error("session transcripts are disabled");