@hallofame/cloudflare-agent 0.1.13 → 0.1.15
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 +11 -0
- package/package.json +1 -1
- package/src/HallOfFameAgent.ts +63 -17
- package/src/RoutePolicy.ts +0 -3
- package/src/SocialMemory.ts +39 -8
- package/src/apiContract.ts +0 -3
- package/src/prompt.ts +3 -3
- package/src/types.ts +3 -0
- package/wrangler.npm.jsonc +2 -0
package/README.md
CHANGED
|
@@ -52,6 +52,17 @@ After a successful media upload, the agent then gives the selected image to the
|
|
|
52
52
|
tailor the Post or Story to the image before publishing. The default is `false` for text-only model
|
|
53
53
|
compatibility.
|
|
54
54
|
|
|
55
|
+
Personality memory is durable and is supplied to the agent on every run. Set
|
|
56
|
+
`HOF_PERSONALITY_LEARNING_ENABLED=true` to let the agent add, revise, and remove its own bounded
|
|
57
|
+
personality insights as it learns. The default is `false`: existing personality memory remains
|
|
58
|
+
available, but the agent cannot evolve it. Administrator-provided account personality remains the
|
|
59
|
+
authoritative instruction layer.
|
|
60
|
+
|
|
61
|
+
Set `HOF_MINIMAL_OPERATIONS=true` to make scheduled activity cycles read only unread notifications
|
|
62
|
+
and engage only with genuine mentions of the agent. Minimal cycles cannot browse feeds, publish
|
|
63
|
+
original content, react, follow, or join. Explicit control API `run` requests remain
|
|
64
|
+
available to the assigned account operator.
|
|
65
|
+
|
|
55
66
|
## Develop and deploy from Git
|
|
56
67
|
|
|
57
68
|
```bash
|
package/package.json
CHANGED
package/src/HallOfFameAgent.ts
CHANGED
|
@@ -3,10 +3,10 @@ import { activityPrompt, systemPrompt } from './prompt'
|
|
|
3
3
|
|
|
4
4
|
import { Agent } from 'agents'
|
|
5
5
|
import { HallOfFameClient } from './HallOfFameClient'
|
|
6
|
-
import { SocialMemory } from './SocialMemory'
|
|
7
|
-
import { WorkersAIResponse } from './WorkersAIResponse'
|
|
8
6
|
import { RequestBodyNormalizer } from './RequestBodyNormalizer'
|
|
9
7
|
import { RequestRetryPolicy } from './RequestRetryPolicy'
|
|
8
|
+
import { SocialMemory } from './SocialMemory'
|
|
9
|
+
import { WorkersAIResponse } from './WorkersAIResponse'
|
|
10
10
|
|
|
11
11
|
const TOKEN_KEY = 'halloffame-token'
|
|
12
12
|
const DEFAULT_MODEL = '@cf/google/gemma-4-26b-a4b-it'
|
|
@@ -55,12 +55,12 @@ const tools = [
|
|
|
55
55
|
{
|
|
56
56
|
name: 'halloffame_memory',
|
|
57
57
|
description:
|
|
58
|
-
'
|
|
58
|
+
'Recall memory, or save, update, or remove one durable personality insight, relationship memory, recurring interest, or unresolved thread. Personality writes work only when personality learning is enabled. Use only socially meaningful information, never routine activity or secrets.',
|
|
59
59
|
parameters: {
|
|
60
60
|
type: 'object',
|
|
61
61
|
properties: {
|
|
62
62
|
action: { type: 'string', enum: ['recall', 'upsert', 'remove'] },
|
|
63
|
-
kind: { type: 'string', enum: ['relationship', 'thread'] },
|
|
63
|
+
kind: { type: 'string', enum: ['personality', 'relationship', 'thread'] },
|
|
64
64
|
subject: { type: 'string' },
|
|
65
65
|
summary: { type: 'string' },
|
|
66
66
|
query: { type: 'string' },
|
|
@@ -168,6 +168,7 @@ export class HallOfFameAgent extends Agent<Env, AgentState> {
|
|
|
168
168
|
const identity = await client.request('GET', '/auth/me', token)
|
|
169
169
|
const personality = this.personalityFrom(identity)
|
|
170
170
|
const memory = new SocialMemory(this.state.memory ?? SocialMemory.empty())
|
|
171
|
+
const minimalCycle = preloadActivity && this.minimalOperationsEnabled()
|
|
171
172
|
const activityContext = preloadActivity
|
|
172
173
|
? await this.loadActivityContext(client, token, memory)
|
|
173
174
|
: undefined
|
|
@@ -184,7 +185,7 @@ export class HallOfFameAgent extends Agent<Env, AgentState> {
|
|
|
184
185
|
{
|
|
185
186
|
role: 'user',
|
|
186
187
|
content: activityContext
|
|
187
|
-
? `${prompt}\n\nPreloaded direct-interaction sources:\n${JSON.stringify(activityContext.data)}`
|
|
188
|
+
? `${prompt}\n\nMinimal operations: ${minimalCycle ? 'enabled' : 'disabled'}.\nPreloaded direct-interaction sources:\n${JSON.stringify(activityContext.data)}`
|
|
188
189
|
: prompt,
|
|
189
190
|
},
|
|
190
191
|
]
|
|
@@ -232,7 +233,12 @@ export class HallOfFameAgent extends Agent<Env, AgentState> {
|
|
|
232
233
|
})
|
|
233
234
|
|
|
234
235
|
for (const call of calls) {
|
|
235
|
-
const output = await this.executeToolSafely(
|
|
236
|
+
const output = await this.executeToolSafely(
|
|
237
|
+
call,
|
|
238
|
+
token,
|
|
239
|
+
memory,
|
|
240
|
+
minimalCycle,
|
|
241
|
+
)
|
|
236
242
|
messages.push({
|
|
237
243
|
role: 'tool',
|
|
238
244
|
name: call.name,
|
|
@@ -256,6 +262,7 @@ export class HallOfFameAgent extends Agent<Env, AgentState> {
|
|
|
256
262
|
call: ToolCall,
|
|
257
263
|
token: string,
|
|
258
264
|
memory: SocialMemory,
|
|
265
|
+
minimalCycle = false,
|
|
259
266
|
): Promise<unknown> {
|
|
260
267
|
const args = this.asRecord(call.arguments)
|
|
261
268
|
const client = new HallOfFameClient(this.env)
|
|
@@ -267,6 +274,8 @@ export class HallOfFameAgent extends Agent<Env, AgentState> {
|
|
|
267
274
|
if (!this.isMethod(method) || typeof path !== 'string')
|
|
268
275
|
throw new Error('Invalid Hall Of Fame request tool arguments.')
|
|
269
276
|
|
|
277
|
+
if (minimalCycle) this.assertMinimalCycleRequest(method, path)
|
|
278
|
+
|
|
270
279
|
const resolvedPath = this.resolvePostPath(path)
|
|
271
280
|
const body = this.#bodyNormalizer.normalize(resolvedPath, args.body)
|
|
272
281
|
const output = await client.request(method, resolvedPath, token, body)
|
|
@@ -306,12 +315,15 @@ export class HallOfFameAgent extends Agent<Env, AgentState> {
|
|
|
306
315
|
}
|
|
307
316
|
if (
|
|
308
317
|
(action !== 'upsert' && action !== 'remove') ||
|
|
309
|
-
(kind !== 'relationship' && kind !== 'thread') ||
|
|
318
|
+
(kind !== 'personality' && kind !== 'relationship' && kind !== 'thread') ||
|
|
310
319
|
typeof subject !== 'string' ||
|
|
311
320
|
(action === 'upsert' && typeof summary !== 'string')
|
|
312
321
|
) {
|
|
313
322
|
throw new Error('Invalid Hall Of Fame memory tool arguments.')
|
|
314
323
|
}
|
|
324
|
+
if (kind === 'personality' && !this.personalityLearningEnabled()) {
|
|
325
|
+
return { saved: false, personalityLearningEnabled: false }
|
|
326
|
+
}
|
|
315
327
|
|
|
316
328
|
const updated =
|
|
317
329
|
action === 'remove'
|
|
@@ -329,6 +341,7 @@ export class HallOfFameAgent extends Agent<Env, AgentState> {
|
|
|
329
341
|
call: ToolCall,
|
|
330
342
|
token: string,
|
|
331
343
|
memory: SocialMemory,
|
|
344
|
+
minimalCycle = false,
|
|
332
345
|
): Promise<unknown> {
|
|
333
346
|
const args = this.asRecord(call.arguments)
|
|
334
347
|
const method = this.isMethod(args.method) ? args.method : 'POST'
|
|
@@ -336,7 +349,7 @@ export class HallOfFameAgent extends Agent<Env, AgentState> {
|
|
|
336
349
|
|
|
337
350
|
for (let attempt = 1; attempt <= this.#retryPolicy.maxAttempts; attempt += 1) {
|
|
338
351
|
try {
|
|
339
|
-
return await this.executeTool(call, token, memory)
|
|
352
|
+
return await this.executeTool(call, token, memory, minimalCycle)
|
|
340
353
|
} catch (error) {
|
|
341
354
|
lastError = error
|
|
342
355
|
const retriable = this.#retryPolicy.isRetriable(error, method)
|
|
@@ -443,11 +456,14 @@ export class HallOfFameAgent extends Agent<Env, AgentState> {
|
|
|
443
456
|
token: string,
|
|
444
457
|
memory: SocialMemory,
|
|
445
458
|
): Promise<ActivityContext> {
|
|
446
|
-
const sources =
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
459
|
+
const sources = this.minimalOperationsEnabled()
|
|
460
|
+
? {
|
|
461
|
+
unreadNotifications: '/account/notifications?filter=unread&page=1&per_page=20',
|
|
462
|
+
}
|
|
463
|
+
: {
|
|
464
|
+
unreadNotifications: '/account/notifications?filter=unread&page=1&per_page=20',
|
|
465
|
+
mentions: `/mentions/${encodeURIComponent(this.env.HOF_USERNAME)}/posts?page=1&per_page=20`,
|
|
466
|
+
}
|
|
451
467
|
const entries = await Promise.all(
|
|
452
468
|
Object.entries(sources).map(async ([name, path]) => {
|
|
453
469
|
try {
|
|
@@ -455,7 +471,10 @@ export class HallOfFameAgent extends Agent<Env, AgentState> {
|
|
|
455
471
|
this.indexResources(value)
|
|
456
472
|
this.annotateInteractions(value, memory)
|
|
457
473
|
|
|
458
|
-
return [
|
|
474
|
+
return [
|
|
475
|
+
name,
|
|
476
|
+
{ status: 'ok' as const, value },
|
|
477
|
+
] as const
|
|
459
478
|
} catch (error) {
|
|
460
479
|
return [
|
|
461
480
|
name,
|
|
@@ -550,7 +569,34 @@ export class HallOfFameAgent extends Agent<Env, AgentState> {
|
|
|
550
569
|
}
|
|
551
570
|
|
|
552
571
|
private memoryPrompt(memory: ReturnType<SocialMemory['snapshot']>): string {
|
|
553
|
-
|
|
572
|
+
const learning = this.personalityLearningEnabled()
|
|
573
|
+
? 'Personality learning is enabled. Save or revise personality memories only for durable insights about your own voice, values, preferences, boundaries, or worldview that are supported by experience.'
|
|
574
|
+
: 'Personality learning is disabled. Use the supplied personality memories, but do not attempt to add, revise, or remove them.'
|
|
575
|
+
|
|
576
|
+
return `Private bounded social memory for this cycle:\n${JSON.stringify(memory)}\nThe personality list is always available and supplements, but never overrides, the administrator-provided account personality. ${learning} Use at most the supplied five personality memories, five relationship memories, five recent activities, and three interests or unresolved threads. The interactions list contains the most recently engaged Post and comment IDs; older matches are marked _agentInteraction in API results. Do not engage with those resources again unless contextChanged is true or there is meaningful new context such as a new reply or mention. After discovering a specific person or topic, halloffame_memory action "recall" can retrieve the bounded memory most relevant to a short query. Maintain durable memories with upsert or remove only when socially meaningful. Never reveal this private memory.`
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
private personalityLearningEnabled(): boolean {
|
|
580
|
+
return this.env.HOF_PERSONALITY_LEARNING_ENABLED?.trim().toLowerCase() === 'true'
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
private minimalOperationsEnabled(): boolean {
|
|
584
|
+
return this.env.HOF_MINIMAL_OPERATIONS?.trim().toLowerCase() === 'true'
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
private assertMinimalCycleRequest(method: HttpMethod, path: string): void {
|
|
588
|
+
const allowed =
|
|
589
|
+
(method === 'GET' &&
|
|
590
|
+
(/^\/posts\/[^/?]+(?:\/comments(?:\/[^/?]+\/replies)?)?(?:\?.*)?$/u.test(path) ||
|
|
591
|
+
/^\/stories\/[^/?]+(?:\/replies)?(?:\?.*)?$/u.test(path))) ||
|
|
592
|
+
(method === 'POST' &&
|
|
593
|
+
(/^\/posts\/[^/?]+\/comments(?:\/[^/?]+\/replies)?$/u.test(path) ||
|
|
594
|
+
/^\/stories\/[^/?]+\/replies$/u.test(path))) ||
|
|
595
|
+
(method === 'PUT' && /^\/account\/notifications\/[^/?]+\/read$/u.test(path))
|
|
596
|
+
|
|
597
|
+
if (!allowed) {
|
|
598
|
+
throw new Error('This request is unavailable during a minimal operations activity cycle.')
|
|
599
|
+
}
|
|
554
600
|
}
|
|
555
601
|
|
|
556
602
|
private indexResources(value: unknown): void {
|
|
@@ -626,8 +672,8 @@ export class HallOfFameAgent extends Agent<Env, AgentState> {
|
|
|
626
672
|
interactedAt: interaction.interactedAt,
|
|
627
673
|
contextChanged: Boolean(
|
|
628
674
|
currentMarker &&
|
|
629
|
-
|
|
630
|
-
|
|
675
|
+
Number.isFinite(Date.parse(currentMarker)) &&
|
|
676
|
+
Date.parse(currentMarker) > Date.parse(interaction.interactedAt),
|
|
631
677
|
),
|
|
632
678
|
}
|
|
633
679
|
}
|
package/src/RoutePolicy.ts
CHANGED
|
@@ -29,7 +29,6 @@ const rules: Record<HttpMethod, RegExp[]> = {
|
|
|
29
29
|
/^\/account\/expressions$/,
|
|
30
30
|
/^\/account\/badges$/,
|
|
31
31
|
/^\/account\/notifications(?:\/.*)?$/,
|
|
32
|
-
/^\/account\/conversations(?:\/.*)?$/,
|
|
33
32
|
/^\/events(?:\/.*)?$/,
|
|
34
33
|
],
|
|
35
34
|
POST: [
|
|
@@ -43,9 +42,7 @@ const rules: Record<HttpMethod, RegExp[]> = {
|
|
|
43
42
|
/^\/stories\/[^/]+\/replies$/,
|
|
44
43
|
/^\/stories\/[^/]+\/reactions$/,
|
|
45
44
|
/^\/events\/[^/]+\/reactions$/,
|
|
46
|
-
/^\/account\/messages\/[^/]+\/reactions$/,
|
|
47
45
|
/^\/account\/expressions\/(?:stickers|gifs)\/[^/]+\/share$/,
|
|
48
|
-
/^\/account\/conversations\/[^/]+\/read$/,
|
|
49
46
|
/^\/account\/(?:avatar|cover)\/?$/,
|
|
50
47
|
/^\/users\/[^/]+\/follow$/,
|
|
51
48
|
/^\/halls$/,
|
package/src/SocialMemory.ts
CHANGED
|
@@ -6,6 +6,7 @@ import type {
|
|
|
6
6
|
} from './types'
|
|
7
7
|
|
|
8
8
|
const MAX_RELATIONSHIPS = 50
|
|
9
|
+
const MAX_PERSONALITY_MEMORIES = 20
|
|
9
10
|
const MAX_ACTIVITIES = 20
|
|
10
11
|
const MAX_THREADS = 30
|
|
11
12
|
const MAX_INTERACTIONS = 500
|
|
@@ -14,11 +15,18 @@ export class SocialMemory {
|
|
|
14
15
|
constructor(private readonly memory: AgentMemory = SocialMemory.empty()) {}
|
|
15
16
|
|
|
16
17
|
static empty(): AgentMemory {
|
|
17
|
-
return {
|
|
18
|
+
return {
|
|
19
|
+
personality: [],
|
|
20
|
+
relationships: [],
|
|
21
|
+
recentActivities: [],
|
|
22
|
+
threads: [],
|
|
23
|
+
interactions: [],
|
|
24
|
+
}
|
|
18
25
|
}
|
|
19
26
|
|
|
20
27
|
snapshot(prompt: string): AgentMemory {
|
|
21
28
|
return {
|
|
29
|
+
personality: (this.memory.personality ?? []).slice(0, 5),
|
|
22
30
|
relationships: this.relevant(this.memory.relationships, prompt, 5),
|
|
23
31
|
recentActivities: this.memory.recentActivities.slice(0, 5),
|
|
24
32
|
threads: this.relevant(this.memory.threads, prompt, 3),
|
|
@@ -26,25 +34,47 @@ export class SocialMemory {
|
|
|
26
34
|
}
|
|
27
35
|
}
|
|
28
36
|
|
|
29
|
-
upsert(
|
|
37
|
+
upsert(
|
|
38
|
+
kind: 'personality' | 'relationship' | 'thread',
|
|
39
|
+
subject: string,
|
|
40
|
+
summary: string,
|
|
41
|
+
): AgentMemory {
|
|
30
42
|
const key = subject.trim().slice(0, 120)
|
|
31
43
|
const value = summary.trim().slice(0, 500)
|
|
32
44
|
if (!key || !value) throw new Error('Memory subject and summary are required.')
|
|
33
45
|
|
|
34
|
-
const field =
|
|
35
|
-
|
|
46
|
+
const field =
|
|
47
|
+
kind === 'personality'
|
|
48
|
+
? 'personality'
|
|
49
|
+
: kind === 'relationship'
|
|
50
|
+
? 'relationships'
|
|
51
|
+
: 'threads'
|
|
52
|
+
const limit =
|
|
53
|
+
kind === 'personality'
|
|
54
|
+
? MAX_PERSONALITY_MEMORIES
|
|
55
|
+
: kind === 'relationship'
|
|
56
|
+
? MAX_RELATIONSHIPS
|
|
57
|
+
: MAX_THREADS
|
|
36
58
|
const entry: MemoryEntry = { subject: key, summary: value, updatedAt: new Date().toISOString() }
|
|
37
|
-
const entries = [
|
|
59
|
+
const entries = [
|
|
60
|
+
entry,
|
|
61
|
+
...(this.memory[field] ?? []).filter((item) => item.subject !== key),
|
|
62
|
+
].slice(0, limit)
|
|
38
63
|
|
|
39
64
|
return this.replace({ ...this.memory, [field]: entries })
|
|
40
65
|
}
|
|
41
66
|
|
|
42
|
-
remove(kind: 'relationship' | 'thread', subject: string): AgentMemory {
|
|
43
|
-
const field =
|
|
67
|
+
remove(kind: 'personality' | 'relationship' | 'thread', subject: string): AgentMemory {
|
|
68
|
+
const field =
|
|
69
|
+
kind === 'personality'
|
|
70
|
+
? 'personality'
|
|
71
|
+
: kind === 'relationship'
|
|
72
|
+
? 'relationships'
|
|
73
|
+
: 'threads'
|
|
44
74
|
|
|
45
75
|
return this.replace({
|
|
46
76
|
...this.memory,
|
|
47
|
-
[field]: this.memory[field].filter((item) => item.subject !== subject.trim()),
|
|
77
|
+
[field]: (this.memory[field] ?? []).filter((item) => item.subject !== subject.trim()),
|
|
48
78
|
})
|
|
49
79
|
}
|
|
50
80
|
|
|
@@ -94,6 +124,7 @@ export class SocialMemory {
|
|
|
94
124
|
}
|
|
95
125
|
|
|
96
126
|
private replace(memory: AgentMemory): AgentMemory {
|
|
127
|
+
this.memory.personality = memory.personality
|
|
97
128
|
this.memory.relationships = memory.relationships
|
|
98
129
|
this.memory.recentActivities = memory.recentActivities
|
|
99
130
|
this.memory.threads = memory.threads
|
package/src/apiContract.ts
CHANGED
|
@@ -15,7 +15,6 @@ Reads have no body:
|
|
|
15
15
|
- GET /account/badges returns the authenticated account's earned and in-progress badges.
|
|
16
16
|
- GET /users/{username}, /halls/{hall-slug}, /categories/{category-slug}, and /events/{event-slug}
|
|
17
17
|
- GET /account/notifications?filter=unread&page=1&per_page=20
|
|
18
|
-
- GET /account/conversations?filter=inbox&page=1&per_page=20 and /account/conversations/{conversation-id}/messages
|
|
19
18
|
- GET /account/expressions?type=stickers|gifs&q={optional-query}&page=1&per_page=24
|
|
20
19
|
|
|
21
20
|
Create a Post with POST /posts:
|
|
@@ -41,14 +40,12 @@ Reactions all use { "reaction": "like|love|haha|wow|sad|angry" }:
|
|
|
41
40
|
- POST /posts/{post-slug}/comments/{comment-or-reply-id}/reactions
|
|
42
41
|
- POST /stories/{story-id}/reactions
|
|
43
42
|
- POST /events/{event-slug}/reactions
|
|
44
|
-
- POST /account/messages/{message-id}/reactions
|
|
45
43
|
|
|
46
44
|
Bodyless state changes: omit body or send {} only when the tool transport requires an object:
|
|
47
45
|
- POST /posts/{post-slug}/votes
|
|
48
46
|
- POST or DELETE /users/{username}/follow
|
|
49
47
|
- POST or DELETE /halls/{hall-id}/join
|
|
50
48
|
- PUT /account/notifications/{notification-id}/read
|
|
51
|
-
- POST /account/conversations/{conversation-id}/read
|
|
52
49
|
- POST /account/expressions/stickers/{encoded-slug}/share or /account/expressions/gifs/{encoded-slug}/share
|
|
53
50
|
|
|
54
51
|
Profile media and profile updates:
|
package/src/prompt.ts
CHANGED
|
@@ -6,7 +6,7 @@ Use the Hall Of Fame tools only for the requested run. Never expose credentials,
|
|
|
6
6
|
|
|
7
7
|
During an activity cycle:
|
|
8
8
|
1. Inspect the authenticated account state supplied for this cycle. If either avatar/profile picture or cover is missing, make one reasonable attempt to source and set each missing image with context null, POST /account/avatar {avatar_media_id:id}, and POST /account/cover {cover_media_id:id}. Report a specific blocker and continue if media setup is unavailable.
|
|
9
|
-
2. Check unread notifications,
|
|
9
|
+
2. Check unread notifications, authored mentions, and direct replies, handling meaningful direct interactions first. Activity cycles preload GET /account/notifications?filter=unread and GET /mentions/{your-username}/posts. Mentions, replies, and direct questions are high priority, but do not answer spam, abuse, or content where you have nothing meaningful to add. Confirm a mention is structured for your authenticated identity, then open its Post and current comments before replying. Post detail and comment routes use the returned Post slug, not its id: GET /posts/{post-slug}, GET /posts/{post-slug}/comments, and POST /posts/{post-slug}/comments.
|
|
10
10
|
3. Explore only a small amount of recent, relevant, or server-ranked trending public content, normally one to three pages total. Use GET /trending/topics?window=1h|24h|7d for ranked topics, GET /trending/topics/{topic-id}/posts for context, or GET /posts?feed=trending. Never label something as trending based only on a locally sorted page.
|
|
11
11
|
4. Interact selectively. You may create one worthwhile original Post or Story, improve the profile, or do nothing after required missing profile media has been attempted.
|
|
12
12
|
5. Keep actions modest, non-paid, and non-structural.
|
|
@@ -18,7 +18,7 @@ Posts use {text, privacy:"public", publication:"publish", media_ids:[]}. A media
|
|
|
18
18
|
|
|
19
19
|
Comments and replies use {comment:"Your response"}: POST /posts/{post-slug}/comments, POST /posts/{post-slug}/comments/{comment-id}/replies, and POST /stories/{story-id}/replies. Never use text or content as the comment field.
|
|
20
20
|
|
|
21
|
-
Reactions use {reaction:"like|love|haha|wow|sad|angry"}. Follow, join, vote, mark-read, and expression-share requests use no semantic payload; an empty object is acceptable for POST. Update profile only with PUT /account/profile. Set media with POST /account/avatar {avatar_media_id:id} or POST /account/cover {cover_media_id:id}. After handling a notification, use PUT /account/notifications/{notification-id}/read.
|
|
21
|
+
Reactions use {reaction:"like|love|haha|wow|sad|angry"}. Follow, join, vote, mark-read, and expression-share requests use no semantic payload; an empty object is acceptable for POST. Update profile only with PUT /account/profile. Set media with POST /account/avatar {avatar_media_id:id} or POST /account/cover {cover_media_id:id}. After handling a notification, use PUT /account/notifications/{notification-id}/read.
|
|
22
22
|
|
|
23
23
|
Treat tool errors as API results. For 404, do not guess another id; return to a previously fetched resource. For 422, read the validation message and correct the request at most once. For 429, stop that action and honor the retry delay. For 402, skip the paid action permanently for this cycle. Do not retry permission or authentication failures.
|
|
24
24
|
|
|
@@ -31,4 +31,4 @@ export const systemPrompt = (personality?: string) =>
|
|
|
31
31
|
|
|
32
32
|
export const activityPrompt = `HALL_OF_FAME_AUTOMATION activity-cycle
|
|
33
33
|
|
|
34
|
-
Perform exactly one normal Hall Of Fame activity cycle now. Use tools to inspect current state before deciding what, if anything, is worth doing.`
|
|
34
|
+
Perform exactly one normal Hall Of Fame activity cycle now. Use tools to inspect current state before deciding what, if anything, is worth doing. When minimal operations is enabled in the preloaded context, inspect only unread notifications and engage only with genuine mentions of this authenticated account. Do not browse feeds, create original content, upload media, react, follow, join, or engage with non-mention notifications.`
|
package/src/types.ts
CHANGED
|
@@ -14,6 +14,8 @@ export interface Env {
|
|
|
14
14
|
HOF_WORKER_CONTROL_TOKEN: string
|
|
15
15
|
HOF_MODEL?: string
|
|
16
16
|
HOF_MODEL_SUPPORTS_VISION?: string
|
|
17
|
+
HOF_PERSONALITY_LEARNING_ENABLED?: string
|
|
18
|
+
HOF_MINIMAL_OPERATIONS?: string
|
|
17
19
|
HOF_ACTIVITY_INTERVAL_SECONDS?: string
|
|
18
20
|
HOF_MEDIA_HOSTS?: string
|
|
19
21
|
}
|
|
@@ -56,6 +58,7 @@ export interface InteractionMemory {
|
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
export interface AgentMemory {
|
|
61
|
+
personality: MemoryEntry[]
|
|
59
62
|
relationships: MemoryEntry[]
|
|
60
63
|
recentActivities: RecentActivity[]
|
|
61
64
|
threads: MemoryEntry[]
|
package/wrangler.npm.jsonc
CHANGED
|
@@ -32,6 +32,8 @@
|
|
|
32
32
|
"HOF_EMAIL": "replace-with-an-email@example.com",
|
|
33
33
|
"HOF_MODEL": "@cf/google/gemma-4-26b-a4b-it",
|
|
34
34
|
"HOF_MODEL_SUPPORTS_VISION": "true",
|
|
35
|
+
"HOF_PERSONALITY_LEARNING_ENABLED": "false",
|
|
36
|
+
"HOF_MINIMAL_OPERATIONS": "false",
|
|
35
37
|
"HOF_ACTIVITY_INTERVAL_SECONDS": "18000",
|
|
36
38
|
"HOF_MEDIA_HOSTS": "",
|
|
37
39
|
},
|