@anuma/sdk 6.10.0 → 6.12.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/expo/{chunk-4M56MKBV.mjs → chunk-732ZLOLA.mjs} +89 -32
- package/dist/expo/index.cjs +112 -38
- package/dist/expo/index.d.mts +109 -0
- package/dist/expo/index.d.ts +109 -0
- package/dist/expo/index.mjs +34 -18
- package/dist/expo/{recall-WIB7RQQZ.mjs → recall-PIATJ336.mjs} +1 -1
- package/dist/index.d.mts +15 -1
- package/dist/index.d.ts +15 -1
- package/dist/react/{chunk-EJ65X4GI.mjs → chunk-6IBFFWCE.mjs} +89 -32
- package/dist/react/index.cjs +112 -38
- package/dist/react/index.d.mts +109 -0
- package/dist/react/index.d.ts +109 -0
- package/dist/react/index.mjs +34 -18
- package/dist/react/{recall-FWILZSFH.mjs → recall-QUWN7DJ7.mjs} +1 -1
- package/dist/server/{chunk-I56324FR.mjs → chunk-7YTEE6JT.mjs} +89 -32
- package/dist/server/index.cjs +112 -38
- package/dist/server/index.d.mts +109 -0
- package/dist/server/index.d.ts +109 -0
- package/dist/server/index.mjs +34 -18
- package/dist/server/{recall-T7CNXTQ3.mjs → recall-HOVWMT4Q.mjs} +1 -1
- package/package.json +1 -1
package/dist/server/index.d.ts
CHANGED
|
@@ -4698,6 +4698,51 @@ interface EntityOperationsContext {
|
|
|
4698
4698
|
allowUnscopedRows?: boolean;
|
|
4699
4699
|
}
|
|
4700
4700
|
|
|
4701
|
+
/**
|
|
4702
|
+
* Class-B task types — the vocabulary of the `X-Anuma-Task-Type` header.
|
|
4703
|
+
*
|
|
4704
|
+
* A Class-B flow has ONE fixed purpose and no conversation: extract memories
|
|
4705
|
+
* from a snippet, pick a topic, consolidate duplicates, classify a query. Today
|
|
4706
|
+
* each of those builds its own system prompt on the client and sends it as a
|
|
4707
|
+
* `role:system` message, which makes the prompt a suggestion rather than a
|
|
4708
|
+
* contract — a caller can reword it into "you are a general assistant" and get
|
|
4709
|
+
* general chat at internal-endpoint prices.
|
|
4710
|
+
*
|
|
4711
|
+
* The fix is that the SERVER owns the text and the client only names the task.
|
|
4712
|
+
* This header is the name. The portal allowlists it against its own copy of this
|
|
4713
|
+
* enum (ai-portal `internal/systemprompt/tasks.go`) and DROPS anything it does
|
|
4714
|
+
* not recognise, so an unknown value degrades to "no task declared" rather than
|
|
4715
|
+
* failing the request.
|
|
4716
|
+
*
|
|
4717
|
+
* ⚠ These string values are a wire contract with ai-portal. Adding one here
|
|
4718
|
+
* before the portal knows it is harmless (it is dropped); renaming or removing
|
|
4719
|
+
* one silently stops that flow being counted. Keep them in step with
|
|
4720
|
+
* `AllTaskTypes` on the portal side, and see ai-portal
|
|
4721
|
+
* `docs/BACKEND_OWNED_TASK_PROMPTS.md` for the rollout.
|
|
4722
|
+
*
|
|
4723
|
+
* ⚠ RELEASE ORDER. This union is a PUBLIC type, so a split is breaking in both
|
|
4724
|
+
* directions and has to be sequenced:
|
|
4725
|
+
*
|
|
4726
|
+
* 1. merge + publish this package;
|
|
4727
|
+
* 2. bump `@anuma/sdk` in the consumer and switch its call sites to the new
|
|
4728
|
+
* names in the same commit.
|
|
4729
|
+
*
|
|
4730
|
+
* A consumer on the OLD version cannot compile the new names, and a consumer on
|
|
4731
|
+
* the NEW version cannot compile the retired ones (`app_inspiration` is gone
|
|
4732
|
+
* here, replaced by the three `app_inspiration_*` names). Both halves of that
|
|
4733
|
+
* are type-only — the wire itself always degrades safely, because the portal
|
|
4734
|
+
* drops any value it does not recognise. Concretely: ai-memoryless-client#5782
|
|
4735
|
+
* is blocked on this publish for exactly that reason.
|
|
4736
|
+
*
|
|
4737
|
+
* Deliberately ABSENT: agent personas, `reflect()` when it answers the user, and
|
|
4738
|
+
* the app-idea chat. Those carry an open conversation with the user, so a fixed
|
|
4739
|
+
* server-owned prompt would be wrong rather than merely premature — the same
|
|
4740
|
+
* boundary {@link INTERNAL_FLOW_MARKER} draws.
|
|
4741
|
+
*
|
|
4742
|
+
* @public
|
|
4743
|
+
*/
|
|
4744
|
+
type TaskType = "title" | "commit_message" | "memory_extract" | "memory_dedup" | "memory_decay" | "memory_injection_check" | "memory_verify_support" | "memory_autosort" | "memory_topic" | "memory_consolidate" | "memory_decompose" | "memory_profile_synth" | "memory_graph" | "folder_context" | "selection_memory" | "summarize" | "style_analysis" | "classify_search" | "app_inspiration_generate" | "app_inspiration_trends" | "app_inspiration_remix" | "spotlight_image" | "slide_image" | "slide_video" | "slide_music" | "slide_sfx" | "media_video" | "media_audio" | "media_bg_removal" | "media_image_preset" | "tool_app_builder" | "tool_document_builder" | "tool_slides" | "tool_slides_image_gen" | "connector_guidance" | "cf_task" | "xbot_intent" | "xbot_council" | "scheduled_task";
|
|
4745
|
+
|
|
4701
4746
|
/**
|
|
4702
4747
|
* Shared portal LLM call for the memory pipeline.
|
|
4703
4748
|
*
|
|
@@ -5641,6 +5686,17 @@ interface RecallDiagnostics {
|
|
|
5641
5686
|
* never the cost.
|
|
5642
5687
|
*/
|
|
5643
5688
|
vaultRowsDecrypted?: number;
|
|
5689
|
+
/**
|
|
5690
|
+
* Rows the fact lane had to re-embed through the portal because their stored
|
|
5691
|
+
* vector was unusable — stale `embedding_model`, wrong dimension, or
|
|
5692
|
+
* unparseable. Absent when the fact lane didn't run.
|
|
5693
|
+
*
|
|
5694
|
+
* Expected to be 0 on a healthy vault: rows are embedded at write time and the
|
|
5695
|
+
* re-embed writes the current model back, so a persistently non-zero value
|
|
5696
|
+
* means the writeback is not sticking and every turn is paying for it. On the
|
|
5697
|
+
* LEGACY read path this batch is uncapped, so it can be the whole vault.
|
|
5698
|
+
*/
|
|
5699
|
+
vaultRowsEmbedded?: number;
|
|
5644
5700
|
/** Facts the fact lane returned (post-dedupe, pre-fusion). */
|
|
5645
5701
|
factCount: number;
|
|
5646
5702
|
/** Chunks the chunk lane returned (post-dedupe, pre-fusion). */
|
|
@@ -5653,6 +5709,37 @@ interface RecallDiagnostics {
|
|
|
5653
5709
|
prep: number;
|
|
5654
5710
|
/** Vault fact-lane search (`searchVaultMemoriesWithSize`). */
|
|
5655
5711
|
factLane: number;
|
|
5712
|
+
/**
|
|
5713
|
+
* The cross-encoder's share of {@link factLane} — wall-clock spent inside
|
|
5714
|
+
* `rerankPairs`. Billed even when the CE threw partway through, because a
|
|
5715
|
+
* rerank that burned three seconds and then failed still cost them.
|
|
5716
|
+
*
|
|
5717
|
+
* A SUBSET of `factLane`, not a sibling: read `factLane - rerank` for
|
|
5718
|
+
* everything else the lane did (query embed, vault read, fused ranking).
|
|
5719
|
+
* 0 when the CE did not run; `reranked` is what distinguishes that from a
|
|
5720
|
+
* rerank that cost nothing.
|
|
5721
|
+
*
|
|
5722
|
+
* Exists because #845 spent three rounds arguing about which stage inside
|
|
5723
|
+
* the fact lane dominated — whole-vault read, then admission window, then
|
|
5724
|
+
* the CE — with one aggregate number for all of them. Every hypothesis was
|
|
5725
|
+
* an inference; this makes the question a query.
|
|
5726
|
+
*/
|
|
5727
|
+
rerank: number;
|
|
5728
|
+
/**
|
|
5729
|
+
* The query embed's share of {@link factLane} — one portal round trip.
|
|
5730
|
+
*
|
|
5731
|
+
* Also a SUBSET of `factLane`. Together with `rerank` this makes the lane
|
|
5732
|
+
* decomposable: `factLane - queryEmbed - rerank` is the local work (vault
|
|
5733
|
+
* read, decrypt, BM25/cosine fusion), and each of the three implies a
|
|
5734
|
+
* completely different fix.
|
|
5735
|
+
*
|
|
5736
|
+
* 0 when the lane returned before embedding, which includes every empty
|
|
5737
|
+
* vault — `prepareVaultCandidates` short-circuits first. That is why the
|
|
5738
|
+
* fast `vault_size = 0` population never established a baseline for this
|
|
5739
|
+
* cost, and why the ~850ms floor on the smallest NON-empty vaults had no
|
|
5740
|
+
* attributable owner.
|
|
5741
|
+
*/
|
|
5742
|
+
queryEmbed: number;
|
|
5656
5743
|
/** Chunk-lane search (`searchChunksOp`). */
|
|
5657
5744
|
chunkLane: number;
|
|
5658
5745
|
/** Cross-lane RRF fusion + provenance dedup after both lanes. */
|
|
@@ -8757,6 +8844,28 @@ interface ReflectOptions extends RecallOptions, PortalLlmAuth {
|
|
|
8757
8844
|
maxTokens?: number;
|
|
8758
8845
|
/** Override the grounding system prompt. */
|
|
8759
8846
|
systemPrompt?: string;
|
|
8847
|
+
/**
|
|
8848
|
+
* Extra caller instruction to carry on the USER turn, between the question and
|
|
8849
|
+
* the evidence block (see the `userMessage` assembly below). This is the slot a
|
|
8850
|
+
* background caller uses to keep its per-request data OUT of the system message
|
|
8851
|
+
* without colliding with the numbered evidence list — profile-facet synthesis
|
|
8852
|
+
* puts its section label, guidance and response-field hint here so its system
|
|
8853
|
+
* half can stay fixed and server-ownable.
|
|
8854
|
+
*/
|
|
8855
|
+
userInstructions?: string;
|
|
8856
|
+
/**
|
|
8857
|
+
* Class-B task name for the `X-Anuma-Task-Type` header, or nothing.
|
|
8858
|
+
*
|
|
8859
|
+
* Deliberately OPTIONAL and unset by default. reflect() also answers the user's
|
|
8860
|
+
* OWN question, and that traffic is chat, not an internal flow — declaring a
|
|
8861
|
+
* task type unconditionally here would put an internal-flow name on real
|
|
8862
|
+
* conversation, which is the same boundary `INTERNAL_FLOW_MARKER` draws
|
|
8863
|
+
* (reflect is deliberately unmarked; its background caller marks its own
|
|
8864
|
+
* prompt — see ../internalFlowMarker.ts). So the name is per call: only a
|
|
8865
|
+
* caller with ONE fixed purpose passes
|
|
8866
|
+
* one, and today that is profile-facet synthesis (`memory_profile_synth`).
|
|
8867
|
+
*/
|
|
8868
|
+
taskType?: TaskType;
|
|
8760
8869
|
/** Endpoint for the answer LLM. */
|
|
8761
8870
|
baseUrl?: string;
|
|
8762
8871
|
/** Override fetch (for tests). */
|
package/dist/server/index.mjs
CHANGED
|
@@ -141,7 +141,7 @@ import {
|
|
|
141
141
|
updateVaultMemoryOp,
|
|
142
142
|
upsertMessageOp,
|
|
143
143
|
vaultMemoryToStored
|
|
144
|
-
} from "./chunk-
|
|
144
|
+
} from "./chunk-7YTEE6JT.mjs";
|
|
145
145
|
import {
|
|
146
146
|
createStreamingDeAnonymizer,
|
|
147
147
|
notifyConsolidationFallback,
|
|
@@ -6963,11 +6963,13 @@ Respond with ONLY a single JSON object conforming to this JSON Schema, with no p
|
|
|
6963
6963
|
${JSON.stringify(
|
|
6964
6964
|
options.responseSchema
|
|
6965
6965
|
)}` : basePrompt;
|
|
6966
|
-
const userMessage =
|
|
6967
|
-
|
|
6968
|
-
|
|
6969
|
-
|
|
6970
|
-
|
|
6966
|
+
const userMessage = [
|
|
6967
|
+
`Question:
|
|
6968
|
+
${trimmed}`,
|
|
6969
|
+
...options.userInstructions ? [options.userInstructions] : [],
|
|
6970
|
+
`Memories (use only these as evidence):
|
|
6971
|
+
${evidence}`
|
|
6972
|
+
].join("\n\n");
|
|
6971
6973
|
const maxTokens = options.maxTokens ?? DEFAULT_MAX_TOKENS;
|
|
6972
6974
|
const fetchImpl = options.fetchFn ?? fetch;
|
|
6973
6975
|
const log = getLogger();
|
|
@@ -6981,7 +6983,13 @@ ${evidence}`;
|
|
|
6981
6983
|
try {
|
|
6982
6984
|
response = await fetchImpl(`${baseUrl}/api/v1/chat/completions`, {
|
|
6983
6985
|
method: "POST",
|
|
6984
|
-
|
|
6986
|
+
// No task type unless the caller named one — an undeclared task adds no
|
|
6987
|
+
// header at all, which is what keeps user-facing reflect() unlabelled.
|
|
6988
|
+
headers: {
|
|
6989
|
+
...authHeaders,
|
|
6990
|
+
...taskTypeHeader(options.taskType),
|
|
6991
|
+
"Content-Type": "application/json"
|
|
6992
|
+
},
|
|
6985
6993
|
body: JSON.stringify({
|
|
6986
6994
|
model,
|
|
6987
6995
|
// Modern OpenAI field; the portal reads only `max_completion_tokens`
|
|
@@ -7421,10 +7429,15 @@ async function synthesizeFacet(facet, ctx, options, prior) {
|
|
|
7421
7429
|
limit,
|
|
7422
7430
|
types: ["fact"],
|
|
7423
7431
|
maxTokens: DEFAULT_FACET_MAX_TOKENS,
|
|
7424
|
-
// Profile-facet synthesis is a background op, so it marks its own prompt
|
|
7425
|
-
// reflect() itself must
|
|
7426
|
-
// and that traffic is chat, not an internal flow. See
|
|
7427
|
-
|
|
7432
|
+
// Profile-facet synthesis is a background op, so it marks its own prompt AND
|
|
7433
|
+
// names its own task. reflect() itself must do neither — it also serves the
|
|
7434
|
+
// user's own questions, and that traffic is chat, not an internal flow. See
|
|
7435
|
+
// ../internalFlowMarker and ReflectOptions.taskType.
|
|
7436
|
+
taskType: "memory_profile_synth",
|
|
7437
|
+
systemPrompt: withInternalFlowMarker(FACET_SYSTEM_PROMPT),
|
|
7438
|
+
// The facet's label/guidance/response-fields, on the user turn — what keeps
|
|
7439
|
+
// the system half fixed and therefore server-ownable.
|
|
7440
|
+
userInstructions: buildFacetUserInstructions(facet),
|
|
7428
7441
|
responseSchema: facetResponseSchema(facet.key),
|
|
7429
7442
|
memories
|
|
7430
7443
|
});
|
|
@@ -7482,19 +7495,22 @@ function fallbackSection(facet, prior) {
|
|
|
7482
7495
|
stale: true
|
|
7483
7496
|
};
|
|
7484
7497
|
}
|
|
7485
|
-
|
|
7486
|
-
const structuredField = FACET_STRUCTURED_RESPONSE_HINT[facet.key] ?? "";
|
|
7487
|
-
return `You are writing the "${facet.label}" section of a person's shareable profile, using their private memories (supplied as evidence) as the only source of truth.
|
|
7488
|
-
|
|
7489
|
-
Task for this section:
|
|
7490
|
-
${facet.guidance}
|
|
7498
|
+
var FACET_SYSTEM_PROMPT = `You are writing one section of a person's shareable profile, using their private memories (supplied as evidence) as the only source of truth. The user turn names the section, states the task for it, and gives the exact JSON shape to respond in.
|
|
7491
7499
|
|
|
7492
7500
|
Rules:
|
|
7493
7501
|
- Ground every claim in the supplied memories \u2014 never invent, infer beyond, or embellish what they support.
|
|
7494
7502
|
- If the memories don't cover this section, return an empty summary with hasEvidence=false. Do not pad or guess.
|
|
7495
7503
|
- Write in third person about the person, in a natural voice suitable for a public profile (no "I"/"you", no name repetition).
|
|
7496
7504
|
- Be concise and specific; no preamble, hedging, or meta-commentary.
|
|
7497
|
-
- Respond as JSON
|
|
7505
|
+
- Respond as JSON in exactly the shape the user turn states, with no extra fields.`;
|
|
7506
|
+
function buildFacetUserInstructions(facet) {
|
|
7507
|
+
const structuredField = FACET_STRUCTURED_RESPONSE_HINT[facet.key] ?? "";
|
|
7508
|
+
return `Section: "${facet.label}"
|
|
7509
|
+
|
|
7510
|
+
Task for this section:
|
|
7511
|
+
${facet.guidance}
|
|
7512
|
+
|
|
7513
|
+
Respond as JSON: { "summary": <the section text, or "">, "hasEvidence": <true|false>${structuredField} }.`;
|
|
7498
7514
|
}
|
|
7499
7515
|
function extractFacetText(structured) {
|
|
7500
7516
|
if (structured && typeof structured === "object") {
|