@xfey/tutti 0.1.119 → 0.1.120
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/collaboration-state/clarification-snapshot.d.ts +9 -9
- package/dist/collaboration-state/task-compile-context.d.ts +1 -1
- package/dist/control-plane/workflows/openai.d.ts +3 -4
- package/dist/control-plane/workflows/openai.js +3 -2
- package/dist/providers/openai/app-server/invocation-coordinator.d.ts +1 -0
- package/dist/providers/openai/app-server/invocation-coordinator.js +4 -1
- package/dist/providers/openai/app-server/invocation-deadline.d.ts +3 -0
- package/dist/providers/openai/app-server/invocation-deadline.js +15 -0
- package/dist/providers/openai/app-server/read-only-procedure.d.ts +4 -2
- package/dist/providers/openai/app-server/read-only-procedure.js +16 -0
- package/dist/providers/openai/app-server/workspace-write-run.d.ts +4 -2
- package/dist/providers/openai/app-server/workspace-write-run.js +16 -0
- package/dist/providers/openai/chat-assistant.d.ts +3 -4
- package/dist/providers/openai/chat-assistant.js +2 -1
- package/dist/providers/openai/execution-access.d.ts +17 -0
- package/dist/providers/openai/execution-access.js +13 -0
- package/dist/providers/openai/sdk-procedure-runner.d.ts +2 -2
- package/dist/providers/openai/sdk-procedure-runner.js +17 -0
- package/dist/run-pipeline/artifact-applicability.d.ts +3 -4
- package/dist/run-pipeline/artifact-applicability.js +2 -1
- package/dist/run-pipeline/openai.d.ts +3 -4
- package/dist/run-pipeline/openai.js +3 -2
- package/dist/run-pipeline/task-run-invocation.js +6 -12
- package/dist/server-shell/cli/cli.js +3 -0
- package/dist/server-shell/cli/host-lifecycle.js +1 -0
- package/dist/server-shell/cli/host-server-runtime.d.ts +1 -0
- package/dist/server-shell/cli/host-server-runtime.js +83 -34
- package/dist/server-shell/cli/launch-command.js +1 -1
- package/dist/server-shell/cli/launch.d.ts +7 -3
- package/dist/server-shell/cli/launch.js +23 -4
- package/dist/server-shell/cli/machine-local.d.ts +9 -0
- package/dist/server-shell/cli/machine-local.js +60 -6
- package/dist/server-shell/cli/project-resolver.d.ts +2 -2
- package/dist/server-shell/cli/project-resolver.js +6 -3
- package/dist/server-shell/cli/relay-registration.js +38 -1
- package/dist/server-shell/http/routes/local-control.d.ts +1 -1
- package/dist/server-shell/http/routes/local-control.js +2 -46
- package/dist/server-shell/http/routes/project-api/openapi-workspace-routes.d.ts +47 -137
- package/dist/server-shell/http/routes/project-api/openapi.d.ts +47 -137
- package/dist/server-shell/http/routes/project-api/schemas.d.ts +25 -136
- package/dist/server-shell/http/routes/project-api/schemas.js +4 -58
- package/dist/server-shell/http/routes/project-api/types.d.ts +4 -0
- package/dist/server-shell/local-console/managed-project-routes.d.ts +9 -0
- package/dist/server-shell/local-console/managed-project-routes.js +120 -0
- package/dist/server-shell/local-console/managed-project-service.d.ts +151 -0
- package/dist/server-shell/local-console/managed-project-service.js +163 -0
- package/dist/server-shell/local-console/operation-coordinator.d.ts +1 -1
- package/dist/server-shell/local-console/package-update-hosts.js +2 -1
- package/dist/server-shell/local-console/project-service.d.ts +5 -1
- package/dist/server-shell/local-console/project-service.js +63 -14
- package/dist/server-shell/local-console/server.js +22 -2
- package/dist/server-shell/managed-access/execution-binding.d.ts +9 -0
- package/dist/server-shell/managed-access/execution-binding.js +22 -0
- package/dist/server-shell/managed-access/existing-project.d.ts +15 -0
- package/dist/server-shell/managed-access/existing-project.js +41 -0
- package/dist/server-shell/managed-access/model-control-client.d.ts +66 -0
- package/dist/server-shell/managed-access/model-control-client.js +114 -0
- package/dist/server-shell/managed-access/private-store.d.ts +19 -0
- package/dist/server-shell/managed-access/private-store.js +275 -0
- package/dist/server-shell/managed-access/project-provider.d.ts +18 -0
- package/dist/server-shell/managed-access/project-provider.js +30 -0
- package/dist/server-shell/managed-access/records.d.ts +108 -0
- package/dist/server-shell/managed-access/records.js +73 -0
- package/dist/server-shell/managed-access/runners.d.ts +11 -0
- package/dist/server-shell/managed-access/runners.js +103 -0
- package/dist/server-shell/managed-access/runtime-records.d.ts +110 -0
- package/dist/server-shell/managed-access/runtime-records.js +65 -0
- package/dist/server-shell/managed-access/runtime.d.ts +48 -0
- package/dist/server-shell/managed-access/runtime.js +301 -0
- package/dist/server-shell/managed-access/state.d.ts +54 -0
- package/dist/server-shell/managed-access/state.js +287 -0
- package/dist/server-shell/managed-access/transport.d.ts +48 -0
- package/dist/server-shell/managed-access/transport.js +38 -0
- package/dist/server-shell/managed-access/workspace.d.ts +10 -0
- package/dist/server-shell/managed-access/workspace.js +69 -0
- package/dist/server-shell/smoke/e2e-client.d.ts +8 -3
- package/dist/server-shell/smoke/e2e-client.js +11 -11
- package/node_modules/@tutti/relay-client/dist/host-control.d.ts +4 -1
- package/node_modules/@tutti/relay-client/dist/host-control.js +26 -3
- package/node_modules/@tutti/relay-client/dist/index.d.ts +1 -0
- package/node_modules/@tutti/relay-client/dist/index.js +1 -0
- package/node_modules/@tutti/relay-client/dist/project-authority.d.ts +75 -0
- package/node_modules/@tutti/relay-client/dist/project-authority.js +140 -0
- package/node_modules/@tutti/shared/dist/ids/index.d.ts +7 -0
- package/node_modules/@tutti/shared/dist/ids/index.js +7 -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/managed-account.d.ts +35 -0
- package/node_modules/@tutti/shared/dist/schemas/api/managed-account.js +41 -0
- package/node_modules/@tutti/shared/dist/schemas/api/provider-config.d.ts +8 -4
- package/node_modules/@tutti/shared/dist/schemas/api/provider-config.js +6 -0
- package/node_modules/@tutti/shared/dist/schemas/api/runtime-events.d.ts +4 -0
- package/node_modules/@tutti/shared/dist/schemas/internal/creation-validation.d.ts +28 -0
- package/node_modules/@tutti/shared/dist/schemas/internal/creation-validation.js +42 -0
- package/node_modules/@tutti/shared/dist/schemas/internal/index.d.ts +5 -0
- package/node_modules/@tutti/shared/dist/schemas/internal/index.js +5 -0
- package/node_modules/@tutti/shared/dist/schemas/internal/managed-account.d.ts +12 -0
- package/node_modules/@tutti/shared/dist/schemas/internal/managed-account.js +13 -0
- package/node_modules/@tutti/shared/dist/schemas/internal/managed-models.d.ts +17 -0
- package/node_modules/@tutti/shared/dist/schemas/internal/managed-models.js +17 -0
- package/node_modules/@tutti/shared/dist/schemas/internal/managed-runtime.d.ts +116 -0
- package/node_modules/@tutti/shared/dist/schemas/internal/managed-runtime.js +87 -0
- package/node_modules/@tutti/shared/dist/schemas/internal/project-authority.d.ts +120 -0
- package/node_modules/@tutti/shared/dist/schemas/internal/project-authority.js +110 -0
- package/package.json +1 -1
- package/web/assets/{homepage-motion-scene-B6lCCHBq.js → homepage-motion-scene-DyMFsYmT.js} +1 -1
- package/web/assets/index-DSlecDXC.js +70 -0
- package/web/index.html +1 -1
- package/web/assets/index-DepsYMLl.js +0 -70
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { Value } from "@sinclair/typebox/value";
|
|
2
|
+
import { ManagedSessionResultSchema, ManagedCredentialIssueResultSchema, ManagedCredentialRevokeResultSchema, ManagedRuntimeCredentialRefSchema, } from "@tutti/shared/schemas/internal";
|
|
3
|
+
import { managedRelayOrigin } from "./state.js";
|
|
4
|
+
import { ManagedLocalStateError } from "./private-store.js";
|
|
5
|
+
export class ManagedControlError extends ManagedLocalStateError {
|
|
6
|
+
status;
|
|
7
|
+
requestId;
|
|
8
|
+
constructor(code, status, requestId) {
|
|
9
|
+
super(code);
|
|
10
|
+
this.status = status;
|
|
11
|
+
this.requestId = requestId;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
const reasons = new Set([
|
|
15
|
+
"authority_invalid",
|
|
16
|
+
"host_delegation_revoked",
|
|
17
|
+
"delegated_tier_fixed",
|
|
18
|
+
"delegated_installation_fixed",
|
|
19
|
+
"session_not_found",
|
|
20
|
+
"session_tier_fixed",
|
|
21
|
+
"tier_unavailable",
|
|
22
|
+
"pinned_route_unavailable",
|
|
23
|
+
"gateway_route_drift",
|
|
24
|
+
"credential_request_mismatch",
|
|
25
|
+
"credential_creation_unknown",
|
|
26
|
+
"credential_policy_mismatch",
|
|
27
|
+
"device_credential_exists",
|
|
28
|
+
"credential_limit",
|
|
29
|
+
"credential_revocation_unknown",
|
|
30
|
+
"gateway_transport_unknown",
|
|
31
|
+
"gateway_rate_limited",
|
|
32
|
+
"gateway_rejected",
|
|
33
|
+
"gateway_response_invalid",
|
|
34
|
+
"control_queue_full",
|
|
35
|
+
]);
|
|
36
|
+
export class NativeModelControlClient {
|
|
37
|
+
options;
|
|
38
|
+
constructor(options) {
|
|
39
|
+
this.options = options;
|
|
40
|
+
}
|
|
41
|
+
async request(path, body, schema) {
|
|
42
|
+
const authority = await this.options.authorize();
|
|
43
|
+
try {
|
|
44
|
+
const origin = managedRelayOrigin(authority.control_origin);
|
|
45
|
+
const response = await (this.options.fetchImpl ?? fetch)(new URL(path, origin), {
|
|
46
|
+
method: "POST",
|
|
47
|
+
redirect: "error",
|
|
48
|
+
signal: AbortSignal.timeout(55_000),
|
|
49
|
+
headers: {
|
|
50
|
+
"content-type": "application/json",
|
|
51
|
+
authorization: `Bearer ${authority.authorization}`,
|
|
52
|
+
},
|
|
53
|
+
body: JSON.stringify(body),
|
|
54
|
+
});
|
|
55
|
+
const header = response.headers.get("x-tutti-request-id");
|
|
56
|
+
const requestId = header && /^[A-Za-z0-9_-]{1,100}$/.test(header) ? header : undefined;
|
|
57
|
+
const reader = response.body?.getReader();
|
|
58
|
+
if (!reader)
|
|
59
|
+
throw new ManagedControlError("managed_control_invalid_response", response.status, requestId);
|
|
60
|
+
const chunks = [];
|
|
61
|
+
let size = 0;
|
|
62
|
+
try {
|
|
63
|
+
for (;;) {
|
|
64
|
+
const item = await reader.read();
|
|
65
|
+
if (item.done)
|
|
66
|
+
break;
|
|
67
|
+
if (!(item.value instanceof Uint8Array))
|
|
68
|
+
throw new ManagedControlError("managed_control_invalid_response", response.status, requestId);
|
|
69
|
+
size += item.value.byteLength;
|
|
70
|
+
if (size > 16 * 1024)
|
|
71
|
+
throw new ManagedControlError("managed_control_invalid_response", response.status, requestId);
|
|
72
|
+
chunks.push(item.value);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
finally {
|
|
76
|
+
await reader.cancel().catch(() => undefined);
|
|
77
|
+
reader.releaseLock();
|
|
78
|
+
}
|
|
79
|
+
let value;
|
|
80
|
+
try {
|
|
81
|
+
value = JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
throw new ManagedControlError("managed_control_invalid_response", response.status, requestId);
|
|
85
|
+
}
|
|
86
|
+
if (!response.ok) {
|
|
87
|
+
const reason = value?.error?.code;
|
|
88
|
+
throw new ManagedControlError(typeof reason === "string" && reasons.has(reason)
|
|
89
|
+
? reason
|
|
90
|
+
: "managed_control_unavailable", response.status, requestId);
|
|
91
|
+
}
|
|
92
|
+
if (!Value.Check(schema, value))
|
|
93
|
+
throw new ManagedControlError("managed_control_invalid_response", response.status, requestId);
|
|
94
|
+
return value;
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
if (error instanceof ManagedLocalStateError)
|
|
98
|
+
throw error;
|
|
99
|
+
throw new ManagedControlError("managed_control_unavailable");
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
pin(sessionRef, routeRef) {
|
|
103
|
+
return this.request("/v2/sessions", { session_ref: sessionRef, ...(routeRef === undefined ? {} : { route_ref: routeRef }) }, ManagedSessionResultSchema);
|
|
104
|
+
}
|
|
105
|
+
issue(sessionRef, requestRef) {
|
|
106
|
+
return this.request("/v2/credentials", { session_ref: sessionRef, request_ref: requestRef }, ManagedCredentialIssueResultSchema);
|
|
107
|
+
}
|
|
108
|
+
revoke(credentialRef) {
|
|
109
|
+
if (!Value.Check(ManagedRuntimeCredentialRefSchema, credentialRef))
|
|
110
|
+
throw new ManagedControlError("managed_control_invalid_request");
|
|
111
|
+
return this.request(`/v2/credentials/${credentialRef}/revoke`, {}, ManagedCredentialRevokeResultSchema);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=model-control-client.js.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare class ManagedLocalStateError extends Error {
|
|
2
|
+
readonly code: string;
|
|
3
|
+
constructor(code: string);
|
|
4
|
+
}
|
|
5
|
+
export declare function isWithin(parent: string, target: string): boolean;
|
|
6
|
+
export declare function ensureManagedPrivateRoot(tuttiHome: string, originHash: string): string;
|
|
7
|
+
export declare class ManagedPrivateStore {
|
|
8
|
+
readonly root: string;
|
|
9
|
+
private readonly identity;
|
|
10
|
+
constructor(root: string);
|
|
11
|
+
private checkRoot;
|
|
12
|
+
private path;
|
|
13
|
+
read(name: string): unknown;
|
|
14
|
+
write(name: string, value: unknown, exclusive?: boolean): boolean;
|
|
15
|
+
transaction<T>(run: () => T): T;
|
|
16
|
+
acquireExecutionLease(name: string): () => void;
|
|
17
|
+
private syncDirectory;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=private-store.d.ts.map
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { closeSync, constants, existsSync, fstatSync, fsyncSync, linkSync, lstatSync, mkdirSync, openSync, readSync, realpathSync, renameSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
3
|
+
import { dirname, isAbsolute, join, relative } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import Database from "better-sqlite3";
|
|
6
|
+
const MAX_PRIVATE_BYTES = 32 * 1024;
|
|
7
|
+
const packageRoot = realpathSync(fileURLToPath(new URL("../../../", import.meta.url)));
|
|
8
|
+
export class ManagedLocalStateError extends Error {
|
|
9
|
+
code;
|
|
10
|
+
constructor(code) {
|
|
11
|
+
super(code);
|
|
12
|
+
this.code = code;
|
|
13
|
+
this.name = "ManagedLocalStateError";
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function systemCode(error) {
|
|
17
|
+
return typeof error === "object" && error !== null && "code" in error ? error.code : undefined;
|
|
18
|
+
}
|
|
19
|
+
function unlinkIfPresent(path) {
|
|
20
|
+
try {
|
|
21
|
+
unlinkSync(path);
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
if (systemCode(error) !== "ENOENT")
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export function isWithin(parent, target) {
|
|
29
|
+
const path = relative(parent, target);
|
|
30
|
+
return path === "" || (!path.startsWith("../") && path !== ".." && !isAbsolute(path));
|
|
31
|
+
}
|
|
32
|
+
function guard(run) {
|
|
33
|
+
try {
|
|
34
|
+
return run();
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
if (error instanceof ManagedLocalStateError)
|
|
38
|
+
throw error;
|
|
39
|
+
throw new ManagedLocalStateError("managed_private_state_unavailable");
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Ancestors such as /var -> /private/var may be OS aliases. The selected Home and
|
|
43
|
+
// every directory we own below it must be actual owner-only directories, not links.
|
|
44
|
+
export function ensureManagedPrivateRoot(tuttiHome, originHash) {
|
|
45
|
+
return guard(() => {
|
|
46
|
+
if (!isAbsolute(tuttiHome) || !/^[a-f0-9]{64}$/.test(originHash))
|
|
47
|
+
throw new ManagedLocalStateError("managed_private_directory_invalid");
|
|
48
|
+
let ancestor = tuttiHome;
|
|
49
|
+
while (!existsSync(ancestor) && dirname(ancestor) !== ancestor)
|
|
50
|
+
ancestor = dirname(ancestor);
|
|
51
|
+
const proposed = join(realpathSync(ancestor), relative(ancestor, tuttiHome));
|
|
52
|
+
if (isWithin(packageRoot, proposed))
|
|
53
|
+
throw new ManagedLocalStateError("managed_state_in_repository");
|
|
54
|
+
for (let path = proposed; dirname(path) !== path; path = dirname(path)) {
|
|
55
|
+
if (existsSync(join(path, ".git")))
|
|
56
|
+
throw new ManagedLocalStateError("managed_state_in_repository");
|
|
57
|
+
}
|
|
58
|
+
for (const path of [
|
|
59
|
+
tuttiHome,
|
|
60
|
+
join(tuttiHome, "credentials"),
|
|
61
|
+
join(tuttiHome, "credentials", "managed"),
|
|
62
|
+
join(tuttiHome, "credentials", "managed", originHash),
|
|
63
|
+
]) {
|
|
64
|
+
mkdirSync(path, { recursive: true, mode: 0o700 });
|
|
65
|
+
const stat = lstatSync(path);
|
|
66
|
+
if (!stat.isDirectory() ||
|
|
67
|
+
stat.isSymbolicLink() ||
|
|
68
|
+
stat.uid !== process.getuid?.() ||
|
|
69
|
+
stat.mode & 0o077)
|
|
70
|
+
throw new ManagedLocalStateError("managed_private_directory_invalid");
|
|
71
|
+
}
|
|
72
|
+
return realpathSync(join(tuttiHome, "credentials", "managed", originHash));
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
export class ManagedPrivateStore {
|
|
76
|
+
root;
|
|
77
|
+
identity;
|
|
78
|
+
constructor(root) {
|
|
79
|
+
// Normalize OS ancestor aliases, but do not accept a linked selected directory.
|
|
80
|
+
if (guard(() => lstatSync(root).isSymbolicLink()))
|
|
81
|
+
throw new ManagedLocalStateError("managed_private_directory_invalid");
|
|
82
|
+
this.root = guard(() => realpathSync(root));
|
|
83
|
+
this.identity = guard(() => this.checkRoot());
|
|
84
|
+
}
|
|
85
|
+
checkRoot() {
|
|
86
|
+
const stat = lstatSync(this.root);
|
|
87
|
+
if (!stat.isDirectory() ||
|
|
88
|
+
stat.isSymbolicLink() ||
|
|
89
|
+
stat.uid !== process.getuid?.() ||
|
|
90
|
+
stat.mode & 0o077 ||
|
|
91
|
+
realpathSync(this.root) !== this.root ||
|
|
92
|
+
(this.identity !== undefined &&
|
|
93
|
+
(stat.dev !== this.identity.dev || stat.ino !== this.identity.ino)))
|
|
94
|
+
throw new ManagedLocalStateError("managed_private_directory_invalid");
|
|
95
|
+
return { dev: stat.dev, ino: stat.ino };
|
|
96
|
+
}
|
|
97
|
+
path(name) {
|
|
98
|
+
if (!/^[a-zA-Z0-9_-]{1,120}\.json$/.test(name))
|
|
99
|
+
throw new ManagedLocalStateError("managed_record_name_invalid");
|
|
100
|
+
return join(this.root, name);
|
|
101
|
+
}
|
|
102
|
+
read(name) {
|
|
103
|
+
return guard(() => {
|
|
104
|
+
this.checkRoot();
|
|
105
|
+
let fd;
|
|
106
|
+
try {
|
|
107
|
+
fd = openSync(this.path(name), constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
if (systemCode(error) === "ENOENT")
|
|
111
|
+
return null;
|
|
112
|
+
throw error;
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
const stat = fstatSync(fd);
|
|
116
|
+
if (!stat.isFile() ||
|
|
117
|
+
stat.uid !== process.getuid?.() ||
|
|
118
|
+
stat.mode & 0o077 ||
|
|
119
|
+
stat.nlink !== 1 ||
|
|
120
|
+
stat.size > MAX_PRIVATE_BYTES)
|
|
121
|
+
throw new ManagedLocalStateError("managed_private_file_invalid");
|
|
122
|
+
// A file can grow after fstat. Bound the allocation and every read as well.
|
|
123
|
+
const bytes = Buffer.alloc(MAX_PRIVATE_BYTES + 1);
|
|
124
|
+
let size = 0;
|
|
125
|
+
while (size < bytes.length) {
|
|
126
|
+
const count = readSync(fd, bytes, size, bytes.length - size, null);
|
|
127
|
+
if (count === 0)
|
|
128
|
+
break;
|
|
129
|
+
size += count;
|
|
130
|
+
}
|
|
131
|
+
if (size > MAX_PRIVATE_BYTES)
|
|
132
|
+
throw new ManagedLocalStateError("managed_private_file_invalid");
|
|
133
|
+
return JSON.parse(bytes.toString("utf8", 0, size));
|
|
134
|
+
}
|
|
135
|
+
finally {
|
|
136
|
+
closeSync(fd);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
write(name, value, exclusive = false) {
|
|
141
|
+
return guard(() => {
|
|
142
|
+
const path = this.path(name);
|
|
143
|
+
const body = JSON.stringify(value) + "\n";
|
|
144
|
+
if (Buffer.byteLength(body) > MAX_PRIVATE_BYTES)
|
|
145
|
+
throw new ManagedLocalStateError("managed_private_file_invalid");
|
|
146
|
+
// Validate an existing destination instead of overwriting an unknown / linked file.
|
|
147
|
+
if (this.read(name) !== null && exclusive)
|
|
148
|
+
return false;
|
|
149
|
+
const temp = join(this.root, `.write-${randomBytes(16).toString("hex")}`);
|
|
150
|
+
try {
|
|
151
|
+
const fd = openSync(temp, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600);
|
|
152
|
+
try {
|
|
153
|
+
writeFileSync(fd, body);
|
|
154
|
+
fsyncSync(fd);
|
|
155
|
+
}
|
|
156
|
+
finally {
|
|
157
|
+
closeSync(fd);
|
|
158
|
+
}
|
|
159
|
+
this.checkRoot();
|
|
160
|
+
if (exclusive) {
|
|
161
|
+
try {
|
|
162
|
+
linkSync(temp, path);
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
if (systemCode(error) === "EEXIST")
|
|
166
|
+
return false;
|
|
167
|
+
throw error;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
renameSync(temp, path);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
finally {
|
|
175
|
+
unlinkIfPresent(temp);
|
|
176
|
+
this.syncDirectory();
|
|
177
|
+
}
|
|
178
|
+
return true;
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
// SQLite is only an OS-released cross-process mutex here: no schema, metadata or
|
|
182
|
+
// secrets are stored in it. Crash recovery never unlinks another process's lock.
|
|
183
|
+
// This callback is intentionally synchronous: never hold it across network I/O.
|
|
184
|
+
transaction(run) {
|
|
185
|
+
return guard(() => {
|
|
186
|
+
this.checkRoot();
|
|
187
|
+
const path = join(this.root, "serialization.sqlite");
|
|
188
|
+
try {
|
|
189
|
+
const fd = openSync(path, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600);
|
|
190
|
+
closeSync(fd);
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
if (systemCode(error) !== "EEXIST")
|
|
194
|
+
throw error;
|
|
195
|
+
}
|
|
196
|
+
const stat = lstatSync(path);
|
|
197
|
+
if (!stat.isFile() ||
|
|
198
|
+
stat.isSymbolicLink() ||
|
|
199
|
+
stat.uid !== process.getuid?.() ||
|
|
200
|
+
stat.mode & 0o077 ||
|
|
201
|
+
stat.nlink !== 1)
|
|
202
|
+
throw new ManagedLocalStateError("managed_private_file_invalid");
|
|
203
|
+
const lock = new Database(path, { timeout: 1000 });
|
|
204
|
+
try {
|
|
205
|
+
lock.exec("BEGIN IMMEDIATE");
|
|
206
|
+
const result = run();
|
|
207
|
+
if (result && typeof result === "object" && "then" in result)
|
|
208
|
+
throw new ManagedLocalStateError("managed_transaction_must_be_synchronous");
|
|
209
|
+
lock.exec("COMMIT");
|
|
210
|
+
return result;
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
if (systemCode(error) === "SQLITE_BUSY")
|
|
214
|
+
throw new ManagedLocalStateError("managed_state_busy");
|
|
215
|
+
throw error;
|
|
216
|
+
}
|
|
217
|
+
finally {
|
|
218
|
+
lock.close();
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
// Separate per-model-session execution lease. Unlike the short journal mutex,
|
|
223
|
+
// this lock deliberately spans one bounded model invocation. It stores no data,
|
|
224
|
+
// fails immediately on contention, and is released by the OS if the Host dies.
|
|
225
|
+
acquireExecutionLease(name) {
|
|
226
|
+
return guard(() => {
|
|
227
|
+
if (!/^(model|workspace)-[a-f0-9]{64}$/.test(name))
|
|
228
|
+
throw new ManagedLocalStateError("managed_record_name_invalid");
|
|
229
|
+
this.checkRoot();
|
|
230
|
+
const path = join(this.root, `${name}.sqlite`);
|
|
231
|
+
try {
|
|
232
|
+
const fd = openSync(path, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600);
|
|
233
|
+
closeSync(fd);
|
|
234
|
+
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
if (systemCode(error) !== "EEXIST")
|
|
237
|
+
throw error;
|
|
238
|
+
}
|
|
239
|
+
const stat = lstatSync(path);
|
|
240
|
+
if (!stat.isFile() ||
|
|
241
|
+
stat.isSymbolicLink() ||
|
|
242
|
+
stat.uid !== process.getuid?.() ||
|
|
243
|
+
stat.mode & 0o077 ||
|
|
244
|
+
stat.nlink !== 1)
|
|
245
|
+
throw new ManagedLocalStateError("managed_private_file_invalid");
|
|
246
|
+
const lock = new Database(path, { timeout: 0 });
|
|
247
|
+
try {
|
|
248
|
+
lock.exec("BEGIN IMMEDIATE");
|
|
249
|
+
}
|
|
250
|
+
catch (error) {
|
|
251
|
+
lock.close();
|
|
252
|
+
if (systemCode(error) === "SQLITE_BUSY")
|
|
253
|
+
throw new ManagedLocalStateError(name.startsWith("workspace-") ? "managed_workspace_busy" : "managed_session_busy");
|
|
254
|
+
throw error;
|
|
255
|
+
}
|
|
256
|
+
let released = false;
|
|
257
|
+
return () => {
|
|
258
|
+
if (!released) {
|
|
259
|
+
released = true;
|
|
260
|
+
lock.close();
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
syncDirectory() {
|
|
266
|
+
const fd = openSync(this.root, constants.O_RDONLY);
|
|
267
|
+
try {
|
|
268
|
+
fsyncSync(fd);
|
|
269
|
+
}
|
|
270
|
+
finally {
|
|
271
|
+
closeSync(fd);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=private-store.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ProjectId } from "@tutti/shared/ids";
|
|
2
|
+
import type { ProviderConfigProjection } from "@tutti/shared/schemas/api";
|
|
3
|
+
import { NativeManagedRuntime, type ManagedRuntimeObservation } from "./runtime.js";
|
|
4
|
+
export declare function readProjectModelAccess(options: {
|
|
5
|
+
tuttiHome: string;
|
|
6
|
+
relayUrl: string;
|
|
7
|
+
projectId: ProjectId;
|
|
8
|
+
}): ProviderConfigProjection;
|
|
9
|
+
export declare function hasProjectModelConfiguration(projection: ProviderConfigProjection): boolean;
|
|
10
|
+
export declare function createNativeManagedHostRuntime(options: {
|
|
11
|
+
tuttiHome: string;
|
|
12
|
+
relayUrl: string;
|
|
13
|
+
projectId: ProjectId;
|
|
14
|
+
workspaceRoot: string;
|
|
15
|
+
surface: "standalone" | "feishu";
|
|
16
|
+
observe?: (event: ManagedRuntimeObservation) => void;
|
|
17
|
+
}): NativeManagedRuntime | null;
|
|
18
|
+
//# sourceMappingURL=project-provider.d.ts.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { realpathSync } from "node:fs";
|
|
2
|
+
import { readOpenAiProviderConfigProjection } from "../../providers/openai/provider-config.js";
|
|
3
|
+
import { findNativeManagedProject } from "./state.js";
|
|
4
|
+
import { readHostRegistrationSecret } from "../cli/machine-local.js";
|
|
5
|
+
import { ManagedLocalStateError } from "./private-store.js";
|
|
6
|
+
import { NativeManagedRuntime } from "./runtime.js";
|
|
7
|
+
// A mode projection, not a promise that current remote authority or quota is
|
|
8
|
+
// available. Every actual managed invocation independently verifies both.
|
|
9
|
+
export function readProjectModelAccess(options) {
|
|
10
|
+
const native = findNativeManagedProject(options);
|
|
11
|
+
if (native !== null) {
|
|
12
|
+
return { status: "managed", funding_kind: "trial", tier: native.journal.tier };
|
|
13
|
+
}
|
|
14
|
+
return readOpenAiProviderConfigProjection(options);
|
|
15
|
+
}
|
|
16
|
+
export function hasProjectModelConfiguration(projection) {
|
|
17
|
+
return projection.status === "configured" || projection.status === "managed";
|
|
18
|
+
}
|
|
19
|
+
export function createNativeManagedHostRuntime(options) {
|
|
20
|
+
const managed = findNativeManagedProject(options);
|
|
21
|
+
if (managed === null)
|
|
22
|
+
return null;
|
|
23
|
+
if (managed.journal.workspace_root !== realpathSync(options.workspaceRoot) ||
|
|
24
|
+
managed.journal.surface !== options.surface ||
|
|
25
|
+
managed.journal.host_registration_secret !==
|
|
26
|
+
readHostRegistrationSecret(options.tuttiHome, options.projectId).secret)
|
|
27
|
+
throw new ManagedLocalStateError("managed_registration_mismatch");
|
|
28
|
+
return new NativeManagedRuntime(options);
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=project-provider.js.map
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { type Static } from "@sinclair/typebox";
|
|
2
|
+
import type { ProjectId } from "@tutti/shared/ids";
|
|
3
|
+
export declare const InstallationSchema: import("@sinclair/typebox").TObject<{
|
|
4
|
+
version: import("@sinclair/typebox").TLiteral<1>;
|
|
5
|
+
relay_origin: import("@sinclair/typebox").TString;
|
|
6
|
+
installation_ref: import("@sinclair/typebox").TString;
|
|
7
|
+
secret: import("@sinclair/typebox").TString;
|
|
8
|
+
created_at: import("@sinclair/typebox").TString;
|
|
9
|
+
}>;
|
|
10
|
+
export type Installation = Static<typeof InstallationSchema>;
|
|
11
|
+
export declare const CreationJournalSchema: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TObject<{
|
|
12
|
+
state: import("@sinclair/typebox").TLiteral<"awaiting_authorization">;
|
|
13
|
+
version: import("@sinclair/typebox").TLiteral<1>;
|
|
14
|
+
request_ref: import("@sinclair/typebox").TString;
|
|
15
|
+
project_id: import("@sinclair/typebox").TString;
|
|
16
|
+
relay_origin: import("@sinclair/typebox").TString;
|
|
17
|
+
installation_ref: import("@sinclair/typebox").TString;
|
|
18
|
+
workspace_root: import("@sinclair/typebox").TString;
|
|
19
|
+
display_name: import("@sinclair/typebox").TString;
|
|
20
|
+
description: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
21
|
+
surface: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"standalone">, import("@sinclair/typebox").TLiteral<"feishu">]>;
|
|
22
|
+
tier: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"light">, import("@sinclair/typebox").TLiteral<"high">, import("@sinclair/typebox").TLiteral<"max">]>;
|
|
23
|
+
existing_relay_project_ref: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
24
|
+
previous_request_ref: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
25
|
+
handoff_token: import("@sinclair/typebox").TString;
|
|
26
|
+
host_registration_secret: import("@sinclair/typebox").TString;
|
|
27
|
+
created_at: import("@sinclair/typebox").TString;
|
|
28
|
+
expires_at: import("@sinclair/typebox").TString;
|
|
29
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
30
|
+
state: import("@sinclair/typebox").TLiteral<"prepared">;
|
|
31
|
+
creation_ref: import("@sinclair/typebox").TString;
|
|
32
|
+
version: import("@sinclair/typebox").TLiteral<1>;
|
|
33
|
+
request_ref: import("@sinclair/typebox").TString;
|
|
34
|
+
project_id: import("@sinclair/typebox").TString;
|
|
35
|
+
relay_origin: import("@sinclair/typebox").TString;
|
|
36
|
+
installation_ref: import("@sinclair/typebox").TString;
|
|
37
|
+
workspace_root: import("@sinclair/typebox").TString;
|
|
38
|
+
display_name: import("@sinclair/typebox").TString;
|
|
39
|
+
description: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
40
|
+
surface: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"standalone">, import("@sinclair/typebox").TLiteral<"feishu">]>;
|
|
41
|
+
tier: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"light">, import("@sinclair/typebox").TLiteral<"high">, import("@sinclair/typebox").TLiteral<"max">]>;
|
|
42
|
+
existing_relay_project_ref: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
43
|
+
previous_request_ref: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
44
|
+
handoff_token: import("@sinclair/typebox").TString;
|
|
45
|
+
host_registration_secret: import("@sinclair/typebox").TString;
|
|
46
|
+
created_at: import("@sinclair/typebox").TString;
|
|
47
|
+
expires_at: import("@sinclair/typebox").TString;
|
|
48
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
49
|
+
state: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"validated">, import("@sinclair/typebox").TLiteral<"validation_unknown">, import("@sinclair/typebox").TLiteral<"validation_failed">]>;
|
|
50
|
+
creation_ref: import("@sinclair/typebox").TString;
|
|
51
|
+
version: import("@sinclair/typebox").TLiteral<1>;
|
|
52
|
+
request_ref: import("@sinclair/typebox").TString;
|
|
53
|
+
project_id: import("@sinclair/typebox").TString;
|
|
54
|
+
relay_origin: import("@sinclair/typebox").TString;
|
|
55
|
+
installation_ref: import("@sinclair/typebox").TString;
|
|
56
|
+
workspace_root: import("@sinclair/typebox").TString;
|
|
57
|
+
display_name: import("@sinclair/typebox").TString;
|
|
58
|
+
description: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
59
|
+
surface: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"standalone">, import("@sinclair/typebox").TLiteral<"feishu">]>;
|
|
60
|
+
tier: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"light">, import("@sinclair/typebox").TLiteral<"high">, import("@sinclair/typebox").TLiteral<"max">]>;
|
|
61
|
+
existing_relay_project_ref: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
62
|
+
previous_request_ref: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
63
|
+
handoff_token: import("@sinclair/typebox").TString;
|
|
64
|
+
host_registration_secret: import("@sinclair/typebox").TString;
|
|
65
|
+
created_at: import("@sinclair/typebox").TString;
|
|
66
|
+
expires_at: import("@sinclair/typebox").TString;
|
|
67
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
68
|
+
state: import("@sinclair/typebox").TLiteral<"registered">;
|
|
69
|
+
creation_ref: import("@sinclair/typebox").TString;
|
|
70
|
+
authority: import("@sinclair/typebox").TObject<{
|
|
71
|
+
delegation_ref: import("@sinclair/typebox").TString;
|
|
72
|
+
grant_ref: import("@sinclair/typebox").TString;
|
|
73
|
+
relay_project_ref: import("@sinclair/typebox").TString;
|
|
74
|
+
installation_ref: import("@sinclair/typebox").TString;
|
|
75
|
+
tier: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"light">, import("@sinclair/typebox").TLiteral<"high">, import("@sinclair/typebox").TLiteral<"max">]>;
|
|
76
|
+
funding_kind: import("@sinclair/typebox").TLiteral<"trial">;
|
|
77
|
+
expires_at: import("@sinclair/typebox").TNull;
|
|
78
|
+
state: import("@sinclair/typebox").TLiteral<"active">;
|
|
79
|
+
model_access: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"runtime_authority_required">, import("@sinclair/typebox").TLiteral<"not_enabled">]>;
|
|
80
|
+
}>;
|
|
81
|
+
version: import("@sinclair/typebox").TLiteral<1>;
|
|
82
|
+
request_ref: import("@sinclair/typebox").TString;
|
|
83
|
+
project_id: import("@sinclair/typebox").TString;
|
|
84
|
+
relay_origin: import("@sinclair/typebox").TString;
|
|
85
|
+
installation_ref: import("@sinclair/typebox").TString;
|
|
86
|
+
workspace_root: import("@sinclair/typebox").TString;
|
|
87
|
+
display_name: import("@sinclair/typebox").TString;
|
|
88
|
+
description: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
89
|
+
surface: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"standalone">, import("@sinclair/typebox").TLiteral<"feishu">]>;
|
|
90
|
+
tier: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"light">, import("@sinclair/typebox").TLiteral<"high">, import("@sinclair/typebox").TLiteral<"max">]>;
|
|
91
|
+
existing_relay_project_ref: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
92
|
+
previous_request_ref: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
93
|
+
handoff_token: import("@sinclair/typebox").TString;
|
|
94
|
+
host_registration_secret: import("@sinclair/typebox").TString;
|
|
95
|
+
created_at: import("@sinclair/typebox").TString;
|
|
96
|
+
expires_at: import("@sinclair/typebox").TString;
|
|
97
|
+
}>]>;
|
|
98
|
+
export type CreationJournal = Static<typeof CreationJournalSchema> & {
|
|
99
|
+
project_id: ProjectId;
|
|
100
|
+
};
|
|
101
|
+
export declare const NativeProjectPointerSchema: import("@sinclair/typebox").TObject<{
|
|
102
|
+
version: import("@sinclair/typebox").TLiteral<1>;
|
|
103
|
+
project_id: import("@sinclair/typebox").TString;
|
|
104
|
+
request_ref: import("@sinclair/typebox").TString;
|
|
105
|
+
}>;
|
|
106
|
+
export declare function parseInstallation(raw: unknown, origin: string): Installation;
|
|
107
|
+
export declare function parseJournal(raw: unknown, origin: string, requestRef: string): CreationJournal;
|
|
108
|
+
//# sourceMappingURL=records.d.ts.map
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Type } from "@sinclair/typebox";
|
|
2
|
+
import { Value } from "@sinclair/typebox/value";
|
|
3
|
+
import { IdempotencyKeySchema, ProjectIdSchema, RelayProjectRefSchema, } from "@tutti/shared/schemas/domain";
|
|
4
|
+
import { AuthoritySecretSchema, AuthorityTimestampSchema, isAuthorityTimestamp, HostInstallationRefSchema, HostDelegationProjectionSchema, ManagedCreationRefSchema, ManagedTierSchema, } from "@tutti/shared/schemas/internal";
|
|
5
|
+
import { ManagedLocalStateError } from "./private-store.js";
|
|
6
|
+
export const InstallationSchema = Type.Object({
|
|
7
|
+
version: Type.Literal(1),
|
|
8
|
+
relay_origin: Type.String({ maxLength: 500 }),
|
|
9
|
+
installation_ref: HostInstallationRefSchema,
|
|
10
|
+
secret: AuthoritySecretSchema,
|
|
11
|
+
created_at: AuthorityTimestampSchema,
|
|
12
|
+
}, { additionalProperties: false });
|
|
13
|
+
const DraftFields = {
|
|
14
|
+
version: Type.Literal(1),
|
|
15
|
+
request_ref: IdempotencyKeySchema,
|
|
16
|
+
project_id: ProjectIdSchema,
|
|
17
|
+
relay_origin: Type.String({ maxLength: 500 }),
|
|
18
|
+
installation_ref: HostInstallationRefSchema,
|
|
19
|
+
workspace_root: Type.String({ minLength: 1, maxLength: 4096 }),
|
|
20
|
+
display_name: Type.String({ minLength: 1, maxLength: 80 }),
|
|
21
|
+
description: Type.Optional(Type.String({ maxLength: 160 })),
|
|
22
|
+
surface: Type.Union([Type.Literal("standalone"), Type.Literal("feishu")]),
|
|
23
|
+
tier: ManagedTierSchema,
|
|
24
|
+
existing_relay_project_ref: Type.Optional(RelayProjectRefSchema),
|
|
25
|
+
previous_request_ref: Type.Optional(IdempotencyKeySchema),
|
|
26
|
+
handoff_token: AuthoritySecretSchema,
|
|
27
|
+
host_registration_secret: AuthoritySecretSchema,
|
|
28
|
+
created_at: AuthorityTimestampSchema,
|
|
29
|
+
expires_at: AuthorityTimestampSchema,
|
|
30
|
+
};
|
|
31
|
+
export const CreationJournalSchema = Type.Union([
|
|
32
|
+
Type.Object({ ...DraftFields, state: Type.Literal("awaiting_authorization") }, { additionalProperties: false }),
|
|
33
|
+
Type.Object({ ...DraftFields, state: Type.Literal("prepared"), creation_ref: ManagedCreationRefSchema }, { additionalProperties: false }),
|
|
34
|
+
Type.Object({
|
|
35
|
+
...DraftFields,
|
|
36
|
+
state: Type.Union([
|
|
37
|
+
Type.Literal("validated"),
|
|
38
|
+
Type.Literal("validation_unknown"),
|
|
39
|
+
Type.Literal("validation_failed"),
|
|
40
|
+
]),
|
|
41
|
+
creation_ref: ManagedCreationRefSchema,
|
|
42
|
+
}, { additionalProperties: false }),
|
|
43
|
+
Type.Object({
|
|
44
|
+
...DraftFields,
|
|
45
|
+
state: Type.Literal("registered"),
|
|
46
|
+
creation_ref: ManagedCreationRefSchema,
|
|
47
|
+
authority: HostDelegationProjectionSchema,
|
|
48
|
+
}, { additionalProperties: false }),
|
|
49
|
+
]);
|
|
50
|
+
export const NativeProjectPointerSchema = Type.Object({
|
|
51
|
+
version: Type.Literal(1),
|
|
52
|
+
project_id: ProjectIdSchema,
|
|
53
|
+
request_ref: IdempotencyKeySchema,
|
|
54
|
+
}, { additionalProperties: false });
|
|
55
|
+
export function parseInstallation(raw, origin) {
|
|
56
|
+
if (!Value.Check(InstallationSchema, raw) ||
|
|
57
|
+
raw.relay_origin !== origin ||
|
|
58
|
+
!isAuthorityTimestamp(raw.created_at))
|
|
59
|
+
throw new ManagedLocalStateError("managed_installation_invalid");
|
|
60
|
+
return raw;
|
|
61
|
+
}
|
|
62
|
+
export function parseJournal(raw, origin, requestRef) {
|
|
63
|
+
if (!Value.Check(CreationJournalSchema, raw) ||
|
|
64
|
+
raw.relay_origin !== origin ||
|
|
65
|
+
raw.request_ref !== requestRef ||
|
|
66
|
+
!isAuthorityTimestamp(raw.created_at) ||
|
|
67
|
+
!isAuthorityTimestamp(raw.expires_at) ||
|
|
68
|
+
raw.expires_at <= raw.created_at)
|
|
69
|
+
throw new ManagedLocalStateError("managed_journal_invalid");
|
|
70
|
+
// ProjectIdSchema checked the complete branded ID pattern above.
|
|
71
|
+
return raw;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=records.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ReadOnlyChatAssistantModel } from "../../chat-assistant/index.js";
|
|
2
|
+
import type { RunPipelineRunner } from "../../control-plane/index.js";
|
|
3
|
+
import { type ProjectOpenAiProcedureWorkflowRunnerOptions } from "../../control-plane/workflows/openai.js";
|
|
4
|
+
import type { ProcedureWorkflowRunner } from "../../control-plane/workflows/types.js";
|
|
5
|
+
import { type ProjectOpenAiReadOnlyChatAssistantModelOptions } from "../../providers/openai/chat-assistant.js";
|
|
6
|
+
import { type ProjectOpenAiRunPipelineRunnerOptions } from "../../run-pipeline/openai.js";
|
|
7
|
+
import { type ManagedExecutionRuntime } from "./execution-binding.js";
|
|
8
|
+
export declare function createManagedWorkflowRunner(runtime: ManagedExecutionRuntime, options: ProjectOpenAiProcedureWorkflowRunnerOptions): ProcedureWorkflowRunner;
|
|
9
|
+
export declare function createManagedRunPipeline(runtime: ManagedExecutionRuntime, options: ProjectOpenAiRunPipelineRunnerOptions): RunPipelineRunner;
|
|
10
|
+
export declare function createManagedChatModel(runtime: ManagedExecutionRuntime, options: ProjectOpenAiReadOnlyChatAssistantModelOptions): ReadOnlyChatAssistantModel;
|
|
11
|
+
//# sourceMappingURL=runners.d.ts.map
|