nolo-cli 0.8.0-alpha.2 → 0.8.0-alpha.20
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/README.md +1 -1
- package/_executeModel-WRUCQIV5.js +205 -0
- package/action-R4M4ORGA.js +28 -0
- package/addContentAction-UYFFTEWJ.js +26 -0
- package/addDialogAgentAction-OT4XZAVP.js +68 -0
- package/agentDeleteCommand-5DD2IM3J.js +327 -0
- package/agentEmailCommands-IASM2YBQ.js +628 -0
- package/agentListCommands-I6KZYCIG.js +223 -0
- package/agentMachineCommands-OUP3YQP7.js +425 -0
- package/agentPullCommand-O2MTUAFR.js +122 -0
- package/agentRecordCommands-QKGE2JTA.js +96 -0
- package/agentRunCommand-TVZXUBQ5.js +114 -0
- package/agentRunControl-K4VKNEHF.js +57 -0
- package/agentRuntimeLocal-ZYEIPTY4.js +104 -0
- package/agentSlice-T4PMW7W6.js +42 -0
- package/authCommand-EB5JSOX5.js +581 -0
- package/authCommands-XPEHTKSM.js +35 -0
- package/chunk-2EHX7F5G.js +1948 -0
- package/chunk-2FTTDCD4.js +675 -0
- package/chunk-3ASDTTEI.js +1774 -0
- package/chunk-3EUW3WEO.js +8 -0
- package/chunk-3LY4F7SV.js +9293 -0
- package/chunk-4CQLVGRV.js +50 -0
- package/chunk-4FBRSEV4.js +573 -0
- package/chunk-4IJYA27C.js +342 -0
- package/chunk-4QEWT7KD.js +933 -0
- package/chunk-4SN6J65J.js +38 -0
- package/chunk-4VNS5WPM.js +42 -0
- package/chunk-4ZDM73SD.js +34 -0
- package/chunk-5CS33IBL.js +301 -0
- package/chunk-5KLGBAAR.js +386 -0
- package/chunk-5MIDPSSK.js +206 -0
- package/chunk-5MMAK75Q.js +15 -0
- package/chunk-5W3VUFOX.js +34 -0
- package/chunk-63W5N6P3.js +150 -0
- package/chunk-6HYVJV7B.js +102 -0
- package/chunk-6WD3OOJS.js +20 -0
- package/chunk-7DAJ4AI4.js +191 -0
- package/chunk-7KCUSYT2.js +354 -0
- package/chunk-7T5PWAZN.js +171 -0
- package/chunk-AFON4QUU.js +112 -0
- package/chunk-AGFH73SK.js +239 -0
- package/chunk-ATNTHIZI.js +13 -0
- package/chunk-AVMKZHBC.js +85 -0
- package/chunk-AZPCASRE.js +36 -0
- package/chunk-BBYVOSU2.js +792 -0
- package/chunk-BCIOM4NZ.js +1078 -0
- package/chunk-C3RUNRHT.js +51 -0
- package/chunk-C4FTUXVF.js +146 -0
- package/chunk-CF2WZF4N.js +134 -0
- package/chunk-CF7PE763.js +10 -0
- package/chunk-CKOJQDKR.js +198 -0
- package/chunk-CMKUBIGW.js +1550 -0
- package/chunk-CWMSB67P.js +34 -0
- package/chunk-DCOA4QSN.js +105 -0
- package/chunk-DFFIZ25G.js +30 -0
- package/chunk-DWLEOOGR.js +8 -0
- package/chunk-DZ3XJVET.js +231 -0
- package/chunk-EHLHSX7R.js +1433 -0
- package/chunk-FM5IVZXO.js +4723 -0
- package/chunk-FVYY6MCS.js +1447 -0
- package/chunk-G3SUCT4W.js +8 -0
- package/chunk-GAKEBQD6.js +30 -0
- package/chunk-GBRG75BQ.js +86 -0
- package/chunk-GLYVN7EQ.js +238 -0
- package/chunk-H33743XH.js +25 -0
- package/chunk-HNMXYYJR.js +12 -0
- package/chunk-HNW7IJSK.js +71 -0
- package/chunk-I42VC5KR.js +15 -0
- package/chunk-IDZTNRP2.js +85 -0
- package/chunk-IHBCLYEE.js +22310 -0
- package/chunk-IJGXKGXW.js +421 -0
- package/chunk-ISNCLGUZ.js +146 -0
- package/chunk-IWX4UW2E.js +548 -0
- package/chunk-JBTJAPUF.js +35 -0
- package/chunk-JEXVIMYZ.js +55 -0
- package/chunk-JRKKFRAV.js +537 -0
- package/chunk-JZPBVBIY.js +94 -0
- package/chunk-K6BPOQLF.js +2052 -0
- package/chunk-K777STIO.js +478 -0
- package/chunk-KKY4B2Q2.js +21 -0
- package/chunk-KQHGZWSV.js +63 -0
- package/chunk-KUG52IAP.js +8 -0
- package/chunk-KX6YBIHG.js +8 -0
- package/chunk-LCBAMY2M.js +60 -0
- package/chunk-LM6IYQ3F.js +16 -0
- package/chunk-LTRXGFMS.js +83 -0
- package/chunk-M76ECQRD.js +13658 -0
- package/chunk-MNJDFJND.js +222 -0
- package/chunk-MRC4Q34M.js +188 -0
- package/chunk-MTU75CZ2.js +91 -0
- package/chunk-N54XAP77.js +19 -0
- package/chunk-O2ZNTTET.js +3272 -0
- package/chunk-O4BU24WZ.js +3212 -0
- package/chunk-OLZBQWZU.js +6 -0
- package/chunk-OPZYGHUC.js +89 -0
- package/chunk-OWOHNGCN.js +50 -0
- package/chunk-P3PKED2I.js +962 -0
- package/chunk-PFTAG6DY.js +1939 -0
- package/chunk-PMKQGGGM.js +221 -0
- package/chunk-PP4S6RTL.js +175 -0
- package/chunk-QJ7FZNYN.js +939 -0
- package/chunk-QSJ3HFEF.js +8 -0
- package/chunk-RGIM3WLT.js +113 -0
- package/chunk-RL776AGR.js +190 -0
- package/chunk-ROWQEJRP.js +139 -0
- package/chunk-S7Z2HMCN.js +25 -0
- package/chunk-SDJDLO5W.js +628 -0
- package/chunk-SOTZ6RDN.js +69 -0
- package/chunk-TILFE6LV.js +381 -0
- package/chunk-TIMLUWQA.js +231 -0
- package/chunk-TISCADJH.js +807 -0
- package/chunk-U4TRT5V4.js +246 -0
- package/chunk-U6VC4MU4.js +8 -0
- package/chunk-UAD2WT54.js +64 -0
- package/chunk-VC6OZXO5.js +298 -0
- package/chunk-VF4K2QE6.js +21 -0
- package/chunk-VHBWHNVT.js +59 -0
- package/chunk-VIDPVFP3.js +20 -0
- package/chunk-VP4WJWKW.js +8882 -0
- package/chunk-VVX233PH.js +482 -0
- package/chunk-W4NVOSFF.js +37 -0
- package/chunk-WI4XWASA.js +208 -0
- package/chunk-WWC7I6TA.js +8 -0
- package/chunk-WZSRQNQG.js +2587 -0
- package/chunk-XBROXIGL.js +3066 -0
- package/chunk-XENYHRUE.js +104 -0
- package/chunk-Y5GCAMGP.js +9 -0
- package/chunk-YN4XDB7B.js +9036 -0
- package/chunk-YPRZSPF3.js +148 -0
- package/chunk-Z4NR32XR.js +50 -0
- package/chunk-Z6EKEXJW.js +138 -0
- package/chunk-ZDRZMLKO.js +27339 -0
- package/chunk-ZNFJWEN4.js +56 -0
- package/cliExecutor-K3F7DMRO.js +36 -0
- package/clipboardy-BVE3LVEH.js +12001 -0
- package/createAgentAutomationAction-CCABEOM6.js +866 -0
- package/createDialogAction-YPKF5ITI.js +55 -0
- package/createPageAction-YEZ7EK5F.js +172 -0
- package/db-HCJ5PRB5.js +271 -0
- package/dbSlice-QPVZHBOE.js +60 -0
- package/deleteFile-SV5MS23W.js +41 -0
- package/dialogCommands-4IX4XIZE.js +63 -0
- package/dialogSlice-OVTO7QGW.js +148 -0
- package/docCreateCommands-SIL3NPGT.js +220 -0
- package/docDeleteCommands-7IOMLUS4.js +181 -0
- package/docReadCommands-FNFXUA5L.js +134 -0
- package/docStore-ZAYLW2HN.js +98 -0
- package/docUpdateCommands-X2HNDVUC.js +318 -0
- package/fetchMessages-KTNM7QAR.js +17 -0
- package/getPricing-3E6UNPKL.js +30 -0
- package/handleSendMessageAction-TZMZ4EP5.js +185 -0
- package/index.js +188 -112958
- package/lib-FYYBQIXS.js +19839 -0
- package/localDialogRead-2VRI24F4.js +26 -0
- package/localFirstLog-DHNOY2NA.js +19 -0
- package/localRuntimeAuthority-TEGCOWX4.js +471 -0
- package/localRuntimeDb-LGDF6FQP.js +12 -0
- package/machineCommands-M4ZJZIMS.js +781 -0
- package/machineInfo-M6KB6HZN.js +10 -0
- package/machineWsRunDispatch-TPJAUGLP.js +112 -0
- package/memoryCommands-O4MIPIWQ.js +476 -0
- package/models-4OPOOLFS.js +9 -0
- package/offlineMarxistsAgentCommand-BCPJITJL.js +242 -0
- package/package.json +4 -23
- package/read-EBMWX4Z6.js +17 -0
- package/readDocTool-2MWHSTQE.js +16 -0
- package/readlineWorkspace-OMCIU3WT.js +5682 -0
- package/removeDialogAgentAction-SNZ662NP.js +73 -0
- package/runAgentClientLoop-H6NGOUAM.js +293 -0
- package/runtimeDoctorCommands-LRHLPDRC.js +289 -0
- package/setDialogExtraReferencesAction-XDI2KM2N.js +60 -0
- package/setPrimaryDialogAgentAction-PYEC4N4Z.js +80 -0
- package/settingSlice-NOWHY2FK.js +199 -0
- package/skillDiscovery-UGSQGX2U.js +16 -0
- package/skillSummaryMarker-42HKSXYY.js +9 -0
- package/slateToRenderMarkdown-Y5IYN73U.js +7 -0
- package/slateUtils-2M7MUTWX.js +19 -0
- package/spaceCommands-E7VOF4LO.js +450 -0
- package/spaceSlice-QHBPICA2.js +149 -0
- package/streamAgentChatTurn-3XTBA2HN.js +4510 -0
- package/tableCommands-R5UCM63M.js +1286 -0
- package/toolApiClient-QI3YBNWB.js +26 -0
- package/tools-GHLZ3XD6.js +87 -0
- package/tuiSummaryLlmCaller-RV3THLZF.js +78 -0
- package/understanding-3CUQQ6SV.js +271 -0
- package/updateCommands-VOSPKXFF.js +31 -0
- package/updateDialogTitleAction-XA2OZTLP.js +188 -0
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
import {
|
|
2
|
+
extractThinkContent,
|
|
3
|
+
flushThinkParser,
|
|
4
|
+
processThinkChunk
|
|
5
|
+
} from "./chunk-OPZYGHUC.js";
|
|
6
|
+
import {
|
|
7
|
+
buildProviderExecutionPlan,
|
|
8
|
+
canUsePlatformChatProvider,
|
|
9
|
+
convertMessagesToResponsesInput,
|
|
10
|
+
extractTextFromResponseOutput,
|
|
11
|
+
extractToolCallsFromResponseOutput,
|
|
12
|
+
hasDirectOpenAiCompatibleProvider,
|
|
13
|
+
resolveAgentRuntimeLocation,
|
|
14
|
+
resolvePlatformAuthToken,
|
|
15
|
+
resolvePlatformServerUrl,
|
|
16
|
+
resolveProviderTransportDecision,
|
|
17
|
+
toResponsesTools
|
|
18
|
+
} from "./chunk-JRKKFRAV.js";
|
|
19
|
+
|
|
20
|
+
// packages/agent-runtime/openAiCompatibleMessages.ts
|
|
21
|
+
function toOpenAiCompatibleMessages(messages) {
|
|
22
|
+
return messages.map((message) => ({
|
|
23
|
+
role: message.role,
|
|
24
|
+
content: message.content ?? "",
|
|
25
|
+
...message.tool_call_id ? { tool_call_id: message.tool_call_id } : {},
|
|
26
|
+
...Array.isArray(message.tool_calls) ? { tool_calls: message.tool_calls } : {},
|
|
27
|
+
...message.reasoning_content ? { reasoning_content: message.reasoning_content } : {}
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// packages/agent-runtime/toolCallAccumulator.ts
|
|
32
|
+
function accumulateToolCallDelta(accumulated, deltas) {
|
|
33
|
+
for (const delta of deltas) {
|
|
34
|
+
const index = typeof delta.index === "number" ? delta.index : 0;
|
|
35
|
+
const current = accumulated[index] ?? {
|
|
36
|
+
id: "",
|
|
37
|
+
type: "function",
|
|
38
|
+
function: { name: "", arguments: "" }
|
|
39
|
+
};
|
|
40
|
+
if (typeof delta.id === "string" && delta.id) current.id = delta.id;
|
|
41
|
+
const fn = delta.function;
|
|
42
|
+
if (fn && typeof fn === "object") {
|
|
43
|
+
const functionDelta = fn;
|
|
44
|
+
if (typeof functionDelta.name === "string" && functionDelta.name) {
|
|
45
|
+
current.function.name += functionDelta.name;
|
|
46
|
+
}
|
|
47
|
+
if (typeof functionDelta.arguments === "string" && functionDelta.arguments) {
|
|
48
|
+
current.function.arguments += functionDelta.arguments;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
accumulated[index] = current;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function finalizeAccumulatedToolCalls(accumulated) {
|
|
55
|
+
return Object.keys(accumulated).map((key) => accumulated[Number(key)]).filter((call) => call?.function?.name);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// packages/agent-runtime/processChatCompletionDelta.ts
|
|
59
|
+
function extractChatCompletionStreamError(parsed) {
|
|
60
|
+
const raw = parsed?.error;
|
|
61
|
+
if (!raw) return null;
|
|
62
|
+
if (typeof raw === "string") {
|
|
63
|
+
return raw.trim() ? { message: raw.trim() } : null;
|
|
64
|
+
}
|
|
65
|
+
if (typeof raw !== "object") return null;
|
|
66
|
+
const message = typeof raw.msg === "string" && raw.msg.trim() ? raw.msg.trim() : typeof raw.message === "string" && raw.message.trim() ? raw.message.trim() : "";
|
|
67
|
+
const code = typeof raw.code === "string" && raw.code.trim() ? raw.code.trim() : typeof raw.type === "string" && raw.type.trim() ? raw.type.trim() : void 0;
|
|
68
|
+
if (!message && !code) return null;
|
|
69
|
+
return {
|
|
70
|
+
message: message || "upstream stream error",
|
|
71
|
+
...code ? { code } : {}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function throwIfChatCompletionStreamFailed(state) {
|
|
75
|
+
const failure = state.streamError;
|
|
76
|
+
if (!failure) return;
|
|
77
|
+
const error = new Error(
|
|
78
|
+
failure.code ? `${failure.message} (${failure.code})` : failure.message
|
|
79
|
+
);
|
|
80
|
+
if (failure.code) error.code = failure.code;
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
function applyChatCompletionDelta(parsed, state) {
|
|
84
|
+
const streamError = extractChatCompletionStreamError(parsed);
|
|
85
|
+
if (streamError && !state.streamError) {
|
|
86
|
+
state.streamError = streamError;
|
|
87
|
+
}
|
|
88
|
+
if (parsed?.usage && typeof parsed.usage === "object") {
|
|
89
|
+
state.usage = parsed.usage;
|
|
90
|
+
}
|
|
91
|
+
const rawFinishReason = parsed?.choices?.[0]?.finish_reason;
|
|
92
|
+
if (typeof rawFinishReason === "string" && rawFinishReason.length > 0) {
|
|
93
|
+
state.finishReason = rawFinishReason;
|
|
94
|
+
}
|
|
95
|
+
const delta = parsed?.choices?.[0]?.delta;
|
|
96
|
+
if (!delta || typeof delta !== "object") return false;
|
|
97
|
+
const reasoningChunk = typeof delta.reasoning_content === "string" ? delta.reasoning_content : typeof delta.reasoning === "string" ? delta.reasoning : "";
|
|
98
|
+
if (reasoningChunk) {
|
|
99
|
+
state.reasoning += reasoningChunk;
|
|
100
|
+
state.onReasoningDelta?.(reasoningChunk);
|
|
101
|
+
}
|
|
102
|
+
if (Array.isArray(delta.tool_calls) && delta.tool_calls.length > 0) {
|
|
103
|
+
accumulateToolCallDelta(state.accumulatedToolCalls, delta.tool_calls);
|
|
104
|
+
}
|
|
105
|
+
const textChunk = typeof delta.content === "string" ? delta.content : "";
|
|
106
|
+
if (textChunk) {
|
|
107
|
+
const parsedChunk = processThinkChunk(textChunk, state.thinkState);
|
|
108
|
+
state.thinkState = parsedChunk.state;
|
|
109
|
+
if (parsedChunk.content) {
|
|
110
|
+
state.content += parsedChunk.content;
|
|
111
|
+
state.onTextDelta?.(parsedChunk.content);
|
|
112
|
+
}
|
|
113
|
+
if (parsedChunk.reasoning) {
|
|
114
|
+
state.reasoning += parsedChunk.reasoning;
|
|
115
|
+
state.onReasoningDelta?.(parsedChunk.reasoning);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
function flushChatCompletionStream(state) {
|
|
121
|
+
const flushed = flushThinkParser(state.thinkState);
|
|
122
|
+
state.thinkState = flushed.state;
|
|
123
|
+
if (flushed.content) {
|
|
124
|
+
state.content += flushed.content;
|
|
125
|
+
state.onTextDelta?.(flushed.content);
|
|
126
|
+
}
|
|
127
|
+
if (flushed.reasoning) {
|
|
128
|
+
state.reasoning += flushed.reasoning;
|
|
129
|
+
state.onReasoningDelta?.(flushed.reasoning);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// packages/agent-runtime/sseFrames.ts
|
|
134
|
+
async function* readSseFrames(response) {
|
|
135
|
+
const reader = response.body?.getReader();
|
|
136
|
+
if (!reader) {
|
|
137
|
+
throw new Error("SSE response did not include a readable body.");
|
|
138
|
+
}
|
|
139
|
+
const decoder = new TextDecoder();
|
|
140
|
+
let buffer = "";
|
|
141
|
+
while (true) {
|
|
142
|
+
const { done, value } = await reader.read();
|
|
143
|
+
if (done) break;
|
|
144
|
+
buffer += decoder.decode(value, { stream: true });
|
|
145
|
+
let boundary = buffer.indexOf("\n\n");
|
|
146
|
+
while (boundary !== -1) {
|
|
147
|
+
yield buffer.slice(0, boundary);
|
|
148
|
+
buffer = buffer.slice(boundary + 2);
|
|
149
|
+
boundary = buffer.indexOf("\n\n");
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (buffer.trim()) yield buffer;
|
|
153
|
+
}
|
|
154
|
+
async function readSseDataValues(response, parse) {
|
|
155
|
+
const reader = response.body?.getReader();
|
|
156
|
+
if (!reader) return [];
|
|
157
|
+
const decoder = new TextDecoder();
|
|
158
|
+
const values = [];
|
|
159
|
+
let buffer = "";
|
|
160
|
+
while (true) {
|
|
161
|
+
const { done, value } = await reader.read();
|
|
162
|
+
if (done) break;
|
|
163
|
+
buffer += decoder.decode(value, { stream: true });
|
|
164
|
+
const lines = buffer.split("\n");
|
|
165
|
+
buffer = lines.pop() ?? "";
|
|
166
|
+
for (const line of lines) {
|
|
167
|
+
const parsed = parse(line);
|
|
168
|
+
if (parsed) values.push(parsed);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (buffer.trim()) {
|
|
172
|
+
const parsed = parse(buffer);
|
|
173
|
+
if (parsed) values.push(parsed);
|
|
174
|
+
}
|
|
175
|
+
return values;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// packages/agent-runtime/platformChatProvider.ts
|
|
179
|
+
var CHAT_PROXY_PATH = "/api/v1/chat";
|
|
180
|
+
function shouldDisableThinking(providerConfig) {
|
|
181
|
+
return providerConfig.provider.toLowerCase() === "mimo" || /xiaomimimo\.com/i.test(providerConfig.endpoint);
|
|
182
|
+
}
|
|
183
|
+
function isResponsesEndpoint(endpoint) {
|
|
184
|
+
return /\/responses$/i.test(endpoint.trim());
|
|
185
|
+
}
|
|
186
|
+
function toResponsesRequestOptions(options) {
|
|
187
|
+
const next = { ...options };
|
|
188
|
+
const reasoningEffort = next.reasoning_effort;
|
|
189
|
+
if (typeof reasoningEffort === "string" && reasoningEffort) {
|
|
190
|
+
next.reasoning = { effort: reasoningEffort };
|
|
191
|
+
delete next.reasoning_effort;
|
|
192
|
+
}
|
|
193
|
+
if (next.max_tokens !== void 0) {
|
|
194
|
+
next.max_output_tokens = next.max_tokens;
|
|
195
|
+
delete next.max_tokens;
|
|
196
|
+
}
|
|
197
|
+
return next;
|
|
198
|
+
}
|
|
199
|
+
async function resolvePlatformChatProviderConfig(args) {
|
|
200
|
+
const plan = await buildProviderExecutionPlan({
|
|
201
|
+
agentConfig: args.agentConfig,
|
|
202
|
+
env: args.env,
|
|
203
|
+
runtimeKind: "local",
|
|
204
|
+
...args.apiKeyRefResolver ? { apiKeyRefResolver: args.apiKeyRefResolver } : {},
|
|
205
|
+
...args.credentialBroker ? { credentialBroker: args.credentialBroker } : {},
|
|
206
|
+
...args.syncFetcher ? { syncFetcher: args.syncFetcher } : {}
|
|
207
|
+
});
|
|
208
|
+
if (plan.mode === "cli") {
|
|
209
|
+
throw new Error("Platform chat provider does not support cli agents.");
|
|
210
|
+
}
|
|
211
|
+
if (plan.transport === "direct") {
|
|
212
|
+
return {
|
|
213
|
+
serverUrl: resolvePlatformServerUrl(args.env),
|
|
214
|
+
authToken: resolvePlatformAuthToken(args.env),
|
|
215
|
+
agentKey: args.agentConfig.key,
|
|
216
|
+
model: plan.model,
|
|
217
|
+
provider: plan.provider,
|
|
218
|
+
endpoint: plan.endpoint,
|
|
219
|
+
requestOptions: plan.requestOptions,
|
|
220
|
+
...plan.apiKey ? { apiKey: plan.apiKey } : {},
|
|
221
|
+
...plan.apiKeyHeader ? { apiKeyHeader: plan.apiKeyHeader } : {},
|
|
222
|
+
...args.agentConfig.apiSource ? { apiSource: args.agentConfig.apiSource } : {}
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
return {
|
|
226
|
+
serverUrl: plan.serverUrl,
|
|
227
|
+
authToken: plan.authToken,
|
|
228
|
+
agentKey: plan.agentKey,
|
|
229
|
+
model: plan.model,
|
|
230
|
+
provider: plan.provider,
|
|
231
|
+
endpoint: plan.endpoint,
|
|
232
|
+
requestOptions: plan.requestOptions,
|
|
233
|
+
...plan.apiKey ? { apiKey: plan.apiKey } : {},
|
|
234
|
+
...plan.apiKeyHeader ? { apiKeyHeader: plan.apiKeyHeader } : {},
|
|
235
|
+
...plan.apiSource ? { apiSource: plan.apiSource } : {}
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
function buildPlatformChatCompletionRequest(args) {
|
|
239
|
+
const usesResponsesApi = isResponsesEndpoint(args.providerConfig.endpoint);
|
|
240
|
+
const requestOptions = usesResponsesApi ? toResponsesRequestOptions(args.providerConfig.requestOptions) : args.providerConfig.requestOptions;
|
|
241
|
+
const body = {
|
|
242
|
+
model: args.providerConfig.model,
|
|
243
|
+
...usesResponsesApi ? { input: convertMessagesToResponsesInput(args.messages) } : { messages: toOpenAiCompatibleMessages(args.messages) },
|
|
244
|
+
stream: args.stream ?? false,
|
|
245
|
+
...args.stream ? { stream_options: { include_usage: true } } : {},
|
|
246
|
+
...requestOptions,
|
|
247
|
+
...args.tools && args.tools.length > 0 ? {
|
|
248
|
+
tools: usesResponsesApi ? toResponsesTools(args.tools) : args.tools,
|
|
249
|
+
...usesResponsesApi ? {} : { tool_choice: "auto" }
|
|
250
|
+
} : {},
|
|
251
|
+
...shouldDisableThinking(args.providerConfig) ? { thinking: { type: "disabled" } } : {},
|
|
252
|
+
url: args.providerConfig.endpoint,
|
|
253
|
+
provider: args.providerConfig.provider,
|
|
254
|
+
agentKey: args.providerConfig.agentKey,
|
|
255
|
+
...args.providerConfig.apiSource ? { apiSource: args.providerConfig.apiSource } : {},
|
|
256
|
+
...args.providerConfig.apiKey ? { KEY: args.providerConfig.apiKey } : {},
|
|
257
|
+
...args.providerConfig.apiKeyHeader ? { apiKeyHeader: args.providerConfig.apiKeyHeader } : {}
|
|
258
|
+
};
|
|
259
|
+
return {
|
|
260
|
+
url: `${args.providerConfig.serverUrl}${CHAT_PROXY_PATH}`,
|
|
261
|
+
init: {
|
|
262
|
+
method: "POST",
|
|
263
|
+
headers: {
|
|
264
|
+
"Content-Type": "application/json",
|
|
265
|
+
Authorization: `Bearer ${args.providerConfig.authToken}`
|
|
266
|
+
},
|
|
267
|
+
body: JSON.stringify(body)
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
function tryParseJson(raw) {
|
|
272
|
+
try {
|
|
273
|
+
return JSON.parse(raw);
|
|
274
|
+
} catch {
|
|
275
|
+
return null;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
function extractJsonObjects(raw) {
|
|
279
|
+
const objects = [];
|
|
280
|
+
let depth = 0;
|
|
281
|
+
let start = -1;
|
|
282
|
+
let inString = false;
|
|
283
|
+
let escaped = false;
|
|
284
|
+
for (let index = 0; index < raw.length; index += 1) {
|
|
285
|
+
const char = raw[index];
|
|
286
|
+
if (inString) {
|
|
287
|
+
if (escaped) {
|
|
288
|
+
escaped = false;
|
|
289
|
+
} else if (char === "\\") {
|
|
290
|
+
escaped = true;
|
|
291
|
+
} else if (char === '"') {
|
|
292
|
+
inString = false;
|
|
293
|
+
}
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
if (char === '"') {
|
|
297
|
+
inString = true;
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
if (char === "{") {
|
|
301
|
+
if (depth === 0) start = index;
|
|
302
|
+
depth += 1;
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
if (char !== "}" || depth === 0) continue;
|
|
306
|
+
depth -= 1;
|
|
307
|
+
if (depth === 0 && start >= 0) {
|
|
308
|
+
const parsed = tryParseJson(raw.slice(start, index + 1));
|
|
309
|
+
if (parsed) objects.push(parsed);
|
|
310
|
+
start = -1;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return objects;
|
|
314
|
+
}
|
|
315
|
+
function parsePlatformChatCompletionData(raw) {
|
|
316
|
+
const direct = tryParseJson(raw.trim());
|
|
317
|
+
if (direct) return direct;
|
|
318
|
+
const objects = extractJsonObjects(raw);
|
|
319
|
+
return objects.find((object) => Array.isArray(object?.choices)) ?? objects[0] ?? {};
|
|
320
|
+
}
|
|
321
|
+
function parsePlatformChatCompletionResponse(args) {
|
|
322
|
+
if (isResponsesEndpoint(args.providerConfig.endpoint)) {
|
|
323
|
+
const content2 = extractTextFromResponseOutput(args.data);
|
|
324
|
+
const tool_calls = extractToolCallsFromResponseOutput(args.data);
|
|
325
|
+
return {
|
|
326
|
+
content: content2,
|
|
327
|
+
model: args.providerConfig.model,
|
|
328
|
+
provider: args.providerConfig.provider,
|
|
329
|
+
...tool_calls.length > 0 ? { tool_calls } : {},
|
|
330
|
+
usage: args.data?.usage,
|
|
331
|
+
trace: args.trace
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
const choiceMessage = args.data?.choices?.[0]?.message ?? {};
|
|
335
|
+
const rawContent = String(choiceMessage?.content ?? "");
|
|
336
|
+
const { content, reasoning } = extractThinkContent(rawContent);
|
|
337
|
+
return {
|
|
338
|
+
content,
|
|
339
|
+
model: args.providerConfig.model,
|
|
340
|
+
provider: args.providerConfig.provider,
|
|
341
|
+
...Array.isArray(choiceMessage?.tool_calls) ? { tool_calls: choiceMessage.tool_calls } : {},
|
|
342
|
+
...reasoning ? { reasoning_content: reasoning } : typeof choiceMessage?.reasoning_content === "string" && choiceMessage.reasoning_content ? { reasoning_content: choiceMessage.reasoning_content } : {},
|
|
343
|
+
usage: args.data?.usage,
|
|
344
|
+
trace: args.trace
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
function canUsePlatformChatProvider2(env) {
|
|
348
|
+
return canUsePlatformChatProvider(env);
|
|
349
|
+
}
|
|
350
|
+
function hasDirectOpenAiCompatibleProvider2(env) {
|
|
351
|
+
return hasDirectOpenAiCompatibleProvider(env);
|
|
352
|
+
}
|
|
353
|
+
function shouldUsePlatformChatProvider(env, agentConfig) {
|
|
354
|
+
if (!agentConfig) {
|
|
355
|
+
return resolveProviderTransportDecision({
|
|
356
|
+
agentConfig: { key: "default-platform" },
|
|
357
|
+
env,
|
|
358
|
+
runtimeLocation: "local-host"
|
|
359
|
+
}).transport === "proxy";
|
|
360
|
+
}
|
|
361
|
+
return resolveProviderTransportDecision({
|
|
362
|
+
agentConfig,
|
|
363
|
+
env,
|
|
364
|
+
runtimeLocation: resolveAgentRuntimeLocation({
|
|
365
|
+
agentConfig,
|
|
366
|
+
runtimeKind: "local"
|
|
367
|
+
})
|
|
368
|
+
}).transport === "proxy";
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
export {
|
|
372
|
+
finalizeAccumulatedToolCalls,
|
|
373
|
+
throwIfChatCompletionStreamFailed,
|
|
374
|
+
applyChatCompletionDelta,
|
|
375
|
+
flushChatCompletionStream,
|
|
376
|
+
toOpenAiCompatibleMessages,
|
|
377
|
+
readSseFrames,
|
|
378
|
+
readSseDataValues,
|
|
379
|
+
resolvePlatformChatProviderConfig,
|
|
380
|
+
buildPlatformChatCompletionRequest,
|
|
381
|
+
parsePlatformChatCompletionData,
|
|
382
|
+
parsePlatformChatCompletionResponse,
|
|
383
|
+
canUsePlatformChatProvider2 as canUsePlatformChatProvider,
|
|
384
|
+
hasDirectOpenAiCompatibleProvider2 as hasDirectOpenAiCompatibleProvider,
|
|
385
|
+
shouldUsePlatformChatProvider
|
|
386
|
+
};
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import {
|
|
2
|
+
extractCustomId
|
|
3
|
+
} from "./chunk-DFFIZ25G.js";
|
|
4
|
+
import {
|
|
5
|
+
getActiveDialogKey
|
|
6
|
+
} from "./chunk-3ASDTTEI.js";
|
|
7
|
+
import {
|
|
8
|
+
compactWhitespace
|
|
9
|
+
} from "./chunk-DWLEOOGR.js";
|
|
10
|
+
import {
|
|
11
|
+
asTrimmedLowercaseString
|
|
12
|
+
} from "./chunk-QSJ3HFEF.js";
|
|
13
|
+
import {
|
|
14
|
+
isRecord
|
|
15
|
+
} from "./chunk-KUG52IAP.js";
|
|
16
|
+
|
|
17
|
+
// packages/ai/tools/toolApiClient.ts
|
|
18
|
+
var MAIN_SERVER = "https://nolo.chat";
|
|
19
|
+
var getIsDesktopApp = () => typeof window !== "undefined" && Boolean(window.__NOLO_DESKTOP__);
|
|
20
|
+
var isLocalServerUrl = (value) => {
|
|
21
|
+
if (!value) return false;
|
|
22
|
+
try {
|
|
23
|
+
const hostname = new URL(value).hostname.toLowerCase();
|
|
24
|
+
return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1";
|
|
25
|
+
} catch {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
var resolveDesktopSafeServer = (value) => {
|
|
30
|
+
if (!getIsDesktopApp()) return value || MAIN_SERVER;
|
|
31
|
+
return isLocalServerUrl(value) ? MAIN_SERVER : value || MAIN_SERVER;
|
|
32
|
+
};
|
|
33
|
+
var selectCurrentServerFromState = (state) => resolveDesktopSafeServer(state?.settings?.currentServer);
|
|
34
|
+
var selectCurrentTokenFromState = (state) => typeof state?.auth?.currentToken === "string" ? state.auth.currentToken : null;
|
|
35
|
+
var selectCurrentDialogKeyFromState = (_state) => getActiveDialogKey();
|
|
36
|
+
var resolveToolBaseUrl = (currentServer) => {
|
|
37
|
+
const _window = globalThis.window;
|
|
38
|
+
if (!_window) return (currentServer || "").replace(/\/+$/, "");
|
|
39
|
+
const fallbackLocal = _window.location.origin;
|
|
40
|
+
if (!currentServer) return fallbackLocal;
|
|
41
|
+
return currentServer.replace(/\/+$/, "");
|
|
42
|
+
};
|
|
43
|
+
var DESKTOP_LOCAL_TOOL_PATHS = /* @__PURE__ */ new Set([
|
|
44
|
+
"/api/exec-shell",
|
|
45
|
+
"/api/check-env",
|
|
46
|
+
"/api/read-file",
|
|
47
|
+
"/api/write-file",
|
|
48
|
+
"/api/apply-edit",
|
|
49
|
+
"/api/apply-line-edits",
|
|
50
|
+
"/api/code-search",
|
|
51
|
+
"/api/search-repo",
|
|
52
|
+
"/api/desktop/files/roots",
|
|
53
|
+
"/api/desktop/files/roots/request",
|
|
54
|
+
"/api/desktop/files/list",
|
|
55
|
+
"/api/desktop/files/read",
|
|
56
|
+
"/api/desktop/files/plan",
|
|
57
|
+
"/api/desktop/files/approve",
|
|
58
|
+
"/api/desktop/files/execute",
|
|
59
|
+
"/api/desktop/files/undo",
|
|
60
|
+
"/api/desktop/files/history"
|
|
61
|
+
]);
|
|
62
|
+
var getWindowOrigin = () => {
|
|
63
|
+
const _window = globalThis.window;
|
|
64
|
+
const origin = _window?.location?.origin;
|
|
65
|
+
return typeof origin === "string" && origin ? origin.replace(/\/+$/, "") : null;
|
|
66
|
+
};
|
|
67
|
+
var resolveToolApiBaseUrl = (currentServer, path) => {
|
|
68
|
+
if (path && DESKTOP_LOCAL_TOOL_PATHS.has(path) && getIsDesktopApp()) {
|
|
69
|
+
const localOrigin = getWindowOrigin();
|
|
70
|
+
if (localOrigin) return localOrigin;
|
|
71
|
+
}
|
|
72
|
+
return resolveToolBaseUrl(currentServer);
|
|
73
|
+
};
|
|
74
|
+
var getRequestConfig = (thunkApi) => {
|
|
75
|
+
const state = thunkApi.getState();
|
|
76
|
+
const currentServer = selectCurrentServerFromState(state);
|
|
77
|
+
const token = selectCurrentTokenFromState(state);
|
|
78
|
+
if (!currentServer) throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5F53\u524D\u670D\u52A1\u5668\u5730\u5740\u3002");
|
|
79
|
+
return { currentServer, token };
|
|
80
|
+
};
|
|
81
|
+
var getToolBaseUrl = (thunkApi) => {
|
|
82
|
+
const { currentServer } = getRequestConfig(thunkApi);
|
|
83
|
+
const baseUrl = resolveToolBaseUrl(currentServer);
|
|
84
|
+
if (!baseUrl) throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5DE5\u5177\u670D\u52A1\u5668\u5730\u5740\u3002");
|
|
85
|
+
return baseUrl;
|
|
86
|
+
};
|
|
87
|
+
var getToolRequestContext = (thunkApi) => {
|
|
88
|
+
const { currentServer, token } = getRequestConfig(thunkApi);
|
|
89
|
+
const baseUrl = resolveToolBaseUrl(currentServer);
|
|
90
|
+
if (!baseUrl) throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5DE5\u5177\u670D\u52A1\u5668\u5730\u5740\u3002");
|
|
91
|
+
return {
|
|
92
|
+
currentServer,
|
|
93
|
+
token,
|
|
94
|
+
baseUrl
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
var maybeAttachDialogId = (thunkApi, body) => {
|
|
98
|
+
if (!isRecord(body)) return body;
|
|
99
|
+
if ("dialogId" in body) return body;
|
|
100
|
+
const state = thunkApi.getState();
|
|
101
|
+
const currentDialogKey = selectCurrentDialogKeyFromState(state);
|
|
102
|
+
const dialogId = currentDialogKey ? extractCustomId(currentDialogKey) : null;
|
|
103
|
+
if (!dialogId) return body;
|
|
104
|
+
return {
|
|
105
|
+
...body,
|
|
106
|
+
dialogId
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
var ToolApiError = class extends Error {
|
|
110
|
+
status;
|
|
111
|
+
code;
|
|
112
|
+
details;
|
|
113
|
+
constructor(message, options) {
|
|
114
|
+
super(message);
|
|
115
|
+
this.name = "ToolApiError";
|
|
116
|
+
this.status = options?.status;
|
|
117
|
+
this.code = options?.code;
|
|
118
|
+
this.details = options?.details;
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
var buildToolRequestHeaders = (thunkApi, options = {}) => {
|
|
122
|
+
const { withAuth = false, agentKey } = options;
|
|
123
|
+
const { token } = getRequestConfig(thunkApi);
|
|
124
|
+
const headers = { "Content-Type": "application/json" };
|
|
125
|
+
if (withAuth && token) {
|
|
126
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
127
|
+
}
|
|
128
|
+
if (agentKey && typeof agentKey === "string" && agentKey.trim()) {
|
|
129
|
+
headers["X-Nolo-Agent-Key"] = agentKey.trim();
|
|
130
|
+
}
|
|
131
|
+
if (typeof window !== "undefined" && window.__NOLO_DESKTOP__) {
|
|
132
|
+
headers["X-Nolo-Desktop-Tool"] = "1";
|
|
133
|
+
}
|
|
134
|
+
return headers;
|
|
135
|
+
};
|
|
136
|
+
var buildResponsePreview = (text) => compactWhitespace(text).slice(0, 240);
|
|
137
|
+
var looksLikeHtmlResponse = (text, contentType) => {
|
|
138
|
+
if (contentType?.toLowerCase().includes("text/html")) return true;
|
|
139
|
+
const trimmed = asTrimmedLowercaseString(text);
|
|
140
|
+
return trimmed.startsWith("<!doctype html") || trimmed.startsWith("<html");
|
|
141
|
+
};
|
|
142
|
+
async function callToolApi(thunkApi, path, body, options = {}) {
|
|
143
|
+
const { currentServer } = getRequestConfig(thunkApi);
|
|
144
|
+
const baseUrl = resolveToolApiBaseUrl(currentServer, path);
|
|
145
|
+
if (!baseUrl) throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5DE5\u5177\u670D\u52A1\u5668\u5730\u5740\u3002");
|
|
146
|
+
const url = `${baseUrl}${path}`;
|
|
147
|
+
const headers = buildToolRequestHeaders(thunkApi, options);
|
|
148
|
+
const response = await fetch(url, {
|
|
149
|
+
method: "POST",
|
|
150
|
+
headers,
|
|
151
|
+
body: JSON.stringify(maybeAttachDialogId(thunkApi, body))
|
|
152
|
+
});
|
|
153
|
+
const contentType = response.headers.get("content-type");
|
|
154
|
+
const responseText = await response.text();
|
|
155
|
+
if (!response.ok) {
|
|
156
|
+
let errorMessage = `API \u8BF7\u6C42\u5931\u8D25\uFF0C\u72B6\u6001\u7801: ${response.status}`;
|
|
157
|
+
let errorCode;
|
|
158
|
+
let errorDetails;
|
|
159
|
+
try {
|
|
160
|
+
const errorData = JSON.parse(responseText);
|
|
161
|
+
const err = errorData?.error;
|
|
162
|
+
if (err) {
|
|
163
|
+
errorMessage += `: ${err.message ?? JSON.stringify(err)}`;
|
|
164
|
+
errorCode = typeof err.code === "string" ? err.code : void 0;
|
|
165
|
+
errorDetails = err.details;
|
|
166
|
+
}
|
|
167
|
+
} catch {
|
|
168
|
+
errorCode = looksLikeHtmlResponse(responseText, contentType) ? "HTML_ERROR_RESPONSE" : "NON_JSON_ERROR_RESPONSE";
|
|
169
|
+
errorDetails = {
|
|
170
|
+
contentType,
|
|
171
|
+
responsePreview: buildResponsePreview(responseText)
|
|
172
|
+
};
|
|
173
|
+
if (typeof errorDetails.responsePreview === "string" && errorDetails.responsePreview) {
|
|
174
|
+
errorMessage += `: ${errorDetails.responsePreview}`;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
throw new ToolApiError(errorMessage, {
|
|
178
|
+
status: response.status,
|
|
179
|
+
code: errorCode,
|
|
180
|
+
details: errorDetails
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
try {
|
|
184
|
+
return JSON.parse(responseText);
|
|
185
|
+
} catch {
|
|
186
|
+
throw new ToolApiError("\u670D\u52A1\u7AEF\u8FD4\u56DE\u4E86\u65E0\u6CD5\u89E3\u6790\u7684\u975E JSON \u54CD\u5E94", {
|
|
187
|
+
status: response.status,
|
|
188
|
+
code: looksLikeHtmlResponse(responseText, contentType) ? "HTML_RESPONSE" : "INVALID_JSON_RESPONSE",
|
|
189
|
+
details: {
|
|
190
|
+
contentType,
|
|
191
|
+
responsePreview: buildResponsePreview(responseText)
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export {
|
|
198
|
+
resolveToolBaseUrl,
|
|
199
|
+
resolveToolApiBaseUrl,
|
|
200
|
+
getRequestConfig,
|
|
201
|
+
getToolBaseUrl,
|
|
202
|
+
getToolRequestContext,
|
|
203
|
+
ToolApiError,
|
|
204
|
+
buildToolRequestHeaders,
|
|
205
|
+
callToolApi
|
|
206
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
compactWhitespace
|
|
3
|
+
} from "./chunk-DWLEOOGR.js";
|
|
4
|
+
|
|
5
|
+
// packages/core/clipCompactText.ts
|
|
6
|
+
function clipCompactText(value, max, ellipsis = "...") {
|
|
7
|
+
const compact = compactWhitespace(value);
|
|
8
|
+
if (compact.length <= max) return compact;
|
|
9
|
+
if (max <= ellipsis.length) return compact.slice(0, max);
|
|
10
|
+
return `${compact.slice(0, max - ellipsis.length)}${ellipsis}`;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
clipCompactText
|
|
15
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {
|
|
2
|
+
fetchReferenceContents,
|
|
3
|
+
resolveReferenceAssets
|
|
4
|
+
} from "./chunk-PFTAG6DY.js";
|
|
5
|
+
|
|
6
|
+
// packages/ai/agent/fetchAgentContexts.ts
|
|
7
|
+
async function fetchAgentContexts(references, dispatch) {
|
|
8
|
+
if (!Array.isArray(references)) {
|
|
9
|
+
return { botInstructionsContext: "", botKnowledgeContext: "" };
|
|
10
|
+
}
|
|
11
|
+
const { references: normalizedRefs, contentByKey } = await resolveReferenceAssets(references, dispatch);
|
|
12
|
+
const instructionKeys = /* @__PURE__ */ new Set();
|
|
13
|
+
const knowledgeKeys = /* @__PURE__ */ new Set();
|
|
14
|
+
normalizedRefs.forEach((ref) => {
|
|
15
|
+
if (!ref.dbKey) return;
|
|
16
|
+
ref.type === "instruction" ? instructionKeys.add(ref.dbKey) : knowledgeKeys.add(ref.dbKey);
|
|
17
|
+
});
|
|
18
|
+
const [instructionsMap, knowledgeMap] = await Promise.all([
|
|
19
|
+
fetchReferenceContents(Array.from(instructionKeys), dispatch, {
|
|
20
|
+
preloaded: contentByKey
|
|
21
|
+
}),
|
|
22
|
+
fetchReferenceContents(Array.from(knowledgeKeys), dispatch, {
|
|
23
|
+
preloaded: contentByKey
|
|
24
|
+
})
|
|
25
|
+
]);
|
|
26
|
+
return {
|
|
27
|
+
botInstructionsContext: Array.from(instructionsMap.values()).join(""),
|
|
28
|
+
botKnowledgeContext: Array.from(knowledgeMap.values()).join("")
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export {
|
|
33
|
+
fetchAgentContexts
|
|
34
|
+
};
|