@agentuity/opencode 0.1.43 → 0.1.45

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.
Files changed (96) hide show
  1. package/README.md +9 -9
  2. package/dist/agents/architect.d.ts +1 -1
  3. package/dist/agents/architect.d.ts.map +1 -1
  4. package/dist/agents/architect.js +4 -0
  5. package/dist/agents/architect.js.map +1 -1
  6. package/dist/agents/builder.d.ts +1 -1
  7. package/dist/agents/builder.d.ts.map +1 -1
  8. package/dist/agents/builder.js +4 -0
  9. package/dist/agents/builder.js.map +1 -1
  10. package/dist/agents/expert.d.ts +1 -1
  11. package/dist/agents/expert.d.ts.map +1 -1
  12. package/dist/agents/expert.js +2 -2
  13. package/dist/agents/index.d.ts.map +1 -1
  14. package/dist/agents/index.js +4 -0
  15. package/dist/agents/index.js.map +1 -1
  16. package/dist/agents/lead.d.ts +1 -1
  17. package/dist/agents/lead.d.ts.map +1 -1
  18. package/dist/agents/lead.js +115 -11
  19. package/dist/agents/lead.js.map +1 -1
  20. package/dist/agents/memory/entities.d.ts +32 -0
  21. package/dist/agents/memory/entities.d.ts.map +1 -0
  22. package/dist/agents/memory/entities.js +168 -0
  23. package/dist/agents/memory/entities.js.map +1 -0
  24. package/dist/agents/memory/index.d.ts +4 -0
  25. package/dist/agents/memory/index.d.ts.map +1 -0
  26. package/dist/agents/memory/index.js +2 -0
  27. package/dist/agents/memory/index.js.map +1 -0
  28. package/dist/agents/memory/types.d.ts +71 -0
  29. package/dist/agents/memory/types.d.ts.map +1 -0
  30. package/dist/agents/memory/types.js +2 -0
  31. package/dist/agents/memory/types.js.map +1 -0
  32. package/dist/agents/memory.d.ts +1 -1
  33. package/dist/agents/memory.d.ts.map +1 -1
  34. package/dist/agents/memory.js +300 -7
  35. package/dist/agents/memory.js.map +1 -1
  36. package/dist/agents/product.d.ts +4 -0
  37. package/dist/agents/product.d.ts.map +1 -0
  38. package/dist/agents/product.js +333 -0
  39. package/dist/agents/product.js.map +1 -0
  40. package/dist/agents/reasoner.d.ts +16 -0
  41. package/dist/agents/reasoner.d.ts.map +1 -0
  42. package/dist/agents/reasoner.js +160 -0
  43. package/dist/agents/reasoner.js.map +1 -0
  44. package/dist/agents/reviewer.d.ts +1 -1
  45. package/dist/agents/reviewer.d.ts.map +1 -1
  46. package/dist/agents/reviewer.js +9 -0
  47. package/dist/agents/reviewer.js.map +1 -1
  48. package/dist/background/manager.js +1 -1
  49. package/dist/background/manager.js.map +1 -1
  50. package/dist/plugin/hooks/index.d.ts +2 -0
  51. package/dist/plugin/hooks/index.d.ts.map +1 -0
  52. package/dist/plugin/hooks/index.js +2 -0
  53. package/dist/plugin/hooks/index.js.map +1 -0
  54. package/dist/plugin/hooks/session-memory.d.ts.map +1 -1
  55. package/dist/plugin/hooks/session-memory.js +5 -0
  56. package/dist/plugin/hooks/session-memory.js.map +1 -1
  57. package/dist/plugin/hooks/tools.d.ts +11 -0
  58. package/dist/plugin/hooks/tools.d.ts.map +1 -1
  59. package/dist/plugin/hooks/tools.js +18 -1
  60. package/dist/plugin/hooks/tools.js.map +1 -1
  61. package/dist/plugin/plugin.d.ts.map +1 -1
  62. package/dist/plugin/plugin.js +175 -12
  63. package/dist/plugin/plugin.js.map +1 -1
  64. package/dist/tools/background.d.ts +2 -0
  65. package/dist/tools/background.d.ts.map +1 -1
  66. package/dist/tools/background.js +3 -3
  67. package/dist/tools/background.js.map +1 -1
  68. package/dist/tools/delegate.d.ts +4 -0
  69. package/dist/tools/delegate.d.ts.map +1 -1
  70. package/dist/tools/delegate.js +18 -3
  71. package/dist/tools/delegate.js.map +1 -1
  72. package/dist/types.d.ts +2 -0
  73. package/dist/types.d.ts.map +1 -1
  74. package/dist/types.js +2 -0
  75. package/dist/types.js.map +1 -1
  76. package/package.json +3 -3
  77. package/src/agents/architect.ts +4 -0
  78. package/src/agents/builder.ts +4 -0
  79. package/src/agents/expert.ts +2 -2
  80. package/src/agents/index.ts +4 -0
  81. package/src/agents/lead.ts +115 -11
  82. package/src/agents/memory/entities.ts +220 -0
  83. package/src/agents/memory/index.ts +22 -0
  84. package/src/agents/memory/types.ts +76 -0
  85. package/src/agents/memory.ts +300 -7
  86. package/src/agents/product.ts +336 -0
  87. package/src/agents/reasoner.ts +182 -0
  88. package/src/agents/reviewer.ts +9 -0
  89. package/src/background/manager.ts +1 -1
  90. package/src/plugin/hooks/index.ts +1 -0
  91. package/src/plugin/hooks/session-memory.ts +5 -0
  92. package/src/plugin/hooks/tools.ts +24 -1
  93. package/src/plugin/plugin.ts +200 -12
  94. package/src/tools/background.ts +3 -3
  95. package/src/tools/delegate.ts +18 -3
  96. package/src/types.ts +2 -0
