@adecore/agents 0.23.1 → 0.24.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.
- package/README.md +3 -3
- package/dist/chat/attachment-store.js +4 -5
- package/dist/chat/backend.d.ts +6 -1
- package/dist/chat/background-work.d.ts +1 -1
- package/dist/chat/background-work.js +2 -1
- package/dist/chat/chat-core.d.ts +53 -161
- package/dist/chat/chat-core.js +146 -112
- package/dist/chat/chat-log.js +3 -3
- package/dist/chat/chat-process.d.ts +21 -0
- package/dist/chat/chat-process.js +109 -9
- package/dist/chat/chat-session.d.ts +10 -17
- package/dist/chat/chat-session.js +141 -182
- package/dist/chat/chat-store.d.ts +1 -0
- package/dist/chat/chat-store.js +105 -1
- package/dist/chat/claude-backend.d.ts +4 -0
- package/dist/chat/claude-backend.js +51 -27
- package/dist/chat/claude-protocol.d.ts +12 -0
- package/dist/chat/claude-protocol.js +137 -7
- package/dist/chat/claude-title.d.ts +1 -3
- package/dist/chat/claude-title.js +11 -39
- package/dist/chat/claude-transcript.d.ts +1 -0
- package/dist/chat/claude-transcript.js +36 -17
- package/dist/chat/codex-backend.d.ts +21 -1
- package/dist/chat/codex-backend.js +168 -10
- package/dist/chat/codex-protocol.d.ts +2 -0
- package/dist/chat/codex-protocol.js +37 -3
- package/dist/chat/codex-thread.js +1 -3
- package/dist/chat/codex-transport.d.ts +3 -0
- package/dist/chat/codex-transport.js +38 -35
- package/dist/chat/context-breakdown.js +2 -2
- package/dist/chat/errors.d.ts +1 -1
- package/dist/chat/external-sessions.js +2 -2
- package/dist/chat/fixtures/claude-2.1.296-goal.json +136 -0
- package/dist/chat/fixtures/claude-projects/-work-demo/5f1c2a9e-0b7d-4c1e-9a53-3e2f8d6b7a10.jsonl +2 -0
- package/dist/chat/index.d.ts +29 -0
- package/dist/chat/index.js +23 -0
- package/dist/chat/projector.d.ts +2 -1
- package/dist/chat/projector.js +12 -3
- package/dist/chat/request-summary.js +1 -4
- package/dist/chat/subagent-settlement.js +1 -3
- package/dist/chat/thread.d.ts +3 -0
- package/dist/chat/thread.js +20 -3
- package/dist/chat/ui-queries.d.ts +2 -0
- package/dist/chat/ui-queries.js +40 -5
- package/dist/chat/ui-replies.d.ts +33 -0
- package/dist/chat/ui-replies.js +152 -0
- package/dist/context/index.d.ts +2 -0
- package/dist/context/index.js +3 -0
- package/dist/coordination/index.d.ts +15 -0
- package/dist/coordination/index.js +16 -0
- package/dist/host/handlers.js +8 -0
- package/dist/host/index.d.ts +7 -0
- package/dist/host/index.js +7 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +10 -0
- package/dist/providers/accounts/status.js +1 -3
- package/dist/providers/claude.js +3 -1
- package/dist/providers/codex.js +3 -1
- package/dist/providers/index.d.ts +14 -0
- package/dist/providers/index.js +12 -0
- package/dist/run-process.js +54 -14
- package/dist/skills.d.ts +1 -0
- package/dist/skills.js +4 -0
- package/dist/tasks/task-coordinator.d.ts +4 -0
- package/dist/tasks/task-coordinator.js +16 -2
- package/dist/tasks/wiring.js +7 -1
- package/dist/{providers/accounts/test-accounts.d.ts → testing/accounts.d.ts} +2 -2
- package/dist/{providers/accounts/test-accounts.js → testing/accounts.js} +3 -3
- package/dist/testing/bin/fake-claude.d.ts +1 -0
- package/dist/testing/bin/fake-claude.js +6 -0
- package/dist/testing/bin/fake-codex.d.ts +1 -0
- package/dist/testing/bin/fake-codex.js +6 -0
- package/dist/{chat → testing}/fake-claude.d.ts +1 -1
- package/dist/{chat → testing}/fake-claude.js +0 -4
- package/dist/{chat → testing}/fake-cli.d.ts +1 -1
- package/dist/{chat → testing}/fake-codex.d.ts +1 -1
- package/dist/{chat → testing}/fake-codex.js +70 -8
- package/dist/testing/index.d.ts +6 -0
- package/dist/testing/index.js +7 -0
- package/dist/{outbox → testing}/manual-clock.d.ts +1 -1
- package/dist/{watch-test-helpers.d.ts → testing/watch.d.ts} +1 -1
- package/dist/usage/exchange.d.ts +5 -3
- package/dist/usage/exchange.js +25 -16
- package/dist/usage/index-file.d.ts +1 -0
- package/dist/usage/index-file.js +20 -2
- package/dist/usage/index.d.ts +9 -0
- package/dist/usage/index.js +6 -0
- package/dist/usage/limits/normalize.js +1 -3
- package/dist/usage/pricing.d.ts +5 -3
- package/dist/usage/pricing.js +28 -19
- package/dist/usage/scanner.js +39 -11
- package/dist/usage/usage-service.js +8 -3
- package/package.json +72 -11
- package/src/chat/attachment-store.ts +4 -6
- package/src/chat/backend.ts +8 -0
- package/src/chat/background-work.ts +2 -2
- package/src/chat/chat-core.ts +221 -143
- package/src/chat/chat-log.ts +3 -3
- package/src/chat/chat-process.ts +128 -8
- package/src/chat/chat-session.ts +153 -204
- package/src/chat/chat-store.ts +104 -1
- package/src/chat/claude-backend.ts +58 -26
- package/src/chat/claude-protocol.ts +147 -8
- package/src/chat/claude-title.ts +11 -39
- package/src/chat/claude-transcript.ts +38 -18
- package/src/chat/codex-backend.ts +182 -20
- package/src/chat/codex-protocol.ts +40 -5
- package/src/chat/codex-thread.ts +1 -4
- package/src/chat/codex-transport.ts +45 -35
- package/src/chat/context-breakdown.ts +2 -2
- package/src/chat/errors.ts +1 -0
- package/src/chat/external-sessions.ts +2 -2
- package/src/chat/fixtures/claude-2.1.296-goal.json +136 -0
- package/src/chat/fixtures/claude-projects/-work-demo/5f1c2a9e-0b7d-4c1e-9a53-3e2f8d6b7a10.jsonl +2 -0
- package/src/chat/index.ts +49 -0
- package/src/chat/projector.ts +13 -4
- package/src/chat/request-summary.ts +8 -5
- package/src/chat/subagent-settlement.ts +1 -4
- package/src/chat/thread.ts +22 -3
- package/src/chat/ui-queries.ts +46 -5
- package/src/chat/ui-replies.ts +187 -0
- package/src/context/index.ts +26 -0
- package/src/coordination/index.ts +67 -0
- package/src/host/handlers.ts +8 -0
- package/src/host/index.ts +8 -0
- package/src/index.ts +20 -0
- package/src/providers/accounts/status.ts +1 -4
- package/src/providers/claude.ts +3 -1
- package/src/providers/codex.ts +3 -1
- package/src/providers/index.ts +15 -0
- package/src/run-process.ts +56 -16
- package/src/skills.ts +5 -0
- package/src/tasks/task-coordinator.ts +22 -2
- package/src/tasks/wiring.ts +7 -1
- package/src/{providers/accounts/test-accounts.ts → testing/accounts.ts} +4 -4
- package/src/testing/bin/fake-claude.ts +7 -0
- package/src/testing/bin/fake-codex.ts +7 -0
- package/src/{chat → testing}/fake-claude.ts +1 -5
- package/src/{chat → testing}/fake-cli.ts +1 -1
- package/src/{chat → testing}/fake-codex.ts +75 -6
- package/src/testing/index.ts +7 -0
- package/src/{outbox → testing}/manual-clock.ts +1 -1
- package/src/{watch-test-helpers.ts → testing/watch.ts} +1 -1
- package/src/usage/exchange.ts +31 -20
- package/src/usage/index-file.ts +23 -2
- package/src/usage/index.ts +10 -0
- package/src/usage/limits/normalize.ts +1 -4
- package/src/usage/pricing.ts +34 -23
- package/src/usage/scanner.ts +48 -11
- package/src/usage/usage-service.ts +8 -3
- /package/dist/{chat → testing}/fake-cli.js +0 -0
- /package/dist/{outbox → testing}/manual-clock.js +0 -0
- /package/dist/{watch-test-helpers.js → testing/watch.js} +0 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { type OutboxEntryOf, OutboxStore, type OutboxWorkShape, type OutboxEntryFields, type OutboxStoreOptions } from '../outbox/outbox.ts';
|
|
2
|
+
export { RETRY_DELAYS_MS, type OutboxClock, systemClock, type OutboxOutcome, type OutboxHandlers, OutboxWorker, type OutboxWorkerOptions } from '../outbox/outbox-worker.ts';
|
|
3
|
+
export { restartBackgroundLimits, type RestartedOutbox } from '../tasks/background-limit.ts';
|
|
4
|
+
export { EndChildrenWorkSchema, endChildren, type EndChildrenWork, type EndChildrenEntry, type EndChildrenOutbox, type EndChildrenDeps, type EndChildren } from '../tasks/end-children.ts';
|
|
5
|
+
export { type TaskCoordinatorDeps, TaskCoordinator } from '../tasks/task-coordinator.ts';
|
|
6
|
+
export { TaskStore, type TaskListener, type TaskEvent, type TaskSink } from '../tasks/task-store.ts';
|
|
7
|
+
export { BackgroundLimitWorkSchema, WakeParentWorkSchema, GiveTaskWorkSchema, DeliverWaitingWorkSchema, type BackgroundLimitWork, type WakeParentWork, type GiveTaskWork, type DeliverWaitingWork, type TaskWork, type BackgroundLimitEntry, type AnyOutboxEntry, type TaskOutbox } from '../tasks/task-work.ts';
|
|
8
|
+
export { type ChatRequests, chatRequests, WAITING_GRACE_MS, WaitingObserver, type WaitingRequest, type WaitingObserverDeps, type WaitingWords } from '../tasks/waiting-child.ts';
|
|
9
|
+
export { RESULT_PREVIEW_BYTES, wakePrompt } from '../tasks/wake-parent.ts';
|
|
10
|
+
export { type TaskVerbs, type TaskWords, wireTasks, type TaskChats, type TaskRecord, type TaskWiringDeps, type TaskWiring } from '../tasks/wiring.ts';
|
|
11
|
+
export { DeliverMessageWorkSchema, deliverMessageHandler, type DeliverMessageWork, type DeliverMessageEntry, type DeliverMessageDeps } from '../messages/deliver-message.ts';
|
|
12
|
+
export { type MessageWords, type ChatNoticeTargets, type ChatDelivery, chatNoticeTargets, deliverToChat, showNotices, type NoticeChat } from '../messages/deliver-notice.ts';
|
|
13
|
+
export { NoticeNotes, unshownNotes } from '../messages/notice-notes.ts';
|
|
14
|
+
export { MAX_NOTICES, NOTICE_MAX_AGE_MS, type Notice, NoticeStore } from '../messages/notice-store.ts';
|
|
15
|
+
export { AgentLineageStore } from '../lineage.ts';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Public API: exports.test.ts snapshots this list, so a name added or dropped here is an API change.
|
|
2
|
+
export { OutboxStore } from '../outbox/outbox.js';
|
|
3
|
+
export { RETRY_DELAYS_MS, systemClock, OutboxWorker } from '../outbox/outbox-worker.js';
|
|
4
|
+
export { restartBackgroundLimits } from '../tasks/background-limit.js';
|
|
5
|
+
export { EndChildrenWorkSchema, endChildren } from '../tasks/end-children.js';
|
|
6
|
+
export { TaskCoordinator } from '../tasks/task-coordinator.js';
|
|
7
|
+
export { TaskStore } from '../tasks/task-store.js';
|
|
8
|
+
export { BackgroundLimitWorkSchema, WakeParentWorkSchema, GiveTaskWorkSchema, DeliverWaitingWorkSchema } from '../tasks/task-work.js';
|
|
9
|
+
export { chatRequests, WAITING_GRACE_MS, WaitingObserver } from '../tasks/waiting-child.js';
|
|
10
|
+
export { RESULT_PREVIEW_BYTES, wakePrompt } from '../tasks/wake-parent.js';
|
|
11
|
+
export { wireTasks } from '../tasks/wiring.js';
|
|
12
|
+
export { DeliverMessageWorkSchema, deliverMessageHandler } from '../messages/deliver-message.js';
|
|
13
|
+
export { chatNoticeTargets, deliverToChat, showNotices } from '../messages/deliver-notice.js';
|
|
14
|
+
export { NoticeNotes, unshownNotes } from '../messages/notice-notes.js';
|
|
15
|
+
export { MAX_NOTICES, NOTICE_MAX_AGE_MS, NoticeStore } from '../messages/notice-store.js';
|
|
16
|
+
export { AgentLineageStore } from '../lineage.js';
|
package/dist/host/handlers.js
CHANGED
|
@@ -27,6 +27,10 @@ export function chatHandlers(chats, providers) {
|
|
|
27
27
|
await chats.stopTask(payload.chatId, payload.taskId);
|
|
28
28
|
return {};
|
|
29
29
|
},
|
|
30
|
+
'chat.goal': async (payload) => {
|
|
31
|
+
await chats.goal(payload.chatId, payload.action);
|
|
32
|
+
return {};
|
|
33
|
+
},
|
|
30
34
|
'chat.detach': (payload, clientId) => {
|
|
31
35
|
chats.detach(payload.chatId, clientId);
|
|
32
36
|
return {};
|
|
@@ -78,6 +82,10 @@ export function chatHandlers(chats, providers) {
|
|
|
78
82
|
await chats.kill(payload.chatId);
|
|
79
83
|
return {};
|
|
80
84
|
},
|
|
85
|
+
'chat.restart': async (payload) => {
|
|
86
|
+
await chats.restart(payload.chatId);
|
|
87
|
+
return {};
|
|
88
|
+
},
|
|
81
89
|
'chat.list': () => ({ chats: chats.list() })
|
|
82
90
|
};
|
|
83
91
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { AgentHost, type AgentHostOptions } from './agent-host.ts';
|
|
2
|
+
export { RUIMTE_SESSION_VARIABLES, cliEnvironment, type CliEnvironmentPolicy } from './environment.ts';
|
|
3
|
+
export { type AgentHandler, type AgentHandlers, chatHandlers, accountHandlers, usageHandlers, type AgentRequestMap, type ChatRequestType } from './handlers.ts';
|
|
4
|
+
export { memoryPortPair } from './memory-port.ts';
|
|
5
|
+
export { type AgentWiring, wireAgents, type AgentWiringOptions } from './wiring.ts';
|
|
6
|
+
export { ClientSinks } from '../client-sinks.ts';
|
|
7
|
+
export type { AgentEvent, AgentEventMap, AgentSink } from '../events.ts';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Public API: exports.test.ts snapshots this list, so a name added or dropped here is an API change.
|
|
2
|
+
export { AgentHost } from './agent-host.js';
|
|
3
|
+
export { RUIMTE_SESSION_VARIABLES, cliEnvironment } from './environment.js';
|
|
4
|
+
export { chatHandlers, accountHandlers, usageHandlers } from './handlers.js';
|
|
5
|
+
export { memoryPortPair } from './memory-port.js';
|
|
6
|
+
export { wireAgents } from './wiring.js';
|
|
7
|
+
export { ClientSinks } from '../client-sinks.js';
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { wait, withTimeout } from './async.ts';
|
|
2
|
+
export { CodedError } from './coded-error.ts';
|
|
3
|
+
export { describeError, setErrorStacks, errorText } from './error-text.ts';
|
|
4
|
+
export { tempNameFor, writeAtomic, replaceSync, writeAtomicSync, isNotFound, fileExists, type WriteAtomicOptions } from './fs.ts';
|
|
5
|
+
export { recordFileName, RecordDirectory, type RecordDirectoryOptions } from './record-directory.ts';
|
|
6
|
+
export { runProcess, type ProcessResult, type RunProcessOptions } from './run-process.ts';
|
|
7
|
+
export { Serializer, KeyedSerializer } from './serializer.ts';
|
|
8
|
+
export { cleanTitle, readLines } from './title-file.ts';
|
|
9
|
+
export { type DirectoryWatcher, type WatchSeams, supportsRecursive, SYSTEM_WATCH, type Settled, settled, PerClientWatches, type WatchDirectory, type Schedule } from './watch-seam.ts';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Public API: exports.test.ts snapshots this list, so a name added or dropped here is an API change.
|
|
2
|
+
export { wait, withTimeout } from './async.js';
|
|
3
|
+
export { CodedError } from './coded-error.js';
|
|
4
|
+
export { describeError, setErrorStacks, errorText } from './error-text.js';
|
|
5
|
+
export { tempNameFor, writeAtomic, replaceSync, writeAtomicSync, isNotFound, fileExists } from './fs.js';
|
|
6
|
+
export { recordFileName, RecordDirectory } from './record-directory.js';
|
|
7
|
+
export { runProcess } from './run-process.js';
|
|
8
|
+
export { Serializer, KeyedSerializer } from './serializer.js';
|
|
9
|
+
export { cleanTitle, readLines } from './title-file.js';
|
|
10
|
+
export { supportsRecursive, SYSTEM_WATCH, settled, PerClientWatches } from './watch-seam.js';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isRecord } from '@adecore/agent-contracts';
|
|
1
2
|
import { withTimeout } from '../../async.js';
|
|
2
3
|
import { CodexTransport } from '../../chat/codex-transport.js';
|
|
3
4
|
import { runProcess } from '../../run-process.js';
|
|
@@ -6,9 +7,6 @@ const ASK_TIMEOUT_MS = 20_000;
|
|
|
6
7
|
function text(value) {
|
|
7
8
|
return typeof value === 'string' && value !== '' ? value : null;
|
|
8
9
|
}
|
|
9
|
-
function isRecord(value) {
|
|
10
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
11
|
-
}
|
|
12
10
|
/* `claude auth status --json`, as Claude Code 2.1.282 prints it: `loggedIn`, `email`, `orgName`, `subscriptionType`. */
|
|
13
11
|
export function readClaudeAuthStatus(output) {
|
|
14
12
|
let status;
|
package/dist/providers/claude.js
CHANGED
|
@@ -85,6 +85,7 @@ export const CLAUDE_CAPABILITIES = {
|
|
|
85
85
|
denyReason: true,
|
|
86
86
|
allowAlways: true,
|
|
87
87
|
asyncQuestions: false,
|
|
88
|
+
steer: true,
|
|
88
89
|
compaction: 'prompt',
|
|
89
90
|
reportsCost: true,
|
|
90
91
|
/*
|
|
@@ -94,7 +95,8 @@ export const CLAUDE_CAPABILITIES = {
|
|
|
94
95
|
*/
|
|
95
96
|
reportsContextWindow: false,
|
|
96
97
|
reportsThinking: true,
|
|
97
|
-
slashCommands: true
|
|
98
|
+
slashCommands: true,
|
|
99
|
+
goals: 'command'
|
|
98
100
|
};
|
|
99
101
|
// Claude Code takes its flags before `--resume`, which takes the id.
|
|
100
102
|
export const CLAUDE_RESUME_COMMAND = 'claude {flags} --resume {id}';
|
package/dist/providers/codex.js
CHANGED
|
@@ -42,11 +42,13 @@ export const CODEX_CAPABILITIES = {
|
|
|
42
42
|
denyReason: false,
|
|
43
43
|
allowAlways: true,
|
|
44
44
|
asyncQuestions: true,
|
|
45
|
+
steer: true,
|
|
45
46
|
compaction: 'native',
|
|
46
47
|
reportsCost: false,
|
|
47
48
|
reportsContextWindow: true,
|
|
48
49
|
reportsThinking: true,
|
|
49
|
-
slashCommands: false
|
|
50
|
+
slashCommands: false,
|
|
51
|
+
goals: 'native'
|
|
50
52
|
};
|
|
51
53
|
// `codex resume` is a subcommand that reads `[OPTIONS] [SESSION_ID]`, so the flags go after it.
|
|
52
54
|
export const CODEX_RESUME_COMMAND = 'codex resume {flags} {id}';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { AccountError, type AccountLaunches, storedAccount, launchEnv } from './accounts/launch.ts';
|
|
2
|
+
export { ProviderAccountsService, type ProviderAccountsOptions } from './accounts/service.ts';
|
|
3
|
+
export type { ShadowHomeReport } from './accounts/shadow-home.ts';
|
|
4
|
+
export type { AccountReading, AskAccount } from './accounts/status.ts';
|
|
5
|
+
export { type AccountsHost, variablesProblem, keychainService, type SecretStore, type ReservedVariables } from './accounts/variables.ts';
|
|
6
|
+
export { ModelCatalog, type ModelCatalogInput } from './catalog.ts';
|
|
7
|
+
export { createClaudeProvider } from './claude-provider.ts';
|
|
8
|
+
export { createCodexProvider } from './codex-provider.ts';
|
|
9
|
+
export { type CodexRules, codexRulesText, codexRulesPathIn, defaultCodexHome, installCodexRules, type CodexRulesResult } from './codex-rules.ts';
|
|
10
|
+
export { codexThreadOptions, codexServiceTier } from './codex.ts';
|
|
11
|
+
export { type CliDetection, detectCli } from './detect.ts';
|
|
12
|
+
export type { ChatProvider, ProviderHome } from './provider.ts';
|
|
13
|
+
export { ProviderRegistry, type ProviderRegistryOptions } from './registry.ts';
|
|
14
|
+
export { MODE_ORDER, narrowerMode, ceilingForOpening, modeFlag } from '../modes.ts';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Public API: exports.test.ts snapshots this list, so a name added or dropped here is an API change.
|
|
2
|
+
export { AccountError, storedAccount, launchEnv } from './accounts/launch.js';
|
|
3
|
+
export { ProviderAccountsService } from './accounts/service.js';
|
|
4
|
+
export { variablesProblem, keychainService } from './accounts/variables.js';
|
|
5
|
+
export { ModelCatalog } from './catalog.js';
|
|
6
|
+
export { createClaudeProvider } from './claude-provider.js';
|
|
7
|
+
export { createCodexProvider } from './codex-provider.js';
|
|
8
|
+
export { codexRulesText, codexRulesPathIn, defaultCodexHome, installCodexRules } from './codex-rules.js';
|
|
9
|
+
export { codexThreadOptions, codexServiceTier } from './codex.js';
|
|
10
|
+
export { detectCli } from './detect.js';
|
|
11
|
+
export { ProviderRegistry } from './registry.js';
|
|
12
|
+
export { MODE_ORDER, narrowerMode, ceilingForOpening, modeFlag } from '../modes.js';
|
package/dist/run-process.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
|
+
import { killProcessTree } from './chat/chat-process.js';
|
|
3
|
+
// What a command and everything it started get between the SIGTERM and the SIGKILL.
|
|
4
|
+
const KILL_GRACE_MS = 2000;
|
|
5
|
+
// Stdout and stderr together; a short command that prints more is ended and fails instead of filling memory.
|
|
6
|
+
const MAX_OUTPUT_BYTES = 16 * 1024 * 1024;
|
|
2
7
|
/* One short command to its end, with what it printed. A command that cannot start rejects. */
|
|
3
8
|
export function runProcess(command, options = {}) {
|
|
4
9
|
return new Promise((resolve, reject) => {
|
|
@@ -10,29 +15,64 @@ export function runProcess(command, options = {}) {
|
|
|
10
15
|
const child = spawn(executable, args, {
|
|
11
16
|
...(options.cwd === undefined ? {} : { cwd: options.cwd }),
|
|
12
17
|
...(options.env === undefined ? {} : { env: options.env }),
|
|
13
|
-
stdio: [options.stdin === undefined ? 'ignore' : 'pipe', 'pipe', 'pipe']
|
|
18
|
+
stdio: [options.stdin === undefined ? 'ignore' : 'pipe', 'pipe', 'pipe'],
|
|
19
|
+
// A group of its own, so ending the command also ends what it started; Windows ends the tree through `taskkill`.
|
|
20
|
+
detached: process.platform !== 'win32',
|
|
21
|
+
windowsHide: true
|
|
14
22
|
});
|
|
15
23
|
const stdout = [];
|
|
16
24
|
const stderr = [];
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
child.on('error', (error) => {
|
|
25
|
+
let printed = 0;
|
|
26
|
+
let settled = false;
|
|
27
|
+
let timer = null;
|
|
28
|
+
const settle = () => {
|
|
29
|
+
if (settled) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
settled = true;
|
|
26
33
|
if (timer !== null) {
|
|
27
34
|
clearTimeout(timer);
|
|
28
35
|
}
|
|
29
|
-
|
|
36
|
+
return true;
|
|
37
|
+
};
|
|
38
|
+
const end = (message) => {
|
|
39
|
+
if (!settle()) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const pid = child.pid;
|
|
43
|
+
if (pid !== undefined) {
|
|
44
|
+
killProcessTree(pid, 'SIGTERM');
|
|
45
|
+
// Sent even when the command left in time: what it started may still ignore the SIGTERM.
|
|
46
|
+
setTimeout(() => killProcessTree(pid, 'SIGKILL'), KILL_GRACE_MS).unref?.();
|
|
47
|
+
}
|
|
48
|
+
reject(new Error(message));
|
|
49
|
+
};
|
|
50
|
+
const collect = (into) => (chunk) => {
|
|
51
|
+
if (settled) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
printed += chunk.length;
|
|
55
|
+
if (printed > MAX_OUTPUT_BYTES) {
|
|
56
|
+
end(`${executable} printed more than ${MAX_OUTPUT_BYTES / 1024 / 1024} MB`);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
into.push(chunk);
|
|
60
|
+
};
|
|
61
|
+
child.stdout?.on('data', collect(stdout));
|
|
62
|
+
child.stderr?.on('data', collect(stderr));
|
|
63
|
+
if (options.timeoutMs !== undefined) {
|
|
64
|
+
const message = options.timeoutMessage ?? `${executable} did not finish in time`;
|
|
65
|
+
timer = setTimeout(() => end(message), options.timeoutMs);
|
|
66
|
+
}
|
|
67
|
+
child.on('error', (error) => {
|
|
68
|
+
if (settle()) {
|
|
69
|
+
reject(error);
|
|
70
|
+
}
|
|
30
71
|
});
|
|
31
72
|
child.on('close', (exitCode) => {
|
|
32
|
-
if (
|
|
33
|
-
|
|
73
|
+
if (settle()) {
|
|
74
|
+
resolve({ exitCode, stdout: Buffer.concat(stdout).toString('utf8'), stderr: Buffer.concat(stderr).toString('utf8') });
|
|
34
75
|
}
|
|
35
|
-
resolve({ exitCode, stdout: Buffer.concat(stdout).toString('utf8'), stderr: Buffer.concat(stderr).toString('utf8') });
|
|
36
76
|
});
|
|
37
77
|
if (options.stdin !== undefined && child.stdin) {
|
|
38
78
|
child.stdin.on('error', () => undefined);
|
package/dist/skills.d.ts
CHANGED
package/dist/skills.js
CHANGED
|
@@ -171,4 +171,8 @@ export class SkillIndex {
|
|
|
171
171
|
this.cache.set(key, { at: Date.now(), skills });
|
|
172
172
|
return skills;
|
|
173
173
|
}
|
|
174
|
+
/* Drops the scan of one CLI in one folder, so the next look reads the disk again. */
|
|
175
|
+
forget(kind, cwd) {
|
|
176
|
+
this.cache.delete(`${kind}:${cwd}`);
|
|
177
|
+
}
|
|
174
178
|
}
|
|
@@ -12,6 +12,10 @@ export interface TaskCoordinatorDeps {
|
|
|
12
12
|
alert(nodeId: string, title: string, body: string): void;
|
|
13
13
|
retryAt?(chatId: string, turn: ChatTurnItem, items: readonly ChatItem[]): number | null;
|
|
14
14
|
afterBackgroundWork(chatId: string): 'reports' | 'silent' | 'gone';
|
|
15
|
+
activeGoal?(chatId: string): {
|
|
16
|
+
objective: string;
|
|
17
|
+
running: boolean;
|
|
18
|
+
} | null;
|
|
15
19
|
commandsOf(chatId: string): readonly ChatBackgroundTask[];
|
|
16
20
|
limit: {
|
|
17
21
|
owed(taskId: string): boolean;
|
|
@@ -33,6 +33,9 @@ function outlastedNote(commands) {
|
|
|
33
33
|
function restartedNote(commands) {
|
|
34
34
|
return `The machine restarted while this still ran in the background: ${commandList(commands)}.`;
|
|
35
35
|
}
|
|
36
|
+
function goalLostNote(objective) {
|
|
37
|
+
return `The agent stopped before its goal was met: ${objective}`;
|
|
38
|
+
}
|
|
36
39
|
/* What a settled turn of a child makes of its task. */
|
|
37
40
|
export function resultOfTurn(turn, items, at) {
|
|
38
41
|
if (turn.state === 'done') {
|
|
@@ -49,8 +52,9 @@ export function resultOfTurn(turn, items, at) {
|
|
|
49
52
|
/*
|
|
50
53
|
* Settles tasks from what children do and does nothing else: it writes the task store and owes wakes
|
|
51
54
|
* in the outbox, never starts a turn, since it runs inside the broadcast of the child it heard. A chat
|
|
52
|
-
* child settles when a turn ends with none of its own tasks still open or waiting to wake it
|
|
53
|
-
* of its CLI's still running in the background, or once the commands it runs
|
|
55
|
+
* child settles when a turn ends with none of its own tasks still open or waiting to wake it, no goal
|
|
56
|
+
* still active and no work of its CLI's still running in the background, or once the commands it runs
|
|
57
|
+
* there outlast their limit;
|
|
54
58
|
* an agent that is not a chat, which the host tells it about, settles only on `done`, or fails when it
|
|
55
59
|
* ends without one.
|
|
56
60
|
*/
|
|
@@ -185,6 +189,16 @@ export class TaskCoordinator {
|
|
|
185
189
|
this.hold(task, paused);
|
|
186
190
|
return;
|
|
187
191
|
}
|
|
192
|
+
// A goal holds the task with no limit, and the parent sleeps on through the turns its CLI opens toward it.
|
|
193
|
+
const goal = turn.state === 'done' ? (this.deps.activeGoal?.(chatId) ?? null) : null;
|
|
194
|
+
if (goal?.running === true) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
if (goal !== null) {
|
|
198
|
+
const { result } = resultOfTurn(turn, items, this.deps.now());
|
|
199
|
+
this.settle(task, 'failed', { ...result, text: `${result.text}\n\n${goalLostNote(goal.objective)}`, source: 'exit' });
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
188
202
|
// A turn a person stopped or that failed ends the task as it always did, whatever still runs beside it.
|
|
189
203
|
if (turn.state === 'done' && this.heldInBackground(chatId, task, items)) {
|
|
190
204
|
this.track(this.deps.tasks.holdBackground(task.id, {
|
package/dist/tasks/wiring.js
CHANGED
|
@@ -37,6 +37,11 @@ export function wireTasks(deps) {
|
|
|
37
37
|
return reportsOnBackgroundWork(chat.info.provider) ? 'reports' : 'silent';
|
|
38
38
|
},
|
|
39
39
|
commandsOf: (chatId) => chats.get(chatId)?.info.background ?? [],
|
|
40
|
+
activeGoal: (chatId) => {
|
|
41
|
+
const chat = chats.get(chatId);
|
|
42
|
+
const goal = chat?.info.goal;
|
|
43
|
+
return chat && goal?.status === 'active' ? { objective: goal.objective, running: chat.running } : null;
|
|
44
|
+
},
|
|
40
45
|
limit
|
|
41
46
|
});
|
|
42
47
|
deps.tasks.onChange((task) => {
|
|
@@ -68,7 +73,8 @@ export function wireTasks(deps) {
|
|
|
68
73
|
}
|
|
69
74
|
const stored = await chats.storedBackground(task.childId);
|
|
70
75
|
const storedWork = stored.items.length > 0 || stored.commands.length > 0;
|
|
71
|
-
|
|
76
|
+
// A goal still active went down with the CLI, which its child's last turn settles on.
|
|
77
|
+
if (!deps.placed(task.childId) || (task.background === undefined && task.requiresTaskTurn !== true && !storedWork && !stored.goal)) {
|
|
72
78
|
return;
|
|
73
79
|
}
|
|
74
80
|
if (task.background === undefined && stored.turnId !== null && storedWork) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ProviderAccountMap } from '@adecore/agent-contracts';
|
|
2
|
-
import { ProviderAccountsService } from '
|
|
3
|
-
import type { SecretStore } from '
|
|
2
|
+
import { ProviderAccountsService } from '../providers/accounts/service.ts';
|
|
3
|
+
import type { SecretStore } from '../providers/accounts/variables.ts';
|
|
4
4
|
export declare function memorySecrets(values?: Map<string, string>): SecretStore & {
|
|
5
5
|
values: Map<string, string>;
|
|
6
6
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { providerFor } from '../registry.js';
|
|
2
|
-
import { ProviderAccountsService } from '
|
|
3
|
-
import { accountsPath, writeAccounts } from '
|
|
1
|
+
import { providerFor } from '../providers/registry.js';
|
|
2
|
+
import { ProviderAccountsService } from '../providers/accounts/service.js';
|
|
3
|
+
import { accountsPath, writeAccounts } from '../providers/accounts/store.js';
|
|
4
4
|
/* A keychain in memory; `values` is what it holds, by key. */
|
|
5
5
|
export function memorySecrets(values = new Map()) {
|
|
6
6
|
return {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { FakeCli, FakeIo, FakeProgram } from './fake-cli.ts';
|
|
2
2
|
export declare function fakeClaude(io: FakeIo): FakeProgram;
|
|
3
3
|
export declare function claudeStoppingOnResume(sessionIds: ReadonlySet<string>, how: 'missing' | 'exit'): FakeCli;
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
import { spawn } from 'node:child_process';
|
|
6
6
|
import { writeFileSync } from 'node:fs';
|
|
7
7
|
import { resolve } from 'node:path';
|
|
8
|
-
import { runOverStdio } from './fake-cli.js';
|
|
9
8
|
export function fakeClaude(io) {
|
|
10
9
|
const args = io.argv;
|
|
11
10
|
const resumeAt = args.indexOf('--resume');
|
|
@@ -1050,6 +1049,3 @@ export function claudeStoppingOnResume(sessionIds, how) {
|
|
|
1050
1049
|
return { onLine: () => undefined };
|
|
1051
1050
|
};
|
|
1052
1051
|
}
|
|
1053
|
-
if (import.meta.main) {
|
|
1054
|
-
await runOverStdio(fakeClaude);
|
|
1055
|
-
}
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Network-free `codex app-server` fake. Prompt commands exercise approvals, edits, questions,
|
|
3
|
-
* interrupts, failures, names, subagents, pagination and forks through the real JSON-RPC shapes.
|
|
4
|
-
*/
|
|
5
|
-
import { runOverStdio } from './fake-cli.js';
|
|
6
1
|
// How many steps a spawned agent takes: more than a thread row keeps, so only its own thread has them all.
|
|
7
2
|
export const FAKE_CHILD_STEPS = 250;
|
|
8
3
|
// The threads of spawned agents, outside any one process: the real ones are on disk, so a process that never ran them reads them too.
|
|
@@ -93,6 +88,34 @@ export function fakeCodexWith(options) {
|
|
|
93
88
|
});
|
|
94
89
|
turnId = '';
|
|
95
90
|
};
|
|
91
|
+
/*
|
|
92
|
+
* The thread's goal (Codex 0.162.1). An objective `steps:N` takes N turns: the first is the one the client
|
|
93
|
+
* starts, which ends when the test says later is, and Codex opens every next one itself while the goal
|
|
94
|
+
* is active, also later, and marks the goal complete in the last.
|
|
95
|
+
*/
|
|
96
|
+
let goal = null;
|
|
97
|
+
let goalSteps = 0;
|
|
98
|
+
const goalChanged = () => {
|
|
99
|
+
notify('thread/goal/updated', { threadId, turnId: turnId === '' ? null : turnId, goal });
|
|
100
|
+
};
|
|
101
|
+
const goalStep = () => {
|
|
102
|
+
goalSteps += 1;
|
|
103
|
+
agentMessage(`goal step ${goalSteps}`);
|
|
104
|
+
const needed = Number(/steps:(\d+)/.exec(String(goal?.objective ?? ''))?.[1] ?? '1');
|
|
105
|
+
if (goal !== null) {
|
|
106
|
+
goal = { ...goal, tokensUsed: Number(goal.tokensUsed) + 100, status: goalSteps >= needed ? 'complete' : goal.status };
|
|
107
|
+
goalChanged();
|
|
108
|
+
}
|
|
109
|
+
turnCompleted('completed');
|
|
110
|
+
if (goal?.status === 'active') {
|
|
111
|
+
io.later(() => {
|
|
112
|
+
if (goal?.status === 'active') {
|
|
113
|
+
turnStarted();
|
|
114
|
+
goalStep();
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
};
|
|
96
119
|
let pendingApproval = null;
|
|
97
120
|
let pendingQuestion = null;
|
|
98
121
|
let pendingSteer = false;
|
|
@@ -132,6 +155,10 @@ export function fakeCodexWith(options) {
|
|
|
132
155
|
const user = item('userMessage', { clientId: null, content: [{ type: 'text', text, text_elements: [] }] });
|
|
133
156
|
started(user);
|
|
134
157
|
completed(user);
|
|
158
|
+
if (goal !== null && (text === goal.objective || text === '')) {
|
|
159
|
+
io.later(goalStep);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
135
162
|
if (text === 'crash') {
|
|
136
163
|
io.exit(1);
|
|
137
164
|
return;
|
|
@@ -494,6 +521,44 @@ export function fakeCodexWith(options) {
|
|
|
494
521
|
turnCompleted('interrupted');
|
|
495
522
|
}
|
|
496
523
|
return;
|
|
524
|
+
case 'thread/goal/get':
|
|
525
|
+
out({ id, result: { goal } });
|
|
526
|
+
return;
|
|
527
|
+
case 'thread/goal/set': {
|
|
528
|
+
const at = Math.floor(Date.now() / 1000);
|
|
529
|
+
if (typeof params.objective === 'string') {
|
|
530
|
+
goal = {
|
|
531
|
+
threadId,
|
|
532
|
+
objective: params.objective,
|
|
533
|
+
status: 'active',
|
|
534
|
+
tokenBudget: null,
|
|
535
|
+
tokensUsed: 0,
|
|
536
|
+
timeUsedSeconds: 0,
|
|
537
|
+
createdAt: at,
|
|
538
|
+
updatedAt: at
|
|
539
|
+
};
|
|
540
|
+
goalSteps = 0;
|
|
541
|
+
}
|
|
542
|
+
if (goal === null) {
|
|
543
|
+
out({ id, error: { code: -32600, message: 'no goal to update' } });
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
if (typeof params.status === 'string') {
|
|
547
|
+
goal = { ...goal, status: params.status, updatedAt: at };
|
|
548
|
+
}
|
|
549
|
+
out({ id, result: { goal } });
|
|
550
|
+
goalChanged();
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
case 'thread/goal/clear': {
|
|
554
|
+
const cleared = goal !== null;
|
|
555
|
+
goal = null;
|
|
556
|
+
out({ id, result: { cleared } });
|
|
557
|
+
if (cleared) {
|
|
558
|
+
notify('thread/goal/cleared', { threadId });
|
|
559
|
+
}
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
497
562
|
case 'thread/compact/start':
|
|
498
563
|
out({ id, result: {} });
|
|
499
564
|
turnStarted();
|
|
@@ -530,6 +595,3 @@ export function fakeCodexWith(options) {
|
|
|
530
595
|
};
|
|
531
596
|
}
|
|
532
597
|
export const fakeCodex = fakeCodexWith({});
|
|
533
|
-
if (import.meta.main) {
|
|
534
|
-
await runOverStdio(fakeCodex);
|
|
535
|
-
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { type FakeIo, type FakeProgram, type FakeCli, type StartedFake, type InProcessCli, inProcess, runOverStdio } from './fake-cli.ts';
|
|
2
|
+
export { fakeClaude, claudeStoppingOnResume } from './fake-claude.ts';
|
|
3
|
+
export { FAKE_CHILD_STEPS, fakeCodexForks, type FakeCodexOptions, fakeCodexWith, fakeCodex } from './fake-codex.ts';
|
|
4
|
+
export { memorySecrets, testAccounts } from './accounts.ts';
|
|
5
|
+
export { ManualClock } from './manual-clock.ts';
|
|
6
|
+
export { FakeDirectoryWatcher, FakeWatch, EventLog } from './watch.ts';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Public API: exports.test.ts snapshots this list, so a name added or dropped here is an API change.
|
|
2
|
+
export { inProcess, runOverStdio } from './fake-cli.js';
|
|
3
|
+
export { fakeClaude, claudeStoppingOnResume } from './fake-claude.js';
|
|
4
|
+
export { FAKE_CHILD_STEPS, fakeCodexForks, fakeCodexWith, fakeCodex } from './fake-codex.js';
|
|
5
|
+
export { memorySecrets, testAccounts } from './accounts.js';
|
|
6
|
+
export { ManualClock } from './manual-clock.js';
|
|
7
|
+
export { FakeDirectoryWatcher, FakeWatch, EventLog } from './watch.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DirectoryWatcher, WatchDirectory, WatchSeams } from '
|
|
1
|
+
import type { DirectoryWatcher, WatchDirectory, WatchSeams } from '../watch-seam.ts';
|
|
2
2
|
export declare class FakeDirectoryWatcher implements DirectoryWatcher {
|
|
3
3
|
readonly path: string;
|
|
4
4
|
readonly recursive: boolean;
|
package/dist/usage/exchange.d.ts
CHANGED
|
@@ -6,11 +6,13 @@ export declare class ExchangeRates {
|
|
|
6
6
|
private readonly home;
|
|
7
7
|
private readonly allowFetch;
|
|
8
8
|
private rate;
|
|
9
|
-
private
|
|
9
|
+
private stored;
|
|
10
10
|
private inFlight;
|
|
11
11
|
constructor(home: string, allowFetch?: boolean);
|
|
12
12
|
get current(): UsageRate | null;
|
|
13
|
-
|
|
13
|
+
load(): Promise<void>;
|
|
14
|
+
ensure(): Promise<boolean>;
|
|
14
15
|
private get file();
|
|
15
|
-
private
|
|
16
|
+
private readStored;
|
|
17
|
+
private fetchFresh;
|
|
16
18
|
}
|