@mastra/memory 1.33.0-alpha.4 → 1.34.0-alpha.0
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/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-agents-human-in-the-loop.md +2 -4
- package/dist/docs/references/docs-harness-background-tasks.md +2 -2
- package/dist/docs/references/docs-harness-goals.md +27 -4
- package/dist/docs/references/docs-memory-observational-memory.md +3 -3
- package/dist/docs/references/docs-memory-overview.md +1 -1
- package/dist/docs/references/reference-memory-observational-memory.md +3 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/processors/index.cjs +1 -1
- package/dist/processors/index.js +1 -1
- package/dist/processors/observational-memory/observation-groups.d.ts.map +1 -1
- package/dist/processors/observational-memory/repro-capture.d.ts.map +1 -1
- package/dist/processors/observational-memory/subconscious/activity.d.ts.map +1 -1
- package/dist/processors/observational-memory/subconscious/remind-questions.d.ts.map +1 -1
- package/dist/processors/observational-memory/temporary-memory.d.ts.map +1 -1
- package/dist/processors/observational-memory/token-counter.d.ts +6 -0
- package/dist/processors/observational-memory/token-counter.d.ts.map +1 -1
- package/dist/{src-CynTAk-_.js → src-BYAwbfUo.js} +219 -42
- package/dist/src-BYAwbfUo.js.map +1 -0
- package/dist/{src-CjK4q2uy.cjs → src-Cm4sUXMu.cjs} +219 -43
- package/dist/src-Cm4sUXMu.cjs.map +1 -0
- package/dist/tools/om-tools.d.ts +22 -0
- package/dist/tools/om-tools.d.ts.map +1 -1
- package/package.json +8 -8
- package/dist/src-CjK4q2uy.cjs.map +0 -1
- package/dist/src-CynTAk-_.js.map +0 -1
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import crypto$1, { createHash, randomBytes, randomUUID } from "crypto";
|
|
2
1
|
import { ZodFirstPartyTypeKind } from "zod/v3";
|
|
3
2
|
import { z } from "zod";
|
|
4
3
|
import * as z4 from "zod/v4";
|
|
@@ -20,6 +19,7 @@ import { createTool } from "@mastra/core/tools";
|
|
|
20
19
|
import { MASTRA_THREAD_ID_KEY, RequestContext } from "@mastra/core/request-context";
|
|
21
20
|
import { modelSupportsAttachments, modelSupportsTemperature, resolveModelConfig } from "@mastra/core/llm";
|
|
22
21
|
import { AsyncLocalStorage } from "async_hooks";
|
|
22
|
+
import { createHash } from "crypto";
|
|
23
23
|
import probeImageSizeSync from "probe-image-size/sync.js";
|
|
24
24
|
import { isStandardSchemaWithJSON as isStandardSchemaWithJSON$1, toStandardSchema as toStandardSchema$1 } from "@mastra/core/schema";
|
|
25
25
|
import { ErrorCategory, ErrorDomain, MastraError } from "@mastra/core/error";
|
|
@@ -3712,7 +3712,7 @@ function trimStartOfStream() {
|
|
|
3712
3712
|
};
|
|
3713
3713
|
}
|
|
3714
3714
|
//#endregion
|
|
3715
|
-
//#region ../_vendored/ai_v5/dist/dist-
|
|
3715
|
+
//#region ../_vendored/ai_v5/dist/dist-KmM6rhg_.js
|
|
3716
3716
|
var marker$2$4 = "vercel.ai.error";
|
|
3717
3717
|
var symbol$2$4 = Symbol.for(marker$2$4);
|
|
3718
3718
|
var _a$2$4;
|
|
@@ -15671,6 +15671,10 @@ if (OM_DEBUG_LOG) {
|
|
|
15671
15671
|
//#endregion
|
|
15672
15672
|
//#region src/processors/observational-memory/subconscious/activity.ts
|
|
15673
15673
|
const SUBCONSCIOUS_ACTIVITY_STATE_ID = "subconscious-activity";
|
|
15674
|
+
async function hashContents(contents) {
|
|
15675
|
+
const digest = await globalThis.crypto.subtle.digest("SHA-256", new TextEncoder().encode(contents));
|
|
15676
|
+
return Buffer.from(digest).toString("hex");
|
|
15677
|
+
}
|
|
15674
15678
|
async function getActivityTarget(store, event, scope) {
|
|
15675
15679
|
if (event.recordType === "node") {
|
|
15676
15680
|
const node = await store.getNode(event.recordId);
|
|
@@ -15772,7 +15776,7 @@ async function publishSubconsciousError(input) {
|
|
|
15772
15776
|
await input.sendStateSignal({
|
|
15773
15777
|
id: SUBCONSCIOUS_ACTIVITY_STATE_ID,
|
|
15774
15778
|
mode: "snapshot",
|
|
15775
|
-
cacheKey:
|
|
15779
|
+
cacheKey: await hashContents(contents),
|
|
15776
15780
|
tagName: "state",
|
|
15777
15781
|
attributes: { id: SUBCONSCIOUS_ACTIVITY_STATE_ID },
|
|
15778
15782
|
metadata: { origin: "subconscious" },
|
|
@@ -15784,7 +15788,7 @@ async function publishSubconsciousActivity(input) {
|
|
|
15784
15788
|
if (!input.sendStateSignal) return void 0;
|
|
15785
15789
|
const snapshot = await buildSubconsciousActivitySnapshot(input);
|
|
15786
15790
|
const contents = renderSubconsciousActivity(snapshot);
|
|
15787
|
-
const cacheKey =
|
|
15791
|
+
const cacheKey = await hashContents(contents);
|
|
15788
15792
|
await input.sendStateSignal({
|
|
15789
15793
|
id: SUBCONSCIOUS_ACTIVITY_STATE_ID,
|
|
15790
15794
|
mode: "snapshot",
|
|
@@ -17519,7 +17523,7 @@ function createAskMemoryTool(options) {
|
|
|
17519
17523
|
status: "rejected",
|
|
17520
17524
|
error: `ask_memory could not resolve calling agent ${parentAgentId} from the registered runtime.`
|
|
17521
17525
|
};
|
|
17522
|
-
const replyId = `subconscious:remind:${crypto
|
|
17526
|
+
const replyId = `subconscious:remind:${crypto.randomUUID()}:reply`;
|
|
17523
17527
|
try {
|
|
17524
17528
|
const scope = resolveKnowledgeToolScope(context);
|
|
17525
17529
|
const model = await resolveSubconsciousAgentModel({
|
|
@@ -17656,7 +17660,7 @@ function createReplyToMemoryQuestionTool(options) {
|
|
|
17656
17660
|
reason: "already-terminal"
|
|
17657
17661
|
};
|
|
17658
17662
|
const trimmedAnswer = answer.trim();
|
|
17659
|
-
const signalId = `${replyId}:${moreComing ? `partial:${crypto
|
|
17663
|
+
const signalId = `${replyId}:${moreComing ? `partial:${Buffer.from(await globalThis.crypto.subtle.digest("SHA-256", new TextEncoder().encode(trimmedAnswer))).toString("hex").slice(0, 12)}` : "terminal"}:signal`;
|
|
17660
17664
|
if (deliveredSignalIds.has(signalId)) return {
|
|
17661
17665
|
delivered: true,
|
|
17662
17666
|
replyId,
|
|
@@ -21322,7 +21326,7 @@ function optimizeObservationsForContext(observations) {
|
|
|
21322
21326
|
//#region src/processors/observational-memory/temporary-memory.ts
|
|
21323
21327
|
function createTemporaryOmMemoryContext(prefix) {
|
|
21324
21328
|
const options = {
|
|
21325
|
-
thread: `${prefix}-${randomUUID()}`,
|
|
21329
|
+
thread: `${prefix}-${globalThis.crypto.randomUUID()}`,
|
|
21326
21330
|
resource: prefix,
|
|
21327
21331
|
options: {
|
|
21328
21332
|
lastMessages: 10,
|
|
@@ -22175,6 +22179,10 @@ function isLikelyBase64Content(value) {
|
|
|
22175
22179
|
if (value.length < 16 || value.length % 4 !== 0 || /\s/.test(value) || isLikelyFilesystemPath(value)) return false;
|
|
22176
22180
|
return /^[A-Za-z0-9+/]+={0,2}$/.test(value);
|
|
22177
22181
|
}
|
|
22182
|
+
/**
|
|
22183
|
+
* Decodes a stored attachment payload (data URI, raw base64, Buffer, or typed array) into bytes.
|
|
22184
|
+
* Returns undefined for remote URLs, filesystem paths, and anything that isn't a decodable payload.
|
|
22185
|
+
*/
|
|
22178
22186
|
function decodeImageBuffer(value) {
|
|
22179
22187
|
if (typeof Buffer !== "undefined" && Buffer.isBuffer(value)) return value;
|
|
22180
22188
|
if (value instanceof Uint8Array) return Buffer.from(value);
|
|
@@ -24044,6 +24052,145 @@ function makePart(msg, partIndex, type, fullText, detail, toolName) {
|
|
|
24044
24052
|
toolName
|
|
24045
24053
|
};
|
|
24046
24054
|
}
|
|
24055
|
+
const PROVIDER_FILE_ID_PATTERN = /^file-[A-Za-z0-9_-]+$/;
|
|
24056
|
+
const REUSABLE_URL_PATTERN = /^[a-z][a-z0-9+.-]*:\/\/\S+$/i;
|
|
24057
|
+
const DATA_URI_PATTERN = /^data:([^;,]*)/i;
|
|
24058
|
+
const INLINE_DATA_OMITTED = "(inline data omitted)";
|
|
24059
|
+
/**
|
|
24060
|
+
* Reads the payload and media type of a stored image/file part. Stored parts use the v4
|
|
24061
|
+
* (`data`/`mimeType`) or v5 (`url`/`mediaType`) shape; prompt-style image parts carry the
|
|
24062
|
+
* payload in `image`. A data URI's header supplies the media type when none was stored.
|
|
24063
|
+
*/
|
|
24064
|
+
function readAttachmentPayload(part) {
|
|
24065
|
+
const payload = part.image ?? part.data ?? part.url;
|
|
24066
|
+
const payloadString = payload instanceof URL ? payload.href : typeof payload === "string" ? payload.trim() : "";
|
|
24067
|
+
const dataUriMatch = DATA_URI_PATTERN.exec(payloadString);
|
|
24068
|
+
const mediaType = [
|
|
24069
|
+
part.mimeType,
|
|
24070
|
+
part.mediaType,
|
|
24071
|
+
dataUriMatch?.[1]
|
|
24072
|
+
].find((v) => typeof v === "string" && v.length > 0);
|
|
24073
|
+
const hasBytes = payload instanceof Uint8Array || payload instanceof ArrayBuffer;
|
|
24074
|
+
return {
|
|
24075
|
+
payload,
|
|
24076
|
+
payloadString,
|
|
24077
|
+
isDataUri: dataUriMatch !== null,
|
|
24078
|
+
hasBytes,
|
|
24079
|
+
mediaType
|
|
24080
|
+
};
|
|
24081
|
+
}
|
|
24082
|
+
/** Returns the reference text for a payload the agent can reuse, or undefined for inline data. */
|
|
24083
|
+
function describeReusableReference(payloadString) {
|
|
24084
|
+
if (PROVIDER_FILE_ID_PATTERN.test(payloadString)) return `file id: ${payloadString}`;
|
|
24085
|
+
if (REUSABLE_URL_PATTERN.test(payloadString)) return `url: ${payloadString}`;
|
|
24086
|
+
}
|
|
24087
|
+
/**
|
|
24088
|
+
* Renders an image/file part with its media type and, when the stored payload is a reusable
|
|
24089
|
+
* reference (URL or provider file ID), that reference so the agent can reuse the attachment.
|
|
24090
|
+
* Inline payloads (data URIs, base64, bytes) are never rendered.
|
|
24091
|
+
*/
|
|
24092
|
+
function formatAttachmentPart(partType, part) {
|
|
24093
|
+
const filename = typeof part.filename === "string" && part.filename ? `: ${part.filename}` : "";
|
|
24094
|
+
const { payloadString, isDataUri, hasBytes, mediaType } = readAttachmentPayload(part);
|
|
24095
|
+
let reference = "";
|
|
24096
|
+
if (!isDataUri && payloadString) reference = describeReusableReference(payloadString) ?? INLINE_DATA_OMITTED;
|
|
24097
|
+
else if (isDataUri || hasBytes) reference = INLINE_DATA_OMITTED;
|
|
24098
|
+
return [
|
|
24099
|
+
`[${partType === "image" ? "Image" : "File"}${filename}]`,
|
|
24100
|
+
mediaType,
|
|
24101
|
+
reference
|
|
24102
|
+
].filter(Boolean).join(" ");
|
|
24103
|
+
}
|
|
24104
|
+
const INLINE_MEDIA_PART_TYPES = /* @__PURE__ */ new Set([
|
|
24105
|
+
"media",
|
|
24106
|
+
"image-data",
|
|
24107
|
+
"file-data",
|
|
24108
|
+
"image",
|
|
24109
|
+
"file"
|
|
24110
|
+
]);
|
|
24111
|
+
/**
|
|
24112
|
+
* Replaces inline media payloads nested in a stored tool result (for example a `media` part in
|
|
24113
|
+
* `modelOutput`, or a viewed attachment) with a placeholder, so rendering the result as text never
|
|
24114
|
+
* dumps base64. URLs and provider file IDs are kept because the agent can reuse them.
|
|
24115
|
+
*/
|
|
24116
|
+
function omitInlineMediaPayloads(value, seen = /* @__PURE__ */ new WeakMap()) {
|
|
24117
|
+
if (typeof value !== "object" || value === null) return value;
|
|
24118
|
+
if (seen.has(value)) return seen.get(value);
|
|
24119
|
+
if (Array.isArray(value)) {
|
|
24120
|
+
const items = [];
|
|
24121
|
+
seen.set(value, items);
|
|
24122
|
+
for (const item of value) items.push(omitInlineMediaPayloads(item, seen));
|
|
24123
|
+
return items;
|
|
24124
|
+
}
|
|
24125
|
+
const record = value;
|
|
24126
|
+
const isMediaPart = typeof record.type === "string" && INLINE_MEDIA_PART_TYPES.has(record.type);
|
|
24127
|
+
const result = {};
|
|
24128
|
+
seen.set(value, result);
|
|
24129
|
+
for (const [key, entry] of Object.entries(record)) if (isMediaPart && (key === "data" || key === "image") && typeof entry === "string" && !describeReusableReference(entry.trim())) result[key] = INLINE_DATA_OMITTED;
|
|
24130
|
+
else result[key] = omitInlineMediaPayloads(entry, seen);
|
|
24131
|
+
return result;
|
|
24132
|
+
}
|
|
24133
|
+
/**
|
|
24134
|
+
* Media types the model can be handed directly. Mirrors the observational memory observer's
|
|
24135
|
+
* default `observeAttachments` allowlist — anything else (docx, pptx, video, …) is not a type
|
|
24136
|
+
* providers accept as an inline part, so it stays text-only.
|
|
24137
|
+
*/
|
|
24138
|
+
function isViewableAttachmentMediaType(mediaType) {
|
|
24139
|
+
if (!mediaType) return false;
|
|
24140
|
+
const normalized = mediaType.toLowerCase();
|
|
24141
|
+
return normalized.startsWith("image/") || normalized === "application/pdf";
|
|
24142
|
+
}
|
|
24143
|
+
/** Mirrors core's DEFAULT_MAX_MEDIA_BYTES cap on inline media results. */
|
|
24144
|
+
const MAX_VIEWABLE_ATTACHMENT_BYTES = 10 * 1024 * 1024;
|
|
24145
|
+
function isRecallAttachmentContent(value) {
|
|
24146
|
+
if (typeof value !== "object" || value === null) return false;
|
|
24147
|
+
const content = value.content;
|
|
24148
|
+
if (!Array.isArray(content) || content.length !== 2) return false;
|
|
24149
|
+
return content.every((part) => {
|
|
24150
|
+
if (typeof part !== "object" || part === null) return false;
|
|
24151
|
+
const { type, text, data, mimeType } = part;
|
|
24152
|
+
if (type === "text") return typeof text === "string";
|
|
24153
|
+
return (type === "image" || type === "file") && typeof data === "string" && typeof mimeType === "string";
|
|
24154
|
+
});
|
|
24155
|
+
}
|
|
24156
|
+
/**
|
|
24157
|
+
* Turns an attachment part into a model-viewable payload. Only inline payloads are returned, as
|
|
24158
|
+
* base64 bytes. Everything else — remote URLs, provider file IDs, oversized payloads, unsupported
|
|
24159
|
+
* media types — comes back as an explanation for the agent instead.
|
|
24160
|
+
*/
|
|
24161
|
+
function resolveViewableAttachment(part) {
|
|
24162
|
+
const { payload, payloadString, isDataUri, hasBytes, mediaType } = readAttachmentPayload(part);
|
|
24163
|
+
if (!payloadString && !hasBytes) return { note: "This attachment has no stored payload to show." };
|
|
24164
|
+
if (!isViewableAttachmentMediaType(mediaType)) return { note: mediaType ? `Attachments of type ${mediaType} can't be shown inline. Use the attachment's url or file id if you need to reference it.` : "This attachment has no media type recorded, so it can't be shown inline." };
|
|
24165
|
+
if (isHttpUrlString(payloadString)) return { note: "This attachment is stored at a remote URL, so it can't be shown inline. Use its url if you need to reference it." };
|
|
24166
|
+
if (payloadString.length * .75 > MAX_VIEWABLE_ATTACHMENT_BYTES) return { note: "This attachment is too large to show inline." };
|
|
24167
|
+
const bytes = decodeImageBuffer(isDataUri ? `data:${payloadString.slice(5)}` : payloadString || payload);
|
|
24168
|
+
if (!bytes) return { note: "This attachment's payload is not inline data, so it can't be shown." };
|
|
24169
|
+
if (bytes.byteLength > MAX_VIEWABLE_ATTACHMENT_BYTES) return { note: "This attachment is too large to show inline." };
|
|
24170
|
+
return {
|
|
24171
|
+
data: bytes.toString("base64"),
|
|
24172
|
+
mimeType: mediaType
|
|
24173
|
+
};
|
|
24174
|
+
}
|
|
24175
|
+
/**
|
|
24176
|
+
* Presents a resolved attachment to the model as a native base64 `media` part alongside its text
|
|
24177
|
+
* description.
|
|
24178
|
+
*/
|
|
24179
|
+
function recallAttachmentToModelOutput(output) {
|
|
24180
|
+
if (!isRecallAttachmentContent(output)) return void 0;
|
|
24181
|
+
const [textPart, attachment] = output.content;
|
|
24182
|
+
return {
|
|
24183
|
+
type: "content",
|
|
24184
|
+
value: [{
|
|
24185
|
+
type: "text",
|
|
24186
|
+
text: textPart.text
|
|
24187
|
+
}, {
|
|
24188
|
+
type: "media",
|
|
24189
|
+
data: attachment.data,
|
|
24190
|
+
mediaType: attachment.mimeType
|
|
24191
|
+
}]
|
|
24192
|
+
};
|
|
24193
|
+
}
|
|
24047
24194
|
function formatMessageParts(msg, detail) {
|
|
24048
24195
|
const parts = [];
|
|
24049
24196
|
if (typeof msg.content === "string") {
|
|
@@ -24076,7 +24223,7 @@ function formatMessageParts(msg, detail) {
|
|
|
24076
24223
|
}
|
|
24077
24224
|
if (inv.state === "result") {
|
|
24078
24225
|
const { value: resultValue } = resolveToolResultValue(part, inv.result);
|
|
24079
|
-
const resultStr = formatToolResultForObserver(resultValue, { maxTokens: HIGH_DETAIL_TOOL_RESULT_TOKENS });
|
|
24226
|
+
const resultStr = formatToolResultForObserver(omitInlineMediaPayloads(resultValue), { maxTokens: HIGH_DETAIL_TOOL_RESULT_TOKENS });
|
|
24080
24227
|
const fullText = `[Tool Result: ${inv.toolName}]\n${resultStr}`;
|
|
24081
24228
|
parts.push(makePart(msg, i, "tool-result", fullText, detail, inv.toolName));
|
|
24082
24229
|
}
|
|
@@ -24099,25 +24246,14 @@ function formatMessageParts(msg, detail) {
|
|
|
24099
24246
|
} else if (partType === "tool-result") {
|
|
24100
24247
|
const toolName = part.toolName;
|
|
24101
24248
|
if (toolName) {
|
|
24102
|
-
const fullText = `[Tool Result: ${toolName}]\n${formatToolResultForObserver(part.output ?? part.result, { maxTokens: HIGH_DETAIL_TOOL_RESULT_TOKENS })}`;
|
|
24249
|
+
const fullText = `[Tool Result: ${toolName}]\n${formatToolResultForObserver(omitInlineMediaPayloads(part.output ?? part.result), { maxTokens: HIGH_DETAIL_TOOL_RESULT_TOKENS })}`;
|
|
24103
24250
|
parts.push(makePart(msg, i, "tool-result", fullText, detail, toolName));
|
|
24104
24251
|
}
|
|
24105
24252
|
} else if (partType === "reasoning") {
|
|
24106
24253
|
const reasoning = part.reasoning ?? part.text;
|
|
24107
24254
|
if (reasoning) parts.push(makePart(msg, i, "reasoning", reasoning, detail));
|
|
24108
|
-
} else if (partType === "image" || partType === "file")
|
|
24109
|
-
|
|
24110
|
-
const label = filename ? `: ${filename}` : "";
|
|
24111
|
-
const fullText = `[${partType === "image" ? "Image" : "File"}${label}]`;
|
|
24112
|
-
parts.push({
|
|
24113
|
-
messageId: msg.id,
|
|
24114
|
-
partIndex: i,
|
|
24115
|
-
role: msg.role,
|
|
24116
|
-
type: partType,
|
|
24117
|
-
text: fullText,
|
|
24118
|
-
fullText
|
|
24119
|
-
});
|
|
24120
|
-
} else if (partType?.startsWith("data-")) {} else if (partType) {
|
|
24255
|
+
} else if (partType === "image" || partType === "file") parts.push(makePart(msg, i, partType, formatAttachmentPart(partType, part), detail));
|
|
24256
|
+
else if (partType?.startsWith("data-")) {} else if (partType) {
|
|
24121
24257
|
const fullText = `[${partType}]`;
|
|
24122
24258
|
parts.push({
|
|
24123
24259
|
messageId: msg.id,
|
|
@@ -24290,6 +24426,29 @@ async function recallPart({ memory, threadId, resourceId, cursor, partIndex, cha
|
|
|
24290
24426
|
note
|
|
24291
24427
|
};
|
|
24292
24428
|
}
|
|
24429
|
+
async function recallAttachmentView({ memory, threadId, resourceId, cursor, partIndex, threadScope, retrievalScope = "thread" }) {
|
|
24430
|
+
if (!memory || typeof memory.getMemoryStore !== "function") throw new Error("Memory instance is required for recall");
|
|
24431
|
+
if (!threadId) throw new Error("Thread ID is required for recall");
|
|
24432
|
+
const resolved = await resolveCursorMessage(memory, cursor, {
|
|
24433
|
+
resourceId,
|
|
24434
|
+
threadScope,
|
|
24435
|
+
enforceThreadScope: retrievalScope !== "resource"
|
|
24436
|
+
});
|
|
24437
|
+
if ("hint" in resolved) return { messages: resolved.hint };
|
|
24438
|
+
const rawPart = getMessageParts(resolved)[partIndex];
|
|
24439
|
+
const partType = rawPart?.type;
|
|
24440
|
+
if (!rawPart || partType !== "image" && partType !== "file") return { messages: `Part ${partIndex} of message ${cursor} is ${rawPart ? `a ${partType ?? "unknown"}-type part` : "missing"}, not an attachment. Call recall with the same cursor and partIndex without viewAttachment to read it.` };
|
|
24441
|
+
const resolvedAttachment = resolveViewableAttachment(rawPart);
|
|
24442
|
+
if ("note" in resolvedAttachment) return { messages: `${formatAttachmentPart(partType, rawPart)} — ${resolvedAttachment.note}` };
|
|
24443
|
+
return { content: [{
|
|
24444
|
+
type: "text",
|
|
24445
|
+
text: formatAttachmentPart(partType, rawPart)
|
|
24446
|
+
}, {
|
|
24447
|
+
type: partType === "image" ? "image" : "file",
|
|
24448
|
+
data: resolvedAttachment.data,
|
|
24449
|
+
mimeType: resolvedAttachment.mimeType
|
|
24450
|
+
}] };
|
|
24451
|
+
}
|
|
24293
24452
|
async function recallMessages({ memory, threadId, resourceId, cursor, page = 1, limit = 20, detail = "low", partType, toolName, threadScope, retrievalScope = "thread", maxTokens = DEFAULT_MAX_RESULT_TOKENS }) {
|
|
24294
24453
|
if (!memory) throw new Error("Memory instance is required for recall");
|
|
24295
24454
|
if (!threadId) throw new Error("Thread ID is required for recall");
|
|
@@ -24575,11 +24734,15 @@ const recallTool = (_memoryConfig, options) => {
|
|
|
24575
24734
|
type: "integer",
|
|
24576
24735
|
minimum: 0,
|
|
24577
24736
|
description: "Continue reading a truncated single part from this position. Pass the exact nextCharOffset value returned by a previous call; do not compute it yourself. Only applies with cursor and partIndex in mode=\"messages\"."
|
|
24737
|
+
},
|
|
24738
|
+
viewAttachment: {
|
|
24739
|
+
type: "boolean",
|
|
24740
|
+
description: "Show the actual attachment instead of just describing it. Requires cursor and partIndex, and only applies when that part is an image or file. Use it after recall shows you an attachment you need to look at."
|
|
24578
24741
|
}
|
|
24579
24742
|
}
|
|
24580
24743
|
},
|
|
24581
24744
|
execute: async (inputData, context) => {
|
|
24582
|
-
const { mode, query, cursor, threadId: explicitThreadId, anchor, page, limit, detail, partType, toolName, partIndex, charOffset, before, after } = inputData;
|
|
24745
|
+
const { mode, query, cursor, threadId: explicitThreadId, anchor, page, limit, detail, partType, toolName, partIndex, charOffset, before, after, viewAttachment } = inputData;
|
|
24583
24746
|
const memory = context?.memory;
|
|
24584
24747
|
const currentThreadId = context?.agent?.threadId;
|
|
24585
24748
|
const resourceId = context?.agent?.resourceId;
|
|
@@ -24668,6 +24831,7 @@ const recallTool = (_memoryConfig, options) => {
|
|
|
24668
24831
|
targetThreadId = resolved.threadId;
|
|
24669
24832
|
}
|
|
24670
24833
|
if (!targetThreadId) throw new Error("Thread ID is required for recall");
|
|
24834
|
+
if (viewAttachment && (!cursor || partIndex === void 0 || partIndex === null)) return { messages: "viewAttachment needs both cursor and partIndex so it knows which attachment to show. Call recall with cursor, partIndex, and viewAttachment: true." };
|
|
24671
24835
|
if (!cursor) {
|
|
24672
24836
|
const result = await recallThreadFromStart({
|
|
24673
24837
|
memory,
|
|
@@ -24686,16 +24850,27 @@ const recallTool = (_memoryConfig, options) => {
|
|
|
24686
24850
|
};
|
|
24687
24851
|
return result;
|
|
24688
24852
|
}
|
|
24689
|
-
if (partIndex !== void 0 && partIndex !== null)
|
|
24690
|
-
|
|
24691
|
-
|
|
24692
|
-
|
|
24693
|
-
|
|
24694
|
-
|
|
24695
|
-
|
|
24696
|
-
|
|
24697
|
-
|
|
24698
|
-
|
|
24853
|
+
if (partIndex !== void 0 && partIndex !== null) {
|
|
24854
|
+
if (viewAttachment) return recallAttachmentView({
|
|
24855
|
+
memory,
|
|
24856
|
+
threadId: targetThreadId,
|
|
24857
|
+
resourceId,
|
|
24858
|
+
cursor,
|
|
24859
|
+
partIndex,
|
|
24860
|
+
threadScope,
|
|
24861
|
+
retrievalScope
|
|
24862
|
+
});
|
|
24863
|
+
return recallPart({
|
|
24864
|
+
memory,
|
|
24865
|
+
threadId: targetThreadId,
|
|
24866
|
+
resourceId,
|
|
24867
|
+
cursor,
|
|
24868
|
+
partIndex,
|
|
24869
|
+
charOffset,
|
|
24870
|
+
threadScope,
|
|
24871
|
+
retrievalScope
|
|
24872
|
+
});
|
|
24873
|
+
}
|
|
24699
24874
|
return recallMessages({
|
|
24700
24875
|
memory,
|
|
24701
24876
|
threadId: targetThreadId,
|
|
@@ -24709,7 +24884,8 @@ const recallTool = (_memoryConfig, options) => {
|
|
|
24709
24884
|
threadScope,
|
|
24710
24885
|
retrievalScope
|
|
24711
24886
|
});
|
|
24712
|
-
}
|
|
24887
|
+
},
|
|
24888
|
+
toModelOutput: recallAttachmentToModelOutput
|
|
24713
24889
|
});
|
|
24714
24890
|
};
|
|
24715
24891
|
//#endregion
|
|
@@ -25670,7 +25846,7 @@ function stripReflectionGroupMetadata(body) {
|
|
|
25670
25846
|
return body.replace(/^_range:\s*`[^`]*`_\s*\n?/m, "").trim();
|
|
25671
25847
|
}
|
|
25672
25848
|
function generateAnchorId() {
|
|
25673
|
-
return
|
|
25849
|
+
return Buffer.from(globalThis.crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(8))).toString("hex");
|
|
25674
25850
|
}
|
|
25675
25851
|
function wrapInObservationGroup(observations, range, id = generateAnchorId(), _sourceGroupIds, kind) {
|
|
25676
25852
|
const content = observations.trim();
|
|
@@ -29022,7 +29198,7 @@ function inferReproIdRemap(preMessages, postMessages) {
|
|
|
29022
29198
|
}
|
|
29023
29199
|
function createOmReproCaptureDir(threadId, label) {
|
|
29024
29200
|
const sanitizedThreadId = sanitizeCapturePathSegment(threadId);
|
|
29025
|
-
const captureDir = join(process.cwd(), getOmReproCaptureDir(), sanitizedThreadId, `${Date.now()}-${label}-${randomUUID()}`);
|
|
29201
|
+
const captureDir = join(process.cwd(), getOmReproCaptureDir(), sanitizedThreadId, `${Date.now()}-${label}-${globalThis.crypto.randomUUID()}`);
|
|
29026
29202
|
mkdirSync(captureDir, { recursive: true });
|
|
29027
29203
|
return captureDir;
|
|
29028
29204
|
}
|
|
@@ -33574,18 +33750,19 @@ Notes:
|
|
|
33574
33750
|
const embedResult = await this.embedMessageContent(text);
|
|
33575
33751
|
if (embedResult.embeddings.length === 0 || embedResult.dimension === void 0) return;
|
|
33576
33752
|
const { indexName } = await this.createObservationEmbeddingIndex(embedResult.dimension);
|
|
33577
|
-
const ids =
|
|
33578
|
-
|
|
33753
|
+
const ids = [];
|
|
33754
|
+
for (const [chunkIndex] of embedResult.chunks.entries()) {
|
|
33755
|
+
const hash = Buffer.from(await globalThis.crypto.subtle.digest("SHA-256", new TextEncoder().encode(JSON.stringify([
|
|
33579
33756
|
resourceId,
|
|
33580
33757
|
threadId,
|
|
33581
33758
|
groupId,
|
|
33582
33759
|
chunkIndex
|
|
33583
|
-
]))
|
|
33760
|
+
]))));
|
|
33584
33761
|
hash[6] = hash[6] & 15 | 128;
|
|
33585
33762
|
hash[8] = hash[8] & 63 | 128;
|
|
33586
33763
|
const hex = hash.toString("hex", 0, 16);
|
|
33587
|
-
|
|
33588
|
-
}
|
|
33764
|
+
ids.push(`${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`);
|
|
33765
|
+
}
|
|
33589
33766
|
await this.vector.upsert({
|
|
33590
33767
|
indexName,
|
|
33591
33768
|
ids,
|
|
@@ -34459,4 +34636,4 @@ Notes:
|
|
|
34459
34636
|
//#endregion
|
|
34460
34637
|
export { formatMessagesForObserver as A, OBSERVATION_CONTEXT_PROMPT_THREAD as B, SUMMARIZE_THREAD_DEFAULTS as C, buildObserverPrompt as D, OBSERVER_SYSTEM_PROMPT as E, parseAnchorId as F, StaleKnowledgeSemanticIndexError as G, getObservationContextPrompt as H, stripEphemeralAnchorIds as I, SUBCONSCIOUS_ACTIVITY_STATE_ID as J, SubconsciousRemindExtractor as K, OBSERVATIONAL_MEMORY_DEFAULTS as L, optimizeObservationsForContext as M, parseObserverOutput as N, buildObserverSystemPrompt as O, injectAnchorIds as P, Extractor as Q, OBSERVATION_CONTEXT_INSTRUCTIONS as R, deepMergeWorkingMemory as S, TokenCounter as T, Subconscious as U, OBSERVATION_CONTINUATION_HINT as V, KnowledgeSemanticIndexCoordinator as W, publishSubconsciousActivity as X, buildSubconsciousActivitySnapshot as Y, renderSubconsciousActivity as Z, wrapInObservationGroup as _, extractWorkingMemoryContent as a, WorkingMemoryStateProcessor as b, getObservationsAsOf as c, combineObservationGroupRanges as d, deriveObservationGroupProvenance as f, stripObservationGroups as g, renderObservationGroupsForReflection as h, WorkingMemory as i, hasCurrentTaskSection as j, extractCurrentTask as k, ObservationalMemoryProcessor as l, reconcileObservationGroupsFromReflection as m, MessageHistory$1 as n, extractWorkingMemoryTags as o, parseObservationGroups as p, ModelByInputTokens as q, SemanticRecall as r, removeWorkingMemoryTags as s, Memory as t, ObservationalMemory as u, WORKING_MEMORY_STATE_ID as v, summarizeConversation as w, WorkingMemoryExtractor as x, WORKING_MEMORY_STATE_PROCESSOR_ID as y, OBSERVATION_CONTEXT_PROMPT as z };
|
|
34461
34638
|
|
|
34462
|
-
//# sourceMappingURL=src-
|
|
34639
|
+
//# sourceMappingURL=src-BYAwbfUo.js.map
|