@standardagents/builder 0.37.8 → 0.38.1
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/built-in-routes.js +1246 -518
- package/dist/built-in-routes.js.map +1 -1
- package/dist/client/{ApiKeysView-L85eJb6G.js → ApiKeysView-AH5i-H6j.js} +1 -1
- package/dist/client/CenteredContentView-DaBp0K-A.js +1 -0
- package/dist/client/{CompositionView-BGp0EJCk.js → CompositionView-yY1Q4M23.js} +1 -1
- package/dist/client/{ConfirmDialog.vue_vue_type_script_setup_true_lang-DgwqZrLV.js → ConfirmDialog.vue_vue_type_script_setup_true_lang-Bwo5CJzF.js} +1 -1
- package/dist/client/{CopyButton.vue_vue_type_script_setup_true_lang-B8cGgU2J.js → CopyButton.vue_vue_type_script_setup_true_lang-D0WYwWyA.js} +1 -1
- package/dist/client/{DataTable.vue_vue_type_script_setup_true_lang-CRBXym9D.js → DataTable.vue_vue_type_script_setup_true_lang-1wwPn2aY.js} +1 -1
- package/dist/client/{JsonViewer-DkHnIfq3.js → JsonViewer-Bi8Zdmir.js} +1 -1
- package/dist/client/LoginView-BIKahEU6.js +1 -0
- package/dist/client/{MarketplaceView-DEnujUBs.js → MarketplaceView-DPDPVH68.js} +1 -1
- package/dist/client/{Modal.vue_vue_type_script_setup_true_lang-keKEwm3K.js → Modal.vue_vue_type_script_setup_true_lang-D1_rfOsy.js} +1 -1
- package/dist/client/{ModelModal.vue_vue_type_script_setup_true_lang-t1n0bbJe.js → ModelModal.vue_vue_type_script_setup_true_lang-DSLeOdxr.js} +1 -1
- package/dist/client/{ModelsView-BkCLr8sp.js → ModelsView-Q2WXu1Gw.js} +1 -1
- package/dist/client/{PromptEditView-BjCfsJQE.js → PromptEditView-BzA-3n1w.js} +1 -1
- package/dist/client/{PromptModal-nxu_LIv6.js → PromptModal-CJWh_cru.js} +1 -1
- package/dist/client/{PromptsView-1yXGCmEZ.js → PromptsView-BezNl-Et.js} +1 -1
- package/dist/client/{ProvidersView-DxF6gafk.js → ProvidersView-BuzSKxuT.js} +1 -1
- package/dist/client/ThreadInspectorPane.vue_vue_type_script_setup_true_lang-DOxNp_3C.js +22 -0
- package/dist/client/{ThreadsView-CBup_w8u.js → ThreadsView-DPCpZA4J.js} +1 -1
- package/dist/client/{ToolsView-B30TfXU9.js → ToolsView-DMjFMAhH.js} +1 -1
- package/dist/client/{UiCodeBlock.vue_vue_type_script_setup_true_lang-BdyzSxZZ.js → UiCodeBlock.vue_vue_type_script_setup_true_lang-7FgZmkfs.js} +1 -1
- package/dist/client/{UsersView-kE7Xr4f3.js → UsersView-B7jXLNQs.js} +1 -1
- package/dist/client/{VariablesView-yYuynG0M.js → VariablesView-CF7x0G8g.js} +1 -1
- package/dist/client/assets/{ThreadInspectorPane-BRGO_P0_.css → ThreadInspectorPane-CZMdV0Tb.css} +1 -1
- package/dist/client/assets/{index-B-69GGhJ.css → index-DAABRRAA.css} +1 -1
- package/dist/client/{check-YKi1o6p6.js → check-CD2lvcVi.js} +1 -1
- package/dist/client/{chevron-right-T0zzq_GX.js → chevron-right-bWZrmJ5a.js} +1 -1
- package/dist/client/{copy-C_gUGAj1.js → copy-B7nifl6a.js} +1 -1
- package/dist/client/{formkit-CE26dtFp.js → formkit-DJxUzqRQ.js} +1 -1
- package/dist/client/index-eGECJFYe.js +6 -0
- package/dist/client/index.html +6 -6
- package/dist/client/{package-B70IFSDB.js → package-Dyv7fTIQ.js} +1 -1
- package/dist/client/{plus-BN9IHYdt.js → plus-XkSslfF4.js} +1 -1
- package/dist/client/{syntax-D-ZcovVx.js → syntax-D68HCEYm.js} +1 -1
- package/dist/client/{timeAgo-G1ovbWPH.js → timeAgo-DRBdu9ed.js} +1 -1
- package/dist/client/{useActionFeedback-7pfPjKMi.js → useActionFeedback-FN4t6ezB.js} +1 -1
- package/dist/client/{vendor-TPZjEwCU.js → vendor-c_uwtQ-S.js} +13 -13
- package/dist/client/{vue-CZ-ORfS3.js → vue-BuvSxRmI.js} +1 -1
- package/dist/{index-Lfan8QMN.d.ts → index-CF-lgN47.d.ts} +83 -12
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1155 -360
- package/dist/index.js.map +1 -1
- package/dist/plugin.js +131 -72
- package/dist/plugin.js.map +1 -1
- package/dist/runtime.d.ts +69 -11
- package/dist/runtime.js +1018 -280
- package/dist/runtime.js.map +1 -1
- package/dist/test.d.ts +1 -1
- package/package.json +7 -6
- package/dist/client/CenteredContentView-D9jkWoLc.js +0 -1
- package/dist/client/LoginView-BXD9Odc-.js +0 -1
- package/dist/client/ThreadInspectorPane.vue_vue_type_script_setup_true_lang-CjwWJ3uw.js +0 -22
- package/dist/client/index-AUGwDdSH.js +0 -6
package/dist/built-in-routes.js
CHANGED
|
@@ -49,6 +49,14 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
49
49
|
mod
|
|
50
50
|
));
|
|
51
51
|
|
|
52
|
+
// src/skills/scope.ts
|
|
53
|
+
var SHARED_SKILL_OWNER;
|
|
54
|
+
var init_scope = __esm({
|
|
55
|
+
"src/skills/scope.ts"() {
|
|
56
|
+
SHARED_SKILL_OWNER = "__instance_shared__";
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
52
60
|
// src/agents/client-forwarding.ts
|
|
53
61
|
function createRuntimeStreams(openClientStream) {
|
|
54
62
|
return {
|
|
@@ -3123,6 +3131,104 @@ var init_sessionTools = __esm({
|
|
|
3123
3131
|
}
|
|
3124
3132
|
});
|
|
3125
3133
|
|
|
3134
|
+
// src/utils/remoteAttachment.ts
|
|
3135
|
+
function parseAllowedHosts(value) {
|
|
3136
|
+
if (typeof value !== "string") {
|
|
3137
|
+
return /* @__PURE__ */ new Set();
|
|
3138
|
+
}
|
|
3139
|
+
return new Set(
|
|
3140
|
+
value.split(",").map((host) => host.trim().toLowerCase().replace(/\.$/, "")).filter(Boolean)
|
|
3141
|
+
);
|
|
3142
|
+
}
|
|
3143
|
+
function isForbiddenHostname(hostname) {
|
|
3144
|
+
const normalized = hostname.toLowerCase().replace(/\.$/, "");
|
|
3145
|
+
if (/^\d{1,3}(?:\.\d{1,3}){3}$/.test(normalized)) {
|
|
3146
|
+
return true;
|
|
3147
|
+
}
|
|
3148
|
+
if (normalized.startsWith("[") && normalized.endsWith("]")) {
|
|
3149
|
+
return true;
|
|
3150
|
+
}
|
|
3151
|
+
if (!normalized.includes(".")) {
|
|
3152
|
+
return true;
|
|
3153
|
+
}
|
|
3154
|
+
return FORBIDDEN_HOST_SUFFIXES.some(
|
|
3155
|
+
(suffix) => normalized === suffix.slice(1) || normalized.endsWith(suffix)
|
|
3156
|
+
);
|
|
3157
|
+
}
|
|
3158
|
+
function validateRemoteAttachmentUrl(value, allowedHostsValue) {
|
|
3159
|
+
let url;
|
|
3160
|
+
try {
|
|
3161
|
+
url = new URL(value);
|
|
3162
|
+
} catch {
|
|
3163
|
+
return null;
|
|
3164
|
+
}
|
|
3165
|
+
if (url.protocol !== "https:" || url.username !== "" || url.password !== "" || url.port !== "" && url.port !== "443") {
|
|
3166
|
+
return null;
|
|
3167
|
+
}
|
|
3168
|
+
const hostname = url.hostname.toLowerCase().replace(/\.$/, "");
|
|
3169
|
+
if (isForbiddenHostname(hostname)) {
|
|
3170
|
+
return null;
|
|
3171
|
+
}
|
|
3172
|
+
const allowedHosts = parseAllowedHosts(allowedHostsValue);
|
|
3173
|
+
if (!allowedHosts.has(hostname)) {
|
|
3174
|
+
return null;
|
|
3175
|
+
}
|
|
3176
|
+
return url;
|
|
3177
|
+
}
|
|
3178
|
+
async function fetchRemoteAttachment(location, allowedHostsValue, fetchImpl = fetch) {
|
|
3179
|
+
let url = validateRemoteAttachmentUrl(location, allowedHostsValue);
|
|
3180
|
+
if (!url) {
|
|
3181
|
+
return null;
|
|
3182
|
+
}
|
|
3183
|
+
for (let redirectCount = 0; redirectCount <= MAX_REDIRECTS; redirectCount++) {
|
|
3184
|
+
let response;
|
|
3185
|
+
try {
|
|
3186
|
+
response = await fetchImpl(url.toString(), {
|
|
3187
|
+
redirect: "manual"
|
|
3188
|
+
});
|
|
3189
|
+
} catch {
|
|
3190
|
+
return null;
|
|
3191
|
+
}
|
|
3192
|
+
if (!REDIRECT_STATUSES.has(response.status)) {
|
|
3193
|
+
return response.ok ? response : null;
|
|
3194
|
+
}
|
|
3195
|
+
await response.body?.cancel().catch(() => void 0);
|
|
3196
|
+
if (redirectCount === MAX_REDIRECTS) {
|
|
3197
|
+
return null;
|
|
3198
|
+
}
|
|
3199
|
+
const redirectLocation = response.headers.get("Location");
|
|
3200
|
+
if (!redirectLocation) {
|
|
3201
|
+
return null;
|
|
3202
|
+
}
|
|
3203
|
+
let resolvedLocation;
|
|
3204
|
+
try {
|
|
3205
|
+
resolvedLocation = new URL(redirectLocation, url).toString();
|
|
3206
|
+
} catch {
|
|
3207
|
+
return null;
|
|
3208
|
+
}
|
|
3209
|
+
url = validateRemoteAttachmentUrl(resolvedLocation, allowedHostsValue);
|
|
3210
|
+
if (!url) {
|
|
3211
|
+
return null;
|
|
3212
|
+
}
|
|
3213
|
+
}
|
|
3214
|
+
return null;
|
|
3215
|
+
}
|
|
3216
|
+
var REDIRECT_STATUSES, MAX_REDIRECTS, FORBIDDEN_HOST_SUFFIXES;
|
|
3217
|
+
var init_remoteAttachment = __esm({
|
|
3218
|
+
"src/utils/remoteAttachment.ts"() {
|
|
3219
|
+
REDIRECT_STATUSES = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
|
|
3220
|
+
MAX_REDIRECTS = 3;
|
|
3221
|
+
FORBIDDEN_HOST_SUFFIXES = [
|
|
3222
|
+
".internal",
|
|
3223
|
+
".lan",
|
|
3224
|
+
".local",
|
|
3225
|
+
".localhost",
|
|
3226
|
+
".home",
|
|
3227
|
+
".test"
|
|
3228
|
+
];
|
|
3229
|
+
}
|
|
3230
|
+
});
|
|
3231
|
+
|
|
3126
3232
|
// src/durable-objects/files.ts
|
|
3127
3233
|
var files_exports = {};
|
|
3128
3234
|
__export(files_exports, {
|
|
@@ -3860,6 +3966,7 @@ var init_ToolExecutor = __esm({
|
|
|
3860
3966
|
init_types();
|
|
3861
3967
|
init_ThreadStateImpl();
|
|
3862
3968
|
init_sessionTools();
|
|
3969
|
+
init_remoteAttachment();
|
|
3863
3970
|
SUBAGENT_CREATE_TOOL = "subagent_create";
|
|
3864
3971
|
SUBAGENT_MESSAGE_TOOL = "subagent_message";
|
|
3865
3972
|
SUBAGENTS_LIST_TOOL = "subagents";
|
|
@@ -4908,7 +5015,8 @@ Message one with subagent_message(referenceId, message).`
|
|
|
4908
5015
|
stub,
|
|
4909
5016
|
state.thread.instance,
|
|
4910
5017
|
childResult.attachments,
|
|
4911
|
-
`from-subagent-${childThreadId}
|
|
5018
|
+
`from-subagent-${childThreadId}`,
|
|
5019
|
+
state.env.AGENT_BUILDER_ATTACHMENT_FETCH_HOSTS
|
|
4912
5020
|
);
|
|
4913
5021
|
if (resumable) {
|
|
4914
5022
|
await this.settleResumableChildAfterRun(
|
|
@@ -4941,7 +5049,8 @@ Message one with subagent_message(referenceId, message).`
|
|
|
4941
5049
|
stub,
|
|
4942
5050
|
state.thread.instance,
|
|
4943
5051
|
childResult.attachments,
|
|
4944
|
-
`from-subagent-${childThreadId}
|
|
5052
|
+
`from-subagent-${childThreadId}`,
|
|
5053
|
+
state.env.AGENT_BUILDER_ATTACHMENT_FETCH_HOSTS
|
|
4945
5054
|
);
|
|
4946
5055
|
const messageContent = this.formatSubagentTerminalMessage(
|
|
4947
5056
|
childThreadId,
|
|
@@ -5355,7 +5464,8 @@ Message one with subagent_message(referenceId, message).`
|
|
|
5355
5464
|
state.thread.instance,
|
|
5356
5465
|
childThread,
|
|
5357
5466
|
parentAttachments,
|
|
5358
|
-
`from-parent-${state.threadId}
|
|
5467
|
+
`from-parent-${state.threadId}`,
|
|
5468
|
+
state.env.AGENT_BUILDER_ATTACHMENT_FETCH_HOSTS
|
|
5359
5469
|
);
|
|
5360
5470
|
const targetRole = receivesMessages === "side_a" ? "user" : "assistant";
|
|
5361
5471
|
const baseTimestamp = Date.now() * 1e3;
|
|
@@ -5615,7 +5725,7 @@ Reference: ${referenceId}` : `Reference: ${referenceId}`;
|
|
|
5615
5725
|
const shortId = crypto.randomUUID().slice(0, 8);
|
|
5616
5726
|
return `/attachments/${normalizedStem}-${shortId}.${finalExt}`;
|
|
5617
5727
|
}
|
|
5618
|
-
static async copyAttachmentsBetweenThreads(sourceThread, targetThread, attachments, _pathPrefix) {
|
|
5728
|
+
static async copyAttachmentsBetweenThreads(sourceThread, targetThread, attachments, _pathPrefix, allowedAttachmentFetchHosts) {
|
|
5619
5729
|
if (!attachments || attachments.length === 0) {
|
|
5620
5730
|
return [];
|
|
5621
5731
|
}
|
|
@@ -5643,7 +5753,8 @@ Reference: ${referenceId}` : `Reference: ${referenceId}`;
|
|
|
5643
5753
|
const copiedData = await this.readAttachmentDataFromSource(
|
|
5644
5754
|
sourceThread,
|
|
5645
5755
|
attachment.path,
|
|
5646
|
-
sourceFile
|
|
5756
|
+
sourceFile,
|
|
5757
|
+
allowedAttachmentFetchHosts
|
|
5647
5758
|
);
|
|
5648
5759
|
if (!copiedData) {
|
|
5649
5760
|
continue;
|
|
@@ -5700,7 +5811,7 @@ Reference: ${referenceId}` : `Reference: ${referenceId}`;
|
|
|
5700
5811
|
}
|
|
5701
5812
|
return copied;
|
|
5702
5813
|
}
|
|
5703
|
-
static async readAttachmentDataFromSource(sourceThread, path10, sourceFile) {
|
|
5814
|
+
static async readAttachmentDataFromSource(sourceThread, path10, sourceFile, allowedAttachmentFetchHosts) {
|
|
5704
5815
|
const sourceData = await sourceThread.readFile(path10);
|
|
5705
5816
|
if (sourceData.success && sourceData.data) {
|
|
5706
5817
|
return sourceData.data;
|
|
@@ -5709,14 +5820,17 @@ Reference: ${referenceId}` : `Reference: ${referenceId}`;
|
|
|
5709
5820
|
return null;
|
|
5710
5821
|
}
|
|
5711
5822
|
const location = sourceFile.location;
|
|
5712
|
-
if (!location
|
|
5823
|
+
if (!location) {
|
|
5824
|
+
return null;
|
|
5825
|
+
}
|
|
5826
|
+
const response = await fetchRemoteAttachment(
|
|
5827
|
+
location,
|
|
5828
|
+
allowedAttachmentFetchHosts
|
|
5829
|
+
);
|
|
5830
|
+
if (!response) {
|
|
5713
5831
|
return null;
|
|
5714
5832
|
}
|
|
5715
5833
|
try {
|
|
5716
|
-
const response = await fetch(location);
|
|
5717
|
-
if (!response.ok) {
|
|
5718
|
-
return null;
|
|
5719
|
-
}
|
|
5720
5834
|
const buffer = await response.arrayBuffer();
|
|
5721
5835
|
return this.arrayBufferToBase64(buffer);
|
|
5722
5836
|
} catch {
|
|
@@ -5970,7 +6084,8 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
|
|
|
5970
6084
|
state.thread.instance,
|
|
5971
6085
|
childStub,
|
|
5972
6086
|
sourceAttachments,
|
|
5973
|
-
`from-parent-${state.threadId}
|
|
6087
|
+
`from-parent-${state.threadId}`,
|
|
6088
|
+
state.env.AGENT_BUILDER_ATTACHMENT_FETCH_HOSTS
|
|
5974
6089
|
);
|
|
5975
6090
|
await childStub.queueMessage(referenceId, {
|
|
5976
6091
|
role: receivesMessages === "side_a" ? "user" : "assistant",
|
|
@@ -12570,6 +12685,32 @@ var ThreadStateImpl_exports = {};
|
|
|
12570
12685
|
__export(ThreadStateImpl_exports, {
|
|
12571
12686
|
ThreadStateImpl: () => ThreadStateImpl
|
|
12572
12687
|
});
|
|
12688
|
+
function isRuntimeDurableNamespace(value) {
|
|
12689
|
+
return value !== null && typeof value === "object" && "idFromName" in value && typeof value.idFromName === "function" && "get" in value && typeof value.get === "function";
|
|
12690
|
+
}
|
|
12691
|
+
function isThreadStateRuntimeEnvironment(value) {
|
|
12692
|
+
return value !== null && typeof value === "object" && "AGENT_BUILDER" in value && isRuntimeDurableNamespace(value.AGENT_BUILDER) && (!("AGENT_BUILDER_USER_HUB" in value) || value.AGENT_BUILDER_USER_HUB === void 0 || isRuntimeDurableNamespace(value.AGENT_BUILDER_USER_HUB));
|
|
12693
|
+
}
|
|
12694
|
+
function confinedUserEndpointUrl(userId, endpoint) {
|
|
12695
|
+
const base = new URL(
|
|
12696
|
+
`https://user-hub/users/${encodeURIComponent(userId)}/endpoints/`
|
|
12697
|
+
);
|
|
12698
|
+
const relative4 = endpoint.replace(/^\/+/, "");
|
|
12699
|
+
let decoded;
|
|
12700
|
+
try {
|
|
12701
|
+
decoded = decodeURIComponent(relative4);
|
|
12702
|
+
} catch {
|
|
12703
|
+
throw new Error("Invalid user endpoint path: malformed percent encoding.");
|
|
12704
|
+
}
|
|
12705
|
+
if (decoded.includes("\\") || decoded.includes("?") || decoded.includes("#") || /[\u0000-\u001f\u007f]/.test(decoded) || decoded.split("/").some((segment) => segment === "." || segment === "..")) {
|
|
12706
|
+
throw new Error("Invalid user endpoint path: traversal and URL syntax are not allowed.");
|
|
12707
|
+
}
|
|
12708
|
+
const resolved = new URL(relative4, base);
|
|
12709
|
+
if (resolved.origin !== base.origin || !resolved.pathname.startsWith(base.pathname)) {
|
|
12710
|
+
throw new Error("Invalid user endpoint path: endpoint escaped the user namespace.");
|
|
12711
|
+
}
|
|
12712
|
+
return resolved.toString();
|
|
12713
|
+
}
|
|
12573
12714
|
function hasLocalCodeExecutionRuntime(threadInstance) {
|
|
12574
12715
|
const candidate = threadInstance;
|
|
12575
12716
|
return Boolean(candidate.env && candidate.ctx);
|
|
@@ -12750,6 +12891,7 @@ function runCodeViaThreadRpc(threadInstance, threadId, source, options) {
|
|
|
12750
12891
|
var ThreadStateImpl, ExecutionStateImpl;
|
|
12751
12892
|
var init_ThreadStateImpl = __esm({
|
|
12752
12893
|
"src/agents/ThreadStateImpl.ts"() {
|
|
12894
|
+
init_scope();
|
|
12753
12895
|
init_client_forwarding();
|
|
12754
12896
|
init_types();
|
|
12755
12897
|
init_utilities();
|
|
@@ -12983,6 +13125,14 @@ var init_ThreadStateImpl = __esm({
|
|
|
12983
13125
|
}
|
|
12984
13126
|
return value;
|
|
12985
13127
|
}
|
|
13128
|
+
async instanceEnv(propertyName) {
|
|
13129
|
+
const agentBuilder = this._getAgentBuilderStub();
|
|
13130
|
+
if (typeof agentBuilder.getInstanceEnv !== "function") {
|
|
13131
|
+
throw new Error("instanceEnv is not supported by this runtime");
|
|
13132
|
+
}
|
|
13133
|
+
const values = await agentBuilder.getInstanceEnv();
|
|
13134
|
+
return values[propertyName];
|
|
13135
|
+
}
|
|
12986
13136
|
async envType(propertyName) {
|
|
12987
13137
|
const agentBuilder = this._getAgentBuilderStub();
|
|
12988
13138
|
if (typeof agentBuilder.resolveThreadEnvType === "function") {
|
|
@@ -14013,12 +14163,11 @@ var init_ThreadStateImpl = __esm({
|
|
|
14013
14163
|
* dispatcher recorded in the runtime context instead.
|
|
14014
14164
|
*/
|
|
14015
14165
|
_getRuntimeEnv() {
|
|
14016
|
-
|
|
14017
|
-
|
|
14018
|
-
return contextEnv;
|
|
14166
|
+
if (isThreadStateRuntimeEnvironment(this._runtimeContext.env)) {
|
|
14167
|
+
return this._runtimeContext.env;
|
|
14019
14168
|
}
|
|
14020
14169
|
const instanceEnv = this._threadInstance.env;
|
|
14021
|
-
if (!instanceEnv
|
|
14170
|
+
if (!isThreadStateRuntimeEnvironment(instanceEnv)) {
|
|
14022
14171
|
throw new Error(
|
|
14023
14172
|
"No runtime environment available on this ThreadState. Stub-backed states must be constructed with runtimeContext.env."
|
|
14024
14173
|
);
|
|
@@ -14035,9 +14184,7 @@ var init_ThreadStateImpl = __esm({
|
|
|
14035
14184
|
return namespace.get(namespace.idFromName(userId));
|
|
14036
14185
|
}
|
|
14037
14186
|
// ─────────────────────────────────────────────────────────────────────────
|
|
14038
|
-
// Skills —
|
|
14039
|
-
// DurableAgentBuilder singleton (skills are never stored per-thread or on
|
|
14040
|
-
// a client machine).
|
|
14187
|
+
// Skills — owner-scoped library plus explicitly shared administrator skills.
|
|
14041
14188
|
// ─────────────────────────────────────────────────────────────────────────
|
|
14042
14189
|
/**
|
|
14043
14190
|
* The profile of the user this thread belongs to (identity fields only —
|
|
@@ -14060,9 +14207,8 @@ var init_ThreadStateImpl = __esm({
|
|
|
14060
14207
|
"Reentrant user-scope call: this ThreadState was raised from user-scope code; state.user().call() is unavailable here."
|
|
14061
14208
|
);
|
|
14062
14209
|
}
|
|
14063
|
-
const path10 = endpoint.replace(/^\/+/, "");
|
|
14064
14210
|
return hub().fetch(
|
|
14065
|
-
new Request(
|
|
14211
|
+
new Request(confinedUserEndpointUrl(userId, endpoint), {
|
|
14066
14212
|
method: "POST",
|
|
14067
14213
|
headers: {
|
|
14068
14214
|
"Content-Type": "application/json",
|
|
@@ -14122,18 +14268,42 @@ var init_ThreadStateImpl = __esm({
|
|
|
14122
14268
|
}
|
|
14123
14269
|
get skills() {
|
|
14124
14270
|
const stub = this._getAgentBuilderStub();
|
|
14271
|
+
const ownerId = this._metadata.user_id ?? SHARED_SKILL_OWNER;
|
|
14272
|
+
const scope = {
|
|
14273
|
+
ownerId,
|
|
14274
|
+
includeShared: ownerId !== SHARED_SKILL_OWNER
|
|
14275
|
+
};
|
|
14276
|
+
const requireMutationAdmin = async () => {
|
|
14277
|
+
const userId = this._metadata.user_id;
|
|
14278
|
+
if (!userId) {
|
|
14279
|
+
throw new Error("Skill mutations require an authenticated instance admin.");
|
|
14280
|
+
}
|
|
14281
|
+
const user = await stub.getUserById(userId);
|
|
14282
|
+
if (user?.role !== "admin") {
|
|
14283
|
+
throw new Error("Skill mutations require an instance admin.");
|
|
14284
|
+
}
|
|
14285
|
+
};
|
|
14125
14286
|
return {
|
|
14126
|
-
list: (options) => stub.listSkills(options),
|
|
14287
|
+
list: (options) => stub.listSkills(scope, options),
|
|
14127
14288
|
get: async (name15) => {
|
|
14128
|
-
const metadata = await stub.getSkill(name15);
|
|
14289
|
+
const metadata = await stub.getSkill(scope, name15);
|
|
14129
14290
|
if (!metadata) return null;
|
|
14130
|
-
const skillMd = await stub.getSkillFile(name15, "SKILL.md") ?? "";
|
|
14291
|
+
const skillMd = await stub.getSkillFile(scope, name15, "SKILL.md") ?? "";
|
|
14131
14292
|
return { metadata, skillMd };
|
|
14132
14293
|
},
|
|
14133
|
-
readFile: (name15, path10) => stub.getSkillFile(name15, path10),
|
|
14134
|
-
install: (files) =>
|
|
14135
|
-
|
|
14136
|
-
|
|
14294
|
+
readFile: (name15, path10) => stub.getSkillFile(scope, name15, path10),
|
|
14295
|
+
install: async (files) => {
|
|
14296
|
+
await requireMutationAdmin();
|
|
14297
|
+
return stub.upsertSkill(scope, files);
|
|
14298
|
+
},
|
|
14299
|
+
setEnabled: async (name15, enabled) => {
|
|
14300
|
+
await requireMutationAdmin();
|
|
14301
|
+
return stub.setSkillEnabled(scope, name15, enabled);
|
|
14302
|
+
},
|
|
14303
|
+
remove: async (name15) => {
|
|
14304
|
+
await requireMutationAdmin();
|
|
14305
|
+
return stub.deleteSkill(scope, name15);
|
|
14306
|
+
}
|
|
14137
14307
|
};
|
|
14138
14308
|
}
|
|
14139
14309
|
// ─────────────────────────────────────────────────────────────────────────
|
|
@@ -67050,113 +67220,9 @@ function getParamRegexp(segment) {
|
|
|
67050
67220
|
|
|
67051
67221
|
// src/router/index.ts
|
|
67052
67222
|
init_ThreadStateImpl();
|
|
67053
|
-
function defineController2(controller) {
|
|
67054
|
-
return controller;
|
|
67055
|
-
}
|
|
67056
|
-
|
|
67057
|
-
// src/api/index.post.ts
|
|
67058
|
-
var index_post_default = defineController2(() => {
|
|
67059
|
-
const stream = new ReadableStream({
|
|
67060
|
-
start(controller) {
|
|
67061
|
-
const text2 = "hello world";
|
|
67062
|
-
let index = 0;
|
|
67063
|
-
const next = () => {
|
|
67064
|
-
if (index < text2.length) {
|
|
67065
|
-
controller.enqueue(new TextEncoder().encode(text2[index]));
|
|
67066
|
-
index++;
|
|
67067
|
-
setTimeout(next, 100);
|
|
67068
|
-
} else {
|
|
67069
|
-
controller.close();
|
|
67070
|
-
}
|
|
67071
|
-
};
|
|
67072
|
-
next();
|
|
67073
|
-
}
|
|
67074
|
-
});
|
|
67075
|
-
return new Response(stream);
|
|
67076
|
-
});
|
|
67077
|
-
|
|
67078
|
-
// src/api/agents.get.ts
|
|
67079
|
-
var agents_get_default = defineController2(async ({ agents, agentNames, registry, auth }) => {
|
|
67080
|
-
const includeAuthoringDetails = auth?.user.role === "admin";
|
|
67081
|
-
const agentList = [];
|
|
67082
|
-
console.log("[agents.get] Registry packages:", registry?.packages ? Object.keys(registry.packages) : "undefined");
|
|
67083
|
-
if (agents && agentNames) {
|
|
67084
|
-
const globalAgents = await Promise.all(
|
|
67085
|
-
agentNames.map(async (name15) => {
|
|
67086
|
-
try {
|
|
67087
|
-
const loader = agents[name15];
|
|
67088
|
-
if (!loader) {
|
|
67089
|
-
return null;
|
|
67090
|
-
}
|
|
67091
|
-
const definition = await loader();
|
|
67092
|
-
return {
|
|
67093
|
-
id: definition.name,
|
|
67094
|
-
name: definition.name,
|
|
67095
|
-
title: definition.title || definition.name,
|
|
67096
|
-
type: definition.type || "ai_human",
|
|
67097
|
-
description: definition.description || null,
|
|
67098
|
-
icon: definition.icon || null,
|
|
67099
|
-
primary: definition.primary !== false,
|
|
67100
|
-
...includeAuthoringDetails ? {
|
|
67101
|
-
default_prompt: definition.sideA?.prompt || "",
|
|
67102
|
-
default_model: "",
|
|
67103
|
-
tools: [],
|
|
67104
|
-
side_a_label: definition.sideA?.label || null,
|
|
67105
|
-
side_a_agent_prompt: definition.sideA?.prompt || null,
|
|
67106
|
-
side_b_label: definition.sideB?.label || null,
|
|
67107
|
-
side_b_agent_prompt: definition.sideB?.prompt || null,
|
|
67108
|
-
env: definition.env || null
|
|
67109
|
-
} : {},
|
|
67110
|
-
created_at: Math.floor(Date.now() / 1e3),
|
|
67111
|
-
packed: false
|
|
67112
|
-
};
|
|
67113
|
-
} catch (error) {
|
|
67114
|
-
console.error(`Error loading agent ${name15}:`, error);
|
|
67115
|
-
return null;
|
|
67116
|
-
}
|
|
67117
|
-
})
|
|
67118
|
-
);
|
|
67119
|
-
agentList.push(...globalAgents);
|
|
67120
|
-
}
|
|
67121
|
-
if (registry?.packages) {
|
|
67122
|
-
for (const [packageId, pkg] of Object.entries(registry.packages)) {
|
|
67123
|
-
const packageData = pkg;
|
|
67124
|
-
for (const agentName of packageData.entryAgents) {
|
|
67125
|
-
try {
|
|
67126
|
-
const loader = packageData.agents[agentName];
|
|
67127
|
-
if (!loader) continue;
|
|
67128
|
-
const definition = await loader();
|
|
67129
|
-
agentList.push({
|
|
67130
|
-
id: `${packageId}/${definition.name}`,
|
|
67131
|
-
name: definition.name,
|
|
67132
|
-
title: definition.title || definition.name,
|
|
67133
|
-
type: definition.type || "ai_human",
|
|
67134
|
-
description: definition.description || null,
|
|
67135
|
-
icon: definition.icon || null,
|
|
67136
|
-
primary: definition.primary !== false,
|
|
67137
|
-
...includeAuthoringDetails ? {
|
|
67138
|
-
default_prompt: definition.sideA?.prompt || "",
|
|
67139
|
-
default_model: "",
|
|
67140
|
-
tools: [],
|
|
67141
|
-
side_a_agent_prompt: definition.sideA?.prompt ? definition.sideA.prompt.includes("/") ? definition.sideA.prompt : `${packageId}/${definition.sideA.prompt}` : null,
|
|
67142
|
-
side_b_agent_prompt: definition.sideB?.prompt ? definition.sideB.prompt.includes("/") ? definition.sideB.prompt : `${packageId}/${definition.sideB.prompt}` : null
|
|
67143
|
-
} : {},
|
|
67144
|
-
created_at: Math.floor(Date.now() / 1e3),
|
|
67145
|
-
packed: true,
|
|
67146
|
-
packageId,
|
|
67147
|
-
source: packageData.signature.source
|
|
67148
|
-
});
|
|
67149
|
-
} catch (error) {
|
|
67150
|
-
console.error(`Error loading packed agent ${agentName} from ${packageId}:`, error);
|
|
67151
|
-
}
|
|
67152
|
-
}
|
|
67153
|
-
}
|
|
67154
|
-
}
|
|
67155
|
-
const validAgents = agentList.filter(Boolean);
|
|
67156
|
-
return Response.json({ agents: validAgents });
|
|
67157
|
-
});
|
|
67158
67223
|
|
|
67159
67224
|
// src/utils/auth.ts
|
|
67225
|
+
var SUPER_ADMIN_TOKEN_TTL_SECONDS = 12 * 60 * 60;
|
|
67160
67226
|
function generateSecureToken(length = 32) {
|
|
67161
67227
|
const array44 = new Uint8Array(length);
|
|
67162
67228
|
crypto.getRandomValues(array44);
|
|
@@ -67168,6 +67234,20 @@ function generateUserToken() {
|
|
|
67168
67234
|
function generateApiKey() {
|
|
67169
67235
|
return `agtbldr_${generateSecureToken(32)}`;
|
|
67170
67236
|
}
|
|
67237
|
+
async function constantTimeEqual(left, right) {
|
|
67238
|
+
const encoder2 = new TextEncoder();
|
|
67239
|
+
const [leftDigest, rightDigest] = await Promise.all([
|
|
67240
|
+
crypto.subtle.digest("SHA-256", encoder2.encode(left)),
|
|
67241
|
+
crypto.subtle.digest("SHA-256", encoder2.encode(right))
|
|
67242
|
+
]);
|
|
67243
|
+
const leftBytes = new Uint8Array(leftDigest);
|
|
67244
|
+
const rightBytes = new Uint8Array(rightDigest);
|
|
67245
|
+
let difference = 0;
|
|
67246
|
+
for (let index = 0; index < leftBytes.length; index++) {
|
|
67247
|
+
difference |= leftBytes[index] ^ rightBytes[index];
|
|
67248
|
+
}
|
|
67249
|
+
return difference === 0;
|
|
67250
|
+
}
|
|
67171
67251
|
async function hashPassword(password) {
|
|
67172
67252
|
const encoder2 = new TextEncoder();
|
|
67173
67253
|
const data = encoder2.encode(password);
|
|
@@ -67279,9 +67359,9 @@ function isValidUserToken(token) {
|
|
|
67279
67359
|
function isValidApiKey(key) {
|
|
67280
67360
|
return key.startsWith("agtbldr_") && key.length > 10 || key.startsWith("sak_live_") && key.length > 10;
|
|
67281
67361
|
}
|
|
67282
|
-
async function signToken(payload,
|
|
67362
|
+
async function signToken(payload, encryptionKey2) {
|
|
67283
67363
|
const encoder2 = new TextEncoder();
|
|
67284
|
-
const keyData = encoder2.encode(
|
|
67364
|
+
const keyData = encoder2.encode(encryptionKey2);
|
|
67285
67365
|
const cryptoKey = await crypto.subtle.importKey(
|
|
67286
67366
|
"raw",
|
|
67287
67367
|
keyData,
|
|
@@ -67295,7 +67375,7 @@ async function signToken(payload, encryptionKey) {
|
|
|
67295
67375
|
const signatureB64 = bufferToBase64(new Uint8Array(signature));
|
|
67296
67376
|
return `${payloadB64}.${signatureB64}`;
|
|
67297
67377
|
}
|
|
67298
|
-
async function verifySignedToken(signedToken,
|
|
67378
|
+
async function verifySignedToken(signedToken, encryptionKey2) {
|
|
67299
67379
|
try {
|
|
67300
67380
|
const parts = signedToken.split(".");
|
|
67301
67381
|
if (parts.length !== 2) {
|
|
@@ -67303,7 +67383,7 @@ async function verifySignedToken(signedToken, encryptionKey) {
|
|
|
67303
67383
|
}
|
|
67304
67384
|
const [payloadB64, signatureB64] = parts;
|
|
67305
67385
|
const encoder2 = new TextEncoder();
|
|
67306
|
-
const keyData = encoder2.encode(
|
|
67386
|
+
const keyData = encoder2.encode(encryptionKey2);
|
|
67307
67387
|
const cryptoKey = await crypto.subtle.importKey(
|
|
67308
67388
|
"raw",
|
|
67309
67389
|
keyData,
|
|
@@ -67324,14 +67404,14 @@ async function verifySignedToken(signedToken, encryptionKey) {
|
|
|
67324
67404
|
return null;
|
|
67325
67405
|
}
|
|
67326
67406
|
}
|
|
67327
|
-
async function generateSuperAdminToken(
|
|
67407
|
+
async function generateSuperAdminToken(encryptionKey2) {
|
|
67328
67408
|
const timestamp = Date.now();
|
|
67329
67409
|
const nonce = generateSecureToken(16);
|
|
67330
67410
|
const payload = `super_admin:${timestamp}:${nonce}`;
|
|
67331
|
-
return await signToken(payload,
|
|
67411
|
+
return await signToken(payload, encryptionKey2);
|
|
67332
67412
|
}
|
|
67333
|
-
async function verifySuperAdminToken(token,
|
|
67334
|
-
const payload = await verifySignedToken(token,
|
|
67413
|
+
async function verifySuperAdminToken(token, encryptionKey2) {
|
|
67414
|
+
const payload = await verifySignedToken(token, encryptionKey2);
|
|
67335
67415
|
if (!payload) {
|
|
67336
67416
|
return false;
|
|
67337
67417
|
}
|
|
@@ -67340,9 +67420,12 @@ async function verifySuperAdminToken(token, encryptionKey) {
|
|
|
67340
67420
|
return false;
|
|
67341
67421
|
}
|
|
67342
67422
|
const timestamp = parseInt(parts[1], 10);
|
|
67423
|
+
if (!Number.isFinite(timestamp)) {
|
|
67424
|
+
return false;
|
|
67425
|
+
}
|
|
67343
67426
|
const age = Date.now() - timestamp;
|
|
67344
|
-
const maxAge =
|
|
67345
|
-
if (age > maxAge) {
|
|
67427
|
+
const maxAge = SUPER_ADMIN_TOKEN_TTL_SECONDS * 1e3;
|
|
67428
|
+
if (age < 0 || age > maxAge) {
|
|
67346
67429
|
return false;
|
|
67347
67430
|
}
|
|
67348
67431
|
return true;
|
|
@@ -67363,17 +67446,99 @@ function base64ToBuffer(base64) {
|
|
|
67363
67446
|
return bytes;
|
|
67364
67447
|
}
|
|
67365
67448
|
|
|
67366
|
-
// src/
|
|
67367
|
-
|
|
67449
|
+
// src/routing/access-policy.ts
|
|
67450
|
+
function isHostedInstance(env2) {
|
|
67451
|
+
const value = env2 && typeof env2 === "object" ? Reflect.get(env2, "STANDARD_AGENTS_HOSTED") : void 0;
|
|
67452
|
+
if (typeof value === "string") {
|
|
67453
|
+
const normalized = value.trim().toLowerCase();
|
|
67454
|
+
return normalized !== "" && normalized !== "0" && normalized !== "false";
|
|
67455
|
+
}
|
|
67456
|
+
return Boolean(value);
|
|
67457
|
+
}
|
|
67458
|
+
function isTrustedLocalDevelopmentRequest(request, env2) {
|
|
67459
|
+
if (isHostedInstance(env2)) return false;
|
|
67460
|
+
let hostname;
|
|
67461
|
+
try {
|
|
67462
|
+
hostname = new URL(request.url).hostname.toLowerCase();
|
|
67463
|
+
} catch {
|
|
67464
|
+
return false;
|
|
67465
|
+
}
|
|
67466
|
+
return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1" || hostname.endsWith(".localhost") || hostname.endsWith(".orb.local");
|
|
67467
|
+
}
|
|
67468
|
+
function requestObservedOrigins(request) {
|
|
67469
|
+
const origins = /* @__PURE__ */ new Set();
|
|
67470
|
+
let url = null;
|
|
67471
|
+
try {
|
|
67472
|
+
url = new URL(request.url);
|
|
67473
|
+
origins.add(url.origin);
|
|
67474
|
+
} catch {
|
|
67475
|
+
url = null;
|
|
67476
|
+
}
|
|
67477
|
+
const forwardedHost = request.headers.get("x-forwarded-host")?.split(",")[0]?.trim();
|
|
67478
|
+
const host = forwardedHost || request.headers.get("host")?.trim();
|
|
67479
|
+
if (!host) return origins;
|
|
67480
|
+
const forwardedProto = request.headers.get("x-forwarded-proto")?.split(",")[0]?.trim().toLowerCase();
|
|
67481
|
+
const schemes = /* @__PURE__ */ new Set();
|
|
67482
|
+
if (forwardedProto === "http" || forwardedProto === "https") schemes.add(forwardedProto);
|
|
67483
|
+
if (url) schemes.add(url.protocol.replace(":", ""));
|
|
67484
|
+
if (schemes.size === 0) {
|
|
67485
|
+
schemes.add(host.endsWith(".orb.local") ? "https" : "http");
|
|
67486
|
+
}
|
|
67487
|
+
for (const scheme of schemes) {
|
|
67488
|
+
try {
|
|
67489
|
+
origins.add(new URL(`${scheme}://${host}`).origin);
|
|
67490
|
+
} catch {
|
|
67491
|
+
}
|
|
67492
|
+
}
|
|
67493
|
+
return origins;
|
|
67494
|
+
}
|
|
67495
|
+
function isSameOriginBrowserRequest(request) {
|
|
67496
|
+
const fetchSite = request.headers.get("Sec-Fetch-Site")?.trim().toLowerCase();
|
|
67497
|
+
if (fetchSite === "same-origin" || fetchSite === "none") {
|
|
67498
|
+
return true;
|
|
67499
|
+
}
|
|
67500
|
+
if (fetchSite) {
|
|
67501
|
+
return false;
|
|
67502
|
+
}
|
|
67503
|
+
const origin = request.headers.get("Origin")?.trim();
|
|
67504
|
+
if (!origin) return true;
|
|
67505
|
+
if (origin === "null") return false;
|
|
67506
|
+
try {
|
|
67507
|
+
return requestObservedOrigins(request).has(new URL(origin).origin);
|
|
67508
|
+
} catch {
|
|
67509
|
+
return false;
|
|
67510
|
+
}
|
|
67511
|
+
}
|
|
67512
|
+
|
|
67513
|
+
// src/routing/cors.ts
|
|
67514
|
+
var RUNTIME_CORS_HEADERS = {
|
|
67368
67515
|
"Access-Control-Allow-Origin": "*",
|
|
67369
67516
|
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
|
|
67370
67517
|
"Access-Control-Allow-Headers": "Content-Type, Authorization, X-Requested-With",
|
|
67371
67518
|
"Access-Control-Max-Age": "86400"
|
|
67372
67519
|
};
|
|
67373
|
-
function
|
|
67520
|
+
function exposesRuntimeCors(request, env2) {
|
|
67521
|
+
return !isTrustedLocalDevelopmentRequest(request, env2);
|
|
67522
|
+
}
|
|
67523
|
+
function runtimeCorsHeaders(request, env2) {
|
|
67524
|
+
return exposesRuntimeCors(request, env2) ? { ...RUNTIME_CORS_HEADERS } : {};
|
|
67525
|
+
}
|
|
67526
|
+
|
|
67527
|
+
// src/middleware/auth.ts
|
|
67528
|
+
function isAuthenticationEnv(env2) {
|
|
67529
|
+
if (!env2 || typeof env2 !== "object") return false;
|
|
67530
|
+
const namespace = env2.AGENT_BUILDER;
|
|
67531
|
+
return !!namespace && typeof namespace === "object" && typeof namespace.idFromName === "function" && typeof namespace.get === "function";
|
|
67532
|
+
}
|
|
67533
|
+
function hasPermission(user, permission, options = {}) {
|
|
67374
67534
|
if (user.role === "admin") return true;
|
|
67375
67535
|
if (Array.isArray(user.permissions)) return user.permissions.includes(permission);
|
|
67376
|
-
return user.role
|
|
67536
|
+
return options.allowLegacyUserFallback !== false && user.role === "user";
|
|
67537
|
+
}
|
|
67538
|
+
function hasPermissionInEnvironment(user, permission, env2) {
|
|
67539
|
+
return hasPermission(user, permission, {
|
|
67540
|
+
allowLegacyUserFallback: !isHostedInstance(env2)
|
|
67541
|
+
});
|
|
67377
67542
|
}
|
|
67378
67543
|
function parsePermissions(value) {
|
|
67379
67544
|
if (Array.isArray(value)) return value.filter((p) => typeof p === "string");
|
|
@@ -67395,43 +67560,96 @@ function extractBearerToken(request) {
|
|
|
67395
67560
|
if (cookieToken) {
|
|
67396
67561
|
return cookieToken;
|
|
67397
67562
|
}
|
|
67398
|
-
const isWebSocket = request.headers.get("upgrade")?.toLowerCase() === "websocket";
|
|
67399
|
-
if (isWebSocket) {
|
|
67400
|
-
try {
|
|
67401
|
-
const url = new URL(request.url);
|
|
67402
|
-
const token = url.searchParams.get("token");
|
|
67403
|
-
if (token) {
|
|
67404
|
-
return token;
|
|
67405
|
-
}
|
|
67406
|
-
} catch (err) {
|
|
67407
|
-
}
|
|
67408
|
-
}
|
|
67409
67563
|
return null;
|
|
67410
67564
|
}
|
|
67411
67565
|
function getAgentBuilder(env2) {
|
|
67412
67566
|
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
67413
67567
|
return env2.AGENT_BUILDER.get(agentBuilderId);
|
|
67414
67568
|
}
|
|
67569
|
+
function parseWebSocketTicketAuth(authJson) {
|
|
67570
|
+
let parsed;
|
|
67571
|
+
try {
|
|
67572
|
+
parsed = JSON.parse(authJson);
|
|
67573
|
+
} catch {
|
|
67574
|
+
return null;
|
|
67575
|
+
}
|
|
67576
|
+
if (!parsed || typeof parsed !== "object") return null;
|
|
67577
|
+
const record24 = parsed;
|
|
67578
|
+
if (!record24.user || typeof record24.user !== "object") return null;
|
|
67579
|
+
const user = record24.user;
|
|
67580
|
+
if (typeof user.id !== "string" || typeof user.username !== "string" || typeof user.role !== "string" || record24.authType !== "super_admin" && record24.authType !== "session" && record24.authType !== "api_key") {
|
|
67581
|
+
return null;
|
|
67582
|
+
}
|
|
67583
|
+
const permissions = user.permissions;
|
|
67584
|
+
if (permissions !== void 0 && permissions !== null && (!Array.isArray(permissions) || !permissions.every((permission) => typeof permission === "string"))) {
|
|
67585
|
+
return null;
|
|
67586
|
+
}
|
|
67587
|
+
if (record24.credentialId !== void 0 && typeof record24.credentialId !== "string") return null;
|
|
67588
|
+
return {
|
|
67589
|
+
user: {
|
|
67590
|
+
id: user.id,
|
|
67591
|
+
username: user.username,
|
|
67592
|
+
role: user.role,
|
|
67593
|
+
permissions,
|
|
67594
|
+
platform_user_id: typeof user.platform_user_id === "string" ? user.platform_user_id : null,
|
|
67595
|
+
email: typeof user.email === "string" ? user.email : null,
|
|
67596
|
+
display_name: typeof user.display_name === "string" ? user.display_name : null,
|
|
67597
|
+
avatar_url: typeof user.avatar_url === "string" ? user.avatar_url : null
|
|
67598
|
+
},
|
|
67599
|
+
authType: record24.authType,
|
|
67600
|
+
credentialId: record24.credentialId
|
|
67601
|
+
};
|
|
67602
|
+
}
|
|
67603
|
+
async function consumeWebSocketTicket(request, env2) {
|
|
67604
|
+
if (request.headers.get("upgrade")?.toLowerCase() !== "websocket") return null;
|
|
67605
|
+
let url;
|
|
67606
|
+
try {
|
|
67607
|
+
url = new URL(request.url);
|
|
67608
|
+
} catch {
|
|
67609
|
+
return null;
|
|
67610
|
+
}
|
|
67611
|
+
const ticket = url.searchParams.get("ticket");
|
|
67612
|
+
if (!ticket) return null;
|
|
67613
|
+
const authJson = await getAgentBuilder(env2).consumeWebSocketTicket({
|
|
67614
|
+
ticket_hash: await hashToken(ticket),
|
|
67615
|
+
pathname: url.pathname
|
|
67616
|
+
});
|
|
67617
|
+
return typeof authJson === "string" ? parseWebSocketTicketAuth(authJson) : null;
|
|
67618
|
+
}
|
|
67619
|
+
function isWebSocketTicketPath(pathname) {
|
|
67620
|
+
if (!pathname.startsWith("/api/") || pathname.includes("?") || pathname.includes("#")) return false;
|
|
67621
|
+
try {
|
|
67622
|
+
return new URL(pathname, "https://runtime.invalid").pathname === pathname;
|
|
67623
|
+
} catch {
|
|
67624
|
+
return false;
|
|
67625
|
+
}
|
|
67626
|
+
}
|
|
67415
67627
|
async function authenticate(request, env2) {
|
|
67628
|
+
const ticketAuth = await consumeWebSocketTicket(request, env2);
|
|
67629
|
+
if (ticketAuth) return ticketAuth;
|
|
67416
67630
|
const token = extractBearerToken(request);
|
|
67417
67631
|
if (!token) {
|
|
67418
67632
|
return null;
|
|
67419
67633
|
}
|
|
67420
|
-
if (env2.SUPER_ADMIN_PASSWORD && env2.ENCRYPTION_KEY) {
|
|
67634
|
+
if (typeof env2.SUPER_ADMIN_PASSWORD === "string" && typeof env2.ENCRYPTION_KEY === "string") {
|
|
67421
67635
|
if (token.includes(".")) {
|
|
67422
67636
|
const isValidSuperAdmin = await verifySuperAdminToken(
|
|
67423
67637
|
token,
|
|
67424
67638
|
env2.ENCRYPTION_KEY
|
|
67425
67639
|
);
|
|
67426
67640
|
if (isValidSuperAdmin) {
|
|
67427
|
-
|
|
67428
|
-
|
|
67429
|
-
|
|
67430
|
-
|
|
67431
|
-
|
|
67432
|
-
|
|
67433
|
-
|
|
67434
|
-
|
|
67641
|
+
const tokenHash = await hashToken(token);
|
|
67642
|
+
const agentBuilder = getAgentBuilder(env2);
|
|
67643
|
+
if (await agentBuilder.validateSuperAdminSession(tokenHash)) {
|
|
67644
|
+
return {
|
|
67645
|
+
user: {
|
|
67646
|
+
id: "super_admin",
|
|
67647
|
+
username: "admin",
|
|
67648
|
+
role: "admin"
|
|
67649
|
+
},
|
|
67650
|
+
authType: "super_admin"
|
|
67651
|
+
};
|
|
67652
|
+
}
|
|
67435
67653
|
}
|
|
67436
67654
|
}
|
|
67437
67655
|
}
|
|
@@ -67476,7 +67694,8 @@ async function authenticate(request, env2) {
|
|
|
67476
67694
|
display_name: user.display_name ?? null,
|
|
67477
67695
|
avatar_url: user.avatar_url ?? null
|
|
67478
67696
|
},
|
|
67479
|
-
authType: "api_key"
|
|
67697
|
+
authType: "api_key",
|
|
67698
|
+
credentialId: apiKey.id
|
|
67480
67699
|
};
|
|
67481
67700
|
}
|
|
67482
67701
|
}
|
|
@@ -67488,7 +67707,10 @@ async function requireAuth(request, env2) {
|
|
|
67488
67707
|
if (!authContext) {
|
|
67489
67708
|
return new Response(JSON.stringify({ error: "Unauthorized" }), {
|
|
67490
67709
|
status: 401,
|
|
67491
|
-
headers: {
|
|
67710
|
+
headers: {
|
|
67711
|
+
"Content-Type": "application/json",
|
|
67712
|
+
...runtimeCorsHeaders(request, env2)
|
|
67713
|
+
}
|
|
67492
67714
|
});
|
|
67493
67715
|
}
|
|
67494
67716
|
return authContext;
|
|
@@ -67498,12 +67720,15 @@ async function requirePermission(request, env2, permission) {
|
|
|
67498
67720
|
if (result instanceof Response) {
|
|
67499
67721
|
return result;
|
|
67500
67722
|
}
|
|
67501
|
-
if (!
|
|
67723
|
+
if (!hasPermissionInEnvironment(result.user, permission, env2)) {
|
|
67502
67724
|
return new Response(
|
|
67503
67725
|
JSON.stringify({ error: `Forbidden: '${permission}' access required` }),
|
|
67504
67726
|
{
|
|
67505
67727
|
status: 403,
|
|
67506
|
-
headers: {
|
|
67728
|
+
headers: {
|
|
67729
|
+
"Content-Type": "application/json",
|
|
67730
|
+
...runtimeCorsHeaders(request, env2)
|
|
67731
|
+
}
|
|
67507
67732
|
}
|
|
67508
67733
|
);
|
|
67509
67734
|
}
|
|
@@ -67519,36 +67744,110 @@ async function requireAdmin(request, env2) {
|
|
|
67519
67744
|
JSON.stringify({ error: "Forbidden: Admin access required" }),
|
|
67520
67745
|
{
|
|
67521
67746
|
status: 403,
|
|
67522
|
-
headers: {
|
|
67747
|
+
headers: {
|
|
67748
|
+
"Content-Type": "application/json",
|
|
67749
|
+
...runtimeCorsHeaders(request, env2)
|
|
67750
|
+
}
|
|
67523
67751
|
}
|
|
67524
67752
|
);
|
|
67525
67753
|
}
|
|
67526
67754
|
return result;
|
|
67527
67755
|
}
|
|
67756
|
+
function defineController2(controller) {
|
|
67757
|
+
return controller;
|
|
67758
|
+
}
|
|
67528
67759
|
|
|
67529
|
-
// src/
|
|
67530
|
-
|
|
67531
|
-
const
|
|
67532
|
-
|
|
67533
|
-
|
|
67534
|
-
|
|
67760
|
+
// src/api/agents.get.ts
|
|
67761
|
+
var agents_get_default = defineController2(async ({ agents, agentNames, registry, auth }) => {
|
|
67762
|
+
const includeAuthoringDetails = auth?.user.role === "admin";
|
|
67763
|
+
const agentList = [];
|
|
67764
|
+
console.log("[agents.get] Registry packages:", registry?.packages ? Object.keys(registry.packages) : "undefined");
|
|
67765
|
+
if (agents && agentNames) {
|
|
67766
|
+
const globalAgents = await Promise.all(
|
|
67767
|
+
agentNames.map(async (name15) => {
|
|
67768
|
+
try {
|
|
67769
|
+
const loader = agents[name15];
|
|
67770
|
+
if (!loader) {
|
|
67771
|
+
return null;
|
|
67772
|
+
}
|
|
67773
|
+
const definition = await loader();
|
|
67774
|
+
return {
|
|
67775
|
+
id: definition.name,
|
|
67776
|
+
name: definition.name,
|
|
67777
|
+
title: definition.title || definition.name,
|
|
67778
|
+
type: definition.type || "ai_human",
|
|
67779
|
+
description: definition.description || null,
|
|
67780
|
+
icon: definition.icon || null,
|
|
67781
|
+
primary: definition.primary !== false,
|
|
67782
|
+
...includeAuthoringDetails ? {
|
|
67783
|
+
default_prompt: definition.sideA?.prompt || "",
|
|
67784
|
+
default_model: "",
|
|
67785
|
+
tools: [],
|
|
67786
|
+
side_a_label: definition.sideA?.label || null,
|
|
67787
|
+
side_a_agent_prompt: definition.sideA?.prompt || null,
|
|
67788
|
+
side_b_label: definition.sideB?.label || null,
|
|
67789
|
+
side_b_agent_prompt: definition.sideB?.prompt || null,
|
|
67790
|
+
env: definition.env || null
|
|
67791
|
+
} : {},
|
|
67792
|
+
created_at: Math.floor(Date.now() / 1e3),
|
|
67793
|
+
packed: false
|
|
67794
|
+
};
|
|
67795
|
+
} catch (error) {
|
|
67796
|
+
console.error(`Error loading agent ${name15}:`, error);
|
|
67797
|
+
return null;
|
|
67798
|
+
}
|
|
67799
|
+
})
|
|
67800
|
+
);
|
|
67801
|
+
agentList.push(...globalAgents);
|
|
67535
67802
|
}
|
|
67536
|
-
|
|
67537
|
-
|
|
67538
|
-
|
|
67539
|
-
|
|
67540
|
-
|
|
67541
|
-
|
|
67542
|
-
|
|
67543
|
-
|
|
67544
|
-
|
|
67803
|
+
if (registry?.packages) {
|
|
67804
|
+
for (const [packageId, pkg] of Object.entries(registry.packages)) {
|
|
67805
|
+
const packageData = pkg;
|
|
67806
|
+
for (const agentName of packageData.entryAgents) {
|
|
67807
|
+
try {
|
|
67808
|
+
const loader = packageData.agents[agentName];
|
|
67809
|
+
if (!loader) continue;
|
|
67810
|
+
const definition = await loader();
|
|
67811
|
+
agentList.push({
|
|
67812
|
+
id: `${packageId}/${definition.name}`,
|
|
67813
|
+
name: definition.name,
|
|
67814
|
+
title: definition.title || definition.name,
|
|
67815
|
+
type: definition.type || "ai_human",
|
|
67816
|
+
description: definition.description || null,
|
|
67817
|
+
icon: definition.icon || null,
|
|
67818
|
+
primary: definition.primary !== false,
|
|
67819
|
+
...includeAuthoringDetails ? {
|
|
67820
|
+
default_prompt: definition.sideA?.prompt || "",
|
|
67821
|
+
default_model: "",
|
|
67822
|
+
tools: [],
|
|
67823
|
+
side_a_agent_prompt: definition.sideA?.prompt ? definition.sideA.prompt.includes("/") ? definition.sideA.prompt : `${packageId}/${definition.sideA.prompt}` : null,
|
|
67824
|
+
side_b_agent_prompt: definition.sideB?.prompt ? definition.sideB.prompt.includes("/") ? definition.sideB.prompt : `${packageId}/${definition.sideB.prompt}` : null
|
|
67825
|
+
} : {},
|
|
67826
|
+
created_at: Math.floor(Date.now() / 1e3),
|
|
67827
|
+
packed: true,
|
|
67828
|
+
packageId,
|
|
67829
|
+
source: packageData.signature.source
|
|
67830
|
+
});
|
|
67831
|
+
} catch (error) {
|
|
67832
|
+
console.error(`Error loading packed agent ${agentName} from ${packageId}:`, error);
|
|
67833
|
+
}
|
|
67834
|
+
}
|
|
67835
|
+
}
|
|
67545
67836
|
}
|
|
67546
|
-
|
|
67547
|
-
}
|
|
67837
|
+
const validAgents = agentList.filter(Boolean);
|
|
67838
|
+
return Response.json({ agents: validAgents });
|
|
67839
|
+
});
|
|
67548
67840
|
|
|
67549
67841
|
// src/utils/platform-auth.ts
|
|
67550
67842
|
var FALLBACK_PLATFORM_ORIGIN = "https://platform.standardagents.ai";
|
|
67551
67843
|
var SESSION_TTL_SECONDS = 30 * 24 * 60 * 60;
|
|
67844
|
+
function agentBuilderAuthStub(env2) {
|
|
67845
|
+
const namespace = env2.AGENT_BUILDER;
|
|
67846
|
+
if (!namespace || typeof namespace.idFromName !== "function" || typeof namespace.get !== "function") {
|
|
67847
|
+
throw new Error("Server misconfigured: AGENT_BUILDER Durable Object binding is required for platform auth");
|
|
67848
|
+
}
|
|
67849
|
+
return namespace.get(namespace.idFromName("singleton"));
|
|
67850
|
+
}
|
|
67552
67851
|
function platformApiKey(env2) {
|
|
67553
67852
|
const value = env2.STANDARD_AGENTS_API_KEY;
|
|
67554
67853
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
@@ -67707,11 +68006,7 @@ async function getPlatformIdentity(env2) {
|
|
|
67707
68006
|
};
|
|
67708
68007
|
}
|
|
67709
68008
|
async function upsertReplicaUserForPlatformProfile(env2, profile) {
|
|
67710
|
-
const
|
|
67711
|
-
if (!namespace || typeof namespace.idFromName !== "function" || typeof namespace.get !== "function") {
|
|
67712
|
-
throw new Error("Server misconfigured: AGENT_BUILDER Durable Object binding is required for platform auth");
|
|
67713
|
-
}
|
|
67714
|
-
const agentBuilder = namespace.get(namespace.idFromName("singleton"));
|
|
68009
|
+
const agentBuilder = agentBuilderAuthStub(env2);
|
|
67715
68010
|
return await agentBuilder.upsertPlatformReplicaUser({
|
|
67716
68011
|
platform_user_id: profile.platform_user_id,
|
|
67717
68012
|
username: profile.username ?? null,
|
|
@@ -67723,11 +68018,7 @@ async function upsertReplicaUserForPlatformProfile(env2, profile) {
|
|
|
67723
68018
|
});
|
|
67724
68019
|
}
|
|
67725
68020
|
async function mintLocalSessionForPlatformUser(env2, platformUser) {
|
|
67726
|
-
const
|
|
67727
|
-
if (!namespace || typeof namespace.idFromName !== "function" || typeof namespace.get !== "function") {
|
|
67728
|
-
throw new Error("Server misconfigured: AGENT_BUILDER Durable Object binding is required for platform auth");
|
|
67729
|
-
}
|
|
67730
|
-
const agentBuilder = namespace.get(namespace.idFromName("singleton"));
|
|
68021
|
+
const agentBuilder = agentBuilderAuthStub(env2);
|
|
67731
68022
|
const profile = typeof platformUser === "string" ? { platform_user_id: platformUser, username: `sa-${platformUser.slice(0, 12)}`, role: "admin" } : platformUser;
|
|
67732
68023
|
const user = await upsertReplicaUserForPlatformProfile(env2, profile);
|
|
67733
68024
|
if (user.role === "api") {
|
|
@@ -67739,6 +68030,12 @@ async function mintLocalSessionForPlatformUser(env2, platformUser) {
|
|
|
67739
68030
|
await agentBuilder.createSession({ user_id: user.id, token_hash: tokenHash, expires_at: expiresAt });
|
|
67740
68031
|
return { token, user: { id: user.id, username: user.username, role: user.role } };
|
|
67741
68032
|
}
|
|
68033
|
+
async function consumePlatformHandoffJti(env2, jti, expiresAt) {
|
|
68034
|
+
return agentBuilderAuthStub(env2).consumePlatformHandoffJti({
|
|
68035
|
+
jti,
|
|
68036
|
+
expires_at: expiresAt
|
|
68037
|
+
});
|
|
68038
|
+
}
|
|
67742
68039
|
async function createPlatformLocalSession(request, env2) {
|
|
67743
68040
|
if (!isTrustedLocalDevelopmentRequest(request, env2)) {
|
|
67744
68041
|
return null;
|
|
@@ -67752,12 +68049,7 @@ async function createPlatformLocalSession(request, env2) {
|
|
|
67752
68049
|
if (!identity) {
|
|
67753
68050
|
throw new Error("STANDARD_AGENTS_API_KEY could not be resolved to one active user-instance membership.");
|
|
67754
68051
|
}
|
|
67755
|
-
const
|
|
67756
|
-
if (!agentBuilderNamespace || typeof agentBuilderNamespace.idFromName !== "function" || typeof agentBuilderNamespace.get !== "function") {
|
|
67757
|
-
throw new Error("Server misconfigured: AGENT_BUILDER Durable Object binding is required for platform auth");
|
|
67758
|
-
}
|
|
67759
|
-
const agentBuilderId = agentBuilderNamespace.idFromName("singleton");
|
|
67760
|
-
const agentBuilder = agentBuilderNamespace.get(agentBuilderId);
|
|
68052
|
+
const agentBuilder = agentBuilderAuthStub(env2);
|
|
67761
68053
|
const user = await agentBuilder.upsertPlatformReplicaUser({
|
|
67762
68054
|
platform_user_id: identity.user.id,
|
|
67763
68055
|
username: identity.user.username,
|
|
@@ -67813,7 +68105,7 @@ var index_get_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
67813
68105
|
});
|
|
67814
68106
|
|
|
67815
68107
|
// src/api/api-keys/index.post.ts
|
|
67816
|
-
var
|
|
68108
|
+
var index_post_default = defineController2(async ({ req, env: env2 }) => {
|
|
67817
68109
|
try {
|
|
67818
68110
|
if (isPlatformHosted(env2)) {
|
|
67819
68111
|
return Response.json({ error: "API keys are managed in the Standard Agents platform." }, { status: 410 });
|
|
@@ -68031,7 +68323,7 @@ var config_get_default = defineController2(async ({ config, env: env2, req }) =>
|
|
|
68031
68323
|
});
|
|
68032
68324
|
|
|
68033
68325
|
// src/version.ts
|
|
68034
|
-
var BUILDER_VERSION = "0.
|
|
68326
|
+
var BUILDER_VERSION = "0.38.1".length > 0 ? "0.38.1" : "dev";
|
|
68035
68327
|
|
|
68036
68328
|
// src/api/diagnostics.get.ts
|
|
68037
68329
|
init_LLMRequest();
|
|
@@ -68429,11 +68721,6 @@ var models_get_default = defineController2(async ({ models, modelNames }) => {
|
|
|
68429
68721
|
const validModels = modelList.filter(Boolean);
|
|
68430
68722
|
return Response.json({ models: validModels });
|
|
68431
68723
|
});
|
|
68432
|
-
|
|
68433
|
-
// src/api/new-test.get.ts
|
|
68434
|
-
var new_test_get_default = defineController2(async ({ req, params, env: env2 }) => {
|
|
68435
|
-
return { message: "Modified new test API route", timestamp: (/* @__PURE__ */ new Date()).toISOString() };
|
|
68436
|
-
});
|
|
68437
68724
|
function toJSONSchema(schema) {
|
|
68438
68725
|
if (!schema) return null;
|
|
68439
68726
|
if (schema && typeof schema === "object" && ("~standard" in schema || "_def" in schema)) {
|
|
@@ -68540,6 +68827,7 @@ var providers_get_default = defineController2(async ({ env: env2 }) => {
|
|
|
68540
68827
|
});
|
|
68541
68828
|
|
|
68542
68829
|
// src/api/skills/index.get.ts
|
|
68830
|
+
init_scope();
|
|
68543
68831
|
var index_get_default2 = defineController2(async ({ req, env: env2 }) => {
|
|
68544
68832
|
const authResult = await requireAdmin(req, env2);
|
|
68545
68833
|
if (authResult instanceof Response) return authResult;
|
|
@@ -68547,7 +68835,10 @@ var index_get_default2 = defineController2(async ({ req, env: env2 }) => {
|
|
|
68547
68835
|
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
68548
68836
|
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
68549
68837
|
try {
|
|
68550
|
-
const skills = await agentBuilder.listSkills(
|
|
68838
|
+
const skills = await agentBuilder.listSkills(
|
|
68839
|
+
{ ownerId: SHARED_SKILL_OWNER },
|
|
68840
|
+
{ includeDisabled }
|
|
68841
|
+
);
|
|
68551
68842
|
return Response.json({ skills });
|
|
68552
68843
|
} catch (error) {
|
|
68553
68844
|
return Response.json(
|
|
@@ -68562,7 +68853,8 @@ var SkillValidationError = class extends Error {
|
|
|
68562
68853
|
};
|
|
68563
68854
|
|
|
68564
68855
|
// src/api/skills/index.post.ts
|
|
68565
|
-
|
|
68856
|
+
init_scope();
|
|
68857
|
+
var index_post_default2 = defineController2(async ({ req, env: env2 }) => {
|
|
68566
68858
|
const authResult = await requireAdmin(req, env2);
|
|
68567
68859
|
if (authResult instanceof Response) return authResult;
|
|
68568
68860
|
let body;
|
|
@@ -68584,7 +68876,7 @@ var index_post_default3 = defineController2(async ({ req, env: env2 }) => {
|
|
|
68584
68876
|
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
68585
68877
|
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
68586
68878
|
try {
|
|
68587
|
-
const skill = await agentBuilder.upsertSkill(files);
|
|
68879
|
+
const skill = await agentBuilder.upsertSkill({ ownerId: SHARED_SKILL_OWNER }, files);
|
|
68588
68880
|
return Response.json({ skill }, { status: 201 });
|
|
68589
68881
|
} catch (error) {
|
|
68590
68882
|
const message = error instanceof Error ? error.message : "Failed to install skill";
|
|
@@ -68646,7 +68938,7 @@ async function hasEnabledImmediatePromptTools(agentBuilder, threadId, agentId) {
|
|
|
68646
68938
|
}
|
|
68647
68939
|
return false;
|
|
68648
68940
|
}
|
|
68649
|
-
var
|
|
68941
|
+
var index_post_default3 = defineController2(async ({ req, env: env2 }) => {
|
|
68650
68942
|
const authResult = await requireAuth(req, env2);
|
|
68651
68943
|
if (authResult instanceof Response) {
|
|
68652
68944
|
return authResult;
|
|
@@ -69243,15 +69535,138 @@ var migration17 = {
|
|
|
69243
69535
|
}
|
|
69244
69536
|
};
|
|
69245
69537
|
|
|
69538
|
+
// src/durable-objects/agentbuilder-migrations/0018_auth_security.ts
|
|
69539
|
+
var migration18 = {
|
|
69540
|
+
version: 18,
|
|
69541
|
+
async up(sql) {
|
|
69542
|
+
sql.exec(`
|
|
69543
|
+
CREATE TABLE IF NOT EXISTS super_admin_sessions (
|
|
69544
|
+
token_hash TEXT PRIMARY KEY,
|
|
69545
|
+
created_at INTEGER NOT NULL,
|
|
69546
|
+
expires_at INTEGER NOT NULL
|
|
69547
|
+
)
|
|
69548
|
+
`);
|
|
69549
|
+
sql.exec(`
|
|
69550
|
+
CREATE INDEX IF NOT EXISTS idx_super_admin_sessions_expires
|
|
69551
|
+
ON super_admin_sessions(expires_at)
|
|
69552
|
+
`);
|
|
69553
|
+
sql.exec(`
|
|
69554
|
+
CREATE TABLE IF NOT EXISTS auth_rate_limits (
|
|
69555
|
+
bucket_key TEXT PRIMARY KEY,
|
|
69556
|
+
attempts INTEGER NOT NULL,
|
|
69557
|
+
reset_at INTEGER NOT NULL
|
|
69558
|
+
)
|
|
69559
|
+
`);
|
|
69560
|
+
sql.exec(`
|
|
69561
|
+
CREATE INDEX IF NOT EXISTS idx_auth_rate_limits_reset
|
|
69562
|
+
ON auth_rate_limits(reset_at)
|
|
69563
|
+
`);
|
|
69564
|
+
sql.exec(`
|
|
69565
|
+
INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '18')
|
|
69566
|
+
`);
|
|
69567
|
+
}
|
|
69568
|
+
};
|
|
69569
|
+
|
|
69570
|
+
// src/durable-objects/agentbuilder-migrations/0019_scope_skills.ts
|
|
69571
|
+
var migration19 = {
|
|
69572
|
+
version: 19,
|
|
69573
|
+
async up(sql) {
|
|
69574
|
+
sql.exec(`
|
|
69575
|
+
CREATE TABLE skills_0019 (
|
|
69576
|
+
owner_id TEXT NOT NULL,
|
|
69577
|
+
name TEXT NOT NULL,
|
|
69578
|
+
description TEXT NOT NULL,
|
|
69579
|
+
version TEXT,
|
|
69580
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
69581
|
+
shared INTEGER NOT NULL DEFAULT 0,
|
|
69582
|
+
created_at INTEGER DEFAULT (strftime('%s', 'now')),
|
|
69583
|
+
updated_at INTEGER DEFAULT (strftime('%s', 'now')),
|
|
69584
|
+
PRIMARY KEY (owner_id, name)
|
|
69585
|
+
)
|
|
69586
|
+
`);
|
|
69587
|
+
sql.exec(`
|
|
69588
|
+
INSERT INTO skills_0019 (
|
|
69589
|
+
owner_id, name, description, version, enabled, shared, created_at, updated_at
|
|
69590
|
+
)
|
|
69591
|
+
SELECT '__instance_shared__', name, description, version, enabled, 1, created_at, updated_at
|
|
69592
|
+
FROM skills
|
|
69593
|
+
`);
|
|
69594
|
+
sql.exec(`
|
|
69595
|
+
CREATE TABLE skill_files_0019 (
|
|
69596
|
+
owner_id TEXT NOT NULL,
|
|
69597
|
+
skill_name TEXT NOT NULL,
|
|
69598
|
+
path TEXT NOT NULL,
|
|
69599
|
+
content TEXT NOT NULL,
|
|
69600
|
+
size INTEGER NOT NULL,
|
|
69601
|
+
PRIMARY KEY (owner_id, skill_name, path),
|
|
69602
|
+
FOREIGN KEY (owner_id, skill_name) REFERENCES skills_0019(owner_id, name) ON DELETE CASCADE
|
|
69603
|
+
)
|
|
69604
|
+
`);
|
|
69605
|
+
sql.exec(`
|
|
69606
|
+
INSERT INTO skill_files_0019 (owner_id, skill_name, path, content, size)
|
|
69607
|
+
SELECT '__instance_shared__', skill_name, path, content, size FROM skill_files
|
|
69608
|
+
`);
|
|
69609
|
+
sql.exec(`DROP TABLE skill_files`);
|
|
69610
|
+
sql.exec(`DROP TABLE skills`);
|
|
69611
|
+
sql.exec(`ALTER TABLE skills_0019 RENAME TO skills`);
|
|
69612
|
+
sql.exec(`ALTER TABLE skill_files_0019 RENAME TO skill_files`);
|
|
69613
|
+
sql.exec(`CREATE INDEX idx_skills_owner_enabled ON skills(owner_id, enabled)`);
|
|
69614
|
+
sql.exec(`CREATE INDEX idx_skills_shared_enabled ON skills(shared, enabled)`);
|
|
69615
|
+
sql.exec(`CREATE INDEX idx_skill_files_skill ON skill_files(owner_id, skill_name)`);
|
|
69616
|
+
sql.exec(`INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '19')`);
|
|
69617
|
+
}
|
|
69618
|
+
};
|
|
69619
|
+
|
|
69620
|
+
// src/durable-objects/agentbuilder-migrations/0020_websocket_tickets.ts
|
|
69621
|
+
var migration20 = {
|
|
69622
|
+
version: 20,
|
|
69623
|
+
async up(sql) {
|
|
69624
|
+
sql.exec(`
|
|
69625
|
+
CREATE TABLE websocket_tickets (
|
|
69626
|
+
ticket_hash TEXT PRIMARY KEY,
|
|
69627
|
+
pathname TEXT NOT NULL,
|
|
69628
|
+
auth_json TEXT NOT NULL,
|
|
69629
|
+
created_at INTEGER NOT NULL,
|
|
69630
|
+
expires_at INTEGER NOT NULL
|
|
69631
|
+
)
|
|
69632
|
+
`);
|
|
69633
|
+
sql.exec(`
|
|
69634
|
+
CREATE INDEX idx_websocket_tickets_expires
|
|
69635
|
+
ON websocket_tickets(expires_at)
|
|
69636
|
+
`);
|
|
69637
|
+
sql.exec(`INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '20')`);
|
|
69638
|
+
}
|
|
69639
|
+
};
|
|
69640
|
+
|
|
69641
|
+
// src/durable-objects/agentbuilder-migrations/0021_platform_handoff_jtis.ts
|
|
69642
|
+
var migration21 = {
|
|
69643
|
+
version: 21,
|
|
69644
|
+
async up(sql) {
|
|
69645
|
+
sql.exec(`
|
|
69646
|
+
CREATE TABLE platform_handoff_jtis (
|
|
69647
|
+
jti TEXT PRIMARY KEY,
|
|
69648
|
+
consumed_at INTEGER NOT NULL,
|
|
69649
|
+
expires_at INTEGER NOT NULL
|
|
69650
|
+
)
|
|
69651
|
+
`);
|
|
69652
|
+
sql.exec(`
|
|
69653
|
+
CREATE INDEX idx_platform_handoff_jtis_expires
|
|
69654
|
+
ON platform_handoff_jtis(expires_at)
|
|
69655
|
+
`);
|
|
69656
|
+
sql.exec(`INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '21')`);
|
|
69657
|
+
}
|
|
69658
|
+
};
|
|
69659
|
+
|
|
69246
69660
|
// src/durable-objects/agentbuilder-migrations/index.ts
|
|
69247
|
-
var migrations = [migration, migration2, migration3, migration4, migration5, migration6, migration7, migration8, migration9, migration10, migration11, migration12, migration13, migration14, migration15, migration16, migration17];
|
|
69661
|
+
var migrations = [migration, migration2, migration3, migration4, migration5, migration6, migration7, migration8, migration9, migration10, migration11, migration12, migration13, migration14, migration15, migration16, migration17, migration18, migration19, migration20, migration21];
|
|
69248
69662
|
migrations.reduce(
|
|
69249
|
-
(max,
|
|
69663
|
+
(max, migration22) => Math.max(max, migration22.version),
|
|
69250
69664
|
0
|
|
69251
69665
|
);
|
|
69252
69666
|
|
|
69253
69667
|
// src/durable-objects/DurableAgentBuilder.ts
|
|
69254
69668
|
init_types();
|
|
69669
|
+
init_scope();
|
|
69255
69670
|
var THREAD_PREVIEW_MAX_CHARS = 140;
|
|
69256
69671
|
var buildThreadPreview = (content) => {
|
|
69257
69672
|
const collapsed = content.replace(/\s+/g, " ").trim();
|
|
@@ -69607,7 +70022,7 @@ var index_get_default3 = defineController2(async ({ req, env: env2 }) => {
|
|
|
69607
70022
|
|
|
69608
70023
|
// src/api/users/index.post.ts
|
|
69609
70024
|
var VALID_ROLES = ["admin", "user"];
|
|
69610
|
-
var
|
|
70025
|
+
var index_post_default4 = defineController2(async ({ req, env: env2 }) => {
|
|
69611
70026
|
try {
|
|
69612
70027
|
if (isPlatformHosted(env2)) {
|
|
69613
70028
|
return Response.json({ error: "Users are managed in the Standard Agents platform." }, { status: 410 });
|
|
@@ -69871,7 +70286,7 @@ var name_get_default2 = defineController2(async ({ params, models }) => {
|
|
|
69871
70286
|
});
|
|
69872
70287
|
|
|
69873
70288
|
// src/api/pack/[agentName]/index.post.ts
|
|
69874
|
-
var
|
|
70289
|
+
var index_post_default5 = defineController2(async ({ req, env: env2 }) => {
|
|
69875
70290
|
const auth = await requireAdmin(req, env2);
|
|
69876
70291
|
if (auth instanceof Response) return auth;
|
|
69877
70292
|
const url = new URL(req.url);
|
|
@@ -70051,6 +70466,7 @@ var name_get_default3 = defineController2(async ({ params, prompts, models, mode
|
|
|
70051
70466
|
});
|
|
70052
70467
|
|
|
70053
70468
|
// src/api/skills/[name].delete.ts
|
|
70469
|
+
init_scope();
|
|
70054
70470
|
var name_delete_default = defineController2(async ({ req, env: env2, params }) => {
|
|
70055
70471
|
const authResult = await requireAdmin(req, env2);
|
|
70056
70472
|
if (authResult instanceof Response) return authResult;
|
|
@@ -70059,7 +70475,7 @@ var name_delete_default = defineController2(async ({ req, env: env2, params }) =
|
|
|
70059
70475
|
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
70060
70476
|
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
70061
70477
|
try {
|
|
70062
|
-
const found = await agentBuilder.deleteSkill(name15);
|
|
70478
|
+
const found = await agentBuilder.deleteSkill({ ownerId: SHARED_SKILL_OWNER }, name15);
|
|
70063
70479
|
if (!found) return Response.json({ error: `Skill not found: ${name15}` }, { status: 404 });
|
|
70064
70480
|
return Response.json({ ok: true, removed: name15 });
|
|
70065
70481
|
} catch (error) {
|
|
@@ -70071,6 +70487,7 @@ var name_delete_default = defineController2(async ({ req, env: env2, params }) =
|
|
|
70071
70487
|
});
|
|
70072
70488
|
|
|
70073
70489
|
// src/api/skills/[name].get.ts
|
|
70490
|
+
init_scope();
|
|
70074
70491
|
var name_get_default4 = defineController2(async ({ req, env: env2, params }) => {
|
|
70075
70492
|
const authResult = await requireAdmin(req, env2);
|
|
70076
70493
|
if (authResult instanceof Response) return authResult;
|
|
@@ -70079,9 +70496,10 @@ var name_get_default4 = defineController2(async ({ req, env: env2, params }) =>
|
|
|
70079
70496
|
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
70080
70497
|
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
70081
70498
|
try {
|
|
70082
|
-
const
|
|
70499
|
+
const scope = { ownerId: SHARED_SKILL_OWNER };
|
|
70500
|
+
const skill = await agentBuilder.getSkill(scope, name15);
|
|
70083
70501
|
if (!skill) return Response.json({ error: `Skill not found: ${name15}` }, { status: 404 });
|
|
70084
|
-
const skillMd = await agentBuilder.getSkillFile(name15, "SKILL.md") ?? "";
|
|
70502
|
+
const skillMd = await agentBuilder.getSkillFile(scope, name15, "SKILL.md") ?? "";
|
|
70085
70503
|
return Response.json({ skill, skillMd });
|
|
70086
70504
|
} catch (error) {
|
|
70087
70505
|
return Response.json(
|
|
@@ -70092,6 +70510,7 @@ var name_get_default4 = defineController2(async ({ req, env: env2, params }) =>
|
|
|
70092
70510
|
});
|
|
70093
70511
|
|
|
70094
70512
|
// src/api/skills/[name].patch.ts
|
|
70513
|
+
init_scope();
|
|
70095
70514
|
var name_patch_default = defineController2(async ({ req, env: env2, params }) => {
|
|
70096
70515
|
const authResult = await requireAdmin(req, env2);
|
|
70097
70516
|
if (authResult instanceof Response) return authResult;
|
|
@@ -70109,9 +70528,10 @@ var name_patch_default = defineController2(async ({ req, env: env2, params }) =>
|
|
|
70109
70528
|
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
70110
70529
|
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
70111
70530
|
try {
|
|
70112
|
-
const
|
|
70531
|
+
const scope = { ownerId: SHARED_SKILL_OWNER };
|
|
70532
|
+
const found = await agentBuilder.setSkillEnabled(scope, name15, body.enabled);
|
|
70113
70533
|
if (!found) return Response.json({ error: `Skill not found: ${name15}` }, { status: 404 });
|
|
70114
|
-
const skill = await agentBuilder.getSkill(name15);
|
|
70534
|
+
const skill = await agentBuilder.getSkill(scope, name15);
|
|
70115
70535
|
return Response.json({ skill });
|
|
70116
70536
|
} catch (error) {
|
|
70117
70537
|
return Response.json(
|
|
@@ -70408,7 +70828,6 @@ var id_patch_default = defineController2(async ({ req, env: env2, params }) => {
|
|
|
70408
70828
|
// Map agent_name back to agent_id for API compat
|
|
70409
70829
|
user_id: updatedThread.user_id,
|
|
70410
70830
|
tags: updatedThread.tags || [],
|
|
70411
|
-
env: updatedThread.env ?? updatedThread.tenvs ?? null,
|
|
70412
70831
|
env_types: updatedThread.env_types ?? null,
|
|
70413
70832
|
created_at: updatedThread.created_at
|
|
70414
70833
|
});
|
|
@@ -70424,15 +70843,17 @@ var id_patch_default = defineController2(async ({ req, env: env2, params }) => {
|
|
|
70424
70843
|
// src/middleware/request-auth.ts
|
|
70425
70844
|
async function resolveRequestAuth(context) {
|
|
70426
70845
|
if (context.auth) return context.auth;
|
|
70846
|
+
if (!isAuthenticationEnv(context.env)) {
|
|
70847
|
+
return new Response(JSON.stringify({ error: "Unauthorized" }), {
|
|
70848
|
+
status: 401,
|
|
70849
|
+
headers: { "Content-Type": "application/json" }
|
|
70850
|
+
});
|
|
70851
|
+
}
|
|
70427
70852
|
return requireAuth(context.req, context.env);
|
|
70428
70853
|
}
|
|
70429
|
-
async function resolveOptionalRequestAuth(context) {
|
|
70430
|
-
if (context.auth) return context.auth;
|
|
70431
|
-
return authenticate(context.req, context.env);
|
|
70432
|
-
}
|
|
70433
70854
|
async function resolveRequestPermission(context, permission) {
|
|
70434
70855
|
if (context.auth) {
|
|
70435
|
-
if (!
|
|
70856
|
+
if (!hasPermissionInEnvironment(context.auth.user, permission, context.env)) {
|
|
70436
70857
|
return Response.json(
|
|
70437
70858
|
{ error: `Forbidden: '${permission}' access required` },
|
|
70438
70859
|
{ status: 403 }
|
|
@@ -70578,7 +70999,7 @@ var name_get_default5 = defineController2(async ({ params, tools }) => {
|
|
|
70578
70999
|
|
|
70579
71000
|
// src/api/unpack/[packageId]/index.post.ts
|
|
70580
71001
|
init_package_identifier();
|
|
70581
|
-
var
|
|
71002
|
+
var index_post_default6 = defineController2(async ({ req, env: env2 }) => {
|
|
70582
71003
|
const auth = await requireAdmin(req, env2);
|
|
70583
71004
|
if (auth instanceof Response) return auth;
|
|
70584
71005
|
const url = new URL(req.url);
|
|
@@ -70723,17 +71144,43 @@ var id_put_default = defineController2(async ({ req, env: env2, params }) => {
|
|
|
70723
71144
|
});
|
|
70724
71145
|
|
|
70725
71146
|
// src/api/auth/bootstrap.post.ts
|
|
71147
|
+
var SESSION_TTL_SECONDS2 = 30 * 24 * 60 * 60;
|
|
70726
71148
|
var bootstrap_post_default = defineController2(async ({ req, env: env2 }) => {
|
|
70727
71149
|
try {
|
|
71150
|
+
if (!isTrustedLocalDevelopmentRequest(req, env2) || !isSameOriginBrowserRequest(req)) {
|
|
71151
|
+
return Response.json(
|
|
71152
|
+
{ error: "Local bootstrap is available only to same-origin clients" },
|
|
71153
|
+
{ status: 403, headers: { "Cache-Control": "no-store" } }
|
|
71154
|
+
);
|
|
71155
|
+
}
|
|
70728
71156
|
const platformTokenSession = await createPlatformLocalSession(req, env2);
|
|
70729
71157
|
if (!platformTokenSession) {
|
|
70730
|
-
return new Response(null, {
|
|
71158
|
+
return new Response(null, {
|
|
71159
|
+
status: 204,
|
|
71160
|
+
headers: { "Cache-Control": "no-store" }
|
|
71161
|
+
});
|
|
70731
71162
|
}
|
|
70732
|
-
return Response.json(
|
|
71163
|
+
return Response.json({
|
|
71164
|
+
user: platformTokenSession.user,
|
|
71165
|
+
authType: platformTokenSession.authType,
|
|
71166
|
+
platform: platformTokenSession.platform
|
|
71167
|
+
}, {
|
|
71168
|
+
headers: {
|
|
71169
|
+
"Cache-Control": "no-store",
|
|
71170
|
+
"Set-Cookie": buildSessionCookie(
|
|
71171
|
+
req,
|
|
71172
|
+
platformTokenSession.token,
|
|
71173
|
+
SESSION_TTL_SECONDS2
|
|
71174
|
+
)
|
|
71175
|
+
}
|
|
71176
|
+
});
|
|
70733
71177
|
} catch (error) {
|
|
70734
71178
|
const message = error instanceof Error ? error.message : "Failed to bootstrap platform auth";
|
|
70735
71179
|
const status = message.includes("STANDARD_AGENTS_API_KEY") ? 401 : 502;
|
|
70736
|
-
return Response.json(
|
|
71180
|
+
return Response.json(
|
|
71181
|
+
{ error: message },
|
|
71182
|
+
{ status, headers: { "Cache-Control": "no-store" } }
|
|
71183
|
+
);
|
|
70737
71184
|
}
|
|
70738
71185
|
});
|
|
70739
71186
|
|
|
@@ -70862,7 +71309,51 @@ var config_get_default2 = defineController2(async ({ req, env: env2 }) => {
|
|
|
70862
71309
|
};
|
|
70863
71310
|
});
|
|
70864
71311
|
|
|
71312
|
+
// src/api/auth/current-key.delete.ts
|
|
71313
|
+
var current_key_delete_default = defineController2(async ({ req, env: env2 }) => {
|
|
71314
|
+
try {
|
|
71315
|
+
const auth = await authenticate(req, env2);
|
|
71316
|
+
if (!auth) return Response.json({ error: "Unauthorized" }, { status: 401 });
|
|
71317
|
+
if (auth.authType !== "api_key" || !auth.credentialId) {
|
|
71318
|
+
return Response.json({ error: "An API key must authenticate this request." }, { status: 403 });
|
|
71319
|
+
}
|
|
71320
|
+
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
71321
|
+
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
71322
|
+
await agentBuilder.deleteApiKey(auth.credentialId, auth.user.id);
|
|
71323
|
+
return Response.json({ revoked: true });
|
|
71324
|
+
} catch (error) {
|
|
71325
|
+
console.error("Current API key revocation error:", error);
|
|
71326
|
+
return Response.json(
|
|
71327
|
+
{ error: error instanceof Error ? error.message : "Failed to revoke API key" },
|
|
71328
|
+
{ status: 500 }
|
|
71329
|
+
);
|
|
71330
|
+
}
|
|
71331
|
+
});
|
|
71332
|
+
|
|
71333
|
+
// src/utils/auth-rate-limit.ts
|
|
71334
|
+
function authClientAddress(request) {
|
|
71335
|
+
return request.headers.get("CF-Connecting-IP")?.trim() || request.headers.get("X-Real-IP")?.trim() || request.headers.get("X-Forwarded-For")?.split(",")[0]?.trim() || "unknown";
|
|
71336
|
+
}
|
|
71337
|
+
async function authRateLimitKey(scope, identifier) {
|
|
71338
|
+
return `${scope}:${await hashToken(identifier.trim().toLowerCase())}`;
|
|
71339
|
+
}
|
|
71340
|
+
function authRateLimitedResponse(result) {
|
|
71341
|
+
return Response.json(
|
|
71342
|
+
{ error: "Too many authentication attempts. Try again later." },
|
|
71343
|
+
{
|
|
71344
|
+
status: 429,
|
|
71345
|
+
headers: {
|
|
71346
|
+
"Cache-Control": "no-store",
|
|
71347
|
+
"Retry-After": String(Math.max(1, Math.ceil(result.retry_after)))
|
|
71348
|
+
}
|
|
71349
|
+
}
|
|
71350
|
+
);
|
|
71351
|
+
}
|
|
71352
|
+
|
|
70865
71353
|
// src/api/auth/login.post.ts
|
|
71354
|
+
var LOGIN_ADDRESS_LIMIT = { limit: 10, window_seconds: 5 * 60 };
|
|
71355
|
+
var LOGIN_IDENTITY_LIMIT = { limit: 25, window_seconds: 15 * 60 };
|
|
71356
|
+
var LOGIN_INSTANCE_LIMIT = { limit: 500, window_seconds: 5 * 60 };
|
|
70866
71357
|
var login_post_default = defineController2(async ({ req, env: env2 }) => {
|
|
70867
71358
|
try {
|
|
70868
71359
|
if (isPlatformHosted(env2)) {
|
|
@@ -70879,7 +71370,31 @@ var login_post_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
70879
71370
|
{ status: 400 }
|
|
70880
71371
|
);
|
|
70881
71372
|
}
|
|
70882
|
-
if (env2.
|
|
71373
|
+
if (!env2.AGENT_BUILDER || typeof env2.AGENT_BUILDER.idFromName !== "function") {
|
|
71374
|
+
return Response.json(
|
|
71375
|
+
{ error: "Server misconfigured: AGENT_BUILDER Durable Object binding is required for local login" },
|
|
71376
|
+
{ status: 500 }
|
|
71377
|
+
);
|
|
71378
|
+
}
|
|
71379
|
+
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
71380
|
+
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
71381
|
+
const instanceLimit = await agentBuilder.consumeAuthRateLimit({
|
|
71382
|
+
key: "login-instance",
|
|
71383
|
+
...LOGIN_INSTANCE_LIMIT
|
|
71384
|
+
});
|
|
71385
|
+
if (!instanceLimit.allowed) return authRateLimitedResponse(instanceLimit);
|
|
71386
|
+
const addressLimit = await agentBuilder.consumeAuthRateLimit({
|
|
71387
|
+
key: await authRateLimitKey("login-address", authClientAddress(req)),
|
|
71388
|
+
...LOGIN_ADDRESS_LIMIT
|
|
71389
|
+
});
|
|
71390
|
+
if (!addressLimit.allowed) return authRateLimitedResponse(addressLimit);
|
|
71391
|
+
const identityLimit = await agentBuilder.consumeAuthRateLimit({
|
|
71392
|
+
key: await authRateLimitKey("login-identity", username || "<missing>"),
|
|
71393
|
+
...LOGIN_IDENTITY_LIMIT
|
|
71394
|
+
});
|
|
71395
|
+
if (!identityLimit.allowed) return authRateLimitedResponse(identityLimit);
|
|
71396
|
+
const isSuperAdminPassword = env2.SUPER_ADMIN_PASSWORD && username === "admin" ? await constantTimeEqual(password, env2.SUPER_ADMIN_PASSWORD) : false;
|
|
71397
|
+
if (isSuperAdminPassword) {
|
|
70883
71398
|
if (!env2.ENCRYPTION_KEY) {
|
|
70884
71399
|
return Response.json(
|
|
70885
71400
|
{ error: "Server misconfigured: ENCRYPTION_KEY required for super admin" },
|
|
@@ -70887,6 +71402,12 @@ var login_post_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
70887
71402
|
);
|
|
70888
71403
|
}
|
|
70889
71404
|
const token2 = await generateSuperAdminToken(env2.ENCRYPTION_KEY);
|
|
71405
|
+
const tokenHash2 = await hashToken(token2);
|
|
71406
|
+
const expiresAt2 = Math.floor(Date.now() / 1e3) + SUPER_ADMIN_TOKEN_TTL_SECONDS;
|
|
71407
|
+
await agentBuilder.createSuperAdminSession({
|
|
71408
|
+
token_hash: tokenHash2,
|
|
71409
|
+
expires_at: expiresAt2
|
|
71410
|
+
});
|
|
70890
71411
|
return Response.json({
|
|
70891
71412
|
token: token2,
|
|
70892
71413
|
user: {
|
|
@@ -70894,6 +71415,11 @@ var login_post_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
70894
71415
|
username: "admin",
|
|
70895
71416
|
role: "admin"
|
|
70896
71417
|
}
|
|
71418
|
+
}, {
|
|
71419
|
+
headers: {
|
|
71420
|
+
"Cache-Control": "no-store",
|
|
71421
|
+
"Set-Cookie": buildSessionCookie(req, token2, SUPER_ADMIN_TOKEN_TTL_SECONDS)
|
|
71422
|
+
}
|
|
70897
71423
|
});
|
|
70898
71424
|
}
|
|
70899
71425
|
if (!username) {
|
|
@@ -70902,14 +71428,6 @@ var login_post_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
70902
71428
|
{ status: 400 }
|
|
70903
71429
|
);
|
|
70904
71430
|
}
|
|
70905
|
-
if (!env2.AGENT_BUILDER || typeof env2.AGENT_BUILDER.idFromName !== "function") {
|
|
70906
|
-
return Response.json(
|
|
70907
|
-
{ error: "Server misconfigured: AGENT_BUILDER Durable Object binding is required for local login" },
|
|
70908
|
-
{ status: 500 }
|
|
70909
|
-
);
|
|
70910
|
-
}
|
|
70911
|
-
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
70912
|
-
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
70913
71431
|
const user = await agentBuilder.getUserByUsername(username);
|
|
70914
71432
|
if (!user) {
|
|
70915
71433
|
return Response.json(
|
|
@@ -70939,11 +71457,16 @@ var login_post_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
70939
71457
|
username: user.username,
|
|
70940
71458
|
role: user.role
|
|
70941
71459
|
}
|
|
71460
|
+
}, {
|
|
71461
|
+
headers: {
|
|
71462
|
+
"Cache-Control": "no-store",
|
|
71463
|
+
"Set-Cookie": buildSessionCookie(req, token, 30 * 24 * 60 * 60)
|
|
71464
|
+
}
|
|
70942
71465
|
});
|
|
70943
71466
|
} catch (error) {
|
|
70944
71467
|
console.error("Login error:", error);
|
|
70945
71468
|
return Response.json(
|
|
70946
|
-
{ error: error.message
|
|
71469
|
+
{ error: error instanceof Error ? error.message : "Login failed" },
|
|
70947
71470
|
{ status: 500 }
|
|
70948
71471
|
);
|
|
70949
71472
|
}
|
|
@@ -70956,38 +71479,23 @@ async function deleteLocalSession(req, env2) {
|
|
|
70956
71479
|
if (!token) {
|
|
70957
71480
|
return;
|
|
70958
71481
|
}
|
|
70959
|
-
|
|
70960
|
-
|
|
70961
|
-
|
|
71482
|
+
const tokenHash = await hashToken(token);
|
|
71483
|
+
const agentBuilder = env2.AGENT_BUILDER.get(env2.AGENT_BUILDER.idFromName("singleton"));
|
|
71484
|
+
if (token.includes(".")) {
|
|
71485
|
+
await agentBuilder.deleteSuperAdminSession(tokenHash);
|
|
71486
|
+
} else if (isValidUserToken(token)) {
|
|
70962
71487
|
await agentBuilder.deleteSession(tokenHash);
|
|
70963
71488
|
}
|
|
70964
71489
|
}
|
|
70965
71490
|
function clearedSessionCookie(req) {
|
|
70966
71491
|
return buildSessionCookie(req, "", 0);
|
|
70967
71492
|
}
|
|
70968
|
-
|
|
70969
|
-
|
|
70970
|
-
|
|
70971
|
-
|
|
70972
|
-
return
|
|
71493
|
+
function isSameOriginLogout(req) {
|
|
71494
|
+
const origin = req.headers.get("Origin");
|
|
71495
|
+
if (origin && origin !== new URL(req.url).origin) return false;
|
|
71496
|
+
const fetchSite = req.headers.get("Sec-Fetch-Site");
|
|
71497
|
+
return !fetchSite || fetchSite === "same-origin" || fetchSite === "none";
|
|
70973
71498
|
}
|
|
70974
|
-
var logout_get_default = defineController2(async ({ req, env: env2 }) => {
|
|
70975
|
-
try {
|
|
70976
|
-
await deleteLocalSession(req, env2);
|
|
70977
|
-
} catch (error) {
|
|
70978
|
-
console.error("Logout error:", error);
|
|
70979
|
-
}
|
|
70980
|
-
const url = new URL(req.url);
|
|
70981
|
-
const returnTo = safeReturnTo(url.searchParams.get("return_to"));
|
|
70982
|
-
const location = isPlatformHosted(env2) ? platformLogoutUrl(req, env2, returnTo) : `${url.origin}/login`;
|
|
70983
|
-
return new Response(null, {
|
|
70984
|
-
status: 302,
|
|
70985
|
-
headers: {
|
|
70986
|
-
Location: location,
|
|
70987
|
-
"Set-Cookie": clearedSessionCookie(req)
|
|
70988
|
-
}
|
|
70989
|
-
});
|
|
70990
|
-
});
|
|
70991
71499
|
|
|
70992
71500
|
// src/api/auth/logout.post.ts
|
|
70993
71501
|
var logout_post_default = defineController2(async ({ req, env: env2 }) => {
|
|
@@ -70998,9 +71506,15 @@ var logout_post_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
70998
71506
|
"Set-Cookie": clearedSessionCookie(req)
|
|
70999
71507
|
}
|
|
71000
71508
|
});
|
|
71509
|
+
if (!isSameOriginLogout(req)) {
|
|
71510
|
+
return Response.json({ error: "Cross-origin logout refused" }, { status: 403 });
|
|
71511
|
+
}
|
|
71001
71512
|
try {
|
|
71002
71513
|
await deleteLocalSession(req, env2);
|
|
71003
|
-
|
|
71514
|
+
const url = new URL(req.url);
|
|
71515
|
+
const returnTo = url.searchParams.get("return_to");
|
|
71516
|
+
const redirect = isPlatformHosted(env2) ? platformLogoutUrl(req, env2, returnTo) : void 0;
|
|
71517
|
+
return clearCookie({ success: true, ...redirect ? { redirect } : {} });
|
|
71004
71518
|
} catch (error) {
|
|
71005
71519
|
console.error("Logout error:", error);
|
|
71006
71520
|
return clearCookie({ error: error.message || "Logout failed" }, 500);
|
|
@@ -71103,6 +71617,37 @@ var platform_replica_post_default = defineController2(async ({ req, env: env2 })
|
|
|
71103
71617
|
return Response.json({ ok: true, ...result });
|
|
71104
71618
|
});
|
|
71105
71619
|
|
|
71620
|
+
// src/api/auth/websocket-ticket.post.ts
|
|
71621
|
+
var WEBSOCKET_TICKET_TTL_SECONDS = 30;
|
|
71622
|
+
var websocket_ticket_post_default = defineController2(async ({ req, env: env2 }) => {
|
|
71623
|
+
const auth = await authenticate(req, env2);
|
|
71624
|
+
if (!auth) return Response.json({ error: "Unauthorized" }, { status: 401 });
|
|
71625
|
+
let body;
|
|
71626
|
+
try {
|
|
71627
|
+
body = await req.json();
|
|
71628
|
+
} catch {
|
|
71629
|
+
return Response.json({ error: "A JSON body is required." }, { status: 400 });
|
|
71630
|
+
}
|
|
71631
|
+
const pathname = body && typeof body === "object" ? body.pathname : void 0;
|
|
71632
|
+
if (typeof pathname !== "string" || !isWebSocketTicketPath(pathname)) {
|
|
71633
|
+
return Response.json({ error: "pathname must be a normalized /api/* path." }, { status: 400 });
|
|
71634
|
+
}
|
|
71635
|
+
const ticket = generateSecureToken(32);
|
|
71636
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
71637
|
+
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
71638
|
+
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
71639
|
+
await agentBuilder.createWebSocketTicket({
|
|
71640
|
+
ticket_hash: await hashToken(ticket),
|
|
71641
|
+
pathname,
|
|
71642
|
+
auth_json: JSON.stringify(auth),
|
|
71643
|
+
expires_at: now + WEBSOCKET_TICKET_TTL_SECONDS
|
|
71644
|
+
});
|
|
71645
|
+
return Response.json(
|
|
71646
|
+
{ ticket, expires_in: WEBSOCKET_TICKET_TTL_SECONDS },
|
|
71647
|
+
{ headers: { "Cache-Control": "no-store" } }
|
|
71648
|
+
);
|
|
71649
|
+
});
|
|
71650
|
+
|
|
71106
71651
|
// src/api/envs/_shared.ts
|
|
71107
71652
|
function buildScopedEnvResponse(entries) {
|
|
71108
71653
|
const variables = [...entries].sort((a, b) => a.name.localeCompare(b.name)).map((entry) => ({
|
|
@@ -71579,6 +72124,7 @@ var path_default = defineController2(async ({ req, params, env: env2, url }) =>
|
|
|
71579
72124
|
});
|
|
71580
72125
|
|
|
71581
72126
|
// src/api/platform-auth/bootstrap.post.ts
|
|
72127
|
+
var AGENT_BUILDER_SESSION_TTL_SECONDS = 30 * 24 * 60 * 60;
|
|
71582
72128
|
function uniqueEndpoints(preferred, candidates) {
|
|
71583
72129
|
return Array.from(new Set([preferred, ...candidates].filter((value) => Boolean(value))));
|
|
71584
72130
|
}
|
|
@@ -71593,10 +72139,10 @@ function buildSessionCookieHeader(req, sessionCookie) {
|
|
|
71593
72139
|
return `${sessionCookie}; ${attributes.join("; ")}`;
|
|
71594
72140
|
}
|
|
71595
72141
|
var bootstrap_post_default2 = defineController2(async ({ req, env: env2 }) => {
|
|
71596
|
-
if (!isTrustedLocalDevelopmentRequest(req, env2)) {
|
|
72142
|
+
if (!isTrustedLocalDevelopmentRequest(req, env2) || !isSameOriginBrowserRequest(req)) {
|
|
71597
72143
|
return Response.json(
|
|
71598
|
-
{ error: "Platform auth bridge is
|
|
71599
|
-
{ status:
|
|
72144
|
+
{ error: "Platform auth bridge is restricted to same-origin local development" },
|
|
72145
|
+
{ status: 403 }
|
|
71600
72146
|
);
|
|
71601
72147
|
}
|
|
71602
72148
|
const requestCookie = req.headers.get("Cookie")?.trim() || "";
|
|
@@ -71623,10 +72169,16 @@ var bootstrap_post_default2 = defineController2(async ({ req, env: env2 }) => {
|
|
|
71623
72169
|
account: localSession.platform.account,
|
|
71624
72170
|
authType: localSession.authType,
|
|
71625
72171
|
verified: localSession.platform.verified,
|
|
71626
|
-
token: localSession.token,
|
|
71627
72172
|
localUser: localSession.user
|
|
71628
72173
|
}, {
|
|
71629
|
-
headers: {
|
|
72174
|
+
headers: {
|
|
72175
|
+
"Cache-Control": "no-store",
|
|
72176
|
+
"Set-Cookie": buildSessionCookie(
|
|
72177
|
+
req,
|
|
72178
|
+
localSession.token,
|
|
72179
|
+
AGENT_BUILDER_SESSION_TTL_SECONDS
|
|
72180
|
+
)
|
|
72181
|
+
}
|
|
71630
72182
|
});
|
|
71631
72183
|
}
|
|
71632
72184
|
}
|
|
@@ -73281,11 +73833,9 @@ var tools_get_default2 = defineController2(async ({ params, url }) => {
|
|
|
73281
73833
|
|
|
73282
73834
|
// src/api/threads/[id]/bridge.ts
|
|
73283
73835
|
var bridge_default = defineController2(async ({ req, params, env: env2 }) => {
|
|
73284
|
-
|
|
73285
|
-
|
|
73286
|
-
|
|
73287
|
-
return authResult;
|
|
73288
|
-
}
|
|
73836
|
+
const authResult = await requireAuth(req, env2);
|
|
73837
|
+
if (authResult instanceof Response) {
|
|
73838
|
+
return authResult;
|
|
73289
73839
|
}
|
|
73290
73840
|
const threadId = params.id;
|
|
73291
73841
|
if (!threadId) {
|
|
@@ -73538,19 +74088,9 @@ var cost_get_default = defineController2(async ({ req, params, env: env2 }) => {
|
|
|
73538
74088
|
|
|
73539
74089
|
// src/api/threads/[id]/diagnostics.get.ts
|
|
73540
74090
|
var diagnostics_get_default2 = defineController2(async ({ req, params, env: env2 }) => {
|
|
73541
|
-
|
|
73542
|
-
|
|
73543
|
-
|
|
73544
|
-
return authResult;
|
|
73545
|
-
}
|
|
73546
|
-
} else {
|
|
73547
|
-
const authContext = await authenticate(req, env2);
|
|
73548
|
-
if (authContext && !hasPermission(authContext.user, "logs")) {
|
|
73549
|
-
return Response.json(
|
|
73550
|
-
{ error: "Forbidden: 'logs' access required" },
|
|
73551
|
-
{ status: 403 }
|
|
73552
|
-
);
|
|
73553
|
-
}
|
|
74091
|
+
const authResult = await requirePermission(req, env2, "logs");
|
|
74092
|
+
if (authResult instanceof Response) {
|
|
74093
|
+
return authResult;
|
|
73554
74094
|
}
|
|
73555
74095
|
const threadId = params.id;
|
|
73556
74096
|
if (!threadId) {
|
|
@@ -73718,6 +74258,33 @@ var fs_default = defineController2(async ({ req, params, env: env2 }) => {
|
|
|
73718
74258
|
}
|
|
73719
74259
|
});
|
|
73720
74260
|
|
|
74261
|
+
// src/utils/kv-key-policy.ts
|
|
74262
|
+
var THREAD_CLIENT_RESERVED_KEYS = /* @__PURE__ */ new Set([
|
|
74263
|
+
"execution_owner",
|
|
74264
|
+
"approvals",
|
|
74265
|
+
"bg_processes",
|
|
74266
|
+
"lines_capacity_cache"
|
|
74267
|
+
]);
|
|
74268
|
+
var THREAD_CLIENT_RESERVED_PREFIXES = [
|
|
74269
|
+
"approval_"
|
|
74270
|
+
];
|
|
74271
|
+
var USER_CLIENT_RESERVED_KEYS = /* @__PURE__ */ new Set([
|
|
74272
|
+
"standardcode.lines.leases",
|
|
74273
|
+
"standardcode.lines.capacity_cache"
|
|
74274
|
+
]);
|
|
74275
|
+
function isThreadKvKeyClientWritable(key) {
|
|
74276
|
+
return !THREAD_CLIENT_RESERVED_KEYS.has(key) && !THREAD_CLIENT_RESERVED_PREFIXES.some((prefix) => key.startsWith(prefix));
|
|
74277
|
+
}
|
|
74278
|
+
function isUserKvKeyClientWritable(key) {
|
|
74279
|
+
return !USER_CLIENT_RESERVED_KEYS.has(key);
|
|
74280
|
+
}
|
|
74281
|
+
function reservedKvKeyResponse() {
|
|
74282
|
+
return Response.json(
|
|
74283
|
+
{ error: "Key is reserved for server-managed state" },
|
|
74284
|
+
{ status: 403 }
|
|
74285
|
+
);
|
|
74286
|
+
}
|
|
74287
|
+
|
|
73721
74288
|
// src/api/threads/[id]/kv/index.ts
|
|
73722
74289
|
async function getAuthorizedThreadStub2(context, threadId) {
|
|
73723
74290
|
const { env: env2 } = context;
|
|
@@ -73811,11 +74378,14 @@ async function handlePost(stub, req) {
|
|
|
73811
74378
|
if (body instanceof Response) return body;
|
|
73812
74379
|
const key = readKey(body.key);
|
|
73813
74380
|
if (key instanceof Response) return key;
|
|
74381
|
+
const previousKey = typeof body.previousKey === "string" && body.previousKey !== key ? body.previousKey : null;
|
|
74382
|
+
if (!isThreadKvKeyClientWritable(key) || previousKey?.trim() && !isThreadKvKeyClientWritable(previousKey)) {
|
|
74383
|
+
return reservedKvKeyResponse();
|
|
74384
|
+
}
|
|
73814
74385
|
if (!Object.prototype.hasOwnProperty.call(body, "value")) {
|
|
73815
74386
|
return Response.json({ error: "Value is required" }, { status: 400 });
|
|
73816
74387
|
}
|
|
73817
74388
|
await stub.setValue(key, body.value);
|
|
73818
|
-
const previousKey = typeof body.previousKey === "string" && body.previousKey !== key ? body.previousKey : null;
|
|
73819
74389
|
if (previousKey?.trim()) {
|
|
73820
74390
|
await stub.setValue(previousKey, null);
|
|
73821
74391
|
}
|
|
@@ -73841,6 +74411,7 @@ async function handleDelete(stub, req, url) {
|
|
|
73841
74411
|
}
|
|
73842
74412
|
const key = readKey(keyValue);
|
|
73843
74413
|
if (key instanceof Response) return key;
|
|
74414
|
+
if (!isThreadKvKeyClientWritable(key)) return reservedKvKeyResponse();
|
|
73844
74415
|
await stub.setValue(key, null);
|
|
73845
74416
|
return new Response(null, { status: 204 });
|
|
73846
74417
|
}
|
|
@@ -73878,19 +74449,9 @@ var kv_default = defineController2(async (context) => {
|
|
|
73878
74449
|
// src/api/threads/[id]/logs.get.ts
|
|
73879
74450
|
var logs_get_default = defineController2(async (context) => {
|
|
73880
74451
|
const { req, params, env: env2 } = context;
|
|
73881
|
-
|
|
73882
|
-
|
|
73883
|
-
|
|
73884
|
-
return authResult;
|
|
73885
|
-
}
|
|
73886
|
-
} else {
|
|
73887
|
-
const authContext = await resolveOptionalRequestAuth(context);
|
|
73888
|
-
if (authContext && !hasPermission(authContext.user, "logs")) {
|
|
73889
|
-
return Response.json(
|
|
73890
|
-
{ error: "Forbidden: 'logs' access required" },
|
|
73891
|
-
{ status: 403 }
|
|
73892
|
-
);
|
|
73893
|
-
}
|
|
74452
|
+
const authResult = await resolveRequestPermission(context, "logs");
|
|
74453
|
+
if (authResult instanceof Response) {
|
|
74454
|
+
return authResult;
|
|
73894
74455
|
}
|
|
73895
74456
|
const url = new URL(req.url);
|
|
73896
74457
|
const threadId = params.id;
|
|
@@ -74123,19 +74684,9 @@ var pending_tool_calls_get_default = defineController2(async ({ params, env: env
|
|
|
74123
74684
|
|
|
74124
74685
|
// src/api/threads/[id]/revive.post.ts
|
|
74125
74686
|
var revive_post_default = defineController2(async ({ req, params, env: env2 }) => {
|
|
74126
|
-
|
|
74127
|
-
|
|
74128
|
-
|
|
74129
|
-
return authResult;
|
|
74130
|
-
}
|
|
74131
|
-
} else {
|
|
74132
|
-
const authContext = await authenticate(req, env2);
|
|
74133
|
-
if (authContext && !hasPermission(authContext.user, "logs")) {
|
|
74134
|
-
return Response.json(
|
|
74135
|
-
{ error: "Forbidden: 'logs' access required" },
|
|
74136
|
-
{ status: 403 }
|
|
74137
|
-
);
|
|
74138
|
-
}
|
|
74687
|
+
const authResult = await requirePermission(req, env2, "logs");
|
|
74688
|
+
if (authResult instanceof Response) {
|
|
74689
|
+
return authResult;
|
|
74139
74690
|
}
|
|
74140
74691
|
const threadId = params.id;
|
|
74141
74692
|
if (!threadId) {
|
|
@@ -74169,20 +74720,15 @@ var revive_post_default = defineController2(async ({ req, params, env: env2 }) =
|
|
|
74169
74720
|
});
|
|
74170
74721
|
|
|
74171
74722
|
// src/api/threads/[id]/rpc.post.ts
|
|
74723
|
+
function unsafeLocalRpcEnabled(env2) {
|
|
74724
|
+
const value = Reflect.get(env2, "AGENT_BUILDER_ENABLE_UNSAFE_RPC");
|
|
74725
|
+
if (typeof value !== "string") return value === true;
|
|
74726
|
+
const normalized = value.trim().toLowerCase();
|
|
74727
|
+
return normalized === "1" || normalized === "true";
|
|
74728
|
+
}
|
|
74172
74729
|
var rpc_post_default = defineController2(async ({ req, params, env: env2 }) => {
|
|
74173
|
-
if (
|
|
74174
|
-
|
|
74175
|
-
if (authResult instanceof Response) {
|
|
74176
|
-
return authResult;
|
|
74177
|
-
}
|
|
74178
|
-
} else {
|
|
74179
|
-
const authContext = await authenticate(req, env2);
|
|
74180
|
-
if (authContext && !hasPermission(authContext.user, "logs")) {
|
|
74181
|
-
return Response.json(
|
|
74182
|
-
{ error: "Forbidden: 'logs' access required" },
|
|
74183
|
-
{ status: 403 }
|
|
74184
|
-
);
|
|
74185
|
-
}
|
|
74730
|
+
if (!isTrustedLocalDevelopmentRequest(req, env2) || !unsafeLocalRpcEnabled(env2)) {
|
|
74731
|
+
return Response.json({ error: "Not found" }, { status: 404 });
|
|
74186
74732
|
}
|
|
74187
74733
|
const threadId = params.id;
|
|
74188
74734
|
if (!threadId) {
|
|
@@ -74196,7 +74742,11 @@ var rpc_post_default = defineController2(async ({ req, params, env: env2 }) => {
|
|
|
74196
74742
|
try {
|
|
74197
74743
|
const id = env2.AGENT_BUILDER_THREAD.idFromName(threadId);
|
|
74198
74744
|
const thread = env2.AGENT_BUILDER_THREAD.get(id);
|
|
74199
|
-
const
|
|
74745
|
+
const rpcMethod = Reflect.get(thread, method);
|
|
74746
|
+
if (typeof rpcMethod !== "function") {
|
|
74747
|
+
return Response.json({ error: "Method not found" }, { status: 404 });
|
|
74748
|
+
}
|
|
74749
|
+
const result = await Reflect.apply(rpcMethod, thread, args);
|
|
74200
74750
|
if (result instanceof Response) {
|
|
74201
74751
|
return result;
|
|
74202
74752
|
}
|
|
@@ -74240,11 +74790,9 @@ var stop_post_default = defineController2(async ({ params, env: env2 }) => {
|
|
|
74240
74790
|
|
|
74241
74791
|
// src/api/threads/[id]/stream.ts
|
|
74242
74792
|
var stream_default = defineController2(async ({ req, params, env: env2 }) => {
|
|
74243
|
-
|
|
74244
|
-
|
|
74245
|
-
|
|
74246
|
-
return authResult;
|
|
74247
|
-
}
|
|
74793
|
+
const authResult = await requireAuth(req, env2);
|
|
74794
|
+
if (authResult instanceof Response) {
|
|
74795
|
+
return authResult;
|
|
74248
74796
|
}
|
|
74249
74797
|
const threadId = params.id;
|
|
74250
74798
|
if (!threadId) {
|
|
@@ -74321,6 +74869,9 @@ var tool_result_post_default = defineController2(async ({ req, params, env: env2
|
|
|
74321
74869
|
if (!toolCallId || typeof toolCallId !== "string") {
|
|
74322
74870
|
return Response.json({ error: "tool_call_id required" }, { status: 400 });
|
|
74323
74871
|
}
|
|
74872
|
+
if (!body.delivery_token || typeof body.delivery_token !== "string") {
|
|
74873
|
+
return Response.json({ error: "delivery_token required" }, { status: 400 });
|
|
74874
|
+
}
|
|
74324
74875
|
try {
|
|
74325
74876
|
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
74326
74877
|
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
@@ -74336,7 +74887,8 @@ var tool_result_post_default = defineController2(async ({ req, params, env: env2
|
|
|
74336
74887
|
typeof body.result === "string" ? body.result : void 0,
|
|
74337
74888
|
typeof body.error === "string" ? body.error : void 0,
|
|
74338
74889
|
typeof body.client_id === "string" ? body.client_id : void 0,
|
|
74339
|
-
typeof body.generation === "number" ? body.generation : void 0
|
|
74890
|
+
typeof body.generation === "number" ? body.generation : void 0,
|
|
74891
|
+
body.delivery_token
|
|
74340
74892
|
);
|
|
74341
74893
|
if (!delivered) {
|
|
74342
74894
|
return Response.json({ status: "ignored" }, { status: 200 });
|
|
@@ -74647,11 +75199,23 @@ var name_get_default8 = defineController2(async ({ params, url, prompts, agents,
|
|
|
74647
75199
|
});
|
|
74648
75200
|
|
|
74649
75201
|
// src/api/auth/device/start.post.ts
|
|
75202
|
+
var DEVICE_ADDRESS_LIMIT = { limit: 20, window_seconds: 10 * 60 };
|
|
75203
|
+
var DEVICE_INSTANCE_LIMIT = { limit: 300, window_seconds: 10 * 60 };
|
|
74650
75204
|
var start_post_default = defineController2(async ({ req, env: env2 }) => {
|
|
74651
|
-
const bytes = crypto.getRandomValues(new Uint8Array(24));
|
|
74652
|
-
const code = [...bytes].map((b) => "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789"[b % 57]).join("");
|
|
74653
75205
|
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
74654
75206
|
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
75207
|
+
const addressLimit = await agentBuilder.consumeAuthRateLimit({
|
|
75208
|
+
key: await authRateLimitKey("device-start-address", authClientAddress(req)),
|
|
75209
|
+
...DEVICE_ADDRESS_LIMIT
|
|
75210
|
+
});
|
|
75211
|
+
if (!addressLimit.allowed) return authRateLimitedResponse(addressLimit);
|
|
75212
|
+
const instanceLimit = await agentBuilder.consumeAuthRateLimit({
|
|
75213
|
+
key: "device-start-instance",
|
|
75214
|
+
...DEVICE_INSTANCE_LIMIT
|
|
75215
|
+
});
|
|
75216
|
+
if (!instanceLimit.allowed) return authRateLimitedResponse(instanceLimit);
|
|
75217
|
+
const bytes = crypto.getRandomValues(new Uint8Array(24));
|
|
75218
|
+
const code = [...bytes].map((b) => "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789"[b % 57]).join("");
|
|
74655
75219
|
await agentBuilder.startDeviceLogin(await hashToken(code));
|
|
74656
75220
|
const origin = new URL(req.url).origin;
|
|
74657
75221
|
const verifyBaseRaw = env2.STANDARD_AGENTS_DEVICE_VERIFY_URL_BASE;
|
|
@@ -74665,8 +75229,74 @@ var start_post_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
74665
75229
|
});
|
|
74666
75230
|
});
|
|
74667
75231
|
|
|
75232
|
+
// src/api/auth/sa/_login-state.ts
|
|
75233
|
+
var LOGIN_STATE_COOKIE = "agtbldr_sa_login_state";
|
|
75234
|
+
var LOGIN_STATE_PARAM = "__sa_login_state";
|
|
75235
|
+
var LOGIN_STATE_TTL_SECONDS = 10 * 60;
|
|
75236
|
+
function safeReturnTo(value) {
|
|
75237
|
+
if (!value || !value.startsWith("/") || value.startsWith("//")) return "/";
|
|
75238
|
+
return value;
|
|
75239
|
+
}
|
|
75240
|
+
function stateCookie(req, value, maxAge) {
|
|
75241
|
+
const attributes = ["Path=/api/auth/sa", "HttpOnly", "SameSite=Lax"];
|
|
75242
|
+
if (new URL(req.url).protocol === "https:") attributes.push("Secure");
|
|
75243
|
+
return `${LOGIN_STATE_COOKIE}=${encodeURIComponent(value)}; ${attributes.join("; ")}; Max-Age=${maxAge}`;
|
|
75244
|
+
}
|
|
75245
|
+
function readStateCookie(req) {
|
|
75246
|
+
const raw = req.headers.get("Cookie");
|
|
75247
|
+
if (!raw) return null;
|
|
75248
|
+
for (const part of raw.split(";")) {
|
|
75249
|
+
const separator = part.indexOf("=");
|
|
75250
|
+
if (separator < 0 || part.slice(0, separator).trim() !== LOGIN_STATE_COOKIE) continue;
|
|
75251
|
+
try {
|
|
75252
|
+
return decodeURIComponent(part.slice(separator + 1).trim()) || null;
|
|
75253
|
+
} catch {
|
|
75254
|
+
return null;
|
|
75255
|
+
}
|
|
75256
|
+
}
|
|
75257
|
+
return null;
|
|
75258
|
+
}
|
|
75259
|
+
function statefulReturnTo(returnTo, state) {
|
|
75260
|
+
const target = new URL(safeReturnTo(returnTo), "https://instance.invalid");
|
|
75261
|
+
target.searchParams.set(LOGIN_STATE_PARAM, state);
|
|
75262
|
+
return `${target.pathname}${target.search}${target.hash}`;
|
|
75263
|
+
}
|
|
75264
|
+
function beginPlatformLogin(req, env2, returnTo, error) {
|
|
75265
|
+
const state = crypto.randomUUID();
|
|
75266
|
+
const location = new URL(platformLoginUrl(req, env2, statefulReturnTo(returnTo, state)));
|
|
75267
|
+
if (error) location.searchParams.set("error", error);
|
|
75268
|
+
return new Response(null, {
|
|
75269
|
+
status: 302,
|
|
75270
|
+
headers: {
|
|
75271
|
+
Location: location.toString(),
|
|
75272
|
+
"Set-Cookie": stateCookie(req, state, LOGIN_STATE_TTL_SECONDS),
|
|
75273
|
+
"Cache-Control": "no-store"
|
|
75274
|
+
}
|
|
75275
|
+
});
|
|
75276
|
+
}
|
|
75277
|
+
function consumePlatformLoginState(req, rawReturnTo) {
|
|
75278
|
+
const target = new URL(safeReturnTo(rawReturnTo), "https://instance.invalid");
|
|
75279
|
+
const state = target.searchParams.get(LOGIN_STATE_PARAM);
|
|
75280
|
+
target.searchParams.delete(LOGIN_STATE_PARAM);
|
|
75281
|
+
const returnTo = `${target.pathname}${target.search}${target.hash}`;
|
|
75282
|
+
return {
|
|
75283
|
+
returnTo,
|
|
75284
|
+
valid: Boolean(state && state === readStateCookie(req)),
|
|
75285
|
+
present: Boolean(state)
|
|
75286
|
+
};
|
|
75287
|
+
}
|
|
75288
|
+
function withClearedPlatformLoginState(req, response) {
|
|
75289
|
+
const headers = new Headers(response.headers);
|
|
75290
|
+
headers.append("Set-Cookie", stateCookie(req, "", 0));
|
|
75291
|
+
return new Response(response.body, {
|
|
75292
|
+
status: response.status,
|
|
75293
|
+
statusText: response.statusText,
|
|
75294
|
+
headers
|
|
75295
|
+
});
|
|
75296
|
+
}
|
|
75297
|
+
|
|
74668
75298
|
// src/api/auth/sa/callback.get.ts
|
|
74669
|
-
var
|
|
75299
|
+
var SESSION_TTL_SECONDS3 = 30 * 24 * 60 * 60;
|
|
74670
75300
|
function safeReturnTo2(value) {
|
|
74671
75301
|
if (!value || !value.startsWith("/") || value.startsWith("//")) return "/";
|
|
74672
75302
|
return value;
|
|
@@ -74674,15 +75304,12 @@ function safeReturnTo2(value) {
|
|
|
74674
75304
|
function failRedirect(req, env2, reason, returnTo) {
|
|
74675
75305
|
const origin = new URL(req.url).origin;
|
|
74676
75306
|
if (isPlatformHosted(env2)) {
|
|
74677
|
-
|
|
74678
|
-
|
|
74679
|
-
|
|
75307
|
+
return beginPlatformLogin(
|
|
75308
|
+
req,
|
|
75309
|
+
env2,
|
|
75310
|
+
returnTo ?? "/",
|
|
74680
75311
|
reason === "api_only_account" ? "api_only_account" : "instance_login_failed"
|
|
74681
75312
|
);
|
|
74682
|
-
return new Response(null, {
|
|
74683
|
-
status: 302,
|
|
74684
|
-
headers: { Location: target.toString() }
|
|
74685
|
-
});
|
|
74686
75313
|
}
|
|
74687
75314
|
return new Response(null, {
|
|
74688
75315
|
status: 302,
|
|
@@ -74694,7 +75321,9 @@ var callback_get_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
74694
75321
|
return failRedirect(req, env2, "not_hosted");
|
|
74695
75322
|
}
|
|
74696
75323
|
const url = new URL(req.url);
|
|
74697
|
-
const
|
|
75324
|
+
const loginState = consumePlatformLoginState(req, url.searchParams.get("return_to"));
|
|
75325
|
+
const finishLoginState = (response) => loginState.present ? withClearedPlatformLoginState(req, response) : response;
|
|
75326
|
+
const failReturnTo = safeReturnTo2(loginState.returnTo);
|
|
74698
75327
|
const handoff = url.searchParams.get("handoff") || url.searchParams.get("token");
|
|
74699
75328
|
if (!handoff) {
|
|
74700
75329
|
return failRedirect(req, env2, "invalid_response", failReturnTo);
|
|
@@ -74708,29 +75337,37 @@ var callback_get_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
74708
75337
|
projectId: configuredProjectId
|
|
74709
75338
|
}
|
|
74710
75339
|
);
|
|
74711
|
-
if (!payload || !payload.platform_user_id || !payload.role) {
|
|
75340
|
+
if (!payload || !payload.platform_user_id || !payload.role || !payload.jti) {
|
|
74712
75341
|
return failRedirect(req, env2, "invalid_handoff", failReturnTo);
|
|
74713
75342
|
}
|
|
74714
75343
|
if (!configuredProjectId && payload.project_id !== hostedInstanceRedirectId(req, env2)) {
|
|
74715
75344
|
return failRedirect(req, env2, "invalid_handoff", failReturnTo);
|
|
74716
75345
|
}
|
|
74717
75346
|
if (payload.role === "api") {
|
|
74718
|
-
const apiReturnTo =
|
|
75347
|
+
const apiReturnTo = failReturnTo;
|
|
74719
75348
|
if (/^\/api\/auth\/device\/[A-Za-z0-9]{8,64}\/approve$/.test(apiReturnTo)) {
|
|
74720
|
-
return new Response(null, {
|
|
75349
|
+
return finishLoginState(new Response(null, {
|
|
74721
75350
|
status: 302,
|
|
74722
75351
|
headers: {
|
|
74723
75352
|
Location: `${url.origin}${apiReturnTo}?handoff=${encodeURIComponent(handoff)}`
|
|
74724
75353
|
}
|
|
74725
|
-
});
|
|
75354
|
+
}));
|
|
74726
75355
|
}
|
|
74727
75356
|
const landingRaw = env2.STANDARD_AGENTS_API_ROLE_LANDING_URL;
|
|
74728
75357
|
const landing = typeof landingRaw === "string" ? landingRaw.trim() : "";
|
|
74729
75358
|
if (landing && /^https:\/\//.test(landing)) {
|
|
74730
|
-
return
|
|
75359
|
+
return finishLoginState(
|
|
75360
|
+
new Response(null, { status: 302, headers: { Location: landing } })
|
|
75361
|
+
);
|
|
74731
75362
|
}
|
|
74732
75363
|
return failRedirect(req, env2, "api_only_account");
|
|
74733
75364
|
}
|
|
75365
|
+
if (!loginState.valid) {
|
|
75366
|
+
return beginPlatformLogin(req, env2, failReturnTo);
|
|
75367
|
+
}
|
|
75368
|
+
if (!await consumePlatformHandoffJti(env2, payload.jti, payload.exp)) {
|
|
75369
|
+
return failRedirect(req, env2, "invalid_handoff", failReturnTo);
|
|
75370
|
+
}
|
|
74734
75371
|
const session = await mintLocalSessionForPlatformUser(env2, {
|
|
74735
75372
|
platform_user_id: payload.platform_user_id,
|
|
74736
75373
|
username: payload.username ?? null,
|
|
@@ -74740,14 +75377,15 @@ var callback_get_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
74740
75377
|
role: payload.role,
|
|
74741
75378
|
permissions: payload.permissions ?? null
|
|
74742
75379
|
});
|
|
74743
|
-
const returnTo =
|
|
74744
|
-
|
|
74745
|
-
|
|
74746
|
-
headers: {
|
|
74747
|
-
Location: `${url.origin}${returnTo}`,
|
|
74748
|
-
"Set-Cookie": buildSessionCookie(req, session.token, SESSION_TTL_SECONDS2)
|
|
74749
|
-
}
|
|
75380
|
+
const returnTo = failReturnTo;
|
|
75381
|
+
const headers = new Headers({
|
|
75382
|
+
Location: `${url.origin}${returnTo}`
|
|
74750
75383
|
});
|
|
75384
|
+
headers.append("Set-Cookie", buildSessionCookie(req, session.token, SESSION_TTL_SECONDS3));
|
|
75385
|
+
return withClearedPlatformLoginState(req, new Response(null, {
|
|
75386
|
+
status: 302,
|
|
75387
|
+
headers
|
|
75388
|
+
}));
|
|
74751
75389
|
});
|
|
74752
75390
|
|
|
74753
75391
|
// src/api/auth/sa/start.get.ts
|
|
@@ -74757,12 +75395,7 @@ var start_get_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
74757
75395
|
}
|
|
74758
75396
|
const url = new URL(req.url);
|
|
74759
75397
|
const returnTo = url.searchParams.get("return_to") || "/";
|
|
74760
|
-
return
|
|
74761
|
-
status: 302,
|
|
74762
|
-
headers: {
|
|
74763
|
-
Location: platformLoginUrl(req, env2, returnTo)
|
|
74764
|
-
}
|
|
74765
|
-
});
|
|
75398
|
+
return beginPlatformLogin(req, env2, returnTo);
|
|
74766
75399
|
});
|
|
74767
75400
|
|
|
74768
75401
|
// src/api/users/me/[...rest].ts
|
|
@@ -74907,6 +75540,7 @@ var index_delete_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
74907
75540
|
if (!key) {
|
|
74908
75541
|
return Response.json({ error: "key query parameter required" }, { status: 400 });
|
|
74909
75542
|
}
|
|
75543
|
+
if (!isUserKvKeyClientWritable(key)) return reservedKvKeyResponse();
|
|
74910
75544
|
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
74911
75545
|
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
74912
75546
|
if (typeof agentBuilder.setUserValue !== "function") {
|
|
@@ -74977,7 +75611,7 @@ var index_get_default4 = defineController2(async ({ req, env: env2 }) => {
|
|
|
74977
75611
|
});
|
|
74978
75612
|
|
|
74979
75613
|
// src/api/users/me/kv/index.post.ts
|
|
74980
|
-
var
|
|
75614
|
+
var index_post_default7 = defineController2(async ({ req, env: env2 }) => {
|
|
74981
75615
|
try {
|
|
74982
75616
|
const authResult = await requireAuth(req, env2);
|
|
74983
75617
|
if (authResult instanceof Response) {
|
|
@@ -75003,6 +75637,7 @@ var index_post_default8 = defineController2(async ({ req, env: env2 }) => {
|
|
|
75003
75637
|
if (typeof key !== "string" || key.length === 0) {
|
|
75004
75638
|
return Response.json({ error: "key required" }, { status: 400 });
|
|
75005
75639
|
}
|
|
75640
|
+
if (!isUserKvKeyClientWritable(key)) return reservedKvKeyResponse();
|
|
75006
75641
|
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
75007
75642
|
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
75008
75643
|
if (typeof agentBuilder.setUserValue !== "function") {
|
|
@@ -75041,13 +75676,39 @@ var stream_default3 = defineController2(async ({ req, env: env2 }) => {
|
|
|
75041
75676
|
return forwardToUserScope(req, env2, authResult.user.id, "stream");
|
|
75042
75677
|
});
|
|
75043
75678
|
|
|
75044
|
-
// src/api/auth/device/[code]/
|
|
75679
|
+
// src/api/auth/device/[code]/_approval.ts
|
|
75680
|
+
var CONFIRMATION_TTL_SECONDS = 5 * 60;
|
|
75681
|
+
function escapeHtml(value) {
|
|
75682
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
75683
|
+
}
|
|
75045
75684
|
function page(title, body, ok) {
|
|
75046
75685
|
return new Response(
|
|
75047
|
-
`<!doctype html><html><head><meta charset="utf-8"><title>${title}</title><style>body{background:#0a0c10;color:#e8ecf3;font:16px/1.6 ui-sans-serif,system-ui;display:flex;min-height:100vh;align-items:center;justify-content:center}
|
|
75048
|
-
{
|
|
75686
|
+
`<!doctype html><html><head><meta charset="utf-8"><meta name="referrer" content="no-referrer"><title>${escapeHtml(title)}</title><style>body{background:#0a0c10;color:#e8ecf3;font:16px/1.6 ui-sans-serif,system-ui;display:flex;min-height:100vh;align-items:center;justify-content:center}main{max-width:420px;text-align:center;padding:40px;border:1px solid #232936;border-radius:14px;background:#11141b}h1{font-size:22px;color:${ok ? "#2dd4bf" : "#f87171"}}p{color:#8b93a7;margin-top:10px}</style></head><body><main><h1>${escapeHtml(title)}</h1><p>${escapeHtml(body)}</p></main></body></html>`,
|
|
75687
|
+
{
|
|
75688
|
+
headers: {
|
|
75689
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
75690
|
+
"Cache-Control": "no-store",
|
|
75691
|
+
"Referrer-Policy": "no-referrer",
|
|
75692
|
+
"X-Content-Type-Options": "nosniff"
|
|
75693
|
+
}
|
|
75694
|
+
}
|
|
75049
75695
|
);
|
|
75050
75696
|
}
|
|
75697
|
+
function confirmationPage(req, code, confirmationToken, handoff) {
|
|
75698
|
+
const url = new URL(req.url);
|
|
75699
|
+
const handoffInput = handoff ? `<input type="hidden" name="handoff" value="${escapeHtml(handoff)}">` : "";
|
|
75700
|
+
const shortCode = code.length > 12 ? `${code.slice(0, 6)}\u2026${code.slice(-6)}` : code;
|
|
75701
|
+
const html = `<!doctype html><html><head><meta charset="utf-8"><meta name="referrer" content="no-referrer"><title>Approve device sign-in</title><style>body{background:#0a0c10;color:#e8ecf3;font:16px/1.6 ui-sans-serif,system-ui;display:flex;min-height:100vh;align-items:center;justify-content:center}main{max-width:440px;text-align:center;padding:40px;border:1px solid #232936;border-radius:14px;background:#11141b}h1{font-size:22px}p{color:#a5adbd}.code{font:600 18px ui-monospace,monospace;letter-spacing:.08em;color:#e8ecf3}form{display:flex;gap:12px;justify-content:center;margin-top:26px}button,a{border-radius:9px;padding:10px 18px;font:inherit;text-decoration:none}button{border:0;background:#2dd4bf;color:#07110f;font-weight:700;cursor:pointer}a{border:1px solid #394150;color:#cbd5e1}</style></head><body><main><h1>Approve device sign-in?</h1><p>A command-line client is requesting a personal instance API key for your account.</p><p class="code">${escapeHtml(shortCode)}</p><form method="post" action="${escapeHtml(url.pathname)}"><input type="hidden" name="confirmation_token" value="${escapeHtml(confirmationToken)}">${handoffInput}<button type="submit">Approve device</button><a href="/">Cancel</a></form></main></body></html>`;
|
|
75702
|
+
return new Response(html, {
|
|
75703
|
+
headers: {
|
|
75704
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
75705
|
+
"Cache-Control": "no-store",
|
|
75706
|
+
"Referrer-Policy": "no-referrer",
|
|
75707
|
+
"X-Content-Type-Options": "nosniff",
|
|
75708
|
+
"Content-Security-Policy": "default-src 'none'; style-src 'unsafe-inline'; form-action 'self'; base-uri 'none'; frame-ancestors 'none'"
|
|
75709
|
+
}
|
|
75710
|
+
});
|
|
75711
|
+
}
|
|
75051
75712
|
function outcome(env2, ok, reason, fallback) {
|
|
75052
75713
|
const baseRaw = env2.STANDARD_AGENTS_DEVICE_OUTCOME_URL_BASE;
|
|
75053
75714
|
const base = typeof baseRaw === "string" ? baseRaw.trim().replace(/\/+$/, "") : "";
|
|
@@ -75057,12 +75718,9 @@ function outcome(env2, ok, reason, fallback) {
|
|
|
75057
75718
|
}
|
|
75058
75719
|
return page(fallback.title, fallback.body, ok);
|
|
75059
75720
|
}
|
|
75060
|
-
|
|
75061
|
-
const code = params.code;
|
|
75062
|
-
if (!code) return outcome(env2, false, "invalid_link", { title: "Missing code", body: "This device link is malformed." });
|
|
75721
|
+
async function resolveDeviceApprovalIdentity(req, env2) {
|
|
75063
75722
|
const url = new URL(req.url);
|
|
75064
|
-
|
|
75065
|
-
const handoff = url.searchParams.get("handoff");
|
|
75723
|
+
const handoff = url.searchParams.get("handoff") ?? (req.method === "POST" ? (await req.clone().formData().catch(() => null))?.get("handoff")?.toString() ?? null : null);
|
|
75066
75724
|
if (handoff && isPlatformHosted(env2)) {
|
|
75067
75725
|
const configuredProjectId = typeof env2.STANDARD_AGENTS_PROJECT_ID === "string" ? env2.STANDARD_AGENTS_PROJECT_ID : void 0;
|
|
75068
75726
|
const payload = await verifyPlatformSignedPayload(
|
|
@@ -75071,10 +75729,13 @@ var approve_get_default = defineController2(async ({ req, env: env2, params }) =
|
|
|
75071
75729
|
{ kind: "instance_handoff", projectId: configuredProjectId }
|
|
75072
75730
|
);
|
|
75073
75731
|
const projectOk = payload && (configuredProjectId || payload.project_id === hostedInstanceRedirectId(req, env2));
|
|
75074
|
-
if (!payload || !payload.platform_user_id || !payload.role || !projectOk) {
|
|
75075
|
-
return outcome(env2, false, "signin_failed", {
|
|
75732
|
+
if (!payload || !payload.platform_user_id || !payload.role || !payload.jti || !projectOk) {
|
|
75733
|
+
return outcome(env2, false, "signin_failed", {
|
|
75734
|
+
title: "Sign in failed",
|
|
75735
|
+
body: "This sign-in link is invalid or has expired. Start again from your terminal."
|
|
75736
|
+
});
|
|
75076
75737
|
}
|
|
75077
|
-
const
|
|
75738
|
+
const platformProfile = {
|
|
75078
75739
|
platform_user_id: payload.platform_user_id,
|
|
75079
75740
|
username: payload.username ?? null,
|
|
75080
75741
|
display_name: payload.display_name ?? null,
|
|
@@ -75082,27 +75743,163 @@ var approve_get_default = defineController2(async ({ req, env: env2, params }) =
|
|
|
75082
75743
|
avatar_url: payload.avatar_url ?? null,
|
|
75083
75744
|
role: payload.role,
|
|
75084
75745
|
permissions: payload.permissions ?? null
|
|
75085
|
-
}
|
|
75086
|
-
|
|
75087
|
-
|
|
75088
|
-
|
|
75089
|
-
|
|
75090
|
-
|
|
75091
|
-
|
|
75092
|
-
|
|
75093
|
-
|
|
75094
|
-
}
|
|
75095
|
-
|
|
75096
|
-
|
|
75746
|
+
};
|
|
75747
|
+
return {
|
|
75748
|
+
confirmationSubject: `platform:${payload.platform_user_id}`,
|
|
75749
|
+
handoff,
|
|
75750
|
+
platformProfile,
|
|
75751
|
+
platformHandoff: {
|
|
75752
|
+
jti: payload.jti,
|
|
75753
|
+
expires_at: payload.exp
|
|
75754
|
+
}
|
|
75755
|
+
};
|
|
75756
|
+
}
|
|
75757
|
+
const authResult = await requireAuth(req, env2);
|
|
75758
|
+
if (authResult instanceof Response) {
|
|
75759
|
+
if (req.method !== "GET") {
|
|
75760
|
+
return outcome(env2, false, "session_required", {
|
|
75761
|
+
title: "Sign in required",
|
|
75762
|
+
body: "Return to the device link and sign in again before approving."
|
|
75763
|
+
});
|
|
75097
75764
|
}
|
|
75098
|
-
|
|
75765
|
+
const returnTo = encodeURIComponent(url.pathname);
|
|
75766
|
+
const hosted = Boolean(
|
|
75767
|
+
env2.STANDARD_AGENTS_HOSTED && String(env2.STANDARD_AGENTS_HOSTED) !== "0" && String(env2.STANDARD_AGENTS_HOSTED).toLowerCase() !== "false"
|
|
75768
|
+
);
|
|
75769
|
+
const target = hosted ? `/api/auth/sa/start?return_to=${returnTo}` : `/login?return_to=${returnTo}`;
|
|
75770
|
+
return new Response(null, { status: 302, headers: { Location: `${url.origin}${target}` } });
|
|
75771
|
+
}
|
|
75772
|
+
if (authResult.authType === "api_key") {
|
|
75773
|
+
return outcome(env2, false, "session_required", {
|
|
75774
|
+
title: "Sign in required",
|
|
75775
|
+
body: "Device logins must be approved from a signed-in browser session."
|
|
75776
|
+
});
|
|
75777
|
+
}
|
|
75778
|
+
return {
|
|
75779
|
+
confirmationSubject: `user:${authResult.user.id}`,
|
|
75780
|
+
handoff: null,
|
|
75781
|
+
localUserId: authResult.user.id
|
|
75782
|
+
};
|
|
75783
|
+
}
|
|
75784
|
+
async function consumeDeviceApprovalHandoff(env2, identity) {
|
|
75785
|
+
if (!identity.platformHandoff) return true;
|
|
75786
|
+
return consumePlatformHandoffJti(
|
|
75787
|
+
env2,
|
|
75788
|
+
identity.platformHandoff.jti,
|
|
75789
|
+
identity.platformHandoff.expires_at
|
|
75790
|
+
);
|
|
75791
|
+
}
|
|
75792
|
+
async function materializeDeviceApprovalUser(env2, identity) {
|
|
75793
|
+
if (identity.localUserId) return identity.localUserId;
|
|
75794
|
+
if (!identity.platformProfile) {
|
|
75795
|
+
throw new Error("Device approval identity is missing a local user and platform profile");
|
|
75099
75796
|
}
|
|
75797
|
+
const user = await upsertReplicaUserForPlatformProfile(
|
|
75798
|
+
env2,
|
|
75799
|
+
identity.platformProfile
|
|
75800
|
+
);
|
|
75801
|
+
return user.id;
|
|
75802
|
+
}
|
|
75803
|
+
function encryptionKey(env2) {
|
|
75804
|
+
const value = env2.ENCRYPTION_KEY;
|
|
75805
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
75806
|
+
}
|
|
75807
|
+
async function createDeviceConfirmationToken(env2, code, confirmationSubject) {
|
|
75808
|
+
const key = encryptionKey(env2);
|
|
75809
|
+
if (!key) return null;
|
|
75810
|
+
return signToken(JSON.stringify({
|
|
75811
|
+
kind: "device_approval_confirmation",
|
|
75812
|
+
code_hash: await hashToken(code),
|
|
75813
|
+
subject: confirmationSubject,
|
|
75814
|
+
exp: Math.floor(Date.now() / 1e3) + CONFIRMATION_TTL_SECONDS,
|
|
75815
|
+
nonce: crypto.randomUUID()
|
|
75816
|
+
}), key);
|
|
75817
|
+
}
|
|
75818
|
+
async function verifyDeviceConfirmationToken(env2, code, confirmationSubject, token) {
|
|
75819
|
+
const key = encryptionKey(env2);
|
|
75820
|
+
if (!key) return false;
|
|
75821
|
+
const raw = await verifySignedToken(token, key);
|
|
75822
|
+
if (!raw) return false;
|
|
75823
|
+
try {
|
|
75824
|
+
const payload = JSON.parse(raw);
|
|
75825
|
+
return payload.kind === "device_approval_confirmation" && payload.code_hash === await hashToken(code) && payload.subject === confirmationSubject && typeof payload.exp === "number" && payload.exp >= Math.floor(Date.now() / 1e3);
|
|
75826
|
+
} catch {
|
|
75827
|
+
return false;
|
|
75828
|
+
}
|
|
75829
|
+
}
|
|
75830
|
+
function isSameOriginApprovalPost(req) {
|
|
75831
|
+
const url = new URL(req.url);
|
|
75832
|
+
const origin = req.headers.get("Origin");
|
|
75833
|
+
if (origin && origin !== url.origin) return false;
|
|
75834
|
+
const fetchSite = req.headers.get("Sec-Fetch-Site");
|
|
75835
|
+
return !fetchSite || fetchSite === "same-origin" || fetchSite === "none";
|
|
75836
|
+
}
|
|
75837
|
+
|
|
75838
|
+
// src/api/auth/device/[code]/approve.get.ts
|
|
75839
|
+
var approve_get_default = defineController2(async ({ req, env: env2, params }) => {
|
|
75840
|
+
const code = params.code;
|
|
75841
|
+
if (!code) {
|
|
75842
|
+
return outcome(env2, false, "invalid_link", {
|
|
75843
|
+
title: "Missing code",
|
|
75844
|
+
body: "This device link is malformed."
|
|
75845
|
+
});
|
|
75846
|
+
}
|
|
75847
|
+
const identity = await resolveDeviceApprovalIdentity(req, env2);
|
|
75848
|
+
if (identity instanceof Response) return identity;
|
|
75849
|
+
const confirmationToken = await createDeviceConfirmationToken(
|
|
75850
|
+
env2,
|
|
75851
|
+
code,
|
|
75852
|
+
identity.confirmationSubject
|
|
75853
|
+
);
|
|
75854
|
+
if (!confirmationToken) {
|
|
75855
|
+
return outcome(env2, false, "signin_failed", {
|
|
75856
|
+
title: "Sign in failed",
|
|
75857
|
+
body: "This instance cannot create a secure device confirmation. Contact its administrator."
|
|
75858
|
+
});
|
|
75859
|
+
}
|
|
75860
|
+
return confirmationPage(req, code, confirmationToken, identity.handoff);
|
|
75861
|
+
});
|
|
75862
|
+
|
|
75863
|
+
// src/api/auth/device/[code]/approve.post.ts
|
|
75864
|
+
var approve_post_default = defineController2(async ({ req, env: env2, params }) => {
|
|
75865
|
+
const code = params.code;
|
|
75866
|
+
if (!code) {
|
|
75867
|
+
return outcome(env2, false, "invalid_link", {
|
|
75868
|
+
title: "Missing code",
|
|
75869
|
+
body: "This device link is malformed."
|
|
75870
|
+
});
|
|
75871
|
+
}
|
|
75872
|
+
if (!isSameOriginApprovalPost(req)) {
|
|
75873
|
+
return Response.json({ error: "Cross-origin device approval refused" }, { status: 403 });
|
|
75874
|
+
}
|
|
75875
|
+
const form = await req.clone().formData().catch(() => null);
|
|
75876
|
+
const confirmationToken = form?.get("confirmation_token")?.toString() ?? "";
|
|
75877
|
+
if (!confirmationToken) {
|
|
75878
|
+
return Response.json({ error: "Device confirmation token required" }, { status: 403 });
|
|
75879
|
+
}
|
|
75880
|
+
const identity = await resolveDeviceApprovalIdentity(req, env2);
|
|
75881
|
+
if (identity instanceof Response) return identity;
|
|
75882
|
+
if (!await verifyDeviceConfirmationToken(
|
|
75883
|
+
env2,
|
|
75884
|
+
code,
|
|
75885
|
+
identity.confirmationSubject,
|
|
75886
|
+
confirmationToken
|
|
75887
|
+
)) {
|
|
75888
|
+
return Response.json({ error: "Invalid or expired device confirmation" }, { status: 403 });
|
|
75889
|
+
}
|
|
75890
|
+
if (!await consumeDeviceApprovalHandoff(env2, identity)) {
|
|
75891
|
+
return outcome(env2, false, "signin_failed", {
|
|
75892
|
+
title: "Sign in failed",
|
|
75893
|
+
body: "This sign-in link was already used or has expired. Start again from your terminal."
|
|
75894
|
+
});
|
|
75895
|
+
}
|
|
75896
|
+
const userId = await materializeDeviceApprovalUser(env2, identity);
|
|
75100
75897
|
const token = generateApiKey();
|
|
75101
75898
|
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
75102
75899
|
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
75103
75900
|
const ok = await agentBuilder.approveDeviceLogin({
|
|
75104
75901
|
code_hash: await hashToken(code),
|
|
75105
|
-
user_id:
|
|
75902
|
+
user_id: userId,
|
|
75106
75903
|
token,
|
|
75107
75904
|
token_hash: await hashToken(token),
|
|
75108
75905
|
key_prefix: token.slice(0, 12),
|
|
@@ -75110,12 +75907,19 @@ var approve_get_default = defineController2(async ({ req, env: env2, params }) =
|
|
|
75110
75907
|
key_name: "CLI device login"
|
|
75111
75908
|
});
|
|
75112
75909
|
if (!ok) {
|
|
75113
|
-
return outcome(env2, false, "expired", {
|
|
75910
|
+
return outcome(env2, false, "expired", {
|
|
75911
|
+
title: "Link expired",
|
|
75912
|
+
body: "This device login has expired or was already used. Start again from your terminal."
|
|
75913
|
+
});
|
|
75114
75914
|
}
|
|
75115
|
-
return outcome(env2, true, "done", {
|
|
75915
|
+
return outcome(env2, true, "done", {
|
|
75916
|
+
title: "You're connected",
|
|
75917
|
+
body: "Standard Code is now signed in. Return to your terminal \u2014 it will pick up automatically."
|
|
75918
|
+
});
|
|
75116
75919
|
});
|
|
75117
75920
|
|
|
75118
75921
|
// src/api/skills/[name]/files/[...path].get.ts
|
|
75922
|
+
init_scope();
|
|
75119
75923
|
var path_get_default = defineController2(async ({ req, env: env2, params }) => {
|
|
75120
75924
|
const authResult = await requireAdmin(req, env2);
|
|
75121
75925
|
if (authResult instanceof Response) return authResult;
|
|
@@ -75128,7 +75932,11 @@ var path_get_default = defineController2(async ({ req, env: env2, params }) => {
|
|
|
75128
75932
|
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
75129
75933
|
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
75130
75934
|
try {
|
|
75131
|
-
const content = await agentBuilder.getSkillFile(
|
|
75935
|
+
const content = await agentBuilder.getSkillFile(
|
|
75936
|
+
{ ownerId: SHARED_SKILL_OWNER },
|
|
75937
|
+
name15,
|
|
75938
|
+
filePath
|
|
75939
|
+
);
|
|
75132
75940
|
if (content === null) {
|
|
75133
75941
|
return Response.json({ error: `File not found: ${filePath} in skill ${name15}` }, { status: 404 });
|
|
75134
75942
|
}
|
|
@@ -75143,6 +75951,24 @@ var path_get_default = defineController2(async ({ req, env: env2, params }) => {
|
|
|
75143
75951
|
|
|
75144
75952
|
// src/api/threads/[id]/fs/[...path].ts
|
|
75145
75953
|
var CHUNK_SIZE2 = 1.75 * 1024 * 1024;
|
|
75954
|
+
var EXECUTABLE_DOCUMENT_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
75955
|
+
"text/html",
|
|
75956
|
+
"image/svg+xml",
|
|
75957
|
+
"application/xhtml+xml"
|
|
75958
|
+
]);
|
|
75959
|
+
function safeDownloadName(name15) {
|
|
75960
|
+
return name15.replace(/["\\\r\n]/g, "_");
|
|
75961
|
+
}
|
|
75962
|
+
function fileResponseHeaders(file) {
|
|
75963
|
+
const mimeType = file.mimeType.split(";", 1)[0]?.trim().toLowerCase();
|
|
75964
|
+
const disposition = mimeType && EXECUTABLE_DOCUMENT_MIME_TYPES.has(mimeType) ? "attachment" : "inline";
|
|
75965
|
+
return {
|
|
75966
|
+
"Content-Type": file.mimeType,
|
|
75967
|
+
"Content-Length": String(file.size),
|
|
75968
|
+
"Content-Disposition": `${disposition}; filename="${safeDownloadName(file.name)}"`,
|
|
75969
|
+
"X-Content-Type-Options": "nosniff"
|
|
75970
|
+
};
|
|
75971
|
+
}
|
|
75146
75972
|
function toAttachmentRef(file) {
|
|
75147
75973
|
const metadata = file.metadata;
|
|
75148
75974
|
const width = file.width ?? metadata?.width;
|
|
@@ -75233,8 +76059,9 @@ async function handleGet2(stub, path10, url) {
|
|
|
75233
76059
|
headers: {
|
|
75234
76060
|
"Content-Type": "image/jpeg",
|
|
75235
76061
|
// Thumbnails are typically JPEG
|
|
75236
|
-
"Cache-Control": "public, max-age=31536000"
|
|
76062
|
+
"Cache-Control": "public, max-age=31536000",
|
|
75237
76063
|
// Cache for 1 year
|
|
76064
|
+
"X-Content-Type-Options": "nosniff"
|
|
75238
76065
|
}
|
|
75239
76066
|
});
|
|
75240
76067
|
}
|
|
@@ -75274,11 +76101,7 @@ async function handleGet2(stub, path10, url) {
|
|
|
75274
76101
|
bytes[i] = binary.charCodeAt(i);
|
|
75275
76102
|
}
|
|
75276
76103
|
return new Response(bytes, {
|
|
75277
|
-
headers:
|
|
75278
|
-
"Content-Type": file.mimeType,
|
|
75279
|
-
"Content-Length": String(file.size),
|
|
75280
|
-
"Content-Disposition": `inline; filename="${file.name}"`
|
|
75281
|
-
}
|
|
76104
|
+
headers: fileResponseHeaders(file)
|
|
75282
76105
|
});
|
|
75283
76106
|
}
|
|
75284
76107
|
function streamChunkedFile(stub, path10, file) {
|
|
@@ -75306,12 +76129,8 @@ function streamChunkedFile(stub, path10, file) {
|
|
|
75306
76129
|
}
|
|
75307
76130
|
})();
|
|
75308
76131
|
return new Response(readable, {
|
|
75309
|
-
|
|
75310
|
-
|
|
75311
|
-
"Content-Length": String(file.size),
|
|
75312
|
-
"Content-Disposition": `inline; filename="${file.name}"`
|
|
75313
|
-
// Note: We set Content-Length, but also use chunked transfer internally
|
|
75314
|
-
}
|
|
76132
|
+
// Note: We set Content-Length, but also use chunked transfer internally.
|
|
76133
|
+
headers: fileResponseHeaders(file)
|
|
75315
76134
|
});
|
|
75316
76135
|
}
|
|
75317
76136
|
async function handlePost2(stub, path10, req) {
|
|
@@ -75508,19 +76327,9 @@ async function handleChunkedUploadComplete(stub, filePath, req) {
|
|
|
75508
76327
|
|
|
75509
76328
|
// src/api/threads/[id]/logs/[logId].get.ts
|
|
75510
76329
|
var logId_get_default = defineController2(async ({ req, params, env: env2 }) => {
|
|
75511
|
-
|
|
75512
|
-
|
|
75513
|
-
|
|
75514
|
-
return authResult;
|
|
75515
|
-
}
|
|
75516
|
-
} else {
|
|
75517
|
-
const authContext = await authenticate(req, env2);
|
|
75518
|
-
if (authContext && !hasPermission(authContext.user, "logs")) {
|
|
75519
|
-
return Response.json(
|
|
75520
|
-
{ error: "Forbidden: 'logs' access required" },
|
|
75521
|
-
{ status: 403 }
|
|
75522
|
-
);
|
|
75523
|
-
}
|
|
76330
|
+
const authResult = await requirePermission(req, env2, "logs");
|
|
76331
|
+
if (authResult instanceof Response) {
|
|
76332
|
+
return authResult;
|
|
75524
76333
|
}
|
|
75525
76334
|
const threadId = params.id;
|
|
75526
76335
|
const logId = params.logId;
|
|
@@ -75649,76 +76458,6 @@ var messageId_patch_default = defineController2(async ({ req, params, env: env2
|
|
|
75649
76458
|
}
|
|
75650
76459
|
});
|
|
75651
76460
|
|
|
75652
|
-
// src/api/threads/[id]/public/[...path].ts
|
|
75653
|
-
var path_default4 = defineController2(async ({ req, params, env: env2 }) => {
|
|
75654
|
-
if (req.method !== "GET" && req.method !== "HEAD") {
|
|
75655
|
-
return Response.json({ error: "Method not allowed" }, { status: 405 });
|
|
75656
|
-
}
|
|
75657
|
-
const threadId = params.id;
|
|
75658
|
-
if (!threadId) {
|
|
75659
|
-
return Response.json({ error: "Thread ID required" }, { status: 400 });
|
|
75660
|
-
}
|
|
75661
|
-
const rawPathParam = params._ || params.path || params["*"] || "";
|
|
75662
|
-
const relative4 = rawPathParam === "public" ? "" : rawPathParam.replace(/^\/?public\//, "");
|
|
75663
|
-
const segments = [];
|
|
75664
|
-
for (const part of relative4.replace(/\\/g, "/").split("/")) {
|
|
75665
|
-
if (!part || part === ".") continue;
|
|
75666
|
-
if (part === "..") return notFound();
|
|
75667
|
-
segments.push(part);
|
|
75668
|
-
}
|
|
75669
|
-
if (segments.length === 0) return notFound();
|
|
75670
|
-
const path10 = `/public/${segments.join("/")}`;
|
|
75671
|
-
try {
|
|
75672
|
-
const durableId = env2.AGENT_BUILDER_THREAD.idFromName(threadId);
|
|
75673
|
-
const stub = env2.AGENT_BUILDER_THREAD.get(durableId);
|
|
75674
|
-
const statResult = await stub.statFile(path10);
|
|
75675
|
-
if (!statResult?.success) return notFound();
|
|
75676
|
-
const file = statResult.file;
|
|
75677
|
-
if (!file || file.isDirectory || file.storage !== "local") return notFound();
|
|
75678
|
-
const headers = {
|
|
75679
|
-
"Content-Type": file.mimeType || "application/octet-stream",
|
|
75680
|
-
"Content-Length": String(file.size),
|
|
75681
|
-
"Content-Disposition": `inline; filename="${file.name}"`,
|
|
75682
|
-
// Public files are mutable (unlike content-addressed assets): cache
|
|
75683
|
-
// briefly so shares are fast without pinning stale content for a year.
|
|
75684
|
-
"Cache-Control": "public, max-age=300"
|
|
75685
|
-
};
|
|
75686
|
-
if (req.method === "HEAD") return new Response(null, { headers });
|
|
75687
|
-
if (file.isChunked && file.chunkCount) {
|
|
75688
|
-
const { readable, writable } = new TransformStream();
|
|
75689
|
-
const writer = writable.getWriter();
|
|
75690
|
-
(async () => {
|
|
75691
|
-
try {
|
|
75692
|
-
for (let i = 0; i < file.chunkCount; i++) {
|
|
75693
|
-
const chunk = await stub.readFileChunk(path10, i);
|
|
75694
|
-
if (!chunk?.success) break;
|
|
75695
|
-
const binary2 = atob(chunk.data);
|
|
75696
|
-
const bytes2 = new Uint8Array(binary2.length);
|
|
75697
|
-
for (let j = 0; j < binary2.length; j++) bytes2[j] = binary2.charCodeAt(j);
|
|
75698
|
-
await writer.write(bytes2);
|
|
75699
|
-
}
|
|
75700
|
-
} finally {
|
|
75701
|
-
await writer.close().catch(() => {
|
|
75702
|
-
});
|
|
75703
|
-
}
|
|
75704
|
-
})();
|
|
75705
|
-
return new Response(readable, { headers });
|
|
75706
|
-
}
|
|
75707
|
-
const result = await stub.readFile(path10);
|
|
75708
|
-
if (!result?.success) return notFound();
|
|
75709
|
-
const binary = atob(result.data);
|
|
75710
|
-
const bytes = new Uint8Array(binary.length);
|
|
75711
|
-
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
75712
|
-
return new Response(bytes, { headers });
|
|
75713
|
-
} catch (error) {
|
|
75714
|
-
console.error(`Error serving public file for thread ${threadId}:`, error);
|
|
75715
|
-
return notFound();
|
|
75716
|
-
}
|
|
75717
|
-
});
|
|
75718
|
-
function notFound() {
|
|
75719
|
-
return Response.json({ error: "Not found" }, { status: 404 });
|
|
75720
|
-
}
|
|
75721
|
-
|
|
75722
76461
|
// src/api/threads/[id]/variables/[requestId].get.ts
|
|
75723
76462
|
var requestId_get_default = defineController2(async ({ req, params, env: env2 }) => {
|
|
75724
76463
|
const authResult = await requireAuth(req, env2);
|
|
@@ -76002,19 +76741,9 @@ function createInspectProviderConfig(providerName, factory, env2) {
|
|
|
76002
76741
|
};
|
|
76003
76742
|
}
|
|
76004
76743
|
var provider_get_default = defineController2(async ({ req, params, env: env2 }) => {
|
|
76005
|
-
|
|
76006
|
-
|
|
76007
|
-
|
|
76008
|
-
return authResult;
|
|
76009
|
-
}
|
|
76010
|
-
} else {
|
|
76011
|
-
const authContext = await authenticate(req, env2);
|
|
76012
|
-
if (authContext && !hasPermission(authContext.user, "logs")) {
|
|
76013
|
-
return Response.json(
|
|
76014
|
-
{ error: "Forbidden: 'logs' access required" },
|
|
76015
|
-
{ status: 403 }
|
|
76016
|
-
);
|
|
76017
|
-
}
|
|
76744
|
+
const authResult = await requirePermission(req, env2, "logs");
|
|
76745
|
+
if (authResult instanceof Response) {
|
|
76746
|
+
return authResult;
|
|
76018
76747
|
}
|
|
76019
76748
|
const threadId = params.id;
|
|
76020
76749
|
const logId = params.logId;
|
|
@@ -76234,30 +76963,28 @@ var provider_get_default = defineController2(async ({ req, params, env: env2 })
|
|
|
76234
76963
|
|
|
76235
76964
|
// src/built-in-routes.ts
|
|
76236
76965
|
var routeHandlers = {
|
|
76237
|
-
"POST:/": index_post_default,
|
|
76238
76966
|
"GET:/agents": agents_get_default,
|
|
76239
76967
|
"GET:/api-keys": index_get_default,
|
|
76240
|
-
"POST:/api-keys":
|
|
76968
|
+
"POST:/api-keys": index_post_default,
|
|
76241
76969
|
"GET:/config": config_get_default,
|
|
76242
76970
|
"GET:/diagnostics": diagnostics_get_default,
|
|
76243
76971
|
"GET:/events": events_get_default,
|
|
76244
76972
|
"GET:/hooks": hooks_get_default,
|
|
76245
76973
|
"GET:/models": models_get_default,
|
|
76246
|
-
"GET:/new-test": new_test_get_default,
|
|
76247
76974
|
"GET:/platform-endpoint": platform_endpoint_default,
|
|
76248
76975
|
"GET:/prompts": prompts_get_default,
|
|
76249
76976
|
"GET:/providers": providers_get_default,
|
|
76250
76977
|
"GET:/skills": index_get_default2,
|
|
76251
|
-
"POST:/skills":
|
|
76252
|
-
"POST:/threads":
|
|
76978
|
+
"POST:/skills": index_post_default2,
|
|
76979
|
+
"POST:/threads": index_post_default3,
|
|
76253
76980
|
"GET:/threads": threads_default,
|
|
76254
76981
|
"GET:/tools": tools_get_default,
|
|
76255
76982
|
"GET:/users": index_get_default3,
|
|
76256
|
-
"POST:/users":
|
|
76983
|
+
"POST:/users": index_post_default4,
|
|
76257
76984
|
"GET:/agents/:name": name_get_default,
|
|
76258
76985
|
"DELETE:/api-keys/:id": id_delete_default,
|
|
76259
76986
|
"GET:/models/:name": name_get_default2,
|
|
76260
|
-
"POST:/pack/:agentName":
|
|
76987
|
+
"POST:/pack/:agentName": index_post_default5,
|
|
76261
76988
|
"GET:/prompts/:name": name_get_default3,
|
|
76262
76989
|
"DELETE:/skills/:name": name_delete_default,
|
|
76263
76990
|
"GET:/skills/:name": name_get_default4,
|
|
@@ -76266,18 +76993,19 @@ var routeHandlers = {
|
|
|
76266
76993
|
"PATCH:/threads/:id": id_patch_default,
|
|
76267
76994
|
"GET:/threads/:id": id_default,
|
|
76268
76995
|
"GET:/tools/:name": name_get_default5,
|
|
76269
|
-
"POST:/unpack/:packageId":
|
|
76996
|
+
"POST:/unpack/:packageId": index_post_default6,
|
|
76270
76997
|
"DELETE:/users/:id": id_delete_default3,
|
|
76271
76998
|
"PUT:/users/:id": id_put_default,
|
|
76272
76999
|
"POST:/auth/bootstrap": bootstrap_post_default,
|
|
76273
77000
|
"POST:/auth/brolly-control": brolly_control_post_default,
|
|
76274
77001
|
"GET:/auth/config": config_get_default2,
|
|
77002
|
+
"DELETE:/auth/current-key": current_key_delete_default,
|
|
76275
77003
|
"POST:/auth/login": login_post_default,
|
|
76276
|
-
"GET:/auth/logout": logout_get_default,
|
|
76277
77004
|
"POST:/auth/logout": logout_post_default,
|
|
76278
77005
|
"GET:/auth/me": me_get_default,
|
|
76279
77006
|
"POST:/auth/platform-cleanup": platform_cleanup_post_default,
|
|
76280
77007
|
"POST:/auth/platform-replica": platform_replica_post_default,
|
|
77008
|
+
"POST:/auth/websocket-ticket": websocket_ticket_post_default,
|
|
76281
77009
|
"GET:/envs/instance": instance_get_default,
|
|
76282
77010
|
"PATCH:/envs/instance": instance_patch_default,
|
|
76283
77011
|
"POST:/models/available": available_post_default,
|
|
@@ -76353,9 +77081,10 @@ var routeHandlers = {
|
|
|
76353
77081
|
"GET:/users/me/hub": hub_default,
|
|
76354
77082
|
"DELETE:/users/me/kv": index_delete_default,
|
|
76355
77083
|
"GET:/users/me/kv": index_get_default4,
|
|
76356
|
-
"POST:/users/me/kv":
|
|
77084
|
+
"POST:/users/me/kv": index_post_default7,
|
|
76357
77085
|
"GET:/users/me/stream": stream_default3,
|
|
76358
77086
|
"GET:/auth/device/:code/approve": approve_get_default,
|
|
77087
|
+
"POST:/auth/device/:code/approve": approve_post_default,
|
|
76359
77088
|
"GET:/skills/:name/files/**": path_get_default,
|
|
76360
77089
|
"DELETE:/threads/:id/fs/**": path_default3,
|
|
76361
77090
|
"POST:/threads/:id/fs/**": path_default3,
|
|
@@ -76363,7 +77092,6 @@ var routeHandlers = {
|
|
|
76363
77092
|
"GET:/threads/:id/logs/:logId": logId_get_default,
|
|
76364
77093
|
"DELETE:/threads/:id/messages/:messageId": messageId_delete_default,
|
|
76365
77094
|
"PATCH:/threads/:id/messages/:messageId": messageId_patch_default,
|
|
76366
|
-
"GET:/threads/:id/public/**": path_default4,
|
|
76367
77095
|
"GET:/threads/:id/variables/:requestId": requestId_get_default,
|
|
76368
77096
|
"POST:/threads/:id/variables/:requestId": requestId_post_default,
|
|
76369
77097
|
"POST:/threads/:id/effects/:effectId/cancel": cancel_post_default,
|