fix: keep memory id out of the add-field menu and drop the memory id telemetry

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
hugocasa
2026-09-15 18:40:14 +02:00
co-authored by Claude Opus 5
parent e75c8acac7
commit 091e1128a3
8 changed files with 29 additions and 26 deletions
+1 -1
View File
@@ -1 +1 @@
1a8f29cd14fce3b7c6eb20d27f5b58b8ae56d9f5
1c1dab33563c4907aff8b0da825fb66db60af82a
@@ -90,7 +90,7 @@
} from './flows/linkedAgentDrafts'
import { agentDraftDeployRefusal } from './flows/agentDraft.svelte'
import { markAgentWritten } from './flows/agentEditorStore.svelte'
import { logReusableAgentUsage, logStepMemoryIdUsage } from './flows/agentTelemetry'
import { logReusableAgentUsage } from './flows/agentTelemetry'
import { deployDraft } from '$lib/utils_draft_deploy'
import { getUserExt } from '$lib/user'
import { Triggers } from './triggers/triggers.svelte'
@@ -657,11 +657,6 @@
...structuredClone($state.snapshot(newSavedFlow)),
path: $pathStore
} as Flow
dfsApply(flow.value.modules ?? [], (module) => {
if (module.value.type === 'aiagent') {
logStepMemoryIdUsage(module.value.input_transforms?.memory_id)
}
})
setDraftTriggers([])
loadingSave = false
onDeploy?.({ path: $pathStore })
@@ -1085,8 +1085,7 @@
change a membership, the plan tier and quota shown when the execution meter is opened,
whether app sandbox isolation is turned on, whether a step's workspace script is
edited from the flow editor, which skin approval steps are given, how many AI sessions
are brought back from the workspace object storage backup, whether AI agent steps set
their own memory id as a fixed id or an expression, how data tables and their
are brought back from the workspace object storage backup, how data tables and their
migrations are set up and used, how often an empty workspace home is seen, how often
the home pages create menu and hub-project picker are opened and from which entry
point, the name of any public hub project imported from the home page and how far that
@@ -1152,8 +1151,7 @@
change a membership, the plan tier and quota shown when the execution meter is opened,
whether app sandbox isolation is turned on, whether a step's workspace script is
edited from the flow editor, which skin approval steps are given, how many AI sessions
are brought back from the workspace object storage backup, whether AI agent steps set
their own memory id as a fixed id or an expression, how data tables and their
are brought back from the workspace object storage backup, how data tables and their
migrations are set up and used, how often an empty workspace home is seen, how often
the home pages create menu and hub-project picker are opened and from which entry
point, the name of any public hub project imported from the home page and how far that
@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest'
import { AI_AGENT_SCHEMA } from './flowInfers'
import { AI_AGENT_SCHEMA, memoryPropertyFor } from './flowInfers'
import {
AGENT_FIELD_BY_KEY,
AGENT_FIELDS,
@@ -100,3 +100,20 @@ describe('historyInputApplies', () => {
expect(historyInputApplies('messages', undefined)).toBe(true)
})
})
describe('memoryPropertyFor', () => {
const property = schemaProperties.memory
const kinds = (value: unknown) =>
memoryPropertyFor(property, value).oneOf.map((variant: { title: string }) => variant.title)
it('adds a legacy kind as an option only while the value holds it', () => {
expect(memoryPropertyFor(property, { kind: 'window', context_length: 10 })).toBe(property)
expect(memoryPropertyFor(property, undefined)).toBe(property)
expect(kinds({ kind: 'auto', context_length: 4, memory_id: 'x' })).toEqual([
'off',
'window',
'auto'
])
expect(kinds({ kind: 'manual', messages: [] })).toEqual(['off', 'window', 'manual'])
})
})
@@ -142,7 +142,6 @@ export const AGENT_FIELDS: AgentFieldSpec[] = [
tooltip:
'Conversation history id: runs with the same id share their history. Inherited uses the memory_id the run was started with: the conversation id in chat mode, or the memory_id query parameter otherwise. Without either, each run starts fresh. Custom sets the id on the step: a fixed id shares one history across all runs, an expression keeps one history per value.',
implicit: '',
defaultHint: 'Default: inherited from the run',
textOnly: true
},
{
@@ -1,4 +1,3 @@
import type { InputTransform } from '$lib/gen'
import { logFeatureUsage } from '$lib/utils/featureUsage'
// Anonymous counters for the reusable-agent lifecycle (`docs/reusable-ai-agents.md`). Same rules
@@ -22,12 +21,3 @@ export type ReusableAgentEvent =
export function logReusableAgentUsage(event: ReusableAgentEvent): void {
logFeatureUsage('ai_agent', 'reusable', { key: event })
}
/** An agent step deployed with a memory id of its own instead of the run's, keyed by whether it is
* one fixed id or an expression giving one memory per key. */
export function logStepMemoryIdUsage(memoryId: InputTransform | undefined): void {
if (!memoryId) return
logFeatureUsage('ai_agent', 'memory_id', {
key: memoryId.type === 'static' ? 'fixed' : 'expression'
})
}
@@ -180,7 +180,7 @@
let schemaProperties = $derived((schema?.properties ?? {}) as Record<string, any>)
// Whether the brain edited here, or the linked agent's, keeps managed memory. Unknown for an
// expression or a linked agent still loading, which leaves both history inputs open.
// expression or a linked agent that has not loaded, which keeps previous messages addable.
let managedMemory = $derived.by((): boolean | undefined => {
if ('memory' in schemaProperties) {
const transform = args?.memory
@@ -232,7 +232,8 @@
)
)
// Offered whenever the agent may keep managed memory: on, or an expression the form cannot read.
// Offered when managed memory is on or an expression the form cannot read, not while a linked
// agent's setting is unknown.
// Unset, the memory id the run was started with applies, so the step's own id sits behind a
// choice and the key exists only once Custom is picked.
let memoryIsExpression = $derived(
@@ -325,6 +326,8 @@
!spec.virtual &&
!isShown(spec.key) &&
!(imageOutput && spec.textOnly) &&
// Memory id's row appears on its own when it is offered, so the menu never adds it.
spec.key !== 'memory_id' &&
!(isHistoryKey(spec.key) && !historyInputApplies(spec.key, managedMemory))
)
}
@@ -210,7 +210,8 @@ export const LEGACY_MEMORY_VARIANTS: Record<string, any> = {
}
/** The memory property to render for a value: a legacy kind is added as an option only while the
* value holds it. */
* value holds it. Otherwise the property itself is returned, which callers compare by identity to
* avoid rebuilding the step schema. */
export function memoryPropertyFor(property: any, value: any): any {
const legacy = value?.kind ? LEGACY_MEMORY_VARIANTS[value.kind] : undefined
if (!legacy || !property?.oneOf) return property