@caupulican/pi-adaptative 0.80.54 → 0.80.57

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.
Files changed (45) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/core/agent-session.d.ts +21 -0
  3. package/dist/core/agent-session.d.ts.map +1 -1
  4. package/dist/core/agent-session.js +110 -0
  5. package/dist/core/agent-session.js.map +1 -1
  6. package/dist/core/context-gc.d.ts.map +1 -1
  7. package/dist/core/context-gc.js +4 -0
  8. package/dist/core/context-gc.js.map +1 -1
  9. package/dist/core/extensions/loader.d.ts.map +1 -1
  10. package/dist/core/extensions/loader.js +5 -0
  11. package/dist/core/extensions/loader.js.map +1 -1
  12. package/dist/core/extensions/runner.d.ts.map +1 -1
  13. package/dist/core/extensions/runner.js +1 -0
  14. package/dist/core/extensions/runner.js.map +1 -1
  15. package/dist/core/extensions/types.d.ts +4 -0
  16. package/dist/core/extensions/types.d.ts.map +1 -1
  17. package/dist/core/extensions/types.js.map +1 -1
  18. package/dist/core/memory/memory-manager.d.ts +22 -0
  19. package/dist/core/memory/memory-manager.d.ts.map +1 -0
  20. package/dist/core/memory/memory-manager.js +212 -0
  21. package/dist/core/memory/memory-manager.js.map +1 -0
  22. package/dist/core/memory/memory-provider.d.ts +25 -0
  23. package/dist/core/memory/memory-provider.d.ts.map +1 -0
  24. package/dist/core/memory/memory-provider.js +2 -0
  25. package/dist/core/memory/memory-provider.js.map +1 -0
  26. package/dist/core/memory/providers/file-store.d.ts +23 -0
  27. package/dist/core/memory/providers/file-store.d.ts.map +1 -0
  28. package/dist/core/memory/providers/file-store.js +212 -0
  29. package/dist/core/memory/providers/file-store.js.map +1 -0
  30. package/dist/core/sdk.d.ts +10 -0
  31. package/dist/core/sdk.d.ts.map +1 -1
  32. package/dist/core/sdk.js +3 -0
  33. package/dist/core/sdk.js.map +1 -1
  34. package/dist/main.d.ts.map +1 -1
  35. package/dist/main.js +5 -0
  36. package/dist/main.js.map +1 -1
  37. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  38. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  39. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  40. package/examples/extensions/sandbox/package-lock.json +2 -2
  41. package/examples/extensions/sandbox/package.json +1 -1
  42. package/examples/extensions/with-deps/package-lock.json +2 -2
  43. package/examples/extensions/with-deps/package.json +1 -1
  44. package/npm-shrinkwrap.json +12 -12
  45. package/package.json +4 -4
@@ -31,7 +31,10 @@ import { createCoreDiagnosticsToolDefinitions } from "./extensions/builtin.js";
31
31
  import { ExtensionRunner, wrapRegisteredTools, } from "./extensions/index.js";
32
32
  import { disposeExtensionEventSubscriptions } from "./extensions/loader.js";
33
33
  import { emitSessionShutdownEvent } from "./extensions/runner.js";
34
+ import { MemoryManager } from "./memory/memory-manager.js";
35
+ import { FileStoreProvider } from "./memory/providers/file-store.js";
34
36
  import { compactToolResultDetailsForRetention } from "./message-retention.js";
37
+ import { resolveProfileModelSettings } from "./model-resolver.js";
35
38
  import { expandPromptTemplate } from "./prompt-templates.js";
36
39
  import { stripResourceProfileBlocks } from "./resource-profile-blocks.js";
37
40
  import { CURRENT_SESSION_VERSION, getLatestCompactionEntry } from "./session-manager.js";
