@mindstudio-ai/agent 0.1.92 → 0.1.94
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/cli.js +548 -17
- package/dist/index.d.ts +49 -1
- package/dist/index.js +566 -57
- package/dist/index.js.map +1 -1
- package/dist/postinstall.js +548 -17
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3581,7 +3581,8 @@ async function runTaskPoll(httpConfig, body) {
|
|
|
3581
3581
|
const res = await fetch(pollUrl, {
|
|
3582
3582
|
headers: { "User-Agent": "@mindstudio-ai/agent" }
|
|
3583
3583
|
});
|
|
3584
|
-
if (res.status === 502 || res.status === 503 || res.status === 504)
|
|
3584
|
+
if (res.status === 502 || res.status === 503 || res.status === 504)
|
|
3585
|
+
continue;
|
|
3585
3586
|
if (res.status === 404) {
|
|
3586
3587
|
throw new MindStudioError(
|
|
3587
3588
|
"Task poll token not found or expired.",
|
|
@@ -3601,7 +3602,9 @@ async function runTaskPoll(httpConfig, body) {
|
|
|
3601
3602
|
const poll = await res.json();
|
|
3602
3603
|
if (poll.status === "pending") {
|
|
3603
3604
|
if (isDevMode() && poll.currentTurn != null) {
|
|
3604
|
-
console.log(
|
|
3605
|
+
console.log(
|
|
3606
|
+
`[task] running... turn ${poll.currentTurn}/${poll.maxTurns ?? "?"}`
|
|
3607
|
+
);
|
|
3605
3608
|
}
|
|
3606
3609
|
continue;
|
|
3607
3610
|
}
|
|
@@ -3617,7 +3620,11 @@ async function runTaskPoll(httpConfig, body) {
|
|
|
3617
3620
|
outputRaw: poll.outputRaw ?? "",
|
|
3618
3621
|
parsedSuccessfully: poll.parsedSuccessfully ?? true,
|
|
3619
3622
|
turns: poll.turns ?? 0,
|
|
3620
|
-
usage: poll.usage ?? {
|
|
3623
|
+
usage: poll.usage ?? {
|
|
3624
|
+
inputTokens: 0,
|
|
3625
|
+
outputTokens: 0,
|
|
3626
|
+
totalBillingCost: 0
|
|
3627
|
+
},
|
|
3621
3628
|
toolCalls: poll.toolCalls ?? []
|
|
3622
3629
|
};
|
|
3623
3630
|
logTaskResult(result);
|
|
@@ -3737,6 +3744,397 @@ async function runTaskStream(httpConfig, body, onEvent) {
|
|
|
3737
3744
|
return result;
|
|
3738
3745
|
}
|
|
3739
3746
|
|
|
3747
|
+
// src/task/local.ts
|
|
3748
|
+
var DEFAULT_MAX_TURNS = 20;
|
|
3749
|
+
var MAX_TURNS_LIMIT = 100;
|
|
3750
|
+
var MAX_TOOL_OUTPUT_CHARS = 5e4;
|
|
3751
|
+
var MAX_TURN_ATTEMPTS = 5;
|
|
3752
|
+
var INITIAL_BACKOFF_MS = 1e3;
|
|
3753
|
+
var STALL_TIMEOUT_MS = 3e5;
|
|
3754
|
+
var TURN_UNAVAILABLE_CODE = "task_turn_unavailable";
|
|
3755
|
+
var UNSAFE_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
3756
|
+
function isPlainObject(value) {
|
|
3757
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
3758
|
+
return false;
|
|
3759
|
+
}
|
|
3760
|
+
const proto = Object.getPrototypeOf(value);
|
|
3761
|
+
return proto === Object.prototype || proto === null;
|
|
3762
|
+
}
|
|
3763
|
+
function mergeToolInput(modelInput, defaults) {
|
|
3764
|
+
const merged = { ...modelInput };
|
|
3765
|
+
for (const [key, defaultValue] of Object.entries(defaults)) {
|
|
3766
|
+
if (UNSAFE_KEYS.has(key)) {
|
|
3767
|
+
continue;
|
|
3768
|
+
}
|
|
3769
|
+
const modelValue = merged[key];
|
|
3770
|
+
merged[key] = isPlainObject(defaultValue) && isPlainObject(modelValue) ? mergeToolInput(modelValue, defaultValue) : defaultValue;
|
|
3771
|
+
}
|
|
3772
|
+
return merged;
|
|
3773
|
+
}
|
|
3774
|
+
function truncateToolOutput(output) {
|
|
3775
|
+
const serialized = JSON.stringify(output);
|
|
3776
|
+
return serialized && serialized.length > MAX_TOOL_OUTPUT_CHARS ? serialized.slice(0, MAX_TOOL_OUTPUT_CHARS) + "... [truncated]" : output;
|
|
3777
|
+
}
|
|
3778
|
+
var TurnError = class extends Error {
|
|
3779
|
+
constructor(message, retryable, phase, status, errorCode) {
|
|
3780
|
+
super(message);
|
|
3781
|
+
this.retryable = retryable;
|
|
3782
|
+
this.phase = phase;
|
|
3783
|
+
this.status = status;
|
|
3784
|
+
this.errorCode = errorCode;
|
|
3785
|
+
}
|
|
3786
|
+
};
|
|
3787
|
+
async function attemptTurn(httpConfig, body) {
|
|
3788
|
+
const url = `${httpConfig.baseUrl}/developer/v2/task/turn`;
|
|
3789
|
+
await httpConfig.rateLimiter.acquire();
|
|
3790
|
+
try {
|
|
3791
|
+
let res;
|
|
3792
|
+
try {
|
|
3793
|
+
res = await fetch(url, {
|
|
3794
|
+
method: "POST",
|
|
3795
|
+
headers: {
|
|
3796
|
+
Authorization: `Bearer ${httpConfig.token}`,
|
|
3797
|
+
"Content-Type": "application/json",
|
|
3798
|
+
"User-Agent": "@mindstudio-ai/agent",
|
|
3799
|
+
Accept: "text/event-stream"
|
|
3800
|
+
},
|
|
3801
|
+
body: JSON.stringify(body)
|
|
3802
|
+
});
|
|
3803
|
+
} catch (err) {
|
|
3804
|
+
throw new TurnError(
|
|
3805
|
+
`Network error: ${err instanceof Error ? err.message : "fetch failed"}`,
|
|
3806
|
+
true,
|
|
3807
|
+
"request"
|
|
3808
|
+
);
|
|
3809
|
+
}
|
|
3810
|
+
httpConfig.rateLimiter.updateFromHeaders(res.headers);
|
|
3811
|
+
if (!res.ok) {
|
|
3812
|
+
let message = `${res.status} ${res.statusText}`;
|
|
3813
|
+
let code;
|
|
3814
|
+
try {
|
|
3815
|
+
const errBody = await res.json();
|
|
3816
|
+
const errMsg = (typeof errBody.errorMessage === "string" ? errBody.errorMessage : void 0) ?? (typeof errBody.errorString === "string" ? errBody.errorString : void 0) ?? (typeof errBody.error === "string" ? errBody.error : void 0);
|
|
3817
|
+
if (errMsg) message = errMsg;
|
|
3818
|
+
if (typeof errBody.errorString === "string") code = errBody.errorString;
|
|
3819
|
+
} catch {
|
|
3820
|
+
}
|
|
3821
|
+
const retryable = res.status >= 500 || res.status === 429;
|
|
3822
|
+
throw new TurnError(message, retryable, "request", res.status, code);
|
|
3823
|
+
}
|
|
3824
|
+
const reader = res.body.getReader();
|
|
3825
|
+
const decoder = new TextDecoder();
|
|
3826
|
+
let buffer = "";
|
|
3827
|
+
const events = [];
|
|
3828
|
+
let text = "";
|
|
3829
|
+
const toolCalls = [];
|
|
3830
|
+
let turn = null;
|
|
3831
|
+
const handleLine = (line) => {
|
|
3832
|
+
if (!line.startsWith("data: ")) {
|
|
3833
|
+
return;
|
|
3834
|
+
}
|
|
3835
|
+
let event;
|
|
3836
|
+
try {
|
|
3837
|
+
event = JSON.parse(line.slice(6));
|
|
3838
|
+
} catch {
|
|
3839
|
+
return;
|
|
3840
|
+
}
|
|
3841
|
+
if (event.type === "error") {
|
|
3842
|
+
const status = typeof event.status === "number" ? event.status : 500;
|
|
3843
|
+
const message = typeof event.error === "string" ? event.error : "Model call failed";
|
|
3844
|
+
const retryable = status >= 500 || /overloaded|terminated|network/i.test(message);
|
|
3845
|
+
throw new TurnError(message, retryable, "model", status);
|
|
3846
|
+
}
|
|
3847
|
+
if (event.type === "turn") {
|
|
3848
|
+
turn = {
|
|
3849
|
+
events,
|
|
3850
|
+
text,
|
|
3851
|
+
toolCalls,
|
|
3852
|
+
stopReason: typeof event.stopReason === "string" ? event.stopReason : "end_turn",
|
|
3853
|
+
usage: event.usage ?? {},
|
|
3854
|
+
billingCost: typeof event.billingCost === "number" ? event.billingCost : 0
|
|
3855
|
+
};
|
|
3856
|
+
return;
|
|
3857
|
+
}
|
|
3858
|
+
if (event.type === "text" && typeof event.text === "string") {
|
|
3859
|
+
text += event.text;
|
|
3860
|
+
} else if (event.type === "tool_use") {
|
|
3861
|
+
toolCalls.push({
|
|
3862
|
+
id: event.id,
|
|
3863
|
+
name: event.name,
|
|
3864
|
+
input: event.input ?? {}
|
|
3865
|
+
});
|
|
3866
|
+
}
|
|
3867
|
+
events.push(event);
|
|
3868
|
+
};
|
|
3869
|
+
while (true) {
|
|
3870
|
+
let stallTimer;
|
|
3871
|
+
let readResult;
|
|
3872
|
+
try {
|
|
3873
|
+
readResult = await Promise.race([
|
|
3874
|
+
reader.read(),
|
|
3875
|
+
new Promise((_, reject) => {
|
|
3876
|
+
stallTimer = setTimeout(
|
|
3877
|
+
() => reject(new Error("stream_stall")),
|
|
3878
|
+
STALL_TIMEOUT_MS
|
|
3879
|
+
);
|
|
3880
|
+
})
|
|
3881
|
+
]);
|
|
3882
|
+
clearTimeout(stallTimer);
|
|
3883
|
+
} catch (err) {
|
|
3884
|
+
clearTimeout(stallTimer);
|
|
3885
|
+
try {
|
|
3886
|
+
await reader.cancel();
|
|
3887
|
+
} catch {
|
|
3888
|
+
}
|
|
3889
|
+
if (err instanceof TurnError) {
|
|
3890
|
+
throw err;
|
|
3891
|
+
}
|
|
3892
|
+
const isStall = err instanceof Error && err.message === "stream_stall";
|
|
3893
|
+
throw new TurnError(
|
|
3894
|
+
isStall ? "Turn stalled \u2014 no data received for 5 minutes" : `Network error: stream interrupted \u2014 ${err instanceof Error ? err.message : "unknown"}`,
|
|
3895
|
+
true,
|
|
3896
|
+
"request"
|
|
3897
|
+
);
|
|
3898
|
+
}
|
|
3899
|
+
if (readResult.done) {
|
|
3900
|
+
break;
|
|
3901
|
+
}
|
|
3902
|
+
buffer += decoder.decode(readResult.value, { stream: true });
|
|
3903
|
+
const lines = buffer.split("\n");
|
|
3904
|
+
buffer = lines.pop() ?? "";
|
|
3905
|
+
for (const line of lines) {
|
|
3906
|
+
handleLine(line);
|
|
3907
|
+
}
|
|
3908
|
+
}
|
|
3909
|
+
if (buffer) {
|
|
3910
|
+
handleLine(buffer);
|
|
3911
|
+
}
|
|
3912
|
+
if (!turn) {
|
|
3913
|
+
throw new TurnError(
|
|
3914
|
+
"Network error: stream ended before turn completion",
|
|
3915
|
+
true,
|
|
3916
|
+
"request"
|
|
3917
|
+
);
|
|
3918
|
+
}
|
|
3919
|
+
return turn;
|
|
3920
|
+
} finally {
|
|
3921
|
+
httpConfig.rateLimiter.release();
|
|
3922
|
+
}
|
|
3923
|
+
}
|
|
3924
|
+
async function runTurnWithRetry(httpConfig, body) {
|
|
3925
|
+
for (let attempt = 0; attempt < MAX_TURN_ATTEMPTS; attempt++) {
|
|
3926
|
+
try {
|
|
3927
|
+
return await attemptTurn(httpConfig, body);
|
|
3928
|
+
} catch (err) {
|
|
3929
|
+
if (!(err instanceof TurnError) || !err.retryable || attempt >= MAX_TURN_ATTEMPTS - 1) {
|
|
3930
|
+
throw err;
|
|
3931
|
+
}
|
|
3932
|
+
if (isDevMode()) {
|
|
3933
|
+
console.log(
|
|
3934
|
+
`[task] connection lost, retrying turn (attempt ${attempt + 2} of ${MAX_TURN_ATTEMPTS})`
|
|
3935
|
+
);
|
|
3936
|
+
}
|
|
3937
|
+
await sleep2(INITIAL_BACKOFF_MS * 2 ** attempt);
|
|
3938
|
+
}
|
|
3939
|
+
}
|
|
3940
|
+
throw new TurnError("Turn retries exhausted", false, "request");
|
|
3941
|
+
}
|
|
3942
|
+
async function runTaskLocal(deps, options) {
|
|
3943
|
+
const { httpConfig } = deps;
|
|
3944
|
+
const onEvent = options.onEvent;
|
|
3945
|
+
const structuredOutputExample = typeof options.structuredOutputExample === "string" ? options.structuredOutputExample : JSON.stringify(options.structuredOutputExample);
|
|
3946
|
+
const system = `${options.prompt}
|
|
3947
|
+
|
|
3948
|
+
When you have completed the task, respond with your final output as JSON matching this example:
|
|
3949
|
+
${structuredOutputExample}
|
|
3950
|
+
<!-- cache_breakpoint -->`;
|
|
3951
|
+
const wireTools = mapTools(options.tools);
|
|
3952
|
+
const toolKinds = /* @__PURE__ */ new Map();
|
|
3953
|
+
const toolDefaults = /* @__PURE__ */ new Map();
|
|
3954
|
+
for (const t of wireTools) {
|
|
3955
|
+
if ("appMethod" in t) {
|
|
3956
|
+
toolKinds.set(t.appMethod, "method");
|
|
3957
|
+
if (t.defaults) toolDefaults.set(t.appMethod, t.defaults);
|
|
3958
|
+
} else {
|
|
3959
|
+
toolKinds.set(t.stepType, "step");
|
|
3960
|
+
if (t.defaults) toolDefaults.set(t.stepType, t.defaults);
|
|
3961
|
+
}
|
|
3962
|
+
}
|
|
3963
|
+
const maxTurns = Math.min(
|
|
3964
|
+
Math.max(options.maxTurns || DEFAULT_MAX_TURNS, 1),
|
|
3965
|
+
MAX_TURNS_LIMIT
|
|
3966
|
+
);
|
|
3967
|
+
const messages = [
|
|
3968
|
+
{ role: "user", content: JSON.stringify(options.input) }
|
|
3969
|
+
];
|
|
3970
|
+
let loopCount = 0;
|
|
3971
|
+
const toolCallLog = [];
|
|
3972
|
+
const totalUsage = {
|
|
3973
|
+
inputTokens: 0,
|
|
3974
|
+
outputTokens: 0,
|
|
3975
|
+
cacheCreationTokens: 0,
|
|
3976
|
+
cacheReadTokens: 0,
|
|
3977
|
+
totalBillingCost: 0
|
|
3978
|
+
};
|
|
3979
|
+
const buildResult = (output2, outputRaw, parsedSuccessfully2, turns) => ({
|
|
3980
|
+
output: output2,
|
|
3981
|
+
outputRaw,
|
|
3982
|
+
parsedSuccessfully: parsedSuccessfully2,
|
|
3983
|
+
turns,
|
|
3984
|
+
usage: totalUsage,
|
|
3985
|
+
toolCalls: toolCallLog
|
|
3986
|
+
});
|
|
3987
|
+
const accumulate = (turn) => {
|
|
3988
|
+
totalUsage.inputTokens += turn.usage.inputTokens ?? 0;
|
|
3989
|
+
totalUsage.outputTokens += turn.usage.outputTokens ?? 0;
|
|
3990
|
+
totalUsage.cacheCreationTokens += turn.usage.cacheCreationTokens ?? 0;
|
|
3991
|
+
totalUsage.cacheReadTokens += turn.usage.cacheReadTokens ?? 0;
|
|
3992
|
+
totalUsage.totalBillingCost += turn.billingCost;
|
|
3993
|
+
for (const event of turn.events) {
|
|
3994
|
+
onEvent?.(event);
|
|
3995
|
+
}
|
|
3996
|
+
};
|
|
3997
|
+
const finish = (result) => {
|
|
3998
|
+
onEvent?.({ type: "done", ...result });
|
|
3999
|
+
logTaskResult(result);
|
|
4000
|
+
return result;
|
|
4001
|
+
};
|
|
4002
|
+
const turnFailure = (err) => {
|
|
4003
|
+
if (err instanceof TurnError && err.phase === "model") {
|
|
4004
|
+
if (isDevMode()) {
|
|
4005
|
+
console.error(`[task] Model call failed: ${err.message}`);
|
|
4006
|
+
}
|
|
4007
|
+
return finish(buildResult(null, "", false, loopCount));
|
|
4008
|
+
}
|
|
4009
|
+
if (err instanceof TurnError) {
|
|
4010
|
+
throw new MindStudioError(
|
|
4011
|
+
`[task] ${err.message}`,
|
|
4012
|
+
err.errorCode ?? "task_turn_error",
|
|
4013
|
+
err.status ?? 500
|
|
4014
|
+
);
|
|
4015
|
+
}
|
|
4016
|
+
throw err;
|
|
4017
|
+
};
|
|
4018
|
+
while (loopCount < maxTurns) {
|
|
4019
|
+
loopCount++;
|
|
4020
|
+
let turn;
|
|
4021
|
+
try {
|
|
4022
|
+
turn = await runTurnWithRetry(httpConfig, {
|
|
4023
|
+
model: options.model,
|
|
4024
|
+
system,
|
|
4025
|
+
messages,
|
|
4026
|
+
tools: wireTools
|
|
4027
|
+
});
|
|
4028
|
+
} catch (err) {
|
|
4029
|
+
if (loopCount === 1 && err instanceof TurnError && err.status === 404 && err.errorCode === "not_found") {
|
|
4030
|
+
throw new MindStudioError(
|
|
4031
|
+
"Task turn endpoint unavailable.",
|
|
4032
|
+
TURN_UNAVAILABLE_CODE,
|
|
4033
|
+
404
|
|
4034
|
+
);
|
|
4035
|
+
}
|
|
4036
|
+
return turnFailure(err);
|
|
4037
|
+
}
|
|
4038
|
+
accumulate(turn);
|
|
4039
|
+
if (turn.stopReason === "tool_use" && turn.toolCalls.length > 0) {
|
|
4040
|
+
messages.push({
|
|
4041
|
+
role: "assistant",
|
|
4042
|
+
content: turn.text,
|
|
4043
|
+
toolCalls: turn.toolCalls
|
|
4044
|
+
});
|
|
4045
|
+
const results = await Promise.all(
|
|
4046
|
+
turn.toolCalls.map(async (toolCall) => {
|
|
4047
|
+
onEvent?.({
|
|
4048
|
+
type: "tool_call_start",
|
|
4049
|
+
id: toolCall.id,
|
|
4050
|
+
name: toolCall.name
|
|
4051
|
+
});
|
|
4052
|
+
const startTime = Date.now();
|
|
4053
|
+
const defaults = toolDefaults.get(toolCall.name) || {};
|
|
4054
|
+
const mergedInput = mergeToolInput(toolCall.input, defaults);
|
|
4055
|
+
const execute = toolKinds.get(toolCall.name) === "method" ? deps.executeMethodTool : deps.executeStepTool;
|
|
4056
|
+
const result = await execute(toolCall.name, mergedInput);
|
|
4057
|
+
toolCallLog.push({
|
|
4058
|
+
name: toolCall.name,
|
|
4059
|
+
success: !result.isError,
|
|
4060
|
+
durationMs: Date.now() - startTime
|
|
4061
|
+
});
|
|
4062
|
+
return { toolCall, ...result };
|
|
4063
|
+
})
|
|
4064
|
+
);
|
|
4065
|
+
for (const { toolCall, output: output2, billingCost, isError } of results) {
|
|
4066
|
+
if (billingCost) {
|
|
4067
|
+
totalUsage.totalBillingCost += billingCost;
|
|
4068
|
+
}
|
|
4069
|
+
const truncated = truncateToolOutput(output2);
|
|
4070
|
+
messages.push({
|
|
4071
|
+
role: "user",
|
|
4072
|
+
content: JSON.stringify(truncated),
|
|
4073
|
+
toolCallId: toolCall.id,
|
|
4074
|
+
...isError && { isToolError: true }
|
|
4075
|
+
});
|
|
4076
|
+
onEvent?.({
|
|
4077
|
+
type: "tool_call_result",
|
|
4078
|
+
id: toolCall.id,
|
|
4079
|
+
output: truncated
|
|
4080
|
+
});
|
|
4081
|
+
}
|
|
4082
|
+
if (isDevMode()) {
|
|
4083
|
+
console.log(`[task] running... turn ${loopCount}/${maxTurns}`);
|
|
4084
|
+
}
|
|
4085
|
+
continue;
|
|
4086
|
+
}
|
|
4087
|
+
messages.push({ role: "assistant", content: turn.text });
|
|
4088
|
+
try {
|
|
4089
|
+
const output2 = JSON.parse(turn.text);
|
|
4090
|
+
return finish(buildResult(output2, turn.text, true, loopCount));
|
|
4091
|
+
} catch {
|
|
4092
|
+
if (loopCount < maxTurns) {
|
|
4093
|
+
messages.push({
|
|
4094
|
+
role: "user",
|
|
4095
|
+
content: "Your response was not valid JSON. Please respond with ONLY the JSON output, no other text."
|
|
4096
|
+
});
|
|
4097
|
+
continue;
|
|
4098
|
+
}
|
|
4099
|
+
}
|
|
4100
|
+
return finish(buildResult(turn.text, turn.text, false, loopCount));
|
|
4101
|
+
}
|
|
4102
|
+
messages.push({
|
|
4103
|
+
role: "user",
|
|
4104
|
+
content: "You have reached the maximum number of turns. Please provide your final output now as JSON."
|
|
4105
|
+
});
|
|
4106
|
+
let finalText = "";
|
|
4107
|
+
try {
|
|
4108
|
+
const turn = await runTurnWithRetry(httpConfig, {
|
|
4109
|
+
model: options.model,
|
|
4110
|
+
system,
|
|
4111
|
+
messages,
|
|
4112
|
+
tools: []
|
|
4113
|
+
});
|
|
4114
|
+
accumulate(turn);
|
|
4115
|
+
finalText = turn.text;
|
|
4116
|
+
} catch (err) {
|
|
4117
|
+
if (err instanceof TurnError && err.phase === "model") {
|
|
4118
|
+
if (isDevMode()) {
|
|
4119
|
+
console.error(`[task] Final model call failed: ${err.message}`);
|
|
4120
|
+
}
|
|
4121
|
+
} else {
|
|
4122
|
+
return turnFailure(err);
|
|
4123
|
+
}
|
|
4124
|
+
}
|
|
4125
|
+
let parsedSuccessfully = true;
|
|
4126
|
+
let output;
|
|
4127
|
+
try {
|
|
4128
|
+
output = JSON.parse(finalText);
|
|
4129
|
+
} catch {
|
|
4130
|
+
output = finalText;
|
|
4131
|
+
parsedSuccessfully = false;
|
|
4132
|
+
}
|
|
4133
|
+
return finish(
|
|
4134
|
+
buildResult(output, finalText, parsedSuccessfully, loopCount + 1)
|
|
4135
|
+
);
|
|
4136
|
+
}
|
|
4137
|
+
|
|
3740
4138
|
// src/generated/steps.ts
|
|
3741
4139
|
function applyStepMethods(AgentClass) {
|
|
3742
4140
|
const proto = AgentClass.prototype;
|
|
@@ -4382,8 +4780,8 @@ var MindStudioAgent = class {
|
|
|
4382
4780
|
...options?.appId != null && { appId: options.appId },
|
|
4383
4781
|
...threadId != null && { threadId },
|
|
4384
4782
|
...this._currentStreamId != null && { streamId: this._currentStreamId },
|
|
4385
|
-
...this._requestSource != null && {
|
|
4386
|
-
requestSource: this._requestSource
|
|
4783
|
+
...(options?.requestSource ?? this._requestSource) != null && {
|
|
4784
|
+
requestSource: options?.requestSource ?? this._requestSource
|
|
4387
4785
|
},
|
|
4388
4786
|
...assetStoreBody(options?.store)
|
|
4389
4787
|
});
|
|
@@ -4469,8 +4867,8 @@ var MindStudioAgent = class {
|
|
|
4469
4867
|
...options.appId != null && { appId: options.appId },
|
|
4470
4868
|
...threadId != null && { threadId },
|
|
4471
4869
|
...this._currentStreamId != null && { streamId: this._currentStreamId },
|
|
4472
|
-
...this._requestSource != null && {
|
|
4473
|
-
requestSource: this._requestSource
|
|
4870
|
+
...(options.requestSource ?? this._requestSource) != null && {
|
|
4871
|
+
requestSource: options.requestSource ?? this._requestSource
|
|
4474
4872
|
},
|
|
4475
4873
|
...assetStoreBody(options.store)
|
|
4476
4874
|
};
|
|
@@ -4772,11 +5170,135 @@ var MindStudioAgent = class {
|
|
|
4772
5170
|
* ```
|
|
4773
5171
|
*/
|
|
4774
5172
|
async runTask(options) {
|
|
4775
|
-
const
|
|
4776
|
-
|
|
4777
|
-
|
|
5173
|
+
const taskPromise = this._runTaskInner(options);
|
|
5174
|
+
const hook = globalThis.__msWaitUntil;
|
|
5175
|
+
if (typeof hook === "function") {
|
|
5176
|
+
try {
|
|
5177
|
+
hook(taskPromise.catch(() => {
|
|
5178
|
+
}));
|
|
5179
|
+
} catch {
|
|
5180
|
+
}
|
|
5181
|
+
}
|
|
5182
|
+
return taskPromise;
|
|
5183
|
+
}
|
|
5184
|
+
/**
|
|
5185
|
+
* Register background work with the platform so the sandbox stays alive
|
|
5186
|
+
* until it settles (bounded at ~30 minutes) instead of being reaped as
|
|
5187
|
+
* idle, and so an interruption is recorded in the request log if the
|
|
5188
|
+
* sandbox is torn down anyway.
|
|
5189
|
+
*
|
|
5190
|
+
* Use it for the fire-and-forget pattern — kick off slow work, return
|
|
5191
|
+
* early, write results back when it finishes:
|
|
5192
|
+
*
|
|
5193
|
+
* ```ts
|
|
5194
|
+
* mindstudio.waitUntil(
|
|
5195
|
+
* enrichRecord(id)
|
|
5196
|
+
* .then((data) => Records.update(id, { ...data, status: 'ready' }))
|
|
5197
|
+
* .catch(() => Records.update(id, { status: 'failed' })),
|
|
5198
|
+
* );
|
|
5199
|
+
* return { status: 'processing' };
|
|
5200
|
+
* ```
|
|
5201
|
+
*
|
|
5202
|
+
* Failures of the registered promise are caught and logged to the request
|
|
5203
|
+
* log — they can never crash the sandbox. Outside a managed sandbox this
|
|
5204
|
+
* degrades to just that error-catching. If you need the result, keep your
|
|
5205
|
+
* own reference to the promise and `await` it — `waitUntil` returns void.
|
|
5206
|
+
*/
|
|
5207
|
+
waitUntil(promise) {
|
|
5208
|
+
const caught = Promise.resolve(promise).catch((err) => {
|
|
5209
|
+
console.error(
|
|
5210
|
+
"[waitUntil] Background work failed:",
|
|
5211
|
+
err instanceof Error ? err.stack ?? err.message : String(err)
|
|
5212
|
+
);
|
|
5213
|
+
});
|
|
5214
|
+
const hook = globalThis.__msWaitUntil;
|
|
5215
|
+
if (typeof hook === "function") {
|
|
5216
|
+
try {
|
|
5217
|
+
hook(caught);
|
|
5218
|
+
} catch {
|
|
5219
|
+
}
|
|
5220
|
+
}
|
|
5221
|
+
}
|
|
5222
|
+
async _runTaskInner(options) {
|
|
5223
|
+
const httpConfig = this._currentHttpConfig;
|
|
5224
|
+
try {
|
|
5225
|
+
return await runTaskLocal(
|
|
5226
|
+
{
|
|
5227
|
+
httpConfig,
|
|
5228
|
+
executeStepTool: async (stepType, input) => {
|
|
5229
|
+
try {
|
|
5230
|
+
const result = await this.executeStep(stepType, input, {
|
|
5231
|
+
requestSource: "v2-task"
|
|
5232
|
+
});
|
|
5233
|
+
const output = {};
|
|
5234
|
+
let billingCost = 0;
|
|
5235
|
+
for (const [key, value] of Object.entries(
|
|
5236
|
+
result
|
|
5237
|
+
)) {
|
|
5238
|
+
if (key === "$billingCost" && typeof value === "number") {
|
|
5239
|
+
billingCost = value;
|
|
5240
|
+
}
|
|
5241
|
+
if (!key.startsWith("$")) {
|
|
5242
|
+
output[key] = value;
|
|
5243
|
+
}
|
|
5244
|
+
}
|
|
5245
|
+
return { output, billingCost, isError: false };
|
|
5246
|
+
} catch (err) {
|
|
5247
|
+
return {
|
|
5248
|
+
output: {
|
|
5249
|
+
error: err instanceof Error ? err.message : "Step execution failed"
|
|
5250
|
+
},
|
|
5251
|
+
billingCost: 0,
|
|
5252
|
+
isError: true
|
|
5253
|
+
};
|
|
5254
|
+
}
|
|
5255
|
+
},
|
|
5256
|
+
executeMethodTool: async (methodId, input) => {
|
|
5257
|
+
try {
|
|
5258
|
+
const { data } = await request(
|
|
5259
|
+
{ ...httpConfig, maxRetries: 0 },
|
|
5260
|
+
"POST",
|
|
5261
|
+
"/task/invoke-method",
|
|
5262
|
+
{
|
|
5263
|
+
methodId,
|
|
5264
|
+
input
|
|
5265
|
+
}
|
|
5266
|
+
);
|
|
5267
|
+
if (data.error) {
|
|
5268
|
+
return {
|
|
5269
|
+
output: { error: data.error },
|
|
5270
|
+
billingCost: 0,
|
|
5271
|
+
isError: true
|
|
5272
|
+
};
|
|
5273
|
+
}
|
|
5274
|
+
return {
|
|
5275
|
+
output: data.output ?? null,
|
|
5276
|
+
billingCost: 0,
|
|
5277
|
+
isError: false
|
|
5278
|
+
};
|
|
5279
|
+
} catch (err) {
|
|
5280
|
+
return {
|
|
5281
|
+
output: {
|
|
5282
|
+
error: err instanceof Error ? err.message : "Method execution failed"
|
|
5283
|
+
},
|
|
5284
|
+
billingCost: 0,
|
|
5285
|
+
isError: true
|
|
5286
|
+
};
|
|
5287
|
+
}
|
|
5288
|
+
}
|
|
5289
|
+
},
|
|
5290
|
+
options
|
|
5291
|
+
);
|
|
5292
|
+
} catch (err) {
|
|
5293
|
+
if (err instanceof MindStudioError && err.code === TURN_UNAVAILABLE_CODE) {
|
|
5294
|
+
const body = buildTaskRequestBody(options);
|
|
5295
|
+
if (options.onEvent) {
|
|
5296
|
+
return runTaskStream(httpConfig, body, options.onEvent);
|
|
5297
|
+
}
|
|
5298
|
+
return runTaskPoll(httpConfig, body);
|
|
5299
|
+
}
|
|
5300
|
+
throw err;
|
|
4778
5301
|
}
|
|
4779
|
-
return runTaskPoll(this._currentHttpConfig, body);
|
|
4780
5302
|
}
|
|
4781
5303
|
/**
|
|
4782
5304
|
* Get the authenticated user's identity and organization info.
|
|
@@ -5930,57 +6452,42 @@ var blockTypeAliases = {
|
|
|
5930
6452
|
// src/index.ts
|
|
5931
6453
|
var MindStudioAgent2 = MindStudioAgent;
|
|
5932
6454
|
var _default;
|
|
5933
|
-
var mindstudio = new Proxy(
|
|
5934
|
-
{
|
|
5935
|
-
|
|
5936
|
-
get(
|
|
5937
|
-
|
|
5938
|
-
const value = Reflect.get(_default, prop, _default);
|
|
5939
|
-
return typeof value === "function" ? value.bind(_default) : value;
|
|
5940
|
-
}
|
|
6455
|
+
var mindstudio = new Proxy({}, {
|
|
6456
|
+
get(_, prop, receiver) {
|
|
6457
|
+
_default ??= new MindStudioAgent2();
|
|
6458
|
+
const value = Reflect.get(_default, prop, _default);
|
|
6459
|
+
return typeof value === "function" ? value.bind(_default) : value;
|
|
5941
6460
|
}
|
|
5942
|
-
);
|
|
6461
|
+
});
|
|
5943
6462
|
var index_default = mindstudio;
|
|
5944
|
-
var auth = new Proxy(
|
|
5945
|
-
{
|
|
5946
|
-
|
|
5947
|
-
get(
|
|
5948
|
-
|
|
5949
|
-
const value = Reflect.get(target, prop, target);
|
|
5950
|
-
return typeof value === "function" ? value.bind(target) : value;
|
|
5951
|
-
}
|
|
6463
|
+
var auth = new Proxy({}, {
|
|
6464
|
+
get(_, prop) {
|
|
6465
|
+
const target = mindstudio.auth;
|
|
6466
|
+
const value = Reflect.get(target, prop, target);
|
|
6467
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
5952
6468
|
}
|
|
5953
|
-
);
|
|
5954
|
-
var db = new Proxy(
|
|
5955
|
-
{
|
|
5956
|
-
|
|
5957
|
-
get(
|
|
5958
|
-
|
|
5959
|
-
const value = Reflect.get(target, prop, target);
|
|
5960
|
-
return typeof value === "function" ? value.bind(target) : value;
|
|
5961
|
-
}
|
|
6469
|
+
});
|
|
6470
|
+
var db = new Proxy({}, {
|
|
6471
|
+
get(_, prop) {
|
|
6472
|
+
const target = mindstudio.db;
|
|
6473
|
+
const value = Reflect.get(target, prop, target);
|
|
6474
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
5962
6475
|
}
|
|
5963
|
-
);
|
|
5964
|
-
var files = new Proxy(
|
|
5965
|
-
{
|
|
5966
|
-
|
|
5967
|
-
get(
|
|
5968
|
-
|
|
5969
|
-
const value = Reflect.get(target, prop, target);
|
|
5970
|
-
return typeof value === "function" ? value.bind(target) : value;
|
|
5971
|
-
}
|
|
6476
|
+
});
|
|
6477
|
+
var files = new Proxy({}, {
|
|
6478
|
+
get(_, prop) {
|
|
6479
|
+
const target = mindstudio.files;
|
|
6480
|
+
const value = Reflect.get(target, prop, target);
|
|
6481
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
5972
6482
|
}
|
|
5973
|
-
);
|
|
5974
|
-
var dataSources = new Proxy(
|
|
5975
|
-
{
|
|
5976
|
-
|
|
5977
|
-
get(
|
|
5978
|
-
|
|
5979
|
-
const value = Reflect.get(target, prop, target);
|
|
5980
|
-
return typeof value === "function" ? value.bind(target) : value;
|
|
5981
|
-
}
|
|
6483
|
+
});
|
|
6484
|
+
var dataSources = new Proxy({}, {
|
|
6485
|
+
get(_, prop) {
|
|
6486
|
+
const target = mindstudio.dataSources;
|
|
6487
|
+
const value = Reflect.get(target, prop, target);
|
|
6488
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
5982
6489
|
}
|
|
5983
|
-
);
|
|
6490
|
+
});
|
|
5984
6491
|
var voice = new Proxy({}, {
|
|
5985
6492
|
get(_, prop) {
|
|
5986
6493
|
const target = mindstudio.voice;
|
|
@@ -5998,6 +6505,7 @@ var session = new Proxy(
|
|
|
5998
6505
|
}
|
|
5999
6506
|
);
|
|
6000
6507
|
var stream = (data) => mindstudio.stream(data);
|
|
6508
|
+
var waitUntil = (promise) => mindstudio.waitUntil(promise);
|
|
6001
6509
|
var resolveUser = (userId) => mindstudio.resolveUser(userId);
|
|
6002
6510
|
var reportIssue = (input) => mindstudio.reportIssue(input);
|
|
6003
6511
|
var prerender = {
|
|
@@ -6024,6 +6532,7 @@ export {
|
|
|
6024
6532
|
session,
|
|
6025
6533
|
stepMetadata,
|
|
6026
6534
|
stream,
|
|
6027
|
-
voice
|
|
6535
|
+
voice,
|
|
6536
|
+
waitUntil
|
|
6028
6537
|
};
|
|
6029
6538
|
//# sourceMappingURL=index.js.map
|