@xfey/tutti 0.1.78 → 0.1.80
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/README.md +1 -1
- package/dist/chat-assistant/index.d.ts +11 -1
- package/dist/chat-assistant/index.js +61 -7
- package/dist/checks/index.d.ts +22 -0
- package/dist/checks/index.js +110 -4
- package/dist/control-plane/follow-up-start.d.ts +1 -0
- package/dist/control-plane/follow-up-start.js +3 -1
- package/dist/control-plane/index.d.ts +6 -1
- package/dist/control-plane/index.js +72 -11
- package/dist/control-plane/procedure-logging.js +24 -67
- package/dist/control-plane/project-context-bootstrap.js +7 -1
- package/dist/control-plane/reference-summary-refresh.js +1 -1
- package/dist/control-plane/run-result-recording.js +2 -1
- package/dist/control-plane/task-compile-start.d.ts +1 -0
- package/dist/control-plane/task-compile-start.js +11 -1
- package/dist/control-plane/workflows/openai.d.ts +6 -0
- package/dist/control-plane/workflows/openai.js +16 -3
- package/dist/procedure-engine/index.d.ts +1 -0
- package/dist/procedure-engine/index.js +7 -1
- package/dist/process-tree.d.ts +25 -0
- package/dist/process-tree.js +121 -0
- package/dist/providers/openai/app-server/invocation-coordinator.d.ts +28 -0
- package/dist/providers/openai/app-server/invocation-coordinator.js +104 -0
- package/dist/providers/openai/app-server/invocation-lifecycle.d.ts +45 -0
- package/dist/providers/openai/app-server/invocation-lifecycle.js +104 -0
- package/dist/providers/openai/app-server/json-rpc.d.ts +1 -1
- package/dist/providers/openai/app-server/json-rpc.js +9 -16
- package/dist/providers/openai/app-server/read-only-procedure.d.ts +8 -2
- package/dist/providers/openai/app-server/read-only-procedure.js +63 -11
- package/dist/providers/openai/app-server/smoke-types.d.ts +4 -2
- package/dist/providers/openai/app-server/smoke.js +41 -12
- package/dist/providers/openai/app-server/stale-temp-cleanup.d.ts +17 -0
- package/dist/providers/openai/app-server/stale-temp-cleanup.js +130 -0
- package/dist/providers/openai/app-server/workspace-write-run.d.ts +8 -2
- package/dist/providers/openai/app-server/workspace-write-run.js +63 -11
- package/dist/providers/openai/chat-assistant.d.ts +6 -0
- package/dist/providers/openai/chat-assistant.js +12 -0
- package/dist/providers/openai/index.d.ts +1 -0
- package/dist/providers/openai/index.js +1 -0
- package/dist/providers/openai/machine-local-files.d.ts +1 -1
- package/dist/providers/openai/machine-local-files.js +32 -9
- package/dist/providers/openai/provider-config.d.ts +5 -1
- package/dist/providers/openai/provider-config.js +25 -4
- package/dist/providers/openai/provider-models.d.ts +41 -0
- package/dist/providers/openai/provider-models.js +82 -0
- package/dist/providers/openai/provider-setup.js +5 -2
- package/dist/run-engine/index.js +2 -1
- package/dist/run-pipeline/artifact-applicability.js +2 -2
- package/dist/run-pipeline/openai.d.ts +9 -0
- package/dist/run-pipeline/openai.js +26 -26
- package/dist/run-pipeline/task-run-invocation.js +6 -0
- package/dist/runtime-failures.d.ts +3 -0
- package/dist/runtime-failures.js +22 -0
- package/dist/server-shell/cli/host-lifecycle.js +1 -1
- package/dist/server-shell/cli/host-project-runtime-lifecycle.d.ts +43 -0
- package/dist/server-shell/cli/host-project-runtime-lifecycle.js +54 -0
- package/dist/server-shell/cli/host-server-runtime.d.ts +1 -1
- package/dist/server-shell/cli/host-server-runtime.js +140 -15
- package/dist/server-shell/http/create-server.d.ts +3 -0
- package/dist/server-shell/http/create-server.js +10 -4
- package/dist/server-shell/http/routes/project-api/invalidations.d.ts +1 -0
- package/dist/server-shell/http/routes/project-api/invalidations.js +4 -5
- package/dist/server-shell/http/routes/project-api/openapi-workspace-routes.d.ts +38 -14
- package/dist/server-shell/http/routes/project-api/openapi-workspace-routes.js +26 -1
- package/dist/server-shell/http/routes/project-api/openapi.d.ts +38 -14
- package/dist/server-shell/http/routes/project-api/schemas.d.ts +8 -2
- package/dist/server-shell/http/routes/project-api/schemas.js +2 -0
- package/dist/server-shell/http/routes/project-api/session-requirements.d.ts +1 -0
- package/dist/server-shell/http/routes/project-api/session-requirements.js +7 -0
- package/dist/server-shell/http/routes/project-api/system-routes.js +96 -5
- package/dist/server-shell/http/routes/project-api/types.d.ts +10 -1
- package/dist/server-shell/http/routes/project-api/workspace-projections.js +4 -2
- package/dist/server-shell/http/routes/project-api.d.ts +1 -1
- package/node_modules/@tutti/shared/dist/schemas/api/index.d.ts +1 -1
- package/node_modules/@tutti/shared/dist/schemas/api/index.js +1 -1
- package/node_modules/@tutti/shared/dist/schemas/api/provider-config.d.ts +36 -0
- package/node_modules/@tutti/shared/dist/schemas/api/provider-config.js +58 -1
- package/node_modules/@tutti/shared/dist/schemas/api/types.d.ts +9 -1
- package/package.json +1 -1
- package/web/assets/{homepage-motion-scene-sNI8fBH3.js → homepage-motion-scene-DXzmjALa.js} +1 -1
- package/web/assets/index-9gApbtPC.js +69 -0
- package/web/assets/index-BKeSEhsn.css +1 -0
- package/web/index.html +2 -2
- package/web/assets/index-BUfAlA_H.css +0 -1
- package/web/assets/index-d-q9yZ09.js +0 -69
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export class HostProjectRuntimeShutdownError extends Error {
|
|
2
|
+
code;
|
|
3
|
+
constructor(code, message) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.code = code;
|
|
6
|
+
this.name = "HostProjectRuntimeShutdownError";
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
const DEFAULT_GRACEFUL_DRAIN_MS = 1_000;
|
|
10
|
+
const DEFAULT_FORCED_DRAIN_MS = 10_000;
|
|
11
|
+
function wait(delayMs) {
|
|
12
|
+
return new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
13
|
+
}
|
|
14
|
+
async function settlesWithin(promise, timeoutMs) {
|
|
15
|
+
return await Promise.race([
|
|
16
|
+
promise.then(() => true),
|
|
17
|
+
wait(timeoutMs).then(() => false),
|
|
18
|
+
]);
|
|
19
|
+
}
|
|
20
|
+
export class HostProjectRuntimeLifecycle {
|
|
21
|
+
options;
|
|
22
|
+
closePromise;
|
|
23
|
+
constructor(options) {
|
|
24
|
+
this.options = options;
|
|
25
|
+
}
|
|
26
|
+
close() {
|
|
27
|
+
this.closePromise ??= this.closeOnce();
|
|
28
|
+
return this.closePromise;
|
|
29
|
+
}
|
|
30
|
+
async closeOnce() {
|
|
31
|
+
this.options.controlPlane.beginShutdown();
|
|
32
|
+
this.options.chatAssistant.stopAccepting();
|
|
33
|
+
this.options.invocationCoordinator.stopAccepting();
|
|
34
|
+
this.options.checkProcessCoordinator.stopAccepting();
|
|
35
|
+
this.options.approvalManager.clearPending();
|
|
36
|
+
const waitForOwners = () => Promise.all([
|
|
37
|
+
this.options.chatAssistant.waitForIdle(),
|
|
38
|
+
this.options.controlPlane.waitForIdle(),
|
|
39
|
+
this.options.invocationCoordinator.waitForIdle(),
|
|
40
|
+
this.options.checkProcessCoordinator.waitForIdle(),
|
|
41
|
+
]).then(() => undefined);
|
|
42
|
+
if (!(await settlesWithin(waitForOwners(), this.options.gracefulDrainMs ?? DEFAULT_GRACEFUL_DRAIN_MS))) {
|
|
43
|
+
await Promise.all([
|
|
44
|
+
this.options.invocationCoordinator.closeActive(),
|
|
45
|
+
this.options.checkProcessCoordinator.terminateActive(),
|
|
46
|
+
]);
|
|
47
|
+
if (!(await settlesWithin(waitForOwners(), this.options.forcedDrainMs ?? DEFAULT_FORCED_DRAIN_MS))) {
|
|
48
|
+
throw new HostProjectRuntimeShutdownError("drain_timeout", "Host project runtime did not settle within the bounded shutdown window.");
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
this.options.approvalManager.dispose();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=host-project-runtime-lifecycle.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { FastifyInstance } from "fastify";
|
|
2
|
-
import type
|
|
2
|
+
import { type ExecutionStatusProjection } from "@tutti/shared/schemas/api";
|
|
3
3
|
import { type HostProjectStore } from "../../store/index.js";
|
|
4
4
|
import type { createHostServer } from "../http/create-server.js";
|
|
5
5
|
import type { HostLocalLaunchStatus } from "../http/routes/local-control.js";
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { basename, join } from "node:path";
|
|
2
|
+
import { MAX_PROVIDER_MODEL_NAME_LENGTH, } from "@tutti/shared/schemas/api";
|
|
2
3
|
import { serializeRuntimeLogLine } from "@tutti/shared/utils";
|
|
3
4
|
import { completeRelayUpload, resolveRelayUpload } from "@tutti/relay-client";
|
|
4
5
|
import { ApprovalRequestManager } from "../../approvals/index.js";
|
|
5
6
|
import { ArtifactPreviewManager } from "../../artifacts/index.js";
|
|
6
7
|
import { ReadOnlyChatAssistant } from "../../chat-assistant/index.js";
|
|
8
|
+
import { CheckProcessCoordinator } from "../../checks/index.js";
|
|
7
9
|
import { ensureInitialProjectWelcomeMessage } from "../../collaboration-state/index.js";
|
|
8
10
|
import { Phase5ControlPlane } from "../../control-plane/index.js";
|
|
9
11
|
import { resolveProjectOpenAiProcedureWorkflowRunner } from "../../control-plane/workflows/index.js";
|
|
12
|
+
import { cleanupStaleCodexAppServerTempRoots } from "../../providers/openai/app-server/stale-temp-cleanup.js";
|
|
13
|
+
import { CodexAppServerInvocationCoordinator } from "../../providers/openai/app-server/invocation-coordinator.js";
|
|
10
14
|
import { resolveProjectOpenAiReadOnlyChatAssistantModel } from "../../providers/openai/chat-assistant.js";
|
|
11
|
-
import { configureProjectOpenAiProvider, readOpenAiProviderConfigProjection, } from "../../providers/openai/index.js";
|
|
15
|
+
import { configureProjectOpenAiProvider, discoverProjectOpenAiModels, readOpenAiProviderConfigProjection, updateProjectOpenAiDefaultModel, } from "../../providers/openai/index.js";
|
|
12
16
|
import { readProviderUsageProjection, recordProviderUsageEvent, } from "../../provider-usage/index.js";
|
|
13
17
|
import { resolveProjectOpenAiRunPipelineRunner } from "../../run-pipeline/openai.js";
|
|
14
18
|
import { openHostProjectStore } from "../../store/index.js";
|
|
@@ -18,6 +22,7 @@ import { readHostRepoProjection } from "../http/routes/project-api.js";
|
|
|
18
22
|
import { WorkspaceEventBus } from "../http/workspace-events.js";
|
|
19
23
|
import { createTrustedRelaySessionMetadataStore, } from "../session/relay-session-context.js";
|
|
20
24
|
import { LaunchError } from "./errors.js";
|
|
25
|
+
import { HostProjectRuntimeLifecycle } from "./host-project-runtime-lifecycle.js";
|
|
21
26
|
import { readCliVersion } from "./version.js";
|
|
22
27
|
import { relayStateFromLaunchStatus } from "./host-relay-status.js";
|
|
23
28
|
import { appendHostLogLine, readHostRegistrationSecret, createMachineRuntimeEndpointToken, deleteMachineRuntimeEndpoint, ensureHostLogFile, getHostLogFilePath, updateMachineProjectDisplayNameSnapshot, writeMachineRuntimeEndpoint, } from "./machine-local.js";
|
|
@@ -32,6 +37,62 @@ export function packageUpdateReadinessFromExecutionStatus(execution) {
|
|
|
32
37
|
? "busy"
|
|
33
38
|
: "ready";
|
|
34
39
|
}
|
|
40
|
+
function createHostProviderModelService(options) {
|
|
41
|
+
return {
|
|
42
|
+
discover: async () => {
|
|
43
|
+
const result = await discoverProjectOpenAiModels(options);
|
|
44
|
+
if (result.kind !== "ok") {
|
|
45
|
+
return { status: "unavailable", reason: result.reason };
|
|
46
|
+
}
|
|
47
|
+
const models = result.models.filter((model) => model.length <= MAX_PROVIDER_MODEL_NAME_LENGTH && /^\S(?:.*\S)?$/.test(model));
|
|
48
|
+
return models.length > 0
|
|
49
|
+
? { status: "available", models }
|
|
50
|
+
: { status: "unavailable", reason: "model_list_empty" };
|
|
51
|
+
},
|
|
52
|
+
update: async (payload) => {
|
|
53
|
+
const result = await updateProjectOpenAiDefaultModel({
|
|
54
|
+
...options,
|
|
55
|
+
defaultModel: payload.default_model,
|
|
56
|
+
expectedDefaultModel: payload.expected_default_model,
|
|
57
|
+
});
|
|
58
|
+
if (result.kind === "updated") {
|
|
59
|
+
return {
|
|
60
|
+
disposition: { kind: "updated" },
|
|
61
|
+
provider_config: result.projection,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
if (result.kind === "unchanged") {
|
|
65
|
+
return {
|
|
66
|
+
disposition: { kind: "unchanged" },
|
|
67
|
+
provider_config: result.projection,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
if (result.kind === "stale_default_model") {
|
|
71
|
+
return {
|
|
72
|
+
disposition: {
|
|
73
|
+
kind: result.kind,
|
|
74
|
+
current_default_model: result.current_default_model,
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
if (result.kind === "validation_failed") {
|
|
79
|
+
return {
|
|
80
|
+
disposition: {
|
|
81
|
+
kind: result.kind,
|
|
82
|
+
reason: result.reason,
|
|
83
|
+
retryable: result.retryable,
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
disposition: {
|
|
89
|
+
kind: result.kind,
|
|
90
|
+
reason: result.reason,
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
|
35
96
|
function createHostRuntimeLogger(options) {
|
|
36
97
|
return {
|
|
37
98
|
info(fields, message) {
|
|
@@ -47,6 +108,15 @@ function createHostRuntimeLogger(options) {
|
|
|
47
108
|
},
|
|
48
109
|
};
|
|
49
110
|
}
|
|
111
|
+
function createLifecycleIncidentReporter(logger, consumer) {
|
|
112
|
+
return (incident) => {
|
|
113
|
+
logger.info({
|
|
114
|
+
consumer,
|
|
115
|
+
incident_code: incident.code,
|
|
116
|
+
error_code: incident.error_code,
|
|
117
|
+
}, "Codex app-server lifecycle incident");
|
|
118
|
+
};
|
|
119
|
+
}
|
|
50
120
|
function createAgentContextRuntime(options) {
|
|
51
121
|
return {
|
|
52
122
|
baseUrl: new URL(AGENT_CONTEXT_BASE_PATH, options.baseUrl).toString(),
|
|
@@ -214,10 +284,25 @@ export async function startForegroundHostServer(options) {
|
|
|
214
284
|
logFilePath,
|
|
215
285
|
now,
|
|
216
286
|
});
|
|
287
|
+
const procedureLifecycleIncident = createLifecycleIncidentReporter(controlPlaneLogger, "procedure");
|
|
288
|
+
const runLifecycleIncident = createLifecycleIncidentReporter(runPipelineLogger, "run");
|
|
289
|
+
const chatLifecycleIncident = createLifecycleIncidentReporter(controlPlaneLogger, "chat_assistant");
|
|
290
|
+
const staleTempCleanup = await cleanupStaleCodexAppServerTempRoots({
|
|
291
|
+
onIncident: (incident) => {
|
|
292
|
+
controlPlaneLogger.info({
|
|
293
|
+
consumer: "maintenance",
|
|
294
|
+
incident_code: incident.code,
|
|
295
|
+
error_code: incident.error_code,
|
|
296
|
+
}, "Codex app-server lifecycle incident");
|
|
297
|
+
},
|
|
298
|
+
});
|
|
299
|
+
controlPlaneLogger.info(staleTempCleanup, "Codex app-server stale temp cleanup completed");
|
|
217
300
|
const approvalManager = new ApprovalRequestManager({
|
|
218
301
|
events: workspaceEvents,
|
|
219
302
|
now,
|
|
220
303
|
});
|
|
304
|
+
const codexInvocationCoordinator = new CodexAppServerInvocationCoordinator();
|
|
305
|
+
const checkProcessCoordinator = new CheckProcessCoordinator();
|
|
221
306
|
const artifactPreviewManager = new ArtifactPreviewManager({
|
|
222
307
|
onStatusChange: () => {
|
|
223
308
|
workspaceEvents.publish({
|
|
@@ -254,6 +339,9 @@ export async function startForegroundHostServer(options) {
|
|
|
254
339
|
approvalManager,
|
|
255
340
|
logger: runPipelineLogger,
|
|
256
341
|
recordUsage,
|
|
342
|
+
invocationCoordinator: codexInvocationCoordinator,
|
|
343
|
+
checkProcessCoordinator,
|
|
344
|
+
onLifecycleIncident: runLifecycleIncident,
|
|
257
345
|
}),
|
|
258
346
|
resolveWorkflowRunner: () => resolveProjectOpenAiProcedureWorkflowRunner({
|
|
259
347
|
tuttiHome: options.preparation.tutti_home,
|
|
@@ -261,6 +349,8 @@ export async function startForegroundHostServer(options) {
|
|
|
261
349
|
workspaceRoot: options.preparation.workspace_root,
|
|
262
350
|
agentContext: agentContextRuntime,
|
|
263
351
|
recordUsage,
|
|
352
|
+
invocationCoordinator: codexInvocationCoordinator,
|
|
353
|
+
onLifecycleIncident: procedureLifecycleIncident,
|
|
264
354
|
}),
|
|
265
355
|
});
|
|
266
356
|
const chatAssistant = new ReadOnlyChatAssistant({
|
|
@@ -276,6 +366,8 @@ export async function startForegroundHostServer(options) {
|
|
|
276
366
|
workspaceRoot: options.preparation.workspace_root,
|
|
277
367
|
agentContext: agentContextRuntime,
|
|
278
368
|
recordUsage,
|
|
369
|
+
invocationCoordinator: codexInvocationCoordinator,
|
|
370
|
+
onLifecycleIncident: chatLifecycleIncident,
|
|
279
371
|
});
|
|
280
372
|
if (resolution.kind !== "ready") {
|
|
281
373
|
throw new Error("Provider is not configured.");
|
|
@@ -283,9 +375,17 @@ export async function startForegroundHostServer(options) {
|
|
|
283
375
|
return await resolution.model.answer(input);
|
|
284
376
|
},
|
|
285
377
|
},
|
|
378
|
+
waitForInspectionAvailability: () => controlPlane.waitForRepoInspectionIdle(),
|
|
286
379
|
onScratchpadSourceChanged: (message) => controlPlane.notifyScratchpadSourceChanged(message),
|
|
287
380
|
now,
|
|
288
381
|
});
|
|
382
|
+
const projectRuntimeLifecycle = new HostProjectRuntimeLifecycle({
|
|
383
|
+
controlPlane,
|
|
384
|
+
chatAssistant,
|
|
385
|
+
invocationCoordinator: codexInvocationCoordinator,
|
|
386
|
+
checkProcessCoordinator,
|
|
387
|
+
approvalManager,
|
|
388
|
+
});
|
|
289
389
|
let close = async () => { };
|
|
290
390
|
let relayConnectionManager;
|
|
291
391
|
const packageUpdateReadiness = () => packageUpdateReadinessFromExecutionStatus(controlPlane.getExecutionStatus());
|
|
@@ -372,6 +472,9 @@ export async function startForegroundHostServer(options) {
|
|
|
372
472
|
},
|
|
373
473
|
},
|
|
374
474
|
logger: { file: logFilePath },
|
|
475
|
+
lifecycle: {
|
|
476
|
+
close: () => projectRuntimeLifecycle.close(),
|
|
477
|
+
},
|
|
375
478
|
localControl,
|
|
376
479
|
now,
|
|
377
480
|
projectApi: {
|
|
@@ -396,6 +499,11 @@ export async function startForegroundHostServer(options) {
|
|
|
396
499
|
chatAssistant,
|
|
397
500
|
tuttiHome: options.preparation.tutti_home,
|
|
398
501
|
getProviderConfig,
|
|
502
|
+
providerModel: createHostProviderModelService({
|
|
503
|
+
tuttiHome: options.preparation.tutti_home,
|
|
504
|
+
projectId: options.preparation.project_id,
|
|
505
|
+
now,
|
|
506
|
+
}),
|
|
399
507
|
getProviderUsage: () => readProviderUsageProjection(store.db),
|
|
400
508
|
updateProjectDisplayName: (displayName) => {
|
|
401
509
|
updateRuntimeProjectDisplayName(displayName);
|
|
@@ -456,30 +564,47 @@ export async function startForegroundHostServer(options) {
|
|
|
456
564
|
recoverInProgressCommands: true,
|
|
457
565
|
});
|
|
458
566
|
let resolveClosed;
|
|
459
|
-
|
|
567
|
+
let rejectClosed;
|
|
568
|
+
const closed = new Promise((resolve, reject) => {
|
|
460
569
|
resolveClosed = resolve;
|
|
570
|
+
rejectClosed = reject;
|
|
461
571
|
});
|
|
462
572
|
let closePromise;
|
|
463
573
|
close = () => {
|
|
464
574
|
closePromise ??= (async () => {
|
|
575
|
+
let closeError;
|
|
576
|
+
let appClosed = false;
|
|
465
577
|
try {
|
|
466
|
-
await relayConnectionManager?.stop();
|
|
467
|
-
await app.close();
|
|
468
|
-
}
|
|
469
|
-
finally {
|
|
470
578
|
try {
|
|
471
|
-
|
|
472
|
-
store.close();
|
|
579
|
+
await relayConnectionManager?.stop();
|
|
473
580
|
}
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
resolveClosed();
|
|
581
|
+
catch (error) {
|
|
582
|
+
closeError = error;
|
|
583
|
+
}
|
|
584
|
+
try {
|
|
585
|
+
await app.close();
|
|
586
|
+
appClosed = true;
|
|
481
587
|
}
|
|
588
|
+
catch (error) {
|
|
589
|
+
closeError ??= error;
|
|
590
|
+
}
|
|
591
|
+
if (appClosed) {
|
|
592
|
+
store.close();
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
finally {
|
|
596
|
+
deleteMachineRuntimeEndpoint({
|
|
597
|
+
tuttiHome: options.preparation.tutti_home,
|
|
598
|
+
projectId: options.preparation.project_id,
|
|
599
|
+
expectedToken: token,
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
if (closeError !== undefined) {
|
|
603
|
+
const normalizedCloseError = closeError instanceof Error ? closeError : new Error("Host server close failed.");
|
|
604
|
+
rejectClosed(normalizedCloseError);
|
|
605
|
+
throw normalizedCloseError;
|
|
482
606
|
}
|
|
607
|
+
resolveClosed();
|
|
483
608
|
})();
|
|
484
609
|
return closePromise;
|
|
485
610
|
};
|
|
@@ -24,10 +24,11 @@ export function createHostServer(options = {}) {
|
|
|
24
24
|
if (options.projectApi !== undefined && options.projectApi !== false) {
|
|
25
25
|
const projectApiOptions = options.projectApi;
|
|
26
26
|
registerHostProjectApiRoutes(app, projectApiOptions);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
if (options.lifecycle === undefined) {
|
|
28
|
+
app.addHook("onClose", async () => {
|
|
29
|
+
await projectApiOptions.controlPlane?.dispose();
|
|
30
|
+
});
|
|
31
|
+
}
|
|
31
32
|
if (options.agentContext !== false) {
|
|
32
33
|
registerAgentContextRoutes(app, {
|
|
33
34
|
project: projectApiOptions.project,
|
|
@@ -46,6 +47,11 @@ export function createHostServer(options = {}) {
|
|
|
46
47
|
});
|
|
47
48
|
}
|
|
48
49
|
}
|
|
50
|
+
if (options.lifecycle !== undefined) {
|
|
51
|
+
app.addHook("onClose", async () => {
|
|
52
|
+
await options.lifecycle?.close();
|
|
53
|
+
});
|
|
54
|
+
}
|
|
49
55
|
if (options.webStatic !== undefined && options.webStatic !== false) {
|
|
50
56
|
registerHostWebStaticRoutes(app, options.webStatic);
|
|
51
57
|
}
|
|
@@ -7,5 +7,6 @@ export declare function clarificationRoundInvalidates(roundId: ClarificationRoun
|
|
|
7
7
|
export declare function approvalInvalidates(): QueryInvalidationHint[];
|
|
8
8
|
export declare function readStateInvalidates(): QueryInvalidationHint[];
|
|
9
9
|
export declare function projectMetadataInvalidates(): QueryInvalidationHint[];
|
|
10
|
+
export declare function providerConfigInvalidates(): QueryInvalidationHint[];
|
|
10
11
|
export declare function projectDisplayNameInvalidates(): QueryInvalidationHint[];
|
|
11
12
|
//# sourceMappingURL=invalidations.d.ts.map
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
export function mainChatMessageInvalidates() {
|
|
2
|
-
return [
|
|
3
|
-
{ kind: "messages", scope: "main_chat" },
|
|
4
|
-
{ kind: "read_state" },
|
|
5
|
-
{ kind: "bootstrap" },
|
|
6
|
-
];
|
|
2
|
+
return [{ kind: "messages", scope: "main_chat" }, { kind: "read_state" }, { kind: "bootstrap" }];
|
|
7
3
|
}
|
|
8
4
|
export function worklistSubmitInvalidates() {
|
|
9
5
|
return [
|
|
@@ -54,6 +50,9 @@ export function readStateInvalidates() {
|
|
|
54
50
|
export function projectMetadataInvalidates() {
|
|
55
51
|
return [{ kind: "workspace" }, { kind: "bootstrap" }];
|
|
56
52
|
}
|
|
53
|
+
export function providerConfigInvalidates() {
|
|
54
|
+
return [{ kind: "provider_config" }, { kind: "workspace" }, { kind: "bootstrap" }];
|
|
55
|
+
}
|
|
57
56
|
export function projectDisplayNameInvalidates() {
|
|
58
57
|
return projectMetadataInvalidates();
|
|
59
58
|
}
|
|
@@ -76,6 +76,36 @@ export declare const HOST_PROJECT_WORKSPACE_OPENAPI_ROUTES: ({
|
|
|
76
76
|
};
|
|
77
77
|
};
|
|
78
78
|
requestBody?: never;
|
|
79
|
+
} | {
|
|
80
|
+
method: "get";
|
|
81
|
+
path: string;
|
|
82
|
+
summary: string;
|
|
83
|
+
tags: string[];
|
|
84
|
+
responses: {
|
|
85
|
+
200: {
|
|
86
|
+
description: string;
|
|
87
|
+
schema: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TObject<{
|
|
88
|
+
status: import("@sinclair/typebox").TLiteral<"available">;
|
|
89
|
+
models: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
|
|
90
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
91
|
+
status: import("@sinclair/typebox").TLiteral<"unavailable">;
|
|
92
|
+
reason: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"model_list_unavailable">, import("@sinclair/typebox").TLiteral<"model_list_empty">, import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"provider_not_configured">, import("@sinclair/typebox").TLiteral<"provider_config_invalid">, import("@sinclair/typebox").TLiteral<"provider_credential_missing">]>]>;
|
|
93
|
+
}>]>;
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
requestBody?: never;
|
|
97
|
+
} | {
|
|
98
|
+
method: "post";
|
|
99
|
+
path: string;
|
|
100
|
+
summary: string;
|
|
101
|
+
tags: string[];
|
|
102
|
+
requestBody: import("@sinclair/typebox").TSchema;
|
|
103
|
+
responses: {
|
|
104
|
+
200: {
|
|
105
|
+
description: string;
|
|
106
|
+
schema: import("@sinclair/typebox").TSchema;
|
|
107
|
+
};
|
|
108
|
+
};
|
|
79
109
|
} | {
|
|
80
110
|
method: "get";
|
|
81
111
|
path: string;
|
|
@@ -555,7 +585,7 @@ export declare const HOST_PROJECT_WORKSPACE_OPENAPI_ROUTES: ({
|
|
|
555
585
|
};
|
|
556
586
|
readonly capabilities: {
|
|
557
587
|
readonly type: "object";
|
|
558
|
-
readonly required: readonly ["sse", "relay_join", "repo_viewer", "provider_config_query", "browser_secret_write", "task_auto_scheduler", "task_run_now_scheduler", "clarification"];
|
|
588
|
+
readonly required: readonly ["sse", "relay_join", "repo_viewer", "provider_config_query", "provider_model_update", "browser_secret_write", "task_auto_scheduler", "task_run_now_scheduler", "clarification"];
|
|
559
589
|
readonly additionalProperties: false;
|
|
560
590
|
readonly properties: {
|
|
561
591
|
readonly sse: {
|
|
@@ -570,6 +600,9 @@ export declare const HOST_PROJECT_WORKSPACE_OPENAPI_ROUTES: ({
|
|
|
570
600
|
readonly provider_config_query: {
|
|
571
601
|
readonly type: "boolean";
|
|
572
602
|
};
|
|
603
|
+
readonly provider_model_update: {
|
|
604
|
+
readonly type: "boolean";
|
|
605
|
+
};
|
|
573
606
|
readonly browser_secret_write: {
|
|
574
607
|
readonly type: "boolean";
|
|
575
608
|
readonly enum: readonly [false];
|
|
@@ -590,18 +623,6 @@ export declare const HOST_PROJECT_WORKSPACE_OPENAPI_ROUTES: ({
|
|
|
590
623
|
};
|
|
591
624
|
};
|
|
592
625
|
requestBody?: never;
|
|
593
|
-
} | {
|
|
594
|
-
method: "post";
|
|
595
|
-
path: string;
|
|
596
|
-
summary: string;
|
|
597
|
-
tags: string[];
|
|
598
|
-
requestBody: import("@sinclair/typebox").TSchema;
|
|
599
|
-
responses: {
|
|
600
|
-
200: {
|
|
601
|
-
description: string;
|
|
602
|
-
schema: import("@sinclair/typebox").TSchema;
|
|
603
|
-
};
|
|
604
|
-
};
|
|
605
626
|
} | {
|
|
606
627
|
method: "get";
|
|
607
628
|
path: string;
|
|
@@ -755,7 +776,7 @@ export declare const HOST_PROJECT_WORKSPACE_OPENAPI_ROUTES: ({
|
|
|
755
776
|
};
|
|
756
777
|
readonly capabilities: {
|
|
757
778
|
readonly type: "object";
|
|
758
|
-
readonly required: readonly ["sse", "relay_join", "repo_viewer", "provider_config_query", "browser_secret_write", "task_auto_scheduler", "task_run_now_scheduler", "clarification"];
|
|
779
|
+
readonly required: readonly ["sse", "relay_join", "repo_viewer", "provider_config_query", "provider_model_update", "browser_secret_write", "task_auto_scheduler", "task_run_now_scheduler", "clarification"];
|
|
759
780
|
readonly additionalProperties: false;
|
|
760
781
|
readonly properties: {
|
|
761
782
|
readonly sse: {
|
|
@@ -770,6 +791,9 @@ export declare const HOST_PROJECT_WORKSPACE_OPENAPI_ROUTES: ({
|
|
|
770
791
|
readonly provider_config_query: {
|
|
771
792
|
readonly type: "boolean";
|
|
772
793
|
};
|
|
794
|
+
readonly provider_model_update: {
|
|
795
|
+
readonly type: "boolean";
|
|
796
|
+
};
|
|
773
797
|
readonly browser_secret_write: {
|
|
774
798
|
readonly type: "boolean";
|
|
775
799
|
readonly enum: readonly [false];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MarkReadBodySchema, MarkReadResponseSchema, ReadStateSummaryProjectionSchema, UpdateProjectDescriptionBodySchema, UpdateProjectDescriptionResponseSchema, UpdateProjectDisplayNameBodySchema, UpdateProjectDisplayNameResponseSchema, } from "@tutti/shared/schemas/api";
|
|
1
|
+
import { MarkReadBodySchema, MarkReadResponseSchema, ReadStateSummaryProjectionSchema, UpdateProjectDescriptionBodySchema, UpdateProjectDescriptionResponseSchema, UpdateProjectDisplayNameBodySchema, UpdateProjectDisplayNameResponseSchema, GetProviderModelsResponseSchema, UpdateProviderDefaultModelBodySchema, UpdateProviderDefaultModelResponseSchema, } from "@tutti/shared/schemas/api";
|
|
2
2
|
import { HOST_PROJECT_API_BASE_PATH } from "./constants.js";
|
|
3
3
|
import { BootstrapResponseSchema, ProviderConfigProjectionSchema, ProviderUsageProjectionSchema, SessionResponseSchema, WorkspaceResponseSchema, } from "./schemas.js";
|
|
4
4
|
export const HOST_PROJECT_WORKSPACE_OPENAPI_ROUTES = [
|
|
@@ -14,6 +14,31 @@ export const HOST_PROJECT_WORKSPACE_OPENAPI_ROUTES = [
|
|
|
14
14
|
},
|
|
15
15
|
},
|
|
16
16
|
},
|
|
17
|
+
{
|
|
18
|
+
method: "get",
|
|
19
|
+
path: `${HOST_PROJECT_API_BASE_PATH}/provider/models`,
|
|
20
|
+
summary: "Discover model names with the configured provider credential (owner only).",
|
|
21
|
+
tags: ["provider"],
|
|
22
|
+
responses: {
|
|
23
|
+
200: {
|
|
24
|
+
description: "Bounded provider model discovery result.",
|
|
25
|
+
schema: GetProviderModelsResponseSchema,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
method: "post",
|
|
31
|
+
path: `${HOST_PROJECT_API_BASE_PATH}/provider/default-model`,
|
|
32
|
+
summary: "Validate and update the default provider model (owner only).",
|
|
33
|
+
tags: ["provider"],
|
|
34
|
+
requestBody: UpdateProviderDefaultModelBodySchema,
|
|
35
|
+
responses: {
|
|
36
|
+
200: {
|
|
37
|
+
description: "Default-model update command response.",
|
|
38
|
+
schema: UpdateProviderDefaultModelResponseSchema,
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
17
42
|
{
|
|
18
43
|
method: "get",
|
|
19
44
|
path: `${HOST_PROJECT_API_BASE_PATH}/provider/usage`,
|
|
@@ -1350,6 +1350,36 @@ export declare const HOST_PROJECT_OPENAPI_ROUTES: ({
|
|
|
1350
1350
|
};
|
|
1351
1351
|
};
|
|
1352
1352
|
requestBody?: never;
|
|
1353
|
+
} | {
|
|
1354
|
+
method: "get";
|
|
1355
|
+
path: string;
|
|
1356
|
+
summary: string;
|
|
1357
|
+
tags: string[];
|
|
1358
|
+
responses: {
|
|
1359
|
+
200: {
|
|
1360
|
+
description: string;
|
|
1361
|
+
schema: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TObject<{
|
|
1362
|
+
status: import("@sinclair/typebox").TLiteral<"available">;
|
|
1363
|
+
models: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
|
|
1364
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
1365
|
+
status: import("@sinclair/typebox").TLiteral<"unavailable">;
|
|
1366
|
+
reason: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"model_list_unavailable">, import("@sinclair/typebox").TLiteral<"model_list_empty">, import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"provider_not_configured">, import("@sinclair/typebox").TLiteral<"provider_config_invalid">, import("@sinclair/typebox").TLiteral<"provider_credential_missing">]>]>;
|
|
1367
|
+
}>]>;
|
|
1368
|
+
};
|
|
1369
|
+
};
|
|
1370
|
+
requestBody?: never;
|
|
1371
|
+
} | {
|
|
1372
|
+
method: "post";
|
|
1373
|
+
path: string;
|
|
1374
|
+
summary: string;
|
|
1375
|
+
tags: string[];
|
|
1376
|
+
requestBody: import("@sinclair/typebox").TSchema;
|
|
1377
|
+
responses: {
|
|
1378
|
+
200: {
|
|
1379
|
+
description: string;
|
|
1380
|
+
schema: import("@sinclair/typebox").TSchema;
|
|
1381
|
+
};
|
|
1382
|
+
};
|
|
1353
1383
|
} | {
|
|
1354
1384
|
method: "get";
|
|
1355
1385
|
path: string;
|
|
@@ -1829,7 +1859,7 @@ export declare const HOST_PROJECT_OPENAPI_ROUTES: ({
|
|
|
1829
1859
|
};
|
|
1830
1860
|
readonly capabilities: {
|
|
1831
1861
|
readonly type: "object";
|
|
1832
|
-
readonly required: readonly ["sse", "relay_join", "repo_viewer", "provider_config_query", "browser_secret_write", "task_auto_scheduler", "task_run_now_scheduler", "clarification"];
|
|
1862
|
+
readonly required: readonly ["sse", "relay_join", "repo_viewer", "provider_config_query", "provider_model_update", "browser_secret_write", "task_auto_scheduler", "task_run_now_scheduler", "clarification"];
|
|
1833
1863
|
readonly additionalProperties: false;
|
|
1834
1864
|
readonly properties: {
|
|
1835
1865
|
readonly sse: {
|
|
@@ -1844,6 +1874,9 @@ export declare const HOST_PROJECT_OPENAPI_ROUTES: ({
|
|
|
1844
1874
|
readonly provider_config_query: {
|
|
1845
1875
|
readonly type: "boolean";
|
|
1846
1876
|
};
|
|
1877
|
+
readonly provider_model_update: {
|
|
1878
|
+
readonly type: "boolean";
|
|
1879
|
+
};
|
|
1847
1880
|
readonly browser_secret_write: {
|
|
1848
1881
|
readonly type: "boolean";
|
|
1849
1882
|
readonly enum: readonly [false];
|
|
@@ -1864,18 +1897,6 @@ export declare const HOST_PROJECT_OPENAPI_ROUTES: ({
|
|
|
1864
1897
|
};
|
|
1865
1898
|
};
|
|
1866
1899
|
requestBody?: never;
|
|
1867
|
-
} | {
|
|
1868
|
-
method: "post";
|
|
1869
|
-
path: string;
|
|
1870
|
-
summary: string;
|
|
1871
|
-
tags: string[];
|
|
1872
|
-
requestBody: import("@sinclair/typebox").TSchema;
|
|
1873
|
-
responses: {
|
|
1874
|
-
200: {
|
|
1875
|
-
description: string;
|
|
1876
|
-
schema: import("@sinclair/typebox").TSchema;
|
|
1877
|
-
};
|
|
1878
|
-
};
|
|
1879
1900
|
} | {
|
|
1880
1901
|
method: "get";
|
|
1881
1902
|
path: string;
|
|
@@ -2029,7 +2050,7 @@ export declare const HOST_PROJECT_OPENAPI_ROUTES: ({
|
|
|
2029
2050
|
};
|
|
2030
2051
|
readonly capabilities: {
|
|
2031
2052
|
readonly type: "object";
|
|
2032
|
-
readonly required: readonly ["sse", "relay_join", "repo_viewer", "provider_config_query", "browser_secret_write", "task_auto_scheduler", "task_run_now_scheduler", "clarification"];
|
|
2053
|
+
readonly required: readonly ["sse", "relay_join", "repo_viewer", "provider_config_query", "provider_model_update", "browser_secret_write", "task_auto_scheduler", "task_run_now_scheduler", "clarification"];
|
|
2033
2054
|
readonly additionalProperties: false;
|
|
2034
2055
|
readonly properties: {
|
|
2035
2056
|
readonly sse: {
|
|
@@ -2044,6 +2065,9 @@ export declare const HOST_PROJECT_OPENAPI_ROUTES: ({
|
|
|
2044
2065
|
readonly provider_config_query: {
|
|
2045
2066
|
readonly type: "boolean";
|
|
2046
2067
|
};
|
|
2068
|
+
readonly provider_model_update: {
|
|
2069
|
+
readonly type: "boolean";
|
|
2070
|
+
};
|
|
2047
2071
|
readonly browser_secret_write: {
|
|
2048
2072
|
readonly type: "boolean";
|
|
2049
2073
|
readonly enum: readonly [false];
|
|
@@ -560,7 +560,7 @@ export declare const WorkspaceResponseSchema: {
|
|
|
560
560
|
};
|
|
561
561
|
readonly capabilities: {
|
|
562
562
|
readonly type: "object";
|
|
563
|
-
readonly required: readonly ["sse", "relay_join", "repo_viewer", "provider_config_query", "browser_secret_write", "task_auto_scheduler", "task_run_now_scheduler", "clarification"];
|
|
563
|
+
readonly required: readonly ["sse", "relay_join", "repo_viewer", "provider_config_query", "provider_model_update", "browser_secret_write", "task_auto_scheduler", "task_run_now_scheduler", "clarification"];
|
|
564
564
|
readonly additionalProperties: false;
|
|
565
565
|
readonly properties: {
|
|
566
566
|
readonly sse: {
|
|
@@ -575,6 +575,9 @@ export declare const WorkspaceResponseSchema: {
|
|
|
575
575
|
readonly provider_config_query: {
|
|
576
576
|
readonly type: "boolean";
|
|
577
577
|
};
|
|
578
|
+
readonly provider_model_update: {
|
|
579
|
+
readonly type: "boolean";
|
|
580
|
+
};
|
|
578
581
|
readonly browser_secret_write: {
|
|
579
582
|
readonly type: "boolean";
|
|
580
583
|
readonly enum: readonly [false];
|
|
@@ -737,7 +740,7 @@ export declare const BootstrapResponseSchema: {
|
|
|
737
740
|
};
|
|
738
741
|
readonly capabilities: {
|
|
739
742
|
readonly type: "object";
|
|
740
|
-
readonly required: readonly ["sse", "relay_join", "repo_viewer", "provider_config_query", "browser_secret_write", "task_auto_scheduler", "task_run_now_scheduler", "clarification"];
|
|
743
|
+
readonly required: readonly ["sse", "relay_join", "repo_viewer", "provider_config_query", "provider_model_update", "browser_secret_write", "task_auto_scheduler", "task_run_now_scheduler", "clarification"];
|
|
741
744
|
readonly additionalProperties: false;
|
|
742
745
|
readonly properties: {
|
|
743
746
|
readonly sse: {
|
|
@@ -752,6 +755,9 @@ export declare const BootstrapResponseSchema: {
|
|
|
752
755
|
readonly provider_config_query: {
|
|
753
756
|
readonly type: "boolean";
|
|
754
757
|
};
|
|
758
|
+
readonly provider_model_update: {
|
|
759
|
+
readonly type: "boolean";
|
|
760
|
+
};
|
|
755
761
|
readonly browser_secret_write: {
|
|
756
762
|
readonly type: "boolean";
|
|
757
763
|
readonly enum: readonly [false];
|