@standardagents/builder 0.39.0 → 0.40.0
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 +671 -144
- package/dist/built-in-routes.js.map +1 -1
- package/dist/client/{ApiKeysView-AH5i-H6j.js → ApiKeysView-DoYvZZ7e.js} +1 -1
- package/dist/client/{CenteredContentView-DaBp0K-A.js → CenteredContentView-53PY0cqY.js} +1 -1
- package/dist/client/{CompositionView-yY1Q4M23.js → CompositionView-fp-0YnPt.js} +1 -1
- package/dist/client/{ConfirmDialog.vue_vue_type_script_setup_true_lang-Bwo5CJzF.js → ConfirmDialog.vue_vue_type_script_setup_true_lang-Cvcagja2.js} +1 -1
- package/dist/client/{CopyButton.vue_vue_type_script_setup_true_lang-D0WYwWyA.js → CopyButton.vue_vue_type_script_setup_true_lang-jYvO2v1K.js} +1 -1
- package/dist/client/{DataTable.vue_vue_type_script_setup_true_lang-1wwPn2aY.js → DataTable.vue_vue_type_script_setup_true_lang-DQ3Ufa7y.js} +1 -1
- package/dist/client/{JsonViewer-Bi8Zdmir.js → JsonViewer-6aaGzutE.js} +1 -1
- package/dist/client/{LoginView-BIKahEU6.js → LoginView-DwpCmNw9.js} +1 -1
- package/dist/client/{MarketplaceView-DPDPVH68.js → MarketplaceView-Da02L0J5.js} +1 -1
- package/dist/client/{Modal.vue_vue_type_script_setup_true_lang-D1_rfOsy.js → Modal.vue_vue_type_script_setup_true_lang-Bi8OjiBf.js} +1 -1
- package/dist/client/{ModelModal.vue_vue_type_script_setup_true_lang-DSLeOdxr.js → ModelModal.vue_vue_type_script_setup_true_lang-cYZLOYY7.js} +1 -1
- package/dist/client/{ModelsView-Q2WXu1Gw.js → ModelsView-BLlHO9Ud.js} +1 -1
- package/dist/client/{PromptEditView-BzA-3n1w.js → PromptEditView-EeNwTDtT.js} +1 -1
- package/dist/client/{PromptModal-CJWh_cru.js → PromptModal-BkwrKJ2d.js} +1 -1
- package/dist/client/{PromptsView-BezNl-Et.js → PromptsView-D1r7tsLu.js} +1 -1
- package/dist/client/{ProvidersView-BuzSKxuT.js → ProvidersView-CmUDl5nM.js} +1 -1
- package/dist/client/{ThreadInspectorPane.vue_vue_type_script_setup_true_lang-DOxNp_3C.js → ThreadInspectorPane.vue_vue_type_script_setup_true_lang-cRs3tApQ.js} +1 -1
- package/dist/client/{ThreadsView-DPCpZA4J.js → ThreadsView-Bl5fSIO1.js} +1 -1
- package/dist/client/{ToolsView-DMjFMAhH.js → ToolsView-DlVEF8-7.js} +1 -1
- package/dist/client/{UsersView-B7jXLNQs.js → UsersView-CGlA7a7R.js} +1 -1
- package/dist/client/{VariablesView-CF7x0G8g.js → VariablesView-BpYmJL4V.js} +1 -1
- package/dist/client/index-CKtIkI0N.js +6 -0
- package/dist/client/index.html +1 -1
- package/dist/{discovery-DiMJWisl.d.ts → discovery-DZ7fv-b4.d.ts} +3 -2
- package/dist/{index-yIcqf7DC.d.ts → index-9MaIifn3.d.ts} +7 -2
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1170 -563
- package/dist/index.js.map +1 -1
- package/dist/packing.d.ts +5 -3
- package/dist/packing.js +180 -5
- package/dist/packing.js.map +1 -1
- package/dist/plugin.js +252 -17
- package/dist/plugin.js.map +1 -1
- package/dist/runtime.d.ts +25 -38
- package/dist/runtime.js +1328 -958
- package/dist/runtime.js.map +1 -1
- package/dist/test.d.ts +2 -2
- package/dist/{types-Bpe7IANZ.d.ts → types-BMnBYNwn.d.ts} +3 -1
- package/package.json +5 -5
- package/dist/client/index-eGECJFYe.js +0 -6
package/dist/runtime.js
CHANGED
|
@@ -1489,6 +1489,9 @@ function normalizeToolCallMessageSequence(messages) {
|
|
|
1489
1489
|
for (const message of messages) {
|
|
1490
1490
|
const isAssistantToolCallMessage = message.role === "assistant" && Array.isArray(message.tool_calls) && message.tool_calls.length > 0;
|
|
1491
1491
|
if (!pending) {
|
|
1492
|
+
if (message.role === "tool") {
|
|
1493
|
+
continue;
|
|
1494
|
+
}
|
|
1492
1495
|
if (!isAssistantToolCallMessage) {
|
|
1493
1496
|
normalized.push(message);
|
|
1494
1497
|
continue;
|
|
@@ -6797,125 +6800,667 @@ var init_context = __esm({
|
|
|
6797
6800
|
}
|
|
6798
6801
|
});
|
|
6799
6802
|
|
|
6800
|
-
// src/
|
|
6801
|
-
|
|
6802
|
-
|
|
6803
|
-
|
|
6804
|
-
|
|
6805
|
-
|
|
6806
|
-
|
|
6807
|
-
|
|
6808
|
-
|
|
6809
|
-
|
|
6810
|
-
|
|
6811
|
-
|
|
6812
|
-
|
|
6813
|
-
|
|
6814
|
-
|
|
6815
|
-
|
|
6816
|
-
|
|
6817
|
-
|
|
6818
|
-
|
|
6819
|
-
|
|
6820
|
-
|
|
6821
|
-
|
|
6822
|
-
|
|
6823
|
-
|
|
6824
|
-
|
|
6825
|
-
|
|
6826
|
-
|
|
6827
|
-
|
|
6828
|
-
|
|
6829
|
-
|
|
6830
|
-
|
|
6831
|
-
|
|
6832
|
-
|
|
6833
|
-
|
|
6834
|
-
|
|
6835
|
-
|
|
6836
|
-
|
|
6837
|
-
|
|
6838
|
-
|
|
6839
|
-
|
|
6840
|
-
|
|
6841
|
-
|
|
6842
|
-
|
|
6843
|
-
|
|
6844
|
-
|
|
6845
|
-
|
|
6846
|
-
|
|
6847
|
-
|
|
6848
|
-
|
|
6849
|
-
|
|
6850
|
-
|
|
6851
|
-
|
|
6852
|
-
}
|
|
6853
|
-
|
|
6854
|
-
|
|
6855
|
-
|
|
6856
|
-
|
|
6857
|
-
|
|
6858
|
-
|
|
6859
|
-
|
|
6860
|
-
|
|
6861
|
-
|
|
6862
|
-
|
|
6863
|
-
|
|
6864
|
-
|
|
6865
|
-
|
|
6866
|
-
|
|
6867
|
-
|
|
6868
|
-
|
|
6869
|
-
|
|
6870
|
-
|
|
6871
|
-
|
|
6872
|
-
|
|
6873
|
-
|
|
6874
|
-
|
|
6875
|
-
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
|
|
6893
|
-
|
|
6894
|
-
|
|
6895
|
-
|
|
6896
|
-
|
|
6897
|
-
|
|
6898
|
-
|
|
6899
|
-
|
|
6900
|
-
|
|
6901
|
-
|
|
6902
|
-
|
|
6903
|
-
|
|
6904
|
-
|
|
6905
|
-
|
|
6906
|
-
|
|
6907
|
-
|
|
6803
|
+
// src/packing/resolver.ts
|
|
6804
|
+
function parseQualifiedName(name) {
|
|
6805
|
+
if (name.startsWith("@")) {
|
|
6806
|
+
const firstSlash = name.indexOf("/");
|
|
6807
|
+
if (firstSlash === -1) {
|
|
6808
|
+
return [null, name];
|
|
6809
|
+
}
|
|
6810
|
+
const secondSlash = name.indexOf("/", firstSlash + 1);
|
|
6811
|
+
if (secondSlash === -1) {
|
|
6812
|
+
return [null, name];
|
|
6813
|
+
}
|
|
6814
|
+
return [name.substring(0, secondSlash), name.substring(secondSlash + 1)];
|
|
6815
|
+
}
|
|
6816
|
+
const separatorIndex = name.indexOf("/");
|
|
6817
|
+
if (separatorIndex === -1) {
|
|
6818
|
+
return [null, name];
|
|
6819
|
+
}
|
|
6820
|
+
return [name.substring(0, separatorIndex), name.substring(separatorIndex + 1)];
|
|
6821
|
+
}
|
|
6822
|
+
function qualifyName(packageId, shortName) {
|
|
6823
|
+
return `${packageId}/${shortName}`;
|
|
6824
|
+
}
|
|
6825
|
+
function getShortName(name) {
|
|
6826
|
+
const [, shortName] = parseQualifiedName(name);
|
|
6827
|
+
return shortName;
|
|
6828
|
+
}
|
|
6829
|
+
function resolveTool(registry, name, namespace) {
|
|
6830
|
+
const [pkgId, shortName] = parseQualifiedName(name);
|
|
6831
|
+
if (pkgId !== null) {
|
|
6832
|
+
const pkg = registry.packages[pkgId];
|
|
6833
|
+
if (!pkg) {
|
|
6834
|
+
throw new NamespaceResolutionError(
|
|
6835
|
+
"tool",
|
|
6836
|
+
name,
|
|
6837
|
+
namespace,
|
|
6838
|
+
`Package "${pkgId}" not found`
|
|
6839
|
+
);
|
|
6840
|
+
}
|
|
6841
|
+
throw new NamespaceResolutionError(
|
|
6842
|
+
"tool",
|
|
6843
|
+
name,
|
|
6844
|
+
namespace,
|
|
6845
|
+
`Cannot access tool "${shortName}" from package "${pkgId}". Only entry point agents are accessible cross-package.`
|
|
6846
|
+
);
|
|
6847
|
+
}
|
|
6848
|
+
if (namespace.type === "packed") {
|
|
6849
|
+
const pkg = registry.packages[namespace.packageId];
|
|
6850
|
+
if (!pkg) {
|
|
6851
|
+
throw new NamespaceResolutionError(
|
|
6852
|
+
"tool",
|
|
6853
|
+
name,
|
|
6854
|
+
namespace,
|
|
6855
|
+
`Package "${namespace.packageId}" not found`
|
|
6856
|
+
);
|
|
6857
|
+
}
|
|
6858
|
+
const loader2 = pkg.tools[shortName];
|
|
6859
|
+
if (!loader2) {
|
|
6860
|
+
throw new NamespaceResolutionError(
|
|
6861
|
+
"tool",
|
|
6862
|
+
name,
|
|
6863
|
+
namespace,
|
|
6864
|
+
`Tool "${shortName}" not found in package "${namespace.packageId}"`
|
|
6865
|
+
);
|
|
6866
|
+
}
|
|
6867
|
+
return loader2;
|
|
6868
|
+
}
|
|
6869
|
+
const loader = registry.global.tools[shortName];
|
|
6870
|
+
if (!loader) {
|
|
6871
|
+
throw new NamespaceResolutionError(
|
|
6872
|
+
"tool",
|
|
6873
|
+
name,
|
|
6874
|
+
namespace,
|
|
6875
|
+
`Tool "${shortName}" not found in global namespace`
|
|
6876
|
+
);
|
|
6877
|
+
}
|
|
6878
|
+
return loader;
|
|
6879
|
+
}
|
|
6880
|
+
function resolvePrompt(registry, name, namespace) {
|
|
6881
|
+
const [pkgId, shortName] = parseQualifiedName(name);
|
|
6882
|
+
if (pkgId !== null) {
|
|
6883
|
+
throw new NamespaceResolutionError(
|
|
6884
|
+
"prompt",
|
|
6885
|
+
name,
|
|
6886
|
+
namespace,
|
|
6887
|
+
`Cannot access prompt "${shortName}" from package "${pkgId}". Prompts are package-internal.`
|
|
6888
|
+
);
|
|
6889
|
+
}
|
|
6890
|
+
if (namespace.type === "packed") {
|
|
6891
|
+
const pkg = registry.packages[namespace.packageId];
|
|
6892
|
+
if (!pkg) {
|
|
6893
|
+
throw new NamespaceResolutionError(
|
|
6894
|
+
"prompt",
|
|
6895
|
+
name,
|
|
6896
|
+
namespace,
|
|
6897
|
+
`Package "${namespace.packageId}" not found`
|
|
6898
|
+
);
|
|
6899
|
+
}
|
|
6900
|
+
const loader2 = pkg.prompts[shortName];
|
|
6901
|
+
if (!loader2) {
|
|
6902
|
+
throw new NamespaceResolutionError(
|
|
6903
|
+
"prompt",
|
|
6904
|
+
name,
|
|
6905
|
+
namespace,
|
|
6906
|
+
`Prompt "${shortName}" not found in package "${namespace.packageId}"`
|
|
6907
|
+
);
|
|
6908
|
+
}
|
|
6909
|
+
return loader2;
|
|
6910
|
+
}
|
|
6911
|
+
const loader = registry.global.prompts[shortName];
|
|
6912
|
+
if (!loader) {
|
|
6913
|
+
throw new NamespaceResolutionError(
|
|
6914
|
+
"prompt",
|
|
6915
|
+
name,
|
|
6916
|
+
namespace,
|
|
6917
|
+
`Prompt "${shortName}" not found in global namespace`
|
|
6918
|
+
);
|
|
6919
|
+
}
|
|
6920
|
+
return loader;
|
|
6921
|
+
}
|
|
6922
|
+
function resolveModel(registry, name, namespace) {
|
|
6923
|
+
const [possiblePkgId, shortName] = parseQualifiedName(name);
|
|
6924
|
+
if (possiblePkgId !== null && registry.packages[possiblePkgId]) {
|
|
6925
|
+
throw new NamespaceResolutionError(
|
|
6926
|
+
"model",
|
|
6927
|
+
name,
|
|
6928
|
+
namespace,
|
|
6929
|
+
`Cannot use qualified model name "${name}". Models must be unqualified. If this is a provider model name, ensure no package named "${possiblePkgId}" exists.`
|
|
6930
|
+
);
|
|
6931
|
+
}
|
|
6932
|
+
const lookupName = name;
|
|
6933
|
+
if (namespace.type === "packed") {
|
|
6934
|
+
const pkg = registry.packages[namespace.packageId];
|
|
6935
|
+
if (pkg) {
|
|
6936
|
+
const loader2 = pkg.models[lookupName];
|
|
6937
|
+
if (loader2) {
|
|
6938
|
+
return loader2;
|
|
6908
6939
|
}
|
|
6909
|
-
|
|
6910
|
-
|
|
6911
|
-
|
|
6912
|
-
|
|
6913
|
-
|
|
6914
|
-
|
|
6915
|
-
|
|
6916
|
-
|
|
6917
|
-
|
|
6918
|
-
|
|
6940
|
+
}
|
|
6941
|
+
const globalLoader = registry.global.models[lookupName];
|
|
6942
|
+
if (globalLoader) {
|
|
6943
|
+
return globalLoader;
|
|
6944
|
+
}
|
|
6945
|
+
throw new NamespaceResolutionError(
|
|
6946
|
+
"model",
|
|
6947
|
+
name,
|
|
6948
|
+
namespace,
|
|
6949
|
+
`Model "${lookupName}" not found in package "${namespace.packageId}" or global namespace`
|
|
6950
|
+
);
|
|
6951
|
+
}
|
|
6952
|
+
const loader = registry.global.models[lookupName];
|
|
6953
|
+
if (!loader) {
|
|
6954
|
+
throw new NamespaceResolutionError(
|
|
6955
|
+
"model",
|
|
6956
|
+
name,
|
|
6957
|
+
namespace,
|
|
6958
|
+
`Model "${lookupName}" not found in global namespace`
|
|
6959
|
+
);
|
|
6960
|
+
}
|
|
6961
|
+
return loader;
|
|
6962
|
+
}
|
|
6963
|
+
function resolveAgent(registry, name, namespace) {
|
|
6964
|
+
const [pkgId, shortName] = parseQualifiedName(name);
|
|
6965
|
+
if (pkgId !== null) {
|
|
6966
|
+
const pkg = registry.packages[pkgId];
|
|
6967
|
+
if (!pkg) {
|
|
6968
|
+
throw new NamespaceResolutionError(
|
|
6969
|
+
"agent",
|
|
6970
|
+
name,
|
|
6971
|
+
namespace,
|
|
6972
|
+
`Package "${pkgId}" not found`
|
|
6973
|
+
);
|
|
6974
|
+
}
|
|
6975
|
+
if (!pkg.entryAgents.includes(shortName)) {
|
|
6976
|
+
throw new NamespaceResolutionError(
|
|
6977
|
+
"agent",
|
|
6978
|
+
name,
|
|
6979
|
+
namespace,
|
|
6980
|
+
`Agent "${shortName}" is not an entry point in package "${pkgId}"`
|
|
6981
|
+
);
|
|
6982
|
+
}
|
|
6983
|
+
const loader = pkg.agents[shortName];
|
|
6984
|
+
if (!loader) {
|
|
6985
|
+
throw new NamespaceResolutionError(
|
|
6986
|
+
"agent",
|
|
6987
|
+
name,
|
|
6988
|
+
namespace,
|
|
6989
|
+
`Agent "${shortName}" not found in package "${pkgId}"`
|
|
6990
|
+
);
|
|
6991
|
+
}
|
|
6992
|
+
return loader;
|
|
6993
|
+
}
|
|
6994
|
+
if (namespace.type === "packed") {
|
|
6995
|
+
const pkg = registry.packages[namespace.packageId];
|
|
6996
|
+
if (!pkg) {
|
|
6997
|
+
throw new NamespaceResolutionError(
|
|
6998
|
+
"agent",
|
|
6999
|
+
name,
|
|
7000
|
+
namespace,
|
|
7001
|
+
`Package "${namespace.packageId}" not found`
|
|
7002
|
+
);
|
|
7003
|
+
}
|
|
7004
|
+
const loader = pkg.agents[shortName];
|
|
7005
|
+
if (!loader) {
|
|
7006
|
+
throw new NamespaceResolutionError(
|
|
7007
|
+
"agent",
|
|
7008
|
+
name,
|
|
7009
|
+
namespace,
|
|
7010
|
+
`Agent "${shortName}" not found in package "${namespace.packageId}"`
|
|
7011
|
+
);
|
|
7012
|
+
}
|
|
7013
|
+
return loader;
|
|
7014
|
+
}
|
|
7015
|
+
const globalLoader = registry.global.agents[shortName];
|
|
7016
|
+
if (globalLoader) {
|
|
7017
|
+
return globalLoader;
|
|
7018
|
+
}
|
|
7019
|
+
for (const [pkgId2, pkg] of Object.entries(registry.packages)) {
|
|
7020
|
+
if (pkg.entryAgents.includes(shortName)) {
|
|
7021
|
+
const loader = pkg.agents[shortName];
|
|
7022
|
+
if (loader) {
|
|
7023
|
+
return loader;
|
|
7024
|
+
}
|
|
7025
|
+
}
|
|
7026
|
+
}
|
|
7027
|
+
throw new NamespaceResolutionError(
|
|
7028
|
+
"agent",
|
|
7029
|
+
name,
|
|
7030
|
+
namespace,
|
|
7031
|
+
`Agent "${shortName}" not found in global namespace`
|
|
7032
|
+
);
|
|
7033
|
+
}
|
|
7034
|
+
function resolveHook(registry, name, namespace) {
|
|
7035
|
+
const [pkgId, shortName] = parseQualifiedName(name);
|
|
7036
|
+
if (pkgId !== null) {
|
|
7037
|
+
throw new NamespaceResolutionError(
|
|
7038
|
+
"hook",
|
|
7039
|
+
name,
|
|
7040
|
+
namespace,
|
|
7041
|
+
`Cannot use qualified hook name "${name}". Hooks must be unqualified.`
|
|
7042
|
+
);
|
|
7043
|
+
}
|
|
7044
|
+
if (namespace.type === "packed") {
|
|
7045
|
+
const pkg = registry.packages[namespace.packageId];
|
|
7046
|
+
if (pkg) {
|
|
7047
|
+
const loader2 = pkg.hooks[shortName];
|
|
7048
|
+
if (loader2) {
|
|
7049
|
+
return loader2;
|
|
7050
|
+
}
|
|
7051
|
+
}
|
|
7052
|
+
return null;
|
|
7053
|
+
}
|
|
7054
|
+
const loader = registry.global.hooks[shortName];
|
|
7055
|
+
return loader || null;
|
|
7056
|
+
}
|
|
7057
|
+
function getVisibleToolNames(registry, namespace) {
|
|
7058
|
+
if (namespace.type === "packed") {
|
|
7059
|
+
const pkg = registry.packages[namespace.packageId];
|
|
7060
|
+
return pkg ? Object.keys(pkg.tools) : [];
|
|
7061
|
+
}
|
|
7062
|
+
return Object.keys(registry.global.tools);
|
|
7063
|
+
}
|
|
7064
|
+
function getVisibleAgentNames(registry, namespace) {
|
|
7065
|
+
if (namespace.type === "packed") {
|
|
7066
|
+
const pkg = registry.packages[namespace.packageId];
|
|
7067
|
+
const ownAgents = pkg ? Object.keys(pkg.agents) : [];
|
|
7068
|
+
const otherEntryPoints = Object.entries(registry.packages).filter(([id]) => id !== namespace.packageId).flatMap(
|
|
7069
|
+
([pkgId, pkg2]) => pkg2.entryAgents.map((name) => qualifyName(pkgId, name))
|
|
7070
|
+
);
|
|
7071
|
+
return [...ownAgents, ...otherEntryPoints];
|
|
7072
|
+
}
|
|
7073
|
+
const globalAgents = Object.keys(registry.global.agents);
|
|
7074
|
+
const entryPoints = Object.values(registry.packages).flatMap((pkg) => pkg.entryAgents);
|
|
7075
|
+
return [.../* @__PURE__ */ new Set([...globalAgents, ...entryPoints])];
|
|
7076
|
+
}
|
|
7077
|
+
function getVisiblePromptNames(registry, namespace) {
|
|
7078
|
+
if (namespace.type === "packed") {
|
|
7079
|
+
const pkg = registry.packages[namespace.packageId];
|
|
7080
|
+
return pkg ? Object.keys(pkg.prompts) : [];
|
|
7081
|
+
}
|
|
7082
|
+
return Object.keys(registry.global.prompts);
|
|
7083
|
+
}
|
|
7084
|
+
function getVisibleModelNames(registry, namespace) {
|
|
7085
|
+
if (namespace.type === "packed") {
|
|
7086
|
+
const pkg = registry.packages[namespace.packageId];
|
|
7087
|
+
const ownModels = pkg ? Object.keys(pkg.models) : [];
|
|
7088
|
+
const globalModels = Object.keys(registry.global.models);
|
|
7089
|
+
return [.../* @__PURE__ */ new Set([...ownModels, ...globalModels])];
|
|
7090
|
+
}
|
|
7091
|
+
return Object.keys(registry.global.models);
|
|
7092
|
+
}
|
|
7093
|
+
function createNamespaceContext(agentDef) {
|
|
7094
|
+
if (agentDef?.__package) {
|
|
7095
|
+
return { type: "packed", packageId: agentDef.__package.packageId };
|
|
7096
|
+
}
|
|
7097
|
+
return { type: "global" };
|
|
7098
|
+
}
|
|
7099
|
+
function isQualifiedName(name) {
|
|
7100
|
+
if (name.startsWith("@")) {
|
|
7101
|
+
const firstSlash = name.indexOf("/");
|
|
7102
|
+
if (firstSlash === -1) return false;
|
|
7103
|
+
return name.indexOf("/", firstSlash + 1) !== -1;
|
|
7104
|
+
}
|
|
7105
|
+
return name.includes("/");
|
|
7106
|
+
}
|
|
7107
|
+
var NamespaceResolutionError;
|
|
7108
|
+
var init_resolver = __esm({
|
|
7109
|
+
"src/packing/resolver.ts"() {
|
|
7110
|
+
NamespaceResolutionError = class extends Error {
|
|
7111
|
+
constructor(itemType, itemName, namespace, message) {
|
|
7112
|
+
super(message);
|
|
7113
|
+
this.itemType = itemType;
|
|
7114
|
+
this.itemName = itemName;
|
|
7115
|
+
this.namespace = namespace;
|
|
7116
|
+
this.name = "NamespaceResolutionError";
|
|
7117
|
+
}
|
|
7118
|
+
};
|
|
7119
|
+
}
|
|
7120
|
+
});
|
|
7121
|
+
|
|
7122
|
+
// src/agents/ParentHookResolver.ts
|
|
7123
|
+
function packageOf(definition) {
|
|
7124
|
+
return definition?.__package ?? definition?._package;
|
|
7125
|
+
}
|
|
7126
|
+
function qualifyWithinPackage(name, packageId) {
|
|
7127
|
+
if (!packageId || parseQualifiedName(name)[0] !== null) {
|
|
7128
|
+
return name;
|
|
7129
|
+
}
|
|
7130
|
+
return qualifyName(packageId, name);
|
|
7131
|
+
}
|
|
7132
|
+
function promptHooks(prompt) {
|
|
7133
|
+
if (!prompt) return [];
|
|
7134
|
+
return Array.isArray(prompt.hooks) ? prompt.hooks : Array.isArray(prompt._hooks) ? prompt._hooks : [];
|
|
7135
|
+
}
|
|
7136
|
+
function promptTools(prompt) {
|
|
7137
|
+
if (!prompt) return [];
|
|
7138
|
+
return Array.isArray(prompt.tools) ? prompt.tools : Array.isArray(prompt._tools) ? prompt._tools : [];
|
|
7139
|
+
}
|
|
7140
|
+
function relationDescriptor(entry) {
|
|
7141
|
+
if (typeof entry === "string") {
|
|
7142
|
+
return {
|
|
7143
|
+
relationshipName: entry,
|
|
7144
|
+
implementingAgent: entry,
|
|
7145
|
+
explicitlyAgentShaped: false
|
|
7146
|
+
};
|
|
7147
|
+
}
|
|
7148
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
|
|
7149
|
+
return null;
|
|
7150
|
+
}
|
|
7151
|
+
const config = entry;
|
|
7152
|
+
if (typeof config.name !== "string" || !config.name) {
|
|
7153
|
+
return null;
|
|
7154
|
+
}
|
|
7155
|
+
const implementingAgent = typeof config.agent === "string" && config.agent ? config.agent : config.name;
|
|
7156
|
+
const explicitlyAgentShaped = "agent" in config || "blocking" in config || "resumable" in config || "immediate" in config || "parentCommunication" in config || "hidden" in config;
|
|
7157
|
+
return {
|
|
7158
|
+
relationshipName: config.name,
|
|
7159
|
+
implementingAgent,
|
|
7160
|
+
optional: typeof config.optional === "string" ? config.optional : void 0,
|
|
7161
|
+
explicitlyAgentShaped
|
|
7162
|
+
};
|
|
7163
|
+
}
|
|
7164
|
+
function hookLoader(host, owner, hookId) {
|
|
7165
|
+
const ownerPackage = packageOf(owner);
|
|
7166
|
+
if (!ownerPackage) {
|
|
7167
|
+
return host.hooks()[hookId];
|
|
7168
|
+
}
|
|
7169
|
+
return host.registry?.()?.packages?.[ownerPackage.packageId]?.hooks?.[hookId];
|
|
7170
|
+
}
|
|
7171
|
+
async function loadBinding(host, owner, hookId, hookType, context, required) {
|
|
7172
|
+
const loader = hookLoader(host, owner, hookId);
|
|
7173
|
+
if (!loader) {
|
|
7174
|
+
if (required) {
|
|
7175
|
+
throw new Error(
|
|
7176
|
+
`Required parent hook '${hookId}' was not found in the child agent namespace`
|
|
7177
|
+
);
|
|
7178
|
+
}
|
|
7179
|
+
return null;
|
|
7180
|
+
}
|
|
7181
|
+
let loaded;
|
|
7182
|
+
try {
|
|
7183
|
+
loaded = await loader();
|
|
7184
|
+
} catch (error) {
|
|
7185
|
+
if (required) throw error;
|
|
7186
|
+
console.error(`[Hooks] Failed to load hook '${hookId}':`, error);
|
|
7187
|
+
return null;
|
|
7188
|
+
}
|
|
7189
|
+
if (!loaded) {
|
|
7190
|
+
if (required) {
|
|
7191
|
+
throw new Error(`Required parent hook '${hookId}' did not export a hook definition`);
|
|
7192
|
+
}
|
|
7193
|
+
return null;
|
|
7194
|
+
}
|
|
7195
|
+
if (typeof loaded.id !== "string" || loaded.id !== hookId) {
|
|
7196
|
+
if (required) {
|
|
7197
|
+
throw new Error(`Required parent hook '${hookId}' exported a mismatched hook ID`);
|
|
7198
|
+
}
|
|
7199
|
+
return null;
|
|
7200
|
+
}
|
|
7201
|
+
if (typeof loaded.execute !== "function") {
|
|
7202
|
+
if (required) {
|
|
7203
|
+
throw new Error(`Required parent hook '${hookId}' did not export an execute function`);
|
|
7204
|
+
}
|
|
7205
|
+
return null;
|
|
7206
|
+
}
|
|
7207
|
+
if (USER_HOOK_NAMES.has(loaded.hook)) {
|
|
7208
|
+
if (required) {
|
|
7209
|
+
throw new Error(
|
|
7210
|
+
`Required parent hook '${hookId}' uses user-scoped hook type '${loaded.hook}'`
|
|
7211
|
+
);
|
|
7212
|
+
}
|
|
7213
|
+
return null;
|
|
7214
|
+
}
|
|
7215
|
+
if (!THREAD_HOOK_NAMES.has(loaded.hook)) {
|
|
7216
|
+
if (required) {
|
|
7217
|
+
throw new Error(`Required parent hook '${hookId}' exported invalid hook type '${loaded.hook}'`);
|
|
7218
|
+
}
|
|
7219
|
+
return null;
|
|
7220
|
+
}
|
|
7221
|
+
if (loaded.hook !== hookType) {
|
|
7222
|
+
return null;
|
|
7223
|
+
}
|
|
7224
|
+
return {
|
|
7225
|
+
id: hookId,
|
|
7226
|
+
hook: hookType,
|
|
7227
|
+
execute: loaded.execute,
|
|
7228
|
+
context
|
|
7229
|
+
};
|
|
7230
|
+
}
|
|
7231
|
+
async function resolveHooksForPrompt(input, hookType) {
|
|
7232
|
+
const agent = input.agent ?? await input.host.loadAgent(input.agentName);
|
|
7233
|
+
const agentPackage = packageOf(agent);
|
|
7234
|
+
const unqualifiedPromptName = input.promptName ?? agent.sideA?.prompt;
|
|
7235
|
+
const resolvedPromptName = unqualifiedPromptName ? qualifyWithinPackage(unqualifiedPromptName, agentPackage?.packageId) : void 0;
|
|
7236
|
+
const prompt = input.prompt ?? (resolvedPromptName ? await input.host.loadPrompt(resolvedPromptName) : void 0);
|
|
7237
|
+
const promptName = prompt?.name ?? prompt?.id ?? resolvedPromptName ?? "unknown_prompt";
|
|
7238
|
+
const before = [];
|
|
7239
|
+
const after = [];
|
|
7240
|
+
for (const entry of promptTools(prompt)) {
|
|
7241
|
+
const relation = relationDescriptor(entry);
|
|
7242
|
+
if (!relation) continue;
|
|
7243
|
+
if (relation.optional && input.isOptionalRelationshipEnabled && !await input.isOptionalRelationshipEnabled(relation.optional)) {
|
|
7244
|
+
continue;
|
|
7245
|
+
}
|
|
7246
|
+
const promptPackage = packageOf(prompt) ?? agentPackage;
|
|
7247
|
+
const childReference = qualifyWithinPackage(
|
|
7248
|
+
relation.implementingAgent,
|
|
7249
|
+
promptPackage?.packageId
|
|
7250
|
+
);
|
|
7251
|
+
let child;
|
|
7252
|
+
try {
|
|
7253
|
+
child = await input.host.loadAgent(childReference);
|
|
7254
|
+
} catch (error) {
|
|
7255
|
+
if (relation.explicitlyAgentShaped) throw error;
|
|
7256
|
+
continue;
|
|
7257
|
+
}
|
|
7258
|
+
if (child.type !== "dual_ai") continue;
|
|
7259
|
+
if (child.parentHooks !== void 0 && child.exposeAsTool !== true) {
|
|
7260
|
+
throw new Error(
|
|
7261
|
+
`Child agent '${childReference}' declares parentHooks but is not exposed as a tool`
|
|
7262
|
+
);
|
|
7263
|
+
}
|
|
7264
|
+
if (child.parentHooks !== void 0 && !Array.isArray(child.parentHooks)) {
|
|
7265
|
+
throw new Error(`Child agent '${childReference}' has an invalid parentHooks declaration`);
|
|
7266
|
+
}
|
|
7267
|
+
const requirements = child.parentHooks ?? [];
|
|
7268
|
+
const seenRequirements = /* @__PURE__ */ new Set();
|
|
7269
|
+
for (const requirement of requirements) {
|
|
7270
|
+
if (!requirement || typeof requirement !== "object" || typeof requirement.hook !== "string" || !requirement.hook || typeof requirement.reason !== "string" || !requirement.reason.trim() || requirement.stage !== void 0 && requirement.stage !== "before_parent" && requirement.stage !== "after_parent" || seenRequirements.has(requirement.hook)) {
|
|
7271
|
+
throw new Error(`Child agent '${childReference}' has an invalid parentHooks requirement`);
|
|
7272
|
+
}
|
|
7273
|
+
seenRequirements.add(requirement.hook);
|
|
7274
|
+
const loaded = await loadBinding(
|
|
7275
|
+
input.host,
|
|
7276
|
+
child,
|
|
7277
|
+
requirement.hook,
|
|
7278
|
+
hookType,
|
|
7279
|
+
{
|
|
7280
|
+
source: {
|
|
7281
|
+
kind: "child",
|
|
7282
|
+
relationshipName: relation.relationshipName,
|
|
7283
|
+
agentName: childReference,
|
|
7284
|
+
package: packageOf(child)
|
|
7285
|
+
}
|
|
7286
|
+
},
|
|
7287
|
+
true
|
|
7288
|
+
);
|
|
7289
|
+
if (!loaded) continue;
|
|
7290
|
+
if ((requirement.stage ?? "after_parent") === "before_parent") {
|
|
7291
|
+
before.push(loaded);
|
|
7292
|
+
} else {
|
|
7293
|
+
after.push(loaded);
|
|
7294
|
+
}
|
|
7295
|
+
}
|
|
7296
|
+
}
|
|
7297
|
+
const promptHookIds = promptHooks(prompt);
|
|
7298
|
+
const promptOwnsBaseHooks = promptHookIds.length > 0 && prompt !== void 0;
|
|
7299
|
+
const baseOwner = promptOwnsBaseHooks ? prompt : agent;
|
|
7300
|
+
const baseIds = promptHookIds.length > 0 ? promptHookIds : Array.isArray(agent.hooks) ? agent.hooks : [];
|
|
7301
|
+
const baseContext = promptOwnsBaseHooks ? { source: { kind: "prompt", promptName } } : { source: { kind: "agent", agentName: input.agentName } };
|
|
7302
|
+
const base = [];
|
|
7303
|
+
for (const hookId of baseIds) {
|
|
7304
|
+
const loaded = await loadBinding(
|
|
7305
|
+
input.host,
|
|
7306
|
+
baseOwner,
|
|
7307
|
+
hookId,
|
|
7308
|
+
hookType,
|
|
7309
|
+
baseContext,
|
|
7310
|
+
false
|
|
7311
|
+
);
|
|
7312
|
+
if (loaded) base.push(loaded);
|
|
7313
|
+
}
|
|
7314
|
+
return [...before, ...base, ...after];
|
|
7315
|
+
}
|
|
7316
|
+
var USER_HOOK_NAMES, THREAD_HOOK_NAMES;
|
|
7317
|
+
var init_ParentHookResolver = __esm({
|
|
7318
|
+
"src/agents/ParentHookResolver.ts"() {
|
|
7319
|
+
init_resolver();
|
|
7320
|
+
USER_HOOK_NAMES = /* @__PURE__ */ new Set([
|
|
7321
|
+
"user_client_attached",
|
|
7322
|
+
"user_client_detached",
|
|
7323
|
+
"user_value_changed"
|
|
7324
|
+
]);
|
|
7325
|
+
THREAD_HOOK_NAMES = /* @__PURE__ */ new Set([
|
|
7326
|
+
"after_thread_created",
|
|
7327
|
+
"after_subagent_created",
|
|
7328
|
+
"after_system_message",
|
|
7329
|
+
"filter_messages",
|
|
7330
|
+
"prefilter_llm_history",
|
|
7331
|
+
"before_create_message",
|
|
7332
|
+
"after_create_message",
|
|
7333
|
+
"before_update_message",
|
|
7334
|
+
"after_update_message",
|
|
7335
|
+
"before_store_tool_result",
|
|
7336
|
+
"after_tool_call_success",
|
|
7337
|
+
"after_tool_call_failure",
|
|
7338
|
+
"tool_call_started",
|
|
7339
|
+
"tool_call_done"
|
|
7340
|
+
]);
|
|
7341
|
+
}
|
|
7342
|
+
});
|
|
7343
|
+
|
|
7344
|
+
// src/agents/FlowEngine.ts
|
|
7345
|
+
var FlowEngine_exports = {};
|
|
7346
|
+
__export(FlowEngine_exports, {
|
|
7347
|
+
FlowEngine: () => FlowEngine,
|
|
7348
|
+
HookBlockedExecutionError: () => HookBlockedExecutionError
|
|
7349
|
+
});
|
|
7350
|
+
var IMMEDIATE_BOOTSTRAP_TOOL_NAME, HookBlockedExecutionError, FlowEngine;
|
|
7351
|
+
var init_FlowEngine = __esm({
|
|
7352
|
+
"src/agents/FlowEngine.ts"() {
|
|
7353
|
+
init_types();
|
|
7354
|
+
init_StreamManager();
|
|
7355
|
+
init_LLMRequest();
|
|
7356
|
+
init_ToolExecutor();
|
|
7357
|
+
init_context();
|
|
7358
|
+
init_sessionTools();
|
|
7359
|
+
init_ThreadStateImpl();
|
|
7360
|
+
init_ParentHookResolver();
|
|
7361
|
+
IMMEDIATE_BOOTSTRAP_TOOL_NAME = "bootstrap_immediate_subagent";
|
|
7362
|
+
HookBlockedExecutionError = class extends Error {
|
|
7363
|
+
constructor(message) {
|
|
7364
|
+
super(message);
|
|
7365
|
+
this.name = "HookBlockedExecutionError";
|
|
7366
|
+
}
|
|
7367
|
+
};
|
|
7368
|
+
FlowEngine = class _FlowEngine {
|
|
7369
|
+
static IMMEDIATE_SCOPED_ENV_CONTEXT_KEY = "__immediate_scoped_env_by_call_id";
|
|
7370
|
+
/**
|
|
7371
|
+
* Main execution entry point
|
|
7372
|
+
* Executes an agent conversation until stopped or max steps reached
|
|
7373
|
+
*
|
|
7374
|
+
* By default, returns immediately with the stream while execution continues in background.
|
|
7375
|
+
* Set awaitCompletion: true to wait for all steps and database writes to complete (required for sub-prompts).
|
|
7376
|
+
*
|
|
7377
|
+
* @param stateInput - Partial FlowState object with required fields
|
|
7378
|
+
* @param awaitCompletion - If true, awaits full execution completion before returning (default: false)
|
|
7379
|
+
*/
|
|
7380
|
+
static async execute(stateInput, awaitCompletion = false) {
|
|
7381
|
+
const state = await this.initializeState(stateInput);
|
|
7382
|
+
if (awaitCompletion) {
|
|
7383
|
+
try {
|
|
7384
|
+
await this.executeAsync(state, state.threadId);
|
|
7385
|
+
} catch (error) {
|
|
7386
|
+
console.error("Fatal error in executeAsync:", error);
|
|
7387
|
+
await this.logError(state, error, "fatal_execution_error", "FlowEngine.executeAsync");
|
|
7388
|
+
await this.settleTerminalFailure(state, error);
|
|
7389
|
+
throw error;
|
|
7390
|
+
}
|
|
7391
|
+
} else {
|
|
7392
|
+
this.executeAsync(state, state.threadId).catch(async (error) => {
|
|
7393
|
+
console.error("Fatal error in executeAsync:", error);
|
|
7394
|
+
await this.logError(state, error, "fatal_execution_error", "FlowEngine.executeAsync");
|
|
7395
|
+
await this.settleTerminalFailure(state, error);
|
|
7396
|
+
});
|
|
7397
|
+
}
|
|
7398
|
+
return {
|
|
7399
|
+
messages: state.messageHistory,
|
|
7400
|
+
stopped: state.stopped,
|
|
7401
|
+
stoppedBy: state.stoppedBy,
|
|
7402
|
+
stopReason: state.stopReason,
|
|
7403
|
+
stopReasonCode: state.stopReasonCode,
|
|
7404
|
+
sessionStopped: state.sessionStopped,
|
|
7405
|
+
sessionStopResult: state.sessionStopResult,
|
|
7406
|
+
stepCount: state.stepCount,
|
|
7407
|
+
stream: state.stream.httpStream
|
|
7408
|
+
};
|
|
7409
|
+
}
|
|
7410
|
+
/**
|
|
7411
|
+
* Execute the agentic loop asynchronously
|
|
7412
|
+
* This runs in the background while the stream is being consumed
|
|
7413
|
+
*/
|
|
7414
|
+
/**
|
|
7415
|
+
* Finalize logs left incomplete by a previous, abandoned execution.
|
|
7416
|
+
*
|
|
7417
|
+
* A log row is created with is_complete=0 the moment a request is sent and is
|
|
7418
|
+
* only flipped complete by logSuccess/logError. If the Durable Object is
|
|
7419
|
+
* evicted (or crashes) while awaiting a hung provider, neither runs and the row
|
|
7420
|
+
* is stranded incomplete forever — which downstream reads as "the agent is
|
|
7421
|
+
* still running". A fresh top-level execution proves the prior request is no
|
|
7422
|
+
* longer in flight, so we mark any lingering incomplete logs as failed and tell
|
|
7423
|
+
* connected clients so their "running" state clears. Best-effort: never let
|
|
7424
|
+
* this cleanup block or fail the execution.
|
|
7425
|
+
*/
|
|
7426
|
+
static async finalizeOrphanedLogs(state) {
|
|
7427
|
+
try {
|
|
7428
|
+
const rows = (await state.storage.sql.exec(
|
|
7429
|
+
`SELECT id FROM logs WHERE is_complete = 0`
|
|
7430
|
+
)).toArray();
|
|
7431
|
+
if (rows.length === 0) return;
|
|
7432
|
+
const error = "Request did not complete \u2014 the response was interrupted (the worker was evicted or the provider stalled) before it finished.";
|
|
7433
|
+
const errorType = "interrupted_incomplete";
|
|
7434
|
+
await state.storage.sql.exec(
|
|
7435
|
+
`UPDATE logs SET is_complete = 1, error = ?1, error_type = ?2 WHERE is_complete = 0`,
|
|
7436
|
+
error,
|
|
7437
|
+
errorType
|
|
7438
|
+
);
|
|
7439
|
+
for (const row of rows) {
|
|
7440
|
+
state.emitLog?.({
|
|
7441
|
+
type: "log_data",
|
|
7442
|
+
log_id: row.id,
|
|
7443
|
+
data: { id: row.id, is_complete: true, error, error_type: errorType }
|
|
7444
|
+
});
|
|
7445
|
+
}
|
|
7446
|
+
console.warn(
|
|
7447
|
+
`[FlowEngine] Finalized ${rows.length} orphaned incomplete log(s) for thread ${state.threadId}`
|
|
7448
|
+
);
|
|
7449
|
+
await state.thread.instance.failPendingMessagesAndBroadcast?.();
|
|
7450
|
+
} catch (err) {
|
|
7451
|
+
console.error("[FlowEngine] Failed to finalize orphaned logs (non-fatal):", err);
|
|
7452
|
+
}
|
|
7453
|
+
}
|
|
7454
|
+
/**
|
|
7455
|
+
* A terminal execution failure ended the run without a normal assistant
|
|
7456
|
+
* reply. Persist a durable failed assistant message + settle pending
|
|
7457
|
+
* messages so every connected head lands on a visible end state instead of
|
|
7458
|
+
* a stuck "Working" spinner. Best-effort — never masks the original error.
|
|
7459
|
+
*/
|
|
7460
|
+
static async settleTerminalFailure(state, error) {
|
|
7461
|
+
try {
|
|
7462
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
7463
|
+
await state.thread.instance.settleTerminalFailure?.(
|
|
6919
7464
|
`The agent run failed unexpectedly: ${detail}`,
|
|
6920
7465
|
state.threadId
|
|
6921
7466
|
);
|
|
@@ -7155,7 +7700,8 @@ This usually points to something I can't fix from here \u2014 for example the wo
|
|
|
7155
7700
|
_variables: def.variables ?? [],
|
|
7156
7701
|
_env: def.env ?? def.tenvs ?? {},
|
|
7157
7702
|
_requiredSchema: def.requiredSchema ?? null,
|
|
7158
|
-
_hooks: def.hooks ?? []
|
|
7703
|
+
_hooks: def.hooks ?? [],
|
|
7704
|
+
_package: def.__package
|
|
7159
7705
|
};
|
|
7160
7706
|
}
|
|
7161
7707
|
/**
|
|
@@ -7545,6 +8091,8 @@ This usually points to something I can't fix from here \u2014 for example the wo
|
|
|
7545
8091
|
type: newAgentDef.type,
|
|
7546
8092
|
created_at: Date.now(),
|
|
7547
8093
|
max_session_turns: newAgentDef.maxSessionTurns ?? null,
|
|
8094
|
+
hooks: newAgentDef.hooks ?? [],
|
|
8095
|
+
_package: newAgentDef.__package,
|
|
7548
8096
|
side_a_label: newAgentDef.sideA?.label ?? null,
|
|
7549
8097
|
side_a_agent_prompt: newAgentDef.sideA?.prompt ?? null,
|
|
7550
8098
|
side_a_stop_on_response: newAgentDef.sideA?.stopOnResponse ?? true,
|
|
@@ -7635,28 +8183,12 @@ This usually points to something I can't fix from here \u2014 for example the wo
|
|
|
7635
8183
|
state.promptPath = [sideAPrompt.name];
|
|
7636
8184
|
state.pendingImmediateAfterHandoff = true;
|
|
7637
8185
|
if (userMessageContent || userMessageAttachments) {
|
|
7638
|
-
|
|
7639
|
-
|
|
7640
|
-
|
|
7641
|
-
|
|
7642
|
-
role: "user",
|
|
7643
|
-
content: userMessageContent || "",
|
|
7644
|
-
created_at: handoffTimestamp,
|
|
7645
|
-
attachments: userMessageAttachments
|
|
7646
|
-
};
|
|
7647
|
-
await state.storage.sql.exec(
|
|
7648
|
-
`INSERT INTO messages (id, role, content, attachments, created_at, prompt) VALUES (?, ?, ?, ?, ?, ?)`,
|
|
7649
|
-
handoffMessage.id,
|
|
7650
|
-
handoffMessage.role,
|
|
7651
|
-
handoffMessage.content,
|
|
7652
|
-
handoffMessage.attachments || null,
|
|
7653
|
-
handoffMessage.created_at,
|
|
8186
|
+
await this.persistHandoffUserMessage(
|
|
8187
|
+
state,
|
|
8188
|
+
userMessageContent || "",
|
|
8189
|
+
userMessageAttachments,
|
|
7654
8190
|
sideAPrompt.name
|
|
7655
8191
|
);
|
|
7656
|
-
state.messageHistory.push(handoffMessage);
|
|
7657
|
-
if (state.emitMessage) {
|
|
7658
|
-
state.emitMessage(handoffMessage);
|
|
7659
|
-
}
|
|
7660
8192
|
}
|
|
7661
8193
|
state.pendingHandoff = void 0;
|
|
7662
8194
|
state.emitTelemetry?.({
|
|
@@ -7671,6 +8203,37 @@ This usually points to something I can't fix from here \u2014 for example the wo
|
|
|
7671
8203
|
throw error;
|
|
7672
8204
|
}
|
|
7673
8205
|
}
|
|
8206
|
+
/**
|
|
8207
|
+
* Persist the user message that rides an agent handoff, applying the
|
|
8208
|
+
* create-message lifecycle hooks like every other insertion path.
|
|
8209
|
+
*/
|
|
8210
|
+
static async persistHandoffUserMessage(state, content, attachments, promptName) {
|
|
8211
|
+
let handoffMessage = {
|
|
8212
|
+
id: crypto.randomUUID(),
|
|
8213
|
+
role: "user",
|
|
8214
|
+
content,
|
|
8215
|
+
created_at: Date.now() * 1e3,
|
|
8216
|
+
status: "completed",
|
|
8217
|
+
attachments: attachments ?? null
|
|
8218
|
+
};
|
|
8219
|
+
handoffMessage = await this.runBeforeCreateMessageHook(state, handoffMessage);
|
|
8220
|
+
await state.storage.sql.exec(
|
|
8221
|
+
`INSERT INTO messages (id, role, content, attachments, created_at, status, silent, prompt) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
8222
|
+
handoffMessage.id,
|
|
8223
|
+
handoffMessage.role,
|
|
8224
|
+
handoffMessage.content,
|
|
8225
|
+
handoffMessage.attachments || null,
|
|
8226
|
+
handoffMessage.created_at,
|
|
8227
|
+
handoffMessage.status ?? "completed",
|
|
8228
|
+
handoffMessage.silent ? 1 : 0,
|
|
8229
|
+
promptName
|
|
8230
|
+
);
|
|
8231
|
+
state.messageHistory.push(handoffMessage);
|
|
8232
|
+
await this.runAfterCreateMessageHook(state, handoffMessage);
|
|
8233
|
+
if (state.emitMessage) {
|
|
8234
|
+
state.emitMessage(handoffMessage);
|
|
8235
|
+
}
|
|
8236
|
+
}
|
|
7674
8237
|
static isEnabledEnvFlag(value) {
|
|
7675
8238
|
if (value === null || value === void 0) return false;
|
|
7676
8239
|
const normalized = value.trim().toLowerCase();
|
|
@@ -7690,7 +8253,7 @@ This usually points to something I can't fix from here \u2014 for example the wo
|
|
|
7690
8253
|
return null;
|
|
7691
8254
|
}
|
|
7692
8255
|
return await stub.resolveThreadEnv({
|
|
7693
|
-
threadId: state.
|
|
8256
|
+
threadId: state.thread.metadata.id,
|
|
7694
8257
|
property,
|
|
7695
8258
|
promptName: state.prompt?.name
|
|
7696
8259
|
});
|
|
@@ -8212,8 +8775,8 @@ This usually points to something I can't fix from here \u2014 for example the wo
|
|
|
8212
8775
|
state.context[key] = existing;
|
|
8213
8776
|
}
|
|
8214
8777
|
static async runImmediateToolsIfNeeded(state) {
|
|
8215
|
-
const
|
|
8216
|
-
if (
|
|
8778
|
+
const promptTools2 = Array.isArray(state.prompt._tools) ? state.prompt._tools : [];
|
|
8779
|
+
if (promptTools2.length === 0) {
|
|
8217
8780
|
return false;
|
|
8218
8781
|
}
|
|
8219
8782
|
if (!state.immediatePromptRuns) {
|
|
@@ -8249,7 +8812,7 @@ This usually points to something I can't fix from here \u2014 for example the wo
|
|
|
8249
8812
|
(activeInstanceCounts.get(child.name) ?? 0) + 1
|
|
8250
8813
|
);
|
|
8251
8814
|
}
|
|
8252
|
-
for (const toolConfig of
|
|
8815
|
+
for (const toolConfig of promptTools2) {
|
|
8253
8816
|
if (!toolConfig || typeof toolConfig !== "object") {
|
|
8254
8817
|
continue;
|
|
8255
8818
|
}
|
|
@@ -8415,10 +8978,10 @@ This usually points to something I can't fix from here \u2014 for example the wo
|
|
|
8415
8978
|
* model's to clean up, and terminate_subagent on an infrastructure child
|
|
8416
8979
|
* kills work the runtime depends on. Static and pure for direct testing.
|
|
8417
8980
|
*/
|
|
8418
|
-
static filterModelVisibleSubagents(registry,
|
|
8981
|
+
static filterModelVisibleSubagents(registry, promptTools2) {
|
|
8419
8982
|
if (registry.length === 0) return registry;
|
|
8420
8983
|
const hidden = /* @__PURE__ */ new Set();
|
|
8421
|
-
for (const config of
|
|
8984
|
+
for (const config of promptTools2 ?? []) {
|
|
8422
8985
|
if (typeof config === "object" && config !== null && "name" in config && config.hidden === true) {
|
|
8423
8986
|
hidden.add(config.name);
|
|
8424
8987
|
}
|
|
@@ -8568,7 +9131,16 @@ This usually points to something I can't fix from here \u2014 for example the wo
|
|
|
8568
9131
|
role: "system",
|
|
8569
9132
|
content: systemPromptText
|
|
8570
9133
|
});
|
|
8571
|
-
const
|
|
9134
|
+
const historySnapshot = state.messageHistory.filter(
|
|
9135
|
+
(msg) => msg.status !== "pending"
|
|
9136
|
+
);
|
|
9137
|
+
const filteredHistory = await this.runFilterMessagesHook(
|
|
9138
|
+
state.thread.instance,
|
|
9139
|
+
state,
|
|
9140
|
+
historySnapshot
|
|
9141
|
+
);
|
|
9142
|
+
const contextHistory = this.filterOrphanedToolCalls(filteredHistory);
|
|
9143
|
+
const completedMessages = contextHistory.filter(
|
|
8572
9144
|
(msg) => msg.status !== "pending"
|
|
8573
9145
|
);
|
|
8574
9146
|
const recentMessageThreshold = state.prompt.recentImageThreshold ?? 10;
|
|
@@ -9439,8 +10011,8 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9439
10011
|
try {
|
|
9440
10012
|
const nativeTools = await this.loadNativeTools(state);
|
|
9441
10013
|
tools.push(...nativeTools);
|
|
9442
|
-
const
|
|
9443
|
-
tools.push(...
|
|
10014
|
+
const promptTools2 = await this.loadPromptTools(state);
|
|
10015
|
+
tools.push(...promptTools2);
|
|
9444
10016
|
const agentTools = await this.loadAgentTools(state);
|
|
9445
10017
|
tools.push(...agentTools);
|
|
9446
10018
|
const toolNameSources = /* @__PURE__ */ new Map();
|
|
@@ -9449,7 +10021,7 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9449
10021
|
sources.add("native tool");
|
|
9450
10022
|
toolNameSources.set(tool.function.name, sources);
|
|
9451
10023
|
}
|
|
9452
|
-
for (const tool of
|
|
10024
|
+
for (const tool of promptTools2) {
|
|
9453
10025
|
const sources = toolNameSources.get(tool.function.name) || /* @__PURE__ */ new Set();
|
|
9454
10026
|
sources.add("prompt");
|
|
9455
10027
|
toolNameSources.set(tool.function.name, sources);
|
|
@@ -9591,24 +10163,8 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9591
10163
|
// Hook Resolution Helpers
|
|
9592
10164
|
// ==========================================================================
|
|
9593
10165
|
/**
|
|
9594
|
-
*
|
|
9595
|
-
*
|
|
9596
|
-
*
|
|
9597
|
-
* @param state - Flow state with prompt and agent configuration
|
|
9598
|
-
* @returns Array of hook IDs to execute
|
|
9599
|
-
*/
|
|
9600
|
-
static getActiveHookIds(state) {
|
|
9601
|
-
if (state.prompt?._hooks !== void 0 && state.prompt._hooks.length > 0) {
|
|
9602
|
-
return state.prompt._hooks;
|
|
9603
|
-
}
|
|
9604
|
-
if (state.agentConfig.hooks !== void 0 && state.agentConfig.hooks.length > 0) {
|
|
9605
|
-
return state.agentConfig.hooks;
|
|
9606
|
-
}
|
|
9607
|
-
return [];
|
|
9608
|
-
}
|
|
9609
|
-
/**
|
|
9610
|
-
* Get hooks of a specific type from the active hook IDs.
|
|
9611
|
-
* Returns typed hook executors in the order they appear in the hooks array.
|
|
10166
|
+
* Resolve hooks of a specific type for the active prompt, including required
|
|
10167
|
+
* hooks contributed automatically by its enabled direct child agents.
|
|
9612
10168
|
*
|
|
9613
10169
|
* @template K - The hook type name (ensures type-safe executors)
|
|
9614
10170
|
* @param state - Flow state with hook configuration
|
|
@@ -9616,24 +10172,17 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9616
10172
|
* @returns Array of typed hook executor functions
|
|
9617
10173
|
*/
|
|
9618
10174
|
static async getHooksForType(state, hookType) {
|
|
9619
|
-
|
|
9620
|
-
|
|
9621
|
-
|
|
9622
|
-
|
|
9623
|
-
|
|
9624
|
-
|
|
9625
|
-
|
|
9626
|
-
|
|
9627
|
-
|
|
9628
|
-
|
|
9629
|
-
|
|
9630
|
-
executors.push(hookDef.execute);
|
|
9631
|
-
}
|
|
9632
|
-
} catch (error) {
|
|
9633
|
-
console.error(`[Hooks] Failed to load hook '${hookId}':`, error);
|
|
9634
|
-
}
|
|
9635
|
-
}
|
|
9636
|
-
return executors;
|
|
10175
|
+
return await resolveHooksForPrompt(
|
|
10176
|
+
{
|
|
10177
|
+
host: state.thread.instance,
|
|
10178
|
+
agentName: state.agentConfig.id,
|
|
10179
|
+
agent: state.agentConfig,
|
|
10180
|
+
promptName: state.prompt?.id,
|
|
10181
|
+
prompt: state.prompt,
|
|
10182
|
+
isOptionalRelationshipEnabled: (envName) => this.isOptionalToolEnabled(state, envName)
|
|
10183
|
+
},
|
|
10184
|
+
hookType
|
|
10185
|
+
);
|
|
9637
10186
|
}
|
|
9638
10187
|
// ==========================================================================
|
|
9639
10188
|
// Hook Runner Methods
|
|
@@ -9651,9 +10200,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9651
10200
|
if (executors.length === 0) return messages;
|
|
9652
10201
|
let result = messages;
|
|
9653
10202
|
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
9654
|
-
for (const
|
|
10203
|
+
for (const { execute, context } of executors) {
|
|
9655
10204
|
try {
|
|
9656
|
-
result = await
|
|
10205
|
+
result = await execute(threadState, result, context);
|
|
9657
10206
|
} catch (error) {
|
|
9658
10207
|
if (error && typeof error === "object" && error.block === true) {
|
|
9659
10208
|
throw new HookBlockedExecutionError(error instanceof Error ? error.message : String(error));
|
|
@@ -9671,9 +10220,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9671
10220
|
if (executors.length === 0) return systemMessage;
|
|
9672
10221
|
let result = systemMessage;
|
|
9673
10222
|
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
9674
|
-
for (const
|
|
10223
|
+
for (const { execute, context } of executors) {
|
|
9675
10224
|
try {
|
|
9676
|
-
const next = await
|
|
10225
|
+
const next = await execute(threadState, result, context);
|
|
9677
10226
|
if (next !== null && next !== void 0) {
|
|
9678
10227
|
result = next;
|
|
9679
10228
|
}
|
|
@@ -9690,9 +10239,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9690
10239
|
const executors = await this.getHooksForType(state, "after_subagent_created");
|
|
9691
10240
|
if (executors.length === 0) return;
|
|
9692
10241
|
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
9693
|
-
for (const
|
|
10242
|
+
for (const { execute, context } of executors) {
|
|
9694
10243
|
try {
|
|
9695
|
-
await
|
|
10244
|
+
await execute(threadState, childState, context);
|
|
9696
10245
|
} catch (error) {
|
|
9697
10246
|
console.error("[Hooks] \u2717 Error running after_subagent_created hook:", error);
|
|
9698
10247
|
}
|
|
@@ -9706,20 +10255,27 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9706
10255
|
* @param message - Message object to be created
|
|
9707
10256
|
* @returns Processed message (or original if hook doesn't exist/fails)
|
|
9708
10257
|
*/
|
|
9709
|
-
static async runBeforeCreateMessageHook(state, message) {
|
|
10258
|
+
static async runBeforeCreateMessageHook(state, message, threadStateOverride, options) {
|
|
9710
10259
|
const executors = await this.getHooksForType(state, "before_create_message");
|
|
9711
10260
|
if (executors.length === 0) return message;
|
|
9712
10261
|
let result = message;
|
|
9713
|
-
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
9714
|
-
for (const
|
|
10262
|
+
const threadState = threadStateOverride ?? ThreadStateImpl.fromFlowState(state);
|
|
10263
|
+
for (const { execute, context } of executors) {
|
|
9715
10264
|
try {
|
|
9716
|
-
const hooked = await
|
|
10265
|
+
const hooked = await execute(
|
|
10266
|
+
threadState,
|
|
10267
|
+
_FlowEngine.rowToHookMessage(result),
|
|
10268
|
+
context
|
|
10269
|
+
);
|
|
9717
10270
|
result = {
|
|
9718
10271
|
...result,
|
|
9719
10272
|
...hooked,
|
|
9720
10273
|
attachments: hooked.attachments === void 0 ? result.attachments : hooked.attachments === null ? null : typeof hooked.attachments === "string" ? hooked.attachments : JSON.stringify(hooked.attachments)
|
|
9721
10274
|
};
|
|
9722
10275
|
} catch (error) {
|
|
10276
|
+
if (options?.propagateHookErrors) {
|
|
10277
|
+
throw error;
|
|
10278
|
+
}
|
|
9723
10279
|
console.error("[Hooks] \u2717 Error running before_create_message hook:", error);
|
|
9724
10280
|
}
|
|
9725
10281
|
}
|
|
@@ -9732,13 +10288,13 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9732
10288
|
* @param state - Flow state with execution context
|
|
9733
10289
|
* @param message - The created message object
|
|
9734
10290
|
*/
|
|
9735
|
-
static async runAfterCreateMessageHook(state, message) {
|
|
10291
|
+
static async runAfterCreateMessageHook(state, message, threadStateOverride) {
|
|
9736
10292
|
const executors = await this.getHooksForType(state, "after_create_message");
|
|
9737
10293
|
if (executors.length === 0) return;
|
|
9738
|
-
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
9739
|
-
for (const
|
|
10294
|
+
const threadState = threadStateOverride ?? ThreadStateImpl.fromFlowState(state);
|
|
10295
|
+
for (const { execute, context } of executors) {
|
|
9740
10296
|
try {
|
|
9741
|
-
await
|
|
10297
|
+
await execute(threadState, _FlowEngine.rowToHookMessage(message), context);
|
|
9742
10298
|
} catch (error) {
|
|
9743
10299
|
console.error("[Hooks] \u2717 Error running after_create_message hook:", error);
|
|
9744
10300
|
}
|
|
@@ -9779,9 +10335,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9779
10335
|
if (executors.length === 0) return updates;
|
|
9780
10336
|
let result = updates;
|
|
9781
10337
|
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
9782
|
-
for (const
|
|
10338
|
+
for (const { execute, context } of executors) {
|
|
9783
10339
|
try {
|
|
9784
|
-
result = await
|
|
10340
|
+
result = await execute(threadState, messageId, result, context);
|
|
9785
10341
|
} catch (error) {
|
|
9786
10342
|
console.error("[Hooks] \u2717 Error running before_update_message hook:", error);
|
|
9787
10343
|
}
|
|
@@ -9799,9 +10355,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9799
10355
|
const executors = await this.getHooksForType(state, "after_update_message");
|
|
9800
10356
|
if (executors.length === 0) return;
|
|
9801
10357
|
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
9802
|
-
for (const
|
|
10358
|
+
for (const { execute, context } of executors) {
|
|
9803
10359
|
try {
|
|
9804
|
-
await
|
|
10360
|
+
await execute(threadState, _FlowEngine.rowToHookMessage(message), context);
|
|
9805
10361
|
} catch (error) {
|
|
9806
10362
|
console.error("[Hooks] \u2717 Error running after_update_message hook:", error);
|
|
9807
10363
|
}
|
|
@@ -9821,9 +10377,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9821
10377
|
if (executors.length === 0) return toolResult;
|
|
9822
10378
|
let result = toolResult;
|
|
9823
10379
|
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
9824
|
-
for (const
|
|
10380
|
+
for (const { execute, context } of executors) {
|
|
9825
10381
|
try {
|
|
9826
|
-
result = await
|
|
10382
|
+
result = await execute(threadState, toolCall, result, context);
|
|
9827
10383
|
} catch (error) {
|
|
9828
10384
|
console.error("[Hooks] \u2717 Error running before_store_tool_result hook:", error);
|
|
9829
10385
|
}
|
|
@@ -9843,10 +10399,10 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9843
10399
|
if (executors.length === 0) return toolResult;
|
|
9844
10400
|
let result = toolResult;
|
|
9845
10401
|
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
9846
|
-
for (const
|
|
10402
|
+
for (const { execute, context } of executors) {
|
|
9847
10403
|
if (result === null) break;
|
|
9848
10404
|
try {
|
|
9849
|
-
result = await
|
|
10405
|
+
result = await execute(threadState, toolCall, result, context);
|
|
9850
10406
|
} catch (error) {
|
|
9851
10407
|
console.error("[Hooks] \u2717 Error running after_tool_call_success hook:", error);
|
|
9852
10408
|
}
|
|
@@ -9866,10 +10422,10 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9866
10422
|
if (executors.length === 0) return toolResult;
|
|
9867
10423
|
let result = toolResult;
|
|
9868
10424
|
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
9869
|
-
for (const
|
|
10425
|
+
for (const { execute, context } of executors) {
|
|
9870
10426
|
if (result === null) break;
|
|
9871
10427
|
try {
|
|
9872
|
-
result = await
|
|
10428
|
+
result = await execute(threadState, toolCall, result, context);
|
|
9873
10429
|
} catch (error) {
|
|
9874
10430
|
console.error("[Hooks] \u2717 Error running after_tool_call_failure hook:", error);
|
|
9875
10431
|
}
|
|
@@ -9899,9 +10455,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9899
10455
|
const executors = await this.getHooksForType(state, "tool_call_started");
|
|
9900
10456
|
if (executors.length === 0) return;
|
|
9901
10457
|
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
9902
|
-
for (const
|
|
10458
|
+
for (const { execute, context } of executors) {
|
|
9903
10459
|
try {
|
|
9904
|
-
await
|
|
10460
|
+
await execute(threadState, toolCall, progress, context);
|
|
9905
10461
|
} catch (error) {
|
|
9906
10462
|
console.error("[Hooks] \u2717 Error running tool_call_started hook:", error);
|
|
9907
10463
|
}
|
|
@@ -9929,9 +10485,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
9929
10485
|
const executors = await this.getHooksForType(state, "tool_call_done");
|
|
9930
10486
|
if (executors.length === 0) return;
|
|
9931
10487
|
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
9932
|
-
for (const
|
|
10488
|
+
for (const { execute, context } of executors) {
|
|
9933
10489
|
try {
|
|
9934
|
-
await
|
|
10490
|
+
await execute(threadState, toolCall, toolResult, context);
|
|
9935
10491
|
} catch (error) {
|
|
9936
10492
|
console.error("[Hooks] \u2717 Error running tool_call_done hook:", error);
|
|
9937
10493
|
}
|
|
@@ -10236,7 +10792,7 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
10236
10792
|
}
|
|
10237
10793
|
existingPathMessages.add(content);
|
|
10238
10794
|
const attachmentsJson = JSON.stringify([ref]);
|
|
10239
|
-
|
|
10795
|
+
let silentMessage = {
|
|
10240
10796
|
id: crypto.randomUUID(),
|
|
10241
10797
|
role: sourceMessage.role,
|
|
10242
10798
|
content,
|
|
@@ -10247,6 +10803,7 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
10247
10803
|
parent_id: parentId,
|
|
10248
10804
|
depth
|
|
10249
10805
|
};
|
|
10806
|
+
silentMessage = await this.runBeforeCreateMessageHook(state, silentMessage);
|
|
10250
10807
|
await state.storage.sql.exec(
|
|
10251
10808
|
`
|
|
10252
10809
|
INSERT INTO messages (
|
|
@@ -10257,15 +10814,16 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
10257
10814
|
silentMessage.id,
|
|
10258
10815
|
silentMessage.role,
|
|
10259
10816
|
silentMessage.content,
|
|
10260
|
-
|
|
10261
|
-
1,
|
|
10817
|
+
silentMessage.attachments ?? null,
|
|
10818
|
+
silentMessage.silent ? 1 : 0,
|
|
10262
10819
|
silentMessage.created_at,
|
|
10263
|
-
silentMessage.status,
|
|
10820
|
+
silentMessage.status ?? "completed",
|
|
10264
10821
|
silentMessage.parent_id,
|
|
10265
10822
|
silentMessage.depth,
|
|
10266
10823
|
currentPrompt
|
|
10267
10824
|
);
|
|
10268
10825
|
state.messageHistory.push(silentMessage);
|
|
10826
|
+
await this.runAfterCreateMessageHook(state, silentMessage);
|
|
10269
10827
|
if (state.emitMessage) {
|
|
10270
10828
|
state.emitMessage(silentMessage);
|
|
10271
10829
|
}
|
|
@@ -10804,7 +11362,7 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
10804
11362
|
*/
|
|
10805
11363
|
static async loadMessageHistory(state) {
|
|
10806
11364
|
const storage = state.storage;
|
|
10807
|
-
|
|
11365
|
+
state.thread;
|
|
10808
11366
|
const includeParentHistory = state.prompt.include_chat ?? true;
|
|
10809
11367
|
const includeToolCalls = state.prompt.include_past_tools ?? true;
|
|
10810
11368
|
try {
|
|
@@ -10840,8 +11398,11 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
10840
11398
|
rows = cursor.toArray();
|
|
10841
11399
|
}
|
|
10842
11400
|
if (state.extraMessages && state.extraMessages.length > 0) {
|
|
10843
|
-
rows.
|
|
10844
|
-
rows.
|
|
11401
|
+
const persistedIds = new Set(rows.map((row) => row.id));
|
|
11402
|
+
rows.push(
|
|
11403
|
+
...state.extraMessages.filter((entry) => !persistedIds.has(entry.id))
|
|
11404
|
+
);
|
|
11405
|
+
rows.sort((a, b) => a.created_at - b.created_at);
|
|
10845
11406
|
}
|
|
10846
11407
|
const messages = rows.map((row) => ({
|
|
10847
11408
|
id: row.id,
|
|
@@ -10864,43 +11425,77 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
|
|
|
10864
11425
|
reasoning_content: row.reasoning_content,
|
|
10865
11426
|
reasoning_details: row.reasoning_details
|
|
10866
11427
|
}));
|
|
10867
|
-
return
|
|
10868
|
-
thread.instance,
|
|
10869
|
-
state,
|
|
10870
|
-
this.filterOrphanedToolCalls(messages)
|
|
10871
|
-
);
|
|
11428
|
+
return messages;
|
|
10872
11429
|
} catch (error) {
|
|
10873
11430
|
console.error("Error loading message history:", error);
|
|
10874
11431
|
return [];
|
|
10875
11432
|
}
|
|
10876
11433
|
}
|
|
10877
11434
|
/**
|
|
10878
|
-
*
|
|
10879
|
-
*
|
|
10880
|
-
*
|
|
10881
|
-
* @param thread - Thread instance with hooks registry
|
|
10882
|
-
* @param state - Flow state for hook context
|
|
10883
|
-
* @param rows - SQL rows from messages table
|
|
10884
|
-
* @returns Processed rows (or original if hook doesn't exist/fails)
|
|
11435
|
+
* Build request-context rows from persisted history.
|
|
11436
|
+
* Mutations and synthetic messages stay in the request context.
|
|
10885
11437
|
*/
|
|
10886
11438
|
static async runFilterMessagesHook(thread, state, messages) {
|
|
10887
11439
|
const executors = await this.getHooksForType(state, "filter_messages");
|
|
10888
11440
|
if (executors.length === 0) return messages;
|
|
10889
11441
|
let result = messages;
|
|
10890
11442
|
const threadState = ThreadStateImpl.fromFlowState(state);
|
|
10891
|
-
for (const
|
|
11443
|
+
for (const { execute, context } of executors) {
|
|
10892
11444
|
try {
|
|
10893
11445
|
const byId = /* @__PURE__ */ new Map();
|
|
10894
11446
|
for (const row of result) if (row.id) byId.set(row.id, row);
|
|
10895
11447
|
const hookView = result.map((row) => _FlowEngine.rowToHookMessage(row));
|
|
10896
|
-
const kept = await
|
|
10897
|
-
result = kept.map((
|
|
11448
|
+
const kept = await execute(threadState, hookView, context);
|
|
11449
|
+
result = kept.map((hookedMessage) => {
|
|
11450
|
+
const original = hookedMessage.id ? byId.get(hookedMessage.id) : void 0;
|
|
11451
|
+
if (original) {
|
|
11452
|
+
return _FlowEngine.applyHookMessageToRow(original, hookedMessage);
|
|
11453
|
+
}
|
|
11454
|
+
return _FlowEngine.hookMessageToContextRow(hookedMessage);
|
|
11455
|
+
});
|
|
10898
11456
|
} catch (error) {
|
|
10899
11457
|
console.error("[Hooks] \u2717 Error running filter_messages hook:", error);
|
|
10900
11458
|
}
|
|
10901
11459
|
}
|
|
10902
11460
|
return result;
|
|
10903
11461
|
}
|
|
11462
|
+
/**
|
|
11463
|
+
* Copy a persisted row and apply hook edits. The original live-history
|
|
11464
|
+
* object is left unchanged.
|
|
11465
|
+
*/
|
|
11466
|
+
static applyHookMessageToRow(original, hooked) {
|
|
11467
|
+
const attachments = hooked.attachments === void 0 ? original.attachments : hooked.attachments === null ? null : typeof hooked.attachments === "string" ? hooked.attachments : JSON.stringify(hooked.attachments);
|
|
11468
|
+
return {
|
|
11469
|
+
...original,
|
|
11470
|
+
role: hooked.role ?? original.role,
|
|
11471
|
+
content: hooked.content !== void 0 ? hooked.content : original.content,
|
|
11472
|
+
name: hooked.name !== void 0 ? hooked.name : original.name,
|
|
11473
|
+
tool_calls: hooked.tool_calls !== void 0 ? hooked.tool_calls : original.tool_calls,
|
|
11474
|
+
tool_call_id: hooked.tool_call_id !== void 0 ? hooked.tool_call_id : original.tool_call_id,
|
|
11475
|
+
silent: hooked.silent !== void 0 ? hooked.silent : original.silent,
|
|
11476
|
+
attachments
|
|
11477
|
+
};
|
|
11478
|
+
}
|
|
11479
|
+
/**
|
|
11480
|
+
* Convert a synthetic hook message into a request-context-only builder row.
|
|
11481
|
+
*/
|
|
11482
|
+
static hookMessageToContextRow(hooked) {
|
|
11483
|
+
const attachments = hooked.attachments === void 0 || hooked.attachments === null ? hooked.attachments ?? null : typeof hooked.attachments === "string" ? hooked.attachments : JSON.stringify(hooked.attachments);
|
|
11484
|
+
return {
|
|
11485
|
+
id: hooked.id || crypto.randomUUID(),
|
|
11486
|
+
role: hooked.role,
|
|
11487
|
+
content: hooked.content ?? null,
|
|
11488
|
+
name: hooked.name ?? null,
|
|
11489
|
+
tool_calls: typeof hooked.tool_calls === "string" ? hooked.tool_calls : null,
|
|
11490
|
+
tool_call_id: hooked.tool_call_id ?? null,
|
|
11491
|
+
created_at: hooked.created_at ?? Date.now() * TIMESTAMP_MULTIPLIER,
|
|
11492
|
+
parent_id: hooked.parent_id ?? null,
|
|
11493
|
+
depth: hooked.depth ?? 0,
|
|
11494
|
+
silent: hooked.silent ?? false,
|
|
11495
|
+
status: "completed",
|
|
11496
|
+
attachments
|
|
11497
|
+
};
|
|
11498
|
+
}
|
|
10904
11499
|
/**
|
|
10905
11500
|
* Log an error to the logs table (best-effort)
|
|
10906
11501
|
* Creates a log entry with error details but no associated message_id
|
|
@@ -11044,6 +11639,35 @@ ${errorStack}` : ""}`;
|
|
|
11044
11639
|
});
|
|
11045
11640
|
|
|
11046
11641
|
// src/agents/utilities.ts
|
|
11642
|
+
var utilities_exports = {};
|
|
11643
|
+
__export(utilities_exports, {
|
|
11644
|
+
cat: () => cat,
|
|
11645
|
+
emitThreadEvent: () => emitThreadEvent,
|
|
11646
|
+
exists: () => exists,
|
|
11647
|
+
find: () => find,
|
|
11648
|
+
forceTurn: () => forceTurn,
|
|
11649
|
+
getFileStats: () => getFileStats,
|
|
11650
|
+
getMessages: () => getMessages,
|
|
11651
|
+
getThumbnail: () => getThumbnail,
|
|
11652
|
+
grep: () => grep,
|
|
11653
|
+
head: () => head,
|
|
11654
|
+
injectMessage: () => injectMessage,
|
|
11655
|
+
linkFile: () => linkFile,
|
|
11656
|
+
mkdir: () => mkdir,
|
|
11657
|
+
move: () => move,
|
|
11658
|
+
queueTool: () => queueTool,
|
|
11659
|
+
readFile: () => readFile,
|
|
11660
|
+
readdir: () => readdir,
|
|
11661
|
+
reloadHistory: () => reloadHistory,
|
|
11662
|
+
rename: () => rename,
|
|
11663
|
+
rmdir: () => rmdir,
|
|
11664
|
+
stat: () => stat,
|
|
11665
|
+
tail: () => tail,
|
|
11666
|
+
unlink: () => unlink,
|
|
11667
|
+
updateThread: () => updateThread,
|
|
11668
|
+
writeFile: () => writeFile,
|
|
11669
|
+
writeImage: () => writeImage
|
|
11670
|
+
});
|
|
11047
11671
|
function queueTool(flow, toolName, args = {}) {
|
|
11048
11672
|
if (flow.currentToolUses !== void 0) {
|
|
11049
11673
|
if (!flow.currentToolUses.includes(toolName)) {
|
|
@@ -11071,7 +11695,7 @@ async function injectMessage(flow, options) {
|
|
|
11071
11695
|
const timestamp = Date.now() * TIMESTAMP_MULTIPLIER;
|
|
11072
11696
|
const silent = options.silent ?? false;
|
|
11073
11697
|
const forceTopLevel = options.forceTopLevel ?? false;
|
|
11074
|
-
|
|
11698
|
+
let message = {
|
|
11075
11699
|
id: messageId,
|
|
11076
11700
|
role: options.role,
|
|
11077
11701
|
content: options.content,
|
|
@@ -11085,41 +11709,52 @@ async function injectMessage(flow, options) {
|
|
|
11085
11709
|
metadata: options.metadata
|
|
11086
11710
|
};
|
|
11087
11711
|
if (options.beforeMessageId) {
|
|
11088
|
-
const
|
|
11089
|
-
|
|
11090
|
-
options.beforeMessageId
|
|
11712
|
+
const liveTarget = flow.messageHistory.find(
|
|
11713
|
+
(entry) => entry.id === options.beforeMessageId
|
|
11091
11714
|
);
|
|
11092
|
-
|
|
11093
|
-
|
|
11094
|
-
|
|
11095
|
-
|
|
11096
|
-
|
|
11715
|
+
let targetCreatedAt = liveTarget?.created_at;
|
|
11716
|
+
if (targetCreatedAt === void 0) {
|
|
11717
|
+
const cursor = await flow.storage.sql.exec(
|
|
11718
|
+
`SELECT created_at FROM messages WHERE id = ?`,
|
|
11719
|
+
options.beforeMessageId
|
|
11097
11720
|
);
|
|
11721
|
+
const rows = cursor.toArray();
|
|
11722
|
+
const targetMessage = rows[0];
|
|
11723
|
+
if (!targetMessage) {
|
|
11724
|
+
throw new Error(
|
|
11725
|
+
`Message with id ${options.beforeMessageId} not found`
|
|
11726
|
+
);
|
|
11727
|
+
}
|
|
11728
|
+
targetCreatedAt = targetMessage.created_at;
|
|
11098
11729
|
}
|
|
11099
|
-
message.created_at =
|
|
11730
|
+
message.created_at = targetCreatedAt - 1;
|
|
11100
11731
|
}
|
|
11101
11732
|
const currentPrompt = flow.promptPath.length > 0 ? flow.promptPath[flow.promptPath.length - 1] : null;
|
|
11102
|
-
const
|
|
11733
|
+
const { FlowEngine: FlowEngine2 } = await Promise.resolve().then(() => (init_FlowEngine(), FlowEngine_exports));
|
|
11734
|
+
message = await FlowEngine2.runBeforeCreateMessageHook(flow, message, void 0, {
|
|
11735
|
+
propagateHookErrors: true
|
|
11736
|
+
});
|
|
11737
|
+
const metadataJson = message.metadata === void 0 ? null : JSON.stringify(message.metadata);
|
|
11103
11738
|
await flow.storage.sql.exec(
|
|
11104
11739
|
`INSERT INTO messages (id, role, content, name, tool_call_id, created_at, status, silent, parent_id, depth, metadata, prompt) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
11105
|
-
|
|
11740
|
+
message.id,
|
|
11106
11741
|
message.role,
|
|
11107
11742
|
message.content,
|
|
11108
11743
|
message.name,
|
|
11109
11744
|
message.tool_call_id,
|
|
11110
11745
|
message.created_at,
|
|
11111
11746
|
message.status,
|
|
11112
|
-
silent ? 1 : 0,
|
|
11747
|
+
message.silent ? 1 : 0,
|
|
11113
11748
|
message.parent_id,
|
|
11114
11749
|
message.depth,
|
|
11115
11750
|
metadataJson,
|
|
11116
11751
|
currentPrompt
|
|
11117
11752
|
);
|
|
11118
|
-
|
|
11119
|
-
|
|
11120
|
-
|
|
11121
|
-
flow.messageHistory = await reloadHistory(flow);
|
|
11753
|
+
appendLiveExecutionHistory(flow, message, options.beforeMessageId);
|
|
11754
|
+
if (flow.prompt.include_chat === false || message.parent_id !== null || (message.depth ?? 0) > 0) {
|
|
11755
|
+
appendInjectedContextMessage(flow.extraMessages, message);
|
|
11122
11756
|
}
|
|
11757
|
+
await FlowEngine2.runAfterCreateMessageHook(flow, message);
|
|
11123
11758
|
if (flow.emitMessage) {
|
|
11124
11759
|
flow.emitMessage(message);
|
|
11125
11760
|
}
|
|
@@ -11128,6 +11763,42 @@ async function injectMessage(flow, options) {
|
|
|
11128
11763
|
}
|
|
11129
11764
|
return message;
|
|
11130
11765
|
}
|
|
11766
|
+
function appendLiveExecutionHistory(flow, message, beforeMessageId) {
|
|
11767
|
+
const history = flow.messageHistory;
|
|
11768
|
+
const existing = history.findIndex((entry) => entry.id === message.id);
|
|
11769
|
+
if (existing >= 0) {
|
|
11770
|
+
history.splice(existing, 1);
|
|
11771
|
+
}
|
|
11772
|
+
if (beforeMessageId) {
|
|
11773
|
+
const targetIndex = history.findIndex((entry) => entry.id === beforeMessageId);
|
|
11774
|
+
if (targetIndex >= 0) {
|
|
11775
|
+
history.splice(targetIndex, 0, message);
|
|
11776
|
+
return;
|
|
11777
|
+
}
|
|
11778
|
+
}
|
|
11779
|
+
const insertAt = history.findIndex(
|
|
11780
|
+
(entry) => entry.created_at > message.created_at
|
|
11781
|
+
);
|
|
11782
|
+
if (insertAt === -1) {
|
|
11783
|
+
history.push(message);
|
|
11784
|
+
return;
|
|
11785
|
+
}
|
|
11786
|
+
history.splice(insertAt, 0, message);
|
|
11787
|
+
}
|
|
11788
|
+
function appendInjectedContextMessage(extraMessages, message) {
|
|
11789
|
+
const existing = extraMessages.findIndex((entry) => entry.id === message.id);
|
|
11790
|
+
if (existing >= 0) {
|
|
11791
|
+
extraMessages.splice(existing, 1);
|
|
11792
|
+
}
|
|
11793
|
+
const insertAt = extraMessages.findIndex(
|
|
11794
|
+
(entry) => entry.created_at > message.created_at
|
|
11795
|
+
);
|
|
11796
|
+
if (insertAt === -1) {
|
|
11797
|
+
extraMessages.push(message);
|
|
11798
|
+
return;
|
|
11799
|
+
}
|
|
11800
|
+
extraMessages.splice(insertAt, 0, message);
|
|
11801
|
+
}
|
|
11131
11802
|
async function getMessages(flow, limit = 100, offset = 0, order = "asc") {
|
|
11132
11803
|
const orderClause = order === "desc" ? "DESC" : "ASC";
|
|
11133
11804
|
const cursor = await flow.storage.sql.exec(
|
|
@@ -17607,649 +18278,336 @@ var migration48 = {
|
|
|
17607
18278
|
)
|
|
17608
18279
|
`);
|
|
17609
18280
|
sql.exec(`INSERT INTO api_keys SELECT * FROM api_keys_0012_backup`);
|
|
17610
|
-
sql.exec(`CREATE INDEX idx_api_keys_key_hash ON api_keys(key_hash)`);
|
|
17611
|
-
sql.exec(`CREATE INDEX idx_api_keys_user_id ON api_keys(user_id)`);
|
|
17612
|
-
sql.exec(`CREATE INDEX idx_api_keys_key_prefix ON api_keys(key_prefix)`);
|
|
17613
|
-
sql.exec(`CREATE INDEX idx_api_keys_platform_key_id ON api_keys(platform_key_id)`);
|
|
17614
|
-
sql.exec(`CREATE INDEX idx_api_keys_replica_active ON api_keys(replica_active)`);
|
|
17615
|
-
sql.exec(`
|
|
17616
|
-
CREATE TABLE sessions (
|
|
17617
|
-
id TEXT PRIMARY KEY NOT NULL,
|
|
17618
|
-
user_id TEXT NOT NULL,
|
|
17619
|
-
token_hash TEXT NOT NULL,
|
|
17620
|
-
expires_at INTEGER NOT NULL,
|
|
17621
|
-
created_at INTEGER DEFAULT (strftime('%s', 'now')),
|
|
17622
|
-
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
17623
|
-
)
|
|
17624
|
-
`);
|
|
17625
|
-
sql.exec(`INSERT INTO sessions SELECT * FROM sessions_0012_backup`);
|
|
17626
|
-
sql.exec(`CREATE INDEX idx_sessions_token_hash ON sessions(token_hash)`);
|
|
17627
|
-
sql.exec(`CREATE INDEX idx_sessions_user_id ON sessions(user_id)`);
|
|
17628
|
-
sql.exec(`CREATE INDEX idx_sessions_expires_at ON sessions(expires_at)`);
|
|
17629
|
-
sql.exec(`DROP TABLE oauth_accounts_0012_backup`);
|
|
17630
|
-
sql.exec(`DROP TABLE api_keys_0012_backup`);
|
|
17631
|
-
sql.exec(`DROP TABLE sessions_0012_backup`);
|
|
17632
|
-
sql.exec(`
|
|
17633
|
-
INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '12')
|
|
17634
|
-
`);
|
|
17635
|
-
}
|
|
17636
|
-
};
|
|
17637
|
-
|
|
17638
|
-
// src/durable-objects/agentbuilder-migrations/0013_add_thread_activity.ts
|
|
17639
|
-
var migration49 = {
|
|
17640
|
-
version: 13,
|
|
17641
|
-
async up(sql) {
|
|
17642
|
-
sql.exec(`ALTER TABLE threads ADD COLUMN last_activity_at INTEGER`);
|
|
17643
|
-
sql.exec(`ALTER TABLE threads ADD COLUMN executing_since INTEGER`);
|
|
17644
|
-
sql.exec(
|
|
17645
|
-
`CREATE INDEX IF NOT EXISTS idx_threads_last_activity_at ON threads(last_activity_at)`
|
|
17646
|
-
);
|
|
17647
|
-
sql.exec(`UPDATE threads SET last_activity_at = created_at`);
|
|
17648
|
-
sql.exec(`
|
|
17649
|
-
INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '13')
|
|
17650
|
-
`);
|
|
17651
|
-
}
|
|
17652
|
-
};
|
|
17653
|
-
|
|
17654
|
-
// src/durable-objects/agentbuilder-migrations/0014_thread_activity_scale.ts
|
|
17655
|
-
var migration50 = {
|
|
17656
|
-
version: 14,
|
|
17657
|
-
async up(sql) {
|
|
17658
|
-
sql.exec(`ALTER TABLE threads ADD COLUMN last_message_preview TEXT`);
|
|
17659
|
-
sql.exec(
|
|
17660
|
-
`CREATE INDEX IF NOT EXISTS idx_threads_executing_since
|
|
17661
|
-
ON threads(executing_since) WHERE executing_since IS NOT NULL`
|
|
17662
|
-
);
|
|
17663
|
-
sql.exec(
|
|
17664
|
-
`UPDATE threads SET last_activity_at = created_at WHERE last_activity_at IS NULL`
|
|
17665
|
-
);
|
|
17666
|
-
sql.exec(`
|
|
17667
|
-
INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '14')
|
|
17668
|
-
`);
|
|
17669
|
-
}
|
|
17670
|
-
};
|
|
17671
|
-
|
|
17672
|
-
// src/durable-objects/agentbuilder-migrations/0015_clear_envelope_previews.ts
|
|
17673
|
-
var migration51 = {
|
|
17674
|
-
version: 15,
|
|
17675
|
-
async up(sql) {
|
|
17676
|
-
sql.exec(
|
|
17677
|
-
`UPDATE threads SET last_message_preview = NULL
|
|
17678
|
-
WHERE last_message_preview LIKE 'Subagent (reference: %'`
|
|
17679
|
-
);
|
|
17680
|
-
sql.exec(`
|
|
17681
|
-
INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '15')
|
|
17682
|
-
`);
|
|
17683
|
-
}
|
|
17684
|
-
};
|
|
17685
|
-
|
|
17686
|
-
// src/durable-objects/agentbuilder-migrations/0016_add_origin_agent.ts
|
|
17687
|
-
var migration52 = {
|
|
17688
|
-
version: 16,
|
|
17689
|
-
async up(sql) {
|
|
17690
|
-
sql.exec(`ALTER TABLE threads ADD COLUMN origin_agent_name TEXT`);
|
|
17691
|
-
sql.exec(
|
|
17692
|
-
`CREATE INDEX IF NOT EXISTS idx_threads_origin_agent_name ON threads(origin_agent_name)`
|
|
17693
|
-
);
|
|
17694
|
-
sql.exec(`UPDATE threads SET origin_agent_name = agent_name`);
|
|
17695
|
-
sql.exec(`
|
|
17696
|
-
INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '16')
|
|
17697
|
-
`);
|
|
17698
|
-
}
|
|
17699
|
-
};
|
|
17700
|
-
|
|
17701
|
-
// src/durable-objects/agentbuilder-migrations/0017_add_thread_message_recency.ts
|
|
17702
|
-
var migration53 = {
|
|
17703
|
-
version: 17,
|
|
17704
|
-
async up(sql) {
|
|
17705
|
-
sql.exec(`ALTER TABLE threads ADD COLUMN last_message_at INTEGER`);
|
|
17706
|
-
sql.exec(`UPDATE threads SET last_message_at = created_at`);
|
|
17707
|
-
sql.exec(`
|
|
17708
|
-
INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '17')
|
|
17709
|
-
`);
|
|
17710
|
-
}
|
|
17711
|
-
};
|
|
17712
|
-
|
|
17713
|
-
// src/durable-objects/agentbuilder-migrations/0018_auth_security.ts
|
|
17714
|
-
var migration54 = {
|
|
17715
|
-
version: 18,
|
|
17716
|
-
async up(sql) {
|
|
17717
|
-
sql.exec(`
|
|
17718
|
-
CREATE TABLE IF NOT EXISTS super_admin_sessions (
|
|
17719
|
-
token_hash TEXT PRIMARY KEY,
|
|
17720
|
-
created_at INTEGER NOT NULL,
|
|
17721
|
-
expires_at INTEGER NOT NULL
|
|
17722
|
-
)
|
|
17723
|
-
`);
|
|
17724
|
-
sql.exec(`
|
|
17725
|
-
CREATE INDEX IF NOT EXISTS idx_super_admin_sessions_expires
|
|
17726
|
-
ON super_admin_sessions(expires_at)
|
|
17727
|
-
`);
|
|
17728
|
-
sql.exec(`
|
|
17729
|
-
CREATE TABLE IF NOT EXISTS auth_rate_limits (
|
|
17730
|
-
bucket_key TEXT PRIMARY KEY,
|
|
17731
|
-
attempts INTEGER NOT NULL,
|
|
17732
|
-
reset_at INTEGER NOT NULL
|
|
17733
|
-
)
|
|
17734
|
-
`);
|
|
17735
|
-
sql.exec(`
|
|
17736
|
-
CREATE INDEX IF NOT EXISTS idx_auth_rate_limits_reset
|
|
17737
|
-
ON auth_rate_limits(reset_at)
|
|
17738
|
-
`);
|
|
17739
|
-
sql.exec(`
|
|
17740
|
-
INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '18')
|
|
17741
|
-
`);
|
|
17742
|
-
}
|
|
17743
|
-
};
|
|
17744
|
-
|
|
17745
|
-
// src/durable-objects/agentbuilder-migrations/0019_scope_skills.ts
|
|
17746
|
-
var migration55 = {
|
|
17747
|
-
version: 19,
|
|
17748
|
-
async up(sql) {
|
|
17749
|
-
sql.exec(`
|
|
17750
|
-
CREATE TABLE skills_0019 (
|
|
17751
|
-
owner_id TEXT NOT NULL,
|
|
17752
|
-
name TEXT NOT NULL,
|
|
17753
|
-
description TEXT NOT NULL,
|
|
17754
|
-
version TEXT,
|
|
17755
|
-
enabled INTEGER NOT NULL DEFAULT 1,
|
|
17756
|
-
shared INTEGER NOT NULL DEFAULT 0,
|
|
17757
|
-
created_at INTEGER DEFAULT (strftime('%s', 'now')),
|
|
17758
|
-
updated_at INTEGER DEFAULT (strftime('%s', 'now')),
|
|
17759
|
-
PRIMARY KEY (owner_id, name)
|
|
17760
|
-
)
|
|
17761
|
-
`);
|
|
17762
|
-
sql.exec(`
|
|
17763
|
-
INSERT INTO skills_0019 (
|
|
17764
|
-
owner_id, name, description, version, enabled, shared, created_at, updated_at
|
|
17765
|
-
)
|
|
17766
|
-
SELECT '__instance_shared__', name, description, version, enabled, 1, created_at, updated_at
|
|
17767
|
-
FROM skills
|
|
17768
|
-
`);
|
|
17769
|
-
sql.exec(`
|
|
17770
|
-
CREATE TABLE skill_files_0019 (
|
|
17771
|
-
owner_id TEXT NOT NULL,
|
|
17772
|
-
skill_name TEXT NOT NULL,
|
|
17773
|
-
path TEXT NOT NULL,
|
|
17774
|
-
content TEXT NOT NULL,
|
|
17775
|
-
size INTEGER NOT NULL,
|
|
17776
|
-
PRIMARY KEY (owner_id, skill_name, path),
|
|
17777
|
-
FOREIGN KEY (owner_id, skill_name) REFERENCES skills_0019(owner_id, name) ON DELETE CASCADE
|
|
17778
|
-
)
|
|
17779
|
-
`);
|
|
17780
|
-
sql.exec(`
|
|
17781
|
-
INSERT INTO skill_files_0019 (owner_id, skill_name, path, content, size)
|
|
17782
|
-
SELECT '__instance_shared__', skill_name, path, content, size FROM skill_files
|
|
17783
|
-
`);
|
|
17784
|
-
sql.exec(`DROP TABLE skill_files`);
|
|
17785
|
-
sql.exec(`DROP TABLE skills`);
|
|
17786
|
-
sql.exec(`ALTER TABLE skills_0019 RENAME TO skills`);
|
|
17787
|
-
sql.exec(`ALTER TABLE skill_files_0019 RENAME TO skill_files`);
|
|
17788
|
-
sql.exec(`CREATE INDEX idx_skills_owner_enabled ON skills(owner_id, enabled)`);
|
|
17789
|
-
sql.exec(`CREATE INDEX idx_skills_shared_enabled ON skills(shared, enabled)`);
|
|
17790
|
-
sql.exec(`CREATE INDEX idx_skill_files_skill ON skill_files(owner_id, skill_name)`);
|
|
17791
|
-
sql.exec(`INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '19')`);
|
|
17792
|
-
}
|
|
17793
|
-
};
|
|
17794
|
-
|
|
17795
|
-
// src/durable-objects/agentbuilder-migrations/0020_websocket_tickets.ts
|
|
17796
|
-
var migration56 = {
|
|
17797
|
-
version: 20,
|
|
17798
|
-
async up(sql) {
|
|
17799
|
-
sql.exec(`
|
|
17800
|
-
CREATE TABLE websocket_tickets (
|
|
17801
|
-
ticket_hash TEXT PRIMARY KEY,
|
|
17802
|
-
pathname TEXT NOT NULL,
|
|
17803
|
-
auth_json TEXT NOT NULL,
|
|
17804
|
-
created_at INTEGER NOT NULL,
|
|
17805
|
-
expires_at INTEGER NOT NULL
|
|
17806
|
-
)
|
|
17807
|
-
`);
|
|
17808
|
-
sql.exec(`
|
|
17809
|
-
CREATE INDEX idx_websocket_tickets_expires
|
|
17810
|
-
ON websocket_tickets(expires_at)
|
|
17811
|
-
`);
|
|
17812
|
-
sql.exec(`INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '20')`);
|
|
17813
|
-
}
|
|
17814
|
-
};
|
|
17815
|
-
|
|
17816
|
-
// src/durable-objects/agentbuilder-migrations/0021_platform_handoff_jtis.ts
|
|
17817
|
-
var migration57 = {
|
|
17818
|
-
version: 21,
|
|
17819
|
-
async up(sql) {
|
|
18281
|
+
sql.exec(`CREATE INDEX idx_api_keys_key_hash ON api_keys(key_hash)`);
|
|
18282
|
+
sql.exec(`CREATE INDEX idx_api_keys_user_id ON api_keys(user_id)`);
|
|
18283
|
+
sql.exec(`CREATE INDEX idx_api_keys_key_prefix ON api_keys(key_prefix)`);
|
|
18284
|
+
sql.exec(`CREATE INDEX idx_api_keys_platform_key_id ON api_keys(platform_key_id)`);
|
|
18285
|
+
sql.exec(`CREATE INDEX idx_api_keys_replica_active ON api_keys(replica_active)`);
|
|
17820
18286
|
sql.exec(`
|
|
17821
|
-
CREATE TABLE
|
|
17822
|
-
|
|
17823
|
-
|
|
17824
|
-
|
|
18287
|
+
CREATE TABLE sessions (
|
|
18288
|
+
id TEXT PRIMARY KEY NOT NULL,
|
|
18289
|
+
user_id TEXT NOT NULL,
|
|
18290
|
+
token_hash TEXT NOT NULL,
|
|
18291
|
+
expires_at INTEGER NOT NULL,
|
|
18292
|
+
created_at INTEGER DEFAULT (strftime('%s', 'now')),
|
|
18293
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
17825
18294
|
)
|
|
17826
18295
|
`);
|
|
18296
|
+
sql.exec(`INSERT INTO sessions SELECT * FROM sessions_0012_backup`);
|
|
18297
|
+
sql.exec(`CREATE INDEX idx_sessions_token_hash ON sessions(token_hash)`);
|
|
18298
|
+
sql.exec(`CREATE INDEX idx_sessions_user_id ON sessions(user_id)`);
|
|
18299
|
+
sql.exec(`CREATE INDEX idx_sessions_expires_at ON sessions(expires_at)`);
|
|
18300
|
+
sql.exec(`DROP TABLE oauth_accounts_0012_backup`);
|
|
18301
|
+
sql.exec(`DROP TABLE api_keys_0012_backup`);
|
|
18302
|
+
sql.exec(`DROP TABLE sessions_0012_backup`);
|
|
17827
18303
|
sql.exec(`
|
|
17828
|
-
|
|
17829
|
-
ON platform_handoff_jtis(expires_at)
|
|
18304
|
+
INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '12')
|
|
17830
18305
|
`);
|
|
17831
|
-
sql.exec(`INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '21')`);
|
|
17832
|
-
}
|
|
17833
|
-
};
|
|
17834
|
-
|
|
17835
|
-
// src/durable-objects/agentbuilder-migrations/index.ts
|
|
17836
|
-
var migrations2 = [migration37, migration38, migration39, migration40, migration41, migration42, migration43, migration44, migration45, migration46, migration47, migration48, migration49, migration50, migration51, migration52, migration53, migration54, migration55, migration56, migration57];
|
|
17837
|
-
var LATEST_SCHEMA_VERSION2 = migrations2.reduce(
|
|
17838
|
-
(max, migration58) => Math.max(max, migration58.version),
|
|
17839
|
-
0
|
|
17840
|
-
);
|
|
17841
|
-
|
|
17842
|
-
// src/utils/crypto.ts
|
|
17843
|
-
var CryptoUtil = class {
|
|
17844
|
-
static algorithm = "aes-256-gcm";
|
|
17845
|
-
/**
|
|
17846
|
-
* Encrypt a string value
|
|
17847
|
-
*/
|
|
17848
|
-
static async encrypt(text, key) {
|
|
17849
|
-
const encoder = new TextEncoder();
|
|
17850
|
-
const data = encoder.encode(text);
|
|
17851
|
-
const cryptoKey = await crypto.subtle.importKey(
|
|
17852
|
-
"raw",
|
|
17853
|
-
hexToBuffer(key),
|
|
17854
|
-
{ name: "AES-GCM" },
|
|
17855
|
-
false,
|
|
17856
|
-
["encrypt"]
|
|
17857
|
-
);
|
|
17858
|
-
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
17859
|
-
const encrypted = await crypto.subtle.encrypt(
|
|
17860
|
-
{
|
|
17861
|
-
name: "AES-GCM",
|
|
17862
|
-
iv
|
|
17863
|
-
},
|
|
17864
|
-
cryptoKey,
|
|
17865
|
-
data
|
|
17866
|
-
);
|
|
17867
|
-
const combined = new Uint8Array(iv.length + encrypted.byteLength);
|
|
17868
|
-
combined.set(iv);
|
|
17869
|
-
combined.set(new Uint8Array(encrypted), iv.length);
|
|
17870
|
-
return bufferToBase64(combined);
|
|
17871
|
-
}
|
|
17872
|
-
/**
|
|
17873
|
-
* Decrypt a string value
|
|
17874
|
-
*/
|
|
17875
|
-
static async decrypt(encryptedText, key) {
|
|
17876
|
-
const combined = base64ToBuffer2(encryptedText);
|
|
17877
|
-
const iv = combined.slice(0, 12);
|
|
17878
|
-
const encrypted = combined.slice(12);
|
|
17879
|
-
const cryptoKey = await crypto.subtle.importKey(
|
|
17880
|
-
"raw",
|
|
17881
|
-
hexToBuffer(key),
|
|
17882
|
-
{ name: "AES-GCM" },
|
|
17883
|
-
false,
|
|
17884
|
-
["decrypt"]
|
|
17885
|
-
);
|
|
17886
|
-
const decrypted = await crypto.subtle.decrypt(
|
|
17887
|
-
{
|
|
17888
|
-
name: "AES-GCM",
|
|
17889
|
-
iv
|
|
17890
|
-
},
|
|
17891
|
-
cryptoKey,
|
|
17892
|
-
encrypted
|
|
17893
|
-
);
|
|
17894
|
-
const decoder = new TextDecoder();
|
|
17895
|
-
return decoder.decode(decrypted);
|
|
17896
18306
|
}
|
|
17897
18307
|
};
|
|
17898
|
-
function hexToBuffer(hex) {
|
|
17899
|
-
const bytes = new Uint8Array(hex.length / 2);
|
|
17900
|
-
for (let i = 0; i < hex.length; i += 2) {
|
|
17901
|
-
bytes[i / 2] = parseInt(hex.substr(i, 2), 16);
|
|
17902
|
-
}
|
|
17903
|
-
return bytes;
|
|
17904
|
-
}
|
|
17905
|
-
function bufferToBase64(buffer) {
|
|
17906
|
-
let binary = "";
|
|
17907
|
-
for (let i = 0; i < buffer.byteLength; i++) {
|
|
17908
|
-
binary += String.fromCharCode(buffer[i]);
|
|
17909
|
-
}
|
|
17910
|
-
return btoa(binary);
|
|
17911
|
-
}
|
|
17912
|
-
function base64ToBuffer2(base64) {
|
|
17913
|
-
const binary = atob(base64);
|
|
17914
|
-
const bytes = new Uint8Array(binary.length);
|
|
17915
|
-
for (let i = 0; i < binary.length; i++) {
|
|
17916
|
-
bytes[i] = binary.charCodeAt(i);
|
|
17917
|
-
}
|
|
17918
|
-
return bytes;
|
|
17919
|
-
}
|
|
17920
|
-
async function encryptEnvs(env, encryptionKey) {
|
|
17921
|
-
const plaintext = JSON.stringify(env);
|
|
17922
|
-
return CryptoUtil.encrypt(plaintext, encryptionKey);
|
|
17923
|
-
}
|
|
17924
|
-
async function decryptEnvs(encrypted, encryptionKey) {
|
|
17925
|
-
const plaintext = await CryptoUtil.decrypt(encrypted, encryptionKey);
|
|
17926
|
-
const parsed = JSON.parse(plaintext);
|
|
17927
|
-
if (!parsed || typeof parsed !== "object") {
|
|
17928
|
-
return {};
|
|
17929
|
-
}
|
|
17930
|
-
const result = {};
|
|
17931
|
-
for (const [key, value] of Object.entries(parsed)) {
|
|
17932
|
-
if (value === void 0 || value === null) continue;
|
|
17933
|
-
result[key] = String(value);
|
|
17934
|
-
}
|
|
17935
|
-
return result;
|
|
17936
|
-
}
|
|
17937
18308
|
|
|
17938
|
-
// src/
|
|
17939
|
-
var
|
|
17940
|
-
|
|
17941
|
-
|
|
17942
|
-
|
|
17943
|
-
|
|
17944
|
-
|
|
17945
|
-
|
|
17946
|
-
}
|
|
17947
|
-
};
|
|
17948
|
-
function parseQualifiedName(name) {
|
|
17949
|
-
if (name.startsWith("@")) {
|
|
17950
|
-
const firstSlash = name.indexOf("/");
|
|
17951
|
-
if (firstSlash === -1) {
|
|
17952
|
-
return [null, name];
|
|
17953
|
-
}
|
|
17954
|
-
const secondSlash = name.indexOf("/", firstSlash + 1);
|
|
17955
|
-
if (secondSlash === -1) {
|
|
17956
|
-
return [null, name];
|
|
17957
|
-
}
|
|
17958
|
-
return [name.substring(0, secondSlash), name.substring(secondSlash + 1)];
|
|
17959
|
-
}
|
|
17960
|
-
const separatorIndex = name.indexOf("/");
|
|
17961
|
-
if (separatorIndex === -1) {
|
|
17962
|
-
return [null, name];
|
|
17963
|
-
}
|
|
17964
|
-
return [name.substring(0, separatorIndex), name.substring(separatorIndex + 1)];
|
|
17965
|
-
}
|
|
17966
|
-
function qualifyName(packageId, shortName) {
|
|
17967
|
-
return `${packageId}/${shortName}`;
|
|
17968
|
-
}
|
|
17969
|
-
function getShortName(name) {
|
|
17970
|
-
const [, shortName] = parseQualifiedName(name);
|
|
17971
|
-
return shortName;
|
|
17972
|
-
}
|
|
17973
|
-
function resolveTool(registry, name, namespace) {
|
|
17974
|
-
const [pkgId, shortName] = parseQualifiedName(name);
|
|
17975
|
-
if (pkgId !== null) {
|
|
17976
|
-
const pkg = registry.packages[pkgId];
|
|
17977
|
-
if (!pkg) {
|
|
17978
|
-
throw new NamespaceResolutionError(
|
|
17979
|
-
"tool",
|
|
17980
|
-
name,
|
|
17981
|
-
namespace,
|
|
17982
|
-
`Package "${pkgId}" not found`
|
|
17983
|
-
);
|
|
17984
|
-
}
|
|
17985
|
-
throw new NamespaceResolutionError(
|
|
17986
|
-
"tool",
|
|
17987
|
-
name,
|
|
17988
|
-
namespace,
|
|
17989
|
-
`Cannot access tool "${shortName}" from package "${pkgId}". Only entry point agents are accessible cross-package.`
|
|
17990
|
-
);
|
|
17991
|
-
}
|
|
17992
|
-
if (namespace.type === "packed") {
|
|
17993
|
-
const pkg = registry.packages[namespace.packageId];
|
|
17994
|
-
if (!pkg) {
|
|
17995
|
-
throw new NamespaceResolutionError(
|
|
17996
|
-
"tool",
|
|
17997
|
-
name,
|
|
17998
|
-
namespace,
|
|
17999
|
-
`Package "${namespace.packageId}" not found`
|
|
18000
|
-
);
|
|
18001
|
-
}
|
|
18002
|
-
const loader2 = pkg.tools[shortName];
|
|
18003
|
-
if (!loader2) {
|
|
18004
|
-
throw new NamespaceResolutionError(
|
|
18005
|
-
"tool",
|
|
18006
|
-
name,
|
|
18007
|
-
namespace,
|
|
18008
|
-
`Tool "${shortName}" not found in package "${namespace.packageId}"`
|
|
18009
|
-
);
|
|
18010
|
-
}
|
|
18011
|
-
return loader2;
|
|
18012
|
-
}
|
|
18013
|
-
const loader = registry.global.tools[shortName];
|
|
18014
|
-
if (!loader) {
|
|
18015
|
-
throw new NamespaceResolutionError(
|
|
18016
|
-
"tool",
|
|
18017
|
-
name,
|
|
18018
|
-
namespace,
|
|
18019
|
-
`Tool "${shortName}" not found in global namespace`
|
|
18020
|
-
);
|
|
18021
|
-
}
|
|
18022
|
-
return loader;
|
|
18023
|
-
}
|
|
18024
|
-
function resolvePrompt(registry, name, namespace) {
|
|
18025
|
-
const [pkgId, shortName] = parseQualifiedName(name);
|
|
18026
|
-
if (pkgId !== null) {
|
|
18027
|
-
throw new NamespaceResolutionError(
|
|
18028
|
-
"prompt",
|
|
18029
|
-
name,
|
|
18030
|
-
namespace,
|
|
18031
|
-
`Cannot access prompt "${shortName}" from package "${pkgId}". Prompts are package-internal.`
|
|
18032
|
-
);
|
|
18033
|
-
}
|
|
18034
|
-
if (namespace.type === "packed") {
|
|
18035
|
-
const pkg = registry.packages[namespace.packageId];
|
|
18036
|
-
if (!pkg) {
|
|
18037
|
-
throw new NamespaceResolutionError(
|
|
18038
|
-
"prompt",
|
|
18039
|
-
name,
|
|
18040
|
-
namespace,
|
|
18041
|
-
`Package "${namespace.packageId}" not found`
|
|
18042
|
-
);
|
|
18043
|
-
}
|
|
18044
|
-
const loader2 = pkg.prompts[shortName];
|
|
18045
|
-
if (!loader2) {
|
|
18046
|
-
throw new NamespaceResolutionError(
|
|
18047
|
-
"prompt",
|
|
18048
|
-
name,
|
|
18049
|
-
namespace,
|
|
18050
|
-
`Prompt "${shortName}" not found in package "${namespace.packageId}"`
|
|
18051
|
-
);
|
|
18052
|
-
}
|
|
18053
|
-
return loader2;
|
|
18054
|
-
}
|
|
18055
|
-
const loader = registry.global.prompts[shortName];
|
|
18056
|
-
if (!loader) {
|
|
18057
|
-
throw new NamespaceResolutionError(
|
|
18058
|
-
"prompt",
|
|
18059
|
-
name,
|
|
18060
|
-
namespace,
|
|
18061
|
-
`Prompt "${shortName}" not found in global namespace`
|
|
18309
|
+
// src/durable-objects/agentbuilder-migrations/0013_add_thread_activity.ts
|
|
18310
|
+
var migration49 = {
|
|
18311
|
+
version: 13,
|
|
18312
|
+
async up(sql) {
|
|
18313
|
+
sql.exec(`ALTER TABLE threads ADD COLUMN last_activity_at INTEGER`);
|
|
18314
|
+
sql.exec(`ALTER TABLE threads ADD COLUMN executing_since INTEGER`);
|
|
18315
|
+
sql.exec(
|
|
18316
|
+
`CREATE INDEX IF NOT EXISTS idx_threads_last_activity_at ON threads(last_activity_at)`
|
|
18062
18317
|
);
|
|
18318
|
+
sql.exec(`UPDATE threads SET last_activity_at = created_at`);
|
|
18319
|
+
sql.exec(`
|
|
18320
|
+
INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '13')
|
|
18321
|
+
`);
|
|
18063
18322
|
}
|
|
18064
|
-
|
|
18065
|
-
|
|
18066
|
-
|
|
18067
|
-
|
|
18068
|
-
|
|
18069
|
-
|
|
18070
|
-
|
|
18071
|
-
|
|
18072
|
-
|
|
18073
|
-
|
|
18323
|
+
};
|
|
18324
|
+
|
|
18325
|
+
// src/durable-objects/agentbuilder-migrations/0014_thread_activity_scale.ts
|
|
18326
|
+
var migration50 = {
|
|
18327
|
+
version: 14,
|
|
18328
|
+
async up(sql) {
|
|
18329
|
+
sql.exec(`ALTER TABLE threads ADD COLUMN last_message_preview TEXT`);
|
|
18330
|
+
sql.exec(
|
|
18331
|
+
`CREATE INDEX IF NOT EXISTS idx_threads_executing_since
|
|
18332
|
+
ON threads(executing_since) WHERE executing_since IS NOT NULL`
|
|
18333
|
+
);
|
|
18334
|
+
sql.exec(
|
|
18335
|
+
`UPDATE threads SET last_activity_at = created_at WHERE last_activity_at IS NULL`
|
|
18074
18336
|
);
|
|
18337
|
+
sql.exec(`
|
|
18338
|
+
INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '14')
|
|
18339
|
+
`);
|
|
18075
18340
|
}
|
|
18076
|
-
|
|
18077
|
-
|
|
18078
|
-
|
|
18079
|
-
|
|
18080
|
-
|
|
18081
|
-
|
|
18082
|
-
|
|
18083
|
-
|
|
18084
|
-
|
|
18085
|
-
const globalLoader = registry.global.models[lookupName];
|
|
18086
|
-
if (globalLoader) {
|
|
18087
|
-
return globalLoader;
|
|
18088
|
-
}
|
|
18089
|
-
throw new NamespaceResolutionError(
|
|
18090
|
-
"model",
|
|
18091
|
-
name,
|
|
18092
|
-
namespace,
|
|
18093
|
-
`Model "${lookupName}" not found in package "${namespace.packageId}" or global namespace`
|
|
18341
|
+
};
|
|
18342
|
+
|
|
18343
|
+
// src/durable-objects/agentbuilder-migrations/0015_clear_envelope_previews.ts
|
|
18344
|
+
var migration51 = {
|
|
18345
|
+
version: 15,
|
|
18346
|
+
async up(sql) {
|
|
18347
|
+
sql.exec(
|
|
18348
|
+
`UPDATE threads SET last_message_preview = NULL
|
|
18349
|
+
WHERE last_message_preview LIKE 'Subagent (reference: %'`
|
|
18094
18350
|
);
|
|
18351
|
+
sql.exec(`
|
|
18352
|
+
INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '15')
|
|
18353
|
+
`);
|
|
18095
18354
|
}
|
|
18096
|
-
|
|
18097
|
-
|
|
18098
|
-
|
|
18099
|
-
|
|
18100
|
-
|
|
18101
|
-
|
|
18102
|
-
|
|
18355
|
+
};
|
|
18356
|
+
|
|
18357
|
+
// src/durable-objects/agentbuilder-migrations/0016_add_origin_agent.ts
|
|
18358
|
+
var migration52 = {
|
|
18359
|
+
version: 16,
|
|
18360
|
+
async up(sql) {
|
|
18361
|
+
sql.exec(`ALTER TABLE threads ADD COLUMN origin_agent_name TEXT`);
|
|
18362
|
+
sql.exec(
|
|
18363
|
+
`CREATE INDEX IF NOT EXISTS idx_threads_origin_agent_name ON threads(origin_agent_name)`
|
|
18103
18364
|
);
|
|
18365
|
+
sql.exec(`UPDATE threads SET origin_agent_name = agent_name`);
|
|
18366
|
+
sql.exec(`
|
|
18367
|
+
INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '16')
|
|
18368
|
+
`);
|
|
18104
18369
|
}
|
|
18105
|
-
|
|
18106
|
-
|
|
18107
|
-
|
|
18108
|
-
|
|
18109
|
-
|
|
18110
|
-
|
|
18111
|
-
|
|
18112
|
-
|
|
18113
|
-
|
|
18114
|
-
|
|
18115
|
-
|
|
18116
|
-
`Package "${pkgId}" not found`
|
|
18117
|
-
);
|
|
18118
|
-
}
|
|
18119
|
-
if (!pkg.entryAgents.includes(shortName)) {
|
|
18120
|
-
throw new NamespaceResolutionError(
|
|
18121
|
-
"agent",
|
|
18122
|
-
name,
|
|
18123
|
-
namespace,
|
|
18124
|
-
`Agent "${shortName}" is not an entry point in package "${pkgId}"`
|
|
18125
|
-
);
|
|
18126
|
-
}
|
|
18127
|
-
const loader = pkg.agents[shortName];
|
|
18128
|
-
if (!loader) {
|
|
18129
|
-
throw new NamespaceResolutionError(
|
|
18130
|
-
"agent",
|
|
18131
|
-
name,
|
|
18132
|
-
namespace,
|
|
18133
|
-
`Agent "${shortName}" not found in package "${pkgId}"`
|
|
18134
|
-
);
|
|
18135
|
-
}
|
|
18136
|
-
return loader;
|
|
18370
|
+
};
|
|
18371
|
+
|
|
18372
|
+
// src/durable-objects/agentbuilder-migrations/0017_add_thread_message_recency.ts
|
|
18373
|
+
var migration53 = {
|
|
18374
|
+
version: 17,
|
|
18375
|
+
async up(sql) {
|
|
18376
|
+
sql.exec(`ALTER TABLE threads ADD COLUMN last_message_at INTEGER`);
|
|
18377
|
+
sql.exec(`UPDATE threads SET last_message_at = created_at`);
|
|
18378
|
+
sql.exec(`
|
|
18379
|
+
INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '17')
|
|
18380
|
+
`);
|
|
18137
18381
|
}
|
|
18138
|
-
|
|
18139
|
-
|
|
18140
|
-
|
|
18141
|
-
|
|
18142
|
-
|
|
18143
|
-
|
|
18144
|
-
|
|
18145
|
-
|
|
18146
|
-
|
|
18147
|
-
|
|
18148
|
-
|
|
18149
|
-
|
|
18150
|
-
|
|
18151
|
-
|
|
18152
|
-
|
|
18153
|
-
|
|
18154
|
-
|
|
18155
|
-
|
|
18156
|
-
|
|
18157
|
-
|
|
18382
|
+
};
|
|
18383
|
+
|
|
18384
|
+
// src/durable-objects/agentbuilder-migrations/0018_auth_security.ts
|
|
18385
|
+
var migration54 = {
|
|
18386
|
+
version: 18,
|
|
18387
|
+
async up(sql) {
|
|
18388
|
+
sql.exec(`
|
|
18389
|
+
CREATE TABLE IF NOT EXISTS super_admin_sessions (
|
|
18390
|
+
token_hash TEXT PRIMARY KEY,
|
|
18391
|
+
created_at INTEGER NOT NULL,
|
|
18392
|
+
expires_at INTEGER NOT NULL
|
|
18393
|
+
)
|
|
18394
|
+
`);
|
|
18395
|
+
sql.exec(`
|
|
18396
|
+
CREATE INDEX IF NOT EXISTS idx_super_admin_sessions_expires
|
|
18397
|
+
ON super_admin_sessions(expires_at)
|
|
18398
|
+
`);
|
|
18399
|
+
sql.exec(`
|
|
18400
|
+
CREATE TABLE IF NOT EXISTS auth_rate_limits (
|
|
18401
|
+
bucket_key TEXT PRIMARY KEY,
|
|
18402
|
+
attempts INTEGER NOT NULL,
|
|
18403
|
+
reset_at INTEGER NOT NULL
|
|
18404
|
+
)
|
|
18405
|
+
`);
|
|
18406
|
+
sql.exec(`
|
|
18407
|
+
CREATE INDEX IF NOT EXISTS idx_auth_rate_limits_reset
|
|
18408
|
+
ON auth_rate_limits(reset_at)
|
|
18409
|
+
`);
|
|
18410
|
+
sql.exec(`
|
|
18411
|
+
INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '18')
|
|
18412
|
+
`);
|
|
18158
18413
|
}
|
|
18159
|
-
|
|
18160
|
-
|
|
18161
|
-
|
|
18414
|
+
};
|
|
18415
|
+
|
|
18416
|
+
// src/durable-objects/agentbuilder-migrations/0019_scope_skills.ts
|
|
18417
|
+
var migration55 = {
|
|
18418
|
+
version: 19,
|
|
18419
|
+
async up(sql) {
|
|
18420
|
+
sql.exec(`
|
|
18421
|
+
CREATE TABLE skills_0019 (
|
|
18422
|
+
owner_id TEXT NOT NULL,
|
|
18423
|
+
name TEXT NOT NULL,
|
|
18424
|
+
description TEXT NOT NULL,
|
|
18425
|
+
version TEXT,
|
|
18426
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
18427
|
+
shared INTEGER NOT NULL DEFAULT 0,
|
|
18428
|
+
created_at INTEGER DEFAULT (strftime('%s', 'now')),
|
|
18429
|
+
updated_at INTEGER DEFAULT (strftime('%s', 'now')),
|
|
18430
|
+
PRIMARY KEY (owner_id, name)
|
|
18431
|
+
)
|
|
18432
|
+
`);
|
|
18433
|
+
sql.exec(`
|
|
18434
|
+
INSERT INTO skills_0019 (
|
|
18435
|
+
owner_id, name, description, version, enabled, shared, created_at, updated_at
|
|
18436
|
+
)
|
|
18437
|
+
SELECT '__instance_shared__', name, description, version, enabled, 1, created_at, updated_at
|
|
18438
|
+
FROM skills
|
|
18439
|
+
`);
|
|
18440
|
+
sql.exec(`
|
|
18441
|
+
CREATE TABLE skill_files_0019 (
|
|
18442
|
+
owner_id TEXT NOT NULL,
|
|
18443
|
+
skill_name TEXT NOT NULL,
|
|
18444
|
+
path TEXT NOT NULL,
|
|
18445
|
+
content TEXT NOT NULL,
|
|
18446
|
+
size INTEGER NOT NULL,
|
|
18447
|
+
PRIMARY KEY (owner_id, skill_name, path),
|
|
18448
|
+
FOREIGN KEY (owner_id, skill_name) REFERENCES skills_0019(owner_id, name) ON DELETE CASCADE
|
|
18449
|
+
)
|
|
18450
|
+
`);
|
|
18451
|
+
sql.exec(`
|
|
18452
|
+
INSERT INTO skill_files_0019 (owner_id, skill_name, path, content, size)
|
|
18453
|
+
SELECT '__instance_shared__', skill_name, path, content, size FROM skill_files
|
|
18454
|
+
`);
|
|
18455
|
+
sql.exec(`DROP TABLE skill_files`);
|
|
18456
|
+
sql.exec(`DROP TABLE skills`);
|
|
18457
|
+
sql.exec(`ALTER TABLE skills_0019 RENAME TO skills`);
|
|
18458
|
+
sql.exec(`ALTER TABLE skill_files_0019 RENAME TO skill_files`);
|
|
18459
|
+
sql.exec(`CREATE INDEX idx_skills_owner_enabled ON skills(owner_id, enabled)`);
|
|
18460
|
+
sql.exec(`CREATE INDEX idx_skills_shared_enabled ON skills(shared, enabled)`);
|
|
18461
|
+
sql.exec(`CREATE INDEX idx_skill_files_skill ON skill_files(owner_id, skill_name)`);
|
|
18462
|
+
sql.exec(`INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '19')`);
|
|
18162
18463
|
}
|
|
18163
|
-
|
|
18164
|
-
|
|
18165
|
-
|
|
18166
|
-
|
|
18167
|
-
|
|
18168
|
-
|
|
18169
|
-
|
|
18464
|
+
};
|
|
18465
|
+
|
|
18466
|
+
// src/durable-objects/agentbuilder-migrations/0020_websocket_tickets.ts
|
|
18467
|
+
var migration56 = {
|
|
18468
|
+
version: 20,
|
|
18469
|
+
async up(sql) {
|
|
18470
|
+
sql.exec(`
|
|
18471
|
+
CREATE TABLE websocket_tickets (
|
|
18472
|
+
ticket_hash TEXT PRIMARY KEY,
|
|
18473
|
+
pathname TEXT NOT NULL,
|
|
18474
|
+
auth_json TEXT NOT NULL,
|
|
18475
|
+
created_at INTEGER NOT NULL,
|
|
18476
|
+
expires_at INTEGER NOT NULL
|
|
18477
|
+
)
|
|
18478
|
+
`);
|
|
18479
|
+
sql.exec(`
|
|
18480
|
+
CREATE INDEX idx_websocket_tickets_expires
|
|
18481
|
+
ON websocket_tickets(expires_at)
|
|
18482
|
+
`);
|
|
18483
|
+
sql.exec(`INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '20')`);
|
|
18484
|
+
}
|
|
18485
|
+
};
|
|
18486
|
+
|
|
18487
|
+
// src/durable-objects/agentbuilder-migrations/0021_platform_handoff_jtis.ts
|
|
18488
|
+
var migration57 = {
|
|
18489
|
+
version: 21,
|
|
18490
|
+
async up(sql) {
|
|
18491
|
+
sql.exec(`
|
|
18492
|
+
CREATE TABLE platform_handoff_jtis (
|
|
18493
|
+
jti TEXT PRIMARY KEY,
|
|
18494
|
+
consumed_at INTEGER NOT NULL,
|
|
18495
|
+
expires_at INTEGER NOT NULL
|
|
18496
|
+
)
|
|
18497
|
+
`);
|
|
18498
|
+
sql.exec(`
|
|
18499
|
+
CREATE INDEX idx_platform_handoff_jtis_expires
|
|
18500
|
+
ON platform_handoff_jtis(expires_at)
|
|
18501
|
+
`);
|
|
18502
|
+
sql.exec(`INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '21')`);
|
|
18170
18503
|
}
|
|
18171
|
-
|
|
18172
|
-
|
|
18173
|
-
|
|
18174
|
-
|
|
18175
|
-
|
|
18176
|
-
)
|
|
18177
|
-
|
|
18178
|
-
|
|
18179
|
-
|
|
18180
|
-
|
|
18181
|
-
|
|
18182
|
-
|
|
18183
|
-
|
|
18184
|
-
|
|
18185
|
-
|
|
18504
|
+
};
|
|
18505
|
+
|
|
18506
|
+
// src/durable-objects/agentbuilder-migrations/index.ts
|
|
18507
|
+
var migrations2 = [migration37, migration38, migration39, migration40, migration41, migration42, migration43, migration44, migration45, migration46, migration47, migration48, migration49, migration50, migration51, migration52, migration53, migration54, migration55, migration56, migration57];
|
|
18508
|
+
var LATEST_SCHEMA_VERSION2 = migrations2.reduce(
|
|
18509
|
+
(max, migration58) => Math.max(max, migration58.version),
|
|
18510
|
+
0
|
|
18511
|
+
);
|
|
18512
|
+
|
|
18513
|
+
// src/utils/crypto.ts
|
|
18514
|
+
var CryptoUtil = class {
|
|
18515
|
+
static algorithm = "aes-256-gcm";
|
|
18516
|
+
/**
|
|
18517
|
+
* Encrypt a string value
|
|
18518
|
+
*/
|
|
18519
|
+
static async encrypt(text, key) {
|
|
18520
|
+
const encoder = new TextEncoder();
|
|
18521
|
+
const data = encoder.encode(text);
|
|
18522
|
+
const cryptoKey = await crypto.subtle.importKey(
|
|
18523
|
+
"raw",
|
|
18524
|
+
hexToBuffer(key),
|
|
18525
|
+
{ name: "AES-GCM" },
|
|
18526
|
+
false,
|
|
18527
|
+
["encrypt"]
|
|
18528
|
+
);
|
|
18529
|
+
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
18530
|
+
const encrypted = await crypto.subtle.encrypt(
|
|
18531
|
+
{
|
|
18532
|
+
name: "AES-GCM",
|
|
18533
|
+
iv
|
|
18534
|
+
},
|
|
18535
|
+
cryptoKey,
|
|
18536
|
+
data
|
|
18186
18537
|
);
|
|
18538
|
+
const combined = new Uint8Array(iv.length + encrypted.byteLength);
|
|
18539
|
+
combined.set(iv);
|
|
18540
|
+
combined.set(new Uint8Array(encrypted), iv.length);
|
|
18541
|
+
return bufferToBase64(combined);
|
|
18187
18542
|
}
|
|
18188
|
-
|
|
18189
|
-
|
|
18190
|
-
|
|
18191
|
-
|
|
18192
|
-
|
|
18193
|
-
|
|
18194
|
-
|
|
18195
|
-
|
|
18196
|
-
|
|
18543
|
+
/**
|
|
18544
|
+
* Decrypt a string value
|
|
18545
|
+
*/
|
|
18546
|
+
static async decrypt(encryptedText, key) {
|
|
18547
|
+
const combined = base64ToBuffer2(encryptedText);
|
|
18548
|
+
const iv = combined.slice(0, 12);
|
|
18549
|
+
const encrypted = combined.slice(12);
|
|
18550
|
+
const cryptoKey = await crypto.subtle.importKey(
|
|
18551
|
+
"raw",
|
|
18552
|
+
hexToBuffer(key),
|
|
18553
|
+
{ name: "AES-GCM" },
|
|
18554
|
+
false,
|
|
18555
|
+
["decrypt"]
|
|
18556
|
+
);
|
|
18557
|
+
const decrypted = await crypto.subtle.decrypt(
|
|
18558
|
+
{
|
|
18559
|
+
name: "AES-GCM",
|
|
18560
|
+
iv
|
|
18561
|
+
},
|
|
18562
|
+
cryptoKey,
|
|
18563
|
+
encrypted
|
|
18564
|
+
);
|
|
18565
|
+
const decoder = new TextDecoder();
|
|
18566
|
+
return decoder.decode(decrypted);
|
|
18197
18567
|
}
|
|
18198
|
-
|
|
18199
|
-
|
|
18200
|
-
|
|
18201
|
-
|
|
18202
|
-
|
|
18203
|
-
const pkg = registry.packages[namespace.packageId];
|
|
18204
|
-
return pkg ? Object.keys(pkg.tools) : [];
|
|
18568
|
+
};
|
|
18569
|
+
function hexToBuffer(hex) {
|
|
18570
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
18571
|
+
for (let i = 0; i < hex.length; i += 2) {
|
|
18572
|
+
bytes[i / 2] = parseInt(hex.substr(i, 2), 16);
|
|
18205
18573
|
}
|
|
18206
|
-
return
|
|
18574
|
+
return bytes;
|
|
18207
18575
|
}
|
|
18208
|
-
function
|
|
18209
|
-
|
|
18210
|
-
|
|
18211
|
-
|
|
18212
|
-
const otherEntryPoints = Object.entries(registry.packages).filter(([id]) => id !== namespace.packageId).flatMap(
|
|
18213
|
-
([pkgId, pkg2]) => pkg2.entryAgents.map((name) => qualifyName(pkgId, name))
|
|
18214
|
-
);
|
|
18215
|
-
return [...ownAgents, ...otherEntryPoints];
|
|
18576
|
+
function bufferToBase64(buffer) {
|
|
18577
|
+
let binary = "";
|
|
18578
|
+
for (let i = 0; i < buffer.byteLength; i++) {
|
|
18579
|
+
binary += String.fromCharCode(buffer[i]);
|
|
18216
18580
|
}
|
|
18217
|
-
|
|
18218
|
-
const entryPoints = Object.values(registry.packages).flatMap((pkg) => pkg.entryAgents);
|
|
18219
|
-
return [.../* @__PURE__ */ new Set([...globalAgents, ...entryPoints])];
|
|
18581
|
+
return btoa(binary);
|
|
18220
18582
|
}
|
|
18221
|
-
function
|
|
18222
|
-
|
|
18223
|
-
|
|
18224
|
-
|
|
18583
|
+
function base64ToBuffer2(base64) {
|
|
18584
|
+
const binary = atob(base64);
|
|
18585
|
+
const bytes = new Uint8Array(binary.length);
|
|
18586
|
+
for (let i = 0; i < binary.length; i++) {
|
|
18587
|
+
bytes[i] = binary.charCodeAt(i);
|
|
18225
18588
|
}
|
|
18226
|
-
return
|
|
18589
|
+
return bytes;
|
|
18227
18590
|
}
|
|
18228
|
-
function
|
|
18229
|
-
|
|
18230
|
-
|
|
18231
|
-
const ownModels = pkg ? Object.keys(pkg.models) : [];
|
|
18232
|
-
const globalModels = Object.keys(registry.global.models);
|
|
18233
|
-
return [.../* @__PURE__ */ new Set([...ownModels, ...globalModels])];
|
|
18234
|
-
}
|
|
18235
|
-
return Object.keys(registry.global.models);
|
|
18591
|
+
async function encryptEnvs(env, encryptionKey) {
|
|
18592
|
+
const plaintext = JSON.stringify(env);
|
|
18593
|
+
return CryptoUtil.encrypt(plaintext, encryptionKey);
|
|
18236
18594
|
}
|
|
18237
|
-
function
|
|
18238
|
-
|
|
18239
|
-
|
|
18595
|
+
async function decryptEnvs(encrypted, encryptionKey) {
|
|
18596
|
+
const plaintext = await CryptoUtil.decrypt(encrypted, encryptionKey);
|
|
18597
|
+
const parsed = JSON.parse(plaintext);
|
|
18598
|
+
if (!parsed || typeof parsed !== "object") {
|
|
18599
|
+
return {};
|
|
18240
18600
|
}
|
|
18241
|
-
|
|
18242
|
-
|
|
18243
|
-
|
|
18244
|
-
|
|
18245
|
-
const firstSlash = name.indexOf("/");
|
|
18246
|
-
if (firstSlash === -1) return false;
|
|
18247
|
-
return name.indexOf("/", firstSlash + 1) !== -1;
|
|
18601
|
+
const result = {};
|
|
18602
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
18603
|
+
if (value === void 0 || value === null) continue;
|
|
18604
|
+
result[key] = String(value);
|
|
18248
18605
|
}
|
|
18249
|
-
return
|
|
18606
|
+
return result;
|
|
18250
18607
|
}
|
|
18251
18608
|
|
|
18252
18609
|
// src/durable-objects/DurableAgentBuilder.ts
|
|
18610
|
+
init_resolver();
|
|
18253
18611
|
init_types();
|
|
18254
18612
|
|
|
18255
18613
|
// src/skills/frontmatter.ts
|
|
@@ -18341,6 +18699,7 @@ function validateSkillFiles(files) {
|
|
|
18341
18699
|
|
|
18342
18700
|
// src/durable-objects/DurableAgentBuilder.ts
|
|
18343
18701
|
init_scope();
|
|
18702
|
+
init_ParentHookResolver();
|
|
18344
18703
|
var ENV_TYPES_PROPERTY = "__agentbuilder_env_types";
|
|
18345
18704
|
function parseStoredPermissions(value) {
|
|
18346
18705
|
if (typeof value !== "string" || !value.trim()) return null;
|
|
@@ -19022,16 +19381,29 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
|
|
|
19022
19381
|
} catch {
|
|
19023
19382
|
return;
|
|
19024
19383
|
}
|
|
19025
|
-
const
|
|
19026
|
-
|
|
19027
|
-
|
|
19028
|
-
|
|
19029
|
-
|
|
19030
|
-
|
|
19031
|
-
|
|
19032
|
-
|
|
19033
|
-
|
|
19034
|
-
|
|
19384
|
+
const packageId = agentDef?.__package?.packageId;
|
|
19385
|
+
const rawPromptName = agentDef?.sideA?.prompt;
|
|
19386
|
+
const promptName = rawPromptName && packageId && !isQualifiedName(rawPromptName) ? `${packageId}/${rawPromptName}` : rawPromptName;
|
|
19387
|
+
const promptDef = promptName ? await this.loadPrompt(promptName) : void 0;
|
|
19388
|
+
const bindings = await resolveHooksForPrompt(
|
|
19389
|
+
{
|
|
19390
|
+
host: this,
|
|
19391
|
+
agentName: thread.agent_name,
|
|
19392
|
+
agent: agentDef,
|
|
19393
|
+
promptName,
|
|
19394
|
+
prompt: promptDef,
|
|
19395
|
+
isOptionalRelationshipEnabled: async (envName) => {
|
|
19396
|
+
const value = await this.resolveThreadEnv({
|
|
19397
|
+
threadId: thread.id,
|
|
19398
|
+
property: envName,
|
|
19399
|
+
promptName: promptName ?? agentDef.name ?? thread.agent_name
|
|
19400
|
+
});
|
|
19401
|
+
return ["true", "1", "yes"].includes((value ?? "").trim().toLowerCase());
|
|
19402
|
+
}
|
|
19403
|
+
},
|
|
19404
|
+
"after_thread_created"
|
|
19405
|
+
);
|
|
19406
|
+
if (bindings.length === 0) return;
|
|
19035
19407
|
const durableId = this.env.AGENT_BUILDER_THREAD.idFromName(thread.id);
|
|
19036
19408
|
const threadStub = this.env.AGENT_BUILDER_THREAD.get(durableId);
|
|
19037
19409
|
const { ThreadStateImpl: ThreadStateImpl2 } = await Promise.resolve().then(() => (init_ThreadStateImpl(), ThreadStateImpl_exports));
|
|
@@ -19046,16 +19418,14 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
|
|
|
19046
19418
|
terminated: thread.terminated,
|
|
19047
19419
|
created_at: thread.created_at
|
|
19048
19420
|
});
|
|
19049
|
-
for (const
|
|
19050
|
-
const hookLoader = hooksRegistry[hookId];
|
|
19051
|
-
if (!hookLoader) continue;
|
|
19421
|
+
for (const binding of bindings) {
|
|
19052
19422
|
try {
|
|
19053
|
-
|
|
19054
|
-
if (hookDef?.hook === "after_thread_created") {
|
|
19055
|
-
await hookDef.execute(threadState);
|
|
19056
|
-
}
|
|
19423
|
+
await binding.execute(threadState, binding.context);
|
|
19057
19424
|
} catch (error) {
|
|
19058
|
-
console.error(
|
|
19425
|
+
console.error(
|
|
19426
|
+
`[Hooks] \u2717 Error running after_thread_created hook '${binding.id}':`,
|
|
19427
|
+
error
|
|
19428
|
+
);
|
|
19059
19429
|
}
|
|
19060
19430
|
}
|
|
19061
19431
|
}
|
|
@@ -20267,6 +20637,15 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
|
|
|
20267
20637
|
* Load a prompt definition by name.
|
|
20268
20638
|
*/
|
|
20269
20639
|
async loadPrompt(name) {
|
|
20640
|
+
if (isQualifiedName(name)) {
|
|
20641
|
+
const [packageId, promptName] = parseQualifiedName(name);
|
|
20642
|
+
const pkg = packageId ? this.registry()?.packages?.[packageId] : void 0;
|
|
20643
|
+
const loader2 = pkg?.prompts?.[promptName];
|
|
20644
|
+
if (!loader2) {
|
|
20645
|
+
throw new Error(`Prompt not found: ${name}`);
|
|
20646
|
+
}
|
|
20647
|
+
return await loader2();
|
|
20648
|
+
}
|
|
20270
20649
|
const registry = this.prompts();
|
|
20271
20650
|
const loader = registry[name];
|
|
20272
20651
|
if (!loader) {
|
|
@@ -21555,6 +21934,8 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
|
|
|
21555
21934
|
// src/durable-objects/DurableThread.ts
|
|
21556
21935
|
init_StreamManager();
|
|
21557
21936
|
init_LLMRequest();
|
|
21937
|
+
init_ThreadStateImpl();
|
|
21938
|
+
init_resolver();
|
|
21558
21939
|
|
|
21559
21940
|
// src/durable-objects/logDetailStream.ts
|
|
21560
21941
|
var LOG_DETAIL_HEAVY_FIELDS = [
|
|
@@ -22228,6 +22609,7 @@ var DurableThread = class _DurableThread extends DurableObject {
|
|
|
22228
22609
|
type: agentDef.type,
|
|
22229
22610
|
created_at: Date.now(),
|
|
22230
22611
|
max_session_turns: agentDef.maxSessionTurns,
|
|
22612
|
+
_package: agentDef.__package,
|
|
22231
22613
|
side_a_label: agentDef.sideA?.label,
|
|
22232
22614
|
side_a_agent_prompt: qualifyPromptName(agentDef.sideA?.prompt),
|
|
22233
22615
|
side_a_stop_on_response: agentDef.sideA?.stopOnResponse ?? true,
|
|
@@ -22257,7 +22639,8 @@ var DurableThread = class _DurableThread extends DurableObject {
|
|
|
22257
22639
|
side_b_session_fail_attachments_property: sideBSession.fail.attachmentsProperty,
|
|
22258
22640
|
side_b_session_status_tool: sideBSession.status.toolName,
|
|
22259
22641
|
side_b_session_status_message_property: sideBSession.status.messageProperty,
|
|
22260
|
-
side_b_session_status_attachments_property: sideBSession.status.attachmentsProperty
|
|
22642
|
+
side_b_session_status_attachments_property: sideBSession.status.attachmentsProperty,
|
|
22643
|
+
hooks: Array.isArray(agentDef.hooks) ? agentDef.hooks : void 0
|
|
22261
22644
|
};
|
|
22262
22645
|
}
|
|
22263
22646
|
/**
|
|
@@ -22927,6 +23310,29 @@ var DurableThread = class _DurableThread extends DurableObject {
|
|
|
22927
23310
|
}
|
|
22928
23311
|
return projections;
|
|
22929
23312
|
}
|
|
23313
|
+
/**
|
|
23314
|
+
* Build hook resolution context and a genuine at-rest ThreadState.
|
|
23315
|
+
* Resolution failures abort insertion so lifecycle hooks cannot be bypassed.
|
|
23316
|
+
*/
|
|
23317
|
+
async buildAtRestHookState(threadId) {
|
|
23318
|
+
try {
|
|
23319
|
+
const metadata = await this.getThreadMetadata(threadId);
|
|
23320
|
+
const agentConfig = await this.loadAgentConfig(metadata.agent_id);
|
|
23321
|
+
const threadInstance = this;
|
|
23322
|
+
return {
|
|
23323
|
+
hookState: {
|
|
23324
|
+
agentConfig,
|
|
23325
|
+
thread: { instance: threadInstance, metadata }
|
|
23326
|
+
},
|
|
23327
|
+
threadState: ThreadStateImpl.fromThreadInstance(threadInstance, metadata)
|
|
23328
|
+
};
|
|
23329
|
+
} catch (error) {
|
|
23330
|
+
throw new Error(
|
|
23331
|
+
`Unable to resolve create-message hooks for ${threadId}`,
|
|
23332
|
+
{ cause: error }
|
|
23333
|
+
);
|
|
23334
|
+
}
|
|
23335
|
+
}
|
|
22930
23336
|
/**
|
|
22931
23337
|
* Inject a top-level message without starting a new execution.
|
|
22932
23338
|
*
|
|
@@ -22939,22 +23345,7 @@ var DurableThread = class _DurableThread extends DurableObject {
|
|
|
22939
23345
|
const id = crypto.randomUUID();
|
|
22940
23346
|
const createdAt = Date.now() * TIMESTAMP_MULTIPLIER;
|
|
22941
23347
|
const silent = message.silent === true;
|
|
22942
|
-
|
|
22943
|
-
await this.ctx.storage.sql.exec(
|
|
22944
|
-
`INSERT INTO messages (id, role, content, created_at, status, silent, parent_id, depth, metadata, prompt)
|
|
22945
|
-
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)`,
|
|
22946
|
-
id,
|
|
22947
|
-
message.role,
|
|
22948
|
-
message.content,
|
|
22949
|
-
createdAt,
|
|
22950
|
-
"completed",
|
|
22951
|
-
silent ? 1 : 0,
|
|
22952
|
-
null,
|
|
22953
|
-
0,
|
|
22954
|
-
metadataJson,
|
|
22955
|
-
null
|
|
22956
|
-
);
|
|
22957
|
-
const inserted = {
|
|
23348
|
+
let inserted = {
|
|
22958
23349
|
id,
|
|
22959
23350
|
role: message.role,
|
|
22960
23351
|
content: message.content,
|
|
@@ -22965,9 +23356,37 @@ var DurableThread = class _DurableThread extends DurableObject {
|
|
|
22965
23356
|
depth: 0,
|
|
22966
23357
|
metadata: message.metadata
|
|
22967
23358
|
};
|
|
23359
|
+
const { hookState, threadState } = await this.buildAtRestHookState(threadId);
|
|
23360
|
+
const { FlowEngine: FlowEngine2 } = await Promise.resolve().then(() => (init_FlowEngine(), FlowEngine_exports));
|
|
23361
|
+
inserted = await FlowEngine2.runBeforeCreateMessageHook(
|
|
23362
|
+
hookState,
|
|
23363
|
+
inserted,
|
|
23364
|
+
threadState,
|
|
23365
|
+
{ propagateHookErrors: true }
|
|
23366
|
+
);
|
|
23367
|
+
const metadataJson = inserted.metadata ? JSON.stringify(inserted.metadata) : null;
|
|
23368
|
+
await this.ctx.storage.sql.exec(
|
|
23369
|
+
`INSERT INTO messages (id, role, content, created_at, status, silent, parent_id, depth, metadata, prompt)
|
|
23370
|
+
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)`,
|
|
23371
|
+
inserted.id,
|
|
23372
|
+
inserted.role,
|
|
23373
|
+
inserted.content,
|
|
23374
|
+
inserted.created_at,
|
|
23375
|
+
inserted.status ?? "completed",
|
|
23376
|
+
inserted.silent ? 1 : 0,
|
|
23377
|
+
inserted.parent_id ?? null,
|
|
23378
|
+
inserted.depth ?? 0,
|
|
23379
|
+
metadataJson,
|
|
23380
|
+
null
|
|
23381
|
+
);
|
|
23382
|
+
await FlowEngine2.runAfterCreateMessageHook(
|
|
23383
|
+
hookState,
|
|
23384
|
+
inserted,
|
|
23385
|
+
threadState
|
|
23386
|
+
);
|
|
22968
23387
|
this.broadcastMessage(inserted);
|
|
22969
23388
|
const record = inserted;
|
|
22970
|
-
const visibleUserInjection =
|
|
23389
|
+
const visibleUserInjection = inserted.role === "user" && !inserted.silent && typeof inserted.content === "string" && inserted.content.trim().length > 0 && !isRuntimeSubagentEnvelope(inserted.content);
|
|
22971
23390
|
if (visibleUserInjection || isVisibleTerminalAssistantMessage(record)) {
|
|
22972
23391
|
const stamp = this.recordRegistryActivity(
|
|
22973
23392
|
threadId,
|
|
@@ -27425,6 +27844,8 @@ Its execution was lost (the executor restarted or hung) and automatic recovery w
|
|
|
27425
27844
|
type: agentDef.type,
|
|
27426
27845
|
created_at: Date.now(),
|
|
27427
27846
|
max_session_turns: agentDef.maxSessionTurns,
|
|
27847
|
+
hooks: agentDef.hooks ?? [],
|
|
27848
|
+
_package: agentDef.__package,
|
|
27428
27849
|
side_a_label: agentDef.sideA?.label,
|
|
27429
27850
|
side_a_agent_prompt: qualifyPromptName(agentDef.sideA?.prompt),
|
|
27430
27851
|
side_a_stop_on_response: agentDef.sideA?.stopOnResponse ?? true,
|
|
@@ -27650,6 +28071,8 @@ Its execution was lost (the executor restarted or hung) and automatic recovery w
|
|
|
27650
28071
|
type: agentDef.type,
|
|
27651
28072
|
created_at: Date.now(),
|
|
27652
28073
|
max_session_turns: agentDef.maxSessionTurns,
|
|
28074
|
+
hooks: agentDef.hooks ?? [],
|
|
28075
|
+
_package: agentDef.__package,
|
|
27653
28076
|
side_a_label: agentDef.sideA?.label,
|
|
27654
28077
|
side_a_agent_prompt: qualifyPromptName(agentDef.sideA?.prompt),
|
|
27655
28078
|
side_a_stop_on_response: agentDef.sideA?.stopOnResponse ?? true,
|
|
@@ -27806,6 +28229,8 @@ Its execution was lost (the executor restarted or hung) and automatic recovery w
|
|
|
27806
28229
|
type: agentDef.type,
|
|
27807
28230
|
created_at: Date.now(),
|
|
27808
28231
|
max_session_turns: agentDef.maxSessionTurns,
|
|
28232
|
+
hooks: agentDef.hooks ?? [],
|
|
28233
|
+
_package: agentDef.__package,
|
|
27809
28234
|
side_a_label: agentDef.sideA?.label,
|
|
27810
28235
|
side_a_agent_prompt: qualifyPromptName(agentDef.sideA?.prompt),
|
|
27811
28236
|
side_a_stop_on_response: agentDef.sideA?.stopOnResponse ?? true,
|
|
@@ -29462,8 +29887,7 @@ var DurableUserHub = class extends DurableObject {
|
|
|
29462
29887
|
init_utilities();
|
|
29463
29888
|
|
|
29464
29889
|
// src/agents/FlowStateSdk.ts
|
|
29465
|
-
|
|
29466
|
-
var FlowStateSdk = class _FlowStateSdk {
|
|
29890
|
+
var FlowStateSdk = class {
|
|
29467
29891
|
/**
|
|
29468
29892
|
* Queue a new tool call to be executed in the current flow
|
|
29469
29893
|
*
|
|
@@ -29530,63 +29954,8 @@ var FlowStateSdk = class _FlowStateSdk {
|
|
|
29530
29954
|
* ```
|
|
29531
29955
|
*/
|
|
29532
29956
|
static async injectMessage(flow, options) {
|
|
29533
|
-
const
|
|
29534
|
-
|
|
29535
|
-
const silent = options.silent ?? false;
|
|
29536
|
-
const forceTopLevel = options.forceTopLevel ?? false;
|
|
29537
|
-
const message = {
|
|
29538
|
-
id: messageId,
|
|
29539
|
-
role: options.role,
|
|
29540
|
-
content: options.content,
|
|
29541
|
-
name: options.name ?? null,
|
|
29542
|
-
tool_call_id: options.toolCallId ?? null,
|
|
29543
|
-
created_at: timestamp,
|
|
29544
|
-
status: "completed",
|
|
29545
|
-
silent,
|
|
29546
|
-
parent_id: forceTopLevel ? null : flow.parentMessageId ?? null,
|
|
29547
|
-
depth: forceTopLevel ? 0 : flow.depth
|
|
29548
|
-
};
|
|
29549
|
-
if (options.beforeMessageId) {
|
|
29550
|
-
const cursor = await flow.storage.sql.exec(
|
|
29551
|
-
`SELECT created_at FROM messages WHERE id = ?`,
|
|
29552
|
-
options.beforeMessageId
|
|
29553
|
-
);
|
|
29554
|
-
const rows = cursor.toArray();
|
|
29555
|
-
const targetMessage = rows[0];
|
|
29556
|
-
if (!targetMessage) {
|
|
29557
|
-
throw new Error(
|
|
29558
|
-
`Message with id ${options.beforeMessageId} not found`
|
|
29559
|
-
);
|
|
29560
|
-
}
|
|
29561
|
-
message.created_at = targetMessage.created_at - 1;
|
|
29562
|
-
}
|
|
29563
|
-
const currentPrompt = flow.promptPath.length > 0 ? flow.promptPath[flow.promptPath.length - 1] : null;
|
|
29564
|
-
await flow.storage.sql.exec(
|
|
29565
|
-
`INSERT INTO messages (id, role, content, name, tool_call_id, created_at, status, silent, parent_id, depth, prompt) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
29566
|
-
messageId,
|
|
29567
|
-
message.role,
|
|
29568
|
-
message.content,
|
|
29569
|
-
message.name,
|
|
29570
|
-
message.tool_call_id,
|
|
29571
|
-
message.created_at,
|
|
29572
|
-
message.status,
|
|
29573
|
-
silent ? 1 : 0,
|
|
29574
|
-
message.parent_id,
|
|
29575
|
-
message.depth,
|
|
29576
|
-
currentPrompt
|
|
29577
|
-
);
|
|
29578
|
-
if (!silent) {
|
|
29579
|
-
flow.messageHistory.push(message);
|
|
29580
|
-
} else {
|
|
29581
|
-
flow.messageHistory = await _FlowStateSdk.reloadHistory(flow);
|
|
29582
|
-
}
|
|
29583
|
-
if (flow.emitMessage) {
|
|
29584
|
-
flow.emitMessage(message);
|
|
29585
|
-
}
|
|
29586
|
-
if (options.forceTurn) {
|
|
29587
|
-
_FlowStateSdk.forceTurn(flow, options.forceTurn);
|
|
29588
|
-
}
|
|
29589
|
-
return message;
|
|
29957
|
+
const { injectMessage: injectMessage2 } = await Promise.resolve().then(() => (init_utilities(), utilities_exports));
|
|
29958
|
+
return injectMessage2(flow, options);
|
|
29590
29959
|
}
|
|
29591
29960
|
/**
|
|
29592
29961
|
* Get messages from the thread history
|
|
@@ -29675,9 +30044,9 @@ var FlowStateSdk = class _FlowStateSdk {
|
|
|
29675
30044
|
/**
|
|
29676
30045
|
* Reload message history from storage
|
|
29677
30046
|
*
|
|
29678
|
-
* Re-loads the complete message history from the thread's SQLite storage
|
|
29679
|
-
*
|
|
29680
|
-
*
|
|
30047
|
+
* Re-loads the complete message history from the thread's SQLite storage.
|
|
30048
|
+
* This is useful when you need to refresh the message history after making
|
|
30049
|
+
* changes (e.g., injecting messages).
|
|
29681
30050
|
*
|
|
29682
30051
|
* @param flow - The current FlowState
|
|
29683
30052
|
* @returns Array of messages (reloaded from storage)
|
|
@@ -29818,6 +30187,7 @@ function enhanceFlowState(flow) {
|
|
|
29818
30187
|
init_context();
|
|
29819
30188
|
init_ProviderRegistry();
|
|
29820
30189
|
init_types2();
|
|
30190
|
+
init_resolver();
|
|
29821
30191
|
|
|
29822
30192
|
export { CLIENT_STREAM_CHUNK_BYTES, CodeExecutionBridge, DurableAgentBuilder, DurableThread, DurableUserHub, FlowStateSdk, NamespaceResolutionError, ProviderRegistry, ThreadWatchdog, applyRuntimeCors, authenticate, buildImageDescription, callClient, callClientStream, canAccessThread, cat, createNamespaceContext, createThreadEndpointHandler, decodeStreamChunk, defineController2 as defineController, emitThreadEvent, encodeStreamChunk, endpointCallerFromAuth, enhanceFlowState, exists, find, forceTurn, generateImageDescription, getFileStats, getMessages, getMessagesToSummarize, getShortName, getThumbnail, getUnsummarizedImageAttachments, getVisibleAgentNames, getVisibleModelNames, getVisiblePromptNames, getVisibleToolNames, grep, hasImageAttachments, head, injectMessage, isAdminOnlyApiRoute, isHostedInstance, isPublicApiRoute, isQualifiedName, isSameOriginBrowserRequest, isTrustedLocalDevelopmentRequest, linkFile, mkdir, move, optimizeImageContext, parseQualifiedName, qualifyName, queueTool, readFile, readdir, reloadHistory, rename, replaceImagesWithDescriptions, requireAdmin, requireAuth, resolveAgent, resolveHook, resolveModel, resolvePrompt, resolveTool, rmdir, runtimeCorsHeaders, runtimePreflightResponse, stat, supportsClientForwarding, tail, unlink, updateThread, writeFile, writeImage };
|
|
29823
30193
|
//# sourceMappingURL=runtime.js.map
|