@standardagents/builder 0.15.0 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/built-in-routes.js +1650 -502
- package/dist/built-in-routes.js.map +1 -1
- package/dist/client/ApiKeysView.js +1 -1
- package/dist/client/CenteredContentView.js +1 -1
- package/dist/client/CompositionView.js +5 -5
- package/dist/client/ConfirmDialog.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/client/CopyButton.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/client/DataTable.vue_vue_type_script_setup_true_lang.js +1 -0
- package/dist/client/JsonViewer.js +1 -1
- package/dist/client/LoginView.js +1 -1
- package/dist/client/Modal.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/client/ModelModal.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/client/ModelsView.js +1 -1
- package/dist/client/PromptEditView.js +1 -1
- package/dist/client/PromptModal.js +1 -1
- package/dist/client/PromptsView.js +1 -1
- package/dist/client/ProvidersView.js +2 -2
- package/dist/client/ThreadInspectorPane.vue_vue_type_script_setup_true_lang.js +19 -19
- package/dist/client/ToolsView.js +1 -1
- package/dist/client/UsersView.js +1 -1
- package/dist/client/VariablesView.js +1 -0
- package/dist/client/assets/CompositionView.css +1 -1
- package/dist/client/assets/ThreadInspectorPane.css +1 -1
- package/dist/client/assets/VariablesView.css +1 -0
- package/dist/client/assets/index.css +1 -1
- package/dist/client/index.js +6 -6
- package/dist/{index-D6_KjpVv.d.ts → index-BwqQtJ4r.d.ts} +47 -0
- package/dist/index.d.ts +116 -4
- package/dist/index.js +1547 -706
- package/dist/index.js.map +1 -1
- package/dist/plugin.js +548 -372
- package/dist/plugin.js.map +1 -1
- package/dist/test.d.ts +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -2,10 +2,10 @@ import { ProviderError, mapReasoningLevel } from '@standardagents/spec';
|
|
|
2
2
|
export { ProviderError, belongsToPackage, defineAgent, defineHook, defineModel, definePrompt, defineTool, isPacked, isVisibleInNamespace, mapReasoningLevel } from '@standardagents/spec';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { transform, collect } from '@standardagents/sip';
|
|
5
|
-
import * as
|
|
6
|
-
import
|
|
7
|
-
import * as
|
|
8
|
-
import
|
|
5
|
+
import * as fs8 from 'fs';
|
|
6
|
+
import fs8__default from 'fs';
|
|
7
|
+
import * as path8 from 'path';
|
|
8
|
+
import path8__default from 'path';
|
|
9
9
|
import { fileURLToPath } from 'url';
|
|
10
10
|
import MagicString from 'magic-string';
|
|
11
11
|
import { exec } from 'child_process';
|
|
@@ -873,8 +873,10 @@ var init_ProviderRegistry = __esm({
|
|
|
873
873
|
ProviderRegistryImpl = class {
|
|
874
874
|
providerCache = /* @__PURE__ */ new Map();
|
|
875
875
|
providerOverrideFn = null;
|
|
876
|
+
providerOverrideRevision = 0;
|
|
876
877
|
setProviderOverride(fn) {
|
|
877
878
|
this.providerOverrideFn = fn;
|
|
879
|
+
this.providerOverrideRevision += 1;
|
|
878
880
|
}
|
|
879
881
|
/**
|
|
880
882
|
* Get provider for a model.
|
|
@@ -894,17 +896,6 @@ var init_ProviderRegistry = __esm({
|
|
|
894
896
|
if (!modelDef) {
|
|
895
897
|
throw new Error(`Model not found: ${modelName}`);
|
|
896
898
|
}
|
|
897
|
-
if (this.providerOverrideFn) {
|
|
898
|
-
const overrideFingerprint = this.getProviderFingerprint("override", modelDef);
|
|
899
|
-
const cached2 = this.providerCache.get(modelName);
|
|
900
|
-
if (cached2?.fingerprint === overrideFingerprint) {
|
|
901
|
-
return this.buildResult(cached2.provider, modelDef);
|
|
902
|
-
}
|
|
903
|
-
const overrideProvider = this.providerOverrideFn(modelName, modelDef, env);
|
|
904
|
-
if (overrideProvider) {
|
|
905
|
-
return this.cacheAndReturn(modelName, overrideProvider, modelDef, overrideFingerprint);
|
|
906
|
-
}
|
|
907
|
-
}
|
|
908
899
|
if (typeof modelDef.provider !== "function") {
|
|
909
900
|
throw new Error(
|
|
910
901
|
`Model '${modelName}' has invalid provider. Provider must be a ProviderFactory function imported from a provider package (e.g., @standardagents/openai).`
|
|
@@ -912,29 +903,45 @@ var init_ProviderRegistry = __esm({
|
|
|
912
903
|
}
|
|
913
904
|
const providerFactory = modelDef.provider;
|
|
914
905
|
const providerName = providerFactory({ apiKey: "" }).name;
|
|
915
|
-
const fingerprint = this.getProviderFingerprint(providerName, modelDef);
|
|
916
|
-
const cached = this.providerCache.get(modelName);
|
|
917
|
-
if (cached?.fingerprint === fingerprint) {
|
|
918
|
-
return this.buildResult(cached.provider, modelDef);
|
|
919
|
-
}
|
|
920
906
|
if (providerName === "test") {
|
|
907
|
+
const fingerprint = this.getProviderFingerprint(providerName, modelDef);
|
|
908
|
+
const cached = this.providerCache.get(modelName);
|
|
909
|
+
if (cached?.fingerprint === fingerprint) {
|
|
910
|
+
return this.buildResult(cached.provider, modelDef);
|
|
911
|
+
}
|
|
921
912
|
return this.cacheAndReturn(modelName, createTestProvider(), modelDef, fingerprint);
|
|
922
913
|
}
|
|
923
914
|
const apiKey = this.getApiKeyForProvider(providerName, env);
|
|
924
|
-
if (
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
config.baseUrl
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
915
|
+
if (apiKey) {
|
|
916
|
+
const config = { apiKey };
|
|
917
|
+
if (modelDef.providerOptions?.baseUrl) {
|
|
918
|
+
config.baseUrl = modelDef.providerOptions.baseUrl;
|
|
919
|
+
}
|
|
920
|
+
if (providerName === "cloudflare" && !config.baseUrl && env.CLOUDFLARE_ACCOUNT_ID) {
|
|
921
|
+
config.baseUrl = `https://api.cloudflare.com/client/v4/accounts/${env.CLOUDFLARE_ACCOUNT_ID}/ai/v1`;
|
|
922
|
+
}
|
|
923
|
+
if (providerName === "cloudflare" && env.CLOUDFLARE_ACCOUNT_ID) {
|
|
924
|
+
config.accountId = env.CLOUDFLARE_ACCOUNT_ID;
|
|
925
|
+
}
|
|
926
|
+
const fingerprint = this.getProviderFingerprint(providerName, modelDef, config);
|
|
927
|
+
const cached = this.providerCache.get(modelName);
|
|
928
|
+
if (cached?.fingerprint === fingerprint) {
|
|
929
|
+
return this.buildResult(cached.provider, modelDef);
|
|
930
|
+
}
|
|
931
|
+
return this.cacheAndReturn(modelName, providerFactory(config), modelDef, fingerprint);
|
|
933
932
|
}
|
|
934
|
-
if (
|
|
935
|
-
|
|
933
|
+
if (this.providerOverrideFn) {
|
|
934
|
+
const overrideFingerprint = this.getProviderFingerprint(`override:${this.providerOverrideRevision}`, modelDef);
|
|
935
|
+
const overrideCached = this.providerCache.get(modelName);
|
|
936
|
+
if (overrideCached?.fingerprint === overrideFingerprint) {
|
|
937
|
+
return this.buildResult(overrideCached.provider, modelDef);
|
|
938
|
+
}
|
|
939
|
+
const overrideProvider = this.providerOverrideFn(modelName, modelDef, env);
|
|
940
|
+
if (overrideProvider) {
|
|
941
|
+
return this.cacheAndReturn(modelName, overrideProvider, modelDef, overrideFingerprint);
|
|
942
|
+
}
|
|
936
943
|
}
|
|
937
|
-
|
|
944
|
+
throw new Error(`No API key found for provider: ${providerName}. Set the provider key or STANDARD_AGENTS_API_KEY.`);
|
|
938
945
|
}
|
|
939
946
|
buildResult(provider, modelDef) {
|
|
940
947
|
return { provider, modelName: modelDef.model, modelDef };
|
|
@@ -943,10 +950,12 @@ var init_ProviderRegistry = __esm({
|
|
|
943
950
|
this.providerCache.set(modelName, { provider, fingerprint });
|
|
944
951
|
return this.buildResult(provider, modelDef);
|
|
945
952
|
}
|
|
946
|
-
getProviderFingerprint(providerName, modelDef) {
|
|
953
|
+
getProviderFingerprint(providerName, modelDef, config) {
|
|
947
954
|
return JSON.stringify({
|
|
948
955
|
providerName,
|
|
949
|
-
baseUrl: modelDef.providerOptions?.baseUrl ?? null
|
|
956
|
+
baseUrl: modelDef.providerOptions?.baseUrl ?? null,
|
|
957
|
+
apiKey: config?.apiKey ?? null,
|
|
958
|
+
accountId: config?.accountId ?? null
|
|
950
959
|
});
|
|
951
960
|
}
|
|
952
961
|
/**
|
|
@@ -1150,11 +1159,11 @@ function stripBase64FromMessages(messages, imagePathMap) {
|
|
|
1150
1159
|
const data = part.data;
|
|
1151
1160
|
if (typeof data === "string") {
|
|
1152
1161
|
if (data.startsWith("data:") || data.length > 1e3) {
|
|
1153
|
-
const
|
|
1162
|
+
const path20 = imagePathMap?.get(data);
|
|
1154
1163
|
return {
|
|
1155
1164
|
...part,
|
|
1156
1165
|
data: "[base64 omitted]",
|
|
1157
|
-
...
|
|
1166
|
+
...path20 ? { path: path20 } : {}
|
|
1158
1167
|
};
|
|
1159
1168
|
}
|
|
1160
1169
|
}
|
|
@@ -1831,6 +1840,7 @@ var init_LLMRequest = __esm({
|
|
|
1831
1840
|
try {
|
|
1832
1841
|
const toolsCalled = response.tool_calls ? JSON.stringify(response.tool_calls.map((tc) => tc.function.name)) : null;
|
|
1833
1842
|
const providerName = response._provider?.name;
|
|
1843
|
+
const standardAgentsRouterUsed = providerName === "platform";
|
|
1834
1844
|
const resolvedPricing = resolveModelPricing(modelDef, providerName);
|
|
1835
1845
|
const calculatedCost = calculateUsageCost(response.usage, resolvedPricing);
|
|
1836
1846
|
const providerReportedCost = typeof response.usage.cost === "number" ? response.usage.cost : typeof response.usage.cost === "string" ? parseFloat(response.usage.cost) : null;
|
|
@@ -1904,6 +1914,7 @@ var init_LLMRequest = __esm({
|
|
|
1904
1914
|
cost_total: cost_total ?? void 0,
|
|
1905
1915
|
actual_provider: actualProvider ?? void 0,
|
|
1906
1916
|
// Store actual provider separately (e.g., from OpenRouter)
|
|
1917
|
+
standard_agents_router_used: standardAgentsRouterUsed,
|
|
1907
1918
|
is_complete: true,
|
|
1908
1919
|
// Now complete
|
|
1909
1920
|
reasoning_content: response.reasoning_content ?? void 0,
|
|
@@ -1931,8 +1942,9 @@ var init_LLMRequest = __esm({
|
|
|
1931
1942
|
is_complete = ?13,
|
|
1932
1943
|
reasoning_content = ?14,
|
|
1933
1944
|
provider_tools = ?15,
|
|
1934
|
-
actual_provider = ?16
|
|
1935
|
-
|
|
1945
|
+
actual_provider = ?16,
|
|
1946
|
+
standard_agents_router_used = ?17
|
|
1947
|
+
WHERE id = ?18
|
|
1936
1948
|
`,
|
|
1937
1949
|
logData.response_body,
|
|
1938
1950
|
logData.input_tokens,
|
|
@@ -1950,6 +1962,7 @@ var init_LLMRequest = __esm({
|
|
|
1950
1962
|
logData.reasoning_content,
|
|
1951
1963
|
providerToolsJson,
|
|
1952
1964
|
actualProvider,
|
|
1965
|
+
standardAgentsRouterUsed ? 1 : 0,
|
|
1953
1966
|
logId
|
|
1954
1967
|
);
|
|
1955
1968
|
}
|
|
@@ -2030,11 +2043,11 @@ var init_LLMRequest = __esm({
|
|
|
2030
2043
|
...choice.message,
|
|
2031
2044
|
images: choice.message?.images?.map(
|
|
2032
2045
|
(img) => {
|
|
2033
|
-
const
|
|
2034
|
-
if (
|
|
2046
|
+
const path20 = img._id ? imagePathMap.get(img._id) : void 0;
|
|
2047
|
+
if (path20) {
|
|
2035
2048
|
return {
|
|
2036
2049
|
type: img.type,
|
|
2037
|
-
image_url: { url:
|
|
2050
|
+
image_url: { url: path20 }
|
|
2038
2051
|
};
|
|
2039
2052
|
}
|
|
2040
2053
|
return img;
|
|
@@ -2412,20 +2425,20 @@ function detectStorageBackend(location) {
|
|
|
2412
2425
|
return "url";
|
|
2413
2426
|
return "local";
|
|
2414
2427
|
}
|
|
2415
|
-
function basename2(
|
|
2416
|
-
const parts =
|
|
2428
|
+
function basename2(path20) {
|
|
2429
|
+
const parts = path20.split("/").filter(Boolean);
|
|
2417
2430
|
return parts[parts.length - 1] || "";
|
|
2418
2431
|
}
|
|
2419
|
-
function normalizePath(
|
|
2420
|
-
let normalized =
|
|
2432
|
+
function normalizePath(path20) {
|
|
2433
|
+
let normalized = path20.replace(/\/+/g, "/");
|
|
2421
2434
|
if (!normalized.startsWith("/")) normalized = "/" + normalized;
|
|
2422
2435
|
if (normalized.length > 1 && normalized.endsWith("/")) {
|
|
2423
2436
|
normalized = normalized.slice(0, -1);
|
|
2424
2437
|
}
|
|
2425
2438
|
return normalized;
|
|
2426
2439
|
}
|
|
2427
|
-
function dirname3(
|
|
2428
|
-
const normalized = normalizePath(
|
|
2440
|
+
function dirname3(path20) {
|
|
2441
|
+
const normalized = normalizePath(path20);
|
|
2429
2442
|
const lastSlash = normalized.lastIndexOf("/");
|
|
2430
2443
|
if (lastSlash <= 0) return "/";
|
|
2431
2444
|
return normalized.slice(0, lastSlash);
|
|
@@ -2550,8 +2563,8 @@ var init_files = __esm({
|
|
|
2550
2563
|
* Write a file to storage.
|
|
2551
2564
|
* Files > CHUNK_SIZE are automatically chunked into file_chunks table.
|
|
2552
2565
|
*/
|
|
2553
|
-
async writeFile(
|
|
2554
|
-
const normalizedPath = normalizePath(
|
|
2566
|
+
async writeFile(path20, data, mimeType, options) {
|
|
2567
|
+
const normalizedPath = normalizePath(path20);
|
|
2555
2568
|
const name = basename2(normalizedPath);
|
|
2556
2569
|
const isText = isTextMimeType(mimeType);
|
|
2557
2570
|
const now = Date.now();
|
|
@@ -2663,8 +2676,8 @@ var init_files = __esm({
|
|
|
2663
2676
|
/**
|
|
2664
2677
|
* Link to an external file (URL, S3, R2)
|
|
2665
2678
|
*/
|
|
2666
|
-
async linkFile(
|
|
2667
|
-
const normalizedPath = normalizePath(
|
|
2679
|
+
async linkFile(path20, location, options) {
|
|
2680
|
+
const normalizedPath = normalizePath(path20);
|
|
2668
2681
|
const name = basename2(normalizedPath);
|
|
2669
2682
|
const storage = detectStorageBackend(location);
|
|
2670
2683
|
const now = Date.now();
|
|
@@ -2703,8 +2716,8 @@ var init_files = __esm({
|
|
|
2703
2716
|
* WARNING: For large chunked files, this loads the entire file into memory.
|
|
2704
2717
|
* Use streamFile() for memory-efficient access to large files.
|
|
2705
2718
|
*/
|
|
2706
|
-
async readFile(
|
|
2707
|
-
const normalizedPath = normalizePath(
|
|
2719
|
+
async readFile(path20) {
|
|
2720
|
+
const normalizedPath = normalizePath(path20);
|
|
2708
2721
|
const cursor = await this.sql.exec(
|
|
2709
2722
|
`SELECT data, content, storage, is_chunked, chunk_count FROM files WHERE path = ? AND is_directory = 0`,
|
|
2710
2723
|
normalizedPath
|
|
@@ -2756,8 +2769,8 @@ var init_files = __esm({
|
|
|
2756
2769
|
* Memory-efficient way to read large chunked files.
|
|
2757
2770
|
* Yields one chunk at a time for streaming HTTP responses.
|
|
2758
2771
|
*/
|
|
2759
|
-
async *streamFile(
|
|
2760
|
-
const normalizedPath = normalizePath(
|
|
2772
|
+
async *streamFile(path20) {
|
|
2773
|
+
const normalizedPath = normalizePath(path20);
|
|
2761
2774
|
const cursor = await this.sql.exec(
|
|
2762
2775
|
`SELECT data, content, storage, is_chunked, chunk_count FROM files WHERE path = ? AND is_directory = 0`,
|
|
2763
2776
|
normalizedPath
|
|
@@ -2791,8 +2804,8 @@ var init_files = __esm({
|
|
|
2791
2804
|
/**
|
|
2792
2805
|
* Read text file content
|
|
2793
2806
|
*/
|
|
2794
|
-
async readTextFile(
|
|
2795
|
-
const normalizedPath = normalizePath(
|
|
2807
|
+
async readTextFile(path20) {
|
|
2808
|
+
const normalizedPath = normalizePath(path20);
|
|
2796
2809
|
const cursor = await this.sql.exec(
|
|
2797
2810
|
`SELECT content, data, storage FROM files WHERE path = ? AND is_directory = 0`,
|
|
2798
2811
|
normalizedPath
|
|
@@ -2810,8 +2823,8 @@ var init_files = __esm({
|
|
|
2810
2823
|
/**
|
|
2811
2824
|
* Get file metadata (stat)
|
|
2812
2825
|
*/
|
|
2813
|
-
async stat(
|
|
2814
|
-
const normalizedPath = normalizePath(
|
|
2826
|
+
async stat(path20) {
|
|
2827
|
+
const normalizedPath = normalizePath(path20);
|
|
2815
2828
|
const cursor = await this.sql.exec(
|
|
2816
2829
|
`SELECT path, name, mime_type, storage, location, size, metadata, is_directory, created_at, width, height, is_chunked, chunk_count
|
|
2817
2830
|
FROM files WHERE path = ?`,
|
|
@@ -2824,8 +2837,8 @@ var init_files = __esm({
|
|
|
2824
2837
|
/**
|
|
2825
2838
|
* Check if file or directory exists
|
|
2826
2839
|
*/
|
|
2827
|
-
async exists(
|
|
2828
|
-
const normalizedPath = normalizePath(
|
|
2840
|
+
async exists(path20) {
|
|
2841
|
+
const normalizedPath = normalizePath(path20);
|
|
2829
2842
|
const cursor = await this.sql.exec(
|
|
2830
2843
|
`SELECT COUNT(*) as count FROM files WHERE path = ?`,
|
|
2831
2844
|
normalizedPath
|
|
@@ -2835,8 +2848,8 @@ var init_files = __esm({
|
|
|
2835
2848
|
/**
|
|
2836
2849
|
* Delete a file
|
|
2837
2850
|
*/
|
|
2838
|
-
async unlink(
|
|
2839
|
-
const normalizedPath = normalizePath(
|
|
2851
|
+
async unlink(path20) {
|
|
2852
|
+
const normalizedPath = normalizePath(path20);
|
|
2840
2853
|
await this.sql.exec(
|
|
2841
2854
|
`DELETE FROM files WHERE path = ? AND is_directory = 0`,
|
|
2842
2855
|
normalizedPath
|
|
@@ -2846,8 +2859,8 @@ var init_files = __esm({
|
|
|
2846
2859
|
/**
|
|
2847
2860
|
* Create a directory marker
|
|
2848
2861
|
*/
|
|
2849
|
-
async mkdir(
|
|
2850
|
-
const normalizedPath = normalizePath(
|
|
2862
|
+
async mkdir(path20) {
|
|
2863
|
+
const normalizedPath = normalizePath(path20);
|
|
2851
2864
|
const name = basename2(normalizedPath);
|
|
2852
2865
|
const now = Date.now();
|
|
2853
2866
|
await this.sql.exec(
|
|
@@ -2872,8 +2885,8 @@ var init_files = __esm({
|
|
|
2872
2885
|
/**
|
|
2873
2886
|
* List directory contents
|
|
2874
2887
|
*/
|
|
2875
|
-
async readdir(
|
|
2876
|
-
const normalizedPath = normalizePath(
|
|
2888
|
+
async readdir(path20) {
|
|
2889
|
+
const normalizedPath = normalizePath(path20);
|
|
2877
2890
|
const prefix = normalizedPath === "/" ? "/" : normalizedPath + "/";
|
|
2878
2891
|
const cursor = await this.sql.exec(
|
|
2879
2892
|
`SELECT path, name, mime_type, storage, location, size, metadata, is_directory, created_at
|
|
@@ -2891,8 +2904,8 @@ var init_files = __esm({
|
|
|
2891
2904
|
/**
|
|
2892
2905
|
* Remove empty directory
|
|
2893
2906
|
*/
|
|
2894
|
-
async rmdir(
|
|
2895
|
-
const normalizedPath = normalizePath(
|
|
2907
|
+
async rmdir(path20) {
|
|
2908
|
+
const normalizedPath = normalizePath(path20);
|
|
2896
2909
|
const prefix = normalizedPath + "/";
|
|
2897
2910
|
const cursor = await this.sql.exec(
|
|
2898
2911
|
`SELECT COUNT(*) as count FROM files WHERE path LIKE ? || '%'`,
|
|
@@ -2934,8 +2947,8 @@ var init_files = __esm({
|
|
|
2934
2947
|
/**
|
|
2935
2948
|
* Get thumbnail for an image
|
|
2936
2949
|
*/
|
|
2937
|
-
async getThumbnail(
|
|
2938
|
-
const normalizedPath = normalizePath(
|
|
2950
|
+
async getThumbnail(path20) {
|
|
2951
|
+
const normalizedPath = normalizePath(path20);
|
|
2939
2952
|
const cursor = await this.sql.exec(
|
|
2940
2953
|
`SELECT thumbnail FROM files WHERE path = ? AND is_directory = 0`,
|
|
2941
2954
|
normalizedPath
|
|
@@ -3276,8 +3289,8 @@ var init_ToolExecutor = __esm({
|
|
|
3276
3289
|
const validation = argsSchema.safeParse(args);
|
|
3277
3290
|
if (!validation.success) {
|
|
3278
3291
|
const errorMessage = validation.error.issues.map((issue) => {
|
|
3279
|
-
const
|
|
3280
|
-
return `[${
|
|
3292
|
+
const path20 = issue.path.length > 0 ? issue.path.map(String).join(".") : "root";
|
|
3293
|
+
return `[${path20}] ${issue.message}`;
|
|
3281
3294
|
}).join("; ");
|
|
3282
3295
|
return {
|
|
3283
3296
|
status: "error",
|
|
@@ -4396,8 +4409,8 @@ Reference: ${referenceId}` : `Reference: ${referenceId}`;
|
|
|
4396
4409
|
}
|
|
4397
4410
|
return [];
|
|
4398
4411
|
}
|
|
4399
|
-
static inferMimeTypeFromPath(
|
|
4400
|
-
const normalized =
|
|
4412
|
+
static inferMimeTypeFromPath(path20) {
|
|
4413
|
+
const normalized = path20.toLowerCase();
|
|
4401
4414
|
if (normalized.endsWith(".png")) return "image/png";
|
|
4402
4415
|
if (normalized.endsWith(".jpg") || normalized.endsWith(".jpeg")) return "image/jpeg";
|
|
4403
4416
|
if (normalized.endsWith(".webp")) return "image/webp";
|
|
@@ -4436,7 +4449,7 @@ Reference: ${referenceId}` : `Reference: ${referenceId}`;
|
|
|
4436
4449
|
ext: value.slice(lastDot + 1).toLowerCase()
|
|
4437
4450
|
};
|
|
4438
4451
|
}
|
|
4439
|
-
static resolveAttachmentMimeType(sourceMimeType, fallbackMimeType,
|
|
4452
|
+
static resolveAttachmentMimeType(sourceMimeType, fallbackMimeType, path20) {
|
|
4440
4453
|
const source = sourceMimeType?.trim();
|
|
4441
4454
|
if (source && source !== "application/octet-stream") {
|
|
4442
4455
|
return source;
|
|
@@ -4445,7 +4458,7 @@ Reference: ${referenceId}` : `Reference: ${referenceId}`;
|
|
|
4445
4458
|
if (fallback && fallback !== "application/octet-stream") {
|
|
4446
4459
|
return fallback;
|
|
4447
4460
|
}
|
|
4448
|
-
return this.inferMimeTypeFromPath(
|
|
4461
|
+
return this.inferMimeTypeFromPath(path20) ?? source ?? fallback ?? "application/octet-stream";
|
|
4449
4462
|
}
|
|
4450
4463
|
static buildAttachmentTargetPath(preferredName, mimeType, sourcePath) {
|
|
4451
4464
|
const safeName = this.sanitizeFilename(preferredName);
|
|
@@ -4541,8 +4554,8 @@ Reference: ${referenceId}` : `Reference: ${referenceId}`;
|
|
|
4541
4554
|
}
|
|
4542
4555
|
return copied;
|
|
4543
4556
|
}
|
|
4544
|
-
static async readAttachmentDataFromSource(sourceThread,
|
|
4545
|
-
const sourceData = await sourceThread.readFile(
|
|
4557
|
+
static async readAttachmentDataFromSource(sourceThread, path20, sourceFile) {
|
|
4558
|
+
const sourceData = await sourceThread.readFile(path20);
|
|
4546
4559
|
if (sourceData.success && sourceData.data) {
|
|
4547
4560
|
return sourceData.data;
|
|
4548
4561
|
}
|
|
@@ -4576,7 +4589,7 @@ Reference: ${referenceId}` : `Reference: ${referenceId}`;
|
|
|
4576
4589
|
if (!attachments || attachments.length === 0) {
|
|
4577
4590
|
return "";
|
|
4578
4591
|
}
|
|
4579
|
-
const paths = attachments.map((attachment) => attachment.path).filter((
|
|
4592
|
+
const paths = attachments.map((attachment) => attachment.path).filter((path20) => typeof path20 === "string" && path20.length > 0);
|
|
4580
4593
|
if (paths.length === 0) {
|
|
4581
4594
|
return "";
|
|
4582
4595
|
}
|
|
@@ -4872,7 +4885,7 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
|
|
|
4872
4885
|
mappedAttachmentValue
|
|
4873
4886
|
);
|
|
4874
4887
|
const resolvedPaths = new Set(mappedRefs.map((ref) => ref.path));
|
|
4875
|
-
const missingPaths = candidatePaths.filter((
|
|
4888
|
+
const missingPaths = candidatePaths.filter((path20) => !resolvedPaths.has(path20));
|
|
4876
4889
|
if (candidatePaths.length === 0 || missingPaths.length > 0) {
|
|
4877
4890
|
processedResult = {
|
|
4878
4891
|
status: "error",
|
|
@@ -5026,8 +5039,8 @@ ${attachmentPaths}`;
|
|
|
5026
5039
|
if (mimeType.startsWith("image/")) {
|
|
5027
5040
|
return true;
|
|
5028
5041
|
}
|
|
5029
|
-
const
|
|
5030
|
-
return
|
|
5042
|
+
const path20 = ref.path.toLowerCase();
|
|
5043
|
+
return path20.endsWith(".png") || path20.endsWith(".jpg") || path20.endsWith(".jpeg") || path20.endsWith(".webp") || path20.endsWith(".gif") || path20.endsWith(".bmp") || path20.endsWith(".svg");
|
|
5031
5044
|
});
|
|
5032
5045
|
if (imageRefs.length === 0) {
|
|
5033
5046
|
return;
|
|
@@ -5093,27 +5106,27 @@ ${attachmentPaths}`;
|
|
|
5093
5106
|
*/
|
|
5094
5107
|
static async processToolAttachments(attachments, state) {
|
|
5095
5108
|
const { FileStorage: FileStorage2 } = await Promise.resolve().then(() => (init_files(), files_exports));
|
|
5096
|
-
const
|
|
5109
|
+
const fs18 = new FileStorage2(state.storage.sql);
|
|
5097
5110
|
const refs = [];
|
|
5098
5111
|
for (const attachment of attachments) {
|
|
5099
5112
|
try {
|
|
5100
5113
|
const attachmentId = crypto.randomUUID();
|
|
5101
5114
|
const timestamp = Date.now();
|
|
5102
5115
|
const ext = attachment.mimeType === "image/png" ? "png" : attachment.mimeType === "image/jpeg" ? "jpg" : attachment.mimeType === "image/gif" ? "gif" : attachment.mimeType === "image/webp" ? "webp" : attachment.name.split(".").pop() || "bin";
|
|
5103
|
-
const
|
|
5116
|
+
const path20 = `/attachments/${timestamp}-${attachmentId}.${ext}`;
|
|
5104
5117
|
const binaryString = atob(attachment.data);
|
|
5105
5118
|
const dataBuffer = new Uint8Array(binaryString.length);
|
|
5106
5119
|
for (let i = 0; i < binaryString.length; i++) {
|
|
5107
5120
|
dataBuffer[i] = binaryString.charCodeAt(i);
|
|
5108
5121
|
}
|
|
5109
|
-
await
|
|
5122
|
+
await fs18.writeFile(path20, dataBuffer.buffer, attachment.mimeType, {
|
|
5110
5123
|
width: attachment.width,
|
|
5111
5124
|
height: attachment.height
|
|
5112
5125
|
});
|
|
5113
5126
|
const ref = {
|
|
5114
5127
|
id: attachmentId,
|
|
5115
5128
|
type: "file",
|
|
5116
|
-
path:
|
|
5129
|
+
path: path20,
|
|
5117
5130
|
name: attachment.name,
|
|
5118
5131
|
mimeType: attachment.mimeType,
|
|
5119
5132
|
size: dataBuffer.byteLength
|
|
@@ -8399,16 +8412,16 @@ ${lines.join("\n\n")}`
|
|
|
8399
8412
|
const base64Data = match[2];
|
|
8400
8413
|
const ext = mimeType.split("/")[1] || "png";
|
|
8401
8414
|
const attachmentId = crypto.randomUUID();
|
|
8402
|
-
const
|
|
8415
|
+
const path20 = `/attachments/${Date.now()}-${attachmentId}.${ext}`;
|
|
8403
8416
|
try {
|
|
8404
|
-
await state.thread.instance.writeFile(
|
|
8417
|
+
await state.thread.instance.writeFile(path20, base64Data, mimeType);
|
|
8405
8418
|
if (image.id) {
|
|
8406
|
-
imagePathMap.set(image.id,
|
|
8419
|
+
imagePathMap.set(image.id, path20);
|
|
8407
8420
|
}
|
|
8408
8421
|
refs.push({
|
|
8409
8422
|
id: attachmentId,
|
|
8410
8423
|
type: "file",
|
|
8411
|
-
path:
|
|
8424
|
+
path: path20,
|
|
8412
8425
|
name: `generated-${attachmentId}.${ext}`,
|
|
8413
8426
|
mimeType,
|
|
8414
8427
|
size: Math.ceil(base64Data.length * 3 / 4)
|
|
@@ -8469,13 +8482,13 @@ ${lines.join("\n\n")}`
|
|
|
8469
8482
|
const base64Data = imageUrl.slice(base64Index + base64Marker.length);
|
|
8470
8483
|
const ext = mimeType.split("/")[1] || "png";
|
|
8471
8484
|
const attachmentId = crypto.randomUUID();
|
|
8472
|
-
const
|
|
8485
|
+
const path20 = `/attachments/${Date.now()}-${attachmentId}.${ext}`;
|
|
8473
8486
|
try {
|
|
8474
|
-
await state.thread.instance.writeFile(
|
|
8487
|
+
await state.thread.instance.writeFile(path20, base64Data, mimeType);
|
|
8475
8488
|
const attachmentRef = {
|
|
8476
8489
|
id: attachmentId,
|
|
8477
8490
|
type: "file",
|
|
8478
|
-
path:
|
|
8491
|
+
path: path20,
|
|
8479
8492
|
name: `generated-${attachmentId}.${ext}`,
|
|
8480
8493
|
mimeType,
|
|
8481
8494
|
size: Math.ceil(base64Data.length * 3 / 4)
|
|
@@ -8538,7 +8551,7 @@ ${lines.join("\n\n")}`
|
|
|
8538
8551
|
content: "Image generated successfully",
|
|
8539
8552
|
status: "success",
|
|
8540
8553
|
timestamp: Date.now(),
|
|
8541
|
-
attachment_path:
|
|
8554
|
+
attachment_path: path20
|
|
8542
8555
|
});
|
|
8543
8556
|
await state.storage.sql.exec(
|
|
8544
8557
|
`UPDATE logs SET tool_results = ?1 WHERE id = ?2`,
|
|
@@ -8560,7 +8573,7 @@ ${lines.join("\n\n")}`
|
|
|
8560
8573
|
}
|
|
8561
8574
|
}
|
|
8562
8575
|
if (image.id) {
|
|
8563
|
-
imagePathMap.set(image.id,
|
|
8576
|
+
imagePathMap.set(image.id, path20);
|
|
8564
8577
|
}
|
|
8565
8578
|
} catch (error) {
|
|
8566
8579
|
console.error(`[FlowEngine] Failed to store provider tool result for ${toolName}:`, error);
|
|
@@ -9294,7 +9307,7 @@ async function updateThread(thread, params) {
|
|
|
9294
9307
|
}
|
|
9295
9308
|
return result.thread;
|
|
9296
9309
|
}
|
|
9297
|
-
async function writeFile(flow,
|
|
9310
|
+
async function writeFile(flow, path20, data, mimeType, options) {
|
|
9298
9311
|
const instance = flow.thread.instance;
|
|
9299
9312
|
let base64Data;
|
|
9300
9313
|
if (typeof data === "string") {
|
|
@@ -9316,7 +9329,7 @@ async function writeFile(flow, path19, data, mimeType, options) {
|
|
|
9316
9329
|
}
|
|
9317
9330
|
base64Thumbnail = btoa(binary);
|
|
9318
9331
|
}
|
|
9319
|
-
const result = await instance.writeFile(
|
|
9332
|
+
const result = await instance.writeFile(path20, base64Data, mimeType, {
|
|
9320
9333
|
metadata: options?.metadata,
|
|
9321
9334
|
thumbnail: base64Thumbnail
|
|
9322
9335
|
});
|
|
@@ -9325,20 +9338,20 @@ async function writeFile(flow, path19, data, mimeType, options) {
|
|
|
9325
9338
|
}
|
|
9326
9339
|
return result.file;
|
|
9327
9340
|
}
|
|
9328
|
-
async function writeImage(flow,
|
|
9329
|
-
return writeFile(flow,
|
|
9341
|
+
async function writeImage(flow, path20, data, mimeType, options) {
|
|
9342
|
+
return writeFile(flow, path20, data, mimeType, options);
|
|
9330
9343
|
}
|
|
9331
|
-
async function linkFile(flow,
|
|
9344
|
+
async function linkFile(flow, path20, location, options) {
|
|
9332
9345
|
const instance = flow.thread.instance;
|
|
9333
|
-
const result = await instance.linkFile(
|
|
9346
|
+
const result = await instance.linkFile(path20, location, options);
|
|
9334
9347
|
if (!result.success) {
|
|
9335
9348
|
throw new Error(result.error || "Failed to link file");
|
|
9336
9349
|
}
|
|
9337
9350
|
return result.file;
|
|
9338
9351
|
}
|
|
9339
|
-
async function readFile(flow,
|
|
9352
|
+
async function readFile(flow, path20) {
|
|
9340
9353
|
const instance = flow.thread.instance;
|
|
9341
|
-
const result = await instance.readFile(
|
|
9354
|
+
const result = await instance.readFile(path20);
|
|
9342
9355
|
if (!result.success) {
|
|
9343
9356
|
return null;
|
|
9344
9357
|
}
|
|
@@ -9349,45 +9362,45 @@ async function readFile(flow, path19) {
|
|
|
9349
9362
|
}
|
|
9350
9363
|
return bytes.buffer;
|
|
9351
9364
|
}
|
|
9352
|
-
async function stat(flow,
|
|
9365
|
+
async function stat(flow, path20) {
|
|
9353
9366
|
const instance = flow.thread.instance;
|
|
9354
|
-
const result = await instance.statFile(
|
|
9367
|
+
const result = await instance.statFile(path20);
|
|
9355
9368
|
if (!result.success) {
|
|
9356
9369
|
return null;
|
|
9357
9370
|
}
|
|
9358
9371
|
return result.file;
|
|
9359
9372
|
}
|
|
9360
|
-
async function exists(flow,
|
|
9373
|
+
async function exists(flow, path20) {
|
|
9361
9374
|
const instance = flow.thread.instance;
|
|
9362
|
-
const result = await instance.fileExists(
|
|
9375
|
+
const result = await instance.fileExists(path20);
|
|
9363
9376
|
return result.success && result.exists;
|
|
9364
9377
|
}
|
|
9365
|
-
async function unlink(flow,
|
|
9378
|
+
async function unlink(flow, path20) {
|
|
9366
9379
|
const instance = flow.thread.instance;
|
|
9367
|
-
const result = await instance.unlinkFile(
|
|
9380
|
+
const result = await instance.unlinkFile(path20);
|
|
9368
9381
|
if (!result.success) {
|
|
9369
9382
|
throw new Error(result.error || "Failed to delete file");
|
|
9370
9383
|
}
|
|
9371
9384
|
}
|
|
9372
|
-
async function mkdir(flow,
|
|
9385
|
+
async function mkdir(flow, path20) {
|
|
9373
9386
|
const instance = flow.thread.instance;
|
|
9374
|
-
const result = await instance.mkdirFile(
|
|
9387
|
+
const result = await instance.mkdirFile(path20);
|
|
9375
9388
|
if (!result.success) {
|
|
9376
9389
|
throw new Error(result.error || "Failed to create directory");
|
|
9377
9390
|
}
|
|
9378
9391
|
return result.directory;
|
|
9379
9392
|
}
|
|
9380
|
-
async function readdir(flow,
|
|
9393
|
+
async function readdir(flow, path20) {
|
|
9381
9394
|
const instance = flow.thread.instance;
|
|
9382
|
-
const result = await instance.readdirFile(
|
|
9395
|
+
const result = await instance.readdirFile(path20);
|
|
9383
9396
|
if (!result.success) {
|
|
9384
9397
|
throw new Error(result.error || "Failed to read directory");
|
|
9385
9398
|
}
|
|
9386
9399
|
return result.files;
|
|
9387
9400
|
}
|
|
9388
|
-
async function rmdir(flow,
|
|
9401
|
+
async function rmdir(flow, path20) {
|
|
9389
9402
|
const instance = flow.thread.instance;
|
|
9390
|
-
const result = await instance.rmdirFile(
|
|
9403
|
+
const result = await instance.rmdirFile(path20);
|
|
9391
9404
|
if (!result.success) {
|
|
9392
9405
|
throw new Error(result.error || "Failed to remove directory");
|
|
9393
9406
|
}
|
|
@@ -9400,9 +9413,9 @@ async function getFileStats(flow) {
|
|
|
9400
9413
|
}
|
|
9401
9414
|
return result.stats;
|
|
9402
9415
|
}
|
|
9403
|
-
async function getThumbnail(flow,
|
|
9416
|
+
async function getThumbnail(flow, path20) {
|
|
9404
9417
|
const instance = flow.thread.instance;
|
|
9405
|
-
const result = await instance.getFileThumbnail(
|
|
9418
|
+
const result = await instance.getFileThumbnail(path20);
|
|
9406
9419
|
if (!result.success) {
|
|
9407
9420
|
return null;
|
|
9408
9421
|
}
|
|
@@ -9413,22 +9426,22 @@ async function getThumbnail(flow, path19) {
|
|
|
9413
9426
|
}
|
|
9414
9427
|
return bytes.buffer;
|
|
9415
9428
|
}
|
|
9416
|
-
async function cat(flow,
|
|
9429
|
+
async function cat(flow, path20) {
|
|
9417
9430
|
const instance = flow.thread.instance;
|
|
9418
|
-
const result = await instance.readTextFile(
|
|
9431
|
+
const result = await instance.readTextFile(path20);
|
|
9419
9432
|
if (!result.success) {
|
|
9420
9433
|
return null;
|
|
9421
9434
|
}
|
|
9422
9435
|
return result.content;
|
|
9423
9436
|
}
|
|
9424
|
-
async function head(flow,
|
|
9425
|
-
const content = await cat(flow,
|
|
9437
|
+
async function head(flow, path20, lines = 10) {
|
|
9438
|
+
const content = await cat(flow, path20);
|
|
9426
9439
|
if (content === null) return null;
|
|
9427
9440
|
const allLines = content.split("\n");
|
|
9428
9441
|
return allLines.slice(0, lines).join("\n");
|
|
9429
9442
|
}
|
|
9430
|
-
async function tail(flow,
|
|
9431
|
-
const content = await cat(flow,
|
|
9443
|
+
async function tail(flow, path20, lines = 10) {
|
|
9444
|
+
const content = await cat(flow, path20);
|
|
9432
9445
|
if (content === null) return null;
|
|
9433
9446
|
const allLines = content.split("\n");
|
|
9434
9447
|
return allLines.slice(-lines).join("\n");
|
|
@@ -9967,32 +9980,32 @@ function prepareBridge(options, reports, logs) {
|
|
|
9967
9980
|
logs
|
|
9968
9981
|
};
|
|
9969
9982
|
}
|
|
9970
|
-
function prepareNamespaceRecord(value,
|
|
9983
|
+
function prepareNamespaceRecord(value, path20, functions) {
|
|
9971
9984
|
const out = {};
|
|
9972
9985
|
for (const [key, namespace] of Object.entries(value)) {
|
|
9973
|
-
out[key] = prepareValueRecord(namespace, `${
|
|
9986
|
+
out[key] = prepareValueRecord(namespace, `${path20}.${key}`, functions);
|
|
9974
9987
|
}
|
|
9975
9988
|
return out;
|
|
9976
9989
|
}
|
|
9977
|
-
function prepareValueRecord(value,
|
|
9990
|
+
function prepareValueRecord(value, path20, functions) {
|
|
9978
9991
|
const out = {};
|
|
9979
9992
|
for (const [key, item] of Object.entries(value)) {
|
|
9980
|
-
out[key] = prepareBridgeValue(item, `${
|
|
9993
|
+
out[key] = prepareBridgeValue(item, `${path20}.${key}`, functions);
|
|
9981
9994
|
}
|
|
9982
9995
|
return out;
|
|
9983
9996
|
}
|
|
9984
|
-
function prepareBridgeValue(value,
|
|
9997
|
+
function prepareBridgeValue(value, path20, functions) {
|
|
9985
9998
|
if (typeof value === "function") {
|
|
9986
|
-
functions.set(
|
|
9987
|
-
return { __agentbuilderType: "function", id:
|
|
9999
|
+
functions.set(path20, value);
|
|
10000
|
+
return { __agentbuilderType: "function", id: path20 };
|
|
9988
10001
|
}
|
|
9989
10002
|
if (isThenable(value)) {
|
|
9990
|
-
const promiseId = `${
|
|
10003
|
+
const promiseId = `${path20}.__promise`;
|
|
9991
10004
|
functions.set(promiseId, async () => value);
|
|
9992
10005
|
return { __agentbuilderType: "promise", id: promiseId };
|
|
9993
10006
|
}
|
|
9994
10007
|
if (Array.isArray(value)) {
|
|
9995
|
-
return value.map((item, index) => prepareBridgeValue(item, `${
|
|
10008
|
+
return value.map((item, index) => prepareBridgeValue(item, `${path20}.${index}`, functions));
|
|
9996
10009
|
}
|
|
9997
10010
|
if (value && typeof value === "object") {
|
|
9998
10011
|
if (value instanceof Date || value instanceof Map || value instanceof Set || ArrayBuffer.isView(value) || value instanceof ArrayBuffer) {
|
|
@@ -10003,7 +10016,7 @@ function prepareBridgeValue(value, path19, functions) {
|
|
|
10003
10016
|
}
|
|
10004
10017
|
const out = {};
|
|
10005
10018
|
for (const [key, item] of Object.entries(value)) {
|
|
10006
|
-
out[key] = prepareBridgeValue(item, `${
|
|
10019
|
+
out[key] = prepareBridgeValue(item, `${path20}.${key}`, functions);
|
|
10007
10020
|
}
|
|
10008
10021
|
return out;
|
|
10009
10022
|
}
|
|
@@ -10878,12 +10891,12 @@ function normalizeVirtualModulePath(basePath, specifier) {
|
|
|
10878
10891
|
}
|
|
10879
10892
|
return normalized;
|
|
10880
10893
|
}
|
|
10881
|
-
function dirnameModulePath(
|
|
10882
|
-
const index =
|
|
10883
|
-
return index <= 0 ? "" :
|
|
10894
|
+
function dirnameModulePath(path20) {
|
|
10895
|
+
const index = path20.lastIndexOf("/");
|
|
10896
|
+
return index <= 0 ? "" : path20.slice(0, index);
|
|
10884
10897
|
}
|
|
10885
|
-
function hasModuleExtension(
|
|
10886
|
-
return /\.[A-Za-z0-9]+$/.test(
|
|
10898
|
+
function hasModuleExtension(path20) {
|
|
10899
|
+
return /\.[A-Za-z0-9]+$/.test(path20);
|
|
10887
10900
|
}
|
|
10888
10901
|
function resolveGraphModuleSpecifier(fromPath, specifier, modulePaths) {
|
|
10889
10902
|
const base = normalizeVirtualModulePath(dirnameModulePath(fromPath), specifier);
|
|
@@ -11214,9 +11227,9 @@ function isPlainObject2(value) {
|
|
|
11214
11227
|
const prototype = Object.getPrototypeOf(value);
|
|
11215
11228
|
return prototype === Object.prototype || prototype === null;
|
|
11216
11229
|
}
|
|
11217
|
-
function findUntransferableOption(value,
|
|
11230
|
+
function findUntransferableOption(value, path20, seen = /* @__PURE__ */ new WeakSet()) {
|
|
11218
11231
|
if (typeof value === "function" || typeof value === "symbol") {
|
|
11219
|
-
return
|
|
11232
|
+
return path20;
|
|
11220
11233
|
}
|
|
11221
11234
|
if (!value || typeof value !== "object") {
|
|
11222
11235
|
return null;
|
|
@@ -11230,7 +11243,7 @@ function findUntransferableOption(value, path19, seen = /* @__PURE__ */ new Weak
|
|
|
11230
11243
|
seen.add(value);
|
|
11231
11244
|
if (Array.isArray(value)) {
|
|
11232
11245
|
for (const [index, item] of value.entries()) {
|
|
11233
|
-
const found = findUntransferableOption(item, `${
|
|
11246
|
+
const found = findUntransferableOption(item, `${path20}.${index}`, seen);
|
|
11234
11247
|
if (found) return found;
|
|
11235
11248
|
}
|
|
11236
11249
|
return null;
|
|
@@ -11238,9 +11251,9 @@ function findUntransferableOption(value, path19, seen = /* @__PURE__ */ new Weak
|
|
|
11238
11251
|
if (value instanceof Map) {
|
|
11239
11252
|
let index = 0;
|
|
11240
11253
|
for (const [key, item] of value.entries()) {
|
|
11241
|
-
const foundKey = findUntransferableOption(key, `${
|
|
11254
|
+
const foundKey = findUntransferableOption(key, `${path20}.mapKey${index}`, seen);
|
|
11242
11255
|
if (foundKey) return foundKey;
|
|
11243
|
-
const foundValue = findUntransferableOption(item, `${
|
|
11256
|
+
const foundValue = findUntransferableOption(item, `${path20}.mapValue${index}`, seen);
|
|
11244
11257
|
if (foundValue) return foundValue;
|
|
11245
11258
|
index += 1;
|
|
11246
11259
|
}
|
|
@@ -11249,17 +11262,17 @@ function findUntransferableOption(value, path19, seen = /* @__PURE__ */ new Weak
|
|
|
11249
11262
|
if (value instanceof Set) {
|
|
11250
11263
|
let index = 0;
|
|
11251
11264
|
for (const item of value.values()) {
|
|
11252
|
-
const found = findUntransferableOption(item, `${
|
|
11265
|
+
const found = findUntransferableOption(item, `${path20}.setValue${index}`, seen);
|
|
11253
11266
|
if (found) return found;
|
|
11254
11267
|
index += 1;
|
|
11255
11268
|
}
|
|
11256
11269
|
return null;
|
|
11257
11270
|
}
|
|
11258
11271
|
if (!isPlainObject2(value)) {
|
|
11259
|
-
return
|
|
11272
|
+
return path20;
|
|
11260
11273
|
}
|
|
11261
11274
|
for (const [key, item] of Object.entries(value)) {
|
|
11262
|
-
const found = findUntransferableOption(item, `${
|
|
11275
|
+
const found = findUntransferableOption(item, `${path20}.${key}`, seen);
|
|
11263
11276
|
if (found) return found;
|
|
11264
11277
|
}
|
|
11265
11278
|
return null;
|
|
@@ -11769,7 +11782,7 @@ var init_ThreadStateImpl = __esm({
|
|
|
11769
11782
|
// ─────────────────────────────────────────────────────────────────────────
|
|
11770
11783
|
// File System
|
|
11771
11784
|
// ─────────────────────────────────────────────────────────────────────────
|
|
11772
|
-
async writeFile(
|
|
11785
|
+
async writeFile(path20, data, mimeType, options) {
|
|
11773
11786
|
const isText = this._isTextMimeType(mimeType);
|
|
11774
11787
|
if (isText) {
|
|
11775
11788
|
let textContent;
|
|
@@ -11778,7 +11791,7 @@ var init_ThreadStateImpl = __esm({
|
|
|
11778
11791
|
} else {
|
|
11779
11792
|
textContent = new TextDecoder().decode(data);
|
|
11780
11793
|
}
|
|
11781
|
-
const result = await this._threadInstance.writeTextFile(
|
|
11794
|
+
const result = await this._threadInstance.writeTextFile(path20, textContent, mimeType, options);
|
|
11782
11795
|
return this._mapFileRecord(result.file);
|
|
11783
11796
|
} else {
|
|
11784
11797
|
let base64Data;
|
|
@@ -11798,7 +11811,7 @@ var init_ThreadStateImpl = __esm({
|
|
|
11798
11811
|
}
|
|
11799
11812
|
base64Data = btoa(binary);
|
|
11800
11813
|
}
|
|
11801
|
-
const result = await this._threadInstance.writeFile(
|
|
11814
|
+
const result = await this._threadInstance.writeFile(path20, base64Data, mimeType, options);
|
|
11802
11815
|
return this._mapFileRecord(result.file);
|
|
11803
11816
|
}
|
|
11804
11817
|
}
|
|
@@ -11870,8 +11883,8 @@ var init_ThreadStateImpl = __esm({
|
|
|
11870
11883
|
(type) => mimeType === type || mimeType.startsWith(type + ";")
|
|
11871
11884
|
);
|
|
11872
11885
|
}
|
|
11873
|
-
async readFile(
|
|
11874
|
-
const result = await this._threadInstance.readFile(
|
|
11886
|
+
async readFile(path20) {
|
|
11887
|
+
const result = await this._threadInstance.readFile(path20);
|
|
11875
11888
|
if (!result.success || !result.data) {
|
|
11876
11889
|
return null;
|
|
11877
11890
|
}
|
|
@@ -11882,8 +11895,8 @@ var init_ThreadStateImpl = __esm({
|
|
|
11882
11895
|
}
|
|
11883
11896
|
return bytes.buffer;
|
|
11884
11897
|
}
|
|
11885
|
-
async readFileStream(
|
|
11886
|
-
const fileInfo = await this._threadInstance.statFile(
|
|
11898
|
+
async readFileStream(path20, options) {
|
|
11899
|
+
const fileInfo = await this._threadInstance.statFile(path20);
|
|
11887
11900
|
if (!fileInfo) {
|
|
11888
11901
|
return null;
|
|
11889
11902
|
}
|
|
@@ -11898,7 +11911,7 @@ var init_ThreadStateImpl = __esm({
|
|
|
11898
11911
|
return {
|
|
11899
11912
|
[Symbol.asyncIterator]: async function* () {
|
|
11900
11913
|
if (!isChunked) {
|
|
11901
|
-
const result = await threadInstance.readFile(
|
|
11914
|
+
const result = await threadInstance.readFile(path20);
|
|
11902
11915
|
if (!result.success || !result.data) {
|
|
11903
11916
|
return;
|
|
11904
11917
|
}
|
|
@@ -11919,7 +11932,7 @@ var init_ThreadStateImpl = __esm({
|
|
|
11919
11932
|
if (signal?.aborted) {
|
|
11920
11933
|
return;
|
|
11921
11934
|
}
|
|
11922
|
-
const result = await threadInstance.readFileChunk(
|
|
11935
|
+
const result = await threadInstance.readFileChunk(path20, i);
|
|
11923
11936
|
if (!result.success || !result.data) {
|
|
11924
11937
|
throw new Error(result.error || `Failed to read chunk ${i}`);
|
|
11925
11938
|
}
|
|
@@ -11938,25 +11951,25 @@ var init_ThreadStateImpl = __esm({
|
|
|
11938
11951
|
}
|
|
11939
11952
|
};
|
|
11940
11953
|
}
|
|
11941
|
-
async statFile(
|
|
11942
|
-
const result = await this._threadInstance.statFile(
|
|
11954
|
+
async statFile(path20) {
|
|
11955
|
+
const result = await this._threadInstance.statFile(path20);
|
|
11943
11956
|
return result ? this._mapFileRecord(result) : null;
|
|
11944
11957
|
}
|
|
11945
|
-
async readdirFile(
|
|
11946
|
-
const entries = await this._threadInstance.readdirFile(
|
|
11958
|
+
async readdirFile(path20) {
|
|
11959
|
+
const entries = await this._threadInstance.readdirFile(path20);
|
|
11947
11960
|
return {
|
|
11948
11961
|
entries: entries.map((e) => this._mapFileRecord(e))
|
|
11949
11962
|
};
|
|
11950
11963
|
}
|
|
11951
|
-
async unlinkFile(
|
|
11952
|
-
await this._threadInstance.unlinkFile(
|
|
11964
|
+
async unlinkFile(path20) {
|
|
11965
|
+
await this._threadInstance.unlinkFile(path20);
|
|
11953
11966
|
}
|
|
11954
|
-
async mkdirFile(
|
|
11955
|
-
const result = await this._threadInstance.mkdirFile(
|
|
11967
|
+
async mkdirFile(path20) {
|
|
11968
|
+
const result = await this._threadInstance.mkdirFile(path20);
|
|
11956
11969
|
return this._mapFileRecord(result);
|
|
11957
11970
|
}
|
|
11958
|
-
async rmdirFile(
|
|
11959
|
-
await this._threadInstance.rmdirFile(
|
|
11971
|
+
async rmdirFile(path20) {
|
|
11972
|
+
await this._threadInstance.rmdirFile(path20);
|
|
11960
11973
|
}
|
|
11961
11974
|
async getFileStats() {
|
|
11962
11975
|
const stats = await this._threadInstance.getFileStats();
|
|
@@ -11979,8 +11992,8 @@ var init_ThreadStateImpl = __esm({
|
|
|
11979
11992
|
paths: Array.isArray(results) ? results : results.paths || []
|
|
11980
11993
|
};
|
|
11981
11994
|
}
|
|
11982
|
-
async getFileThumbnail(
|
|
11983
|
-
return this._threadInstance.getFileThumbnail(
|
|
11995
|
+
async getFileThumbnail(path20) {
|
|
11996
|
+
return this._threadInstance.getFileThumbnail(path20);
|
|
11984
11997
|
}
|
|
11985
11998
|
// ─────────────────────────────────────────────────────────────────────────
|
|
11986
11999
|
// Execution State
|
|
@@ -12293,15 +12306,15 @@ function extractSchemaFields(content) {
|
|
|
12293
12306
|
}
|
|
12294
12307
|
function scanPromptsWithSchemas(dir) {
|
|
12295
12308
|
const results = [];
|
|
12296
|
-
if (!
|
|
12309
|
+
if (!fs8__default.existsSync(dir)) {
|
|
12297
12310
|
return results;
|
|
12298
12311
|
}
|
|
12299
12312
|
try {
|
|
12300
|
-
const entries =
|
|
12313
|
+
const entries = fs8__default.readdirSync(dir, { withFileTypes: true });
|
|
12301
12314
|
for (const entry of entries) {
|
|
12302
12315
|
if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
12303
|
-
const filePath =
|
|
12304
|
-
const content =
|
|
12316
|
+
const filePath = path8__default.join(dir, entry.name);
|
|
12317
|
+
const content = fs8__default.readFileSync(filePath, "utf-8");
|
|
12305
12318
|
const nameMatch = content.match(/name:\s*['"]([^'"]+)['"]/);
|
|
12306
12319
|
if (nameMatch) {
|
|
12307
12320
|
const name = nameMatch[1];
|
|
@@ -12317,15 +12330,15 @@ function scanPromptsWithSchemas(dir) {
|
|
|
12317
12330
|
}
|
|
12318
12331
|
function scanAgentsWithSideA(dir) {
|
|
12319
12332
|
const results = [];
|
|
12320
|
-
if (!
|
|
12333
|
+
if (!fs8__default.existsSync(dir)) {
|
|
12321
12334
|
return results;
|
|
12322
12335
|
}
|
|
12323
12336
|
try {
|
|
12324
|
-
const entries =
|
|
12337
|
+
const entries = fs8__default.readdirSync(dir, { withFileTypes: true });
|
|
12325
12338
|
for (const entry of entries) {
|
|
12326
12339
|
if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
12327
|
-
const filePath =
|
|
12328
|
-
const content =
|
|
12340
|
+
const filePath = path8__default.join(dir, entry.name);
|
|
12341
|
+
const content = fs8__default.readFileSync(filePath, "utf-8");
|
|
12329
12342
|
const nameMatch = content.match(/name:\s*['"]([^'"]+)['"]/);
|
|
12330
12343
|
if (nameMatch) {
|
|
12331
12344
|
const name = nameMatch[1];
|
|
@@ -12345,15 +12358,15 @@ function scanAgentsWithSideA(dir) {
|
|
|
12345
12358
|
}
|
|
12346
12359
|
function scanForNames(dir, useFilename = false) {
|
|
12347
12360
|
const names = [];
|
|
12348
|
-
if (!
|
|
12361
|
+
if (!fs8__default.existsSync(dir)) {
|
|
12349
12362
|
return names;
|
|
12350
12363
|
}
|
|
12351
12364
|
try {
|
|
12352
|
-
const entries =
|
|
12365
|
+
const entries = fs8__default.readdirSync(dir, { withFileTypes: true });
|
|
12353
12366
|
for (const entry of entries) {
|
|
12354
12367
|
if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
12355
|
-
const filePath =
|
|
12356
|
-
const content =
|
|
12368
|
+
const filePath = path8__default.join(dir, entry.name);
|
|
12369
|
+
const content = fs8__default.readFileSync(filePath, "utf-8");
|
|
12357
12370
|
if (useFilename) {
|
|
12358
12371
|
const toolName = entry.name.replace(/\.ts$/, "");
|
|
12359
12372
|
if (content.includes("defineTool")) {
|
|
@@ -12374,18 +12387,18 @@ function scanForNames(dir, useFilename = false) {
|
|
|
12374
12387
|
}
|
|
12375
12388
|
function scanHooksForIds(dir) {
|
|
12376
12389
|
const hookIds = [];
|
|
12377
|
-
if (!
|
|
12390
|
+
if (!fs8__default.existsSync(dir)) {
|
|
12378
12391
|
return hookIds;
|
|
12379
12392
|
}
|
|
12380
12393
|
try {
|
|
12381
|
-
const entries =
|
|
12394
|
+
const entries = fs8__default.readdirSync(dir, { withFileTypes: true });
|
|
12382
12395
|
for (const entry of entries) {
|
|
12383
12396
|
if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
12384
12397
|
if (entry.name === "index.ts") {
|
|
12385
12398
|
continue;
|
|
12386
12399
|
}
|
|
12387
|
-
const filePath =
|
|
12388
|
-
const content =
|
|
12400
|
+
const filePath = path8__default.join(dir, entry.name);
|
|
12401
|
+
const content = fs8__default.readFileSync(filePath, "utf-8");
|
|
12389
12402
|
const idMatch = content.match(/defineHook\s*\(\s*\{[^}]*id:\s*['"]([^'"]+)['"]/s);
|
|
12390
12403
|
if (idMatch) {
|
|
12391
12404
|
hookIds.push(idMatch[1]);
|
|
@@ -12852,6 +12865,34 @@ declare module 'virtual:@standardagents/builder' {
|
|
|
12852
12865
|
property: string;
|
|
12853
12866
|
promptName?: string;
|
|
12854
12867
|
}): Promise<'text' | 'secret'>;
|
|
12868
|
+
getInstanceEnv(): Promise<Record<string, string>>;
|
|
12869
|
+
getInstanceEnvTypes(): Promise<Record<string, 'text' | 'secret'>>;
|
|
12870
|
+
getInstanceEnvEntries(): Promise<Array<{
|
|
12871
|
+
name: string;
|
|
12872
|
+
value: string;
|
|
12873
|
+
type: 'text' | 'secret';
|
|
12874
|
+
created_at: number;
|
|
12875
|
+
updated_at: number;
|
|
12876
|
+
}>>;
|
|
12877
|
+
patchInstanceEnv(params: {
|
|
12878
|
+
env_patch?: Record<string, unknown> | null;
|
|
12879
|
+
env_type_patch?: Record<string, unknown> | null;
|
|
12880
|
+
env_delete?: string[] | null;
|
|
12881
|
+
}): Promise<void>;
|
|
12882
|
+
getUserEnv(userId: string): Promise<Record<string, string>>;
|
|
12883
|
+
getUserEnvTypes(userId: string): Promise<Record<string, 'text' | 'secret'>>;
|
|
12884
|
+
getUserEnvEntries(userId: string): Promise<Array<{
|
|
12885
|
+
name: string;
|
|
12886
|
+
value: string;
|
|
12887
|
+
type: 'text' | 'secret';
|
|
12888
|
+
created_at: number;
|
|
12889
|
+
updated_at: number;
|
|
12890
|
+
}>>;
|
|
12891
|
+
patchUserEnv(userId: string, params: {
|
|
12892
|
+
env_patch?: Record<string, unknown> | null;
|
|
12893
|
+
env_type_patch?: Record<string, unknown> | null;
|
|
12894
|
+
env_delete?: string[] | null;
|
|
12895
|
+
}): Promise<void>;
|
|
12855
12896
|
listThreads(params?: {
|
|
12856
12897
|
agent_name?: string;
|
|
12857
12898
|
user_id?: string;
|
|
@@ -13009,44 +13050,44 @@ declare module 'virtual:@standardagents/router' {
|
|
|
13009
13050
|
`;
|
|
13010
13051
|
}
|
|
13011
13052
|
function ensureDir(dir) {
|
|
13012
|
-
if (!
|
|
13013
|
-
|
|
13053
|
+
if (!fs8__default.existsSync(dir)) {
|
|
13054
|
+
fs8__default.mkdirSync(dir, { recursive: true });
|
|
13014
13055
|
}
|
|
13015
13056
|
}
|
|
13016
13057
|
function writeFileIfChanged(filePath, content) {
|
|
13017
|
-
if (
|
|
13018
|
-
const existing =
|
|
13058
|
+
if (fs8__default.existsSync(filePath)) {
|
|
13059
|
+
const existing = fs8__default.readFileSync(filePath, "utf-8");
|
|
13019
13060
|
if (existing === content) {
|
|
13020
13061
|
return;
|
|
13021
13062
|
}
|
|
13022
13063
|
}
|
|
13023
|
-
|
|
13064
|
+
fs8__default.writeFileSync(filePath, content);
|
|
13024
13065
|
}
|
|
13025
13066
|
function generateTypes(config) {
|
|
13026
13067
|
ensureDir(config.outputDir);
|
|
13027
13068
|
const typesContent = generateTypesContent(config);
|
|
13028
|
-
writeFileIfChanged(
|
|
13069
|
+
writeFileIfChanged(path8__default.join(config.outputDir, "types.d.ts"), typesContent);
|
|
13029
13070
|
const virtualModuleContent = generateVirtualModuleContent();
|
|
13030
|
-
writeFileIfChanged(
|
|
13031
|
-
writeFileIfChanged(
|
|
13032
|
-
writeFileIfChanged(
|
|
13071
|
+
writeFileIfChanged(path8__default.join(config.outputDir, "virtual-module.d.ts"), virtualModuleContent);
|
|
13072
|
+
writeFileIfChanged(path8__default.join(config.outputDir, "tsconfig.json"), TSCONFIG_CONTENT);
|
|
13073
|
+
writeFileIfChanged(path8__default.join(config.outputDir, ".gitignore"), "*\n");
|
|
13033
13074
|
}
|
|
13034
13075
|
function needsRegeneration(config) {
|
|
13035
|
-
const typesPath =
|
|
13036
|
-
if (!
|
|
13076
|
+
const typesPath = path8__default.join(config.outputDir, "types.d.ts");
|
|
13077
|
+
if (!fs8__default.existsSync(typesPath)) {
|
|
13037
13078
|
return true;
|
|
13038
13079
|
}
|
|
13039
|
-
const typesMtime =
|
|
13080
|
+
const typesMtime = fs8__default.statSync(typesPath).mtime;
|
|
13040
13081
|
const dirs = [config.modelsDir, config.promptsDir, config.agentsDir, config.toolsDir, config.hooksDir];
|
|
13041
13082
|
for (const dir of dirs) {
|
|
13042
|
-
if (!
|
|
13083
|
+
if (!fs8__default.existsSync(dir)) {
|
|
13043
13084
|
continue;
|
|
13044
13085
|
}
|
|
13045
|
-
const entries =
|
|
13086
|
+
const entries = fs8__default.readdirSync(dir, { withFileTypes: true });
|
|
13046
13087
|
for (const entry of entries) {
|
|
13047
13088
|
if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
13048
|
-
const filePath =
|
|
13049
|
-
const fileMtime =
|
|
13089
|
+
const filePath = path8__default.join(dir, entry.name);
|
|
13090
|
+
const fileMtime = fs8__default.statSync(filePath).mtime;
|
|
13050
13091
|
if (fileMtime > typesMtime) {
|
|
13051
13092
|
return true;
|
|
13052
13093
|
}
|
|
@@ -13233,7 +13274,7 @@ function createHmrReloader() {
|
|
|
13233
13274
|
versions,
|
|
13234
13275
|
invalidateSourceFileModule(server, filePath) {
|
|
13235
13276
|
if (!filePath) return;
|
|
13236
|
-
const absolutePath =
|
|
13277
|
+
const absolutePath = path8__default.resolve(filePath);
|
|
13237
13278
|
for (const [envName, env] of Object.entries(server.environments)) {
|
|
13238
13279
|
const modules = env.moduleGraph.getModulesByFile(absolutePath);
|
|
13239
13280
|
if (!modules) continue;
|
|
@@ -13244,10 +13285,10 @@ function createHmrReloader() {
|
|
|
13244
13285
|
}
|
|
13245
13286
|
},
|
|
13246
13287
|
invalidateSourceDirectoryModules(server, dirPath) {
|
|
13247
|
-
if (!
|
|
13288
|
+
if (!fs8__default.existsSync(dirPath)) return;
|
|
13248
13289
|
const scan = (currentDir) => {
|
|
13249
|
-
for (const entry of
|
|
13250
|
-
const nextPath =
|
|
13290
|
+
for (const entry of fs8__default.readdirSync(currentDir, { withFileTypes: true })) {
|
|
13291
|
+
const nextPath = path8__default.join(currentDir, entry.name);
|
|
13251
13292
|
if (entry.isDirectory()) {
|
|
13252
13293
|
scan(nextPath);
|
|
13253
13294
|
} else if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
@@ -13399,6 +13440,73 @@ function createHmrReloader() {
|
|
|
13399
13440
|
};
|
|
13400
13441
|
return reloader;
|
|
13401
13442
|
}
|
|
13443
|
+
var STATE_RELATIVE_PATH = path8__default.join(".agents", "bootstrap-session.json");
|
|
13444
|
+
var PROJECT_ROOT_ENV_KEYS = ["INIT_CWD", "PWD", "npm_config_local_prefix"];
|
|
13445
|
+
function uniquePaths(paths) {
|
|
13446
|
+
return Array.from(
|
|
13447
|
+
new Set(
|
|
13448
|
+
paths.filter((value) => !!value?.trim()).map((value) => path8__default.resolve(value))
|
|
13449
|
+
)
|
|
13450
|
+
);
|
|
13451
|
+
}
|
|
13452
|
+
function isBootstrapSessionRoute(routePath) {
|
|
13453
|
+
return routePath === "/api/platform-auth/me" || routePath === "/api/platform-session" || routePath.startsWith("/api/platform-session/");
|
|
13454
|
+
}
|
|
13455
|
+
function hasSessionCookie(cookieHeader) {
|
|
13456
|
+
const raw = Array.isArray(cookieHeader) ? cookieHeader.join("; ") : cookieHeader || "";
|
|
13457
|
+
return /(?:^|;\s*)session=/.test(raw);
|
|
13458
|
+
}
|
|
13459
|
+
function mergeCookieHeader(cookieHeader, injectedCookie) {
|
|
13460
|
+
const raw = Array.isArray(cookieHeader) ? cookieHeader.join("; ") : cookieHeader || "";
|
|
13461
|
+
return raw ? `${raw}; ${injectedCookie}` : injectedCookie;
|
|
13462
|
+
}
|
|
13463
|
+
function loadLocalBootstrapSession(projectRoot) {
|
|
13464
|
+
const statePath = path8__default.join(projectRoot, STATE_RELATIVE_PATH);
|
|
13465
|
+
if (!fs8__default.existsSync(statePath)) return null;
|
|
13466
|
+
try {
|
|
13467
|
+
const parsed = JSON.parse(
|
|
13468
|
+
fs8__default.readFileSync(statePath, "utf-8")
|
|
13469
|
+
);
|
|
13470
|
+
if (parsed.version !== 1) return null;
|
|
13471
|
+
if (!parsed.endpoint || !parsed.user?.id || !parsed.account?.id) return null;
|
|
13472
|
+
if (!parsed.session_cookie || typeof parsed.session_cookie !== "string") return null;
|
|
13473
|
+
return parsed;
|
|
13474
|
+
} catch {
|
|
13475
|
+
return null;
|
|
13476
|
+
}
|
|
13477
|
+
}
|
|
13478
|
+
function loadLocalBootstrapSessionFromEnv(env) {
|
|
13479
|
+
return null;
|
|
13480
|
+
}
|
|
13481
|
+
function findLocalBootstrapSession(projectRoot, env) {
|
|
13482
|
+
const envSession = loadLocalBootstrapSessionFromEnv();
|
|
13483
|
+
if (envSession) {
|
|
13484
|
+
return {
|
|
13485
|
+
projectRoot: projectRoot ? path8__default.resolve(projectRoot) : process.cwd(),
|
|
13486
|
+
session: envSession
|
|
13487
|
+
};
|
|
13488
|
+
}
|
|
13489
|
+
const candidates = uniquePaths([
|
|
13490
|
+
projectRoot,
|
|
13491
|
+
process.cwd(),
|
|
13492
|
+
...PROJECT_ROOT_ENV_KEYS.map((key) => process.env[key])
|
|
13493
|
+
]);
|
|
13494
|
+
for (const candidate of candidates) {
|
|
13495
|
+
const session = loadLocalBootstrapSession(candidate);
|
|
13496
|
+
if (session) {
|
|
13497
|
+
return {
|
|
13498
|
+
projectRoot: candidate,
|
|
13499
|
+
session
|
|
13500
|
+
};
|
|
13501
|
+
}
|
|
13502
|
+
}
|
|
13503
|
+
return null;
|
|
13504
|
+
}
|
|
13505
|
+
function resolveLocalBootstrapCookie(projectRoot, routePath, cookieHeader) {
|
|
13506
|
+
if (!isBootstrapSessionRoute(routePath)) return null;
|
|
13507
|
+
if (hasSessionCookie(cookieHeader)) return null;
|
|
13508
|
+
return findLocalBootstrapSession(projectRoot)?.session.session_cookie ?? null;
|
|
13509
|
+
}
|
|
13402
13510
|
|
|
13403
13511
|
// src/sdk/generators/generateModelFile.ts
|
|
13404
13512
|
function generateModelFile(data, options) {
|
|
@@ -14019,19 +14127,19 @@ function nameToFilename(name) {
|
|
|
14019
14127
|
}
|
|
14020
14128
|
function getModelFilePath(modelsDir, name) {
|
|
14021
14129
|
const filename = nameToFilename(name);
|
|
14022
|
-
return
|
|
14130
|
+
return path8__default.join(modelsDir, `${filename}.ts`);
|
|
14023
14131
|
}
|
|
14024
14132
|
function modelExists(modelsDir, name) {
|
|
14025
14133
|
const filePath = getModelFilePath(modelsDir, name);
|
|
14026
|
-
return
|
|
14134
|
+
return fs8__default.existsSync(filePath);
|
|
14027
14135
|
}
|
|
14028
14136
|
async function saveModel(modelsDir, data, overwrite = false, providerPackageMap = defaultProviderPackageMap) {
|
|
14029
14137
|
try {
|
|
14030
|
-
if (!
|
|
14031
|
-
|
|
14138
|
+
if (!fs8__default.existsSync(modelsDir)) {
|
|
14139
|
+
fs8__default.mkdirSync(modelsDir, { recursive: true });
|
|
14032
14140
|
}
|
|
14033
14141
|
const filePath = getModelFilePath(modelsDir, data.name);
|
|
14034
|
-
if (!overwrite &&
|
|
14142
|
+
if (!overwrite && fs8__default.existsSync(filePath)) {
|
|
14035
14143
|
return {
|
|
14036
14144
|
success: false,
|
|
14037
14145
|
error: `Model file already exists: ${filePath}. Use update to modify existing models.`
|
|
@@ -14048,7 +14156,7 @@ async function saveModel(modelsDir, data, overwrite = false, providerPackageMap
|
|
|
14048
14156
|
providerName: providerInfo.name,
|
|
14049
14157
|
providerPackage: providerInfo.package
|
|
14050
14158
|
});
|
|
14051
|
-
await
|
|
14159
|
+
await fs8__default.promises.writeFile(filePath, content, "utf-8");
|
|
14052
14160
|
return {
|
|
14053
14161
|
success: true,
|
|
14054
14162
|
filePath
|
|
@@ -14063,13 +14171,13 @@ async function saveModel(modelsDir, data, overwrite = false, providerPackageMap
|
|
|
14063
14171
|
async function deleteModel(modelsDir, name) {
|
|
14064
14172
|
try {
|
|
14065
14173
|
const filePath = getModelFilePath(modelsDir, name);
|
|
14066
|
-
if (!
|
|
14174
|
+
if (!fs8__default.existsSync(filePath)) {
|
|
14067
14175
|
return {
|
|
14068
14176
|
success: false,
|
|
14069
14177
|
error: `Model file not found: ${filePath}`
|
|
14070
14178
|
};
|
|
14071
14179
|
}
|
|
14072
|
-
await
|
|
14180
|
+
await fs8__default.promises.unlink(filePath);
|
|
14073
14181
|
return {
|
|
14074
14182
|
success: true,
|
|
14075
14183
|
filePath
|
|
@@ -14330,26 +14438,26 @@ function transformPromptData(data) {
|
|
|
14330
14438
|
}
|
|
14331
14439
|
function getPromptFilePath(promptsDir, name) {
|
|
14332
14440
|
const filename = nameToFilename(name);
|
|
14333
|
-
return
|
|
14441
|
+
return path8__default.join(promptsDir, `${filename}.ts`);
|
|
14334
14442
|
}
|
|
14335
14443
|
function promptExists(promptsDir, name) {
|
|
14336
14444
|
const filePath = getPromptFilePath(promptsDir, name);
|
|
14337
|
-
return
|
|
14445
|
+
return fs8__default.existsSync(filePath);
|
|
14338
14446
|
}
|
|
14339
14447
|
async function savePrompt(promptsDir, data, overwrite = false) {
|
|
14340
14448
|
try {
|
|
14341
|
-
if (!
|
|
14342
|
-
|
|
14449
|
+
if (!fs8__default.existsSync(promptsDir)) {
|
|
14450
|
+
fs8__default.mkdirSync(promptsDir, { recursive: true });
|
|
14343
14451
|
}
|
|
14344
14452
|
const filePath = getPromptFilePath(promptsDir, data.name);
|
|
14345
|
-
if (!overwrite &&
|
|
14453
|
+
if (!overwrite && fs8__default.existsSync(filePath)) {
|
|
14346
14454
|
return {
|
|
14347
14455
|
success: false,
|
|
14348
14456
|
error: `Prompt file already exists: ${filePath}. Use update to modify existing prompts.`
|
|
14349
14457
|
};
|
|
14350
14458
|
}
|
|
14351
14459
|
const content = generatePromptFile(data);
|
|
14352
|
-
await
|
|
14460
|
+
await fs8__default.promises.writeFile(filePath, content, "utf-8");
|
|
14353
14461
|
return {
|
|
14354
14462
|
success: true,
|
|
14355
14463
|
filePath
|
|
@@ -14364,13 +14472,13 @@ async function savePrompt(promptsDir, data, overwrite = false) {
|
|
|
14364
14472
|
async function deletePrompt(promptsDir, name) {
|
|
14365
14473
|
try {
|
|
14366
14474
|
const filePath = getPromptFilePath(promptsDir, name);
|
|
14367
|
-
if (!
|
|
14475
|
+
if (!fs8__default.existsSync(filePath)) {
|
|
14368
14476
|
return {
|
|
14369
14477
|
success: false,
|
|
14370
14478
|
error: `Prompt file not found: ${filePath}`
|
|
14371
14479
|
};
|
|
14372
14480
|
}
|
|
14373
|
-
await
|
|
14481
|
+
await fs8__default.promises.unlink(filePath);
|
|
14374
14482
|
return {
|
|
14375
14483
|
success: true,
|
|
14376
14484
|
filePath
|
|
@@ -14386,25 +14494,25 @@ async function renamePrompt(promptsDir, oldName, newName) {
|
|
|
14386
14494
|
try {
|
|
14387
14495
|
const oldFilePath = getPromptFilePath(promptsDir, oldName);
|
|
14388
14496
|
const newFilePath = getPromptFilePath(promptsDir, newName);
|
|
14389
|
-
if (!
|
|
14497
|
+
if (!fs8__default.existsSync(oldFilePath)) {
|
|
14390
14498
|
return {
|
|
14391
14499
|
success: false,
|
|
14392
14500
|
error: `Prompt file not found: ${oldFilePath}`
|
|
14393
14501
|
};
|
|
14394
14502
|
}
|
|
14395
|
-
if (
|
|
14503
|
+
if (fs8__default.existsSync(newFilePath)) {
|
|
14396
14504
|
return {
|
|
14397
14505
|
success: false,
|
|
14398
14506
|
error: `Prompt file already exists: ${newFilePath}`
|
|
14399
14507
|
};
|
|
14400
14508
|
}
|
|
14401
|
-
const content = await
|
|
14509
|
+
const content = await fs8__default.promises.readFile(oldFilePath, "utf-8");
|
|
14402
14510
|
const updatedContent = content.replace(
|
|
14403
14511
|
/name:\s*['"]([^'"]+)['"]/,
|
|
14404
14512
|
`name: '${newName}'`
|
|
14405
14513
|
);
|
|
14406
|
-
await
|
|
14407
|
-
await
|
|
14514
|
+
await fs8__default.promises.writeFile(newFilePath, updatedContent, "utf-8");
|
|
14515
|
+
await fs8__default.promises.unlink(oldFilePath);
|
|
14408
14516
|
return {
|
|
14409
14517
|
success: true,
|
|
14410
14518
|
filePath: newFilePath
|
|
@@ -14704,15 +14812,15 @@ function transformAgentData(data) {
|
|
|
14704
14812
|
}
|
|
14705
14813
|
function getAgentFilePath(agentsDir, name) {
|
|
14706
14814
|
const filename = nameToFilename(name);
|
|
14707
|
-
return
|
|
14815
|
+
return path8__default.join(agentsDir, `${filename}.ts`);
|
|
14708
14816
|
}
|
|
14709
14817
|
function agentExists(agentsDir, name) {
|
|
14710
14818
|
const filePath = getAgentFilePath(agentsDir, name);
|
|
14711
|
-
return
|
|
14819
|
+
return fs8__default.existsSync(filePath);
|
|
14712
14820
|
}
|
|
14713
14821
|
function extractAgentMetadata(filePath) {
|
|
14714
14822
|
try {
|
|
14715
|
-
const content =
|
|
14823
|
+
const content = fs8__default.readFileSync(filePath, "utf-8");
|
|
14716
14824
|
const metadata = {};
|
|
14717
14825
|
const packageNameMatch = content.match(/packageName:\s*['"]([^'"]+)['"]/);
|
|
14718
14826
|
if (packageNameMatch) metadata.packageName = packageNameMatch[1];
|
|
@@ -14729,17 +14837,17 @@ function extractAgentMetadata(filePath) {
|
|
|
14729
14837
|
}
|
|
14730
14838
|
async function saveAgent(agentsDir, data, overwrite = false) {
|
|
14731
14839
|
try {
|
|
14732
|
-
if (!
|
|
14733
|
-
|
|
14840
|
+
if (!fs8__default.existsSync(agentsDir)) {
|
|
14841
|
+
fs8__default.mkdirSync(agentsDir, { recursive: true });
|
|
14734
14842
|
}
|
|
14735
14843
|
const filePath = getAgentFilePath(agentsDir, data.name);
|
|
14736
|
-
if (!overwrite &&
|
|
14844
|
+
if (!overwrite && fs8__default.existsSync(filePath)) {
|
|
14737
14845
|
return {
|
|
14738
14846
|
success: false,
|
|
14739
14847
|
error: `Agent file already exists: ${filePath}. Use update to modify existing agents.`
|
|
14740
14848
|
};
|
|
14741
14849
|
}
|
|
14742
|
-
if (overwrite &&
|
|
14850
|
+
if (overwrite && fs8__default.existsSync(filePath)) {
|
|
14743
14851
|
const existingMetadata = extractAgentMetadata(filePath);
|
|
14744
14852
|
if (existingMetadata.packageName && !data.packageName) {
|
|
14745
14853
|
data.packageName = existingMetadata.packageName;
|
|
@@ -14755,7 +14863,7 @@ async function saveAgent(agentsDir, data, overwrite = false) {
|
|
|
14755
14863
|
}
|
|
14756
14864
|
}
|
|
14757
14865
|
const content = generateAgentFile(data);
|
|
14758
|
-
await
|
|
14866
|
+
await fs8__default.promises.writeFile(filePath, content, "utf-8");
|
|
14759
14867
|
return {
|
|
14760
14868
|
success: true,
|
|
14761
14869
|
filePath
|
|
@@ -14770,13 +14878,13 @@ async function saveAgent(agentsDir, data, overwrite = false) {
|
|
|
14770
14878
|
async function deleteAgent(agentsDir, name) {
|
|
14771
14879
|
try {
|
|
14772
14880
|
const filePath = getAgentFilePath(agentsDir, name);
|
|
14773
|
-
if (!
|
|
14881
|
+
if (!fs8__default.existsSync(filePath)) {
|
|
14774
14882
|
return {
|
|
14775
14883
|
success: false,
|
|
14776
14884
|
error: `Agent file not found: ${filePath}`
|
|
14777
14885
|
};
|
|
14778
14886
|
}
|
|
14779
|
-
await
|
|
14887
|
+
await fs8__default.promises.unlink(filePath);
|
|
14780
14888
|
return {
|
|
14781
14889
|
success: true,
|
|
14782
14890
|
filePath
|
|
@@ -14792,25 +14900,25 @@ async function renameModel(modelsDir, oldName, newName) {
|
|
|
14792
14900
|
try {
|
|
14793
14901
|
const oldFilePath = getModelFilePath(modelsDir, oldName);
|
|
14794
14902
|
const newFilePath = getModelFilePath(modelsDir, newName);
|
|
14795
|
-
if (!
|
|
14903
|
+
if (!fs8__default.existsSync(oldFilePath)) {
|
|
14796
14904
|
return {
|
|
14797
14905
|
success: false,
|
|
14798
14906
|
error: `Model file not found: ${oldFilePath}`
|
|
14799
14907
|
};
|
|
14800
14908
|
}
|
|
14801
|
-
if (
|
|
14909
|
+
if (fs8__default.existsSync(newFilePath)) {
|
|
14802
14910
|
return {
|
|
14803
14911
|
success: false,
|
|
14804
14912
|
error: `Model file already exists: ${newFilePath}`
|
|
14805
14913
|
};
|
|
14806
14914
|
}
|
|
14807
|
-
const content = await
|
|
14915
|
+
const content = await fs8__default.promises.readFile(oldFilePath, "utf-8");
|
|
14808
14916
|
const updatedContent = content.replace(
|
|
14809
14917
|
/name:\s*['"]([^'"]+)['"]/,
|
|
14810
14918
|
`name: '${newName}'`
|
|
14811
14919
|
);
|
|
14812
|
-
await
|
|
14813
|
-
await
|
|
14920
|
+
await fs8__default.promises.writeFile(newFilePath, updatedContent, "utf-8");
|
|
14921
|
+
await fs8__default.promises.unlink(oldFilePath);
|
|
14814
14922
|
return {
|
|
14815
14923
|
success: true,
|
|
14816
14924
|
filePath: newFilePath
|
|
@@ -14824,17 +14932,17 @@ async function renameModel(modelsDir, oldName, newName) {
|
|
|
14824
14932
|
}
|
|
14825
14933
|
async function updateModelReferencesInPrompts(promptsDir, oldModelName, newModelName) {
|
|
14826
14934
|
const updatedFiles = [];
|
|
14827
|
-
if (!
|
|
14935
|
+
if (!fs8__default.existsSync(promptsDir)) {
|
|
14828
14936
|
return updatedFiles;
|
|
14829
14937
|
}
|
|
14830
|
-
const files =
|
|
14938
|
+
const files = fs8__default.readdirSync(promptsDir).filter((f) => f.endsWith(".ts"));
|
|
14831
14939
|
for (const file of files) {
|
|
14832
|
-
const filePath =
|
|
14833
|
-
let content = await
|
|
14940
|
+
const filePath = path8__default.join(promptsDir, file);
|
|
14941
|
+
let content = await fs8__default.promises.readFile(filePath, "utf-8");
|
|
14834
14942
|
const modelRegex = new RegExp(`model:\\s*['"]${escapeRegExp(oldModelName)}['"]`, "g");
|
|
14835
14943
|
if (modelRegex.test(content)) {
|
|
14836
14944
|
content = content.replace(modelRegex, `model: '${newModelName}'`);
|
|
14837
|
-
await
|
|
14945
|
+
await fs8__default.promises.writeFile(filePath, content, "utf-8");
|
|
14838
14946
|
updatedFiles.push(filePath);
|
|
14839
14947
|
}
|
|
14840
14948
|
}
|
|
@@ -14842,13 +14950,13 @@ async function updateModelReferencesInPrompts(promptsDir, oldModelName, newModel
|
|
|
14842
14950
|
}
|
|
14843
14951
|
async function updatePromptReferencesInPrompts(promptsDir, oldPromptName, newPromptName) {
|
|
14844
14952
|
const updatedFiles = [];
|
|
14845
|
-
if (!
|
|
14953
|
+
if (!fs8__default.existsSync(promptsDir)) {
|
|
14846
14954
|
return updatedFiles;
|
|
14847
14955
|
}
|
|
14848
|
-
const files =
|
|
14956
|
+
const files = fs8__default.readdirSync(promptsDir).filter((f) => f.endsWith(".ts"));
|
|
14849
14957
|
for (const file of files) {
|
|
14850
|
-
const filePath =
|
|
14851
|
-
let content = await
|
|
14958
|
+
const filePath = path8__default.join(promptsDir, file);
|
|
14959
|
+
let content = await fs8__default.promises.readFile(filePath, "utf-8");
|
|
14852
14960
|
let modified = false;
|
|
14853
14961
|
const toolsArrayRegex = /tools:\s*\[([^\]]*)\]/gs;
|
|
14854
14962
|
const newContent = content.replace(toolsArrayRegex, (match) => {
|
|
@@ -14861,7 +14969,7 @@ async function updatePromptReferencesInPrompts(promptsDir, oldPromptName, newPro
|
|
|
14861
14969
|
return replaced;
|
|
14862
14970
|
});
|
|
14863
14971
|
if (modified) {
|
|
14864
|
-
await
|
|
14972
|
+
await fs8__default.promises.writeFile(filePath, newContent, "utf-8");
|
|
14865
14973
|
updatedFiles.push(filePath);
|
|
14866
14974
|
}
|
|
14867
14975
|
}
|
|
@@ -14869,17 +14977,17 @@ async function updatePromptReferencesInPrompts(promptsDir, oldPromptName, newPro
|
|
|
14869
14977
|
}
|
|
14870
14978
|
async function updatePromptReferencesInAgents(agentsDir, oldPromptName, newPromptName) {
|
|
14871
14979
|
const updatedFiles = [];
|
|
14872
|
-
if (!
|
|
14980
|
+
if (!fs8__default.existsSync(agentsDir)) {
|
|
14873
14981
|
return updatedFiles;
|
|
14874
14982
|
}
|
|
14875
|
-
const files =
|
|
14983
|
+
const files = fs8__default.readdirSync(agentsDir).filter((f) => f.endsWith(".ts"));
|
|
14876
14984
|
for (const file of files) {
|
|
14877
|
-
const filePath =
|
|
14878
|
-
let content = await
|
|
14985
|
+
const filePath = path8__default.join(agentsDir, file);
|
|
14986
|
+
let content = await fs8__default.promises.readFile(filePath, "utf-8");
|
|
14879
14987
|
const promptRegex = new RegExp(`prompt:\\s*['"]${escapeRegExp(oldPromptName)}['"]`, "g");
|
|
14880
14988
|
if (promptRegex.test(content)) {
|
|
14881
14989
|
content = content.replace(promptRegex, `prompt: '${newPromptName}'`);
|
|
14882
|
-
await
|
|
14990
|
+
await fs8__default.promises.writeFile(filePath, content, "utf-8");
|
|
14883
14991
|
updatedFiles.push(filePath);
|
|
14884
14992
|
}
|
|
14885
14993
|
}
|
|
@@ -15006,16 +15114,16 @@ function parseThreadEndpointRouteKey(input) {
|
|
|
15006
15114
|
};
|
|
15007
15115
|
}
|
|
15008
15116
|
function scanThreadEndpointFiles(dir, options = {}) {
|
|
15009
|
-
if (!
|
|
15117
|
+
if (!fs8__default.existsSync(dir)) {
|
|
15010
15118
|
return [];
|
|
15011
15119
|
}
|
|
15012
15120
|
const extensions = options.extensions ?? [".ts"];
|
|
15013
15121
|
const routes = [];
|
|
15014
15122
|
const scan = (currentDir, relativeDir = "") => {
|
|
15015
|
-
const entries =
|
|
15123
|
+
const entries = fs8__default.readdirSync(currentDir, { withFileTypes: true });
|
|
15016
15124
|
for (const entry of entries) {
|
|
15017
|
-
const filePath =
|
|
15018
|
-
const relativePath = relativeDir ?
|
|
15125
|
+
const filePath = path8__default.join(currentDir, entry.name);
|
|
15126
|
+
const relativePath = relativeDir ? path8__default.posix.join(relativeDir, entry.name) : entry.name;
|
|
15019
15127
|
if (entry.isDirectory()) {
|
|
15020
15128
|
scan(filePath, relativePath);
|
|
15021
15129
|
continue;
|
|
@@ -15049,7 +15157,7 @@ function scanApiDirectory(dir) {
|
|
|
15049
15157
|
try {
|
|
15050
15158
|
return scanThreadEndpointFiles(dir, {
|
|
15051
15159
|
extensions: [".ts"],
|
|
15052
|
-
importPathForFile: (filePath) => "./" +
|
|
15160
|
+
importPathForFile: (filePath) => "./" + path8__default.relative(process.cwd(), filePath).replace(/\\/g, "/")
|
|
15053
15161
|
}).map(({ method, route, importPath }) => ({
|
|
15054
15162
|
method,
|
|
15055
15163
|
route,
|
|
@@ -15061,26 +15169,26 @@ function scanApiDirectory(dir) {
|
|
|
15061
15169
|
}
|
|
15062
15170
|
}
|
|
15063
15171
|
function discoverPackedPackageDirectories(packedDir) {
|
|
15064
|
-
if (!
|
|
15172
|
+
if (!fs8__default.existsSync(packedDir)) {
|
|
15065
15173
|
return [];
|
|
15066
15174
|
}
|
|
15067
15175
|
const packageDirs = [];
|
|
15068
|
-
const entries =
|
|
15176
|
+
const entries = fs8__default.readdirSync(packedDir, { withFileTypes: true }).filter((entry) => entry.isDirectory());
|
|
15069
15177
|
for (const entry of entries) {
|
|
15070
|
-
const fullPath =
|
|
15071
|
-
const packageJsonPath =
|
|
15072
|
-
if (
|
|
15178
|
+
const fullPath = path8__default.join(packedDir, entry.name);
|
|
15179
|
+
const packageJsonPath = path8__default.join(fullPath, "package.json");
|
|
15180
|
+
if (fs8__default.existsSync(packageJsonPath)) {
|
|
15073
15181
|
packageDirs.push(fullPath);
|
|
15074
15182
|
continue;
|
|
15075
15183
|
}
|
|
15076
15184
|
if (!entry.name.startsWith("@")) {
|
|
15077
15185
|
continue;
|
|
15078
15186
|
}
|
|
15079
|
-
const scopedEntries =
|
|
15187
|
+
const scopedEntries = fs8__default.readdirSync(fullPath, { withFileTypes: true }).filter((scopedEntry) => scopedEntry.isDirectory());
|
|
15080
15188
|
for (const scopedEntry of scopedEntries) {
|
|
15081
|
-
const scopedPackagePath =
|
|
15082
|
-
const scopedPackageJson =
|
|
15083
|
-
if (
|
|
15189
|
+
const scopedPackagePath = path8__default.join(fullPath, scopedEntry.name);
|
|
15190
|
+
const scopedPackageJson = path8__default.join(scopedPackagePath, "package.json");
|
|
15191
|
+
if (fs8__default.existsSync(scopedPackageJson)) {
|
|
15084
15192
|
packageDirs.push(scopedPackagePath);
|
|
15085
15193
|
}
|
|
15086
15194
|
}
|
|
@@ -15088,26 +15196,26 @@ function discoverPackedPackageDirectories(packedDir) {
|
|
|
15088
15196
|
return packageDirs;
|
|
15089
15197
|
}
|
|
15090
15198
|
function scanPackedDistDirectory(packagePath, outputDir, subDir) {
|
|
15091
|
-
const fullPath =
|
|
15092
|
-
if (!
|
|
15199
|
+
const fullPath = path8__default.join(packagePath, outputDir, subDir);
|
|
15200
|
+
if (!fs8__default.existsSync(fullPath)) {
|
|
15093
15201
|
return [];
|
|
15094
15202
|
}
|
|
15095
|
-
return
|
|
15203
|
+
return fs8__default.readdirSync(fullPath).filter((fileName) => fileName.endsWith(".js") || fileName.endsWith(".ts")).map((fileName) => ({
|
|
15096
15204
|
name: fileName.replace(/\.(js|ts)$/, ""),
|
|
15097
|
-
path:
|
|
15205
|
+
path: path8__default.join(fullPath, fileName).replace(/\\/g, "/")
|
|
15098
15206
|
}));
|
|
15099
15207
|
}
|
|
15100
15208
|
function scanPackedThreadEndpoints(packagePath, outputDir) {
|
|
15101
|
-
const rootDir =
|
|
15102
|
-
if (!
|
|
15209
|
+
const rootDir = path8__default.join(packagePath, outputDir, "thread-endpoints");
|
|
15210
|
+
if (!fs8__default.existsSync(rootDir)) {
|
|
15103
15211
|
return [];
|
|
15104
15212
|
}
|
|
15105
15213
|
const endpoints = [];
|
|
15106
15214
|
const scan = (dir, relativeDir = "") => {
|
|
15107
|
-
const entries =
|
|
15215
|
+
const entries = fs8__default.readdirSync(dir, { withFileTypes: true });
|
|
15108
15216
|
for (const entry of entries) {
|
|
15109
|
-
const nextRelative = relativeDir ?
|
|
15110
|
-
const absolutePath =
|
|
15217
|
+
const nextRelative = relativeDir ? path8__default.posix.join(relativeDir, entry.name) : entry.name;
|
|
15218
|
+
const absolutePath = path8__default.join(dir, entry.name);
|
|
15111
15219
|
if (entry.isDirectory()) {
|
|
15112
15220
|
scan(absolutePath, nextRelative);
|
|
15113
15221
|
continue;
|
|
@@ -15137,7 +15245,7 @@ function isSnakeCase(str) {
|
|
|
15137
15245
|
}
|
|
15138
15246
|
function validateToolFile(filePath, fileName) {
|
|
15139
15247
|
try {
|
|
15140
|
-
const content =
|
|
15248
|
+
const content = fs8__default.readFileSync(filePath, "utf-8");
|
|
15141
15249
|
const hasDefaultExport = /export\s+default\s+defineTool/.test(content);
|
|
15142
15250
|
if (!hasDefaultExport) {
|
|
15143
15251
|
return `Tool file '${fileName}.ts' must have a default export using defineTool()`;
|
|
@@ -15149,15 +15257,15 @@ function validateToolFile(filePath, fileName) {
|
|
|
15149
15257
|
}
|
|
15150
15258
|
async function scanToolsDirectory(dir) {
|
|
15151
15259
|
const tools = [];
|
|
15152
|
-
if (!
|
|
15260
|
+
if (!fs8__default.existsSync(dir)) {
|
|
15153
15261
|
return tools;
|
|
15154
15262
|
}
|
|
15155
|
-
const entries = await
|
|
15263
|
+
const entries = await fs8__default.promises.readdir(dir, { withFileTypes: true });
|
|
15156
15264
|
for (const entry of entries) {
|
|
15157
15265
|
if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
15158
15266
|
const fileName = entry.name.replace(".ts", "");
|
|
15159
|
-
const filePath =
|
|
15160
|
-
const importPath = "./" +
|
|
15267
|
+
const filePath = path8__default.join(dir, entry.name);
|
|
15268
|
+
const importPath = "./" + path8__default.relative(process.cwd(), filePath).replace(/\\/g, "/");
|
|
15161
15269
|
let toolError;
|
|
15162
15270
|
const validationError = validateToolFile(filePath, fileName);
|
|
15163
15271
|
if (validationError) {
|
|
@@ -15184,18 +15292,18 @@ async function scanToolsDirectory(dir) {
|
|
|
15184
15292
|
}
|
|
15185
15293
|
async function scanHooksDirectory(dir) {
|
|
15186
15294
|
const hooks = [];
|
|
15187
|
-
if (!
|
|
15295
|
+
if (!fs8__default.existsSync(dir)) {
|
|
15188
15296
|
return hooks;
|
|
15189
15297
|
}
|
|
15190
|
-
const entries = await
|
|
15298
|
+
const entries = await fs8__default.promises.readdir(dir, { withFileTypes: true });
|
|
15191
15299
|
for (const entry of entries) {
|
|
15192
15300
|
if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
15193
15301
|
const fileName = entry.name.replace(".ts", "");
|
|
15194
15302
|
if (fileName === "index") continue;
|
|
15195
|
-
const filePath =
|
|
15196
|
-
const importPath = "./" +
|
|
15303
|
+
const filePath = path8__default.join(dir, entry.name);
|
|
15304
|
+
const importPath = "./" + path8__default.relative(process.cwd(), filePath).replace(/\\/g, "/");
|
|
15197
15305
|
try {
|
|
15198
|
-
const content =
|
|
15306
|
+
const content = fs8__default.readFileSync(filePath, "utf-8");
|
|
15199
15307
|
const idMatch = content.match(/id:\s*['"]([^'"]+)['"]/);
|
|
15200
15308
|
const hookMatch = content.match(/hook:\s*['"]([^'"]+)['"]/);
|
|
15201
15309
|
if (idMatch && hookMatch) {
|
|
@@ -15218,16 +15326,16 @@ async function scanHooksDirectory(dir) {
|
|
|
15218
15326
|
}
|
|
15219
15327
|
async function scanConfigDirectory(dir, definePattern) {
|
|
15220
15328
|
const items = [];
|
|
15221
|
-
if (!
|
|
15329
|
+
if (!fs8__default.existsSync(dir)) {
|
|
15222
15330
|
return items;
|
|
15223
15331
|
}
|
|
15224
|
-
const entries = await
|
|
15332
|
+
const entries = await fs8__default.promises.readdir(dir, { withFileTypes: true });
|
|
15225
15333
|
for (const entry of entries) {
|
|
15226
15334
|
if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
15227
|
-
const filePath =
|
|
15228
|
-
const importPath = "./" +
|
|
15335
|
+
const filePath = path8__default.join(dir, entry.name);
|
|
15336
|
+
const importPath = "./" + path8__default.relative(process.cwd(), filePath).replace(/\\/g, "/");
|
|
15229
15337
|
try {
|
|
15230
|
-
const content =
|
|
15338
|
+
const content = fs8__default.readFileSync(filePath, "utf-8");
|
|
15231
15339
|
const hasDefaultExport = definePattern.test(content);
|
|
15232
15340
|
if (!hasDefaultExport) {
|
|
15233
15341
|
items.push({
|
|
@@ -15269,20 +15377,20 @@ async function scanAgentsDirectory(dir) {
|
|
|
15269
15377
|
}
|
|
15270
15378
|
async function scanEffectsDirectory(dir) {
|
|
15271
15379
|
const effects = [];
|
|
15272
|
-
if (!
|
|
15380
|
+
if (!fs8__default.existsSync(dir)) {
|
|
15273
15381
|
return effects;
|
|
15274
15382
|
}
|
|
15275
|
-
const entries = await
|
|
15383
|
+
const entries = await fs8__default.promises.readdir(dir, { withFileTypes: true });
|
|
15276
15384
|
for (const entry of entries) {
|
|
15277
15385
|
if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
15278
15386
|
const fileName = entry.name.replace(".ts", "");
|
|
15279
|
-
const filePath =
|
|
15280
|
-
const importPath = "./" +
|
|
15387
|
+
const filePath = path8__default.join(dir, entry.name);
|
|
15388
|
+
const importPath = "./" + path8__default.relative(process.cwd(), filePath).replace(/\\/g, "/");
|
|
15281
15389
|
if (fileName === "CLAUDE" || fileName.startsWith("_")) {
|
|
15282
15390
|
continue;
|
|
15283
15391
|
}
|
|
15284
15392
|
try {
|
|
15285
|
-
const content =
|
|
15393
|
+
const content = fs8__default.readFileSync(filePath, "utf-8");
|
|
15286
15394
|
if (!content.includes("defineEffect")) {
|
|
15287
15395
|
continue;
|
|
15288
15396
|
}
|
|
@@ -15769,7 +15877,7 @@ var MetadataService = class {
|
|
|
15769
15877
|
* @param agentsDir - Path to the agents/ directory
|
|
15770
15878
|
*/
|
|
15771
15879
|
constructor(agentsDir) {
|
|
15772
|
-
this.metadataDir =
|
|
15880
|
+
this.metadataDir = path8.join(agentsDir, ".standardagent");
|
|
15773
15881
|
}
|
|
15774
15882
|
/**
|
|
15775
15883
|
* Read metadata for an agent.
|
|
@@ -15779,11 +15887,11 @@ var MetadataService = class {
|
|
|
15779
15887
|
*/
|
|
15780
15888
|
async read(agentName) {
|
|
15781
15889
|
const filePath = this.getMetadataPath(agentName);
|
|
15782
|
-
if (!
|
|
15890
|
+
if (!fs8.existsSync(filePath)) {
|
|
15783
15891
|
return null;
|
|
15784
15892
|
}
|
|
15785
15893
|
try {
|
|
15786
|
-
const content =
|
|
15894
|
+
const content = fs8.readFileSync(filePath, "utf-8");
|
|
15787
15895
|
return JSON.parse(content);
|
|
15788
15896
|
} catch {
|
|
15789
15897
|
return null;
|
|
@@ -15796,11 +15904,11 @@ var MetadataService = class {
|
|
|
15796
15904
|
* @param metadata - Metadata to write
|
|
15797
15905
|
*/
|
|
15798
15906
|
async write(agentName, metadata) {
|
|
15799
|
-
if (!
|
|
15800
|
-
|
|
15907
|
+
if (!fs8.existsSync(this.metadataDir)) {
|
|
15908
|
+
fs8.mkdirSync(this.metadataDir, { recursive: true });
|
|
15801
15909
|
}
|
|
15802
15910
|
const filePath = this.getMetadataPath(agentName);
|
|
15803
|
-
|
|
15911
|
+
fs8.writeFileSync(filePath, JSON.stringify(metadata, null, 2));
|
|
15804
15912
|
}
|
|
15805
15913
|
/**
|
|
15806
15914
|
* Delete metadata for an agent.
|
|
@@ -15809,8 +15917,8 @@ var MetadataService = class {
|
|
|
15809
15917
|
*/
|
|
15810
15918
|
async delete(agentName) {
|
|
15811
15919
|
const filePath = this.getMetadataPath(agentName);
|
|
15812
|
-
if (
|
|
15813
|
-
|
|
15920
|
+
if (fs8.existsSync(filePath)) {
|
|
15921
|
+
fs8.unlinkSync(filePath);
|
|
15814
15922
|
}
|
|
15815
15923
|
}
|
|
15816
15924
|
/**
|
|
@@ -15891,7 +15999,7 @@ var MetadataService = class {
|
|
|
15891
15999
|
* Get the file path for an agent's metadata.
|
|
15892
16000
|
*/
|
|
15893
16001
|
getMetadataPath(agentName) {
|
|
15894
|
-
return
|
|
16002
|
+
return path8.join(this.metadataDir, `${agentName}.json`);
|
|
15895
16003
|
}
|
|
15896
16004
|
};
|
|
15897
16005
|
var _ts;
|
|
@@ -16263,9 +16371,9 @@ var PackingService = class {
|
|
|
16263
16371
|
* @returns Version specifier (e.g., '^1.2.3') or '*' if not found
|
|
16264
16372
|
*/
|
|
16265
16373
|
resolvePackageVersion(pkgName, rootDir) {
|
|
16266
|
-
const pkgJsonPath =
|
|
16374
|
+
const pkgJsonPath = path8.join(rootDir, "node_modules", pkgName, "package.json");
|
|
16267
16375
|
try {
|
|
16268
|
-
const pkgJson = JSON.parse(
|
|
16376
|
+
const pkgJson = JSON.parse(fs8.readFileSync(pkgJsonPath, "utf-8"));
|
|
16269
16377
|
return `^${pkgJson.version}`;
|
|
16270
16378
|
} catch {
|
|
16271
16379
|
return "*";
|
|
@@ -16282,7 +16390,7 @@ var PackingService = class {
|
|
|
16282
16390
|
* @returns Analysis result with all discovered constituents
|
|
16283
16391
|
*/
|
|
16284
16392
|
async analyzeAgent(agentName, rootDir) {
|
|
16285
|
-
const agentsDir =
|
|
16393
|
+
const agentsDir = path8.join(rootDir, "agents");
|
|
16286
16394
|
const analysis = {
|
|
16287
16395
|
agent: agentName,
|
|
16288
16396
|
primaryPrompt: "",
|
|
@@ -16306,7 +16414,7 @@ var PackingService = class {
|
|
|
16306
16414
|
warnings: [],
|
|
16307
16415
|
errors: []
|
|
16308
16416
|
};
|
|
16309
|
-
const agentFilePath = await this.findFile(
|
|
16417
|
+
const agentFilePath = await this.findFile(path8.join(agentsDir, "agents"), agentName);
|
|
16310
16418
|
if (!agentFilePath) {
|
|
16311
16419
|
analysis.errors.push(`Agent file not found: ${agentName}`);
|
|
16312
16420
|
return analysis;
|
|
@@ -16317,7 +16425,7 @@ var PackingService = class {
|
|
|
16317
16425
|
discoveredVia: "static",
|
|
16318
16426
|
sharedWith: []
|
|
16319
16427
|
});
|
|
16320
|
-
const agentSource =
|
|
16428
|
+
const agentSource = fs8.readFileSync(agentFilePath, "utf-8");
|
|
16321
16429
|
const agentPrompts = await extractAgentPrompts(agentSource);
|
|
16322
16430
|
if (agentPrompts.sideA) {
|
|
16323
16431
|
analysis.primaryPrompt = agentPrompts.sideA;
|
|
@@ -16342,13 +16450,13 @@ var PackingService = class {
|
|
|
16342
16450
|
* @returns Object with generatedReadme and agentDescription
|
|
16343
16451
|
*/
|
|
16344
16452
|
async generateReadmeForAnalysis(analysis, rootDir) {
|
|
16345
|
-
const agentsDir =
|
|
16453
|
+
const agentsDir = path8.join(rootDir, "agents");
|
|
16346
16454
|
const metadataService = new MetadataService(agentsDir);
|
|
16347
16455
|
let agentDescription;
|
|
16348
16456
|
const agentItem = analysis.constituents.agents.find((a) => a.name === analysis.agent);
|
|
16349
16457
|
if (agentItem?.filePath) {
|
|
16350
16458
|
try {
|
|
16351
|
-
const agentSource =
|
|
16459
|
+
const agentSource = fs8.readFileSync(agentItem.filePath, "utf-8");
|
|
16352
16460
|
agentDescription = await extractAgentDescription(agentSource) || void 0;
|
|
16353
16461
|
} catch {
|
|
16354
16462
|
}
|
|
@@ -16372,7 +16480,7 @@ var PackingService = class {
|
|
|
16372
16480
|
* include all endpoint modules discovered under agents/api.
|
|
16373
16481
|
*/
|
|
16374
16482
|
async analyzeThreadEndpoints(agentsDir, analysis) {
|
|
16375
|
-
const apiDir =
|
|
16483
|
+
const apiDir = path8.join(agentsDir, "api");
|
|
16376
16484
|
const endpoints = this.scanThreadEndpointFiles(apiDir);
|
|
16377
16485
|
for (const endpoint of endpoints) {
|
|
16378
16486
|
if (analysis.constituents.threadEndpoints.some((item) => item.name === endpoint.name)) {
|
|
@@ -16394,15 +16502,15 @@ var PackingService = class {
|
|
|
16394
16502
|
* - `admin/users/[userId]/sync.post`
|
|
16395
16503
|
*/
|
|
16396
16504
|
scanThreadEndpointFiles(apiDir, relativeDir = "") {
|
|
16397
|
-
if (!
|
|
16505
|
+
if (!fs8.existsSync(apiDir)) {
|
|
16398
16506
|
return [];
|
|
16399
16507
|
}
|
|
16400
16508
|
const endpoints = [];
|
|
16401
|
-
const currentDir = relativeDir ?
|
|
16402
|
-
if (!
|
|
16509
|
+
const currentDir = relativeDir ? path8.join(apiDir, relativeDir) : apiDir;
|
|
16510
|
+
if (!fs8.existsSync(currentDir)) {
|
|
16403
16511
|
return endpoints;
|
|
16404
16512
|
}
|
|
16405
|
-
const entries =
|
|
16513
|
+
const entries = fs8.readdirSync(currentDir, { withFileTypes: true });
|
|
16406
16514
|
if (entries.length > 0 && typeof entries[0] === "string") {
|
|
16407
16515
|
return endpoints;
|
|
16408
16516
|
}
|
|
@@ -16410,8 +16518,8 @@ var PackingService = class {
|
|
|
16410
16518
|
const entryName = typeof entry === "string" ? entry : entry.name;
|
|
16411
16519
|
const isDirectory = typeof entry === "string" ? false : entry.isDirectory();
|
|
16412
16520
|
const isFile = typeof entry === "string" ? true : entry.isFile();
|
|
16413
|
-
const entryRelative = relativeDir ?
|
|
16414
|
-
const absolutePath =
|
|
16521
|
+
const entryRelative = relativeDir ? path8.posix.join(relativeDir.replace(/\\/g, "/"), entryName) : entryName;
|
|
16522
|
+
const absolutePath = path8.join(apiDir, entryRelative);
|
|
16415
16523
|
if (isDirectory) {
|
|
16416
16524
|
endpoints.push(...this.scanThreadEndpointFiles(apiDir, entryRelative));
|
|
16417
16525
|
continue;
|
|
@@ -16438,7 +16546,7 @@ var PackingService = class {
|
|
|
16438
16546
|
* include all effect modules discovered under agents/effects.
|
|
16439
16547
|
*/
|
|
16440
16548
|
async analyzeEffects(agentsDir, analysis) {
|
|
16441
|
-
const effectsDir =
|
|
16549
|
+
const effectsDir = path8.join(agentsDir, "effects");
|
|
16442
16550
|
const effects = this.scanEffectFiles(effectsDir);
|
|
16443
16551
|
for (const effect of effects) {
|
|
16444
16552
|
if (analysis.constituents.effects.some((item) => item.name === effect.name)) {
|
|
@@ -16460,15 +16568,15 @@ var PackingService = class {
|
|
|
16460
16568
|
* - `notifications/digest`
|
|
16461
16569
|
*/
|
|
16462
16570
|
scanEffectFiles(effectsDir, relativeDir = "") {
|
|
16463
|
-
if (!
|
|
16571
|
+
if (!fs8.existsSync(effectsDir)) {
|
|
16464
16572
|
return [];
|
|
16465
16573
|
}
|
|
16466
16574
|
const effects = [];
|
|
16467
|
-
const currentDir = relativeDir ?
|
|
16468
|
-
if (!
|
|
16575
|
+
const currentDir = relativeDir ? path8.join(effectsDir, relativeDir) : effectsDir;
|
|
16576
|
+
if (!fs8.existsSync(currentDir)) {
|
|
16469
16577
|
return effects;
|
|
16470
16578
|
}
|
|
16471
|
-
const entries =
|
|
16579
|
+
const entries = fs8.readdirSync(currentDir, { withFileTypes: true });
|
|
16472
16580
|
if (entries.length > 0 && typeof entries[0] === "string") {
|
|
16473
16581
|
return effects;
|
|
16474
16582
|
}
|
|
@@ -16476,8 +16584,8 @@ var PackingService = class {
|
|
|
16476
16584
|
const entryName = typeof entry === "string" ? entry : entry.name;
|
|
16477
16585
|
const isDirectory = typeof entry === "string" ? false : entry.isDirectory();
|
|
16478
16586
|
const isFile = typeof entry === "string" ? true : entry.isFile();
|
|
16479
|
-
const entryRelative = relativeDir ?
|
|
16480
|
-
const absolutePath =
|
|
16587
|
+
const entryRelative = relativeDir ? path8.posix.join(relativeDir.replace(/\\/g, "/"), entryName) : entryName;
|
|
16588
|
+
const absolutePath = path8.join(effectsDir, entryRelative);
|
|
16481
16589
|
if (isDirectory) {
|
|
16482
16590
|
effects.push(...this.scanEffectFiles(effectsDir, entryRelative));
|
|
16483
16591
|
continue;
|
|
@@ -16501,7 +16609,7 @@ var PackingService = class {
|
|
|
16501
16609
|
* Recursively analyze a prompt and its dependencies.
|
|
16502
16610
|
*/
|
|
16503
16611
|
async analyzePrompt(promptName, agentsDir, analysis, visited, parentKey) {
|
|
16504
|
-
const promptFilePath = await this.findFile(
|
|
16612
|
+
const promptFilePath = await this.findFile(path8.join(agentsDir, "prompts"), promptName);
|
|
16505
16613
|
if (!promptFilePath) {
|
|
16506
16614
|
analysis.warnings.push(`Prompt file not found: ${promptName}`);
|
|
16507
16615
|
return;
|
|
@@ -16520,7 +16628,7 @@ var PackingService = class {
|
|
|
16520
16628
|
return;
|
|
16521
16629
|
}
|
|
16522
16630
|
visited.add(`prompt:${promptName}`);
|
|
16523
|
-
const promptSource =
|
|
16631
|
+
const promptSource = fs8.readFileSync(promptFilePath, "utf-8");
|
|
16524
16632
|
const modelName = await extractPromptModel(promptSource);
|
|
16525
16633
|
if (modelName) {
|
|
16526
16634
|
await this.analyzeModel(modelName, agentsDir, analysis, visited, thisKey);
|
|
@@ -16546,17 +16654,17 @@ var PackingService = class {
|
|
|
16546
16654
|
*/
|
|
16547
16655
|
async analyzeTool(toolName, agentsDir, analysis, visited, discoveredVia, parentKey) {
|
|
16548
16656
|
const thisKey = `tool:${toolName}`;
|
|
16549
|
-
const promptFilePath = await this.findFile(
|
|
16657
|
+
const promptFilePath = await this.findFile(path8.join(agentsDir, "prompts"), toolName);
|
|
16550
16658
|
if (promptFilePath) {
|
|
16551
16659
|
await this.analyzePrompt(toolName, agentsDir, analysis, visited, parentKey);
|
|
16552
16660
|
return;
|
|
16553
16661
|
}
|
|
16554
|
-
const agentFilePath = await this.findFile(
|
|
16662
|
+
const agentFilePath = await this.findFile(path8.join(agentsDir, "agents"), toolName);
|
|
16555
16663
|
if (agentFilePath) {
|
|
16556
16664
|
await this.analyzeNestedAgent(toolName, agentsDir, analysis, visited, parentKey);
|
|
16557
16665
|
return;
|
|
16558
16666
|
}
|
|
16559
|
-
const toolFilePath = await this.findFile(
|
|
16667
|
+
const toolFilePath = await this.findFile(path8.join(agentsDir, "tools"), toolName);
|
|
16560
16668
|
if (!toolFilePath) {
|
|
16561
16669
|
analysis.warnings.push(`Tool file not found: ${toolName}`);
|
|
16562
16670
|
return;
|
|
@@ -16574,7 +16682,7 @@ var PackingService = class {
|
|
|
16574
16682
|
return;
|
|
16575
16683
|
}
|
|
16576
16684
|
visited.add(`tool:${toolName}`);
|
|
16577
|
-
const toolSource =
|
|
16685
|
+
const toolSource = fs8.readFileSync(toolFilePath, "utf-8");
|
|
16578
16686
|
const { uses } = await extractToolUses(toolSource);
|
|
16579
16687
|
for (const usedItem of uses) {
|
|
16580
16688
|
await this.analyzeTool(usedItem, agentsDir, analysis, visited, "uses", thisKey);
|
|
@@ -16584,7 +16692,7 @@ var PackingService = class {
|
|
|
16584
16692
|
* Analyze a nested agent (used as a handoff target).
|
|
16585
16693
|
*/
|
|
16586
16694
|
async analyzeNestedAgent(agentName, agentsDir, analysis, visited, parentKey) {
|
|
16587
|
-
const agentFilePath = await this.findFile(
|
|
16695
|
+
const agentFilePath = await this.findFile(path8.join(agentsDir, "agents"), agentName);
|
|
16588
16696
|
if (!agentFilePath) {
|
|
16589
16697
|
analysis.warnings.push(`Agent file not found: ${agentName}`);
|
|
16590
16698
|
return;
|
|
@@ -16603,7 +16711,7 @@ var PackingService = class {
|
|
|
16603
16711
|
return;
|
|
16604
16712
|
}
|
|
16605
16713
|
visited.add(`agent:${agentName}`);
|
|
16606
|
-
const agentSource =
|
|
16714
|
+
const agentSource = fs8.readFileSync(agentFilePath, "utf-8");
|
|
16607
16715
|
const agentPrompts = await extractAgentPrompts(agentSource);
|
|
16608
16716
|
if (agentPrompts.sideA) {
|
|
16609
16717
|
await this.analyzePrompt(agentPrompts.sideA, agentsDir, analysis, visited, thisKey);
|
|
@@ -16616,7 +16724,7 @@ var PackingService = class {
|
|
|
16616
16724
|
* Analyze a model and its fallbacks.
|
|
16617
16725
|
*/
|
|
16618
16726
|
async analyzeModel(modelName, agentsDir, analysis, visited, parentKey) {
|
|
16619
|
-
const modelFilePath = await this.findFile(
|
|
16727
|
+
const modelFilePath = await this.findFile(path8.join(agentsDir, "models"), modelName);
|
|
16620
16728
|
if (!modelFilePath) {
|
|
16621
16729
|
analysis.warnings.push(`Model file not found: ${modelName}`);
|
|
16622
16730
|
return;
|
|
@@ -16635,7 +16743,7 @@ var PackingService = class {
|
|
|
16635
16743
|
return;
|
|
16636
16744
|
}
|
|
16637
16745
|
visited.add(`model:${modelName}`);
|
|
16638
|
-
const modelSource =
|
|
16746
|
+
const modelSource = fs8.readFileSync(modelFilePath, "utf-8");
|
|
16639
16747
|
const fallbacks = await extractModelFallbacks(modelSource);
|
|
16640
16748
|
for (const fallbackName of fallbacks) {
|
|
16641
16749
|
await this.analyzeModel(fallbackName, agentsDir, analysis, visited, thisKey);
|
|
@@ -16645,13 +16753,13 @@ var PackingService = class {
|
|
|
16645
16753
|
* Check which items are shared with other agents.
|
|
16646
16754
|
*/
|
|
16647
16755
|
async checkSharedItems(agentsDir, analysis) {
|
|
16648
|
-
const agentsPath =
|
|
16649
|
-
if (!
|
|
16650
|
-
const agentFiles =
|
|
16756
|
+
const agentsPath = path8.join(agentsDir, "agents");
|
|
16757
|
+
if (!fs8.existsSync(agentsPath)) return;
|
|
16758
|
+
const agentFiles = fs8.readdirSync(agentsPath).filter((f) => f.endsWith(".ts"));
|
|
16651
16759
|
for (const agentFile of agentFiles) {
|
|
16652
16760
|
const otherAgentName = agentFile.replace(".ts", "");
|
|
16653
16761
|
if (otherAgentName === analysis.agent) continue;
|
|
16654
|
-
const otherAnalysis = await this.analyzeAgentLight(otherAgentName,
|
|
16762
|
+
const otherAnalysis = await this.analyzeAgentLight(otherAgentName, path8.dirname(agentsDir));
|
|
16655
16763
|
for (const prompt of analysis.constituents.prompts) {
|
|
16656
16764
|
if (otherAnalysis.prompts.includes(prompt.name)) {
|
|
16657
16765
|
prompt.sharedWith.push(otherAgentName);
|
|
@@ -16683,19 +16791,19 @@ var PackingService = class {
|
|
|
16683
16791
|
*/
|
|
16684
16792
|
async analyzeAgentLight(agentName, rootDir) {
|
|
16685
16793
|
const result = { prompts: [], tools: [], models: [] };
|
|
16686
|
-
const agentsDir =
|
|
16794
|
+
const agentsDir = path8.join(rootDir, "agents");
|
|
16687
16795
|
const visited = /* @__PURE__ */ new Set();
|
|
16688
|
-
const agentFilePath = await this.findFile(
|
|
16796
|
+
const agentFilePath = await this.findFile(path8.join(agentsDir, "agents"), agentName);
|
|
16689
16797
|
if (!agentFilePath) return result;
|
|
16690
|
-
const agentSource =
|
|
16798
|
+
const agentSource = fs8.readFileSync(agentFilePath, "utf-8");
|
|
16691
16799
|
const agentPrompts = await extractAgentPrompts(agentSource);
|
|
16692
16800
|
const analyzePromptLight = async (promptName) => {
|
|
16693
16801
|
if (visited.has(promptName)) return;
|
|
16694
16802
|
visited.add(promptName);
|
|
16695
16803
|
result.prompts.push(promptName);
|
|
16696
|
-
const promptFilePath = await this.findFile(
|
|
16804
|
+
const promptFilePath = await this.findFile(path8.join(agentsDir, "prompts"), promptName);
|
|
16697
16805
|
if (!promptFilePath) return;
|
|
16698
|
-
const promptSource =
|
|
16806
|
+
const promptSource = fs8.readFileSync(promptFilePath, "utf-8");
|
|
16699
16807
|
const modelName = await extractPromptModel(promptSource);
|
|
16700
16808
|
if (modelName && !result.models.includes(modelName)) {
|
|
16701
16809
|
result.models.push(modelName);
|
|
@@ -16768,14 +16876,14 @@ var PackingService = class {
|
|
|
16768
16876
|
return result;
|
|
16769
16877
|
}
|
|
16770
16878
|
result.warnings = analysis.warnings;
|
|
16771
|
-
const pkgOutputDir =
|
|
16772
|
-
|
|
16773
|
-
|
|
16774
|
-
|
|
16775
|
-
|
|
16776
|
-
|
|
16777
|
-
|
|
16778
|
-
|
|
16879
|
+
const pkgOutputDir = path8.join(outputDir, packageId);
|
|
16880
|
+
fs8.mkdirSync(path8.join(pkgOutputDir, "dist", "agents"), { recursive: true });
|
|
16881
|
+
fs8.mkdirSync(path8.join(pkgOutputDir, "dist", "prompts"), { recursive: true });
|
|
16882
|
+
fs8.mkdirSync(path8.join(pkgOutputDir, "dist", "tools"), { recursive: true });
|
|
16883
|
+
fs8.mkdirSync(path8.join(pkgOutputDir, "dist", "models"), { recursive: true });
|
|
16884
|
+
fs8.mkdirSync(path8.join(pkgOutputDir, "dist", "hooks"), { recursive: true });
|
|
16885
|
+
fs8.mkdirSync(path8.join(pkgOutputDir, "dist", "effects"), { recursive: true });
|
|
16886
|
+
fs8.mkdirSync(path8.join(pkgOutputDir, "dist", "thread-endpoints"), { recursive: true });
|
|
16779
16887
|
const seenItems = /* @__PURE__ */ new Set();
|
|
16780
16888
|
const allItems = [];
|
|
16781
16889
|
for (const a of analysis.constituents.agents) {
|
|
@@ -16829,13 +16937,13 @@ var PackingService = class {
|
|
|
16829
16937
|
}
|
|
16830
16938
|
const externalDeps = /* @__PURE__ */ new Map();
|
|
16831
16939
|
for (const item of allItems) {
|
|
16832
|
-
const outputPath =
|
|
16940
|
+
const outputPath = path8.join(
|
|
16833
16941
|
pkgOutputDir,
|
|
16834
16942
|
"dist",
|
|
16835
16943
|
this.getTypeDir(item.type),
|
|
16836
16944
|
`${item.name}.js`
|
|
16837
16945
|
);
|
|
16838
|
-
|
|
16946
|
+
fs8.mkdirSync(path8.dirname(outputPath), { recursive: true });
|
|
16839
16947
|
const deps = await this.bundleFile(item.filePath, outputPath, rootDir);
|
|
16840
16948
|
for (const [depName, depVersion] of deps) {
|
|
16841
16949
|
if (!externalDeps.has(depName)) {
|
|
@@ -16845,12 +16953,12 @@ var PackingService = class {
|
|
|
16845
16953
|
result.filesCreated.push(outputPath);
|
|
16846
16954
|
}
|
|
16847
16955
|
const indexJs = this.generateReExportIndex(analysis, meta);
|
|
16848
|
-
const indexJsPath =
|
|
16849
|
-
|
|
16956
|
+
const indexJsPath = path8.join(pkgOutputDir, "dist", "index.js");
|
|
16957
|
+
fs8.writeFileSync(indexJsPath, indexJs);
|
|
16850
16958
|
result.filesCreated.push(indexJsPath);
|
|
16851
16959
|
const indexDts = this.generateIndexDts(analysis);
|
|
16852
|
-
const indexDtsPath =
|
|
16853
|
-
|
|
16960
|
+
const indexDtsPath = path8.join(pkgOutputDir, "dist", "index.d.ts");
|
|
16961
|
+
fs8.writeFileSync(indexDtsPath, indexDts);
|
|
16854
16962
|
result.filesCreated.push(indexDtsPath);
|
|
16855
16963
|
const pkgJson = this.generatePackageJson(
|
|
16856
16964
|
finalPackageName,
|
|
@@ -16863,13 +16971,13 @@ var PackingService = class {
|
|
|
16863
16971
|
license,
|
|
16864
16972
|
licenseOwner
|
|
16865
16973
|
);
|
|
16866
|
-
const pkgJsonPath =
|
|
16867
|
-
|
|
16974
|
+
const pkgJsonPath = path8.join(pkgOutputDir, "package.json");
|
|
16975
|
+
fs8.writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, null, 2));
|
|
16868
16976
|
result.filesCreated.push(pkgJsonPath);
|
|
16869
16977
|
if (license) {
|
|
16870
16978
|
const licenseContent = this.generateLicenseFile(license, licenseOwner);
|
|
16871
|
-
const licensePath =
|
|
16872
|
-
|
|
16979
|
+
const licensePath = path8.join(pkgOutputDir, "LICENSE");
|
|
16980
|
+
fs8.writeFileSync(licensePath, licenseContent);
|
|
16873
16981
|
result.filesCreated.push(licensePath);
|
|
16874
16982
|
}
|
|
16875
16983
|
let readmeContent = readme;
|
|
@@ -16877,7 +16985,7 @@ var PackingService = class {
|
|
|
16877
16985
|
const agentItem = analysis.constituents.agents.find((a) => a.name === agentName);
|
|
16878
16986
|
let agentDescription;
|
|
16879
16987
|
if (agentItem?.filePath) {
|
|
16880
|
-
const agentSource =
|
|
16988
|
+
const agentSource = fs8.readFileSync(agentItem.filePath, "utf-8");
|
|
16881
16989
|
agentDescription = await extractAgentDescription(agentSource) || void 0;
|
|
16882
16990
|
}
|
|
16883
16991
|
readmeContent = this.generateReadme(
|
|
@@ -16888,21 +16996,21 @@ var PackingService = class {
|
|
|
16888
16996
|
agentDescription
|
|
16889
16997
|
);
|
|
16890
16998
|
}
|
|
16891
|
-
const readmePath =
|
|
16892
|
-
|
|
16999
|
+
const readmePath = path8.join(pkgOutputDir, "README.md");
|
|
17000
|
+
fs8.writeFileSync(readmePath, readmeContent);
|
|
16893
17001
|
result.filesCreated.push(readmePath);
|
|
16894
17002
|
if (removeOriginals || itemSelections) {
|
|
16895
17003
|
result.filesRemoved = [];
|
|
16896
17004
|
for (const item of allItems) {
|
|
16897
17005
|
const selection = itemSelections?.find((s) => s.name === item.name && s.type === item.type);
|
|
16898
17006
|
const shouldRemove = selection ? selection.mode === "extract" : removeOriginals && item.sharedWith.length === 0 && item.type !== "thread-endpoint" && item.type !== "effect";
|
|
16899
|
-
if (shouldRemove &&
|
|
16900
|
-
|
|
17007
|
+
if (shouldRemove && fs8.existsSync(item.filePath)) {
|
|
17008
|
+
fs8.unlinkSync(item.filePath);
|
|
16901
17009
|
result.filesRemoved.push(item.filePath);
|
|
16902
17010
|
}
|
|
16903
17011
|
}
|
|
16904
17012
|
}
|
|
16905
|
-
const agentsDir =
|
|
17013
|
+
const agentsDir = path8.join(rootDir, "agents");
|
|
16906
17014
|
const metadataService = new MetadataService(agentsDir);
|
|
16907
17015
|
const metadata = {
|
|
16908
17016
|
packageName: finalPackageName,
|
|
@@ -16936,7 +17044,7 @@ var PackingService = class {
|
|
|
16936
17044
|
const commonjs = (await import('@rollup/plugin-commonjs')).default;
|
|
16937
17045
|
const esbuild = (await import('rollup-plugin-esbuild')).default;
|
|
16938
17046
|
const externalDeps = /* @__PURE__ */ new Map();
|
|
16939
|
-
const agentsDir =
|
|
17047
|
+
const agentsDir = path8.join(rootDir, "agents");
|
|
16940
17048
|
const resolveVersion = this.resolvePackageVersion.bind(this);
|
|
16941
17049
|
const trackExternalsPlugin = {
|
|
16942
17050
|
name: "track-externals",
|
|
@@ -16945,14 +17053,14 @@ var PackingService = class {
|
|
|
16945
17053
|
return null;
|
|
16946
17054
|
}
|
|
16947
17055
|
if (source.startsWith("./") || source.startsWith("../")) {
|
|
16948
|
-
const resolved =
|
|
17056
|
+
const resolved = path8.resolve(path8.dirname(importer), source);
|
|
16949
17057
|
let tsResolved = resolved;
|
|
16950
17058
|
if (!resolved.endsWith(".ts") && !resolved.endsWith(".js")) {
|
|
16951
|
-
if (
|
|
17059
|
+
if (fs8.existsSync(`${resolved}.ts`)) {
|
|
16952
17060
|
tsResolved = `${resolved}.ts`;
|
|
16953
|
-
} else if (
|
|
17061
|
+
} else if (fs8.existsSync(`${resolved}.js`)) {
|
|
16954
17062
|
tsResolved = `${resolved}.js`;
|
|
16955
|
-
} else if (
|
|
17063
|
+
} else if (fs8.existsSync(`${resolved}/index.ts`)) {
|
|
16956
17064
|
tsResolved = `${resolved}/index.ts`;
|
|
16957
17065
|
}
|
|
16958
17066
|
}
|
|
@@ -17001,11 +17109,11 @@ var PackingService = class {
|
|
|
17001
17109
|
exports: "named"
|
|
17002
17110
|
});
|
|
17003
17111
|
const bundledCode = output[0].code;
|
|
17004
|
-
const header = `// Bundled from: ${
|
|
17112
|
+
const header = `// Bundled from: ${path8.relative(rootDir, inputPath)}
|
|
17005
17113
|
// Local dependencies have been inlined
|
|
17006
17114
|
|
|
17007
17115
|
`;
|
|
17008
|
-
|
|
17116
|
+
fs8.writeFileSync(outputPath, header + bundledCode);
|
|
17009
17117
|
await bundle.close();
|
|
17010
17118
|
} catch (error) {
|
|
17011
17119
|
await bundle.close();
|
|
@@ -17430,30 +17538,30 @@ Copyright (c) ${year} ${copyrightHolder}
|
|
|
17430
17538
|
* @returns Package info or null if not found
|
|
17431
17539
|
*/
|
|
17432
17540
|
getPackedInfo(packageId, rootDir) {
|
|
17433
|
-
const packedDir =
|
|
17434
|
-
let packageDir =
|
|
17435
|
-
if (!
|
|
17436
|
-
if (!
|
|
17541
|
+
const packedDir = path8.join(rootDir, "agents", "packed");
|
|
17542
|
+
let packageDir = path8.join(packedDir, packageId);
|
|
17543
|
+
if (!fs8.existsSync(packageDir)) {
|
|
17544
|
+
if (!fs8.existsSync(packedDir)) {
|
|
17437
17545
|
return null;
|
|
17438
17546
|
}
|
|
17439
|
-
const dirs =
|
|
17547
|
+
const dirs = fs8.readdirSync(packedDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
17440
17548
|
const matchingDir = dirs.find(
|
|
17441
17549
|
(d) => d === packageId || d === `standardagent-${packageId}` || d === `standardagent-${packageId.replace(/_/g, "-")}`
|
|
17442
17550
|
);
|
|
17443
17551
|
if (!matchingDir) {
|
|
17444
17552
|
return null;
|
|
17445
17553
|
}
|
|
17446
|
-
packageDir =
|
|
17554
|
+
packageDir = path8.join(packedDir, matchingDir);
|
|
17447
17555
|
}
|
|
17448
|
-
const pkgJsonPath =
|
|
17449
|
-
if (!
|
|
17556
|
+
const pkgJsonPath = path8.join(packageDir, "package.json");
|
|
17557
|
+
if (!fs8.existsSync(pkgJsonPath)) {
|
|
17450
17558
|
return null;
|
|
17451
17559
|
}
|
|
17452
|
-
const pkgJson = JSON.parse(
|
|
17560
|
+
const pkgJson = JSON.parse(fs8.readFileSync(pkgJsonPath, "utf-8"));
|
|
17453
17561
|
let readme;
|
|
17454
|
-
const readmePath =
|
|
17455
|
-
if (
|
|
17456
|
-
readme =
|
|
17562
|
+
const readmePath = path8.join(packageDir, "README.md");
|
|
17563
|
+
if (fs8.existsSync(readmePath)) {
|
|
17564
|
+
readme = fs8.readFileSync(readmePath, "utf-8");
|
|
17457
17565
|
}
|
|
17458
17566
|
return {
|
|
17459
17567
|
packageName: pkgJson.name,
|
|
@@ -17471,11 +17579,11 @@ Copyright (c) ${year} ${copyrightHolder}
|
|
|
17471
17579
|
* @returns Array of package directory names
|
|
17472
17580
|
*/
|
|
17473
17581
|
listPackedPackages(rootDir) {
|
|
17474
|
-
const packedDir =
|
|
17475
|
-
if (!
|
|
17582
|
+
const packedDir = path8.join(rootDir, "agents", "packed");
|
|
17583
|
+
if (!fs8.existsSync(packedDir)) {
|
|
17476
17584
|
return [];
|
|
17477
17585
|
}
|
|
17478
|
-
return
|
|
17586
|
+
return fs8.readdirSync(packedDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
17479
17587
|
}
|
|
17480
17588
|
/**
|
|
17481
17589
|
* Generate README.md content for a packed agent.
|
|
@@ -17522,17 +17630,17 @@ ${license || "See LICENSE file"}
|
|
|
17522
17630
|
* Find a file by name in a directory.
|
|
17523
17631
|
*/
|
|
17524
17632
|
async findFile(dir, name) {
|
|
17525
|
-
if (!
|
|
17633
|
+
if (!fs8.existsSync(dir)) {
|
|
17526
17634
|
return null;
|
|
17527
17635
|
}
|
|
17528
|
-
const exactPath =
|
|
17529
|
-
if (
|
|
17636
|
+
const exactPath = path8.join(dir, `${name}.ts`);
|
|
17637
|
+
if (fs8.existsSync(exactPath)) {
|
|
17530
17638
|
return exactPath;
|
|
17531
17639
|
}
|
|
17532
|
-
const files =
|
|
17640
|
+
const files = fs8.readdirSync(dir).filter((f) => f.endsWith(".ts"));
|
|
17533
17641
|
for (const file of files) {
|
|
17534
|
-
const filePath =
|
|
17535
|
-
const source =
|
|
17642
|
+
const filePath = path8.join(dir, file);
|
|
17643
|
+
const source = fs8.readFileSync(filePath, "utf-8");
|
|
17536
17644
|
const extractedName = await extractDefinitionName(source);
|
|
17537
17645
|
if (extractedName === name) {
|
|
17538
17646
|
return filePath;
|
|
@@ -17544,15 +17652,15 @@ ${license || "See LICENSE file"}
|
|
|
17544
17652
|
* List all agents in the workspace.
|
|
17545
17653
|
*/
|
|
17546
17654
|
async listAgents(rootDir) {
|
|
17547
|
-
const agentsDir =
|
|
17548
|
-
if (!
|
|
17655
|
+
const agentsDir = path8.join(rootDir, "agents", "agents");
|
|
17656
|
+
if (!fs8.existsSync(agentsDir)) {
|
|
17549
17657
|
return [];
|
|
17550
17658
|
}
|
|
17551
|
-
const files =
|
|
17659
|
+
const files = fs8.readdirSync(agentsDir).filter((f) => f.endsWith(".ts"));
|
|
17552
17660
|
const agents = [];
|
|
17553
17661
|
for (const file of files) {
|
|
17554
|
-
const filePath =
|
|
17555
|
-
const source =
|
|
17662
|
+
const filePath = path8.join(agentsDir, file);
|
|
17663
|
+
const source = fs8.readFileSync(filePath, "utf-8");
|
|
17556
17664
|
const name = await extractDefinitionName(source);
|
|
17557
17665
|
if (name) {
|
|
17558
17666
|
agents.push(name);
|
|
@@ -17568,7 +17676,7 @@ var PackageDiscoveryService = class {
|
|
|
17568
17676
|
constructor(config) {
|
|
17569
17677
|
this.config = {
|
|
17570
17678
|
rootDir: config.rootDir,
|
|
17571
|
-
packedDir: config.packedDir ??
|
|
17679
|
+
packedDir: config.packedDir ?? path8.join(config.rootDir, "agents", "packed"),
|
|
17572
17680
|
scanNpm: config.scanNpm ?? true,
|
|
17573
17681
|
scanLocal: config.scanLocal ?? true
|
|
17574
17682
|
};
|
|
@@ -17601,19 +17709,19 @@ var PackageDiscoveryService = class {
|
|
|
17601
17709
|
*/
|
|
17602
17710
|
async discoverNpmPackages() {
|
|
17603
17711
|
const packages = [];
|
|
17604
|
-
const nodeModulesDir =
|
|
17605
|
-
if (!
|
|
17712
|
+
const nodeModulesDir = path8.join(this.config.rootDir, "node_modules");
|
|
17713
|
+
if (!fs8.existsSync(nodeModulesDir)) {
|
|
17606
17714
|
return packages;
|
|
17607
17715
|
}
|
|
17608
17716
|
const rootEntries = await this.scanDirectory(nodeModulesDir);
|
|
17609
17717
|
for (const entry of rootEntries) {
|
|
17610
17718
|
if (entry.startsWith(".")) continue;
|
|
17611
17719
|
if (entry.startsWith("@")) {
|
|
17612
|
-
const scopeDir =
|
|
17720
|
+
const scopeDir = path8.join(nodeModulesDir, entry);
|
|
17613
17721
|
const scopeEntries = await this.scanDirectory(scopeDir);
|
|
17614
17722
|
for (const scopedPkg of scopeEntries) {
|
|
17615
17723
|
if (scopedPkg.startsWith(".")) continue;
|
|
17616
|
-
const pkgDir =
|
|
17724
|
+
const pkgDir = path8.join(scopeDir, scopedPkg);
|
|
17617
17725
|
const fullName = `${entry}/${scopedPkg}`;
|
|
17618
17726
|
const pkg = await this.checkNpmPackage(pkgDir, fullName);
|
|
17619
17727
|
if (pkg) {
|
|
@@ -17621,7 +17729,7 @@ var PackageDiscoveryService = class {
|
|
|
17621
17729
|
}
|
|
17622
17730
|
}
|
|
17623
17731
|
} else {
|
|
17624
|
-
const pkgDir =
|
|
17732
|
+
const pkgDir = path8.join(nodeModulesDir, entry);
|
|
17625
17733
|
const pkg = await this.checkNpmPackage(pkgDir, entry);
|
|
17626
17734
|
if (pkg) {
|
|
17627
17735
|
packages.push(pkg);
|
|
@@ -17637,12 +17745,12 @@ var PackageDiscoveryService = class {
|
|
|
17637
17745
|
* which must contain `entryAgents` array.
|
|
17638
17746
|
*/
|
|
17639
17747
|
async checkNpmPackage(pkgDir, pkgName) {
|
|
17640
|
-
const pkgJsonPath =
|
|
17641
|
-
if (!
|
|
17748
|
+
const pkgJsonPath = path8.join(pkgDir, "package.json");
|
|
17749
|
+
if (!fs8.existsSync(pkgJsonPath)) {
|
|
17642
17750
|
return null;
|
|
17643
17751
|
}
|
|
17644
17752
|
try {
|
|
17645
|
-
const pkgJson = JSON.parse(
|
|
17753
|
+
const pkgJson = JSON.parse(fs8.readFileSync(pkgJsonPath, "utf-8"));
|
|
17646
17754
|
const isStandardAgent = (
|
|
17647
17755
|
// Has "standardagent" keyword
|
|
17648
17756
|
pkgJson.keywords?.includes("standardagent") || // Has "standardagent-*" prefix
|
|
@@ -17679,21 +17787,21 @@ var PackageDiscoveryService = class {
|
|
|
17679
17787
|
*/
|
|
17680
17788
|
async discoverLocalPackages() {
|
|
17681
17789
|
const packages = [];
|
|
17682
|
-
if (!
|
|
17790
|
+
if (!fs8.existsSync(this.config.packedDir)) {
|
|
17683
17791
|
return packages;
|
|
17684
17792
|
}
|
|
17685
17793
|
const entries = await this.scanDirectory(this.config.packedDir);
|
|
17686
17794
|
for (const entry of entries) {
|
|
17687
17795
|
if (entry.startsWith(".")) continue;
|
|
17688
|
-
const pkgDir =
|
|
17689
|
-
const stat2 =
|
|
17796
|
+
const pkgDir = path8.join(this.config.packedDir, entry);
|
|
17797
|
+
const stat2 = fs8.statSync(pkgDir);
|
|
17690
17798
|
if (!stat2.isDirectory()) continue;
|
|
17691
17799
|
if (entry.startsWith("@")) {
|
|
17692
17800
|
const scopeEntries = await this.scanDirectory(pkgDir);
|
|
17693
17801
|
for (const scopedPkg of scopeEntries) {
|
|
17694
17802
|
if (scopedPkg.startsWith(".")) continue;
|
|
17695
|
-
const scopedPkgDir =
|
|
17696
|
-
const scopedStat =
|
|
17803
|
+
const scopedPkgDir = path8.join(pkgDir, scopedPkg);
|
|
17804
|
+
const scopedStat = fs8.statSync(scopedPkgDir);
|
|
17697
17805
|
if (!scopedStat.isDirectory()) continue;
|
|
17698
17806
|
const fullName = `${entry}/${scopedPkg}`;
|
|
17699
17807
|
const pkg = await this.checkLocalPackage(scopedPkgDir, fullName);
|
|
@@ -17716,12 +17824,12 @@ var PackageDiscoveryService = class {
|
|
|
17716
17824
|
* Detection is based on the `standardagent` field in package.json.
|
|
17717
17825
|
*/
|
|
17718
17826
|
async checkLocalPackage(pkgDir, dirName) {
|
|
17719
|
-
const pkgJsonPath =
|
|
17720
|
-
if (!
|
|
17827
|
+
const pkgJsonPath = path8.join(pkgDir, "package.json");
|
|
17828
|
+
if (!fs8.existsSync(pkgJsonPath)) {
|
|
17721
17829
|
return null;
|
|
17722
17830
|
}
|
|
17723
17831
|
try {
|
|
17724
|
-
const pkgJson = JSON.parse(
|
|
17832
|
+
const pkgJson = JSON.parse(fs8.readFileSync(pkgJsonPath, "utf-8"));
|
|
17725
17833
|
if (!pkgJson.standardagent?.entryAgents) {
|
|
17726
17834
|
return null;
|
|
17727
17835
|
}
|
|
@@ -17746,10 +17854,10 @@ var PackageDiscoveryService = class {
|
|
|
17746
17854
|
* Scan a directory and return entry names.
|
|
17747
17855
|
*/
|
|
17748
17856
|
async scanDirectory(dir) {
|
|
17749
|
-
if (!
|
|
17857
|
+
if (!fs8.existsSync(dir)) {
|
|
17750
17858
|
return [];
|
|
17751
17859
|
}
|
|
17752
|
-
const entries =
|
|
17860
|
+
const entries = fs8.readdirSync(dir);
|
|
17753
17861
|
return entries;
|
|
17754
17862
|
}
|
|
17755
17863
|
/**
|
|
@@ -17846,29 +17954,29 @@ var UnpackingService = class {
|
|
|
17846
17954
|
}
|
|
17847
17955
|
analysis.version = pkg.version;
|
|
17848
17956
|
analysis.source = pkg.source;
|
|
17849
|
-
const indexPath =
|
|
17850
|
-
if (!
|
|
17957
|
+
const indexPath = path8.join(pkg.path, "dist", "index.js");
|
|
17958
|
+
if (!fs8.existsSync(indexPath)) {
|
|
17851
17959
|
analysis.errors.push(`Package index not found: ${indexPath}`);
|
|
17852
17960
|
return analysis;
|
|
17853
17961
|
}
|
|
17854
|
-
const indexContent =
|
|
17962
|
+
const indexContent = fs8.readFileSync(indexPath, "utf-8");
|
|
17855
17963
|
const registryItems = await this.parseIndexExports(indexContent);
|
|
17856
17964
|
const availableItems = /* @__PURE__ */ new Map();
|
|
17857
17965
|
for (const item of registryItems) {
|
|
17858
17966
|
availableItems.set(`${item.type}:${item.name}`, item);
|
|
17859
17967
|
}
|
|
17860
|
-
const agentsDir =
|
|
17968
|
+
const agentsDir = path8.join(rootDir, "agents");
|
|
17861
17969
|
const itemsWithRelations = [];
|
|
17862
17970
|
for (const item of registryItems) {
|
|
17863
|
-
const targetPath =
|
|
17864
|
-
const sourcePath =
|
|
17971
|
+
const targetPath = path8.join(agentsDir, TYPE_TO_TARGET_DIR[item.type], `${item.name}.ts`);
|
|
17972
|
+
const sourcePath = path8.join(pkg.path, "dist", TYPE_TO_DIR[item.type], `${item.name}.js`);
|
|
17865
17973
|
const existsGlobally = this.fileExists(targetPath);
|
|
17866
|
-
const sourceExists =
|
|
17974
|
+
const sourceExists = fs8.existsSync(sourcePath);
|
|
17867
17975
|
if (!sourceExists) {
|
|
17868
17976
|
analysis.warnings.push(`Source file not found for ${item.type} "${item.name}": ${sourcePath}`);
|
|
17869
17977
|
continue;
|
|
17870
17978
|
}
|
|
17871
|
-
const bundledCode =
|
|
17979
|
+
const bundledCode = fs8.readFileSync(sourcePath, "utf-8");
|
|
17872
17980
|
const children = await this.discoverRelationships(item.type, item.name, bundledCode, availableItems);
|
|
17873
17981
|
itemsWithRelations.push({
|
|
17874
17982
|
name: item.name,
|
|
@@ -17878,10 +17986,10 @@ var UnpackingService = class {
|
|
|
17878
17986
|
action: existsGlobally ? "skip" : "generate"
|
|
17879
17987
|
});
|
|
17880
17988
|
for (const child of children) {
|
|
17881
|
-
const childTargetPath =
|
|
17882
|
-
const childSourcePath =
|
|
17989
|
+
const childTargetPath = path8.join(agentsDir, TYPE_TO_TARGET_DIR[child.type], `${child.name}.ts`);
|
|
17990
|
+
const childSourcePath = path8.join(pkg.path, "dist", TYPE_TO_DIR[child.type], `${child.name}.js`);
|
|
17883
17991
|
const childExists = this.fileExists(childTargetPath);
|
|
17884
|
-
const childSourceExists =
|
|
17992
|
+
const childSourceExists = fs8.existsSync(childSourcePath);
|
|
17885
17993
|
if (!childSourceExists) {
|
|
17886
17994
|
continue;
|
|
17887
17995
|
}
|
|
@@ -17984,8 +18092,8 @@ var UnpackingService = class {
|
|
|
17984
18092
|
return result;
|
|
17985
18093
|
}
|
|
17986
18094
|
const itemsToProcess = this.applySelections(analysis.items, itemSelections);
|
|
17987
|
-
const pkgJsonPath =
|
|
17988
|
-
const pkgJson = JSON.parse(
|
|
18095
|
+
const pkgJsonPath = path8.join(pkg.path, "package.json");
|
|
18096
|
+
const pkgJson = JSON.parse(fs8.readFileSync(pkgJsonPath, "utf-8"));
|
|
17989
18097
|
let author = "";
|
|
17990
18098
|
if (typeof pkgJson.author === "string") {
|
|
17991
18099
|
author = pkgJson.author;
|
|
@@ -18010,17 +18118,17 @@ var UnpackingService = class {
|
|
|
18010
18118
|
continue;
|
|
18011
18119
|
}
|
|
18012
18120
|
try {
|
|
18013
|
-
const sourcePath =
|
|
18014
|
-
const bundledCode =
|
|
18121
|
+
const sourcePath = path8.join(pkg.path, "dist", TYPE_TO_DIR[item.type], `${item.name}.js`);
|
|
18122
|
+
const bundledCode = fs8.readFileSync(sourcePath, "utf-8");
|
|
18015
18123
|
let tsCode = await transformBundledJs(bundledCode);
|
|
18016
18124
|
if (item.type === "agent") {
|
|
18017
18125
|
tsCode = await injectAgentMetadata(tsCode, agentMetadata);
|
|
18018
18126
|
}
|
|
18019
|
-
const dir =
|
|
18020
|
-
if (!
|
|
18021
|
-
|
|
18127
|
+
const dir = path8.dirname(item.targetPath);
|
|
18128
|
+
if (!fs8.existsSync(dir)) {
|
|
18129
|
+
fs8.mkdirSync(dir, { recursive: true });
|
|
18022
18130
|
}
|
|
18023
|
-
|
|
18131
|
+
fs8.writeFileSync(item.targetPath, tsCode);
|
|
18024
18132
|
result.filesGenerated.push(item.targetPath);
|
|
18025
18133
|
} catch (error) {
|
|
18026
18134
|
result.warnings.push(
|
|
@@ -18109,14 +18217,14 @@ var UnpackingService = class {
|
|
|
18109
18217
|
*/
|
|
18110
18218
|
async resolvePackage(pkgIdentifier, rootDir) {
|
|
18111
18219
|
if (pkgIdentifier.startsWith("/") || pkgIdentifier.startsWith("./")) {
|
|
18112
|
-
const absolutePath =
|
|
18113
|
-
const pkgJsonPath2 =
|
|
18114
|
-
if (
|
|
18220
|
+
const absolutePath = path8.isAbsolute(pkgIdentifier) ? pkgIdentifier : path8.join(rootDir, pkgIdentifier);
|
|
18221
|
+
const pkgJsonPath2 = path8.join(absolutePath, "package.json");
|
|
18222
|
+
if (fs8.existsSync(pkgJsonPath2)) {
|
|
18115
18223
|
try {
|
|
18116
|
-
const pkgJson = JSON.parse(
|
|
18224
|
+
const pkgJson = JSON.parse(fs8.readFileSync(pkgJsonPath2, "utf-8"));
|
|
18117
18225
|
if (pkgJson.standardagent?.entryAgents) {
|
|
18118
18226
|
return {
|
|
18119
|
-
packageId: pkgJson.name ||
|
|
18227
|
+
packageId: pkgJson.name || path8.basename(absolutePath),
|
|
18120
18228
|
version: pkgJson.version || "0.0.0",
|
|
18121
18229
|
source: "local",
|
|
18122
18230
|
path: absolutePath,
|
|
@@ -18128,11 +18236,11 @@ var UnpackingService = class {
|
|
|
18128
18236
|
}
|
|
18129
18237
|
return null;
|
|
18130
18238
|
}
|
|
18131
|
-
const packedDir =
|
|
18132
|
-
const pkgJsonPath =
|
|
18133
|
-
if (
|
|
18239
|
+
const packedDir = path8.join(rootDir, "agents", "packed", pkgIdentifier);
|
|
18240
|
+
const pkgJsonPath = path8.join(packedDir, "package.json");
|
|
18241
|
+
if (fs8.existsSync(pkgJsonPath)) {
|
|
18134
18242
|
try {
|
|
18135
|
-
const pkgJson = JSON.parse(
|
|
18243
|
+
const pkgJson = JSON.parse(fs8.readFileSync(pkgJsonPath, "utf-8"));
|
|
18136
18244
|
if (pkgJson.standardagent?.entryAgents) {
|
|
18137
18245
|
return {
|
|
18138
18246
|
packageId: pkgJson.name || pkgIdentifier,
|
|
@@ -18173,18 +18281,18 @@ var UnpackingService = class {
|
|
|
18173
18281
|
* Check if a file exists.
|
|
18174
18282
|
*/
|
|
18175
18283
|
fileExists(filePath) {
|
|
18176
|
-
if (
|
|
18284
|
+
if (fs8.existsSync(filePath)) {
|
|
18177
18285
|
return true;
|
|
18178
18286
|
}
|
|
18179
18287
|
const withoutExt = filePath.replace(/\.(ts|js)$/, "");
|
|
18180
|
-
return
|
|
18288
|
+
return fs8.existsSync(`${withoutExt}.ts`) || fs8.existsSync(`${withoutExt}.js`);
|
|
18181
18289
|
}
|
|
18182
18290
|
/**
|
|
18183
18291
|
* Recursively delete a directory.
|
|
18184
18292
|
*/
|
|
18185
18293
|
deleteDirectory(dirPath) {
|
|
18186
|
-
if (
|
|
18187
|
-
|
|
18294
|
+
if (fs8.existsSync(dirPath)) {
|
|
18295
|
+
fs8.rmSync(dirPath, { recursive: true, force: true });
|
|
18188
18296
|
}
|
|
18189
18297
|
}
|
|
18190
18298
|
/**
|
|
@@ -18260,8 +18368,8 @@ var NpmPublishService = class {
|
|
|
18260
18368
|
error: "Registry URL must use HTTPS"
|
|
18261
18369
|
};
|
|
18262
18370
|
}
|
|
18263
|
-
const pkgJsonPath =
|
|
18264
|
-
if (!
|
|
18371
|
+
const pkgJsonPath = path8.join(packageDir, "package.json");
|
|
18372
|
+
if (!fs8.existsSync(pkgJsonPath)) {
|
|
18265
18373
|
return {
|
|
18266
18374
|
success: false,
|
|
18267
18375
|
output: "",
|
|
@@ -18271,7 +18379,7 @@ var NpmPublishService = class {
|
|
|
18271
18379
|
let packageName;
|
|
18272
18380
|
let version;
|
|
18273
18381
|
try {
|
|
18274
|
-
const pkgJson = JSON.parse(
|
|
18382
|
+
const pkgJson = JSON.parse(fs8.readFileSync(pkgJsonPath, "utf-8"));
|
|
18275
18383
|
packageName = pkgJson.name;
|
|
18276
18384
|
version = pkgJson.version;
|
|
18277
18385
|
} catch (e) {
|
|
@@ -18281,13 +18389,13 @@ var NpmPublishService = class {
|
|
|
18281
18389
|
error: `Failed to read package.json: ${e instanceof Error ? e.message : String(e)}`
|
|
18282
18390
|
};
|
|
18283
18391
|
}
|
|
18284
|
-
const npmrcPath =
|
|
18392
|
+
const npmrcPath = path8.join(packageDir, ".npmrc");
|
|
18285
18393
|
const registryHost = new URL(registry).host;
|
|
18286
18394
|
const npmrcContent = `//${registryHost}/:_authToken=${token}
|
|
18287
18395
|
registry=${registry}
|
|
18288
18396
|
`;
|
|
18289
18397
|
try {
|
|
18290
|
-
|
|
18398
|
+
fs8.writeFileSync(npmrcPath, npmrcContent, { mode: 384 });
|
|
18291
18399
|
const args = ["publish"];
|
|
18292
18400
|
if (dryRun) {
|
|
18293
18401
|
args.push("--dry-run");
|
|
@@ -18319,8 +18427,8 @@ registry=${registry}
|
|
|
18319
18427
|
};
|
|
18320
18428
|
} finally {
|
|
18321
18429
|
try {
|
|
18322
|
-
if (
|
|
18323
|
-
|
|
18430
|
+
if (fs8.existsSync(npmrcPath)) {
|
|
18431
|
+
fs8.unlinkSync(npmrcPath);
|
|
18324
18432
|
}
|
|
18325
18433
|
} catch {
|
|
18326
18434
|
}
|
|
@@ -18413,7 +18521,7 @@ async function handlePackingApiRequest(context) {
|
|
|
18413
18521
|
const body = await parseRequestBody(req);
|
|
18414
18522
|
const packingService = new PackingService();
|
|
18415
18523
|
const rootDir = process.cwd();
|
|
18416
|
-
const outputDir =
|
|
18524
|
+
const outputDir = path8__default.join(rootDir, "agents", "packed");
|
|
18417
18525
|
const result = await packingService.pack({
|
|
18418
18526
|
agentName,
|
|
18419
18527
|
rootDir,
|
|
@@ -18466,8 +18574,8 @@ async function handlePackingApiRequest(context) {
|
|
|
18466
18574
|
res.end(JSON.stringify({ error: "Cannot delete npm packages. Use npm uninstall instead." }));
|
|
18467
18575
|
return true;
|
|
18468
18576
|
}
|
|
18469
|
-
const
|
|
18470
|
-
|
|
18577
|
+
const fs18 = await import('fs');
|
|
18578
|
+
fs18.rmSync(pkg.path, { recursive: true, force: true });
|
|
18471
18579
|
await reloadAllAgentModules(context);
|
|
18472
18580
|
res.statusCode = 200;
|
|
18473
18581
|
res.setHeader("Content-Type", "application/json");
|
|
@@ -18495,8 +18603,8 @@ async function handlePackingApiRequest(context) {
|
|
|
18495
18603
|
return true;
|
|
18496
18604
|
}
|
|
18497
18605
|
const { spawn } = await import('child_process');
|
|
18498
|
-
const parentDir =
|
|
18499
|
-
const dirName =
|
|
18606
|
+
const parentDir = path8__default.dirname(pkg.path);
|
|
18607
|
+
const dirName = path8__default.basename(pkg.path);
|
|
18500
18608
|
res.setHeader("Content-Type", "application/gzip");
|
|
18501
18609
|
res.setHeader("Content-Disposition", `attachment; filename="${packageId}.tar.gz"`);
|
|
18502
18610
|
const tar = spawn("tar", ["-czf", "-", "-C", parentDir, dirName]);
|
|
@@ -18552,16 +18660,16 @@ async function handlePackingApiRequest(context) {
|
|
|
18552
18660
|
const packageId = decodeURIComponent(packPublishMatch[1]);
|
|
18553
18661
|
const body = await parseRequestBody(req);
|
|
18554
18662
|
const rootDir = process.cwd();
|
|
18555
|
-
const packedDir =
|
|
18556
|
-
let packageDir =
|
|
18557
|
-
if (!
|
|
18558
|
-
if (!
|
|
18663
|
+
const packedDir = path8__default.join(rootDir, "agents", "packed");
|
|
18664
|
+
let packageDir = path8__default.join(packedDir, packageId);
|
|
18665
|
+
if (!fs8__default.existsSync(packageDir)) {
|
|
18666
|
+
if (!fs8__default.existsSync(packedDir)) {
|
|
18559
18667
|
res.statusCode = 400;
|
|
18560
18668
|
res.setHeader("Content-Type", "application/json");
|
|
18561
18669
|
res.end(JSON.stringify({ error: "No packed packages found. Pack the agent first." }));
|
|
18562
18670
|
return true;
|
|
18563
18671
|
}
|
|
18564
|
-
const dirs =
|
|
18672
|
+
const dirs = fs8__default.readdirSync(packedDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
18565
18673
|
const matchingDir = dirs.find(
|
|
18566
18674
|
(d) => d === packageId || d === `standardagent-${packageId}` || d === `standardagent-${packageId.replace(/_/g, "-")}`
|
|
18567
18675
|
);
|
|
@@ -18573,14 +18681,14 @@ async function handlePackingApiRequest(context) {
|
|
|
18573
18681
|
}));
|
|
18574
18682
|
return true;
|
|
18575
18683
|
}
|
|
18576
|
-
packageDir =
|
|
18684
|
+
packageDir = path8__default.join(packedDir, matchingDir);
|
|
18577
18685
|
}
|
|
18578
18686
|
let token = body.token || process.env.NPM_TOKEN;
|
|
18579
18687
|
let tokenSource = body.token ? "provided" : "environment";
|
|
18580
18688
|
if (!token) {
|
|
18581
|
-
const devVarsPath =
|
|
18582
|
-
if (
|
|
18583
|
-
const devVars =
|
|
18689
|
+
const devVarsPath = path8__default.join(rootDir, ".dev.vars");
|
|
18690
|
+
if (fs8__default.existsSync(devVarsPath)) {
|
|
18691
|
+
const devVars = fs8__default.readFileSync(devVarsPath, "utf-8");
|
|
18584
18692
|
const match = devVars.match(/^NPM_TOKEN=(.+)$/m);
|
|
18585
18693
|
if (match) {
|
|
18586
18694
|
token = match[1].trim();
|
|
@@ -18692,6 +18800,23 @@ async function handlePackingApiRequest(context) {
|
|
|
18692
18800
|
}
|
|
18693
18801
|
|
|
18694
18802
|
// src/plugin/dev-middleware.ts
|
|
18803
|
+
function readRawRequestBody(req) {
|
|
18804
|
+
return new Promise((resolve2, reject) => {
|
|
18805
|
+
const chunks = [];
|
|
18806
|
+
req.on("data", (chunk) => {
|
|
18807
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
18808
|
+
});
|
|
18809
|
+
req.on("end", () => {
|
|
18810
|
+
resolve2(chunks.length > 0 ? Buffer.concat(chunks) : void 0);
|
|
18811
|
+
});
|
|
18812
|
+
req.on("error", reject);
|
|
18813
|
+
});
|
|
18814
|
+
}
|
|
18815
|
+
function injectUiConfigIntoHtml(htmlContent, mountPoint) {
|
|
18816
|
+
const configScript = `<script>window.__AGENTBUILDER_CONFIG__ = { mountPoint: "${mountPoint}", devMode: true };</script>`;
|
|
18817
|
+
const assetPrefix = mountPoint === "/" ? "/" : `${mountPoint}/`;
|
|
18818
|
+
return htmlContent.replace(/\/agents\//g, assetPrefix).replace("</head>", `${configScript}</head>`);
|
|
18819
|
+
}
|
|
18695
18820
|
function createDevMiddleware(server, context) {
|
|
18696
18821
|
const {
|
|
18697
18822
|
mountPoint,
|
|
@@ -18723,6 +18848,19 @@ function createDevMiddleware(server, context) {
|
|
|
18723
18848
|
pathWithoutMount = "/" + pathWithoutMount;
|
|
18724
18849
|
}
|
|
18725
18850
|
const method = req.method?.toUpperCase();
|
|
18851
|
+
const legacyMountPoint = "/agentbuilder";
|
|
18852
|
+
if (mountPoint === "/" && (pathWithoutMount === legacyMountPoint || pathWithoutMount.startsWith(`${legacyMountPoint}/`))) {
|
|
18853
|
+
const normalizedPath = pathWithoutMount.slice(legacyMountPoint.length) || "/";
|
|
18854
|
+
if (normalizedPath.startsWith("/api/")) {
|
|
18855
|
+
req.url = normalizedPath;
|
|
18856
|
+
pathWithoutMount = normalizedPath;
|
|
18857
|
+
} else if (method === "GET" || method === "HEAD") {
|
|
18858
|
+
res.statusCode = 302;
|
|
18859
|
+
res.setHeader("Location", normalizedPath);
|
|
18860
|
+
res.end();
|
|
18861
|
+
return;
|
|
18862
|
+
}
|
|
18863
|
+
}
|
|
18726
18864
|
if (await handleConfigApiRequest({
|
|
18727
18865
|
req,
|
|
18728
18866
|
res,
|
|
@@ -18753,6 +18891,14 @@ function createDevMiddleware(server, context) {
|
|
|
18753
18891
|
})) {
|
|
18754
18892
|
return;
|
|
18755
18893
|
}
|
|
18894
|
+
const bootstrapCookie = resolveLocalBootstrapCookie(
|
|
18895
|
+
process.cwd(),
|
|
18896
|
+
pathWithoutMount,
|
|
18897
|
+
req.headers.cookie
|
|
18898
|
+
);
|
|
18899
|
+
if (bootstrapCookie) {
|
|
18900
|
+
req.headers.cookie = mergeCookieHeader(req.headers.cookie, bootstrapCookie);
|
|
18901
|
+
}
|
|
18756
18902
|
if (pathWithoutMount.startsWith("/api/")) {
|
|
18757
18903
|
next();
|
|
18758
18904
|
return;
|
|
@@ -18761,13 +18907,38 @@ function createDevMiddleware(server, context) {
|
|
|
18761
18907
|
if (uiDevServer && !pathWithoutMount.startsWith("/api/")) {
|
|
18762
18908
|
const targetUrl = `${uiDevServer}${pathWithoutMount}`;
|
|
18763
18909
|
try {
|
|
18764
|
-
const
|
|
18910
|
+
const proxyHeaders = new Headers();
|
|
18911
|
+
for (const [key, value] of Object.entries(req.headers)) {
|
|
18912
|
+
if (value === void 0) continue;
|
|
18913
|
+
if (Array.isArray(value)) {
|
|
18914
|
+
for (const item of value) {
|
|
18915
|
+
proxyHeaders.append(key, item);
|
|
18916
|
+
}
|
|
18917
|
+
continue;
|
|
18918
|
+
}
|
|
18919
|
+
proxyHeaders.set(key, value);
|
|
18920
|
+
}
|
|
18921
|
+
proxyHeaders.delete("host");
|
|
18922
|
+
const proxyBody = method === "GET" || method === "HEAD" ? void 0 : await readRawRequestBody(req);
|
|
18923
|
+
const proxyRes = await fetch(targetUrl, {
|
|
18924
|
+
method: method || "GET",
|
|
18925
|
+
headers: proxyHeaders,
|
|
18926
|
+
body: proxyBody
|
|
18927
|
+
});
|
|
18765
18928
|
res.statusCode = proxyRes.status;
|
|
18766
18929
|
proxyRes.headers.forEach((value, key) => {
|
|
18767
|
-
if (!["content-encoding", "transfer-encoding"].includes(key.toLowerCase())) {
|
|
18930
|
+
if (!["content-encoding", "transfer-encoding", "content-length"].includes(key.toLowerCase())) {
|
|
18768
18931
|
res.setHeader(key, value);
|
|
18769
18932
|
}
|
|
18770
18933
|
});
|
|
18934
|
+
const contentType = proxyRes.headers.get("content-type") || "";
|
|
18935
|
+
if (contentType.includes("text/html")) {
|
|
18936
|
+
const htmlBody = await proxyRes.text();
|
|
18937
|
+
const injectedHtml = Buffer.from(injectUiConfigIntoHtml(htmlBody, mountPoint));
|
|
18938
|
+
res.setHeader("content-length", String(injectedHtml.byteLength));
|
|
18939
|
+
res.end(injectedHtml);
|
|
18940
|
+
return;
|
|
18941
|
+
}
|
|
18771
18942
|
const body = await proxyRes.arrayBuffer();
|
|
18772
18943
|
res.end(Buffer.from(body));
|
|
18773
18944
|
return;
|
|
@@ -18778,30 +18949,27 @@ function createDevMiddleware(server, context) {
|
|
|
18778
18949
|
const clientPath = mountPoint === "/" && pathWithoutMount.startsWith("/agents/") ? pathWithoutMount.slice("/agents".length) || "/" : pathWithoutMount;
|
|
18779
18950
|
const isStaticAsset = clientPath.startsWith("/assets/") || clientPath.startsWith("/vendor.js") || clientPath.startsWith("/vue.js") || clientPath.startsWith("/monaco.js") || clientPath.startsWith("/index.js") || clientPath.startsWith("/index.css") || clientPath.match(/\.(js|css|png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot|ico)$/);
|
|
18780
18951
|
{
|
|
18781
|
-
const currentDir =
|
|
18952
|
+
const currentDir = path8__default.dirname(fileURLToPath(import.meta.url));
|
|
18782
18953
|
const isInDist = currentDir.endsWith("dist");
|
|
18783
|
-
const clientDir =
|
|
18954
|
+
const clientDir = path8__default.resolve(
|
|
18784
18955
|
currentDir,
|
|
18785
18956
|
isInDist ? "./client" : "../dist/client"
|
|
18786
18957
|
);
|
|
18787
18958
|
let filePath;
|
|
18788
18959
|
if (isStaticAsset) {
|
|
18789
18960
|
const cleanUrl = clientPath.split("?")[0];
|
|
18790
|
-
filePath =
|
|
18961
|
+
filePath = path8__default.join(clientDir, cleanUrl);
|
|
18791
18962
|
} else {
|
|
18792
|
-
filePath =
|
|
18963
|
+
filePath = path8__default.join(clientDir, "index.html");
|
|
18793
18964
|
}
|
|
18794
18965
|
try {
|
|
18795
|
-
if (
|
|
18796
|
-
let content =
|
|
18797
|
-
const ext =
|
|
18966
|
+
if (fs8__default.existsSync(filePath)) {
|
|
18967
|
+
let content = fs8__default.readFileSync(filePath);
|
|
18968
|
+
const ext = path8__default.extname(filePath).toLowerCase();
|
|
18798
18969
|
if (ext === ".html") {
|
|
18799
|
-
|
|
18800
|
-
|
|
18801
|
-
|
|
18802
|
-
htmlContent = htmlContent.replace(/\/agents\//g, assetPrefix);
|
|
18803
|
-
htmlContent = htmlContent.replace("</head>", `${configScript}</head>`);
|
|
18804
|
-
content = Buffer.from(htmlContent);
|
|
18970
|
+
content = Buffer.from(
|
|
18971
|
+
injectUiConfigIntoHtml(content.toString(), mountPoint)
|
|
18972
|
+
);
|
|
18805
18973
|
}
|
|
18806
18974
|
const mimeTypes = {
|
|
18807
18975
|
".html": "text/html",
|
|
@@ -18836,7 +19004,7 @@ async function loadBuilderVirtualModule(context) {
|
|
|
18836
19004
|
const effects = await scanEffectsDirectory(effectsDir);
|
|
18837
19005
|
const toAbsolutePath = (relativePath) => {
|
|
18838
19006
|
if (relativePath.startsWith("./")) {
|
|
18839
|
-
return
|
|
19007
|
+
return path8__default.resolve(process.cwd(), relativePath).replace(/\\/g, "/");
|
|
18840
19008
|
}
|
|
18841
19009
|
return relativePath;
|
|
18842
19010
|
};
|
|
@@ -19066,7 +19234,7 @@ async function loadRegistryVirtualModule(context) {
|
|
|
19066
19234
|
const effects = await scanEffectsDirectory(effectsDir);
|
|
19067
19235
|
const toAbsolutePath = (relativePath) => {
|
|
19068
19236
|
if (relativePath.startsWith("./")) {
|
|
19069
|
-
return
|
|
19237
|
+
return path8__default.resolve(process.cwd(), relativePath).replace(/\\/g, "/");
|
|
19070
19238
|
}
|
|
19071
19239
|
return relativePath;
|
|
19072
19240
|
};
|
|
@@ -19094,23 +19262,23 @@ async function loadRegistryVirtualModule(context) {
|
|
|
19094
19262
|
const absPath = toAbsolutePath(importPath);
|
|
19095
19263
|
return ` "${name}": async () => (await import("${absPath}")).default,`;
|
|
19096
19264
|
}).join("\n");
|
|
19097
|
-
const packedDir =
|
|
19265
|
+
const packedDir = path8__default.resolve(process.cwd(), "agents/packed");
|
|
19098
19266
|
const packedPackages = [];
|
|
19099
|
-
if (
|
|
19267
|
+
if (fs8__default.existsSync(packedDir)) {
|
|
19100
19268
|
console.log(`[vite-plugin-agent] Scanning packed directory: ${packedDir}`);
|
|
19101
19269
|
const packageDirs = discoverPackedPackageDirectories(packedDir);
|
|
19102
19270
|
console.log(`[vite-plugin-agent] Found package dirs: ${packageDirs.join(", ")}`);
|
|
19103
19271
|
for (const pkgPath of packageDirs) {
|
|
19104
|
-
const pkgJsonPath =
|
|
19105
|
-
if (
|
|
19272
|
+
const pkgJsonPath = path8__default.join(pkgPath, "package.json");
|
|
19273
|
+
if (fs8__default.existsSync(pkgJsonPath)) {
|
|
19106
19274
|
try {
|
|
19107
|
-
const pkgJson = JSON.parse(
|
|
19275
|
+
const pkgJson = JSON.parse(fs8__default.readFileSync(pkgJsonPath, "utf-8"));
|
|
19108
19276
|
console.log(`[vite-plugin-agent] Loaded ${pkgPath} package.json, standardagent:`, pkgJson.standardagent);
|
|
19109
19277
|
if (!pkgJson.standardagent) {
|
|
19110
19278
|
continue;
|
|
19111
19279
|
}
|
|
19112
19280
|
const mainEntry = pkgJson.main || "./dist/index.js";
|
|
19113
|
-
const outputDir =
|
|
19281
|
+
const outputDir = path8__default.dirname(mainEntry).replace(/^\.\//, "");
|
|
19114
19282
|
const pkg = {
|
|
19115
19283
|
packageId: pkgJson.name,
|
|
19116
19284
|
version: pkgJson.version,
|
|
@@ -19228,7 +19396,7 @@ export function getVisibleToolNames() {
|
|
|
19228
19396
|
async function loadRoutesVirtualModule(context) {
|
|
19229
19397
|
const { mountPoint, threadApiDir, rou3Code, hmr } = context;
|
|
19230
19398
|
const threadRoutes = scanApiDirectory(threadApiDir);
|
|
19231
|
-
const toAbsolutePath = (inputPath) =>
|
|
19399
|
+
const toAbsolutePath = (inputPath) => path8__default.resolve(process.cwd(), inputPath).replace(/\\/g, "/");
|
|
19232
19400
|
const threadRouteCode = threadRoutes.map(({ method, route, importPath }) => {
|
|
19233
19401
|
const apiRoute = `/api/threads/:threadId${route}`;
|
|
19234
19402
|
return ` addRoute(
|
|
@@ -19239,20 +19407,20 @@ async function loadRoutesVirtualModule(context) {
|
|
|
19239
19407
|
);`;
|
|
19240
19408
|
}).join("\n");
|
|
19241
19409
|
const packedThreadRoutes = [];
|
|
19242
|
-
const packedDir =
|
|
19410
|
+
const packedDir = path8__default.resolve(process.cwd(), "agents/packed");
|
|
19243
19411
|
const packedPackageDirs = discoverPackedPackageDirectories(packedDir);
|
|
19244
19412
|
for (const packagePath of packedPackageDirs) {
|
|
19245
|
-
const packageJsonPath =
|
|
19246
|
-
if (!
|
|
19413
|
+
const packageJsonPath = path8__default.join(packagePath, "package.json");
|
|
19414
|
+
if (!fs8__default.existsSync(packageJsonPath)) {
|
|
19247
19415
|
continue;
|
|
19248
19416
|
}
|
|
19249
19417
|
try {
|
|
19250
|
-
const packageJson = JSON.parse(
|
|
19418
|
+
const packageJson = JSON.parse(fs8__default.readFileSync(packageJsonPath, "utf-8"));
|
|
19251
19419
|
if (!packageJson.standardagent) {
|
|
19252
19420
|
continue;
|
|
19253
19421
|
}
|
|
19254
19422
|
const mainEntry = packageJson.main || "./dist/index.js";
|
|
19255
|
-
const outputDir =
|
|
19423
|
+
const outputDir = path8__default.dirname(mainEntry).replace(/^\.\//, "");
|
|
19256
19424
|
const threadEndpoints = scanPackedThreadEndpoints(packagePath, outputDir);
|
|
19257
19425
|
for (const endpoint of threadEndpoints) {
|
|
19258
19426
|
const apiRoute = `/api/threads/:threadId${endpoint.route}`;
|
|
@@ -19292,12 +19460,19 @@ const MOUNT_POINT = "${mountPoint}";
|
|
|
19292
19460
|
|
|
19293
19461
|
// Routes that don't require authentication
|
|
19294
19462
|
const PUBLIC_ROUTES = [
|
|
19463
|
+
'/api/auth/bootstrap',
|
|
19295
19464
|
'/api/auth/login',
|
|
19465
|
+
'/api/auth/bootstrap',
|
|
19296
19466
|
'/api/auth/config',
|
|
19467
|
+
'/api/config',
|
|
19297
19468
|
'/api/auth/oauth/github',
|
|
19298
19469
|
'/api/auth/oauth/google',
|
|
19299
19470
|
'/api/auth/oauth/github/callback',
|
|
19300
19471
|
'/api/auth/oauth/google/callback',
|
|
19472
|
+
'/api/platform-auth/bootstrap',
|
|
19473
|
+
'/api/platform-auth/login',
|
|
19474
|
+
'/api/platform-auth/logout',
|
|
19475
|
+
'/api/platform-auth/me',
|
|
19301
19476
|
'/api/hooks' // Hook metadata is safe to expose publicly
|
|
19302
19477
|
];
|
|
19303
19478
|
|
|
@@ -19318,6 +19493,20 @@ function isPublicRoute(routePath) {
|
|
|
19318
19493
|
return true;
|
|
19319
19494
|
}
|
|
19320
19495
|
|
|
19496
|
+
// Platform proxy routes handle their own auth.
|
|
19497
|
+
if (routePath.startsWith('/api/platform/') || routePath === '/api/platform') {
|
|
19498
|
+
return true;
|
|
19499
|
+
}
|
|
19500
|
+
|
|
19501
|
+
// Platform session proxy and auth bridge handle auth via platform cookies.
|
|
19502
|
+
if (routePath.startsWith('/api/platform-session/') || routePath === '/api/platform-session') {
|
|
19503
|
+
return true;
|
|
19504
|
+
}
|
|
19505
|
+
|
|
19506
|
+
if (routePath.startsWith('/api/platform-auth/') || routePath === '/api/platform-auth') {
|
|
19507
|
+
return true;
|
|
19508
|
+
}
|
|
19509
|
+
|
|
19321
19510
|
return false;
|
|
19322
19511
|
}
|
|
19323
19512
|
|
|
@@ -19582,12 +19771,12 @@ ${hooksCode}
|
|
|
19582
19771
|
};`;
|
|
19583
19772
|
}
|
|
19584
19773
|
if (id === RESOLVED_VIRTUAL_CONFIG_ID) {
|
|
19585
|
-
const relativeToolsDir =
|
|
19586
|
-
const relativeHooksDir =
|
|
19587
|
-
const relativeApiDir =
|
|
19588
|
-
const relativeModelsDir =
|
|
19589
|
-
const relativePromptsDir =
|
|
19590
|
-
const relativeAgentsDir =
|
|
19774
|
+
const relativeToolsDir = path8__default.relative(process.cwd(), toolsDir).replace(/\\/g, "/");
|
|
19775
|
+
const relativeHooksDir = path8__default.relative(process.cwd(), hooksDir).replace(/\\/g, "/");
|
|
19776
|
+
const relativeApiDir = path8__default.relative(process.cwd(), threadApiDir).replace(/\\/g, "/");
|
|
19777
|
+
const relativeModelsDir = path8__default.relative(process.cwd(), modelsDir).replace(/\\/g, "/");
|
|
19778
|
+
const relativePromptsDir = path8__default.relative(process.cwd(), promptsDir).replace(/\\/g, "/");
|
|
19779
|
+
const relativeAgentsDir = path8__default.relative(process.cwd(), agentsDir).replace(/\\/g, "/");
|
|
19591
19780
|
return `// Virtual agent config module
|
|
19592
19781
|
export const config = {
|
|
19593
19782
|
toolsDir: "${relativeToolsDir}",
|
|
@@ -19757,14 +19946,14 @@ var packingDeps = [
|
|
|
19757
19946
|
"typescript"
|
|
19758
19947
|
];
|
|
19759
19948
|
function createPluginViteConfig(pluginModuleUrl) {
|
|
19760
|
-
const currentDir =
|
|
19949
|
+
const currentDir = path8__default.dirname(fileURLToPath(pluginModuleUrl));
|
|
19761
19950
|
const isInDist = currentDir.endsWith("dist");
|
|
19762
|
-
const builderClientDir =
|
|
19951
|
+
const builderClientDir = path8__default.resolve(
|
|
19763
19952
|
currentDir,
|
|
19764
19953
|
isInDist ? "./client" : "../dist/client"
|
|
19765
19954
|
);
|
|
19766
19955
|
return {
|
|
19767
|
-
publicDir:
|
|
19956
|
+
publicDir: fs8__default.existsSync(builderClientDir) ? builderClientDir : void 0,
|
|
19768
19957
|
build: {
|
|
19769
19958
|
rollupOptions: {
|
|
19770
19959
|
external: [...packingDeps]
|
|
@@ -19821,14 +20010,14 @@ function agentbuilder(options = {}) {
|
|
|
19821
20010
|
if (mountPoint.endsWith("/") && mountPoint.length > 1) {
|
|
19822
20011
|
mountPoint = mountPoint.slice(0, -1);
|
|
19823
20012
|
}
|
|
19824
|
-
const toolsDir = options.toolsDir ?
|
|
19825
|
-
const hooksDir = options.hooksDir ?
|
|
19826
|
-
const threadApiDir = options.apiDir ?
|
|
19827
|
-
const modelsDir = options.modelsDir ?
|
|
19828
|
-
const promptsDir = options.promptsDir ?
|
|
19829
|
-
const agentsDir = options.agentsDir ?
|
|
19830
|
-
const effectsDir = options.effectsDir ?
|
|
19831
|
-
const outputDir =
|
|
20013
|
+
const toolsDir = options.toolsDir ? path8__default.resolve(process.cwd(), options.toolsDir) : path8__default.resolve(process.cwd(), "agents/tools");
|
|
20014
|
+
const hooksDir = options.hooksDir ? path8__default.resolve(process.cwd(), options.hooksDir) : path8__default.resolve(process.cwd(), "agents/hooks");
|
|
20015
|
+
const threadApiDir = options.apiDir ? path8__default.resolve(process.cwd(), options.apiDir) : path8__default.resolve(process.cwd(), "agents/api");
|
|
20016
|
+
const modelsDir = options.modelsDir ? path8__default.resolve(process.cwd(), options.modelsDir) : path8__default.resolve(process.cwd(), "agents/models");
|
|
20017
|
+
const promptsDir = options.promptsDir ? path8__default.resolve(process.cwd(), options.promptsDir) : path8__default.resolve(process.cwd(), "agents/prompts");
|
|
20018
|
+
const agentsDir = options.agentsDir ? path8__default.resolve(process.cwd(), options.agentsDir) : path8__default.resolve(process.cwd(), "agents/agents");
|
|
20019
|
+
const effectsDir = options.effectsDir ? path8__default.resolve(process.cwd(), options.effectsDir) : path8__default.resolve(process.cwd(), "agents/effects");
|
|
20020
|
+
const outputDir = path8__default.resolve(process.cwd(), ".agents");
|
|
19832
20021
|
const installedProviders = buildInstalledProviderCatalog(options.providers || []);
|
|
19833
20022
|
const installedProviderPackageMap = buildProviderPackageMap(options.providers || []);
|
|
19834
20023
|
const typeGenConfig = {
|
|
@@ -19845,11 +20034,11 @@ function agentbuilder(options = {}) {
|
|
|
19845
20034
|
}
|
|
19846
20035
|
}
|
|
19847
20036
|
const __filename = fileURLToPath(import.meta.url);
|
|
19848
|
-
const __dirname =
|
|
19849
|
-
const rou3Path =
|
|
20037
|
+
const __dirname = path8__default.dirname(__filename);
|
|
20038
|
+
const rou3Path = path8__default.join(__dirname, "../dist/rou3.js");
|
|
19850
20039
|
let rou3Code = "";
|
|
19851
20040
|
try {
|
|
19852
|
-
rou3Code =
|
|
20041
|
+
rou3Code = fs8__default.readFileSync(rou3Path, "utf-8").replace(/^export \{[^}]+\};?\s*$/gm, "").replace(/\/\/# sourceMappingURL=.+$/gm, "").trim();
|
|
19853
20042
|
} catch (err) {
|
|
19854
20043
|
console.warn("[vite-plugin-agent] Could not read rou3.js for inlining:", err);
|
|
19855
20044
|
}
|
|
@@ -19959,28 +20148,28 @@ function agentbuilder(options = {}) {
|
|
|
19959
20148
|
writeBundle(options2, bundle) {
|
|
19960
20149
|
const outDir = options2.dir || "dist";
|
|
19961
20150
|
const mountPath = mountPoint.slice(1);
|
|
19962
|
-
const mountDir = mountPath ?
|
|
19963
|
-
const currentDir =
|
|
20151
|
+
const mountDir = mountPath ? path8__default.join(outDir, "../client", mountPath) : path8__default.join(outDir, "../client");
|
|
20152
|
+
const currentDir = path8__default.dirname(fileURLToPath(import.meta.url));
|
|
19964
20153
|
const isInDist = currentDir.endsWith("dist");
|
|
19965
|
-
const clientDir =
|
|
20154
|
+
const clientDir = path8__default.resolve(
|
|
19966
20155
|
currentDir,
|
|
19967
20156
|
isInDist ? "./client" : "../dist/client"
|
|
19968
20157
|
);
|
|
19969
|
-
if (!
|
|
20158
|
+
if (!fs8__default.existsSync(clientDir)) {
|
|
19970
20159
|
console.warn(`[agentbuilder] Client directory not found at ${clientDir}`);
|
|
19971
20160
|
return;
|
|
19972
20161
|
}
|
|
19973
|
-
|
|
20162
|
+
fs8__default.mkdirSync(mountDir, { recursive: true });
|
|
19974
20163
|
function copyRecursive(src, dest) {
|
|
19975
|
-
const entries =
|
|
20164
|
+
const entries = fs8__default.readdirSync(src, { withFileTypes: true });
|
|
19976
20165
|
for (const entry of entries) {
|
|
19977
|
-
const srcPath =
|
|
19978
|
-
const destPath =
|
|
20166
|
+
const srcPath = path8__default.join(src, entry.name);
|
|
20167
|
+
const destPath = path8__default.join(dest, entry.name);
|
|
19979
20168
|
if (entry.isDirectory()) {
|
|
19980
|
-
|
|
20169
|
+
fs8__default.mkdirSync(destPath, { recursive: true });
|
|
19981
20170
|
copyRecursive(srcPath, destPath);
|
|
19982
20171
|
} else {
|
|
19983
|
-
let content =
|
|
20172
|
+
let content = fs8__default.readFileSync(srcPath);
|
|
19984
20173
|
if (entry.name === "index.html") {
|
|
19985
20174
|
const configScript = `<script>window.__AGENTBUILDER_CONFIG__ = { mountPoint: "${mountPoint}" };</script>`;
|
|
19986
20175
|
let htmlContent = content.toString();
|
|
@@ -19989,7 +20178,7 @@ function agentbuilder(options = {}) {
|
|
|
19989
20178
|
htmlContent = htmlContent.replace("</head>", `${configScript}</head>`);
|
|
19990
20179
|
content = Buffer.from(htmlContent);
|
|
19991
20180
|
}
|
|
19992
|
-
|
|
20181
|
+
fs8__default.writeFileSync(destPath, content);
|
|
19993
20182
|
}
|
|
19994
20183
|
}
|
|
19995
20184
|
}
|
|
@@ -21003,8 +21192,27 @@ var migration29 = {
|
|
|
21003
21192
|
}
|
|
21004
21193
|
};
|
|
21005
21194
|
|
|
21195
|
+
// src/durable-objects/migrations/030_add_standard_agents_router_used.ts
|
|
21196
|
+
var migration30 = {
|
|
21197
|
+
version: 30,
|
|
21198
|
+
name: "add_standard_agents_router_used",
|
|
21199
|
+
async up(sql) {
|
|
21200
|
+
const tableInfo = sql.exec(`PRAGMA table_info(logs)`).toArray();
|
|
21201
|
+
const hasRouterUsed = tableInfo.some((col) => col.name === "standard_agents_router_used");
|
|
21202
|
+
if (!hasRouterUsed) {
|
|
21203
|
+
await sql.exec(`
|
|
21204
|
+
ALTER TABLE logs ADD COLUMN standard_agents_router_used INTEGER NOT NULL DEFAULT 0;
|
|
21205
|
+
`);
|
|
21206
|
+
await sql.exec(`
|
|
21207
|
+
CREATE INDEX IF NOT EXISTS idx_logs_standard_agents_router_used
|
|
21208
|
+
ON logs(standard_agents_router_used);
|
|
21209
|
+
`);
|
|
21210
|
+
}
|
|
21211
|
+
}
|
|
21212
|
+
};
|
|
21213
|
+
|
|
21006
21214
|
// src/durable-objects/migrations/index.ts
|
|
21007
|
-
var migrations = [migration, migration2, migration3, migration4, migration5, migration6, migration7, migration8, migration9, migration10, migration11, migration12, migration13, migration14, migration15, migration16, migration17, migration18, migration19, migration20, migration21, migration22, migration23, migration24, migration25, migration26, migration27, migration28, migration29];
|
|
21215
|
+
var migrations = [migration, migration2, migration3, migration4, migration5, migration6, migration7, migration8, migration9, migration10, migration11, migration12, migration13, migration14, migration15, migration16, migration17, migration18, migration19, migration20, migration21, migration22, migration23, migration24, migration25, migration26, migration27, migration28, migration29, migration30];
|
|
21008
21216
|
var LATEST_SCHEMA_VERSION = migrations.length;
|
|
21009
21217
|
|
|
21010
21218
|
// src/durable-objects/DurableThread.ts
|
|
@@ -21773,12 +21981,12 @@ function isQualifiedName(name) {
|
|
|
21773
21981
|
init_sessionTools();
|
|
21774
21982
|
init_code_execution();
|
|
21775
21983
|
var RUNTIME_STORAGE_PREFIX = "__agentbuilder_runtime_storage__:";
|
|
21776
|
-
function normalizeEndpointThreadPath(
|
|
21777
|
-
if (!
|
|
21984
|
+
function normalizeEndpointThreadPath(path20) {
|
|
21985
|
+
if (!path20 || /^[A-Za-z][A-Za-z\d+\-.]*:/.test(path20)) {
|
|
21778
21986
|
throw new Error("Use a relative thread filesystem path");
|
|
21779
21987
|
}
|
|
21780
21988
|
const parts = [];
|
|
21781
|
-
for (const part of
|
|
21989
|
+
for (const part of path20.replace(/\\/g, "/").split("/")) {
|
|
21782
21990
|
if (!part || part === ".") continue;
|
|
21783
21991
|
if (part === "..") {
|
|
21784
21992
|
if (parts.length === 0) throw new Error("Path cannot escape the thread filesystem root");
|
|
@@ -21828,12 +22036,12 @@ function createEndpointFetchBridge() {
|
|
|
21828
22036
|
function createEndpointFsBridge(state) {
|
|
21829
22037
|
const decoder = new TextDecoder();
|
|
21830
22038
|
return {
|
|
21831
|
-
readFile: async (
|
|
21832
|
-
const data = await state.readFile(normalizeEndpointThreadPath(
|
|
22039
|
+
readFile: async (path20) => {
|
|
22040
|
+
const data = await state.readFile(normalizeEndpointThreadPath(path20));
|
|
21833
22041
|
return data ? decoder.decode(data) : null;
|
|
21834
22042
|
},
|
|
21835
|
-
writeFile: async (
|
|
21836
|
-
return state.writeFile(normalizeEndpointThreadPath(
|
|
22043
|
+
writeFile: async (path20, content, mimeType = "text/plain") => {
|
|
22044
|
+
return state.writeFile(normalizeEndpointThreadPath(path20), content, mimeType);
|
|
21837
22045
|
}
|
|
21838
22046
|
};
|
|
21839
22047
|
}
|
|
@@ -21901,19 +22109,19 @@ function createEndpointThreadStateBridge(state) {
|
|
|
21901
22109
|
emit: (event, data) => state.emit(event, data),
|
|
21902
22110
|
getValue: (key) => state.getValue(key),
|
|
21903
22111
|
setValue: (key, value) => state.setValue(key, value),
|
|
21904
|
-
readFile: (
|
|
21905
|
-
writeFile: (
|
|
21906
|
-
return state.writeFile(normalizeEndpointThreadPath(
|
|
22112
|
+
readFile: (path20) => state.readFile(normalizeEndpointThreadPath(path20)),
|
|
22113
|
+
writeFile: (path20, data, mimeType = "application/octet-stream", options) => {
|
|
22114
|
+
return state.writeFile(normalizeEndpointThreadPath(path20), data, mimeType, options);
|
|
21907
22115
|
},
|
|
21908
|
-
statFile: (
|
|
21909
|
-
readdirFile: (
|
|
21910
|
-
unlinkFile: (
|
|
21911
|
-
mkdirFile: (
|
|
21912
|
-
rmdirFile: (
|
|
22116
|
+
statFile: (path20) => state.statFile(normalizeEndpointThreadPath(path20)),
|
|
22117
|
+
readdirFile: (path20) => state.readdirFile(normalizeEndpointThreadPath(path20)),
|
|
22118
|
+
unlinkFile: (path20) => state.unlinkFile(normalizeEndpointThreadPath(path20)),
|
|
22119
|
+
mkdirFile: (path20) => state.mkdirFile(normalizeEndpointThreadPath(path20)),
|
|
22120
|
+
rmdirFile: (path20) => state.rmdirFile(normalizeEndpointThreadPath(path20)),
|
|
21913
22121
|
getFileStats: () => state.getFileStats(),
|
|
21914
22122
|
grepFiles: (pattern) => state.grepFiles(pattern),
|
|
21915
22123
|
findFiles: (pattern) => state.findFiles(pattern),
|
|
21916
|
-
getFileThumbnail: (
|
|
22124
|
+
getFileThumbnail: (path20) => state.getFileThumbnail(normalizeEndpointThreadPath(path20))
|
|
21917
22125
|
};
|
|
21918
22126
|
}
|
|
21919
22127
|
var DurableThread = class extends DurableObject {
|
|
@@ -21941,7 +22149,14 @@ var DurableThread = class extends DurableObject {
|
|
|
21941
22149
|
);
|
|
21942
22150
|
break;
|
|
21943
22151
|
case "processMessage":
|
|
21944
|
-
await this.processMessage(
|
|
22152
|
+
await this.processMessage(
|
|
22153
|
+
args.threadId,
|
|
22154
|
+
args.content,
|
|
22155
|
+
args.role,
|
|
22156
|
+
args.attachments,
|
|
22157
|
+
args.messageId,
|
|
22158
|
+
args.queuedAt
|
|
22159
|
+
);
|
|
21945
22160
|
break;
|
|
21946
22161
|
case "testOperation":
|
|
21947
22162
|
await this.testOperation(args.id, args.label, args.expectedOrder);
|
|
@@ -22456,7 +22671,7 @@ var DurableThread = class extends DurableObject {
|
|
|
22456
22671
|
this.assertJsonSerializableThreadValue(value, "$", /* @__PURE__ */ new WeakSet());
|
|
22457
22672
|
return JSON.stringify(value);
|
|
22458
22673
|
}
|
|
22459
|
-
assertJsonSerializableThreadValue(value,
|
|
22674
|
+
assertJsonSerializableThreadValue(value, path20, seen) {
|
|
22460
22675
|
if (value === null) {
|
|
22461
22676
|
return;
|
|
22462
22677
|
}
|
|
@@ -22466,36 +22681,36 @@ var DurableThread = class extends DurableObject {
|
|
|
22466
22681
|
return;
|
|
22467
22682
|
case "number":
|
|
22468
22683
|
if (!Number.isFinite(value)) {
|
|
22469
|
-
throw new Error(`Thread value at ${
|
|
22684
|
+
throw new Error(`Thread value at ${path20} must be a finite number`);
|
|
22470
22685
|
}
|
|
22471
22686
|
return;
|
|
22472
22687
|
case "object": {
|
|
22473
22688
|
if (seen.has(value)) {
|
|
22474
|
-
throw new Error(`Thread value at ${
|
|
22689
|
+
throw new Error(`Thread value at ${path20} cannot contain circular references`);
|
|
22475
22690
|
}
|
|
22476
22691
|
seen.add(value);
|
|
22477
22692
|
if (Array.isArray(value)) {
|
|
22478
22693
|
for (let i = 0; i < value.length; i += 1) {
|
|
22479
|
-
this.assertJsonSerializableThreadValue(value[i], `${
|
|
22694
|
+
this.assertJsonSerializableThreadValue(value[i], `${path20}[${i}]`, seen);
|
|
22480
22695
|
}
|
|
22481
22696
|
seen.delete(value);
|
|
22482
22697
|
return;
|
|
22483
22698
|
}
|
|
22484
22699
|
const prototype = Object.getPrototypeOf(value);
|
|
22485
22700
|
if (prototype !== Object.prototype && prototype !== null) {
|
|
22486
|
-
throw new Error(`Thread value at ${
|
|
22701
|
+
throw new Error(`Thread value at ${path20} must be a JSON object, array, or primitive`);
|
|
22487
22702
|
}
|
|
22488
22703
|
if (Object.getOwnPropertySymbols(value).length > 0) {
|
|
22489
|
-
throw new Error(`Thread value at ${
|
|
22704
|
+
throw new Error(`Thread value at ${path20} cannot contain symbol keys`);
|
|
22490
22705
|
}
|
|
22491
22706
|
for (const [entryKey, entryValue] of Object.entries(value)) {
|
|
22492
|
-
this.assertJsonSerializableThreadValue(entryValue, `${
|
|
22707
|
+
this.assertJsonSerializableThreadValue(entryValue, `${path20}.${entryKey}`, seen);
|
|
22493
22708
|
}
|
|
22494
22709
|
seen.delete(value);
|
|
22495
22710
|
return;
|
|
22496
22711
|
}
|
|
22497
22712
|
default:
|
|
22498
|
-
throw new Error(`Thread value at ${
|
|
22713
|
+
throw new Error(`Thread value at ${path20} must be JSON-serializable`);
|
|
22499
22714
|
}
|
|
22500
22715
|
}
|
|
22501
22716
|
// ============================================================
|
|
@@ -22720,17 +22935,37 @@ var DurableThread = class extends DurableObject {
|
|
|
22720
22935
|
await this.assertNotTerminated();
|
|
22721
22936
|
const id = crypto.randomUUID();
|
|
22722
22937
|
const now = Date.now() * 1e3;
|
|
22938
|
+
const attachmentsJson = message.attachments ? JSON.stringify(message.attachments) : null;
|
|
22939
|
+
const metadataJson = message.metadata ? JSON.stringify(message.metadata) : null;
|
|
22723
22940
|
await this.ctx.storage.sql.exec(
|
|
22724
22941
|
`INSERT INTO message_queue (id, role, content, attachments, silent, metadata, created_at)
|
|
22725
22942
|
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)`,
|
|
22726
22943
|
id,
|
|
22727
22944
|
message.role,
|
|
22728
22945
|
message.content,
|
|
22729
|
-
|
|
22946
|
+
attachmentsJson,
|
|
22730
22947
|
message.silent ? 1 : 0,
|
|
22731
|
-
|
|
22948
|
+
metadataJson,
|
|
22732
22949
|
now
|
|
22733
22950
|
);
|
|
22951
|
+
if (this.messageSockets?.size > 0) {
|
|
22952
|
+
await this.broadcastMessageWithSubagentProjection({
|
|
22953
|
+
id,
|
|
22954
|
+
role: message.role,
|
|
22955
|
+
content: message.content,
|
|
22956
|
+
attachments: message.attachments ?? null,
|
|
22957
|
+
silent: !!message.silent,
|
|
22958
|
+
created_at: now,
|
|
22959
|
+
status: "pending",
|
|
22960
|
+
depth: 0,
|
|
22961
|
+
metadata: {
|
|
22962
|
+
...message.metadata ?? {},
|
|
22963
|
+
queued: true,
|
|
22964
|
+
queue_status: "queued"
|
|
22965
|
+
},
|
|
22966
|
+
subagent_id: this.extractSubagentIdFromMetadata(metadataJson)
|
|
22967
|
+
});
|
|
22968
|
+
}
|
|
22734
22969
|
const side = message.role === "user" ? "a" : "b";
|
|
22735
22970
|
await this.ensureQueuedMessageExecution(threadId, side);
|
|
22736
22971
|
}
|
|
@@ -22934,9 +23169,9 @@ var DurableThread = class extends DurableObject {
|
|
|
22934
23169
|
* Each migration is run in order, starting from the current version + 1.
|
|
22935
23170
|
*/
|
|
22936
23171
|
async runMigrations(fromVersion) {
|
|
22937
|
-
for (const
|
|
22938
|
-
if (
|
|
22939
|
-
await
|
|
23172
|
+
for (const migration37 of migrations) {
|
|
23173
|
+
if (migration37.version > fromVersion) {
|
|
23174
|
+
await migration37.up(this.ctx.storage.sql);
|
|
22940
23175
|
}
|
|
22941
23176
|
}
|
|
22942
23177
|
}
|
|
@@ -23182,21 +23417,42 @@ var DurableThread = class extends DurableObject {
|
|
|
23182
23417
|
await this.ensureMigrated();
|
|
23183
23418
|
try {
|
|
23184
23419
|
await this.assertNotTerminated();
|
|
23420
|
+
const messageId = crypto.randomUUID();
|
|
23421
|
+
const queuedAt = Date.now() * 1e3;
|
|
23185
23422
|
const queueId = await this.alarmQueue.enqueue(
|
|
23186
23423
|
"processMessage",
|
|
23187
23424
|
{
|
|
23188
23425
|
threadId,
|
|
23189
23426
|
content,
|
|
23190
23427
|
role,
|
|
23191
|
-
attachments
|
|
23428
|
+
attachments,
|
|
23429
|
+
messageId,
|
|
23430
|
+
queuedAt
|
|
23192
23431
|
},
|
|
23193
23432
|
1
|
|
23194
23433
|
// Execute almost immediately (1ms)
|
|
23195
23434
|
);
|
|
23435
|
+
this.broadcastMessage({
|
|
23436
|
+
id: messageId,
|
|
23437
|
+
role,
|
|
23438
|
+
content,
|
|
23439
|
+
attachments: this.parseAttachmentRefsJson(attachments ?? null) ?? null,
|
|
23440
|
+
created_at: queuedAt,
|
|
23441
|
+
status: "pending",
|
|
23442
|
+
depth: 0,
|
|
23443
|
+
silent: false,
|
|
23444
|
+
metadata: {
|
|
23445
|
+
queued: true,
|
|
23446
|
+
queue_status: "queued",
|
|
23447
|
+
queue_source: "alarm_queue",
|
|
23448
|
+
alarm_queue_id: queueId
|
|
23449
|
+
}
|
|
23450
|
+
});
|
|
23196
23451
|
return Response.json(
|
|
23197
23452
|
{
|
|
23198
23453
|
status: "queued",
|
|
23199
23454
|
queueId,
|
|
23455
|
+
messageId,
|
|
23200
23456
|
message: "Message queued for processing. Connect via WebSocket for real-time updates."
|
|
23201
23457
|
},
|
|
23202
23458
|
{ status: 202 }
|
|
@@ -23300,6 +23556,78 @@ var DurableThread = class extends DurableObject {
|
|
|
23300
23556
|
return void 0;
|
|
23301
23557
|
}
|
|
23302
23558
|
}
|
|
23559
|
+
async deleteAttachmentRefsFromJson(raw) {
|
|
23560
|
+
const refs = this.parseAttachmentRefsJson(raw);
|
|
23561
|
+
if (!refs) {
|
|
23562
|
+
return;
|
|
23563
|
+
}
|
|
23564
|
+
for (const ref of refs) {
|
|
23565
|
+
if (ref.path) {
|
|
23566
|
+
await this.unlinkFile(ref.path);
|
|
23567
|
+
}
|
|
23568
|
+
}
|
|
23569
|
+
}
|
|
23570
|
+
async cancelQueuedMessage(messageId) {
|
|
23571
|
+
let cancelled = false;
|
|
23572
|
+
const queuedRows = await this.ctx.storage.sql.exec(
|
|
23573
|
+
`SELECT id, attachments FROM message_queue WHERE id = ?`,
|
|
23574
|
+
messageId
|
|
23575
|
+
).toArray();
|
|
23576
|
+
for (const row of queuedRows) {
|
|
23577
|
+
await this.deleteAttachmentRefsFromJson(row.attachments);
|
|
23578
|
+
await this.ctx.storage.sql.exec(
|
|
23579
|
+
`DELETE FROM message_queue WHERE id = ?`,
|
|
23580
|
+
row.id
|
|
23581
|
+
);
|
|
23582
|
+
cancelled = true;
|
|
23583
|
+
}
|
|
23584
|
+
const alarmRows = await this.ctx.storage.sql.exec(
|
|
23585
|
+
`
|
|
23586
|
+
SELECT id, args
|
|
23587
|
+
FROM alarm_queue
|
|
23588
|
+
WHERE method = 'processMessage'
|
|
23589
|
+
AND status = 'pending'
|
|
23590
|
+
AND (
|
|
23591
|
+
id = ?
|
|
23592
|
+
OR json_extract(args, '$.messageId') = ?
|
|
23593
|
+
)
|
|
23594
|
+
`,
|
|
23595
|
+
messageId,
|
|
23596
|
+
messageId
|
|
23597
|
+
).toArray();
|
|
23598
|
+
for (const row of alarmRows) {
|
|
23599
|
+
try {
|
|
23600
|
+
const args = JSON.parse(row.args);
|
|
23601
|
+
if (typeof args.attachments === "string") {
|
|
23602
|
+
await this.deleteAttachmentRefsFromJson(args.attachments);
|
|
23603
|
+
}
|
|
23604
|
+
} catch (error) {
|
|
23605
|
+
console.error("[DurableThread] Failed to parse queued message args:", error);
|
|
23606
|
+
}
|
|
23607
|
+
await this.ctx.storage.sql.exec(
|
|
23608
|
+
`DELETE FROM alarm_queue WHERE id = ? AND status = 'pending'`,
|
|
23609
|
+
row.id
|
|
23610
|
+
);
|
|
23611
|
+
cancelled = true;
|
|
23612
|
+
}
|
|
23613
|
+
return cancelled;
|
|
23614
|
+
}
|
|
23615
|
+
parseMessageMetadata(raw) {
|
|
23616
|
+
if (typeof raw !== "string") {
|
|
23617
|
+
return void 0;
|
|
23618
|
+
}
|
|
23619
|
+
try {
|
|
23620
|
+
const parsed = JSON.parse(raw);
|
|
23621
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
|
|
23622
|
+
} catch {
|
|
23623
|
+
return void 0;
|
|
23624
|
+
}
|
|
23625
|
+
}
|
|
23626
|
+
extractSubagentIdFromMetadata(raw) {
|
|
23627
|
+
const metadata = this.parseMessageMetadata(raw);
|
|
23628
|
+
const value = typeof metadata?.subagent_id === "string" ? metadata.subagent_id : typeof metadata?.subagentId === "string" ? metadata.subagentId : null;
|
|
23629
|
+
return value && value.trim().length > 0 ? value.trim() : null;
|
|
23630
|
+
}
|
|
23303
23631
|
async getLatestTerminalSessionMessageAfter(messageId, terminalToolNames) {
|
|
23304
23632
|
const toolNames = Array.from(terminalToolNames);
|
|
23305
23633
|
if (toolNames.length === 0) {
|
|
@@ -23330,8 +23658,8 @@ var DurableThread = class extends DurableObject {
|
|
|
23330
23658
|
);
|
|
23331
23659
|
return terminalCursor.toArray()[0] ?? null;
|
|
23332
23660
|
}
|
|
23333
|
-
inferMimeTypeFromPath(
|
|
23334
|
-
const normalized =
|
|
23661
|
+
inferMimeTypeFromPath(path20) {
|
|
23662
|
+
const normalized = path20.toLowerCase();
|
|
23335
23663
|
if (normalized.endsWith(".png")) return "image/png";
|
|
23336
23664
|
if (normalized.endsWith(".jpg") || normalized.endsWith(".jpeg")) return "image/jpeg";
|
|
23337
23665
|
if (normalized.endsWith(".webp")) return "image/webp";
|
|
@@ -23370,7 +23698,7 @@ var DurableThread = class extends DurableObject {
|
|
|
23370
23698
|
ext: value.slice(lastDot + 1).toLowerCase()
|
|
23371
23699
|
};
|
|
23372
23700
|
}
|
|
23373
|
-
resolveAttachmentMimeType(sourceMimeType, fallbackMimeType,
|
|
23701
|
+
resolveAttachmentMimeType(sourceMimeType, fallbackMimeType, path20) {
|
|
23374
23702
|
const source = sourceMimeType?.trim();
|
|
23375
23703
|
if (source && source !== "application/octet-stream") {
|
|
23376
23704
|
return source;
|
|
@@ -23379,7 +23707,7 @@ var DurableThread = class extends DurableObject {
|
|
|
23379
23707
|
if (fallback && fallback !== "application/octet-stream") {
|
|
23380
23708
|
return fallback;
|
|
23381
23709
|
}
|
|
23382
|
-
return this.inferMimeTypeFromPath(
|
|
23710
|
+
return this.inferMimeTypeFromPath(path20) ?? source ?? fallback ?? "application/octet-stream";
|
|
23383
23711
|
}
|
|
23384
23712
|
buildAttachmentTargetPath(preferredName, mimeType, sourcePath) {
|
|
23385
23713
|
const safeName = this.sanitizeFilename(preferredName);
|
|
@@ -23474,8 +23802,8 @@ var DurableThread = class extends DurableObject {
|
|
|
23474
23802
|
}
|
|
23475
23803
|
return copied;
|
|
23476
23804
|
}
|
|
23477
|
-
async readAttachmentDataFromSource(
|
|
23478
|
-
const sourceData = await this.readFile(
|
|
23805
|
+
async readAttachmentDataFromSource(path20, sourceFile) {
|
|
23806
|
+
const sourceData = await this.readFile(path20);
|
|
23479
23807
|
if (sourceData.success && sourceData.data) {
|
|
23480
23808
|
return sourceData.data;
|
|
23481
23809
|
}
|
|
@@ -23509,7 +23837,7 @@ var DurableThread = class extends DurableObject {
|
|
|
23509
23837
|
if (!attachments || attachments.length === 0) {
|
|
23510
23838
|
return "";
|
|
23511
23839
|
}
|
|
23512
|
-
const paths = attachments.map((attachment) => attachment.path).filter((
|
|
23840
|
+
const paths = attachments.map((attachment) => attachment.path).filter((path20) => typeof path20 === "string" && path20.length > 0);
|
|
23513
23841
|
if (paths.length === 0) {
|
|
23514
23842
|
return "";
|
|
23515
23843
|
}
|
|
@@ -23852,22 +24180,163 @@ ${resultContent}${attachmentSummary}`;
|
|
|
23852
24180
|
}
|
|
23853
24181
|
whereClauses.push(`(depth <= ${maxDepth} OR depth IS NULL)`);
|
|
23854
24182
|
const whereClause = whereClauses.length > 0 ? `WHERE ${whereClauses.join(" AND ")}` : "";
|
|
24183
|
+
const orderDirection = order === "ASC" ? "ASC" : "DESC";
|
|
24184
|
+
const combinedMessagesSql = `
|
|
24185
|
+
WITH combined_messages AS (
|
|
24186
|
+
SELECT
|
|
24187
|
+
rowid AS source_rowid,
|
|
24188
|
+
0 AS source_order,
|
|
24189
|
+
'message' AS source,
|
|
24190
|
+
id, role, content, name, tool_calls, tool_call_id, tool_status,
|
|
24191
|
+
log_id, created_at, silent, parent_id, depth, status,
|
|
24192
|
+
reasoning_content, reasoning_details, attachments, metadata,
|
|
24193
|
+
subagent_id
|
|
24194
|
+
FROM messages
|
|
24195
|
+
UNION ALL
|
|
24196
|
+
SELECT
|
|
24197
|
+
rowid AS source_rowid,
|
|
24198
|
+
1 AS source_order,
|
|
24199
|
+
'queue' AS source,
|
|
24200
|
+
id, role, content, NULL AS name, NULL AS tool_calls,
|
|
24201
|
+
NULL AS tool_call_id, NULL AS tool_status, NULL AS log_id,
|
|
24202
|
+
created_at, silent, NULL AS parent_id, 0 AS depth,
|
|
24203
|
+
'pending' AS status, NULL AS reasoning_content,
|
|
24204
|
+
NULL AS reasoning_details, attachments, metadata,
|
|
24205
|
+
NULL AS subagent_id
|
|
24206
|
+
FROM message_queue
|
|
24207
|
+
UNION ALL
|
|
24208
|
+
SELECT
|
|
24209
|
+
rowid AS source_rowid,
|
|
24210
|
+
2 AS source_order,
|
|
24211
|
+
'send_queue' AS source,
|
|
24212
|
+
COALESCE(json_extract(args, '$.messageId'), id) AS id,
|
|
24213
|
+
COALESCE(json_extract(args, '$.role'), 'user') AS role,
|
|
24214
|
+
json_extract(args, '$.content') AS content,
|
|
24215
|
+
NULL AS name, NULL AS tool_calls,
|
|
24216
|
+
NULL AS tool_call_id, NULL AS tool_status, NULL AS log_id,
|
|
24217
|
+
created_at, 0 AS silent, NULL AS parent_id, 0 AS depth,
|
|
24218
|
+
'pending' AS status, NULL AS reasoning_content,
|
|
24219
|
+
NULL AS reasoning_details,
|
|
24220
|
+
json_extract(args, '$.attachments') AS attachments,
|
|
24221
|
+
NULL AS metadata,
|
|
24222
|
+
NULL AS subagent_id
|
|
24223
|
+
FROM alarm_queue
|
|
24224
|
+
WHERE method = 'processMessage'
|
|
24225
|
+
AND status IN ('pending', 'processing')
|
|
24226
|
+
AND (
|
|
24227
|
+
status = 'pending'
|
|
24228
|
+
OR json_extract(args, '$.messageId') IS NOT NULL
|
|
24229
|
+
)
|
|
24230
|
+
AND NOT EXISTS (
|
|
24231
|
+
SELECT 1
|
|
24232
|
+
FROM messages persisted
|
|
24233
|
+
WHERE persisted.id = COALESCE(json_extract(alarm_queue.args, '$.messageId'), alarm_queue.id)
|
|
24234
|
+
)
|
|
24235
|
+
)
|
|
24236
|
+
`;
|
|
23855
24237
|
const countResult = await this.ctx.storage.sql.exec(
|
|
23856
|
-
`
|
|
24238
|
+
`
|
|
24239
|
+
${combinedMessagesSql}
|
|
24240
|
+
SELECT COUNT(*) as total FROM combined_messages ${whereClause}
|
|
24241
|
+
`
|
|
23857
24242
|
);
|
|
23858
24243
|
const total = countResult.one().total;
|
|
23859
24244
|
const result = await this.ctx.storage.sql.exec(
|
|
23860
24245
|
`
|
|
23861
|
-
|
|
23862
|
-
|
|
24246
|
+
${combinedMessagesSql}
|
|
24247
|
+
SELECT source, id, role, content, name, tool_calls, tool_call_id,
|
|
24248
|
+
tool_status, log_id, created_at, silent, parent_id, depth, status,
|
|
24249
|
+
reasoning_content, reasoning_details, attachments, metadata,
|
|
24250
|
+
subagent_id
|
|
24251
|
+
FROM combined_messages
|
|
23863
24252
|
${whereClause}
|
|
23864
|
-
ORDER BY created_at ${
|
|
24253
|
+
ORDER BY created_at ${orderDirection}, source_order ${orderDirection}, source_rowid ${orderDirection}
|
|
23865
24254
|
LIMIT ? OFFSET ?
|
|
23866
24255
|
`,
|
|
23867
24256
|
limit,
|
|
23868
24257
|
offset
|
|
23869
24258
|
);
|
|
23870
24259
|
let messages = result.toArray().map((row) => {
|
|
24260
|
+
const metadata = this.parseMessageMetadata(row.metadata);
|
|
24261
|
+
const isQueuedSource = row.source === "queue" || row.source === "send_queue";
|
|
24262
|
+
const messageMetadata = isQueuedSource ? {
|
|
24263
|
+
...metadata ?? {},
|
|
24264
|
+
queued: true,
|
|
24265
|
+
queue_status: "queued",
|
|
24266
|
+
queue_source: row.source === "send_queue" ? "alarm_queue" : "message_queue"
|
|
24267
|
+
} : metadata;
|
|
24268
|
+
return {
|
|
24269
|
+
id: row.id,
|
|
24270
|
+
role: row.role,
|
|
24271
|
+
content: row.content,
|
|
24272
|
+
name: row.name,
|
|
24273
|
+
tool_calls: row.tool_calls,
|
|
24274
|
+
tool_call_id: row.tool_call_id,
|
|
24275
|
+
tool_status: row.tool_status,
|
|
24276
|
+
log_id: row.log_id,
|
|
24277
|
+
created_at: row.created_at,
|
|
24278
|
+
silent: row.silent === 1,
|
|
24279
|
+
parent_id: row.parent_id,
|
|
24280
|
+
depth: row.depth,
|
|
24281
|
+
status: row.status,
|
|
24282
|
+
reasoning_content: row.reasoning_content,
|
|
24283
|
+
reasoning_details: row.reasoning_details,
|
|
24284
|
+
attachments: row.attachments ? JSON.parse(row.attachments) : null,
|
|
24285
|
+
metadata: messageMetadata,
|
|
24286
|
+
subagent_id: row.subagent_id ?? (row.source === "queue" ? this.extractSubagentIdFromMetadata(row.metadata) : null)
|
|
24287
|
+
};
|
|
24288
|
+
});
|
|
24289
|
+
const subagentIds = Array.from(
|
|
24290
|
+
new Set(
|
|
24291
|
+
messages.map(
|
|
24292
|
+
(message) => typeof message.subagent_id === "string" ? message.subagent_id.trim() : ""
|
|
24293
|
+
).filter((id) => id.length > 0)
|
|
24294
|
+
)
|
|
24295
|
+
);
|
|
24296
|
+
if (subagentIds.length > 0) {
|
|
24297
|
+
const projectionMap = await this.resolveSubagentMessageProjections(
|
|
24298
|
+
subagentIds
|
|
24299
|
+
);
|
|
24300
|
+
messages = messages.map((message) => {
|
|
24301
|
+
const subagentId = typeof message.subagent_id === "string" ? message.subagent_id.trim() : "";
|
|
24302
|
+
if (!subagentId) {
|
|
24303
|
+
return message;
|
|
24304
|
+
}
|
|
24305
|
+
const projection = projectionMap.get(subagentId);
|
|
24306
|
+
return projection ? { ...message, ...projection } : message;
|
|
24307
|
+
});
|
|
24308
|
+
}
|
|
24309
|
+
if (order === "DESC") {
|
|
24310
|
+
messages = messages.reverse();
|
|
24311
|
+
}
|
|
24312
|
+
const hasMore = offset + messages.length < total;
|
|
24313
|
+
return { messages, total, hasMore };
|
|
24314
|
+
} catch (error) {
|
|
24315
|
+
console.error("Error in getMessages:", error);
|
|
24316
|
+
throw error;
|
|
24317
|
+
}
|
|
24318
|
+
}
|
|
24319
|
+
/**
|
|
24320
|
+
* Get specific messages, optionally expanding any requested tool-call message
|
|
24321
|
+
* to the full contiguous workblock it belongs to.
|
|
24322
|
+
*/
|
|
24323
|
+
async getMessagesByIds(ids, includeSilent = false, maxDepth = 0, includeWorkblocks = false) {
|
|
24324
|
+
await this.ensureMigrated();
|
|
24325
|
+
const uniqueIds = Array.from(new Set(ids.map((id) => id.trim()).filter(Boolean)));
|
|
24326
|
+
if (uniqueIds.length === 0) {
|
|
24327
|
+
return { messages: [], total: 0, hasMore: false };
|
|
24328
|
+
}
|
|
24329
|
+
if (uniqueIds.length > 200) {
|
|
24330
|
+
throw new Error("Too many message IDs requested");
|
|
24331
|
+
}
|
|
24332
|
+
const whereClauses = [];
|
|
24333
|
+
if (!includeSilent) {
|
|
24334
|
+
whereClauses.push("silent = 0");
|
|
24335
|
+
}
|
|
24336
|
+
whereClauses.push(`(depth <= ${maxDepth} OR depth IS NULL)`);
|
|
24337
|
+
const baseWhereClause = whereClauses.length > 0 ? whereClauses.join(" AND ") : "1 = 1";
|
|
24338
|
+
const mapRows = async (rows) => {
|
|
24339
|
+
let messages2 = rows.map((row) => {
|
|
23871
24340
|
let metadata;
|
|
23872
24341
|
if (typeof row.metadata === "string") {
|
|
23873
24342
|
try {
|
|
@@ -23902,7 +24371,7 @@ ${resultContent}${attachmentSummary}`;
|
|
|
23902
24371
|
});
|
|
23903
24372
|
const subagentIds = Array.from(
|
|
23904
24373
|
new Set(
|
|
23905
|
-
|
|
24374
|
+
messages2.map(
|
|
23906
24375
|
(message) => typeof message.subagent_id === "string" ? message.subagent_id.trim() : ""
|
|
23907
24376
|
).filter((id) => id.length > 0)
|
|
23908
24377
|
)
|
|
@@ -23911,7 +24380,7 @@ ${resultContent}${attachmentSummary}`;
|
|
|
23911
24380
|
const projectionMap = await this.resolveSubagentMessageProjections(
|
|
23912
24381
|
subagentIds
|
|
23913
24382
|
);
|
|
23914
|
-
|
|
24383
|
+
messages2 = messages2.map((message) => {
|
|
23915
24384
|
const subagentId = typeof message.subagent_id === "string" ? message.subagent_id.trim() : "";
|
|
23916
24385
|
if (!subagentId) {
|
|
23917
24386
|
return message;
|
|
@@ -23920,15 +24389,61 @@ ${resultContent}${attachmentSummary}`;
|
|
|
23920
24389
|
return projection ? { ...message, ...projection } : message;
|
|
23921
24390
|
});
|
|
23922
24391
|
}
|
|
23923
|
-
|
|
23924
|
-
|
|
24392
|
+
return messages2;
|
|
24393
|
+
};
|
|
24394
|
+
const selectColumns = `
|
|
24395
|
+
id, role, content, name, tool_calls, tool_call_id, tool_status, log_id,
|
|
24396
|
+
created_at, silent, parent_id, depth, status, reasoning_content,
|
|
24397
|
+
reasoning_details, attachments, metadata, subagent_id
|
|
24398
|
+
`;
|
|
24399
|
+
if (!includeWorkblocks) {
|
|
24400
|
+
const placeholders = uniqueIds.map(() => "?").join(", ");
|
|
24401
|
+
const rows = await this.ctx.storage.sql.exec(
|
|
24402
|
+
`
|
|
24403
|
+
SELECT ${selectColumns}
|
|
24404
|
+
FROM messages
|
|
24405
|
+
WHERE ${baseWhereClause} AND id IN (${placeholders})
|
|
24406
|
+
ORDER BY created_at ASC, rowid ASC
|
|
24407
|
+
`,
|
|
24408
|
+
...uniqueIds
|
|
24409
|
+
).toArray();
|
|
24410
|
+
const messages2 = await mapRows(rows);
|
|
24411
|
+
return { messages: messages2, total: messages2.length, hasMore: false };
|
|
24412
|
+
}
|
|
24413
|
+
const allRows = await this.ctx.storage.sql.exec(
|
|
24414
|
+
`
|
|
24415
|
+
SELECT ${selectColumns}
|
|
24416
|
+
FROM messages
|
|
24417
|
+
WHERE ${baseWhereClause}
|
|
24418
|
+
ORDER BY created_at ASC, rowid ASC
|
|
24419
|
+
`
|
|
24420
|
+
).toArray();
|
|
24421
|
+
const requestedIds = new Set(uniqueIds);
|
|
24422
|
+
const selectedIds = /* @__PURE__ */ new Set();
|
|
24423
|
+
const isWorkblockRow = (row) => row.role === "tool" || row.role === "assistant" && typeof row.tool_calls === "string" && row.tool_calls.length > 0;
|
|
24424
|
+
for (let index = 0; index < allRows.length; index++) {
|
|
24425
|
+
const row = allRows[index];
|
|
24426
|
+
if (!requestedIds.has(row.id)) continue;
|
|
24427
|
+
if (!isWorkblockRow(row)) {
|
|
24428
|
+
selectedIds.add(row.id);
|
|
24429
|
+
continue;
|
|
24430
|
+
}
|
|
24431
|
+
let start = index;
|
|
24432
|
+
while (start > 0 && isWorkblockRow(allRows[start - 1])) {
|
|
24433
|
+
start--;
|
|
24434
|
+
}
|
|
24435
|
+
let end = index;
|
|
24436
|
+
while (end + 1 < allRows.length && isWorkblockRow(allRows[end + 1])) {
|
|
24437
|
+
end++;
|
|
24438
|
+
}
|
|
24439
|
+
for (let i = start; i <= end; i++) {
|
|
24440
|
+
selectedIds.add(allRows[i].id);
|
|
23925
24441
|
}
|
|
23926
|
-
const hasMore = offset + messages.length < total;
|
|
23927
|
-
return { messages, total, hasMore };
|
|
23928
|
-
} catch (error) {
|
|
23929
|
-
console.error("Error in getMessages:", error);
|
|
23930
|
-
throw error;
|
|
23931
24442
|
}
|
|
24443
|
+
const messages = await mapRows(
|
|
24444
|
+
allRows.filter((row) => selectedIds.has(row.id))
|
|
24445
|
+
);
|
|
24446
|
+
return { messages, total: messages.length, hasMore: false };
|
|
23932
24447
|
}
|
|
23933
24448
|
/**
|
|
23934
24449
|
* Delete a message (RPC method)
|
|
@@ -23937,6 +24452,9 @@ ${resultContent}${attachmentSummary}`;
|
|
|
23937
24452
|
async deleteMessage(messageId) {
|
|
23938
24453
|
await this.ensureMigrated();
|
|
23939
24454
|
try {
|
|
24455
|
+
if (await this.cancelQueuedMessage(messageId)) {
|
|
24456
|
+
return { success: true };
|
|
24457
|
+
}
|
|
23940
24458
|
const rows = await this.ctx.storage.sql.exec(
|
|
23941
24459
|
`SELECT id, attachments FROM messages WHERE id = ?`,
|
|
23942
24460
|
messageId
|
|
@@ -23947,12 +24465,7 @@ ${resultContent}${attachmentSummary}`;
|
|
|
23947
24465
|
const attachmentsJson = rows[0].attachments;
|
|
23948
24466
|
if (attachmentsJson) {
|
|
23949
24467
|
try {
|
|
23950
|
-
|
|
23951
|
-
for (const ref of refs) {
|
|
23952
|
-
if (ref.path) {
|
|
23953
|
-
await this.unlinkFile(ref.path);
|
|
23954
|
-
}
|
|
23955
|
-
}
|
|
24468
|
+
await this.deleteAttachmentRefsFromJson(attachmentsJson);
|
|
23956
24469
|
} catch (e) {
|
|
23957
24470
|
console.error("Failed to cleanup attachments:", e);
|
|
23958
24471
|
}
|
|
@@ -24076,7 +24589,7 @@ ${resultContent}${attachmentSummary}`;
|
|
|
24076
24589
|
const result = await this.ctx.storage.sql.exec(
|
|
24077
24590
|
`
|
|
24078
24591
|
SELECT
|
|
24079
|
-
id, message_id, provider, actual_provider, model, model_name, prompt_name,
|
|
24592
|
+
id, message_id, provider, actual_provider, standard_agents_router_used, model, model_name, prompt_name,
|
|
24080
24593
|
tools_called, queued_tools, provider_tools, parent_log_id, retry_of_log_id, error, cost_total,
|
|
24081
24594
|
is_complete, created_at, request_body
|
|
24082
24595
|
FROM logs
|
|
@@ -24091,6 +24604,7 @@ ${resultContent}${attachmentSummary}`;
|
|
|
24091
24604
|
message_id: row.message_id,
|
|
24092
24605
|
provider: row.provider,
|
|
24093
24606
|
actual_provider: row.actual_provider,
|
|
24607
|
+
standard_agents_router_used: row.standard_agents_router_used === 1,
|
|
24094
24608
|
model: row.model,
|
|
24095
24609
|
model_name: row.model_name,
|
|
24096
24610
|
prompt_name: row.prompt_name,
|
|
@@ -24112,6 +24626,203 @@ ${resultContent}${attachmentSummary}`;
|
|
|
24112
24626
|
throw error;
|
|
24113
24627
|
}
|
|
24114
24628
|
}
|
|
24629
|
+
/**
|
|
24630
|
+
* Get specific logs, optionally including all descendant logs.
|
|
24631
|
+
*/
|
|
24632
|
+
async getLogsByIds(ids, includeDescendants = false, order = "ASC") {
|
|
24633
|
+
await this.ensureMigrated();
|
|
24634
|
+
const uniqueIds = Array.from(new Set(ids.map((id) => id.trim()).filter(Boolean)));
|
|
24635
|
+
if (uniqueIds.length === 0) {
|
|
24636
|
+
return { logs: [], total: 0, hasMore: false };
|
|
24637
|
+
}
|
|
24638
|
+
if (uniqueIds.length > 200) {
|
|
24639
|
+
throw new Error("Too many log IDs requested");
|
|
24640
|
+
}
|
|
24641
|
+
const placeholders = uniqueIds.map(() => "?").join(", ");
|
|
24642
|
+
const sourceQuery = includeDescendants ? `
|
|
24643
|
+
WITH RECURSIVE
|
|
24644
|
+
seed_logs(id) AS (
|
|
24645
|
+
SELECT id FROM logs WHERE id IN (${placeholders})
|
|
24646
|
+
),
|
|
24647
|
+
descendant_logs(id) AS (
|
|
24648
|
+
SELECT id FROM seed_logs
|
|
24649
|
+
UNION
|
|
24650
|
+
SELECT logs.id
|
|
24651
|
+
FROM logs
|
|
24652
|
+
JOIN descendant_logs ON logs.parent_log_id = descendant_logs.id
|
|
24653
|
+
),
|
|
24654
|
+
selected_logs(id) AS (
|
|
24655
|
+
SELECT id FROM descendant_logs
|
|
24656
|
+
UNION
|
|
24657
|
+
SELECT logs.parent_log_id
|
|
24658
|
+
FROM logs
|
|
24659
|
+
JOIN selected_logs ON logs.id = selected_logs.id
|
|
24660
|
+
WHERE logs.parent_log_id IS NOT NULL
|
|
24661
|
+
)
|
|
24662
|
+
SELECT
|
|
24663
|
+
id, message_id, provider, actual_provider, model, model_name, prompt_name,
|
|
24664
|
+
tools_called, queued_tools, provider_tools, parent_log_id, retry_of_log_id, error, cost_total,
|
|
24665
|
+
is_complete, created_at, request_body
|
|
24666
|
+
FROM logs
|
|
24667
|
+
WHERE id IN (SELECT id FROM selected_logs)
|
|
24668
|
+
ORDER BY created_at ${order}, rowid ${order}
|
|
24669
|
+
` : `
|
|
24670
|
+
SELECT
|
|
24671
|
+
id, message_id, provider, actual_provider, model, model_name, prompt_name,
|
|
24672
|
+
tools_called, queued_tools, provider_tools, parent_log_id, retry_of_log_id, error, cost_total,
|
|
24673
|
+
is_complete, created_at, request_body
|
|
24674
|
+
FROM logs
|
|
24675
|
+
WHERE id IN (${placeholders})
|
|
24676
|
+
ORDER BY created_at ${order}, rowid ${order}
|
|
24677
|
+
`;
|
|
24678
|
+
const result = await this.ctx.storage.sql.exec(sourceQuery, ...uniqueIds);
|
|
24679
|
+
const logs = result.toArray().map((row) => ({
|
|
24680
|
+
id: row.id,
|
|
24681
|
+
message_id: row.message_id,
|
|
24682
|
+
provider: row.provider,
|
|
24683
|
+
actual_provider: row.actual_provider,
|
|
24684
|
+
model: row.model,
|
|
24685
|
+
model_name: row.model_name,
|
|
24686
|
+
prompt_name: row.prompt_name,
|
|
24687
|
+
tools_called: row.tools_called,
|
|
24688
|
+
queued_tools: row.queued_tools,
|
|
24689
|
+
provider_tools: row.provider_tools,
|
|
24690
|
+
parent_log_id: row.parent_log_id,
|
|
24691
|
+
retry_of_log_id: row.retry_of_log_id,
|
|
24692
|
+
error: row.error,
|
|
24693
|
+
cost_total: row.cost_total,
|
|
24694
|
+
is_complete: row.is_complete === 1,
|
|
24695
|
+
created_at: row.created_at,
|
|
24696
|
+
request_body: row.request_body
|
|
24697
|
+
}));
|
|
24698
|
+
return { logs, total: logs.length, hasMore: false };
|
|
24699
|
+
}
|
|
24700
|
+
/**
|
|
24701
|
+
* Get logs for specific messages, optionally expanding requested messages to
|
|
24702
|
+
* the full contiguous workblock they belong to and including descendant logs.
|
|
24703
|
+
*/
|
|
24704
|
+
async getLogsByMessageIds(messageIds, includeWorkblocks = false, includeDescendants = false, order = "ASC") {
|
|
24705
|
+
await this.ensureMigrated();
|
|
24706
|
+
const uniqueMessageIds = Array.from(
|
|
24707
|
+
new Set(messageIds.map((id) => id.trim()).filter(Boolean))
|
|
24708
|
+
);
|
|
24709
|
+
if (uniqueMessageIds.length === 0) {
|
|
24710
|
+
return { logs: [], total: 0, hasMore: false };
|
|
24711
|
+
}
|
|
24712
|
+
if (uniqueMessageIds.length > 200) {
|
|
24713
|
+
throw new Error("Too many message IDs requested");
|
|
24714
|
+
}
|
|
24715
|
+
const selectedMessageIds = /* @__PURE__ */ new Set();
|
|
24716
|
+
if (includeWorkblocks) {
|
|
24717
|
+
const allRows = await this.ctx.storage.sql.exec(
|
|
24718
|
+
`
|
|
24719
|
+
SELECT id, role, tool_calls
|
|
24720
|
+
FROM messages
|
|
24721
|
+
ORDER BY created_at ASC, rowid ASC
|
|
24722
|
+
`
|
|
24723
|
+
).toArray();
|
|
24724
|
+
const requestedIds = new Set(uniqueMessageIds);
|
|
24725
|
+
const isWorkblockRow = (row) => row.role === "tool" || row.role === "assistant" && typeof row.tool_calls === "string" && row.tool_calls.length > 0;
|
|
24726
|
+
for (let index = 0; index < allRows.length; index++) {
|
|
24727
|
+
const row = allRows[index];
|
|
24728
|
+
if (!requestedIds.has(row.id)) continue;
|
|
24729
|
+
if (!isWorkblockRow(row)) {
|
|
24730
|
+
selectedMessageIds.add(row.id);
|
|
24731
|
+
continue;
|
|
24732
|
+
}
|
|
24733
|
+
let start = index;
|
|
24734
|
+
while (start > 0 && isWorkblockRow(allRows[start - 1])) {
|
|
24735
|
+
start--;
|
|
24736
|
+
}
|
|
24737
|
+
let end = index;
|
|
24738
|
+
while (end + 1 < allRows.length && isWorkblockRow(allRows[end + 1])) {
|
|
24739
|
+
end++;
|
|
24740
|
+
}
|
|
24741
|
+
for (let i = start; i <= end; i++) {
|
|
24742
|
+
selectedMessageIds.add(allRows[i].id);
|
|
24743
|
+
}
|
|
24744
|
+
}
|
|
24745
|
+
} else {
|
|
24746
|
+
uniqueMessageIds.forEach((id) => selectedMessageIds.add(id));
|
|
24747
|
+
}
|
|
24748
|
+
const selectedMessageIdList = Array.from(selectedMessageIds);
|
|
24749
|
+
if (selectedMessageIdList.length === 0) {
|
|
24750
|
+
return { logs: [], total: 0, hasMore: false };
|
|
24751
|
+
}
|
|
24752
|
+
const rowsById = /* @__PURE__ */ new Map();
|
|
24753
|
+
const MESSAGE_ID_CHUNK_SIZE = 80;
|
|
24754
|
+
for (let index = 0; index < selectedMessageIdList.length; index += MESSAGE_ID_CHUNK_SIZE) {
|
|
24755
|
+
const chunk = selectedMessageIdList.slice(index, index + MESSAGE_ID_CHUNK_SIZE);
|
|
24756
|
+
const placeholders = chunk.map(() => "?").join(", ");
|
|
24757
|
+
const sourceQuery = includeDescendants ? `
|
|
24758
|
+
WITH RECURSIVE
|
|
24759
|
+
seed_logs(id) AS (
|
|
24760
|
+
SELECT id FROM logs WHERE message_id IN (${placeholders})
|
|
24761
|
+
),
|
|
24762
|
+
descendant_logs(id) AS (
|
|
24763
|
+
SELECT id FROM seed_logs
|
|
24764
|
+
UNION
|
|
24765
|
+
SELECT logs.id
|
|
24766
|
+
FROM logs
|
|
24767
|
+
JOIN descendant_logs ON logs.parent_log_id = descendant_logs.id
|
|
24768
|
+
),
|
|
24769
|
+
selected_logs(id) AS (
|
|
24770
|
+
SELECT id FROM descendant_logs
|
|
24771
|
+
UNION
|
|
24772
|
+
SELECT logs.parent_log_id
|
|
24773
|
+
FROM logs
|
|
24774
|
+
JOIN selected_logs ON logs.id = selected_logs.id
|
|
24775
|
+
WHERE logs.parent_log_id IS NOT NULL
|
|
24776
|
+
)
|
|
24777
|
+
SELECT
|
|
24778
|
+
rowid AS row_index,
|
|
24779
|
+
id, message_id, provider, actual_provider, model, model_name, prompt_name,
|
|
24780
|
+
tools_called, queued_tools, provider_tools, parent_log_id, retry_of_log_id, error, cost_total,
|
|
24781
|
+
is_complete, created_at, request_body
|
|
24782
|
+
FROM logs
|
|
24783
|
+
WHERE id IN (SELECT id FROM selected_logs)
|
|
24784
|
+
ORDER BY created_at ${order}, rowid ${order}
|
|
24785
|
+
` : `
|
|
24786
|
+
SELECT
|
|
24787
|
+
rowid AS row_index,
|
|
24788
|
+
id, message_id, provider, actual_provider, model, model_name, prompt_name,
|
|
24789
|
+
tools_called, queued_tools, provider_tools, parent_log_id, retry_of_log_id, error, cost_total,
|
|
24790
|
+
is_complete, created_at, request_body
|
|
24791
|
+
FROM logs
|
|
24792
|
+
WHERE message_id IN (${placeholders})
|
|
24793
|
+
ORDER BY created_at ${order}, rowid ${order}
|
|
24794
|
+
`;
|
|
24795
|
+
const result = await this.ctx.storage.sql.exec(sourceQuery, ...chunk);
|
|
24796
|
+
for (const row of result.toArray()) {
|
|
24797
|
+
rowsById.set(row.id, row);
|
|
24798
|
+
}
|
|
24799
|
+
}
|
|
24800
|
+
const rows = Array.from(rowsById.values()).sort((left, right) => {
|
|
24801
|
+
const createdAtDelta = left.created_at - right.created_at;
|
|
24802
|
+
const rowDelta = left.row_index - right.row_index;
|
|
24803
|
+
return order === "ASC" ? createdAtDelta || rowDelta : -createdAtDelta || -rowDelta;
|
|
24804
|
+
});
|
|
24805
|
+
const logs = rows.map((row) => ({
|
|
24806
|
+
id: row.id,
|
|
24807
|
+
message_id: row.message_id,
|
|
24808
|
+
provider: row.provider,
|
|
24809
|
+
actual_provider: row.actual_provider,
|
|
24810
|
+
model: row.model,
|
|
24811
|
+
model_name: row.model_name,
|
|
24812
|
+
prompt_name: row.prompt_name,
|
|
24813
|
+
tools_called: row.tools_called,
|
|
24814
|
+
queued_tools: row.queued_tools,
|
|
24815
|
+
provider_tools: row.provider_tools,
|
|
24816
|
+
parent_log_id: row.parent_log_id,
|
|
24817
|
+
retry_of_log_id: row.retry_of_log_id,
|
|
24818
|
+
error: row.error,
|
|
24819
|
+
cost_total: row.cost_total,
|
|
24820
|
+
is_complete: row.is_complete === 1,
|
|
24821
|
+
created_at: row.created_at,
|
|
24822
|
+
request_body: row.request_body
|
|
24823
|
+
}));
|
|
24824
|
+
return { logs, total: logs.length, hasMore: false };
|
|
24825
|
+
}
|
|
24115
24826
|
/**
|
|
24116
24827
|
* Get detailed information for a single log (RPC method)
|
|
24117
24828
|
* This includes all fields including large ones like request/response bodies
|
|
@@ -24122,7 +24833,7 @@ ${resultContent}${attachmentSummary}`;
|
|
|
24122
24833
|
const result = await this.ctx.storage.sql.exec(
|
|
24123
24834
|
`
|
|
24124
24835
|
SELECT
|
|
24125
|
-
l.id, l.message_id, l.provider, l.actual_provider, l.model, l.model_name, l.endpoint,
|
|
24836
|
+
l.id, l.message_id, l.provider, l.actual_provider, l.standard_agents_router_used, l.model, l.model_name, l.endpoint,
|
|
24126
24837
|
l.request_body, l.request_headers, l.response_body, l.response_headers,
|
|
24127
24838
|
l.status_code, l.reasoning_content, l.input_tokens, l.cached_tokens, l.output_tokens,
|
|
24128
24839
|
l.reasoning_tokens, l.total_tokens, l.latency_ms, l.time_to_first_token_ms,
|
|
@@ -24194,6 +24905,7 @@ ${resultContent}${attachmentSummary}`;
|
|
|
24194
24905
|
message_id: row.message_id,
|
|
24195
24906
|
provider: row.provider,
|
|
24196
24907
|
actual_provider: row.actual_provider,
|
|
24908
|
+
standard_agents_router_used: row.standard_agents_router_used === 1,
|
|
24197
24909
|
model: row.model,
|
|
24198
24910
|
model_name: row.model_name,
|
|
24199
24911
|
endpoint: row.endpoint,
|
|
@@ -24787,7 +25499,7 @@ ${resultContent}${attachmentSummary}`;
|
|
|
24787
25499
|
* Internal method: Process a message (called by alarm queue)
|
|
24788
25500
|
* This is the actual message processing logic, separate from the public sendMessage() RPC method
|
|
24789
25501
|
*/
|
|
24790
|
-
async processMessage(threadId, content, role = "user", attachments) {
|
|
25502
|
+
async processMessage(threadId, content, role = "user", attachments, queuedMessageId, queuedAt) {
|
|
24791
25503
|
await this.assertNotTerminated();
|
|
24792
25504
|
if (role === "user") {
|
|
24793
25505
|
await this.ctx.storage.sql.exec(
|
|
@@ -24863,8 +25575,8 @@ ${resultContent}${attachmentSummary}`;
|
|
|
24863
25575
|
side_b_session_status_message_property: sideBSession.status.messageProperty,
|
|
24864
25576
|
side_b_session_status_attachments_property: sideBSession.status.attachmentsProperty
|
|
24865
25577
|
};
|
|
24866
|
-
const messageId = crypto.randomUUID();
|
|
24867
|
-
const timestamp = Date.now() * 1e3;
|
|
25578
|
+
const messageId = this.asOptionalString(queuedMessageId) ?? crypto.randomUUID();
|
|
25579
|
+
const timestamp = typeof queuedAt === "number" && Number.isFinite(queuedAt) && queuedAt > 0 ? queuedAt : Date.now() * 1e3;
|
|
24868
25580
|
let message = {
|
|
24869
25581
|
id: messageId,
|
|
24870
25582
|
role,
|
|
@@ -25232,11 +25944,11 @@ ${resultContent}${attachmentSummary}`;
|
|
|
25232
25944
|
/**
|
|
25233
25945
|
* Write a file to storage (RPC method)
|
|
25234
25946
|
*/
|
|
25235
|
-
async writeFile(
|
|
25947
|
+
async writeFile(path20, data, mimeType, options) {
|
|
25236
25948
|
await this.ensureMigrated();
|
|
25237
25949
|
try {
|
|
25238
|
-
const
|
|
25239
|
-
const existingFile = await
|
|
25950
|
+
const fs18 = this.getFileStorage();
|
|
25951
|
+
const existingFile = await fs18.stat(path20);
|
|
25240
25952
|
const isUpdate = existingFile !== null;
|
|
25241
25953
|
const binaryString = atob(data);
|
|
25242
25954
|
const dataBuffer = new Uint8Array(binaryString.length);
|
|
@@ -25258,12 +25970,12 @@ ${resultContent}${attachmentSummary}`;
|
|
|
25258
25970
|
}
|
|
25259
25971
|
}
|
|
25260
25972
|
}
|
|
25261
|
-
const record = await
|
|
25973
|
+
const record = await fs18.writeFile(path20, dataBuffer, mimeType, {
|
|
25262
25974
|
metadata: options?.metadata,
|
|
25263
25975
|
thumbnail: thumbnailBuffer
|
|
25264
25976
|
});
|
|
25265
25977
|
this.broadcastEvent(isUpdate ? "file_updated" : "file_created", {
|
|
25266
|
-
path:
|
|
25978
|
+
path: path20,
|
|
25267
25979
|
file: record
|
|
25268
25980
|
});
|
|
25269
25981
|
return { success: true, file: record };
|
|
@@ -25275,15 +25987,15 @@ ${resultContent}${attachmentSummary}`;
|
|
|
25275
25987
|
/**
|
|
25276
25988
|
* Write a text file to storage (RPC method)
|
|
25277
25989
|
*/
|
|
25278
|
-
async writeTextFile(
|
|
25990
|
+
async writeTextFile(path20, content, mimeType = "text/plain", options) {
|
|
25279
25991
|
await this.ensureMigrated();
|
|
25280
25992
|
try {
|
|
25281
|
-
const
|
|
25282
|
-
const existingFile = await
|
|
25993
|
+
const fs18 = this.getFileStorage();
|
|
25994
|
+
const existingFile = await fs18.stat(path20);
|
|
25283
25995
|
const isUpdate = existingFile !== null;
|
|
25284
|
-
const record = await
|
|
25996
|
+
const record = await fs18.writeFile(path20, content, mimeType, options);
|
|
25285
25997
|
this.broadcastEvent(isUpdate ? "file_updated" : "file_created", {
|
|
25286
|
-
path:
|
|
25998
|
+
path: path20,
|
|
25287
25999
|
file: record
|
|
25288
26000
|
});
|
|
25289
26001
|
return { success: true, file: record };
|
|
@@ -25320,11 +26032,11 @@ ${resultContent}${attachmentSummary}`;
|
|
|
25320
26032
|
/**
|
|
25321
26033
|
* Link to an external file (RPC method)
|
|
25322
26034
|
*/
|
|
25323
|
-
async linkFile(
|
|
26035
|
+
async linkFile(path20, location, options) {
|
|
25324
26036
|
await this.ensureMigrated();
|
|
25325
26037
|
try {
|
|
25326
|
-
const
|
|
25327
|
-
const record = await
|
|
26038
|
+
const fs18 = this.getFileStorage();
|
|
26039
|
+
const record = await fs18.linkFile(path20, location, options);
|
|
25328
26040
|
return { success: true, file: record };
|
|
25329
26041
|
} catch (error) {
|
|
25330
26042
|
console.error("Error in linkFile:", error);
|
|
@@ -25335,11 +26047,11 @@ ${resultContent}${attachmentSummary}`;
|
|
|
25335
26047
|
* Read a file from storage (RPC method)
|
|
25336
26048
|
* Returns base64-encoded data
|
|
25337
26049
|
*/
|
|
25338
|
-
async readFile(
|
|
26050
|
+
async readFile(path20) {
|
|
25339
26051
|
await this.ensureMigrated();
|
|
25340
26052
|
try {
|
|
25341
|
-
const
|
|
25342
|
-
const data = await
|
|
26053
|
+
const fs18 = this.getFileStorage();
|
|
26054
|
+
const data = await fs18.readFile(path20);
|
|
25343
26055
|
if (data === null) {
|
|
25344
26056
|
return { success: false, error: "File not found or external" };
|
|
25345
26057
|
}
|
|
@@ -25358,11 +26070,11 @@ ${resultContent}${attachmentSummary}`;
|
|
|
25358
26070
|
/**
|
|
25359
26071
|
* Read a text file from storage (RPC method)
|
|
25360
26072
|
*/
|
|
25361
|
-
async readTextFile(
|
|
26073
|
+
async readTextFile(path20) {
|
|
25362
26074
|
await this.ensureMigrated();
|
|
25363
26075
|
try {
|
|
25364
|
-
const
|
|
25365
|
-
const content = await
|
|
26076
|
+
const fs18 = this.getFileStorage();
|
|
26077
|
+
const content = await fs18.readTextFile(path20);
|
|
25366
26078
|
if (content === null) {
|
|
25367
26079
|
return { success: false, error: "File not found or external" };
|
|
25368
26080
|
}
|
|
@@ -25375,11 +26087,11 @@ ${resultContent}${attachmentSummary}`;
|
|
|
25375
26087
|
/**
|
|
25376
26088
|
* Get file metadata (RPC method)
|
|
25377
26089
|
*/
|
|
25378
|
-
async statFile(
|
|
26090
|
+
async statFile(path20) {
|
|
25379
26091
|
await this.ensureMigrated();
|
|
25380
26092
|
try {
|
|
25381
|
-
const
|
|
25382
|
-
const record = await
|
|
26093
|
+
const fs18 = this.getFileStorage();
|
|
26094
|
+
const record = await fs18.stat(path20);
|
|
25383
26095
|
if (record === null) {
|
|
25384
26096
|
return { success: false, error: "File not found" };
|
|
25385
26097
|
}
|
|
@@ -25392,11 +26104,11 @@ ${resultContent}${attachmentSummary}`;
|
|
|
25392
26104
|
/**
|
|
25393
26105
|
* Check if file exists (RPC method)
|
|
25394
26106
|
*/
|
|
25395
|
-
async fileExists(
|
|
26107
|
+
async fileExists(path20) {
|
|
25396
26108
|
await this.ensureMigrated();
|
|
25397
26109
|
try {
|
|
25398
|
-
const
|
|
25399
|
-
const exists2 = await
|
|
26110
|
+
const fs18 = this.getFileStorage();
|
|
26111
|
+
const exists2 = await fs18.exists(path20);
|
|
25400
26112
|
return { success: true, exists: exists2 };
|
|
25401
26113
|
} catch (error) {
|
|
25402
26114
|
console.error("Error in fileExists:", error);
|
|
@@ -25406,12 +26118,12 @@ ${resultContent}${attachmentSummary}`;
|
|
|
25406
26118
|
/**
|
|
25407
26119
|
* Delete a file (RPC method)
|
|
25408
26120
|
*/
|
|
25409
|
-
async unlinkFile(
|
|
26121
|
+
async unlinkFile(path20) {
|
|
25410
26122
|
await this.ensureMigrated();
|
|
25411
26123
|
try {
|
|
25412
|
-
const
|
|
25413
|
-
await
|
|
25414
|
-
this.broadcastEvent("file_deleted", { path:
|
|
26124
|
+
const fs18 = this.getFileStorage();
|
|
26125
|
+
await fs18.unlink(path20);
|
|
26126
|
+
this.broadcastEvent("file_deleted", { path: path20 });
|
|
25415
26127
|
return { success: true };
|
|
25416
26128
|
} catch (error) {
|
|
25417
26129
|
console.error("Error in unlinkFile:", error);
|
|
@@ -25421,12 +26133,12 @@ ${resultContent}${attachmentSummary}`;
|
|
|
25421
26133
|
/**
|
|
25422
26134
|
* Create a directory (RPC method)
|
|
25423
26135
|
*/
|
|
25424
|
-
async mkdirFile(
|
|
26136
|
+
async mkdirFile(path20) {
|
|
25425
26137
|
await this.ensureMigrated();
|
|
25426
26138
|
try {
|
|
25427
|
-
const
|
|
25428
|
-
const record = await
|
|
25429
|
-
this.broadcastEvent("file_created", { path:
|
|
26139
|
+
const fs18 = this.getFileStorage();
|
|
26140
|
+
const record = await fs18.mkdir(path20);
|
|
26141
|
+
this.broadcastEvent("file_created", { path: path20, file: record });
|
|
25430
26142
|
return { success: true, directory: record };
|
|
25431
26143
|
} catch (error) {
|
|
25432
26144
|
console.error("Error in mkdirFile:", error);
|
|
@@ -25436,11 +26148,11 @@ ${resultContent}${attachmentSummary}`;
|
|
|
25436
26148
|
/**
|
|
25437
26149
|
* List directory contents (RPC method)
|
|
25438
26150
|
*/
|
|
25439
|
-
async readdirFile(
|
|
26151
|
+
async readdirFile(path20) {
|
|
25440
26152
|
await this.ensureMigrated();
|
|
25441
26153
|
try {
|
|
25442
|
-
const
|
|
25443
|
-
const files = await
|
|
26154
|
+
const fs18 = this.getFileStorage();
|
|
26155
|
+
const files = await fs18.readdir(path20);
|
|
25444
26156
|
return { success: true, files };
|
|
25445
26157
|
} catch (error) {
|
|
25446
26158
|
console.error("Error in readdirFile:", error);
|
|
@@ -25450,12 +26162,12 @@ ${resultContent}${attachmentSummary}`;
|
|
|
25450
26162
|
/**
|
|
25451
26163
|
* Remove empty directory (RPC method)
|
|
25452
26164
|
*/
|
|
25453
|
-
async rmdirFile(
|
|
26165
|
+
async rmdirFile(path20) {
|
|
25454
26166
|
await this.ensureMigrated();
|
|
25455
26167
|
try {
|
|
25456
|
-
const
|
|
25457
|
-
await
|
|
25458
|
-
this.broadcastEvent("file_deleted", { path:
|
|
26168
|
+
const fs18 = this.getFileStorage();
|
|
26169
|
+
await fs18.rmdir(path20);
|
|
26170
|
+
this.broadcastEvent("file_deleted", { path: path20 });
|
|
25459
26171
|
return { success: true };
|
|
25460
26172
|
} catch (error) {
|
|
25461
26173
|
console.error("Error in rmdirFile:", error);
|
|
@@ -25468,8 +26180,8 @@ ${resultContent}${attachmentSummary}`;
|
|
|
25468
26180
|
async getFileStats() {
|
|
25469
26181
|
await this.ensureMigrated();
|
|
25470
26182
|
try {
|
|
25471
|
-
const
|
|
25472
|
-
const stats = await
|
|
26183
|
+
const fs18 = this.getFileStorage();
|
|
26184
|
+
const stats = await fs18.getFileStats();
|
|
25473
26185
|
return { success: true, stats };
|
|
25474
26186
|
} catch (error) {
|
|
25475
26187
|
console.error("Error in getFileStats:", error);
|
|
@@ -25480,11 +26192,11 @@ ${resultContent}${attachmentSummary}`;
|
|
|
25480
26192
|
* Get thumbnail for an image (RPC method)
|
|
25481
26193
|
* Returns base64-encoded data
|
|
25482
26194
|
*/
|
|
25483
|
-
async getFileThumbnail(
|
|
26195
|
+
async getFileThumbnail(path20) {
|
|
25484
26196
|
await this.ensureMigrated();
|
|
25485
26197
|
try {
|
|
25486
|
-
const
|
|
25487
|
-
const data = await
|
|
26198
|
+
const fs18 = this.getFileStorage();
|
|
26199
|
+
const data = await fs18.getThumbnail(path20);
|
|
25488
26200
|
if (data === null) {
|
|
25489
26201
|
return { success: false, error: "Thumbnail not found" };
|
|
25490
26202
|
}
|
|
@@ -25506,8 +26218,8 @@ ${resultContent}${attachmentSummary}`;
|
|
|
25506
26218
|
async grepFiles(pattern, options) {
|
|
25507
26219
|
await this.ensureMigrated();
|
|
25508
26220
|
try {
|
|
25509
|
-
const
|
|
25510
|
-
const results = await
|
|
26221
|
+
const fs18 = this.getFileStorage();
|
|
26222
|
+
const results = await fs18.grep(pattern, options);
|
|
25511
26223
|
return { success: true, results };
|
|
25512
26224
|
} catch (error) {
|
|
25513
26225
|
console.error("Error in grepFiles:", error);
|
|
@@ -25520,8 +26232,8 @@ ${resultContent}${attachmentSummary}`;
|
|
|
25520
26232
|
async findFiles(pattern, options) {
|
|
25521
26233
|
await this.ensureMigrated();
|
|
25522
26234
|
try {
|
|
25523
|
-
const
|
|
25524
|
-
const files = await
|
|
26235
|
+
const fs18 = this.getFileStorage();
|
|
26236
|
+
const files = await fs18.find(pattern, options);
|
|
25525
26237
|
return { success: true, files };
|
|
25526
26238
|
} catch (error) {
|
|
25527
26239
|
console.error("Error in findFiles:", error);
|
|
@@ -25536,11 +26248,11 @@ ${resultContent}${attachmentSummary}`;
|
|
|
25536
26248
|
* Creates file record with is_chunked=1 and chunk_count=null.
|
|
25537
26249
|
* Caller should then use writeFileChunk() to write chunks.
|
|
25538
26250
|
*/
|
|
25539
|
-
async startChunkedUpload(
|
|
26251
|
+
async startChunkedUpload(path20, totalSize, mimeType, options) {
|
|
25540
26252
|
await this.ensureMigrated();
|
|
25541
26253
|
try {
|
|
25542
26254
|
const { CHUNK_SIZE: CHUNK_SIZE2, normalizePath: normalizePath2, basename: basename3 } = await Promise.resolve().then(() => (init_files(), files_exports));
|
|
25543
|
-
const normalizedPath = normalizePath2(
|
|
26255
|
+
const normalizedPath = normalizePath2(path20);
|
|
25544
26256
|
const name = basename3(normalizedPath);
|
|
25545
26257
|
const now = Date.now();
|
|
25546
26258
|
const expectedChunks = Math.ceil(totalSize / CHUNK_SIZE2);
|
|
@@ -25577,11 +26289,11 @@ ${resultContent}${attachmentSummary}`;
|
|
|
25577
26289
|
* @param chunkIndex - 0-based chunk index
|
|
25578
26290
|
* @param data - Base64 encoded chunk data
|
|
25579
26291
|
*/
|
|
25580
|
-
async writeFileChunk(
|
|
26292
|
+
async writeFileChunk(path20, chunkIndex, data) {
|
|
25581
26293
|
await this.ensureMigrated();
|
|
25582
26294
|
try {
|
|
25583
26295
|
const { normalizePath: normalizePath2 } = await Promise.resolve().then(() => (init_files(), files_exports));
|
|
25584
|
-
const normalizedPath = normalizePath2(
|
|
26296
|
+
const normalizedPath = normalizePath2(path20);
|
|
25585
26297
|
const binaryString = atob(data);
|
|
25586
26298
|
const dataBuffer = new Uint8Array(binaryString.length);
|
|
25587
26299
|
for (let i = 0; i < binaryString.length; i++) {
|
|
@@ -25603,12 +26315,12 @@ ${resultContent}${attachmentSummary}`;
|
|
|
25603
26315
|
* Complete a chunked file upload.
|
|
25604
26316
|
* Validates all chunks are present and sets chunk_count.
|
|
25605
26317
|
*/
|
|
25606
|
-
async completeChunkedUpload(
|
|
26318
|
+
async completeChunkedUpload(path20, expectedChunks, options) {
|
|
25607
26319
|
await this.ensureMigrated();
|
|
25608
26320
|
try {
|
|
25609
26321
|
const { normalizePath: normalizePath2 } = await Promise.resolve().then(() => (init_files(), files_exports));
|
|
25610
|
-
const
|
|
25611
|
-
const normalizedPath = normalizePath2(
|
|
26322
|
+
const fs18 = this.getFileStorage();
|
|
26323
|
+
const normalizedPath = normalizePath2(path20);
|
|
25612
26324
|
const countResult = await this.ctx.storage.sql.exec(
|
|
25613
26325
|
`SELECT COUNT(*) as count FROM file_chunks WHERE file_path = ?`,
|
|
25614
26326
|
normalizedPath
|
|
@@ -25634,7 +26346,7 @@ ${resultContent}${attachmentSummary}`;
|
|
|
25634
26346
|
thumbnailBuffer || null,
|
|
25635
26347
|
normalizedPath
|
|
25636
26348
|
);
|
|
25637
|
-
const file = await
|
|
26349
|
+
const file = await fs18.stat(normalizedPath);
|
|
25638
26350
|
if (file) {
|
|
25639
26351
|
this.broadcastEvent("file_created", { path: normalizedPath, file });
|
|
25640
26352
|
}
|
|
@@ -25648,11 +26360,11 @@ ${resultContent}${attachmentSummary}`;
|
|
|
25648
26360
|
* Read a single chunk of a file.
|
|
25649
26361
|
* Use for streaming large files to client.
|
|
25650
26362
|
*/
|
|
25651
|
-
async readFileChunk(
|
|
26363
|
+
async readFileChunk(path20, chunkIndex) {
|
|
25652
26364
|
await this.ensureMigrated();
|
|
25653
26365
|
try {
|
|
25654
26366
|
const { normalizePath: normalizePath2 } = await Promise.resolve().then(() => (init_files(), files_exports));
|
|
25655
|
-
const normalizedPath = normalizePath2(
|
|
26367
|
+
const normalizedPath = normalizePath2(path20);
|
|
25656
26368
|
const cursor = await this.ctx.storage.sql.exec(
|
|
25657
26369
|
`SELECT data FROM file_chunks WHERE file_path = ? AND chunk_index = ?`,
|
|
25658
26370
|
normalizedPath,
|
|
@@ -25677,11 +26389,11 @@ ${resultContent}${attachmentSummary}`;
|
|
|
25677
26389
|
/**
|
|
25678
26390
|
* Get file info including chunking metadata.
|
|
25679
26391
|
*/
|
|
25680
|
-
async getFileInfo(
|
|
26392
|
+
async getFileInfo(path20) {
|
|
25681
26393
|
await this.ensureMigrated();
|
|
25682
26394
|
try {
|
|
25683
|
-
const
|
|
25684
|
-
const file = await
|
|
26395
|
+
const fs18 = this.getFileStorage();
|
|
26396
|
+
const file = await fs18.stat(path20);
|
|
25685
26397
|
if (!file) {
|
|
25686
26398
|
return { success: false, error: "File not found" };
|
|
25687
26399
|
}
|
|
@@ -25694,7 +26406,7 @@ ${resultContent}${attachmentSummary}`;
|
|
|
25694
26406
|
};
|
|
25695
26407
|
|
|
25696
26408
|
// src/durable-objects/agentbuilder-migrations/0001_initial.ts
|
|
25697
|
-
var
|
|
26409
|
+
var migration31 = {
|
|
25698
26410
|
version: 1,
|
|
25699
26411
|
async up(sql) {
|
|
25700
26412
|
sql.exec(`
|
|
@@ -25793,7 +26505,7 @@ var migration30 = {
|
|
|
25793
26505
|
};
|
|
25794
26506
|
|
|
25795
26507
|
// src/durable-objects/agentbuilder-migrations/0002_add_tenvs_properties.ts
|
|
25796
|
-
var
|
|
26508
|
+
var migration32 = {
|
|
25797
26509
|
version: 2,
|
|
25798
26510
|
async up(sql) {
|
|
25799
26511
|
sql.exec(`ALTER TABLE threads ADD COLUMN tenvs TEXT`);
|
|
@@ -25805,7 +26517,7 @@ var migration31 = {
|
|
|
25805
26517
|
};
|
|
25806
26518
|
|
|
25807
26519
|
// src/durable-objects/agentbuilder-migrations/0003_add_parent_and_terminated.ts
|
|
25808
|
-
var
|
|
26520
|
+
var migration33 = {
|
|
25809
26521
|
version: 3,
|
|
25810
26522
|
async up(sql) {
|
|
25811
26523
|
sql.exec(`ALTER TABLE threads ADD COLUMN parent TEXT REFERENCES threads(id)`);
|
|
@@ -25818,7 +26530,7 @@ var migration32 = {
|
|
|
25818
26530
|
};
|
|
25819
26531
|
|
|
25820
26532
|
// src/durable-objects/agentbuilder-migrations/0004_add_env_tables.ts
|
|
25821
|
-
var
|
|
26533
|
+
var migration34 = {
|
|
25822
26534
|
version: 4,
|
|
25823
26535
|
async up(sql) {
|
|
25824
26536
|
sql.exec(`ALTER TABLE threads ADD COLUMN env TEXT`);
|
|
@@ -25842,7 +26554,7 @@ var migration33 = {
|
|
|
25842
26554
|
};
|
|
25843
26555
|
|
|
25844
26556
|
// src/durable-objects/agentbuilder-migrations/0005_add_pending_subagent_env_requests.ts
|
|
25845
|
-
var
|
|
26557
|
+
var migration35 = {
|
|
25846
26558
|
version: 5,
|
|
25847
26559
|
async up(sql) {
|
|
25848
26560
|
sql.exec(`
|
|
@@ -25867,9 +26579,24 @@ var migration34 = {
|
|
|
25867
26579
|
}
|
|
25868
26580
|
};
|
|
25869
26581
|
|
|
26582
|
+
// src/durable-objects/agentbuilder-migrations/0006_add_env_value_types.ts
|
|
26583
|
+
var migration36 = {
|
|
26584
|
+
version: 6,
|
|
26585
|
+
async up(sql) {
|
|
26586
|
+
sql.exec(
|
|
26587
|
+
`ALTER TABLE envs
|
|
26588
|
+
ADD COLUMN value_type TEXT NOT NULL DEFAULT 'secret'
|
|
26589
|
+
CHECK (value_type IN ('text', 'secret'))`
|
|
26590
|
+
);
|
|
26591
|
+
sql.exec(`
|
|
26592
|
+
INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '6')
|
|
26593
|
+
`);
|
|
26594
|
+
}
|
|
26595
|
+
};
|
|
26596
|
+
|
|
25870
26597
|
// src/durable-objects/agentbuilder-migrations/index.ts
|
|
25871
|
-
var migrations2 = [
|
|
25872
|
-
var LATEST_SCHEMA_VERSION2 =
|
|
26598
|
+
var migrations2 = [migration31, migration32, migration33, migration34, migration35, migration36];
|
|
26599
|
+
var LATEST_SCHEMA_VERSION2 = 6;
|
|
25873
26600
|
|
|
25874
26601
|
// src/utils/crypto.ts
|
|
25875
26602
|
var CryptoUtil = class {
|
|
@@ -26209,10 +26936,10 @@ var DurableAgentBuilder = class extends DurableObject {
|
|
|
26209
26936
|
for (const entry of value) {
|
|
26210
26937
|
if (!entry || typeof entry !== "object") continue;
|
|
26211
26938
|
const attachment = entry;
|
|
26212
|
-
const
|
|
26213
|
-
if (!
|
|
26939
|
+
const path20 = typeof attachment.path === "string" ? attachment.path.trim() : "";
|
|
26940
|
+
if (!path20) continue;
|
|
26214
26941
|
output.push({
|
|
26215
|
-
path:
|
|
26942
|
+
path: path20,
|
|
26216
26943
|
name: typeof attachment.name === "string" ? attachment.name : void 0,
|
|
26217
26944
|
mimeType: typeof attachment.mimeType === "string" ? attachment.mimeType : void 0,
|
|
26218
26945
|
size: typeof attachment.size === "number" ? attachment.size : void 0,
|
|
@@ -26229,8 +26956,8 @@ var DurableAgentBuilder = class extends DurableObject {
|
|
|
26229
26956
|
const trimmed = sanitized.replace(/^[-.]+|[-.]+$/g, "");
|
|
26230
26957
|
return trimmed || "attachment";
|
|
26231
26958
|
}
|
|
26232
|
-
inferMimeTypeFromPath(
|
|
26233
|
-
const normalized =
|
|
26959
|
+
inferMimeTypeFromPath(path20) {
|
|
26960
|
+
const normalized = path20.toLowerCase();
|
|
26234
26961
|
if (normalized.endsWith(".png")) return "image/png";
|
|
26235
26962
|
if (normalized.endsWith(".jpg") || normalized.endsWith(".jpeg")) return "image/jpeg";
|
|
26236
26963
|
if (normalized.endsWith(".webp")) return "image/webp";
|
|
@@ -26268,7 +26995,7 @@ var DurableAgentBuilder = class extends DurableObject {
|
|
|
26268
26995
|
if (!attachments || attachments.length === 0) {
|
|
26269
26996
|
return "";
|
|
26270
26997
|
}
|
|
26271
|
-
const paths = attachments.map((attachment) => attachment.path).filter((
|
|
26998
|
+
const paths = attachments.map((attachment) => attachment.path).filter((path20) => typeof path20 === "string" && path20.length > 0);
|
|
26272
26999
|
if (paths.length === 0) {
|
|
26273
27000
|
return "";
|
|
26274
27001
|
}
|
|
@@ -26493,9 +27220,9 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
|
|
|
26493
27220
|
}
|
|
26494
27221
|
}
|
|
26495
27222
|
async runMigrations(fromVersion) {
|
|
26496
|
-
for (const
|
|
26497
|
-
if (
|
|
26498
|
-
await
|
|
27223
|
+
for (const migration37 of migrations2) {
|
|
27224
|
+
if (migration37.version > fromVersion) {
|
|
27225
|
+
await migration37.up(this.ctx.storage.sql);
|
|
26499
27226
|
}
|
|
26500
27227
|
}
|
|
26501
27228
|
}
|
|
@@ -26852,23 +27579,49 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
|
|
|
26852
27579
|
return CryptoUtil.decrypt(encrypted, this.getEncryptionKey());
|
|
26853
27580
|
}
|
|
26854
27581
|
async listScopedEnv(scope, userId = "") {
|
|
27582
|
+
const entries = await this.listScopedEnvEntries(scope, userId);
|
|
27583
|
+
const env = {};
|
|
27584
|
+
for (const entry of entries) {
|
|
27585
|
+
env[entry.name] = entry.value;
|
|
27586
|
+
}
|
|
27587
|
+
return env;
|
|
27588
|
+
}
|
|
27589
|
+
async listScopedEnvEntries(scope, userId = "") {
|
|
26855
27590
|
await this.ensureMigrated();
|
|
26856
27591
|
const cursor = await this.ctx.storage.sql.exec(
|
|
26857
|
-
`SELECT name, value
|
|
27592
|
+
`SELECT name, value, value_type, created_at, updated_at
|
|
27593
|
+
FROM envs
|
|
27594
|
+
WHERE scope = ? AND user_id = ?`,
|
|
26858
27595
|
scope,
|
|
26859
27596
|
userId
|
|
26860
27597
|
);
|
|
26861
|
-
const
|
|
27598
|
+
const entries = [];
|
|
26862
27599
|
const rows = cursor.toArray();
|
|
26863
27600
|
for (const row of rows) {
|
|
26864
27601
|
try {
|
|
26865
|
-
|
|
27602
|
+
entries.push({
|
|
27603
|
+
name: row.name,
|
|
27604
|
+
value: await this.decryptEnvValue(row.value),
|
|
27605
|
+
type: row.value_type === "text" ? "text" : "secret",
|
|
27606
|
+
created_at: row.created_at,
|
|
27607
|
+
updated_at: row.updated_at
|
|
27608
|
+
});
|
|
26866
27609
|
} catch {
|
|
26867
27610
|
}
|
|
26868
27611
|
}
|
|
26869
|
-
return
|
|
27612
|
+
return entries;
|
|
27613
|
+
}
|
|
27614
|
+
async getScopedEnvTypeRecord(scope, userId = "") {
|
|
27615
|
+
const entries = await this.listScopedEnvEntries(scope, userId);
|
|
27616
|
+
const envTypes = {};
|
|
27617
|
+
for (const entry of entries) {
|
|
27618
|
+
if (entry.type === "text") {
|
|
27619
|
+
envTypes[entry.name] = "text";
|
|
27620
|
+
}
|
|
27621
|
+
}
|
|
27622
|
+
return envTypes;
|
|
26870
27623
|
}
|
|
26871
|
-
async replaceScopedEnv(scope, userId, env) {
|
|
27624
|
+
async replaceScopedEnv(scope, userId, env, envTypes) {
|
|
26872
27625
|
await this.ensureMigrated();
|
|
26873
27626
|
await this.ctx.storage.sql.exec(
|
|
26874
27627
|
`DELETE FROM envs WHERE scope = ? AND user_id = ?`,
|
|
@@ -26876,32 +27629,93 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
|
|
|
26876
27629
|
userId
|
|
26877
27630
|
);
|
|
26878
27631
|
const now = Math.floor(Date.now() / 1e3);
|
|
27632
|
+
const normalizedEnvTypes = this.normalizeEnvTypeRecord(envTypes ?? null, env) ?? {};
|
|
26879
27633
|
for (const [name, value] of Object.entries(env)) {
|
|
26880
27634
|
await this.ctx.storage.sql.exec(
|
|
26881
|
-
`INSERT INTO envs (scope, user_id, name, value, created_at, updated_at)
|
|
26882
|
-
VALUES (?, ?, ?, ?, ?, ?)`,
|
|
27635
|
+
`INSERT INTO envs (scope, user_id, name, value, value_type, created_at, updated_at)
|
|
27636
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
|
26883
27637
|
scope,
|
|
26884
27638
|
userId,
|
|
26885
27639
|
name,
|
|
26886
27640
|
await this.encryptEnvValue(value),
|
|
27641
|
+
normalizedEnvTypes[name] === "text" ? "text" : "secret",
|
|
26887
27642
|
now,
|
|
26888
27643
|
now
|
|
26889
27644
|
);
|
|
26890
27645
|
}
|
|
26891
27646
|
}
|
|
27647
|
+
async patchScopedEnv(scope, userId, params) {
|
|
27648
|
+
const currentEnv = await this.listScopedEnv(scope, userId);
|
|
27649
|
+
const currentEnvTypes = await this.getScopedEnvTypeRecord(scope, userId);
|
|
27650
|
+
const nextEnv = { ...currentEnv };
|
|
27651
|
+
const nextEnvTypes = { ...currentEnvTypes };
|
|
27652
|
+
if (params.env_patch) {
|
|
27653
|
+
for (const [key, value] of Object.entries(params.env_patch)) {
|
|
27654
|
+
const property = key.trim();
|
|
27655
|
+
if (!property) {
|
|
27656
|
+
throw new Error("env_patch keys must be non-empty strings");
|
|
27657
|
+
}
|
|
27658
|
+
if (value === void 0 || value === null) {
|
|
27659
|
+
throw new Error(`env_patch.${property} must be a string`);
|
|
27660
|
+
}
|
|
27661
|
+
nextEnv[property] = String(value);
|
|
27662
|
+
}
|
|
27663
|
+
}
|
|
27664
|
+
if (params.env_type_patch) {
|
|
27665
|
+
for (const [key, value] of Object.entries(params.env_type_patch)) {
|
|
27666
|
+
const property = key.trim();
|
|
27667
|
+
if (!property) {
|
|
27668
|
+
throw new Error("env_type_patch keys must be non-empty strings");
|
|
27669
|
+
}
|
|
27670
|
+
if (nextEnv[property] === void 0) {
|
|
27671
|
+
throw new Error(`env_type_patch.${property} has no matching env value`);
|
|
27672
|
+
}
|
|
27673
|
+
if (value === "text") {
|
|
27674
|
+
nextEnvTypes[property] = "text";
|
|
27675
|
+
} else {
|
|
27676
|
+
delete nextEnvTypes[property];
|
|
27677
|
+
}
|
|
27678
|
+
}
|
|
27679
|
+
}
|
|
27680
|
+
for (const key of params.env_delete ?? []) {
|
|
27681
|
+
delete nextEnv[key];
|
|
27682
|
+
delete nextEnvTypes[key];
|
|
27683
|
+
}
|
|
27684
|
+
await this.replaceScopedEnv(scope, userId, nextEnv, nextEnvTypes);
|
|
27685
|
+
}
|
|
26892
27686
|
async getInstanceEnv() {
|
|
26893
27687
|
return this.listScopedEnv("instance", "");
|
|
26894
27688
|
}
|
|
26895
|
-
async
|
|
27689
|
+
async getInstanceEnvTypes() {
|
|
27690
|
+
return this.getScopedEnvTypeRecord("instance", "");
|
|
27691
|
+
}
|
|
27692
|
+
async getInstanceEnvEntries() {
|
|
27693
|
+
return this.listScopedEnvEntries("instance", "");
|
|
27694
|
+
}
|
|
27695
|
+
async setInstanceEnv(env, envTypes) {
|
|
26896
27696
|
const normalized = this.normalizeEnvRecord(env) ?? {};
|
|
26897
|
-
|
|
27697
|
+
const normalizedTypes = this.normalizeEnvTypeRecord(envTypes ?? null, normalized);
|
|
27698
|
+
await this.replaceScopedEnv("instance", "", normalized, normalizedTypes);
|
|
27699
|
+
}
|
|
27700
|
+
async patchInstanceEnv(params) {
|
|
27701
|
+
await this.patchScopedEnv("instance", "", params);
|
|
26898
27702
|
}
|
|
26899
27703
|
async getUserEnv(userId) {
|
|
26900
27704
|
return this.listScopedEnv("user", userId);
|
|
26901
27705
|
}
|
|
26902
|
-
async
|
|
27706
|
+
async getUserEnvTypes(userId) {
|
|
27707
|
+
return this.getScopedEnvTypeRecord("user", userId);
|
|
27708
|
+
}
|
|
27709
|
+
async getUserEnvEntries(userId) {
|
|
27710
|
+
return this.listScopedEnvEntries("user", userId);
|
|
27711
|
+
}
|
|
27712
|
+
async setUserEnv(userId, env, envTypes) {
|
|
26903
27713
|
const normalized = this.normalizeEnvRecord(env) ?? {};
|
|
26904
|
-
|
|
27714
|
+
const normalizedTypes = this.normalizeEnvTypeRecord(envTypes ?? null, normalized);
|
|
27715
|
+
await this.replaceScopedEnv("user", userId, normalized, normalizedTypes);
|
|
27716
|
+
}
|
|
27717
|
+
async patchUserEnv(userId, params) {
|
|
27718
|
+
await this.patchScopedEnv("user", userId, params);
|
|
26905
27719
|
}
|
|
26906
27720
|
async getMissingRequiredScopedSubagentEnv(params) {
|
|
26907
27721
|
await this.ensureMigrated();
|
|
@@ -26947,10 +27761,10 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
|
|
|
26947
27761
|
const missing = [];
|
|
26948
27762
|
for (const property of requiredScoped) {
|
|
26949
27763
|
if (providedEnv[property] !== void 0) continue;
|
|
26950
|
-
if (userEnv[property] !== void 0) continue;
|
|
26951
|
-
if (instanceEnv[property] !== void 0) continue;
|
|
26952
27764
|
if (agentEnv[property] !== void 0) continue;
|
|
26953
27765
|
if (promptEnv[property] !== void 0) continue;
|
|
27766
|
+
if (userEnv[property] !== void 0) continue;
|
|
27767
|
+
if (instanceEnv[property] !== void 0) continue;
|
|
26954
27768
|
missing.push(property);
|
|
26955
27769
|
}
|
|
26956
27770
|
missing.sort((a, b) => a.localeCompare(b));
|
|
@@ -27226,16 +28040,6 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
|
|
|
27226
28040
|
if (thread.env && thread.env[params.property] !== void 0) {
|
|
27227
28041
|
return thread.env[params.property];
|
|
27228
28042
|
}
|
|
27229
|
-
if (thread.user_id) {
|
|
27230
|
-
const userEnv = await this.getUserEnv(thread.user_id);
|
|
27231
|
-
if (userEnv[params.property] !== void 0) {
|
|
27232
|
-
return userEnv[params.property];
|
|
27233
|
-
}
|
|
27234
|
-
}
|
|
27235
|
-
const instanceEnv = await this.getInstanceEnv();
|
|
27236
|
-
if (instanceEnv[params.property] !== void 0) {
|
|
27237
|
-
return instanceEnv[params.property];
|
|
27238
|
-
}
|
|
27239
28043
|
let agentDef = null;
|
|
27240
28044
|
try {
|
|
27241
28045
|
agentDef = await this.loadAgent(thread.agent_name);
|
|
@@ -27257,6 +28061,16 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
|
|
|
27257
28061
|
} catch {
|
|
27258
28062
|
}
|
|
27259
28063
|
}
|
|
28064
|
+
if (thread.user_id) {
|
|
28065
|
+
const userEnv = await this.getUserEnv(thread.user_id);
|
|
28066
|
+
if (userEnv[params.property] !== void 0) {
|
|
28067
|
+
return userEnv[params.property];
|
|
28068
|
+
}
|
|
28069
|
+
}
|
|
28070
|
+
const instanceEnv = await this.getInstanceEnv();
|
|
28071
|
+
if (instanceEnv[params.property] !== void 0) {
|
|
28072
|
+
return instanceEnv[params.property];
|
|
28073
|
+
}
|
|
27260
28074
|
return null;
|
|
27261
28075
|
}
|
|
27262
28076
|
async resolveThreadEnvType(params) {
|
|
@@ -27265,12 +28079,39 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
|
|
|
27265
28079
|
if (thread.env && thread.env[params.property] !== void 0) {
|
|
27266
28080
|
return thread.env_types?.[params.property] === "text" ? "text" : "secret";
|
|
27267
28081
|
}
|
|
28082
|
+
let agentDef = null;
|
|
28083
|
+
try {
|
|
28084
|
+
agentDef = await this.loadAgent(thread.agent_name);
|
|
28085
|
+
} catch {
|
|
28086
|
+
agentDef = null;
|
|
28087
|
+
}
|
|
28088
|
+
const agentEnv = this.normalizeEnvRecord(agentDef?.env ?? agentDef?.tenvs ?? null);
|
|
28089
|
+
if (agentEnv && agentEnv[params.property] !== void 0) {
|
|
28090
|
+
return "secret";
|
|
28091
|
+
}
|
|
28092
|
+
const fallbackPromptName = params.promptName ?? (typeof agentDef?.sideA?.prompt === "string" ? agentDef.sideA.prompt : void 0);
|
|
28093
|
+
if (fallbackPromptName) {
|
|
28094
|
+
try {
|
|
28095
|
+
const promptDef = await this.loadPrompt(fallbackPromptName);
|
|
28096
|
+
const promptEnv = this.normalizeEnvRecord(promptDef?.env ?? promptDef?.tenvs ?? null);
|
|
28097
|
+
if (promptEnv && promptEnv[params.property] !== void 0) {
|
|
28098
|
+
return "secret";
|
|
28099
|
+
}
|
|
28100
|
+
} catch {
|
|
28101
|
+
}
|
|
28102
|
+
}
|
|
27268
28103
|
if (thread.user_id) {
|
|
27269
28104
|
const userEnv = await this.getUserEnv(thread.user_id);
|
|
27270
|
-
if (userEnv[params.property] !== void 0)
|
|
28105
|
+
if (userEnv[params.property] !== void 0) {
|
|
28106
|
+
const userEnvTypes = await this.getUserEnvTypes(thread.user_id);
|
|
28107
|
+
return userEnvTypes[params.property] === "text" ? "text" : "secret";
|
|
28108
|
+
}
|
|
27271
28109
|
}
|
|
27272
28110
|
const instanceEnv = await this.getInstanceEnv();
|
|
27273
|
-
if (instanceEnv[params.property] !== void 0)
|
|
28111
|
+
if (instanceEnv[params.property] !== void 0) {
|
|
28112
|
+
const instanceEnvTypes = await this.getInstanceEnvTypes();
|
|
28113
|
+
return instanceEnvTypes[params.property] === "text" ? "text" : "secret";
|
|
28114
|
+
}
|
|
27274
28115
|
return "secret";
|
|
27275
28116
|
}
|
|
27276
28117
|
async toThreadEventPayload(thread) {
|
|
@@ -28289,8 +29130,8 @@ var GitHubClient = class _GitHubClient {
|
|
|
28289
29130
|
/**
|
|
28290
29131
|
* Make an authenticated request to GitHub API.
|
|
28291
29132
|
*/
|
|
28292
|
-
async request(method,
|
|
28293
|
-
const url = `${GITHUB_API_BASE}${
|
|
29133
|
+
async request(method, path20, body) {
|
|
29134
|
+
const url = `${GITHUB_API_BASE}${path20}`;
|
|
28294
29135
|
const response = await fetch(url, {
|
|
28295
29136
|
method,
|
|
28296
29137
|
headers: {
|
|
@@ -28446,8 +29287,8 @@ var GitHubClient = class _GitHubClient {
|
|
|
28446
29287
|
const headSha = branchRef.object.sha;
|
|
28447
29288
|
const headCommit = await this.getCommit(headSha);
|
|
28448
29289
|
const baseTreeSha = headCommit.tree.sha;
|
|
28449
|
-
const tree = paths.map((
|
|
28450
|
-
path:
|
|
29290
|
+
const tree = paths.map((path20) => ({
|
|
29291
|
+
path: path20,
|
|
28451
29292
|
mode: "100644",
|
|
28452
29293
|
type: "blob",
|
|
28453
29294
|
sha: null
|