maka-agent 0.2.2-dev.97.20261024 → 0.2.2-dev.99.20261024

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.
@@ -40,6 +40,11 @@ export class AcpCatalog {
40
40
  this.drain = drain;
41
41
  this.store = store;
42
42
  }
43
+ /** Presentation-only lookup: never probes, launches an Agent, or supplies Session capabilities. */
44
+ async readCached() {
45
+ await this.#hydrate();
46
+ return this.#disposed ? undefined : this.#cached;
47
+ }
43
48
  async get(signal, refresh = false) {
44
49
  signal.throwIfAborted();
45
50
  if (this.#disposed)
@@ -23,6 +23,7 @@ import { tmpdir } from 'node:os';
23
23
  import { AdmissionLimiter } from '@maka/runtime/admission-limiter';
24
24
  import { AcpCatalog } from './acp-catalog.js';
25
25
  import { createAcpCatalogStore } from './acp-catalog-store.js';
26
+ import { normalizeCatalogEntry, } from '@maka/core/executor-catalog';
26
27
  import { dirname, isAbsolute, join, resolve } from 'node:path';
27
28
  import { methods, } from '@agentclientprotocol/sdk';
28
29
  import { pluginIdentity } from '@maka/runtime/plugin-runtime';
@@ -159,10 +160,15 @@ export class AcpExecutor {
159
160
  return this.#catalogEntry('unavailable');
160
161
  if (session && session.cwd !== resolve(input.cwd))
161
162
  return this.#catalogEntry('history_only', [], input.configuration);
162
- if (session?.restoring)
163
- return this.#catalogEntry('restoring', session.configOptions, input.configuration);
164
- if (session?.restoreFailed)
165
- return this.#catalogEntry('restore_failed', session.configOptions, input.configuration);
163
+ if (session?.restoring || session?.restoreFailed) {
164
+ const entry = this.#catalogEntry(session.restoring ? 'restoring' : 'restore_failed', session.configOptions, {
165
+ model: input.configuration?.model ?? session.record?.confirmedModel,
166
+ mode: input.configuration?.mode ?? session.record?.confirmedMode,
167
+ });
168
+ return session.configOptions.length
169
+ ? entry
170
+ : this.#withSavedPresentation(entry, session.record?.presentation);
171
+ }
166
172
  if (session?.historyGap)
167
173
  return this.#catalogEntry('history_gap', session.configOptions, input.configuration);
168
174
  if (session && !session.lost)
@@ -180,12 +186,49 @@ export class AcpExecutor {
180
186
  return this.#catalogEntry('history_only', [], input.configuration);
181
187
  if (stored.phase === 'reserved')
182
188
  return this.#catalogEntry('history_only', [], input.configuration);
183
- return this.#catalogEntry(stored.phase === 'prompt_pending' || stored.phase === 'history_gap'
189
+ return this.#withSavedPresentation(this.#catalogEntry(stored.phase === 'prompt_pending' || stored.phase === 'history_gap'
184
190
  ? 'history_gap'
185
191
  : 'restorable', [], {
186
192
  model: input.configuration?.model ?? stored.confirmedModel,
187
193
  mode: input.configuration?.mode ?? stored.confirmedMode,
188
- });
194
+ }), stored.presentation);
195
+ }
196
+ #readPresentation(value) {
197
+ if (!value || typeof value !== 'object' || value.version !== 1)
198
+ return;
199
+ try {
200
+ // Normalize optional display metadata separately: a corrupt cache must not invalidate continuity.
201
+ const input = value;
202
+ const entry = normalizeCatalogEntry({
203
+ ...this.#catalogEntry('restorable'),
204
+ models: input.models,
205
+ modelGroups: input.modelGroups,
206
+ modes: input.modes,
207
+ }, this.id);
208
+ return {
209
+ version: 1,
210
+ models: entry.models,
211
+ modelGroups: entry.modelGroups,
212
+ modes: entry.modes,
213
+ };
214
+ }
215
+ catch {
216
+ return;
217
+ }
218
+ }
219
+ async #withSavedPresentation(entry, saved) {
220
+ const presentation = this.#readPresentation(saved) ?? (await this.#catalog.readCached());
221
+ if (!presentation)
222
+ return entry;
223
+ return {
224
+ ...entry,
225
+ ...(entry.currentModel && presentation.models.some((model) => model.id === entry.currentModel)
226
+ ? { models: presentation.models, modelGroups: presentation.modelGroups }
227
+ : {}),
228
+ ...(entry.currentMode && presentation.modes?.some((mode) => mode.id === entry.currentMode)
229
+ ? { modes: presentation.modes }
230
+ : {}),
231
+ };
189
232
  }
