replicas-engine 0.1.545 → 0.1.546
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/index.js +85 -36
- package/package.json +1 -1
package/dist/src/index.js
CHANGED
|
@@ -702,7 +702,7 @@ var WORKSPACE_SIZES = ["small", "large"];
|
|
|
702
702
|
var INVALID_WORKSPACE_SIZE_ERROR = `Invalid size: must be one of ${WORKSPACE_SIZES.join(", ")}`;
|
|
703
703
|
|
|
704
704
|
// ../shared/src/e2b.ts
|
|
705
|
-
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-08-02-
|
|
705
|
+
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-08-02-v2";
|
|
706
706
|
|
|
707
707
|
// ../shared/src/runtime-env.ts
|
|
708
708
|
function shellQuotePosix(value) {
|
|
@@ -2772,6 +2772,7 @@ var DEFAULT_USER_PREFERENCES = {
|
|
|
2772
2772
|
default_agent: "codex",
|
|
2773
2773
|
default_model: null,
|
|
2774
2774
|
cursor_models: null,
|
|
2775
|
+
openrouter_models: null,
|
|
2775
2776
|
close_workspace_on_pr_close: true,
|
|
2776
2777
|
close_workspace_on_pr_merge: true,
|
|
2777
2778
|
default_environment_id: null,
|
|
@@ -5258,6 +5259,18 @@ var MonolithService = class {
|
|
|
5258
5259
|
return null;
|
|
5259
5260
|
}
|
|
5260
5261
|
}
|
|
5262
|
+
async getOpenRouterModels() {
|
|
5263
|
+
try {
|
|
5264
|
+
const response = await monolithRequest("/v1/engine/openrouter-models", { method: "GET" });
|
|
5265
|
+
if (!response.ok) {
|
|
5266
|
+
return null;
|
|
5267
|
+
}
|
|
5268
|
+
const body = await response.json();
|
|
5269
|
+
return isRecord(body) && Array.isArray(body.models) && body.models.every((model) => typeof model === "string") ? body.models : null;
|
|
5270
|
+
} catch {
|
|
5271
|
+
return null;
|
|
5272
|
+
}
|
|
5273
|
+
}
|
|
5261
5274
|
async sendEvent(event) {
|
|
5262
5275
|
if (!ENGINE_ENV.WORKSPACE_ID) {
|
|
5263
5276
|
return;
|
|
@@ -10263,7 +10276,7 @@ var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
|
|
|
10263
10276
|
var MIN_CODEX_CLI_VERSION = "0.144.6";
|
|
10264
10277
|
var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
|
|
10265
10278
|
var codexCliVersionEnsured = null;
|
|
10266
|
-
var ENGINE_PACKAGE_VERSION = "0.1.
|
|
10279
|
+
var ENGINE_PACKAGE_VERSION = "0.1.546";
|
|
10267
10280
|
var INITIALIZE_METHOD = "initialize";
|
|
10268
10281
|
var INITIALIZED_NOTIFICATION = "initialized";
|
|
10269
10282
|
var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
|
|
@@ -12887,6 +12900,25 @@ import {
|
|
|
12887
12900
|
createOpencodeClient,
|
|
12888
12901
|
createOpencodeServer
|
|
12889
12902
|
} from "@opencode-ai/sdk/v2";
|
|
12903
|
+
|
|
12904
|
+
// src/services/openrouter-models-service.ts
|
|
12905
|
+
var OPENROUTER_MODELS_CACHE_MS = 6e4;
|
|
12906
|
+
var OPENROUTER_MODELS_STALE_GRACE_MS = 10 * 6e4;
|
|
12907
|
+
var cache = null;
|
|
12908
|
+
async function getAllowedOpenRouterModels() {
|
|
12909
|
+
const now = Date.now();
|
|
12910
|
+
if (cache && now - cache.fetchedAt < OPENROUTER_MODELS_CACHE_MS) return cache.models;
|
|
12911
|
+
const models = await monolithService.getOpenRouterModels();
|
|
12912
|
+
if (models?.length) {
|
|
12913
|
+
cache = { models, fetchedAt: now };
|
|
12914
|
+
return models;
|
|
12915
|
+
}
|
|
12916
|
+
if (cache && now - cache.fetchedAt < OPENROUTER_MODELS_STALE_GRACE_MS) return cache.models;
|
|
12917
|
+
cache = null;
|
|
12918
|
+
throw new Error("Could not load the organization's allowed OpenRouter models; refusing to run an unverified model.");
|
|
12919
|
+
}
|
|
12920
|
+
|
|
12921
|
+
// src/managers/opencode-manager.ts
|
|
12890
12922
|
var OPENCODE_SHIM_DIR = dirname6(fileURLToPath(new URL("../../scripts/opencode", import.meta.url)));
|
|
12891
12923
|
var OPENCODE_CONFIG_PATH = join20(ENGINE_ENV.HOME_DIR, ".config", "opencode", "opencode.json");
|
|
12892
12924
|
var OPENCODE_FETCH_DISPATCHER = new Agent({ headersTimeout: 0, bodyTimeout: 0 });
|
|
@@ -12936,10 +12968,10 @@ async function getOpencodeProvider() {
|
|
|
12936
12968
|
if (await hasOpencodeCredentials(ASTER_PROVIDER)) return ASTER_PROVIDER;
|
|
12937
12969
|
return "openrouter";
|
|
12938
12970
|
}
|
|
12939
|
-
function getDefaultOpencodeModel(provider) {
|
|
12971
|
+
async function getDefaultOpencodeModel(provider) {
|
|
12940
12972
|
if (provider === OPENCODE_GO_PROVIDER) return DEFAULT_OPENCODE_GO_MODEL;
|
|
12941
12973
|
if (provider === ASTER_PROVIDER) return DEFAULT_ASTER_MODEL;
|
|
12942
|
-
return DEFAULT_OPENCODE_MODEL;
|
|
12974
|
+
return (await getAllowedOpenRouterModels())[0] ?? DEFAULT_OPENCODE_MODEL;
|
|
12943
12975
|
}
|
|
12944
12976
|
function getOpenCodeGoModel(model) {
|
|
12945
12977
|
return model.replace(/^[^/]+\//, "");
|
|
@@ -12986,7 +13018,7 @@ function opencodeConfig(provider, model) {
|
|
|
12986
13018
|
return config;
|
|
12987
13019
|
}
|
|
12988
13020
|
function getConfiguredOpencodeModels(model, provider) {
|
|
12989
|
-
return [.../* @__PURE__ */ new Set([model, ...provider === ASTER_PROVIDER ? ASTER_MODELS :
|
|
13021
|
+
return [.../* @__PURE__ */ new Set([model, ...provider === ASTER_PROVIDER ? ASTER_MODELS : []])];
|
|
12990
13022
|
}
|
|
12991
13023
|
function opencodeCommandToSlashCommand(command) {
|
|
12992
13024
|
return createProviderSlashCommand("opencode", command.name, command.description);
|
|
@@ -13177,7 +13209,7 @@ var OpencodeManager = class extends CodingAgentManager {
|
|
|
13177
13209
|
this.slashCommandsRequest ??= (async () => {
|
|
13178
13210
|
try {
|
|
13179
13211
|
const provider = await getOpencodeProvider();
|
|
13180
|
-
const client = await this.ensureClient(getDefaultOpencodeModel(provider), provider);
|
|
13212
|
+
const client = await this.ensureClient(await getDefaultOpencodeModel(provider), provider);
|
|
13181
13213
|
const directories = [this.workingDirectory, ...await getAgentAdditionalDirectories()];
|
|
13182
13214
|
const perDirectory = await Promise.all(directories.map(async (directory) => {
|
|
13183
13215
|
try {
|
|
@@ -13217,7 +13249,7 @@ var OpencodeManager = class extends CodingAgentManager {
|
|
|
13217
13249
|
}
|
|
13218
13250
|
this.providerId = providerId;
|
|
13219
13251
|
const configuredModel = providerId === OPENCODE_GO_PROVIDER ? getOpenCodeGoModel(model) : model;
|
|
13220
|
-
const providerModels = providerId === ASTER_PROVIDER ? ASTER_MODELS : providerId === "openrouter" ?
|
|
13252
|
+
const providerModels = providerId === ASTER_PROVIDER ? ASTER_MODELS : providerId === "openrouter" ? await getAllowedOpenRouterModels() : null;
|
|
13221
13253
|
if (providerModels && !providerModels.includes(configuredModel)) {
|
|
13222
13254
|
throw new Error(`Model ${configuredModel} is not available through ${providerId}.`);
|
|
13223
13255
|
}
|
|
@@ -13317,7 +13349,6 @@ var OpencodeManager = class extends CodingAgentManager {
|
|
|
13317
13349
|
}
|
|
13318
13350
|
async processMessageInternal(request) {
|
|
13319
13351
|
const provider = await getOpencodeProvider();
|
|
13320
|
-
const model = request.model ?? getDefaultOpencodeModel(provider);
|
|
13321
13352
|
const controller = new AbortController();
|
|
13322
13353
|
const linearSessionId = ENGINE_ENV.LINEAR_SESSION_ID;
|
|
13323
13354
|
const linearForwarder = new LinearEventForwarder(linearSessionId);
|
|
@@ -13325,6 +13356,7 @@ var OpencodeManager = class extends CodingAgentManager {
|
|
|
13325
13356
|
this.activeLinearForwarder = linearForwarder;
|
|
13326
13357
|
this.forwardedLinearPartKeys.clear();
|
|
13327
13358
|
try {
|
|
13359
|
+
const model = request.model ?? await getDefaultOpencodeModel(provider);
|
|
13328
13360
|
const client = await this.ensureClient(model, provider);
|
|
13329
13361
|
const providerModel = this.providerId === OPENCODE_GO_PROVIDER ? getOpenCodeGoModel(model) : model;
|
|
13330
13362
|
const agent = request.planMode ? "plan" : "build";
|
|
@@ -13643,6 +13675,30 @@ import {
|
|
|
13643
13675
|
SessionManager,
|
|
13644
13676
|
DefaultResourceLoader
|
|
13645
13677
|
} from "@earendil-works/pi-coding-agent";
|
|
13678
|
+
function registerOpenRouterModels(modelRegistry, apiKey, modelIds) {
|
|
13679
|
+
const openRouterModels = modelRegistry.getAll().filter((model) => model.provider === "openrouter");
|
|
13680
|
+
const modelTemplate = openRouterModels[0];
|
|
13681
|
+
if (!modelTemplate) throw new Error("Pi OpenAI-compatible model template is unavailable.");
|
|
13682
|
+
modelRegistry.registerProvider("openrouter", {
|
|
13683
|
+
api: modelTemplate.api,
|
|
13684
|
+
apiKey,
|
|
13685
|
+
baseUrl: modelTemplate.baseUrl,
|
|
13686
|
+
models: [
|
|
13687
|
+
...openRouterModels,
|
|
13688
|
+
...modelIds.filter((id) => !openRouterModels.some((model) => model.id === id)).map((id) => ({
|
|
13689
|
+
id,
|
|
13690
|
+
name: id,
|
|
13691
|
+
api: modelTemplate.api,
|
|
13692
|
+
baseUrl: modelTemplate.baseUrl,
|
|
13693
|
+
reasoning: modelTemplate.reasoning,
|
|
13694
|
+
input: modelTemplate.input,
|
|
13695
|
+
cost: modelTemplate.cost,
|
|
13696
|
+
contextWindow: modelTemplate.contextWindow,
|
|
13697
|
+
maxTokens: modelTemplate.maxTokens
|
|
13698
|
+
}))
|
|
13699
|
+
]
|
|
13700
|
+
});
|
|
13701
|
+
}
|
|
13646
13702
|
function eventPayload(event) {
|
|
13647
13703
|
return isRecord4(event) ? { ...event } : { value: event };
|
|
13648
13704
|
}
|
|
@@ -13674,6 +13730,7 @@ var PiManager = class extends CodingAgentManager {
|
|
|
13674
13730
|
historyFilePath;
|
|
13675
13731
|
historyFile;
|
|
13676
13732
|
providerId = "openrouter";
|
|
13733
|
+
providerApiKey = null;
|
|
13677
13734
|
constructor(options) {
|
|
13678
13735
|
super(options);
|
|
13679
13736
|
this.historyFilePath = options.historyFilePath ?? join21(PI_HISTORY_DIR, `${Date.now()}.jsonl`);
|
|
@@ -13718,8 +13775,16 @@ var PiManager = class extends CodingAgentManager {
|
|
|
13718
13775
|
}
|
|
13719
13776
|
async ensureSession(request) {
|
|
13720
13777
|
if (this.session) {
|
|
13778
|
+
const turnModel = request.model ?? this.session.model?.id;
|
|
13779
|
+
if (this.providerId === "openrouter" && turnModel && !(await getAllowedOpenRouterModels()).includes(turnModel)) {
|
|
13780
|
+
throw new Error(`Pi model is not available through ${this.providerId}: ${turnModel}`);
|
|
13781
|
+
}
|
|
13721
13782
|
if (request.model && request.model !== this.session.model?.id) {
|
|
13722
|
-
|
|
13783
|
+
let model2 = this.session.modelRegistry.find(this.providerId, request.model);
|
|
13784
|
+
if (!model2 && this.providerId === "openrouter" && this.providerApiKey) {
|
|
13785
|
+
registerOpenRouterModels(this.session.modelRegistry, this.providerApiKey, [request.model]);
|
|
13786
|
+
model2 = this.session.modelRegistry.find(this.providerId, request.model);
|
|
13787
|
+
}
|
|
13723
13788
|
if (!model2) throw new Error(`Pi model is not available through ${this.providerId}: ${request.model}`);
|
|
13724
13789
|
await this.session.setModel(model2);
|
|
13725
13790
|
}
|
|
@@ -13732,10 +13797,8 @@ var PiManager = class extends CodingAgentManager {
|
|
|
13732
13797
|
const credentials = this.getProviderCredentials(authStorage);
|
|
13733
13798
|
if (!credentials) throw new Error("Aster or OpenRouter API key is not configured for Pi.");
|
|
13734
13799
|
this.providerId = credentials.provider;
|
|
13800
|
+
this.providerApiKey = credentials.apiKey;
|
|
13735
13801
|
const modelRegistry = ModelRegistry.create(authStorage);
|
|
13736
|
-
const openRouterModels = modelRegistry.getAll().filter((candidate) => candidate.provider === "openrouter");
|
|
13737
|
-
const modelTemplate = openRouterModels[0];
|
|
13738
|
-
if (!modelTemplate) throw new Error("Pi OpenAI-compatible model template is unavailable.");
|
|
13739
13802
|
if (this.providerId === ASTER_PROVIDER) {
|
|
13740
13803
|
modelRegistry.registerProvider(ASTER_PROVIDER, {
|
|
13741
13804
|
name: "Aster",
|
|
@@ -13754,30 +13817,16 @@ var PiManager = class extends CodingAgentManager {
|
|
|
13754
13817
|
maxTokens: 65536
|
|
13755
13818
|
}))
|
|
13756
13819
|
});
|
|
13757
|
-
} else {
|
|
13758
|
-
modelRegistry.registerProvider("openrouter", {
|
|
13759
|
-
api: modelTemplate.api,
|
|
13760
|
-
apiKey: credentials.apiKey,
|
|
13761
|
-
baseUrl: modelTemplate.baseUrl,
|
|
13762
|
-
models: [
|
|
13763
|
-
...openRouterModels,
|
|
13764
|
-
...OPENROUTER_MODELS.filter((id) => !openRouterModels.some((candidate) => candidate.id === id)).map((id) => ({
|
|
13765
|
-
id,
|
|
13766
|
-
name: id,
|
|
13767
|
-
api: modelTemplate.api,
|
|
13768
|
-
baseUrl: modelTemplate.baseUrl,
|
|
13769
|
-
reasoning: modelTemplate.reasoning,
|
|
13770
|
-
input: modelTemplate.input,
|
|
13771
|
-
cost: modelTemplate.cost,
|
|
13772
|
-
contextWindow: modelTemplate.contextWindow,
|
|
13773
|
-
maxTokens: modelTemplate.maxTokens
|
|
13774
|
-
}))
|
|
13775
|
-
]
|
|
13776
|
-
});
|
|
13777
13820
|
}
|
|
13778
|
-
|
|
13821
|
+
let defaultModel = DEFAULT_ASTER_MODEL;
|
|
13822
|
+
let allowedModels = null;
|
|
13823
|
+
if (this.providerId !== ASTER_PROVIDER) {
|
|
13824
|
+
allowedModels = await getAllowedOpenRouterModels();
|
|
13825
|
+
registerOpenRouterModels(modelRegistry, credentials.apiKey, allowedModels);
|
|
13826
|
+
defaultModel = allowedModels[0] ?? DEFAULT_PI_MODEL;
|
|
13827
|
+
}
|
|
13779
13828
|
const modelId = request.model ?? defaultModel;
|
|
13780
|
-
const model = modelRegistry.find(this.providerId, modelId);
|
|
13829
|
+
const model = allowedModels && !allowedModels.includes(modelId) ? null : modelRegistry.find(this.providerId, modelId);
|
|
13781
13830
|
if (!model) throw new Error(`Pi model is not available through ${this.providerId}: ${modelId}`);
|
|
13782
13831
|
const sessionManager = this.initialSessionId ? SessionManager.open(this.initialSessionId, PI_HISTORY_DIR, this.workingDirectory) : SessionManager.create(this.workingDirectory, PI_HISTORY_DIR);
|
|
13783
13832
|
const resourceLoader = new DefaultResourceLoader({
|
|
@@ -13816,9 +13865,9 @@ var PiManager = class extends CodingAgentManager {
|
|
|
13816
13865
|
this.recordHistoryEvent(`pi-${event.type}`, payload, this.historyFile);
|
|
13817
13866
|
}
|
|
13818
13867
|
async processMessageInternal(request) {
|
|
13819
|
-
const session = await this.ensureSession(request);
|
|
13820
|
-
this.recordHistoryEvent("event_msg", { type: "user_message", message: request.message }, this.historyFile);
|
|
13821
13868
|
try {
|
|
13869
|
+
const session = await this.ensureSession(request);
|
|
13870
|
+
this.recordHistoryEvent("event_msg", { type: "user_message", message: request.message }, this.historyFile);
|
|
13822
13871
|
const images = request.images && request.images.length > 0 ? (await normalizeImages(request.images)).map((image) => ({
|
|
13823
13872
|
type: "image",
|
|
13824
13873
|
data: image.source.data,
|