@ai-sdk/harness-cline 1.0.27 → 1.0.28
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/CHANGELOG.md +8 -0
- package/dist/index.d.ts +682 -0
- package/dist/index.js +137 -9
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/cline-harness.ts +6 -0
- package/src/cline-session.ts +51 -3
- package/src/cline-tools.ts +89 -2
- package/src/cline-translate.ts +36 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// src/cline-harness.ts
|
|
2
2
|
import {
|
|
3
|
-
commonTool
|
|
3
|
+
commonTool,
|
|
4
|
+
HARNESS_V1_BUILTIN_TOOLS
|
|
4
5
|
} from "@ai-sdk/harness";
|
|
5
6
|
import { isHarnessAuthenticationEnvironment as isHarnessAuthenticationEnvironment2 } from "@ai-sdk/harness/utils";
|
|
6
7
|
import { tool } from "@ai-sdk/provider-utils";
|
|
@@ -623,6 +624,7 @@ ${description}${skill.content}${files}
|
|
|
623
624
|
import {
|
|
624
625
|
createTool
|
|
625
626
|
} from "@cline/agents";
|
|
627
|
+
import { createDefaultTools as createDefaultTools2 } from "@cline/core";
|
|
626
628
|
|
|
627
629
|
// src/cline-utils.ts
|
|
628
630
|
import {
|
|
@@ -725,6 +727,7 @@ function usageFromMessageMetrics(metrics) {
|
|
|
725
727
|
|
|
726
728
|
// src/cline-tools.ts
|
|
727
729
|
var CLINE_NATIVE_BUILTIN_NAMES = [
|
|
730
|
+
"ask_question",
|
|
728
731
|
"read",
|
|
729
732
|
"write",
|
|
730
733
|
"edit",
|
|
@@ -735,6 +738,7 @@ var CLINE_NATIVE_BUILTIN_NAMES = [
|
|
|
735
738
|
"skills"
|
|
736
739
|
];
|
|
737
740
|
var CLINE_NATIVE_TOOL_KINDS = {
|
|
741
|
+
ask_question: "readonly",
|
|
738
742
|
read: "readonly",
|
|
739
743
|
write: "edit",
|
|
740
744
|
edit: "edit",
|
|
@@ -749,15 +753,21 @@ function isClineBuiltinToolName(name) {
|
|
|
749
753
|
}
|
|
750
754
|
function resolveActiveClineBuiltinNames(toolFiltering) {
|
|
751
755
|
if (toolFiltering == null) return CLINE_NATIVE_BUILTIN_NAMES;
|
|
756
|
+
const filteredNames = toolFiltering.toolNames.map(
|
|
757
|
+
(name) => name === "askUserQuestions" ? "ask_question" : name
|
|
758
|
+
);
|
|
752
759
|
if (toolFiltering.mode === "allow") {
|
|
753
760
|
return CLINE_NATIVE_BUILTIN_NAMES.filter(
|
|
754
|
-
(name) =>
|
|
761
|
+
(name) => filteredNames.includes(name)
|
|
755
762
|
);
|
|
756
763
|
}
|
|
757
764
|
return CLINE_NATIVE_BUILTIN_NAMES.filter(
|
|
758
|
-
(name) => !
|
|
765
|
+
(name) => !filteredNames.includes(name)
|
|
759
766
|
);
|
|
760
767
|
}
|
|
768
|
+
function clineQuestionKey(input) {
|
|
769
|
+
return JSON.stringify([input.question, input.options]);
|
|
770
|
+
}
|
|
761
771
|
var clineToolResultMarker = /* @__PURE__ */ Symbol("cline-tool-result");
|
|
762
772
|
function createClineToolResult({
|
|
763
773
|
output,
|
|
@@ -791,9 +801,45 @@ async function guarded(run) {
|
|
|
791
801
|
}
|
|
792
802
|
function buildBuiltinAgentTools({
|
|
793
803
|
ops,
|
|
794
|
-
activeNames
|
|
804
|
+
activeNames,
|
|
805
|
+
pendingQuestions = /* @__PURE__ */ new Map(),
|
|
806
|
+
pendingQuestionResults = /* @__PURE__ */ new Map()
|
|
795
807
|
}) {
|
|
796
808
|
const tools = {
|
|
809
|
+
ask_question: createDefaultTools2({
|
|
810
|
+
executors: {
|
|
811
|
+
askQuestion: async (question, options, context) => {
|
|
812
|
+
if (context.toolCallId == null) {
|
|
813
|
+
throw new Error(
|
|
814
|
+
"Cline ask_question did not provide a tool call id."
|
|
815
|
+
);
|
|
816
|
+
}
|
|
817
|
+
const questionKey = clineQuestionKey({ question, options });
|
|
818
|
+
const pendingResult = pendingQuestionResults.get(questionKey);
|
|
819
|
+
if (pendingResult != null) {
|
|
820
|
+
pendingQuestionResults.delete(questionKey);
|
|
821
|
+
return toClineQuestionResult({
|
|
822
|
+
nativeInput: { question, options },
|
|
823
|
+
output: pendingResult.output
|
|
824
|
+
});
|
|
825
|
+
}
|
|
826
|
+
return new Promise((resolve) => {
|
|
827
|
+
pendingQuestions.set(context.toolCallId, {
|
|
828
|
+
input: { question, options },
|
|
829
|
+
resolve
|
|
830
|
+
});
|
|
831
|
+
});
|
|
832
|
+
}
|
|
833
|
+
},
|
|
834
|
+
enableReadFiles: false,
|
|
835
|
+
enableSearch: false,
|
|
836
|
+
enableBash: false,
|
|
837
|
+
enableWebFetch: false,
|
|
838
|
+
enableApplyPatch: false,
|
|
839
|
+
enableEditor: false,
|
|
840
|
+
enableSkills: false,
|
|
841
|
+
enableAskQuestion: true
|
|
842
|
+
}).find((tool2) => tool2.name === "ask_question"),
|
|
797
843
|
read: createTool({
|
|
798
844
|
name: "read",
|
|
799
845
|
description: "Read file contents.",
|
|
@@ -948,6 +994,19 @@ function buildBuiltinAgentTools({
|
|
|
948
994
|
};
|
|
949
995
|
return activeNames.map((name) => tools[name]).filter((tool2) => tool2 != null);
|
|
950
996
|
}
|
|
997
|
+
function toClineQuestionResult(input) {
|
|
998
|
+
if (input.output.action === "declined" || input.output.action === "cancelled") {
|
|
999
|
+
return `The user ${input.output.action} the question.`;
|
|
1000
|
+
}
|
|
1001
|
+
const answer = input.output.answers["question-1"];
|
|
1002
|
+
if (answer == null) return "The user did not answer the question.";
|
|
1003
|
+
if (answer.freeform != null) return answer.freeform;
|
|
1004
|
+
const result = answer.optionIds.map((id) => {
|
|
1005
|
+
const index = Number(id.replace(/^option-/, "")) - 1;
|
|
1006
|
+
return input.nativeInput.options[index];
|
|
1007
|
+
}).filter((value) => value != null).join(", ");
|
|
1008
|
+
return result;
|
|
1009
|
+
}
|
|
951
1010
|
function buildUserAgentTools({
|
|
952
1011
|
specs,
|
|
953
1012
|
pendingToolResults
|
|
@@ -1027,6 +1086,35 @@ function toolCallPart(state, toolCall) {
|
|
|
1027
1086
|
if (isMcpTool) {
|
|
1028
1087
|
state.dynamicToolCallIds.add(toolCall.toolCallId);
|
|
1029
1088
|
}
|
|
1089
|
+
if (toolCall.toolName === "ask_question") {
|
|
1090
|
+
const nativeInput = toolCall.input;
|
|
1091
|
+
return {
|
|
1092
|
+
type: "tool-call",
|
|
1093
|
+
toolCallId: toolCall.toolCallId,
|
|
1094
|
+
toolName: "askUserQuestions",
|
|
1095
|
+
input: JSON.stringify({
|
|
1096
|
+
allowPartialAnswers: false,
|
|
1097
|
+
questions: [
|
|
1098
|
+
{
|
|
1099
|
+
id: "question-1",
|
|
1100
|
+
question: nativeInput.question,
|
|
1101
|
+
options: nativeInput.options.map((label, index) => ({
|
|
1102
|
+
id: `option-${index + 1}`,
|
|
1103
|
+
label
|
|
1104
|
+
})),
|
|
1105
|
+
allowFreeForm: true
|
|
1106
|
+
}
|
|
1107
|
+
]
|
|
1108
|
+
}),
|
|
1109
|
+
providerExecuted: false,
|
|
1110
|
+
providerMetadata: {
|
|
1111
|
+
cline: {
|
|
1112
|
+
nativeRequest: nativeInput
|
|
1113
|
+
}
|
|
1114
|
+
},
|
|
1115
|
+
nativeName: "ask_question"
|
|
1116
|
+
};
|
|
1117
|
+
}
|
|
1030
1118
|
return {
|
|
1031
1119
|
type: "tool-call",
|
|
1032
1120
|
toolCallId: toolCall.toolCallId,
|
|
@@ -1128,7 +1216,7 @@ function translateClineEvent(event, state) {
|
|
|
1128
1216
|
{
|
|
1129
1217
|
type: "tool-result",
|
|
1130
1218
|
toolCallId: event.toolCall.toolCallId,
|
|
1131
|
-
toolName: event.toolCall.toolName,
|
|
1219
|
+
toolName: event.toolCall.toolName === "ask_question" ? "askUserQuestions" : event.toolCall.toolName,
|
|
1132
1220
|
result: toToolResultValue(output),
|
|
1133
1221
|
...resultPart?.isError ? { isError: true } : {},
|
|
1134
1222
|
...dynamic ? { dynamic: true } : {}
|
|
@@ -1309,6 +1397,8 @@ async function createClineSession(input) {
|
|
|
1309
1397
|
let acceptingUserMessages = false;
|
|
1310
1398
|
let currentEmit;
|
|
1311
1399
|
let translatorState;
|
|
1400
|
+
const pendingQuestions = /* @__PURE__ */ new Map();
|
|
1401
|
+
const pendingQuestionResults = /* @__PURE__ */ new Map();
|
|
1312
1402
|
let activeTurn;
|
|
1313
1403
|
function settlePendingToolResults(reason) {
|
|
1314
1404
|
for (const pending of pendingToolResults.values()) {
|
|
@@ -1339,6 +1429,13 @@ async function createClineSession(input) {
|
|
|
1339
1429
|
}
|
|
1340
1430
|
pendingUserMessages.length = 0;
|
|
1341
1431
|
}
|
|
1432
|
+
function settlePendingQuestions(reason) {
|
|
1433
|
+
for (const pending of pendingQuestions.values()) {
|
|
1434
|
+
pending.resolve(reason);
|
|
1435
|
+
}
|
|
1436
|
+
pendingQuestions.clear();
|
|
1437
|
+
pendingQuestionResults.clear();
|
|
1438
|
+
}
|
|
1342
1439
|
async function persistHistory() {
|
|
1343
1440
|
const messages = agent?.snapshot().messages ?? currentMessages;
|
|
1344
1441
|
await persistHistoryToSandbox({
|
|
@@ -1383,7 +1480,12 @@ ${rebuildInput.instructions}` : baseSystemPrompt;
|
|
|
1383
1480
|
toolExecution: "parallel",
|
|
1384
1481
|
...input.settings.maxIterations !== void 0 ? { maxIterations: input.settings.maxIterations } : {},
|
|
1385
1482
|
tools: [
|
|
1386
|
-
...buildBuiltinAgentTools({
|
|
1483
|
+
...buildBuiltinAgentTools({
|
|
1484
|
+
ops,
|
|
1485
|
+
activeNames: activeBuiltinNames,
|
|
1486
|
+
pendingQuestions,
|
|
1487
|
+
pendingQuestionResults
|
|
1488
|
+
}),
|
|
1387
1489
|
...rebuildInput.skillsRuntime.tool && activeBuiltinNames.includes("skills") ? [rebuildInput.skillsRuntime.tool] : [],
|
|
1388
1490
|
...mcpRuntime.tools,
|
|
1389
1491
|
...buildUserAgentTools({
|
|
@@ -1452,6 +1554,7 @@ ${rebuildInput.instructions}` : baseSystemPrompt;
|
|
|
1452
1554
|
const abortHandler = () => {
|
|
1453
1555
|
settlePendingToolResults("Turn aborted");
|
|
1454
1556
|
settlePendingToolApprovals("Turn aborted");
|
|
1557
|
+
settlePendingQuestions("The question was cancelled.");
|
|
1455
1558
|
agent?.abort("Turn aborted by caller");
|
|
1456
1559
|
};
|
|
1457
1560
|
if (controlInput.abortSignal) {
|
|
@@ -1469,6 +1572,25 @@ ${rebuildInput.instructions}` : baseSystemPrompt;
|
|
|
1469
1572
|
}
|
|
1470
1573
|
return {
|
|
1471
1574
|
async submitToolResult(args) {
|
|
1575
|
+
const pendingQuestion = pendingQuestions.get(args.toolCallId);
|
|
1576
|
+
if (pendingQuestion != null) {
|
|
1577
|
+
pendingQuestions.delete(args.toolCallId);
|
|
1578
|
+
pendingQuestion.resolve(
|
|
1579
|
+
toClineQuestionResult({
|
|
1580
|
+
nativeInput: pendingQuestion.input,
|
|
1581
|
+
output: args.output
|
|
1582
|
+
})
|
|
1583
|
+
);
|
|
1584
|
+
return;
|
|
1585
|
+
}
|
|
1586
|
+
if (args.toolResult?.toolName === "askUserQuestions") {
|
|
1587
|
+
const nativeRequest = args.toolResult.providerOptions?.cline?.nativeRequest;
|
|
1588
|
+
if (nativeRequest == null) return;
|
|
1589
|
+
pendingQuestionResults.set(clineQuestionKey(nativeRequest), {
|
|
1590
|
+
output: args.output
|
|
1591
|
+
});
|
|
1592
|
+
return;
|
|
1593
|
+
}
|
|
1472
1594
|
const pending = pendingToolResults.get(args.toolCallId);
|
|
1473
1595
|
if (!pending) return;
|
|
1474
1596
|
pendingToolResults.delete(args.toolCallId);
|
|
@@ -1668,6 +1790,7 @@ ${rebuildInput.instructions}` : baseSystemPrompt;
|
|
|
1668
1790
|
parkedClineSessions.delete(input.sessionId);
|
|
1669
1791
|
settlePendingToolResults("Cline session stopped");
|
|
1670
1792
|
settlePendingToolApprovals("Cline session stopped");
|
|
1793
|
+
settlePendingQuestions("The question was cancelled.");
|
|
1671
1794
|
try {
|
|
1672
1795
|
await persistHistory();
|
|
1673
1796
|
} catch {
|
|
@@ -1735,7 +1858,7 @@ ${rebuildInput.instructions}` : baseSystemPrompt;
|
|
|
1735
1858
|
},
|
|
1736
1859
|
doStop,
|
|
1737
1860
|
doDetach: async () => {
|
|
1738
|
-
if (activeTurn != null || pendingToolResults.size > 0) {
|
|
1861
|
+
if (activeTurn != null || pendingToolResults.size > 0 || pendingQuestions.size > 0) {
|
|
1739
1862
|
parkedClineSessions.set(input.sessionId, sessionImpl);
|
|
1740
1863
|
try {
|
|
1741
1864
|
await persistHistory();
|
|
@@ -1754,7 +1877,7 @@ ${rebuildInput.instructions}` : baseSystemPrompt;
|
|
|
1754
1877
|
if (stopped) {
|
|
1755
1878
|
throw new Error("Cline session has been stopped.");
|
|
1756
1879
|
}
|
|
1757
|
-
if (activeTurn != null && (pendingToolResults.size > 0 || pendingToolApprovals.size > 0)) {
|
|
1880
|
+
if (activeTurn != null && (pendingToolResults.size > 0 || pendingToolApprovals.size > 0 || pendingQuestions.size > 0)) {
|
|
1758
1881
|
parkedClineSessions.set(input.sessionId, sessionImpl);
|
|
1759
1882
|
try {
|
|
1760
1883
|
await persistHistory();
|
|
@@ -1794,11 +1917,16 @@ ${rebuildInput.instructions}` : baseSystemPrompt;
|
|
|
1794
1917
|
}
|
|
1795
1918
|
|
|
1796
1919
|
// src/version.ts
|
|
1797
|
-
var VERSION = true ? "1.0.
|
|
1920
|
+
var VERSION = true ? "1.0.28" : "0.0.0-test";
|
|
1798
1921
|
|
|
1799
1922
|
// src/cline-harness.ts
|
|
1800
1923
|
var CLINE_CLIENT_APP = `ai-sdk/harness-cline/${VERSION}`;
|
|
1801
1924
|
var CLINE_BUILTIN_TOOLS = {
|
|
1925
|
+
askUserQuestions: {
|
|
1926
|
+
...HARNESS_V1_BUILTIN_TOOLS.askUserQuestions,
|
|
1927
|
+
nativeName: "ask_question",
|
|
1928
|
+
toolUseKind: "readonly"
|
|
1929
|
+
},
|
|
1802
1930
|
read: commonTool("read", {
|
|
1803
1931
|
nativeName: "read",
|
|
1804
1932
|
toolUseKind: "readonly",
|