190
233
  async configureConversation(input, signal) {
191
234
  if (!input.configuration?.model && !input.configuration?.mode)
@@ -734,7 +777,16 @@ export class AcpExecutor {
734
777
  async #persistConfirmedConfig(session, configOptions = session.configOptions) {
735
778
  if (!session.record)
736
779
  return;
737
- const record = withConfirmedConfiguration(session.record, configOptions);
780
+ let record = withConfirmedConfiguration(session.record, configOptions);
781
+ const observed = this.#catalogEntry('ready', configOptions);
782
+ const presentation = this.#readPresentation({
783
+ version: 1,
784
+ models: observed.models,
785
+ modelGroups: observed.modelGroups,
786
+ modes: observed.modes,
787
+ });
788
+ if (presentation && JSON.stringify(record.presentation) !== JSON.stringify(presentation))
789
+ record = { ...record, presentation };
738
790
  if (record === session.record)
739
791
  return;
740
792
  await this.#state?.write?.(session.conversationKey, record);
@@ -120,6 +120,11 @@ var AcpCatalog = class {
120
120
  #hydration;
121
121
  #writes = Promise.resolve();
122
122
  #failure;
123
+ /** Presentation-only lookup: never probes, launches an Agent, or supplies Session capabilities. */
124
+ async readCached() {
125
+ await this.#hydrate();
126
+ return this.#disposed ? void 0 : this.#cached;
127
+ }
123
128
  async get(signal, refresh = false) {
124
129
  signal.throwIfAborted();
125
130
  if (this.#disposed) return this.unavailable();
@@ -28085,10 +28090,17 @@ var AcpExecutor = class {
28085
28090
  if (this.#disposed) return this.#catalogEntry("unavailable");
28086
28091
  if (session && session.cwd !== resolve2(input2.cwd))
28087
28092
  return this.#catalogEntry("history_only", [], input2.configuration);
28088
- if (session?.restoring)
28089
- return this.#catalogEntry("restoring", session.configOptions, input2.configuration);
28090
- if (session?.restoreFailed)
28091
- return this.#catalogEntry("restore_failed", session.configOptions, input2.configuration);
28093
+ if (session?.restoring || session?.restoreFailed) {
28094
+ const entry = this.#catalogEntry(
28095
+ session.restoring ? "restoring" : "restore_failed",
28096
+ session.configOptions,
28097
+ {
28098
+ model: input2.configuration?.model ?? session.record?.confirmedModel,
28099
+ mode: input2.configuration?.mode ?? session.record?.confirmedMode
28100
+ }
28101
+ );
28102
+ return session.configOptions.length ? entry : this.#withSavedPresentation(entry, session.record?.presentation);
28103
+ }
28092
28104
  if (session?.historyGap)
28093
28105
  return this.#catalogEntry("history_gap", session.configOptions, input2.configuration);
28094
28106
  if (session && !session.lost)
@@ -28101,15 +28113,51 @@ var AcpExecutor = class {
28101
28113
  return this.#catalogEntry("history_only", [], input2.configuration);
28102
28114
  if (stored.phase === "reserved")
28103
28115
  return this.#catalogEntry("history_only", [], input2.configuration);
28104
- return this.#catalogEntry(
28105
- stored.phase === "prompt_pending" || stored.phase === "history_gap" ? "history_gap" : "restorable",
28106
- [],
28107
- {
28108
- model: input2.configuration?.model ?? stored.confirmedModel,
28109
- mode: input2.configuration?.mode ?? stored.confirmedMode
28110
- }
28116
+ return this.#withSavedPresentation(
28117
+ this.#catalogEntry(
28118
+ stored.phase === "prompt_pending" || stored.phase === "history_gap" ? "history_gap" : "restorable",
28119
+ [],
28120
+ {
28121
+ model: input2.configuration?.model ?? stored.confirmedModel,
28122
+ mode: input2.configuration?.mode ?? stored.confirmedMode
28123
+ }
28124
+ ),
28125
+ stored.presentation
28111
28126
  );
28112
28127
  }
28128
+ #readPresentation(value) {
28129
+ if (!value || typeof value !== "object" || value.version !== 1)
28130
+ return;
28131
+ try {
28132
+ const input2 = value;
28133
+ const entry = normalizeCatalogEntry(
28134
+ {
28135
+ ...this.#catalogEntry("restorable"),
28136
+ models: input2.models,
28137
+ modelGroups: input2.modelGroups,
28138
+ modes: input2.modes
28139
+ },
28140
+ this.id
28141
+ );
28142
+ return {
28143
+ version: 1,
28144
+ models: entry.models,
28145
+ modelGroups: entry.modelGroups,
28146
+ modes: entry.modes
28147
+ };
28148
+ } catch {
28149
+ return;
28150
+ }
28151
+ }
28152
+ async #withSavedPresentation(entry, saved) {
28153
+ const presentation = this.#readPresentation(saved) ?? await this.#catalog.readCached();
28154
+ if (!presentation) return entry;
28155
+ return {
28156
+ ...entry,
28157
+ ...entry.currentModel && presentation.models.some((model) => model.id === entry.currentModel) ? { models: presentation.models, modelGroups: presentation.modelGroups } : {},
28158
+ ...entry.currentMode && presentation.modes?.some((mode) => mode.id === entry.currentMode) ? { modes: presentation.modes } : {}
28159
+ };
28160
+ }
28113
28161
  async configureConversation(input2, signal) {
28114
28162
  if (!input2.configuration?.model && !input2.configuration?.mode)
28115
28163
  throw new Error("ACP configuration change is unavailable");
@@ -28620,7 +28668,16 @@ var AcpExecutor = class {
28620
28668
  }
28621
28669
  async #persistConfirmedConfig(session, configOptions = session.configOptions) {
28622
28670
  if (!session.record) return;
28623
- const record2 = withConfirmedConfiguration(session.record, configOptions);
28671
+ let record2 = withConfirmedConfiguration(session.record, configOptions);
28672
+ const observed = this.#catalogEntry("ready", configOptions);
28673
+ const presentation = this.#readPresentation({
28674
+ version: 1,
28675
+ models: observed.models,
28676
+ modelGroups: observed.modelGroups,
28677
+ modes: observed.modes
28678
+ });
28679
+ if (presentation && JSON.stringify(record2.presentation) !== JSON.stringify(presentation))
28680
+ record2 = { ...record2, presentation };
28624
28681
  if (record2 === session.record) return;
