@ai-sdk/harness-cline 1.0.27 → 1.0.29
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 +19 -0
- package/dist/index.d.ts +682 -0
- package/dist/index.js +143 -10
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/cline-harness.ts +7 -0
- package/src/cline-session.ts +59 -4
- 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 } : {}
|
|
@@ -1215,9 +1303,13 @@ function createClineAgentModel({
|
|
|
1215
1303
|
const baseUrl = isAiGateway ? toAiGatewayProviderBaseUrl(gatewayBaseUrl) : settings.baseUrl ?? (providerId === "cline" && settings.authEnv.CLINE_API_BASE_URL ? toClineBackendProviderBaseUrl(settings.authEnv.CLINE_API_BASE_URL) : void 0);
|
|
1216
1304
|
const headers = isAiGateway ? {
|
|
1217
1305
|
...settings.headers,
|
|
1306
|
+
...settings.agentHeaders,
|
|
1218
1307
|
"User-Agent": clientApp,
|
|
1219
1308
|
"x-client-app": clientApp
|
|
1220
|
-
} : settings.headers
|
|
1309
|
+
} : settings.headers != null || settings.agentHeaders != null ? {
|
|
1310
|
+
...settings.headers,
|
|
1311
|
+
...settings.agentHeaders
|
|
1312
|
+
} : void 0;
|
|
1221
1313
|
const gateway = Llms.createGateway({
|
|
1222
1314
|
providerConfigs: [
|
|
1223
1315
|
{
|
|
@@ -1309,6 +1401,8 @@ async function createClineSession(input) {
|
|
|
1309
1401
|
let acceptingUserMessages = false;
|
|
1310
1402
|
let currentEmit;
|
|
1311
1403
|
let translatorState;
|
|
1404
|
+
const pendingQuestions = /* @__PURE__ */ new Map();
|
|
1405
|
+
const pendingQuestionResults = /* @__PURE__ */ new Map();
|
|
1312
1406
|
let activeTurn;
|
|
1313
1407
|
function settlePendingToolResults(reason) {
|
|
1314
1408
|
for (const pending of pendingToolResults.values()) {
|
|
@@ -1339,6 +1433,13 @@ async function createClineSession(input) {
|
|
|
1339
1433
|
}
|
|
1340
1434
|
pendingUserMessages.length = 0;
|
|
1341
1435
|
}
|
|
1436
|
+
function settlePendingQuestions(reason) {
|
|
1437
|
+
for (const pending of pendingQuestions.values()) {
|
|
1438
|
+
pending.resolve(reason);
|
|
1439
|
+
}
|
|
1440
|
+
pendingQuestions.clear();
|
|
1441
|
+
pendingQuestionResults.clear();
|
|
1442
|
+
}
|
|
1342
1443
|
async function persistHistory() {
|
|
1343
1444
|
const messages = agent?.snapshot().messages ?? currentMessages;
|
|
1344
1445
|
await persistHistoryToSandbox({
|
|
@@ -1383,7 +1484,12 @@ ${rebuildInput.instructions}` : baseSystemPrompt;
|
|
|
1383
1484
|
toolExecution: "parallel",
|
|
1384
1485
|
...input.settings.maxIterations !== void 0 ? { maxIterations: input.settings.maxIterations } : {},
|
|
1385
1486
|
tools: [
|
|
1386
|
-
...buildBuiltinAgentTools({
|
|
1487
|
+
...buildBuiltinAgentTools({
|
|
1488
|
+
ops,
|
|
1489
|
+
activeNames: activeBuiltinNames,
|
|
1490
|
+
pendingQuestions,
|
|
1491
|
+
pendingQuestionResults
|
|
1492
|
+
}),
|
|
1387
1493
|
...rebuildInput.skillsRuntime.tool && activeBuiltinNames.includes("skills") ? [rebuildInput.skillsRuntime.tool] : [],
|
|
1388
1494
|
...mcpRuntime.tools,
|
|
1389
1495
|
...buildUserAgentTools({
|
|
@@ -1452,6 +1558,7 @@ ${rebuildInput.instructions}` : baseSystemPrompt;
|
|
|
1452
1558
|
const abortHandler = () => {
|
|
1453
1559
|
settlePendingToolResults("Turn aborted");
|
|
1454
1560
|
settlePendingToolApprovals("Turn aborted");
|
|
1561
|
+
settlePendingQuestions("The question was cancelled.");
|
|
1455
1562
|
agent?.abort("Turn aborted by caller");
|
|
1456
1563
|
};
|
|
1457
1564
|
if (controlInput.abortSignal) {
|
|
@@ -1469,6 +1576,25 @@ ${rebuildInput.instructions}` : baseSystemPrompt;
|
|
|
1469
1576
|
}
|
|
1470
1577
|
return {
|
|
1471
1578
|
async submitToolResult(args) {
|
|
1579
|
+
const pendingQuestion = pendingQuestions.get(args.toolCallId);
|
|
1580
|
+
if (pendingQuestion != null) {
|
|
1581
|
+
pendingQuestions.delete(args.toolCallId);
|
|
1582
|
+
pendingQuestion.resolve(
|
|
1583
|
+
toClineQuestionResult({
|
|
1584
|
+
nativeInput: pendingQuestion.input,
|
|
1585
|
+
output: args.output
|
|
1586
|
+
})
|
|
1587
|
+
);
|
|
1588
|
+
return;
|
|
1589
|
+
}
|
|
1590
|
+
if (args.toolResult?.toolName === "askUserQuestions") {
|
|
1591
|
+
const nativeRequest = args.toolResult.providerOptions?.cline?.nativeRequest;
|
|
1592
|
+
if (nativeRequest == null) return;
|
|
1593
|
+
pendingQuestionResults.set(clineQuestionKey(nativeRequest), {
|
|
1594
|
+
output: args.output
|
|
1595
|
+
});
|
|
1596
|
+
return;
|
|
1597
|
+
}
|
|
1472
1598
|
const pending = pendingToolResults.get(args.toolCallId);
|
|
1473
1599
|
if (!pending) return;
|
|
1474
1600
|
pendingToolResults.delete(args.toolCallId);
|
|
@@ -1668,6 +1794,7 @@ ${rebuildInput.instructions}` : baseSystemPrompt;
|
|
|
1668
1794
|
parkedClineSessions.delete(input.sessionId);
|
|
1669
1795
|
settlePendingToolResults("Cline session stopped");
|
|
1670
1796
|
settlePendingToolApprovals("Cline session stopped");
|
|
1797
|
+
settlePendingQuestions("The question was cancelled.");
|
|
1671
1798
|
try {
|
|
1672
1799
|
await persistHistory();
|
|
1673
1800
|
} catch {
|
|
@@ -1735,7 +1862,7 @@ ${rebuildInput.instructions}` : baseSystemPrompt;
|
|
|
1735
1862
|
},
|
|
1736
1863
|
doStop,
|
|
1737
1864
|
doDetach: async () => {
|
|
1738
|
-
if (activeTurn != null || pendingToolResults.size > 0) {
|
|
1865
|
+
if (activeTurn != null || pendingToolResults.size > 0 || pendingQuestions.size > 0) {
|
|
1739
1866
|
parkedClineSessions.set(input.sessionId, sessionImpl);
|
|
1740
1867
|
try {
|
|
1741
1868
|
await persistHistory();
|
|
@@ -1754,7 +1881,7 @@ ${rebuildInput.instructions}` : baseSystemPrompt;
|
|
|
1754
1881
|
if (stopped) {
|
|
1755
1882
|
throw new Error("Cline session has been stopped.");
|
|
1756
1883
|
}
|
|
1757
|
-
if (activeTurn != null && (pendingToolResults.size > 0 || pendingToolApprovals.size > 0)) {
|
|
1884
|
+
if (activeTurn != null && (pendingToolResults.size > 0 || pendingToolApprovals.size > 0 || pendingQuestions.size > 0)) {
|
|
1758
1885
|
parkedClineSessions.set(input.sessionId, sessionImpl);
|
|
1759
1886
|
try {
|
|
1760
1887
|
await persistHistory();
|
|
@@ -1794,11 +1921,16 @@ ${rebuildInput.instructions}` : baseSystemPrompt;
|
|
|
1794
1921
|
}
|
|
1795
1922
|
|
|
1796
1923
|
// src/version.ts
|
|
1797
|
-
var VERSION = true ? "1.0.
|
|
1924
|
+
var VERSION = true ? "1.0.29" : "0.0.0-test";
|
|
1798
1925
|
|
|
1799
1926
|
// src/cline-harness.ts
|
|
1800
1927
|
var CLINE_CLIENT_APP = `ai-sdk/harness-cline/${VERSION}`;
|
|
1801
1928
|
var CLINE_BUILTIN_TOOLS = {
|
|
1929
|
+
askUserQuestions: {
|
|
1930
|
+
...HARNESS_V1_BUILTIN_TOOLS.askUserQuestions,
|
|
1931
|
+
nativeName: "ask_question",
|
|
1932
|
+
toolUseKind: "readonly"
|
|
1933
|
+
},
|
|
1802
1934
|
read: commonTool("read", {
|
|
1803
1935
|
nativeName: "read",
|
|
1804
1936
|
toolUseKind: "readonly",
|
|
@@ -1909,6 +2041,7 @@ function createCline(settings = {}) {
|
|
|
1909
2041
|
...settings.apiKey ? { apiKey: settings.apiKey } : {},
|
|
1910
2042
|
...settings.baseUrl ? { baseUrl: settings.baseUrl } : {},
|
|
1911
2043
|
...settings.headers ? { headers: settings.headers } : {},
|
|
2044
|
+
...startOpts.headers ? { agentHeaders: startOpts.headers } : {},
|
|
1912
2045
|
...settings.reasoningEffort !== void 0 ? { reasoningEffort: settings.reasoningEffort } : {},
|
|
1913
2046
|
...settings.maxIterations !== void 0 ? { maxIterations: settings.maxIterations } : {}
|
|
1914
2047
|
},
|