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
@@ -107,35 +107,53 @@ export class HostMessageCoordinator {
107
107
  }
108
108
  return success({ cancelledMessageIds });
109
109
  }
110
- async queryMessageExecutions(input) {
111
- const resolutions = [];
112
- for (const messageId of input.messageIds) {
113
- const disposition = await this.#resolveMessageExecution(input.sessionId, messageId);
114
- if (disposition.kind === 'owned_root' || disposition.kind === 'shared_turn') {
115
- // This read projects current execution, including safe-boundary
116
- // continuations. The Message's durable admission ownership is unchanged.
117
- const latest = await this.#root.readLatestRootTurnLineage({
118
- sessionId: input.sessionId,
119
- turnId: disposition.turnId,
120
- runId: disposition.runId,
121
- });
122
- resolutions.push({
123
- messageId,
124
- state: 'owned',
125
- turnId: latest.turnId,
126
- runId: latest.runId,
127
- });
128
- continue;
129
- }
130
- if (disposition.kind === 'cancelled') {
131
- resolutions.push({ messageId, state: 'cancelled' });
132
- continue;
133
- }
134
- if (disposition.kind === 'pending') {
135
- resolutions.push({ messageId, state: 'pending' });
110
+ queryMessageExecutions(input) {
111
+ // Enter the Session admission the way every other admission reader does.
112
+ // `not_admitted` claims that no epoch ever admitted this identity, and it
113
+ // is only sound while no admission write can be in flight. WorkHub writes
114
+ // admission rows without an in-memory submit to observe, so the gate —
115
+ // not `#pendingSubmits` alone — is what makes the read atomic.
116
+ return this.#sessionAdmission.runOrJoin(input.sessionId, async () => {
117
+ const resolutions = [];
118
+ for (const messageId of input.messageIds) {
119
+ const disposition = await this.#resolveMessageExecution(input.sessionId, messageId);
120
+ if (disposition.kind === 'owned_root' || disposition.kind === 'shared_turn') {
121
+ // This read projects current execution, including safe-boundary
122
+ // continuations. The Message's durable admission ownership is unchanged.
123
+ const latest = await this.#root.readLatestRootTurnLineage({
124
+ sessionId: input.sessionId,
125
+ turnId: disposition.turnId,
126
+ runId: disposition.runId,
127
+ });
128
+ resolutions.push({
129
+ messageId,
130
+ state: 'owned',
131
+ turnId: latest.turnId,
132
+ runId: latest.runId,
133
+ });
134
+ continue;
135
+ }
136
+ if (disposition.kind === 'cancelled') {
137
+ resolutions.push({ messageId, state: 'cancelled' });
138
+ continue;
139
+ }
140
+ if (disposition.kind === 'pending') {
141
+ resolutions.push({ messageId, state: 'pending' });
142
+ continue;
143
+ }
144
+ // `recovering` means no durable receipt, steering proof, cancellation
145
+ // tombstone, or pending admission names this identity. Under the
146
+ // Session gate no admission write is in flight, so that silence is
147
+ // itself the proof: nothing in this epoch — or any prior one, since a
148
+ // stale epoch's submit can never commit here — ever admitted it.
149
+ // Report that fact positively instead of omitting the identity, so a
150
+ // missing entry stops meaning both "not admitted" and "cannot say yet".
151
+ if (this.#pendingSubmits.has(operationKey(input.sessionId, messageId)))
152
+ continue;
153
+ resolutions.push({ messageId, state: 'not_admitted' });
136
154
  }
137
- }
138
- return success({ resolutions });
155
+ return success({ resolutions });
156
+ });
139
157
  }
