@sw4rm/js-sdk 0.5.0 → 0.6.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/README.md +165 -1
- package/dist/cjs/index.cjs +1573 -88
- package/dist/esm/index.js +1530 -80
- package/dist/types/clients/handoff.d.ts +44 -1
- package/dist/types/index.d.ts +5 -1
- package/dist/types/internal/errorMapping.d.ts +2 -0
- package/dist/types/llm/anthropic.d.ts +83 -0
- package/dist/types/llm/client.d.ts +107 -0
- package/dist/types/llm/factory.d.ts +69 -0
- package/dist/types/llm/groq.d.ts +79 -0
- package/dist/types/llm/index.d.ts +45 -0
- package/dist/types/llm/mock.d.ts +89 -0
- package/dist/types/llm/rateLimiter.d.ts +101 -0
- package/dist/types/runtime/cancellation.d.ts +41 -0
- package/dist/types/runtime/delegation.d.ts +20 -0
- package/dist/types/runtime/gateway.d.ts +80 -0
- package/package.json +1 -1
- package/protos/common.proto +7 -0
- package/protos/handoff.proto +42 -0
- package/protos/registry.proto +11 -0
package/dist/cjs/index.cjs
CHANGED
|
@@ -1856,25 +1856,25 @@ var require_codegen = __commonJS({
|
|
|
1856
1856
|
var require_fetch = __commonJS({
|
|
1857
1857
|
"node_modules/@protobufjs/fetch/index.js"(exports2, module2) {
|
|
1858
1858
|
"use strict";
|
|
1859
|
-
module2.exports =
|
|
1859
|
+
module2.exports = fetch2;
|
|
1860
1860
|
var asPromise = require_aspromise();
|
|
1861
1861
|
var inquire2 = require_inquire();
|
|
1862
|
-
var
|
|
1863
|
-
function
|
|
1862
|
+
var fs5 = inquire2("fs");
|
|
1863
|
+
function fetch2(filename, options, callback) {
|
|
1864
1864
|
if (typeof options === "function") {
|
|
1865
1865
|
callback = options;
|
|
1866
1866
|
options = {};
|
|
1867
1867
|
} else if (!options)
|
|
1868
1868
|
options = {};
|
|
1869
1869
|
if (!callback)
|
|
1870
|
-
return asPromise(
|
|
1871
|
-
if (!options.xhr &&
|
|
1872
|
-
return
|
|
1873
|
-
return err && typeof XMLHttpRequest !== "undefined" ?
|
|
1870
|
+
return asPromise(fetch2, this, filename, options);
|
|
1871
|
+
if (!options.xhr && fs5 && fs5.readFile)
|
|
1872
|
+
return fs5.readFile(filename, function fetchReadFileCallback(err, contents) {
|
|
1873
|
+
return err && typeof XMLHttpRequest !== "undefined" ? fetch2.xhr(filename, options, callback) : err ? callback(err) : callback(null, options.binary ? contents : contents.toString("utf8"));
|
|
1874
1874
|
});
|
|
1875
|
-
return
|
|
1875
|
+
return fetch2.xhr(filename, options, callback);
|
|
1876
1876
|
}
|
|
1877
|
-
|
|
1877
|
+
fetch2.xhr = function fetch_xhr(filename, options, callback) {
|
|
1878
1878
|
var xhr = new XMLHttpRequest();
|
|
1879
1879
|
xhr.onreadystatechange = function fetchOnReadyStateChange() {
|
|
1880
1880
|
if (xhr.readyState !== 4)
|
|
@@ -1907,15 +1907,15 @@ var require_fetch = __commonJS({
|
|
|
1907
1907
|
var require_path = __commonJS({
|
|
1908
1908
|
"node_modules/@protobufjs/path/index.js"(exports2) {
|
|
1909
1909
|
"use strict";
|
|
1910
|
-
var
|
|
1910
|
+
var path7 = exports2;
|
|
1911
1911
|
var isAbsolute = (
|
|
1912
1912
|
/**
|
|
1913
1913
|
* Tests if the specified path is absolute.
|
|
1914
1914
|
* @param {string} path Path to test
|
|
1915
1915
|
* @returns {boolean} `true` if path is absolute
|
|
1916
1916
|
*/
|
|
1917
|
-
|
|
1918
|
-
return /^(?:\/|\w+:)/.test(
|
|
1917
|
+
path7.isAbsolute = function isAbsolute2(path8) {
|
|
1918
|
+
return /^(?:\/|\w+:)/.test(path8);
|
|
1919
1919
|
}
|
|
1920
1920
|
);
|
|
1921
1921
|
var normalize = (
|
|
@@ -1924,9 +1924,9 @@ var require_path = __commonJS({
|
|
|
1924
1924
|
* @param {string} path Path to normalize
|
|
1925
1925
|
* @returns {string} Normalized path
|
|
1926
1926
|
*/
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
var parts =
|
|
1927
|
+
path7.normalize = function normalize2(path8) {
|
|
1928
|
+
path8 = path8.replace(/\\/g, "/").replace(/\/{2,}/g, "/");
|
|
1929
|
+
var parts = path8.split("/"), absolute = isAbsolute(path8), prefix = "";
|
|
1930
1930
|
if (absolute)
|
|
1931
1931
|
prefix = parts.shift() + "/";
|
|
1932
1932
|
for (var i = 0; i < parts.length; ) {
|
|
@@ -1945,7 +1945,7 @@ var require_path = __commonJS({
|
|
|
1945
1945
|
return prefix + parts.join("/");
|
|
1946
1946
|
}
|
|
1947
1947
|
);
|
|
1948
|
-
|
|
1948
|
+
path7.resolve = function resolve(originPath, includePath, alreadyNormalized) {
|
|
1949
1949
|
if (!alreadyNormalized)
|
|
1950
1950
|
includePath = normalize(includePath);
|
|
1951
1951
|
if (isAbsolute(includePath))
|
|
@@ -2096,16 +2096,16 @@ var require_namespace = __commonJS({
|
|
|
2096
2096
|
object.onRemove(this);
|
|
2097
2097
|
return clearCache(this);
|
|
2098
2098
|
};
|
|
2099
|
-
Namespace.prototype.define = function define2(
|
|
2100
|
-
if (util.isString(
|
|
2101
|
-
|
|
2102
|
-
else if (!Array.isArray(
|
|
2099
|
+
Namespace.prototype.define = function define2(path7, json) {
|
|
2100
|
+
if (util.isString(path7))
|
|
2101
|
+
path7 = path7.split(".");
|
|
2102
|
+
else if (!Array.isArray(path7))
|
|
2103
2103
|
throw TypeError("illegal path");
|
|
2104
|
-
if (
|
|
2104
|
+
if (path7 && path7.length && path7[0] === "")
|
|
2105
2105
|
throw Error("path must be relative");
|
|
2106
2106
|
var ptr = this;
|
|
2107
|
-
while (
|
|
2108
|
-
var part =
|
|
2107
|
+
while (path7.length > 0) {
|
|
2108
|
+
var part = path7.shift();
|
|
2109
2109
|
if (ptr.nested && ptr.nested[part]) {
|
|
2110
2110
|
ptr = ptr.nested[part];
|
|
2111
2111
|
if (!(ptr instanceof Namespace))
|
|
@@ -2142,26 +2142,26 @@ var require_namespace = __commonJS({
|
|
|
2142
2142
|
});
|
|
2143
2143
|
return this;
|
|
2144
2144
|
};
|
|
2145
|
-
Namespace.prototype.lookup = function lookup(
|
|
2145
|
+
Namespace.prototype.lookup = function lookup(path7, filterTypes, parentAlreadyChecked) {
|
|
2146
2146
|
if (typeof filterTypes === "boolean") {
|
|
2147
2147
|
parentAlreadyChecked = filterTypes;
|
|
2148
2148
|
filterTypes = void 0;
|
|
2149
2149
|
} else if (filterTypes && !Array.isArray(filterTypes))
|
|
2150
2150
|
filterTypes = [filterTypes];
|
|
2151
|
-
if (util.isString(
|
|
2152
|
-
if (
|
|
2151
|
+
if (util.isString(path7) && path7.length) {
|
|
2152
|
+
if (path7 === ".")
|
|
2153
2153
|
return this.root;
|
|
2154
|
-
|
|
2155
|
-
} else if (!
|
|
2154
|
+
path7 = path7.split(".");
|
|
2155
|
+
} else if (!path7.length)
|
|
2156
2156
|
return this;
|
|
2157
|
-
var flatPath =
|
|
2158
|
-
if (
|
|
2159
|
-
return this.root.lookup(
|
|
2157
|
+
var flatPath = path7.join(".");
|
|
2158
|
+
if (path7[0] === "")
|
|
2159
|
+
return this.root.lookup(path7.slice(1), filterTypes);
|
|
2160
2160
|
var found = this.root._fullyQualifiedObjects && this.root._fullyQualifiedObjects["." + flatPath];
|
|
2161
2161
|
if (found && (!filterTypes || filterTypes.indexOf(found.constructor) > -1)) {
|
|
2162
2162
|
return found;
|
|
2163
2163
|
}
|
|
2164
|
-
found = this._lookupImpl(
|
|
2164
|
+
found = this._lookupImpl(path7, flatPath);
|
|
2165
2165
|
if (found && (!filterTypes || filterTypes.indexOf(found.constructor) > -1)) {
|
|
2166
2166
|
return found;
|
|
2167
2167
|
}
|
|
@@ -2169,7 +2169,7 @@ var require_namespace = __commonJS({
|
|
|
2169
2169
|
return null;
|
|
2170
2170
|
var current = this;
|
|
2171
2171
|
while (current.parent) {
|
|
2172
|
-
found = current.parent._lookupImpl(
|
|
2172
|
+
found = current.parent._lookupImpl(path7, flatPath);
|
|
2173
2173
|
if (found && (!filterTypes || filterTypes.indexOf(found.constructor) > -1)) {
|
|
2174
2174
|
return found;
|
|
2175
2175
|
}
|
|
@@ -2177,49 +2177,49 @@ var require_namespace = __commonJS({
|
|
|
2177
2177
|
}
|
|
2178
2178
|
return null;
|
|
2179
2179
|
};
|
|
2180
|
-
Namespace.prototype._lookupImpl = function lookup(
|
|
2180
|
+
Namespace.prototype._lookupImpl = function lookup(path7, flatPath) {
|
|
2181
2181
|
if (Object.prototype.hasOwnProperty.call(this._lookupCache, flatPath)) {
|
|
2182
2182
|
return this._lookupCache[flatPath];
|
|
2183
2183
|
}
|
|
2184
|
-
var found = this.get(
|
|
2184
|
+
var found = this.get(path7[0]);
|
|
2185
2185
|
var exact = null;
|
|
2186
2186
|
if (found) {
|
|
2187
|
-
if (
|
|
2187
|
+
if (path7.length === 1) {
|
|
2188
2188
|
exact = found;
|
|
2189
2189
|
} else if (found instanceof Namespace) {
|
|
2190
|
-
|
|
2191
|
-
exact = found._lookupImpl(
|
|
2190
|
+
path7 = path7.slice(1);
|
|
2191
|
+
exact = found._lookupImpl(path7, path7.join("."));
|
|
2192
2192
|
}
|
|
2193
2193
|
} else {
|
|
2194
2194
|
for (var i = 0; i < this.nestedArray.length; ++i)
|
|
2195
|
-
if (this._nestedArray[i] instanceof Namespace && (found = this._nestedArray[i]._lookupImpl(
|
|
2195
|
+
if (this._nestedArray[i] instanceof Namespace && (found = this._nestedArray[i]._lookupImpl(path7, flatPath)))
|
|
2196
2196
|
exact = found;
|
|
2197
2197
|
}
|
|
2198
2198
|
this._lookupCache[flatPath] = exact;
|
|
2199
2199
|
return exact;
|
|
2200
2200
|
};
|
|
2201
|
-
Namespace.prototype.lookupType = function lookupType(
|
|
2202
|
-
var found = this.lookup(
|
|
2201
|
+
Namespace.prototype.lookupType = function lookupType(path7) {
|
|
2202
|
+
var found = this.lookup(path7, [Type]);
|
|
2203
2203
|
if (!found)
|
|
2204
|
-
throw Error("no such type: " +
|
|
2204
|
+
throw Error("no such type: " + path7);
|
|
2205
2205
|
return found;
|
|
2206
2206
|
};
|
|
2207
|
-
Namespace.prototype.lookupEnum = function lookupEnum(
|
|
2208
|
-
var found = this.lookup(
|
|
2207
|
+
Namespace.prototype.lookupEnum = function lookupEnum(path7) {
|
|
2208
|
+
var found = this.lookup(path7, [Enum]);
|
|
2209
2209
|
if (!found)
|
|
2210
|
-
throw Error("no such Enum '" +
|
|
2210
|
+
throw Error("no such Enum '" + path7 + "' in " + this);
|
|
2211
2211
|
return found;
|
|
2212
2212
|
};
|
|
2213
|
-
Namespace.prototype.lookupTypeOrEnum = function lookupTypeOrEnum(
|
|
2214
|
-
var found = this.lookup(
|
|
2213
|
+
Namespace.prototype.lookupTypeOrEnum = function lookupTypeOrEnum(path7) {
|
|
2214
|
+
var found = this.lookup(path7, [Type, Enum]);
|
|
2215
2215
|
if (!found)
|
|
2216
|
-
throw Error("no such Type or Enum '" +
|
|
2216
|
+
throw Error("no such Type or Enum '" + path7 + "' in " + this);
|
|
2217
2217
|
return found;
|
|
2218
2218
|
};
|
|
2219
|
-
Namespace.prototype.lookupService = function lookupService(
|
|
2220
|
-
var found = this.lookup(
|
|
2219
|
+
Namespace.prototype.lookupService = function lookupService(path7) {
|
|
2220
|
+
var found = this.lookup(path7, [Service]);
|
|
2221
2221
|
if (!found)
|
|
2222
|
-
throw Error("no such Service '" +
|
|
2222
|
+
throw Error("no such Service '" + path7 + "' in " + this);
|
|
2223
2223
|
return found;
|
|
2224
2224
|
};
|
|
2225
2225
|
Namespace._configure = function(Type_, Service_, Enum_) {
|
|
@@ -3365,12 +3365,12 @@ var require_root = __commonJS({
|
|
|
3365
3365
|
if (parsed.imports) {
|
|
3366
3366
|
for (; i2 < parsed.imports.length; ++i2)
|
|
3367
3367
|
if (resolved2 = getBundledFileName(parsed.imports[i2]) || self2.resolvePath(filename2, parsed.imports[i2]))
|
|
3368
|
-
|
|
3368
|
+
fetch2(resolved2);
|
|
3369
3369
|
}
|
|
3370
3370
|
if (parsed.weakImports) {
|
|
3371
3371
|
for (i2 = 0; i2 < parsed.weakImports.length; ++i2)
|
|
3372
3372
|
if (resolved2 = getBundledFileName(parsed.weakImports[i2]) || self2.resolvePath(filename2, parsed.weakImports[i2]))
|
|
3373
|
-
|
|
3373
|
+
fetch2(resolved2, true);
|
|
3374
3374
|
}
|
|
3375
3375
|
}
|
|
3376
3376
|
} catch (err) {
|
|
@@ -3380,7 +3380,7 @@ var require_root = __commonJS({
|
|
|
3380
3380
|
finish(null, self2);
|
|
3381
3381
|
}
|
|
3382
3382
|
}
|
|
3383
|
-
function
|
|
3383
|
+
function fetch2(filename2, weak) {
|
|
3384
3384
|
filename2 = getBundledFileName(filename2) || filename2;
|
|
3385
3385
|
if (self2.files.indexOf(filename2) > -1) {
|
|
3386
3386
|
return;
|
|
@@ -3432,7 +3432,7 @@ var require_root = __commonJS({
|
|
|
3432
3432
|
}
|
|
3433
3433
|
for (var i = 0, resolved; i < filename.length; ++i)
|
|
3434
3434
|
if (resolved = self2.resolvePath("", filename[i]))
|
|
3435
|
-
|
|
3435
|
+
fetch2(resolved);
|
|
3436
3436
|
if (sync) {
|
|
3437
3437
|
self2.resolveAll();
|
|
3438
3438
|
return self2;
|
|
@@ -3620,14 +3620,14 @@ var require_util = __commonJS({
|
|
|
3620
3620
|
Object.defineProperty(object, "$type", { value: enm, enumerable: false });
|
|
3621
3621
|
return enm;
|
|
3622
3622
|
};
|
|
3623
|
-
util.setProperty = function setProperty(dst,
|
|
3624
|
-
function setProp(dst2,
|
|
3625
|
-
var part =
|
|
3623
|
+
util.setProperty = function setProperty(dst, path7, value, ifNotSet) {
|
|
3624
|
+
function setProp(dst2, path8, value2) {
|
|
3625
|
+
var part = path8.shift();
|
|
3626
3626
|
if (part === "__proto__" || part === "prototype") {
|
|
3627
3627
|
return dst2;
|
|
3628
3628
|
}
|
|
3629
|
-
if (
|
|
3630
|
-
dst2[part] = setProp(dst2[part] || {},
|
|
3629
|
+
if (path8.length > 0) {
|
|
3630
|
+
dst2[part] = setProp(dst2[part] || {}, path8, value2);
|
|
3631
3631
|
} else {
|
|
3632
3632
|
var prevValue = dst2[part];
|
|
3633
3633
|
if (prevValue && ifNotSet)
|
|
@@ -3640,10 +3640,10 @@ var require_util = __commonJS({
|
|
|
3640
3640
|
}
|
|
3641
3641
|
if (typeof dst !== "object")
|
|
3642
3642
|
throw TypeError("dst must be an object");
|
|
3643
|
-
if (!
|
|
3643
|
+
if (!path7)
|
|
3644
3644
|
throw TypeError("path must be specified");
|
|
3645
|
-
|
|
3646
|
-
return setProp(dst,
|
|
3645
|
+
path7 = path7.split(".");
|
|
3646
|
+
return setProp(dst, path7, value);
|
|
3647
3647
|
};
|
|
3648
3648
|
Object.defineProperty(util, "decorateRoot", {
|
|
3649
3649
|
get: function() {
|
|
@@ -4190,12 +4190,12 @@ var require_object = __commonJS({
|
|
|
4190
4190
|
*/
|
|
4191
4191
|
fullName: {
|
|
4192
4192
|
get: function() {
|
|
4193
|
-
var
|
|
4193
|
+
var path7 = [this.name], ptr = this.parent;
|
|
4194
4194
|
while (ptr) {
|
|
4195
|
-
|
|
4195
|
+
path7.unshift(ptr.name);
|
|
4196
4196
|
ptr = ptr.parent;
|
|
4197
4197
|
}
|
|
4198
|
-
return
|
|
4198
|
+
return path7.join(".");
|
|
4199
4199
|
}
|
|
4200
4200
|
}
|
|
4201
4201
|
});
|
|
@@ -8177,19 +8177,19 @@ var require_util2 = __commonJS({
|
|
|
8177
8177
|
"use strict";
|
|
8178
8178
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
8179
8179
|
exports2.addCommonProtos = exports2.loadProtosWithOptionsSync = exports2.loadProtosWithOptions = void 0;
|
|
8180
|
-
var
|
|
8181
|
-
var
|
|
8180
|
+
var fs5 = require("fs");
|
|
8181
|
+
var path7 = require("path");
|
|
8182
8182
|
var Protobuf = require_protobufjs();
|
|
8183
8183
|
function addIncludePathResolver(root, includePaths) {
|
|
8184
8184
|
const originalResolvePath = root.resolvePath;
|
|
8185
8185
|
root.resolvePath = (origin, target) => {
|
|
8186
|
-
if (
|
|
8186
|
+
if (path7.isAbsolute(target)) {
|
|
8187
8187
|
return target;
|
|
8188
8188
|
}
|
|
8189
8189
|
for (const directory of includePaths) {
|
|
8190
|
-
const fullPath =
|
|
8190
|
+
const fullPath = path7.join(directory, target);
|
|
8191
8191
|
try {
|
|
8192
|
-
|
|
8192
|
+
fs5.accessSync(fullPath, fs5.constants.R_OK);
|
|
8193
8193
|
return fullPath;
|
|
8194
8194
|
} catch (err) {
|
|
8195
8195
|
continue;
|
|
@@ -9483,26 +9483,40 @@ var require_src2 = __commonJS({
|
|
|
9483
9483
|
var src_exports = {};
|
|
9484
9484
|
__export(src_exports, {
|
|
9485
9485
|
ACKLifecycleManager: () => ACKLifecycleManager,
|
|
9486
|
+
AGENT_STATE_FAILED: () => AGENT_STATE_FAILED,
|
|
9487
|
+
AGENT_STATE_INITIALIZING: () => AGENT_STATE_INITIALIZING,
|
|
9488
|
+
AGENT_STATE_RUNNING: () => AGENT_STATE_RUNNING,
|
|
9489
|
+
AGENT_STATE_SHUTTING_DOWN: () => AGENT_STATE_SHUTTING_DOWN,
|
|
9486
9490
|
AckStage: () => AckStage2,
|
|
9487
9491
|
ActivityBuffer: () => ActivityBuffer,
|
|
9488
9492
|
ActivityBufferSync: () => ActivityBufferSync,
|
|
9489
9493
|
ActivityClient: () => ActivityClient,
|
|
9490
9494
|
AgentState: () => AgentState,
|
|
9491
9495
|
AgentStateMachine: () => AgentStateMachine,
|
|
9496
|
+
AnthropicClient: () => AnthropicClient,
|
|
9492
9497
|
ArtifactType: () => ArtifactType,
|
|
9493
9498
|
BaseClient: () => BaseClient,
|
|
9494
9499
|
BordaCountAggregator: () => BordaCountAggregator,
|
|
9495
9500
|
BufferFullError: () => BufferFullError,
|
|
9496
9501
|
CT_AGENT_REPORT_V1: () => CT_AGENT_REPORT_V1,
|
|
9497
9502
|
CT_SCHEDULER_COMMAND_V1: () => CT_SCHEDULER_COMMAND_V1,
|
|
9503
|
+
CancellationManager: () => CancellationManager,
|
|
9504
|
+
CancellationValidationError: () => CancellationValidationError,
|
|
9498
9505
|
CommunicationClass: () => CommunicationClass,
|
|
9499
9506
|
ConfidenceWeightedAggregator: () => ConfidenceWeightedAggregator,
|
|
9500
9507
|
ConnectorClient: () => ConnectorClient,
|
|
9501
9508
|
DEDUP_WINDOW_S: () => DEDUP_WINDOW_S,
|
|
9502
9509
|
DEFAULT_ACK_TIMEOUT_MS: () => DEFAULT_ACK_TIMEOUT_MS,
|
|
9510
|
+
DEFAULT_BACKOFF_MULTIPLIER: () => DEFAULT_BACKOFF_MULTIPLIER,
|
|
9511
|
+
DEFAULT_EFFECTIVE_MAX_REDIRECTS: () => DEFAULT_EFFECTIVE_MAX_REDIRECTS,
|
|
9503
9512
|
DEFAULT_ESCALATION_POLICY: () => DEFAULT_ESCALATION_POLICY,
|
|
9504
9513
|
DEFAULT_EXECUTION_POLICY: () => DEFAULT_EXECUTION_POLICY,
|
|
9514
|
+
DEFAULT_INITIAL_BACKOFF_MS: () => DEFAULT_INITIAL_BACKOFF_MS,
|
|
9515
|
+
DEFAULT_MAX_BACKOFF_MS: () => DEFAULT_MAX_BACKOFF_MS,
|
|
9516
|
+
DEFAULT_MAX_REDIRECTS: () => DEFAULT_MAX_REDIRECTS,
|
|
9517
|
+
DEFAULT_MAX_RETRIES_ON_OVERLOADED: () => DEFAULT_MAX_RETRIES_ON_OVERLOADED,
|
|
9505
9518
|
DEFAULT_NEGOTIATION_POLICY: () => DEFAULT_NEGOTIATION_POLICY,
|
|
9519
|
+
DEFAULT_PEER_LIVENESS_THRESHOLD_MS: () => DEFAULT_PEER_LIVENESS_THRESHOLD_MS,
|
|
9506
9520
|
DebateIntensity: () => DebateIntensity,
|
|
9507
9521
|
DecisionOutcome: () => DecisionOutcome,
|
|
9508
9522
|
DefaultWorktreePolicy: () => DefaultWorktreePolicy,
|
|
@@ -9511,6 +9525,9 @@ __export(src_exports, {
|
|
|
9511
9525
|
ErrorCode: () => ErrorCode,
|
|
9512
9526
|
ErrorCodeMapper: () => ErrorCodeMapper,
|
|
9513
9527
|
FileBackend: () => FileBackend,
|
|
9528
|
+
GatewayRedirectEmitter: () => GatewayRedirectEmitter,
|
|
9529
|
+
GatewayValidationError: () => GatewayValidationError,
|
|
9530
|
+
GroqClient: () => GroqClient,
|
|
9514
9531
|
HITLClient: () => HITLClient,
|
|
9515
9532
|
HandoffClient: () => HandoffClient,
|
|
9516
9533
|
HandoffStatus: () => HandoffStatus,
|
|
@@ -9525,11 +9542,19 @@ __export(src_exports, {
|
|
|
9525
9542
|
JSONFilePersistence: () => JSONFilePersistence,
|
|
9526
9543
|
JsonFilePolicyStore: () => JsonFilePolicyStore,
|
|
9527
9544
|
KeyringBackend: () => KeyringBackend,
|
|
9545
|
+
LlmAuthenticationError: () => LlmAuthenticationError,
|
|
9546
|
+
LlmContextLengthError: () => LlmContextLengthError,
|
|
9547
|
+
LlmError: () => LlmError,
|
|
9548
|
+
LlmRateLimitError: () => LlmRateLimitError,
|
|
9549
|
+
LlmTimeoutError: () => LlmTimeoutError,
|
|
9528
9550
|
LoggingClient: () => LoggingClient,
|
|
9551
|
+
MIN_GRACE_PERIOD_MS: () => MIN_GRACE_PERIOD_MS,
|
|
9529
9552
|
MajorityVoteAggregator: () => MajorityVoteAggregator,
|
|
9530
9553
|
MaxEntriesStrategy: () => MaxEntriesStrategy,
|
|
9531
9554
|
MessageProcessor: () => MessageProcessor,
|
|
9532
9555
|
MessageType: () => MessageType,
|
|
9556
|
+
MockLlmClient: () => MockLlmClient,
|
|
9557
|
+
NON_SERVING_AGENT_STATES: () => NON_SERVING_AGENT_STATES,
|
|
9533
9558
|
NegotiationClient: () => NegotiationClient,
|
|
9534
9559
|
NegotiationError: () => NegotiationError,
|
|
9535
9560
|
NegotiationRoomClient: () => NegotiationRoomClient,
|
|
@@ -9538,12 +9563,16 @@ __export(src_exports, {
|
|
|
9538
9563
|
NegotiationValidationError: () => NegotiationValidationError,
|
|
9539
9564
|
NoOpAuditor: () => NoOpAuditor,
|
|
9540
9565
|
NodeStatus: () => NodeStatus,
|
|
9566
|
+
PeerSelector: () => PeerSelector,
|
|
9541
9567
|
PermissionError: () => PermissionError,
|
|
9542
9568
|
PersistentActivityBuffer: () => PersistentActivityBuffer,
|
|
9543
9569
|
PersistentWorktreeState: () => PersistentWorktreeState,
|
|
9544
9570
|
PolicyStoreError: () => PolicyStoreError,
|
|
9545
9571
|
PolicyViolationError: () => PolicyViolationError,
|
|
9546
9572
|
PreemptionError: () => PreemptionError,
|
|
9573
|
+
REGISTRATION_TYPE_STANDARD_AGENT: () => REGISTRATION_TYPE_STANDARD_AGENT,
|
|
9574
|
+
REGISTRATION_TYPE_SWARM_GATEWAY: () => REGISTRATION_TYPE_SWARM_GATEWAY,
|
|
9575
|
+
RETRY_AFTER_JITTER_RATIO: () => RETRY_AFTER_JITTER_RATIO,
|
|
9547
9576
|
ReasoningClient: () => ReasoningClient,
|
|
9548
9577
|
RegistryClient: () => RegistryClient,
|
|
9549
9578
|
Resolver: () => Resolver,
|
|
@@ -9566,6 +9595,7 @@ __export(src_exports, {
|
|
|
9566
9595
|
StateTransitionError: () => StateTransitionError,
|
|
9567
9596
|
Sw4rmError: () => Sw4rmError,
|
|
9568
9597
|
TimeoutError: () => TimeoutError,
|
|
9598
|
+
TokenBucket: () => TokenBucket,
|
|
9569
9599
|
ToolClient: () => ToolClient,
|
|
9570
9600
|
TriggerType: () => TriggerType,
|
|
9571
9601
|
ValidationError: () => ValidationError,
|
|
@@ -9581,8 +9611,10 @@ __export(src_exports, {
|
|
|
9581
9611
|
aggregateVotes: () => aggregateVotes,
|
|
9582
9612
|
buildAckEnvelope: () => buildAckEnvelope,
|
|
9583
9613
|
buildEnvelope: () => buildEnvelope,
|
|
9614
|
+
buildRateLimiterConfig: () => buildRateLimiterConfig,
|
|
9584
9615
|
computeEnvelopeHash: () => computeEnvelopeHash,
|
|
9585
9616
|
computeIdempotencyToken: () => computeIdempotencyToken,
|
|
9617
|
+
createLlmClient: () => createLlmClient,
|
|
9586
9618
|
createResilientIncomingStream: () => createResilientIncomingStream,
|
|
9587
9619
|
createSimpleProof: () => createSimpleProof,
|
|
9588
9620
|
decodeAgentReportV1: () => decodeAgentReportV1,
|
|
@@ -9591,10 +9623,12 @@ __export(src_exports, {
|
|
|
9591
9623
|
defaultEndpoints: () => defaultEndpoints,
|
|
9592
9624
|
defaultRetryPolicy: () => defaultRetryPolicy,
|
|
9593
9625
|
defaultSW4RMConfig: () => defaultSW4RMConfig,
|
|
9626
|
+
delegateToSwarm: () => delegateToSwarm,
|
|
9594
9627
|
durationToMs: () => durationToMs,
|
|
9595
9628
|
encodeSchedulerCommandV1: () => encodeSchedulerCommandV1,
|
|
9596
9629
|
getConfig: () => getConfig,
|
|
9597
9630
|
getDefaultStore: () => getDefaultStore,
|
|
9631
|
+
getGlobalRateLimiter: () => getGlobalRateLimiter,
|
|
9598
9632
|
getValidTransitions: () => getValidTransitions,
|
|
9599
9633
|
isTerminalEnvelopeState: () => isTerminalEnvelopeState,
|
|
9600
9634
|
isValidTransition: () => isValidTransition,
|
|
@@ -9609,6 +9643,7 @@ __export(src_exports, {
|
|
|
9609
9643
|
parseNegotiationEvent: () => parseNegotiationEvent,
|
|
9610
9644
|
resetConfig: () => resetConfig,
|
|
9611
9645
|
resetDefaultStore: () => resetDefaultStore,
|
|
9646
|
+
resetGlobalRateLimiter: () => resetGlobalRateLimiter,
|
|
9612
9647
|
selectBackend: () => selectBackend,
|
|
9613
9648
|
sendMessageWithAck: () => sendMessageWithAck,
|
|
9614
9649
|
setConfig: () => setConfig,
|
|
@@ -9645,6 +9680,8 @@ var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
|
|
|
9645
9680
|
ErrorCode2[ErrorCode2["TTL_EXPIRED"] = 13] = "TTL_EXPIRED";
|
|
9646
9681
|
ErrorCode2[ErrorCode2["DUPLICATE_DETECTED"] = 14] = "DUPLICATE_DETECTED";
|
|
9647
9682
|
ErrorCode2[ErrorCode2["ALREADY_IN_PROGRESS"] = 15] = "ALREADY_IN_PROGRESS";
|
|
9683
|
+
ErrorCode2[ErrorCode2["OVERLOADED"] = 16] = "OVERLOADED";
|
|
9684
|
+
ErrorCode2[ErrorCode2["REDIRECT"] = 20] = "REDIRECT";
|
|
9648
9685
|
ErrorCode2[ErrorCode2["INTERNAL_ERROR"] = 99] = "INTERNAL_ERROR";
|
|
9649
9686
|
return ErrorCode2;
|
|
9650
9687
|
})(ErrorCode || {});
|
|
@@ -10920,6 +10957,38 @@ var HandoffStatus = /* @__PURE__ */ ((HandoffStatus2) => {
|
|
|
10920
10957
|
HandoffStatus2[HandoffStatus2["EXPIRED"] = 5] = "EXPIRED";
|
|
10921
10958
|
return HandoffStatus2;
|
|
10922
10959
|
})(HandoffStatus || {});
|
|
10960
|
+
var DEFAULT_MAX_RETRIES_ON_OVERLOADED = 2;
|
|
10961
|
+
var DEFAULT_INITIAL_BACKOFF_MS = 250;
|
|
10962
|
+
var DEFAULT_BACKOFF_MULTIPLIER = 2;
|
|
10963
|
+
var DEFAULT_MAX_BACKOFF_MS = 2e3;
|
|
10964
|
+
var DEFAULT_MAX_REDIRECTS = 0;
|
|
10965
|
+
function defaultDelegationPolicy() {
|
|
10966
|
+
return {
|
|
10967
|
+
maxRetriesOnOverloaded: DEFAULT_MAX_RETRIES_ON_OVERLOADED,
|
|
10968
|
+
initialBackoffMs: DEFAULT_INITIAL_BACKOFF_MS,
|
|
10969
|
+
backoffMultiplier: DEFAULT_BACKOFF_MULTIPLIER,
|
|
10970
|
+
maxBackoffMs: DEFAULT_MAX_BACKOFF_MS,
|
|
10971
|
+
allowSpilloverRouting: false,
|
|
10972
|
+
maxRedirects: DEFAULT_MAX_REDIRECTS
|
|
10973
|
+
};
|
|
10974
|
+
}
|
|
10975
|
+
function normalizeDelegationPolicy(policy) {
|
|
10976
|
+
const defaults = defaultDelegationPolicy();
|
|
10977
|
+
const maxRetriesOnOverloaded = policy?.maxRetriesOnOverloaded;
|
|
10978
|
+
const initialBackoffMs = policy?.initialBackoffMs;
|
|
10979
|
+
const backoffMultiplier = policy?.backoffMultiplier;
|
|
10980
|
+
const maxBackoffMs = policy?.maxBackoffMs;
|
|
10981
|
+
const allowSpilloverRouting = policy?.allowSpilloverRouting;
|
|
10982
|
+
const maxRedirects = policy?.maxRedirects;
|
|
10983
|
+
return {
|
|
10984
|
+
maxRetriesOnOverloaded: maxRetriesOnOverloaded === void 0 ? defaults.maxRetriesOnOverloaded : maxRetriesOnOverloaded,
|
|
10985
|
+
initialBackoffMs: initialBackoffMs !== void 0 && initialBackoffMs > 0 ? initialBackoffMs : defaults.initialBackoffMs,
|
|
10986
|
+
backoffMultiplier: backoffMultiplier !== void 0 && backoffMultiplier > 0 ? backoffMultiplier : defaults.backoffMultiplier,
|
|
10987
|
+
maxBackoffMs: maxBackoffMs !== void 0 && maxBackoffMs > 0 ? maxBackoffMs : defaults.maxBackoffMs,
|
|
10988
|
+
allowSpilloverRouting: allowSpilloverRouting ?? defaults.allowSpilloverRouting,
|
|
10989
|
+
maxRedirects: maxRedirects === void 0 ? defaults.maxRedirects : maxRedirects
|
|
10990
|
+
};
|
|
10991
|
+
}
|
|
10923
10992
|
var HandoffValidationError = class extends Error {
|
|
10924
10993
|
constructor(message) {
|
|
10925
10994
|
super(message);
|
|
@@ -10968,9 +11037,15 @@ var HandoffClient = class {
|
|
|
10968
11037
|
`Handoff request with ID '${request.requestId}' already exists`
|
|
10969
11038
|
);
|
|
10970
11039
|
}
|
|
11040
|
+
if (request.budget !== void 0 && (!request.budget.deadlineEpochMs || request.budget.deadlineEpochMs <= 0)) {
|
|
11041
|
+
throw new HandoffValidationError(
|
|
11042
|
+
"budget.deadlineEpochMs is required for cross-swarm delegation"
|
|
11043
|
+
);
|
|
11044
|
+
}
|
|
10971
11045
|
const requestWithTimestamp = {
|
|
10972
11046
|
...request,
|
|
10973
|
-
createdAt: request.createdAt || (/* @__PURE__ */ new Date()).toISOString()
|
|
11047
|
+
createdAt: request.createdAt || (/* @__PURE__ */ new Date()).toISOString(),
|
|
11048
|
+
delegationPolicy: request.budget !== void 0 || request.delegationPolicy !== void 0 ? normalizeDelegationPolicy(request.delegationPolicy) : void 0
|
|
10974
11049
|
};
|
|
10975
11050
|
this.requests.set(request.requestId, requestWithTimestamp);
|
|
10976
11051
|
if (request.toAgent) {
|
|
@@ -10992,7 +11067,8 @@ var HandoffClient = class {
|
|
|
10992
11067
|
const timeoutResponse = {
|
|
10993
11068
|
requestId: request.requestId,
|
|
10994
11069
|
accepted: false,
|
|
10995
|
-
rejectionReason: `Handoff request timed out after ${timeoutMs}ms
|
|
11070
|
+
rejectionReason: `Handoff request timed out after ${timeoutMs}ms`,
|
|
11071
|
+
rejectionCode: 3 /* ACK_TIMEOUT */
|
|
10996
11072
|
};
|
|
10997
11073
|
this.responses.set(request.requestId, timeoutResponse);
|
|
10998
11074
|
if (request.toAgent && this.pendingByAgent.has(request.toAgent)) {
|
|
@@ -11057,7 +11133,7 @@ var HandoffClient = class {
|
|
|
11057
11133
|
* await client.rejectHandoff("handoff-123", "Agent at capacity");
|
|
11058
11134
|
* ```
|
|
11059
11135
|
*/
|
|
11060
|
-
async rejectHandoff(handoffId, reason) {
|
|
11136
|
+
async rejectHandoff(handoffId, reason, options) {
|
|
11061
11137
|
const request = this.requests.get(handoffId);
|
|
11062
11138
|
if (!request) {
|
|
11063
11139
|
throw new HandoffValidationError(
|
|
@@ -11072,7 +11148,10 @@ var HandoffClient = class {
|
|
|
11072
11148
|
const response = {
|
|
11073
11149
|
requestId: handoffId,
|
|
11074
11150
|
accepted: false,
|
|
11075
|
-
rejectionReason: reason
|
|
11151
|
+
rejectionReason: reason,
|
|
11152
|
+
rejectionCode: options?.rejectionCode ?? 0 /* ERROR_CODE_UNSPECIFIED */,
|
|
11153
|
+
retryAfterMs: options?.retryAfterMs,
|
|
11154
|
+
redirectToAgentId: options?.redirectToAgentId
|
|
11076
11155
|
};
|
|
11077
11156
|
this.responses.set(handoffId, response);
|
|
11078
11157
|
if (request.toAgent && this.pendingByAgent.has(request.toAgent)) {
|
|
@@ -11576,8 +11655,8 @@ function nowHlcStub(date = /* @__PURE__ */ new Date()) {
|
|
|
11576
11655
|
const wallUs = date.getTime() * 1e3;
|
|
11577
11656
|
let node = "unknown";
|
|
11578
11657
|
try {
|
|
11579
|
-
const
|
|
11580
|
-
node =
|
|
11658
|
+
const os3 = require("node:os");
|
|
11659
|
+
node = os3.hostname() || "unknown";
|
|
11581
11660
|
} catch {
|
|
11582
11661
|
node = "browser";
|
|
11583
11662
|
}
|
|
@@ -12034,6 +12113,542 @@ function decodeBase64(b64) {
|
|
|
12034
12113
|
return new Uint8Array(Buffer.from(b64, "base64"));
|
|
12035
12114
|
}
|
|
12036
12115
|
|
|
12116
|
+
// src/runtime/delegation.ts
|
|
12117
|
+
var import_node_crypto3 = require("node:crypto");
|
|
12118
|
+
var RETRY_AFTER_JITTER_RATIO = 0.2;
|
|
12119
|
+
var DEFAULT_EFFECTIVE_MAX_REDIRECTS = 2;
|
|
12120
|
+
function defaultNowMs() {
|
|
12121
|
+
return Date.now();
|
|
12122
|
+
}
|
|
12123
|
+
function defaultSleepMs(milliseconds) {
|
|
12124
|
+
return new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
12125
|
+
}
|
|
12126
|
+
function defaultRandUniform(low, high) {
|
|
12127
|
+
if (high <= low) {
|
|
12128
|
+
return low;
|
|
12129
|
+
}
|
|
12130
|
+
return low + Math.random() * (high - low);
|
|
12131
|
+
}
|
|
12132
|
+
function normalizePolicy(policy) {
|
|
12133
|
+
return {
|
|
12134
|
+
maxRetriesOnOverloaded: policy?.maxRetriesOnOverloaded ?? DEFAULT_MAX_RETRIES_ON_OVERLOADED,
|
|
12135
|
+
initialBackoffMs: policy?.initialBackoffMs !== void 0 && policy.initialBackoffMs > 0 ? policy.initialBackoffMs : DEFAULT_INITIAL_BACKOFF_MS,
|
|
12136
|
+
backoffMultiplier: policy?.backoffMultiplier !== void 0 && policy.backoffMultiplier > 0 ? policy.backoffMultiplier : DEFAULT_BACKOFF_MULTIPLIER,
|
|
12137
|
+
maxBackoffMs: policy?.maxBackoffMs !== void 0 && policy.maxBackoffMs > 0 ? policy.maxBackoffMs : DEFAULT_MAX_BACKOFF_MS,
|
|
12138
|
+
allowSpilloverRouting: policy?.allowSpilloverRouting ?? false,
|
|
12139
|
+
maxRedirects: policy?.maxRedirects ?? DEFAULT_MAX_REDIRECTS
|
|
12140
|
+
};
|
|
12141
|
+
}
|
|
12142
|
+
function deadlineExhaustedResponse(requestId) {
|
|
12143
|
+
return {
|
|
12144
|
+
requestId,
|
|
12145
|
+
accepted: false,
|
|
12146
|
+
rejectionReason: "Delegation deadline exhausted before handoff acceptance",
|
|
12147
|
+
rejectionCode: 3 /* ACK_TIMEOUT */
|
|
12148
|
+
};
|
|
12149
|
+
}
|
|
12150
|
+
function invalidRedirectResponse(requestId, reason) {
|
|
12151
|
+
return {
|
|
12152
|
+
requestId,
|
|
12153
|
+
accepted: false,
|
|
12154
|
+
rejectionReason: reason,
|
|
12155
|
+
rejectionCode: 6 /* VALIDATION_ERROR */
|
|
12156
|
+
};
|
|
12157
|
+
}
|
|
12158
|
+
function effectiveMaxRedirects(policy) {
|
|
12159
|
+
const configured = policy.maxRedirects ?? DEFAULT_MAX_REDIRECTS;
|
|
12160
|
+
return configured > 0 ? configured : DEFAULT_EFFECTIVE_MAX_REDIRECTS;
|
|
12161
|
+
}
|
|
12162
|
+
function nextRetryWaitMs(response, retryIndex, policy, randUniformFn) {
|
|
12163
|
+
if (response.retryAfterMs !== void 0 && response.retryAfterMs > 0) {
|
|
12164
|
+
const retryAfter = response.retryAfterMs;
|
|
12165
|
+
const jitter = randUniformFn(0, retryAfter * RETRY_AFTER_JITTER_RATIO);
|
|
12166
|
+
return Math.floor(retryAfter + jitter);
|
|
12167
|
+
}
|
|
12168
|
+
const initialBackoffMs = policy.initialBackoffMs ?? DEFAULT_INITIAL_BACKOFF_MS;
|
|
12169
|
+
const backoffMultiplier = policy.backoffMultiplier ?? DEFAULT_BACKOFF_MULTIPLIER;
|
|
12170
|
+
const maxBackoffMs = policy.maxBackoffMs ?? DEFAULT_MAX_BACKOFF_MS;
|
|
12171
|
+
const exponential = initialBackoffMs * backoffMultiplier ** retryIndex;
|
|
12172
|
+
const bounded = Math.min(exponential, maxBackoffMs);
|
|
12173
|
+
return Math.floor(randUniformFn(0, bounded));
|
|
12174
|
+
}
|
|
12175
|
+
function deductWallTime(request, elapsedMs) {
|
|
12176
|
+
if (request.budget?.wallTimeRemainingMs !== void 0) {
|
|
12177
|
+
request.budget.wallTimeRemainingMs = Math.max(
|
|
12178
|
+
request.budget.wallTimeRemainingMs - elapsedMs,
|
|
12179
|
+
0
|
|
12180
|
+
);
|
|
12181
|
+
}
|
|
12182
|
+
}
|
|
12183
|
+
function budgetExhausted(budget, nowMs) {
|
|
12184
|
+
return budget.wallTimeRemainingMs !== void 0 && budget.wallTimeRemainingMs <= 0 || nowMs > budget.deadlineEpochMs;
|
|
12185
|
+
}
|
|
12186
|
+
async function delegateToSwarm(options) {
|
|
12187
|
+
if (!options.budget.deadlineEpochMs || options.budget.deadlineEpochMs <= 0) {
|
|
12188
|
+
throw new HandoffValidationError(
|
|
12189
|
+
"budget.deadlineEpochMs is required for cross-swarm delegation"
|
|
12190
|
+
);
|
|
12191
|
+
}
|
|
12192
|
+
if (options.timeoutMs !== void 0 && options.timeoutMs < 0) {
|
|
12193
|
+
throw new HandoffValidationError("timeoutMs must be >= 0");
|
|
12194
|
+
}
|
|
12195
|
+
const nowMs = options.nowMsFn ?? defaultNowMs;
|
|
12196
|
+
const sleepMs = options.sleepMsFn ?? defaultSleepMs;
|
|
12197
|
+
const randUniform = options.randUniformFn ?? defaultRandUniform;
|
|
12198
|
+
const policy = normalizePolicy(options.delegationPolicy);
|
|
12199
|
+
const requestBudget = { ...options.budget };
|
|
12200
|
+
const request = {
|
|
12201
|
+
requestId: options.requestId ?? (0, import_node_crypto3.randomUUID)(),
|
|
12202
|
+
fromAgent: options.fromAgent,
|
|
12203
|
+
toAgent: options.toAgent,
|
|
12204
|
+
reason: options.reason,
|
|
12205
|
+
contextSnapshot: options.contextSnapshot ?? new Uint8Array(),
|
|
12206
|
+
capabilitiesRequired: [...options.capabilitiesRequired ?? []],
|
|
12207
|
+
priority: options.priority ?? 0,
|
|
12208
|
+
timeoutMs: options.timeoutMs,
|
|
12209
|
+
budget: requestBudget,
|
|
12210
|
+
delegationPolicy: policy
|
|
12211
|
+
};
|
|
12212
|
+
const maxRetriesOnOverloaded = policy.maxRetriesOnOverloaded ?? DEFAULT_MAX_RETRIES_ON_OVERLOADED;
|
|
12213
|
+
let retryIndex = 0;
|
|
12214
|
+
let redirectHops = 0;
|
|
12215
|
+
const redirectBound = effectiveMaxRedirects(policy);
|
|
12216
|
+
const visitedAgents = /* @__PURE__ */ new Set([request.toAgent]);
|
|
12217
|
+
while (true) {
|
|
12218
|
+
const startMs = nowMs();
|
|
12219
|
+
if (budgetExhausted(request.budget, startMs)) {
|
|
12220
|
+
return deadlineExhaustedResponse(request.requestId);
|
|
12221
|
+
}
|
|
12222
|
+
const response = await options.sendHandoffFn(request);
|
|
12223
|
+
const endMs = nowMs();
|
|
12224
|
+
const elapsedMs = Math.max(endMs - startMs, 0);
|
|
12225
|
+
deductWallTime(request, elapsedMs);
|
|
12226
|
+
if (response.accepted) {
|
|
12227
|
+
return response;
|
|
12228
|
+
}
|
|
12229
|
+
if (budgetExhausted(request.budget, endMs)) {
|
|
12230
|
+
return deadlineExhaustedResponse(request.requestId);
|
|
12231
|
+
}
|
|
12232
|
+
if (response.rejectionCode !== 16 /* OVERLOADED */) {
|
|
12233
|
+
if (response.rejectionCode !== 20 /* REDIRECT */) {
|
|
12234
|
+
return response;
|
|
12235
|
+
}
|
|
12236
|
+
if (!policy.allowSpilloverRouting) {
|
|
12237
|
+
return response;
|
|
12238
|
+
}
|
|
12239
|
+
const targetAgent = response.redirectToAgentId?.trim();
|
|
12240
|
+
if (!targetAgent) {
|
|
12241
|
+
return invalidRedirectResponse(
|
|
12242
|
+
request.requestId,
|
|
12243
|
+
"Redirect response missing non-empty redirectToAgentId"
|
|
12244
|
+
);
|
|
12245
|
+
}
|
|
12246
|
+
if (visitedAgents.has(targetAgent)) {
|
|
12247
|
+
return invalidRedirectResponse(
|
|
12248
|
+
request.requestId,
|
|
12249
|
+
`Redirect loop detected for agent '${targetAgent}'`
|
|
12250
|
+
);
|
|
12251
|
+
}
|
|
12252
|
+
if (redirectHops >= redirectBound) {
|
|
12253
|
+
return response;
|
|
12254
|
+
}
|
|
12255
|
+
request.toAgent = targetAgent;
|
|
12256
|
+
visitedAgents.add(targetAgent);
|
|
12257
|
+
redirectHops += 1;
|
|
12258
|
+
continue;
|
|
12259
|
+
}
|
|
12260
|
+
if (retryIndex >= maxRetriesOnOverloaded) {
|
|
12261
|
+
return response;
|
|
12262
|
+
}
|
|
12263
|
+
const waitMs = nextRetryWaitMs(response, retryIndex, policy, randUniform);
|
|
12264
|
+
retryIndex += 1;
|
|
12265
|
+
const remainingDeadlineMs = request.budget.deadlineEpochMs - endMs;
|
|
12266
|
+
const remainingWallTimeMs = request.budget?.wallTimeRemainingMs;
|
|
12267
|
+
if (waitMs <= 0 || remainingWallTimeMs !== void 0 && waitMs > remainingWallTimeMs || waitMs > remainingDeadlineMs) {
|
|
12268
|
+
return response;
|
|
12269
|
+
}
|
|
12270
|
+
const beforeSleepMs = nowMs();
|
|
12271
|
+
await sleepMs(waitMs);
|
|
12272
|
+
const afterSleepMs = nowMs();
|
|
12273
|
+
deductWallTime(request, Math.max(afterSleepMs - beforeSleepMs, 0));
|
|
12274
|
+
}
|
|
12275
|
+
}
|
|
12276
|
+
|
|
12277
|
+
// src/runtime/cancellation.ts
|
|
12278
|
+
var MIN_GRACE_PERIOD_MS = 5e3;
|
|
12279
|
+
var CancellationValidationError = class extends Error {
|
|
12280
|
+
constructor(message) {
|
|
12281
|
+
super(message);
|
|
12282
|
+
this.name = "CancellationValidationError";
|
|
12283
|
+
}
|
|
12284
|
+
};
|
|
12285
|
+
function defaultNowMs2() {
|
|
12286
|
+
return Date.now();
|
|
12287
|
+
}
|
|
12288
|
+
function normalizeCorrelationId(correlationId) {
|
|
12289
|
+
const normalized = correlationId.trim();
|
|
12290
|
+
if (!normalized) {
|
|
12291
|
+
throw new CancellationValidationError(
|
|
12292
|
+
"cancel.correlationId is required and must be a non-empty string"
|
|
12293
|
+
);
|
|
12294
|
+
}
|
|
12295
|
+
return normalized;
|
|
12296
|
+
}
|
|
12297
|
+
function normalizeReason(reason) {
|
|
12298
|
+
if (reason === void 0) {
|
|
12299
|
+
return "";
|
|
12300
|
+
}
|
|
12301
|
+
return reason.trim();
|
|
12302
|
+
}
|
|
12303
|
+
function normalizeGracePeriodMs(gracePeriodMs) {
|
|
12304
|
+
const requested = gracePeriodMs !== void 0 && Number.isFinite(gracePeriodMs) && gracePeriodMs > 0 ? Math.floor(gracePeriodMs) : 0;
|
|
12305
|
+
return Math.max(requested, MIN_GRACE_PERIOD_MS);
|
|
12306
|
+
}
|
|
12307
|
+
function normalizeMetadataValue(value) {
|
|
12308
|
+
if (value === null) {
|
|
12309
|
+
return null;
|
|
12310
|
+
}
|
|
12311
|
+
if (typeof value === "string") {
|
|
12312
|
+
return value.trim();
|
|
12313
|
+
}
|
|
12314
|
+
if (typeof value === "number") {
|
|
12315
|
+
return Number.isFinite(value) ? value : void 0;
|
|
12316
|
+
}
|
|
12317
|
+
if (typeof value === "boolean") {
|
|
12318
|
+
return value;
|
|
12319
|
+
}
|
|
12320
|
+
if (value instanceof Date) {
|
|
12321
|
+
return value.toISOString();
|
|
12322
|
+
}
|
|
12323
|
+
if (typeof value === "bigint") {
|
|
12324
|
+
return value.toString();
|
|
12325
|
+
}
|
|
12326
|
+
if (typeof value === "object") {
|
|
12327
|
+
try {
|
|
12328
|
+
return JSON.stringify(value);
|
|
12329
|
+
} catch {
|
|
12330
|
+
return void 0;
|
|
12331
|
+
}
|
|
12332
|
+
}
|
|
12333
|
+
return void 0;
|
|
12334
|
+
}
|
|
12335
|
+
function normalizeMetadata(metadata, options) {
|
|
12336
|
+
const { reason, gracePeriodMs } = options;
|
|
12337
|
+
const normalized = {};
|
|
12338
|
+
if (metadata !== void 0) {
|
|
12339
|
+
for (const [rawKey, rawValue] of Object.entries(metadata)) {
|
|
12340
|
+
const key = rawKey.trim();
|
|
12341
|
+
if (!key) {
|
|
12342
|
+
continue;
|
|
12343
|
+
}
|
|
12344
|
+
const value = normalizeMetadataValue(rawValue);
|
|
12345
|
+
if (value !== void 0) {
|
|
12346
|
+
normalized[key] = value;
|
|
12347
|
+
}
|
|
12348
|
+
}
|
|
12349
|
+
}
|
|
12350
|
+
normalized.reason = reason;
|
|
12351
|
+
normalized.grace_period_ms = gracePeriodMs;
|
|
12352
|
+
return normalized;
|
|
12353
|
+
}
|
|
12354
|
+
function cloneMetadata(metadata) {
|
|
12355
|
+
return { ...metadata };
|
|
12356
|
+
}
|
|
12357
|
+
function cloneFlag(flag) {
|
|
12358
|
+
return {
|
|
12359
|
+
cancelled: flag.cancelled,
|
|
12360
|
+
gracePeriodMs: flag.gracePeriodMs,
|
|
12361
|
+
cancelTimeMs: flag.cancelTimeMs,
|
|
12362
|
+
metadata: cloneMetadata(flag.metadata)
|
|
12363
|
+
};
|
|
12364
|
+
}
|
|
12365
|
+
var CancellationManager = class {
|
|
12366
|
+
childDelegations = /* @__PURE__ */ new Map();
|
|
12367
|
+
cancellationFlags = /* @__PURE__ */ new Map();
|
|
12368
|
+
nowMs;
|
|
12369
|
+
constructor(options = {}) {
|
|
12370
|
+
this.nowMs = options.nowMsFn ?? defaultNowMs2;
|
|
12371
|
+
}
|
|
12372
|
+
registerChildDelegation(parentCorrelationId, childCorrelationId) {
|
|
12373
|
+
const parent = normalizeCorrelationId(parentCorrelationId);
|
|
12374
|
+
const child = normalizeCorrelationId(childCorrelationId);
|
|
12375
|
+
if (!this.childDelegations.has(parent)) {
|
|
12376
|
+
this.childDelegations.set(parent, /* @__PURE__ */ new Set());
|
|
12377
|
+
}
|
|
12378
|
+
this.childDelegations.get(parent).add(child);
|
|
12379
|
+
}
|
|
12380
|
+
handleCancelDelegation(cancel) {
|
|
12381
|
+
const correlationId = normalizeCorrelationId(cancel.correlationId);
|
|
12382
|
+
const gracePeriodMs = normalizeGracePeriodMs(cancel.gracePeriodMs);
|
|
12383
|
+
const reason = normalizeReason(cancel.reason);
|
|
12384
|
+
const cancelTimeMs = this.nowMs();
|
|
12385
|
+
const metadata = normalizeMetadata(cancel.metadata, {
|
|
12386
|
+
reason,
|
|
12387
|
+
gracePeriodMs
|
|
12388
|
+
});
|
|
12389
|
+
const flag = {
|
|
12390
|
+
cancelled: true,
|
|
12391
|
+
gracePeriodMs,
|
|
12392
|
+
cancelTimeMs,
|
|
12393
|
+
metadata
|
|
12394
|
+
};
|
|
12395
|
+
this.cancellationFlags.set(correlationId, cloneFlag(flag));
|
|
12396
|
+
for (const childCorrelationId of this.childDelegations.get(correlationId) ?? []) {
|
|
12397
|
+
this.cancellationFlags.set(childCorrelationId, cloneFlag(flag));
|
|
12398
|
+
}
|
|
12399
|
+
return {
|
|
12400
|
+
acknowledged: true,
|
|
12401
|
+
correlationId,
|
|
12402
|
+
gracePeriodMs,
|
|
12403
|
+
message: "Cancellation recorded",
|
|
12404
|
+
metadata: cloneMetadata(metadata)
|
|
12405
|
+
};
|
|
12406
|
+
}
|
|
12407
|
+
isCancelled(correlationId) {
|
|
12408
|
+
const normalized = correlationId.trim();
|
|
12409
|
+
if (!normalized) {
|
|
12410
|
+
return false;
|
|
12411
|
+
}
|
|
12412
|
+
const entry = this.cancellationFlags.get(normalized);
|
|
12413
|
+
return Boolean(entry?.cancelled);
|
|
12414
|
+
}
|
|
12415
|
+
isGraceExpired(correlationId, nowMs) {
|
|
12416
|
+
const normalized = correlationId.trim();
|
|
12417
|
+
if (!normalized) {
|
|
12418
|
+
return false;
|
|
12419
|
+
}
|
|
12420
|
+
const entry = this.cancellationFlags.get(normalized);
|
|
12421
|
+
if (entry === void 0 || !entry.cancelled) {
|
|
12422
|
+
return false;
|
|
12423
|
+
}
|
|
12424
|
+
const currentMs = nowMs ?? this.nowMs();
|
|
12425
|
+
return currentMs - entry.cancelTimeMs >= entry.gracePeriodMs;
|
|
12426
|
+
}
|
|
12427
|
+
forcedPreemptionErrorCode(correlationId, nowMs) {
|
|
12428
|
+
if (this.isGraceExpired(correlationId, nowMs)) {
|
|
12429
|
+
return 12 /* FORCED_PREEMPTION */;
|
|
12430
|
+
}
|
|
12431
|
+
return 0 /* ERROR_CODE_UNSPECIFIED */;
|
|
12432
|
+
}
|
|
12433
|
+
collectForcedPreemptions(correlationIds, nowMs) {
|
|
12434
|
+
const currentMs = nowMs ?? this.nowMs();
|
|
12435
|
+
const forced = /* @__PURE__ */ new Set();
|
|
12436
|
+
for (const correlationId of correlationIds) {
|
|
12437
|
+
if (this.isGraceExpired(correlationId, currentMs)) {
|
|
12438
|
+
forced.add(correlationId);
|
|
12439
|
+
}
|
|
12440
|
+
}
|
|
12441
|
+
return forced;
|
|
12442
|
+
}
|
|
12443
|
+
};
|
|
12444
|
+
|
|
12445
|
+
// src/runtime/gateway.ts
|
|
12446
|
+
var REGISTRATION_TYPE_STANDARD_AGENT = 1;
|
|
12447
|
+
var REGISTRATION_TYPE_SWARM_GATEWAY = 2;
|
|
12448
|
+
var AGENT_STATE_INITIALIZING = 1;
|
|
12449
|
+
var AGENT_STATE_RUNNING = 4;
|
|
12450
|
+
var AGENT_STATE_FAILED = 10;
|
|
12451
|
+
var AGENT_STATE_SHUTTING_DOWN = 11;
|
|
12452
|
+
var DEFAULT_PEER_LIVENESS_THRESHOLD_MS = 3e4;
|
|
12453
|
+
var NON_SERVING_AGENT_STATES = /* @__PURE__ */ new Set([
|
|
12454
|
+
AGENT_STATE_INITIALIZING,
|
|
12455
|
+
AGENT_STATE_FAILED,
|
|
12456
|
+
AGENT_STATE_SHUTTING_DOWN
|
|
12457
|
+
]);
|
|
12458
|
+
var GatewayValidationError = class extends Error {
|
|
12459
|
+
constructor(message) {
|
|
12460
|
+
super(message);
|
|
12461
|
+
this.name = "GatewayValidationError";
|
|
12462
|
+
}
|
|
12463
|
+
};
|
|
12464
|
+
function defaultNowMs3() {
|
|
12465
|
+
return Date.now();
|
|
12466
|
+
}
|
|
12467
|
+
function sameCapabilities(peerCapabilities, localCapabilities) {
|
|
12468
|
+
const peerSet = new Set(peerCapabilities);
|
|
12469
|
+
if (peerSet.size !== localCapabilities.size) {
|
|
12470
|
+
return false;
|
|
12471
|
+
}
|
|
12472
|
+
for (const localCapability of localCapabilities) {
|
|
12473
|
+
if (!peerSet.has(localCapability)) {
|
|
12474
|
+
return false;
|
|
12475
|
+
}
|
|
12476
|
+
}
|
|
12477
|
+
return true;
|
|
12478
|
+
}
|
|
12479
|
+
var PeerSelector = class {
|
|
12480
|
+
localAgentId;
|
|
12481
|
+
localCapabilities;
|
|
12482
|
+
nowMs;
|
|
12483
|
+
peerHealthFn;
|
|
12484
|
+
livenessThresholdMs;
|
|
12485
|
+
peers = [];
|
|
12486
|
+
runtime = /* @__PURE__ */ new Map();
|
|
12487
|
+
rrCursor = 0;
|
|
12488
|
+
constructor(options) {
|
|
12489
|
+
const threshold = options.livenessThresholdMs ?? DEFAULT_PEER_LIVENESS_THRESHOLD_MS;
|
|
12490
|
+
if (threshold < 0) {
|
|
12491
|
+
throw new GatewayValidationError("livenessThresholdMs must be >= 0");
|
|
12492
|
+
}
|
|
12493
|
+
this.localAgentId = options.localAgentId;
|
|
12494
|
+
this.localCapabilities = new Set(options.localCapabilities ?? []);
|
|
12495
|
+
this.nowMs = options.nowMsFn ?? defaultNowMs3;
|
|
12496
|
+
this.peerHealthFn = options.peerHealthFn ?? (() => true);
|
|
12497
|
+
this.livenessThresholdMs = threshold;
|
|
12498
|
+
}
|
|
12499
|
+
setPeers(peers) {
|
|
12500
|
+
this.peers = [...peers];
|
|
12501
|
+
const activeIds = new Set(this.peers.map((peer) => peer.agentId));
|
|
12502
|
+
for (const agentId of [...this.runtime.keys()]) {
|
|
12503
|
+
if (!activeIds.has(agentId)) {
|
|
12504
|
+
this.runtime.delete(agentId);
|
|
12505
|
+
}
|
|
12506
|
+
}
|
|
12507
|
+
const nowMs = this.nowMs();
|
|
12508
|
+
for (const peer of this.peers) {
|
|
12509
|
+
if (!this.runtime.has(peer.agentId)) {
|
|
12510
|
+
this.runtime.set(peer.agentId, {
|
|
12511
|
+
state: AGENT_STATE_RUNNING,
|
|
12512
|
+
lastHeartbeatMs: nowMs,
|
|
12513
|
+
cooldownUntilMs: 0
|
|
12514
|
+
});
|
|
12515
|
+
}
|
|
12516
|
+
}
|
|
12517
|
+
}
|
|
12518
|
+
updatePeerRuntimeState(agentId, options = {}) {
|
|
12519
|
+
const runtime = this.ensureRuntime(agentId);
|
|
12520
|
+
if (options.state !== void 0) {
|
|
12521
|
+
runtime.state = options.state;
|
|
12522
|
+
}
|
|
12523
|
+
if (options.lastHeartbeatMs !== void 0) {
|
|
12524
|
+
runtime.lastHeartbeatMs = Math.max(Math.floor(options.lastHeartbeatMs), 0);
|
|
12525
|
+
}
|
|
12526
|
+
if (options.cooldownUntilMs !== void 0) {
|
|
12527
|
+
runtime.cooldownUntilMs = Math.max(Math.floor(options.cooldownUntilMs), 0);
|
|
12528
|
+
}
|
|
12529
|
+
this.runtime.set(agentId, runtime);
|
|
12530
|
+
}
|
|
12531
|
+
touchPeerHeartbeat(agentId, options = {}) {
|
|
12532
|
+
this.updatePeerRuntimeState(agentId, {
|
|
12533
|
+
state: options.state,
|
|
12534
|
+
lastHeartbeatMs: options.nowMs ?? this.nowMs()
|
|
12535
|
+
});
|
|
12536
|
+
}
|
|
12537
|
+
recordPeerOverloaded(agentId, options = {}) {
|
|
12538
|
+
const runtime = this.ensureRuntime(agentId);
|
|
12539
|
+
const nowMs = this.nowMs();
|
|
12540
|
+
const retryAfterMs = Math.max(Math.floor(options.retryAfterMs ?? 0), 0);
|
|
12541
|
+
const localCooldownMs = Math.max(Math.floor(options.localCooldownMs ?? 0), 0);
|
|
12542
|
+
const cooldownMs = Math.max(retryAfterMs, localCooldownMs);
|
|
12543
|
+
runtime.cooldownUntilMs = Math.max(runtime.cooldownUntilMs, nowMs + cooldownMs);
|
|
12544
|
+
this.runtime.set(agentId, runtime);
|
|
12545
|
+
}
|
|
12546
|
+
isEligible(peer) {
|
|
12547
|
+
if (peer.registrationType !== REGISTRATION_TYPE_SWARM_GATEWAY) {
|
|
12548
|
+
return false;
|
|
12549
|
+
}
|
|
12550
|
+
if (peer.agentId === this.localAgentId) {
|
|
12551
|
+
return false;
|
|
12552
|
+
}
|
|
12553
|
+
return sameCapabilities(peer.capabilities, this.localCapabilities);
|
|
12554
|
+
}
|
|
12555
|
+
selectPeer() {
|
|
12556
|
+
const healthy = this.peers.filter((peer) => this.isHealthy(peer));
|
|
12557
|
+
if (healthy.length === 0) {
|
|
12558
|
+
return "";
|
|
12559
|
+
}
|
|
12560
|
+
const idx = this.rrCursor % healthy.length;
|
|
12561
|
+
this.rrCursor += 1;
|
|
12562
|
+
return healthy[idx].agentId;
|
|
12563
|
+
}
|
|
12564
|
+
ensureRuntime(agentId) {
|
|
12565
|
+
const existing = this.runtime.get(agentId);
|
|
12566
|
+
if (existing !== void 0) {
|
|
12567
|
+
return existing;
|
|
12568
|
+
}
|
|
12569
|
+
return {
|
|
12570
|
+
state: AGENT_STATE_RUNNING,
|
|
12571
|
+
lastHeartbeatMs: this.nowMs(),
|
|
12572
|
+
cooldownUntilMs: 0
|
|
12573
|
+
};
|
|
12574
|
+
}
|
|
12575
|
+
isHealthy(peer) {
|
|
12576
|
+
if (!this.isEligible(peer)) {
|
|
12577
|
+
return false;
|
|
12578
|
+
}
|
|
12579
|
+
if (!this.peerHealthFn(peer)) {
|
|
12580
|
+
return false;
|
|
12581
|
+
}
|
|
12582
|
+
const runtime = this.runtime.get(peer.agentId);
|
|
12583
|
+
if (runtime === void 0) {
|
|
12584
|
+
return false;
|
|
12585
|
+
}
|
|
12586
|
+
const nowMs = this.nowMs();
|
|
12587
|
+
if (runtime.cooldownUntilMs > nowMs) {
|
|
12588
|
+
return false;
|
|
12589
|
+
}
|
|
12590
|
+
if (nowMs - runtime.lastHeartbeatMs > this.livenessThresholdMs) {
|
|
12591
|
+
return false;
|
|
12592
|
+
}
|
|
12593
|
+
if (NON_SERVING_AGENT_STATES.has(runtime.state)) {
|
|
12594
|
+
return false;
|
|
12595
|
+
}
|
|
12596
|
+
return true;
|
|
12597
|
+
}
|
|
12598
|
+
};
|
|
12599
|
+
var GatewayRedirectEmitter = class {
|
|
12600
|
+
retryAfterMs;
|
|
12601
|
+
peerSelector;
|
|
12602
|
+
constructor(options) {
|
|
12603
|
+
if ((options.retryAfterMs ?? 0) < 0) {
|
|
12604
|
+
throw new GatewayValidationError("retryAfterMs must be >= 0");
|
|
12605
|
+
}
|
|
12606
|
+
this.retryAfterMs = options.retryAfterMs ?? 1e3;
|
|
12607
|
+
this.peerSelector = new PeerSelector({
|
|
12608
|
+
localAgentId: options.agentId,
|
|
12609
|
+
localCapabilities: options.capabilities ?? [],
|
|
12610
|
+
nowMsFn: options.nowMsFn,
|
|
12611
|
+
peerHealthFn: options.peerHealthFn,
|
|
12612
|
+
livenessThresholdMs: options.peerLivenessThresholdMs
|
|
12613
|
+
});
|
|
12614
|
+
this.peerSelector.setPeers(options.peerDescriptors ?? []);
|
|
12615
|
+
}
|
|
12616
|
+
setPeerDescriptors(peers) {
|
|
12617
|
+
this.peerSelector.setPeers(peers);
|
|
12618
|
+
}
|
|
12619
|
+
updatePeerRuntimeState(agentId, options = {}) {
|
|
12620
|
+
this.peerSelector.updatePeerRuntimeState(agentId, options);
|
|
12621
|
+
}
|
|
12622
|
+
touchPeerHeartbeat(agentId, options = {}) {
|
|
12623
|
+
this.peerSelector.touchPeerHeartbeat(agentId, options);
|
|
12624
|
+
}
|
|
12625
|
+
recordPeerOverloaded(agentId, options = {}) {
|
|
12626
|
+
this.peerSelector.recordPeerOverloaded(agentId, options);
|
|
12627
|
+
}
|
|
12628
|
+
emitOverloadedResponse(request) {
|
|
12629
|
+
if (request.delegationPolicy?.allowSpilloverRouting) {
|
|
12630
|
+
const redirectToAgentId = this.peerSelector.selectPeer();
|
|
12631
|
+
if (redirectToAgentId) {
|
|
12632
|
+
return {
|
|
12633
|
+
requestId: request.requestId,
|
|
12634
|
+
accepted: false,
|
|
12635
|
+
rejectionReason: "Gateway at capacity; redirect to peer gateway",
|
|
12636
|
+
rejectionCode: 20 /* REDIRECT */,
|
|
12637
|
+
retryAfterMs: 0,
|
|
12638
|
+
redirectToAgentId
|
|
12639
|
+
};
|
|
12640
|
+
}
|
|
12641
|
+
}
|
|
12642
|
+
return {
|
|
12643
|
+
requestId: request.requestId,
|
|
12644
|
+
accepted: false,
|
|
12645
|
+
rejectionReason: "Gateway at capacity",
|
|
12646
|
+
rejectionCode: 16 /* OVERLOADED */,
|
|
12647
|
+
retryAfterMs: this.retryAfterMs
|
|
12648
|
+
};
|
|
12649
|
+
}
|
|
12650
|
+
};
|
|
12651
|
+
|
|
12037
12652
|
// src/persistence/persistence.ts
|
|
12038
12653
|
var import_promises = __toESM(require("node:fs/promises"), 1);
|
|
12039
12654
|
var import_node_path2 = __toESM(require("node:path"), 1);
|
|
@@ -13263,9 +13878,9 @@ var AgentStateMachine = class {
|
|
|
13263
13878
|
};
|
|
13264
13879
|
|
|
13265
13880
|
// src/internal/idempotency.ts
|
|
13266
|
-
var
|
|
13881
|
+
var import_node_crypto4 = __toESM(require("node:crypto"), 1);
|
|
13267
13882
|
function computeIdempotencyToken(input) {
|
|
13268
|
-
const h =
|
|
13883
|
+
const h = import_node_crypto4.default.createHash("sha256");
|
|
13269
13884
|
h.update(input.producer_id);
|
|
13270
13885
|
h.update("\n");
|
|
13271
13886
|
h.update(input.operation);
|
|
@@ -13459,12 +14074,12 @@ function updateEnvelopeState(envelope, newState) {
|
|
|
13459
14074
|
}
|
|
13460
14075
|
|
|
13461
14076
|
// src/audit.ts
|
|
13462
|
-
var
|
|
14077
|
+
var import_node_crypto5 = __toESM(require("node:crypto"), 1);
|
|
13463
14078
|
function uuidv43() {
|
|
13464
|
-
if (typeof
|
|
13465
|
-
return
|
|
14079
|
+
if (typeof import_node_crypto5.default.randomUUID === "function") {
|
|
14080
|
+
return import_node_crypto5.default.randomUUID();
|
|
13466
14081
|
}
|
|
13467
|
-
const buf =
|
|
14082
|
+
const buf = import_node_crypto5.default.randomBytes(16);
|
|
13468
14083
|
buf[6] = buf[6] & 15 | 64;
|
|
13469
14084
|
buf[8] = buf[8] & 63 | 128;
|
|
13470
14085
|
const hex = [...buf].map((b) => b.toString(16).padStart(2, "0"));
|
|
@@ -13477,7 +14092,7 @@ function computeEnvelopeHash(envelope) {
|
|
|
13477
14092
|
delete envelopeCopy.payload;
|
|
13478
14093
|
delete envelopeCopy.audit_proof;
|
|
13479
14094
|
const envelopeJson = JSON.stringify(envelopeCopy, Object.keys(envelopeCopy).sort());
|
|
13480
|
-
const hasher =
|
|
14095
|
+
const hasher = import_node_crypto5.default.createHash("sha256");
|
|
13481
14096
|
hasher.update(envelopeJson, "utf-8");
|
|
13482
14097
|
if (payload) {
|
|
13483
14098
|
if (payload instanceof Uint8Array) {
|
|
@@ -13499,7 +14114,7 @@ function createSimpleProof(envelope, actor_id) {
|
|
|
13499
14114
|
const envelopeHash = computeEnvelopeHash(envelope);
|
|
13500
14115
|
const timestamp = nowHlcStub();
|
|
13501
14116
|
const proofInput = `${envelopeHash}:${actor_id}:${timestamp}`;
|
|
13502
|
-
const proofHash =
|
|
14117
|
+
const proofHash = import_node_crypto5.default.createHash("sha256").update(proofInput, "utf-8").digest();
|
|
13503
14118
|
return {
|
|
13504
14119
|
proof_id: uuidv43(),
|
|
13505
14120
|
proof_type: "simple_hash",
|
|
@@ -14163,8 +14778,8 @@ function defaultPath() {
|
|
|
14163
14778
|
}
|
|
14164
14779
|
var FileBackend = class {
|
|
14165
14780
|
path;
|
|
14166
|
-
constructor(
|
|
14167
|
-
this.path =
|
|
14781
|
+
constructor(path7) {
|
|
14782
|
+
this.path = path7 ?? defaultPath();
|
|
14168
14783
|
(0, import_node_fs3.mkdirSync)((0, import_node_path5.dirname)(this.path), { recursive: true });
|
|
14169
14784
|
try {
|
|
14170
14785
|
(0, import_node_fs3.chmodSync)((0, import_node_path5.dirname)(this.path), 448);
|
|
@@ -14294,31 +14909,880 @@ async function selectBackend(mode) {
|
|
|
14294
14909
|
}
|
|
14295
14910
|
}
|
|
14296
14911
|
|
|
14912
|
+
// src/llm/client.ts
|
|
14913
|
+
var LlmError = class extends Error {
|
|
14914
|
+
constructor(message) {
|
|
14915
|
+
super(message);
|
|
14916
|
+
this.name = "LlmError";
|
|
14917
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
14918
|
+
}
|
|
14919
|
+
};
|
|
14920
|
+
var LlmAuthenticationError = class extends LlmError {
|
|
14921
|
+
constructor(message) {
|
|
14922
|
+
super(message);
|
|
14923
|
+
this.name = "LlmAuthenticationError";
|
|
14924
|
+
}
|
|
14925
|
+
};
|
|
14926
|
+
var LlmRateLimitError = class extends LlmError {
|
|
14927
|
+
constructor(message) {
|
|
14928
|
+
super(message);
|
|
14929
|
+
this.name = "LlmRateLimitError";
|
|
14930
|
+
}
|
|
14931
|
+
};
|
|
14932
|
+
var LlmTimeoutError = class extends LlmError {
|
|
14933
|
+
constructor(message) {
|
|
14934
|
+
super(message);
|
|
14935
|
+
this.name = "LlmTimeoutError";
|
|
14936
|
+
}
|
|
14937
|
+
};
|
|
14938
|
+
var LlmContextLengthError = class extends LlmError {
|
|
14939
|
+
constructor(message) {
|
|
14940
|
+
super(message);
|
|
14941
|
+
this.name = "LlmContextLengthError";
|
|
14942
|
+
}
|
|
14943
|
+
};
|
|
14944
|
+
|
|
14945
|
+
// src/llm/rateLimiter.ts
|
|
14946
|
+
function envBool(name, defaultVal) {
|
|
14947
|
+
const raw = (process.env[name] ?? defaultVal).toLowerCase();
|
|
14948
|
+
return !["0", "false", "no"].includes(raw);
|
|
14949
|
+
}
|
|
14950
|
+
function buildRateLimiterConfig(overrides) {
|
|
14951
|
+
return {
|
|
14952
|
+
tokensPerMinute: overrides?.tokensPerMinute ?? parseInt(process.env["LLM_RATE_LIMIT_TOKENS_PER_MIN"] ?? "250000", 10),
|
|
14953
|
+
burstAllowance: overrides?.burstAllowance ?? 1,
|
|
14954
|
+
minTokensPerRequest: overrides?.minTokensPerRequest ?? 100,
|
|
14955
|
+
maxWaitSeconds: overrides?.maxWaitSeconds ?? 120,
|
|
14956
|
+
enabled: overrides?.enabled ?? envBool("LLM_RATE_LIMIT_ENABLED", "1"),
|
|
14957
|
+
adaptiveEnabled: overrides?.adaptiveEnabled ?? envBool("LLM_RATE_LIMIT_ADAPTIVE", "1"),
|
|
14958
|
+
reductionFactor: overrides?.reductionFactor ?? parseFloat(process.env["LLM_RATE_LIMIT_REDUCTION_FACTOR"] ?? "0.7"),
|
|
14959
|
+
recoveryFactor: overrides?.recoveryFactor ?? parseFloat(process.env["LLM_RATE_LIMIT_RECOVERY_FACTOR"] ?? "1.1"),
|
|
14960
|
+
cooldownSeconds: overrides?.cooldownSeconds ?? parseFloat(process.env["LLM_RATE_LIMIT_COOLDOWN_SECONDS"] ?? "30"),
|
|
14961
|
+
successesForRecovery: overrides?.successesForRecovery ?? parseInt(
|
|
14962
|
+
process.env["LLM_RATE_LIMIT_RECOVERY_SUCCESS_THRESHOLD"] ?? "20",
|
|
14963
|
+
10
|
|
14964
|
+
)
|
|
14965
|
+
};
|
|
14966
|
+
}
|
|
14967
|
+
var TokenBucket = class {
|
|
14968
|
+
config;
|
|
14969
|
+
baseTpm;
|
|
14970
|
+
currentTpm;
|
|
14971
|
+
minTpm;
|
|
14972
|
+
tokens;
|
|
14973
|
+
lastRefill;
|
|
14974
|
+
lastRateLimitTime = null;
|
|
14975
|
+
successesSinceLimit = 0;
|
|
14976
|
+
constructor(config) {
|
|
14977
|
+
this.config = buildRateLimiterConfig(config);
|
|
14978
|
+
this.baseTpm = this.config.tokensPerMinute;
|
|
14979
|
+
this.currentTpm = this.config.tokensPerMinute;
|
|
14980
|
+
this.minTpm = Math.max(1e3, this.baseTpm * 0.25);
|
|
14981
|
+
this.tokens = this.currentTpm;
|
|
14982
|
+
this.lastRefill = performance.now();
|
|
14983
|
+
}
|
|
14984
|
+
// -- Internal helpers ----------------------------------------------------
|
|
14985
|
+
refill() {
|
|
14986
|
+
const now = performance.now();
|
|
14987
|
+
const elapsedSeconds = (now - this.lastRefill) / 1e3;
|
|
14988
|
+
const refill = elapsedSeconds * (this.currentTpm / 60);
|
|
14989
|
+
this.tokens = Math.min(
|
|
14990
|
+
this.tokens + refill,
|
|
14991
|
+
this.currentTpm * this.config.burstAllowance
|
|
14992
|
+
);
|
|
14993
|
+
this.lastRefill = now;
|
|
14994
|
+
this.maybeRecover(now);
|
|
14995
|
+
}
|
|
14996
|
+
maybeRecover(now) {
|
|
14997
|
+
if (!this.config.adaptiveEnabled)
|
|
14998
|
+
return;
|
|
14999
|
+
if (this.currentTpm >= this.baseTpm)
|
|
15000
|
+
return;
|
|
15001
|
+
if (this.lastRateLimitTime === null)
|
|
15002
|
+
return;
|
|
15003
|
+
if ((now - this.lastRateLimitTime) / 1e3 < this.config.cooldownSeconds)
|
|
15004
|
+
return;
|
|
15005
|
+
if (this.successesSinceLimit < this.config.successesForRecovery)
|
|
15006
|
+
return;
|
|
15007
|
+
const newLimit = Math.min(
|
|
15008
|
+
this.baseTpm,
|
|
15009
|
+
this.currentTpm * this.config.recoveryFactor
|
|
15010
|
+
);
|
|
15011
|
+
if (newLimit > this.currentTpm) {
|
|
15012
|
+
this.currentTpm = newLimit;
|
|
15013
|
+
this.successesSinceLimit = 0;
|
|
15014
|
+
}
|
|
15015
|
+
}
|
|
15016
|
+
// -- Public API ----------------------------------------------------------
|
|
15017
|
+
/**
|
|
15018
|
+
* Acquire tokens, waiting if necessary.
|
|
15019
|
+
*
|
|
15020
|
+
* @param estimatedTokens - Estimated token count for the request.
|
|
15021
|
+
* @returns Time spent waiting in milliseconds (0 if immediate).
|
|
15022
|
+
* @throws Error if waiting exceeds {@link RateLimiterConfig.maxWaitSeconds}.
|
|
15023
|
+
*/
|
|
15024
|
+
async acquire(estimatedTokens) {
|
|
15025
|
+
if (!this.config.enabled)
|
|
15026
|
+
return 0;
|
|
15027
|
+
estimatedTokens = Math.max(estimatedTokens, this.config.minTokensPerRequest);
|
|
15028
|
+
const waitStart = performance.now();
|
|
15029
|
+
for (; ; ) {
|
|
15030
|
+
this.refill();
|
|
15031
|
+
if (this.tokens >= estimatedTokens) {
|
|
15032
|
+
this.tokens -= estimatedTokens;
|
|
15033
|
+
return performance.now() - waitStart;
|
|
15034
|
+
}
|
|
15035
|
+
const elapsed = (performance.now() - waitStart) / 1e3;
|
|
15036
|
+
if (elapsed >= this.config.maxWaitSeconds) {
|
|
15037
|
+
throw new Error(
|
|
15038
|
+
`Rate limiter: waited ${elapsed.toFixed(1)}s for ${estimatedTokens} tokens`
|
|
15039
|
+
);
|
|
15040
|
+
}
|
|
15041
|
+
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
15042
|
+
}
|
|
15043
|
+
}
|
|
15044
|
+
/**
|
|
15045
|
+
* Record a 429 event -- adaptively reduce budget.
|
|
15046
|
+
*
|
|
15047
|
+
* Call this when the upstream API returns HTTP 429 or an equivalent
|
|
15048
|
+
* rate-limit error.
|
|
15049
|
+
*/
|
|
15050
|
+
recordRateLimit() {
|
|
15051
|
+
if (!(this.config.enabled && this.config.adaptiveEnabled))
|
|
15052
|
+
return;
|
|
15053
|
+
this.lastRateLimitTime = performance.now();
|
|
15054
|
+
this.successesSinceLimit = 0;
|
|
15055
|
+
const newLimit = Math.max(
|
|
15056
|
+
this.minTpm,
|
|
15057
|
+
this.currentTpm * this.config.reductionFactor
|
|
15058
|
+
);
|
|
15059
|
+
if (newLimit < this.currentTpm) {
|
|
15060
|
+
this.currentTpm = newLimit;
|
|
15061
|
+
this.tokens = Math.min(this.tokens, this.currentTpm);
|
|
15062
|
+
}
|
|
15063
|
+
}
|
|
15064
|
+
/**
|
|
15065
|
+
* Record a successful request for adaptive recovery.
|
|
15066
|
+
*
|
|
15067
|
+
* Call this after each successful API response.
|
|
15068
|
+
*/
|
|
15069
|
+
recordSuccess() {
|
|
15070
|
+
if (!(this.config.enabled && this.config.adaptiveEnabled))
|
|
15071
|
+
return;
|
|
15072
|
+
this.successesSinceLimit += 1;
|
|
15073
|
+
}
|
|
15074
|
+
/** Current available token count. */
|
|
15075
|
+
get availableTokens() {
|
|
15076
|
+
return this.tokens;
|
|
15077
|
+
}
|
|
15078
|
+
/** Current tokens-per-minute budget (may be reduced after 429). */
|
|
15079
|
+
get currentTokensPerMinute() {
|
|
15080
|
+
return this.currentTpm;
|
|
15081
|
+
}
|
|
15082
|
+
};
|
|
15083
|
+
var globalBucket = null;
|
|
15084
|
+
function getGlobalRateLimiter(config) {
|
|
15085
|
+
if (globalBucket === null) {
|
|
15086
|
+
globalBucket = new TokenBucket(config);
|
|
15087
|
+
}
|
|
15088
|
+
return globalBucket;
|
|
15089
|
+
}
|
|
15090
|
+
function resetGlobalRateLimiter() {
|
|
15091
|
+
globalBucket = null;
|
|
15092
|
+
}
|
|
15093
|
+
|
|
15094
|
+
// src/llm/mock.ts
|
|
15095
|
+
var MockLlmClient = class {
|
|
15096
|
+
/** The model name returned in responses. */
|
|
15097
|
+
defaultModel;
|
|
15098
|
+
responses;
|
|
15099
|
+
responseIndex = 0;
|
|
15100
|
+
responseGenerator;
|
|
15101
|
+
_callCount = 0;
|
|
15102
|
+
_callHistory = [];
|
|
15103
|
+
constructor(opts) {
|
|
15104
|
+
this.defaultModel = opts?.defaultModel ?? "mock-model";
|
|
15105
|
+
this.responses = opts?.responses ?? [];
|
|
15106
|
+
this.responseGenerator = opts?.responseGenerator;
|
|
15107
|
+
}
|
|
15108
|
+
/** Number of queries made to this client. */
|
|
15109
|
+
get callCount() {
|
|
15110
|
+
return this._callCount;
|
|
15111
|
+
}
|
|
15112
|
+
/** History of all calls made to this client. */
|
|
15113
|
+
get callHistory() {
|
|
15114
|
+
return this._callHistory;
|
|
15115
|
+
}
|
|
15116
|
+
/** Reset call count, history, and response index. */
|
|
15117
|
+
reset() {
|
|
15118
|
+
this._callCount = 0;
|
|
15119
|
+
this._callHistory.length = 0;
|
|
15120
|
+
this.responseIndex = 0;
|
|
15121
|
+
}
|
|
15122
|
+
/**
|
|
15123
|
+
* Return a mock response.
|
|
15124
|
+
*
|
|
15125
|
+
* Priority for determining response content:
|
|
15126
|
+
* 1. `responseGenerator` function (if provided)
|
|
15127
|
+
* 2. `responses` array (cycles through entries)
|
|
15128
|
+
* 3. Default echo: "Mock response to: <prompt>"
|
|
15129
|
+
*
|
|
15130
|
+
* @param prompt - The prompt (recorded in history).
|
|
15131
|
+
* @param opts - Optional query configuration (recorded in history).
|
|
15132
|
+
* @returns LlmResponse with mock content.
|
|
15133
|
+
*/
|
|
15134
|
+
async query(prompt, opts) {
|
|
15135
|
+
const model = opts?.model ?? this.defaultModel;
|
|
15136
|
+
const maxTokens = opts?.maxTokens ?? 4096;
|
|
15137
|
+
const temperature = opts?.temperature ?? 1;
|
|
15138
|
+
this._callCount += 1;
|
|
15139
|
+
this._callHistory.push({
|
|
15140
|
+
prompt,
|
|
15141
|
+
systemPrompt: opts?.systemPrompt,
|
|
15142
|
+
maxTokens,
|
|
15143
|
+
temperature,
|
|
15144
|
+
model
|
|
15145
|
+
});
|
|
15146
|
+
let content;
|
|
15147
|
+
if (this.responseGenerator) {
|
|
15148
|
+
content = this.responseGenerator(prompt);
|
|
15149
|
+
} else if (this.responses.length > 0) {
|
|
15150
|
+
content = this.responses[this.responseIndex % this.responses.length];
|
|
15151
|
+
this.responseIndex += 1;
|
|
15152
|
+
} else {
|
|
15153
|
+
content = `Mock response to: ${prompt.slice(0, 100)}`;
|
|
15154
|
+
}
|
|
15155
|
+
return {
|
|
15156
|
+
content,
|
|
15157
|
+
model,
|
|
15158
|
+
usage: {
|
|
15159
|
+
input_tokens: Math.max(Math.floor(prompt.length / 4), 1),
|
|
15160
|
+
output_tokens: Math.max(Math.floor(content.length / 4), 1)
|
|
15161
|
+
},
|
|
15162
|
+
metadata: { mock: true, call_count: this._callCount }
|
|
15163
|
+
};
|
|
15164
|
+
}
|
|
15165
|
+
/**
|
|
15166
|
+
* Stream a mock response.
|
|
15167
|
+
*
|
|
15168
|
+
* Yields the response word by word to simulate streaming.
|
|
15169
|
+
*
|
|
15170
|
+
* @param prompt - The prompt (recorded in history).
|
|
15171
|
+
* @param opts - Optional query configuration.
|
|
15172
|
+
* @yields Words from the mock response.
|
|
15173
|
+
*/
|
|
15174
|
+
async *streamQuery(prompt, opts) {
|
|
15175
|
+
const response = await this.query(prompt, opts);
|
|
15176
|
+
const words = response.content.split(" ");
|
|
15177
|
+
for (let i = 0; i < words.length; i++) {
|
|
15178
|
+
yield words[i] + (i < words.length - 1 ? " " : "");
|
|
15179
|
+
}
|
|
15180
|
+
}
|
|
15181
|
+
};
|
|
15182
|
+
|
|
15183
|
+
// src/llm/groq.ts
|
|
15184
|
+
var import_node_fs4 = __toESM(require("node:fs"), 1);
|
|
15185
|
+
var import_node_os = __toESM(require("node:os"), 1);
|
|
15186
|
+
var import_node_path6 = __toESM(require("node:path"), 1);
|
|
15187
|
+
var DEFAULT_MODEL = "llama-3.3-70b-versatile";
|
|
15188
|
+
var BASE_URL = "https://api.groq.com/openai/v1/chat/completions";
|
|
15189
|
+
var GroqClient = class _GroqClient {
|
|
15190
|
+
/** The resolved API key. */
|
|
15191
|
+
apiKey;
|
|
15192
|
+
/** The default model used when none is specified per-call. */
|
|
15193
|
+
defaultModel;
|
|
15194
|
+
timeoutMs;
|
|
15195
|
+
rateLimiter;
|
|
15196
|
+
constructor(opts) {
|
|
15197
|
+
this.defaultModel = opts?.defaultModel ?? process.env["GROQ_DEFAULT_MODEL"] ?? DEFAULT_MODEL;
|
|
15198
|
+
const envKey = process.env["GROQ_API_KEY"]?.trim();
|
|
15199
|
+
const resolved = opts?.apiKey ?? envKey ?? _GroqClient.loadKeyFile();
|
|
15200
|
+
if (!resolved) {
|
|
15201
|
+
throw new LlmAuthenticationError(
|
|
15202
|
+
"No Groq API key. Set GROQ_API_KEY, pass apiKey, or create ~/.groq"
|
|
15203
|
+
);
|
|
15204
|
+
}
|
|
15205
|
+
this.apiKey = resolved;
|
|
15206
|
+
this.timeoutMs = opts?.timeoutMs ?? 12e4;
|
|
15207
|
+
this.rateLimiter = getGlobalRateLimiter();
|
|
15208
|
+
}
|
|
15209
|
+
/**
|
|
15210
|
+
* Load API key from ~/.groq file.
|
|
15211
|
+
*
|
|
15212
|
+
* @returns The key string, or null if the file does not exist.
|
|
15213
|
+
*/
|
|
15214
|
+
static loadKeyFile() {
|
|
15215
|
+
try {
|
|
15216
|
+
const keyPath = import_node_path6.default.join(import_node_os.default.homedir(), ".groq");
|
|
15217
|
+
if (import_node_fs4.default.existsSync(keyPath)) {
|
|
15218
|
+
return import_node_fs4.default.readFileSync(keyPath, "utf-8").trim();
|
|
15219
|
+
}
|
|
15220
|
+
} catch {
|
|
15221
|
+
}
|
|
15222
|
+
return null;
|
|
15223
|
+
}
|
|
15224
|
+
// -- Helpers -------------------------------------------------------------
|
|
15225
|
+
estimateTokens(prompt, systemPrompt) {
|
|
15226
|
+
let total = prompt.length;
|
|
15227
|
+
if (systemPrompt)
|
|
15228
|
+
total += systemPrompt.length;
|
|
15229
|
+
return Math.max(Math.floor(total / 4), 100);
|
|
15230
|
+
}
|
|
15231
|
+
buildMessages(prompt, systemPrompt) {
|
|
15232
|
+
const messages = [];
|
|
15233
|
+
if (systemPrompt) {
|
|
15234
|
+
messages.push({ role: "system", content: systemPrompt });
|
|
15235
|
+
}
|
|
15236
|
+
messages.push({ role: "user", content: prompt });
|
|
15237
|
+
return messages;
|
|
15238
|
+
}
|
|
15239
|
+
/**
|
|
15240
|
+
* Map an HTTP error response to the appropriate LlmError subclass.
|
|
15241
|
+
*
|
|
15242
|
+
* @param status - HTTP status code.
|
|
15243
|
+
* @param body - Parsed response body (if available).
|
|
15244
|
+
* @param message - Raw error message.
|
|
15245
|
+
*/
|
|
15246
|
+
mapError(status, body, message) {
|
|
15247
|
+
if (status === 401 || status === 403) {
|
|
15248
|
+
return new LlmAuthenticationError(`Groq auth failed (${status}): ${message}`);
|
|
15249
|
+
}
|
|
15250
|
+
if (status === 429) {
|
|
15251
|
+
this.rateLimiter.recordRateLimit();
|
|
15252
|
+
return new LlmRateLimitError(`Groq rate limit exceeded: ${message}`);
|
|
15253
|
+
}
|
|
15254
|
+
if (status === 408 || status === 504) {
|
|
15255
|
+
return new LlmTimeoutError(`Groq request timed out (${status}): ${message}`);
|
|
15256
|
+
}
|
|
15257
|
+
const errorObj = body?.["error"];
|
|
15258
|
+
const code = errorObj?.["code"];
|
|
15259
|
+
if (code === "context_length_exceeded") {
|
|
15260
|
+
return new LlmContextLengthError(`Groq context length exceeded: ${message}`);
|
|
15261
|
+
}
|
|
15262
|
+
return new LlmError(`Groq API error (${status}): ${message}`);
|
|
15263
|
+
}
|
|
15264
|
+
// -- Public API ----------------------------------------------------------
|
|
15265
|
+
/**
|
|
15266
|
+
* Send a query to Groq and get a complete response.
|
|
15267
|
+
*
|
|
15268
|
+
* @param prompt - The user prompt/query.
|
|
15269
|
+
* @param opts - Optional query configuration.
|
|
15270
|
+
* @returns LlmResponse with generated content and metadata.
|
|
15271
|
+
*/
|
|
15272
|
+
async query(prompt, opts) {
|
|
15273
|
+
const useModel = opts?.model ?? this.defaultModel;
|
|
15274
|
+
const maxTokens = opts?.maxTokens ?? 4096;
|
|
15275
|
+
const temperature = opts?.temperature ?? 1;
|
|
15276
|
+
const systemPrompt = opts?.systemPrompt;
|
|
15277
|
+
const estimated = this.estimateTokens(prompt, systemPrompt);
|
|
15278
|
+
await this.rateLimiter.acquire(estimated);
|
|
15279
|
+
const body = {
|
|
15280
|
+
model: useModel,
|
|
15281
|
+
messages: this.buildMessages(prompt, systemPrompt),
|
|
15282
|
+
max_tokens: maxTokens,
|
|
15283
|
+
temperature
|
|
15284
|
+
};
|
|
15285
|
+
let response;
|
|
15286
|
+
try {
|
|
15287
|
+
const controller = new AbortController();
|
|
15288
|
+
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
15289
|
+
response = await fetch(BASE_URL, {
|
|
15290
|
+
method: "POST",
|
|
15291
|
+
headers: {
|
|
15292
|
+
"Content-Type": "application/json",
|
|
15293
|
+
"Authorization": `Bearer ${this.apiKey}`
|
|
15294
|
+
},
|
|
15295
|
+
body: JSON.stringify(body),
|
|
15296
|
+
signal: controller.signal
|
|
15297
|
+
});
|
|
15298
|
+
clearTimeout(timer);
|
|
15299
|
+
} catch (err) {
|
|
15300
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
15301
|
+
throw new LlmTimeoutError(`Groq request timed out after ${this.timeoutMs}ms`);
|
|
15302
|
+
}
|
|
15303
|
+
throw new LlmError(`Groq network error: ${String(err)}`);
|
|
15304
|
+
}
|
|
15305
|
+
if (!response.ok) {
|
|
15306
|
+
let errorBody = null;
|
|
15307
|
+
let errorMessage = response.statusText;
|
|
15308
|
+
try {
|
|
15309
|
+
errorBody = await response.json();
|
|
15310
|
+
const errorObj = errorBody?.["error"];
|
|
15311
|
+
errorMessage = errorObj?.["message"] ?? errorMessage;
|
|
15312
|
+
} catch {
|
|
15313
|
+
}
|
|
15314
|
+
throw this.mapError(response.status, errorBody, errorMessage);
|
|
15315
|
+
}
|
|
15316
|
+
const data = await response.json();
|
|
15317
|
+
this.rateLimiter.recordSuccess();
|
|
15318
|
+
const choices = data["choices"];
|
|
15319
|
+
const firstChoice = choices?.[0];
|
|
15320
|
+
const messageObj = firstChoice?.["message"];
|
|
15321
|
+
const content = messageObj?.["content"] ?? "";
|
|
15322
|
+
const usageObj = data["usage"];
|
|
15323
|
+
let usage;
|
|
15324
|
+
if (usageObj) {
|
|
15325
|
+
usage = {
|
|
15326
|
+
input_tokens: usageObj["prompt_tokens"] ?? 0,
|
|
15327
|
+
output_tokens: usageObj["completion_tokens"] ?? 0
|
|
15328
|
+
};
|
|
15329
|
+
}
|
|
15330
|
+
return {
|
|
15331
|
+
content,
|
|
15332
|
+
model: data["model"] ?? useModel,
|
|
15333
|
+
usage
|
|
15334
|
+
};
|
|
15335
|
+
}
|
|
15336
|
+
/**
|
|
15337
|
+
* Stream a query response chunk by chunk.
|
|
15338
|
+
*
|
|
15339
|
+
* Uses Server-Sent Events (SSE) streaming from the Groq API.
|
|
15340
|
+
*
|
|
15341
|
+
* @param prompt - The user prompt/query.
|
|
15342
|
+
* @param opts - Optional query configuration.
|
|
15343
|
+
* @yields Text chunks as they arrive from the API.
|
|
15344
|
+
*/
|
|
15345
|
+
async *streamQuery(prompt, opts) {
|
|
15346
|
+
const useModel = opts?.model ?? this.defaultModel;
|
|
15347
|
+
const maxTokens = opts?.maxTokens ?? 4096;
|
|
15348
|
+
const temperature = opts?.temperature ?? 1;
|
|
15349
|
+
const systemPrompt = opts?.systemPrompt;
|
|
15350
|
+
const estimated = this.estimateTokens(prompt, systemPrompt);
|
|
15351
|
+
await this.rateLimiter.acquire(estimated);
|
|
15352
|
+
const body = {
|
|
15353
|
+
model: useModel,
|
|
15354
|
+
messages: this.buildMessages(prompt, systemPrompt),
|
|
15355
|
+
max_tokens: maxTokens,
|
|
15356
|
+
temperature,
|
|
15357
|
+
stream: true
|
|
15358
|
+
};
|
|
15359
|
+
let response;
|
|
15360
|
+
try {
|
|
15361
|
+
const controller = new AbortController();
|
|
15362
|
+
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
15363
|
+
response = await fetch(BASE_URL, {
|
|
15364
|
+
method: "POST",
|
|
15365
|
+
headers: {
|
|
15366
|
+
"Content-Type": "application/json",
|
|
15367
|
+
"Authorization": `Bearer ${this.apiKey}`
|
|
15368
|
+
},
|
|
15369
|
+
body: JSON.stringify(body),
|
|
15370
|
+
signal: controller.signal
|
|
15371
|
+
});
|
|
15372
|
+
clearTimeout(timer);
|
|
15373
|
+
} catch (err) {
|
|
15374
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
15375
|
+
throw new LlmTimeoutError(`Groq request timed out after ${this.timeoutMs}ms`);
|
|
15376
|
+
}
|
|
15377
|
+
throw new LlmError(`Groq network error: ${String(err)}`);
|
|
15378
|
+
}
|
|
15379
|
+
if (!response.ok) {
|
|
15380
|
+
let errorBody = null;
|
|
15381
|
+
let errorMessage = response.statusText;
|
|
15382
|
+
try {
|
|
15383
|
+
errorBody = await response.json();
|
|
15384
|
+
const errorObj = errorBody?.["error"];
|
|
15385
|
+
errorMessage = errorObj?.["message"] ?? errorMessage;
|
|
15386
|
+
} catch {
|
|
15387
|
+
}
|
|
15388
|
+
throw this.mapError(response.status, errorBody, errorMessage);
|
|
15389
|
+
}
|
|
15390
|
+
if (!response.body) {
|
|
15391
|
+
throw new LlmError("Groq streaming response has no body");
|
|
15392
|
+
}
|
|
15393
|
+
const reader = response.body.getReader();
|
|
15394
|
+
const decoder = new TextDecoder();
|
|
15395
|
+
let buffer = "";
|
|
15396
|
+
let streamCompleted = false;
|
|
15397
|
+
try {
|
|
15398
|
+
for (; ; ) {
|
|
15399
|
+
const { done, value } = await reader.read();
|
|
15400
|
+
if (done)
|
|
15401
|
+
break;
|
|
15402
|
+
buffer += decoder.decode(value, { stream: true });
|
|
15403
|
+
const lines = buffer.split("\n");
|
|
15404
|
+
buffer = lines.pop() ?? "";
|
|
15405
|
+
for (const line of lines) {
|
|
15406
|
+
const trimmed = line.trim();
|
|
15407
|
+
if (!trimmed || !trimmed.startsWith("data: "))
|
|
15408
|
+
continue;
|
|
15409
|
+
const payload = trimmed.slice(6);
|
|
15410
|
+
if (payload === "[DONE]") {
|
|
15411
|
+
streamCompleted = true;
|
|
15412
|
+
return;
|
|
15413
|
+
}
|
|
15414
|
+
try {
|
|
15415
|
+
const chunk = JSON.parse(payload);
|
|
15416
|
+
const choices = chunk["choices"];
|
|
15417
|
+
const delta = choices?.[0]?.["delta"];
|
|
15418
|
+
const content = delta?.["content"];
|
|
15419
|
+
if (content)
|
|
15420
|
+
yield content;
|
|
15421
|
+
} catch {
|
|
15422
|
+
}
|
|
15423
|
+
}
|
|
15424
|
+
}
|
|
15425
|
+
streamCompleted = true;
|
|
15426
|
+
} finally {
|
|
15427
|
+
reader.releaseLock();
|
|
15428
|
+
if (streamCompleted)
|
|
15429
|
+
this.rateLimiter.recordSuccess();
|
|
15430
|
+
}
|
|
15431
|
+
}
|
|
15432
|
+
};
|
|
15433
|
+
|
|
15434
|
+
// src/llm/anthropic.ts
|
|
15435
|
+
var import_node_fs5 = __toESM(require("node:fs"), 1);
|
|
15436
|
+
var import_node_os2 = __toESM(require("node:os"), 1);
|
|
15437
|
+
var import_node_path7 = __toESM(require("node:path"), 1);
|
|
15438
|
+
var DEFAULT_MODEL2 = "claude-sonnet-4-20250514";
|
|
15439
|
+
var BASE_URL2 = "https://api.anthropic.com/v1/messages";
|
|
15440
|
+
var ANTHROPIC_VERSION = "2023-06-01";
|
|
15441
|
+
var AnthropicClient = class _AnthropicClient {
|
|
15442
|
+
/** The resolved API key. */
|
|
15443
|
+
apiKey;
|
|
15444
|
+
/** The default model used when none is specified per-call. */
|
|
15445
|
+
defaultModel;
|
|
15446
|
+
timeoutMs;
|
|
15447
|
+
rateLimiter;
|
|
15448
|
+
constructor(opts) {
|
|
15449
|
+
this.defaultModel = opts?.defaultModel ?? process.env["ANTHROPIC_DEFAULT_MODEL"] ?? DEFAULT_MODEL2;
|
|
15450
|
+
const envKey = process.env["ANTHROPIC_API_KEY"]?.trim();
|
|
15451
|
+
const resolved = opts?.apiKey ?? envKey ?? _AnthropicClient.loadKeyFile();
|
|
15452
|
+
if (!resolved) {
|
|
15453
|
+
throw new LlmAuthenticationError(
|
|
15454
|
+
"No Anthropic API key. Set ANTHROPIC_API_KEY, pass apiKey, or create ~/.anthropic"
|
|
15455
|
+
);
|
|
15456
|
+
}
|
|
15457
|
+
this.apiKey = resolved;
|
|
15458
|
+
this.timeoutMs = opts?.timeoutMs ?? 3e5;
|
|
15459
|
+
this.rateLimiter = getGlobalRateLimiter();
|
|
15460
|
+
}
|
|
15461
|
+
/**
|
|
15462
|
+
* Load API key from ~/.anthropic file.
|
|
15463
|
+
*
|
|
15464
|
+
* @returns The key string, or null if the file does not exist.
|
|
15465
|
+
*/
|
|
15466
|
+
static loadKeyFile() {
|
|
15467
|
+
try {
|
|
15468
|
+
const keyPath = import_node_path7.default.join(import_node_os2.default.homedir(), ".anthropic");
|
|
15469
|
+
if (import_node_fs5.default.existsSync(keyPath)) {
|
|
15470
|
+
return import_node_fs5.default.readFileSync(keyPath, "utf-8").trim();
|
|
15471
|
+
}
|
|
15472
|
+
} catch {
|
|
15473
|
+
}
|
|
15474
|
+
return null;
|
|
15475
|
+
}
|
|
15476
|
+
// -- Helpers -------------------------------------------------------------
|
|
15477
|
+
estimateTokens(prompt, systemPrompt) {
|
|
15478
|
+
let total = prompt.length;
|
|
15479
|
+
if (systemPrompt)
|
|
15480
|
+
total += systemPrompt.length;
|
|
15481
|
+
return Math.max(Math.floor(total / 4), 100);
|
|
15482
|
+
}
|
|
15483
|
+
/**
|
|
15484
|
+
* Map an HTTP error response to the appropriate LlmError subclass.
|
|
15485
|
+
*
|
|
15486
|
+
* @param status - HTTP status code.
|
|
15487
|
+
* @param body - Parsed response body (if available).
|
|
15488
|
+
* @param message - Raw error message.
|
|
15489
|
+
*/
|
|
15490
|
+
mapError(status, body, message) {
|
|
15491
|
+
if (status === 401 || status === 403) {
|
|
15492
|
+
return new LlmAuthenticationError(
|
|
15493
|
+
`Anthropic auth failed (${status}): ${message}`
|
|
15494
|
+
);
|
|
15495
|
+
}
|
|
15496
|
+
if (status === 429) {
|
|
15497
|
+
this.rateLimiter.recordRateLimit();
|
|
15498
|
+
return new LlmRateLimitError(
|
|
15499
|
+
`Anthropic rate limit exceeded: ${message}`
|
|
15500
|
+
);
|
|
15501
|
+
}
|
|
15502
|
+
if (status === 408 || status === 504) {
|
|
15503
|
+
return new LlmTimeoutError(
|
|
15504
|
+
`Anthropic request timed out (${status}): ${message}`
|
|
15505
|
+
);
|
|
15506
|
+
}
|
|
15507
|
+
const errorType = body?.["error"];
|
|
15508
|
+
const errType = errorType?.["type"];
|
|
15509
|
+
if (errType === "invalid_request_error") {
|
|
15510
|
+
const msg = message.toLowerCase();
|
|
15511
|
+
if (msg.includes("context") || msg.includes("token")) {
|
|
15512
|
+
return new LlmContextLengthError(
|
|
15513
|
+
`Anthropic context length exceeded: ${message}`
|
|
15514
|
+
);
|
|
15515
|
+
}
|
|
15516
|
+
}
|
|
15517
|
+
const lowerMsg = message.toLowerCase();
|
|
15518
|
+
if (lowerMsg.includes("credit balance") || lowerMsg.includes("billing")) {
|
|
15519
|
+
return new LlmAuthenticationError(
|
|
15520
|
+
`Anthropic billing error: ${message}`
|
|
15521
|
+
);
|
|
15522
|
+
}
|
|
15523
|
+
return new LlmError(`Anthropic API error (${status}): ${message}`);
|
|
15524
|
+
}
|
|
15525
|
+
// -- Public API ----------------------------------------------------------
|
|
15526
|
+
/**
|
|
15527
|
+
* Send a query to Anthropic and get a complete response.
|
|
15528
|
+
*
|
|
15529
|
+
* System prompts are sent via the top-level `system` parameter rather
|
|
15530
|
+
* than as a system message in the messages array, per the Anthropic API
|
|
15531
|
+
* specification.
|
|
15532
|
+
*
|
|
15533
|
+
* @param prompt - The user prompt/query.
|
|
15534
|
+
* @param opts - Optional query configuration.
|
|
15535
|
+
* @returns LlmResponse with generated content and metadata.
|
|
15536
|
+
*/
|
|
15537
|
+
async query(prompt, opts) {
|
|
15538
|
+
const useModel = opts?.model ?? this.defaultModel;
|
|
15539
|
+
const maxTokens = opts?.maxTokens ?? 4096;
|
|
15540
|
+
const temperature = opts?.temperature ?? 1;
|
|
15541
|
+
const systemPrompt = opts?.systemPrompt;
|
|
15542
|
+
const estimated = this.estimateTokens(prompt, systemPrompt);
|
|
15543
|
+
await this.rateLimiter.acquire(estimated);
|
|
15544
|
+
const requestBody = {
|
|
15545
|
+
model: useModel,
|
|
15546
|
+
messages: [{ role: "user", content: prompt }],
|
|
15547
|
+
max_tokens: maxTokens,
|
|
15548
|
+
temperature
|
|
15549
|
+
};
|
|
15550
|
+
if (systemPrompt) {
|
|
15551
|
+
requestBody["system"] = systemPrompt;
|
|
15552
|
+
}
|
|
15553
|
+
let response;
|
|
15554
|
+
try {
|
|
15555
|
+
const controller = new AbortController();
|
|
15556
|
+
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
15557
|
+
response = await fetch(BASE_URL2, {
|
|
15558
|
+
method: "POST",
|
|
15559
|
+
headers: {
|
|
15560
|
+
"Content-Type": "application/json",
|
|
15561
|
+
"x-api-key": this.apiKey,
|
|
15562
|
+
"anthropic-version": ANTHROPIC_VERSION
|
|
15563
|
+
},
|
|
15564
|
+
body: JSON.stringify(requestBody),
|
|
15565
|
+
signal: controller.signal
|
|
15566
|
+
});
|
|
15567
|
+
clearTimeout(timer);
|
|
15568
|
+
} catch (err) {
|
|
15569
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
15570
|
+
throw new LlmTimeoutError(
|
|
15571
|
+
`Anthropic request timed out after ${this.timeoutMs}ms`
|
|
15572
|
+
);
|
|
15573
|
+
}
|
|
15574
|
+
throw new LlmError(`Anthropic network error: ${String(err)}`);
|
|
15575
|
+
}
|
|
15576
|
+
if (!response.ok) {
|
|
15577
|
+
let errorBody = null;
|
|
15578
|
+
let errorMessage = response.statusText;
|
|
15579
|
+
try {
|
|
15580
|
+
errorBody = await response.json();
|
|
15581
|
+
const errorObj = errorBody?.["error"];
|
|
15582
|
+
errorMessage = errorObj?.["message"] ?? errorMessage;
|
|
15583
|
+
} catch {
|
|
15584
|
+
}
|
|
15585
|
+
throw this.mapError(response.status, errorBody, errorMessage);
|
|
15586
|
+
}
|
|
15587
|
+
const data = await response.json();
|
|
15588
|
+
this.rateLimiter.recordSuccess();
|
|
15589
|
+
const contentBlocks = data["content"];
|
|
15590
|
+
const textParts = [];
|
|
15591
|
+
if (contentBlocks) {
|
|
15592
|
+
for (const block of contentBlocks) {
|
|
15593
|
+
if (block["type"] === "text" && typeof block["text"] === "string") {
|
|
15594
|
+
textParts.push(block["text"]);
|
|
15595
|
+
}
|
|
15596
|
+
}
|
|
15597
|
+
}
|
|
15598
|
+
const content = textParts.join("").trim();
|
|
15599
|
+
const usageObj = data["usage"];
|
|
15600
|
+
const inputTokens = usageObj?.["input_tokens"] ?? 0;
|
|
15601
|
+
const outputTokens = usageObj?.["output_tokens"] ?? 0;
|
|
15602
|
+
return {
|
|
15603
|
+
content,
|
|
15604
|
+
model: data["model"] ?? useModel,
|
|
15605
|
+
usage: {
|
|
15606
|
+
input_tokens: inputTokens,
|
|
15607
|
+
output_tokens: outputTokens
|
|
15608
|
+
}
|
|
15609
|
+
};
|
|
15610
|
+
}
|
|
15611
|
+
/**
|
|
15612
|
+
* Stream a query response chunk by chunk.
|
|
15613
|
+
*
|
|
15614
|
+
* Uses Server-Sent Events (SSE) streaming from the Anthropic API.
|
|
15615
|
+
* System prompts are sent via the top-level `system` parameter.
|
|
15616
|
+
*
|
|
15617
|
+
* @param prompt - The user prompt/query.
|
|
15618
|
+
* @param opts - Optional query configuration.
|
|
15619
|
+
* @yields Text chunks as they arrive from the API.
|
|
15620
|
+
*/
|
|
15621
|
+
async *streamQuery(prompt, opts) {
|
|
15622
|
+
const useModel = opts?.model ?? this.defaultModel;
|
|
15623
|
+
const maxTokens = opts?.maxTokens ?? 4096;
|
|
15624
|
+
const temperature = opts?.temperature ?? 1;
|
|
15625
|
+
const systemPrompt = opts?.systemPrompt;
|
|
15626
|
+
const estimated = this.estimateTokens(prompt, systemPrompt);
|
|
15627
|
+
await this.rateLimiter.acquire(estimated);
|
|
15628
|
+
const requestBody = {
|
|
15629
|
+
model: useModel,
|
|
15630
|
+
messages: [{ role: "user", content: prompt }],
|
|
15631
|
+
max_tokens: maxTokens,
|
|
15632
|
+
temperature,
|
|
15633
|
+
stream: true
|
|
15634
|
+
};
|
|
15635
|
+
if (systemPrompt) {
|
|
15636
|
+
requestBody["system"] = systemPrompt;
|
|
15637
|
+
}
|
|
15638
|
+
let response;
|
|
15639
|
+
try {
|
|
15640
|
+
const controller = new AbortController();
|
|
15641
|
+
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
15642
|
+
response = await fetch(BASE_URL2, {
|
|
15643
|
+
method: "POST",
|
|
15644
|
+
headers: {
|
|
15645
|
+
"Content-Type": "application/json",
|
|
15646
|
+
"x-api-key": this.apiKey,
|
|
15647
|
+
"anthropic-version": ANTHROPIC_VERSION
|
|
15648
|
+
},
|
|
15649
|
+
body: JSON.stringify(requestBody),
|
|
15650
|
+
signal: controller.signal
|
|
15651
|
+
});
|
|
15652
|
+
clearTimeout(timer);
|
|
15653
|
+
} catch (err) {
|
|
15654
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
15655
|
+
throw new LlmTimeoutError(
|
|
15656
|
+
`Anthropic request timed out after ${this.timeoutMs}ms`
|
|
15657
|
+
);
|
|
15658
|
+
}
|
|
15659
|
+
throw new LlmError(`Anthropic network error: ${String(err)}`);
|
|
15660
|
+
}
|
|
15661
|
+
if (!response.ok) {
|
|
15662
|
+
let errorBody = null;
|
|
15663
|
+
let errorMessage = response.statusText;
|
|
15664
|
+
try {
|
|
15665
|
+
errorBody = await response.json();
|
|
15666
|
+
const errorObj = errorBody?.["error"];
|
|
15667
|
+
errorMessage = errorObj?.["message"] ?? errorMessage;
|
|
15668
|
+
} catch {
|
|
15669
|
+
}
|
|
15670
|
+
throw this.mapError(response.status, errorBody, errorMessage);
|
|
15671
|
+
}
|
|
15672
|
+
if (!response.body) {
|
|
15673
|
+
throw new LlmError("Anthropic streaming response has no body");
|
|
15674
|
+
}
|
|
15675
|
+
const reader = response.body.getReader();
|
|
15676
|
+
const decoder = new TextDecoder();
|
|
15677
|
+
let buffer = "";
|
|
15678
|
+
let streamCompleted = false;
|
|
15679
|
+
try {
|
|
15680
|
+
for (; ; ) {
|
|
15681
|
+
const { done, value } = await reader.read();
|
|
15682
|
+
if (done)
|
|
15683
|
+
break;
|
|
15684
|
+
buffer += decoder.decode(value, { stream: true });
|
|
15685
|
+
const lines = buffer.split("\n");
|
|
15686
|
+
buffer = lines.pop() ?? "";
|
|
15687
|
+
for (const line of lines) {
|
|
15688
|
+
const trimmed = line.trim();
|
|
15689
|
+
if (!trimmed || !trimmed.startsWith("data: "))
|
|
15690
|
+
continue;
|
|
15691
|
+
const payload = trimmed.slice(6);
|
|
15692
|
+
try {
|
|
15693
|
+
const event = JSON.parse(payload);
|
|
15694
|
+
const eventType = event["type"];
|
|
15695
|
+
if (eventType === "content_block_delta") {
|
|
15696
|
+
const delta = event["delta"];
|
|
15697
|
+
if (delta?.["type"] === "text_delta") {
|
|
15698
|
+
const text = delta["text"];
|
|
15699
|
+
if (text)
|
|
15700
|
+
yield text;
|
|
15701
|
+
}
|
|
15702
|
+
} else if (eventType === "message_stop") {
|
|
15703
|
+
streamCompleted = true;
|
|
15704
|
+
return;
|
|
15705
|
+
}
|
|
15706
|
+
} catch {
|
|
15707
|
+
}
|
|
15708
|
+
}
|
|
15709
|
+
}
|
|
15710
|
+
streamCompleted = true;
|
|
15711
|
+
} finally {
|
|
15712
|
+
reader.releaseLock();
|
|
15713
|
+
if (streamCompleted)
|
|
15714
|
+
this.rateLimiter.recordSuccess();
|
|
15715
|
+
}
|
|
15716
|
+
}
|
|
15717
|
+
};
|
|
15718
|
+
|
|
15719
|
+
// src/llm/factory.ts
|
|
15720
|
+
function createLlmClient(opts) {
|
|
15721
|
+
const clientType = (opts?.clientType ?? process.env["LLM_CLIENT_TYPE"] ?? "mock").toLowerCase();
|
|
15722
|
+
const model = opts?.model ?? process.env["LLM_DEFAULT_MODEL"];
|
|
15723
|
+
if (clientType === "mock") {
|
|
15724
|
+
return new MockLlmClient({
|
|
15725
|
+
defaultModel: model ?? "mock-model"
|
|
15726
|
+
});
|
|
15727
|
+
}
|
|
15728
|
+
if (clientType === "groq") {
|
|
15729
|
+
return new GroqClient({
|
|
15730
|
+
apiKey: opts?.apiKey,
|
|
15731
|
+
defaultModel: model,
|
|
15732
|
+
timeoutMs: opts?.timeoutMs
|
|
15733
|
+
});
|
|
15734
|
+
}
|
|
15735
|
+
if (clientType === "anthropic") {
|
|
15736
|
+
return new AnthropicClient({
|
|
15737
|
+
apiKey: opts?.apiKey,
|
|
15738
|
+
defaultModel: model,
|
|
15739
|
+
timeoutMs: opts?.timeoutMs
|
|
15740
|
+
});
|
|
15741
|
+
}
|
|
15742
|
+
throw new Error(
|
|
15743
|
+
`Unknown LLM client type: "${clientType}". Valid types: "groq", "anthropic", "mock"`
|
|
15744
|
+
);
|
|
15745
|
+
}
|
|
15746
|
+
|
|
14297
15747
|
// src/index.ts
|
|
14298
|
-
var version = "0.
|
|
15748
|
+
var version = "0.6.0";
|
|
14299
15749
|
// Annotate the CommonJS export names for ESM import in node:
|
|
14300
15750
|
0 && (module.exports = {
|
|
14301
15751
|
ACKLifecycleManager,
|
|
15752
|
+
AGENT_STATE_FAILED,
|
|
15753
|
+
AGENT_STATE_INITIALIZING,
|
|
15754
|
+
AGENT_STATE_RUNNING,
|
|
15755
|
+
AGENT_STATE_SHUTTING_DOWN,
|
|
14302
15756
|
AckStage,
|
|
14303
15757
|
ActivityBuffer,
|
|
14304
15758
|
ActivityBufferSync,
|
|
14305
15759
|
ActivityClient,
|
|
14306
15760
|
AgentState,
|
|
14307
15761
|
AgentStateMachine,
|
|
15762
|
+
AnthropicClient,
|
|
14308
15763
|
ArtifactType,
|
|
14309
15764
|
BaseClient,
|
|
14310
15765
|
BordaCountAggregator,
|
|
14311
15766
|
BufferFullError,
|
|
14312
15767
|
CT_AGENT_REPORT_V1,
|
|
14313
15768
|
CT_SCHEDULER_COMMAND_V1,
|
|
15769
|
+
CancellationManager,
|
|
15770
|
+
CancellationValidationError,
|
|
14314
15771
|
CommunicationClass,
|
|
14315
15772
|
ConfidenceWeightedAggregator,
|
|
14316
15773
|
ConnectorClient,
|
|
14317
15774
|
DEDUP_WINDOW_S,
|
|
14318
15775
|
DEFAULT_ACK_TIMEOUT_MS,
|
|
15776
|
+
DEFAULT_BACKOFF_MULTIPLIER,
|
|
15777
|
+
DEFAULT_EFFECTIVE_MAX_REDIRECTS,
|
|
14319
15778
|
DEFAULT_ESCALATION_POLICY,
|
|
14320
15779
|
DEFAULT_EXECUTION_POLICY,
|
|
15780
|
+
DEFAULT_INITIAL_BACKOFF_MS,
|
|
15781
|
+
DEFAULT_MAX_BACKOFF_MS,
|
|
15782
|
+
DEFAULT_MAX_REDIRECTS,
|
|
15783
|
+
DEFAULT_MAX_RETRIES_ON_OVERLOADED,
|
|
14321
15784
|
DEFAULT_NEGOTIATION_POLICY,
|
|
15785
|
+
DEFAULT_PEER_LIVENESS_THRESHOLD_MS,
|
|
14322
15786
|
DebateIntensity,
|
|
14323
15787
|
DecisionOutcome,
|
|
14324
15788
|
DefaultWorktreePolicy,
|
|
@@ -14327,6 +15791,9 @@ var version = "0.5.0";
|
|
|
14327
15791
|
ErrorCode,
|
|
14328
15792
|
ErrorCodeMapper,
|
|
14329
15793
|
FileBackend,
|
|
15794
|
+
GatewayRedirectEmitter,
|
|
15795
|
+
GatewayValidationError,
|
|
15796
|
+
GroqClient,
|
|
14330
15797
|
HITLClient,
|
|
14331
15798
|
HandoffClient,
|
|
14332
15799
|
HandoffStatus,
|
|
@@ -14341,11 +15808,19 @@ var version = "0.5.0";
|
|
|
14341
15808
|
JSONFilePersistence,
|
|
14342
15809
|
JsonFilePolicyStore,
|
|
14343
15810
|
KeyringBackend,
|
|
15811
|
+
LlmAuthenticationError,
|
|
15812
|
+
LlmContextLengthError,
|
|
15813
|
+
LlmError,
|
|
15814
|
+
LlmRateLimitError,
|
|
15815
|
+
LlmTimeoutError,
|
|
14344
15816
|
LoggingClient,
|
|
15817
|
+
MIN_GRACE_PERIOD_MS,
|
|
14345
15818
|
MajorityVoteAggregator,
|
|
14346
15819
|
MaxEntriesStrategy,
|
|
14347
15820
|
MessageProcessor,
|
|
14348
15821
|
MessageType,
|
|
15822
|
+
MockLlmClient,
|
|
15823
|
+
NON_SERVING_AGENT_STATES,
|
|
14349
15824
|
NegotiationClient,
|
|
14350
15825
|
NegotiationError,
|
|
14351
15826
|
NegotiationRoomClient,
|
|
@@ -14354,12 +15829,16 @@ var version = "0.5.0";
|
|
|
14354
15829
|
NegotiationValidationError,
|
|
14355
15830
|
NoOpAuditor,
|
|
14356
15831
|
NodeStatus,
|
|
15832
|
+
PeerSelector,
|
|
14357
15833
|
PermissionError,
|
|
14358
15834
|
PersistentActivityBuffer,
|
|
14359
15835
|
PersistentWorktreeState,
|
|
14360
15836
|
PolicyStoreError,
|
|
14361
15837
|
PolicyViolationError,
|
|
14362
15838
|
PreemptionError,
|
|
15839
|
+
REGISTRATION_TYPE_STANDARD_AGENT,
|
|
15840
|
+
REGISTRATION_TYPE_SWARM_GATEWAY,
|
|
15841
|
+
RETRY_AFTER_JITTER_RATIO,
|
|
14363
15842
|
ReasoningClient,
|
|
14364
15843
|
RegistryClient,
|
|
14365
15844
|
Resolver,
|
|
@@ -14382,6 +15861,7 @@ var version = "0.5.0";
|
|
|
14382
15861
|
StateTransitionError,
|
|
14383
15862
|
Sw4rmError,
|
|
14384
15863
|
TimeoutError,
|
|
15864
|
+
TokenBucket,
|
|
14385
15865
|
ToolClient,
|
|
14386
15866
|
TriggerType,
|
|
14387
15867
|
ValidationError,
|
|
@@ -14397,8 +15877,10 @@ var version = "0.5.0";
|
|
|
14397
15877
|
aggregateVotes,
|
|
14398
15878
|
buildAckEnvelope,
|
|
14399
15879
|
buildEnvelope,
|
|
15880
|
+
buildRateLimiterConfig,
|
|
14400
15881
|
computeEnvelopeHash,
|
|
14401
15882
|
computeIdempotencyToken,
|
|
15883
|
+
createLlmClient,
|
|
14402
15884
|
createResilientIncomingStream,
|
|
14403
15885
|
createSimpleProof,
|
|
14404
15886
|
decodeAgentReportV1,
|
|
@@ -14407,10 +15889,12 @@ var version = "0.5.0";
|
|
|
14407
15889
|
defaultEndpoints,
|
|
14408
15890
|
defaultRetryPolicy,
|
|
14409
15891
|
defaultSW4RMConfig,
|
|
15892
|
+
delegateToSwarm,
|
|
14410
15893
|
durationToMs,
|
|
14411
15894
|
encodeSchedulerCommandV1,
|
|
14412
15895
|
getConfig,
|
|
14413
15896
|
getDefaultStore,
|
|
15897
|
+
getGlobalRateLimiter,
|
|
14414
15898
|
getValidTransitions,
|
|
14415
15899
|
isTerminalEnvelopeState,
|
|
14416
15900
|
isValidTransition,
|
|
@@ -14425,6 +15909,7 @@ var version = "0.5.0";
|
|
|
14425
15909
|
parseNegotiationEvent,
|
|
14426
15910
|
resetConfig,
|
|
14427
15911
|
resetDefaultStore,
|
|
15912
|
+
resetGlobalRateLimiter,
|
|
14428
15913
|
selectBackend,
|
|
14429
15914
|
sendMessageWithAck,
|
|
14430
15915
|
setConfig,
|