maka-agent 0.2.0-dev.43.20260919 → 0.2.0-dev.45.20260921

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 (89) hide show
  1. package/LICENSE +12 -6
  2. package/dist/mcp-capability-provider.js +7 -0
  3. package/dist/runtime-host-service-manager.js +1 -6
  4. package/dist/runtime-host-tui-command.js +1 -1
  5. package/dist/runtime-host-update-command.js +39 -27
  6. package/native/runtime-host-windows-task-launcher/prebuilds/win32-x64/maka-runtime-host-task-launcher.exe +0 -0
  7. package/node_modules/@maka/core/dist/artifacts.js +1 -0
  8. package/node_modules/@maka/core/dist/chat-model-choice.js +3 -0
  9. package/node_modules/@maka/core/dist/llm-connections.js +3 -21
  10. package/node_modules/@maka/core/dist/model-catalog.js +8 -20
  11. package/node_modules/@maka/core/dist/model-metadata.generated.js +304 -304
  12. package/node_modules/@maka/core/dist/model-metadata.js +1 -2
  13. package/node_modules/@maka/core/dist/model-thinking.js +16 -1
  14. package/node_modules/@maka/core/dist/models-dev-projection.js +0 -1
  15. package/node_modules/@maka/core/dist/provider-auth.js +1 -7
  16. package/node_modules/@maka/core/dist/provider-registry.js +20 -58
  17. package/node_modules/@maka/core/dist/recall.js +5 -1
  18. package/node_modules/@maka/core/dist/runtime-policy/connection-catalog-codec.js +7 -0
  19. package/node_modules/@maka/core/dist/runtime-policy/model-catalog-entry-codec.js +14 -1
  20. package/node_modules/@maka/core/dist/session-start-mode.js +2 -5
  21. package/node_modules/@maka/core/dist/session.js +0 -1
  22. package/node_modules/@maka/core/dist/settings.js +19 -3
  23. package/node_modules/@maka/core/dist/tool-quiet-preview.js +2 -16
  24. package/node_modules/@maka/core/dist/transcript-search.js +46 -0
  25. package/node_modules/@maka/core/package.json +1 -4
  26. package/node_modules/@maka/mcp/dist/index.js +22 -0
  27. package/node_modules/@maka/mcp/dist/oauth.js +4 -2
  28. package/node_modules/@maka/mcp/dist/tool-progress.js +45 -0
  29. package/node_modules/@maka/runtime/dist/model-factory.js +0 -16
  30. package/node_modules/@maka/runtime/dist/model-fetcher.js +1 -4
  31. package/node_modules/@maka/runtime/dist/model-runtime.js +0 -8
  32. package/node_modules/@maka/runtime/dist/opencode-session-header.js +2 -3
  33. package/node_modules/@maka/runtime/dist/recall-tools.js +4 -0
  34. package/node_modules/@maka/runtime/dist/session-manager.js +5 -57
  35. package/node_modules/@maka/runtime/dist/subagent-tools.js +69 -11
  36. package/node_modules/@maka/runtime/dist/test-connection.js +4 -114
  37. package/node_modules/@maka/runtime/package.json +0 -1
  38. package/node_modules/@maka/runtime-host/dist/client/client-capability-channel.js +44 -9
  39. package/node_modules/@maka/runtime-host/dist/client/host-handoff-copy.js +25 -18
  40. package/node_modules/@maka/runtime-host/dist/client/host-handoff.js +3 -1
  41. package/node_modules/@maka/runtime-host/dist/client/index.js +1 -1
  42. package/node_modules/@maka/runtime-host/dist/client/session-subscription.js +33 -3
  43. package/node_modules/@maka/runtime-host/dist/protocol/connection-effects.js +0 -108
  44. package/node_modules/@maka/runtime-host/dist/protocol/index.js +12 -1
  45. package/node_modules/@maka/runtime-host/dist/protocol/message.js +10 -0
  46. package/node_modules/@maka/runtime-host/dist/protocol/operations.js +4 -6
  47. package/node_modules/@maka/runtime-host/dist/protocol/recall.js +270 -0
  48. package/node_modules/@maka/runtime-host/dist/protocol/session-catalog.js +1 -1
  49. package/node_modules/@maka/runtime-host/dist/protocol/session-continuity.js +1 -7
  50. package/node_modules/@maka/runtime-host/dist/protocol/turn.js +0 -33
  51. package/node_modules/@maka/runtime-host/dist/protocol/usage-screen.js +12 -4
  52. package/node_modules/@maka/runtime-host/dist/server/access-credential-store.js +6 -0
  53. package/node_modules/@maka/runtime-host/dist/server/bootstrap-runtime-policy.js +31 -104
  54. package/node_modules/@maka/runtime-host/dist/server/connection-effect-coordinator.js +1 -57
  55. package/node_modules/@maka/runtime-host/dist/server/execution-composition.js +11 -35
  56. package/node_modules/@maka/runtime-host/dist/server/interactive-run-composer.js +3 -20
  57. package/node_modules/@maka/runtime-host/dist/server/interactive-turn-coordinator.js +1 -16
  58. package/node_modules/@maka/runtime-host/dist/server/message-coordinator.js +46 -28
  59. package/node_modules/@maka/runtime-host/dist/server/recall-coordinator.js +117 -0
  60. package/node_modules/@maka/runtime-host/dist/server/root-turn-coordinator.js +5 -16
  61. package/node_modules/@maka/runtime-host/dist/server/session-catalog-coordinator.js +21 -12
  62. package/node_modules/@maka/runtime-host/dist/server/session-revision-coordinator.js +0 -4
  63. package/node_modules/@maka/runtime-host/dist/server/session-turn-access-request-coordinator.js +7 -17
  64. package/node_modules/@maka/storage/dist/artifact-metadata-codec.js +4 -3
  65. package/node_modules/@maka/storage/dist/artifact-store.js +1 -11
  66. package/node_modules/@maka/storage/dist/process-lifetime-file-update-lock.js +0 -41
  67. package/node_modules/@maka/storage/dist/runtime-policy/connection-catalog-document.js +0 -62
  68. package/node_modules/@maka/storage/dist/runtime-policy/coordinator.js +0 -31
  69. package/node_modules/@maka/storage/dist/runtime-policy-stores.js +0 -3
  70. package/node_modules/@maka/storage/dist/sqlite-usage-schema.js +29 -5
  71. package/node_modules/@maka/storage/dist/sqlite-workflow-schema.js +2 -0
  72. package/node_modules/@maka/storage/dist/storage-writer-composition.js +0 -3
  73. package/node_modules/@maka/storage/dist/telemetry-file-schema.js +5 -3
  74. package/node_modules/@maka/storage/dist/usage-screen.js +5 -6
  75. package/node_modules/@maka/storage/dist/usage-stores.js +14 -4
  76. package/node_modules/@maka/storage/package.json +0 -2
  77. package/package.json +1 -1
  78. package/node_modules/@maka/core/dist/connection-usage.js +0 -27
  79. package/node_modules/@maka/core/dist/deep-research-client-progress.js +0 -132
  80. package/node_modules/@maka/core/dist/deep-research-run.js +0 -625
  81. package/node_modules/@maka/core/dist/deep-research.js +0 -208
  82. package/node_modules/@maka/core/dist/thread-search.js +0 -498
  83. package/node_modules/@maka/runtime/dist/commandcode-cli-language-model.js +0 -837
  84. package/node_modules/@maka/runtime/dist/connection-usage.js +0 -232
  85. package/node_modules/@maka/runtime/dist/deep-research-tools.js +0 -732
  86. package/node_modules/@maka/runtime-host/dist/protocol/deep-research.js +0 -233
  87. package/node_modules/@maka/runtime-host/dist/server/deep-research-coordinator.js +0 -116
  88. package/node_modules/@maka/storage/dist/deep-research-authority.js +0 -129
  89. package/node_modules/@maka/storage/dist/deep-research-store.js +0 -343