140
158
  /**
141
159
  * Cancels exactly one durable pending Message, or returns the Turn that has
@@ -0,0 +1,117 @@
1
+ /*
2
+ * Licensed to the Apache Software Foundation (ASF) under one
3
+ * or more contributor license agreements. See the NOTICE file
4
+ * distributed with this work for additional information
5
+ * regarding copyright ownership. The ASF licenses this file
6
+ * to you under the Apache License, Version 2.0 (the
7
+ * "License"); you may not use this file except in compliance
8
+ * with the License. You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing,
13
+ * software distributed under the License is distributed on an
14
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ * KIND, either express or implied. See the License for the
16
+ * specific language governing permissions and limitations
17
+ * under the License.
18
+ */
19
+ import { runRecall } from '@maka/core/recall';
20
+ /**
21
+ * Serves `recall.query` from the same dependency graph the model's `Recall`
22
+ * tool uses.
23
+ *
24
+ * The point of this coordinator is that it owns no retrieval logic: it hands
25
+ * the request to `runRecall` and projects the answer. Whatever recall can see —
26
+ * privacy gating, archived Sessions, the distilled-fact store — a Client
27
+ * asking over the wire sees the same thing, because there is one implementation
28
+ * and this is not a second one.
29
+ *
30
+ * Unlike the model's tool, no turn is excluded. A tool call runs inside a turn
31
+ * and must not surface that turn's own text back as corroboration; a Client
32
+ * search is not inside any turn, so there is nothing to exclude.
33
+ */
34
+ export class HostRecallCoordinator {
35
+ deps;
36
+ handlers = {
37
+ 'recall.query': (input) => this.#query(input),
38
+ };
39
+ constructor(deps) {
40
+ this.deps = deps;
41
+ }
42
+ async #query(input) {
43
+ try {
44
+ const result = await runRecall(input, this.deps, { includeArchived: true });
45
+ return { ok: true, result: projectRecallResult(result) };
46
+ }
47
+ catch {
48
+ return {
49
+ ok: false,
50
+ error: { code: 'internal_failure', message: 'Recall query failed' },
51
+ };
52
+ }
53
+ }
54
+ }
55
+ /**
56
+ * `RecallQueryResult` is the core result with the Host's field vocabulary.
57
+ *
58
+ * Recall already returns exactly these fields; the projection exists to drop
59
+ * core-internal detail and to make the boundary explicit, so a change to the
60
+ * core shape shows up here rather than silently widening the wire.
61
+ */
62
+ export function projectRecallResult(result) {
63
+ if (!result.ok) {
64
+ return { ok: false, reason: result.reason, message: result.message };
65
+ }
66
+ return {
67
+ ok: true,
68
+ facts: result.facts.map((fact) => ({
69
+ content: fact.content,
70
+ kind: fact.kind,
71
+ observedAt: fact.observedAt,
72
+ })),
73
+ passages: result.passages.map((passage) => projectPassage(passage)),
74
+ gaps: result.gaps,
75
+ searchedEverySession: result.scannedFully,
76
+ };
77
+ }
78
+ function projectPassage(passage) {
79
+ return {
80
+ sessionId: passage.sessionId,
81
+ sessionTitle: passage.sessionTitle,
82
+ ...(passage.turnId ? { turnId: passage.turnId } : {}),
83
+ anchorMessageId: passage.anchorMessageId,
84
+ sequence: passage.sequence,
85
+ messages: passage.messages.map((message) => ({
86
+ messageId: message.messageId,
87
+ role: message.role,
88
+ matchKind: message.matchKind,
89
+ text: message.text,
90
+ timestamp: message.timestamp,
91
+ isAnchor: message.isAnchor,
92
+ ...(message.materials
93
+ ? {
94
+ materials: message.materials.map((material) => ({
95
+ name: material.name,
96
+ kind: material.kind,
97
+ mimeType: material.mimeType,
98
+ bytes: material.bytes,
99
+ ...(material.resource ? { resource: material.resource } : {}),
100
+ ...(material.sourceSessionId && material.materialId
101
+ ? {
102
+ sourceSessionId: material.sourceSessionId,
103
+ materialId: material.materialId,
104
+ }
105
+ : {}),
106
+ })),
107
+ }
108
+ : {}),
109
+ })),
110
+ matchedTerms: passage.matchedTerms,
111
+ score: passage.score,
112
+ ...(passage.lastMessageAt !== undefined ? { lastMessageAt: passage.lastMessageAt } : {}),
113
+ hasMoreBefore: passage.hasMoreBefore,
114
+ hasMoreAfter: passage.hasMoreAfter,
115
+ ...(passage.truncated ? { truncated: true } : {}),
116
+ };
117
+ }
@@ -27,7 +27,7 @@ import { decodeSkillInvocationResult, } from '@maka/core/skill-invocation';
27
27
  import { agentGraphIdForRootSession } from '@maka/runtime/stream-graph-coordinator';
