@kruntime/komputer 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/approvals.js +6 -1
- package/dist/agent/approvals.js.map +1 -1
- package/dist/agent-session.d.ts +1 -0
- package/dist/agent-session.js +248 -12
- package/dist/agent-session.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/komputer.js +29 -2
- package/dist/komputer.js.map +1 -1
- package/dist/shell/builtins/commands/filesystem.js +22 -20
- package/dist/shell/builtins/commands/filesystem.js.map +1 -1
- package/dist/shell/builtins/commands/network.js +3 -2
- package/dist/shell/builtins/commands/network.js.map +1 -1
- package/dist/shell/builtins/commands/process.js +9 -7
- package/dist/shell/builtins/commands/process.js.map +1 -1
- package/dist/shell/builtins/commands/system.js +27 -24
- package/dist/shell/builtins/commands/system.js.map +1 -1
- package/dist/shell/builtins/commands/text.js +20 -18
- package/dist/shell/builtins/commands/text.js.map +1 -1
- package/dist/shell/builtins/run.d.ts +9 -1
- package/dist/shell/builtins/run.js +12 -0
- package/dist/shell/builtins/run.js.map +1 -1
- package/dist/shell/builtins/runtime.d.ts +6 -2
- package/dist/shell/builtins/runtime.js +10 -3
- package/dist/shell/builtins/runtime.js.map +1 -1
- package/dist/types.d.ts +33 -0
- package/package.json +1 -1
package/dist/agent/approvals.js
CHANGED
|
@@ -96,7 +96,12 @@ export function resultSummary(value) {
|
|
|
96
96
|
return { type: typeof value };
|
|
97
97
|
}
|
|
98
98
|
function approvalActionKey(hook, current) {
|
|
99
|
-
return sha256(stableJson({ hook, current }));
|
|
99
|
+
return sha256(stableJson({ hook, current: approvalActionCurrent(current) }));
|
|
100
|
+
}
|
|
101
|
+
function approvalActionCurrent(current) {
|
|
102
|
+
const copy = { ...current };
|
|
103
|
+
delete copy.execToolUseId;
|
|
104
|
+
return copy;
|
|
100
105
|
}
|
|
101
106
|
function stableJson(value) {
|
|
102
107
|
if (value === null || typeof value !== 'object')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"approvals.js","sourceRoot":"","sources":["../../../../../packages/komputer/src/agent/approvals.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"approvals.js","sourceRoot":"","sources":["../../../../../packages/komputer/src/agent/approvals.ts"],"names":[],"mappings":"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"}
|
package/dist/agent-session.d.ts
CHANGED
package/dist/agent-session.js
CHANGED
|
@@ -594,10 +594,24 @@ export class AgentSession {
|
|
|
594
594
|
return this.send(current.content, recordField(current, 'options') || {});
|
|
595
595
|
}
|
|
596
596
|
if (hook === 'shell.before' || hook === 'cmd.before') {
|
|
597
|
-
|
|
597
|
+
const result = await this.execInternal(stringField(current, 'shellScript') || stringField(current, 'script'), {
|
|
598
598
|
by: stringField(current, 'by') || `approval:${approval.id}`,
|
|
599
599
|
foreground: typeof current.foreground === 'boolean' ? current.foreground : undefined,
|
|
600
600
|
});
|
|
601
|
+
const execToolUseId = stringField(current, 'execToolUseId');
|
|
602
|
+
if (execToolUseId) {
|
|
603
|
+
const bounded = this.boundShellResult(result);
|
|
604
|
+
await this.appendExecToolExchange(execToolUseMessageFromApproval(current, execToolUseId), execToolUseId, bounded, stringField(current, 'by') || `approval:${approval.id}`);
|
|
605
|
+
await this.emit({
|
|
606
|
+
type: 'tool',
|
|
607
|
+
status: shellToolEventStatus(bounded),
|
|
608
|
+
tool: 'shell',
|
|
609
|
+
result: bounded,
|
|
610
|
+
opId: execToolUseId,
|
|
611
|
+
approvalId: approval.id,
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
return result;
|
|
601
615
|
}
|
|
602
616
|
if (hook === 'tool.before') {
|
|
603
617
|
return this.command(stringField(current, 'command'), recordField(current, 'input') || {}, {
|
|
@@ -1060,10 +1074,20 @@ export class AgentSession {
|
|
|
1060
1074
|
};
|
|
1061
1075
|
try {
|
|
1062
1076
|
await this.emit({ type: 'tool', status: 'requested', tool: 'shell', input: toolUseMessage.content[0]?.input, opId: toolUseId });
|
|
1063
|
-
const result = await this.execShell(command, options);
|
|
1077
|
+
const result = await this.execShell(command, { ...options, execToolUseId: toolUseId });
|
|
1064
1078
|
const bounded = this.boundShellResult(result);
|
|
1065
|
-
|
|
1066
|
-
|
|
1079
|
+
const toolStatus = shellToolEventStatus(bounded);
|
|
1080
|
+
if (toolStatus !== 'waiting_approval') {
|
|
1081
|
+
await this.appendExecToolExchange(toolUseMessage, toolUseId, bounded, by);
|
|
1082
|
+
}
|
|
1083
|
+
await this.emit({
|
|
1084
|
+
type: 'tool',
|
|
1085
|
+
status: toolStatus,
|
|
1086
|
+
tool: 'shell',
|
|
1087
|
+
result: bounded,
|
|
1088
|
+
opId: toolUseId,
|
|
1089
|
+
approvalId: stringField(recordField(bounded, 'approval') || {}, 'id'),
|
|
1090
|
+
});
|
|
1067
1091
|
return bounded;
|
|
1068
1092
|
}
|
|
1069
1093
|
catch (error) {
|
|
@@ -1134,7 +1158,7 @@ export class AgentSession {
|
|
|
1134
1158
|
const shell = String(command);
|
|
1135
1159
|
const foreground = options.foreground ?? !shell.trimEnd().endsWith('&');
|
|
1136
1160
|
let script = foreground ? shell : shell.trimEnd().replace(/&\s*$/, '');
|
|
1137
|
-
const beforeShell = await this.runHook('shell.before', { script, cwd: this.hookCwd(), by: normalizeBy(options.by) });
|
|
1161
|
+
const beforeShell = await this.runHook('shell.before', { script, cwd: this.hookCwd(), by: normalizeBy(options.by), foreground, execToolUseId: options.execToolUseId });
|
|
1138
1162
|
if (beforeShell.rejected) {
|
|
1139
1163
|
await this.trace('process.rejected', { script, reason: beforeShell.reason });
|
|
1140
1164
|
if (beforeShell.waitingApproval) {
|
|
@@ -1184,6 +1208,7 @@ export class AgentSession {
|
|
|
1184
1208
|
by: normalizeBy(options.by),
|
|
1185
1209
|
foreground: foreground && !concrete.background,
|
|
1186
1210
|
background: !foreground || concrete.background,
|
|
1211
|
+
execToolUseId: options.execToolUseId,
|
|
1187
1212
|
});
|
|
1188
1213
|
if (beforeCmd.rejected) {
|
|
1189
1214
|
await this.trace('process.rejected', { cmd: concrete.cmd, args: concrete.args, reason: beforeCmd.reason });
|
|
@@ -2621,6 +2646,9 @@ export class AgentSession {
|
|
|
2621
2646
|
throw new Error(`command not found: ${name}`);
|
|
2622
2647
|
if (command.agent && command.agent !== this.agentName)
|
|
2623
2648
|
throw new Error(`command ${name} belongs to agent ${command.agent}`);
|
|
2649
|
+
if (isCommandHelpInput(input)) {
|
|
2650
|
+
return { type: 'stdout', text: `${commandHelpText(name, command)}\n`, code: 0 };
|
|
2651
|
+
}
|
|
2624
2652
|
const by = normalizeBy(options.by || (typeof input.by === 'string' ? input.by : undefined));
|
|
2625
2653
|
const toolName = `command:${name}`;
|
|
2626
2654
|
const before = await this.runHook('tool.before', { tool: toolName, command: name, input, by });
|
|
@@ -2637,7 +2665,16 @@ export class AgentSession {
|
|
|
2637
2665
|
throw new Error(authority.reason);
|
|
2638
2666
|
}
|
|
2639
2667
|
const toolUseId = id('tool');
|
|
2640
|
-
const
|
|
2668
|
+
const parsed = parseCommandInput(name, command, currentInput);
|
|
2669
|
+
const ctx = this.runtime.runtimeContext(this, {
|
|
2670
|
+
kind: 'command',
|
|
2671
|
+
name,
|
|
2672
|
+
input: currentInput,
|
|
2673
|
+
args: parsed.args,
|
|
2674
|
+
argv: parsed.argv,
|
|
2675
|
+
stdin: parsed.stdin,
|
|
2676
|
+
env: parsed.env,
|
|
2677
|
+
});
|
|
2641
2678
|
await this.emit({ type: 'tool', status: 'requested', tool: toolName, input: currentInput, opId: toolUseId });
|
|
2642
2679
|
await this.trace('tool.started', { name, input: currentInput, by, toolUseId });
|
|
2643
2680
|
let result;
|
|
@@ -2652,20 +2689,30 @@ export class AgentSession {
|
|
|
2652
2689
|
result = invocationMode ? await this.withTemporaryMode(invocationMode, runShell) : await runShell();
|
|
2653
2690
|
}
|
|
2654
2691
|
else if (command.kind === 'markdown') {
|
|
2655
|
-
const
|
|
2692
|
+
const prompt = String(command.prompt ?? '');
|
|
2693
|
+
const rendered = renderMarkdownCommandPrompt(prompt, parsed.args, parsed.stdin);
|
|
2694
|
+
const args = hasCommandTemplate(prompt) || Object.keys(currentInput).length === 0
|
|
2695
|
+
? ''
|
|
2696
|
+
: `\n\nInput:\n${JSON.stringify(currentInput, null, 2)}`;
|
|
2656
2697
|
const invocationMode = command.readonly === true
|
|
2657
2698
|
? 'readonly'
|
|
2658
2699
|
: typeof command.mode === 'string'
|
|
2659
2700
|
? command.mode
|
|
2660
2701
|
: undefined;
|
|
2661
|
-
const runMarkdown = () => this.run(`${
|
|
2702
|
+
const runMarkdown = () => this.run(`${rendered}${args}`, { by: options.by || `command:${name}`, model: typeof command.model === 'string' ? command.model : undefined });
|
|
2662
2703
|
result = invocationMode ? await this.withTemporaryMode(invocationMode, runMarkdown) : await runMarkdown();
|
|
2663
2704
|
}
|
|
2664
2705
|
else {
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2706
|
+
const main = command.main ?? command.handler;
|
|
2707
|
+
if (!main)
|
|
2708
|
+
throw new Error(`command has no main: ${name}`);
|
|
2709
|
+
const runModule = () => this.withFsActor(options.by ? by : `command:${name}`, () => Promise.resolve(main(ctx, parsed.args)));
|
|
2710
|
+
const invocationMode = command.readonly === true
|
|
2711
|
+
? 'readonly'
|
|
2712
|
+
: typeof command.mode === 'string'
|
|
2713
|
+
? command.mode
|
|
2714
|
+
: undefined;
|
|
2715
|
+
result = invocationMode ? await this.withTemporaryMode(invocationMode, runModule) : await runModule();
|
|
2669
2716
|
}
|
|
2670
2717
|
const after = await this.runHook('tool.after', { tool: toolName, command: name, input: currentInput, result, by });
|
|
2671
2718
|
if (after.rejected) {
|
|
@@ -2967,6 +3014,169 @@ function commandErrorText(command, error) {
|
|
|
2967
3014
|
function isHelpArg(value) {
|
|
2968
3015
|
return value === '--help' || value === '-h';
|
|
2969
3016
|
}
|
|
3017
|
+
function isCommandHelpInput(input) {
|
|
3018
|
+
const argv = stringArrayField(input, 'argv') || [];
|
|
3019
|
+
return argv.length === 1 && isHelpArg(argv[0]);
|
|
3020
|
+
}
|
|
3021
|
+
function parseCommandInput(name, command, input) {
|
|
3022
|
+
const argv = stringArrayField(input, 'argv') || [];
|
|
3023
|
+
const stdin = typeof input.stdin === 'string' ? input.stdin : '';
|
|
3024
|
+
const envRecord = recordField(input, 'env');
|
|
3025
|
+
const env = envRecord ? stringRecord(envRecord) : undefined;
|
|
3026
|
+
if (command.args === 'none') {
|
|
3027
|
+
const extra = argv.filter((arg) => arg !== '--');
|
|
3028
|
+
if (extra.length)
|
|
3029
|
+
throw new Error(`${name}: unexpected argument: ${extra[0]}`);
|
|
3030
|
+
return { argv, stdin, env, args: {} };
|
|
3031
|
+
}
|
|
3032
|
+
if (!command.args || command.args === 'argv')
|
|
3033
|
+
return { argv, stdin, env, args: input };
|
|
3034
|
+
return { argv, stdin, env, args: parseStructuredCommandArgs(name, command.args, input, argv) };
|
|
3035
|
+
}
|
|
3036
|
+
function parseStructuredCommandArgs(name, specs, input, argv) {
|
|
3037
|
+
const parsed = {};
|
|
3038
|
+
const options = commandOptionSpecs(specs);
|
|
3039
|
+
for (const [key, spec] of Object.entries(specs)) {
|
|
3040
|
+
if ('default' in spec)
|
|
3041
|
+
parsed[key] = spec.default;
|
|
3042
|
+
else if ('defaultValue' in spec)
|
|
3043
|
+
parsed[key] = spec.defaultValue;
|
|
3044
|
+
}
|
|
3045
|
+
for (const [key, value] of Object.entries(input)) {
|
|
3046
|
+
if (key !== 'argv' && key !== 'stdin' && key !== 'env' && specs[key])
|
|
3047
|
+
parsed[key] = value;
|
|
3048
|
+
}
|
|
3049
|
+
const positional = Object.entries(specs)
|
|
3050
|
+
.filter(([, spec]) => typeof spec.position === 'number')
|
|
3051
|
+
.sort((a, b) => Number(a[1].position) - Number(b[1].position));
|
|
3052
|
+
let positionalIndex = 0;
|
|
3053
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
3054
|
+
const token = argv[index];
|
|
3055
|
+
if (token === '--') {
|
|
3056
|
+
for (const rest of argv.slice(index + 1))
|
|
3057
|
+
assignPositional(name, parsed, positional, positionalIndex++, rest);
|
|
3058
|
+
break;
|
|
3059
|
+
}
|
|
3060
|
+
if (token.startsWith('--')) {
|
|
3061
|
+
const body = token.slice(2);
|
|
3062
|
+
const eq = body.indexOf('=');
|
|
3063
|
+
const option = eq >= 0 ? body.slice(0, eq) : body;
|
|
3064
|
+
const resolved = options.get(option);
|
|
3065
|
+
if (!resolved)
|
|
3066
|
+
throw new Error(`${name}: unsupported option: --${option}`);
|
|
3067
|
+
const [key, spec] = resolved;
|
|
3068
|
+
if (spec.type === 'boolean' && eq < 0) {
|
|
3069
|
+
parsed[key] = true;
|
|
3070
|
+
continue;
|
|
3071
|
+
}
|
|
3072
|
+
const value = eq >= 0 ? body.slice(eq + 1) : argv[++index];
|
|
3073
|
+
if (value === undefined)
|
|
3074
|
+
throw new Error(`${name}: option requires an argument: --${key}`);
|
|
3075
|
+
assignCommandArg(name, parsed, key, spec, value);
|
|
3076
|
+
continue;
|
|
3077
|
+
}
|
|
3078
|
+
const eq = token.indexOf('=');
|
|
3079
|
+
if (eq > 0 && specs[token.slice(0, eq)]) {
|
|
3080
|
+
const key = token.slice(0, eq);
|
|
3081
|
+
assignCommandArg(name, parsed, key, specs[key], token.slice(eq + 1));
|
|
3082
|
+
continue;
|
|
3083
|
+
}
|
|
3084
|
+
assignPositional(name, parsed, positional, positionalIndex++, token);
|
|
3085
|
+
}
|
|
3086
|
+
for (const [key, spec] of Object.entries(specs)) {
|
|
3087
|
+
if (spec.required === true && (parsed[key] === undefined || parsed[key] === '')) {
|
|
3088
|
+
throw new Error(`${name}: missing required argument: --${key}`);
|
|
3089
|
+
}
|
|
3090
|
+
if (parsed[key] !== undefined)
|
|
3091
|
+
parsed[key] = coerceCommandArg(name, key, spec, parsed[key]);
|
|
3092
|
+
}
|
|
3093
|
+
return parsed;
|
|
3094
|
+
}
|
|
3095
|
+
function commandOptionSpecs(specs) {
|
|
3096
|
+
const options = new Map();
|
|
3097
|
+
for (const [key, spec] of Object.entries(specs)) {
|
|
3098
|
+
options.set(key, [key, spec]);
|
|
3099
|
+
const flag = typeof spec.flag === 'string' ? normalizeCommandFlag(spec.flag) : undefined;
|
|
3100
|
+
if (flag)
|
|
3101
|
+
options.set(flag, [key, spec]);
|
|
3102
|
+
}
|
|
3103
|
+
return options;
|
|
3104
|
+
}
|
|
3105
|
+
function normalizeCommandFlag(flag) {
|
|
3106
|
+
return flag.trim().replace(/^-+/, '');
|
|
3107
|
+
}
|
|
3108
|
+
function assignPositional(name, parsed, positional, index, value) {
|
|
3109
|
+
const entry = positional[index];
|
|
3110
|
+
if (!entry)
|
|
3111
|
+
throw new Error(`${name}: unexpected argument: ${String(value)}`);
|
|
3112
|
+
assignCommandArg(name, parsed, entry[0], entry[1], value);
|
|
3113
|
+
}
|
|
3114
|
+
function assignCommandArg(name, parsed, key, spec, value) {
|
|
3115
|
+
const coerced = coerceCommandArg(name, key, spec, value);
|
|
3116
|
+
if (spec.repeat) {
|
|
3117
|
+
const current = Array.isArray(parsed[key]) ? parsed[key] : parsed[key] === undefined ? [] : [parsed[key]];
|
|
3118
|
+
current.push(coerced);
|
|
3119
|
+
parsed[key] = current;
|
|
3120
|
+
return;
|
|
3121
|
+
}
|
|
3122
|
+
parsed[key] = coerced;
|
|
3123
|
+
}
|
|
3124
|
+
function coerceCommandArg(name, key, spec, value) {
|
|
3125
|
+
if (value === undefined)
|
|
3126
|
+
return value;
|
|
3127
|
+
if (spec.type === 'string' || spec.type === 'path')
|
|
3128
|
+
return String(value);
|
|
3129
|
+
if (spec.type === 'number') {
|
|
3130
|
+
const number = typeof value === 'number' ? value : Number(String(value));
|
|
3131
|
+
if (!Number.isFinite(number))
|
|
3132
|
+
throw new Error(`${name}: invalid value for --${key}: expected number`);
|
|
3133
|
+
return number;
|
|
3134
|
+
}
|
|
3135
|
+
if (spec.type === 'boolean') {
|
|
3136
|
+
if (typeof value === 'boolean')
|
|
3137
|
+
return value;
|
|
3138
|
+
const text = String(value).toLowerCase();
|
|
3139
|
+
if (text === 'true' || text === '1' || text === 'yes')
|
|
3140
|
+
return true;
|
|
3141
|
+
if (text === 'false' || text === '0' || text === 'no')
|
|
3142
|
+
return false;
|
|
3143
|
+
throw new Error(`${name}: invalid value for --${key}: expected boolean`);
|
|
3144
|
+
}
|
|
3145
|
+
if (spec.type === 'json') {
|
|
3146
|
+
if (typeof value !== 'string')
|
|
3147
|
+
return value;
|
|
3148
|
+
try {
|
|
3149
|
+
return JSON.parse(value);
|
|
3150
|
+
}
|
|
3151
|
+
catch {
|
|
3152
|
+
throw new Error(`${name}: invalid value for --${key}: expected json`);
|
|
3153
|
+
}
|
|
3154
|
+
}
|
|
3155
|
+
return value;
|
|
3156
|
+
}
|
|
3157
|
+
function stringRecord(record) {
|
|
3158
|
+
const output = {};
|
|
3159
|
+
for (const [key, value] of Object.entries(record)) {
|
|
3160
|
+
if (typeof value === 'string')
|
|
3161
|
+
output[key] = value;
|
|
3162
|
+
}
|
|
3163
|
+
return output;
|
|
3164
|
+
}
|
|
3165
|
+
function hasCommandTemplate(prompt) {
|
|
3166
|
+
return /\{\{\s*(?:arg|args)\.[A-Za-z0-9_.-]+\s*\}\}|\{\{\s*stdin\s*\}\}/.test(prompt);
|
|
3167
|
+
}
|
|
3168
|
+
function renderMarkdownCommandPrompt(prompt, args, stdin) {
|
|
3169
|
+
return prompt.replace(/\{\{\s*((?:arg|args)\.([A-Za-z0-9_.-]+)|stdin)\s*\}\}/g, (_match, token, argName) => {
|
|
3170
|
+
if (token === 'stdin')
|
|
3171
|
+
return stdin;
|
|
3172
|
+
const value = argName ? args[argName] : undefined;
|
|
3173
|
+
if (value === undefined || value === null)
|
|
3174
|
+
return '';
|
|
3175
|
+
if (typeof value === 'string')
|
|
3176
|
+
return value;
|
|
3177
|
+
return JSON.stringify(value);
|
|
3178
|
+
});
|
|
3179
|
+
}
|
|
2970
3180
|
function isExpiredWorker(worker) {
|
|
2971
3181
|
const expiresAt = typeof worker.expiresAt === 'string' ? Date.parse(worker.expiresAt) : Number.NaN;
|
|
2972
3182
|
return Number.isFinite(expiresAt) && expiresAt <= Date.now();
|
|
@@ -3010,6 +3220,32 @@ function turnStatus(status) {
|
|
|
3010
3220
|
return 'cancelled';
|
|
3011
3221
|
return 'completed';
|
|
3012
3222
|
}
|
|
3223
|
+
function shellToolEventStatus(result) {
|
|
3224
|
+
if (result.status === 'waiting_approval')
|
|
3225
|
+
return 'waiting_approval';
|
|
3226
|
+
if (result.status === 'committed' || result.status === 'completed')
|
|
3227
|
+
return 'completed';
|
|
3228
|
+
if (typeof result.code === 'number')
|
|
3229
|
+
return result.code === 0 ? 'completed' : 'failed';
|
|
3230
|
+
return 'failed';
|
|
3231
|
+
}
|
|
3232
|
+
function execToolUseMessageFromApproval(current, toolUseId) {
|
|
3233
|
+
const script = stringField(current, 'shellScript') || stringField(current, 'script');
|
|
3234
|
+
return {
|
|
3235
|
+
role: 'assistant',
|
|
3236
|
+
by: stringField(current, 'by') || 'approval',
|
|
3237
|
+
content: [{
|
|
3238
|
+
type: 'tool_use',
|
|
3239
|
+
id: toolUseId,
|
|
3240
|
+
name: 'shell',
|
|
3241
|
+
input: {
|
|
3242
|
+
script,
|
|
3243
|
+
cwd: stringField(current, 'cwd'),
|
|
3244
|
+
foreground: typeof current.foreground === 'boolean' ? current.foreground : undefined,
|
|
3245
|
+
},
|
|
3246
|
+
}],
|
|
3247
|
+
};
|
|
3248
|
+
}
|
|
3013
3249
|
function shouldExpandBraces(token) {
|
|
3014
3250
|
let hasUnquotedBrace = false;
|
|
3015
3251
|
for (const part of token.parts) {
|