@deepagents/context 0.12.0 → 0.12.1
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.js +140 -20
- package/dist/index.js.map +2 -2
- package/dist/lib/agent.d.ts.map +1 -1
- package/dist/lib/engine.d.ts +18 -0
- package/dist/lib/engine.d.ts.map +1 -1
- package/dist/lib/fragments.d.ts +44 -0
- package/dist/lib/fragments.d.ts.map +1 -1
- package/dist/lib/skills/fragments.d.ts +6 -2
- package/dist/lib/skills/fragments.d.ts.map +1 -1
- package/dist/lib/skills/index.d.ts +8 -3
- package/dist/lib/skills/index.d.ts.map +1 -1
- package/dist/lib/skills/types.d.ts +24 -2
- package/dist/lib/skills/types.d.ts.map +1 -1
- package/dist/lib/store/sqlite.store.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -222,7 +222,7 @@ function message(content) {
|
|
|
222
222
|
} : content;
|
|
223
223
|
return {
|
|
224
224
|
id: message2.id,
|
|
225
|
-
name:
|
|
225
|
+
name: message2.role,
|
|
226
226
|
data: "content",
|
|
227
227
|
type: "message",
|
|
228
228
|
persist: true,
|
|
@@ -244,6 +244,22 @@ function assistantText(content, options) {
|
|
|
244
244
|
parts: [{ type: "text", text: content }]
|
|
245
245
|
});
|
|
246
246
|
}
|
|
247
|
+
var LAZY_ID = Symbol("lazy-id");
|
|
248
|
+
function isLazyFragment(fragment2) {
|
|
249
|
+
return LAZY_ID in fragment2;
|
|
250
|
+
}
|
|
251
|
+
function lastAssistantMessage(content) {
|
|
252
|
+
return {
|
|
253
|
+
name: "assistant",
|
|
254
|
+
type: "message",
|
|
255
|
+
persist: true,
|
|
256
|
+
data: "content",
|
|
257
|
+
[LAZY_ID]: {
|
|
258
|
+
type: "last-assistant",
|
|
259
|
+
content
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
}
|
|
247
263
|
|
|
248
264
|
// packages/context/src/lib/renderers/abstract.renderer.ts
|
|
249
265
|
import pluralize from "pluralize";
|
|
@@ -1208,6 +1224,12 @@ var ContextEngine = class {
|
|
|
1208
1224
|
if (this.#pendingMessages.length === 0) {
|
|
1209
1225
|
return;
|
|
1210
1226
|
}
|
|
1227
|
+
for (let i = 0; i < this.#pendingMessages.length; i++) {
|
|
1228
|
+
const fragment2 = this.#pendingMessages[i];
|
|
1229
|
+
if (isLazyFragment(fragment2)) {
|
|
1230
|
+
this.#pendingMessages[i] = await this.#resolveLazyFragment(fragment2);
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1211
1233
|
let parentId = this.#branch.headMessageId;
|
|
1212
1234
|
const now = Date.now();
|
|
1213
1235
|
for (const fragment2 of this.#pendingMessages) {
|
|
@@ -1227,6 +1249,39 @@ var ContextEngine = class {
|
|
|
1227
1249
|
this.#branch.headMessageId = parentId;
|
|
1228
1250
|
this.#pendingMessages = [];
|
|
1229
1251
|
}
|
|
1252
|
+
/**
|
|
1253
|
+
* Resolve a lazy fragment by finding the appropriate ID.
|
|
1254
|
+
*/
|
|
1255
|
+
async #resolveLazyFragment(fragment2) {
|
|
1256
|
+
const lazy = fragment2[LAZY_ID];
|
|
1257
|
+
if (lazy.type === "last-assistant") {
|
|
1258
|
+
const lastId = await this.#getLastAssistantId();
|
|
1259
|
+
return assistantText(lazy.content, { id: lastId ?? crypto.randomUUID() });
|
|
1260
|
+
}
|
|
1261
|
+
throw new Error(`Unknown lazy fragment type: ${lazy.type}`);
|
|
1262
|
+
}
|
|
1263
|
+
/**
|
|
1264
|
+
* Find the most recent assistant message ID (pending or persisted).
|
|
1265
|
+
*/
|
|
1266
|
+
async #getLastAssistantId() {
|
|
1267
|
+
for (let i = this.#pendingMessages.length - 1; i >= 0; i--) {
|
|
1268
|
+
const msg = this.#pendingMessages[i];
|
|
1269
|
+
if (msg.name === "assistant" && !isLazyFragment(msg)) {
|
|
1270
|
+
return msg.id;
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
if (this.#branch?.headMessageId) {
|
|
1274
|
+
const chain = await this.#store.getMessageChain(
|
|
1275
|
+
this.#branch.headMessageId
|
|
1276
|
+
);
|
|
1277
|
+
for (let i = chain.length - 1; i >= 0; i--) {
|
|
1278
|
+
if (chain[i].name === "assistant") {
|
|
1279
|
+
return chain[i].id;
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
return void 0;
|
|
1284
|
+
}
|
|
1230
1285
|
/**
|
|
1231
1286
|
* Estimate token count and cost for the full context.
|
|
1232
1287
|
*
|
|
@@ -1506,6 +1561,35 @@ var ContextEngine = class {
|
|
|
1506
1561
|
consolidate() {
|
|
1507
1562
|
return void 0;
|
|
1508
1563
|
}
|
|
1564
|
+
/**
|
|
1565
|
+
* Extract skill path mappings from available_skills fragments.
|
|
1566
|
+
* Returns array of { host, sandbox } for mounting in sandbox filesystem.
|
|
1567
|
+
*
|
|
1568
|
+
* Reads the original `paths` configuration stored in fragment metadata
|
|
1569
|
+
* by the skills() fragment helper.
|
|
1570
|
+
*
|
|
1571
|
+
* @example
|
|
1572
|
+
* ```ts
|
|
1573
|
+
* const context = new ContextEngine({ store, chatId, userId })
|
|
1574
|
+
* .set(skills({ paths: [{ host: './skills', sandbox: '/skills' }] }));
|
|
1575
|
+
*
|
|
1576
|
+
* const mounts = context.getSkillMounts();
|
|
1577
|
+
* // [{ host: './skills', sandbox: '/skills' }]
|
|
1578
|
+
* ```
|
|
1579
|
+
*/
|
|
1580
|
+
getSkillMounts() {
|
|
1581
|
+
const mounts = [];
|
|
1582
|
+
for (const fragment2 of this.#fragments) {
|
|
1583
|
+
if (fragment2.name === "available_skills" && fragment2.metadata && Array.isArray(fragment2.metadata.paths)) {
|
|
1584
|
+
for (const mapping of fragment2.metadata.paths) {
|
|
1585
|
+
if (typeof mapping === "object" && mapping !== null && typeof mapping.host === "string" && typeof mapping.sandbox === "string") {
|
|
1586
|
+
mounts.push({ host: mapping.host, sandbox: mapping.sandbox });
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
return mounts;
|
|
1592
|
+
}
|
|
1509
1593
|
/**
|
|
1510
1594
|
* Inspect the full context state for debugging.
|
|
1511
1595
|
* Returns a JSON-serializable object with context information.
|
|
@@ -1816,7 +1900,7 @@ var errorRecoveryGuardrail = {
|
|
|
1816
1900
|
}
|
|
1817
1901
|
return logAndFail(
|
|
1818
1902
|
"Unknown error",
|
|
1819
|
-
`An error occurred: ${errorText
|
|
1903
|
+
`An error occurred: ${errorText}. Let me try a different approach.`
|
|
1820
1904
|
);
|
|
1821
1905
|
}
|
|
1822
1906
|
};
|
|
@@ -2642,9 +2726,13 @@ function discoverSkillsInDirectory(directory) {
|
|
|
2642
2726
|
|
|
2643
2727
|
// packages/context/src/lib/skills/fragments.ts
|
|
2644
2728
|
function skills(options) {
|
|
2729
|
+
const pathMapping = /* @__PURE__ */ new Map();
|
|
2730
|
+
for (const { host, sandbox } of options.paths) {
|
|
2731
|
+
pathMapping.set(host, sandbox);
|
|
2732
|
+
}
|
|
2645
2733
|
const skillsMap = /* @__PURE__ */ new Map();
|
|
2646
|
-
for (const
|
|
2647
|
-
const discovered = discoverSkillsInDirectory(
|
|
2734
|
+
for (const { host } of options.paths) {
|
|
2735
|
+
const discovered = discoverSkillsInDirectory(host);
|
|
2648
2736
|
for (const skill of discovered) {
|
|
2649
2737
|
skillsMap.set(skill.name, skill);
|
|
2650
2738
|
}
|
|
@@ -2659,14 +2747,26 @@ function skills(options) {
|
|
|
2659
2747
|
(s) => !options.exclude.includes(s.name)
|
|
2660
2748
|
);
|
|
2661
2749
|
}
|
|
2662
|
-
const skillFragments = filteredSkills.map((skill) =>
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2750
|
+
const skillFragments = filteredSkills.map((skill) => {
|
|
2751
|
+
const originalPath = skill.skillMdPath;
|
|
2752
|
+
let sandboxPath = originalPath;
|
|
2753
|
+
for (const [host, sandbox] of pathMapping) {
|
|
2754
|
+
if (originalPath.startsWith(host)) {
|
|
2755
|
+
const relativePath = originalPath.slice(host.length);
|
|
2756
|
+
sandboxPath = sandbox + relativePath;
|
|
2757
|
+
break;
|
|
2758
|
+
}
|
|
2668
2759
|
}
|
|
2669
|
-
|
|
2760
|
+
return {
|
|
2761
|
+
name: "skill",
|
|
2762
|
+
data: {
|
|
2763
|
+
name: skill.name,
|
|
2764
|
+
path: sandboxPath,
|
|
2765
|
+
description: skill.description
|
|
2766
|
+
},
|
|
2767
|
+
metadata: { originalPath }
|
|
2768
|
+
};
|
|
2769
|
+
});
|
|
2670
2770
|
return {
|
|
2671
2771
|
name: "available_skills",
|
|
2672
2772
|
data: [
|
|
@@ -2675,7 +2775,11 @@ function skills(options) {
|
|
|
2675
2775
|
data: SKILLS_INSTRUCTIONS
|
|
2676
2776
|
},
|
|
2677
2777
|
...skillFragments
|
|
2678
|
-
]
|
|
2778
|
+
],
|
|
2779
|
+
metadata: {
|
|
2780
|
+
paths: options.paths
|
|
2781
|
+
// Store original path mappings for getSkillMounts()
|
|
2782
|
+
}
|
|
2679
2783
|
};
|
|
2680
2784
|
}
|
|
2681
2785
|
var SKILLS_INSTRUCTIONS = `When a user's request matches one of the skills listed below, read the skill's SKILL.md file to get detailed instructions before proceeding. Skills provide specialized knowledge and workflows for specific tasks.
|
|
@@ -2933,18 +3037,19 @@ var SqliteContextStore = class extends ContextStore {
|
|
|
2933
3037
|
// Message Operations (Graph Nodes)
|
|
2934
3038
|
// ==========================================================================
|
|
2935
3039
|
async addMessage(message2) {
|
|
3040
|
+
const existingParent = message2.parentId === message2.id ? this.#db.prepare("SELECT parentId FROM messages WHERE id = ?").get(message2.id) : void 0;
|
|
3041
|
+
const parentId = message2.parentId === message2.id ? existingParent?.parentId ?? null : message2.parentId;
|
|
2936
3042
|
this.#db.prepare(
|
|
2937
3043
|
`INSERT INTO messages (id, chatId, parentId, name, type, data, createdAt)
|
|
2938
3044
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
2939
3045
|
ON CONFLICT(id) DO UPDATE SET
|
|
2940
|
-
parentId = excluded.parentId,
|
|
2941
3046
|
name = excluded.name,
|
|
2942
3047
|
type = excluded.type,
|
|
2943
3048
|
data = excluded.data`
|
|
2944
3049
|
).run(
|
|
2945
3050
|
message2.id,
|
|
2946
3051
|
message2.chatId,
|
|
2947
|
-
|
|
3052
|
+
parentId,
|
|
2948
3053
|
message2.name,
|
|
2949
3054
|
message2.type ?? null,
|
|
2950
3055
|
JSON.stringify(message2.data),
|
|
@@ -3487,13 +3592,9 @@ var Agent = class _Agent {
|
|
|
3487
3592
|
writer.write({ type: "finish" });
|
|
3488
3593
|
return;
|
|
3489
3594
|
}
|
|
3490
|
-
writer
|
|
3491
|
-
type: "text-delta",
|
|
3492
|
-
id: generateId2(),
|
|
3493
|
-
delta: ` ${failureFeedback}`
|
|
3494
|
-
});
|
|
3595
|
+
writeText(writer, failureFeedback);
|
|
3495
3596
|
const selfCorrectionText = accumulatedText + " " + failureFeedback;
|
|
3496
|
-
context.set(
|
|
3597
|
+
context.set(lastAssistantMessage(selfCorrectionText));
|
|
3497
3598
|
await context.save();
|
|
3498
3599
|
currentResult = await this.#createRawStream(
|
|
3499
3600
|
contextVariables,
|
|
@@ -3598,6 +3699,22 @@ var repairToolCall = async ({
|
|
|
3598
3699
|
});
|
|
3599
3700
|
return { ...toolCall, input: JSON.stringify(output) };
|
|
3600
3701
|
};
|
|
3702
|
+
function writeText(writer, text) {
|
|
3703
|
+
const feedbackPartId = generateId2();
|
|
3704
|
+
writer.write({
|
|
3705
|
+
id: feedbackPartId,
|
|
3706
|
+
type: "text-start"
|
|
3707
|
+
});
|
|
3708
|
+
writer.write({
|
|
3709
|
+
id: feedbackPartId,
|
|
3710
|
+
type: "text-delta",
|
|
3711
|
+
delta: ` ${text}`
|
|
3712
|
+
});
|
|
3713
|
+
writer.write({
|
|
3714
|
+
id: feedbackPartId,
|
|
3715
|
+
type: "text-end"
|
|
3716
|
+
});
|
|
3717
|
+
}
|
|
3601
3718
|
|
|
3602
3719
|
// packages/context/src/lib/render.ts
|
|
3603
3720
|
function render(tag, ...fragments) {
|
|
@@ -3622,6 +3739,7 @@ export {
|
|
|
3622
3739
|
DockerfileBuildError,
|
|
3623
3740
|
DockerfileStrategy,
|
|
3624
3741
|
InMemoryContextStore,
|
|
3742
|
+
LAZY_ID,
|
|
3625
3743
|
MarkdownRenderer,
|
|
3626
3744
|
ModelsRegistry,
|
|
3627
3745
|
MountPathError,
|
|
@@ -3658,7 +3776,9 @@ export {
|
|
|
3658
3776
|
isDockerfileOptions,
|
|
3659
3777
|
isFragment,
|
|
3660
3778
|
isFragmentObject,
|
|
3779
|
+
isLazyFragment,
|
|
3661
3780
|
isMessageFragment,
|
|
3781
|
+
lastAssistantMessage,
|
|
3662
3782
|
loadSkillMetadata,
|
|
3663
3783
|
message,
|
|
3664
3784
|
parseFrontmatter,
|