@@ -109,6 +112,13 @@ export class AgentSession {
109
112
  _allowedToolNames;
110
113
  _excludedToolNames;
111
114
  _toolProfileFilter;
115
+ _isExplicitModel;
116
+ _isExplicitThinking;
117
+ /** Plug-and-play memory subsystem. Recreated on each (re)initialize so reload is safe. */
118
+ _memoryManager = new MemoryManager();
119
+ _isChildSession;
120
+ /** Memory providers registered by extensions via pi.registerMemoryProvider, applied on (re)init. */
121
+ _pendingMemoryProviders = [];
112
122
  _baseToolsOverride;
113
123
  _sessionStartEvent;
114
124
  _extensionUIContext;
@@ -145,6 +155,9 @@ export class AgentSession {
145
155
  this._toolProfileFilter = config.toolProfileFilter
146
156
  ? { allow: config.toolProfileFilter.allow ?? [], block: config.toolProfileFilter.block ?? [] }
147
157
  : undefined;
158
+ this._isExplicitModel = config.isExplicitModel ?? false;
159
+ this._isExplicitThinking = config.isExplicitThinking ?? false;
160
+ this._isChildSession = config.isChildSession ?? process.env.PI_CHILD_SESSION === "1";
148
161
  this._baseToolsOverride = config.baseToolsOverride;
149
162
  this._sessionStartEvent = config.sessionStartEvent ?? { type: "session_start", reason: "startup" };
150
163
  // Always subscribe to agent events for internal handling
@@ -646,6 +659,9 @@ export class AgentSession {
646
659
  this._extensionRunner.invalidate("This extension ctx is stale after session replacement or reload. Do not use a captured pi or command ctx after ctx.newSession(), ctx.fork(), ctx.switchSession(), or ctx.reload(). For newSession, fork, and switchSession, move post-replacement work into withSession and use the ctx passed to withSession. For reload, do not use the old ctx after await ctx.reload().");
647
660
  this._disconnectFromAgent();
648
661
  this._eventListeners = [];
662
+ // Best-effort memory cleanup (release locks/handles). Write-side onSessionEnd is wired on a
663
+ // true session-end hook (P3); file-store shutdown is a no-op.
664
+ void this._memoryManager.shutdownAll().catch(() => { });
649
665
  cleanupSessionResources(this.sessionId);
650
666
  }
651
667
  // =========================================================================
@@ -862,6 +878,8 @@ export class AgentSession {
862
878
  const appendSystemPromptParts = [
863
879
  this._buildSelfModificationPrompt(),
864
880
  this._buildAutonomyPrompt(),
881
+ // Memory subsystem: static, frozen-per-session block (e.g. file-store MEMORY.md/USER.md).
882
+ this._memoryManager.buildSystemPromptBlock() || undefined,
865
883
  ...loaderAppendSystemPrompt,
866
884
  ].filter((part) => Boolean(part));
867
885
  const appendSystemPrompt = appendSystemPromptParts.length > 0 ? appendSystemPromptParts.join("\n\n") : undefined;
@@ -1933,6 +1951,8 @@ export class AgentSession {
1933
1951
  this._applyExtensionBindings(this._extensionRunner);
1934
1952
  await this._extensionRunner.emit(this._sessionStartEvent);
1935
1953
  await this.extendResourcesFromExtensions(this._sessionStartEvent.reason === "reload" ? "reload" : "startup");
1954
+ // Initialize the memory subsystem after extensions have had a chance to register providers.
1955
+ await this._initializeMemory();
1936
1956
  }
1937
1957
  async extendResourcesFromExtensions(reason) {
1938
1958
  if (!this._extensionRunner.hasHandlers("resources_discover")) {
@@ -2061,6 +2081,7 @@ export class AgentSession {
2061
2081
  getThinkingLevel: () => this.thinkingLevel,
2062
2082
  setThinkingLevel: (level) => this.setThinkingLevel(level),
2063
2083
  getExternalResourceRoots: () => this.settingsManager.getEffectiveExternalResourceRoots(),
2084
+ registerMemoryProvider: (provider) => this.registerMemoryProvider(provider),
2064
2085
  }, {
2065
2086
  getModel: () => this.model,
2066
2087
  isIdle: () => !this.isStreaming,
@@ -2123,6 +2144,82 @@ export class AgentSession {
2123
2144
  const filter = this.settingsManager.getResourceProfileFilter("tools");
2124
2145
  return { allow: filter.allow ?? [], block: filter.block ?? [] };
2125
2146
  }
2147
+ /**
2148
+ * Re-resolve the active resource profile's model/thinking from current settings and apply it.
2149
+ * Only acts when the profile actually binds model/thinking AND that field was not set by an
2150
+ * explicit launch flag — so live profile edits apply on reload without clobbering an explicit
2151
+ * --model/--thinking. A no-op for profiles that don't bind a model.
2152
+ */
2153
+ async _reapplyActiveProfileModelSettings() {
2154
+ if (this._isExplicitModel && this._isExplicitThinking)
2155
+ return;
2156
+ const activeProfileNames = this.settingsManager.getActiveResourceProfileNames();
2157
+ if (activeProfileNames.length === 0)
2158
+ return;
2159
+ const profileSettings = resolveProfileModelSettings({
2160
+ activeProfileNames,
2161
+ registry: this.settingsManager.getProfileRegistry(),
2162
+ modelRegistry: this._modelRegistry,
2163
+ cwd: this._cwd,
2164
+ });
2165
+ if (!this._isExplicitModel && profileSettings.model) {
2166
+ const current = this.agent.state.model;
2167
+ const next = profileSettings.model;
2168
+ if (!current || current.provider !== next.provider || current.id !== next.id) {
2169
+ // Mirror the startup/cycle path: set the model directly (no auth gate, no settings
2170
+ // persist) so re-applying the profile model behaves like initial resolution rather
2171
+ // than a runtime model switch. No model_select emit here — reload rebuilds the
2172
+ // extension runtime and emits session_start("reload") right after, and the UI
2173
+ // re-renders from session.model.
2174
+ this.agent.state.model = next;
2175
+ this.sessionManager.appendModelChange(next.provider, next.id);
2176
+ }
2177
+ }
2178
+ if (!this._isExplicitThinking && profileSettings.thinkingLevel) {
2179
+ this.setThinkingLevel(profileSettings.thinkingLevel);
2180
+ }
2181
+ }
2182
+ /**
2183
+ * (Re)build the memory subsystem: a fresh MemoryManager (reload-safe), register the bundled
2184
+ * file-store + any extension-contributed providers, initialize, then surface the memory tools and
2185
+ * the frozen system-prompt block. Best-effort: never throws into the session lifecycle.
2186
+ */
2187
+ async _initializeMemory() {
2188
+ try {
2189
+ // Release the previous generation's providers (locks/handles) before recreating, so a
2190
+ // reload does not orphan the old MemoryManager. No-op on first init / for file-store.
2191
+ await this._memoryManager.shutdownAll().catch(() => { });
2192
+ const manager = new MemoryManager();
2193
+ manager.registerProvider(new FileStoreProvider());
2194
+ for (const provider of this._pendingMemoryProviders) {
2195
+ try {
2196
+ manager.registerProvider(provider);
2197
+ }
2198
+ catch {
2199
+ // Duplicate name or reserved-tool collision — skip this provider, keep the rest.
2200
+ }
2201
+ }
2202
+ this._memoryManager = manager;
2203
+ await manager.initializeAll(this.sessionManager.getSessionId(), {
2204
+ agentDir: this._agentDir,
2205
+ cwd: this._cwd,
2206
+ isChildSession: this._isChildSession,
2207
+ });
2208
+ // Surface memory tools + the frozen memory block now that providers are initialized.
2209
+ // _refreshToolRegistry() ends in setActiveToolsByName(), which rebuilds AND assigns the
2210
+ // system prompt (including the memory block), so no explicit _rebuildSystemPrompt is needed.
2211
+ this._refreshToolRegistry();
2212
+ }
2213
+ catch (error) {
2214
+ console.error("Memory subsystem init failed:", error instanceof Error ? error.message : String(error));
2215
+ }
2216
+ }
2217
+ /** Register a memory provider contributed by an extension; applied on the next memory (re)init. */
2218
+ registerMemoryProvider(provider) {
2219
+ if (!this._pendingMemoryProviders.some((p) => p.name === provider.name)) {
2220
+ this._pendingMemoryProviders.push(provider);
2221
+ }
2222
+ }
2126
2223
  _refreshToolRegistry(options) {
2127
2224
  const previousRegistryNames = new Set(this._toolRegistry.keys());
2128
2225
  const previousActiveToolNames = this.getActiveToolNames();
@@ -2150,6 +2247,11 @@ export class AgentSession {
2150
2247
  definition,
2151
2248
  sourceInfo: createSyntheticSourceInfo(`<sdk:${definition.name}>`, { source: "sdk" }),
2152
2249
  })),
2250
+ // Memory subsystem provider tools (e.g. file-store's `memory` tool).
2251
+ ...this._memoryManager.getToolDefinitions().map((definition) => ({
2252
+ definition,
2253
+ sourceInfo: createSyntheticSourceInfo(`<memory:${definition.name}>`, { source: "sdk" }),
2254
+ })),
2153
2255
  ].filter((tool) => isAllowedTool(tool.definition.name));
2154
2256
  const definitionRegistry = new Map(Array.from(this._baseToolDefinitions.entries())
2155
2257
  .filter(([name]) => isAllowedTool(name))
@@ -2324,6 +2426,10 @@ export class AgentSession {
2324
2426
  // active profile's tools allow/block — or switching the active profile — would not
2325
2427
  // apply on /reload and allowed tools would stay missing.
2326
2428
  this._toolProfileFilter = this._deriveToolProfileFilter();
2429
+ // Re-apply the active profile's model/thinking from the freshly reloaded settings, so a live
2430
+ // profile edit (or switch) takes effect on /reload. Skipped when the launch used an explicit
2431
+ // --model/--thinking flag, which must win over the profile across reloads.
2432
+ await this._reapplyActiveProfileModelSettings();
2327
2433
  await this._resourceLoader.reload({ failOnExtensionErrors: true, deferExtensionDispose: true });
2328
2434
  resetApiProviders();
2329
2435
  this._buildRuntime({
@@ -2337,6 +2443,8 @@ export class AgentSession {
2337
2443
  });
2338
2444
  try {
2339
2445
  this._doctorReloadRuntime();
2446
+ // Reload starts memory providers fresh; loaded extensions re-register below.
2447
+ this._pendingMemoryProviders = [];
2340
2448
  const hasBindings = this._extensionUIContext ||
2341
2449
  this._extensionCommandContextActions ||
2342
2450
  this._extensionShutdownHandler ||
@@ -2356,6 +2464,8 @@ export class AgentSession {
2356
2464
  await emitSessionShutdownEvent(previousRunner, { type: "session_shutdown", reason: "reload" });
2357
2465
  previousRunner.invalidate();
2358
2466
  this._resourceLoader.commitReload?.();
2467
+ // Re-derive the memory subsystem from the reloaded settings/providers.
2468
+ await this._initializeMemory();
2359
2469
  }
2360
2470
  catch (error) {
2361
2471
  if (newRunner && newRunner !== previousRunner) {