prompt-language-shell 0.4.6 → 0.4.9
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/config/CONFIG.md +66 -0
- package/dist/config/EXECUTE.md +279 -0
- package/dist/config/INTROSPECT.md +29 -14
- package/dist/config/PLAN.md +40 -6
- package/dist/handlers/answer.js +13 -20
- package/dist/handlers/command.js +26 -30
- package/dist/handlers/config.js +44 -12
- package/dist/handlers/execute.js +38 -0
- package/dist/handlers/execution.js +66 -61
- package/dist/handlers/introspect.js +13 -20
- package/dist/handlers/plan.js +33 -36
- package/dist/services/anthropic.js +66 -12
- package/dist/services/colors.js +6 -5
- package/dist/services/components.js +159 -22
- package/dist/services/configuration.js +80 -0
- package/dist/services/keyboard.js +86 -0
- package/dist/services/messages.js +31 -0
- package/dist/services/shell.js +117 -0
- package/dist/services/tool-registry.js +10 -0
- package/dist/services/utils.js +21 -0
- package/dist/tools/config.tool.js +43 -0
- package/dist/tools/execute.tool.js +44 -0
- package/dist/types/handlers.js +1 -0
- package/dist/types/types.js +1 -0
- package/dist/ui/Answer.js +7 -5
- package/dist/ui/Command.js +15 -3
- package/dist/ui/Component.js +7 -1
- package/dist/ui/Config.js +6 -3
- package/dist/ui/Confirm.js +4 -3
- package/dist/ui/Execute.js +217 -0
- package/dist/ui/Introspect.js +20 -7
- package/dist/ui/Main.js +35 -74
- package/dist/ui/Plan.js +2 -1
- package/dist/ui/Refinement.js +2 -1
- package/dist/ui/Report.js +7 -3
- package/dist/ui/Spinner.js +10 -5
- package/package.json +7 -7
package/dist/handlers/config.js
CHANGED
|
@@ -1,39 +1,71 @@
|
|
|
1
1
|
import { ComponentName, FeedbackType } from '../types/types.js';
|
|
2
2
|
import { createAnthropicService, } from '../services/anthropic.js';
|
|
3
3
|
import { createCommandDefinition, createFeedback, markAsDone, } from '../services/components.js';
|
|
4
|
-
import { saveAnthropicConfig } from '../services/configuration.js';
|
|
4
|
+
import { saveAnthropicConfig, saveConfig } from '../services/configuration.js';
|
|
5
5
|
import { FeedbackMessages } from '../services/messages.js';
|
|
6
6
|
import { exitApp } from '../services/process.js';
|
|
7
7
|
import { withQueueHandler } from '../services/queue.js';
|
|
8
8
|
/**
|
|
9
|
-
* Creates config
|
|
9
|
+
* Creates all config handlers
|
|
10
10
|
*/
|
|
11
|
-
export function
|
|
12
|
-
|
|
11
|
+
export function createConfigHandlers(ops, handleAborted, command, commandHandlers, setService) {
|
|
12
|
+
const onFinished = (config) => {
|
|
13
13
|
const anthropicConfig = config;
|
|
14
14
|
saveAnthropicConfig(anthropicConfig);
|
|
15
15
|
const newService = createAnthropicService(anthropicConfig);
|
|
16
16
|
setService(newService);
|
|
17
|
-
|
|
18
|
-
addToTimeline(markAsDone(first), createFeedback(FeedbackType.Succeeded, FeedbackMessages.ConfigurationComplete));
|
|
19
|
-
// Add command to queue if we have one
|
|
17
|
+
ops.setQueue(withQueueHandler(ComponentName.Config, (first, rest) => {
|
|
18
|
+
ops.addToTimeline(markAsDone(first), createFeedback(FeedbackType.Succeeded, FeedbackMessages.ConfigurationComplete));
|
|
20
19
|
if (command) {
|
|
21
20
|
return [
|
|
22
21
|
...rest,
|
|
23
|
-
createCommandDefinition(command, newService,
|
|
22
|
+
createCommandDefinition(command, newService, commandHandlers.onError, commandHandlers.onComplete, commandHandlers.onAborted),
|
|
24
23
|
];
|
|
25
24
|
}
|
|
26
|
-
|
|
25
|
+
exitApp(0);
|
|
26
|
+
return rest;
|
|
27
|
+
}, false, 0));
|
|
28
|
+
};
|
|
29
|
+
const onAborted = () => {
|
|
30
|
+
handleAborted('Configuration');
|
|
31
|
+
};
|
|
32
|
+
return { onFinished, onAborted };
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Creates config execution finished handler for CONFIG skill
|
|
36
|
+
* Saves arbitrary config keys and exits
|
|
37
|
+
*/
|
|
38
|
+
export function createConfigExecutionFinishedHandler(addToTimeline, keys) {
|
|
39
|
+
return (config) => {
|
|
40
|
+
const sections = {};
|
|
41
|
+
for (const fullKey of keys) {
|
|
42
|
+
const parts = fullKey.split('.');
|
|
43
|
+
const shortKey = parts[parts.length - 1];
|
|
44
|
+
const section = parts.slice(0, -1).join('.');
|
|
45
|
+
sections[section] = sections[section] ?? {};
|
|
46
|
+
if (shortKey in config) {
|
|
47
|
+
sections[section][shortKey] = config[shortKey];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
for (const [section, sectionConfig] of Object.entries(sections)) {
|
|
51
|
+
saveConfig(section, sectionConfig);
|
|
52
|
+
}
|
|
53
|
+
return withQueueHandler(ComponentName.Config, (first, rest) => {
|
|
54
|
+
addToTimeline(markAsDone(first), createFeedback(FeedbackType.Succeeded, FeedbackMessages.ConfigurationComplete));
|
|
27
55
|
exitApp(0);
|
|
28
56
|
return rest;
|
|
29
57
|
}, false, 0);
|
|
30
58
|
};
|
|
31
59
|
}
|
|
32
60
|
/**
|
|
33
|
-
* Creates config aborted handler
|
|
61
|
+
* Creates config execution aborted handler for CONFIG skill
|
|
34
62
|
*/
|
|
35
|
-
export function
|
|
63
|
+
export function createConfigExecutionAbortedHandler(addToTimeline) {
|
|
36
64
|
return () => {
|
|
37
|
-
|
|
65
|
+
return withQueueHandler(ComponentName.Config, (first, rest) => {
|
|
66
|
+
addToTimeline(markAsDone(first), createFeedback(FeedbackType.Aborted, 'Configuration cancelled.'));
|
|
67
|
+
exitApp(0);
|
|
68
|
+
return rest;
|
|
69
|
+
}, false, 0);
|
|
38
70
|
};
|
|
39
71
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ComponentName, FeedbackType } from '../types/types.js';
|
|
2
|
+
import { createFeedback, createMessage, markAsDone, } from '../services/components.js';
|
|
3
|
+
import { formatDuration } from '../services/messages.js';
|
|
4
|
+
import { exitApp } from '../services/process.js';
|
|
5
|
+
import { ExecutionResult } from '../services/shell.js';
|
|
6
|
+
import { withQueueHandler } from '../services/queue.js';
|
|
7
|
+
/**
|
|
8
|
+
* Creates all execute handlers
|
|
9
|
+
*/
|
|
10
|
+
export function createExecuteHandlers(ops, handleAborted) {
|
|
11
|
+
const onError = (error) => {
|
|
12
|
+
ops.setQueue(withQueueHandler(ComponentName.Execute, (first) => {
|
|
13
|
+
ops.addToTimeline(markAsDone(first), createFeedback(FeedbackType.Failed, error));
|
|
14
|
+
exitApp(1);
|
|
15
|
+
return [];
|
|
16
|
+
}));
|
|
17
|
+
};
|
|
18
|
+
const onComplete = (outputs, totalElapsed) => {
|
|
19
|
+
ops.setQueue(withQueueHandler(ComponentName.Execute, (first) => {
|
|
20
|
+
const failed = outputs.find((out) => out.result !== ExecutionResult.Success);
|
|
21
|
+
if (failed) {
|
|
22
|
+
const errorMessage = failed.error
|
|
23
|
+
? `${failed.description}: ${failed.error}`
|
|
24
|
+
: `${failed.description} failed`;
|
|
25
|
+
ops.addToTimeline(markAsDone(first), createFeedback(FeedbackType.Failed, errorMessage));
|
|
26
|
+
exitApp(1);
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
ops.addToTimeline(markAsDone(first), createMessage(`Execution completed in ${formatDuration(totalElapsed)}.`));
|
|
30
|
+
exitApp(0);
|
|
31
|
+
return [];
|
|
32
|
+
}));
|
|
33
|
+
};
|
|
34
|
+
const onAborted = () => {
|
|
35
|
+
handleAborted('Execution');
|
|
36
|
+
};
|
|
37
|
+
return { onError, onComplete, onAborted };
|
|
38
|
+
}
|
|
@@ -1,68 +1,73 @@
|
|
|
1
1
|
import { ComponentName, FeedbackType, TaskType } from '../types/types.js';
|
|
2
|
-
import { createAnswerDefinition, createFeedback, createIntrospectDefinition, markAsDone, } from '../services/components.js';
|
|
2
|
+
import { createAnswerDefinition, createConfigDefinitionWithKeys, createExecuteDefinition, createFeedback, createIntrospectDefinition, markAsDone, } from '../services/components.js';
|
|
3
3
|
import { getCancellationMessage } from '../services/messages.js';
|
|
4
4
|
import { exitApp } from '../services/process.js';
|
|
5
5
|
import { withQueueHandler } from '../services/queue.js';
|
|
6
|
+
import { createConfigExecutionAbortedHandler, createConfigExecutionFinishedHandler, } from './config.js';
|
|
6
7
|
/**
|
|
7
|
-
* Creates execution
|
|
8
|
+
* Creates all execution handlers
|
|
8
9
|
*/
|
|
9
|
-
export function
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
.
|
|
15
|
-
.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
10
|
+
export function createExecutionHandlers(ops, taskHandlers) {
|
|
11
|
+
const onConfirmed = (tasks) => {
|
|
12
|
+
ops.setQueue(withQueueHandler(ComponentName.Confirm, (first) => {
|
|
13
|
+
const allIntrospect = tasks.every((task) => task.type === TaskType.Introspect);
|
|
14
|
+
const allAnswer = tasks.every((task) => task.type === TaskType.Answer);
|
|
15
|
+
const allConfig = tasks.every((task) => task.type === TaskType.Config);
|
|
16
|
+
const allExecute = tasks.every((task) => task.type === TaskType.Execute);
|
|
17
|
+
const service = ops.service;
|
|
18
|
+
if (!service) {
|
|
19
|
+
ops.addToTimeline(markAsDone(first), createFeedback(FeedbackType.Failed, 'Service not available'));
|
|
20
|
+
exitApp(1);
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
if (allIntrospect && tasks.length > 0) {
|
|
24
|
+
ops.addToTimeline(markAsDone(first));
|
|
25
|
+
return [
|
|
26
|
+
createIntrospectDefinition(tasks, service, taskHandlers.introspect.onError, taskHandlers.introspect.onComplete, taskHandlers.introspect.onAborted),
|
|
27
|
+
];
|
|
28
|
+
}
|
|
29
|
+
else if (allAnswer && tasks.length > 0) {
|
|
30
|
+
const question = tasks[0].action;
|
|
31
|
+
ops.addToTimeline(markAsDone(first));
|
|
32
|
+
return [
|
|
33
|
+
createAnswerDefinition(question, service, taskHandlers.answer.onError, taskHandlers.answer.onComplete, taskHandlers.answer.onAborted),
|
|
34
|
+
];
|
|
35
|
+
}
|
|
36
|
+
else if (allConfig && tasks.length > 0) {
|
|
37
|
+
const keys = tasks
|
|
38
|
+
.map((task) => task.params?.key)
|
|
39
|
+
.filter((key) => typeof key === 'string');
|
|
40
|
+
ops.addToTimeline(markAsDone(first));
|
|
41
|
+
const handleConfigFinished = (config) => {
|
|
42
|
+
ops.setQueue(createConfigExecutionFinishedHandler(ops.addToTimeline, keys)(config));
|
|
43
|
+
};
|
|
44
|
+
const handleConfigAborted = () => {
|
|
45
|
+
ops.setQueue(createConfigExecutionAbortedHandler(ops.addToTimeline)());
|
|
46
|
+
};
|
|
47
|
+
return [
|
|
48
|
+
createConfigDefinitionWithKeys(keys, handleConfigFinished, handleConfigAborted),
|
|
49
|
+
];
|
|
50
|
+
}
|
|
51
|
+
else if (allExecute && tasks.length > 0) {
|
|
52
|
+
ops.addToTimeline(markAsDone(first));
|
|
53
|
+
return [
|
|
54
|
+
createExecuteDefinition(tasks, service, taskHandlers.execute.onError, taskHandlers.execute.onComplete, taskHandlers.execute.onAborted),
|
|
55
|
+
];
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
ops.addToTimeline(markAsDone(first), createFeedback(FeedbackType.Failed, 'I can only process one type of task at a time for now.'));
|
|
59
|
+
exitApp(0);
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
}));
|
|
63
|
+
};
|
|
64
|
+
const onCancelled = (tasks) => {
|
|
65
|
+
ops.setQueue(withQueueHandler(ComponentName.Confirm, (first) => {
|
|
66
|
+
const allIntrospect = tasks.every((task) => task.type === TaskType.Introspect);
|
|
67
|
+
const operation = allIntrospect ? 'introspection' : 'execution';
|
|
68
|
+
ops.addToTimeline(markAsDone(first), createFeedback(FeedbackType.Aborted, getCancellationMessage(operation)));
|
|
69
|
+
return undefined;
|
|
70
|
+
}, true, 0));
|
|
71
|
+
};
|
|
72
|
+
return { onConfirmed, onCancelled };
|
|
68
73
|
}
|
|
@@ -2,27 +2,20 @@ import { ComponentName } from '../types/types.js';
|
|
|
2
2
|
import { createReportDefinition } from '../services/components.js';
|
|
3
3
|
import { createErrorHandler, withQueueHandler } from '../services/queue.js';
|
|
4
4
|
/**
|
|
5
|
-
* Creates introspect
|
|
5
|
+
* Creates all introspect handlers
|
|
6
6
|
*/
|
|
7
|
-
export function
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
return undefined;
|
|
19
|
-
}, true, 0);
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Creates introspect aborted handler
|
|
23
|
-
*/
|
|
24
|
-
export function createIntrospectAbortedHandler(handleAborted) {
|
|
25
|
-
return () => {
|
|
7
|
+
export function createIntrospectHandlers(ops, handleAborted) {
|
|
8
|
+
const onError = (error) => {
|
|
9
|
+
ops.setQueue(createErrorHandler(ComponentName.Introspect, ops.addToTimeline)(error));
|
|
10
|
+
};
|
|
11
|
+
const onComplete = (message, capabilities) => {
|
|
12
|
+
ops.setQueue(withQueueHandler(ComponentName.Introspect, () => {
|
|
13
|
+
ops.addToTimeline(createReportDefinition(message, capabilities));
|
|
14
|
+
return undefined;
|
|
15
|
+
}, true, 0));
|
|
16
|
+
};
|
|
17
|
+
const onAborted = () => {
|
|
26
18
|
handleAborted('Introspection');
|
|
27
19
|
};
|
|
20
|
+
return { onError, onComplete, onAborted };
|
|
28
21
|
}
|
package/dist/handlers/plan.js
CHANGED
|
@@ -1,48 +1,43 @@
|
|
|
1
1
|
import { ComponentName, FeedbackType, TaskType } from '../types/types.js';
|
|
2
2
|
import { createConfirmDefinition, createFeedback, createPlanDefinition, markAsDone, createRefinement, } from '../services/components.js';
|
|
3
|
-
import { FeedbackMessages, getRefiningMessage } from '../services/messages.js';
|
|
3
|
+
import { FeedbackMessages, formatErrorMessage, getRefiningMessage, } from '../services/messages.js';
|
|
4
4
|
import { exitApp } from '../services/process.js';
|
|
5
5
|
/**
|
|
6
|
-
* Creates plan
|
|
6
|
+
* Creates all plan handlers
|
|
7
7
|
*/
|
|
8
|
-
export function
|
|
9
|
-
|
|
8
|
+
export function createPlanHandlers(ops, handleAborted, executionHandlers) {
|
|
9
|
+
const onAborted = () => {
|
|
10
10
|
handleAborted('Task selection');
|
|
11
11
|
};
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Creates plan abort handler factory
|
|
15
|
-
*/
|
|
16
|
-
export function createPlanAbortHandlerFactory(handleAborted, handlePlanAborted) {
|
|
17
|
-
return (tasks) => {
|
|
12
|
+
const createAbortHandler = (tasks) => {
|
|
18
13
|
const allIntrospect = tasks.every((task) => task.type === TaskType.Introspect);
|
|
19
14
|
if (allIntrospect) {
|
|
20
15
|
return () => {
|
|
21
16
|
handleAborted('Introspection');
|
|
22
17
|
};
|
|
23
18
|
}
|
|
24
|
-
return
|
|
19
|
+
return onAborted;
|
|
25
20
|
};
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return async (selectedTasks) => {
|
|
32
|
-
// Mark current plan as done and add refinement to queue
|
|
33
|
-
const refinementDef = createRefinement(getRefiningMessage(), handleRefinementAborted);
|
|
34
|
-
setQueue((currentQueue) => {
|
|
21
|
+
const onSelectionConfirmed = async (selectedTasks) => {
|
|
22
|
+
const refinementDef = createRefinement(getRefiningMessage(), () => {
|
|
23
|
+
handleAborted('Plan refinement');
|
|
24
|
+
});
|
|
25
|
+
ops.setQueue((currentQueue) => {
|
|
35
26
|
if (currentQueue.length === 0)
|
|
36
27
|
return currentQueue;
|
|
37
28
|
const [first] = currentQueue;
|
|
38
29
|
if (first.name === ComponentName.Plan) {
|
|
39
|
-
addToTimeline(markAsDone(first));
|
|
30
|
+
ops.addToTimeline(markAsDone(first));
|
|
40
31
|
}
|
|
41
|
-
// Add refinement to queue so it becomes the active component
|
|
42
32
|
return [refinementDef];
|
|
43
33
|
});
|
|
44
|
-
// Process refined command in background
|
|
45
34
|
try {
|
|
35
|
+
const service = ops.service;
|
|
36
|
+
if (!service) {
|
|
37
|
+
ops.addToTimeline(createFeedback(FeedbackType.Failed, FeedbackMessages.UnexpectedError, 'Service not available'));
|
|
38
|
+
exitApp(1);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
46
41
|
const refinedCommand = selectedTasks
|
|
47
42
|
.map((task) => {
|
|
48
43
|
const action = task.action.toLowerCase().replace(/,/g, ' -');
|
|
@@ -51,32 +46,34 @@ export function createPlanSelectionConfirmedHandler(addToTimeline, service, hand
|
|
|
51
46
|
})
|
|
52
47
|
.join(', ');
|
|
53
48
|
const result = await service.processWithTool(refinedCommand, 'plan');
|
|
54
|
-
|
|
55
|
-
setQueue((currentQueue) => {
|
|
49
|
+
ops.setQueue((currentQueue) => {
|
|
56
50
|
if (currentQueue.length > 0 &&
|
|
57
51
|
currentQueue[0].id === refinementDef.id) {
|
|
58
|
-
addToTimeline(markAsDone(currentQueue[0]));
|
|
52
|
+
ops.addToTimeline(markAsDone(currentQueue[0]));
|
|
59
53
|
}
|
|
60
54
|
return [];
|
|
61
55
|
});
|
|
62
|
-
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
56
|
+
const planDefinition = createPlanDefinition(result.message, result.tasks, createAbortHandler(result.tasks), undefined);
|
|
57
|
+
const confirmDefinition = createConfirmDefinition(() => {
|
|
58
|
+
executionHandlers.onConfirmed(result.tasks);
|
|
59
|
+
}, () => {
|
|
60
|
+
executionHandlers.onCancelled(result.tasks);
|
|
61
|
+
});
|
|
62
|
+
ops.addToTimeline(planDefinition);
|
|
63
|
+
ops.setQueue([confirmDefinition]);
|
|
67
64
|
}
|
|
68
65
|
catch (error) {
|
|
69
|
-
const errorMessage = error
|
|
70
|
-
|
|
71
|
-
setQueue((currentQueue) => {
|
|
66
|
+
const errorMessage = formatErrorMessage(error);
|
|
67
|
+
ops.setQueue((currentQueue) => {
|
|
72
68
|
if (currentQueue.length > 0 &&
|
|
73
69
|
currentQueue[0].id === refinementDef.id) {
|
|
74
|
-
addToTimeline(markAsDone(currentQueue[0]));
|
|
70
|
+
ops.addToTimeline(markAsDone(currentQueue[0]));
|
|
75
71
|
}
|
|
76
72
|
return [];
|
|
77
73
|
});
|
|
78
|
-
addToTimeline(createFeedback(FeedbackType.Failed, FeedbackMessages.UnexpectedError, errorMessage));
|
|
74
|
+
ops.addToTimeline(createFeedback(FeedbackType.Failed, FeedbackMessages.UnexpectedError, errorMessage));
|
|
79
75
|
exitApp(1);
|
|
80
76
|
}
|
|
81
77
|
};
|
|
78
|
+
return { onAborted, createAbortHandler, onSelectionConfirmed };
|
|
82
79
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Anthropic from '@anthropic-ai/sdk';
|
|
2
|
+
import { getAvailableConfigStructure, } from './configuration.js';
|
|
2
3
|
import { formatSkillsForPrompt, loadSkills } from './skills.js';
|
|
3
4
|
import { toolRegistry } from './tool-registry.js';
|
|
4
5
|
export class AnthropicService {
|
|
@@ -12,16 +13,38 @@ export class AnthropicService {
|
|
|
12
13
|
// Load tool from registry
|
|
13
14
|
const tool = toolRegistry.getSchema(toolName);
|
|
14
15
|
const instructions = toolRegistry.getInstructions(toolName);
|
|
15
|
-
//
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
// Build system prompt with additional context based on tool
|
|
17
|
+
let systemPrompt = instructions;
|
|
18
|
+
// Add skills section for applicable tools
|
|
19
|
+
if (toolName === 'plan' ||
|
|
20
|
+
toolName === 'introspect' ||
|
|
21
|
+
toolName === 'execute') {
|
|
22
|
+
const skills = loadSkills();
|
|
23
|
+
const skillsSection = formatSkillsForPrompt(skills);
|
|
24
|
+
systemPrompt += skillsSection;
|
|
25
|
+
}
|
|
26
|
+
// Add config structure for config tool only
|
|
27
|
+
if (toolName === 'config') {
|
|
28
|
+
const configStructure = getAvailableConfigStructure();
|
|
29
|
+
const configSection = '\n\n## Available Configuration\n\n' +
|
|
30
|
+
'Config structure (key: description):\n' +
|
|
31
|
+
JSON.stringify(configStructure, null, 2);
|
|
32
|
+
systemPrompt += configSection;
|
|
33
|
+
}
|
|
34
|
+
// Build tools array - add web search for answer tool
|
|
35
|
+
const tools = [tool];
|
|
36
|
+
if (toolName === 'answer') {
|
|
37
|
+
tools.push({
|
|
38
|
+
type: 'web_search_20250305',
|
|
39
|
+
name: 'web_search',
|
|
40
|
+
});
|
|
41
|
+
}
|
|
19
42
|
// Call API with tool
|
|
20
43
|
const response = await this.client.messages.create({
|
|
21
44
|
model: this.model,
|
|
22
45
|
max_tokens: 1024,
|
|
23
46
|
system: systemPrompt,
|
|
24
|
-
tools
|
|
47
|
+
tools,
|
|
25
48
|
tool_choice: { type: 'any' },
|
|
26
49
|
messages: [
|
|
27
50
|
{
|
|
@@ -34,15 +57,48 @@ export class AnthropicService {
|
|
|
34
57
|
if (response.stop_reason === 'max_tokens') {
|
|
35
58
|
throw new Error('Response was truncated due to length. Please simplify your request or break it into smaller parts.');
|
|
36
59
|
}
|
|
37
|
-
//
|
|
38
|
-
|
|
39
|
-
|
|
60
|
+
// Find tool_use block in response (may not be first with web search)
|
|
61
|
+
const toolUseContent = response.content.find((block) => block.type === 'tool_use');
|
|
62
|
+
// For answer tool with web search, model might return text directly
|
|
63
|
+
if (toolName === 'answer' && !toolUseContent) {
|
|
64
|
+
const textContent = response.content.find((block) => block.type === 'text');
|
|
65
|
+
if (textContent) {
|
|
66
|
+
return {
|
|
67
|
+
message: '',
|
|
68
|
+
tasks: [],
|
|
69
|
+
answer: textContent.text,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (!toolUseContent) {
|
|
40
74
|
throw new Error('Expected tool_use response from Claude API');
|
|
41
75
|
}
|
|
42
|
-
const content =
|
|
76
|
+
const content = toolUseContent;
|
|
43
77
|
// Extract and validate response based on tool type
|
|
44
78
|
const input = content.input;
|
|
45
|
-
|
|
79
|
+
// Handle execute tool response
|
|
80
|
+
if (toolName === 'execute') {
|
|
81
|
+
if (!input.message || typeof input.message !== 'string') {
|
|
82
|
+
throw new Error('Invalid tool response: missing or invalid message field');
|
|
83
|
+
}
|
|
84
|
+
if (!input.commands || !Array.isArray(input.commands)) {
|
|
85
|
+
throw new Error('Invalid tool response: missing or invalid commands array');
|
|
86
|
+
}
|
|
87
|
+
// Validate each command has required fields
|
|
88
|
+
input.commands.forEach((cmd, i) => {
|
|
89
|
+
if (!cmd.description || typeof cmd.description !== 'string') {
|
|
90
|
+
throw new Error(`Invalid command at index ${String(i)}: missing or invalid 'description' field`);
|
|
91
|
+
}
|
|
92
|
+
if (!cmd.command || typeof cmd.command !== 'string') {
|
|
93
|
+
throw new Error(`Invalid command at index ${String(i)}: missing or invalid 'command' field`);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
return {
|
|
97
|
+
message: input.message,
|
|
98
|
+
tasks: [],
|
|
99
|
+
commands: input.commands,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
46
102
|
// Handle answer tool response
|
|
47
103
|
if (toolName === 'answer') {
|
|
48
104
|
if (!input.question || typeof input.question !== 'string') {
|
|
@@ -55,7 +111,6 @@ export class AnthropicService {
|
|
|
55
111
|
message: '',
|
|
56
112
|
tasks: [],
|
|
57
113
|
answer: input.answer,
|
|
58
|
-
systemPrompt: isDebug ? systemPrompt : undefined,
|
|
59
114
|
};
|
|
60
115
|
}
|
|
61
116
|
// Handle plan and introspect tool responses
|
|
@@ -74,7 +129,6 @@ export class AnthropicService {
|
|
|
74
129
|
return {
|
|
75
130
|
message: input.message,
|
|
76
131
|
tasks: input.tasks,
|
|
77
|
-
systemPrompt: isDebug ? systemPrompt : undefined,
|
|
78
132
|
};
|
|
79
133
|
}
|
|
80
134
|
}
|
package/dist/services/colors.js
CHANGED
|
@@ -12,7 +12,7 @@ export const Palette = {
|
|
|
12
12
|
CharcoalGray: '#282828',
|
|
13
13
|
Green: '#5aaa8a',
|
|
14
14
|
LightGreen: '#65b595',
|
|
15
|
-
BrightGreen: '#
|
|
15
|
+
BrightGreen: '#3e9a3e',
|
|
16
16
|
Yellow: '#cccc5c',
|
|
17
17
|
LightYellow: '#d4d47a',
|
|
18
18
|
Orange: '#cc9c5c',
|
|
@@ -69,12 +69,13 @@ export const Colors = {
|
|
|
69
69
|
Origin: {
|
|
70
70
|
BuiltIn: Palette.Cyan,
|
|
71
71
|
UserProvided: Palette.Green,
|
|
72
|
+
Indirect: Palette.Purple,
|
|
72
73
|
},
|
|
73
74
|
};
|
|
74
75
|
/**
|
|
75
76
|
* Task-specific color mappings (internal)
|
|
76
77
|
*/
|
|
77
|
-
const
|
|
78
|
+
const taskColors = {
|
|
78
79
|
[TaskType.Config]: {
|
|
79
80
|
description: Colors.Label.Default,
|
|
80
81
|
type: Colors.Type.Config,
|
|
@@ -119,7 +120,7 @@ const TaskColors = {
|
|
|
119
120
|
/**
|
|
120
121
|
* Feedback-specific color mappings (internal)
|
|
121
122
|
*/
|
|
122
|
-
const
|
|
123
|
+
const feedbackColors = {
|
|
123
124
|
[FeedbackType.Info]: Colors.Status.Info,
|
|
124
125
|
[FeedbackType.Succeeded]: Colors.Status.Success,
|
|
125
126
|
[FeedbackType.Aborted]: Colors.Status.Warning,
|
|
@@ -147,7 +148,7 @@ function processColor(color, isCurrent) {
|
|
|
147
148
|
* - Colors.Text.Active for current items
|
|
148
149
|
*/
|
|
149
150
|
export function getTaskColors(type, isCurrent) {
|
|
150
|
-
const colors =
|
|
151
|
+
const colors = taskColors[type];
|
|
151
152
|
return {
|
|
152
153
|
description: processColor(colors.description, isCurrent),
|
|
153
154
|
type: processColor(colors.type, isCurrent),
|
|
@@ -161,7 +162,7 @@ export function getTaskColors(type, isCurrent) {
|
|
|
161
162
|
* - Colors.Text.Active for current items
|
|
162
163
|
*/
|
|
163
164
|
export function getFeedbackColor(type, isCurrent) {
|
|
164
|
-
return processColor(
|
|
165
|
+
return processColor(feedbackColors[type], isCurrent);
|
|
165
166
|
}
|
|
166
167
|
/**
|
|
167
168
|
* Get text color based on current/historical state.
|