maka-agent 0.2.0-dev.48.20260923 → 0.2.0-dev.49.20260924
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.
- package/dist/acp/session-event-mapper.js +1 -4
- package/dist/onboarding-catalog.js +20 -4
- package/dist/pi-transcript.js +0 -8
- package/dist/pi-tui-pickers.js +1 -1
- package/dist/pi-tui-runner.js +6 -4
- package/dist/runtime-host-onboarding.js +5 -3
- package/dist/runtime-host-session-channel.js +9 -3
- package/native/runtime-host-windows-task-launcher/prebuilds/win32-x64/maka-runtime-host-task-launcher.exe +0 -0
- package/node_modules/@maka/core/dist/events.js +13 -0
- package/node_modules/@maka/core/dist/llm-connections.js +2 -5
- package/node_modules/@maka/core/dist/model-facts.js +2 -4
- package/node_modules/@maka/core/dist/model-metadata.generated.js +345 -248
- package/node_modules/@maka/core/dist/model-thinking.js +17 -17
- package/node_modules/@maka/core/dist/model-web-search.js +7 -9
- package/node_modules/@maka/core/dist/models-dev-projection.js +1 -1
- package/node_modules/@maka/core/dist/onboarding.js +1 -4
- package/node_modules/@maka/core/dist/provider-registry.js +60 -86
- package/node_modules/@maka/core/dist/runtime-event.js +2 -2
- package/node_modules/@maka/core/dist/runtime-policy/connection-catalog-codec.js +28 -16
- package/node_modules/@maka/core/dist/runtime-policy.js +1 -1
- package/node_modules/@maka/core/dist/session.js +23 -9
- package/node_modules/@maka/core/dist/transcript-search.js +1 -0
- package/node_modules/@maka/core/dist/usage-stats/types.js +1 -0
- package/node_modules/@maka/eval/dist/harbor-maka-subject.js +3 -0
- package/node_modules/@maka/eval/dist/maka-subject.js +8 -1
- package/node_modules/@maka/runtime/dist/ai-sdk-backend.js +1 -11
- package/node_modules/@maka/runtime/dist/ai-sdk-compaction.js +2 -12
- package/node_modules/@maka/runtime/dist/ai-sdk-turn.js +3 -71
- package/node_modules/@maka/runtime/dist/conversation-copy.js +2 -2
- package/node_modules/@maka/runtime/dist/local-web-fetch.js +23 -11
- package/node_modules/@maka/runtime/dist/model-adapter.js +10 -5
- package/node_modules/@maka/runtime/dist/model-factory.js +33 -30
- package/node_modules/@maka/runtime/dist/model-fetcher.js +4 -1
- package/node_modules/@maka/runtime/dist/model-runtime.js +3 -9
- package/node_modules/@maka/runtime/dist/read-page.js +11 -8
- package/node_modules/@maka/runtime/dist/recovery-resolver.js +47 -20
- package/node_modules/@maka/runtime/dist/runtime-event-backfill.js +1 -0
- package/node_modules/@maka/runtime/dist/scheduled-task-tools.js +39 -8
- package/node_modules/@maka/runtime/dist/session-manager.js +12 -2
- package/node_modules/@maka/runtime/dist/telemetry/model-pricing.generated.js +141 -134
- package/node_modules/@maka/runtime/dist/tool-result-archive-transition.js +3 -3
- package/node_modules/@maka/runtime/dist/workers/filesystem-worker.js +7 -6
- package/node_modules/@maka/runtime-host/dist/adapter/session-projector.js +28 -62
- package/node_modules/@maka/runtime-host/dist/client/hosted-execution-target.js +7 -1
- package/node_modules/@maka/runtime-host/dist/client/session-subscription.js +3 -0
- package/node_modules/@maka/runtime-host/dist/protocol/connection-effects.js +6 -3
- package/node_modules/@maka/runtime-host/dist/protocol/index.js +5 -1
- package/node_modules/@maka/runtime-host/dist/protocol/operations.js +4 -1
- package/node_modules/@maka/runtime-host/dist/protocol/prompt-suggestions.js +61 -0
- package/node_modules/@maka/runtime-host/dist/protocol/runtime-policy.js +4 -1
- package/node_modules/@maka/runtime-host/dist/protocol/session-continuity.js +2 -1
- package/node_modules/@maka/runtime-host/dist/server/connection-effect-coordinator.js +3 -0
- package/node_modules/@maka/runtime-host/dist/server/execution-composition.js +54 -6
- package/node_modules/@maka/runtime-host/dist/server/execution-model-authority.js +38 -2
- package/node_modules/@maka/runtime-host/dist/server/generated-text.js +39 -0
- package/node_modules/@maka/runtime-host/dist/server/hosted-execution-tool-profile.js +8 -0
- package/node_modules/@maka/runtime-host/dist/server/prompt-suggestion.js +179 -0
- package/node_modules/@maka/runtime-host/dist/server/root-turn-coordinator.js +2 -2
- package/node_modules/@maka/runtime-host/dist/server/session-continuity-coordinator.js +48 -16
- package/node_modules/@maka/runtime-host/dist/server/session-title.js +3 -16
- package/node_modules/@maka/runtime-host/dist/server/session-transcript-reader.js +38 -3
- package/node_modules/@maka/runtime-host/dist/server/shared-session-transcript.js +3 -0
- package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-action-gate.js +6 -13
- package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-coordinator.js +35 -11
- package/node_modules/@maka/storage/dist/config-transfer.js +14 -8
- package/node_modules/@maka/storage/dist/execution-stores.js +4 -3
- package/node_modules/@maka/storage/dist/interaction-store.js +13 -0
- package/node_modules/@maka/storage/dist/runtime-policy/connection-catalog-document.js +28 -17
- package/node_modules/@maka/storage/dist/runtime-policy/coordinator.js +9 -3
- package/node_modules/@maka/storage/dist/runtime-policy/legacy-custom-connection.js +65 -0
- package/node_modules/@maka/storage/dist/runtime-policy/onboarding-transaction.js +10 -5
- package/node_modules/@maka/storage/dist/session-bundle-policy.js +11 -0
- package/node_modules/@maka/storage/dist/session-store.js +29 -6
- package/node_modules/@maka/storage/dist/sqlite-core-execution-schema.js +3 -0
- package/node_modules/@maka/storage/dist/sqlite-runtime-store.js +125 -7
- package/node_modules/@maka/storage/dist/sqlite-session-metadata-store.js +5 -3
- package/node_modules/@maka/storage/dist/usage-screen.js +138 -108
- package/package.json +1 -1
|
@@ -41,7 +41,7 @@ import { isCollaborationMode } from './collaboration.js';
|
|
|
41
41
|
import { isAgentSwarmAuthorizationSource, isEffectiveOrchestrationSource, isOrchestrationMode, } from './orchestration.js';
|
|
42
42
|
import { isToolMode } from './tool-mode.js';
|
|
43
43
|
import { isExecutorId } from './executor-id.js';
|
|
44
|
-
import {
|
|
44
|
+
import { isSystemNoteKind } from './session.js';
|
|
45
45
|
import { decodeTurnOrigin } from './turn-origin.js';
|
|
46
46
|
import { defineObjectShape, hasExactShape, isFiniteNumber, isOptionalMember, isOptionalString, isRecord, isStringArray, } from './record-schema.js';
|
|
47
47
|
import { isPermissionDecisionFields, isPermissionRequestPayload, isUserQuestionRequest, } from './interaction-record-schema.js';
|
|
@@ -451,7 +451,7 @@ function isRuntimeEventContent(value) {
|
|
|
451
451
|
case 'system_note':
|
|
452
452
|
return (hasExactShape(value, SYSTEM_NOTE_CONTENT_SHAPE) &&
|
|
453
453
|
typeof value.note === 'string' &&
|
|
454
|
-
|
|
454
|
+
isSystemNoteKind(value.note));
|
|
455
455
|
case 'invocation_opened':
|
|
456
456
|
return isRuntimeInvocationOpened(value);
|
|
457
457
|
default:
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* specific language governing permissions and limitations
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
|
-
import {
|
|
19
|
+
import { isModelApiProtocol, isModelModality, effectiveBaseUrl, PROVIDER_REGISTRY, providerDefaultsOf, validateSlug, } from '../llm-connections.js';
|
|
20
20
|
import { CONNECTION_MODEL_DESCRIPTION_MAX_LENGTH, CONNECTION_MODEL_DISPLAY_NAME_MAX_LENGTH, MAX_PREPENDED_FALLBACK_MODELS, } from '../model-catalog.js';
|
|
21
21
|
import { DECLARABLE_RELAY_THINKING_LEVELS, isThinkingLevel, } from '../model-thinking.js';
|
|
22
22
|
import { normalizeOptionalRequestBodyOverlay, RequestCustomizationValidationError, } from '../request-customization.js';
|
|
@@ -78,6 +78,7 @@ export function normalizeConnectionCatalogEntryDraft(value) {
|
|
|
78
78
|
'name',
|
|
79
79
|
'providerType',
|
|
80
80
|
'baseUrl',
|
|
81
|
+
'defaultApiProtocol',
|
|
81
82
|
'enabled',
|
|
82
83
|
'enabledModelIds',
|
|
83
84
|
'modelOverrides',
|
|
@@ -85,6 +86,7 @@ export function normalizeConnectionCatalogEntryDraft(value) {
|
|
|
85
86
|
], ['slug', 'name', 'providerType', 'enabled', 'enabledModelIds']);
|
|
86
87
|
const providerType = decodeProviderType(item.providerType);
|
|
87
88
|
const baseUrl = normalizeCatalogConnectionBaseUrl(item.baseUrl, providerType);
|
|
89
|
+
const defaultApiProtocol = decodeDefaultApiProtocol(item.defaultApiProtocol, providerType);
|
|
88
90
|
const enabledModelIds = decodeConnectionModelIds(item.enabledModelIds);
|
|
89
91
|
const requestBodyOverlay = item.requestBodyOverlay === undefined
|
|
90
92
|
? undefined
|
|
@@ -96,6 +98,7 @@ export function normalizeConnectionCatalogEntryDraft(value) {
|
|
|
96
98
|
name: decodeConnectionName(item.name),
|
|
97
99
|
providerType,
|
|
98
100
|
...(baseUrl === undefined ? {} : { baseUrl }),
|
|
101
|
+
...(defaultApiProtocol === undefined ? {} : { defaultApiProtocol }),
|
|
99
102
|
enabled: booleanValue(item.enabled, 'connection enabled'),
|
|
100
103
|
enabledModelIds,
|
|
101
104
|
...profiles,
|
|
@@ -261,28 +264,36 @@ export function decodeModelOverridesTable(value) {
|
|
|
261
264
|
* `contextWindow` and `vision` state facts about a model. A user has them when
|
|
262
265
|
* Maka does not — a model newer than the bundled snapshot, or any model on a
|
|
263
266
|
* provider with no model-list endpoint — and that need is not confined to
|
|
264
|
-
*
|
|
267
|
+
* custom connections (#1584), so they are legal everywhere.
|
|
265
268
|
*
|
|
266
|
-
* `thinkingLevels` and `serviceTier` name a wire feature instead.
|
|
267
|
-
*
|
|
268
|
-
*
|
|
269
|
-
* `supportsRelayFastServiceTier` gates the read side by provider for the same
|
|
270
|
-
* reason. A table carrying them on another provider describes a request Maka
|
|
271
|
-
* would never send: dead state at best, and on a provider whose wire rejects
|
|
272
|
-
* the unknown value, a 400 the user cannot explain.
|
|
269
|
+
* `thinkingLevels` and `serviceTier` name a wire feature instead. Built-in
|
|
270
|
+
* providers take thinking levels from model metadata and never send a declared
|
|
271
|
+
* one; a table carrying them there describes a request Maka would never send.
|
|
273
272
|
*/
|
|
274
273
|
function assertProfileFieldsFitProvider(profiles, providerType) {
|
|
275
|
-
if (!profiles ||
|
|
274
|
+
if (!profiles || providerType === 'custom')
|
|
276
275
|
return;
|
|
277
276
|
for (const [modelId, profile] of Object.entries(profiles)) {
|
|
278
277
|
if (profile.thinkingLevels !== undefined) {
|
|
279
|
-
throw domainError(`declared thinking levels for ${modelId} require
|
|
278
|
+
throw domainError(`declared thinking levels for ${modelId} require a custom connection`);
|
|
280
279
|
}
|
|
281
280
|
if (profile.serviceTier !== undefined) {
|
|
282
|
-
throw domainError(`declared service tier for ${modelId} requires
|
|
281
|
+
throw domainError(`declared service tier for ${modelId} requires a custom connection`);
|
|
283
282
|
}
|
|
284
283
|
}
|
|
285
284
|
}
|
|
285
|
+
export function decodeDefaultApiProtocol(value, providerType) {
|
|
286
|
+
if (providerType !== 'custom') {
|
|
287
|
+
if (value !== undefined) {
|
|
288
|
+
throw domainError('only a custom connection has a default API protocol');
|
|
289
|
+
}
|
|
290
|
+
return undefined;
|
|
291
|
+
}
|
|
292
|
+
if (!isModelApiProtocol(value)) {
|
|
293
|
+
throw domainError('custom connection default API protocol is invalid');
|
|
294
|
+
}
|
|
295
|
+
return value;
|
|
296
|
+
}
|
|
286
297
|
// An empty table is not a state worth storing: drafts/canonical entries omit
|
|
287
298
|
// the key, and updates treat it as the same instruction as `null` (clear).
|
|
288
299
|
function nonEmptyRelayProfiles(value) {
|
|
@@ -297,6 +308,7 @@ export function decodeCanonicalConnectionCatalogEntry(value) {
|
|
|
297
308
|
'name',
|
|
298
309
|
'providerType',
|
|
299
310
|
'baseUrl',
|
|
311
|
+
'defaultApiProtocol',
|
|
300
312
|
'enabled',
|
|
301
313
|
'enabledModelIds',
|
|
302
314
|
'modelOverrides',
|
|
@@ -320,6 +332,9 @@ export function decodeCanonicalConnectionCatalogEntry(value) {
|
|
|
320
332
|
name: item.name,
|
|
321
333
|
providerType: item.providerType,
|
|
322
334
|
...(item.baseUrl === undefined ? {} : { baseUrl: item.baseUrl }),
|
|
335
|
+
...(item.defaultApiProtocol === undefined
|
|
336
|
+
? {}
|
|
337
|
+
: { defaultApiProtocol: item.defaultApiProtocol }),
|
|
323
338
|
enabled: item.enabled,
|
|
324
339
|
enabledModelIds: item.enabledModelIds,
|
|
325
340
|
...(item.modelOverrides === undefined ? {} : { modelOverrides: item.modelOverrides }),
|
|
@@ -435,10 +450,7 @@ export function decodeConnectionModel(value) {
|
|
|
435
450
|
'capabilities',
|
|
436
451
|
'modalities',
|
|
437
452
|
], ['id']);
|
|
438
|
-
if (item.apiProtocol !== undefined &&
|
|
439
|
-
item.apiProtocol !== 'openai-chat' &&
|
|
440
|
-
item.apiProtocol !== 'openai-responses' &&
|
|
441
|
-
item.apiProtocol !== 'anthropic-messages') {
|
|
453
|
+
if (item.apiProtocol !== undefined && !isModelApiProtocol(item.apiProtocol)) {
|
|
442
454
|
throw domainError('connection model API protocol is invalid');
|
|
443
455
|
}
|
|
444
456
|
let capabilities;
|
|
@@ -22,7 +22,7 @@ export { WEB_SEARCH_PROVIDERS };
|
|
|
22
22
|
export { networkProxyCredentialTarget };
|
|
23
23
|
export { decodeRuntimePolicyEntityId, RuntimePolicyDomainDecodeError, } from './runtime-policy/domain-codec.js';
|
|
24
24
|
export { decodeCanonicalRuntimePolicy, normalizeNetworkProxyCredentialTarget, decodeRuntimePolicyV2, decodeRuntimePolicyV3, normalizeNetworkProxyUpdate, normalizeRuntimePolicyMutation, } from './runtime-policy/policy-codec.js';
|
|
25
|
-
export { CONNECTION_CATALOG_MAX_CONNECTIONS, CONNECTION_CATALOG_MAX_ENABLED_MODEL_IDS, CONNECTION_CATALOG_MAX_ENTRIES_PER_CONNECTION, CONNECTION_CATALOG_MAX_MODELS_PER_CONNECTION, CONNECTION_MODEL_ID_MAX_LENGTH, CONNECTION_NAME_MAX_LENGTH, decodeCanonicalConnectionBaseUrl, decodeCanonicalConnectionCatalogEntry, decodeConnectionModelId, decodeConnectionCredentialTarget, decodeModelOverridesTable, decodeConnectionModel, decodeConnectionModels, decodeConnectionName, decodeConnectionSlug, decodeConnectionTarget, decodeConnectionTestSummary, decodeConnectionVersionBasis, decodeProviderType, normalizeCatalogConnectionBaseUrl, normalizeConnectionCatalogEntryDraft, normalizeConnectionCatalogEntryUpdate, normalizeConnectionCatalogEntryUpdateForProvider, normalizeConnectionModelDiscoveryResult, canonicalConnectionEffectiveBaseUrl, connectionCredentialTarget, normalizeCreateCatalogConnectionInput, normalizeRemoveCatalogConnectionInput, normalizeSetDefaultConnectionTargetInput, normalizeUpdateCatalogConnectionInput, } from './runtime-policy/connection-catalog-codec.js';
|
|
25
|
+
export { CONNECTION_CATALOG_MAX_CONNECTIONS, CONNECTION_CATALOG_MAX_ENABLED_MODEL_IDS, CONNECTION_CATALOG_MAX_ENTRIES_PER_CONNECTION, CONNECTION_CATALOG_MAX_MODELS_PER_CONNECTION, CONNECTION_MODEL_ID_MAX_LENGTH, CONNECTION_NAME_MAX_LENGTH, decodeCanonicalConnectionBaseUrl, decodeCanonicalConnectionCatalogEntry, decodeConnectionModelId, decodeConnectionCredentialTarget, decodeModelOverridesTable, decodeConnectionModel, decodeConnectionModels, decodeConnectionName, decodeConnectionSlug, decodeConnectionTarget, decodeConnectionTestSummary, decodeConnectionVersionBasis, decodeDefaultApiProtocol, decodeProviderType, normalizeCatalogConnectionBaseUrl, normalizeConnectionCatalogEntryDraft, normalizeConnectionCatalogEntryUpdate, normalizeConnectionCatalogEntryUpdateForProvider, normalizeConnectionModelDiscoveryResult, canonicalConnectionEffectiveBaseUrl, connectionCredentialTarget, normalizeCreateCatalogConnectionInput, normalizeRemoveCatalogConnectionInput, normalizeSetDefaultConnectionTargetInput, normalizeUpdateCatalogConnectionInput, } from './runtime-policy/connection-catalog-codec.js';
|
|
26
26
|
export { decodeModelCatalogEntry } from './runtime-policy/model-catalog-entry-codec.js';
|
|
27
27
|
export { decodeCredentialLocator, decodeCredentialStatus, decodeCredentialVersionBasis, normalizeCredentialSecret, normalizeDeleteCredentialInput, normalizeSetCredentialInput, } from './runtime-policy/credential-vault-codec.js';
|
|
28
28
|
export { normalizeRequestBodyOverlay, normalizeOptionalRequestBodyOverlay, normalizeRequestHeaderUpdates, normalizeRequestHeaders, parseRequestHeaders, REQUEST_BODY_OVERLAY_MAX_BYTES, REQUEST_HEADERS_MAX_BYTES, RequestCustomizationValidationError, serializeRequestHeaders, } from './request-customization.js';
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
19
|
import { isWorkHubActionReceipt } from './workhub-action-result.js';
|
|
20
|
+
import { decodeInteractionRequest, decodeInteractionCanonicalOutcome, isInteractionCanonicalOutcomeValidForRequest, } from './interaction.js';
|
|
20
21
|
import { isExecutorId } from './executor-id.js';
|
|
21
22
|
import { isThinkingLevel } from './model-thinking.js';
|
|
22
23
|
import { MODEL_FAILURE_MESSAGE_MAX_BYTES, isModelRetryDecision, } from './model-failure.js';
|
|
@@ -352,7 +353,6 @@ function isWorkHubDelegationStopResolution(outcome, targetTurnId) {
|
|
|
352
353
|
export const RUNTIME_SYSTEM_NOTE_KINDS = [
|
|
353
354
|
'context_compacted',
|
|
354
355
|
'context_compaction_failed_open',
|
|
355
|
-
'context_provider_dropping',
|
|
356
356
|
'context_window_suggestion',
|
|
357
357
|
'context_window_overrun',
|
|
358
358
|
'context_reported_window_exceeded',
|
|
@@ -360,9 +360,9 @@ export const RUNTIME_SYSTEM_NOTE_KINDS = [
|
|
|
360
360
|
'step_limit',
|
|
361
361
|
];
|
|
362
362
|
/**
|
|
363
|
-
* Notes
|
|
364
|
-
* readable
|
|
365
|
-
*
|
|
363
|
+
* Notes nothing writes any more, still decoded so old transcripts and run
|
|
364
|
+
* ledgers stay readable, and never shown. The session-level ones are owned by
|
|
365
|
+
* the Session header and the invocation's opening and terminal facts.
|
|
366
366
|
*/
|
|
367
367
|
export const RETIRED_SYSTEM_NOTE_KINDS = [
|
|
368
368
|
'session_start',
|
|
@@ -371,10 +371,14 @@ export const RETIRED_SYSTEM_NOTE_KINDS = [
|
|
|
371
371
|
'model_change',
|
|
372
372
|
'error',
|
|
373
373
|
'abort',
|
|
374
|
+
'context_provider_dropping',
|
|
374
375
|
];
|
|
375
376
|
export function isRuntimeSystemNoteKind(kind) {
|
|
376
377
|
return RUNTIME_SYSTEM_NOTE_KINDS.includes(kind);
|
|
377
378
|
}
|
|
379
|
+
export function isSystemNoteKind(kind) {
|
|
380
|
+
return (isRuntimeSystemNoteKind(kind) || RETIRED_SYSTEM_NOTE_KINDS.includes(kind));
|
|
381
|
+
}
|
|
378
382
|
const USER_MESSAGE_SHAPE = defineObjectShape()(['type', 'id', 'turnId', 'ts', 'text'], [
|
|
379
383
|
'displayText',
|
|
380
384
|
'attachments',
|
|
@@ -407,6 +411,7 @@ const TOOL_RESULT_MESSAGE_SHAPE = defineObjectShape()(['type', 'id', 'turnId', '
|
|
|
407
411
|
'parentToolCallId',
|
|
408
412
|
'parentOperationId',
|
|
409
413
|
]);
|
|
414
|
+
const FORM_INTERACTION_MESSAGE_SHAPE = defineObjectShape()(['type', 'id', 'turnId', 'ts', 'request', 'outcome'], []);
|
|
410
415
|
const PERMISSION_DECISION_MESSAGE_SHAPE = defineObjectShape()(['type', 'id', 'turnId', 'ts', 'toolUseId', 'toolName', 'decision'], ['rememberForTurn', 'reviewer', 'rationale', 'riskLevel', 'hint']);
|
|
411
416
|
const TOKEN_USAGE_MESSAGE_SHAPE = defineObjectShape()(['type', 'id', 'turnId', 'ts', 'input', 'output'], [
|
|
412
417
|
'cacheHitInput',
|
|
@@ -556,10 +561,6 @@ const WORKHUB_DELEGATION_HOST_PATH_WORKSPACE_SHAPE = defineObjectShape()(['kind'
|
|
|
556
561
|
const SYSTEM_NOTE_MESSAGE_SHAPE = defineObjectShape()(['type', 'id', 'ts', 'kind'], ['turnId', 'data']);
|
|
557
562
|
const ASSISTANT_THINKING_PART_SHAPE = defineObjectShape()(['text'], ['signature', 'providerOptions']);
|
|
558
563
|
const ASSISTANT_THINKING_SHAPE = defineObjectShape()(['text'], ['signature', 'providerOptions', 'parts']);
|
|
559
|
-
const SYSTEM_NOTE_KINDS = new Set([
|
|
560
|
-
...RUNTIME_SYSTEM_NOTE_KINDS,
|
|
561
|
-
...RETIRED_SYSTEM_NOTE_KINDS,
|
|
562
|
-
]);
|
|
563
564
|
export function decodeCanonicalMessage(value) {
|
|
564
565
|
return decodeMessage(value, decodeCanonicalToolResultContent);
|
|
565
566
|
}
|
|
@@ -637,6 +638,19 @@ function decodeMessage(value, decodeToolResultContent) {
|
|
|
637
638
|
isToolActivityIdentity(message))
|
|
638
639
|
return message;
|
|
639
640
|
break;
|
|
641
|
+
case 'form_interaction':
|
|
642
|
+
if (hasMessageEnvelope(message, true) &&
|
|
643
|
+
hasExactShape(message, FORM_INTERACTION_MESSAGE_SHAPE)) {
|
|
644
|
+
const request = decodeInteractionRequest(message.request);
|
|
645
|
+
const outcome = decodeInteractionCanonicalOutcome(message.outcome);
|
|
646
|
+
if ((request.kind === 'form' || request.kind === 'question') &&
|
|
647
|
+
(outcome.kind === 'form_answer' ||
|
|
648
|
+
outcome.kind === 'question_answer' ||
|
|
649
|
+
outcome.kind === 'closure') &&
|
|
650
|
+
isInteractionCanonicalOutcomeValidForRequest(request, outcome))
|
|
651
|
+
return { ...message, request, outcome };
|
|
652
|
+
}
|
|
653
|
+
break;
|
|
640
654
|
case 'permission_decision':
|
|
641
655
|
if (hasExactShape(message, PERMISSION_DECISION_MESSAGE_SHAPE) &&
|
|
642
656
|
hasMessageEnvelope(message, true) &&
|
|
@@ -680,7 +694,7 @@ function decodeMessage(value, decodeToolResultContent) {
|
|
|
680
694
|
if (hasExactShape(message, SYSTEM_NOTE_MESSAGE_SHAPE) &&
|
|
681
695
|
hasMessageEnvelope(message, false) &&
|
|
682
696
|
isOptionalString(message.turnId) &&
|
|
683
|
-
|
|
697
|
+
isSystemNoteKind(message.kind))
|
|
684
698
|
return message;
|
|
685
699
|
break;
|
|
686
700
|
}
|
|
@@ -62,6 +62,9 @@ try {
|
|
|
62
62
|
? {
|
|
63
63
|
connection: {
|
|
64
64
|
providerType: payload.connection.providerType,
|
|
65
|
+
...(payload.connection.defaultApiProtocol === undefined
|
|
66
|
+
? {}
|
|
67
|
+
: { defaultApiProtocol: payload.connection.defaultApiProtocol }),
|
|
65
68
|
apiKey: process.env[payload.connection.apiKeyEnvironment] ?? '',
|
|
66
69
|
},
|
|
67
70
|
}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
19
|
import { randomUUID } from 'node:crypto';
|
|
20
|
-
import { PROVIDER_REGISTRY } from '@maka/core/llm-connections';
|
|
20
|
+
import { isModelApiProtocol, PROVIDER_REGISTRY } from '@maka/core/llm-connections';
|
|
21
21
|
import { isThinkingLevel } from '@maka/core/model-thinking';
|
|
22
22
|
import { isSessionToolProfile } from '@maka/core/session';
|
|
23
23
|
import { decodeHostedExecutionProjection } from '@maka/runtime-host/protocol';
|
|
@@ -63,6 +63,9 @@ export function createMakaSubjectAdapter() {
|
|
|
63
63
|
? {
|
|
64
64
|
connection: {
|
|
65
65
|
providerType: config.providerType,
|
|
66
|
+
...(config.defaultApiProtocol === undefined
|
|
67
|
+
? {}
|
|
68
|
+
: { defaultApiProtocol: config.defaultApiProtocol }),
|
|
66
69
|
apiKeyEnvironment: config.apiKeyEnvironment,
|
|
67
70
|
},
|
|
68
71
|
}
|
|
@@ -237,6 +240,7 @@ function decodeConfig(value) {
|
|
|
237
240
|
'connectionSlug',
|
|
238
241
|
'model',
|
|
239
242
|
...(Object.hasOwn(value, 'providerType') ? ['providerType', 'apiKeyEnvironment'] : []),
|
|
243
|
+
...(value.providerType === 'custom' ? ['defaultApiProtocol'] : []),
|
|
240
244
|
...(Object.hasOwn(value, 'thinkingLevel') ? ['thinkingLevel'] : []),
|
|
241
245
|
'permissionMode',
|
|
242
246
|
'collaborationMode',
|
|
@@ -249,6 +253,9 @@ function decodeConfig(value) {
|
|
|
249
253
|
!Object.hasOwn(PROVIDER_REGISTRY, String(config.providerType))) {
|
|
250
254
|
throw new Error('Maka config.providerType is invalid');
|
|
251
255
|
}
|
|
256
|
+
if (config.providerType === 'custom' && !isModelApiProtocol(config.defaultApiProtocol)) {
|
|
257
|
+
throw new Error('Maka config.defaultApiProtocol is invalid');
|
|
258
|
+
}
|
|
252
259
|
if (config.thinkingLevel !== undefined && !isThinkingLevel(config.thinkingLevel)) {
|
|
253
260
|
throw new Error('Maka config.thinkingLevel is invalid');
|
|
254
261
|
}
|
|
@@ -91,17 +91,7 @@ export class AiSdkBackend {
|
|
|
91
91
|
*/
|
|
92
92
|
activeTurns = new Set();
|
|
93
93
|
compaction;
|
|
94
|
-
|
|
95
|
-
* The provider has been reported dropping context, for this backend.
|
|
96
|
-
*
|
|
97
|
-
* Not per send: the condition persists once a provider starts truncating, so
|
|
98
|
-
* a note on every later turn would repeat one fact the user has already been
|
|
99
|
-
* told. The scope is this backend's lifetime rather than the Session's, so a
|
|
100
|
-
* backend that is disposed and rebuilt may say it once more.
|
|
101
|
-
*/
|
|
102
|
-
turnSessionState = {
|
|
103
|
-
contextProviderDroppingReported: false,
|
|
104
|
-
};
|
|
94
|
+
turnSessionState = {};
|
|
105
95
|
constructor(input) {
|
|
106
96
|
this.input = input;
|
|
107
97
|
this.sessionId = input.sessionId;
|
|
@@ -536,7 +536,6 @@ export class AiSdkCompaction {
|
|
|
536
536
|
if (persisted) {
|
|
537
537
|
state.baselineTokens = persisted.inputTokens + (persisted.outputTokens ?? 0);
|
|
538
538
|
state.lastAcceptedTotalTokens = state.baselineTokens;
|
|
539
|
-
state.priorAcceptedInputTokens = persisted.inputTokens;
|
|
540
539
|
}
|
|
541
540
|
if (persisted)
|
|
542
541
|
state.replyReserveTokens = replyReserveTokens(persisted.outputTokens);
|
|
@@ -1034,9 +1033,8 @@ export class MidTurnCapacityCompactState {
|
|
|
1034
1033
|
}
|
|
1035
1034
|
/**
|
|
1036
1035
|
* What has reshaped the request since the last one a provider accepted. The
|
|
1037
|
-
* turn clears it at that acceptance
|
|
1038
|
-
*
|
|
1039
|
-
* request is a pure append of its predecessor.
|
|
1036
|
+
* turn clears it at that acceptance; overflow recovery reads it so a request
|
|
1037
|
+
* that was already folded or stripped of images is not reshaped again.
|
|
1040
1038
|
*/
|
|
1041
1039
|
stepShaping = new Set();
|
|
1042
1040
|
/**
|
|
@@ -1050,14 +1048,6 @@ export class MidTurnCapacityCompactState {
|
|
|
1050
1048
|
omittedImageToolResults = new Map();
|
|
1051
1049
|
/** Malformed summaries spend one bounded repair budget for this whole Turn. */
|
|
1052
1050
|
summarizerFailure;
|
|
1053
|
-
/**
|
|
1054
|
-
* Input tokens of the last request a provider accepted before this send.
|
|
1055
|
-
*
|
|
1056
|
-
* Input against input, across the send boundary: the first request of a send
|
|
1057
|
-
* has no earlier step to compare with, and `baselineTokens` counts the reply
|
|
1058
|
-
* too, which the next request does not always carry.
|
|
1059
|
-
*/
|
|
1060
|
-
priorAcceptedInputTokens;
|
|
1061
1051
|
constructor(headAnchor, priorContentEvents, priorInvocations,
|
|
1062
1052
|
/**
|
|
1063
1053
|
* The Maka window: the context window the USER declared for this model,
|
|
@@ -695,8 +695,6 @@ export class AiSdkTurn {
|
|
|
695
695
|
// result.usage.inputTokens is cumulative across steps and would produce
|
|
696
696
|
// misleading >100% percentages, so the per-step value is captured here.
|
|
697
697
|
let lastStepInputTokens;
|
|
698
|
-
/** Tool count of the request that produced `lastStepInputTokens`. */
|
|
699
|
-
let lastStepActiveToolCount;
|
|
700
698
|
// Output tokens of the same step: with the input they are the baseline the
|
|
701
699
|
// next request is judged from (everything the model produced is re-sent).
|
|
702
700
|
let lastStepOutputTokens;
|
|
@@ -977,8 +975,6 @@ export class AiSdkTurn {
|
|
|
977
975
|
const turnEvents = await loadDurableTurnEvents();
|
|
978
976
|
const pruned = await this.deps.compaction.pruneToolResults(turnEvents, turnId);
|
|
979
977
|
if (pruned.stats) {
|
|
980
|
-
if (pruned.stats.prunedToolResults > 0)
|
|
981
|
-
midTurnState?.stepShaping.add('prune');
|
|
982
978
|
contextBudgetForTelemetry = addToolResultPruneStats(contextBudgetForTelemetry ?? minimalContextBudgetDiagnostic(), pruned.stats);
|
|
983
979
|
}
|
|
984
980
|
const projectionCheckpoint = midTurnState?.projectionCheckpoint;
|
|
@@ -1151,14 +1147,6 @@ export class AiSdkTurn {
|
|
|
1151
1147
|
? codeModeCatalogPrompt
|
|
1152
1148
|
: undefined,
|
|
1153
1149
|
]);
|
|
1154
|
-
// A finalization step resolves an empty tool set, so its request
|
|
1155
|
-
// legitimately drops several thousand schema tokens with no fold,
|
|
1156
|
-
// prune or image omission. Maka shaped that request; the provider did
|
|
1157
|
-
// not drop anything.
|
|
1158
|
-
if (lastStepActiveToolCount !== undefined &&
|
|
1159
|
-
activeToolsForRequest.length < lastStepActiveToolCount) {
|
|
1160
|
-
midTurnState?.stepShaping.add('tools');
|
|
1161
|
-
}
|
|
1162
1150
|
const requestCompositionId = this.runId && this.deps.backend.recordRequestComposition
|
|
1163
1151
|
? await this.deps.backend.recordRequestComposition(this.runId, {
|
|
1164
1152
|
compositionId: this.deps.newId(),
|
|
@@ -1440,61 +1428,6 @@ export class AiSdkTurn {
|
|
|
1440
1428
|
providerStepUsage = stepUsage;
|
|
1441
1429
|
if (!stepUsage)
|
|
1442
1430
|
sawUnusableStepUsage = true;
|
|
1443
|
-
// Silent eviction / rewrite check (#4559): this step only
|
|
1444
|
-
// appended (no fold, no prune, no image omission) yet the
|
|
1445
|
-
// provider counted no more input tokens than for the previous
|
|
1446
|
-
// request. Not-greater, not strictly-fewer: a provider that
|
|
1447
|
-
// truncates to a fixed window (Ollama's `num_ctx`) reports the
|
|
1448
|
-
// same total on every later request while Maka keeps
|
|
1449
|
-
// appending, so a plateau is the signal, and an equal count
|
|
1450
|
-
// after an append is already impossible without provider-side
|
|
1451
|
-
// eviction or rewriting. Input against input: the previous
|
|
1452
|
-
// reply's reasoning may not be resent, so input + output is
|
|
1453
|
-
// not the floor of the next input on every wire.
|
|
1454
|
-
const completedRequestIndex = runtimeSteps - 1;
|
|
1455
|
-
// Across the send boundary the comparison is the same one,
|
|
1456
|
-
// against the last request a provider accepted before this
|
|
1457
|
-
// send. A provider that truncates to a fixed window reports
|
|
1458
|
-
// the same input on every later request while the user keeps
|
|
1459
|
-
// adding turns, and a send of one or two steps never sees
|
|
1460
|
-
// that from the inside: the live evidence plateaus at 3,716
|
|
1461
|
-
// input tokens across eight turns with nothing reported
|
|
1462
|
-
// (#4623). The first request of a send therefore compares
|
|
1463
|
-
// against the persisted anchor, which is route-validated
|
|
1464
|
-
// where it is read.
|
|
1465
|
-
const acrossSends = completedRequestIndex === 0;
|
|
1466
|
-
const priorInput = acrossSends
|
|
1467
|
-
? midTurnState?.priorAcceptedInputTokens
|
|
1468
|
-
: lastStepInputTokens;
|
|
1469
|
-
if (!this.deps.session.contextProviderDroppingReported &&
|
|
1470
|
-
midTurnState &&
|
|
1471
|
-
priorInput !== undefined &&
|
|
1472
|
-
midTurnState.stepShaping.size === 0 &&
|
|
1473
|
-
stepUsage !== undefined &&
|
|
1474
|
-
Number.isFinite(stepUsage.inputTokens) &&
|
|
1475
|
-
stepUsage.inputTokens > 0 &&
|
|
1476
|
-
// Across sends the test is equality, not "did not grow".
|
|
1477
|
-
// Inside a send Maka knows it only appended, so any
|
|
1478
|
-
// shortfall is the provider's. Across the boundary it does
|
|
1479
|
-
// not: a manual compaction leaves the pre-compaction anchor
|
|
1480
|
-
// behind, a turn can carry a smaller tool set, and a user
|
|
1481
|
-
// can edit or branch history. All three shrink the input
|
|
1482
|
-
// legitimately, and none of them lands on exactly the same
|
|
1483
|
-
// count. A provider truncating to a fixed window does, on
|
|
1484
|
-
// every later request.
|
|
1485
|
-
(acrossSends
|
|
1486
|
-
? stepUsage.inputTokens === priorInput
|
|
1487
|
-
: stepUsage.inputTokens <= priorInput)) {
|
|
1488
|
-
this.deps.session.contextProviderDroppingReported = true;
|
|
1489
|
-
await this.recordSystemNote('context_provider_dropping', turnId, {
|
|
1490
|
-
inputTokens: stepUsage.inputTokens,
|
|
1491
|
-
priorInputTokens: priorInput,
|
|
1492
|
-
});
|
|
1493
|
-
}
|
|
1494
|
-
// Clear here, not at the top of the next step: the continuation
|
|
1495
|
-
// lane archives its prune below, after this point, and archiving
|
|
1496
|
-
// is idempotent — the next step's re-projection reports no prune,
|
|
1497
|
-
// so a clear above it would lose the only record of this one.
|
|
1498
1431
|
midTurnState?.stepShaping.clear();
|
|
1499
1432
|
// Fail closed: reset on every step boundary so a missing final
|
|
1500
1433
|
// step's usage does not leave a stale value from an earlier step.
|
|
@@ -1520,9 +1453,9 @@ export class AiSdkTurn {
|
|
|
1520
1453
|
}
|
|
1521
1454
|
// Nothing declared, and the provider accepted a request past
|
|
1522
1455
|
// the window this model reports. Every other signal in this
|
|
1523
|
-
// design stays dark there: no rejection to recover from
|
|
1524
|
-
//
|
|
1525
|
-
//
|
|
1456
|
+
// design stays dark there: no rejection to recover from and
|
|
1457
|
+
// no declaration to arm the proactive threshold, so the
|
|
1458
|
+
// session degrades quietly and
|
|
1526
1459
|
// indefinitely (#4634). Report the two real numbers and
|
|
1527
1460
|
// leave the decision with the user: a reported window is a
|
|
1528
1461
|
// hint, and Maka still declares nothing on their behalf.
|
|
@@ -1560,7 +1493,6 @@ export class AiSdkTurn {
|
|
|
1560
1493
|
}
|
|
1561
1494
|
lastStepInputTokens = stepUsage?.inputTokens;
|
|
1562
1495
|
lastStepOutputTokens = stepUsage?.outputTokens;
|
|
1563
|
-
lastStepActiveToolCount = activeToolsForRequest.length;
|
|
1564
1496
|
// A `finishReason: length` is deliberately not a trigger. The
|
|
1565
1497
|
// reply may have been cut because the provider ran out of
|
|
1566
1498
|
// window room, or because the provider's own output cap is
|
|
@@ -39,7 +39,7 @@ import { baseToolResultProjection, decodeLedgerTransition, reduceEffectiveModelP
|
|
|
39
39
|
import { archivedToolResultProjection } from './tool-result-archive-transition.js';
|
|
40
40
|
import { serializeToolResultProjectionV1 } from './tool-result-archive-encoding.js';
|
|
41
41
|
import { createHash } from 'node:crypto';
|
|
42
|
-
import { readToolResultPage, readableToolResult, resolveReadInput,
|
|
42
|
+
import { readToolResultPage, readableToolResult, resolveReadInput, READ_PAGE_MAX_BYTES, } from './read-page.js';
|
|
43
43
|
/** Walks every typed StorageRef site reached by conversation-copy rewriting. */
|
|
44
44
|
function collectConversationCopyStorageRefs(input) {
|
|
45
45
|
const refs = [];
|
|
@@ -937,7 +937,7 @@ function cloneModelProjectionTransition(event, references, clonedRuntimeEvents,
|
|
|
937
937
|
});
|
|
938
938
|
if (rewritten.page) {
|
|
939
939
|
delete rewritten.page;
|
|
940
|
-
rewritten.page = readToolResultPage(serialized, { path: rewritten.resourceRef },
|
|
940
|
+
rewritten.page = readToolResultPage(serialized, { path: rewritten.resourceRef }, READ_PAGE_MAX_BYTES - Buffer.byteLength(JSON.stringify(rewritten)) - 32);
|
|
941
941
|
}
|
|
942
942
|
references.ledgerArchives?.set(placeholder.resourceRef ?? buildToolResultArchiveResourceRef(placeholder), rewritten);
|
|
943
943
|
}
|
|
@@ -144,24 +144,36 @@ function htmlToMarkdown(html, pageUrl) {
|
|
|
144
144
|
assertSafeHtmlNesting(html);
|
|
145
145
|
const { document } = parseHTML(html);
|
|
146
146
|
const baseHref = document.querySelector('base[href]')?.getAttribute('href');
|
|
147
|
-
let
|
|
147
|
+
let baseUrl = pageUrl;
|
|
148
148
|
if (baseHref) {
|
|
149
149
|
try {
|
|
150
|
-
|
|
150
|
+
baseUrl = new URL(baseHref, pageUrl).toString();
|
|
151
151
|
}
|
|
152
152
|
catch {
|
|
153
153
|
// Fall back to the response URL for a malformed page-authored base URL.
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
156
|
+
const documentBase = document.querySelector('base') ?? document.createElement('base');
|
|
157
|
+
documentBase.setAttribute('href', baseUrl);
|
|
158
|
+
if (!documentBase.parentNode)
|
|
159
|
+
document.head?.prepend(documentBase);
|
|
160
|
+
// Turndown renders both `<a href>` and `<img src>` as Markdown links, so each
|
|
161
|
+
// has to carry an absolute URL: a relative path stops meaning anything once
|
|
162
|
+
// the model reads the Markdown apart from the page it was extracted from.
|
|
163
|
+
for (const [selector, attribute] of [
|
|
164
|
+
['[href]', 'href'],
|
|
165
|
+
['img[src]', 'src'],
|
|
166
|
+
]) {
|
|
167
|
+
for (const element of document.querySelectorAll(selector)) {
|
|
168
|
+
const value = element.getAttribute(attribute);
|
|
169
|
+
if (!value)
|
|
170
|
+
continue;
|
|
171
|
+
try {
|
|
172
|
+
element.setAttribute(attribute, new URL(value, baseUrl).toString());
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
// Keep malformed page-authored values as-is.
|
|
176
|
+
}
|
|
165
177
|
}
|
|
166
178
|
}
|
|
167
179
|
const article = new Readability(document).parse();
|
|
@@ -152,7 +152,12 @@ export class ModelAdapter {
|
|
|
152
152
|
const providerToolName = (name) => usesOpenAiResponsesAdapter && name === TOOL_SEARCH_NAME ? TOOL_SEARCH_PROVIDER_NAME : name;
|
|
153
153
|
const runtimeToolName = (name) => usesOpenAiResponsesAdapter && name === TOOL_SEARCH_PROVIDER_NAME ? TOOL_SEARCH_NAME : name;
|
|
154
154
|
const sdkTools = lowerModelTools(input.tools);
|
|
155
|
-
|
|
155
|
+
// Prose names the alias only when the provider can call it. In Code Mode
|
|
156
|
+
// tool_search is nested inside exec under its runtime name, so the
|
|
157
|
+
// catalog prompt must keep that name.
|
|
158
|
+
const providerExposesToolSearch = usesOpenAiResponsesAdapter && sdkTools[TOOL_SEARCH_NAME] !== undefined;
|
|
159
|
+
const providerTextToolName = (name) => providerExposesToolSearch ? providerToolName(name) : name;
|
|
160
|
+
if (providerExposesToolSearch) {
|
|
156
161
|
sdkTools[TOOL_SEARCH_PROVIDER_NAME] = sdkTools[TOOL_SEARCH_NAME];
|
|
157
162
|
delete sdkTools[TOOL_SEARCH_NAME];
|
|
158
163
|
}
|
|
@@ -163,9 +168,9 @@ export class ModelAdapter {
|
|
|
163
168
|
const continuation = responsesLane
|
|
164
169
|
? planOpenAiResponsesContinuation(fullMessages, this.openAiResponsesTransportState.semanticBaseline(responsesLane))
|
|
165
170
|
: { messages: fullMessages };
|
|
166
|
-
const providerMessages = remapModelMessageToolNames(continuation.messages, providerToolName);
|
|
171
|
+
const providerMessages = remapModelMessageToolNames(continuation.messages, providerToolName, providerTextToolName);
|
|
167
172
|
const providerSystem = input.system
|
|
168
|
-
? remapProviderToolNamesInText(input.system,
|
|
173
|
+
? remapProviderToolNamesInText(input.system, providerTextToolName)
|
|
169
174
|
: undefined;
|
|
170
175
|
const providerOptions = usesNativeOpenAiResponses(this.input.connection, this.runtime)
|
|
171
176
|
? mergeOpenAiResponsesProviderOptions(this.input.providerOptions, this.input.sessionId ?? this.input.connection.slug, continuation.previousResponseId)
|
|
@@ -914,7 +919,7 @@ function lowerChatToolImages(messages) {
|
|
|
914
919
|
* OpenAI Responses reserves the provider name `tool_search`. Keep Maka's
|
|
915
920
|
* persisted/history name intact and translate only the provider-bound copy.
|
|
916
921
|
*/
|
|
917
|
-
function remapModelMessageToolNames(messages, providerToolName) {
|
|
922
|
+
function remapModelMessageToolNames(messages, providerToolName, providerTextToolName) {
|
|
918
923
|
const remapContent = (content) => content.map((part) => {
|
|
919
924
|
if ((part.type === 'tool-call' || part.type === 'tool-result') &&
|
|
920
925
|
'toolName' in part &&
|
|
@@ -925,7 +930,7 @@ function remapModelMessageToolNames(messages, providerToolName) {
|
|
|
925
930
|
typeof remapped.output.value === 'string') {
|
|
926
931
|
remapped.output = {
|
|
927
932
|
...remapped.output,
|
|
928
|
-
value: remapProviderToolNamesInText(remapped.output.value,
|
|
933
|
+
value: remapProviderToolNamesInText(remapped.output.value, providerTextToolName),
|
|
929
934
|
};
|
|
930
935
|
}
|
|
931
936
|
}
|