28
28
  import { RuntimeHostedRootConflictError, RuntimeHostedRootUnavailableError, RuntimeMessageAuthorityInvariantError, } from '@maka/runtime/message-authority';
29
29
  import { isShutdownCancelledInteractionAdmission, RuntimeInteractionAdmissionRejectedError, RuntimeInteractionFailStopError, RuntimeInteractionInvariantError, } from '@maka/runtime/interaction-authority';
30
- import { normalizeStopSessionSource, RuntimeRegenerateTurnError, } from '@maka/runtime/session-manager';
30
+ import { normalizeStopSessionSource, } from '@maka/runtime/session-manager';
31
31
  import { RuntimeOwnerCleanupError } from '@maka/runtime/runtime-kernel';
32
32
  import { parseSkillInvocationTokens, } from '@maka/runtime/skill-invocation';
33
33
  import { skillInvocationInlineReferences } from '@maka/runtime/skill-invocation-receipt';
@@ -1422,21 +1422,10 @@ export class RootTurnCoordinator {
1422
1422
  return { kind: 'ready', content: request.content };
1423
1423
  if ('prepareFreshContent' in request)
1424
1424
  return request.prepareFreshContent(lease);
1425
- try {
1426
- return {
1427
- kind: 'ready',
1428
- content: normalizeMessageContent(await request.prepareContent()),
1429
- };
1430
- }
1431
- catch (error) {
1432
- if (error instanceof RuntimeRegenerateTurnError) {
1433
- return {
1434
- kind: 'rejected',
1435
- outcome: error.code === 'not_found' ? notFound(error.message) : operationConflict(error.message),
1436
- };
1437
- }
1438
- throw error;
1439
- }
1425
+ return {
1426
+ kind: 'ready',
1427
+ content: normalizeMessageContent(await request.prepareContent()),
1428
+ };
1440
1429
  }