28625
28682
  await this.#state?.write?.(session.conversationKey, record2);
28626
28683
  session.record = record2;
@@ -19,6 +19,10 @@
19
19
  import { isExecutorId } from './executor-id.js';
20
20
  import { CATALOG_PROVIDER_TYPES } from './provider-registry.js';
21
21
  import { isThinkingLevel } from './model-thinking.js';
22
+ /** Existing conversations restore their external connection as part of execution. */
23
+ export function canExecuteExistingConversation(readiness) {
24
+ return readiness === 'ready' || readiness === 'restorable' || readiness === 'restore_failed';
25
+ }
22
26
  export function isExecutorConfiguration(value) {
23
27
  if (!value || typeof value !== 'object' || Array.isArray(value))
24
28
  return false;
@@ -16,6 +16,7 @@
16
16
  * specific language governing permissions and limitations
17
17
  * under the License.
18
18
  */
19
+ import { canExecuteExistingConversation } from '@maka/core/executor-catalog';
19
20
  import { readMatterRuntimeEvents } from '../assistant/proactive-matters/settlement-context.js';
20
21
  import { markAssistantBackgroundSessions } from '../assistant/background-sessions.js';
21
22
  import { PersonalAssistantService, ASSISTANT_LEGACY_PACKAGES } from '../assistant/service.js';
@@ -854,7 +855,7 @@ export async function createExecutionRuntimeHostComposition(context, options = {
854
855
  ...projected,
855
856
  idleOnly: true,
856
857
  supportsAttachments: entry?.supportsAttachments ?? false,
857
- ...(entry?.readiness === 'ready'
858
+ ...(canExecuteExistingConversation(entry?.readiness)
858
859
  ? {}
859
860
  : {
860
861
  unavailableReason: entry?.readiness === 'history_only'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "maka-agent",
3
- "version": "0.2.2-dev.97.20261024",
3
+ "version": "0.2.2-dev.99.20261024",
4
4
  "description": "Apache Maka (Incubating) developer snapshot; not an Apache release.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",