@standardagents/builder 0.38.0 → 0.38.2
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 +1243 -418
- 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-BBu-Osn5.d.ts → index-CF-lgN47.d.ts} +74 -11
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1064 -304
- package/dist/index.js.map +1 -1
- package/dist/plugin.js +106 -69
- package/dist/plugin.js.map +1 -1
- package/dist/runtime.d.ts +68 -11
- package/dist/runtime.js +950 -225
- 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
|
// ─────────────────────────────────────────────────────────────────────────
|
|
@@ -67052,6 +67222,7 @@ function getParamRegexp(segment) {
|
|
|
67052
67222
|
init_ThreadStateImpl();
|
|
67053
67223
|
|
|
67054
67224
|
// src/utils/auth.ts
|
|
67225
|
+
var SUPER_ADMIN_TOKEN_TTL_SECONDS = 12 * 60 * 60;
|
|
67055
67226
|
function generateSecureToken(length = 32) {
|
|
67056
67227
|
const array44 = new Uint8Array(length);
|
|
67057
67228
|
crypto.getRandomValues(array44);
|
|
@@ -67063,6 +67234,20 @@ function generateUserToken() {
|
|
|
67063
67234
|
function generateApiKey() {
|
|
67064
67235
|
return `agtbldr_${generateSecureToken(32)}`;
|
|
67065
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
|
+
}
|
|
67066
67251
|
async function hashPassword(password) {
|
|
67067
67252
|
const encoder2 = new TextEncoder();
|
|
67068
67253
|
const data = encoder2.encode(password);
|
|
@@ -67174,9 +67359,9 @@ function isValidUserToken(token) {
|
|
|
67174
67359
|
function isValidApiKey(key) {
|
|
67175
67360
|
return key.startsWith("agtbldr_") && key.length > 10 || key.startsWith("sak_live_") && key.length > 10;
|
|
67176
67361
|
}
|
|
67177
|
-
async function signToken(payload,
|
|
67362
|
+
async function signToken(payload, encryptionKey2) {
|
|
67178
67363
|
const encoder2 = new TextEncoder();
|
|
67179
|
-
const keyData = encoder2.encode(
|
|
67364
|
+
const keyData = encoder2.encode(encryptionKey2);
|
|
67180
67365
|
const cryptoKey = await crypto.subtle.importKey(
|
|
67181
67366
|
"raw",
|
|
67182
67367
|
keyData,
|
|
@@ -67190,7 +67375,7 @@ async function signToken(payload, encryptionKey) {
|
|
|
67190
67375
|
const signatureB64 = bufferToBase64(new Uint8Array(signature));
|
|
67191
67376
|
return `${payloadB64}.${signatureB64}`;
|
|
67192
67377
|
}
|
|
67193
|
-
async function verifySignedToken(signedToken,
|
|
67378
|
+
async function verifySignedToken(signedToken, encryptionKey2) {
|
|
67194
67379
|
try {
|
|
67195
67380
|
const parts = signedToken.split(".");
|
|
67196
67381
|
if (parts.length !== 2) {
|
|
@@ -67198,7 +67383,7 @@ async function verifySignedToken(signedToken, encryptionKey) {
|
|
|
67198
67383
|
}
|
|
67199
67384
|
const [payloadB64, signatureB64] = parts;
|
|
67200
67385
|
const encoder2 = new TextEncoder();
|
|
67201
|
-
const keyData = encoder2.encode(
|
|
67386
|
+
const keyData = encoder2.encode(encryptionKey2);
|
|
67202
67387
|
const cryptoKey = await crypto.subtle.importKey(
|
|
67203
67388
|
"raw",
|
|
67204
67389
|
keyData,
|
|
@@ -67219,14 +67404,14 @@ async function verifySignedToken(signedToken, encryptionKey) {
|
|
|
67219
67404
|
return null;
|
|
67220
67405
|
}
|
|
67221
67406
|
}
|
|
67222
|
-
async function generateSuperAdminToken(
|
|
67407
|
+
async function generateSuperAdminToken(encryptionKey2) {
|
|
67223
67408
|
const timestamp = Date.now();
|
|
67224
67409
|
const nonce = generateSecureToken(16);
|
|
67225
67410
|
const payload = `super_admin:${timestamp}:${nonce}`;
|
|
67226
|
-
return await signToken(payload,
|
|
67411
|
+
return await signToken(payload, encryptionKey2);
|
|
67227
67412
|
}
|
|
67228
|
-
async function verifySuperAdminToken(token,
|
|
67229
|
-
const payload = await verifySignedToken(token,
|
|
67413
|
+
async function verifySuperAdminToken(token, encryptionKey2) {
|
|
67414
|
+
const payload = await verifySignedToken(token, encryptionKey2);
|
|
67230
67415
|
if (!payload) {
|
|
67231
67416
|
return false;
|
|
67232
67417
|
}
|
|
@@ -67235,9 +67420,12 @@ async function verifySuperAdminToken(token, encryptionKey) {
|
|
|
67235
67420
|
return false;
|
|
67236
67421
|
}
|
|
67237
67422
|
const timestamp = parseInt(parts[1], 10);
|
|
67423
|
+
if (!Number.isFinite(timestamp)) {
|
|
67424
|
+
return false;
|
|
67425
|
+
}
|
|
67238
67426
|
const age = Date.now() - timestamp;
|
|
67239
|
-
const maxAge =
|
|
67240
|
-
if (age > maxAge) {
|
|
67427
|
+
const maxAge = SUPER_ADMIN_TOKEN_TTL_SECONDS * 1e3;
|
|
67428
|
+
if (age < 0 || age > maxAge) {
|
|
67241
67429
|
return false;
|
|
67242
67430
|
}
|
|
67243
67431
|
return true;
|
|
@@ -67258,17 +67446,99 @@ function base64ToBuffer(base64) {
|
|
|
67258
67446
|
return bytes;
|
|
67259
67447
|
}
|
|
67260
67448
|
|
|
67261
|
-
// src/
|
|
67262
|
-
|
|
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 = {
|
|
67263
67515
|
"Access-Control-Allow-Origin": "*",
|
|
67264
67516
|
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
|
|
67265
67517
|
"Access-Control-Allow-Headers": "Content-Type, Authorization, X-Requested-With",
|
|
67266
67518
|
"Access-Control-Max-Age": "86400"
|
|
67267
67519
|
};
|
|
67268
|
-
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 = {}) {
|
|
67269
67534
|
if (user.role === "admin") return true;
|
|
67270
67535
|
if (Array.isArray(user.permissions)) return user.permissions.includes(permission);
|
|
67271
|
-
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
|
+
});
|
|
67272
67542
|
}
|
|
67273
67543
|
function parsePermissions(value) {
|
|
67274
67544
|
if (Array.isArray(value)) return value.filter((p) => typeof p === "string");
|
|
@@ -67290,43 +67560,96 @@ function extractBearerToken(request) {
|
|
|
67290
67560
|
if (cookieToken) {
|
|
67291
67561
|
return cookieToken;
|
|
67292
67562
|
}
|
|
67293
|
-
const isWebSocket = request.headers.get("upgrade")?.toLowerCase() === "websocket";
|
|
67294
|
-
if (isWebSocket) {
|
|
67295
|
-
try {
|
|
67296
|
-
const url = new URL(request.url);
|
|
67297
|
-
const token = url.searchParams.get("token");
|
|
67298
|
-
if (token) {
|
|
67299
|
-
return token;
|
|
67300
|
-
}
|
|
67301
|
-
} catch (err) {
|
|
67302
|
-
}
|
|
67303
|
-
}
|
|
67304
67563
|
return null;
|
|
67305
67564
|
}
|
|
67306
67565
|
function getAgentBuilder(env2) {
|
|
67307
67566
|
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
67308
67567
|
return env2.AGENT_BUILDER.get(agentBuilderId);
|
|
67309
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
|
+
}
|
|
67310
67627
|
async function authenticate(request, env2) {
|
|
67628
|
+
const ticketAuth = await consumeWebSocketTicket(request, env2);
|
|
67629
|
+
if (ticketAuth) return ticketAuth;
|
|
67311
67630
|
const token = extractBearerToken(request);
|
|
67312
67631
|
if (!token) {
|
|
67313
67632
|
return null;
|
|
67314
67633
|
}
|
|
67315
|
-
if (env2.SUPER_ADMIN_PASSWORD && env2.ENCRYPTION_KEY) {
|
|
67634
|
+
if (typeof env2.SUPER_ADMIN_PASSWORD === "string" && typeof env2.ENCRYPTION_KEY === "string") {
|
|
67316
67635
|
if (token.includes(".")) {
|
|
67317
67636
|
const isValidSuperAdmin = await verifySuperAdminToken(
|
|
67318
67637
|
token,
|
|
67319
67638
|
env2.ENCRYPTION_KEY
|
|
67320
67639
|
);
|
|
67321
67640
|
if (isValidSuperAdmin) {
|
|
67322
|
-
|
|
67323
|
-
|
|
67324
|
-
|
|
67325
|
-
|
|
67326
|
-
|
|
67327
|
-
|
|
67328
|
-
|
|
67329
|
-
|
|
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
|
+
}
|
|
67330
67653
|
}
|
|
67331
67654
|
}
|
|
67332
67655
|
}
|
|
@@ -67371,7 +67694,8 @@ async function authenticate(request, env2) {
|
|
|
67371
67694
|
display_name: user.display_name ?? null,
|
|
67372
67695
|
avatar_url: user.avatar_url ?? null
|
|
67373
67696
|
},
|
|
67374
|
-
authType: "api_key"
|
|
67697
|
+
authType: "api_key",
|
|
67698
|
+
credentialId: apiKey.id
|
|
67375
67699
|
};
|
|
67376
67700
|
}
|
|
67377
67701
|
}
|
|
@@ -67383,7 +67707,10 @@ async function requireAuth(request, env2) {
|
|
|
67383
67707
|
if (!authContext) {
|
|
67384
67708
|
return new Response(JSON.stringify({ error: "Unauthorized" }), {
|
|
67385
67709
|
status: 401,
|
|
67386
|
-
headers: {
|
|
67710
|
+
headers: {
|
|
67711
|
+
"Content-Type": "application/json",
|
|
67712
|
+
...runtimeCorsHeaders(request, env2)
|
|
67713
|
+
}
|
|
67387
67714
|
});
|
|
67388
67715
|
}
|
|
67389
67716
|
return authContext;
|
|
@@ -67393,12 +67720,15 @@ async function requirePermission(request, env2, permission) {
|
|
|
67393
67720
|
if (result instanceof Response) {
|
|
67394
67721
|
return result;
|
|
67395
67722
|
}
|
|
67396
|
-
if (!
|
|
67723
|
+
if (!hasPermissionInEnvironment(result.user, permission, env2)) {
|
|
67397
67724
|
return new Response(
|
|
67398
67725
|
JSON.stringify({ error: `Forbidden: '${permission}' access required` }),
|
|
67399
67726
|
{
|
|
67400
67727
|
status: 403,
|
|
67401
|
-
headers: {
|
|
67728
|
+
headers: {
|
|
67729
|
+
"Content-Type": "application/json",
|
|
67730
|
+
...runtimeCorsHeaders(request, env2)
|
|
67731
|
+
}
|
|
67402
67732
|
}
|
|
67403
67733
|
);
|
|
67404
67734
|
}
|
|
@@ -67414,7 +67744,10 @@ async function requireAdmin(request, env2) {
|
|
|
67414
67744
|
JSON.stringify({ error: "Forbidden: Admin access required" }),
|
|
67415
67745
|
{
|
|
67416
67746
|
status: 403,
|
|
67417
|
-
headers: {
|
|
67747
|
+
headers: {
|
|
67748
|
+
"Content-Type": "application/json",
|
|
67749
|
+
...runtimeCorsHeaders(request, env2)
|
|
67750
|
+
}
|
|
67418
67751
|
}
|
|
67419
67752
|
);
|
|
67420
67753
|
}
|
|
@@ -67424,27 +67757,6 @@ function defineController2(controller) {
|
|
|
67424
67757
|
return controller;
|
|
67425
67758
|
}
|
|
67426
67759
|
|
|
67427
|
-
// src/api/index.post.ts
|
|
67428
|
-
var index_post_default = defineController2(() => {
|
|
67429
|
-
const stream = new ReadableStream({
|
|
67430
|
-
start(controller) {
|
|
67431
|
-
const text2 = "hello world";
|
|
67432
|
-
let index = 0;
|
|
67433
|
-
const next = () => {
|
|
67434
|
-
if (index < text2.length) {
|
|
67435
|
-
controller.enqueue(new TextEncoder().encode(text2[index]));
|
|
67436
|
-
index++;
|
|
67437
|
-
setTimeout(next, 100);
|
|
67438
|
-
} else {
|
|
67439
|
-
controller.close();
|
|
67440
|
-
}
|
|
67441
|
-
};
|
|
67442
|
-
next();
|
|
67443
|
-
}
|
|
67444
|
-
});
|
|
67445
|
-
return new Response(stream);
|
|
67446
|
-
});
|
|
67447
|
-
|
|
67448
67760
|
// src/api/agents.get.ts
|
|
67449
67761
|
var agents_get_default = defineController2(async ({ agents, agentNames, registry, auth }) => {
|
|
67450
67762
|
const includeAuthoringDetails = auth?.user.role === "admin";
|
|
@@ -67526,29 +67838,16 @@ var agents_get_default = defineController2(async ({ agents, agentNames, registry
|
|
|
67526
67838
|
return Response.json({ agents: validAgents });
|
|
67527
67839
|
});
|
|
67528
67840
|
|
|
67529
|
-
// src/routing/access-policy.ts
|
|
67530
|
-
function isHostedInstance(env2) {
|
|
67531
|
-
const value = env2?.STANDARD_AGENTS_HOSTED;
|
|
67532
|
-
if (typeof value === "string") {
|
|
67533
|
-
const normalized = value.trim().toLowerCase();
|
|
67534
|
-
return normalized !== "" && normalized !== "0" && normalized !== "false";
|
|
67535
|
-
}
|
|
67536
|
-
return Boolean(value);
|
|
67537
|
-
}
|
|
67538
|
-
function isTrustedLocalDevelopmentRequest(request, env2) {
|
|
67539
|
-
if (isHostedInstance(env2)) return false;
|
|
67540
|
-
let hostname;
|
|
67541
|
-
try {
|
|
67542
|
-
hostname = new URL(request.url).hostname.toLowerCase();
|
|
67543
|
-
} catch {
|
|
67544
|
-
return false;
|
|
67545
|
-
}
|
|
67546
|
-
return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1" || hostname.endsWith(".localhost") || hostname.endsWith(".orb.local");
|
|
67547
|
-
}
|
|
67548
|
-
|
|
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.38.
|
|
68326
|
+
var BUILDER_VERSION = "0.38.2".length > 0 ? "0.38.2" : "dev";
|
|
68035
68327
|
|
|
68036
68328
|
// src/api/diagnostics.get.ts
|
|
68037
68329
|
init_LLMRequest();
|
|
@@ -68150,6 +68442,35 @@ function resolveStreamTimeoutValue(env2, key, fallback) {
|
|
|
68150
68442
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
68151
68443
|
}
|
|
68152
68444
|
|
|
68445
|
+
// src/middleware/request-auth.ts
|
|
68446
|
+
async function resolveRequestAuth(context) {
|
|
68447
|
+
if (context.auth) return context.auth;
|
|
68448
|
+
if (!isAuthenticationEnv(context.env)) {
|
|
68449
|
+
return new Response(JSON.stringify({ error: "Unauthorized" }), {
|
|
68450
|
+
status: 401,
|
|
68451
|
+
headers: { "Content-Type": "application/json" }
|
|
68452
|
+
});
|
|
68453
|
+
}
|
|
68454
|
+
return requireAuth(context.req, context.env);
|
|
68455
|
+
}
|
|
68456
|
+
async function resolveRequestPermission(context, permission) {
|
|
68457
|
+
if (context.auth) {
|
|
68458
|
+
if (!hasPermissionInEnvironment(context.auth.user, permission, context.env)) {
|
|
68459
|
+
return Response.json(
|
|
68460
|
+
{ error: `Forbidden: '${permission}' access required` },
|
|
68461
|
+
{ status: 403 }
|
|
68462
|
+
);
|
|
68463
|
+
}
|
|
68464
|
+
return context.auth;
|
|
68465
|
+
}
|
|
68466
|
+
return requirePermission(context.req, context.env, permission);
|
|
68467
|
+
}
|
|
68468
|
+
function routerAuthorizedThread(context, threadId) {
|
|
68469
|
+
const access = context.threadAccess;
|
|
68470
|
+
if (!access || !threadId) return null;
|
|
68471
|
+
return access.threadId === threadId ? access.thread : null;
|
|
68472
|
+
}
|
|
68473
|
+
|
|
68153
68474
|
// src/events/access.ts
|
|
68154
68475
|
var EVENT_STREAM_USER_ID_HEADER = "X-Standard-Agents-Event-User-Id";
|
|
68155
68476
|
var EVENT_STREAM_SCOPE_HEADER = "X-Standard-Agents-Event-Scope";
|
|
@@ -68181,8 +68502,9 @@ function resolveEventStreamSubscription(request, auth) {
|
|
|
68181
68502
|
}
|
|
68182
68503
|
|
|
68183
68504
|
// src/api/events.get.ts
|
|
68184
|
-
var events_get_default = defineController2(async (
|
|
68185
|
-
const
|
|
68505
|
+
var events_get_default = defineController2(async (context) => {
|
|
68506
|
+
const { req, env: env2 } = context;
|
|
68507
|
+
const authResult = await resolveRequestAuth(context);
|
|
68186
68508
|
if (authResult instanceof Response) {
|
|
68187
68509
|
return authResult;
|
|
68188
68510
|
}
|
|
@@ -68211,9 +68533,10 @@ var events_get_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
68211
68533
|
const stub = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
68212
68534
|
return await stub.fetch(authenticatedUpgrade);
|
|
68213
68535
|
} catch (error) {
|
|
68536
|
+
const message = error instanceof Error ? error.message : "Failed to establish WebSocket connection";
|
|
68214
68537
|
console.error("Error establishing events WebSocket:", error);
|
|
68215
68538
|
return Response.json(
|
|
68216
|
-
{ error:
|
|
68539
|
+
{ error: message },
|
|
68217
68540
|
{ status: 500 }
|
|
68218
68541
|
);
|
|
68219
68542
|
}
|
|
@@ -68429,11 +68752,6 @@ var models_get_default = defineController2(async ({ models, modelNames }) => {
|
|
|
68429
68752
|
const validModels = modelList.filter(Boolean);
|
|
68430
68753
|
return Response.json({ models: validModels });
|
|
68431
68754
|
});
|
|
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
68755
|
function toJSONSchema(schema) {
|
|
68438
68756
|
if (!schema) return null;
|
|
68439
68757
|
if (schema && typeof schema === "object" && ("~standard" in schema || "_def" in schema)) {
|
|
@@ -68540,6 +68858,7 @@ var providers_get_default = defineController2(async ({ env: env2 }) => {
|
|
|
68540
68858
|
});
|
|
68541
68859
|
|
|
68542
68860
|
// src/api/skills/index.get.ts
|
|
68861
|
+
init_scope();
|
|
68543
68862
|
var index_get_default2 = defineController2(async ({ req, env: env2 }) => {
|
|
68544
68863
|
const authResult = await requireAdmin(req, env2);
|
|
68545
68864
|
if (authResult instanceof Response) return authResult;
|
|
@@ -68547,7 +68866,10 @@ var index_get_default2 = defineController2(async ({ req, env: env2 }) => {
|
|
|
68547
68866
|
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
68548
68867
|
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
68549
68868
|
try {
|
|
68550
|
-
const skills = await agentBuilder.listSkills(
|
|
68869
|
+
const skills = await agentBuilder.listSkills(
|
|
68870
|
+
{ ownerId: SHARED_SKILL_OWNER },
|
|
68871
|
+
{ includeDisabled }
|
|
68872
|
+
);
|
|
68551
68873
|
return Response.json({ skills });
|
|
68552
68874
|
} catch (error) {
|
|
68553
68875
|
return Response.json(
|
|
@@ -68562,7 +68884,8 @@ var SkillValidationError = class extends Error {
|
|
|
68562
68884
|
};
|
|
68563
68885
|
|
|
68564
68886
|
// src/api/skills/index.post.ts
|
|
68565
|
-
|
|
68887
|
+
init_scope();
|
|
68888
|
+
var index_post_default2 = defineController2(async ({ req, env: env2 }) => {
|
|
68566
68889
|
const authResult = await requireAdmin(req, env2);
|
|
68567
68890
|
if (authResult instanceof Response) return authResult;
|
|
68568
68891
|
let body;
|
|
@@ -68584,7 +68907,7 @@ var index_post_default3 = defineController2(async ({ req, env: env2 }) => {
|
|
|
68584
68907
|
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
68585
68908
|
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
68586
68909
|
try {
|
|
68587
|
-
const skill = await agentBuilder.upsertSkill(files);
|
|
68910
|
+
const skill = await agentBuilder.upsertSkill({ ownerId: SHARED_SKILL_OWNER }, files);
|
|
68588
68911
|
return Response.json({ skill }, { status: 201 });
|
|
68589
68912
|
} catch (error) {
|
|
68590
68913
|
const message = error instanceof Error ? error.message : "Failed to install skill";
|
|
@@ -68646,7 +68969,7 @@ async function hasEnabledImmediatePromptTools(agentBuilder, threadId, agentId) {
|
|
|
68646
68969
|
}
|
|
68647
68970
|
return false;
|
|
68648
68971
|
}
|
|
68649
|
-
var
|
|
68972
|
+
var index_post_default3 = defineController2(async ({ req, env: env2 }) => {
|
|
68650
68973
|
const authResult = await requireAuth(req, env2);
|
|
68651
68974
|
if (authResult instanceof Response) {
|
|
68652
68975
|
return authResult;
|
|
@@ -69243,15 +69566,138 @@ var migration17 = {
|
|
|
69243
69566
|
}
|
|
69244
69567
|
};
|
|
69245
69568
|
|
|
69569
|
+
// src/durable-objects/agentbuilder-migrations/0018_auth_security.ts
|
|
69570
|
+
var migration18 = {
|
|
69571
|
+
version: 18,
|
|
69572
|
+
async up(sql) {
|
|
69573
|
+
sql.exec(`
|
|
69574
|
+
CREATE TABLE IF NOT EXISTS super_admin_sessions (
|
|
69575
|
+
token_hash TEXT PRIMARY KEY,
|
|
69576
|
+
created_at INTEGER NOT NULL,
|
|
69577
|
+
expires_at INTEGER NOT NULL
|
|
69578
|
+
)
|
|
69579
|
+
`);
|
|
69580
|
+
sql.exec(`
|
|
69581
|
+
CREATE INDEX IF NOT EXISTS idx_super_admin_sessions_expires
|
|
69582
|
+
ON super_admin_sessions(expires_at)
|
|
69583
|
+
`);
|
|
69584
|
+
sql.exec(`
|
|
69585
|
+
CREATE TABLE IF NOT EXISTS auth_rate_limits (
|
|
69586
|
+
bucket_key TEXT PRIMARY KEY,
|
|
69587
|
+
attempts INTEGER NOT NULL,
|
|
69588
|
+
reset_at INTEGER NOT NULL
|
|
69589
|
+
)
|
|
69590
|
+
`);
|
|
69591
|
+
sql.exec(`
|
|
69592
|
+
CREATE INDEX IF NOT EXISTS idx_auth_rate_limits_reset
|
|
69593
|
+
ON auth_rate_limits(reset_at)
|
|
69594
|
+
`);
|
|
69595
|
+
sql.exec(`
|
|
69596
|
+
INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '18')
|
|
69597
|
+
`);
|
|
69598
|
+
}
|
|
69599
|
+
};
|
|
69600
|
+
|
|
69601
|
+
// src/durable-objects/agentbuilder-migrations/0019_scope_skills.ts
|
|
69602
|
+
var migration19 = {
|
|
69603
|
+
version: 19,
|
|
69604
|
+
async up(sql) {
|
|
69605
|
+
sql.exec(`
|
|
69606
|
+
CREATE TABLE skills_0019 (
|
|
69607
|
+
owner_id TEXT NOT NULL,
|
|
69608
|
+
name TEXT NOT NULL,
|
|
69609
|
+
description TEXT NOT NULL,
|
|
69610
|
+
version TEXT,
|
|
69611
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
69612
|
+
shared INTEGER NOT NULL DEFAULT 0,
|
|
69613
|
+
created_at INTEGER DEFAULT (strftime('%s', 'now')),
|
|
69614
|
+
updated_at INTEGER DEFAULT (strftime('%s', 'now')),
|
|
69615
|
+
PRIMARY KEY (owner_id, name)
|
|
69616
|
+
)
|
|
69617
|
+
`);
|
|
69618
|
+
sql.exec(`
|
|
69619
|
+
INSERT INTO skills_0019 (
|
|
69620
|
+
owner_id, name, description, version, enabled, shared, created_at, updated_at
|
|
69621
|
+
)
|
|
69622
|
+
SELECT '__instance_shared__', name, description, version, enabled, 1, created_at, updated_at
|
|
69623
|
+
FROM skills
|
|
69624
|
+
`);
|
|
69625
|
+
sql.exec(`
|
|
69626
|
+
CREATE TABLE skill_files_0019 (
|
|
69627
|
+
owner_id TEXT NOT NULL,
|
|
69628
|
+
skill_name TEXT NOT NULL,
|
|
69629
|
+
path TEXT NOT NULL,
|
|
69630
|
+
content TEXT NOT NULL,
|
|
69631
|
+
size INTEGER NOT NULL,
|
|
69632
|
+
PRIMARY KEY (owner_id, skill_name, path),
|
|
69633
|
+
FOREIGN KEY (owner_id, skill_name) REFERENCES skills_0019(owner_id, name) ON DELETE CASCADE
|
|
69634
|
+
)
|
|
69635
|
+
`);
|
|
69636
|
+
sql.exec(`
|
|
69637
|
+
INSERT INTO skill_files_0019 (owner_id, skill_name, path, content, size)
|
|
69638
|
+
SELECT '__instance_shared__', skill_name, path, content, size FROM skill_files
|
|
69639
|
+
`);
|
|
69640
|
+
sql.exec(`DROP TABLE skill_files`);
|
|
69641
|
+
sql.exec(`DROP TABLE skills`);
|
|
69642
|
+
sql.exec(`ALTER TABLE skills_0019 RENAME TO skills`);
|
|
69643
|
+
sql.exec(`ALTER TABLE skill_files_0019 RENAME TO skill_files`);
|
|
69644
|
+
sql.exec(`CREATE INDEX idx_skills_owner_enabled ON skills(owner_id, enabled)`);
|
|
69645
|
+
sql.exec(`CREATE INDEX idx_skills_shared_enabled ON skills(shared, enabled)`);
|
|
69646
|
+
sql.exec(`CREATE INDEX idx_skill_files_skill ON skill_files(owner_id, skill_name)`);
|
|
69647
|
+
sql.exec(`INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '19')`);
|
|
69648
|
+
}
|
|
69649
|
+
};
|
|
69650
|
+
|
|
69651
|
+
// src/durable-objects/agentbuilder-migrations/0020_websocket_tickets.ts
|
|
69652
|
+
var migration20 = {
|
|
69653
|
+
version: 20,
|
|
69654
|
+
async up(sql) {
|
|
69655
|
+
sql.exec(`
|
|
69656
|
+
CREATE TABLE websocket_tickets (
|
|
69657
|
+
ticket_hash TEXT PRIMARY KEY,
|
|
69658
|
+
pathname TEXT NOT NULL,
|
|
69659
|
+
auth_json TEXT NOT NULL,
|
|
69660
|
+
created_at INTEGER NOT NULL,
|
|
69661
|
+
expires_at INTEGER NOT NULL
|
|
69662
|
+
)
|
|
69663
|
+
`);
|
|
69664
|
+
sql.exec(`
|
|
69665
|
+
CREATE INDEX idx_websocket_tickets_expires
|
|
69666
|
+
ON websocket_tickets(expires_at)
|
|
69667
|
+
`);
|
|
69668
|
+
sql.exec(`INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '20')`);
|
|
69669
|
+
}
|
|
69670
|
+
};
|
|
69671
|
+
|
|
69672
|
+
// src/durable-objects/agentbuilder-migrations/0021_platform_handoff_jtis.ts
|
|
69673
|
+
var migration21 = {
|
|
69674
|
+
version: 21,
|
|
69675
|
+
async up(sql) {
|
|
69676
|
+
sql.exec(`
|
|
69677
|
+
CREATE TABLE platform_handoff_jtis (
|
|
69678
|
+
jti TEXT PRIMARY KEY,
|
|
69679
|
+
consumed_at INTEGER NOT NULL,
|
|
69680
|
+
expires_at INTEGER NOT NULL
|
|
69681
|
+
)
|
|
69682
|
+
`);
|
|
69683
|
+
sql.exec(`
|
|
69684
|
+
CREATE INDEX idx_platform_handoff_jtis_expires
|
|
69685
|
+
ON platform_handoff_jtis(expires_at)
|
|
69686
|
+
`);
|
|
69687
|
+
sql.exec(`INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '21')`);
|
|
69688
|
+
}
|
|
69689
|
+
};
|
|
69690
|
+
|
|
69246
69691
|
// 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];
|
|
69692
|
+
var migrations = [migration, migration2, migration3, migration4, migration5, migration6, migration7, migration8, migration9, migration10, migration11, migration12, migration13, migration14, migration15, migration16, migration17, migration18, migration19, migration20, migration21];
|
|
69248
69693
|
migrations.reduce(
|
|
69249
|
-
(max,
|
|
69694
|
+
(max, migration22) => Math.max(max, migration22.version),
|
|
69250
69695
|
0
|
|
69251
69696
|
);
|
|
69252
69697
|
|
|
69253
69698
|
// src/durable-objects/DurableAgentBuilder.ts
|
|
69254
69699
|
init_types();
|
|
69700
|
+
init_scope();
|
|
69255
69701
|
var THREAD_PREVIEW_MAX_CHARS = 140;
|
|
69256
69702
|
var buildThreadPreview = (content) => {
|
|
69257
69703
|
const collapsed = content.replace(/\s+/g, " ").trim();
|
|
@@ -69607,7 +70053,7 @@ var index_get_default3 = defineController2(async ({ req, env: env2 }) => {
|
|
|
69607
70053
|
|
|
69608
70054
|
// src/api/users/index.post.ts
|
|
69609
70055
|
var VALID_ROLES = ["admin", "user"];
|
|
69610
|
-
var
|
|
70056
|
+
var index_post_default4 = defineController2(async ({ req, env: env2 }) => {
|
|
69611
70057
|
try {
|
|
69612
70058
|
if (isPlatformHosted(env2)) {
|
|
69613
70059
|
return Response.json({ error: "Users are managed in the Standard Agents platform." }, { status: 410 });
|
|
@@ -69871,7 +70317,7 @@ var name_get_default2 = defineController2(async ({ params, models }) => {
|
|
|
69871
70317
|
});
|
|
69872
70318
|
|
|
69873
70319
|
// src/api/pack/[agentName]/index.post.ts
|
|
69874
|
-
var
|
|
70320
|
+
var index_post_default5 = defineController2(async ({ req, env: env2 }) => {
|
|
69875
70321
|
const auth = await requireAdmin(req, env2);
|
|
69876
70322
|
if (auth instanceof Response) return auth;
|
|
69877
70323
|
const url = new URL(req.url);
|
|
@@ -70051,6 +70497,7 @@ var name_get_default3 = defineController2(async ({ params, prompts, models, mode
|
|
|
70051
70497
|
});
|
|
70052
70498
|
|
|
70053
70499
|
// src/api/skills/[name].delete.ts
|
|
70500
|
+
init_scope();
|
|
70054
70501
|
var name_delete_default = defineController2(async ({ req, env: env2, params }) => {
|
|
70055
70502
|
const authResult = await requireAdmin(req, env2);
|
|
70056
70503
|
if (authResult instanceof Response) return authResult;
|
|
@@ -70059,7 +70506,7 @@ var name_delete_default = defineController2(async ({ req, env: env2, params }) =
|
|
|
70059
70506
|
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
70060
70507
|
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
70061
70508
|
try {
|
|
70062
|
-
const found = await agentBuilder.deleteSkill(name15);
|
|
70509
|
+
const found = await agentBuilder.deleteSkill({ ownerId: SHARED_SKILL_OWNER }, name15);
|
|
70063
70510
|
if (!found) return Response.json({ error: `Skill not found: ${name15}` }, { status: 404 });
|
|
70064
70511
|
return Response.json({ ok: true, removed: name15 });
|
|
70065
70512
|
} catch (error) {
|
|
@@ -70071,6 +70518,7 @@ var name_delete_default = defineController2(async ({ req, env: env2, params }) =
|
|
|
70071
70518
|
});
|
|
70072
70519
|
|
|
70073
70520
|
// src/api/skills/[name].get.ts
|
|
70521
|
+
init_scope();
|
|
70074
70522
|
var name_get_default4 = defineController2(async ({ req, env: env2, params }) => {
|
|
70075
70523
|
const authResult = await requireAdmin(req, env2);
|
|
70076
70524
|
if (authResult instanceof Response) return authResult;
|
|
@@ -70079,9 +70527,10 @@ var name_get_default4 = defineController2(async ({ req, env: env2, params }) =>
|
|
|
70079
70527
|
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
70080
70528
|
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
70081
70529
|
try {
|
|
70082
|
-
const
|
|
70530
|
+
const scope = { ownerId: SHARED_SKILL_OWNER };
|
|
70531
|
+
const skill = await agentBuilder.getSkill(scope, name15);
|
|
70083
70532
|
if (!skill) return Response.json({ error: `Skill not found: ${name15}` }, { status: 404 });
|
|
70084
|
-
const skillMd = await agentBuilder.getSkillFile(name15, "SKILL.md") ?? "";
|
|
70533
|
+
const skillMd = await agentBuilder.getSkillFile(scope, name15, "SKILL.md") ?? "";
|
|
70085
70534
|
return Response.json({ skill, skillMd });
|
|
70086
70535
|
} catch (error) {
|
|
70087
70536
|
return Response.json(
|
|
@@ -70092,6 +70541,7 @@ var name_get_default4 = defineController2(async ({ req, env: env2, params }) =>
|
|
|
70092
70541
|
});
|
|
70093
70542
|
|
|
70094
70543
|
// src/api/skills/[name].patch.ts
|
|
70544
|
+
init_scope();
|
|
70095
70545
|
var name_patch_default = defineController2(async ({ req, env: env2, params }) => {
|
|
70096
70546
|
const authResult = await requireAdmin(req, env2);
|
|
70097
70547
|
if (authResult instanceof Response) return authResult;
|
|
@@ -70109,9 +70559,10 @@ var name_patch_default = defineController2(async ({ req, env: env2, params }) =>
|
|
|
70109
70559
|
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
70110
70560
|
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
70111
70561
|
try {
|
|
70112
|
-
const
|
|
70562
|
+
const scope = { ownerId: SHARED_SKILL_OWNER };
|
|
70563
|
+
const found = await agentBuilder.setSkillEnabled(scope, name15, body.enabled);
|
|
70113
70564
|
if (!found) return Response.json({ error: `Skill not found: ${name15}` }, { status: 404 });
|
|
70114
|
-
const skill = await agentBuilder.getSkill(name15);
|
|
70565
|
+
const skill = await agentBuilder.getSkill(scope, name15);
|
|
70115
70566
|
return Response.json({ skill });
|
|
70116
70567
|
} catch (error) {
|
|
70117
70568
|
return Response.json(
|
|
@@ -70408,7 +70859,6 @@ var id_patch_default = defineController2(async ({ req, env: env2, params }) => {
|
|
|
70408
70859
|
// Map agent_name back to agent_id for API compat
|
|
70409
70860
|
user_id: updatedThread.user_id,
|
|
70410
70861
|
tags: updatedThread.tags || [],
|
|
70411
|
-
env: updatedThread.env ?? updatedThread.tenvs ?? null,
|
|
70412
70862
|
env_types: updatedThread.env_types ?? null,
|
|
70413
70863
|
created_at: updatedThread.created_at
|
|
70414
70864
|
});
|
|
@@ -70421,33 +70871,6 @@ var id_patch_default = defineController2(async ({ req, env: env2, params }) => {
|
|
|
70421
70871
|
}
|
|
70422
70872
|
});
|
|
70423
70873
|
|
|
70424
|
-
// src/middleware/request-auth.ts
|
|
70425
|
-
async function resolveRequestAuth(context) {
|
|
70426
|
-
if (context.auth) return context.auth;
|
|
70427
|
-
return requireAuth(context.req, context.env);
|
|
70428
|
-
}
|
|
70429
|
-
async function resolveOptionalRequestAuth(context) {
|
|
70430
|
-
if (context.auth) return context.auth;
|
|
70431
|
-
return authenticate(context.req, context.env);
|
|
70432
|
-
}
|
|
70433
|
-
async function resolveRequestPermission(context, permission) {
|
|
70434
|
-
if (context.auth) {
|
|
70435
|
-
if (!hasPermission(context.auth.user, permission)) {
|
|
70436
|
-
return Response.json(
|
|
70437
|
-
{ error: `Forbidden: '${permission}' access required` },
|
|
70438
|
-
{ status: 403 }
|
|
70439
|
-
);
|
|
70440
|
-
}
|
|
70441
|
-
return context.auth;
|
|
70442
|
-
}
|
|
70443
|
-
return requirePermission(context.req, context.env, permission);
|
|
70444
|
-
}
|
|
70445
|
-
function routerAuthorizedThread(context, threadId) {
|
|
70446
|
-
const access = context.threadAccess;
|
|
70447
|
-
if (!access || !threadId) return null;
|
|
70448
|
-
return access.threadId === threadId ? access.thread : null;
|
|
70449
|
-
}
|
|
70450
|
-
|
|
70451
70874
|
// src/api/threads/[id].ts
|
|
70452
70875
|
function resolveIconUrl2(icon, origin) {
|
|
70453
70876
|
if (!icon) return void 0;
|
|
@@ -70578,7 +71001,7 @@ var name_get_default5 = defineController2(async ({ params, tools }) => {
|
|
|
70578
71001
|
|
|
70579
71002
|
// src/api/unpack/[packageId]/index.post.ts
|
|
70580
71003
|
init_package_identifier();
|
|
70581
|
-
var
|
|
71004
|
+
var index_post_default6 = defineController2(async ({ req, env: env2 }) => {
|
|
70582
71005
|
const auth = await requireAdmin(req, env2);
|
|
70583
71006
|
if (auth instanceof Response) return auth;
|
|
70584
71007
|
const url = new URL(req.url);
|
|
@@ -70723,17 +71146,43 @@ var id_put_default = defineController2(async ({ req, env: env2, params }) => {
|
|
|
70723
71146
|
});
|
|
70724
71147
|
|
|
70725
71148
|
// src/api/auth/bootstrap.post.ts
|
|
71149
|
+
var SESSION_TTL_SECONDS2 = 30 * 24 * 60 * 60;
|
|
70726
71150
|
var bootstrap_post_default = defineController2(async ({ req, env: env2 }) => {
|
|
70727
71151
|
try {
|
|
71152
|
+
if (!isTrustedLocalDevelopmentRequest(req, env2) || !isSameOriginBrowserRequest(req)) {
|
|
71153
|
+
return Response.json(
|
|
71154
|
+
{ error: "Local bootstrap is available only to same-origin clients" },
|
|
71155
|
+
{ status: 403, headers: { "Cache-Control": "no-store" } }
|
|
71156
|
+
);
|
|
71157
|
+
}
|
|
70728
71158
|
const platformTokenSession = await createPlatformLocalSession(req, env2);
|
|
70729
71159
|
if (!platformTokenSession) {
|
|
70730
|
-
return new Response(null, {
|
|
71160
|
+
return new Response(null, {
|
|
71161
|
+
status: 204,
|
|
71162
|
+
headers: { "Cache-Control": "no-store" }
|
|
71163
|
+
});
|
|
70731
71164
|
}
|
|
70732
|
-
return Response.json(
|
|
71165
|
+
return Response.json({
|
|
71166
|
+
user: platformTokenSession.user,
|
|
71167
|
+
authType: platformTokenSession.authType,
|
|
71168
|
+
platform: platformTokenSession.platform
|
|
71169
|
+
}, {
|
|
71170
|
+
headers: {
|
|
71171
|
+
"Cache-Control": "no-store",
|
|
71172
|
+
"Set-Cookie": buildSessionCookie(
|
|
71173
|
+
req,
|
|
71174
|
+
platformTokenSession.token,
|
|
71175
|
+
SESSION_TTL_SECONDS2
|
|
71176
|
+
)
|
|
71177
|
+
}
|
|
71178
|
+
});
|
|
70733
71179
|
} catch (error) {
|
|
70734
71180
|
const message = error instanceof Error ? error.message : "Failed to bootstrap platform auth";
|
|
70735
71181
|
const status = message.includes("STANDARD_AGENTS_API_KEY") ? 401 : 502;
|
|
70736
|
-
return Response.json(
|
|
71182
|
+
return Response.json(
|
|
71183
|
+
{ error: message },
|
|
71184
|
+
{ status, headers: { "Cache-Control": "no-store" } }
|
|
71185
|
+
);
|
|
70737
71186
|
}
|
|
70738
71187
|
});
|
|
70739
71188
|
|
|
@@ -70862,7 +71311,51 @@ var config_get_default2 = defineController2(async ({ req, env: env2 }) => {
|
|
|
70862
71311
|
};
|
|
70863
71312
|
});
|
|
70864
71313
|
|
|
71314
|
+
// src/api/auth/current-key.delete.ts
|
|
71315
|
+
var current_key_delete_default = defineController2(async ({ req, env: env2 }) => {
|
|
71316
|
+
try {
|
|
71317
|
+
const auth = await authenticate(req, env2);
|
|
71318
|
+
if (!auth) return Response.json({ error: "Unauthorized" }, { status: 401 });
|
|
71319
|
+
if (auth.authType !== "api_key" || !auth.credentialId) {
|
|
71320
|
+
return Response.json({ error: "An API key must authenticate this request." }, { status: 403 });
|
|
71321
|
+
}
|
|
71322
|
+
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
71323
|
+
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
71324
|
+
await agentBuilder.deleteApiKey(auth.credentialId, auth.user.id);
|
|
71325
|
+
return Response.json({ revoked: true });
|
|
71326
|
+
} catch (error) {
|
|
71327
|
+
console.error("Current API key revocation error:", error);
|
|
71328
|
+
return Response.json(
|
|
71329
|
+
{ error: error instanceof Error ? error.message : "Failed to revoke API key" },
|
|
71330
|
+
{ status: 500 }
|
|
71331
|
+
);
|
|
71332
|
+
}
|
|
71333
|
+
});
|
|
71334
|
+
|
|
71335
|
+
// src/utils/auth-rate-limit.ts
|
|
71336
|
+
function authClientAddress(request) {
|
|
71337
|
+
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";
|
|
71338
|
+
}
|
|
71339
|
+
async function authRateLimitKey(scope, identifier) {
|
|
71340
|
+
return `${scope}:${await hashToken(identifier.trim().toLowerCase())}`;
|
|
71341
|
+
}
|
|
71342
|
+
function authRateLimitedResponse(result) {
|
|
71343
|
+
return Response.json(
|
|
71344
|
+
{ error: "Too many authentication attempts. Try again later." },
|
|
71345
|
+
{
|
|
71346
|
+
status: 429,
|
|
71347
|
+
headers: {
|
|
71348
|
+
"Cache-Control": "no-store",
|
|
71349
|
+
"Retry-After": String(Math.max(1, Math.ceil(result.retry_after)))
|
|
71350
|
+
}
|
|
71351
|
+
}
|
|
71352
|
+
);
|
|
71353
|
+
}
|
|
71354
|
+
|
|
70865
71355
|
// src/api/auth/login.post.ts
|
|
71356
|
+
var LOGIN_ADDRESS_LIMIT = { limit: 10, window_seconds: 5 * 60 };
|
|
71357
|
+
var LOGIN_IDENTITY_LIMIT = { limit: 25, window_seconds: 15 * 60 };
|
|
71358
|
+
var LOGIN_INSTANCE_LIMIT = { limit: 500, window_seconds: 5 * 60 };
|
|
70866
71359
|
var login_post_default = defineController2(async ({ req, env: env2 }) => {
|
|
70867
71360
|
try {
|
|
70868
71361
|
if (isPlatformHosted(env2)) {
|
|
@@ -70879,7 +71372,31 @@ var login_post_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
70879
71372
|
{ status: 400 }
|
|
70880
71373
|
);
|
|
70881
71374
|
}
|
|
70882
|
-
if (env2.
|
|
71375
|
+
if (!env2.AGENT_BUILDER || typeof env2.AGENT_BUILDER.idFromName !== "function") {
|
|
71376
|
+
return Response.json(
|
|
71377
|
+
{ error: "Server misconfigured: AGENT_BUILDER Durable Object binding is required for local login" },
|
|
71378
|
+
{ status: 500 }
|
|
71379
|
+
);
|
|
71380
|
+
}
|
|
71381
|
+
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
71382
|
+
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
71383
|
+
const instanceLimit = await agentBuilder.consumeAuthRateLimit({
|
|
71384
|
+
key: "login-instance",
|
|
71385
|
+
...LOGIN_INSTANCE_LIMIT
|
|
71386
|
+
});
|
|
71387
|
+
if (!instanceLimit.allowed) return authRateLimitedResponse(instanceLimit);
|
|
71388
|
+
const addressLimit = await agentBuilder.consumeAuthRateLimit({
|
|
71389
|
+
key: await authRateLimitKey("login-address", authClientAddress(req)),
|
|
71390
|
+
...LOGIN_ADDRESS_LIMIT
|
|
71391
|
+
});
|
|
71392
|
+
if (!addressLimit.allowed) return authRateLimitedResponse(addressLimit);
|
|
71393
|
+
const identityLimit = await agentBuilder.consumeAuthRateLimit({
|
|
71394
|
+
key: await authRateLimitKey("login-identity", username || "<missing>"),
|
|
71395
|
+
...LOGIN_IDENTITY_LIMIT
|
|
71396
|
+
});
|
|
71397
|
+
if (!identityLimit.allowed) return authRateLimitedResponse(identityLimit);
|
|
71398
|
+
const isSuperAdminPassword = env2.SUPER_ADMIN_PASSWORD && username === "admin" ? await constantTimeEqual(password, env2.SUPER_ADMIN_PASSWORD) : false;
|
|
71399
|
+
if (isSuperAdminPassword) {
|
|
70883
71400
|
if (!env2.ENCRYPTION_KEY) {
|
|
70884
71401
|
return Response.json(
|
|
70885
71402
|
{ error: "Server misconfigured: ENCRYPTION_KEY required for super admin" },
|
|
@@ -70887,6 +71404,12 @@ var login_post_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
70887
71404
|
);
|
|
70888
71405
|
}
|
|
70889
71406
|
const token2 = await generateSuperAdminToken(env2.ENCRYPTION_KEY);
|
|
71407
|
+
const tokenHash2 = await hashToken(token2);
|
|
71408
|
+
const expiresAt2 = Math.floor(Date.now() / 1e3) + SUPER_ADMIN_TOKEN_TTL_SECONDS;
|
|
71409
|
+
await agentBuilder.createSuperAdminSession({
|
|
71410
|
+
token_hash: tokenHash2,
|
|
71411
|
+
expires_at: expiresAt2
|
|
71412
|
+
});
|
|
70890
71413
|
return Response.json({
|
|
70891
71414
|
token: token2,
|
|
70892
71415
|
user: {
|
|
@@ -70894,6 +71417,11 @@ var login_post_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
70894
71417
|
username: "admin",
|
|
70895
71418
|
role: "admin"
|
|
70896
71419
|
}
|
|
71420
|
+
}, {
|
|
71421
|
+
headers: {
|
|
71422
|
+
"Cache-Control": "no-store",
|
|
71423
|
+
"Set-Cookie": buildSessionCookie(req, token2, SUPER_ADMIN_TOKEN_TTL_SECONDS)
|
|
71424
|
+
}
|
|
70897
71425
|
});
|
|
70898
71426
|
}
|
|
70899
71427
|
if (!username) {
|
|
@@ -70902,14 +71430,6 @@ var login_post_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
70902
71430
|
{ status: 400 }
|
|
70903
71431
|
);
|
|
70904
71432
|
}
|
|
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
71433
|
const user = await agentBuilder.getUserByUsername(username);
|
|
70914
71434
|
if (!user) {
|
|
70915
71435
|
return Response.json(
|
|
@@ -70939,11 +71459,16 @@ var login_post_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
70939
71459
|
username: user.username,
|
|
70940
71460
|
role: user.role
|
|
70941
71461
|
}
|
|
71462
|
+
}, {
|
|
71463
|
+
headers: {
|
|
71464
|
+
"Cache-Control": "no-store",
|
|
71465
|
+
"Set-Cookie": buildSessionCookie(req, token, 30 * 24 * 60 * 60)
|
|
71466
|
+
}
|
|
70942
71467
|
});
|
|
70943
71468
|
} catch (error) {
|
|
70944
71469
|
console.error("Login error:", error);
|
|
70945
71470
|
return Response.json(
|
|
70946
|
-
{ error: error.message
|
|
71471
|
+
{ error: error instanceof Error ? error.message : "Login failed" },
|
|
70947
71472
|
{ status: 500 }
|
|
70948
71473
|
);
|
|
70949
71474
|
}
|
|
@@ -70956,38 +71481,23 @@ async function deleteLocalSession(req, env2) {
|
|
|
70956
71481
|
if (!token) {
|
|
70957
71482
|
return;
|
|
70958
71483
|
}
|
|
70959
|
-
|
|
70960
|
-
|
|
70961
|
-
|
|
71484
|
+
const tokenHash = await hashToken(token);
|
|
71485
|
+
const agentBuilder = env2.AGENT_BUILDER.get(env2.AGENT_BUILDER.idFromName("singleton"));
|
|
71486
|
+
if (token.includes(".")) {
|
|
71487
|
+
await agentBuilder.deleteSuperAdminSession(tokenHash);
|
|
71488
|
+
} else if (isValidUserToken(token)) {
|
|
70962
71489
|
await agentBuilder.deleteSession(tokenHash);
|
|
70963
71490
|
}
|
|
70964
71491
|
}
|
|
70965
71492
|
function clearedSessionCookie(req) {
|
|
70966
71493
|
return buildSessionCookie(req, "", 0);
|
|
70967
71494
|
}
|
|
70968
|
-
|
|
70969
|
-
|
|
70970
|
-
|
|
70971
|
-
|
|
70972
|
-
return
|
|
71495
|
+
function isSameOriginLogout(req) {
|
|
71496
|
+
const origin = req.headers.get("Origin");
|
|
71497
|
+
if (origin && origin !== new URL(req.url).origin) return false;
|
|
71498
|
+
const fetchSite = req.headers.get("Sec-Fetch-Site");
|
|
71499
|
+
return !fetchSite || fetchSite === "same-origin" || fetchSite === "none";
|
|
70973
71500
|
}
|
|
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
71501
|
|
|
70992
71502
|
// src/api/auth/logout.post.ts
|
|
70993
71503
|
var logout_post_default = defineController2(async ({ req, env: env2 }) => {
|
|
@@ -70998,9 +71508,15 @@ var logout_post_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
70998
71508
|
"Set-Cookie": clearedSessionCookie(req)
|
|
70999
71509
|
}
|
|
71000
71510
|
});
|
|
71511
|
+
if (!isSameOriginLogout(req)) {
|
|
71512
|
+
return Response.json({ error: "Cross-origin logout refused" }, { status: 403 });
|
|
71513
|
+
}
|
|
71001
71514
|
try {
|
|
71002
71515
|
await deleteLocalSession(req, env2);
|
|
71003
|
-
|
|
71516
|
+
const url = new URL(req.url);
|
|
71517
|
+
const returnTo = url.searchParams.get("return_to");
|
|
71518
|
+
const redirect = isPlatformHosted(env2) ? platformLogoutUrl(req, env2, returnTo) : void 0;
|
|
71519
|
+
return clearCookie({ success: true, ...redirect ? { redirect } : {} });
|
|
71004
71520
|
} catch (error) {
|
|
71005
71521
|
console.error("Logout error:", error);
|
|
71006
71522
|
return clearCookie({ error: error.message || "Logout failed" }, 500);
|
|
@@ -71103,6 +71619,37 @@ var platform_replica_post_default = defineController2(async ({ req, env: env2 })
|
|
|
71103
71619
|
return Response.json({ ok: true, ...result });
|
|
71104
71620
|
});
|
|
71105
71621
|
|
|
71622
|
+
// src/api/auth/websocket-ticket.post.ts
|
|
71623
|
+
var WEBSOCKET_TICKET_TTL_SECONDS = 30;
|
|
71624
|
+
var websocket_ticket_post_default = defineController2(async ({ req, env: env2 }) => {
|
|
71625
|
+
const auth = await authenticate(req, env2);
|
|
71626
|
+
if (!auth) return Response.json({ error: "Unauthorized" }, { status: 401 });
|
|
71627
|
+
let body;
|
|
71628
|
+
try {
|
|
71629
|
+
body = await req.json();
|
|
71630
|
+
} catch {
|
|
71631
|
+
return Response.json({ error: "A JSON body is required." }, { status: 400 });
|
|
71632
|
+
}
|
|
71633
|
+
const pathname = body && typeof body === "object" ? body.pathname : void 0;
|
|
71634
|
+
if (typeof pathname !== "string" || !isWebSocketTicketPath(pathname)) {
|
|
71635
|
+
return Response.json({ error: "pathname must be a normalized /api/* path." }, { status: 400 });
|
|
71636
|
+
}
|
|
71637
|
+
const ticket = generateSecureToken(32);
|
|
71638
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
71639
|
+
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
71640
|
+
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
71641
|
+
await agentBuilder.createWebSocketTicket({
|
|
71642
|
+
ticket_hash: await hashToken(ticket),
|
|
71643
|
+
pathname,
|
|
71644
|
+
auth_json: JSON.stringify(auth),
|
|
71645
|
+
expires_at: now + WEBSOCKET_TICKET_TTL_SECONDS
|
|
71646
|
+
});
|
|
71647
|
+
return Response.json(
|
|
71648
|
+
{ ticket, expires_in: WEBSOCKET_TICKET_TTL_SECONDS },
|
|
71649
|
+
{ headers: { "Cache-Control": "no-store" } }
|
|
71650
|
+
);
|
|
71651
|
+
});
|
|
71652
|
+
|
|
71106
71653
|
// src/api/envs/_shared.ts
|
|
71107
71654
|
function buildScopedEnvResponse(entries) {
|
|
71108
71655
|
const variables = [...entries].sort((a, b) => a.name.localeCompare(b.name)).map((entry) => ({
|
|
@@ -71579,6 +72126,7 @@ var path_default = defineController2(async ({ req, params, env: env2, url }) =>
|
|
|
71579
72126
|
});
|
|
71580
72127
|
|
|
71581
72128
|
// src/api/platform-auth/bootstrap.post.ts
|
|
72129
|
+
var AGENT_BUILDER_SESSION_TTL_SECONDS = 30 * 24 * 60 * 60;
|
|
71582
72130
|
function uniqueEndpoints(preferred, candidates) {
|
|
71583
72131
|
return Array.from(new Set([preferred, ...candidates].filter((value) => Boolean(value))));
|
|
71584
72132
|
}
|
|
@@ -71593,10 +72141,10 @@ function buildSessionCookieHeader(req, sessionCookie) {
|
|
|
71593
72141
|
return `${sessionCookie}; ${attributes.join("; ")}`;
|
|
71594
72142
|
}
|
|
71595
72143
|
var bootstrap_post_default2 = defineController2(async ({ req, env: env2 }) => {
|
|
71596
|
-
if (!isTrustedLocalDevelopmentRequest(req, env2)) {
|
|
72144
|
+
if (!isTrustedLocalDevelopmentRequest(req, env2) || !isSameOriginBrowserRequest(req)) {
|
|
71597
72145
|
return Response.json(
|
|
71598
|
-
{ error: "Platform auth bridge is
|
|
71599
|
-
{ status:
|
|
72146
|
+
{ error: "Platform auth bridge is restricted to same-origin local development" },
|
|
72147
|
+
{ status: 403 }
|
|
71600
72148
|
);
|
|
71601
72149
|
}
|
|
71602
72150
|
const requestCookie = req.headers.get("Cookie")?.trim() || "";
|
|
@@ -71623,10 +72171,16 @@ var bootstrap_post_default2 = defineController2(async ({ req, env: env2 }) => {
|
|
|
71623
72171
|
account: localSession.platform.account,
|
|
71624
72172
|
authType: localSession.authType,
|
|
71625
72173
|
verified: localSession.platform.verified,
|
|
71626
|
-
token: localSession.token,
|
|
71627
72174
|
localUser: localSession.user
|
|
71628
72175
|
}, {
|
|
71629
|
-
headers: {
|
|
72176
|
+
headers: {
|
|
72177
|
+
"Cache-Control": "no-store",
|
|
72178
|
+
"Set-Cookie": buildSessionCookie(
|
|
72179
|
+
req,
|
|
72180
|
+
localSession.token,
|
|
72181
|
+
AGENT_BUILDER_SESSION_TTL_SECONDS
|
|
72182
|
+
)
|
|
72183
|
+
}
|
|
71630
72184
|
});
|
|
71631
72185
|
}
|
|
71632
72186
|
}
|
|
@@ -73280,12 +73834,11 @@ var tools_get_default2 = defineController2(async ({ params, url }) => {
|
|
|
73280
73834
|
});
|
|
73281
73835
|
|
|
73282
73836
|
// src/api/threads/[id]/bridge.ts
|
|
73283
|
-
var bridge_default = defineController2(async (
|
|
73284
|
-
|
|
73285
|
-
|
|
73286
|
-
|
|
73287
|
-
|
|
73288
|
-
}
|
|
73837
|
+
var bridge_default = defineController2(async (context) => {
|
|
73838
|
+
const { req, params, env: env2 } = context;
|
|
73839
|
+
const authResult = await resolveRequestAuth(context);
|
|
73840
|
+
if (authResult instanceof Response) {
|
|
73841
|
+
return authResult;
|
|
73289
73842
|
}
|
|
73290
73843
|
const threadId = params.id;
|
|
73291
73844
|
if (!threadId) {
|
|
@@ -73298,22 +73851,31 @@ var bridge_default = defineController2(async ({ req, params, env: env2 }) => {
|
|
|
73298
73851
|
);
|
|
73299
73852
|
}
|
|
73300
73853
|
try {
|
|
73301
|
-
|
|
73302
|
-
|
|
73303
|
-
|
|
73304
|
-
|
|
73305
|
-
|
|
73306
|
-
|
|
73307
|
-
|
|
73308
|
-
|
|
73854
|
+
if (!routerAuthorizedThread(context, threadId)) {
|
|
73855
|
+
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
73856
|
+
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
73857
|
+
const thread = await agentBuilder.getThread(threadId);
|
|
73858
|
+
if (!thread) {
|
|
73859
|
+
return Response.json(
|
|
73860
|
+
{ error: `Thread not found: ${threadId}` },
|
|
73861
|
+
{ status: 404 }
|
|
73862
|
+
);
|
|
73863
|
+
}
|
|
73864
|
+
if (!canAccessThread(authResult, thread)) {
|
|
73865
|
+
return Response.json(
|
|
73866
|
+
{ error: "Forbidden: You don't have access to this thread" },
|
|
73867
|
+
{ status: 403 }
|
|
73868
|
+
);
|
|
73869
|
+
}
|
|
73309
73870
|
}
|
|
73310
73871
|
const durableId = env2.AGENT_BUILDER_THREAD.idFromName(threadId);
|
|
73311
73872
|
const stub = env2.AGENT_BUILDER_THREAD.get(durableId);
|
|
73312
73873
|
return await stub.fetch(req);
|
|
73313
73874
|
} catch (error) {
|
|
73875
|
+
const message = error instanceof Error ? error.message : "Failed to establish client bridge";
|
|
73314
73876
|
console.error(`Error establishing bridge for thread ${threadId}:`, error);
|
|
73315
73877
|
return Response.json(
|
|
73316
|
-
{ error:
|
|
73878
|
+
{ error: message },
|
|
73317
73879
|
{ status: 500 }
|
|
73318
73880
|
);
|
|
73319
73881
|
}
|
|
@@ -73538,19 +74100,9 @@ var cost_get_default = defineController2(async ({ req, params, env: env2 }) => {
|
|
|
73538
74100
|
|
|
73539
74101
|
// src/api/threads/[id]/diagnostics.get.ts
|
|
73540
74102
|
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
|
-
}
|
|
74103
|
+
const authResult = await requirePermission(req, env2, "logs");
|
|
74104
|
+
if (authResult instanceof Response) {
|
|
74105
|
+
return authResult;
|
|
73554
74106
|
}
|
|
73555
74107
|
const threadId = params.id;
|
|
73556
74108
|
if (!threadId) {
|
|
@@ -73718,6 +74270,33 @@ var fs_default = defineController2(async ({ req, params, env: env2 }) => {
|
|
|
73718
74270
|
}
|
|
73719
74271
|
});
|
|
73720
74272
|
|
|
74273
|
+
// src/utils/kv-key-policy.ts
|
|
74274
|
+
var THREAD_CLIENT_RESERVED_KEYS = /* @__PURE__ */ new Set([
|
|
74275
|
+
"execution_owner",
|
|
74276
|
+
"approvals",
|
|
74277
|
+
"bg_processes",
|
|
74278
|
+
"lines_capacity_cache"
|
|
74279
|
+
]);
|
|
74280
|
+
var THREAD_CLIENT_RESERVED_PREFIXES = [
|
|
74281
|
+
"approval_"
|
|
74282
|
+
];
|
|
74283
|
+
var USER_CLIENT_RESERVED_KEYS = /* @__PURE__ */ new Set([
|
|
74284
|
+
"standardcode.lines.leases",
|
|
74285
|
+
"standardcode.lines.capacity_cache"
|
|
74286
|
+
]);
|
|
74287
|
+
function isThreadKvKeyClientWritable(key) {
|
|
74288
|
+
return !THREAD_CLIENT_RESERVED_KEYS.has(key) && !THREAD_CLIENT_RESERVED_PREFIXES.some((prefix) => key.startsWith(prefix));
|
|
74289
|
+
}
|
|
74290
|
+
function isUserKvKeyClientWritable(key) {
|
|
74291
|
+
return !USER_CLIENT_RESERVED_KEYS.has(key);
|
|
74292
|
+
}
|
|
74293
|
+
function reservedKvKeyResponse() {
|
|
74294
|
+
return Response.json(
|
|
74295
|
+
{ error: "Key is reserved for server-managed state" },
|
|
74296
|
+
{ status: 403 }
|
|
74297
|
+
);
|
|
74298
|
+
}
|
|
74299
|
+
|
|
73721
74300
|
// src/api/threads/[id]/kv/index.ts
|
|
73722
74301
|
async function getAuthorizedThreadStub2(context, threadId) {
|
|
73723
74302
|
const { env: env2 } = context;
|
|
@@ -73811,11 +74390,14 @@ async function handlePost(stub, req) {
|
|
|
73811
74390
|
if (body instanceof Response) return body;
|
|
73812
74391
|
const key = readKey(body.key);
|
|
73813
74392
|
if (key instanceof Response) return key;
|
|
74393
|
+
const previousKey = typeof body.previousKey === "string" && body.previousKey !== key ? body.previousKey : null;
|
|
74394
|
+
if (!isThreadKvKeyClientWritable(key) || previousKey?.trim() && !isThreadKvKeyClientWritable(previousKey)) {
|
|
74395
|
+
return reservedKvKeyResponse();
|
|
74396
|
+
}
|
|
73814
74397
|
if (!Object.prototype.hasOwnProperty.call(body, "value")) {
|
|
73815
74398
|
return Response.json({ error: "Value is required" }, { status: 400 });
|
|
73816
74399
|
}
|
|
73817
74400
|
await stub.setValue(key, body.value);
|
|
73818
|
-
const previousKey = typeof body.previousKey === "string" && body.previousKey !== key ? body.previousKey : null;
|
|
73819
74401
|
if (previousKey?.trim()) {
|
|
73820
74402
|
await stub.setValue(previousKey, null);
|
|
73821
74403
|
}
|
|
@@ -73841,6 +74423,7 @@ async function handleDelete(stub, req, url) {
|
|
|
73841
74423
|
}
|
|
73842
74424
|
const key = readKey(keyValue);
|
|
73843
74425
|
if (key instanceof Response) return key;
|
|
74426
|
+
if (!isThreadKvKeyClientWritable(key)) return reservedKvKeyResponse();
|
|
73844
74427
|
await stub.setValue(key, null);
|
|
73845
74428
|
return new Response(null, { status: 204 });
|
|
73846
74429
|
}
|
|
@@ -73878,19 +74461,9 @@ var kv_default = defineController2(async (context) => {
|
|
|
73878
74461
|
// src/api/threads/[id]/logs.get.ts
|
|
73879
74462
|
var logs_get_default = defineController2(async (context) => {
|
|
73880
74463
|
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
|
-
}
|
|
74464
|
+
const authResult = await resolveRequestPermission(context, "logs");
|
|
74465
|
+
if (authResult instanceof Response) {
|
|
74466
|
+
return authResult;
|
|
73894
74467
|
}
|
|
73895
74468
|
const url = new URL(req.url);
|
|
73896
74469
|
const threadId = params.id;
|
|
@@ -74123,19 +74696,9 @@ var pending_tool_calls_get_default = defineController2(async ({ params, env: env
|
|
|
74123
74696
|
|
|
74124
74697
|
// src/api/threads/[id]/revive.post.ts
|
|
74125
74698
|
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
|
-
}
|
|
74699
|
+
const authResult = await requirePermission(req, env2, "logs");
|
|
74700
|
+
if (authResult instanceof Response) {
|
|
74701
|
+
return authResult;
|
|
74139
74702
|
}
|
|
74140
74703
|
const threadId = params.id;
|
|
74141
74704
|
if (!threadId) {
|
|
@@ -74169,20 +74732,15 @@ var revive_post_default = defineController2(async ({ req, params, env: env2 }) =
|
|
|
74169
74732
|
});
|
|
74170
74733
|
|
|
74171
74734
|
// src/api/threads/[id]/rpc.post.ts
|
|
74735
|
+
function unsafeLocalRpcEnabled(env2) {
|
|
74736
|
+
const value = Reflect.get(env2, "AGENT_BUILDER_ENABLE_UNSAFE_RPC");
|
|
74737
|
+
if (typeof value !== "string") return value === true;
|
|
74738
|
+
const normalized = value.trim().toLowerCase();
|
|
74739
|
+
return normalized === "1" || normalized === "true";
|
|
74740
|
+
}
|
|
74172
74741
|
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
|
-
}
|
|
74742
|
+
if (!isTrustedLocalDevelopmentRequest(req, env2) || !unsafeLocalRpcEnabled(env2)) {
|
|
74743
|
+
return Response.json({ error: "Not found" }, { status: 404 });
|
|
74186
74744
|
}
|
|
74187
74745
|
const threadId = params.id;
|
|
74188
74746
|
if (!threadId) {
|
|
@@ -74196,7 +74754,11 @@ var rpc_post_default = defineController2(async ({ req, params, env: env2 }) => {
|
|
|
74196
74754
|
try {
|
|
74197
74755
|
const id = env2.AGENT_BUILDER_THREAD.idFromName(threadId);
|
|
74198
74756
|
const thread = env2.AGENT_BUILDER_THREAD.get(id);
|
|
74199
|
-
const
|
|
74757
|
+
const rpcMethod = Reflect.get(thread, method);
|
|
74758
|
+
if (typeof rpcMethod !== "function") {
|
|
74759
|
+
return Response.json({ error: "Method not found" }, { status: 404 });
|
|
74760
|
+
}
|
|
74761
|
+
const result = await Reflect.apply(rpcMethod, thread, args);
|
|
74200
74762
|
if (result instanceof Response) {
|
|
74201
74763
|
return result;
|
|
74202
74764
|
}
|
|
@@ -74239,12 +74801,11 @@ var stop_post_default = defineController2(async ({ params, env: env2 }) => {
|
|
|
74239
74801
|
});
|
|
74240
74802
|
|
|
74241
74803
|
// src/api/threads/[id]/stream.ts
|
|
74242
|
-
var stream_default = defineController2(async (
|
|
74243
|
-
|
|
74244
|
-
|
|
74245
|
-
|
|
74246
|
-
|
|
74247
|
-
}
|
|
74804
|
+
var stream_default = defineController2(async (context) => {
|
|
74805
|
+
const { req, params, env: env2 } = context;
|
|
74806
|
+
const authResult = await resolveRequestAuth(context);
|
|
74807
|
+
if (authResult instanceof Response) {
|
|
74808
|
+
return authResult;
|
|
74248
74809
|
}
|
|
74249
74810
|
const threadId = params.id;
|
|
74250
74811
|
if (!threadId) {
|
|
@@ -74257,22 +74818,31 @@ var stream_default = defineController2(async ({ req, params, env: env2 }) => {
|
|
|
74257
74818
|
);
|
|
74258
74819
|
}
|
|
74259
74820
|
try {
|
|
74260
|
-
|
|
74261
|
-
|
|
74262
|
-
|
|
74263
|
-
|
|
74264
|
-
|
|
74265
|
-
|
|
74266
|
-
|
|
74267
|
-
|
|
74821
|
+
if (!routerAuthorizedThread(context, threadId)) {
|
|
74822
|
+
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
74823
|
+
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
74824
|
+
const thread = await agentBuilder.getThread(threadId);
|
|
74825
|
+
if (!thread) {
|
|
74826
|
+
return Response.json(
|
|
74827
|
+
{ error: `Thread not found: ${threadId}` },
|
|
74828
|
+
{ status: 404 }
|
|
74829
|
+
);
|
|
74830
|
+
}
|
|
74831
|
+
if (!canAccessThread(authResult, thread)) {
|
|
74832
|
+
return Response.json(
|
|
74833
|
+
{ error: "Forbidden: You don't have access to this thread" },
|
|
74834
|
+
{ status: 403 }
|
|
74835
|
+
);
|
|
74836
|
+
}
|
|
74268
74837
|
}
|
|
74269
74838
|
const durableId = env2.AGENT_BUILDER_THREAD.idFromName(threadId);
|
|
74270
74839
|
const stub = env2.AGENT_BUILDER_THREAD.get(durableId);
|
|
74271
74840
|
return await stub.fetch(req);
|
|
74272
74841
|
} catch (error) {
|
|
74842
|
+
const message = error instanceof Error ? error.message : "Failed to establish message stream";
|
|
74273
74843
|
console.error(`Error handling message stream for thread ${threadId}:`, error);
|
|
74274
74844
|
return Response.json(
|
|
74275
|
-
{ error:
|
|
74845
|
+
{ error: message },
|
|
74276
74846
|
{ status: 500 }
|
|
74277
74847
|
);
|
|
74278
74848
|
}
|
|
@@ -74321,6 +74891,9 @@ var tool_result_post_default = defineController2(async ({ req, params, env: env2
|
|
|
74321
74891
|
if (!toolCallId || typeof toolCallId !== "string") {
|
|
74322
74892
|
return Response.json({ error: "tool_call_id required" }, { status: 400 });
|
|
74323
74893
|
}
|
|
74894
|
+
if (!body.delivery_token || typeof body.delivery_token !== "string") {
|
|
74895
|
+
return Response.json({ error: "delivery_token required" }, { status: 400 });
|
|
74896
|
+
}
|
|
74324
74897
|
try {
|
|
74325
74898
|
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
74326
74899
|
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
@@ -74336,7 +74909,8 @@ var tool_result_post_default = defineController2(async ({ req, params, env: env2
|
|
|
74336
74909
|
typeof body.result === "string" ? body.result : void 0,
|
|
74337
74910
|
typeof body.error === "string" ? body.error : void 0,
|
|
74338
74911
|
typeof body.client_id === "string" ? body.client_id : void 0,
|
|
74339
|
-
typeof body.generation === "number" ? body.generation : void 0
|
|
74912
|
+
typeof body.generation === "number" ? body.generation : void 0,
|
|
74913
|
+
body.delivery_token
|
|
74340
74914
|
);
|
|
74341
74915
|
if (!delivered) {
|
|
74342
74916
|
return Response.json({ status: "ignored" }, { status: 200 });
|
|
@@ -74504,8 +75078,9 @@ var env_patch_default = defineController2(async ({ req, env: env2, params }) =>
|
|
|
74504
75078
|
});
|
|
74505
75079
|
|
|
74506
75080
|
// src/api/users/[id]/stream.ts
|
|
74507
|
-
var stream_default2 = defineController2(async (
|
|
74508
|
-
const
|
|
75081
|
+
var stream_default2 = defineController2(async (context) => {
|
|
75082
|
+
const { req, env: env2, params } = context;
|
|
75083
|
+
const authResult = await resolveRequestAuth(context);
|
|
74509
75084
|
if (authResult instanceof Response) return authResult;
|
|
74510
75085
|
const isAdmin = authResult.authType === "super_admin" || authResult.user?.role === "admin";
|
|
74511
75086
|
if (!isAdmin) {
|
|
@@ -74647,11 +75222,23 @@ var name_get_default8 = defineController2(async ({ params, url, prompts, agents,
|
|
|
74647
75222
|
});
|
|
74648
75223
|
|
|
74649
75224
|
// src/api/auth/device/start.post.ts
|
|
75225
|
+
var DEVICE_ADDRESS_LIMIT = { limit: 20, window_seconds: 10 * 60 };
|
|
75226
|
+
var DEVICE_INSTANCE_LIMIT = { limit: 300, window_seconds: 10 * 60 };
|
|
74650
75227
|
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
75228
|
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
74654
75229
|
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
75230
|
+
const addressLimit = await agentBuilder.consumeAuthRateLimit({
|
|
75231
|
+
key: await authRateLimitKey("device-start-address", authClientAddress(req)),
|
|
75232
|
+
...DEVICE_ADDRESS_LIMIT
|
|
75233
|
+
});
|
|
75234
|
+
if (!addressLimit.allowed) return authRateLimitedResponse(addressLimit);
|
|
75235
|
+
const instanceLimit = await agentBuilder.consumeAuthRateLimit({
|
|
75236
|
+
key: "device-start-instance",
|
|
75237
|
+
...DEVICE_INSTANCE_LIMIT
|
|
75238
|
+
});
|
|
75239
|
+
if (!instanceLimit.allowed) return authRateLimitedResponse(instanceLimit);
|
|
75240
|
+
const bytes = crypto.getRandomValues(new Uint8Array(24));
|
|
75241
|
+
const code = [...bytes].map((b) => "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789"[b % 57]).join("");
|
|
74655
75242
|
await agentBuilder.startDeviceLogin(await hashToken(code));
|
|
74656
75243
|
const origin = new URL(req.url).origin;
|
|
74657
75244
|
const verifyBaseRaw = env2.STANDARD_AGENTS_DEVICE_VERIFY_URL_BASE;
|
|
@@ -74665,8 +75252,74 @@ var start_post_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
74665
75252
|
});
|
|
74666
75253
|
});
|
|
74667
75254
|
|
|
75255
|
+
// src/api/auth/sa/_login-state.ts
|
|
75256
|
+
var LOGIN_STATE_COOKIE = "agtbldr_sa_login_state";
|
|
75257
|
+
var LOGIN_STATE_PARAM = "__sa_login_state";
|
|
75258
|
+
var LOGIN_STATE_TTL_SECONDS = 10 * 60;
|
|
75259
|
+
function safeReturnTo(value) {
|
|
75260
|
+
if (!value || !value.startsWith("/") || value.startsWith("//")) return "/";
|
|
75261
|
+
return value;
|
|
75262
|
+
}
|
|
75263
|
+
function stateCookie(req, value, maxAge) {
|
|
75264
|
+
const attributes = ["Path=/api/auth/sa", "HttpOnly", "SameSite=Lax"];
|
|
75265
|
+
if (new URL(req.url).protocol === "https:") attributes.push("Secure");
|
|
75266
|
+
return `${LOGIN_STATE_COOKIE}=${encodeURIComponent(value)}; ${attributes.join("; ")}; Max-Age=${maxAge}`;
|
|
75267
|
+
}
|
|
75268
|
+
function readStateCookie(req) {
|
|
75269
|
+
const raw = req.headers.get("Cookie");
|
|
75270
|
+
if (!raw) return null;
|
|
75271
|
+
for (const part of raw.split(";")) {
|
|
75272
|
+
const separator = part.indexOf("=");
|
|
75273
|
+
if (separator < 0 || part.slice(0, separator).trim() !== LOGIN_STATE_COOKIE) continue;
|
|
75274
|
+
try {
|
|
75275
|
+
return decodeURIComponent(part.slice(separator + 1).trim()) || null;
|
|
75276
|
+
} catch {
|
|
75277
|
+
return null;
|
|
75278
|
+
}
|
|
75279
|
+
}
|
|
75280
|
+
return null;
|
|
75281
|
+
}
|
|
75282
|
+
function statefulReturnTo(returnTo, state) {
|
|
75283
|
+
const target = new URL(safeReturnTo(returnTo), "https://instance.invalid");
|
|
75284
|
+
target.searchParams.set(LOGIN_STATE_PARAM, state);
|
|
75285
|
+
return `${target.pathname}${target.search}${target.hash}`;
|
|
75286
|
+
}
|
|
75287
|
+
function beginPlatformLogin(req, env2, returnTo, error) {
|
|
75288
|
+
const state = crypto.randomUUID();
|
|
75289
|
+
const location = new URL(platformLoginUrl(req, env2, statefulReturnTo(returnTo, state)));
|
|
75290
|
+
if (error) location.searchParams.set("error", error);
|
|
75291
|
+
return new Response(null, {
|
|
75292
|
+
status: 302,
|
|
75293
|
+
headers: {
|
|
75294
|
+
Location: location.toString(),
|
|
75295
|
+
"Set-Cookie": stateCookie(req, state, LOGIN_STATE_TTL_SECONDS),
|
|
75296
|
+
"Cache-Control": "no-store"
|
|
75297
|
+
}
|
|
75298
|
+
});
|
|
75299
|
+
}
|
|
75300
|
+
function consumePlatformLoginState(req, rawReturnTo) {
|
|
75301
|
+
const target = new URL(safeReturnTo(rawReturnTo), "https://instance.invalid");
|
|
75302
|
+
const state = target.searchParams.get(LOGIN_STATE_PARAM);
|
|
75303
|
+
target.searchParams.delete(LOGIN_STATE_PARAM);
|
|
75304
|
+
const returnTo = `${target.pathname}${target.search}${target.hash}`;
|
|
75305
|
+
return {
|
|
75306
|
+
returnTo,
|
|
75307
|
+
valid: Boolean(state && state === readStateCookie(req)),
|
|
75308
|
+
present: Boolean(state)
|
|
75309
|
+
};
|
|
75310
|
+
}
|
|
75311
|
+
function withClearedPlatformLoginState(req, response) {
|
|
75312
|
+
const headers = new Headers(response.headers);
|
|
75313
|
+
headers.append("Set-Cookie", stateCookie(req, "", 0));
|
|
75314
|
+
return new Response(response.body, {
|
|
75315
|
+
status: response.status,
|
|
75316
|
+
statusText: response.statusText,
|
|
75317
|
+
headers
|
|
75318
|
+
});
|
|
75319
|
+
}
|
|
75320
|
+
|
|
74668
75321
|
// src/api/auth/sa/callback.get.ts
|
|
74669
|
-
var
|
|
75322
|
+
var SESSION_TTL_SECONDS3 = 30 * 24 * 60 * 60;
|
|
74670
75323
|
function safeReturnTo2(value) {
|
|
74671
75324
|
if (!value || !value.startsWith("/") || value.startsWith("//")) return "/";
|
|
74672
75325
|
return value;
|
|
@@ -74674,15 +75327,12 @@ function safeReturnTo2(value) {
|
|
|
74674
75327
|
function failRedirect(req, env2, reason, returnTo) {
|
|
74675
75328
|
const origin = new URL(req.url).origin;
|
|
74676
75329
|
if (isPlatformHosted(env2)) {
|
|
74677
|
-
|
|
74678
|
-
|
|
74679
|
-
|
|
75330
|
+
return beginPlatformLogin(
|
|
75331
|
+
req,
|
|
75332
|
+
env2,
|
|
75333
|
+
returnTo ?? "/",
|
|
74680
75334
|
reason === "api_only_account" ? "api_only_account" : "instance_login_failed"
|
|
74681
75335
|
);
|
|
74682
|
-
return new Response(null, {
|
|
74683
|
-
status: 302,
|
|
74684
|
-
headers: { Location: target.toString() }
|
|
74685
|
-
});
|
|
74686
75336
|
}
|
|
74687
75337
|
return new Response(null, {
|
|
74688
75338
|
status: 302,
|
|
@@ -74694,7 +75344,9 @@ var callback_get_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
74694
75344
|
return failRedirect(req, env2, "not_hosted");
|
|
74695
75345
|
}
|
|
74696
75346
|
const url = new URL(req.url);
|
|
74697
|
-
const
|
|
75347
|
+
const loginState = consumePlatformLoginState(req, url.searchParams.get("return_to"));
|
|
75348
|
+
const finishLoginState = (response) => loginState.present ? withClearedPlatformLoginState(req, response) : response;
|
|
75349
|
+
const failReturnTo = safeReturnTo2(loginState.returnTo);
|
|
74698
75350
|
const handoff = url.searchParams.get("handoff") || url.searchParams.get("token");
|
|
74699
75351
|
if (!handoff) {
|
|
74700
75352
|
return failRedirect(req, env2, "invalid_response", failReturnTo);
|
|
@@ -74708,29 +75360,37 @@ var callback_get_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
74708
75360
|
projectId: configuredProjectId
|
|
74709
75361
|
}
|
|
74710
75362
|
);
|
|
74711
|
-
if (!payload || !payload.platform_user_id || !payload.role) {
|
|
75363
|
+
if (!payload || !payload.platform_user_id || !payload.role || !payload.jti) {
|
|
74712
75364
|
return failRedirect(req, env2, "invalid_handoff", failReturnTo);
|
|
74713
75365
|
}
|
|
74714
75366
|
if (!configuredProjectId && payload.project_id !== hostedInstanceRedirectId(req, env2)) {
|
|
74715
75367
|
return failRedirect(req, env2, "invalid_handoff", failReturnTo);
|
|
74716
75368
|
}
|
|
74717
75369
|
if (payload.role === "api") {
|
|
74718
|
-
const apiReturnTo =
|
|
75370
|
+
const apiReturnTo = failReturnTo;
|
|
74719
75371
|
if (/^\/api\/auth\/device\/[A-Za-z0-9]{8,64}\/approve$/.test(apiReturnTo)) {
|
|
74720
|
-
return new Response(null, {
|
|
75372
|
+
return finishLoginState(new Response(null, {
|
|
74721
75373
|
status: 302,
|
|
74722
75374
|
headers: {
|
|
74723
75375
|
Location: `${url.origin}${apiReturnTo}?handoff=${encodeURIComponent(handoff)}`
|
|
74724
75376
|
}
|
|
74725
|
-
});
|
|
75377
|
+
}));
|
|
74726
75378
|
}
|
|
74727
75379
|
const landingRaw = env2.STANDARD_AGENTS_API_ROLE_LANDING_URL;
|
|
74728
75380
|
const landing = typeof landingRaw === "string" ? landingRaw.trim() : "";
|
|
74729
75381
|
if (landing && /^https:\/\//.test(landing)) {
|
|
74730
|
-
return
|
|
75382
|
+
return finishLoginState(
|
|
75383
|
+
new Response(null, { status: 302, headers: { Location: landing } })
|
|
75384
|
+
);
|
|
74731
75385
|
}
|
|
74732
75386
|
return failRedirect(req, env2, "api_only_account");
|
|
74733
75387
|
}
|
|
75388
|
+
if (!loginState.valid) {
|
|
75389
|
+
return beginPlatformLogin(req, env2, failReturnTo);
|
|
75390
|
+
}
|
|
75391
|
+
if (!await consumePlatformHandoffJti(env2, payload.jti, payload.exp)) {
|
|
75392
|
+
return failRedirect(req, env2, "invalid_handoff", failReturnTo);
|
|
75393
|
+
}
|
|
74734
75394
|
const session = await mintLocalSessionForPlatformUser(env2, {
|
|
74735
75395
|
platform_user_id: payload.platform_user_id,
|
|
74736
75396
|
username: payload.username ?? null,
|
|
@@ -74740,14 +75400,15 @@ var callback_get_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
74740
75400
|
role: payload.role,
|
|
74741
75401
|
permissions: payload.permissions ?? null
|
|
74742
75402
|
});
|
|
74743
|
-
const returnTo =
|
|
74744
|
-
|
|
74745
|
-
|
|
74746
|
-
headers: {
|
|
74747
|
-
Location: `${url.origin}${returnTo}`,
|
|
74748
|
-
"Set-Cookie": buildSessionCookie(req, session.token, SESSION_TTL_SECONDS2)
|
|
74749
|
-
}
|
|
75403
|
+
const returnTo = failReturnTo;
|
|
75404
|
+
const headers = new Headers({
|
|
75405
|
+
Location: `${url.origin}${returnTo}`
|
|
74750
75406
|
});
|
|
75407
|
+
headers.append("Set-Cookie", buildSessionCookie(req, session.token, SESSION_TTL_SECONDS3));
|
|
75408
|
+
return withClearedPlatformLoginState(req, new Response(null, {
|
|
75409
|
+
status: 302,
|
|
75410
|
+
headers
|
|
75411
|
+
}));
|
|
74751
75412
|
});
|
|
74752
75413
|
|
|
74753
75414
|
// src/api/auth/sa/start.get.ts
|
|
@@ -74757,12 +75418,7 @@ var start_get_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
74757
75418
|
}
|
|
74758
75419
|
const url = new URL(req.url);
|
|
74759
75420
|
const returnTo = url.searchParams.get("return_to") || "/";
|
|
74760
|
-
return
|
|
74761
|
-
status: 302,
|
|
74762
|
-
headers: {
|
|
74763
|
-
Location: platformLoginUrl(req, env2, returnTo)
|
|
74764
|
-
}
|
|
74765
|
-
});
|
|
75421
|
+
return beginPlatformLogin(req, env2, returnTo);
|
|
74766
75422
|
});
|
|
74767
75423
|
|
|
74768
75424
|
// src/api/users/me/[...rest].ts
|
|
@@ -74852,8 +75508,9 @@ var env_patch_default2 = defineController2(async ({ req, env: env2 }) => {
|
|
|
74852
75508
|
});
|
|
74853
75509
|
|
|
74854
75510
|
// src/api/users/me/hub.ts
|
|
74855
|
-
var hub_default = defineController2(async (
|
|
74856
|
-
const
|
|
75511
|
+
var hub_default = defineController2(async (context) => {
|
|
75512
|
+
const { req, env: env2 } = context;
|
|
75513
|
+
const authResult = await resolveRequestAuth(context);
|
|
74857
75514
|
if (authResult instanceof Response) {
|
|
74858
75515
|
return authResult;
|
|
74859
75516
|
}
|
|
@@ -74881,9 +75538,10 @@ var hub_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
74881
75538
|
const stub = namespace.get(hubId);
|
|
74882
75539
|
return await stub.fetch(req);
|
|
74883
75540
|
} catch (error) {
|
|
75541
|
+
const message = error instanceof Error ? error.message : "Failed to establish hub connection";
|
|
74884
75542
|
console.error("Error establishing user hub socket:", error);
|
|
74885
75543
|
return Response.json(
|
|
74886
|
-
{ error:
|
|
75544
|
+
{ error: message },
|
|
74887
75545
|
{ status: 500 }
|
|
74888
75546
|
);
|
|
74889
75547
|
}
|
|
@@ -74907,6 +75565,7 @@ var index_delete_default = defineController2(async ({ req, env: env2 }) => {
|
|
|
74907
75565
|
if (!key) {
|
|
74908
75566
|
return Response.json({ error: "key query parameter required" }, { status: 400 });
|
|
74909
75567
|
}
|
|
75568
|
+
if (!isUserKvKeyClientWritable(key)) return reservedKvKeyResponse();
|
|
74910
75569
|
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
74911
75570
|
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
74912
75571
|
if (typeof agentBuilder.setUserValue !== "function") {
|
|
@@ -74977,7 +75636,7 @@ var index_get_default4 = defineController2(async ({ req, env: env2 }) => {
|
|
|
74977
75636
|
});
|
|
74978
75637
|
|
|
74979
75638
|
// src/api/users/me/kv/index.post.ts
|
|
74980
|
-
var
|
|
75639
|
+
var index_post_default7 = defineController2(async ({ req, env: env2 }) => {
|
|
74981
75640
|
try {
|
|
74982
75641
|
const authResult = await requireAuth(req, env2);
|
|
74983
75642
|
if (authResult instanceof Response) {
|
|
@@ -75003,6 +75662,7 @@ var index_post_default8 = defineController2(async ({ req, env: env2 }) => {
|
|
|
75003
75662
|
if (typeof key !== "string" || key.length === 0) {
|
|
75004
75663
|
return Response.json({ error: "key required" }, { status: 400 });
|
|
75005
75664
|
}
|
|
75665
|
+
if (!isUserKvKeyClientWritable(key)) return reservedKvKeyResponse();
|
|
75006
75666
|
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
75007
75667
|
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
75008
75668
|
if (typeof agentBuilder.setUserValue !== "function") {
|
|
@@ -75023,8 +75683,9 @@ var index_post_default8 = defineController2(async ({ req, env: env2 }) => {
|
|
|
75023
75683
|
});
|
|
75024
75684
|
|
|
75025
75685
|
// src/api/users/me/stream.ts
|
|
75026
|
-
var stream_default3 = defineController2(async (
|
|
75027
|
-
const
|
|
75686
|
+
var stream_default3 = defineController2(async (context) => {
|
|
75687
|
+
const { req, env: env2 } = context;
|
|
75688
|
+
const authResult = await resolveRequestAuth(context);
|
|
75028
75689
|
if (authResult instanceof Response) return authResult;
|
|
75029
75690
|
if (authResult.authType === "super_admin") {
|
|
75030
75691
|
return Response.json(
|
|
@@ -75041,13 +75702,39 @@ var stream_default3 = defineController2(async ({ req, env: env2 }) => {
|
|
|
75041
75702
|
return forwardToUserScope(req, env2, authResult.user.id, "stream");
|
|
75042
75703
|
});
|
|
75043
75704
|
|
|
75044
|
-
// src/api/auth/device/[code]/
|
|
75705
|
+
// src/api/auth/device/[code]/_approval.ts
|
|
75706
|
+
var CONFIRMATION_TTL_SECONDS = 5 * 60;
|
|
75707
|
+
function escapeHtml(value) {
|
|
75708
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
75709
|
+
}
|
|
75045
75710
|
function page(title, body, ok) {
|
|
75046
75711
|
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
|
-
{
|
|
75712
|
+
`<!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>`,
|
|
75713
|
+
{
|
|
75714
|
+
headers: {
|
|
75715
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
75716
|
+
"Cache-Control": "no-store",
|
|
75717
|
+
"Referrer-Policy": "no-referrer",
|
|
75718
|
+
"X-Content-Type-Options": "nosniff"
|
|
75719
|
+
}
|
|
75720
|
+
}
|
|
75049
75721
|
);
|
|
75050
75722
|
}
|
|
75723
|
+
function confirmationPage(req, code, confirmationToken, handoff) {
|
|
75724
|
+
const url = new URL(req.url);
|
|
75725
|
+
const handoffInput = handoff ? `<input type="hidden" name="handoff" value="${escapeHtml(handoff)}">` : "";
|
|
75726
|
+
const shortCode = code.length > 12 ? `${code.slice(0, 6)}\u2026${code.slice(-6)}` : code;
|
|
75727
|
+
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>`;
|
|
75728
|
+
return new Response(html, {
|
|
75729
|
+
headers: {
|
|
75730
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
75731
|
+
"Cache-Control": "no-store",
|
|
75732
|
+
"Referrer-Policy": "no-referrer",
|
|
75733
|
+
"X-Content-Type-Options": "nosniff",
|
|
75734
|
+
"Content-Security-Policy": "default-src 'none'; style-src 'unsafe-inline'; form-action 'self'; base-uri 'none'; frame-ancestors 'none'"
|
|
75735
|
+
}
|
|
75736
|
+
});
|
|
75737
|
+
}
|
|
75051
75738
|
function outcome(env2, ok, reason, fallback) {
|
|
75052
75739
|
const baseRaw = env2.STANDARD_AGENTS_DEVICE_OUTCOME_URL_BASE;
|
|
75053
75740
|
const base = typeof baseRaw === "string" ? baseRaw.trim().replace(/\/+$/, "") : "";
|
|
@@ -75057,12 +75744,9 @@ function outcome(env2, ok, reason, fallback) {
|
|
|
75057
75744
|
}
|
|
75058
75745
|
return page(fallback.title, fallback.body, ok);
|
|
75059
75746
|
}
|
|
75060
|
-
|
|
75061
|
-
const code = params.code;
|
|
75062
|
-
if (!code) return outcome(env2, false, "invalid_link", { title: "Missing code", body: "This device link is malformed." });
|
|
75747
|
+
async function resolveDeviceApprovalIdentity(req, env2) {
|
|
75063
75748
|
const url = new URL(req.url);
|
|
75064
|
-
|
|
75065
|
-
const handoff = url.searchParams.get("handoff");
|
|
75749
|
+
const handoff = url.searchParams.get("handoff") ?? (req.method === "POST" ? (await req.clone().formData().catch(() => null))?.get("handoff")?.toString() ?? null : null);
|
|
75066
75750
|
if (handoff && isPlatformHosted(env2)) {
|
|
75067
75751
|
const configuredProjectId = typeof env2.STANDARD_AGENTS_PROJECT_ID === "string" ? env2.STANDARD_AGENTS_PROJECT_ID : void 0;
|
|
75068
75752
|
const payload = await verifyPlatformSignedPayload(
|
|
@@ -75071,10 +75755,13 @@ var approve_get_default = defineController2(async ({ req, env: env2, params }) =
|
|
|
75071
75755
|
{ kind: "instance_handoff", projectId: configuredProjectId }
|
|
75072
75756
|
);
|
|
75073
75757
|
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", {
|
|
75758
|
+
if (!payload || !payload.platform_user_id || !payload.role || !payload.jti || !projectOk) {
|
|
75759
|
+
return outcome(env2, false, "signin_failed", {
|
|
75760
|
+
title: "Sign in failed",
|
|
75761
|
+
body: "This sign-in link is invalid or has expired. Start again from your terminal."
|
|
75762
|
+
});
|
|
75076
75763
|
}
|
|
75077
|
-
const
|
|
75764
|
+
const platformProfile = {
|
|
75078
75765
|
platform_user_id: payload.platform_user_id,
|
|
75079
75766
|
username: payload.username ?? null,
|
|
75080
75767
|
display_name: payload.display_name ?? null,
|
|
@@ -75082,27 +75769,163 @@ var approve_get_default = defineController2(async ({ req, env: env2, params }) =
|
|
|
75082
75769
|
avatar_url: payload.avatar_url ?? null,
|
|
75083
75770
|
role: payload.role,
|
|
75084
75771
|
permissions: payload.permissions ?? null
|
|
75085
|
-
}
|
|
75086
|
-
|
|
75087
|
-
|
|
75088
|
-
|
|
75089
|
-
|
|
75090
|
-
|
|
75091
|
-
|
|
75092
|
-
|
|
75093
|
-
|
|
75094
|
-
}
|
|
75095
|
-
|
|
75096
|
-
|
|
75772
|
+
};
|
|
75773
|
+
return {
|
|
75774
|
+
confirmationSubject: `platform:${payload.platform_user_id}`,
|
|
75775
|
+
handoff,
|
|
75776
|
+
platformProfile,
|
|
75777
|
+
platformHandoff: {
|
|
75778
|
+
jti: payload.jti,
|
|
75779
|
+
expires_at: payload.exp
|
|
75780
|
+
}
|
|
75781
|
+
};
|
|
75782
|
+
}
|
|
75783
|
+
const authResult = await requireAuth(req, env2);
|
|
75784
|
+
if (authResult instanceof Response) {
|
|
75785
|
+
if (req.method !== "GET") {
|
|
75786
|
+
return outcome(env2, false, "session_required", {
|
|
75787
|
+
title: "Sign in required",
|
|
75788
|
+
body: "Return to the device link and sign in again before approving."
|
|
75789
|
+
});
|
|
75097
75790
|
}
|
|
75098
|
-
|
|
75791
|
+
const returnTo = encodeURIComponent(url.pathname);
|
|
75792
|
+
const hosted = Boolean(
|
|
75793
|
+
env2.STANDARD_AGENTS_HOSTED && String(env2.STANDARD_AGENTS_HOSTED) !== "0" && String(env2.STANDARD_AGENTS_HOSTED).toLowerCase() !== "false"
|
|
75794
|
+
);
|
|
75795
|
+
const target = hosted ? `/api/auth/sa/start?return_to=${returnTo}` : `/login?return_to=${returnTo}`;
|
|
75796
|
+
return new Response(null, { status: 302, headers: { Location: `${url.origin}${target}` } });
|
|
75797
|
+
}
|
|
75798
|
+
if (authResult.authType === "api_key") {
|
|
75799
|
+
return outcome(env2, false, "session_required", {
|
|
75800
|
+
title: "Sign in required",
|
|
75801
|
+
body: "Device logins must be approved from a signed-in browser session."
|
|
75802
|
+
});
|
|
75803
|
+
}
|
|
75804
|
+
return {
|
|
75805
|
+
confirmationSubject: `user:${authResult.user.id}`,
|
|
75806
|
+
handoff: null,
|
|
75807
|
+
localUserId: authResult.user.id
|
|
75808
|
+
};
|
|
75809
|
+
}
|
|
75810
|
+
async function consumeDeviceApprovalHandoff(env2, identity) {
|
|
75811
|
+
if (!identity.platformHandoff) return true;
|
|
75812
|
+
return consumePlatformHandoffJti(
|
|
75813
|
+
env2,
|
|
75814
|
+
identity.platformHandoff.jti,
|
|
75815
|
+
identity.platformHandoff.expires_at
|
|
75816
|
+
);
|
|
75817
|
+
}
|
|
75818
|
+
async function materializeDeviceApprovalUser(env2, identity) {
|
|
75819
|
+
if (identity.localUserId) return identity.localUserId;
|
|
75820
|
+
if (!identity.platformProfile) {
|
|
75821
|
+
throw new Error("Device approval identity is missing a local user and platform profile");
|
|
75822
|
+
}
|
|
75823
|
+
const user = await upsertReplicaUserForPlatformProfile(
|
|
75824
|
+
env2,
|
|
75825
|
+
identity.platformProfile
|
|
75826
|
+
);
|
|
75827
|
+
return user.id;
|
|
75828
|
+
}
|
|
75829
|
+
function encryptionKey(env2) {
|
|
75830
|
+
const value = env2.ENCRYPTION_KEY;
|
|
75831
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
75832
|
+
}
|
|
75833
|
+
async function createDeviceConfirmationToken(env2, code, confirmationSubject) {
|
|
75834
|
+
const key = encryptionKey(env2);
|
|
75835
|
+
if (!key) return null;
|
|
75836
|
+
return signToken(JSON.stringify({
|
|
75837
|
+
kind: "device_approval_confirmation",
|
|
75838
|
+
code_hash: await hashToken(code),
|
|
75839
|
+
subject: confirmationSubject,
|
|
75840
|
+
exp: Math.floor(Date.now() / 1e3) + CONFIRMATION_TTL_SECONDS,
|
|
75841
|
+
nonce: crypto.randomUUID()
|
|
75842
|
+
}), key);
|
|
75843
|
+
}
|
|
75844
|
+
async function verifyDeviceConfirmationToken(env2, code, confirmationSubject, token) {
|
|
75845
|
+
const key = encryptionKey(env2);
|
|
75846
|
+
if (!key) return false;
|
|
75847
|
+
const raw = await verifySignedToken(token, key);
|
|
75848
|
+
if (!raw) return false;
|
|
75849
|
+
try {
|
|
75850
|
+
const payload = JSON.parse(raw);
|
|
75851
|
+
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);
|
|
75852
|
+
} catch {
|
|
75853
|
+
return false;
|
|
75854
|
+
}
|
|
75855
|
+
}
|
|
75856
|
+
function isSameOriginApprovalPost(req) {
|
|
75857
|
+
const url = new URL(req.url);
|
|
75858
|
+
const origin = req.headers.get("Origin");
|
|
75859
|
+
if (origin && origin !== url.origin) return false;
|
|
75860
|
+
const fetchSite = req.headers.get("Sec-Fetch-Site");
|
|
75861
|
+
return !fetchSite || fetchSite === "same-origin" || fetchSite === "none";
|
|
75862
|
+
}
|
|
75863
|
+
|
|
75864
|
+
// src/api/auth/device/[code]/approve.get.ts
|
|
75865
|
+
var approve_get_default = defineController2(async ({ req, env: env2, params }) => {
|
|
75866
|
+
const code = params.code;
|
|
75867
|
+
if (!code) {
|
|
75868
|
+
return outcome(env2, false, "invalid_link", {
|
|
75869
|
+
title: "Missing code",
|
|
75870
|
+
body: "This device link is malformed."
|
|
75871
|
+
});
|
|
75872
|
+
}
|
|
75873
|
+
const identity = await resolveDeviceApprovalIdentity(req, env2);
|
|
75874
|
+
if (identity instanceof Response) return identity;
|
|
75875
|
+
const confirmationToken = await createDeviceConfirmationToken(
|
|
75876
|
+
env2,
|
|
75877
|
+
code,
|
|
75878
|
+
identity.confirmationSubject
|
|
75879
|
+
);
|
|
75880
|
+
if (!confirmationToken) {
|
|
75881
|
+
return outcome(env2, false, "signin_failed", {
|
|
75882
|
+
title: "Sign in failed",
|
|
75883
|
+
body: "This instance cannot create a secure device confirmation. Contact its administrator."
|
|
75884
|
+
});
|
|
75099
75885
|
}
|
|
75886
|
+
return confirmationPage(req, code, confirmationToken, identity.handoff);
|
|
75887
|
+
});
|
|
75888
|
+
|
|
75889
|
+
// src/api/auth/device/[code]/approve.post.ts
|
|
75890
|
+
var approve_post_default = defineController2(async ({ req, env: env2, params }) => {
|
|
75891
|
+
const code = params.code;
|
|
75892
|
+
if (!code) {
|
|
75893
|
+
return outcome(env2, false, "invalid_link", {
|
|
75894
|
+
title: "Missing code",
|
|
75895
|
+
body: "This device link is malformed."
|
|
75896
|
+
});
|
|
75897
|
+
}
|
|
75898
|
+
if (!isSameOriginApprovalPost(req)) {
|
|
75899
|
+
return Response.json({ error: "Cross-origin device approval refused" }, { status: 403 });
|
|
75900
|
+
}
|
|
75901
|
+
const form = await req.clone().formData().catch(() => null);
|
|
75902
|
+
const confirmationToken = form?.get("confirmation_token")?.toString() ?? "";
|
|
75903
|
+
if (!confirmationToken) {
|
|
75904
|
+
return Response.json({ error: "Device confirmation token required" }, { status: 403 });
|
|
75905
|
+
}
|
|
75906
|
+
const identity = await resolveDeviceApprovalIdentity(req, env2);
|
|
75907
|
+
if (identity instanceof Response) return identity;
|
|
75908
|
+
if (!await verifyDeviceConfirmationToken(
|
|
75909
|
+
env2,
|
|
75910
|
+
code,
|
|
75911
|
+
identity.confirmationSubject,
|
|
75912
|
+
confirmationToken
|
|
75913
|
+
)) {
|
|
75914
|
+
return Response.json({ error: "Invalid or expired device confirmation" }, { status: 403 });
|
|
75915
|
+
}
|
|
75916
|
+
if (!await consumeDeviceApprovalHandoff(env2, identity)) {
|
|
75917
|
+
return outcome(env2, false, "signin_failed", {
|
|
75918
|
+
title: "Sign in failed",
|
|
75919
|
+
body: "This sign-in link was already used or has expired. Start again from your terminal."
|
|
75920
|
+
});
|
|
75921
|
+
}
|
|
75922
|
+
const userId = await materializeDeviceApprovalUser(env2, identity);
|
|
75100
75923
|
const token = generateApiKey();
|
|
75101
75924
|
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
75102
75925
|
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
75103
75926
|
const ok = await agentBuilder.approveDeviceLogin({
|
|
75104
75927
|
code_hash: await hashToken(code),
|
|
75105
|
-
user_id:
|
|
75928
|
+
user_id: userId,
|
|
75106
75929
|
token,
|
|
75107
75930
|
token_hash: await hashToken(token),
|
|
75108
75931
|
key_prefix: token.slice(0, 12),
|
|
@@ -75110,12 +75933,19 @@ var approve_get_default = defineController2(async ({ req, env: env2, params }) =
|
|
|
75110
75933
|
key_name: "CLI device login"
|
|
75111
75934
|
});
|
|
75112
75935
|
if (!ok) {
|
|
75113
|
-
return outcome(env2, false, "expired", {
|
|
75936
|
+
return outcome(env2, false, "expired", {
|
|
75937
|
+
title: "Link expired",
|
|
75938
|
+
body: "This device login has expired or was already used. Start again from your terminal."
|
|
75939
|
+
});
|
|
75114
75940
|
}
|
|
75115
|
-
return outcome(env2, true, "done", {
|
|
75941
|
+
return outcome(env2, true, "done", {
|
|
75942
|
+
title: "You're connected",
|
|
75943
|
+
body: "Standard Code is now signed in. Return to your terminal \u2014 it will pick up automatically."
|
|
75944
|
+
});
|
|
75116
75945
|
});
|
|
75117
75946
|
|
|
75118
75947
|
// src/api/skills/[name]/files/[...path].get.ts
|
|
75948
|
+
init_scope();
|
|
75119
75949
|
var path_get_default = defineController2(async ({ req, env: env2, params }) => {
|
|
75120
75950
|
const authResult = await requireAdmin(req, env2);
|
|
75121
75951
|
if (authResult instanceof Response) return authResult;
|
|
@@ -75128,7 +75958,11 @@ var path_get_default = defineController2(async ({ req, env: env2, params }) => {
|
|
|
75128
75958
|
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
75129
75959
|
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
75130
75960
|
try {
|
|
75131
|
-
const content = await agentBuilder.getSkillFile(
|
|
75961
|
+
const content = await agentBuilder.getSkillFile(
|
|
75962
|
+
{ ownerId: SHARED_SKILL_OWNER },
|
|
75963
|
+
name15,
|
|
75964
|
+
filePath
|
|
75965
|
+
);
|
|
75132
75966
|
if (content === null) {
|
|
75133
75967
|
return Response.json({ error: `File not found: ${filePath} in skill ${name15}` }, { status: 404 });
|
|
75134
75968
|
}
|
|
@@ -75143,6 +75977,24 @@ var path_get_default = defineController2(async ({ req, env: env2, params }) => {
|
|
|
75143
75977
|
|
|
75144
75978
|
// src/api/threads/[id]/fs/[...path].ts
|
|
75145
75979
|
var CHUNK_SIZE2 = 1.75 * 1024 * 1024;
|
|
75980
|
+
var EXECUTABLE_DOCUMENT_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
75981
|
+
"text/html",
|
|
75982
|
+
"image/svg+xml",
|
|
75983
|
+
"application/xhtml+xml"
|
|
75984
|
+
]);
|
|
75985
|
+
function safeDownloadName(name15) {
|
|
75986
|
+
return name15.replace(/["\\\r\n]/g, "_");
|
|
75987
|
+
}
|
|
75988
|
+
function fileResponseHeaders(file) {
|
|
75989
|
+
const mimeType = file.mimeType.split(";", 1)[0]?.trim().toLowerCase();
|
|
75990
|
+
const disposition = mimeType && EXECUTABLE_DOCUMENT_MIME_TYPES.has(mimeType) ? "attachment" : "inline";
|
|
75991
|
+
return {
|
|
75992
|
+
"Content-Type": file.mimeType,
|
|
75993
|
+
"Content-Length": String(file.size),
|
|
75994
|
+
"Content-Disposition": `${disposition}; filename="${safeDownloadName(file.name)}"`,
|
|
75995
|
+
"X-Content-Type-Options": "nosniff"
|
|
75996
|
+
};
|
|
75997
|
+
}
|
|
75146
75998
|
function toAttachmentRef(file) {
|
|
75147
75999
|
const metadata = file.metadata;
|
|
75148
76000
|
const width = file.width ?? metadata?.width;
|
|
@@ -75233,8 +76085,9 @@ async function handleGet2(stub, path10, url) {
|
|
|
75233
76085
|
headers: {
|
|
75234
76086
|
"Content-Type": "image/jpeg",
|
|
75235
76087
|
// Thumbnails are typically JPEG
|
|
75236
|
-
"Cache-Control": "public, max-age=31536000"
|
|
76088
|
+
"Cache-Control": "public, max-age=31536000",
|
|
75237
76089
|
// Cache for 1 year
|
|
76090
|
+
"X-Content-Type-Options": "nosniff"
|
|
75238
76091
|
}
|
|
75239
76092
|
});
|
|
75240
76093
|
}
|
|
@@ -75274,11 +76127,7 @@ async function handleGet2(stub, path10, url) {
|
|
|
75274
76127
|
bytes[i] = binary.charCodeAt(i);
|
|
75275
76128
|
}
|
|
75276
76129
|
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
|
-
}
|
|
76130
|
+
headers: fileResponseHeaders(file)
|
|
75282
76131
|
});
|
|
75283
76132
|
}
|
|
75284
76133
|
function streamChunkedFile(stub, path10, file) {
|
|
@@ -75306,12 +76155,8 @@ function streamChunkedFile(stub, path10, file) {
|
|
|
75306
76155
|
}
|
|
75307
76156
|
})();
|
|
75308
76157
|
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
|
-
}
|
|
76158
|
+
// Note: We set Content-Length, but also use chunked transfer internally.
|
|
76159
|
+
headers: fileResponseHeaders(file)
|
|
75315
76160
|
});
|
|
75316
76161
|
}
|
|
75317
76162
|
async function handlePost2(stub, path10, req) {
|
|
@@ -75508,19 +76353,9 @@ async function handleChunkedUploadComplete(stub, filePath, req) {
|
|
|
75508
76353
|
|
|
75509
76354
|
// src/api/threads/[id]/logs/[logId].get.ts
|
|
75510
76355
|
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
|
-
}
|
|
76356
|
+
const authResult = await requirePermission(req, env2, "logs");
|
|
76357
|
+
if (authResult instanceof Response) {
|
|
76358
|
+
return authResult;
|
|
75524
76359
|
}
|
|
75525
76360
|
const threadId = params.id;
|
|
75526
76361
|
const logId = params.logId;
|
|
@@ -75932,19 +76767,9 @@ function createInspectProviderConfig(providerName, factory, env2) {
|
|
|
75932
76767
|
};
|
|
75933
76768
|
}
|
|
75934
76769
|
var provider_get_default = defineController2(async ({ req, params, env: env2 }) => {
|
|
75935
|
-
|
|
75936
|
-
|
|
75937
|
-
|
|
75938
|
-
return authResult;
|
|
75939
|
-
}
|
|
75940
|
-
} else {
|
|
75941
|
-
const authContext = await authenticate(req, env2);
|
|
75942
|
-
if (authContext && !hasPermission(authContext.user, "logs")) {
|
|
75943
|
-
return Response.json(
|
|
75944
|
-
{ error: "Forbidden: 'logs' access required" },
|
|
75945
|
-
{ status: 403 }
|
|
75946
|
-
);
|
|
75947
|
-
}
|
|
76770
|
+
const authResult = await requirePermission(req, env2, "logs");
|
|
76771
|
+
if (authResult instanceof Response) {
|
|
76772
|
+
return authResult;
|
|
75948
76773
|
}
|
|
75949
76774
|
const threadId = params.id;
|
|
75950
76775
|
const logId = params.logId;
|
|
@@ -76164,30 +76989,28 @@ var provider_get_default = defineController2(async ({ req, params, env: env2 })
|
|
|
76164
76989
|
|
|
76165
76990
|
// src/built-in-routes.ts
|
|
76166
76991
|
var routeHandlers = {
|
|
76167
|
-
"POST:/": index_post_default,
|
|
76168
76992
|
"GET:/agents": agents_get_default,
|
|
76169
76993
|
"GET:/api-keys": index_get_default,
|
|
76170
|
-
"POST:/api-keys":
|
|
76994
|
+
"POST:/api-keys": index_post_default,
|
|
76171
76995
|
"GET:/config": config_get_default,
|
|
76172
76996
|
"GET:/diagnostics": diagnostics_get_default,
|
|
76173
76997
|
"GET:/events": events_get_default,
|
|
76174
76998
|
"GET:/hooks": hooks_get_default,
|
|
76175
76999
|
"GET:/models": models_get_default,
|
|
76176
|
-
"GET:/new-test": new_test_get_default,
|
|
76177
77000
|
"GET:/platform-endpoint": platform_endpoint_default,
|
|
76178
77001
|
"GET:/prompts": prompts_get_default,
|
|
76179
77002
|
"GET:/providers": providers_get_default,
|
|
76180
77003
|
"GET:/skills": index_get_default2,
|
|
76181
|
-
"POST:/skills":
|
|
76182
|
-
"POST:/threads":
|
|
77004
|
+
"POST:/skills": index_post_default2,
|
|
77005
|
+
"POST:/threads": index_post_default3,
|
|
76183
77006
|
"GET:/threads": threads_default,
|
|
76184
77007
|
"GET:/tools": tools_get_default,
|
|
76185
77008
|
"GET:/users": index_get_default3,
|
|
76186
|
-
"POST:/users":
|
|
77009
|
+
"POST:/users": index_post_default4,
|
|
76187
77010
|
"GET:/agents/:name": name_get_default,
|
|
76188
77011
|
"DELETE:/api-keys/:id": id_delete_default,
|
|
76189
77012
|
"GET:/models/:name": name_get_default2,
|
|
76190
|
-
"POST:/pack/:agentName":
|
|
77013
|
+
"POST:/pack/:agentName": index_post_default5,
|
|
76191
77014
|
"GET:/prompts/:name": name_get_default3,
|
|
76192
77015
|
"DELETE:/skills/:name": name_delete_default,
|
|
76193
77016
|
"GET:/skills/:name": name_get_default4,
|
|
@@ -76196,18 +77019,19 @@ var routeHandlers = {
|
|
|
76196
77019
|
"PATCH:/threads/:id": id_patch_default,
|
|
76197
77020
|
"GET:/threads/:id": id_default,
|
|
76198
77021
|
"GET:/tools/:name": name_get_default5,
|
|
76199
|
-
"POST:/unpack/:packageId":
|
|
77022
|
+
"POST:/unpack/:packageId": index_post_default6,
|
|
76200
77023
|
"DELETE:/users/:id": id_delete_default3,
|
|
76201
77024
|
"PUT:/users/:id": id_put_default,
|
|
76202
77025
|
"POST:/auth/bootstrap": bootstrap_post_default,
|
|
76203
77026
|
"POST:/auth/brolly-control": brolly_control_post_default,
|
|
76204
77027
|
"GET:/auth/config": config_get_default2,
|
|
77028
|
+
"DELETE:/auth/current-key": current_key_delete_default,
|
|
76205
77029
|
"POST:/auth/login": login_post_default,
|
|
76206
|
-
"GET:/auth/logout": logout_get_default,
|
|
76207
77030
|
"POST:/auth/logout": logout_post_default,
|
|
76208
77031
|
"GET:/auth/me": me_get_default,
|
|
76209
77032
|
"POST:/auth/platform-cleanup": platform_cleanup_post_default,
|
|
76210
77033
|
"POST:/auth/platform-replica": platform_replica_post_default,
|
|
77034
|
+
"POST:/auth/websocket-ticket": websocket_ticket_post_default,
|
|
76211
77035
|
"GET:/envs/instance": instance_get_default,
|
|
76212
77036
|
"PATCH:/envs/instance": instance_patch_default,
|
|
76213
77037
|
"POST:/models/available": available_post_default,
|
|
@@ -76283,9 +77107,10 @@ var routeHandlers = {
|
|
|
76283
77107
|
"GET:/users/me/hub": hub_default,
|
|
76284
77108
|
"DELETE:/users/me/kv": index_delete_default,
|
|
76285
77109
|
"GET:/users/me/kv": index_get_default4,
|
|
76286
|
-
"POST:/users/me/kv":
|
|
77110
|
+
"POST:/users/me/kv": index_post_default7,
|
|
76287
77111
|
"GET:/users/me/stream": stream_default3,
|
|
76288
77112
|
"GET:/auth/device/:code/approve": approve_get_default,
|
|
77113
|
+
"POST:/auth/device/:code/approve": approve_post_default,
|
|
76289
77114
|
"GET:/skills/:name/files/**": path_get_default,
|
|
76290
77115
|
"DELETE:/threads/:id/fs/**": path_default3,
|
|
76291
77116
|
"POST:/threads/:id/fs/**": path_default3,
|