1441
1430
  async queryTurnResume(input, context) {
1442
1431
  if (isWorkHubCoordinationSessionId(input.sessionId)) {
@@ -21,7 +21,7 @@ import { RuntimeHostProtocolError } from '../protocol/errors.js';
21
21
  import { createHash } from 'node:crypto';
22
22
  import { authorizeConnectionModel, connectionEnabledModelIds } from '@maka/core/llm-connections';
23
23
  import { isModelExplicitlyUnsupportedForChat } from '@maka/core/model-catalog';
24
- import { thinkingVariantsForConnection } from '@maka/core/model-thinking';
24
+ import { defaultThinkingLevelForConnection, thinkingVariantsForConnection, } from '@maka/core/model-thinking';
25
25
  import { executionBoundaryDisplayMode, } from '@maka/core/sandbox-boundary';
26
26
  import { isExecutorId } from '@maka/core/executor-id';
27
27
  import { DEFAULT_SESSION_NAME, normalizeUserSessionName } from '@maka/core/session-name';
@@ -184,7 +184,7 @@ export class HostSessionCatalogCoordinator {
184
184
  */
185
185
  async resolveDefaultCreateTarget() {
186
186
  try {
187
- return await this.#composeCreateTarget(this.#resolveModel({ kind: 'default' }, undefined));
187
+ return await this.#composeCreateTarget(this.#resolveModel({ kind: 'default' }, undefined, true));
188
188
  }
189
189
  catch (error) {
190
190
  if (error instanceof SessionOperationFailure &&
@@ -200,6 +200,7 @@ export class HostSessionCatalogCoordinator {
200
200
  llmConnectionId: model.connectionId,
201
201
  llmConnectionSlug: model.connectionSlug,
202
202
  model: model.model,
203
+ ...(model.thinkingLevel === undefined ? {} : { thinkingLevel: model.thinkingLevel }),
203
204
  permissionMode: policy.policy.chatDefaults.permissionMode,
204
205
  toolMode: policy.policy.chatDefaults.codeModeEnabled ? 'code_mode' : 'direct',
205
206
  collaborationMode: 'agent',
@@ -235,7 +236,7 @@ export class HostSessionCatalogCoordinator {
235
236
  ...(model.connectionId ? { llmConnectionId: model.connectionId } : {}),
236
237
  llmConnectionSlug: model.connectionSlug,
237
238
  model: model.model,
238
- ...(input.thinkingLevel === undefined ? {} : { thinkingLevel: input.thinkingLevel }),
239
+ ...(model.thinkingLevel === undefined ? {} : { thinkingLevel: model.thinkingLevel }),
239
240
  ...(input.toolProfile === undefined ? {} : { toolProfile: input.toolProfile }),
240
241
  permissionMode: prepared.permissionMode ?? policy.policy.chatDefaults.permissionMode,
241
242
  toolMode: policy.policy.chatDefaults.codeModeEnabled ? 'code_mode' : 'direct',
@@ -405,7 +406,7 @@ export class HostSessionCatalogCoordinator {
405
406
  ...(model.connectionId ? { llmConnectionId: model.connectionId } : {}),
406
407
  llmConnectionSlug: model.connectionSlug,
407
408
  model: model.model,
408
- ...(input.thinkingLevel === undefined ? {} : { thinkingLevel: input.thinkingLevel }),
409
+ ...(model.thinkingLevel === undefined ? {} : { thinkingLevel: model.thinkingLevel }),
409
410
  ...(input.toolProfile === undefined ? {} : { toolProfile: input.toolProfile }),
410
411
  permissionMode: prepared.permissionMode ?? policy.policy.chatDefaults.permissionMode,
411
412
  toolMode: toolMode ?? (policy.policy.chatDefaults.codeModeEnabled ? 'code_mode' : 'direct'),
@@ -715,7 +716,7 @@ export class HostSessionCatalogCoordinator {
715
716
  connectionId: candidate.connectionId,
716
717
  connectionSlug: candidate.connectionSlug,
717
718
  model: candidate.modelId,
718
- }, undefined);
719
+ }, undefined, true);
719
720
  }
720
721
  catch (error) {
721
722
  if (!(error instanceof SessionOperationFailure))
@@ -741,7 +742,7 @@ export class HostSessionCatalogCoordinator {
741
742
  }
742
743
  throw new NoUsableImportModelError('No usable Session model connection is available for import');
743
744
  }
744
- async #resolveModel(target, thinkingLevel) {
745
+ async #resolveModel(target, thinkingLevel, applyConfiguredDefault = false) {
745
746
  const selected = await this.#selectModelTarget(target);
746
747
  const readiness = await this.#runtimePolicy.operations.resolveExecutionConnection({
747
748
  kind: 'bound',
@@ -788,17 +789,25 @@ export class HostSessionCatalogCoordinator {
788
789
  // rejected — execution-model-authority rebuilds the runtime connection
789
790
  // from the same table, so whatever passes here is exactly what the wire
790
791
  // can send.
791
- if (thinkingLevel !== undefined &&
792
+ const resolvedThinkingLevel = thinkingLevel ??
793
+ (applyConfiguredDefault
794
+ ? defaultThinkingLevelForConnection({
795
+ providerType: connection.providerType,
796
+ modelOverrides: connection.modelOverrides,
797
+ }, selected.modelId)
798
+ : undefined);
799
+ if (resolvedThinkingLevel !== undefined &&
792
800
  !thinkingVariantsForConnection({
793
801
  providerType: connection.providerType,
794
802
  modelOverrides: connection.modelOverrides,
795
- }, selected.modelId).includes(thinkingLevel)) {
796
- throw new SessionOperationFailure('invalid_request', `Session model does not support thinking level ${thinkingLevel}`);
803
+ }, selected.modelId).includes(resolvedThinkingLevel)) {
804
+ throw new SessionOperationFailure('invalid_request', `Session model does not support thinking level ${resolvedThinkingLevel}`);
797
805
  }
798
806
  return {
799
807
  connectionId: connection.connectionId,
800
808
  connectionSlug: connection.slug,
801
809
  model: selected.modelId,
810
+ thinkingLevel: resolvedThinkingLevel,
802
811
  };
803
812
  }
804
813
  async #selectModelTarget(target) {
@@ -888,7 +897,7 @@ export class HostSessionCatalogCoordinator {
888
897
  if (!input.modelTarget) {
889
898
  throw new SessionOperationFailure('invalid_request', 'Session creation requires a model target or executor id');
890
899
  }
891
- return await this.#resolveModel(input.modelTarget, input.thinkingLevel);
900
+ return await this.#resolveModel(input.modelTarget, input.thinkingLevel ?? undefined, input.thinkingLevel !== null);
892
901
  }
893
902
  async #readRuntimePolicy() {
894
903
  try {
@@ -943,7 +952,7 @@ async function prepareCreate(input) {
943
952
  }
944
953
  function createRequestFingerprint(input, prepared) {
945
954
  const identity = [
946
- 'session.create.v4',
955
+ 'session.create.v5',
947
956
  input.sessionId,
948
957
  input.workspace.kind === 'project'
949
958
  ? ['project', input.workspace.projectId]
@@ -960,7 +969,7 @@ function createRequestFingerprint(input, prepared) {
960
969
  input.modelTarget.connectionSlug,
961
970
  input.modelTarget.model,
962
971
  ],
963
- input.thinkingLevel ?? null,
972
+ input.thinkingLevel === undefined ? ['model_default'] : input.thinkingLevel,
964
973
  input.toolProfile ?? null,
965
974
  prepared.permissionMode ?? ['runtime_default'],
966
975
  input.collaborationMode ?? 'agent',
@@ -17,7 +17,6 @@
17
17
  * under the License.
18
18
  */
19
19
  import { createHash, randomUUID } from 'node:crypto';
20
- import { isDeepResearchSession } from '@maka/core/deep-research';
21
20
  import { SIDE_CONVERSATION_SESSION_LABEL } from '@maka/core/side-conversation';
22
21
  import { isWorkHubCoordinationSessionId, isWorkHubCoordinationSessionTarget, sessionRevisionFamilyId, } from '@maka/core/session';
23
22
  import { runtimeHostConversationCopyUnavailableReason } from './host-session-availability.js';
@@ -204,9 +203,6 @@ export class HostSessionRevisionCoordinator {
204
203
  if (sourceHeader.subagentParent) {
205
204
  return copyFailure('operation_conflict', 'Linked child Sessions cannot be copied as ordinary conversations');
206
205
  }
207
- if (isDeepResearchSession(sourceHeader.labels)) {
208
- return copyFailure('operation_unavailable', 'Deep Research Sessions cannot be copied without an exact research ledger boundary');
209
- }
210
206
  const copyUnavailableReason = runtimeHostConversationCopyUnavailableReason(sourceHeader);
211
207
  if (copyUnavailableReason)
212
208
  return copyFailure('operation_unavailable', copyUnavailableReason);
@@ -19,7 +19,6 @@
19
19
  export class SessionTurnAccessRequestCoordinator {
20
20
  #authority;
21
21
  #startTurn;
22
- #regenerateTurn;
23
22
  #acquireResidency;
24
23
  #requestDrain;
25
24
  #whenIdle;
@@ -30,7 +29,6 @@ export class SessionTurnAccessRequestCoordinator {
30
29
  constructor(input) {
31
30
  this.#authority = input.authority;
32
31
  this.#startTurn = input.startTurn;
33
- this.#regenerateTurn = input.regenerateTurn;
34
32
  this.#acquireResidency = input.acquireResidency;
35
33
  this.#requestDrain = input.requestDrain;
36
34
  this.#whenIdle = input.whenIdle;
@@ -98,21 +96,13 @@ export class SessionTurnAccessRequestCoordinator {
98
96
  async #run(request, context) {
99
97
  for (;;) {
100
98
  try {
101
- if ('content' in request.intent) {
102
- const outcome = await this.#startTurn(request.intent, context);
103
- if (outcome.ok)
104
- return outcome.result.kind;
105
- if (outcome.error.code !== 'session_busy') {
106
- return this.#draining ? undefined : 'failed';
107
- }
108
- }
109
- else {
110
- const outcome = await this.#regenerateTurn(request.intent, context);
111
- if (outcome.ok)
112
- return 'started';
113
- if (outcome.error.code !== 'session_busy') {
114
- return this.#draining ? undefined : 'failed';
115
- }
99
+ if (!('content' in request.intent))
100
+ return 'failed';
101
+ const outcome = await this.#startTurn(request.intent, context);
102
+ if (outcome.ok)
103
+ return outcome.result.kind;
104
+ if (outcome.error.code !== 'session_busy') {
105
+ return this.#draining ? undefined : 'failed';
116
106
  }
117
107
  }
118
108
  catch {
@@ -18,7 +18,6 @@
18
18
  */
19
19
  import { isAbsolute } from 'node:path';
20
20
  import { ARTIFACT_KINDS, ARTIFACT_SOURCES, isArtifactTurnKey, isCanonicalArtifactEntityId, } from '@maka/core/artifacts';
21
- import { isDeepResearchArtifactRole } from '@maka/core/deep-research-run';
22
21
  const ARTIFACT_KIND_SET = new Set(ARTIFACT_KINDS);
23
22
  const ARTIFACT_SOURCE_SET = new Set(ARTIFACT_SOURCES);
24
23
  const ARTIFACT_RECORD_KEYS = new Set([
@@ -104,7 +103,6 @@ function decodeArtifactRecord(value, index) {
104
103
  value.sizeBytes < 0 ||
105
104
  !isOptionalNonEmptyString(value.mimeType) ||
106
105
  !isOptionalNonEmptyString(value.summary) ||
107
- (value.deepResearchRole !== undefined && !isDeepResearchArtifactRole(value.deepResearchRole)) ||
108
106
  typeof value.source !== 'string') {
109
107
  throw invalidMetadataRecord(index);
110
108
  }
@@ -114,7 +112,10 @@ function decodeArtifactRecord(value, index) {
114
112
  if (value.relativePath !== `${value.sessionId}/${value.id}-${value.name}`) {
115
113
  throw invalidMetadataRecord(index);
116
114
  }
117
- return value;
115
+ // Old reports carry a workflow role that no longer has a consumer.
116
+ const record = { ...value };
117
+ delete record.deepResearchRole;
118
+ return record;
118
119
  }
119
120
  function isCompatibleArtifactName(name) {
120
121
  if (name.length === 0 || name.length > 120)
@@ -22,7 +22,6 @@ import { constants as fsConstants } from 'node:fs';
22
22
  import { access, copyFile, lstat, mkdir, open, readFile, realpath, rm, stat, unlink, writeFile, } from 'node:fs/promises';
23
23
  import { basename, dirname, join, relative, sep } from 'node:path';
24
24
  import { ARTIFACT_ENTITY_ID_MAX_CHARS, ARTIFACT_KINDS, ARTIFACT_SOURCES, canUserDeleteArtifact, isArtifactTurnKey, isCanonicalArtifactEntityId, } from '@maka/core/artifacts';
25
- import { isDeepResearchArtifactRole, } from '@maka/core/deep-research-run';
26
25
  import { sniffAttachmentMimeType } from '@maka/core/attachments';
27
26
  import { isSafeRelativeArtifactPath, validateRelativeArtifactPath, } from './artifact-metadata-codec.js';
28
27
  import { withArtifactWriterLock, withLeaseBoundArtifactWriterLock, } from './artifact-writer-lock.js';
@@ -68,10 +67,6 @@ class SqliteArtifactStore {
68
67
  if (!ARTIFACT_SOURCE_SET.has(acceptedInput.source)) {
69
68
  throw new Error('Invalid Artifact source');
70
69
  }
71
- if (acceptedInput.deepResearchRole !== undefined &&
72
- !isDeepResearchArtifactRole(acceptedInput.deepResearchRole)) {
73
- throw new Error('Invalid Artifact deep-research role');
74
- }
75
70
  if (acceptedInput.now !== undefined &&
76
71
  (!Number.isSafeInteger(acceptedInput.now) || acceptedInput.now < 0)) {
77
72
  throw new Error('Invalid Artifact creation time');
@@ -103,9 +98,6 @@ class SqliteArtifactStore {
103
98
  ...(acceptedInput.mimeType ? { mimeType: acceptedInput.mimeType } : {}),
104
99
  source: acceptedInput.source,
105
100
  ...(acceptedInput.summary ? { summary: acceptedInput.summary } : {}),
106
- ...(acceptedInput.deepResearchRole
107
- ? { deepResearchRole: acceptedInput.deepResearchRole }
108
- : {}),
109
101
  }, (targetPath) => writeFile(targetPath, acceptedInput.content, { flag: 'wx' }));
110
102
  });
111
103
  }
@@ -346,7 +338,6 @@ class SqliteArtifactStore {
346
338
  existing.mimeType !== optionalCanonicalText(input.mimeType) ||
347
339
  existing.source !== input.source ||
348
340
  existing.summary !== optionalCanonicalText(input.summary) ||
349
- existing.deepResearchRole !== input.deepResearchRole ||
350
341
  (input.now !== undefined && existing.createdAt !== input.now)) {
351
342
  throw artifactReplayConflict(canonical.id);
352
343
  }
@@ -798,8 +789,7 @@ function sameArtifactRecord(a, b) {
798
789
  a.sizeBytes === b.sizeBytes &&
799
790
  a.mimeType === b.mimeType &&
800
791
  a.source === b.source &&
801
- a.summary === b.summary &&
802
- a.deepResearchRole === b.deepResearchRole);
792
+ a.summary === b.summary);
803
793
  }
804
794
  function assertPageBound(value, allowZero, label) {
805
795
  if (!Number.isSafeInteger(value) || value < (allowZero ? 0 : 1)) {
@@ -22,43 +22,6 @@ import { openStableNativeLockFile, releaseNativeFileLock, tryAcquireNativeFileLo
22
22
  const LOCK_POLL_MS = 25;
23
23
  const LOCK_TIMEOUT_MS = 10_000;
24
24
  const lockGates = new Map();
25
- export async function withLegacyFileUpdateLockLease(targetPath, operation, timeoutMs = LOCK_TIMEOUT_MS) {
26
- const lockPath = `${targetPath}.lock`;
27
- const leasePath = `${targetPath}.lease`;
28
- const supervisionPath = `${targetPath}.supervised`;
29
- const deadline = Date.now() + timeoutMs;
30
- return runWithLockGate(leasePath, deadline, async () => {
31
- const lease = await openStableNativeLockFile(leasePath);
32
- let leased = false;
33
- let supervised = false;
34
- let completed = false;
35
- try {
36
- while (!(leased = tryAcquireNativeFileLock(lease))) {
37
- await waitForLockTurn(lockPath, deadline);
38
- }
39
- // The inherited advisory lease follows the legacy child process. A surviving
40
- // supervision marker therefore proves that its directory lock is ownerless
41
- // once a later process can acquire this lease.
42
- await recoverSupervisedLegacyLock(lockPath, supervisionPath);
43
- await createSupervisionMarker(supervisionPath);
44
- supervised = true;
45
- const result = await operation(lease.fd);
46
- completed = true;
47
- return result;
48
- }
49
- finally {
50
- try {
51
- if (supervised && completed)
52
- await unlink(supervisionPath).catch(ignoreMissing);
53
- }
54
- finally {
55
- if (leased)
56
- releaseNativeFileLock(lease);
57
- await lease.close();
58
- }
59
- }
60
- });
61
- }
62
25
  /**
63
26
  * The callback may pass the lease fd as an extra child stdio descriptor. The
64
27
  * advisory lock then survives a parent crash until that exact child exits.
@@ -93,10 +56,6 @@ export async function withProcessLifetimeFileUpdateLock(targetPath, operation, t
93
56
  }
94
57
  });
95
58
  }
96
- async function createSupervisionMarker(path) {
97
- const marker = await open(path, fsConstants.O_CREAT | fsConstants.O_EXCL | fsConstants.O_WRONLY | fsConstants.O_NOFOLLOW, 0o600);
98
- await marker.close();
99
- }
100
59
  async function recoverSupervisedLegacyLock(lockPath, supervisionPath) {
101
60
  const supervision = await lstat(supervisionPath).catch((error) => {
102
61
  if (isNodeError(error, 'ENOENT'))
@@ -26,7 +26,6 @@ import { CONNECTION_CATALOG_MAX_CONNECTIONS, decodeCanonicalConnectionCatalogEnt
26
26
  import { PROVIDER_REGISTRY, reconcileConnectionAfterModelFetch } from '@maka/core/llm-connections';
27
27
  import { modelIdAliasesForProvider, providerReportsCompleteModelCatalog, } from '@maka/core/model-metadata';
28
28
  import { isRetiredProvider } from '@maka/core/provider-registry';
29
- import { pruneModelOverrides } from '@maka/core/model-thinking';
30
29
  import { deepFreeze, nextRevision, record, revision, unique } from './codec.js';
31
30
  import { codecError, decodeConnectionInput, decodePersistedDomain, RuntimePolicyStoreError, } from './errors.js';
32
31
  import { CATALOG_DOCUMENT_MAX_BYTES, readBoundedJsonDocument, serializeJsonDocument, writeJsonDocument, } from './document-io.js';
@@ -285,67 +284,6 @@ export class ConnectionCatalogDocumentOwner {
285
284
  await this.write(root, next);
286
285
  return committed(next);
287
286
  }
288
- /**
289
- * Built-in seed evolution as ONE atomic catalog mutation. A row whose
290
- * `enabledModelIds` still exactly match a historical system seed is provably
291
- * system-owned: it follows the current seed, its static inventory is
292
- * re-derived from the current build, and a default target the migration
293
- * removes is retargeted inside the same document write — so no restart can
294
- * observe enabled ids without their inventory, or a nulled default awaiting
295
- * a second write. Any other inventory (including a reordering) is a user
296
- * selection and is never touched; an already-null default stays null.
297
- */
298
- async migrateSystemSeed(root, input) {
299
- if (!input.enabledModelIds.includes(input.defaultModelId)) {
300
- throw codecError('invalid_connection_input', 'Seed default must be in the seed selection');
301
- }
302
- const current = await this.read(root);
303
- const index = current.connections.findIndex((item) => item.slug === input.slug && item.providerType === input.providerType);
304
- const previous = current.connections[index];
305
- const retired = new Set(input.retiredModelIds);
306
- const sameIds = (left, right) => left.length === right.length && left.every((id, position) => id === right[position]);
307
- const isLegacySeed = previous
308
- ? input.legacyEnabledModelIds.some((seed) => sameIds(previous.enabledModelIds, seed))
309
- : false;
310
- const hasRetiredModels = previous
311
- ? previous.enabledModelIds.some((id) => retired.has(id)) ||
312
- previous.models.some((model) => retired.has(model.id))
313
- : false;
314
- if (!previous || (!isLegacySeed && !hasRetiredModels)) {
315
- return committed(current);
316
- }
317
- // A legacy seed's stored inventory was the registry's shipped list copied
318
- // in at write time. Clearing it is the migration: the resolver prepends
319
- // that list from the current build, so the row stops carrying a stale
320
- // second copy of it. Any other row keeps its own inventory, minus the
321
- // retired ids.
322
- const models = isLegacySeed ? [] : previous.models.filter((model) => !retired.has(model.id));
323
- const { lastTest: _lastTest, modelSource: _modelSource, modelsFetchedAt: _modelsFetchedAt, ...retained } = previous;
324
- const migratedEnabledModelIds = isLegacySeed
325
- ? [...input.enabledModelIds]
326
- : previous.enabledModelIds.filter((id) => !retired.has(id));
327
- const connections = [...current.connections];
328
- const modelOverrides = pruneModelOverrides(previous.modelOverrides, Object.keys(previous.modelOverrides ?? {}).filter((id) => !retired.has(id)));
329
- connections[index] = {
330
- ...retained,
331
- revision: nextRevision(previous.revision),
332
- enabledModelIds: migratedEnabledModelIds,
333
- models,
334
- ...(isLegacySeed || previous.modelSource === undefined
335
- ? {}
336
- : { modelSource: previous.modelSource, modelsFetchedAt: previous.modelsFetchedAt }),
337
- ...(modelOverrides === undefined ? {} : { modelOverrides }),
338
- };
339
- const target = current.defaultTarget;
340
- const defaultTarget = target !== null &&
341
- target.connectionId === previous.connectionId &&
342
- !migratedEnabledModelIds.includes(target.modelId)
343
- ? { connectionId: previous.connectionId, modelId: input.defaultModelId }
344
- : target;
345
- const next = this.nextDocument(current, connections, defaultTarget);
346
- await this.write(root, next);
347
- return committed(next);
348
- }
349
287
  async setDefaultTarget(root, rawInput) {
350
288
  const input = decodeConnectionInput(() => normalizeSetDefaultConnectionTargetInput(rawInput));
351
289
  const current = await this.read(root);