Repository navigation
chore: version packages - #54
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
Releases
@context-chef/ai-sdk-middleware@3.1.0
Minor Changes
#53
3549deeThanks @MyPrototypeWhat! - Track core 4.2: one context store, one overflow strategy.truncate.storereplacestruncate.storage(now@deprecated): pass aStorageBackend—InMemoryBackend,FileSystemBackend, your own — or a pre-builtStoreshared with an archive, instead of a bareVFSStorageAdapter.storewins when both are set; a legacy adapter still works and is wrapped withStore.fromVfsAdapter. Truncated output carries the samecontext://vfs/URI either way, readable back throughchef.resolveRecall(uri)or thecontexttool'sview.overflow: { strategy, archive }: pass an explicitOverflowStrategy—summarize(),anchored(),reset(), composed withchain()/background()— in place of the policy thecompressoptions describe, and anarchivethat keeps the evicted span retrievable behind the URI its summary cites. Settingoverflow.strategyignores thecompresstuning options (two descriptions of one thing would disagree); the runner concerns —contextWindow,tokenizer,compress.triggerRatio,compress.usagePreference,onCompress,onBeforeCompress— keep applying whatever the strategy is, andcontextWindowstays required.archivetakes the explicit{ store }form: the'vfs'shorthand substitutes a ContextChef-owned Offloader, which a middleware does not have.contextWindowthrow and the compress-without-persistence warning now come from core's sharedcreateJanitorPool()instead of a copy maintained here. No behavior change.toolsmode has no target in this package: it neither constructs aContextChefnor dispatches library-owned tools, so thecontexttool is reached through a chef in your own loop.Patch Changes
3549dee]:@context-chef/core@4.2.0
Minor Changes
#53
3549deeThanks @MyPrototypeWhat! - The five-axis refactor: one owner per axis — selection, placement, persistence, retrieval, adaptation.Every option that changed name keeps a working deprecated alias,
toolsstays'legacy', and a golden suite (10 configurations × 3 targets, payloads captured before the first edit) asserts the compiled bytes are unchanged under default configuration through every phase below.MIGRATION-5.mdlists each alias and what replaces it in 5.0.createJanitorPool()replaces the budgeting / persistence-warning / Janitor assembly thatai-sdk-middlewareandtanstack-aihad each copied;createThinkingTextifier()dedupes the<thinking>textifier and the redacted-thinking warn-once shared by the OpenAI and Gemini adapters.computeAnthropicBetasand the default server-edits config move out of the facade intoanthropicServerContextManagement()in the Anthropic adapter._anthropic_compaction,_gemini_thought_signatureand_openai_reasoningbecome typed optionalMessagefields instead of index-signature passthroughs.resolveRecall(uri, { format: 'text' })renders an archived span as a readable transcript instead of the stored{ version, messages }JSON (default unchanged). No behavior change under default config.compile()is now a fixed, named phase list (start→transform-tool-results→handoff→overflow→inject→memory→skill→assemble→tail→adapt→audit→done), each phase its own file undersrc/pipeline/phases/, reaching chef state through a closure so nothing became public that was not already.chef.use(slot, handler)/chef.unuse(slot, handler)are the composition surface:before-overflow(returnfalseto skip overflow this compile),after-overflow,before-assemble(ctx.inject(text)),after-assemble(messages → messages),before-adapt,after-adapt. Handlers run in registration order.ChefConfig.onBeforeCompileandtransformContextare now registrations onbefore-assemble/after-assemble— same code path, same output, and both are@deprecated.ChefConfig.pipelineChecks(default off) verifies once after the wholeafter-assemblechain that pinned messages survived and tool pairs are intact, and once after the tail phase that nothing ahead of the insertion point changed; violations are reported throughlogger.warnand apipeline:invariantevent and never throw. No behavior change under default config.OverflowStrategy(phase 2): what leaves the window is now a policy object, and the Janitor is the runner around it — budget evaluation, circuit breaker,compress:*events,onCompress/onBeforeCompress, durable compaction, archive. Built-ins insrc/overflow/:summarize(opts)(the'rewrite'path),anchored(opts)(the persistent anchor document),server(config, { fallback })(Anthropic server-managed compaction, running the fallback on every other target),reset(opts)(new — keep pinned, evict the rest),chain(...strategies)(escalate when a strategy returnschanged: falseor is still over budget) andbackground(strategy)(the non-blocking job, with its content-equivalence staleness check). A strategy may implementcommit()(so a speculative apply cannot pollute an anchor),attach(),snapshot()/restore().ChefConfig.overflow: { strategy, archive, handoff }is the new home;janitor.compressionMode/compressionScheduling/archiveandcontextManagement.strategy/.serverall still build exactly the equivalent strategy and are@deprecated(setting both warns once, andoverflow.strategywins). Archiving is strategy-agnostic now: whatever span a strategy compressed is what gets stored, still undercontext://vfs/in 4.x.before-overflowhandlers receive the runner's real budget.OverflowResultdeclares bothspanandevicted:spanis what the summary covers (pinned turns re-inserted included),evictedis what actually left the window, and a result that changed nothing declares both empty.onCompress, the archive payload and the citation all readspan, so those numbers match 4.1.OverflowInput.forcedmarks arequestNewContext()pass:summarize()/anchored()then fold every turn but the most recent, ignoringpreserveRecentMessages/preserveRatio.OverflowStrategy.pending?()letsbackground()land a finished job on the next compile even when the history is back under budget (its job accessor is nowpendingJob). Janitor: 1294 → 870 lines. No behavior change under default config.new_context, window lineage (phase 3):overflow.handoff: { budgetTokens, prompt? }reserves headroom above the compression trigger — when remaining tokens drop into that band, one compile carries a notice through the tail channel telling the model its window is about to be cut, so state worth keeping can be written tomemory//notes/while the conversation is still there to write it from. Once per window, validated at construction,{n_remaining}template, never persisted and never ingetAnnouncements(), skipped on server-managed compiles.getNewContextToolDefinition()(static, no parameters) pluschef.requestNewContext()let the model close a window deliberately: the next compile applies the strategy whatever the budget says, and abefore-overflowveto or an open circuit breaker still wins. Window lineage ({ first, previous?, current }) is owned by the runner and advances at commit time only, so a stale background result never moves it;OverflowResult.meta.windowIdis the window acted on,CompileMeta.windowIdthe window the payload belongs to.anchored()keys its anchor per window (pre-4.2 flatanchorDocsnapshots are adopted by the first window). A forced overflow that cannot run — server-managed target, or abefore-overflowveto — is consumed anyway and reported through apipeline:invariantevent plus a warn-once, never silently. The once-per-window handoff flag travels inChefSnapshot.handoffNoticedWindow. Opt-in; no behavior change under default config.StorageBackend, oneStore(phase 4a): persistence collapses to addressed content plus metadata.StorageBackendisread/write/delete/listwith optionalreadAll/append/search/snapshot/restore/getPhysicalPathqueried as capabilities;Storeroutes namespaces, parses and buildscontext://<ns>/<path>URIs, assigns auto-ids, falls back to read-modify-write forappend, and owns the per-namespace LRU eviction that used to live in the Offloader. ShipsInMemoryBackendandFileSystemBackend(a port ofFileSystemAdapterwith a per-namespace on-disk layout, so the Offloader's flat VFS files keep loading).Memoryaccepts aMemoryStore, aStorageBackendor aStoreand speaks only tonamespace('memory');readAllkeepsgetAll()at 1+N reads.Offloaderaccepts aStore, aStorageBackendor aVFSStorageAdapter.VFSMemoryStoreis rebuilt onFileSystemBackend(same on-disk format;_index.jsonis still written through so a 4.1 process sharing the directory stays in sync).StoredEntriesisMap<string, StoredEntry>, soreadAllandNamespaceView.entries()hand back the backend's key order — the orderMemory.getAll()renders into the<memory>block, which a plain object would reshuffle — andgetAll()preserves it as 4.1 did.FileSystemBackendlists nested paths recursively and refuses any physical path outside its namespace directory.MemoryStore,VFSStorageAdapter,VFSMemoryStoreandFileSystemAdapterare@deprecatedand wrapped byStore.fromMemoryStore/Store.fromVfsAdapter. Public module APIs unchanged; no behavior change under default config.contexttool (phase 4b):getContextToolDefinition()returns a single static, frozen, reference-stable tool shaped likememory_20250818—view/create/str_replace/insert/delete/renameplussearch, addressed ascontext://<ns>/<path>. Its schema has exactly one enum (command), so no live key list can ever enter the cached prefix.chef.ownsTool(name)/chef.handleTool(call)are the one entry point for every library-owned tool —context,new_contextand the legacy trio — accepting the JSON string the OpenAI and Anthropic SDKs produce or an already-parsed object.memory/routes through the Memory module soallowedKeys, theonMemoryUpdateveto,onMemoryChanged, TTL andupdateCountall still apply;notes/is the model's own scratch space;vfs/andarchive/are view-only by default and render through the recall path. Model-facing mistakes (unknown path, missing argument, write to a read-only namespace, vetoed write) come back asError: …text the model can correct; programmer errors throw.ChefConfig.tools: 'legacy' | 'unified'(default'legacy') decides whatcompile()emits — under'unified'the payload carriescontext(plusnew_contextwhenoverflow.handoffis set) and never the legacy memory tools; the two sets never co-exist.ChefConfig.contextTool.writableis the access policy (default['memory', 'notes']), enforced at dispatch, never in the store.ChefConfig.storewires one backend into Memory and the Offloader, with explicit per-module stores taking precedence, andchef.getStore()exposes it.Memory.getToolDefinitions()is@deprecated. Everycontext://address is validated at dispatch — namespace and each segment reject.,.., empty segments, backslashes and control characters — and the tool description does not advertisearchive/in 4.x (reads still resolve; the namespace goes live in 5.0). Default stays'legacy'; no behavior change under default config.Vocabularyresolved once in the constructor fromtoolsmode.LEGACY_VOCABULARYdelegates verbatim to the existingPromptsentries (that delegation is the byte-identity guarantee);UNIFIED_VOCABULARYspeakscontext://addressing, names thecontexttool, and adds the window lineage line (Context window: … (previous: …)) to summaries. New constants:CONTEXT_STORE_INSTRUCTION,CONTEXT_MEMORY_BLOCK_HEADER,getContextMemoryBlock,getContextOffloadReminder,getContextSummaryWrapper,CONTEXT_HANDOFF_NOTICE_TEMPLATE.auditAnthropicCachePlacementderives its memory markers from both vocabularies, so the audit catches the block either way. A standaloneMemory/Offloader/Janitorwith no vocabulary injected behaves exactly as before, and a test asserts the one-vocabulary invariant undertools: 'unified'— no legacy tool name appears anywhere in the payload.@context-chef/tanstack-ai@1.1.0
Minor Changes
#53
3549deeThanks @MyPrototypeWhat! - Track core 4.2: one context store, one overflow strategy.truncate.storereplacestruncate.storage(now@deprecated): pass aStorageBackend—InMemoryBackend,FileSystemBackend, your own — or a pre-builtStoreshared with an archive, instead of a bareVFSStorageAdapter.storewins when both are set; a legacy adapter still works and is wrapped withStore.fromVfsAdapter. Truncated output carries the samecontext://vfs/URI either way, readable back throughchef.resolveRecall(uri)or thecontexttool'sview.overflow: { strategy, archive }: pass an explicitOverflowStrategy—summarize(),anchored(),reset(), composed withchain()/background()— in place of the policy thecompressoptions describe, and anarchivethat keeps the evicted span retrievable behind the URI its summary cites. Settingoverflow.strategyignores thecompresstuning options (two descriptions of one thing would disagree); the runner concerns —contextWindow,tokenizer,compress.triggerRatio,compress.usagePreference,onCompress,onBeforeCompress— keep applying whatever the strategy is, andcontextWindowstays required as soon as compression is configured.archivetakes the explicit{ store }form: the'vfs'shorthand substitutes a ContextChef-owned Offloader, which a middleware does not have.contextWindowthrow and the compress-without-persistence warning now come from core's sharedcreateJanitorPool()instead of a copy maintained here, and the derivable_originalText/_originalThinkingTextprojections are gone from the adapter. No behavior change.toolsmode has no target in this package: it neither constructs aContextChefnor dispatches library-owned tools, so thecontexttool is reached through a chef in your own loop.Patch Changes
3549dee]:@context-chef/examples@0.0.3
Patch Changes
3549dee,3549dee,3549dee]: