@xfey/tutti 0.1.127 → 0.1.129
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/approvals/decision-command.d.ts +2 -2
- package/dist/chat-assistant/diagnostics.d.ts +17 -3
- package/dist/chat-assistant/diagnostics.js +5 -2
- package/dist/chat-assistant/failure-messages.d.ts +4 -0
- package/dist/chat-assistant/failure-messages.js +57 -0
- package/dist/chat-assistant/failures.d.ts +27 -0
- package/dist/chat-assistant/failures.js +46 -0
- package/dist/chat-assistant/index.d.ts +18 -4
- package/dist/chat-assistant/index.js +254 -51
- package/dist/chat-assistant/language-context.d.ts +2 -0
- package/dist/chat-assistant/language-context.js +17 -14
- package/dist/chat-assistant/requests.d.ts +34 -0
- package/dist/chat-assistant/requests.js +64 -0
- package/dist/collaboration-ingestion/clarification.js +3 -1
- package/dist/collaboration-ingestion/main-chat.js +1 -0
- package/dist/collaboration-ingestion/types.d.ts +2 -0
- package/dist/collaboration-state/clarification-snapshot.d.ts +5 -5
- package/dist/collaboration-state/context-sync-attempts.d.ts +9 -0
- package/dist/collaboration-state/context-sync-attempts.js +13 -0
- package/dist/collaboration-state/task-compile-context.d.ts +1 -1
- package/dist/collaboration-state/task-compile-context.js +11 -1
- package/dist/collaboration-state/task-compile-requests.d.ts +6 -0
- package/dist/collaboration-state/task-compile-requests.js +16 -0
- package/dist/communication-language/notice-locale.d.ts +4 -0
- package/dist/communication-language/notice-locale.js +14 -0
- package/dist/control-plane/context-sync-completion.d.ts +7 -0
- package/dist/control-plane/context-sync-completion.js +27 -0
- package/dist/control-plane/context-sync.d.ts +1 -0
- package/dist/control-plane/context-sync.js +23 -0
- package/dist/control-plane/index.d.ts +13 -4
- package/dist/control-plane/index.js +30 -23
- package/dist/control-plane/task-compile-continuation.js +2 -0
- package/dist/control-plane/task-compile-request-status.d.ts +6 -0
- package/dist/control-plane/task-compile-request-status.js +70 -0
- package/dist/control-plane/task-compile-start.js +40 -2
- package/dist/control-plane/types.d.ts +2 -0
- package/dist/providers/failure-classification.d.ts +23 -0
- package/dist/providers/failure-classification.js +43 -0
- package/dist/providers/invocation-progress.d.ts +6 -0
- package/dist/providers/invocation-progress.js +24 -0
- package/dist/providers/openai/app-server/read-only-procedure.js +1 -0
- package/dist/providers/openai/chat-assistant.js +2 -1
- package/dist/reference-access/read-evidence.d.ts +2 -0
- package/dist/reference-access/read-evidence.js +5 -0
- package/dist/reference-access/service.d.ts +2 -0
- package/dist/reference-access/service.js +2 -0
- package/dist/runtime-failures.js +15 -1
- package/dist/server-shell/cli/external-reference-runtime.js +6 -3
- package/dist/server-shell/cli/host-server-runtime.js +8 -2
- package/dist/server-shell/cli/relay-registration.js +1 -0
- package/dist/server-shell/http/routes/project-api/messages-routes.js +22 -1
- package/dist/server-shell/http/routes/project-api/openapi-collaboration-routes.d.ts +140 -5
- package/dist/server-shell/http/routes/project-api/openapi-collaboration-routes.js +29 -2
- package/dist/server-shell/http/routes/project-api/openapi-skills-routes.d.ts +2 -0
- package/dist/server-shell/http/routes/project-api/openapi-workspace-routes.d.ts +6 -0
- package/dist/server-shell/http/routes/project-api/openapi.d.ts +148 -5
- package/dist/server-shell/http/routes/project-api/schemas.d.ts +6 -0
- package/dist/server-shell/http/routes/project-api/schemas.js +1 -0
- package/dist/server-shell/http/routes/project-api/types.d.ts +1 -0
- package/dist/server-shell/http/routes/project-api/workflow-routes.js +39 -3
- package/dist/server-shell/http/routes/project-api/workspace-projections.js +1 -0
- package/dist/server-shell/http/validation.js +8 -2
- package/dist/server-shell/local-console/managed-project-service.d.ts +1 -1
- package/dist/server-shell/managed-access/transport.d.ts +1 -1
- package/migrations/0024_chat_requests.sql +19 -0
- package/migrations/0025_task_compile_requests.sql +50 -0
- package/migrations/0026_context_sync_and_chat_locale.sql +12 -0
- package/migrations/README.md +3 -1
- package/node_modules/@tutti/relay-client/dist/host-control.d.ts +1 -0
- package/node_modules/@tutti/relay-client/dist/host-control.js +1 -0
- package/node_modules/@tutti/shared/dist/schemas/api/index.d.ts +1 -0
- package/node_modules/@tutti/shared/dist/schemas/api/index.js +1 -0
- package/node_modules/@tutti/shared/dist/schemas/api/operation-status.d.ts +174 -0
- package/node_modules/@tutti/shared/dist/schemas/api/operation-status.js +75 -0
- package/node_modules/@tutti/shared/dist/schemas/api/primitives.d.ts +1 -0
- package/node_modules/@tutti/shared/dist/schemas/api/primitives.js +1 -0
- package/node_modules/@tutti/shared/dist/schemas/api/workspace-commands.d.ts +1 -0
- package/node_modules/@tutti/shared/dist/schemas/api/workspace-commands.js +2 -1
- package/package.json +1 -1
- package/web/assets/{homepage-motion-scene-DyEmWwvt.js → homepage-motion-scene-BHhw4CfM.js} +1 -1
- package/web/assets/index-5COc1Yku.js +70 -0
- package/web/assets/index-BJvKuUiT.css +1 -0
- package/web/index.html +2 -2
- package/web/assets/index-By3idT4U.js +0 -70
- package/web/assets/index-DSBjOZmJ.css +0 -1
|
@@ -17,6 +17,8 @@ export type Phase5ControlPlaneOptions = {
|
|
|
17
17
|
mainline_clean: boolean;
|
|
18
18
|
};
|
|
19
19
|
readActiveApproval?: () => ActiveApprovalProjection;
|
|
20
|
+
/** Read-only Chat owner signal; does not merge Chat into the workflow state machine. */
|
|
21
|
+
hasPendingChatRequests?: () => boolean;
|
|
20
22
|
logger?: ControlPlaneLogger;
|
|
21
23
|
projectContext?: {
|
|
22
24
|
workspaceRoot: string;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
declare const aliases: {
|
|
2
|
+
readonly provider_not_configured: "provider_not_configured";
|
|
3
|
+
readonly provider_auth_invalid: "provider_auth_invalid";
|
|
4
|
+
readonly provider_quota_or_billing_required: "provider_quota_or_billing_required";
|
|
5
|
+
readonly provider_rate_limited: "provider_rate_limited";
|
|
6
|
+
readonly provider_model_unavailable: "provider_model_unavailable";
|
|
7
|
+
readonly provider_network_error: "provider_network_error";
|
|
8
|
+
readonly auth_failed: "provider_auth_invalid";
|
|
9
|
+
readonly host_delegation_revoked: "provider_auth_invalid";
|
|
10
|
+
readonly authority_invalid: "provider_auth_invalid";
|
|
11
|
+
readonly gateway_rate_limited: "provider_rate_limited";
|
|
12
|
+
readonly control_queue_full: "provider_rate_limited";
|
|
13
|
+
readonly turn_timeout: "provider_timeout";
|
|
14
|
+
readonly output_parse_failed: "provider_output_invalid";
|
|
15
|
+
readonly output_validation_failed: "provider_output_invalid";
|
|
16
|
+
readonly process_lifecycle_failed: "provider_lifecycle_failed";
|
|
17
|
+
readonly process_tree_not_terminated: "provider_lifecycle_failed";
|
|
18
|
+
};
|
|
19
|
+
export type ProviderFailureCode = (typeof aliases)[keyof typeof aliases];
|
|
20
|
+
/** Facts only, never a retry policy. Do not parse provider prose or raw stderr. */
|
|
21
|
+
export declare function providerFailureCode(error: unknown): ProviderFailureCode | undefined;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=failure-classification.d.ts.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const aliases = {
|
|
2
|
+
provider_not_configured: "provider_not_configured",
|
|
3
|
+
provider_auth_invalid: "provider_auth_invalid",
|
|
4
|
+
provider_quota_or_billing_required: "provider_quota_or_billing_required",
|
|
5
|
+
provider_rate_limited: "provider_rate_limited",
|
|
6
|
+
provider_model_unavailable: "provider_model_unavailable",
|
|
7
|
+
provider_network_error: "provider_network_error",
|
|
8
|
+
auth_failed: "provider_auth_invalid",
|
|
9
|
+
host_delegation_revoked: "provider_auth_invalid",
|
|
10
|
+
authority_invalid: "provider_auth_invalid",
|
|
11
|
+
gateway_rate_limited: "provider_rate_limited",
|
|
12
|
+
control_queue_full: "provider_rate_limited",
|
|
13
|
+
turn_timeout: "provider_timeout",
|
|
14
|
+
output_parse_failed: "provider_output_invalid",
|
|
15
|
+
output_validation_failed: "provider_output_invalid",
|
|
16
|
+
process_lifecycle_failed: "provider_lifecycle_failed",
|
|
17
|
+
process_tree_not_terminated: "provider_lifecycle_failed",
|
|
18
|
+
};
|
|
19
|
+
/** Facts only, never a retry policy. Do not parse provider prose or raw stderr. */
|
|
20
|
+
export function providerFailureCode(error) {
|
|
21
|
+
if (typeof error !== "object" || error === null)
|
|
22
|
+
return undefined;
|
|
23
|
+
const value = error;
|
|
24
|
+
const code = typeof value.code === "string" ? value.code : value.reason;
|
|
25
|
+
if (typeof code === "string" && Object.hasOwn(aliases, code))
|
|
26
|
+
return aliases[code];
|
|
27
|
+
if (code !== "turn_failed" || typeof value.details !== "object" || value.details === null)
|
|
28
|
+
return undefined;
|
|
29
|
+
const details = value.details;
|
|
30
|
+
// Quota can also carry HTTP 429; the specific bounded code takes precedence.
|
|
31
|
+
if (details.turn_error_code === "insufficient_quota")
|
|
32
|
+
return "provider_quota_or_billing_required";
|
|
33
|
+
if (details.turn_error_code === "invalid_api_key")
|
|
34
|
+
return "provider_auth_invalid";
|
|
35
|
+
if (details.turn_error_code === "model_not_found")
|
|
36
|
+
return "provider_model_unavailable";
|
|
37
|
+
if (details.turn_error_code === "rate_limit_exceeded" || details.turn_error_http_status === 429)
|
|
38
|
+
return "provider_rate_limited";
|
|
39
|
+
if (details.turn_error_http_status === 401)
|
|
40
|
+
return "provider_auth_invalid";
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=failure-classification.js.map
|
|
@@ -3,8 +3,14 @@ export type ProviderInvocationProgress = {
|
|
|
3
3
|
invocation_ref?: string;
|
|
4
4
|
skill_count?: number;
|
|
5
5
|
completed_tool_count?: number;
|
|
6
|
+
turn_timeout_ms?: number;
|
|
7
|
+
notification_count?: number;
|
|
8
|
+
server_request_count?: number;
|
|
9
|
+
last_activity_age_ms?: number;
|
|
6
10
|
reason_code?: "provider_unavailable" | "app_server_protocol_error" | "auth_failed" | "thread_start_failed" | "turn_failed" | "turn_timeout" | "unexpected_server_request" | "skill_selection_failed" | "output_parse_failed" | "output_validation_failed" | "file_read_not_observed" | "write_detected" | "secret_leak_detected" | "process_lifecycle_failed" | "admission_unavailable";
|
|
7
11
|
};
|
|
8
12
|
export type ProviderInvocationProgressObserver = (event: ProviderInvocationProgress) => void;
|
|
13
|
+
/** Copy only finite counters. Do not forward raw error details/methods/prose. */
|
|
14
|
+
export declare function providerInvocationFailureCounters(error: unknown, now?: number): Partial<ProviderInvocationProgress>;
|
|
9
15
|
export declare function reportProviderInvocationProgress(observer: ProviderInvocationProgressObserver | undefined, event: ProviderInvocationProgress): void;
|
|
10
16
|
//# sourceMappingURL=invocation-progress.d.ts.map
|
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
/** Copy only finite counters. Do not forward raw error details/methods/prose. */
|
|
2
|
+
export function providerInvocationFailureCounters(error, now = Date.now()) {
|
|
3
|
+
if (typeof error !== "object" || error === null || !("details" in error))
|
|
4
|
+
return {};
|
|
5
|
+
const details = error.details;
|
|
6
|
+
if (typeof details !== "object" || details === null)
|
|
7
|
+
return {};
|
|
8
|
+
const source = details;
|
|
9
|
+
const counters = {};
|
|
10
|
+
for (const key of ["turn_timeout_ms", "notification_count", "completed_tool_count"]) {
|
|
11
|
+
const value = source[key];
|
|
12
|
+
if (typeof value === "number" && Number.isSafeInteger(value) && value >= 0)
|
|
13
|
+
counters[key] = value;
|
|
14
|
+
}
|
|
15
|
+
if (Array.isArray(source.server_request_methods))
|
|
16
|
+
counters.server_request_count = source.server_request_methods.length;
|
|
17
|
+
if (typeof source.last_activity_at === "string" &&
|
|
18
|
+
/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(source.last_activity_at)) {
|
|
19
|
+
const age = now - Date.parse(source.last_activity_at);
|
|
20
|
+
if (Number.isSafeInteger(age) && age >= 0)
|
|
21
|
+
counters.last_activity_age_ms = age;
|
|
22
|
+
}
|
|
23
|
+
return counters;
|
|
24
|
+
}
|
|
1
25
|
export function reportProviderInvocationProgress(observer, event) {
|
|
2
26
|
try {
|
|
3
27
|
observer?.(event);
|
|
@@ -55,6 +55,7 @@ function readOnlyTimeoutDetails(input) {
|
|
|
55
55
|
const details = {
|
|
56
56
|
turn_timeout_ms: input.turnTimeoutMs,
|
|
57
57
|
notification_count: input.client.notifications.length,
|
|
58
|
+
completed_tool_count: structuredOutputDetails(input.client, "").completed_tool_count ?? 0,
|
|
58
59
|
server_request_methods: input.client.serverRequests.map(extractServerRequestMethod),
|
|
59
60
|
notification_methods: input.client.notifications
|
|
60
61
|
.map((notification) => notification.method)
|
|
@@ -3,7 +3,7 @@ import { readOpenAiApiKeyCredential } from "./credential-store.js";
|
|
|
3
3
|
import { resolveOpenAiProviderConfig } from "./provider-config.js";
|
|
4
4
|
import { openAiCredentialAccess, } from "./execution-access.js";
|
|
5
5
|
import { CodexAppServerReadOnlyProcedureError, runCodexAppServerReadOnlyProcedure, } from "./app-server/read-only-procedure.js";
|
|
6
|
-
import { reportProviderInvocationProgress } from "../invocation-progress.js";
|
|
6
|
+
import { reportProviderInvocationProgress, providerInvocationFailureCounters, } from "../invocation-progress.js";
|
|
7
7
|
import { getProjectUserSkillsRoot } from "../../skills/index.js";
|
|
8
8
|
export function createOpenAiReadOnlyChatAssistantModel(options) {
|
|
9
9
|
return {
|
|
@@ -42,6 +42,7 @@ export function createOpenAiReadOnlyChatAssistantModel(options) {
|
|
|
42
42
|
: { onLifecycleIncident: options.onLifecycleIncident }),
|
|
43
43
|
}).catch((error) => {
|
|
44
44
|
reportProviderInvocationProgress(input.onProgress, {
|
|
45
|
+
...providerInvocationFailureCounters(error),
|
|
45
46
|
stage: "provider_failed",
|
|
46
47
|
reason_code: error instanceof CodexAppServerReadOnlyProcedureError
|
|
47
48
|
? error.code
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { SqliteDatabase } from "../store/index.js";
|
|
2
2
|
import type { ReferenceCopy } from "./cache.js";
|
|
3
3
|
import type { ReferenceInvocation } from "./service.js";
|
|
4
|
+
import type { ReferenceAuthorization } from "@tutti/shared/schemas/api";
|
|
5
|
+
export declare function recordExternalReferenceAccessRequirement(db: SqliteDatabase, invocation: ReferenceInvocation, requestRef: string, authorization: ReferenceAuthorization, now?: () => Date): void;
|
|
4
6
|
/** Prior answer context only: a source reference is not proof of freshness in a later turn. */
|
|
5
7
|
export declare function readExternalReferenceReadSources(db: SqliteDatabase, invocationRef: string): string[];
|
|
6
8
|
/** Durable observation, separate from evictable cache metadata; no content or locator. */
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
export function recordExternalReferenceAccessRequirement(db, invocation, requestRef, authorization, now = () => new Date()) {
|
|
2
|
+
db.prepare(`INSERT OR IGNORE INTO external_reference_access_requirements
|
|
3
|
+
(invocation_ref, request_ref, activity_ref, authorization_ref, profile, observed_at)
|
|
4
|
+
VALUES (?, ?, ?, ?, ?, ?)`).run(invocation.reference_invocation_ref, requestRef, invocation.activity_ref ?? null, authorization.authorization_ref, authorization.profile, now().toISOString());
|
|
5
|
+
}
|
|
1
6
|
/** Prior answer context only: a source reference is not proof of freshness in a later turn. */
|
|
2
7
|
export function readExternalReferenceReadSources(db, invocationRef) {
|
|
3
8
|
return db
|
|
@@ -8,6 +8,8 @@ export type ReferenceInvocation = {
|
|
|
8
8
|
};
|
|
9
9
|
export declare class ReferenceAuthorizationRequiredError extends Error {
|
|
10
10
|
readonly result: ReferenceAuthorizationRequired;
|
|
11
|
+
readonly code = "reference_authorization_required";
|
|
12
|
+
readonly continuation = "explicit_request";
|
|
11
13
|
constructor(result: ReferenceAuthorizationRequired);
|
|
12
14
|
}
|
|
13
15
|
export declare class ExternalReferenceAccess {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { ReferenceCacheError } from "./cache.js";
|
|
2
2
|
export class ReferenceAuthorizationRequiredError extends Error {
|
|
3
3
|
result;
|
|
4
|
+
code = "reference_authorization_required";
|
|
5
|
+
continuation = "explicit_request";
|
|
4
6
|
constructor(result) {
|
|
5
7
|
super("reference_authorization_required");
|
|
6
8
|
this.result = result;
|
package/dist/runtime-failures.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { providerFailureCode } from "./providers/failure-classification.js";
|
|
1
2
|
const STABLE_FAILURE_CODE = /^[a-z][a-z0-9_]{0,63}$/u;
|
|
2
3
|
export function stableRuntimeFailureCode(error, fallback) {
|
|
3
4
|
if (typeof error === "object" &&
|
|
@@ -17,6 +18,19 @@ export function safeRuntimeFailureSummary(subject, error, fallbackCode) {
|
|
|
17
18
|
if (code === "admission_unavailable" || code === "admission_closed") {
|
|
18
19
|
return `${subject} stopped because provider execution is unavailable while the Host is closing. Retry after the Host is ready. (${code})`;
|
|
19
20
|
}
|
|
20
|
-
|
|
21
|
+
if (code === "reference_authorization_required") {
|
|
22
|
+
return `${subject} needs document access. Authorize using the group card, then review the task or request before continuing. (${code})`;
|
|
23
|
+
}
|
|
24
|
+
const providerCode = providerFailureCode(error);
|
|
25
|
+
if (providerCode === "provider_auth_invalid" ||
|
|
26
|
+
providerCode === "provider_quota_or_billing_required" ||
|
|
27
|
+
providerCode === "provider_model_unavailable" ||
|
|
28
|
+
providerCode === "provider_not_configured") {
|
|
29
|
+
return `${subject} could not use model access. Ask the project owner to check the provider or account, then review available recovery actions. (${providerCode})`;
|
|
30
|
+
}
|
|
31
|
+
if (providerCode === "provider_rate_limited") {
|
|
32
|
+
return `${subject} stopped because the model service is busy. Wait, then review available recovery actions. (${providerCode})`;
|
|
33
|
+
}
|
|
34
|
+
return `${subject} could not complete. Review its status and available recovery actions before continuing. (${code})`;
|
|
21
35
|
}
|
|
22
36
|
//# sourceMappingURL=runtime-failures.js.map
|
|
@@ -4,7 +4,7 @@ import { requestExternalReferences } from "@tutti/relay-client";
|
|
|
4
4
|
import { isExternalReferenceList, isExternalReferenceReadResult, isExternalReferenceDescriptor, isReferenceAuthorizationRequired, } from "@tutti/shared/schemas/internal";
|
|
5
5
|
import { ExternalReferenceCache } from "../../reference-access/cache.js";
|
|
6
6
|
import { ExternalReferenceAccess, ReferenceAuthorizationRequiredError, } from "../../reference-access/service.js";
|
|
7
|
-
import { recordExternalReferenceRead } from "../../reference-access/read-evidence.js";
|
|
7
|
+
import { recordExternalReferenceRead, recordExternalReferenceAccessRequirement, } from "../../reference-access/read-evidence.js";
|
|
8
8
|
import { downloadStagedUploadWithResolver, cleanupDownloadedStagedUpload, } from "../http/routes/project-api/staged-uploads.js";
|
|
9
9
|
import { readHostRegistrationSecret } from "./machine-local.js";
|
|
10
10
|
export function createExternalReferenceRuntime(options) {
|
|
@@ -14,6 +14,7 @@ export function createExternalReferenceRuntime(options) {
|
|
|
14
14
|
if (!relay)
|
|
15
15
|
throw new Error("reference_host_offline");
|
|
16
16
|
const secret = readHostRegistrationSecret(preparation.tutti_home, preparation.project_id);
|
|
17
|
+
const requestRef = `eref_${randomUUID().replaceAll("-", "")}`;
|
|
17
18
|
const result = await requestExternalReferences({
|
|
18
19
|
relayUrl: preparation.relay_url,
|
|
19
20
|
body: {
|
|
@@ -22,15 +23,17 @@ export function createExternalReferenceRuntime(options) {
|
|
|
22
23
|
host_auth: { kind: "host_registration_secret_v1", secret: secret.secret },
|
|
23
24
|
relay_project_ref: relay.relay_project_ref,
|
|
24
25
|
host_connection_ref: relay.host_connection_ref,
|
|
25
|
-
request_ref:
|
|
26
|
+
request_ref: requestRef,
|
|
26
27
|
invocation_ref: invocation.reference_invocation_ref,
|
|
27
28
|
action,
|
|
28
29
|
...(sourceRef === undefined ? {} : { source_ref: sourceRef }),
|
|
29
30
|
...(documentUrl === undefined ? {} : { document_url: documentUrl }),
|
|
30
31
|
},
|
|
31
32
|
});
|
|
32
|
-
if (isReferenceAuthorizationRequired(result))
|
|
33
|
+
if (isReferenceAuthorizationRequired(result)) {
|
|
34
|
+
recordExternalReferenceAccessRequirement(options.store.db, invocation, requestRef, result.authorization);
|
|
33
35
|
throw new ReferenceAuthorizationRequiredError(result);
|
|
36
|
+
}
|
|
34
37
|
return result;
|
|
35
38
|
}
|
|
36
39
|
return new ExternalReferenceAccess({
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { basename, join } from "node:path";
|
|
2
|
+
import { hasPendingChatRequests } from "../../chat-assistant/requests.js";
|
|
2
3
|
import { MAX_PROVIDER_MODEL_NAME_LENGTH, } from "@tutti/shared/schemas/api";
|
|
3
4
|
import { serializeRuntimeLogLine } from "@tutti/shared/utils";
|
|
4
5
|
import { completeRelayUpload, deliverRelayPlatformOutbound, RelayHostControlClientError, resolveRelayUpload, } from "@tutti/relay-client";
|
|
@@ -397,6 +398,7 @@ export async function startForegroundHostServer(options) {
|
|
|
397
398
|
events: workspaceEvents,
|
|
398
399
|
now,
|
|
399
400
|
logger: controlPlaneLogger,
|
|
401
|
+
hasPendingChatRequests: () => hasPendingChatRequests(store.db),
|
|
400
402
|
projectContext,
|
|
401
403
|
runLifecycle: {
|
|
402
404
|
started: () => artifactPreviewManager.beginWorkspaceUpdate(),
|
|
@@ -464,12 +466,15 @@ export async function startForegroundHostServer(options) {
|
|
|
464
466
|
model: createManagedChatModel(managedRuntime, runtimeOptions),
|
|
465
467
|
};
|
|
466
468
|
if (resolution.kind !== "ready") {
|
|
467
|
-
throw new Error("Provider is not configured.")
|
|
469
|
+
throw Object.assign(new Error("Provider is not configured."), {
|
|
470
|
+
code: "provider_not_configured",
|
|
471
|
+
});
|
|
468
472
|
}
|
|
469
473
|
return await resolution.model.answer(input);
|
|
470
474
|
},
|
|
471
475
|
},
|
|
472
|
-
waitForInspectionAvailability: () => controlPlane.waitForRepoInspectionIdle(),
|
|
476
|
+
waitForInspectionAvailability: (onBlocked) => controlPlane.waitForRepoInspectionIdle(onBlocked),
|
|
477
|
+
onRequestsChanged: () => controlPlane.notifyChatRequestsChanged(),
|
|
473
478
|
onScratchpadSourceChanged: (message) => controlPlane.notifyScratchpadSourceChanged(message),
|
|
474
479
|
...(platformOutboundCoordinator === undefined
|
|
475
480
|
? {}
|
|
@@ -704,6 +709,7 @@ export async function startForegroundHostServer(options) {
|
|
|
704
709
|
workspaceRoot: options.preparation.workspace_root,
|
|
705
710
|
recoverInProgressCommands: true,
|
|
706
711
|
});
|
|
712
|
+
chatAssistant.start();
|
|
707
713
|
};
|
|
708
714
|
// Managed creation / reauthorization activates during Relay registration. Do
|
|
709
715
|
// not recover a stored task against a not-yet-activated native delegation.
|
|
@@ -66,6 +66,7 @@ export async function registerHostWithRelay(options) {
|
|
|
66
66
|
integration_development_bot_v1: true,
|
|
67
67
|
integration_clarification_v1: true,
|
|
68
68
|
feishu_supporting_reads_v1: true,
|
|
69
|
+
request_status_v1: true,
|
|
69
70
|
integration_external_references_v1: true,
|
|
70
71
|
integration_attachment_ingestion_v1: true,
|
|
71
72
|
integration_managed_reference_ingestion_v1: true,
|
|
@@ -1,11 +1,32 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Type } from "@sinclair/typebox";
|
|
2
|
+
import { MessageIdSchema } from "@tutti/shared/schemas/domain";
|
|
3
|
+
import { GetMessagesRequestSchema, ChatRequestStatusSchema, MessageWindowSchema, SendMainChatMessageBodySchema, SendMainChatMessageResponseSchema, } from "@tutti/shared/schemas/api";
|
|
2
4
|
import { createArtifactFeedbackMessage } from "../../../../artifact-feedback/index.js";
|
|
3
5
|
import { ingestMainChatMessage } from "../../../../collaboration-ingestion/index.js";
|
|
4
6
|
import { readMainChatMessageWindow } from "../../../../collaboration-state/index.js";
|
|
5
7
|
import { HOST_PROJECT_API_BASE_PATH } from "./constants.js";
|
|
6
8
|
import { requireValidMessageWindowRequest, requireValidSendMainChatPayload, } from "./payload-validation.js";
|
|
7
9
|
import { requireHostProjectSession, requireProjectStore, requireWorkspaceRoot, } from "./session-requirements.js";
|
|
10
|
+
import { HostProjectNotFoundError, HostProjectBadRequestError } from "./errors.js";
|
|
11
|
+
import { chatRequestStatus, readChatRequest } from "../../../../chat-assistant/requests.js";
|
|
8
12
|
export function registerMessagesRoutes(app, { options, workspaceEvents, artifactPreviewManager, }) {
|
|
13
|
+
app.get(`${HOST_PROJECT_API_BASE_PATH}/chat-requests/:messageId`, {
|
|
14
|
+
preValidation: (request, _reply, done) => done(Object.keys(request.query).length === 0
|
|
15
|
+
? undefined
|
|
16
|
+
: new HostProjectBadRequestError("Request status does not accept query parameters")),
|
|
17
|
+
schema: {
|
|
18
|
+
params: Type.Object({ messageId: MessageIdSchema }, { additionalProperties: false }),
|
|
19
|
+
querystring: Type.Object({}, { additionalProperties: false }),
|
|
20
|
+
response: { 200: ChatRequestStatusSchema },
|
|
21
|
+
},
|
|
22
|
+
}, (request, reply) => {
|
|
23
|
+
requireHostProjectSession(request, options);
|
|
24
|
+
reply.header("cache-control", "no-store");
|
|
25
|
+
const record = readChatRequest(requireProjectStore(options).db, request.params.messageId);
|
|
26
|
+
if (record === null)
|
|
27
|
+
throw new HostProjectNotFoundError();
|
|
28
|
+
return chatRequestStatus(record);
|
|
29
|
+
});
|
|
9
30
|
app.get(`${HOST_PROJECT_API_BASE_PATH}/messages`, {
|
|
10
31
|
schema: {
|
|
11
32
|
querystring: GetMessagesRequestSchema,
|
|
@@ -1,4 +1,139 @@
|
|
|
1
1
|
export declare const HOST_PROJECT_COLLABORATION_OPENAPI_ROUTES: ({
|
|
2
|
+
method: "get";
|
|
3
|
+
path: string;
|
|
4
|
+
summary: string;
|
|
5
|
+
tags: string[];
|
|
6
|
+
querystring: import("@sinclair/typebox").TObject<{
|
|
7
|
+
workflow_ref: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
8
|
+
command_id: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
9
|
+
}>;
|
|
10
|
+
responses: {
|
|
11
|
+
200: {
|
|
12
|
+
description: string;
|
|
13
|
+
schema: import("@sinclair/typebox").TObject<{
|
|
14
|
+
request: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TObject<{
|
|
15
|
+
status: import("@sinclair/typebox").TLiteral<"running">;
|
|
16
|
+
phase: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"preparing">, import("@sinclair/typebox").TLiteral<"scratchpad_refresh">, import("@sinclair/typebox").TLiteral<"reference_summary_refresh">, import("@sinclair/typebox").TLiteral<"project_context_bootstrap">, import("@sinclair/typebox").TLiteral<"task_compile">]>;
|
|
17
|
+
operation: import("@sinclair/typebox").TObject<{
|
|
18
|
+
kind: import("@sinclair/typebox").TLiteral<"worklist_submit">;
|
|
19
|
+
ref: import("@sinclair/typebox").TString;
|
|
20
|
+
}>;
|
|
21
|
+
created_at: import("@sinclair/typebox").TString;
|
|
22
|
+
activity_ref: import("@sinclair/typebox").TString;
|
|
23
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
24
|
+
status: import("@sinclair/typebox").TLiteral<"waiting_input">;
|
|
25
|
+
phase: import("@sinclair/typebox").TLiteral<"clarification">;
|
|
26
|
+
round_id: import("@sinclair/typebox").TString;
|
|
27
|
+
operation: import("@sinclair/typebox").TObject<{
|
|
28
|
+
kind: import("@sinclair/typebox").TLiteral<"worklist_submit">;
|
|
29
|
+
ref: import("@sinclair/typebox").TString;
|
|
30
|
+
}>;
|
|
31
|
+
created_at: import("@sinclair/typebox").TString;
|
|
32
|
+
activity_ref: import("@sinclair/typebox").TString;
|
|
33
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
34
|
+
status: import("@sinclair/typebox").TLiteral<"succeeded">;
|
|
35
|
+
phase: import("@sinclair/typebox").TLiteral<"settled">;
|
|
36
|
+
operation: import("@sinclair/typebox").TObject<{
|
|
37
|
+
kind: import("@sinclair/typebox").TLiteral<"worklist_submit">;
|
|
38
|
+
ref: import("@sinclair/typebox").TString;
|
|
39
|
+
}>;
|
|
40
|
+
created_at: import("@sinclair/typebox").TString;
|
|
41
|
+
activity_ref: import("@sinclair/typebox").TString;
|
|
42
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
43
|
+
status: import("@sinclair/typebox").TLiteral<"failed">;
|
|
44
|
+
phase: import("@sinclair/typebox").TLiteral<"settled">;
|
|
45
|
+
failure: import("@sinclair/typebox").TObject<{
|
|
46
|
+
code: import("@sinclair/typebox").TString;
|
|
47
|
+
category: import("@sinclair/typebox").TUnion<import("@sinclair/typebox").TLiteral<"interrupted" | "capacity" | "access" | "configuration" | "dependency" | "internal">[]>;
|
|
48
|
+
recovery: import("@sinclair/typebox").TUnion<import("@sinclair/typebox").TLiteral<"resend_request" | "check_provider" | "restart_host" | "contact_support" | "none">[]>;
|
|
49
|
+
diagnostic_id: import("@sinclair/typebox").TString;
|
|
50
|
+
}>;
|
|
51
|
+
operation: import("@sinclair/typebox").TObject<{
|
|
52
|
+
kind: import("@sinclair/typebox").TLiteral<"worklist_submit">;
|
|
53
|
+
ref: import("@sinclair/typebox").TString;
|
|
54
|
+
}>;
|
|
55
|
+
created_at: import("@sinclair/typebox").TString;
|
|
56
|
+
activity_ref: import("@sinclair/typebox").TString;
|
|
57
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
58
|
+
status: import("@sinclair/typebox").TLiteral<"unknown">;
|
|
59
|
+
phase: import("@sinclair/typebox").TLiteral<"unconfirmed">;
|
|
60
|
+
operation: import("@sinclair/typebox").TObject<{
|
|
61
|
+
kind: import("@sinclair/typebox").TLiteral<"worklist_submit">;
|
|
62
|
+
ref: import("@sinclair/typebox").TString;
|
|
63
|
+
}>;
|
|
64
|
+
created_at: import("@sinclair/typebox").TString;
|
|
65
|
+
activity_ref: import("@sinclair/typebox").TString;
|
|
66
|
+
}>]>, import("@sinclair/typebox").TNull]>;
|
|
67
|
+
}>;
|
|
68
|
+
contentType?: never;
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
parameters?: never;
|
|
72
|
+
requestBody?: never;
|
|
73
|
+
} | {
|
|
74
|
+
method: "get";
|
|
75
|
+
path: string;
|
|
76
|
+
summary: string;
|
|
77
|
+
tags: string[];
|
|
78
|
+
parameters: import("@tutti/shared/schemas/api").BrowserFacingOpenApiParameter[];
|
|
79
|
+
responses: {
|
|
80
|
+
200: {
|
|
81
|
+
description: string;
|
|
82
|
+
schema: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TObject<{
|
|
83
|
+
status: import("@sinclair/typebox").TLiteral<"queued">;
|
|
84
|
+
phase: import("@sinclair/typebox").TLiteral<"queue">;
|
|
85
|
+
operation: import("@sinclair/typebox").TObject<{
|
|
86
|
+
kind: import("@sinclair/typebox").TLiteral<"chat_answer">;
|
|
87
|
+
ref: import("@sinclair/typebox").TString;
|
|
88
|
+
}>;
|
|
89
|
+
revision: import("@sinclair/typebox").TInteger;
|
|
90
|
+
created_at: import("@sinclair/typebox").TString;
|
|
91
|
+
updated_at: import("@sinclair/typebox").TString;
|
|
92
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
93
|
+
status: import("@sinclair/typebox").TLiteral<"running">;
|
|
94
|
+
phase: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"workspace_wait">, import("@sinclair/typebox").TLiteral<"answer">]>;
|
|
95
|
+
operation: import("@sinclair/typebox").TObject<{
|
|
96
|
+
kind: import("@sinclair/typebox").TLiteral<"chat_answer">;
|
|
97
|
+
ref: import("@sinclair/typebox").TString;
|
|
98
|
+
}>;
|
|
99
|
+
revision: import("@sinclair/typebox").TInteger;
|
|
100
|
+
created_at: import("@sinclair/typebox").TString;
|
|
101
|
+
updated_at: import("@sinclair/typebox").TString;
|
|
102
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
103
|
+
status: import("@sinclair/typebox").TLiteral<"succeeded">;
|
|
104
|
+
phase: import("@sinclair/typebox").TLiteral<"settled">;
|
|
105
|
+
response_message_id: import("@sinclair/typebox").TString;
|
|
106
|
+
operation: import("@sinclair/typebox").TObject<{
|
|
107
|
+
kind: import("@sinclair/typebox").TLiteral<"chat_answer">;
|
|
108
|
+
ref: import("@sinclair/typebox").TString;
|
|
109
|
+
}>;
|
|
110
|
+
revision: import("@sinclair/typebox").TInteger;
|
|
111
|
+
created_at: import("@sinclair/typebox").TString;
|
|
112
|
+
updated_at: import("@sinclair/typebox").TString;
|
|
113
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
114
|
+
status: import("@sinclair/typebox").TLiteral<"failed">;
|
|
115
|
+
phase: import("@sinclair/typebox").TLiteral<"settled">;
|
|
116
|
+
failure: import("@sinclair/typebox").TObject<{
|
|
117
|
+
code: import("@sinclair/typebox").TString;
|
|
118
|
+
category: import("@sinclair/typebox").TUnion<import("@sinclair/typebox").TLiteral<"interrupted" | "capacity" | "access" | "configuration" | "dependency" | "internal">[]>;
|
|
119
|
+
recovery: import("@sinclair/typebox").TUnion<import("@sinclair/typebox").TLiteral<"resend_request" | "check_provider" | "restart_host" | "contact_support" | "none">[]>;
|
|
120
|
+
diagnostic_id: import("@sinclair/typebox").TString;
|
|
121
|
+
}>;
|
|
122
|
+
response_message_id: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
123
|
+
operation: import("@sinclair/typebox").TObject<{
|
|
124
|
+
kind: import("@sinclair/typebox").TLiteral<"chat_answer">;
|
|
125
|
+
ref: import("@sinclair/typebox").TString;
|
|
126
|
+
}>;
|
|
127
|
+
revision: import("@sinclair/typebox").TInteger;
|
|
128
|
+
created_at: import("@sinclair/typebox").TString;
|
|
129
|
+
updated_at: import("@sinclair/typebox").TString;
|
|
130
|
+
}>]>;
|
|
131
|
+
contentType?: never;
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
querystring?: never;
|
|
135
|
+
requestBody?: never;
|
|
136
|
+
} | {
|
|
2
137
|
method: "get";
|
|
3
138
|
path: string;
|
|
4
139
|
summary: string;
|
|
@@ -17,8 +152,8 @@ export declare const HOST_PROJECT_COLLABORATION_OPENAPI_ROUTES: ({
|
|
|
17
152
|
contentType?: never;
|
|
18
153
|
};
|
|
19
154
|
};
|
|
20
|
-
requestBody?: never;
|
|
21
155
|
parameters?: never;
|
|
156
|
+
requestBody?: never;
|
|
22
157
|
} | {
|
|
23
158
|
method: "post";
|
|
24
159
|
path: string;
|
|
@@ -77,8 +212,8 @@ export declare const HOST_PROJECT_COLLABORATION_OPENAPI_ROUTES: ({
|
|
|
77
212
|
};
|
|
78
213
|
};
|
|
79
214
|
};
|
|
80
|
-
requestBody?: never;
|
|
81
215
|
parameters?: never;
|
|
216
|
+
requestBody?: never;
|
|
82
217
|
} | {
|
|
83
218
|
method: "get";
|
|
84
219
|
path: string;
|
|
@@ -123,8 +258,8 @@ export declare const HOST_PROJECT_COLLABORATION_OPENAPI_ROUTES: ({
|
|
|
123
258
|
};
|
|
124
259
|
};
|
|
125
260
|
querystring?: never;
|
|
126
|
-
requestBody?: never;
|
|
127
261
|
parameters?: never;
|
|
262
|
+
requestBody?: never;
|
|
128
263
|
} | {
|
|
129
264
|
method: "get";
|
|
130
265
|
path: string;
|
|
@@ -165,8 +300,8 @@ export declare const HOST_PROJECT_COLLABORATION_OPENAPI_ROUTES: ({
|
|
|
165
300
|
};
|
|
166
301
|
};
|
|
167
302
|
querystring?: never;
|
|
168
|
-
requestBody?: never;
|
|
169
303
|
parameters?: never;
|
|
304
|
+
requestBody?: never;
|
|
170
305
|
} | {
|
|
171
306
|
method: "post";
|
|
172
307
|
path: string;
|
|
@@ -294,8 +429,8 @@ export declare const HOST_PROJECT_COLLABORATION_OPENAPI_ROUTES: ({
|
|
|
294
429
|
};
|
|
295
430
|
};
|
|
296
431
|
querystring?: never;
|
|
297
|
-
requestBody?: never;
|
|
298
432
|
parameters?: never;
|
|
433
|
+
requestBody?: never;
|
|
299
434
|
} | {
|
|
300
435
|
method: "get";
|
|
301
436
|
path: string;
|
|
@@ -1,8 +1,35 @@
|
|
|
1
|
-
import { ActiveClarificationProjectionSchema, GetClarificationRoundMessagesRequestSchema, GetClarificationRoundResponseSchema, GetClarificationThreadResponseSchema, GetMessagesRequestSchema, MessageWindowSchema, RunSchedulerNowBodySchema, RunSchedulerNowResponseSchema, ScratchpadProjectionSchema, SendClarificationRoundMessageBodySchema, SendClarificationRoundMessageResponseSchema, SendMainChatMessageResponseSchema, SubmitClarificationRoundBodySchema, SubmitClarificationRoundResponseSchema, SubmitWorklistBodySchema, SubmitWorklistResponseSchema, WorklistProjectionSchema, } from "@tutti/shared/schemas/api";
|
|
1
|
+
import { ActiveClarificationProjectionSchema, ChatRequestStatusSchema, CurrentWorklistSubmissionSchema, WorklistSubmissionQuerySchema, GetClarificationRoundMessagesRequestSchema, GetClarificationRoundResponseSchema, GetClarificationThreadResponseSchema, GetMessagesRequestSchema, MessageWindowSchema, RunSchedulerNowBodySchema, RunSchedulerNowResponseSchema, ScratchpadProjectionSchema, SendClarificationRoundMessageBodySchema, SendClarificationRoundMessageResponseSchema, SendMainChatMessageResponseSchema, SubmitClarificationRoundBodySchema, SubmitClarificationRoundResponseSchema, SubmitWorklistBodySchema, SubmitWorklistResponseSchema, WorklistProjectionSchema, } from "@tutti/shared/schemas/api";
|
|
2
|
+
import { MessageIdSchema } from "@tutti/shared/schemas/domain";
|
|
2
3
|
import { HOST_PROJECT_API_BASE_PATH } from "./constants.js";
|
|
3
4
|
import { EventStreamResponseSchema, GetEventsRequestSchema, SendMainChatMessageBodySchema, } from "./schemas.js";
|
|
4
|
-
import { ClarificationRoundIdPathParameter, ClarificationThreadIdPathParameter, } from "./openapi-path-parameters.js";
|
|
5
|
+
import { ClarificationRoundIdPathParameter, pathParameter, ClarificationThreadIdPathParameter, } from "./openapi-path-parameters.js";
|
|
5
6
|
export const HOST_PROJECT_COLLABORATION_OPENAPI_ROUTES = [
|
|
7
|
+
{
|
|
8
|
+
method: "get",
|
|
9
|
+
path: `${HOST_PROJECT_API_BASE_PATH}/worklist/submission`,
|
|
10
|
+
summary: "Read the latest or identified Submit operation; acceptance is not completion.",
|
|
11
|
+
tags: ["worklist"],
|
|
12
|
+
querystring: WorklistSubmissionQuerySchema,
|
|
13
|
+
responses: {
|
|
14
|
+
200: {
|
|
15
|
+
description: "Submission evidence or null when not recorded.",
|
|
16
|
+
schema: CurrentWorklistSubmissionSchema,
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
method: "get",
|
|
22
|
+
path: `${HOST_PROJECT_API_BASE_PATH}/chat-requests/{message_id}`,
|
|
23
|
+
summary: "Read a durable answer request by its trigger message id.",
|
|
24
|
+
tags: ["messages"],
|
|
25
|
+
parameters: [pathParameter("message_id", MessageIdSchema, "Original question message id.")],
|
|
26
|
+
responses: {
|
|
27
|
+
200: {
|
|
28
|
+
description: "Host processing status, not platform delivery status.",
|
|
29
|
+
schema: ChatRequestStatusSchema,
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
},
|
|
6
33
|
{
|
|
7
34
|
method: "get",
|
|
8
35
|
path: `${HOST_PROJECT_API_BASE_PATH}/messages`,
|
|
@@ -25,6 +25,7 @@ export declare const HOST_PROJECT_SKILLS_OPENAPI_ROUTES: ({
|
|
|
25
25
|
message: import("@sinclair/typebox").TString;
|
|
26
26
|
retryable: import("@sinclair/typebox").TBoolean;
|
|
27
27
|
details: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnknown>;
|
|
28
|
+
request_id: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
28
29
|
}>;
|
|
29
30
|
}>;
|
|
30
31
|
};
|
|
@@ -60,6 +61,7 @@ export declare const HOST_PROJECT_SKILLS_OPENAPI_ROUTES: ({
|
|
|
60
61
|
message: import("@sinclair/typebox").TString;
|
|
61
62
|
retryable: import("@sinclair/typebox").TBoolean;
|
|
62
63
|
details: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnknown>;
|
|
64
|
+
request_id: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
63
65
|
}>;
|
|
64
66
|
}>;
|
|
65
67
|
};
|
|
@@ -575,6 +575,9 @@ export declare const HOST_PROJECT_WORKSPACE_OPENAPI_ROUTES: ({
|
|
|
575
575
|
readonly artifact_feedback: {
|
|
576
576
|
readonly type: "boolean";
|
|
577
577
|
};
|
|
578
|
+
readonly request_status_v1: {
|
|
579
|
+
readonly type: "boolean";
|
|
580
|
+
};
|
|
578
581
|
};
|
|
579
582
|
};
|
|
580
583
|
};
|
|
@@ -769,6 +772,9 @@ export declare const HOST_PROJECT_WORKSPACE_OPENAPI_ROUTES: ({
|
|
|
769
772
|
readonly artifact_feedback: {
|
|
770
773
|
readonly type: "boolean";
|
|
771
774
|
};
|
|
775
|
+
readonly request_status_v1: {
|
|
776
|
+
readonly type: "boolean";
|
|
777
|
+
};
|
|
772
778
|
};
|
|
773
779
|
};
|
|
774
780
|
};
|