@mindstudio-ai/agent 0.1.137 → 0.1.139
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 +147 -17
- package/dist/index.d.ts +368 -25
- package/dist/index.js +267 -9
- package/dist/index.js.map +1 -1
- package/dist/postinstall.js +147 -17
- package/llms.txt +18 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3131,6 +3131,8 @@ function createFiles(call) {
|
|
|
3131
3131
|
|
|
3132
3132
|
// src/datasources/source.ts
|
|
3133
3133
|
import { createHash as createHash2 } from "crypto";
|
|
3134
|
+
var DICTIONARY_PAGE_ENTRIES = 1e4;
|
|
3135
|
+
var DICTIONARY_PAGE_BYTES = 4e6;
|
|
3134
3136
|
var REMOVE_WHERE_MAX_PAGES = 100;
|
|
3135
3137
|
var DataSource = class {
|
|
3136
3138
|
constructor(_slug, _call) {
|
|
@@ -3251,6 +3253,120 @@ var DataSource = class {
|
|
|
3251
3253
|
});
|
|
3252
3254
|
return { chunks: chunks ?? 0, latencyMs: latencyMs ?? 0 };
|
|
3253
3255
|
}
|
|
3256
|
+
/**
|
|
3257
|
+
* Which entities the passages matching a filter are about, most first.
|
|
3258
|
+
*
|
|
3259
|
+
* Filter on one entity (`{ entities: ['P-101A'] }`) and the answer is what
|
|
3260
|
+
* appears beside it: a co-mention graph for free. Filter on a date range and
|
|
3261
|
+
* it is who or what was written about then. No filter covers the corpus.
|
|
3262
|
+
* `chunks` is how many matching passages carry each id, not documents: a
|
|
3263
|
+
* long document's passages each count. Approximate counts, ordered most
|
|
3264
|
+
* first; `limit` defaults to 20, at most 100.
|
|
3265
|
+
*
|
|
3266
|
+
* Shares the search rate limit (300/minute per app), and shows the same
|
|
3267
|
+
* `index_warming` / `index_building` as search while a corpus loads.
|
|
3268
|
+
*/
|
|
3269
|
+
async entities(options) {
|
|
3270
|
+
const { entities, latencyMs } = await this._call("entities", {
|
|
3271
|
+
slug: this._slug,
|
|
3272
|
+
...options?.filter !== void 0 ? { filter: options.filter } : {},
|
|
3273
|
+
...options?.limit !== void 0 ? { limit: options.limit } : {}
|
|
3274
|
+
});
|
|
3275
|
+
return { entities: entities ?? [], latencyMs: latencyMs ?? 0 };
|
|
3276
|
+
}
|
|
3277
|
+
/**
|
|
3278
|
+
* Push this source's dictionary: every entity id you have and the names it
|
|
3279
|
+
* goes by, replacing the dictionary it had. From then on every passage is
|
|
3280
|
+
* tagged with the ids whose names its text mentions, beside the ones its
|
|
3281
|
+
* document asserts, so `filter.entities` and {@link entities} find a tag
|
|
3282
|
+
* wherever it's written. Passages indexed before are re-tagged in the
|
|
3283
|
+
* background (a relink; see {@link dictionary}), and nothing is
|
|
3284
|
+
* re-embedded.
|
|
3285
|
+
*
|
|
3286
|
+
* Push it whole after each load of the tables it comes from: an unchanged
|
|
3287
|
+
* dictionary commits nothing (`unchanged: true`). Takes an array or any
|
|
3288
|
+
* (async) iterable, and sends it in pages, so a register of a quarter of a
|
|
3289
|
+
* million entries is fine. A repeated id merges its names.
|
|
3290
|
+
*/
|
|
3291
|
+
async pushDictionary(entries, options) {
|
|
3292
|
+
const { stageId, pageMaxEntries } = await this._call("dictionary/stage", {
|
|
3293
|
+
slug: this._slug,
|
|
3294
|
+
...options?.linkerVersion !== void 0 ? { linkerVersion: options.linkerVersion } : {}
|
|
3295
|
+
});
|
|
3296
|
+
const perPage = Math.min(
|
|
3297
|
+
DICTIONARY_PAGE_ENTRIES,
|
|
3298
|
+
Number(pageMaxEntries) || DICTIONARY_PAGE_ENTRIES
|
|
3299
|
+
);
|
|
3300
|
+
let pages = 0;
|
|
3301
|
+
let page = [];
|
|
3302
|
+
let bytes = 0;
|
|
3303
|
+
const send = async () => {
|
|
3304
|
+
if (page.length === 0) {
|
|
3305
|
+
return;
|
|
3306
|
+
}
|
|
3307
|
+
await this._call("dictionary/page", {
|
|
3308
|
+
slug: this._slug,
|
|
3309
|
+
stageId,
|
|
3310
|
+
page: pages,
|
|
3311
|
+
entries: page
|
|
3312
|
+
});
|
|
3313
|
+
pages += 1;
|
|
3314
|
+
page = [];
|
|
3315
|
+
bytes = 0;
|
|
3316
|
+
};
|
|
3317
|
+
for await (const entry of entries) {
|
|
3318
|
+
const size = JSON.stringify(entry).length;
|
|
3319
|
+
if (page.length >= perPage || bytes + size > DICTIONARY_PAGE_BYTES) {
|
|
3320
|
+
await send();
|
|
3321
|
+
}
|
|
3322
|
+
page.push(entry);
|
|
3323
|
+
bytes += size;
|
|
3324
|
+
}
|
|
3325
|
+
await send();
|
|
3326
|
+
if (pages === 0) {
|
|
3327
|
+
throw new Error(
|
|
3328
|
+
"pushDictionary needs at least one entry. To clear what a dictionary tags, push its entries with the names you mean."
|
|
3329
|
+
);
|
|
3330
|
+
}
|
|
3331
|
+
return this._call("dictionary/commit", {
|
|
3332
|
+
slug: this._slug,
|
|
3333
|
+
stageId,
|
|
3334
|
+
pages
|
|
3335
|
+
});
|
|
3336
|
+
}
|
|
3337
|
+
/**
|
|
3338
|
+
* The source's current dictionary, or null when none was pushed, and the
|
|
3339
|
+
* relink re-tagging its passages while one runs.
|
|
3340
|
+
*/
|
|
3341
|
+
async dictionary() {
|
|
3342
|
+
const { dictionary, relink } = await this._call("dictionary", {
|
|
3343
|
+
slug: this._slug
|
|
3344
|
+
});
|
|
3345
|
+
return {
|
|
3346
|
+
dictionary: dictionary ?? null,
|
|
3347
|
+
relink: relink ? {
|
|
3348
|
+
version: relink.version,
|
|
3349
|
+
lap: relink.lap,
|
|
3350
|
+
walked: relink.walked,
|
|
3351
|
+
total: relink.total,
|
|
3352
|
+
waiting: relink.waiting ?? null,
|
|
3353
|
+
error: relink.error ?? null
|
|
3354
|
+
} : null
|
|
3355
|
+
};
|
|
3356
|
+
}
|
|
3357
|
+
/**
|
|
3358
|
+
* What the current dictionary finds in a piece of text: each mention, in
|
|
3359
|
+
* order, with the ids it tags. How to check a dictionary before relying on
|
|
3360
|
+
* it. `version` is null when the source has none. Shares the search rate
|
|
3361
|
+
* limit.
|
|
3362
|
+
*/
|
|
3363
|
+
async link(text) {
|
|
3364
|
+
const { version, mentions } = await this._call("link", {
|
|
3365
|
+
slug: this._slug,
|
|
3366
|
+
text
|
|
3367
|
+
});
|
|
3368
|
+
return { version: version ?? null, mentions: mentions ?? [] };
|
|
3369
|
+
}
|
|
3254
3370
|
/**
|
|
3255
3371
|
* Every chunk of one document, exactly as it was indexed.
|
|
3256
3372
|
*
|
|
@@ -3302,6 +3418,7 @@ var DataSource = class {
|
|
|
3302
3418
|
filename: options.filename,
|
|
3303
3419
|
...options.contentType ? { contentType: options.contentType } : {},
|
|
3304
3420
|
...options.metadata !== void 0 ? { metadata: options.metadata } : {},
|
|
3421
|
+
...options.entities !== void 0 ? { entities: options.entities } : {},
|
|
3305
3422
|
body: bytes.toString("base64")
|
|
3306
3423
|
});
|
|
3307
3424
|
}
|
|
@@ -4989,7 +5106,7 @@ function logTaskResult(result) {
|
|
|
4989
5106
|
}
|
|
4990
5107
|
const toolSummary = result.toolCalls.map((tc) => `${tc.name} (${tc.durationMs}ms) ${tc.success ? "\u2713" : "\u2717"}`).join(", ");
|
|
4991
5108
|
console.log(
|
|
4992
|
-
`[task] ${result.turns} turn${result.turns === 1 ? "" : "s"}` + (toolSummary ? `: ${toolSummary}` : "") + ` | ${result.parsedSuccessfully ? "output OK" : "\u26A0 output not valid JSON"} | cost: ${result.usage.totalBillingCost}`
|
|
5109
|
+
`[task] ${result.turns} turn${result.turns === 1 ? "" : "s"}` + (toolSummary ? `: ${toolSummary}` : "") + ` | ${result.parsedSuccessfully ? "output OK" : "\u26A0 output not valid JSON"} | cost: ${result.usage.totalBillingCost} | trace: ${result.traceId}`
|
|
4993
5110
|
);
|
|
4994
5111
|
}
|
|
4995
5112
|
async function runTaskPoll(httpConfig, body) {
|
|
@@ -5496,7 +5613,8 @@ ${structuredOutputExample}
|
|
|
5496
5613
|
errors,
|
|
5497
5614
|
turns: loopCount,
|
|
5498
5615
|
usage: totalUsage,
|
|
5499
|
-
toolCalls: toolCallLog
|
|
5616
|
+
toolCalls: toolCallLog,
|
|
5617
|
+
traceId
|
|
5500
5618
|
}
|
|
5501
5619
|
);
|
|
5502
5620
|
};
|
|
@@ -5510,7 +5628,12 @@ ${structuredOutputExample}
|
|
|
5510
5628
|
`[task] ${err.message}`,
|
|
5511
5629
|
"task_execution_error",
|
|
5512
5630
|
500,
|
|
5513
|
-
{
|
|
5631
|
+
{
|
|
5632
|
+
turns: loopCount,
|
|
5633
|
+
usage: totalUsage,
|
|
5634
|
+
toolCalls: toolCallLog,
|
|
5635
|
+
traceId
|
|
5636
|
+
}
|
|
5514
5637
|
);
|
|
5515
5638
|
}
|
|
5516
5639
|
return finish(buildResult(null, "", false, loopCount));
|
|
@@ -5519,7 +5642,8 @@ ${structuredOutputExample}
|
|
|
5519
5642
|
throw new MindStudioError(
|
|
5520
5643
|
`[task] ${err.message}`,
|
|
5521
5644
|
err.errorCode ?? "task_turn_error",
|
|
5522
|
-
err.status ?? 500
|
|
5645
|
+
err.status ?? 500,
|
|
5646
|
+
{ traceId }
|
|
5523
5647
|
);
|
|
5524
5648
|
}
|
|
5525
5649
|
throw err;
|
|
@@ -5583,9 +5707,13 @@ ${structuredOutputExample}
|
|
|
5583
5707
|
isError: true
|
|
5584
5708
|
};
|
|
5585
5709
|
}
|
|
5710
|
+
} else if (kind === "method") {
|
|
5711
|
+
result = await deps.executeMethodTool(toolCall.name, mergedInput, {
|
|
5712
|
+
traceId,
|
|
5713
|
+
toolCallId: toolCall.id
|
|
5714
|
+
});
|
|
5586
5715
|
} else {
|
|
5587
|
-
|
|
5588
|
-
result = await execute(toolCall.name, mergedInput);
|
|
5716
|
+
result = await deps.executeStepTool(toolCall.name, mergedInput);
|
|
5589
5717
|
}
|
|
5590
5718
|
toolCallLog.push({
|
|
5591
5719
|
name: toolCall.name,
|
|
@@ -6795,7 +6923,7 @@ var MindStudioAgent = class {
|
|
|
6795
6923
|
};
|
|
6796
6924
|
}
|
|
6797
6925
|
},
|
|
6798
|
-
executeMethodTool: async (methodId, input) => {
|
|
6926
|
+
executeMethodTool: async (methodId, input, call) => {
|
|
6799
6927
|
try {
|
|
6800
6928
|
const { data } = await request(
|
|
6801
6929
|
{ ...httpConfig, maxRetries: 0 },
|
|
@@ -6803,7 +6931,9 @@ var MindStudioAgent = class {
|
|
|
6803
6931
|
"/task/invoke-method",
|
|
6804
6932
|
{
|
|
6805
6933
|
methodId,
|
|
6806
|
-
input
|
|
6934
|
+
input,
|
|
6935
|
+
traceId: call.traceId,
|
|
6936
|
+
toolCallId: call.toolCallId
|
|
6807
6937
|
}
|
|
6808
6938
|
);
|
|
6809
6939
|
if (data.error) {
|
|
@@ -8239,7 +8369,11 @@ function documents(list) {
|
|
|
8239
8369
|
return { kind: "documents", documents: Array.isArray(list) ? list : [list] };
|
|
8240
8370
|
}
|
|
8241
8371
|
function passthrough(options) {
|
|
8242
|
-
return
|
|
8372
|
+
return {
|
|
8373
|
+
kind: "passthrough",
|
|
8374
|
+
...options?.metadata !== void 0 ? { metadata: options.metadata } : {},
|
|
8375
|
+
...options?.entities !== void 0 ? { entities: options.entities } : {}
|
|
8376
|
+
};
|
|
8243
8377
|
}
|
|
8244
8378
|
function skip(reason) {
|
|
8245
8379
|
return { kind: "skip", reason };
|
|
@@ -8283,6 +8417,7 @@ function objectFor(input) {
|
|
|
8283
8417
|
etag: input.etag,
|
|
8284
8418
|
lastModified: input.lastModified,
|
|
8285
8419
|
metadata: input.metadata,
|
|
8420
|
+
entities: input.entities ?? null,
|
|
8286
8421
|
bytes,
|
|
8287
8422
|
text: async () => new TextDecoder("utf-8").decode(await bytes()),
|
|
8288
8423
|
json: async () => JSON.parse(new TextDecoder("utf-8").decode(await bytes()))
|
|
@@ -8372,6 +8507,128 @@ function defineMapper(source, config) {
|
|
|
8372
8507
|
});
|
|
8373
8508
|
}
|
|
8374
8509
|
|
|
8510
|
+
// src/reader/index.ts
|
|
8511
|
+
var DEFAULT_TIMEOUT_MS2 = 6e4;
|
|
8512
|
+
var DEFAULT_CONCURRENCY3 = 4;
|
|
8513
|
+
function errorInfo3(e) {
|
|
8514
|
+
if (e instanceof Error) {
|
|
8515
|
+
return { message: e.message, stack: e.stack };
|
|
8516
|
+
}
|
|
8517
|
+
return { message: String(e) };
|
|
8518
|
+
}
|
|
8519
|
+
function refOf(delivery) {
|
|
8520
|
+
switch (delivery.kind) {
|
|
8521
|
+
case "read":
|
|
8522
|
+
return delivery.document.id;
|
|
8523
|
+
case "removed":
|
|
8524
|
+
return delivery.documentId;
|
|
8525
|
+
case "cleared":
|
|
8526
|
+
return delivery.sourceId;
|
|
8527
|
+
}
|
|
8528
|
+
}
|
|
8529
|
+
async function withTimeout2(work, timeoutMs, ref) {
|
|
8530
|
+
let timer;
|
|
8531
|
+
try {
|
|
8532
|
+
return await Promise.race([
|
|
8533
|
+
work,
|
|
8534
|
+
new Promise((_, reject) => {
|
|
8535
|
+
timer = setTimeout(
|
|
8536
|
+
() => reject(
|
|
8537
|
+
new Error(`reader timed out after ${timeoutMs}ms on ${ref}`)
|
|
8538
|
+
),
|
|
8539
|
+
timeoutMs
|
|
8540
|
+
);
|
|
8541
|
+
})
|
|
8542
|
+
]);
|
|
8543
|
+
} finally {
|
|
8544
|
+
if (timer) {
|
|
8545
|
+
clearTimeout(timer);
|
|
8546
|
+
}
|
|
8547
|
+
}
|
|
8548
|
+
}
|
|
8549
|
+
function defineReader(source, config) {
|
|
8550
|
+
const documentFor = (delivery) => {
|
|
8551
|
+
let cached = delivery.chunks ? Promise.resolve(delivery.chunks) : null;
|
|
8552
|
+
return {
|
|
8553
|
+
...delivery.document,
|
|
8554
|
+
chunks: () => {
|
|
8555
|
+
if (!cached) {
|
|
8556
|
+
cached = source.chunks(delivery.document.id);
|
|
8557
|
+
}
|
|
8558
|
+
return cached;
|
|
8559
|
+
}
|
|
8560
|
+
};
|
|
8561
|
+
};
|
|
8562
|
+
const deliver2 = async (delivery) => {
|
|
8563
|
+
switch (delivery.kind) {
|
|
8564
|
+
case "read":
|
|
8565
|
+
await config.read(documentFor(delivery));
|
|
8566
|
+
return;
|
|
8567
|
+
case "removed":
|
|
8568
|
+
await config.removed(delivery.documentId);
|
|
8569
|
+
return;
|
|
8570
|
+
case "cleared":
|
|
8571
|
+
await config.cleared?.(delivery.sourceId);
|
|
8572
|
+
return;
|
|
8573
|
+
}
|
|
8574
|
+
};
|
|
8575
|
+
const run = async (params) => {
|
|
8576
|
+
const startedAt = Date.now();
|
|
8577
|
+
const timeoutMs = params.timeoutMs ?? DEFAULT_TIMEOUT_MS2;
|
|
8578
|
+
const concurrency = Math.max(1, params.concurrency ?? DEFAULT_CONCURRENCY3);
|
|
8579
|
+
const deliveries = Array.isArray(params.deliveries) ? params.deliveries : [];
|
|
8580
|
+
const outcomes = new Array(deliveries.length);
|
|
8581
|
+
let next = 0;
|
|
8582
|
+
const worker = async () => {
|
|
8583
|
+
while (true) {
|
|
8584
|
+
const index = next++;
|
|
8585
|
+
if (index >= deliveries.length) {
|
|
8586
|
+
return;
|
|
8587
|
+
}
|
|
8588
|
+
const delivery = deliveries[index];
|
|
8589
|
+
const ref = refOf(delivery);
|
|
8590
|
+
const t = Date.now();
|
|
8591
|
+
try {
|
|
8592
|
+
await withTimeout2(
|
|
8593
|
+
Promise.resolve().then(() => deliver2(delivery)),
|
|
8594
|
+
timeoutMs,
|
|
8595
|
+
ref
|
|
8596
|
+
);
|
|
8597
|
+
outcomes[index] = {
|
|
8598
|
+
ref,
|
|
8599
|
+
kind: delivery.kind,
|
|
8600
|
+
ok: true,
|
|
8601
|
+
durationMs: Date.now() - t
|
|
8602
|
+
};
|
|
8603
|
+
} catch (e) {
|
|
8604
|
+
outcomes[index] = {
|
|
8605
|
+
ref,
|
|
8606
|
+
kind: delivery.kind,
|
|
8607
|
+
ok: false,
|
|
8608
|
+
error: errorInfo3(e),
|
|
8609
|
+
durationMs: Date.now() - t
|
|
8610
|
+
};
|
|
8611
|
+
}
|
|
8612
|
+
}
|
|
8613
|
+
};
|
|
8614
|
+
await Promise.all(
|
|
8615
|
+
Array.from({ length: Math.min(concurrency, deliveries.length) }, worker)
|
|
8616
|
+
);
|
|
8617
|
+
return {
|
|
8618
|
+
v: 1,
|
|
8619
|
+
source: source.name,
|
|
8620
|
+
outcomes,
|
|
8621
|
+
startedAt,
|
|
8622
|
+
durationMs: Date.now() - startedAt
|
|
8623
|
+
};
|
|
8624
|
+
};
|
|
8625
|
+
return Object.assign(run, {
|
|
8626
|
+
kind: "reader",
|
|
8627
|
+
source: source.name,
|
|
8628
|
+
config
|
|
8629
|
+
});
|
|
8630
|
+
}
|
|
8631
|
+
|
|
8375
8632
|
// src/generated/snippets.ts
|
|
8376
8633
|
var monacoSnippets = {
|
|
8377
8634
|
"activeCampaignAddNote": { fields: [["contactId", "string"], ["note", "string"]], outputKeys: [] },
|
|
@@ -8632,6 +8889,7 @@ export {
|
|
|
8632
8889
|
index_default as default,
|
|
8633
8890
|
defineJewel,
|
|
8634
8891
|
defineMapper,
|
|
8892
|
+
defineReader,
|
|
8635
8893
|
deletes,
|
|
8636
8894
|
documents,
|
|
8637
8895
|
email,
|