Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/context-fragment-conversations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@gemstack/framework': minor
---

feat(framework): context fragment lists the recorded conversations (#683)

Adds `.the-framework/conversations/**.md` to `CONTEXT_DOCS`, so a run is told to read the human conversations (Discord/chat turns) that earlier runs committed there. A read-only pointer, like `tickets/` and `TODO_AGENTS.md`, so it stays out of the merge-update set. The path is pinned by a test to the canonical `THE_FRAMEWORK_DIR`/`CONVERSATIONS_DIR` constants so it cannot drift from where runs actually commit.
13 changes: 10 additions & 3 deletions packages/framework/src/system-prompt.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {
} from './system-prompt.js'
import { FLAT_TODO_FILE, TICKETING_FORMAT_FILE, TODO_FORMAT_FILE } from './tickets.js'
import { loadUserSystemPrompt, SYSTEM_PROMPT_FILE } from './system-prompt-file.js'
import { CONVERSATIONS_DIR } from './conversations.js'
import { THE_FRAMEWORK_DIR } from './framework-dir.js'

/** The context docs as the commented bullets they render to (#559/#683). */
const KNOWLEDGE_LINES = CONTEXT_DOCS.map(d => `- \`${d.path}\` (${d.comment})`).join('\n')
Expand All @@ -29,14 +31,15 @@ test('CONTEXT_DOCS is the #683 fragment: business knowledge plus the roadmap/que
'knowledge-base/MARKET_RESEARCH.md',
'knowledge-base/**.md',
'tickets/**.md',
'.the-framework/conversations/**.md',
'TODO_AGENTS.md',
])
// The business-knowledge docs are a subset the agent also updates at merge.
for (const doc of BUSINESS_KNOWLEDGE_DOCS) assert.ok(paths.includes(doc.path), `missing ${doc.path}`)
// GOAL / market research / tickets / TODO_AGENTS are read-only context, so they are not in the
// merge-update set.
// GOAL / market research / tickets / conversations / TODO_AGENTS are read-only context, so they
// are not in the merge-update set.
const businessPaths = BUSINESS_KNOWLEDGE_DOCS.map(d => d.path)
for (const p of ['GOAL.md', 'knowledge-base/MARKET_RESEARCH.md', 'knowledge-base/**.md', 'tickets/**.md', 'TODO_AGENTS.md']) {
for (const p of ['GOAL.md', 'knowledge-base/MARKET_RESEARCH.md', 'knowledge-base/**.md', 'tickets/**.md', '.the-framework/conversations/**.md', 'TODO_AGENTS.md']) {
assert.ok(!businessPaths.includes(p))
}
// The ticket-format pointer is inlined here (this module stays node-free), so pin it to the
Expand All @@ -46,6 +49,10 @@ test('CONTEXT_DOCS is the #683 fragment: business knowledge plus the roadmap/que
// Same for the #880 backlog-format pointer.
const todo = CONTEXT_DOCS.find(d => d.path === FLAT_TODO_FILE)
assert.ok(todo?.comment.includes(TODO_FORMAT_FILE), `expected the ${TODO_FORMAT_FILE} pointer`)
// The conversations pointer (#683/#908) is inlined too, so pin its dir to the canonical
// constants rather than a bare literal that could drift from where runs actually commit.
const conversations = CONTEXT_DOCS.find(d => d.path.startsWith(`${THE_FRAMEWORK_DIR}/${CONVERSATIONS_DIR}/`))
assert.ok(conversations, `expected the ${THE_FRAMEWORK_DIR}/${CONVERSATIONS_DIR}/ pointer`)
})
import { AWAIT_PROTOCOL, BROWSER_PROTOCOL, SIGNAL_PROTOCOL } from './turn-gate.js'

Expand Down
19 changes: 12 additions & 7 deletions packages/framework/src/system-prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,15 @@ export const BUSINESS_KNOWLEDGE_DOCS: readonly ContextDoc[] = [DECISIONS_DOC, FA
/**
* Everything the agent keeps in context at the start of a run (#683), which
* {@link systemPromptBlock} renders as the `Context:` bullets. A superset of
* {@link BUSINESS_KNOWLEDGE_DOCS}: it adds `GOAL.md` and the two roadmap/queue pointers the
* {@link BUSINESS_KNOWLEDGE_DOCS}: it adds `GOAL.md` and the roadmap/queue/history pointers the
* agent reads but does *not* fold knowledge back into — `tickets/**.md` (the potential work,
* whose file shape is the packaged `ticketing_format.md` spec, #684/#674) and the `TODO_AGENTS.md`
* task queue. Repo-root paths, because that is the agent's cwd. README is left out: a repo's
* own `README.md` already covers the overview. The ticket-format path is inlined rather than
* imported from `tickets.ts`: this module must stay free of `node:fs` (it renders in the
* browser, #520), and a test pins the literal to `TICKETING_FORMAT_FILE`. The `TODO_AGENTS.md`
* format pointer (#880) is inlined for the same reason and pinned to `TODO_FORMAT_FILE`.
* whose file shape is the packaged `ticketing_format.md` spec, #684/#674), the `TODO_AGENTS.md`
* task queue, and the committed conversations (#683/#908). Repo-root paths, because that is the
* agent's cwd. README is left out: a repo's own `README.md` already covers the overview. The
* ticket-format path is inlined rather than imported from `tickets.ts`: this module must stay free
* of `node:fs` (it renders in the browser, #520), and a test pins the literal to
* `TICKETING_FORMAT_FILE`. The `TODO_AGENTS.md` format pointer (#880) and the
* `.the-framework/conversations/` path are inlined for the same reason and pinned by a test.
*/
export const CONTEXT_DOCS: readonly ContextDoc[] = [
DECISIONS_DOC,
Expand All @@ -133,6 +134,10 @@ export const CONTEXT_DOCS: readonly ContextDoc[] = [
// The catch-all (#683): any other file the agent parks under knowledge-base/.
{ path: 'knowledge-base/**.md', comment: 'more files holding knowledge related to the project' },
{ path: 'tickets/**.md', comment: 'things to potentially work on; format: node_modules/@gemstack/framework/prompts/ticketing_format.md' },
// Recorded human conversations (#683/#908): the run committed each Discord/chat turn here, so a
// future agent can read what was said. A read-only pointer, so it stays out of BUSINESS_KNOWLEDGE_DOCS.
// Path inlined to keep this module node-free; pinned to THE_FRAMEWORK_DIR/CONVERSATIONS_DIR by a test.
{ path: '.the-framework/conversations/**.md', comment: 'recorded human conversations (e.g. via the Discord bot)' },
{ path: 'TODO_AGENTS.md', comment: 'the AI task queue; format: node_modules/@gemstack/framework/prompts/todo_format.md' },
]

Expand Down
Loading