@cognipeer/agent-sdk 0.10.2 → 0.10.4
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/index.cjs +298 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +66 -2
- package/dist/index.d.ts +66 -2
- package/dist/index.mjs +294 -16
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -513,7 +513,7 @@ function getModelCapabilities(model) {
|
|
|
513
513
|
return {
|
|
514
514
|
provider,
|
|
515
515
|
structuredOutput: supportsNativeStructuredOutput(provider) ? "native" : "tool_based",
|
|
516
|
-
strictToolCalling: requiresStrictToolCalling(provider),
|
|
516
|
+
strictToolCalling: requiresStrictToolCalling(provider) && isOpenAIHostedEndpoint(model._lc),
|
|
517
517
|
streaming: true
|
|
518
518
|
};
|
|
519
519
|
}
|
|
@@ -556,6 +556,17 @@ function supportsNativeStructuredOutput(provider) {
|
|
|
556
556
|
function requiresStrictToolCalling(provider) {
|
|
557
557
|
return ["openai"].includes(provider);
|
|
558
558
|
}
|
|
559
|
+
function isOpenAIHostedEndpoint(lcModel) {
|
|
560
|
+
if (!lcModel) return true;
|
|
561
|
+
const baseURL = lcModel.clientConfig?.baseURL ?? lcModel.configuration?.baseURL ?? lcModel.baseURL;
|
|
562
|
+
if (typeof baseURL !== "string" || baseURL.trim() === "") return true;
|
|
563
|
+
try {
|
|
564
|
+
const host = new URL(baseURL).hostname.toLowerCase();
|
|
565
|
+
return host === "api.openai.com" || host.endsWith(".openai.azure.com") || host.endsWith(".cognitiveservices.azure.com");
|
|
566
|
+
} catch {
|
|
567
|
+
return false;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
559
570
|
|
|
560
571
|
// src/model.ts
|
|
561
572
|
function isSmartModel(m) {
|
|
@@ -2520,13 +2531,19 @@ function resolveCapabilities(provider) {
|
|
|
2520
2531
|
switch (provider) {
|
|
2521
2532
|
case "openai":
|
|
2522
2533
|
case "azure":
|
|
2523
|
-
case "openai-compatible":
|
|
2524
2534
|
return {
|
|
2525
2535
|
structuredOutput: "native",
|
|
2526
2536
|
strictToolCalling: true,
|
|
2527
2537
|
streaming: true,
|
|
2528
2538
|
provider
|
|
2529
2539
|
};
|
|
2540
|
+
case "openai-compatible":
|
|
2541
|
+
return {
|
|
2542
|
+
structuredOutput: "native",
|
|
2543
|
+
strictToolCalling: false,
|
|
2544
|
+
streaming: true,
|
|
2545
|
+
provider
|
|
2546
|
+
};
|
|
2530
2547
|
case "anthropic":
|
|
2531
2548
|
return {
|
|
2532
2549
|
structuredOutput: "tool_based",
|
|
@@ -3855,6 +3872,187 @@ Identical to an earlier ${duplicate.toolName} result. Use get_tool_response with
|
|
|
3855
3872
|
}
|
|
3856
3873
|
return notApplied4(output);
|
|
3857
3874
|
}
|
|
3875
|
+
var identity = (value) => value;
|
|
3876
|
+
function describeLike(schema, source, suffix) {
|
|
3877
|
+
const description = [source.description, suffix].filter(Boolean).join(" ");
|
|
3878
|
+
return description ? schema.describe(description) : schema;
|
|
3879
|
+
}
|
|
3880
|
+
function jsonString(source) {
|
|
3881
|
+
return {
|
|
3882
|
+
schema: describeLike(zod.z.string(), source, "(a JSON value, encoded as a string)"),
|
|
3883
|
+
restore: (value) => {
|
|
3884
|
+
if (typeof value !== "string") return value;
|
|
3885
|
+
try {
|
|
3886
|
+
return JSON.parse(value);
|
|
3887
|
+
} catch {
|
|
3888
|
+
return value;
|
|
3889
|
+
}
|
|
3890
|
+
}
|
|
3891
|
+
};
|
|
3892
|
+
}
|
|
3893
|
+
function unwrapOptional(schema) {
|
|
3894
|
+
const def = schema._def;
|
|
3895
|
+
if (def?.typeName === "ZodOptional") return { inner: def.innerType, optional: true };
|
|
3896
|
+
if (def?.typeName === "ZodDefault") return { inner: def.innerType, optional: true };
|
|
3897
|
+
return { inner: schema, optional: false };
|
|
3898
|
+
}
|
|
3899
|
+
function isZodSchema2(schema) {
|
|
3900
|
+
return Boolean(schema) && typeof schema.safeParse === "function" && Boolean(schema._def);
|
|
3901
|
+
}
|
|
3902
|
+
function toStrictCompatible(schema) {
|
|
3903
|
+
const def = schema?._def;
|
|
3904
|
+
switch (def?.typeName) {
|
|
3905
|
+
case "ZodObject": {
|
|
3906
|
+
const shape = typeof def.shape === "function" ? def.shape() : def.shape;
|
|
3907
|
+
const keys = Object.keys(shape ?? {});
|
|
3908
|
+
const open = def.unknownKeys === "passthrough" || def.catchall && def.catchall._def?.typeName !== "ZodNever";
|
|
3909
|
+
if (keys.length === 0 && open) return jsonString(schema);
|
|
3910
|
+
const nextShape = {};
|
|
3911
|
+
const restores = {};
|
|
3912
|
+
for (const key of keys) {
|
|
3913
|
+
const field = shape[key];
|
|
3914
|
+
const { inner, optional } = unwrapOptional(field);
|
|
3915
|
+
const child = toStrictCompatible(inner);
|
|
3916
|
+
const childSchema = describeLike(child.schema, field.description ? field : inner);
|
|
3917
|
+
nextShape[key] = optional ? childSchema.nullable() : childSchema;
|
|
3918
|
+
restores[key] = { restore: child.restore, optional };
|
|
3919
|
+
}
|
|
3920
|
+
return {
|
|
3921
|
+
schema: describeLike(zod.z.object(nextShape), schema),
|
|
3922
|
+
restore: (value) => {
|
|
3923
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return value;
|
|
3924
|
+
const out = {};
|
|
3925
|
+
for (const [key, raw] of Object.entries(value)) {
|
|
3926
|
+
const entry = restores[key];
|
|
3927
|
+
if (raw === null && entry?.optional) continue;
|
|
3928
|
+
out[key] = entry ? entry.restore(raw) : raw;
|
|
3929
|
+
}
|
|
3930
|
+
return out;
|
|
3931
|
+
}
|
|
3932
|
+
};
|
|
3933
|
+
}
|
|
3934
|
+
case "ZodOptional":
|
|
3935
|
+
case "ZodDefault": {
|
|
3936
|
+
const child = toStrictCompatible(def.innerType);
|
|
3937
|
+
return {
|
|
3938
|
+
schema: describeLike(child.schema.nullable(), schema),
|
|
3939
|
+
restore: (value) => value === null ? void 0 : child.restore(value)
|
|
3940
|
+
};
|
|
3941
|
+
}
|
|
3942
|
+
case "ZodNullable": {
|
|
3943
|
+
const child = toStrictCompatible(def.innerType);
|
|
3944
|
+
return {
|
|
3945
|
+
schema: describeLike(child.schema.nullable(), schema),
|
|
3946
|
+
restore: (value) => value === null ? null : child.restore(value)
|
|
3947
|
+
};
|
|
3948
|
+
}
|
|
3949
|
+
case "ZodArray": {
|
|
3950
|
+
const child = toStrictCompatible(def.type);
|
|
3951
|
+
return {
|
|
3952
|
+
schema: describeLike(zod.z.array(child.schema), schema),
|
|
3953
|
+
restore: (value) => Array.isArray(value) ? value.map(child.restore) : value
|
|
3954
|
+
};
|
|
3955
|
+
}
|
|
3956
|
+
case "ZodUnion":
|
|
3957
|
+
case "ZodDiscriminatedUnion": {
|
|
3958
|
+
const rawOptions = def.options instanceof Map ? [...def.options.values()] : def.options;
|
|
3959
|
+
const options = rawOptions.map(toStrictCompatible);
|
|
3960
|
+
if (options.length === 1) return options[0];
|
|
3961
|
+
if (options.every((option, index) => option.schema === rawOptions[index])) {
|
|
3962
|
+
return { schema, restore: identity };
|
|
3963
|
+
}
|
|
3964
|
+
return {
|
|
3965
|
+
schema: describeLike(zod.z.union(options.map((option) => option.schema)), schema),
|
|
3966
|
+
restore: (value) => {
|
|
3967
|
+
const candidates = options.map((option) => option.restore(value));
|
|
3968
|
+
const index = candidates.findIndex((candidate, i) => rawOptions[i].safeParse(candidate).success);
|
|
3969
|
+
return candidates[index >= 0 ? index : 0];
|
|
3970
|
+
}
|
|
3971
|
+
};
|
|
3972
|
+
}
|
|
3973
|
+
case "ZodEffects":
|
|
3974
|
+
return toStrictCompatible(def.schema);
|
|
3975
|
+
case "ZodRecord":
|
|
3976
|
+
case "ZodAny":
|
|
3977
|
+
case "ZodUnknown":
|
|
3978
|
+
return jsonString(schema);
|
|
3979
|
+
default:
|
|
3980
|
+
return { schema, restore: identity };
|
|
3981
|
+
}
|
|
3982
|
+
}
|
|
3983
|
+
function topLevelObject(transform) {
|
|
3984
|
+
if (transform.schema._def?.typeName === "ZodObject") return transform;
|
|
3985
|
+
return {
|
|
3986
|
+
schema: zod.z.object({
|
|
3987
|
+
input: transform.schema.describe(
|
|
3988
|
+
transform.schema.description ?? "The tool arguments as a JSON object, encoded as a string"
|
|
3989
|
+
)
|
|
3990
|
+
}),
|
|
3991
|
+
restore: (value) => {
|
|
3992
|
+
const input = value && typeof value === "object" ? value.input : void 0;
|
|
3993
|
+
const restored = transform.restore(input);
|
|
3994
|
+
return restored && typeof restored === "object" ? restored : {};
|
|
3995
|
+
}
|
|
3996
|
+
};
|
|
3997
|
+
}
|
|
3998
|
+
function toStrictToolSchema(schema) {
|
|
3999
|
+
return topLevelObject(toStrictCompatible(schema));
|
|
4000
|
+
}
|
|
4001
|
+
function restoreToolCalls(message, restorers) {
|
|
4002
|
+
if (!message || typeof message !== "object" || restorers.size === 0) return message;
|
|
4003
|
+
const restoreList = (calls) => {
|
|
4004
|
+
if (!Array.isArray(calls) || calls.length === 0) return calls;
|
|
4005
|
+
return calls.map((call) => {
|
|
4006
|
+
const fn = call?.function;
|
|
4007
|
+
const name = call?.name ?? fn?.name;
|
|
4008
|
+
const restore = name ? restorers.get(name) : void 0;
|
|
4009
|
+
if (!restore) return call;
|
|
4010
|
+
let next = call;
|
|
4011
|
+
if (call.args && typeof call.args === "object") next = { ...next, args: restore(call.args) };
|
|
4012
|
+
if (fn && typeof fn.arguments === "string") {
|
|
4013
|
+
try {
|
|
4014
|
+
next = { ...next, function: { ...fn, arguments: JSON.stringify(restore(JSON.parse(fn.arguments))) } };
|
|
4015
|
+
} catch {
|
|
4016
|
+
}
|
|
4017
|
+
}
|
|
4018
|
+
return next;
|
|
4019
|
+
});
|
|
4020
|
+
};
|
|
4021
|
+
const m = message;
|
|
4022
|
+
const hasDirect = Array.isArray(m.tool_calls) && m.tool_calls.length > 0;
|
|
4023
|
+
const hasKwargs = Array.isArray(m.additional_kwargs?.tool_calls) && m.additional_kwargs.tool_calls.length > 0;
|
|
4024
|
+
if (!hasDirect && !hasKwargs) return message;
|
|
4025
|
+
return {
|
|
4026
|
+
...message,
|
|
4027
|
+
...hasDirect ? { tool_calls: restoreList(m.tool_calls) } : {},
|
|
4028
|
+
...hasKwargs ? { additional_kwargs: { ...m.additional_kwargs, tool_calls: restoreList(m.additional_kwargs.tool_calls) } } : {}
|
|
4029
|
+
};
|
|
4030
|
+
}
|
|
4031
|
+
var strictViews = /* @__PURE__ */ new WeakMap();
|
|
4032
|
+
function prepareStrictToolMenu(tools) {
|
|
4033
|
+
const restorers = /* @__PURE__ */ new Map();
|
|
4034
|
+
const menu = tools.map((tool) => {
|
|
4035
|
+
const t = tool;
|
|
4036
|
+
if (!t || typeof t.name !== "string" || !isZodSchema2(t.schema)) return tool;
|
|
4037
|
+
const cached = strictViews.get(tool);
|
|
4038
|
+
if (cached && cached.schema === t.schema) {
|
|
4039
|
+
restorers.set(t.name, cached.restore);
|
|
4040
|
+
return cached.view;
|
|
4041
|
+
}
|
|
4042
|
+
try {
|
|
4043
|
+
const transform = toStrictToolSchema(t.schema);
|
|
4044
|
+
const view = Object.create(tool);
|
|
4045
|
+
view.schema = transform.schema;
|
|
4046
|
+
view.__lcTool = void 0;
|
|
4047
|
+
strictViews.set(tool, { schema: t.schema, view, restore: transform.restore });
|
|
4048
|
+
restorers.set(t.name, transform.restore);
|
|
4049
|
+
return view;
|
|
4050
|
+
} catch {
|
|
4051
|
+
return tool;
|
|
4052
|
+
}
|
|
4053
|
+
});
|
|
4054
|
+
return { menu, restorers };
|
|
4055
|
+
}
|
|
3858
4056
|
|
|
3859
4057
|
// src/nodes/agentCore.ts
|
|
3860
4058
|
function createAgentCoreNode(opts) {
|
|
@@ -3875,10 +4073,17 @@ function createAgentCoreNode(opts) {
|
|
|
3875
4073
|
};
|
|
3876
4074
|
let tools = runtime.tools ?? [];
|
|
3877
4075
|
const shouldUseStrictToolCalling = Boolean(
|
|
3878
|
-
runtime.
|
|
4076
|
+
runtime.model?.capabilities?.strictToolCalling
|
|
3879
4077
|
);
|
|
4078
|
+
let strictRestorers = /* @__PURE__ */ new Map();
|
|
4079
|
+
const wireMenu = (menu) => {
|
|
4080
|
+
if (!shouldUseStrictToolCalling) return menu;
|
|
4081
|
+
const prepared = prepareStrictToolMenu(menu);
|
|
4082
|
+
strictRestorers = prepared.restorers;
|
|
4083
|
+
return prepared.menu;
|
|
4084
|
+
};
|
|
3880
4085
|
const bindToolMenu = (menu) => runtime.model?.bindTools ? runtime.model.bindTools(
|
|
3881
|
-
menu,
|
|
4086
|
+
wireMenu(menu),
|
|
3882
4087
|
shouldUseStrictToolCalling ? { strict: true } : void 0
|
|
3883
4088
|
) : runtime.model;
|
|
3884
4089
|
const menuMutationReachesProvider = typeof runtime.model?.bindTools === "function";
|
|
@@ -3889,7 +4094,8 @@ function createAgentCoreNode(opts) {
|
|
|
3889
4094
|
const computeTraceToolDefinitions = (menu) => {
|
|
3890
4095
|
if (!traceSession || !traceSession.resolvedConfig.logData || menu.length === 0) return void 0;
|
|
3891
4096
|
try {
|
|
3892
|
-
|
|
4097
|
+
const wire = shouldUseStrictToolCalling ? prepareStrictToolMenu(menu).menu : menu;
|
|
4098
|
+
return wire.map((tool) => {
|
|
3893
4099
|
const def = toToolDefinition(tool, shouldUseStrictToolCalling ? true : void 0);
|
|
3894
4100
|
return { name: def.name, description: def.description || void 0, parameters: def.parameters };
|
|
3895
4101
|
});
|
|
@@ -4195,6 +4401,9 @@ ${append}`;
|
|
|
4195
4401
|
throw err;
|
|
4196
4402
|
}
|
|
4197
4403
|
}
|
|
4404
|
+
if (shortCircuited === void 0 && strictRestorers.size > 0) {
|
|
4405
|
+
response = restoreToolCalls(response, strictRestorers);
|
|
4406
|
+
}
|
|
4198
4407
|
if (!host?.has("postModelCall")) break;
|
|
4199
4408
|
const postGate = await host.runGate("postModelCall", {
|
|
4200
4409
|
message: response,
|
|
@@ -6156,6 +6365,9 @@ function isSyntheticSummaryMessage(message) {
|
|
|
6156
6365
|
}
|
|
6157
6366
|
return false;
|
|
6158
6367
|
}
|
|
6368
|
+
function isCompactedToolContent(content) {
|
|
6369
|
+
return typeof content === "string" && (content === "SUMMARIZED" || content.startsWith("SUMMARIZED_TOOL_RESPONSE") || content.startsWith("ARCHIVED_TOOL_RESPONSE") || content.startsWith("STRUCTURED_TOOL_RESPONSE") || content.startsWith("DROPPED_TOOL_RESPONSE"));
|
|
6370
|
+
}
|
|
6159
6371
|
|
|
6160
6372
|
// src/structuredOutput/manager.ts
|
|
6161
6373
|
var StructuredOutputManager = class {
|
|
@@ -8072,6 +8284,10 @@ function collectRecentTurns(messages, lastTurnsToKeep) {
|
|
|
8072
8284
|
function renderStructuredSummary(summary) {
|
|
8073
8285
|
if (!summary) return "";
|
|
8074
8286
|
const lines = ["Context summary:"];
|
|
8287
|
+
if (summary.user_directives && summary.user_directives.length > 0) {
|
|
8288
|
+
lines.push("User directives (still in force \u2014 follow them):");
|
|
8289
|
+
lines.push(...summary.user_directives.map((directive) => `- ${directive}`));
|
|
8290
|
+
}
|
|
8075
8291
|
if (summary.stable_facts.length > 0) {
|
|
8076
8292
|
lines.push("Stable facts:");
|
|
8077
8293
|
lines.push(...summary.stable_facts.map((fact) => `- ${fact.key}: ${fact.value}`));
|
|
@@ -8147,17 +8363,46 @@ function clampToBudget(messages, maxContextTokens) {
|
|
|
8147
8363
|
}
|
|
8148
8364
|
return working;
|
|
8149
8365
|
}
|
|
8366
|
+
function collectSummaryOnlyBody(body, hasSummary, lastTurnsToKeep) {
|
|
8367
|
+
if (!hasSummary) {
|
|
8368
|
+
return collectRecentTurns(body, Math.max(1, lastTurnsToKeep));
|
|
8369
|
+
}
|
|
8370
|
+
let boundary = -1;
|
|
8371
|
+
for (let index = body.length - 1; index >= 0; index -= 1) {
|
|
8372
|
+
if (isSyntheticSummaryMessage(body[index])) {
|
|
8373
|
+
boundary = index;
|
|
8374
|
+
break;
|
|
8375
|
+
}
|
|
8376
|
+
}
|
|
8377
|
+
let lastUserIndex = -1;
|
|
8378
|
+
for (let index = body.length - 1; index >= 0; index -= 1) {
|
|
8379
|
+
if (body[index].role === "user") {
|
|
8380
|
+
lastUserIndex = index;
|
|
8381
|
+
break;
|
|
8382
|
+
}
|
|
8383
|
+
}
|
|
8384
|
+
const keep = /* @__PURE__ */ new Set();
|
|
8385
|
+
const firstUserIndex = body.findIndex((message) => message.role === "user");
|
|
8386
|
+
if (firstUserIndex >= 0) keep.add(firstUserIndex);
|
|
8387
|
+
const verbatimFrom = Math.min(lastUserIndex >= 0 ? lastUserIndex : body.length, boundary + 1);
|
|
8388
|
+
for (let index = Math.max(0, verbatimFrom); index < body.length; index += 1) {
|
|
8389
|
+
if (!isSyntheticSummaryMessage(body[index])) keep.add(index);
|
|
8390
|
+
}
|
|
8391
|
+
return body.filter((_, index) => keep.has(index));
|
|
8392
|
+
}
|
|
8150
8393
|
function buildModelMessages(state, config) {
|
|
8151
8394
|
const rawMessages = state.messages || [];
|
|
8152
8395
|
if (config.context.policy === "raw") {
|
|
8153
8396
|
return clampToBudget(rawMessages, config.limits.maxContextTokens);
|
|
8154
8397
|
}
|
|
8155
|
-
const recentMessages = collectRecentTurns(rawMessages, config.context.lastTurnsToKeep);
|
|
8156
8398
|
const latestSummary = state.summaryRecords?.[state.summaryRecords.length - 1];
|
|
8157
8399
|
const summaryText = renderStructuredSummary(latestSummary);
|
|
8158
8400
|
const memoryText = renderMemoryBlock(state.memoryFacts);
|
|
8159
|
-
const systemMessage2 =
|
|
8160
|
-
const body = systemMessage2 ?
|
|
8401
|
+
const systemMessage2 = rawMessages[0]?.role === "system" ? rawMessages[0] : void 0;
|
|
8402
|
+
const body = config.context.policy === "summary_only" ? collectSummaryOnlyBody(systemMessage2 ? rawMessages.slice(1) : rawMessages, Boolean(summaryText), config.context.lastTurnsToKeep) : (() => {
|
|
8403
|
+
const recentMessages = collectRecentTurns(rawMessages, config.context.lastTurnsToKeep);
|
|
8404
|
+
return recentMessages[0]?.role === "system" ? recentMessages.slice(1) : recentMessages;
|
|
8405
|
+
})();
|
|
8161
8406
|
const syntheticContextMessages = [];
|
|
8162
8407
|
if (summaryText) {
|
|
8163
8408
|
syntheticContextMessages.push({ role: "system", name: "context_summary", content: summaryText });
|
|
@@ -8168,7 +8413,7 @@ function buildModelMessages(state, config) {
|
|
|
8168
8413
|
const assembled = [
|
|
8169
8414
|
...systemMessage2 ? [systemMessage2] : [],
|
|
8170
8415
|
...syntheticContextMessages,
|
|
8171
|
-
...
|
|
8416
|
+
...body
|
|
8172
8417
|
];
|
|
8173
8418
|
return clampToBudget(assembled, config.limits.maxContextTokens);
|
|
8174
8419
|
}
|
|
@@ -8213,6 +8458,7 @@ function extractJsonObject(text) {
|
|
|
8213
8458
|
}
|
|
8214
8459
|
function normalizeStructuredSummary(input, fallbackText) {
|
|
8215
8460
|
const summary = {
|
|
8461
|
+
user_directives: Array.isArray(input?.user_directives) ? input.user_directives.map((directive) => String(directive ?? "").trim()).filter(Boolean) : [],
|
|
8216
8462
|
stable_facts: Array.isArray(input?.stable_facts) ? input.stable_facts.filter((fact) => fact && typeof fact === "object").map((fact) => ({
|
|
8217
8463
|
key: String(fact.key || "unknown"),
|
|
8218
8464
|
value: String(fact.value || ""),
|
|
@@ -8273,7 +8519,7 @@ function extractCanonicalFacts(messages) {
|
|
|
8273
8519
|
return [...facts.values()];
|
|
8274
8520
|
}
|
|
8275
8521
|
function isSummarizedToolPlaceholder(content) {
|
|
8276
|
-
return
|
|
8522
|
+
return isCompactedToolContent(content);
|
|
8277
8523
|
}
|
|
8278
8524
|
function collectLatestTurnToolCallIds(messages) {
|
|
8279
8525
|
const ids = /* @__PURE__ */ new Set();
|
|
@@ -8332,11 +8578,16 @@ function runIntegrityCheck(previous, current) {
|
|
|
8332
8578
|
const previousKeys = new Set((previous?.stable_facts || []).map((fact) => fact.key));
|
|
8333
8579
|
const currentKeys = new Set(current.stable_facts.map((fact) => fact.key));
|
|
8334
8580
|
const obsoleteKeys = new Set(current.discarded_obsolete);
|
|
8335
|
-
const
|
|
8581
|
+
const currentDirectives = new Set(current.user_directives || []);
|
|
8582
|
+
const lostDirectives = (previous?.user_directives || []).filter((directive) => !currentDirectives.has(directive) && !obsoleteKeys.has(directive));
|
|
8583
|
+
const criticalFactLoss = [...previousKeys].some((key) => !obsoleteKeys.has(key) && !currentKeys.has(key)) || lostDirectives.length > 0;
|
|
8336
8584
|
const obsoleteFactRevived = current.stable_facts.some((fact) => obsoleteKeys.has(fact.key));
|
|
8337
8585
|
if (criticalFactLoss) {
|
|
8338
8586
|
notes.push("Missing previously retained facts; merged forward during integrity repair.");
|
|
8339
8587
|
}
|
|
8588
|
+
if (lostDirectives.length > 0) {
|
|
8589
|
+
notes.push(`Dropped ${lostDirectives.length} user directive(s); merged forward during integrity repair.`);
|
|
8590
|
+
}
|
|
8340
8591
|
if (obsoleteFactRevived) {
|
|
8341
8592
|
notes.push("Obsolete facts reappeared; removed during integrity repair.");
|
|
8342
8593
|
}
|
|
@@ -8359,7 +8610,13 @@ function repairStructuredSummary(previous, current, integrity) {
|
|
|
8359
8610
|
}
|
|
8360
8611
|
}
|
|
8361
8612
|
const filteredFacts = integrity.obsoleteFactRevived ? nextFacts.filter((fact) => !current.discarded_obsolete.includes(fact.key)) : nextFacts;
|
|
8362
|
-
|
|
8613
|
+
const directives = [...current.user_directives || []];
|
|
8614
|
+
for (const directive of previous.user_directives || []) {
|
|
8615
|
+
if (!directives.includes(directive) && !current.discarded_obsolete.includes(directive)) {
|
|
8616
|
+
directives.push(directive);
|
|
8617
|
+
}
|
|
8618
|
+
}
|
|
8619
|
+
return { ...current, user_directives: directives, stable_facts: filteredFacts };
|
|
8363
8620
|
}
|
|
8364
8621
|
function createContextSummarizeNode(opts) {
|
|
8365
8622
|
return async (state) => {
|
|
@@ -8433,6 +8690,7 @@ function createContextSummarizeNode(opts) {
|
|
|
8433
8690
|
|
|
8434
8691
|
Return exactly one JSON object with this schema:
|
|
8435
8692
|
{
|
|
8693
|
+
"user_directives": [string],
|
|
8436
8694
|
"stable_facts": [{ "key": string, "value": string, "confidence": number }],
|
|
8437
8695
|
"active_goals": [string],
|
|
8438
8696
|
"open_questions": [string],
|
|
@@ -8441,6 +8699,7 @@ Return exactly one JSON object with this schema:
|
|
|
8441
8699
|
}
|
|
8442
8700
|
|
|
8443
8701
|
Rules:
|
|
8702
|
+
- user_directives: standing instructions the user gave about HOW to work or answer for the rest of the conversation (language, format, tone, scope, things to always or never do) that still apply. NOT the tasks or questions themselves \u2014 "read the logs" is a task (an active goal), "always answer in Turkish" is a directive. Copy each directive close to verbatim; never merge, soften or drop one. Carry forward every directive from the previous structured summary unless the user explicitly revoked it \u2014 then put its exact text in discarded_obsolete.
|
|
8444
8703
|
- Keep stable_facts only for facts that future turns must remember.
|
|
8445
8704
|
- Put invalidated or superseded fact keys in discarded_obsolete.
|
|
8446
8705
|
- Preserve active_goals still relevant to the user.
|
|
@@ -8508,6 +8767,7 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
|
|
|
8508
8767
|
durationMs = Date.now() - startTime;
|
|
8509
8768
|
structuredSummary = normalizeStructuredSummary(void 0, previousSummary || conversationText.slice(0, 800));
|
|
8510
8769
|
structuredSummary = mergeStableFacts(structuredSummary, canonicalFacts);
|
|
8770
|
+
structuredSummary.user_directives = [...previousStructuredSummary?.user_directives || []];
|
|
8511
8771
|
integrity = { passed: true, criticalFactLoss: false, obsoleteFactRevived: false, notes: ["Fallback summary generated locally."] };
|
|
8512
8772
|
summaryText = renderStructuredSummary(structuredSummary);
|
|
8513
8773
|
const errorEvent = {
|
|
@@ -8742,6 +9002,21 @@ var todoUpdateItemSchema = zod.z.object({
|
|
|
8742
9002
|
status: todoStatusSchema.optional(),
|
|
8743
9003
|
evidence: zod.z.string().max(300).optional()
|
|
8744
9004
|
});
|
|
9005
|
+
var todoItemWireSchema = zod.z.object({
|
|
9006
|
+
id: zod.z.number().int().min(1).describe("Sequential id starting from 1 (write) or an existing id (update)"),
|
|
9007
|
+
step: zod.z.string().min(1).optional(),
|
|
9008
|
+
title: zod.z.string().min(1).optional(),
|
|
9009
|
+
description: zod.z.string().min(1).optional(),
|
|
9010
|
+
owner: zod.z.string().min(1).optional(),
|
|
9011
|
+
exitCriteria: zod.z.string().min(1).optional(),
|
|
9012
|
+
status: todoStatusSchema.optional().describe("Required for every item on write"),
|
|
9013
|
+
evidence: zod.z.string().max(300).optional()
|
|
9014
|
+
});
|
|
9015
|
+
function describeTodoIssue(issue) {
|
|
9016
|
+
if (!issue) return void 0;
|
|
9017
|
+
const path2 = issue.path.length > 0 ? `todoList[${issue.path[0]}]${issue.path.slice(1).map((p) => `.${String(p)}`).join("")}` : "todoList";
|
|
9018
|
+
return `${path2}: ${issue.message}`;
|
|
9019
|
+
}
|
|
8745
9020
|
function normalizeTodoItem(item, existing) {
|
|
8746
9021
|
const id = item.id ?? existing?.id;
|
|
8747
9022
|
const step = item.step || item.title || item.description || existing?.step || existing?.title || existing?.description || `Step ${id}`;
|
|
@@ -8858,7 +9133,7 @@ function createPlanTool(stateRef, toolName, description) {
|
|
|
8858
9133
|
schema: zod.z.object({
|
|
8859
9134
|
operation: zod.z.enum(["write", "read", "update"]),
|
|
8860
9135
|
expectedVersion: zod.z.number().int().min(0).optional(),
|
|
8861
|
-
todoList: zod.z.array(
|
|
9136
|
+
todoList: zod.z.array(todoItemWireSchema).optional()
|
|
8862
9137
|
}),
|
|
8863
9138
|
func: async ({ operation, expectedVersion, todoList }) => {
|
|
8864
9139
|
const toolStateRef = manageTodo._stateRef;
|
|
@@ -8924,7 +9199,10 @@ function createPlanTool(stateRef, toolName, description) {
|
|
|
8924
9199
|
return {
|
|
8925
9200
|
status: "error",
|
|
8926
9201
|
operation,
|
|
8927
|
-
|
|
9202
|
+
// The wire schema has `status` optional (one shape for write and
|
|
9203
|
+
// update), so a missing one is caught here — named, so the model
|
|
9204
|
+
// can fix the call.
|
|
9205
|
+
error: describeTodoIssue(parsed.error.issues[0]) || "Invalid todoList for write.",
|
|
8928
9206
|
version: currentVersion,
|
|
8929
9207
|
adherenceScore: stateRef.adherenceScore || 0
|
|
8930
9208
|
};
|
|
@@ -8947,7 +9225,7 @@ function createPlanTool(stateRef, toolName, description) {
|
|
|
8947
9225
|
return {
|
|
8948
9226
|
status: "error",
|
|
8949
9227
|
operation,
|
|
8950
|
-
error: parsed.error.issues[0]
|
|
9228
|
+
error: describeTodoIssue(parsed.error.issues[0]) || "Invalid todoList for update.",
|
|
8951
9229
|
version: currentVersion,
|
|
8952
9230
|
adherenceScore: stateRef.adherenceScore || 0
|
|
8953
9231
|
};
|
|
@@ -16607,6 +16885,7 @@ exports.httpSink = httpSink;
|
|
|
16607
16885
|
exports.inMemoryCheckpointStore = inMemoryCheckpointStore;
|
|
16608
16886
|
exports.inMemoryConversationStore = inMemoryConversationStore;
|
|
16609
16887
|
exports.isHookImplemented = isHookImplemented;
|
|
16888
|
+
exports.isOpenAIHostedEndpoint = isOpenAIHostedEndpoint;
|
|
16610
16889
|
exports.isSmartModel = isSmartModel;
|
|
16611
16890
|
exports.isValidIban = isValidIban;
|
|
16612
16891
|
exports.isValidLuhn = isValidLuhn;
|
|
@@ -16635,6 +16914,7 @@ exports.portkeyGateway = portkeyGateway;
|
|
|
16635
16914
|
exports.portkeyGuardrail = portkeyGuardrail;
|
|
16636
16915
|
exports.preopenSkills = preopenSkills;
|
|
16637
16916
|
exports.preopenToolCallId = preopenToolCallId;
|
|
16917
|
+
exports.prepareStrictToolMenu = prepareStrictToolMenu;
|
|
16638
16918
|
exports.promptInjectionGuard = promptInjectionGuard;
|
|
16639
16919
|
exports.rateLimit = rateLimit;
|
|
16640
16920
|
exports.readMemoryFacts = readMemoryFacts;
|
|
@@ -16654,6 +16934,7 @@ exports.resolveToolApprovalState = resolveToolApprovalState;
|
|
|
16654
16934
|
exports.resolveUserQuestionState = resolveUserQuestionState;
|
|
16655
16935
|
exports.responseCache = responseCache;
|
|
16656
16936
|
exports.restoreSnapshot = restoreSnapshot;
|
|
16937
|
+
exports.restoreToolCalls = restoreToolCalls;
|
|
16657
16938
|
exports.runSmartAgentEvalHarness = runSmartAgentEvalHarness;
|
|
16658
16939
|
exports.scoreItemsByRelevance = scoreItemsByRelevance;
|
|
16659
16940
|
exports.searchSkills = searchSkills;
|
|
@@ -16664,6 +16945,8 @@ exports.setTokenCounter = setTokenCounter;
|
|
|
16664
16945
|
exports.startStreamingSession = startStreamingSession;
|
|
16665
16946
|
exports.summarizeObject = summarizeObject;
|
|
16666
16947
|
exports.textFromContent = textFromContent;
|
|
16948
|
+
exports.toStrictCompatible = toStrictCompatible;
|
|
16949
|
+
exports.toStrictToolSchema = toStrictToolSchema;
|
|
16667
16950
|
exports.tokenize = tokenize;
|
|
16668
16951
|
exports.toolPolicy = toolPolicy;
|
|
16669
16952
|
exports.traceSessionToOtlp = traceSessionToOtlp;
|