@@ -16,6 +16,7 @@
16
16
  * specific language governing permissions and limitations
17
17
  * under the License.
18
18
  */
19
+ import { isUsageScreenSearch, isUsageTimestamp, } from '@maka/core/settings';
19
20
  import { requireExactRecord, requireRecord, requireShapedRecord, requireCount } from './codec.js';
20
21
  import { invalidProtocolFrame } from './errors.js';
21
22
  import { decodeUsageProvenance } from './usage-pricing.js';
@@ -41,16 +42,23 @@ function amount(value) {
41
42
  return fail();
42
43
  return value;
43
44
  }
45
+ function timestamp(value) {
46
+ if (!isUsageTimestamp(value))
47
+ return fail();
48
+ return value;
49
+ }
44
50
  function query(value) {
45
51
  const v = requireExactRecord(value, 'Usage screen query', ['range', 'search', 'status']);
46
52
  const range = requireExactRecord(v.range, 'Usage range', ['from', 'to']);
47
- const from = requireCount(range.from, 'Usage from');
48
- const to = requireCount(range.to, 'Usage to');
53
+ const from = timestamp(range.from);
54
+ const to = timestamp(range.to);
49
55
  if (from > to || !['all', 'success', 'error', 'aborted'].includes(String(v.status)))
50
56
  return fail();
57
+ if (!isUsageScreenSearch(v.search))
58
+ return fail();
51
59
  return {
52
60
  range: { from, to },
53
- search: text(v.search),
61
+ search: v.search,
54
62
  status: v.status,
55
63
  };
56
64
  }
