maka-agent 0.2.0-dev.6.20260830 → 0.2.0-dev.8.20260830
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/native/runtime-host-peer/prebuilds/win32-x64/maka_runtime_host_peer.node +0 -0
- package/node_modules/@maka/core/dist/agent-run.js +0 -2
- package/node_modules/@maka/core/dist/foreign-session.js +1 -1
- package/node_modules/@maka/core/dist/task-ledger.js +6 -134
- package/node_modules/@maka/core/dist/usage-record-schema.js +1 -0
- package/node_modules/@maka/runtime/dist/ai-sdk-backend.js +3 -115
- package/node_modules/@maka/runtime/dist/ai-sdk-compaction.js +4 -18
- package/node_modules/@maka/runtime/dist/context-budget.js +0 -1
- package/node_modules/@maka/runtime/dist/plan-mode.js +0 -65
- package/node_modules/@maka/runtime/dist/run-trace.js +0 -10
- package/node_modules/@maka/runtime/dist/runtime-kernel.js +0 -1
- package/node_modules/@maka/runtime/dist/sandbox/index.js +0 -1
- package/node_modules/@maka/runtime/dist/sandbox/linux-sandbox.js +0 -12
- package/node_modules/@maka/runtime/dist/sandbox/macos-seatbelt.js +0 -12
- package/node_modules/@maka/runtime/dist/sandbox/sandbox-manager.js +0 -35
- package/node_modules/@maka/runtime/dist/sandbox/windows-sandbox.js +0 -12
- package/node_modules/@maka/runtime/dist/shell-detect.js +3 -7
- package/node_modules/@maka/runtime/dist/shell-run-contract.js +0 -1
- package/node_modules/@maka/runtime/dist/shell-run-manager.js +1 -39
- package/node_modules/@maka/runtime/dist/shell-tools.js +1 -1
- package/node_modules/@maka/runtime/dist/task-ledger-tools.js +2 -2
- package/node_modules/@maka/runtime/package.json +0 -1
- package/node_modules/@maka/runtime-host/dist/server/execution-composition.js +1 -8
- package/node_modules/@maka/runtime-host/dist/server/execution-model-composition.js +0 -6
- package/node_modules/@maka/runtime-host/dist/server/interactive-run-composer.js +2 -58
- package/package.json +1 -1
- package/node_modules/@maka/runtime/dist/sandbox/diagnostics.js +0 -285
- package/node_modules/@maka/runtime/dist/system-prompt/sandbox-context-prompt.js +0 -77
- package/node_modules/@maka/runtime/dist/system-prompt/session-environment-prompt.js +0 -47
|
@@ -128,41 +128,6 @@ export class SandboxManager {
|
|
|
128
128
|
return false;
|
|
129
129
|
return backend.canEnforceProfile?.(input.profile) ?? true;
|
|
130
130
|
}
|
|
131
|
-
probe(request) {
|
|
132
|
-
const selected = this.selectInitial({
|
|
133
|
-
profile: request.command.profile,
|
|
134
|
-
preference: request.preference,
|
|
135
|
-
platform: request.platform,
|
|
136
|
-
});
|
|
137
|
-
if (!selected.ok)
|
|
138
|
-
return selected;
|
|
139
|
-
if (selected.sandboxType === 'none') {
|
|
140
|
-
return {
|
|
141
|
-
ok: true,
|
|
142
|
-
executable: request.command.program,
|
|
143
|
-
sandboxType: 'none',
|
|
144
|
-
requiresSandbox: false,
|
|
145
|
-
preference: selected.preference,
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
const backend = this.backends.get(selected.sandboxType);
|
|
149
|
-
if (!backend) {
|
|
150
|
-
return {
|
|
151
|
-
ok: false,
|
|
152
|
-
reason: 'backend_not_available',
|
|
153
|
-
sandboxType: selected.sandboxType,
|
|
154
|
-
requiresSandbox: selected.requiresSandbox,
|
|
155
|
-
platform: selected.platform,
|
|
156
|
-
preference: selected.preference,
|
|
157
|
-
message: `Sandbox backend ${selected.sandboxType} is not registered.`,
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
return backend.probe({
|
|
161
|
-
...request,
|
|
162
|
-
preference: selected.preference,
|
|
163
|
-
platform: selected.platform,
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
131
|
transform(request) {
|
|
167
132
|
const selected = this.selectInitial({
|
|
168
133
|
profile: request.command.profile,
|
|
@@ -70,18 +70,6 @@ export class WindowsBrokerSandboxBackend {
|
|
|
70
70
|
profile.fileSystem.kind === 'restricted' &&
|
|
71
71
|
profile.network.kind === 'restricted');
|
|
72
72
|
}
|
|
73
|
-
probe(request) {
|
|
74
|
-
const plan = this.plan(request);
|
|
75
|
-
if (!plan.ok)
|
|
76
|
-
return plan;
|
|
77
|
-
return {
|
|
78
|
-
ok: true,
|
|
79
|
-
executable: this.options.clientPath,
|
|
80
|
-
sandboxType: 'windows',
|
|
81
|
-
requiresSandbox: true,
|
|
82
|
-
preference: plan.preference,
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
73
|
transform(request) {
|
|
86
74
|
const plan = this.plan(request);
|
|
87
75
|
if (!plan.ok)
|
|
@@ -26,9 +26,9 @@
|
|
|
26
26
|
// the model is trapped writing `dir /s /b` style commands. This module detects
|
|
27
27
|
// a better shell (pwsh > powershell > cmd) and carries the result to the two
|
|
28
28
|
// places that need it: the spawn call (shell-exec / shell-run-manager) and the
|
|
29
|
-
//
|
|
30
|
-
//
|
|
31
|
-
//
|
|
29
|
+
// Bash tool description that declares the dialect to the model. Selection
|
|
30
|
+
// without declaration — or the other way round — makes the model guess the
|
|
31
|
+
// dialect, which is the original bug.
|
|
32
32
|
import { execFile } from 'node:child_process';
|
|
33
33
|
import { existsSync } from 'node:fs';
|
|
34
34
|
import { win32 } from 'node:path';
|
|
@@ -87,10 +87,6 @@ export function throwIfShellSetupFailed(shell) {
|
|
|
87
87
|
if (shell.setupError)
|
|
88
88
|
throw shell.setupError;
|
|
89
89
|
}
|
|
90
|
-
/** Model-facing shell name; a broken preference is declared, not silently hidden. */
|
|
91
|
-
export function turnShellDisplayName(shell) {
|
|
92
|
-
return shell.setupError ? `Unavailable (${shell.setupError.message})` : shell.plan.displayName;
|
|
93
|
-
}
|
|
94
90
|
/** Rejects a persisted override unless the Host can execute it as GNU Bash. */
|
|
95
91
|
export async function validateShellPreference(settings, input = {}) {
|
|
96
92
|
const plan = resolveShellPlan(settings, input);
|
|
@@ -32,7 +32,6 @@ export const DEFAULT_MAX_LIVE_PTY_RUNS = 8;
|
|
|
32
32
|
export const DEFAULT_SHELL_RUN_FLUSH_INTERVAL_MS = 1_000;
|
|
33
33
|
export const DEFAULT_SHELL_RUN_FLUSH_BYTES = 64 * 1024;
|
|
34
34
|
export const DEFAULT_PIPE_OUTPUT_DRAIN_MS = 2_000;
|
|
35
|
-
export const SHELL_RUN_CONTEXT_SUMMARY_LIMIT = 8;
|
|
36
35
|
export const SHELL_RUN_RESOURCE_PREFIX = 'maka://runtime/background-tasks';
|
|
37
36
|
export const MAX_SHELL_RUN_RESOURCE_REF_CHARS = SHELL_RUN_RESOURCE_PREFIX.length + 1 + SHELL_RUN_ID_MAX_CHARS;
|
|
38
37
|
export { isWellFormedTerminalInput };
|
|
@@ -30,7 +30,7 @@ import { PipeTailCollector } from './pipe-tail-collector.js';
|
|
|
30
30
|
import { PtyProcessDriver } from './pty-process-driver.js';
|
|
31
31
|
import { PTY_INITIAL_COLS, PTY_INITIAL_ROWS, PtyScreenCollector, } from './pty-screen-collector.js';
|
|
32
32
|
import { loadPtyStack } from './pty-stack.js';
|
|
33
|
-
import { DEFAULT_BASH_TIMEOUT_MS, DEFAULT_MAX_LIVE_PTY_RUNS, DEFAULT_MAX_LIVE_SHELL_RUNS, DEFAULT_PIPE_OUTPUT_DRAIN_MS, DEFAULT_SHELL_RUN_FLUSH_BYTES, DEFAULT_SHELL_RUN_FLUSH_INTERVAL_MS, MAX_FOREGROUND_BASH_TIMEOUT_MS, MAX_SHELL_RUN_TIMEOUT_MS,
|
|
33
|
+
import { DEFAULT_BASH_TIMEOUT_MS, DEFAULT_MAX_LIVE_PTY_RUNS, DEFAULT_MAX_LIVE_SHELL_RUNS, DEFAULT_PIPE_OUTPUT_DRAIN_MS, DEFAULT_SHELL_RUN_FLUSH_BYTES, DEFAULT_SHELL_RUN_FLUSH_INTERVAL_MS, MAX_FOREGROUND_BASH_TIMEOUT_MS, MAX_SHELL_RUN_TIMEOUT_MS, ShellRunPtyControlClosedError, parseShellRunResourceRef, shellRunResourceRef, validateWriteStdinInput, } from './shell-run-contract.js';
|
|
34
34
|
import { compactShellRunContent, ptyControlOperation, shellRunContent, shellRunUpdate, terminalContent, } from './shell-run-tool-result.js';
|
|
35
35
|
import { CompletionLatch } from './completion-latch.js';
|
|
36
36
|
import { closeChildFdSources } from './child-fd-input.js';
|
|
@@ -404,30 +404,6 @@ export class ShellRunProcessManager {
|
|
|
404
404
|
const record = await this.markObserved(await live.finished.join());
|
|
405
405
|
return shellRunContent(record, { kind: 'stop', applied });
|
|
406
406
|
}
|
|
407
|
-
async buildContextSummary(sessionId) {
|
|
408
|
-
const records = (await this.actionableRecords(sessionId)).filter((record) => record.visibility !== 'user');
|
|
409
|
-
if (records.length === 0)
|
|
410
|
-
return undefined;
|
|
411
|
-
const visible = records.slice(0, SHELL_RUN_CONTEXT_SUMMARY_LIMIT);
|
|
412
|
-
const lines = [
|
|
413
|
-
'Background tasks for this session:',
|
|
414
|
-
...visible.map((record) => {
|
|
415
|
-
const completed = record.completedAt !== undefined ? ` completedAt=${record.completedAt}` : '';
|
|
416
|
-
return `- ref=${shellRunResourceRef(record.shellRunId)} mode=${record.output.mode} status=${record.status} cwd=${record.cwd} updatedAt=${record.updatedAt}${completed} command=${JSON.stringify(record.command)}`;
|
|
417
|
-
}),
|
|
418
|
-
];
|
|
419
|
-
const overflow = records.length - visible.length;
|
|
420
|
-
if (overflow > 0)
|
|
421
|
-
lines.push(`- ${overflow} more background task(s) not shown in this turn tail.`);
|
|
422
|
-
const hasControllablePty = records.some((record) => {
|
|
423
|
-
const live = this.liveResource(sessionId, record.shellRunId);
|
|
424
|
-
return live?.mode === 'pty' && isPtyControlOpen(live);
|
|
425
|
-
});
|
|
426
|
-
lines.push(hasControllablePty
|
|
427
|
-
? 'Use Read on a ref for its bounded output snapshot; use WriteStdin to control a running PTY task.'
|
|
428
|
-
: 'Use Read on a ref for its bounded output snapshot.');
|
|
429
|
-
return lines.join('\n');
|
|
430
|
-
}
|
|
431
407
|
async listSessionUpdates(sessionId) {
|
|
432
408
|
const records = await this.input.store.listSessionShellRuns(sessionId);
|
|
433
409
|
return records.map(shellRunUpdate);
|
|
@@ -1483,13 +1459,6 @@ export class ShellRunProcessManager {
|
|
|
1483
1459
|
return this.input.store.updateShellRun(current.sessionId, current.shellRunId, buildPatch());
|
|
1484
1460
|
}
|
|
1485
1461
|
}
|
|
1486
|
-
async actionableRecords(sessionId) {
|
|
1487
|
-
const records = await this.input.store.listSessionShellRuns(sessionId);
|
|
1488
|
-
return records
|
|
1489
|
-
.filter((record) => isActiveShellRunStatus(record.status) ||
|
|
1490
|
-
(record.observedAt === undefined && isTerminalShellRunStatus(record.status)))
|
|
1491
|
-
.sort(compareActionableShellRuns);
|
|
1492
|
-
}
|
|
1493
1462
|
notifyShellRunUpdate(record) {
|
|
1494
1463
|
try {
|
|
1495
1464
|
this.input.onShellRunUpdate?.(shellRunUpdate(record));
|
|
@@ -1679,13 +1648,6 @@ function startupCleanupError(startupError, cleanupFailure) {
|
|
|
1679
1648
|
const cleanupError = asError(cleanupFailure, 'Shell process startup cleanup failed');
|
|
1680
1649
|
return new Error(`Shell process startup failed: ${safeFailureMessage(startupError)}; startup cleanup failed: ${safeFailureMessage(cleanupError)}`, { cause: new AggregateError([startupError, cleanupError]) });
|
|
1681
1650
|
}
|
|
1682
|
-
function compareActionableShellRuns(a, b) {
|
|
1683
|
-
const rank = (record) => (isActiveShellRunStatus(record.status) ? 1 : 0);
|
|
1684
|
-
return (rank(a) - rank(b) ||
|
|
1685
|
-
b.updatedAt - a.updatedAt ||
|
|
1686
|
-
b.startedAt - a.startedAt ||
|
|
1687
|
-
a.shellRunId.localeCompare(b.shellRunId));
|
|
1688
|
-
}
|
|
1689
1651
|
async function racePromiseWithAbort(promise, signal) {
|
|
1690
1652
|
if (!signal)
|
|
1691
1653
|
return promise;
|
|
@@ -211,7 +211,7 @@ export function buildStopBackgroundTaskTool(backgroundTasks) {
|
|
|
211
211
|
return {
|
|
212
212
|
name: 'StopBackgroundTask',
|
|
213
213
|
activityKind: 'command',
|
|
214
|
-
description: 'Stop a background task by runtime ref. Currently supports background shell run refs returned by Bash
|
|
214
|
+
description: 'Stop a background task by runtime ref. Currently supports background shell run refs returned by Bash.',
|
|
215
215
|
parameters: z.object({
|
|
216
216
|
ref: z
|
|
217
217
|
.string()
|
|
@@ -34,8 +34,8 @@ function buildTaskCreateTool(store, name, updateToolName) {
|
|
|
34
34
|
return {
|
|
35
35
|
name,
|
|
36
36
|
displayName: 'Task Create',
|
|
37
|
-
description: 'Add one or more tasks to the session task ledger.
|
|
38
|
-
`
|
|
37
|
+
description: 'Add one or more tasks to the session task ledger. ' +
|
|
38
|
+
`Use task_list or task_get to read it later, and update status with ${updateToolName} as you progress.`,
|
|
39
39
|
parameters: z.object({
|
|
40
40
|
tasks: z
|
|
41
41
|
.array(z.object({
|
|
@@ -96,7 +96,6 @@
|
|
|
96
96
|
"./system-prompt/main-session-prompt": "./dist/system-prompt/main-session-prompt.js",
|
|
97
97
|
"./system-prompt/personalization-prompt": "./dist/system-prompt/personalization-prompt.js",
|
|
98
98
|
"./system-prompt/project-context": "./dist/system-prompt/project-context.js",
|
|
99
|
-
"./system-prompt/session-environment-prompt": "./dist/system-prompt/session-environment-prompt.js",
|
|
100
99
|
"./system-prompt/workspace-instructions": "./dist/system-prompt/workspace-instructions.js",
|
|
101
100
|
"./task-ledger-tools": "./dist/task-ledger-tools.js",
|
|
102
101
|
"./tavily-search": "./dist/tavily-search.js",
|
|
@@ -32,7 +32,7 @@ import { buildHistoryTools } from '@maka/runtime/history-tools';
|
|
|
32
32
|
import { createLocalContinuationSafetyInspector } from '@maka/runtime/continuation-safety';
|
|
33
33
|
import { createConfiguredSubagentCatalog } from '@maka/runtime/configured-subagent-catalog';
|
|
34
34
|
import { buildHostCapabilitiesFromBinding } from '@maka/runtime/skills';
|
|
35
|
-
import { createBuiltinSandboxManager,
|
|
35
|
+
import { createBuiltinSandboxManager, isBuiltinFilesystemWorkerSandboxAvailable, } from '@maka/runtime/sandbox';
|
|
36
36
|
import { createFilesystemWorkerLaunchSpecProvider, FilesystemWorkerClient, } from '@maka/runtime/filesystem-worker';
|
|
37
37
|
import { isOAuthEnrollmentProviderEnabled } from '@maka/runtime/oauth-provider-contracts';
|
|
38
38
|
import { loadHistoryCompactCheckpointsFromRunLedger, loadLatestHistoryCompactCheckpointFromRunLedger, } from '@maka/runtime/history-compact-ledger';
|
|
@@ -224,12 +224,6 @@ export async function createExecutionRuntimeHostComposition(context, options = {
|
|
|
224
224
|
resourceLocation: { kind: 'runtime' },
|
|
225
225
|
})
|
|
226
226
|
: undefined;
|
|
227
|
-
const sandboxDiagnostics = createSandboxDiagnosticsProvider({
|
|
228
|
-
...(sandboxManager ? { sandboxManager } : {}),
|
|
229
|
-
...(filesystemWorkerLaunchSpecProvider
|
|
230
|
-
? { getFilesystemWorkerLaunchSpec: filesystemWorkerLaunchSpecProvider }
|
|
231
|
-
: {}),
|
|
232
|
-
});
|
|
233
227
|
const filesystemWorker = sandboxManager && filesystemWorkerLaunchSpecProvider
|
|
234
228
|
? new FilesystemWorkerClient({
|
|
235
229
|
sandboxManager,
|
|
@@ -478,7 +472,6 @@ export async function createExecutionRuntimeHostComposition(context, options = {
|
|
|
478
472
|
context: backendContext,
|
|
479
473
|
runtimePolicy: runtimePolicyStores,
|
|
480
474
|
oauthCredentials,
|
|
481
|
-
sandboxDiagnostics,
|
|
482
475
|
createRunComposer: createInteractiveRunComposerFactory({
|
|
483
476
|
skills,
|
|
484
477
|
memory: requireMemory(memory),
|
|
@@ -195,9 +195,7 @@ export async function createHostAiSdkBackend(input) {
|
|
|
195
195
|
const resolved = await modelComposition.resolveSystemPrompt({
|
|
196
196
|
sessionId: input.context.sessionId,
|
|
197
197
|
turnId: context.turnId,
|
|
198
|
-
...(context.runId ? { runId: context.runId } : {}),
|
|
199
198
|
cwd: input.context.header.cwd,
|
|
200
|
-
workspaceRoot: input.context.workspaceRoot,
|
|
201
199
|
...(context.emitSkillCatalogTrace
|
|
202
200
|
? { emitSkillCatalogTrace: context.emitSkillCatalogTrace }
|
|
203
201
|
: {}),
|
|
@@ -239,7 +237,6 @@ export async function createHostAiSdkBackend(input) {
|
|
|
239
237
|
appendMessage: input.context.appendMessage ??
|
|
240
238
|
((message) => input.context.store.appendMessage(input.context.sessionId, message)),
|
|
241
239
|
readExecutionBoundary: () => input.context.store.readExecutionBoundary(input.context.sessionId),
|
|
242
|
-
sandboxDiagnostics: input.sandboxDiagnostics,
|
|
243
240
|
...(input.context.store.createSandboxBoundaryRequest
|
|
244
241
|
? {
|
|
245
242
|
createSandboxBoundaryRequest: (request) => input.context.store.createSandboxBoundaryRequest(request),
|
|
@@ -307,15 +304,12 @@ export async function createHostAiSdkBackend(input) {
|
|
|
307
304
|
systemPrompt: async (context) => {
|
|
308
305
|
const resolved = await resolveRunPrompt({
|
|
309
306
|
turnId: context.turnId,
|
|
310
|
-
...(context.runId ? { runId: context.runId } : {}),
|
|
311
307
|
...(context.emitSkillCatalogTrace
|
|
312
308
|
? { emitSkillCatalogTrace: context.emitSkillCatalogTrace }
|
|
313
309
|
: {}),
|
|
314
310
|
});
|
|
315
311
|
return resolved.text;
|
|
316
312
|
},
|
|
317
|
-
turnTailPrompt: modelComposition.turnTailPrompt,
|
|
318
|
-
shellRunContextSummary: input.context.shellRunContextSummary,
|
|
319
313
|
lookupPricing: pricing,
|
|
320
314
|
recordModelCallAttempt,
|
|
321
315
|
assertModelCallAccountingReady,
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
import { buildSideConversationSystemPromptFragment, isSideConversationSession, } from '@maka/core/side-conversation';
|
|
20
20
|
import { buildDeepResearchSystemPromptFragment, isDeepResearchSession, } from '@maka/core/deep-research';
|
|
21
21
|
import { activePlanExecution } from '@maka/core/plan';
|
|
22
|
-
import { filterModelVisibleTaskLedgerTasks, renderTaskLedgerPromptText, } from '@maka/core/task-ledger';
|
|
23
22
|
import { assembleMainSessionSystemPrompt } from '@maka/runtime/system-prompt/main-session-prompt';
|
|
24
23
|
import { buildAskUserQuestionTool } from '@maka/runtime/ask-user-question-tool';
|
|
25
24
|
import { buildBuiltinTools } from '@maka/runtime/builtin-tools';
|
|
@@ -27,17 +26,15 @@ import { buildCancelPlanTool, buildSubmitPlanTool, buildUpdatePlanTool, } from '
|
|
|
27
26
|
import { buildParentAgentTools } from '@maka/runtime/subagent-tools';
|
|
28
27
|
import { buildPersonalizationPromptFragment } from '@maka/runtime/system-prompt/personalization-prompt';
|
|
29
28
|
import { buildRequestSandboxBoundaryTool } from '@maka/runtime/sandbox-boundary-tool';
|
|
30
|
-
import { buildSessionEnvironmentPromptFragment } from '@maka/runtime/system-prompt/session-environment-prompt';
|
|
31
29
|
import { buildHostCapabilitiesFromBinding, buildSkillAgentToolFromInventory, buildSkillSearchAgentToolFromInventory, buildSkillsPromptFragmentFromInventoryWithReport, SkillShadowSelectionTracker, } from '@maka/runtime/skills';
|
|
32
30
|
import { buildTaskLedgerTools } from '@maka/runtime/task-ledger-tools';
|
|
33
31
|
import { buildWorkspaceInstructionsPromptFragment } from '@maka/runtime/system-prompt/workspace-instructions';
|
|
34
32
|
import { isDeepResearchToolAllowed } from '@maka/runtime/deep-research-tools';
|
|
35
33
|
import { listRunnableBuiltinAgentDefinitions } from '@maka/runtime/agent-catalog';
|
|
36
|
-
import {
|
|
37
|
-
import { resolveProjectGitInfo } from '@maka/runtime/system-prompt/project-context';
|
|
34
|
+
import { renderPlanModePrompt, selectCollaborationTools } from '@maka/runtime/plan-mode';
|
|
38
35
|
import { routeWebFetchTools } from '@maka/runtime/web-fetch-tool';
|
|
39
36
|
import { routeWebSearchTools } from '@maka/runtime/native-web-search-tool';
|
|
40
|
-
import { resolveTurnShellPlan
|
|
37
|
+
import { resolveTurnShellPlan } from '@maka/runtime/shell-detect';
|
|
41
38
|
import { readDuringBackendCreation } from './execution-model-authority.js';
|
|
42
39
|
import { hostedExecutionRunProfile, projectHostedExecutionTools, } from './hosted-execution-tool-profile.js';
|
|
43
40
|
import { shouldResolveHostTavilyWebSearchReadiness } from './web-search-tool.js';
|
|
@@ -165,26 +162,6 @@ export function createInteractiveRunComposer(input) {
|
|
|
165
162
|
tools,
|
|
166
163
|
toolAvailability,
|
|
167
164
|
resolveSystemPrompt,
|
|
168
|
-
turnTailPrompt: async (context) => {
|
|
169
|
-
const environment = buildSessionEnvironmentPromptFragment({
|
|
170
|
-
cwd: context.cwd,
|
|
171
|
-
projectGit: await resolveProjectGitInfo(context.cwd),
|
|
172
|
-
...(input.platform ? { platform: input.platform } : {}),
|
|
173
|
-
...(input.shell ? { shell: turnShellDisplayName(input.shell) } : {}),
|
|
174
|
-
...(input.now ? { now: input.now() } : {}),
|
|
175
|
-
});
|
|
176
|
-
const tasks = filterModelVisibleTaskLedgerTasks(await input.taskLedger.list(context.sessionId, {
|
|
177
|
-
classifyResumeTrust: true,
|
|
178
|
-
includeArchived: false,
|
|
179
|
-
}));
|
|
180
|
-
return (joinFragments([
|
|
181
|
-
environment,
|
|
182
|
-
renderTaskLedgerTail(tasks),
|
|
183
|
-
input.plan
|
|
184
|
-
? renderPlanTail(input.plan.state, input.plan.mode, input.plan.permissionMode === 'bypass')
|
|
185
|
-
: undefined,
|
|
186
|
-
]) ?? environment);
|
|
187
|
-
},
|
|
188
165
|
});
|
|
189
166
|
}
|
|
190
167
|
/** Routes every model-visible tool surface through the same policy and readiness snapshot. */
|
|
@@ -372,21 +349,6 @@ function requireDeepResearchTools(tools) {
|
|
|
372
349
|
throw new Error('Runtime Host Deep Research tools are not composed');
|
|
373
350
|
return tools;
|
|
374
351
|
}
|
|
375
|
-
function renderPlanTail(state, mode, fullAccess) {
|
|
376
|
-
const active = activePlanExecution(state);
|
|
377
|
-
const execution = active ??
|
|
378
|
-
(mode === 'plan'
|
|
379
|
-
? [...state.executions].reverse().find((candidate) => candidate.status === 'interrupted')
|
|
380
|
-
: undefined);
|
|
381
|
-
if (!execution)
|
|
382
|
-
return undefined;
|
|
383
|
-
const proposal = state.proposals.find((candidate) => candidate.proposalId === execution.proposalId);
|
|
384
|
-
if (!proposal)
|
|
385
|
-
return undefined;
|
|
386
|
-
return active
|
|
387
|
-
? renderPlanExecutionPrompt({ proposal, execution: active })
|
|
388
|
-
: renderInterruptedPlanContext({ proposal, execution, fullAccess });
|
|
389
|
-
}
|
|
390
352
|
function filterToolGroups(groups, names) {
|
|
391
353
|
const seenIds = new Set();
|
|
392
354
|
return groups.flatMap((group) => {
|
|
@@ -472,24 +434,6 @@ function renderMemoryPrompt(body) {
|
|
|
472
434
|
'</local-memory>',
|
|
473
435
|
].join('\n');
|
|
474
436
|
}
|
|
475
|
-
function renderTaskLedgerTail(tasks) {
|
|
476
|
-
if (tasks.length === 0)
|
|
477
|
-
return undefined;
|
|
478
|
-
const rendered = renderTaskLedgerPromptText(tasks);
|
|
479
|
-
if (!rendered.text)
|
|
480
|
-
return undefined;
|
|
481
|
-
return [
|
|
482
|
-
'Current task ledger (current-turn context only; maintain it with task_create, task_update, task_list, and task_get — activate them via tool_search first when they are not already visible):',
|
|
483
|
-
'<task-ledger>',
|
|
484
|
-
rendered.text,
|
|
485
|
-
...(rendered.omittedCount > 0
|
|
486
|
-
? [
|
|
487
|
-
`omitted=${rendered.omittedCount} (use task_list/task_get via tool_search for the complete ledger)`,
|
|
488
|
-
]
|
|
489
|
-
: []),
|
|
490
|
-
'</task-ledger>',
|
|
491
|
-
].join('\n');
|
|
492
|
-
}
|
|
493
437
|
function joinFragments(fragments) {
|
|
494
438
|
const present = fragments
|
|
495
439
|
.map((fragment) => fragment?.trim())
|
package/package.json
CHANGED
|
@@ -1,285 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Licensed to the Apache Software Foundation (ASF) under one
|
|
3
|
-
* or more contributor license agreements. See the NOTICE file
|
|
4
|
-
* distributed with this work for additional information
|
|
5
|
-
* regarding copyright ownership. The ASF licenses this file
|
|
6
|
-
* to you under the Apache License, Version 2.0 (the
|
|
7
|
-
* "License"); you may not use this file except in compliance
|
|
8
|
-
* with the License. You may obtain a copy of the License at
|
|
9
|
-
*
|
|
10
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
-
*
|
|
12
|
-
* Unless required by applicable law or agreed to in writing,
|
|
13
|
-
* software distributed under the License is distributed on an
|
|
14
|
-
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
15
|
-
* KIND, either express or implied. See the License for the
|
|
16
|
-
* specific language governing permissions and limitations
|
|
17
|
-
* under the License.
|
|
18
|
-
*/
|
|
19
|
-
import { constants } from 'node:fs';
|
|
20
|
-
import { access, realpath } from 'node:fs/promises';
|
|
21
|
-
import { tmpdir } from 'node:os';
|
|
22
|
-
import { resolve } from 'node:path';
|
|
23
|
-
import { compilePermissionProfile } from '@maka/core/permission-profile-compiler';
|
|
24
|
-
export function createSandboxDiagnosticsProvider(input) {
|
|
25
|
-
return {
|
|
26
|
-
resolve: async (request) => {
|
|
27
|
-
const canonicalize = input.canonicalizePath ?? canonicalPath;
|
|
28
|
-
const cwd = await canonicalize(request.cwd);
|
|
29
|
-
const workspaceRoots = await Promise.all((request.workspaceRoots ?? [cwd]).map(canonicalize));
|
|
30
|
-
const compiled = request.permissionProfile
|
|
31
|
-
? { profile: request.permissionProfile, workspaceRoots }
|
|
32
|
-
: compilePermissionProfile({ mode: request.mode, cwd, workspaceRoots });
|
|
33
|
-
const platform = input.platform ?? process.platform;
|
|
34
|
-
const capabilityInput = {
|
|
35
|
-
profile: compiled.profile,
|
|
36
|
-
cwd,
|
|
37
|
-
workspaceRoots: compiled.workspaceRoots,
|
|
38
|
-
platform,
|
|
39
|
-
sandboxManager: input.sandboxManager,
|
|
40
|
-
isExecutable: input.isExecutable ?? defaultIsExecutable,
|
|
41
|
-
};
|
|
42
|
-
const command = await probeCommandCapability(capabilityInput);
|
|
43
|
-
const filesystem = await probeFilesystemCapability({
|
|
44
|
-
...capabilityInput,
|
|
45
|
-
getLaunchSpec: input.getFilesystemWorkerLaunchSpec,
|
|
46
|
-
});
|
|
47
|
-
return {
|
|
48
|
-
schemaVersion: 1,
|
|
49
|
-
platform,
|
|
50
|
-
profile: {
|
|
51
|
-
name: profileName(compiled.profile),
|
|
52
|
-
type: compiled.profile.type,
|
|
53
|
-
fileSystem: summarizeFileSystem(compiled.profile),
|
|
54
|
-
network: summarizeNetwork(compiled.profile),
|
|
55
|
-
cwd,
|
|
56
|
-
workspaceRoots: [...new Set(compiled.workspaceRoots)],
|
|
57
|
-
protectedMetadata: protectedMetadataNames(compiled.profile),
|
|
58
|
-
},
|
|
59
|
-
capabilities: { command, filesystem },
|
|
60
|
-
};
|
|
61
|
-
},
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
export function toSandboxRunTraceProjection(snapshot) {
|
|
65
|
-
return {
|
|
66
|
-
schemaVersion: snapshot.schemaVersion,
|
|
67
|
-
platform: snapshot.platform,
|
|
68
|
-
profile: {
|
|
69
|
-
name: snapshot.profile.name,
|
|
70
|
-
type: snapshot.profile.type,
|
|
71
|
-
fileSystem: snapshot.profile.fileSystem,
|
|
72
|
-
network: snapshot.profile.network,
|
|
73
|
-
protectedMetadata: [...snapshot.profile.protectedMetadata],
|
|
74
|
-
},
|
|
75
|
-
capabilities: {
|
|
76
|
-
command: cloneCapability(snapshot.capabilities.command),
|
|
77
|
-
filesystem: cloneCapability(snapshot.capabilities.filesystem),
|
|
78
|
-
},
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
async function probeCommandCapability(input) {
|
|
82
|
-
const passive = passiveCapability(input.profile);
|
|
83
|
-
if (passive)
|
|
84
|
-
return passive;
|
|
85
|
-
const manager = input.sandboxManager;
|
|
86
|
-
if (!manager) {
|
|
87
|
-
return unavailable(expectedSandboxType(input.platform), 'selection', input.platform === 'darwin' || input.platform === 'linux' || input.platform === 'win32'
|
|
88
|
-
? 'backend_not_available'
|
|
89
|
-
: 'unsupported_platform');
|
|
90
|
-
}
|
|
91
|
-
const selection = manager.selectInitial({ profile: input.profile, platform: input.platform });
|
|
92
|
-
if (!selection.ok) {
|
|
93
|
-
return unavailable(selection.sandboxType ?? expectedSandboxType(input.platform), 'selection', selection.reason);
|
|
94
|
-
}
|
|
95
|
-
if (selection.sandboxType === 'none') {
|
|
96
|
-
return {
|
|
97
|
-
status: 'not_required',
|
|
98
|
-
backend: 'none',
|
|
99
|
-
selectionReason: selection.reason,
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
// The Windows broker runs the purpose-built filesystem worker, but cannot
|
|
103
|
-
// launch an arbitrary shell inside its capability-less AppContainer. Match
|
|
104
|
-
// the real Bash execution contract instead of reporting the broker itself as
|
|
105
|
-
// evidence that command sandboxing is available.
|
|
106
|
-
if (input.platform === 'win32') {
|
|
107
|
-
return unavailable('windows', 'capability', 'backend_not_implemented', selection.reason);
|
|
108
|
-
}
|
|
109
|
-
try {
|
|
110
|
-
const probed = manager.probe({
|
|
111
|
-
platform: input.platform,
|
|
112
|
-
command: {
|
|
113
|
-
program: '/bin/sh',
|
|
114
|
-
args: ['-c', 'true'],
|
|
115
|
-
cwd: input.cwd,
|
|
116
|
-
env: {},
|
|
117
|
-
profile: input.profile,
|
|
118
|
-
pathContext: {
|
|
119
|
-
workspaceRoots: input.workspaceRoots,
|
|
120
|
-
tmpdir: await canonicalPath(tmpdir()),
|
|
121
|
-
...(input.platform === 'win32' ? {} : { slashTmp: await canonicalPath('/tmp') }),
|
|
122
|
-
},
|
|
123
|
-
},
|
|
124
|
-
});
|
|
125
|
-
if (!probed.ok) {
|
|
126
|
-
return unavailable(probed.sandboxType ?? selection.sandboxType, 'transform', probed.reason, selection.reason);
|
|
127
|
-
}
|
|
128
|
-
const executable = probed.executable;
|
|
129
|
-
if (!executable || !(await safelyCheckExecutable(executable, input.isExecutable))) {
|
|
130
|
-
return unavailable(probed.sandboxType, 'capability', 'executable_unavailable', selection.reason);
|
|
131
|
-
}
|
|
132
|
-
return {
|
|
133
|
-
status: 'available',
|
|
134
|
-
backend: probed.sandboxType,
|
|
135
|
-
selectionReason: selection.reason,
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
catch {
|
|
139
|
-
return unavailable(selection.sandboxType, 'capability', 'capability_probe_failed', selection.reason);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
async function probeFilesystemCapability(input) {
|
|
143
|
-
const passive = passiveCapability(input.profile);
|
|
144
|
-
if (passive)
|
|
145
|
-
return passive;
|
|
146
|
-
if (!input.sandboxManager) {
|
|
147
|
-
return unavailable(expectedSandboxType(input.platform), 'selection', 'backend_not_available');
|
|
148
|
-
}
|
|
149
|
-
const selection = input.sandboxManager.selectInitial({
|
|
150
|
-
profile: input.profile,
|
|
151
|
-
platform: input.platform,
|
|
152
|
-
});
|
|
153
|
-
if (!selection.ok) {
|
|
154
|
-
return unavailable(selection.sandboxType ?? expectedSandboxType(input.platform), 'selection', selection.reason);
|
|
155
|
-
}
|
|
156
|
-
if (!input.getLaunchSpec) {
|
|
157
|
-
return unavailable(selection.sandboxType, 'launch', 'filesystem_worker_unavailable', selection.reason);
|
|
158
|
-
}
|
|
159
|
-
let launch;
|
|
160
|
-
try {
|
|
161
|
-
launch = await input.getLaunchSpec();
|
|
162
|
-
}
|
|
163
|
-
catch {
|
|
164
|
-
return unavailable(selection.sandboxType, 'capability', 'capability_probe_failed', selection.reason);
|
|
165
|
-
}
|
|
166
|
-
if (!launch.ok) {
|
|
167
|
-
return unavailable(selection.sandboxType, 'launch', launch.reason, selection.reason);
|
|
168
|
-
}
|
|
169
|
-
try {
|
|
170
|
-
const probed = input.sandboxManager.probe({
|
|
171
|
-
platform: input.platform,
|
|
172
|
-
command: {
|
|
173
|
-
program: launch.spec.program,
|
|
174
|
-
args: launch.spec.args,
|
|
175
|
-
cwd: input.cwd,
|
|
176
|
-
env: launch.spec.env,
|
|
177
|
-
profile: input.profile,
|
|
178
|
-
pathContext: {
|
|
179
|
-
workspaceRoots: input.workspaceRoots,
|
|
180
|
-
tmpdir: await canonicalPath(tmpdir()),
|
|
181
|
-
...(input.platform === 'win32' ? {} : { slashTmp: await canonicalPath('/tmp') }),
|
|
182
|
-
runtimeReadableRoots: launch.spec.runtimeReadableRoots,
|
|
183
|
-
executableRoots: launch.spec.executableRoots,
|
|
184
|
-
},
|
|
185
|
-
},
|
|
186
|
-
});
|
|
187
|
-
if (!probed.ok) {
|
|
188
|
-
return unavailable(probed.sandboxType ?? selection.sandboxType, 'transform', probed.reason, selection.reason);
|
|
189
|
-
}
|
|
190
|
-
const executable = probed.executable;
|
|
191
|
-
if (!executable || !(await safelyCheckExecutable(executable, input.isExecutable))) {
|
|
192
|
-
return unavailable(probed.sandboxType, 'capability', 'executable_unavailable', selection.reason);
|
|
193
|
-
}
|
|
194
|
-
return {
|
|
195
|
-
status: 'available',
|
|
196
|
-
backend: probed.sandboxType,
|
|
197
|
-
selectionReason: selection.reason,
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
catch {
|
|
201
|
-
return unavailable(selection.sandboxType, 'capability', 'capability_probe_failed', selection.reason);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
function passiveCapability(profile) {
|
|
205
|
-
if (profile.type === 'external')
|
|
206
|
-
return { status: 'external', backend: 'none' };
|
|
207
|
-
if (profile.type === 'disabled' ||
|
|
208
|
-
(profile.type === 'managed' && profile.fileSystem.kind !== 'restricted')) {
|
|
209
|
-
return {
|
|
210
|
-
status: 'not_required',
|
|
211
|
-
backend: 'none',
|
|
212
|
-
selectionReason: 'sandbox_not_required',
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
return undefined;
|
|
216
|
-
}
|
|
217
|
-
function unavailable(backend, stage, reason, selectionReason) {
|
|
218
|
-
return {
|
|
219
|
-
status: 'unavailable',
|
|
220
|
-
backend,
|
|
221
|
-
...(selectionReason ? { selectionReason } : {}),
|
|
222
|
-
failure: { stage, reason },
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
function expectedSandboxType(platform) {
|
|
226
|
-
if (platform === 'darwin')
|
|
227
|
-
return 'macos-seatbelt';
|
|
228
|
-
if (platform === 'linux')
|
|
229
|
-
return 'linux';
|
|
230
|
-
if (platform === 'win32')
|
|
231
|
-
return 'windows';
|
|
232
|
-
return 'none';
|
|
233
|
-
}
|
|
234
|
-
function profileName(profile) {
|
|
235
|
-
return profile.name ?? profile.type;
|
|
236
|
-
}
|
|
237
|
-
function summarizeFileSystem(profile) {
|
|
238
|
-
if (profile.type === 'disabled')
|
|
239
|
-
return 'disabled';
|
|
240
|
-
if (profile.type === 'external')
|
|
241
|
-
return 'external';
|
|
242
|
-
if (profile.fileSystem.kind === 'unrestricted')
|
|
243
|
-
return 'unrestricted';
|
|
244
|
-
if (profile.fileSystem.kind === 'external_sandbox')
|
|
245
|
-
return 'external';
|
|
246
|
-
if (!profile.fileSystem.entries.some((entry) => entry.access === 'write'))
|
|
247
|
-
return 'read-only';
|
|
248
|
-
return profile.fileSystem.entries.some((entry) => entry.kind === 'special' && entry.special === ':workspace_roots' && entry.access === 'write')
|
|
249
|
-
? 'workspace-write'
|
|
250
|
-
: 'custom-restricted';
|
|
251
|
-
}
|
|
252
|
-
function summarizeNetwork(profile) {
|
|
253
|
-
return profile.type === 'disabled' ? 'unmanaged' : profile.network.kind;
|
|
254
|
-
}
|
|
255
|
-
function protectedMetadataNames(profile) {
|
|
256
|
-
if (profile.type !== 'managed')
|
|
257
|
-
return [];
|
|
258
|
-
return [...(profile.fileSystem.protectedMetadata?.names ?? [])];
|
|
259
|
-
}
|
|
260
|
-
function cloneCapability(capability) {
|
|
261
|
-
return {
|
|
262
|
-
...capability,
|
|
263
|
-
...(capability.failure ? { failure: { ...capability.failure } } : {}),
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
async function safelyCheckExecutable(path, isExecutable) {
|
|
267
|
-
try {
|
|
268
|
-
return await isExecutable(path);
|
|
269
|
-
}
|
|
270
|
-
catch {
|
|
271
|
-
return false;
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
async function defaultIsExecutable(path) {
|
|
275
|
-
try {
|
|
276
|
-
await access(path, constants.X_OK);
|
|
277
|
-
return true;
|
|
278
|
-
}
|
|
279
|
-
catch {
|
|
280
|
-
return false;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
async function canonicalPath(path) {
|
|
284
|
-
return await realpath(path).catch(() => resolve(path));
|
|
285
|
-
}
|