@zenera/neo 1.1.17 → 1.1.18
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/README.md +1 -1
- package/dist/memory/store.js +2 -2
- package/dist/project/load.d.ts +13 -1
- package/dist/project/load.js +13 -5
- package/dist/prompt.d.ts +2 -0
- package/dist/prompt.js +1 -1
- package/dist/skill-providers/file.js +5 -3
- package/dist/skills.d.ts +7 -0
- package/dist/skills.js +11 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -166,7 +166,7 @@ of surfacing three turns into a run as a confused model.
|
|
|
166
166
|
[docs/projects.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/projects.md) ·
|
|
167
167
|
[docs/agents-yaml.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/agents-yaml.md)
|
|
168
168
|
· and
|
|
169
|
-
[`examples/`](https://github.com/andreyryabov/ZeneraNeo/tree/main/examples) for
|
|
169
|
+
[`examples/sdk/`](https://github.com/andreyryabov/ZeneraNeo/tree/main/examples/sdk) for
|
|
170
170
|
eight worked demos, from a single agent to a project loaded entirely from a
|
|
171
171
|
folder.
|
|
172
172
|
|
package/dist/memory/store.js
CHANGED
|
@@ -51,7 +51,7 @@ export class MemoryStore {
|
|
|
51
51
|
const b = opts.embedding;
|
|
52
52
|
if (a.model !== b.model || a.dimensions !== b.dimensions) {
|
|
53
53
|
throw new MemoryError(`this memory was embedded with ${a.model} (${a.dimensions}d), ` +
|
|
54
|
-
`but ${b.model} (${b.dimensions}d) is configured`, '
|
|
54
|
+
`but ${b.model} (${b.dimensions}d) is configured`, 'restore the original model, or start a new memory');
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
const graph = manifest
|
|
@@ -79,7 +79,7 @@ export class MemoryStore {
|
|
|
79
79
|
if (held) {
|
|
80
80
|
if (held.model !== embedding.model || held.dimensions !== embedding.dimensions) {
|
|
81
81
|
throw new MemoryError(`this memory was embedded with ${held.model} (${held.dimensions}d), ` +
|
|
82
|
-
`but ${embedding.model} (${embedding.dimensions}d) is configured`, '
|
|
82
|
+
`but ${embedding.model} (${embedding.dimensions}d) is configured`, 'restore the original model, or start a new memory');
|
|
83
83
|
}
|
|
84
84
|
return;
|
|
85
85
|
}
|
package/dist/project/load.d.ts
CHANGED
|
@@ -56,6 +56,13 @@ export interface ProjectOptions<TCtx = unknown> {
|
|
|
56
56
|
*/
|
|
57
57
|
registry?: ModelRegistry;
|
|
58
58
|
memory?: MemoryIndex;
|
|
59
|
+
/**
|
|
60
|
+
* Another directory to keep the memory graph in, relative to the project
|
|
61
|
+
* root when it is not absolute. Whoever sets it must mount that directory
|
|
62
|
+
* as `/memory` too, or the agent reads its remembered files from one graph
|
|
63
|
+
* and writes to another.
|
|
64
|
+
*/
|
|
65
|
+
memoryDir?: string;
|
|
59
66
|
/** turns an agent-visible path into a host path, so files can be remembered */
|
|
60
67
|
resolveFile?: (path: string) => string;
|
|
61
68
|
payloads?: PayloadStore;
|
|
@@ -166,8 +173,13 @@ export declare function projectRegistry<TCtx>(config: ProjectConfig, opts?: Proj
|
|
|
166
173
|
* with the front end, which has to mount the same directory into the sandbox:
|
|
167
174
|
* two answers to this question would mean `/memory` pointing somewhere the
|
|
168
175
|
* graph is not.
|
|
176
|
+
*
|
|
177
|
+
* `override` is the host pointing the run at another graph — `zen run
|
|
178
|
+
* --memory`. It answers for a project that declares no memory at all, because
|
|
179
|
+
* naming a directory is the declaration; the agents bound to it are still the
|
|
180
|
+
* ones that said `memory: true`.
|
|
169
181
|
*/
|
|
170
|
-
export declare function memoryDir(root: string, config: ProjectConfig): string | undefined;
|
|
182
|
+
export declare function memoryDir(root: string, config: ProjectConfig, override?: string): string | undefined;
|
|
171
183
|
/**
|
|
172
184
|
* Where each skill directory appears in the agent's namespace.
|
|
173
185
|
*
|
package/dist/project/load.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
2
|
-
import { basename, join, relative, sep } from 'node:path';
|
|
2
|
+
import { basename, join, relative, resolve, sep } from 'node:path';
|
|
3
3
|
import { Agent, AgentRegistry } from "../agent.js";
|
|
4
4
|
import { RunStream } from "../events.js";
|
|
5
5
|
import { MemoryIndex } from "../memory/index.js";
|
|
@@ -74,7 +74,7 @@ export async function loadProject(dir, opts = {}) {
|
|
|
74
74
|
// The default is resolved here rather than on first use, so a broken
|
|
75
75
|
// `embedding:` fails at load like a broken `model:` does.
|
|
76
76
|
embedders(config.embedding, 'embedding');
|
|
77
|
-
const memory = opts.memory ?? (await openMemory(root, config, embedders));
|
|
77
|
+
const memory = opts.memory ?? (await openMemory(root, config, embedders, opts.memoryDir));
|
|
78
78
|
return new AgentProject({
|
|
79
79
|
root,
|
|
80
80
|
source,
|
|
@@ -392,8 +392,16 @@ function memoryFor(spec) {
|
|
|
392
392
|
* with the front end, which has to mount the same directory into the sandbox:
|
|
393
393
|
* two answers to this question would mean `/memory` pointing somewhere the
|
|
394
394
|
* graph is not.
|
|
395
|
+
*
|
|
396
|
+
* `override` is the host pointing the run at another graph — `zen run
|
|
397
|
+
* --memory`. It answers for a project that declares no memory at all, because
|
|
398
|
+
* naming a directory is the declaration; the agents bound to it are still the
|
|
399
|
+
* ones that said `memory: true`.
|
|
395
400
|
*/
|
|
396
|
-
export function memoryDir(root, config) {
|
|
401
|
+
export function memoryDir(root, config, override) {
|
|
402
|
+
if (override) {
|
|
403
|
+
return resolve(root, override);
|
|
404
|
+
}
|
|
397
405
|
if (!config.memory && !config.agents.some((a) => a.memory)) {
|
|
398
406
|
return undefined;
|
|
399
407
|
}
|
|
@@ -405,8 +413,8 @@ export function memoryDir(root, config) {
|
|
|
405
413
|
* to it still counts: it is how a project declares the graph `zen memory`
|
|
406
414
|
* inspects between runs.
|
|
407
415
|
*/
|
|
408
|
-
async function openMemory(root, config, embedders) {
|
|
409
|
-
const dir = memoryDir(root, config);
|
|
416
|
+
async function openMemory(root, config, embedders, override) {
|
|
417
|
+
const dir = memoryDir(root, config, override);
|
|
410
418
|
if (!dir) {
|
|
411
419
|
return undefined;
|
|
412
420
|
}
|
package/dist/prompt.d.ts
CHANGED
|
@@ -58,6 +58,8 @@ export interface ComposedPrompt {
|
|
|
58
58
|
/** the editable contributors, in the order they were rendered */
|
|
59
59
|
sources: PromptSource[];
|
|
60
60
|
}
|
|
61
|
+
/** `&`, `<` and `"` are the three that would end the attribute or the tag. */
|
|
62
|
+
export declare function attribute(value: string): string;
|
|
61
63
|
/**
|
|
62
64
|
* Renders the authored parts, then the kernel's derived text, into one string —
|
|
63
65
|
* and reports which documents went into it.
|
package/dist/prompt.js
CHANGED
|
@@ -22,7 +22,7 @@ export function promptFile(path, section, src) {
|
|
|
22
22
|
}
|
|
23
23
|
const SEPARATOR = '\n\n';
|
|
24
24
|
/** `&`, `<` and `"` are the three that would end the attribute or the tag. */
|
|
25
|
-
function attribute(value) {
|
|
25
|
+
export function attribute(value) {
|
|
26
26
|
return value.replace(/&/g, '&').replace(/</g, '<').replace(/"/g, '"');
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readFile, readdir } from 'node:fs/promises';
|
|
2
|
-
import { basename, join, resolve } from 'node:path';
|
|
2
|
+
import { basename, join, relative, resolve } from 'node:path';
|
|
3
3
|
import { selectTools } from "../types.js";
|
|
4
4
|
// ---------------------------------------------------------------------------
|
|
5
5
|
// Filesystem-backed skill provider
|
|
@@ -83,6 +83,7 @@ export class FileSkillProvider {
|
|
|
83
83
|
...entry.summary,
|
|
84
84
|
content: entry.content,
|
|
85
85
|
file: entry.file,
|
|
86
|
+
src: entry.src,
|
|
86
87
|
...(tools.length ? { tools } : {}),
|
|
87
88
|
...(entry.at ? { path: entry.at } : {}),
|
|
88
89
|
};
|
|
@@ -122,19 +123,20 @@ export class FileSkillProvider {
|
|
|
122
123
|
// Only a folder skill has files of its own to point at, and
|
|
123
124
|
// only when the host said where the directory can be reached.
|
|
124
125
|
const at = folder && dir.at ? `${dir.at}/${basename(folder)}` : undefined;
|
|
125
|
-
const entry = parse(raw, base, file, folder, at);
|
|
126
|
+
const entry = parse(raw, base, file, relative(dir.path, file), folder, at);
|
|
126
127
|
index.set(entry.summary.name, entry);
|
|
127
128
|
}
|
|
128
129
|
}
|
|
129
130
|
return index;
|
|
130
131
|
}
|
|
131
132
|
}
|
|
132
|
-
function parse(raw, base, file, folder, at) {
|
|
133
|
+
function parse(raw, base, file, src, folder, at) {
|
|
133
134
|
const { data, body } = frontmatter(raw);
|
|
134
135
|
const tags = toList(data.tags);
|
|
135
136
|
const tools = toList(data.tools);
|
|
136
137
|
return {
|
|
137
138
|
file,
|
|
139
|
+
src,
|
|
138
140
|
folder,
|
|
139
141
|
...(at ? { at } : {}),
|
|
140
142
|
content: body,
|
package/dist/skills.d.ts
CHANGED
|
@@ -33,6 +33,13 @@ export interface Skill extends SkillSummary {
|
|
|
33
33
|
path?: string;
|
|
34
34
|
/** absolute path of the source file, if known (set by file-backed providers) */
|
|
35
35
|
file?: string;
|
|
36
|
+
/**
|
|
37
|
+
* The source document *as the model is told it*, written onto the block as
|
|
38
|
+
* `src`. Deliberately not `file`: that one is absolute, so it would put a
|
|
39
|
+
* home directory in the prompt and give two machines two different cache
|
|
40
|
+
* prefixes for the same catalog.
|
|
41
|
+
*/
|
|
42
|
+
src?: string;
|
|
36
43
|
}
|
|
37
44
|
export interface SkillProvider {
|
|
38
45
|
readonly id: string;
|
package/dist/skills.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { hash } from "./payload.js";
|
|
2
|
+
import { attribute } from "./prompt.js";
|
|
2
3
|
import { projected } from "./trajectory.js";
|
|
3
4
|
import { SKILL_LOAD_TOOL, SKILL_SEARCH_TOOL, tool, withEffects, } from "./types.js";
|
|
4
5
|
export function skillContentHash(s) {
|
|
@@ -7,15 +8,21 @@ export function skillContentHash(s) {
|
|
|
7
8
|
export function renderSkills(skills) {
|
|
8
9
|
return skills
|
|
9
10
|
.map((s) => {
|
|
10
|
-
const
|
|
11
|
+
const attrs = [
|
|
12
|
+
` name="${attribute(s.name)}"`,
|
|
13
|
+
s.version ? ` version="${attribute(s.version)}"` : '',
|
|
14
|
+
// Same contract as a prompt block's `src`: the document to edit,
|
|
15
|
+
// under a name that is the same on every machine.
|
|
16
|
+
s.src ? ` src="${attribute(s.src)}"` : '',
|
|
17
|
+
].join('');
|
|
11
18
|
// One line, and only when the files are reachable. Without it the
|
|
12
19
|
// model has the instructions and no way to act on the half of them
|
|
13
20
|
// that names a file.
|
|
14
21
|
const where = s.path
|
|
15
|
-
?
|
|
16
|
-
'relative to that directory.\n'
|
|
22
|
+
? `This skill's files are at ${s.path}, read-only. Paths written in it are ` +
|
|
23
|
+
'relative to that directory.\n\n'
|
|
17
24
|
: '';
|
|
18
|
-
return
|
|
25
|
+
return `<skill${attrs}>\n${where}${s.content}\n</skill>`;
|
|
19
26
|
})
|
|
20
27
|
.join('\n\n');
|
|
21
28
|
}
|