maka-agent 0.2.0-dev.14.20260902 → 0.2.0-dev.16.20260903
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/cli-core.js +0 -1
- package/dist/pi-transcript.js +48 -0
- package/dist/pi-tui-form-interaction.js +497 -0
- package/dist/pi-tui-pickers.js +256 -55
- package/dist/pi-tui-runner.js +215 -12
- package/dist/runtime-host-cli.js +17 -42
- package/dist/runtime-host-lifecycle-transaction.js +31 -13
- package/dist/runtime-host-managed-lifecycle-manager.js +1 -1
- package/dist/runtime-host-onboarding.js +3 -1
- package/dist/runtime-host-openrc-service.js +469 -0
- package/dist/runtime-host-run-command.js +6 -2
- package/dist/runtime-host-service-command.js +3 -3
- package/dist/runtime-host-service-management-command.js +43 -15
- package/dist/runtime-host-session-channel.js +3 -0
- package/dist/runtime-host-session-driver.js +21 -6
- package/dist/runtime-host-setup-command.js +30 -31
- package/dist/tui-context-refresh.js +103 -0
- package/dist/tui-copy-catalog.js +73 -0
- package/native/runtime-host-peer/prebuilds/darwin-arm64/maka_runtime_host_peer.node +0 -0
- package/native/runtime-host-peer/prebuilds/linux-arm64/maka_runtime_host_peer.node +0 -0
- package/native/runtime-host-peer/prebuilds/linux-x64/maka_runtime_host_peer.node +0 -0
- package/native/runtime-host-peer/prebuilds/win32-x64/maka_runtime_host_peer.node +0 -0
- package/node_modules/@maka/core/dist/chat-model-choice.js +4 -0
- package/node_modules/@maka/core/dist/computer-use.js +27 -92
- package/node_modules/@maka/core/dist/interaction.js +577 -3
- package/node_modules/@maka/core/dist/llm-connections.js +4 -0
- package/node_modules/@maka/core/dist/local-memory.js +2 -2
- package/node_modules/@maka/core/dist/model-call-usage-projection.js +3 -0
- package/node_modules/@maka/core/dist/model-metadata.js +26 -7
- package/node_modules/@maka/core/dist/model-thinking.js +17 -0
- package/node_modules/@maka/core/dist/provider-registry.js +1 -0
- package/node_modules/@maka/core/dist/runtime-event.js +23 -1
- package/node_modules/@maka/core/dist/scheduled-task.js +4 -0
- package/node_modules/@maka/core/dist/session.js +95 -2
- package/node_modules/@maka/core/dist/text-sanitize.js +19 -0
- package/node_modules/@maka/core/dist/usage-ledger-merge.js +3 -0
- package/node_modules/@maka/core/dist/usage-record-schema.js +11 -5
- package/node_modules/@maka/core/dist/workhub-creation-intent.js +75 -9
- package/node_modules/@maka/core/dist/workhub-session-resolver.js +50 -0
- package/node_modules/@maka/core/package.json +2 -0
- package/node_modules/@maka/eval/dist/harbor-external-subject.js +2 -1
- package/node_modules/@maka/eval/dist/harness-executor.js +3 -2
- package/node_modules/@maka/eval/dist/install-preflight.js +39 -10
- package/node_modules/@maka/eval/dist/process-termination.js +83 -0
- package/node_modules/@maka/mcp/dist/sep-2243.js +3 -3
- package/node_modules/@maka/runtime/dist/agent-run.js +6 -3
- package/node_modules/@maka/runtime/dist/ai-sdk-backend.js +332 -118
- package/node_modules/@maka/runtime/dist/ai-sdk-compaction-contract.js +6 -1
- package/node_modules/@maka/runtime/dist/ai-sdk-compaction.js +171 -341
- package/node_modules/@maka/runtime/dist/bots/telegram-bridge.js +3 -26
- package/node_modules/@maka/runtime/dist/bundled-skill-catalog.generated.js +1 -1
- package/node_modules/@maka/runtime/dist/computer-use-codec.js +1 -141
- package/node_modules/@maka/runtime/dist/computer-use-tools.js +23 -105
- package/node_modules/@maka/runtime/dist/context-budget-policy.js +20 -26
- package/node_modules/@maka/runtime/dist/context-budget.js +18 -20
- package/node_modules/@maka/runtime/dist/conversation-copy.js +23 -19
- package/node_modules/@maka/runtime/dist/cua-frame-state.js +1 -69
- package/node_modules/@maka/runtime/dist/github-copilot-oauth-enrollment.js +267 -0
- package/node_modules/@maka/runtime/dist/history-compact-checkpoint.js +6 -9
- package/node_modules/@maka/runtime/dist/history-compact-summarizer.js +67 -23
- package/node_modules/@maka/runtime/dist/history-compact-summary-validation.js +11 -18
- package/node_modules/@maka/runtime/dist/history-compaction.js +66 -73
- package/node_modules/@maka/runtime/dist/interaction-authority.js +69 -0
- package/node_modules/@maka/runtime/dist/mcp-tools.js +13 -1
- package/node_modules/@maka/runtime/dist/memory-extraction.js +11 -11
- package/node_modules/@maka/runtime/dist/model-adapter.js +24 -6
- package/node_modules/@maka/runtime/dist/model-factory.js +14 -5
- package/node_modules/@maka/runtime/dist/oauth-provider-contracts.js +28 -1
- package/node_modules/@maka/runtime/dist/openai-codex-history-compactor.js +7 -6
- package/node_modules/@maka/runtime/dist/opencode-session-header.js +29 -0
- package/node_modules/@maka/runtime/dist/runtime-event-read-model.js +11 -1
- package/node_modules/@maka/runtime/dist/runtime-kernel.js +12 -11
- package/node_modules/@maka/runtime/dist/runtime-read-model.js +51 -13
- package/node_modules/@maka/runtime/dist/scheduled-task-tools.js +3 -0
- package/node_modules/@maka/runtime/dist/session-event-runtime-mapper.js +26 -0
- package/node_modules/@maka/runtime/dist/session-manager.js +1 -0
- package/node_modules/@maka/runtime/dist/session-projection-helpers.js +16 -1
- package/node_modules/@maka/runtime/dist/stream-graph-projection.js +6 -0
- package/node_modules/@maka/runtime/dist/stream-graph-read-model.js +5 -0
- package/node_modules/@maka/runtime/dist/stream-usage-fallback-fetch.js +74 -0
- package/node_modules/@maka/runtime/dist/subscription-credentials.js +51 -4
- package/node_modules/@maka/runtime/dist/subscription-model-fetch.js +47 -3
- package/node_modules/@maka/runtime/dist/system-prompt/main-session-prompt.js +20 -1
- package/node_modules/@maka/runtime/dist/test-connection.js +18 -11
- package/node_modules/@maka/runtime/dist/tool-runtime.js +183 -0
- package/node_modules/@maka/runtime/package.json +1 -0
- package/node_modules/@maka/runtime-host/dist/adapter/session-projector.js +14 -0
- package/node_modules/@maka/runtime-host/dist/client/client-capability-channel.js +84 -1
- package/node_modules/@maka/runtime-host/dist/client/host-profile.js +68 -51
- package/node_modules/@maka/runtime-host/dist/client/index.js +1 -1
- package/node_modules/@maka/runtime-host/dist/client/owner-connection-code.js +8 -5
- package/node_modules/@maka/runtime-host/dist/client/peer-client.js +342 -36
- package/node_modules/@maka/runtime-host/dist/client/reconnect-lifecycle.js +60 -4
- package/node_modules/@maka/runtime-host/dist/peer-mesh/index.js +3 -3
- package/node_modules/@maka/runtime-host/dist/peer-mesh/limits.js +1 -1
- package/node_modules/@maka/runtime-host/dist/peer-mesh/model.js +48 -60
- package/node_modules/@maka/runtime-host/dist/peer-mesh/node.js +847 -431
- package/node_modules/@maka/runtime-host/dist/peer-mesh/owner.js +33 -74
- package/node_modules/@maka/runtime-host/dist/peer-mesh/store.js +82 -69
- package/node_modules/@maka/runtime-host/dist/peer-reachability/index.js +21 -0
- package/node_modules/@maka/runtime-host/dist/peer-reachability/model.js +202 -0
- package/node_modules/@maka/runtime-host/dist/peer-reachability/owner.js +119 -0
- package/node_modules/@maka/runtime-host/dist/peer-reachability/publisher.js +245 -0
- package/node_modules/@maka/runtime-host/dist/protocol/agent-graph.js +4 -1
- package/node_modules/@maka/runtime-host/dist/protocol/client-capability.js +68 -0
- package/node_modules/@maka/runtime-host/dist/protocol/connection-effects.js +15 -8
- package/node_modules/@maka/runtime-host/dist/protocol/host-status.js +7 -23
- package/node_modules/@maka/runtime-host/dist/protocol/index.js +47 -1
- package/node_modules/@maka/runtime-host/dist/protocol/oauth.js +25 -1
- package/node_modules/@maka/runtime-host/dist/protocol/operations.js +1 -0
- package/node_modules/@maka/runtime-host/dist/protocol/peer-mesh.js +14 -31
- package/node_modules/@maka/runtime-host/dist/protocol/scheduled-task.js +19 -6
- package/node_modules/@maka/runtime-host/dist/protocol/session-collaboration.js +36 -1
- package/node_modules/@maka/runtime-host/dist/protocol/session-revision.js +11 -2
- package/node_modules/@maka/runtime-host/dist/protocol/usage-pricing.js +16 -2
- package/node_modules/@maka/runtime-host/dist/protocol/workhub-coordination.js +51 -2
- package/node_modules/@maka/runtime-host/dist/server/access-authority.js +35 -2
- package/node_modules/@maka/runtime-host/dist/server/access-credential-store.js +1 -0
- package/node_modules/@maka/runtime-host/dist/server/client-capability-coordinator.js +12 -10
- package/node_modules/@maka/runtime-host/dist/server/client-capability-invocation-broker.js +163 -30
- package/node_modules/@maka/runtime-host/dist/server/connection-effect-coordinator.js +38 -14
- package/node_modules/@maka/runtime-host/dist/server/daily-review-coordinator.js +45 -22
- package/node_modules/@maka/runtime-host/dist/server/execution-composition.js +78 -20
- package/node_modules/@maka/runtime-host/dist/server/execution-model-authority.js +4 -2
- package/node_modules/@maka/runtime-host/dist/server/execution-model-composition.js +2 -1
- package/node_modules/@maka/runtime-host/dist/server/execution-service.js +49 -28
- package/node_modules/@maka/runtime-host/dist/server/host-kernel.js +3 -6
- package/node_modules/@maka/runtime-host/dist/server/interaction-coordinator.js +130 -27
- package/node_modules/@maka/runtime-host/dist/server/interaction-projection.js +30 -1
- package/node_modules/@maka/runtime-host/dist/server/listener-set.js +2 -4
- package/node_modules/@maka/runtime-host/dist/server/message-coordinator.js +16 -3
- package/node_modules/@maka/runtime-host/dist/server/oauth-coordinator.js +66 -3
- package/node_modules/@maka/runtime-host/dist/server/oauth-execution-authority.js +20 -3
- package/node_modules/@maka/runtime-host/dist/server/peer-listener.js +8 -21
- package/node_modules/@maka/runtime-host/dist/server/peer-mesh-authority.js +1 -1
- package/node_modules/@maka/runtime-host/dist/server/root-turn-coordinator.js +6 -3
- package/node_modules/@maka/runtime-host/dist/server/scheduled-task-coordinator.js +72 -12
- package/node_modules/@maka/runtime-host/dist/server/session-revision-coordinator.js +48 -18
- package/node_modules/@maka/runtime-host/dist/server/session-turn-access-request-coordinator.js +43 -26
- package/node_modules/@maka/runtime-host/dist/server/usage-pricing-coordinator.js +15 -1
- package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-action-gate.js +229 -4
- package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-coordinator.js +146 -8
- package/node_modules/@maka/runtime-host/dist/transport/peer-native.js +32 -6
- package/node_modules/@maka/runtime-host/package.json +1 -0
- package/node_modules/@maka/storage/dist/agent-run-store.js +18 -5
- package/node_modules/@maka/storage/dist/codex-session-adapter.js +14 -0
- package/node_modules/@maka/storage/dist/execution-stores.js +5 -0
- package/node_modules/@maka/storage/dist/interaction-store.js +13 -1
- package/node_modules/@maka/storage/dist/runtime-policy/connection-catalog-document.js +9 -3
- package/node_modules/@maka/storage/dist/runtime-policy/coordinator.js +49 -19
- package/node_modules/@maka/storage/dist/runtime-policy/oauth-login-receipt-document.js +3 -1
- package/node_modules/@maka/storage/dist/runtime-policy/onboarding-transaction.js +13 -5
- package/node_modules/@maka/storage/dist/session-copy-cleanup.js +4 -2
- package/node_modules/@maka/storage/dist/session-store.js +39 -6
- package/node_modules/@maka/storage/dist/sqlite-runtime-store.js +16 -9
- package/node_modules/@maka/storage/dist/sqlite-session-metadata-schema.js +30 -3
- package/node_modules/@maka/storage/dist/sqlite-session-metadata-store.js +117 -0
- package/node_modules/@maka/storage/dist/sqlite-usage-store.js +29 -6
- package/node_modules/@maka/storage/dist/usage-stores.js +3 -1
- package/package.json +1 -1
package/dist/pi-tui-runner.js
CHANGED
|
@@ -20,6 +20,7 @@ import { randomUUID } from 'node:crypto';
|
|
|
20
20
|
import { basename } from 'node:path';
|
|
21
21
|
import { Key, ProcessTerminal, SelectList, TuiMainScreen, isKeyRelease, isKeyRepeat, matchesKey, } from '@earendil-works/pi-tui';
|
|
22
22
|
import { isThinkingLevel } from '@maka/core/model-thinking';
|
|
23
|
+
import { deriveConnectionSlug, } from '@maka/core/llm-connections';
|
|
23
24
|
import { projectRevisionLinkedSessionTree } from '@maka/core/session-revisions';
|
|
24
25
|
import { slashCommandsForSurface, } from '@maka/core/slash-command-catalog';
|
|
25
26
|
import { latestAssistantModelId, } from '@maka/core/session';
|
|
@@ -32,7 +33,8 @@ import { parseGraphCommand } from '@maka/core/graph-command';
|
|
|
32
33
|
import { parseSwarmCommand } from '@maka/core/swarm-command';
|
|
33
34
|
import { inspectSessionResumeAvailability, } from './session-driver.js';
|
|
34
35
|
import { SafeBoundaryResumeParkedError } from './runtime-host-session-driver.js';
|
|
35
|
-
import { appendExpansionCollapseConfirmation, appendTurnFailureToTranscript, appendUserCommandToTranscript, appendUserPrompt, applyMakaSessionEventToTranscript, applyShellRunUpdateToTranscript, createMakaPiTranscriptState, hasRunningUserCommand, activeSandboxBoundaryRequest, activeUserQuestionRequest, applyExpansionDefaultToAll, completePendingInteraction, applyShellRunViewUpdateToTranscript, EXPANSION_COLLAPSE_CONFIRM_WINDOW_MS, hasExpandedEntriesAboveViewport, permissionModeLabel, retireCancelledTransientMessages, replaceTranscriptWithStoredMessages, hydrateToolsWithStoredMessages, submitCompactToTranscript, toggleAllThinkingExpansion, toggleAllToolExpansion, } from './pi-transcript.js';
|
|
36
|
+
import { appendExpansionCollapseConfirmation, appendTurnFailureToTranscript, appendUserCommandToTranscript, appendUserPrompt, applyMakaSessionEventToTranscript, applyShellRunUpdateToTranscript, createMakaPiTranscriptState, hasRunningUserCommand, activeSandboxBoundaryRequest, activeFormRequest, activeUserQuestionRequest, applyExpansionDefaultToAll, completePendingInteraction, applyShellRunViewUpdateToTranscript, EXPANSION_COLLAPSE_CONFIRM_WINDOW_MS, hasExpandedEntriesAboveViewport, permissionModeLabel, retireCancelledTransientMessages, replaceTranscriptWithStoredMessages, hydrateToolsWithStoredMessages, submitCompactToTranscript, toggleAllThinkingExpansion, toggleAllToolExpansion, } from './pi-transcript.js';
|
|
37
|
+
import { FormInteractionOverlay } from './pi-tui-form-interaction.js';
|
|
36
38
|
import { runMakaPiTuiTurn } from './pi-tui-turn.js';
|
|
37
39
|
import { editorTheme, selectListTheme } from './tui-ansi.js';
|
|
38
40
|
import { MakaAutocompleteAboveEditorComponent } from './tui-autocomplete-layout.js';
|
|
@@ -42,6 +44,7 @@ import { getTuiCopyCopy, lastAssistantText, serializeTranscriptText } from './tu
|
|
|
42
44
|
import { McpManagementOverlay } from './pi-tui-mcp-status.js';
|
|
43
45
|
import { createShellRunElapsedTicker } from './shell-run-elapsed-ticker.js';
|
|
44
46
|
import { createShellRunHydrationController } from './shell-run-hydration.js';
|
|
47
|
+
import { CTX_REFRESH_DEBOUNCE_MS, createCtxRefresher, scheduleCtxRefreshTimeout, } from './tui-context-refresh.js';
|
|
45
48
|
import { sessionStatusBadge } from './tui-session-status.js';
|
|
46
49
|
import { AttentionController, DISABLE_FOCUS_REPORTING, ENABLE_FOCUS_REPORTING, FOCUS_IN_SEQUENCE, FOCUS_OUT_SEQUENCE, } from './tui-attention.js';
|
|
47
50
|
import { MakaActivityStripComponent, MakaPendingQueueComponent, MakaPiLayoutComponent, MakaStatusLineComponent, MakaTranscriptComponent, } from './pi-tui-layout.js';
|
|
@@ -184,6 +187,13 @@ export async function runMakaPiTui(input) {
|
|
|
184
187
|
let userQuestionInFlight = false;
|
|
185
188
|
let userQuestionOverlay;
|
|
186
189
|
let userQuestionProgress;
|
|
190
|
+
let formResponseInFlightRequestId;
|
|
191
|
+
let formOverlay;
|
|
192
|
+
let formOverlayComponent;
|
|
193
|
+
let formOverlayRequestId;
|
|
194
|
+
let formOverlaySessionId;
|
|
195
|
+
let formOverlaySchema;
|
|
196
|
+
let retainedFormDraft;
|
|
187
197
|
let turnRunning = false;
|
|
188
198
|
// Monotonic generation for visible agent turns. A mid-turn `/session`
|
|
189
199
|
// switch-away (#3380) bumps it to orphan the in-flight drain: every callback
|
|
@@ -369,7 +379,7 @@ export async function runMakaPiTui(input) {
|
|
|
369
379
|
return;
|
|
370
380
|
}
|
|
371
381
|
permissionResponseInFlightRequestId = null;
|
|
372
|
-
|
|
382
|
+
syncInteractionOverlays();
|
|
373
383
|
requestRender();
|
|
374
384
|
}) ?? (() => { });
|
|
375
385
|
const unsubscribeTranscriptReplacements = input.driver.subscribeTranscriptReplacements?.((sessionId, turnId, messages, reason) => {
|
|
@@ -377,6 +387,7 @@ export async function runMakaPiTui(input) {
|
|
|
377
387
|
return;
|
|
378
388
|
if (reason === 'reconnect') {
|
|
379
389
|
replaceTranscript(messages, { preserveClientLocalEntries: true });
|
|
390
|
+
syncInteractionOverlays();
|
|
380
391
|
shellRunElapsedTicker.sync();
|
|
381
392
|
requestRender();
|
|
382
393
|
const messageIds = state.entries.flatMap((entry) => entry.kind === 'user' && entry.transient === true ? [entry.messageId] : []);
|
|
@@ -405,6 +416,40 @@ export async function runMakaPiTui(input) {
|
|
|
405
416
|
now: input.shellRunTicker?.now,
|
|
406
417
|
schedule: input.shellRunTicker?.schedule,
|
|
407
418
|
});
|
|
419
|
+
// Live ctx refresh (#4545): the end-of-turn token_usage event moves the
|
|
420
|
+
// statusline once per turn, but the Host's latest-context snapshot moves at
|
|
421
|
+
// every settled provider request. Pull it on the desktop inspector's signal
|
|
422
|
+
// (tui-context-refresh.ts) so a long turn shows the context filling as it
|
|
423
|
+
// fills. The query is a plain read on the driver — deliberately not routed
|
|
424
|
+
// through runControl, whose serial lock exists for mutations.
|
|
425
|
+
const getContextDiagnostics = input.driver.getContextDiagnostics?.bind(input.driver);
|
|
426
|
+
const ctxRefresher = getContextDiagnostics
|
|
427
|
+
? createCtxRefresher({
|
|
428
|
+
query: async () => {
|
|
429
|
+
const sessionId = input.driver.getSessionId();
|
|
430
|
+
const diagnostics = await getContextDiagnostics();
|
|
431
|
+
return { sessionId, diagnostics };
|
|
432
|
+
},
|
|
433
|
+
apply: ({ sessionId, diagnostics }) => {
|
|
434
|
+
// The session moved under the query (switch, /new): its usage was
|
|
435
|
+
// rebuilt from stored messages, and a pre-switch snapshot must not
|
|
436
|
+
// overwrite it.
|
|
437
|
+
if (closed || input.driver.getSessionId() !== sessionId)
|
|
438
|
+
return;
|
|
439
|
+
if (diagnostics.status !== 'available')
|
|
440
|
+
return;
|
|
441
|
+
const { inputTokens, contextWindow } = diagnostics;
|
|
442
|
+
if (inputTokens === undefined || contextWindow === undefined || contextWindow <= 0)
|
|
443
|
+
return;
|
|
444
|
+
// Same formula the token_usage path uses (#1067), from the same
|
|
445
|
+
// settled request — the two cannot disagree.
|
|
446
|
+
state.usage.contextRemaining = Math.max(0, contextWindow - inputTokens);
|
|
447
|
+
requestRender();
|
|
448
|
+
},
|
|
449
|
+
delayMs: input.ctxRefreshTicker?.delayMs ?? CTX_REFRESH_DEBOUNCE_MS,
|
|
450
|
+
schedule: input.ctxRefreshTicker?.schedule ?? scheduleCtxRefreshTimeout,
|
|
451
|
+
})
|
|
452
|
+
: undefined;
|
|
408
453
|
// ── Explicit skill invocation (#1148) ────────────────────────────────────
|
|
409
454
|
// One cached list feeds autocomplete, the `/skill` picker, and the editor's
|
|
410
455
|
// sync highlight validator. The cache is keyed by cwd (project-level skill
|
|
@@ -568,6 +613,7 @@ export async function runMakaPiTui(input) {
|
|
|
568
613
|
unsubscribeTranscriptReplacements();
|
|
569
614
|
shellRunHydration.dispose();
|
|
570
615
|
shellRunElapsedTicker.dispose();
|
|
616
|
+
ctxRefresher?.cancel();
|
|
571
617
|
stopTurnElapsedTicker();
|
|
572
618
|
setTaskbarProgress(false);
|
|
573
619
|
// Drop the busy / attention title marker so the tab is not handed back to
|
|
@@ -859,6 +905,10 @@ export async function runMakaPiTui(input) {
|
|
|
859
905
|
// The existing connection the picked provider resolved to, so saving edits
|
|
860
906
|
// it in place (a Desktop-created relay may live under a custom slug).
|
|
861
907
|
let wizardTarget;
|
|
908
|
+
// The identity step's answer for a create target. Null halves keep the wire
|
|
909
|
+
// target bare so any Host vintage accepts it; an edited slug/name rides on
|
|
910
|
+
// the target and gets `slug_taken` back when it loses.
|
|
911
|
+
let wizardIdentity = { slug: null, name: null };
|
|
862
912
|
let wizardModels = [];
|
|
863
913
|
// Authoritative ready model choices for `/model`. A startup snapshot refreshed
|
|
864
914
|
// in place after `/setup` saves so newly configured models are immediately
|
|
@@ -1043,6 +1093,7 @@ export async function runMakaPiTui(input) {
|
|
|
1043
1093
|
replaceTranscript(authoritativeAttachedTurn.messages, {
|
|
1044
1094
|
preserveClientLocalEntries: true,
|
|
1045
1095
|
});
|
|
1096
|
+
syncInteractionOverlays();
|
|
1046
1097
|
shellRunHydration.reset();
|
|
1047
1098
|
if (input.listShellRunUpdates) {
|
|
1048
1099
|
await shellRunHydration.hydrate(authoritativeAttachedTurn.sessionId);
|
|
@@ -1067,11 +1118,14 @@ export async function runMakaPiTui(input) {
|
|
|
1067
1118
|
// not reach the adopted Session's transcript or overlays.
|
|
1068
1119
|
if (superseded())
|
|
1069
1120
|
return;
|
|
1070
|
-
if ((event.type === 'sandbox_boundary_request' ||
|
|
1121
|
+
if ((event.type === 'sandbox_boundary_request' ||
|
|
1122
|
+
event.type === 'user_question_request' ||
|
|
1123
|
+
event.type === 'form_request') &&
|
|
1071
1124
|
resolvedInteractionIds.delete(event.requestId)) {
|
|
1072
1125
|
return;
|
|
1073
1126
|
}
|
|
1074
1127
|
applyMakaSessionEventToTranscript(state, event);
|
|
1128
|
+
ctxRefresher?.observe(event);
|
|
1075
1129
|
if (event.type === 'error')
|
|
1076
1130
|
attention.attentionNeeded();
|
|
1077
1131
|
if (permissionResponseInFlightRequestId !== null &&
|
|
@@ -1091,7 +1145,7 @@ export async function runMakaPiTui(input) {
|
|
|
1091
1145
|
permissionAlerted = false;
|
|
1092
1146
|
}
|
|
1093
1147
|
shellRunElapsedTicker.sync();
|
|
1094
|
-
|
|
1148
|
+
syncInteractionOverlays();
|
|
1095
1149
|
requestRender();
|
|
1096
1150
|
},
|
|
1097
1151
|
// A turn failing is worth pulling the user back, regardless of how long it
|
|
@@ -1106,7 +1160,7 @@ export async function runMakaPiTui(input) {
|
|
|
1106
1160
|
appendTurnFailureToTranscript(state, error);
|
|
1107
1161
|
attention.attentionNeeded();
|
|
1108
1162
|
shellRunElapsedTicker.sync();
|
|
1109
|
-
|
|
1163
|
+
syncInteractionOverlays();
|
|
1110
1164
|
requestRender();
|
|
1111
1165
|
},
|
|
1112
1166
|
}).then(async (outcome) => {
|
|
@@ -1246,6 +1300,7 @@ export async function runMakaPiTui(input) {
|
|
|
1246
1300
|
const applySwitchResult = async ({ summary, messages, activeTurn, }) => {
|
|
1247
1301
|
adoptSessionMetadata(summary, false);
|
|
1248
1302
|
replaceTranscript(messages);
|
|
1303
|
+
syncInteractionOverlays();
|
|
1249
1304
|
if (connectionIdentityNotice) {
|
|
1250
1305
|
state.entries.push({ kind: 'notice', level: 'error', text: connectionIdentityNotice });
|
|
1251
1306
|
}
|
|
@@ -1606,7 +1661,10 @@ export async function runMakaPiTui(input) {
|
|
|
1606
1661
|
const showBottomPicker = (picker) => tui.showOverlay(picker, {
|
|
1607
1662
|
anchor: 'bottom-left',
|
|
1608
1663
|
width: '100%',
|
|
1609
|
-
|
|
1664
|
+
// A numeric cap would freeze today's rows into the option; '100%' is
|
|
1665
|
+
// re-resolved against the live terminal height on every composite, so
|
|
1666
|
+
// after a resize the cap still lands at rows - margin (#4610 review).
|
|
1667
|
+
maxHeight: '100%',
|
|
1610
1668
|
margin: { bottom: BOTTOM_PICKER_MARGIN_ROWS },
|
|
1611
1669
|
});
|
|
1612
1670
|
const closeUserQuestionOverlay = () => {
|
|
@@ -1631,13 +1689,13 @@ export async function runMakaPiTui(input) {
|
|
|
1631
1689
|
completePendingInteraction(state, requestId);
|
|
1632
1690
|
}
|
|
1633
1691
|
userQuestionProgress = undefined;
|
|
1634
|
-
|
|
1692
|
+
syncInteractionOverlays();
|
|
1635
1693
|
requestRender();
|
|
1636
1694
|
})
|
|
1637
1695
|
.catch((error) => {
|
|
1638
1696
|
userQuestionInFlight = false;
|
|
1639
1697
|
reportError(error);
|
|
1640
|
-
|
|
1698
|
+
syncInteractionOverlays();
|
|
1641
1699
|
});
|
|
1642
1700
|
};
|
|
1643
1701
|
const showUserQuestion = () => {
|
|
@@ -1662,6 +1720,9 @@ export async function runMakaPiTui(input) {
|
|
|
1662
1720
|
hint: '↑↓ move · type to answer · Enter select · Esc unanswered · Ctrl+C stop',
|
|
1663
1721
|
placeholder: 'Other: type your answer…',
|
|
1664
1722
|
options: question.options,
|
|
1723
|
+
// Live budget: terminal.rows changes on resize, so read it per render
|
|
1724
|
+
// rather than at overlay construction.
|
|
1725
|
+
maxRows: () => Math.max(1, terminal.rows - BOTTOM_PICKER_MARGIN_ROWS),
|
|
1665
1726
|
onSelectOption: (index) => advance(question.options[index]?.label ?? null),
|
|
1666
1727
|
onSubmitText: (value) => advance(value),
|
|
1667
1728
|
onSkip: () => advance(null),
|
|
@@ -1685,6 +1746,120 @@ export async function runMakaPiTui(input) {
|
|
|
1685
1746
|
showUserQuestion();
|
|
1686
1747
|
}
|
|
1687
1748
|
};
|
|
1749
|
+
const closeFormOverlay = (retainDraft = true) => {
|
|
1750
|
+
if (retainDraft &&
|
|
1751
|
+
formOverlayComponent &&
|
|
1752
|
+
formOverlaySessionId &&
|
|
1753
|
+
formOverlayRequestId &&
|
|
1754
|
+
formOverlaySchema) {
|
|
1755
|
+
retainedFormDraft = {
|
|
1756
|
+
sessionId: formOverlaySessionId,
|
|
1757
|
+
requestId: formOverlayRequestId,
|
|
1758
|
+
schema: formOverlaySchema,
|
|
1759
|
+
drafts: formOverlayComponent.snapshotDrafts(),
|
|
1760
|
+
};
|
|
1761
|
+
}
|
|
1762
|
+
formOverlay?.hide();
|
|
1763
|
+
formOverlay = undefined;
|
|
1764
|
+
formOverlayComponent = undefined;
|
|
1765
|
+
formOverlayRequestId = undefined;
|
|
1766
|
+
formOverlaySessionId = undefined;
|
|
1767
|
+
formOverlaySchema = undefined;
|
|
1768
|
+
};
|
|
1769
|
+
const finishUserForm = (response) => {
|
|
1770
|
+
if (formResponseInFlightRequestId)
|
|
1771
|
+
return;
|
|
1772
|
+
const respond = input.driver.respondToUserForm;
|
|
1773
|
+
if (!respond) {
|
|
1774
|
+
formOverlayComponent?.setSubmissionFailed();
|
|
1775
|
+
reportError(new Error('User forms are unavailable on this driver.'));
|
|
1776
|
+
return;
|
|
1777
|
+
}
|
|
1778
|
+
const responseSessionId = formOverlaySessionId ?? input.driver.getSessionId();
|
|
1779
|
+
formResponseInFlightRequestId = response.requestId;
|
|
1780
|
+
void respond
|
|
1781
|
+
.call(input.driver, response)
|
|
1782
|
+
.then(() => {
|
|
1783
|
+
if (formResponseInFlightRequestId === response.requestId) {
|
|
1784
|
+
formResponseInFlightRequestId = undefined;
|
|
1785
|
+
}
|
|
1786
|
+
if (input.driver.getSessionId() === responseSessionId &&
|
|
1787
|
+
activeFormRequest(state)?.requestId === response.requestId) {
|
|
1788
|
+
completePendingInteraction(state, response.requestId);
|
|
1789
|
+
}
|
|
1790
|
+
if (retainedFormDraft?.sessionId === responseSessionId &&
|
|
1791
|
+
retainedFormDraft.requestId === response.requestId) {
|
|
1792
|
+
retainedFormDraft = undefined;
|
|
1793
|
+
}
|
|
1794
|
+
if (formOverlaySessionId === responseSessionId &&
|
|
1795
|
+
formOverlayRequestId === response.requestId) {
|
|
1796
|
+
closeFormOverlay(false);
|
|
1797
|
+
}
|
|
1798
|
+
syncInteractionOverlays();
|
|
1799
|
+
requestRender();
|
|
1800
|
+
})
|
|
1801
|
+
.catch((error) => {
|
|
1802
|
+
if (formResponseInFlightRequestId === response.requestId) {
|
|
1803
|
+
formResponseInFlightRequestId = undefined;
|
|
1804
|
+
}
|
|
1805
|
+
if (activeFormRequest(state)?.requestId === response.requestId &&
|
|
1806
|
+
formOverlaySessionId === responseSessionId &&
|
|
1807
|
+
formOverlayRequestId === response.requestId) {
|
|
1808
|
+
formOverlayComponent?.setSubmissionFailed();
|
|
1809
|
+
}
|
|
1810
|
+
else {
|
|
1811
|
+
closeFormOverlay();
|
|
1812
|
+
syncInteractionOverlays();
|
|
1813
|
+
}
|
|
1814
|
+
reportError(error);
|
|
1815
|
+
requestRender();
|
|
1816
|
+
});
|
|
1817
|
+
};
|
|
1818
|
+
const syncFormOverlay = () => {
|
|
1819
|
+
const request = activeFormRequest(state);
|
|
1820
|
+
if (!request) {
|
|
1821
|
+
closeFormOverlay();
|
|
1822
|
+
return;
|
|
1823
|
+
}
|
|
1824
|
+
const sessionId = input.driver.getSessionId();
|
|
1825
|
+
if (!sessionId) {
|
|
1826
|
+
closeFormOverlay();
|
|
1827
|
+
return;
|
|
1828
|
+
}
|
|
1829
|
+
if (retainedFormDraft?.sessionId === sessionId &&
|
|
1830
|
+
retainedFormDraft.requestId !== request.requestId) {
|
|
1831
|
+
retainedFormDraft = undefined;
|
|
1832
|
+
}
|
|
1833
|
+
if (formOverlaySessionId !== sessionId || formOverlayRequestId !== request.requestId)
|
|
1834
|
+
closeFormOverlay();
|
|
1835
|
+
if (formResponseInFlightRequestId || formOverlayComponent)
|
|
1836
|
+
return;
|
|
1837
|
+
const schema = JSON.stringify(request.fields);
|
|
1838
|
+
const restoredDrafts = retainedFormDraft?.sessionId === sessionId &&
|
|
1839
|
+
retainedFormDraft.requestId === request.requestId &&
|
|
1840
|
+
retainedFormDraft.schema === schema
|
|
1841
|
+
? retainedFormDraft.drafts
|
|
1842
|
+
: undefined;
|
|
1843
|
+
if (retainedFormDraft?.sessionId === sessionId &&
|
|
1844
|
+
retainedFormDraft.requestId === request.requestId &&
|
|
1845
|
+
retainedFormDraft.schema !== schema) {
|
|
1846
|
+
retainedFormDraft = undefined;
|
|
1847
|
+
}
|
|
1848
|
+
formOverlayComponent = new FormInteractionOverlay(tui, {
|
|
1849
|
+
locale,
|
|
1850
|
+
request,
|
|
1851
|
+
initialDrafts: restoredDrafts,
|
|
1852
|
+
onRespond: finishUserForm,
|
|
1853
|
+
});
|
|
1854
|
+
formOverlaySessionId = sessionId;
|
|
1855
|
+
formOverlaySchema = schema;
|
|
1856
|
+
formOverlayRequestId = request.requestId;
|
|
1857
|
+
formOverlay = showBottomPicker(formOverlayComponent);
|
|
1858
|
+
};
|
|
1859
|
+
const syncInteractionOverlays = () => {
|
|
1860
|
+
syncUserQuestionOverlay();
|
|
1861
|
+
syncFormOverlay();
|
|
1862
|
+
};
|
|
1688
1863
|
const showSelectPicker = (title, rightLabel, items, onSelect, options) => {
|
|
1689
1864
|
const list = new SelectList(items, 10, selectListTheme(), {
|
|
1690
1865
|
minPrimaryColumnWidth: options.minPrimaryColumnWidth,
|
|
@@ -1717,6 +1892,7 @@ export async function runMakaPiTui(input) {
|
|
|
1717
1892
|
wizardApiKey = '';
|
|
1718
1893
|
wizardBaseUrl = '';
|
|
1719
1894
|
wizardTarget = undefined;
|
|
1895
|
+
wizardIdentity = { slug: null, name: null };
|
|
1720
1896
|
wizardModels = [];
|
|
1721
1897
|
};
|
|
1722
1898
|
// Key submit from the wizard. Slash commands route as commands (so /exit
|
|
@@ -1745,7 +1921,13 @@ export async function runMakaPiTui(input) {
|
|
|
1745
1921
|
if (closed || wizard !== targetWizard || attempt !== wizardAttempt)
|
|
1746
1922
|
return;
|
|
1747
1923
|
if (result.kind !== 'ok') {
|
|
1748
|
-
|
|
1924
|
+
// A rejected slug is the identity step's to fix, not the key's.
|
|
1925
|
+
if (result.kind === 'rejected' && result.reason === 'slug_taken') {
|
|
1926
|
+
wizard.setIdentityError(onboardingFailureMessage(result, locale));
|
|
1927
|
+
}
|
|
1928
|
+
else {
|
|
1929
|
+
wizard.setKeyError(onboardingFailureMessage(result, locale));
|
|
1930
|
+
}
|
|
1749
1931
|
requestRender();
|
|
1750
1932
|
return;
|
|
1751
1933
|
}
|
|
@@ -1787,7 +1969,12 @@ export async function runMakaPiTui(input) {
|
|
|
1787
1969
|
if (result.kind !== 'ok') {
|
|
1788
1970
|
if (closed || wizard !== targetWizard || attempt !== wizardAttempt)
|
|
1789
1971
|
return;
|
|
1790
|
-
|
|
1972
|
+
if (result.kind === 'rejected' && result.reason === 'slug_taken') {
|
|
1973
|
+
wizard.setIdentityError(onboardingFailureMessage(result, locale));
|
|
1974
|
+
}
|
|
1975
|
+
else {
|
|
1976
|
+
wizard.setModelError(onboardingFailureMessage(result, locale));
|
|
1977
|
+
}
|
|
1791
1978
|
requestRender();
|
|
1792
1979
|
return;
|
|
1793
1980
|
}
|
|
@@ -1845,6 +2032,7 @@ export async function runMakaPiTui(input) {
|
|
|
1845
2032
|
...provider,
|
|
1846
2033
|
target: { kind: 'create', providerType: provider.providerType },
|
|
1847
2034
|
label: provider.label,
|
|
2035
|
+
suggestedSlug: deriveConnectionSlug(provider.providerType),
|
|
1848
2036
|
enabledModelIds: [],
|
|
1849
2037
|
}));
|
|
1850
2038
|
}
|
|
@@ -1866,12 +2054,25 @@ export async function runMakaPiTui(input) {
|
|
|
1866
2054
|
// reselects the same catalog row. A late save may converge only the
|
|
1867
2055
|
// exact target object captured by its own submit.
|
|
1868
2056
|
wizardTarget = { ...provider.target };
|
|
2057
|
+
wizardIdentity = { slug: null, name: null };
|
|
1869
2058
|
wizardApiKey = '';
|
|
1870
2059
|
wizardBaseUrl = '';
|
|
1871
2060
|
wizardModels = [];
|
|
1872
2061
|
wizardAttempt += 1; // a new pick supersedes any in-flight attempt
|
|
1873
2062
|
requestRender();
|
|
1874
2063
|
},
|
|
2064
|
+
onSubmitIdentity: (identity) => {
|
|
2065
|
+
wizardIdentity = identity;
|
|
2066
|
+
if (wizardTarget?.kind === 'create') {
|
|
2067
|
+
wizardTarget = {
|
|
2068
|
+
kind: 'create',
|
|
2069
|
+
providerType: wizardTarget.providerType,
|
|
2070
|
+
...(identity.slug === null ? {} : { slug: identity.slug }),
|
|
2071
|
+
...(identity.name === null ? {} : { name: identity.name }),
|
|
2072
|
+
};
|
|
2073
|
+
}
|
|
2074
|
+
requestRender();
|
|
2075
|
+
},
|
|
1875
2076
|
onSubmitBaseUrl: (baseUrl) => {
|
|
1876
2077
|
wizardBaseUrl = baseUrl;
|
|
1877
2078
|
requestRender();
|
|
@@ -2038,8 +2239,9 @@ export async function runMakaPiTui(input) {
|
|
|
2038
2239
|
try {
|
|
2039
2240
|
for await (const event of input.driver.resumeLatest()) {
|
|
2040
2241
|
applyMakaSessionEventToTranscript(state, event);
|
|
2242
|
+
ctxRefresher?.observe(event);
|
|
2041
2243
|
shellRunElapsedTicker.sync();
|
|
2042
|
-
|
|
2244
|
+
syncInteractionOverlays();
|
|
2043
2245
|
requestRender();
|
|
2044
2246
|
}
|
|
2045
2247
|
}
|
|
@@ -2240,6 +2442,7 @@ export async function runMakaPiTui(input) {
|
|
|
2240
2442
|
// session, send a prompt to begin" cue. A notice here would make entries
|
|
2241
2443
|
// non-empty and suppress it.
|
|
2242
2444
|
replaceTranscript([]);
|
|
2445
|
+
syncInteractionOverlays();
|
|
2243
2446
|
shellRunElapsedTicker.sync();
|
|
2244
2447
|
await discardCurrentSidePair();
|
|
2245
2448
|
requestRender();
|
|
@@ -3277,7 +3480,7 @@ export async function runMakaPiTui(input) {
|
|
|
3277
3480
|
void runControl(closeSideConversation);
|
|
3278
3481
|
return { consume: true };
|
|
3279
3482
|
}
|
|
3280
|
-
if (activeUserQuestionRequest(state) &&
|
|
3483
|
+
if ((activeUserQuestionRequest(state) || activeFormRequest(state)) &&
|
|
3281
3484
|
turnRunning &&
|
|
3282
3485
|
matchesKey(data, Key.ctrl('c')) &&
|
|
3283
3486
|
!isKeyRepeat(data)) {
|
package/dist/runtime-host-cli.js
CHANGED
|
@@ -1347,11 +1347,8 @@ function parseProfileCommand(argv) {
|
|
|
1347
1347
|
let sshRemotePort;
|
|
1348
1348
|
let sshWebSocketPath = '/runtime-host';
|
|
1349
1349
|
let sshWebSocketPathConfigured = false;
|
|
1350
|
-
let peerId;
|
|
1351
1350
|
let wslDistribution;
|
|
1352
1351
|
let operatorPath;
|
|
1353
|
-
const peerRouteHints = [];
|
|
1354
|
-
const peerCoordinationRelays = [];
|
|
1355
1352
|
let expectedRootId;
|
|
1356
1353
|
let credentialEnv;
|
|
1357
1354
|
for (let index = 1; index < argv.length; index += 1) {
|
|
@@ -1364,9 +1361,6 @@ function parseProfileCommand(argv) {
|
|
|
1364
1361
|
argument !== '--ssh-port' &&
|
|
1365
1362
|
argument !== '--ssh-remote-port' &&
|
|
1366
1363
|
argument !== '--ssh-websocket-path' &&
|
|
1367
|
-
argument !== '--peer-id' &&
|
|
1368
|
-
argument !== '--peer-route' &&
|
|
1369
|
-
argument !== '--peer-coordination-relay' &&
|
|
1370
1364
|
argument !== '--wsl-distribution' &&
|
|
1371
1365
|
argument !== '--operator-path' &&
|
|
1372
1366
|
argument !== '--expected-root' &&
|
|
@@ -1399,12 +1393,6 @@ function parseProfileCommand(argv) {
|
|
|
1399
1393
|
sshWebSocketPath = parsed;
|
|
1400
1394
|
sshWebSocketPathConfigured = true;
|
|
1401
1395
|
}
|
|
1402
|
-
if (argument === '--peer-id')
|
|
1403
|
-
peerId = parsed;
|
|
1404
|
-
if (argument === '--peer-route')
|
|
1405
|
-
peerRouteHints.push(parsed);
|
|
1406
|
-
if (argument === '--peer-coordination-relay')
|
|
1407
|
-
peerCoordinationRelays.push(parsed);
|
|
1408
1396
|
if (argument === '--wsl-distribution')
|
|
1409
1397
|
wslDistribution = parsed;
|
|
1410
1398
|
if (argument === '--operator-path')
|
|
@@ -1422,10 +1410,9 @@ function parseProfileCommand(argv) {
|
|
|
1422
1410
|
if ((tlsUrl ? 1 : 0) +
|
|
1423
1411
|
(plaintextUrl ? 1 : 0) +
|
|
1424
1412
|
(sshDestination ? 1 : 0) +
|
|
1425
|
-
(peerId ? 1 : 0) +
|
|
1426
1413
|
(wslDistribution ? 1 : 0) !==
|
|
1427
1414
|
1) {
|
|
1428
|
-
return error('exactly one of --tls-url, --plaintext-url, --ssh-destination,
|
|
1415
|
+
return error('exactly one of --tls-url, --plaintext-url, --ssh-destination, or --wsl-distribution is required');
|
|
1429
1416
|
}
|
|
1430
1417
|
if (wslDistribution && !operatorPath) {
|
|
1431
1418
|
return error('--wsl-distribution requires --operator-path');
|
|
@@ -1449,12 +1436,6 @@ function parseProfileCommand(argv) {
|
|
|
1449
1436
|
if (sshDestination && !sshRemotePort) {
|
|
1450
1437
|
return error('--ssh-destination requires --ssh-remote-port');
|
|
1451
1438
|
}
|
|
1452
|
-
if (!peerId && (peerRouteHints.length > 0 || peerCoordinationRelays.length > 0)) {
|
|
1453
|
-
return error('peer route options require --peer-id');
|
|
1454
|
-
}
|
|
1455
|
-
if (peerId && peerRouteHints.length === 0 && peerCoordinationRelays.length === 0) {
|
|
1456
|
-
return error('--peer-id requires at least one --peer-route or --peer-coordination-relay');
|
|
1457
|
-
}
|
|
1458
1439
|
if (sshPort !== undefined && (!Number.isInteger(sshPort) || sshPort < 1 || sshPort > 65_535)) {
|
|
1459
1440
|
return error('--ssh-port must be an integer between 1 and 65535');
|
|
1460
1441
|
}
|
|
@@ -1474,32 +1455,26 @@ function parseProfileCommand(argv) {
|
|
|
1474
1455
|
expectedRootId,
|
|
1475
1456
|
};
|
|
1476
1457
|
}
|
|
1458
|
+
const transport = tlsUrl
|
|
1459
|
+
? { kind: 'tls', url: tlsUrl }
|
|
1460
|
+
: plaintextUrl
|
|
1461
|
+
? {
|
|
1462
|
+
kind: 'plaintext',
|
|
1463
|
+
url: plaintextUrl,
|
|
1464
|
+
acknowledgement: 'plaintext-bearer-v1',
|
|
1465
|
+
}
|
|
1466
|
+
: {
|
|
1467
|
+
kind: 'ssh',
|
|
1468
|
+
destination: sshDestination,
|
|
1469
|
+
...(sshPort === undefined ? {} : { sshPort }),
|
|
1470
|
+
remotePort: sshRemotePort,
|
|
1471
|
+
websocketPath: sshWebSocketPath,
|
|
1472
|
+
};
|
|
1477
1473
|
return {
|
|
1478
1474
|
kind: 'runtime-host-profile-set',
|
|
1479
1475
|
id,
|
|
1480
1476
|
name,
|
|
1481
|
-
transport
|
|
1482
|
-
? { kind: 'tls', url: tlsUrl }
|
|
1483
|
-
: plaintextUrl
|
|
1484
|
-
? {
|
|
1485
|
-
kind: 'plaintext',
|
|
1486
|
-
url: plaintextUrl,
|
|
1487
|
-
acknowledgement: 'plaintext-bearer-v1',
|
|
1488
|
-
}
|
|
1489
|
-
: sshDestination
|
|
1490
|
-
? {
|
|
1491
|
-
kind: 'ssh',
|
|
1492
|
-
destination: sshDestination,
|
|
1493
|
-
...(sshPort === undefined ? {} : { sshPort }),
|
|
1494
|
-
remotePort: sshRemotePort,
|
|
1495
|
-
websocketPath: sshWebSocketPath,
|
|
1496
|
-
}
|
|
1497
|
-
: {
|
|
1498
|
-
kind: 'libp2p-direct',
|
|
1499
|
-
peerId: peerId,
|
|
1500
|
-
routeHints: peerRouteHints,
|
|
1501
|
-
coordinationRelays: peerCoordinationRelays,
|
|
1502
|
-
},
|
|
1477
|
+
transport,
|
|
1503
1478
|
expectedRootId,
|
|
1504
1479
|
...(credentialEnv ? { credentialEnv } : {}),
|
|
1505
1480
|
};
|
|
@@ -20,7 +20,7 @@ import { randomUUID } from 'node:crypto';
|
|
|
20
20
|
import { join } from 'node:path';
|
|
21
21
|
import { isDeepStrictEqual } from 'node:util';
|
|
22
22
|
import { resolveExistingStorageRoot, tryAcquireStateRootOwner, } from '@maka/storage/root-authority';
|
|
23
|
-
import { connectExistingRuntimeHost, prepareConnectedRuntimeHostRetirement, waitForRuntimeHostReady, } from '@maka/runtime-host/client';
|
|
23
|
+
import { connectExistingRuntimeHost, prepareConnectedRuntimeHostRetirement, RuntimeHostOperationError, RuntimeHostRequestInterruptedError, waitForRuntimeHostReady, } from '@maka/runtime-host/client';
|
|
24
24
|
import { RUNTIME_HOST_PROTOCOL_VERSION } from '@maka/runtime-host/protocol';
|
|
25
25
|
import { beginRuntimeHostManagedDeploymentTransition, blockRuntimeHostManagedDeploymentTransition, commitRuntimeHostManagedDeploymentTransition, decodeRuntimeHostManagedDeploymentConfig, readRuntimeHostManagedDeploymentAuthorityRecord, resolveRuntimeHostManagedDeploymentAuthority, resolveRuntimeHostNpmDeploymentLayout, rollbackRuntimeHostManagedDeploymentTransition, RuntimeHostManagedDeploymentError, } from '@maka/runtime-host/operator';
|
|
26
26
|
/** The budget a managed Runtime Host has to become reachable after its lifecycle is activated. */
|
|
@@ -198,7 +198,7 @@ export async function retireRuntimeHostLifecycleOwner(input) {
|
|
|
198
198
|
throw error;
|
|
199
199
|
}
|
|
200
200
|
}
|
|
201
|
-
const connected = await connectExistingRuntimeHost({
|
|
201
|
+
const connected = await (input.connectExisting ?? connectExistingRuntimeHost)({
|
|
202
202
|
rootPath: capability.canonicalPath,
|
|
203
203
|
protocol: {
|
|
204
204
|
min: RUNTIME_HOST_PROTOCOL_VERSION,
|
|
@@ -220,22 +220,35 @@ export async function retireRuntimeHostLifecycleOwner(input) {
|
|
|
220
220
|
throw new RuntimeHostLifecycleTransactionError('transition_failed', `Runtime Host cannot prepare for retirement: ${connected.kind}`);
|
|
221
221
|
}
|
|
222
222
|
try {
|
|
223
|
-
const diagnostics = await connected.connection.request('host.diagnostics.query', {});
|
|
224
223
|
const supervisorStatus = await input.supervisor?.status();
|
|
225
224
|
if (supervisorStatus)
|
|
226
225
|
assertExpectedSupervisorOwner(input.expectedOwner, supervisorStatus);
|
|
227
226
|
if (supervisorStatus &&
|
|
228
|
-
(!supervisorStatus.active || supervisorStatus.pid !==
|
|
229
|
-
throw new RuntimeHostLifecycleTransactionError('transition_failed', 'The supervisor and
|
|
227
|
+
(!supervisorStatus.active || supervisorStatus.pid !== connected.registration.pid)) {
|
|
228
|
+
throw new RuntimeHostLifecycleTransactionError('transition_failed', 'The supervisor and Runtime Host registration report different processes');
|
|
230
229
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
230
|
+
try {
|
|
231
|
+
const diagnostics = await connected.connection.request('host.diagnostics.query', {});
|
|
232
|
+
if (diagnostics.pid !== connected.registration.pid) {
|
|
233
|
+
throw new RuntimeHostLifecycleTransactionError('transition_failed', 'The Runtime Host registration and diagnostics report different processes');
|
|
234
|
+
}
|
|
235
|
+
// The exact Root owner and canonical supervisor now agree while the deployment lock is held.
|
|
236
|
+
// This admits retirement of that deployment; a later same-deployment restart is not a new
|
|
237
|
+
// authority, but it must not acquire the Root before the supervisor is retired.
|
|
238
|
+
const prepared = await prepareConnectedRuntimeHostRetirement(connected.connection, input.allowInterruptActiveTasks ? 'interrupt_active_work' : 'refuse_active_work');
|
|
239
|
+
if (prepared.kind === 'active_tasks')
|
|
240
|
+
return prepared;
|
|
241
|
+
if (prepared.pid !== diagnostics.pid) {
|
|
242
|
+
throw new RuntimeHostLifecycleTransactionError('transition_failed', 'The Runtime Host process changed while retirement was prepared');
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
if (!isRuntimeHostRetirementUnavailable(error) || !input.supervisor)
|
|
247
|
+
throw error;
|
|
248
|
+
if (!input.allowInterruptActiveTasks)
|
|
249
|
+
return { kind: 'active_tasks' };
|
|
250
|
+
await input.supervisor.retire();
|
|
251
|
+
return waitForRuntimeHostLifecycleOwner(capability, input.timeoutMs ?? 45_000);
|
|
239
252
|
}
|
|
240
253
|
const retirement = await waitForRuntimeHostLifecycleOwner(capability, input.timeoutMs ?? 45_000);
|
|
241
254
|
try {
|
|
@@ -251,6 +264,11 @@ export async function retireRuntimeHostLifecycleOwner(input) {
|
|
|
251
264
|
await connected.connection.close().catch(() => undefined);
|
|
252
265
|
}
|
|
253
266
|
}
|
|
267
|
+
function isRuntimeHostRetirementUnavailable(error) {
|
|
268
|
+
return (error instanceof RuntimeHostRequestInterruptedError ||
|
|
269
|
+
(error instanceof RuntimeHostOperationError &&
|
|
270
|
+
(error.code === 'host_not_ready' || error.code === 'host_draining')));
|
|
271
|
+
}
|
|
254
272
|
function assertExpectedRuntimeHostOwner(expected, observed) {
|
|
255
273
|
if (!expected)
|
|
256
274
|
return;
|
|
@@ -276,7 +276,7 @@ function absentStatus(config) {
|
|
|
276
276
|
function presentationManager(config) {
|
|
277
277
|
if (config.lifecycle.mode === 'on_demand')
|
|
278
278
|
return 'on_demand';
|
|
279
|
-
return config.lifecycle.provider
|
|
279
|
+
return config.lifecycle.provider;
|
|
280
280
|
}
|
|
281
281
|
function projectLegacyConfig(config) {
|
|
282
282
|
const layout = resolveRuntimeHostNpmDeploymentLayout(config.deploymentRoot, config.launch.package.integrity);
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* specific language governing permissions and limitations
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
|
-
import { offerableCatalogEntries } from '@maka/core/llm-connections';
|
|
19
|
+
import { deriveConnectionSlug, offerableCatalogEntries } from '@maka/core/llm-connections';
|
|
20
20
|
import { readRuntimeHostConnectionCatalog, } from '@maka/runtime-host/client';
|
|
21
21
|
import { listApiKeyOnboardableProviders } from './onboarding-catalog.js';
|
|
22
22
|
/** Adapt the TUI onboarding workflow to Host-owned verification and persistence. */
|
|
@@ -115,6 +115,7 @@ export function projectRuntimeHostConnectionIdentities(catalog) {
|
|
|
115
115
|
}
|
|
116
116
|
export function projectProviders(catalog) {
|
|
117
117
|
const entries = [];
|
|
118
|
+
const existingSlugs = catalog.connections.map((connection) => connection.slug);
|
|
118
119
|
for (const provider of listApiKeyOnboardableProviders()) {
|
|
119
120
|
for (const connection of catalog.connections) {
|
|
120
121
|
if (connection.providerType !== provider.providerType)
|
|
@@ -131,6 +132,7 @@ export function projectProviders(catalog) {
|
|
|
131
132
|
...provider,
|
|
132
133
|
target: { kind: 'create', providerType: provider.providerType },
|
|
133
134
|
label: provider.label,
|
|
135
|
+
suggestedSlug: deriveConnectionSlug(provider.providerType, existingSlugs),
|
|
134
136
|
enabledModelIds: [],
|
|
135
137
|
});
|
|
136
138
|
}
|