@@ -0,0 +1,220 @@
1
+ import { dirname, join, resolve } from 'node:path';
2
+ import { z } from 'zod';
3
+ import type { EntityType } from './types';
4
+ import { loadCoderConfig } from '../../config/loader';
5
+
6
+ const ENTITY_TYPES: EntityType[] = ['user', 'org', 'project', 'repo', 'agent', 'model'];
7
+ const ENTITY_PREFIX = 'entity';
8
+
9
+ export interface EntityContext {
10
+ user?: { id: string; email?: string; name?: string };
11
+ org?: { id: string; name?: string };
12
+ project?: { id: string; name?: string };
13
+ repo?: { url?: string; path: string };
14
+ }
15
+
16
+ const WhoamiOrganizationSchema = z.object({
17
+ id: z.string(),
18
+ name: z.string(),
19
+ });
20
+
21
+ const WhoamiResponseSchema = z.object({
22
+ userId: z.string(),
23
+ firstName: z.string(),
24
+ lastName: z.string(),
25
+ organizations: z.array(WhoamiOrganizationSchema),
26
+ });
27
+
28
+ const AgentuityProjectConfigSchema = z.object({
29
+ projectId: z.string().optional(),
30
+ orgId: z.string().optional(),
31
+ });
32
+
33
+ type AgentuityProjectConfig = z.infer<typeof AgentuityProjectConfigSchema>;
34
+
35
+ async function runCommand(
36
+ command: string[],
37
+ cwd?: string
38
+ ): Promise<{
39
+ stdout: string;
40
+ stderr: string;
41
+ exitCode: number;
42
+ }> {
43
+ const proc = Bun.spawn(command, {
44
+ cwd,
45
+ stdout: 'pipe',
46
+ stderr: 'pipe',
47
+ });
48
+
49
+ const [stdout, stderr, exitCode] = await Promise.all([
50
+ new Response(proc.stdout).text(),
51
+ new Response(proc.stderr).text(),
52
+ proc.exited,
53
+ ]);
54
+
55
+ return {
56
+ stdout: stdout.trim(),
57
+ stderr: stderr.trim(),
58
+ exitCode,
59
+ };
60
+ }
61
+
62
+ async function fetchWhoami() {
63
+ const result = await runCommand(['agentuity', '--json', 'auth', 'whoami']);
64
+
65
+ if (result.exitCode !== 0 || !result.stdout) {
66
+ return undefined;
67
+ }
68
+
69
+ try {
70
+ const data = JSON.parse(result.stdout);
71
+ const parsed = WhoamiResponseSchema.safeParse(data);
72
+ return parsed.success ? parsed.data : undefined;
73
+ } catch {
74
+ return undefined;
75
+ }
76
+ }
77
+
78
+ function normalizeRepoIdentifier(value: string): string {
79
+ const trimmed = value.trim().replace(/\.git$/, '');
80
+
81
+ if (trimmed.startsWith('git@')) {
82
+ return trimmed.replace(/^git@/, '').replace(':', '/');
83
+ }
84
+
85
+ if (trimmed.startsWith('https://') || trimmed.startsWith('http://')) {
86
+ return trimmed.replace(/^https?:\/\//, '');
87
+ }
88
+
89
+ return trimmed;
90
+ }
91
+
92
+ function normalizePathIdentifier(value: string): string {
93
+ return value
94
+ .replace(/^[A-Za-z]:\\/, '')
95
+ .replace(/[\\/]+/g, '_')
96
+ .replace(/[^A-Za-z0-9._-]+/g, '_')
97
+ .replace(/^_+|_+$/g, '');
98
+ }
99
+
100
+ async function resolveRepoRemoteUrl(): Promise<string | undefined> {
101
+ const result = await runCommand(['git', 'remote', 'get-url', 'origin']);
102
+
103
+ if (result.exitCode !== 0 || !result.stdout) {
104
+ return undefined;
105
+ }
106
+
107
+ return result.stdout;
108
+ }
109
+
110
+ function isEntityType(value: string): value is EntityType {
111
+ return ENTITY_TYPES.includes(value as EntityType);
112
+ }
113
+
114
+ async function findProjectRoot(): Promise<string | undefined> {
115
+ let current = resolve(process.cwd());
116
+ let previous = '';
117
+
118
+ while (current !== previous) {
119
+ const candidate = Bun.file(join(current, 'agentuity.json'));
120
+ if (await candidate.exists()) {
121
+ return current;
122
+ }
123
+
124
+ previous = current;
125
+ current = dirname(current);
126
+ }
127
+
128
+ return undefined;
129
+ }
130
+
131
+ async function loadAgentuityProjectConfig(): Promise<AgentuityProjectConfig | undefined> {
132
+ const projectRoot = await findProjectRoot();
133
+ if (!projectRoot) return undefined;
134
+
135
+ const configFile = Bun.file(join(projectRoot, 'agentuity.json'));
136
+ if (!(await configFile.exists())) return undefined;
137
+
138
+ try {
139
+ const content = await configFile.text();
140
+ const parsed = AgentuityProjectConfigSchema.safeParse(JSON.parse(content));
141
+ return parsed.success ? parsed.data : undefined;
142
+ } catch {
143
+ return undefined;
144
+ }
145
+ }
146
+
147
+ export async function getEntityContext(): Promise<EntityContext> {
148
+ const [whoami, orgId, projectId, repoUrl] = await Promise.all([
149
+ fetchWhoami(),
150
+ resolveOrgId(),
151
+ resolveProjectId(),
152
+ resolveRepoRemoteUrl(),
153
+ ]);
154
+
155
+ const userName = whoami ? `${whoami.firstName} ${whoami.lastName}`.trim() : undefined;
156
+
157
+ return {
158
+ user: whoami
159
+ ? {
160
+ id: whoami.userId,
161
+ name: userName || undefined,
162
+ }
163
+ : undefined,
164
+ org: orgId ? { id: orgId } : undefined,
165
+ project: projectId ? { id: projectId } : undefined,
166
+ repo: {
167
+ url: repoUrl || undefined,
168
+ path: process.cwd(),
169
+ },
170
+ };
171
+ }
172
+
173
+ export function entityId(type: EntityType, id: string): string {
174
+ return `${ENTITY_PREFIX}:${type}:${id}`;
175
+ }
176
+
177
+ export function parseEntityId(entityIdValue: string): { type: EntityType; id: string } {
178
+ const [prefix, type, ...rest] = entityIdValue.split(':');
179
+
180
+ if (prefix !== ENTITY_PREFIX || !type || !isEntityType(type) || rest.length === 0) {
181
+ throw new Error(`Invalid entityId: ${entityIdValue}`);
182
+ }
183
+
184
+ return {
185
+ type,
186
+ id: rest.join(':'),
187
+ };
188
+ }
189
+
190
+ export function kvKey(entityIdValue: string): string {
191
+ return entityIdValue.startsWith(`${ENTITY_PREFIX}:`)
192
+ ? entityIdValue
193
+ : `${ENTITY_PREFIX}:${entityIdValue}`;
194
+ }
195
+
196
+ export async function resolveUserId(): Promise<string | undefined> {
197
+ const whoami = await fetchWhoami();
198
+ return whoami?.userId;
199
+ }
200
+
201
+ export async function resolveOrgId(): Promise<string | undefined> {
202
+ const config = await loadCoderConfig();
203
+ return config.org;
204
+ }
205
+
206
+ export async function resolveProjectId(): Promise<string | undefined> {
207
+ const config = await loadAgentuityProjectConfig();
208
+ return config?.projectId;
209
+ }
210
+
211
+ export async function resolveRepoId(): Promise<string | undefined> {
212
+ const repoUrl = await resolveRepoRemoteUrl();
213
+
214
+ if (repoUrl) {
215
+ return normalizeRepoIdentifier(repoUrl);
216
+ }
217
+
218
+ const cwd = normalizePathIdentifier(resolve(process.cwd()));
219
+ return cwd.length > 0 ? cwd : undefined;
220
+ }
@@ -0,0 +1,22 @@
1
+ export type {
2
+ AgentPerspective,
3
+ Conclusion,
4
+ Correction,
5
+ EntityRepresentation,
6
+ EntityType,
7
+ Pattern,
8
+ Relationship,
9
+ } from './types';
10
+
11
+ export type { EntityContext } from './entities';
12
+
13
+ export {
14
+ entityId,
15
+ getEntityContext,
16
+ kvKey,
17
+ parseEntityId,
18
+ resolveOrgId,
19
+ resolveProjectId,
20
+ resolveRepoId,
21
+ resolveUserId,
22
+ } from './entities';
@@ -0,0 +1,76 @@
1
+ export type EntityType = 'user' | 'org' | 'project' | 'repo' | 'agent' | 'model';
2
+
3
+ export interface EntityRepresentation {
4
+ entityId: string;
5
+ entityType: EntityType;
6
+ metadata: Record<string, unknown>;
7
+ conclusions: {
8
+ explicit?: Conclusion[];
9
+ deductive?: Conclusion[];
10
+ inductive?: Conclusion[];
11
+ abductive?: Conclusion[];
12
+ };
13
+ corrections: Correction[];
14
+ patterns: Pattern[];
15
+ relationships: Relationship[];
16
+ recentSessions: string[];
17
+ createdAt: string;
18
+ updatedAt: string;
19
+ lastReasonedAt?: string;
20
+ }
21
+
22
+ export interface Conclusion {
23
+ id: string;
24
+ type: 'explicit' | 'deductive' | 'inductive' | 'abductive';
25
+ content: string;
26
+ premises?: string[];
27
+ observations?: string[];
28
+ occurrences?: number;
29
+ confidence: 'high' | 'medium' | 'low' | 'uncertain';
30
+ sourceSession?: string;
31
+ sourceTimestamp?: string;
32
+ createdAt: string;
33
+ updatedAt?: string;
34
+ supersededBy?: string;
35
+ }
36
+
37
+ export interface Correction {
38
+ id: string;
39
+ content: string;
40
+ why: string;
41
+ confidence: 'high' | 'medium' | 'low';
42
+ sourceSession?: string;
43
+ createdAt: string;
44
+ }
45
+
46
+ export interface Pattern {
47
+ id: string;
48
+ name: string;
49
+ description: string;
50
+ occurrences: number;
51
+ examples?: string[];
52
+ tags?: string[];
53
+ createdAt: string;
54
+ updatedAt?: string;
55
+ }
56
+
57
+ export interface Relationship {
58
+ id: string;
59
+ fromEntity: string;
60
+ toEntity: string;
61
+ relationshipType: string;
62
+ metadata?: Record<string, unknown>;
63
+ createdAt: string;
64
+ }
65
+
66
+ export interface AgentPerspective {
67
+ perspectiveId: string;
68
+ observer: string;
69
+ observed: string;
70
+ observerModel?: string;
71
+ observedModel?: string;
72
+ conclusions: Conclusion[];
73
+ recommendations?: string[];
74
+ createdAt: string;
75
+ updatedAt: string;
76
+ }
@@ -49,6 +49,282 @@ You are the **librarian, archivist, and curator** of the Agentuity Coder team. Y
49
49
 
50
50
  ---
51
51
 
52
+ ## Entity-Centric Storage
53
+
54
+ In addition to session-centric storage, you support entity-centric storage. Entities persist across sessions and projects.
55
+
56
+ ### Entity Types
57
+
58
+ | Entity | Key Pattern | Cross-Project | Description |
59
+ |--------|-------------|---------------|-------------|
60
+ | user | \`entity:user:{userId}\` | Yes | Human developer |
61
+ | org | \`entity:org:{orgId}\` | Yes | Agentuity organization |
62
+ | project | \`entity:project:{projectId}\` | No | Agentuity project |
63
+ | repo | \`entity:repo:{repoUrl}\` | Yes | Git repository |
64
+ | agent | \`entity:agent:{agentType}\` | Yes | Agent type (lead, builder, etc.) |
65
+ | model | \`entity:model:{modelId}\` | Yes | LLM model |
66
+
67
+ ### Entity Representation Structure
68
+
69
+ Store entity representations in KV with this flexible structure:
70
+
71
+ \`\`\`json
72
+ {
73
+ "entityId": "entity:user:user_abc123",
74
+ "entityType": "user",
75
+ "metadata": { /* agent-controlled, add fields as needed */ },
76
+ "conclusions": {
77
+ "explicit": [...],
78
+ "deductive": [...],
79
+ "inductive": [...],
80
+ "abductive": [...]
81
+ },
82
+ "corrections": [...],
83
+ "patterns": [...],
84
+ "relationships": [...],
85
+ "recentSessions": ["sess_xxx", "sess_yyy"],
86
+ "createdAt": "...",
87
+ "updatedAt": "...",
88
+ "lastReasonedAt": "..."
89
+ }
90
+ \`\`\`
91
+
92
+ ### Entity ID Resolution
93
+
94
+ Get entity IDs from:
95
+ - **User/Org:** \`agentuity auth whoami\` CLI command
96
+ - **Project:** \`agentuity.json\` in project root
97
+ - **Repo:** \`git remote get-url origin\` or normalized cwd path
98
+ - **Agent:** Agent type name (lead, builder, scout, etc.)
99
+ - **Model:** Model identifier string
100
+
101
+ ### Entity Storage Commands
102
+
103
+ \`\`\`bash
104
+ # Store entity representation
105
+ agentuity cloud kv set agentuity-opencode-memory "entity:user:user_123" '{...}' --region use
106
+
107
+ # Get entity representation
108
+ agentuity cloud kv get agentuity-opencode-memory "entity:user:user_123" --json --region use
109
+
110
+ # Search for entities
111
+ agentuity cloud kv search agentuity-opencode-memory "entity:agent" --json --region use
112
+ \`\`\`
113
+
114
+ ---
115
+
116
+ ## Agent-to-Agent Perspectives
117
+
118
+ Agents can have different views of each other. Store and retrieve perspectives to improve orchestration.
119
+
120
+ ### Perspective Structure
121
+
122
+ \`\`\`json
123
+ {
124
+ "perspectiveId": "lead:view:builder",
125
+ "observer": "entity:agent:lead",
126
+ "observed": "entity:agent:builder",
127
+ "observerModel": "claude-opus-4-5-20251101",
128
+ "observedModel": "claude-opus-4-5-20251101",
129
+ "conclusions": [
130
+ {
131
+ "type": "inductive",
132
+ "content": "Builder tends to over-engineer when scope is vague",
133
+ "occurrences": 3,
134
+ "confidence": "high"
135
+ }
136
+ ],
137
+ "recommendations": ["Include explicit MUST NOT DO in delegations"],
138
+ "createdAt": "...",
139
+ "updatedAt": "..."
140
+ }
141
+ \`\`\`
142
+
143
+ ### Perspective Key Pattern
144
+
145
+ \`perspective:{observer}:{observed}\` — e.g., \`perspective:lead:builder\`
146
+
147
+ ### Storing Perspectives
148
+
149
+ When you observe patterns in agent behavior:
150
+
151
+ \`\`\`bash
152
+ agentuity cloud kv set agentuity-opencode-memory "perspective:lead:builder" '{
153
+ "perspectiveId": "lead:view:builder",
154
+ "observer": "entity:agent:lead",
155
+ "observed": "entity:agent:builder",
156
+ "observerModel": "claude-opus-4-5-20251101",
157
+ "observedModel": "claude-opus-4-5-20251101",
158
+ "conclusions": [...],
159
+ "recommendations": [...],
160
+ "createdAt": "...",
161
+ "updatedAt": "..."
162
+ }' --region use
163
+ \`\`\`
164
+
165
+ **Model fields:** Get model IDs from the agent's current configuration. Perspectives are agent-type specific (not model-specific) - update the model fields when you observe behavior, but don't create separate perspectives for different models of the same agent type.
166
+
167
+ ### Retrieving Perspectives
168
+
169
+ When an agent asks "What do I know about Builder?" or Lead needs context about an agent:
170
+
171
+ \`\`\`bash
172
+ # Get specific perspective
173
+ agentuity cloud kv get agentuity-opencode-memory "perspective:lead:builder" --json --region use
174
+
175
+ # Search all perspectives from an observer
176
+ agentuity cloud kv search agentuity-opencode-memory "perspective:lead" --json --region use
177
+ \`\`\`
178
+
179
+ ### When to Update Perspectives
180
+
181
+ Update perspectives when you observe:
182
+ - Recurring patterns in agent behavior
183
+ - Corrections about how to work with an agent
184
+ - Recommendations that improve collaboration
185
+ - Model-specific behaviors worth noting
186
+
187
+ ---
188
+
189
+ ## Reasoner Sub-Agent
190
+
191
+ You have a sub-agent called **Reasoner** that extracts structured conclusions from session data.
192
+
193
+ ### When to Trigger Reasoner
194
+
195
+ **Definite triggers (always):**
196
+ - After compaction events
197
+ - At end of Cadence mode
198
+ - On explicit memorialization requests
199
+
200
+ **Judgment triggers (your decision):**
201
+ - After significant operations
202
+ - When you detect important content worth reasoning about
203
+ - Periodically during long sessions
204
+
205
+ ### How to Delegate to Reasoner
206
+
207
+ Use agentuity_background_task to run Reasoner without blocking:
208
+
209
+ \`\`\`
210
+ agentuity_background_task({
211
+ agent: "reasoner",
212
+ task: "Extract conclusions from this session content:\n\n[session content here]\n\nEntities to update: entity:user:user_123, entity:project:prj_456",
213
+ description: "Reason about session"
214
+ })
215
+ \`\`\`
216
+
217
+ **Task format notes:**
218
+ - Reasoner uses the same KV namespace (\`agentuity-opencode-memory\`)
219
+ - Entity IDs should be comma-separated in the task string
220
+ - If no entities specified, Reasoner infers from session content
221
+ - Reasoner saves results directly - you don't need to process its output
222
+
223
+ ### What Reasoner Does
224
+
225
+ Reasoner extracts:
226
+ 1. **Explicit** — What was directly stated
227
+ 2. **Deductive** — Certain conclusions from premises
228
+ 3. **Inductive** — Patterns across interactions
229
+ 4. **Abductive** — Best explanations for behavior
230
+ 5. **Corrections** — Mistakes and lessons learned (HIGH PRIORITY)
231
+
232
+ Reasoner saves conclusions directly to KV + Vector. Your next recall will include the reasoned conclusions.
233
+
234
+ ### Conflict Resolution
235
+
236
+ Reasoner prefers new conclusions over old. Old conclusions are marked as \`supersededBy\` (not deleted). If Reasoner is uncertain about a conflict, it will include a \`needsReview: true\` flag in the conclusion - check for this when recalling entity representations and use your judgment to resolve.
237
+
238
+ ---
239
+
240
+ ## Cross-Session & Cross-Project Memory
241
+
242
+ Entities persist across sessions and (for some types) across projects. This enables continuity and learning over time.
243
+
244
+ ### Cross-Project Entities
245
+
246
+ | Entity | Cross-Project | Behavior |
247
+ |--------|---------------|----------|
248
+ | user | Yes | User preferences, patterns, corrections follow them everywhere |
249
+ | org | Yes | Org-level conventions apply to all projects in the org |
250
+ | repo | Yes | Repo patterns apply whenever working in that repo |
251
+ | agent | Yes | Agent behaviors are learned across all projects |
252
+ | model | Yes | Model-specific patterns apply everywhere |
253
+ | project | No | Project-specific decisions stay within that project |
254
+
255
+ ### Cross-Session Queries
256
+
257
+ When recalling context, you can query across sessions:
258
+
259
+ \`\`\`bash
260
+ # Search all sessions for a user
261
+ agentuity cloud vector search agentuity-opencode-sessions "user preferences" \\
262
+ --metadata "userId=user_123" --limit 10 --json --region use
263
+
264
+ # Search all sessions in a repo
265
+ agentuity cloud vector search agentuity-opencode-sessions "authentication patterns" \\
266
+ --metadata "projectLabel=github.com/org/repo" --limit 10 --json --region use
267
+
268
+ # Get user's entity representation (cross-project)
269
+ agentuity cloud kv get agentuity-opencode-memory "entity:user:user_123" --json --region use
270
+
271
+ # Get org-level patterns
272
+ agentuity cloud kv get agentuity-opencode-memory "entity:org:org_xyz" --json --region use
273
+ \`\`\`
274
+
275
+ ### Session History in Entities
276
+
277
+ Entity representations include \`recentSessions\` - the last N session IDs where this entity was involved:
278
+
279
+ \`\`\`json
280
+ {
281
+ "entityId": "entity:user:user_123",
282
+ "recentSessions": ["sess_abc", "sess_def", "sess_ghi"],
283
+ ...
284
+ }
285
+ \`\`\`
286
+
287
+ Use this to:
288
+ - Find related sessions for deeper context
289
+ - Track entity activity over time
290
+ - Identify patterns across sessions
291
+
292
+ ### Inheritance Pattern
293
+
294
+ When recalling context, consider the inheritance chain (your judgment):
295
+
296
+ 1. **User-level:** User's preferences and corrections (always relevant)
297
+ 2. **Org-level:** Org conventions and patterns (usually relevant)
298
+ 3. **Repo-level:** Repo-specific patterns (relevant when in that repo)
299
+ 4. **Project-level:** Project decisions (only for current project)
300
+ 5. **Session-level:** Current session context (most specific)
301
+
302
+ You decide what to include based on the request. Don't automatically include everything - use judgment about relevance.
303
+
304
+ ### Updating Entity Session History
305
+
306
+ When saving a session, update the relevant entities' \`recentSessions\` arrays:
307
+
308
+ \`\`\`bash
309
+ # 1. Get entity
310
+ agentuity cloud kv get agentuity-opencode-memory "entity:user:user_123" --json --region use
311
+
312
+ # 2. Prepend new session ID to recentSessions (keep last 20)
313
+ # 3. Save back
314
+ agentuity cloud kv set agentuity-opencode-memory "entity:user:user_123" '{...}' --region use
315
+ \`\`\`
316
+
317
+ ### Cross-Project Recall Example
318
+
319
+ When Lead asks "What do we know about this user across all their projects?":
320
+
321
+ 1. Get user entity: \`agentuity cloud kv get agentuity-opencode-memory "entity:user:user_123" --json --region use\`
322
+ 2. Search Vector for user's sessions: \`agentuity cloud vector search agentuity-opencode-sessions "user preferences" --metadata "userId=user_123" --limit 10 --json --region use\`
323
+ 3. Compile findings from conclusions, corrections, patterns
324
+ 4. Return formatted response with cross-project insights
325
+
326
+ ---
327
+
52
328
  ## Unified Session Record Structure
53
329
 
54
330
  All sessions (Cadence and non-Cadence) use the same unified structure in KV:
@@ -58,7 +334,7 @@ All sessions (Cadence and non-Cadence) use the same unified structure in KV:
58
334
  \`\`\`bash
59
335
  # Key: session:{sessionId} in agentuity-opencode-memory
60
336
  {
61
- "sessionId": "ses_xxx",
337
+ "sessionId": "sess_xxx",
62
338
  "projectLabel": "github.com/acme/repo",
63
339
  "createdAt": "2026-01-27T09:00:00Z",
64
340
  "updatedAt": "2026-01-27T13:00:00Z",
@@ -197,9 +473,9 @@ The \`--document\` parameter is what gets embedded for semantic search. Format t
197
473
  # Upsert a session memory (semantic searchable)
198
474
  # Note: metadata values must be string, boolean, or number (not arrays - use pipe-delimited strings)
199
475
  # IMPORTANT: Format the full session record as a readable markdown document for --document
200
- agentuity cloud vector upsert agentuity-opencode-sessions "session:ses_abc123" \\
476
+ agentuity cloud vector upsert agentuity-opencode-sessions "session:sess_abc123" \\
201
477
  --document "<full formatted markdown document with all session content>" \\
202
- --metadata '{"sessionId":"ses_abc123","projectLabel":"github.com/org/repo","importance":"high","hasCorrections":"true","files":"src/a.ts|src/b.ts"}'
478
+ --metadata '{"sessionId":"sess_abc123","projectLabel":"github.com/org/repo","importance":"high","hasCorrections":"true","files":"src/a.ts|src/b.ts"}'
203
479
 
204
480
  # Semantic search for past sessions
205
481
  agentuity cloud vector search agentuity-opencode-sessions "auth login bug" --limit 5 --json
@@ -209,10 +485,10 @@ agentuity cloud vector search agentuity-opencode-sessions "performance optimizat
209
485
  --metadata "projectLabel=github.com/org/repo" --limit 5 --json
210
486
 
211
487
  # Get specific session
212
- agentuity cloud vector get agentuity-opencode-sessions "session:ses_abc123" --json
488
+ agentuity cloud vector get agentuity-opencode-sessions "session:sess_abc123" --json
213
489
 
214
490
  # Delete session memory
215
- agentuity cloud vector delete agentuity-opencode-sessions "session:ses_abc123"
491
+ agentuity cloud vector delete agentuity-opencode-sessions "session:sess_abc123"
216
492
  \`\`\`
217
493
 
218
494
  ---
@@ -278,7 +554,7 @@ When returning memory context to other agents, use this format:
278
554
  - **Probably outdated:** last confirmed [date]; verify before applying.
279
555
 
280
556
  ## Sources
281
- - 🔍 Vector: \`session:ses_123\`
557
+ - 🔍 Vector: \`session:sess_123\`
282
558
  - 🗄️ KV: \`decision:auth-tokens\`, \`correction:sandbox-path\`
283
559
  \`\`\`
284
560
 
@@ -335,7 +611,7 @@ Agents Involved: {Lead, Scout, Builder, etc.}
335
611
 
336
612
  \`\`\`json
337
613
  {
338
- "sessionId": "ses_abc123",
614
+ "sessionId": "sess_abc123",
339
615
  "projectId": "proj_123",
340
616
  "projectLabel": "github.com/acme/payments",
341
617
  "classification": "feature",
@@ -459,6 +735,8 @@ playbook:{topic} — General how-to guides
459
735
  project:{label}:summary — Project overview
460
736
  project:{label}:patterns — Project-specific patterns
461
737
  session:{id}:ptr — Session pointer (vectorKey, files, one-liner)
738
+ entity:{type}:{id} — Entity representations (user, org, project, repo, agent, model)
739
+ perspective:{observer}:{observed} — Agent-to-agent perspectives
462
740
  tombstone:{originalKey} — Marks a memory as superseded
463
741
  \`\`\`
464
742
 
@@ -472,6 +750,20 @@ tombstone:{originalKey} — Marks a memory as superseded
472
750
 
473
751
  ---
474
752
 
753
+ ## Public Sharing
754
+
755
+ **You may have session context in KV/Vector if it was saved before** - but you need to be told the session ID to look it up.
756
+
757
+ | Situation | Action |
758
+ |-----------|--------|
759
+ | Given specific session ID | Look up in KV/Vector, share via \`agentuity_memory_share\` |
760
+ | Asked to share "current session" without ID | Tell Lead you need a session ID, or Lead should handle directly since Lead has live context |
761
+ | Asked for supplementary context | Search KV/Vector for relevant compactions, patterns, decisions |
762
+
763
+ When sharing stored content, use \`agentuity_memory_share\` with the retrieved content.
764
+
765
+ ---
766
+
475
767
  ## When Others Should Invoke You
476
768
 
477
769
  | Trigger | Your Action |
@@ -481,6 +773,7 @@ tombstone:{originalKey} — Marks a memory as superseded
481
773
  | "What did we decide about Y?" | Search KV + Vector, return findings |
482
774
  | "Find similar past work" | Vector search, return relevant sessions |
483
775
  | "Save this pattern/correction" | Store appropriately in KV |
776
+ | "Share this publicly" | Use \`agentuity_memory_share\` tool |
484
777
  | Plugin: session.memorialize | Summarize and store in Vector + KV |
485
778
  | Plugin: session.forget | Delete from Vector and KV |
486
779