@ai-ecoverse/slicc-agent 3.13.1 → 3.14.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/README.md +19 -2
- package/bin/agent +1 -1
- package/dist/agents.js.map +2 -2
- package/dist/client.js +5 -1
- package/dist/client.js.map +2 -2
- package/dist/control.js +14 -1
- package/dist/control.js.map +2 -2
- package/dist/host.js +6 -2
- package/dist/host.js.map +2 -2
- package/dist/main.js +19 -2
- package/dist/main.js.map +2 -2
- package/dist/memory/context.js +91 -0
- package/dist/memory/context.js.map +7 -0
- package/dist/memory/format.js +251 -0
- package/dist/memory/format.js.map +7 -0
- package/dist/memory/index.js +32 -0
- package/dist/memory/index.js.map +7 -0
- package/dist/memory/prompt.js +175 -0
- package/dist/memory/prompt.js.map +7 -0
- package/dist/memory/runtime.js +194 -0
- package/dist/memory/runtime.js.map +7 -0
- package/dist/memory/store.js +153 -0
- package/dist/memory/store.js.map +7 -0
- package/dist/roles/frontmatter.js +9 -4
- package/dist/roles/frontmatter.js.map +2 -2
- package/dist/roles/roles.js +55 -11
- package/dist/roles/roles.js.map +2 -2
- package/dist/scoops/cli.js +3 -0
- package/dist/scoops/cli.js.map +2 -2
- package/dist/scoops/index.js +3 -2
- package/dist/scoops/index.js.map +2 -2
- package/dist/scoops/requests.js +1 -1
- package/dist/scoops/requests.js.map +2 -2
- package/dist/scoops/service.js +3 -0
- package/dist/scoops/service.js.map +2 -2
- package/dist/scoops/sync.js +1 -0
- package/dist/scoops/sync.js.map +2 -2
- package/dist/services.js.map +2 -2
- package/dist/skills/index.js +8 -1
- package/dist/skills/index.js.map +2 -2
- package/dist/spectrum/index.js +5 -1
- package/dist/spectrum/index.js.map +3 -3
- package/dist/spectrum/memory-port.js +64 -0
- package/dist/spectrum/memory-port.js.map +7 -0
- package/dist/types/agents.d.ts +7 -0
- package/dist/types/client.d.ts +3 -0
- package/dist/types/control.d.ts +2 -1
- package/dist/types/host.d.ts +2 -0
- package/dist/types/memory/context.d.ts +27 -0
- package/dist/types/memory/format.d.ts +67 -0
- package/dist/types/memory/index.d.ts +12 -0
- package/dist/types/memory/prompt.d.ts +48 -0
- package/dist/types/memory/runtime.d.ts +45 -0
- package/dist/types/memory/store.d.ts +41 -0
- package/dist/types/roles/frontmatter.d.ts +1 -1
- package/dist/types/roles/roles.d.ts +8 -0
- package/dist/types/scoops/cli.d.ts +1 -0
- package/dist/types/scoops/index.d.ts +1 -0
- package/dist/types/scoops/requests.d.ts +1 -1
- package/dist/types/scoops/service.d.ts +1 -0
- package/dist/types/services.d.ts +15 -0
- package/dist/types/spectrum/index.d.ts +3 -0
- package/dist/types/spectrum/memory-port.d.ts +12 -0
- package/package.json +2 -2
- package/packages/vfs-root/skills/memory/SKILL.md +48 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Context } from '@earendil-works/chord';
|
|
2
|
+
import type { ExecutionEnv } from '@earendil-works/pi-durable/env';
|
|
3
|
+
import { type Change, type MemoryEntry } from './format.ts';
|
|
4
|
+
export declare const GLOBAL = "global";
|
|
5
|
+
export declare const ROLE_PREFIX = "role:";
|
|
6
|
+
export type RoleMemory = {
|
|
7
|
+
scope: 'user' | 'project';
|
|
8
|
+
path: string;
|
|
9
|
+
};
|
|
10
|
+
export type Place = {
|
|
11
|
+
scope: string;
|
|
12
|
+
file: string;
|
|
13
|
+
label: string;
|
|
14
|
+
};
|
|
15
|
+
export type Written = {
|
|
16
|
+
entry: MemoryEntry | null;
|
|
17
|
+
found: boolean;
|
|
18
|
+
bytes: number;
|
|
19
|
+
redacted: number;
|
|
20
|
+
file: string;
|
|
21
|
+
};
|
|
22
|
+
export declare function memoryRoot(home: string): string;
|
|
23
|
+
export declare function roleRoot(home: string): string;
|
|
24
|
+
export declare function safePath(path: string): string | null;
|
|
25
|
+
export declare function placeOf(home: string, scope: string): Place | null;
|
|
26
|
+
export declare function projectRoot(env: Pick<ExecutionEnv, 'exists'>, cwd: string, context: Context): Promise<string | null>;
|
|
27
|
+
export declare function rolePlace(env: Pick<ExecutionEnv, 'exists'>, home: string, memory: RoleMemory, cwd: string, context: Context): Promise<Place | {
|
|
28
|
+
problem: string;
|
|
29
|
+
}>;
|
|
30
|
+
type Files = Pick<ExecutionEnv, 'readTextFile' | 'writeFile' | 'createDir' | 'canonicalPath' | 'fileInfo'>;
|
|
31
|
+
export declare class MemoryFiles {
|
|
32
|
+
#private;
|
|
33
|
+
constructor(env: Files);
|
|
34
|
+
read(file: string, context: Context): Promise<{
|
|
35
|
+
text: string;
|
|
36
|
+
updatedAt: number;
|
|
37
|
+
} | null>;
|
|
38
|
+
entries(place: Place, context: Context): Promise<MemoryEntry[]>;
|
|
39
|
+
change(place: Place, change: Change, context: Context): Promise<Written>;
|
|
40
|
+
}
|
|
41
|
+
export {};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { Context } from '@earendil-works/chord';
|
|
2
2
|
import type { ExecutionEnv } from '@earendil-works/pi-durable/env';
|
|
3
|
+
import type { RoleMemory } from '../memory/store.ts';
|
|
4
|
+
import { type FrontmatterValue } from './frontmatter.ts';
|
|
3
5
|
export type RoleSource = 'builtin' | 'package' | 'user' | 'project';
|
|
4
6
|
export type Thinking = 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh';
|
|
5
7
|
export interface Role {
|
|
@@ -12,6 +14,11 @@ export interface Role {
|
|
|
12
14
|
thinking?: Thinking;
|
|
13
15
|
aliases: string[];
|
|
14
16
|
output?: string;
|
|
17
|
+
memory?: RoleMemory;
|
|
18
|
+
context?: {
|
|
19
|
+
project: boolean;
|
|
20
|
+
global: boolean;
|
|
21
|
+
};
|
|
15
22
|
source: RoleSource;
|
|
16
23
|
path: string;
|
|
17
24
|
}
|
|
@@ -32,6 +39,7 @@ export interface RoleSourceDir {
|
|
|
32
39
|
source: RoleSource;
|
|
33
40
|
dir: string;
|
|
34
41
|
}
|
|
42
|
+
export declare function roleMemory(value: FrontmatterValue): RoleMemory | undefined;
|
|
35
43
|
export declare function parseRole(text: string, source: RoleSource, path: string, warnings: string[]): Role | undefined;
|
|
36
44
|
export interface LoadOptions {
|
|
37
45
|
files: RoleFiles;
|
|
@@ -20,6 +20,7 @@ export interface CliOptions {
|
|
|
20
20
|
alive?: (pid: number) => Promise<boolean>;
|
|
21
21
|
now?: () => number;
|
|
22
22
|
sprinkle?: (argv: readonly string[], caller: string | null, context: Context) => Promise<Answer>;
|
|
23
|
+
memory?: (argv: readonly string[], caller: string | null, context: Context) => Promise<Answer>;
|
|
23
24
|
}
|
|
24
25
|
export type Deps = CliOptions & {
|
|
25
26
|
now: () => number;
|
|
@@ -25,6 +25,7 @@ export interface AttachOptions {
|
|
|
25
25
|
alive?: (pid: number) => Promise<boolean>;
|
|
26
26
|
reads: () => readonly string[];
|
|
27
27
|
sprinkle?: CliOptions['sprinkle'];
|
|
28
|
+
memory?: CliOptions['memory'];
|
|
28
29
|
}
|
|
29
30
|
export interface ScoopsRuntime {
|
|
30
31
|
roles(context: Context): Promise<Roles>;
|
|
@@ -6,7 +6,7 @@ export declare const PROTOCOL = "slicc-agent/1";
|
|
|
6
6
|
export declare const STALE_MS: number;
|
|
7
7
|
export interface Request {
|
|
8
8
|
id: string;
|
|
9
|
-
as: 'agent' | 'subagent' | 'sprinkle';
|
|
9
|
+
as: 'agent' | 'subagent' | 'sprinkle' | 'memory';
|
|
10
10
|
caller: string;
|
|
11
11
|
cwd: string;
|
|
12
12
|
pid: number | null;
|
package/dist/types/services.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type Context, type JsonValue, type ReplicatedState } from '@earendil-works/chord';
|
|
2
2
|
import type { ConversationView } from '@earendil-works/pi-durable';
|
|
3
|
+
import type { MemoryEntry, MemoryScope, MemoryTag } from './memory/format.ts';
|
|
3
4
|
import type { Sprinkle } from './sprinkles/kind.ts';
|
|
4
5
|
export type SendMode = 'steer' | 'followUp' | 'reject';
|
|
5
6
|
export interface SendRequest {
|
|
@@ -61,6 +62,18 @@ export interface AgentControl {
|
|
|
61
62
|
delivered: boolean;
|
|
62
63
|
}>;
|
|
63
64
|
sprinkleCall(sprinkleId: string, method: string, args: JsonValue[], context: Context): Promise<JsonValue>;
|
|
65
|
+
memorySave(draft: MemoryDraft, context: Context): Promise<MemoryEntry>;
|
|
66
|
+
memoryRemove(id: string, context: Context): Promise<{
|
|
67
|
+
removed: boolean;
|
|
68
|
+
}>;
|
|
69
|
+
}
|
|
70
|
+
export interface MemoryDraft {
|
|
71
|
+
id: string | null;
|
|
72
|
+
scope: string;
|
|
73
|
+
section: string;
|
|
74
|
+
title: string;
|
|
75
|
+
body: string;
|
|
76
|
+
tag: MemoryTag | null;
|
|
64
77
|
}
|
|
65
78
|
export type Created = {
|
|
66
79
|
id: string;
|
|
@@ -120,6 +133,8 @@ export interface AgentTranscript {
|
|
|
120
133
|
readonly views: ReplicatedState<Record<string, ConversationView>>;
|
|
121
134
|
readonly commands: ReplicatedState<Command[]>;
|
|
122
135
|
readonly sprinkles: ReplicatedState<Sprinkle[]>;
|
|
136
|
+
readonly memories: ReplicatedState<MemoryEntry[]>;
|
|
137
|
+
readonly memoryScopes: ReplicatedState<MemoryScope[]>;
|
|
123
138
|
}
|
|
124
139
|
export interface Command {
|
|
125
140
|
name: string;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { AgentConnection } from '../client.ts';
|
|
2
2
|
import { AgentAdapter } from './agent-port.ts';
|
|
3
|
+
import { MemoryAdapter } from './memory-port.ts';
|
|
3
4
|
import { type Login, SettingsAdapter } from './settings-port.ts';
|
|
4
5
|
import { SprinkleAdapter } from './sprinkle-port.ts';
|
|
5
6
|
import { TrayAdapter } from './tray-port.ts';
|
|
6
7
|
export { AgentAdapter, CONE } from './agent-port.ts';
|
|
8
|
+
export { MemoryAdapter } from './memory-port.ts';
|
|
7
9
|
export { assistant, errorAction, errorPart, isBusy, queued, textOf, toMessages, } from './messages.ts';
|
|
8
10
|
export { type Login, SETTINGS_KEY, SettingsAdapter } from './settings-port.ts';
|
|
9
11
|
export { SprinkleAdapter } from './sprinkle-port.ts';
|
|
@@ -16,4 +18,5 @@ export declare function createAgentModel(connection: AgentConnection, options?:
|
|
|
16
18
|
settings: SettingsAdapter;
|
|
17
19
|
tray: TrayAdapter;
|
|
18
20
|
sprinkles: SprinkleAdapter;
|
|
21
|
+
memory: MemoryAdapter;
|
|
19
22
|
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Memory, MemoryDraft, MemoryEvents, MemoryPort } from '@ai-ecoverse/slicc-spectrum/ui';
|
|
2
|
+
import type { AgentConnection } from '../client.ts';
|
|
3
|
+
import { type MemoryScope } from '../memory/format.ts';
|
|
4
|
+
import { Emitter } from './emitter.ts';
|
|
5
|
+
export declare class MemoryAdapter extends Emitter<MemoryEvents> implements MemoryPort {
|
|
6
|
+
#private;
|
|
7
|
+
constructor(connection: AgentConnection);
|
|
8
|
+
list(): readonly Memory[];
|
|
9
|
+
scopes(): readonly MemoryScope[];
|
|
10
|
+
save(draft: MemoryDraft): Memory;
|
|
11
|
+
remove(id: string): void;
|
|
12
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-ecoverse/slicc-agent",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.14.0",
|
|
4
4
|
"description": "SLICC's agent core on pi durable: an agent worker, session storage, remoting and pi extensions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"release": "semantic-release"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
|
-
"@ai-ecoverse/slicc-shared-web": "1.
|
|
64
|
+
"@ai-ecoverse/slicc-shared-web": "1.10.0",
|
|
65
65
|
"@ai-ecoverse/slicc-spectrum": "1.27.3",
|
|
66
66
|
"@ai-ecoverse/wasm-bash": "5.3.0-8",
|
|
67
67
|
"@ai-ecoverse/wasm-coreutils": "9.7.0-3",
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: memory
|
|
3
|
+
description: Use this when the user asks what you remember, tells you to remember or forget something, corrects how you work, or when you learn a durable fact worth keeping across conversations. Covers the memory files, the memory_write tool, scopes and the `memory` command.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Memory
|
|
7
|
+
|
|
8
|
+
Memory is plain markdown, one `MEMORY.md` per scope, shown to you in the `memory` section of your system prompt (the first 200 lines of each file):
|
|
9
|
+
|
|
10
|
+
| Scope | File | Who writes it |
|
|
11
|
+
| --- | --- | --- |
|
|
12
|
+
| `global` | `~/.pi/agent/memory/MEMORY.md` | cones, for every agent |
|
|
13
|
+
| a cone (`cone`, `cone-2`, …) | `~/.pi/agent/memory/<cone>/MEMORY.md` | that cone |
|
|
14
|
+
| a role (`role:<path>`) | `~/.pi/agent/agent-memory/<path>/MEMORY.md` | scoops of a role with `memory: { scope: user, path: <path> }` |
|
|
15
|
+
|
|
16
|
+
A role with `memory: { scope: project, path: <path> }` keeps it in `<project>/.pi/agent-memory/<path>/MEMORY.md`, where the project is the nearest folder above the scoop's working directory with a `.pi` or `.git`, inside /home.
|
|
17
|
+
|
|
18
|
+
## Writing
|
|
19
|
+
|
|
20
|
+
Use `memory_write` rather than editing the files:
|
|
21
|
+
|
|
22
|
+
- `section` and `title` name the entry; saving the same section and title again replaces it.
|
|
23
|
+
- `tag` is `user` (who the user is), `feedback` (how they want you to work) or `project` (facts about their work).
|
|
24
|
+
- `remove: true` forgets an entry. `scope: "global"` writes the shared file (cones only).
|
|
25
|
+
|
|
26
|
+
Keep entries short and durable: a preference, a correction, a convention, a project fact. Don't save one-off task details, transcripts, or anything secret (keys, tokens, passwords, signed or launch URLs); memory_write redacts what looks like one. Each file holds 16 KB; when it's full, merge or remove entries before adding.
|
|
27
|
+
|
|
28
|
+
The file format, if you or the user edit it by hand:
|
|
29
|
+
|
|
30
|
+
```markdown
|
|
31
|
+
## Preferences
|
|
32
|
+
|
|
33
|
+
### Lead with the result
|
|
34
|
+
tag: feedback
|
|
35
|
+
|
|
36
|
+
Keep replies short. Lead with the result, then the detail.
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## The `memory` command
|
|
40
|
+
|
|
41
|
+
- `memory scopes` lists every scope with its entry count and file.
|
|
42
|
+
- `memory show [<scope>]` prints a memory file, yours by default.
|
|
43
|
+
|
|
44
|
+
The user sees and edits the same entries in the Memory panel.
|
|
45
|
+
|
|
46
|
+
## Instructions are not memory
|
|
47
|
+
|
|
48
|
+
`AGENTS.md` and `CLAUDE.md` files hold instructions the user wrote: `~/.pi/agent/AGENTS.md` and the ones on your working directory's path inside /home are in the `project_context` section. Files in mounted folders are listed there as not loaded; they load once SLICC can trust a folder.
|