@@ -228,8 +236,8 @@ export function decodeUsageScreenResult(value) {
228
236
  for (const key of ['id', 'provider', 'model', 'sessionId', 'sessionName', 'turnId', 'toolName'])
229
237
  if (row[key] !== undefined)
230
238
  text(row[key]);
239
+ timestamp(row.ts);
231
240
  for (const key of [
232
- 'ts',
233
241
  'inputTokens',
234
242
  'outputTokens',
235
243
  'cacheMiss',
@@ -48,6 +48,12 @@ const PERSISTED_GRANT_MIGRATIONS = new Map([
48
48
  // Retired with the second execution-inspection contract; no shipped surface
49
49
  // called execution.inspect.resolve.
50
50
  ['execution.inspect.resolve', { kind: 'release' }],
51
+ // Retired with the Command Code GO provider, whose private transport the
52
+ // usage read required.
53
+ ['connection.usage.read', { kind: 'release' }],
54
+ // Retired in favor of editing and resending the original user message.
55
+ ['turn.regenerate', { kind: 'release' }],
56
+ ['deep-research.query', { kind: 'release' }],
51
57
  // Direct WorkHub actions and record writes were retired. Their grants do not
52
58
  // authorize actFromTurn, which requires the active coordination Turn.
53
59
  ['workhub.coordination.act', { kind: 'release' }],
@@ -19,70 +19,43 @@
19
19
  import { randomUUID } from 'node:crypto';
20
20
  import { readFile, rename, rm, writeFile } from 'node:fs/promises';
21
21
  import { join } from 'node:path';
22
- import { OPENCODE_FREE_DEFAULT_MODEL, defaultEnabledModelIdsWhenOmitted, } from '@maka/core/llm-connections';
23
22
  const JOURNAL_FILE = '.runtime-host-bootstrap.json';
24
- /**
25
- * What the seeded OpenCode Free connection starts with — the provider's own
26
- * declaration of the models a fresh connection to it enables, so the seed and
27
- * a hand-added connection cannot drift apart.
28
- */
29
- const OPENCODE_FREE_SEED_MODEL_IDS = defaultEnabledModelIdsWhenOmitted('opencode-free') ?? [];
30
- /** Establishes a usable first target before Runtime Host accepts clients. */
23
+ /** Imports a user's environment credential on first start, before accepting clients. */
31
24
  export async function ensureBootstrapRuntimePolicy(input) {
32
25
  if (input.initialization)
33
26
  await initializeHostedPolicy(input.stores, input.initialization);
34
27
  const journalPath = join(input.workspaceRoot, JOURNAL_FILE);
35
28
  const resuming = await readJournal(journalPath);
36
29
  const initialCatalog = await input.stores.connectionCatalog.getSnapshot();
37
- if (initialCatalog.connections.length > 0) {
38
- // One atomic catalog mutation: enabled ids, static inventory, and a
39
- // retarget of a system default the migration removes all land in the same
40
- // document write, so no restart can observe a half-migrated row.
41
- try {
42
- await input.stores.connectionCatalog.migrateSystemSeed({
43
- slug: 'opencode-free',
44
- providerType: 'opencode-free',
45
- legacyEnabledModelIds: LEGACY_OPENCODE_FREE_SEEDS,
46
- enabledModelIds: OPENCODE_FREE_SEED_MODEL_IDS,
47
- defaultModelId: OPENCODE_FREE_DEFAULT_MODEL,
48
- retiredModelIds: retiredOpencodeFreeModelIds(),
49
- });
50
- }
51
- catch (error) {
52
- input.onDeferredError?.(error);
53
- }
30
+ if (!resuming && initialCatalog.connections.length > 0)
31
+ return;
32
+ const seed = bootstrapSeed(input.environment ?? process.env);
33
+ if (!seed || initialCatalog.connections.some((connection) => connection.slug !== seed.slug)) {
34
+ await rm(journalPath, { force: true });
35
+ return;
54
36
  }
55
- if (!resuming) {
56
- if (initialCatalog.connections.length > 0)
57
- return;
37
+ if (!resuming)
58
38
  await writeJournal(journalPath);
59
- }
60
- const seeds = bootstrapSeeds(input.environment ?? process.env);
61
- const { connection: free } = await ensureConnection(input.stores, seeds[0]);
62
- await setDefaultIfMissing(input.stores, free);
63
- await rm(journalPath, { force: true });
39
+ let connection;
64
40
  try {
65
- let preferred = free;
66
- for (const seed of seeds.slice(1)) {
67
- const ensured = await ensureConnection(input.stores, seed);
68
- const connection = ensured.connection;
69
- if (seed.secret) {
70
- try {
71
- await ensureCredential(input.stores, connection, seed.secret);
72
- }
73
- catch (error) {
74
- if (ensured.created)
75
- await removeFailedBootstrapConnection(input.stores, connection);
76
- throw error;
77
- }
78
- }
79
- preferred = connection;
41
+ const ensured = await ensureConnection(input.stores, seed);
42
+ connection = ensured.connection;
43
+ try {
44
+ await ensureCredential(input.stores, connection, seed.secret);
45
+ }
46
+ catch (error) {
47
+ if (ensured.created)
48
+ await removeFailedBootstrapConnection(input.stores, ensured.connection);
49
+ throw error;
80
50
  }
81
- await replaceBootstrapDefault(input.stores, free, preferred);
82
51
  }
83
52
  catch (error) {
84
53
  input.onDeferredError?.(error);
54
+ await rm(journalPath, { force: true });
55
+ return;
85
56
  }
57
+ await setDefaultIfMissing(input.stores, connection);
58
+ await rm(journalPath, { force: true });
86
59
  }
87
60
  async function initializeHostedPolicy(stores, input) {
88
61
  if (input.incognito !== true ||
@@ -147,47 +120,39 @@ async function initializeHostedPolicy(stores, input) {
147
120
  if (result.kind !== 'committed')
148
121
  throw new Error('Hosted proxy initialization failed');
149
122
  }
150
- function bootstrapSeeds(environment) {
151
- const seeds = [
152
- {
153
- slug: 'opencode-free',
154
- name: 'OpenCode Free',
155
- providerType: 'opencode-free',
156
- enabledModelIds: OPENCODE_FREE_SEED_MODEL_IDS,
157
- },
158
- ];
123
+ function bootstrapSeed(environment) {
159
124
  const deepseek = environment.DEEPSEEK_API_KEY?.trim();
160
125
  const anthropic = environment.ANTHROPIC_API_KEY?.trim();
161
126
  const openai = environment.OPENAI_API_KEY?.trim();
162
127
  if (deepseek) {
163
- seeds.push({
128
+ return {
164
129
  slug: 'env-deepseek',
165
130
  name: 'DeepSeek (env)',
166
131
  providerType: 'deepseek',
167
132
  enabledModelIds: ['deepseek-v4-flash'],
168
133
  baseUrl: environment.DEEPSEEK_BASE_URL?.trim() || 'https://api.deepseek.com',
169
134
  secret: deepseek,
170
- });
135
+ };
171
136
  }
172
137
  else if (anthropic) {
173
- seeds.push({
138
+ return {
174
139
  slug: 'env-anthropic',
175
140
  name: 'Anthropic (env)',
176
141
  providerType: 'anthropic',
177
142
  enabledModelIds: ['claude-sonnet-4-5-20250929'],
178
143
  secret: anthropic,
179
- });
144
+ };
180
145
  }
181
146
  else if (openai) {
182
- seeds.push({
147
+ return {
183
148
  slug: 'env-openai',
184
149
  name: 'OpenAI (env)',
185
150
  providerType: 'openai',
186
151
  enabledModelIds: ['gpt-4o-mini'],
187
152
  secret: openai,
188
- });
153
+ };
189
154
  }
190
- return seeds;
155
+ return undefined;
191
156
  }
192
157
  async function ensureConnection(stores, seed) {
193
158
  for (let attempt = 0; attempt < 3; attempt += 1) {
@@ -219,24 +184,6 @@ async function ensureConnection(stores, seed) {
219
184
  }
220
185
  throw new Error(`Bootstrap Connection could not be created: ${seed.slug}`);
221
186
  }
222
- /**
223
- * Every opencode-free inventory a past release seeded, verbatim. A row still
224
- * equal to one of these is provably system-owned and may follow the current
225
- * seed; any other value is a user selection and is never touched. Every
226
- * release that changes the derived seed must append the previous value here,
227
- * or rows it planted read as user selections forever. (This exact-match
228
- * enumeration is deliberately lossy; the versioned seed policy discussed in
229
- * #3354 is the durable replacement.)
230
- */
231
- const LEGACY_OPENCODE_FREE_SEEDS = [
232
- ['big-pickle'],
233
- ['nemotron-3-ultra-free'],
234
- ['nemotron-3-ultra-free', 'mimo-v2.5-free', 'deepseek-v4-flash-free'],
235
- ];
236
- function retiredOpencodeFreeModelIds() {
237
- const current = new Set(OPENCODE_FREE_SEED_MODEL_IDS);
238
- return [...new Set(LEGACY_OPENCODE_FREE_SEEDS.flat())].filter((id) => !current.has(id));
239
- }
240
187
  async function removeFailedBootstrapConnection(stores, connection) {
241
188
  const removed = await stores.connectionCatalog.remove({
242
189
  expected: { connectionId: connection.connectionId, revision: connection.revision },
@@ -270,33 +217,13 @@ async function setDefaultIfMissing(stores, connection) {
270
217
  expectedCatalogRevision: catalog.revision,
271
218
  target: {
272
219
  connectionId: connection.connectionId,
273
- modelId: OPENCODE_FREE_DEFAULT_MODEL,
220
+ modelId: connection.enabledModelIds[0],
274
221
  },
275
222
  });
276
223
  if (committed.kind !== 'committed') {
277
224
  throw new Error(`Bootstrap default target could not be stored: ${committed.kind}`);
278
225
  }
279
226
  }
280
- async function replaceBootstrapDefault(stores, free, preferred) {
281
- if (preferred.connectionId === free.connectionId || !preferred.enabled)
282
- return;
283
- const catalog = await stores.connectionCatalog.getSnapshot();
284
- const current = catalog.defaultTarget;
285
- if (current !== null &&
286
- (current.connectionId !== free.connectionId || current.modelId !== OPENCODE_FREE_DEFAULT_MODEL)) {
287
- return;
288
- }
289
- const modelId = preferred.enabledModelIds[0];
290
- if (!modelId)
291
- return;
292
- const committed = await stores.connectionCatalog.setDefaultTarget({
293
- expectedCatalogRevision: catalog.revision,
294
- target: { connectionId: preferred.connectionId, modelId },
295
- });
296
- if (committed.kind !== 'committed') {
297
- throw new Error(`Bootstrap preferred target could not be stored: ${committed.kind}`);
298
- }
299
- }
300
227
  async function readJournal(path) {
301
228
  let contents;
302
229
  try {
@@ -17,13 +17,12 @@
17
17
  * under the License.
18
18
  */
19
19
  import { parseRequestHeaders } from '@maka/core/runtime-policy';
20
- import { PROVIDER_REGISTRY, effectiveBaseUrl, providerFallbackModelIds, } from '@maka/core/llm-connections';
20
+ import { PROVIDER_REGISTRY, providerFallbackModelIds, } from '@maka/core/llm-connections';
21
21
  import { createConnectionEffectFetchTransport, } from '@maka/runtime/network/scoped-fetch-transport';
22
22
  import { createRequestCustomizationFetch } from '@maka/runtime/request-customization-fetch';
23
23
  import { isOAuthSubscriptionProvider, parseOAuthSubscriptionTokens, } from '@maka/runtime/subscription-credentials';
24
24
  import { runConnectionModelDiscoveryEffect } from '@maka/runtime/model-fetcher';
25
25
  import { runConnectionTestEffect } from '@maka/runtime/test-connection';
26
- import { fetchConnectionUsage } from '@maka/runtime/connection-usage';
27
26
  import { authenticateRuntimePolicyStoresWriter, RuntimePolicyStoreError, } from '@maka/storage/runtime-policy-stores';
28
27
  import { toRuntimePolicyProxy } from './runtime-policy-proxy.js';
29
28
  /** Runs provider I/O outside Storage lanes and conditionally commits canonical results. */
@@ -33,7 +32,6 @@ export class HostConnectionEffectCoordinator {
33
32
  'connection.onboarding.verify': (input) => this.#verifyOnboarding(input),
34
33
  'connection.models.fetch': (input) => this.#fetchModels(input),
35
34
  'connection.test.run': (input) => this.#testConnection(input),
36
- 'connection.usage.read': (input) => this.#readConnectionUsage(input),
37
35
  };
38
36
  #stores;
39
37
  #activation;
@@ -265,32 +263,6 @@ export class HostConnectionEffectCoordinator {
265
263
  : projectSuperseded(completion);
266
264
  });
267
265
  }
268
- /**
269
- * Read-only: fetch the account's usage and project it. Nothing is committed,
270
- * so no superseded branch exists — the ticket is spent and the report
271
- * returned.
272
- */
273
- #readConnectionUsage(input) {
274
- return this.#admit(input.connectionId, 'connection.usage.read', async () => {
275
- const prepared = await this.#stores.operations.beginConnectionUsage(input.connectionId);
276
- if (prepared.kind !== 'ready')
277
- return preparationResult(prepared);
278
- try {
279
- const result = await this.#withTransport(prepared, (fetch, secret) => fetchConnectionUsage({
280
- providerType: prepared.connection.providerType,
281
- apiKey: secret,
282
- baseUrl: effectiveBaseUrl(prepared.connection),
283
- fetch,
284
- }));
285
- return result.kind === 'report'
286
- ? { kind: 'report', report: projectUsageReport(result.report) }
287
- : { kind: 'unavailable', reason: result.reason };
288
- }
289
- finally {
290
- await this.#stores.operations.completeConnectionUsage(prepared.ticket);
291
- }
292
- });
293
- }
294
266
  #admit(connectionId, operation, run) {
295
267
  if (!this.#accepting) {
296
268
  return Promise.resolve({
@@ -379,34 +351,6 @@ function projectSuperseded(completion) {
379
351
  changed: completion.changed.map((domain) => domain),
380
352
  };
381
353
  }
382
- function projectUsageReport(report) {
383
- return {
384
- accountLabel: report.accountLabel ?? null,
385
- planLabel: report.planLabel ?? null,
386
- stats: report.stats
387
- ? {
388
- requests: report.stats.requests ?? null,
389
- failed: report.stats.failed ?? null,
390
- successRate: report.stats.successRate ?? null,
391
- cost: report.stats.cost ?? null,
392
- tokensIn: report.stats.tokensIn ?? null,
393
- tokensOut: report.stats.tokensOut ?? null,
394
- }
395
- : null,
396
- windows: report.windows.map((window) => ({
397
- id: window.id,
398
- label: window.label ?? null,
399
- used: window.used,
400
- cap: window.cap,
401
- unit: window.unit,
402
- resetsAt: window.resetsAt ?? null,
403
- unlimited: window.unlimited ?? null,
404
- })),
405
- periodEnd: report.periodEnd ?? null,
406
- partiallyUnauthorized: report.partiallyUnauthorized === true,
407
- fetchedAt: report.fetchedAt,
408
- };
409
- }
410
354
  function projectConnectionTest(outcome, checkedAt) {
411
355
  const checkedAtIso = new Date(checkedAt).toISOString();
412
356
  if (outcome.ok) {
@@ -24,9 +24,9 @@ import { NO_REAL_CONNECTION_CODE } from '@maka/core/connection-error-copy';
24
24
  import { generalizedErrorMessage } from '@maka/core/redaction';
25
25
  import { emptyPlanSessionState } from '@maka/core/plan';
26
26
  import { readLogicalRuntimeExecutionForRun } from '@maka/core/runtime-logical-execution';
27
- import { foldForMatch } from '@maka/core/thread-search';
27
+ import { foldForMatch } from '@maka/core/transcript-search';
28
28
  import { runtimeInvocationOutcome, } from '@maka/core/runtime-invocation';
29
- import { isDeepResearchSession, WORKHUB_COORDINATION_SESSION_ID, WORKHUB_COORDINATION_REPLACEMENT_SCHEMA_VERSION, } from '@maka/core/session';
29
+ import { WORKHUB_COORDINATION_SESSION_ID, WORKHUB_COORDINATION_REPLACEMENT_SCHEMA_VERSION, } from '@maka/core/session';
30
30
  import { AgentGraphClientOperationError, AgentGraphCoordinator, } from '@maka/runtime/stream-graph-coordinator';
31
31
  import { AgentGraphSupervisorWakeCoordinator } from '@maka/runtime/agent-graph-supervisor-wake';
32
32
  import { BackendRegistry, SessionManager, workHubDirectStopAbortSource, } from '@maka/runtime/session-manager';
@@ -34,6 +34,7 @@ import { buildToolsForAgentDefinition } from '@maka/runtime/agent-catalog';
34
34
  import { buildRecallTools } from '@maka/runtime/recall-tools';
35
35
  import { RECALL_SYNTHETIC_TEXT_PATTERNS } from '@maka/runtime/recall-candidates';
36
36
  import { createRecallMaterialFetch } from './recall-material-fetch.js';
37
+ import { HostRecallCoordinator } from './recall-coordinator.js';
37
38
  import { buildBuiltinTools } from '@maka/runtime/builtin-tools';
38
39
  import { createLocalContinuationSafetyInspector } from '@maka/runtime/continuation-safety';
39
40
  import { createConfiguredSubagentCatalog } from '@maka/runtime/configured-subagent-catalog';
@@ -95,7 +96,6 @@ import { HostChangeFeed } from './host-change-feed.js';
95
96
  import { HostConfigurationCoordinator } from './configuration-coordinator.js';
96
97
  import { HostContextCoordinator } from './context-coordinator.js';
97
98
  import { HostClientCapabilityCoordinator } from './client-capability-coordinator.js';
98
- import { HostDeepResearchCoordinator } from './deep-research-coordinator.js';
99
99
  import { HostDailyReviewCoordinator } from './daily-review-coordinator.js';
100
100
  import { prepareHostAiSdkBackend } from './execution-model-composition.js';
101
101
  import { createInteractiveRunComposer, createInteractiveRunComposerFactory, routeInteractiveRunToolSurface, } from './interactive-run-composer.js';
@@ -258,7 +258,6 @@ export async function createExecutionRuntimeHostComposition(context, options = {
258
258
  const oauthCredentials = new HostOAuthExecutionAuthority(runtimePolicyStores);
259
259
  const openedScheduledTaskStore = storage.scheduledTasks;
260
260
  const openedPlanStore = storage.plan;
261
- const openedDeepResearchStore = storage.deepResearch;
262
261
  const openedDailyReviewStore = storage.dailyReview;
263
262
  const openedGoalStore = storage.goal;
264
263
  const memoryStore = storage.memoryBundle;
@@ -485,7 +484,10 @@ export async function createExecutionRuntimeHostComposition(context, options = {
485
484
  search: ({ query, limit, abortSignal }) => webSearchService.search({ query, limit, ...(abortSignal ? { abortSignal } : {}) }),
486
485
  fetch: (input) => webFetchService.fetch(input),
487
486
  });
488
- const recallTools = buildRecallTools({
487
+ // The recall surface is built once and shared: the model's tools and the
488
+ // Host's `recall.query` operation answer from the same dependency graph, so
489
+ // a UI search and a model recall cannot diverge in what they can see.
490
+ const recallDeps = {
489
491
  listSessions: () => requireSessionManager(manager).listSessions(),
490
492
  readMessages: async (sessionId, abortSignal) => {
491
493
  if (abortSignal?.aborted)
@@ -540,7 +542,9 @@ export async function createExecutionRuntimeHostComposition(context, options = {
540
542
  incognitoActive: (await runtimePolicyStores.runtimePolicy.getSnapshot()).policy.privacy
541
543
  .incognitoActive,
542
544
  }),
543
- });
545
+ };
546
+ const recallTools = buildRecallTools(recallDeps);
547
+ const recall = new HostRecallCoordinator(recallDeps);
544
548
  const childHostTools = [
545
549
  createHostWebSearchToolFromService(webSearchService),
546
550
  createHostWebFetchToolFromService(webFetchService),
@@ -626,7 +630,6 @@ export async function createExecutionRuntimeHostComposition(context, options = {
626
630
  let scheduledTasks;
627
631
  let scheduledTaskTool;
628
632
  let goal;
629
- let deepResearch;
630
633
  let dailyReview;
631
634
  const rootPort = {
632
635
  readLatestRootTurnLineage: (identity) => requireRootCoordinator(rootCoordinator).readLatestRootTurnLineage(identity),
@@ -675,13 +678,6 @@ export async function createExecutionRuntimeHostComposition(context, options = {
675
678
  unsubscribeTranscriptChanges = stores.sessionStore.subscribeTranscriptChanges((sessionId) => continuityCoordinator.enqueueCanonicalRefresh(sessionId));
676
679
  unsubscribeRuntimeEventCommits = stores.runtimeEventStore.subscribeRuntimeEventCommits((sessionId) => continuityCoordinator.enqueueTranscriptAdvanced(sessionId));
677
680
  unsubscribeUsageChanges = openedUsageStores.subscribeSessionUsageChanges((sessionId) => continuityCoordinator.enqueueSessionDomainChanged(sessionId, 'usage'));
678
- deepResearch = new HostDeepResearchCoordinator({
679
- store: openedDeepResearchStore,
680
- artifacts: openedArtifactStore,
681
- sessions: stores.sessionStore,
682
- sessionAdmission,
683
- onProjectionChanged: (sessionId) => continuityCoordinator.enqueueSessionDomainChanged(sessionId, 'deep_research'),
684
- });
685
681
  dailyReview = new HostDailyReviewCoordinator({
686
682
  store: openedDailyReviewStore,
687
683
  usage: openedUsageStores,
@@ -784,7 +780,6 @@ export async function createExecutionRuntimeHostComposition(context, options = {
784
780
  resolveTavilyWebSearchReadiness: () => resolveHostTavilyWebSearchReadiness(runtimePolicyStores.operations),
785
781
  ...(scheduledTaskTool ? { scheduledTaskTool } : {}),
786
782
  planStore,
787
- deepResearchTools: requireDeepResearch(deepResearch).toolsForSession(backendContext.sessionId),
788
783
  goalTools: requireGoal(goal).tools,
789
784
  builtinTools,
790
785
  hostTools,
@@ -946,13 +941,6 @@ export async function createExecutionRuntimeHostComposition(context, options = {
946
941
  mode: header.collaborationMode ?? 'agent',
947
942
  permissionMode: header.permissionMode,
948
943
  },
949
- ...(isDeepResearchSession(header.labels)
950
- ? {
951
- deepResearch: {
952
- tools: requireDeepResearch(deepResearch).toolsForSession(sessionId),
953
- },
954
- }
955
- : {}),
956
944
  }).tools.map((tool) => tool.name);
957
945
  }
958
946
  finally {
@@ -1484,7 +1472,6 @@ export async function createExecutionRuntimeHostComposition(context, options = {
1484
1472
  const interactiveTurns = new HostInteractiveTurnCoordinator({
1485
1473
  executions: coordinator,
1486
1474
  turns: stores.agentRunStore,
1487
- runtime: manager,
1488
1475
  });
1489
1476
  // Compile-time guarantee that the three Turn coordinators together cover
1490
1477
  // every key in TURN_OPERATION_SPECS. Domain composition seeds all domain
@@ -1500,7 +1487,6 @@ export async function createExecutionRuntimeHostComposition(context, options = {
1500
1487
  ? new SessionTurnAccessRequestCoordinator({
1501
1488
  authority: context.sessionAccessAuthority,
1502
1489
  startTurn: interactiveTurns.handlers['turn.start'],
1503
- regenerateTurn: interactiveTurns.handlers['turn.regenerate'],
1504
1490
  hostEpoch: context.hostEpoch,
1505
1491
  acquireResidency: () => context.acquireResidency('collaboration-turn-request'),
1506
1492
  requestDrain: context.requestDrain,
@@ -2033,7 +2019,6 @@ export async function createExecutionRuntimeHostComposition(context, options = {
2033
2019
  // writer: publishing a per-Session `plan` invalidation for state that is
2034
2020
  // being removed would only wake subscribers to read nothing.
2035
2021
  await openedPlanStore.purgeSessionState(sessionId);
2036
- await openedDeepResearchStore.purgeSessionState(sessionId);
2037
2022
  },
2038
2023
  purgeAgentGraphState: async (sessionId) => {
2039
2024
  for (const graphId of await requireGraphCoordinator(graphCoordinator).listGraphIds(sessionId)) {
@@ -2152,6 +2137,7 @@ export async function createExecutionRuntimeHostComposition(context, options = {
2152
2137
  oauth.handlers,
2153
2138
  externalAgentSetup.handlers,
2154
2139
  webSearch.handlers,
2140
+ recall.handlers,
2155
2141
  networkProxy.handlers,
2156
2142
  configuration.handlers,
2157
2143
  ],
@@ -2224,11 +2210,6 @@ export async function createExecutionRuntimeHostComposition(context, options = {
2224
2210
  drain: [() => clientCapabilities.beginDrain()],
2225
2211
  close: [() => clientCapabilities.close()],
2226
2212
  }),
2227
- createRuntimeHostDomainModule({
2228
- id: 'deep-research',
2229
- handlers: [requireDeepResearch(deepResearch).handlers],
2230
- close: [() => deepResearch?.close()],
2231
- }),
2232
2213
  createRuntimeHostDomainModule({
2233
2214
  id: 'daily-review',
2234
2215
  handlers: [requireDailyReview(dailyReview).handlers],
@@ -2648,11 +2629,6 @@ function requireScheduledTasks(coordinator) {
2648
2629
  throw new Error('Runtime Host ScheduledTask coordinator is not composed');
2649
2630
  return coordinator;
2650
2631
  }
2651
- function requireDeepResearch(coordinator) {
2652
- if (!coordinator)
2653
- throw new Error('Runtime Host Deep Research coordinator is not composed');
2654
- return coordinator;
2655
- }
2656
2632
  function requireDailyReview(coordinator) {
2657
2633
  if (!coordinator)
2658
2634
  throw new Error('Runtime Host Daily Review coordinator is not composed');
@@ -18,7 +18,6 @@
18
18
  */
19
19
  import { isDeepStrictEqual } from 'node:util';
20
20
  import { buildSideConversationSystemPromptFragment, isSideConversationSession, } from '@maka/core/side-conversation';
21
- import { buildDeepResearchSystemPromptFragment, isDeepResearchSession, } from '@maka/core/deep-research';
22
21
  import { activePlanExecution } from '@maka/core/plan';
23
22
  import { createHash } from 'node:crypto';
24
23
  import { assembleMainSessionSystemPrompt } from '@maka/runtime/system-prompt/main-session-prompt';
@@ -31,7 +30,6 @@ import { buildRequestSandboxBoundaryTool } from '@maka/runtime/sandbox-boundary-
31
30
  import { buildHostCapabilitiesFromBinding, buildSkillAgentToolFromInventory, buildSkillSearchAgentToolFromInventory, buildSkillsPromptFragmentFromInventoryWithReport, SkillShadowSelectionTracker, } from '@maka/runtime/skills';
32
31
  import { buildSessionTodoTools } from '@maka/runtime/session-todo-tools';
33
32
  import { buildWorkspaceInstructionsPromptFragment } from '@maka/runtime/system-prompt/workspace-instructions';
34
- import { isDeepResearchToolAllowed } from '@maka/runtime/deep-research-tools';
35
33
  import { listRunnableBuiltinAgentDefinitions } from '@maka/runtime/agent-catalog';
36
34
  import { renderPlanModePrompt, selectCollaborationTools } from '@maka/runtime/plan-mode';
37
35
  import { routeWebFetchTools } from '@maka/runtime/web-fetch-tool';
@@ -60,7 +58,7 @@ export function createInteractiveRunComposer(input) {
60
58
  // contributions are sampled at logical step boundaries.
61
59
  const defaultTools = input.boundTools
62
60
  ? input.boundTools
63
- : buildDefaultHostTools(input.sessionTodo, inventoryFor, builtinTools, input.hostTools ?? [], input.scheduledTaskTool, input.goalTools, input.parentAgentTools, input.plan, input.deepResearch?.tools);
61
+ : buildDefaultHostTools(input.sessionTodo, inventoryFor, builtinTools, input.hostTools ?? [], input.scheduledTaskTool, input.goalTools, input.parentAgentTools, input.plan);
64
62
  const clientCapabilityTools = input.boundTools !== undefined ||
65
63
  (input.toolProfile !== undefined && input.toolProfile !== 'workhub-coordination-v2')
66
64
  ? []
@@ -70,11 +68,7 @@ export function createInteractiveRunComposer(input) {
70
68
  const additionalTools = hasToolCeiling
71
69
  ? []
72
70
  : (input.resolveAdditionalTools?.(stableHostTools) ?? []);
73
- const unscopedCandidateTools = [...stableHostTools, ...additionalTools];
74
- const routedCandidateTools = input.deepResearch
75
- ? unscopedCandidateTools.filter(isDeepResearchToolAllowed)
76
- : unscopedCandidateTools;
77
- const candidateTools = projectHostedExecutionTools(routedCandidateTools, input.toolProfile);
71
+ const candidateTools = projectHostedExecutionTools([...stableHostTools, ...additionalTools], input.toolProfile);
78
72
  const selectedTools = input.plan
79
73
  ? selectCollaborationTools({
80
74
  mode: input.plan.mode,
@@ -145,7 +139,6 @@ export function createInteractiveRunComposer(input) {
145
139
  input.plan?.mode === 'plan'
146
140
  ? renderPlanModePrompt({ fullAccess: input.plan.permissionMode === 'bypass' })
147
141
  : undefined,
148
- input.deepResearch ? buildDeepResearchSystemPromptFragment() : undefined,
149
142
  input.sideConversation ? buildSideConversationSystemPromptFragment() : undefined,
150
143
  ]);
151
144
  // Keep each turn's source revisions independent while sharing identical
@@ -320,9 +313,6 @@ export function createInteractiveRunComposerFactory(input) {
320
313
  },
321
314
  }
322
315
  : {}),
323
- ...(isDeepResearchSession(backendContext.header.labels) && !backendContext.tools
324
- ? { deepResearch: { tools: requireDeepResearchTools(input.deepResearchTools) } }
325
- : {}),
326
316
  skillBudget: contextWindow === null ? {} : { contextWindow },
327
317
  shell,
328
318
  ...(input.resolveProfileSystemPrompt
@@ -354,7 +344,7 @@ function assertUniqueToolNames(tools) {
354
344
  names.add(tool.name);
355
345
  }
356
346
  }
357
- function buildDefaultHostTools(sessionTodo, inventoryFor, builtinOptions, hostTools = [], scheduledTaskTool, goalTools = [], parentAgentTools = [], plan, deepResearchTools = []) {
347
+ function buildDefaultHostTools(sessionTodo, inventoryFor, builtinOptions, hostTools = [], scheduledTaskTool, goalTools = [], parentAgentTools = [], plan) {
358
348
  // Full access has no boundary to widen, so neither the Bash declaration nor
359
349
  // the widening tool is offered. An unknown mode is not Full access.
360
350
  const fullAccess = plan?.permissionMode === 'bypass';
@@ -390,7 +380,6 @@ function buildDefaultHostTools(sessionTodo, inventoryFor, builtinOptions, hostTo
390
380
  ...goalTools.map((tool) => tool.name),
391
381
  ...parentAgentTools.map((tool) => tool.name),
392
382
  ...planTools.map((tool) => tool.name),
393
- ...deepResearchTools.map((tool) => tool.name),
394
383
  ];
395
384
  const skillHost = buildHostCapabilitiesFromBinding(toolNames);
396
385
  const shadowTracker = new SkillShadowSelectionTracker();
@@ -406,14 +395,8 @@ function buildDefaultHostTools(sessionTodo, inventoryFor, builtinOptions, hostTo
406
395
  ...goalTools,
407
396
  ...parentAgentTools,
408
397
  ...planTools,
409
- ...deepResearchTools,
410
398
  ];
411
399
  }
412
- function requireDeepResearchTools(tools) {
413
- if (!tools)
414
- throw new Error('Runtime Host Deep Research tools are not composed');
415
- return tools;
416
- }
417
400
  function filterToolGroups(groups, names) {
418
401
  const seenIds = new Set();
419
402
  return groups.flatMap((group) => {
@@ -26,19 +26,16 @@ const EMPTY_SKILL_INVOCATION = {
26
26
  failed: [],
27
27
  receipts: [],
28
28
  };
29
- /** Owns Interactive Turn start and regenerate wire semantics. */
29
+ /** Owns Interactive Turn start wire semantics. */
30
30
  export class HostInteractiveTurnCoordinator {
31
31
  handlers = {
32
32
  'turn.start': (input, context) => this.#start(input, context),
33
- 'turn.regenerate': (input, context) => this.#regenerate(input, context),
34
33
  };
35
34
  #executions;
36
35
  #turns;
37
- #runtime;
38
36
  constructor(options) {
39
37
  this.#executions = options.executions;
40
38
  this.#turns = options.turns;
41
- this.#runtime = options.runtime;
42
39
  }
43
40
  async #start(input, context) {
44
41
  const content = normalizeMessageContent(input.content);
@@ -128,18 +125,6 @@ export class HostInteractiveTurnCoordinator {
128
125
  },
129
126
  };
130
127
  }
131
- #regenerate(input, context) {
132
- if (input.sourceTurnId === input.turnId) {
133
- return Promise.resolve(operationConflict('Regenerate source and target Turn identities must differ'));
134
- }
135
- return this.#executions.startInteractiveRootMessage({
136
- sessionId: input.sessionId,
137
- turnId: input.turnId,
138
- execution: { kind: 'regenerate', sourceTurnId: input.sourceTurnId },
139
- archivedMessage: 'Cannot regenerate a Turn in an archived Session',
140
- prepareContent: async () => (await this.#runtime.prepareRegenerateTurn(input.sessionId, input.sourceTurnId)).content,
141
- }, context);
142
- }
143
128
  }
144
129
  function rejected(message) {
145
130
  return { kind: 'rejected', outcome: operationConflict(message) };