refactor(core): simplify system context update metadata

This commit is contained in:
Kit Langton 2026-07-02 20:13:02 -04:00
commit 860604ec4c
5 changed files with 47 additions and 56 deletions

View file

@ -31,23 +31,10 @@ const update = (previous: ReadonlyArray<Summary>, current: ReadonlyArray<Summary
(server) => server.server,
(before, after) => before.instructions !== after.instructions,
)
const items = [
...diff.added.map((server) => ({
key: server.server,
description: "MCP server instructions",
action: "added" as const,
})),
...diff.removed.map((server) => ({
key: server.server,
description: "MCP server instructions",
action: "removed" as const,
})),
...diff.changed.map((server) => ({
key: server.current.server,
description: "MCP server instructions",
action: "updated" as const,
})),
]
const items = SystemContext.diffItems(diff, (server) => ({
key: server.server,
description: "MCP server instructions",
}))
// Additions and removals render as small deltas; anything else restates the full list.
if (diff.changed.length > 0 || (diff.added.length === 0 && diff.removed.length === 0))
return {

View file

@ -35,23 +35,10 @@ const update = (previous: ReadonlyArray<typeof Summary.Type>, current: ReadonlyA
(reference) => reference.name,
(before, after) => before.path !== after.path || before.description !== after.description,
)
const items = [
...diff.added.map((reference) => ({
key: reference.name,
description: reference.description ?? reference.path,
action: "added" as const,
})),
...diff.removed.map((reference) => ({
key: reference.name,
description: reference.description ?? reference.path,
action: "removed" as const,
})),
...diff.changed.map((reference) => ({
key: reference.current.name,
description: reference.current.description ?? reference.current.path,
action: "updated" as const,
})),
]
const items = SystemContext.diffItems(diff, (reference) => ({
key: reference.name,
description: reference.description ?? reference.path,
}))
// Additions and removals render as small deltas; anything else restates the full list.
if (diff.changed.length > 0 || (diff.added.length === 0 && diff.removed.length === 0))
return {

View file

@ -37,15 +37,7 @@ const update = (previous: ReadonlyArray<Summary>, current: ReadonlyArray<Summary
(skill) => skill.name,
(before, after) => before.description !== after.description,
)
const items = [
...diff.added.map((skill) => ({ key: skill.name, description: skill.description, action: "added" as const })),
...diff.removed.map((skill) => ({ key: skill.name, description: skill.description, action: "removed" as const })),
...diff.changed.map((skill) => ({
key: skill.current.name,
description: skill.current.description,
action: "updated" as const,
})),
]
const items = SystemContext.diffItems(diff, (skill) => ({ key: skill.name, description: skill.description }))
// Additions and removals render as small deltas; anything else restates the full list.
if (diff.changed.length > 0 || (diff.added.length === 0 && diff.removed.length === 0))
return {

View file

@ -117,7 +117,6 @@ export class DuplicateKeyError extends Schema.TaggedErrorClass<DuplicateKeyError
interface PackedSource {
readonly key: Key
readonly description: string
readonly load: Effect.Effect<Observed | Unavailable>
/** Restates the model's belief from a last-applied value when the source cannot be observed. */
readonly recall: (stored: AppliedSource) => string | undefined
@ -150,7 +149,6 @@ export function make<A>(source: Source<A>): SystemContext {
return context([
{
key: source.key,
description,
recall: (stored) =>
Option.match(decode(stored.value), {
onNone: () => undefined,
@ -163,8 +161,9 @@ export function make<A>(source: Source<A>): SystemContext {
description,
applied: {
value: encode(value),
description,
...(source.removed ? { removed: requireText(source.key, "removal", source.removed(value)) } : {}),
...(source.removed
? { description, removed: requireText(source.key, "removal", source.removed(value)) }
: {}),
},
baseline: () => baseline(value),
update: (previous) =>
@ -206,6 +205,17 @@ export function diffByKey<A>(
}
}
export function diffItems<A>(
diff: ReturnType<typeof diffByKey<A>>,
item: (value: A) => { readonly key: string; readonly description: string },
): ReadonlyArray<ReconcileItemUpdate> {
return [
...diff.added.map((value) => ({ ...item(value), action: "added" as const })),
...diff.removed.map((value) => ({ ...item(value), action: "removed" as const })),
...diff.changed.map((value) => ({ ...item(value.current), action: "updated" as const })),
]
}
/** Combines contexts in order and rejects duplicate source keys immediately. */
export function combine(values: ReadonlyArray<SystemContext>): SystemContext {
const sources = values.flatMap((value) => value[ContextTypeId])

View file

@ -62,7 +62,7 @@ describe("SystemContext", () => {
text: "Today's date is 2026-06-03.\n\nDirectory: /repo",
applied: {
"core/date": { value: "2026-06-03", description: "Current date", removed: "The date was removed." },
"core/location": { value: "/repo", description: "Description for core/location" },
"core/location": { value: "/repo" },
},
})
expect(loads).toBe(1)
@ -123,7 +123,7 @@ describe("SystemContext", () => {
_tag: "Updated",
text: "Available skill: effect",
updates: [{ key: key("core/skills"), description: "Description for core/skills", action: "added" }],
applied: { "core/skills": { value: "effect", description: "Description for core/skills" } },
applied: { "core/skills": { value: "effect" } },
})
}),
)
@ -182,7 +182,7 @@ describe("SystemContext", () => {
text: "effect",
updates: [{ key: key("core/skills"), description: "Description for core/skills", action: "added" }],
applied: {
"core/skills": { value: "effect", description: "Description for core/skills" },
"core/skills": { value: "effect" },
"core/date": { value: "2026-06-04" },
},
})
@ -221,7 +221,7 @@ describe("SystemContext", () => {
_tag: "Updated",
text: "2026-06-04",
updates: [{ key: key("core/date"), description: "Description for core/date", action: "updated" }],
applied: { "core/date": { value: "2026-06-04", description: "Description for core/date" } },
applied: { "core/date": { value: "2026-06-04" } },
})
}),
)
@ -250,8 +250,8 @@ describe("SystemContext", () => {
{ key: key("core/location"), description: "Description for core/location", action: "updated" },
],
applied: {
"core/date": { value: "2026-06-04", description: "Description for core/date" },
"core/location": { value: "/repo", description: "Description for core/location" },
"core/date": { value: "2026-06-04" },
"core/location": { value: "/repo" },
},
})
}),
@ -274,7 +274,7 @@ describe("SystemContext", () => {
expect(yield* SystemContext.rebaseline(context, { "core/date": { value: "2026-06-03" } })).toEqual({
text: "2026-06-04",
applied: { "core/date": { value: "2026-06-04", description: "Current date" } },
applied: { "core/date": { value: "2026-06-04" } },
})
expect(loads).toBe(1)
}),
@ -298,7 +298,7 @@ describe("SystemContext", () => {
).toEqual({
text: "2026-06-04\n\nInstructions: contents",
applied: {
"core/date": { value: "2026-06-04", description: "Description for core/date" },
"core/date": { value: "2026-06-04" },
"core/remote": { value: "contents", removed: "Instructions removed" },
},
})
@ -349,6 +349,21 @@ describe("SystemContext", () => {
},
],
})
expect(
SystemContext.diffItems(
SystemContext.diffByKey(
previous,
current,
(value) => value.name,
(before, after) => before.description !== after.description,
),
(value) => ({ key: value.name, description: value.description }),
),
).toEqual([
{ key: "writing", description: "Write prose", action: "added" },
{ key: "retired", description: "Old", action: "removed" },
{ key: "effect", description: "Build with Effect v4", action: "updated" },
])
}),
)
@ -375,7 +390,7 @@ describe("SystemContext", () => {
items: [{ key: "effect", description: "Build with Effect", action: "updated" }],
},
],
applied: { "core/skills": { value: "new", description: "Available skills" } },
applied: { "core/skills": { value: "new" } },
})
}),
)