opensteer 0.5.5 → 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/CHANGELOG.md +6 -0
- package/README.md +2 -3
- package/dist/{chunk-YIQDOALV.js → chunk-AVXUMEDG.js} +3 -2
- package/dist/{chunk-SPHS6YWD.js → chunk-DN3GI5CH.js} +3 -2
- package/dist/{chunk-QHZFY3ZK.js → chunk-FAHE5DB2.js} +79 -20
- package/dist/{chunk-XIH3WGPY.js → chunk-SGZYTGY3.js} +232 -22
- package/dist/cli/server.cjs +312 -43
- package/dist/cli/server.js +1 -1
- package/dist/{extractor-CZFCFUME.js → extractor-4Q3TFZJB.js} +2 -2
- package/dist/index.cjs +316 -43
- package/dist/index.d.cts +13 -4
- package/dist/index.d.ts +13 -4
- package/dist/index.js +8 -4
- package/dist/{resolver-ZREUOOTV.js → resolver-MGN64KCP.js} +2 -2
- package/package.json +1 -1
- package/skills/opensteer/SKILL.md +92 -99
package/dist/cli/server.cjs
CHANGED
|
@@ -117,7 +117,7 @@ function resolveProviderInfo(modelStr) {
|
|
|
117
117
|
);
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
|
-
return
|
|
120
|
+
return OPENAI_PROVIDER_INFO;
|
|
121
121
|
}
|
|
122
122
|
function stripProviderPrefix(modelStr) {
|
|
123
123
|
const slash = modelStr.indexOf("/");
|
|
@@ -128,42 +128,101 @@ function stripProviderPrefix(modelStr) {
|
|
|
128
128
|
}
|
|
129
129
|
return modelStr;
|
|
130
130
|
}
|
|
131
|
-
|
|
132
|
-
|
|
131
|
+
function normalizeEnvValue(value) {
|
|
132
|
+
if (typeof value !== "string") return void 0;
|
|
133
|
+
const trimmed = value.trim();
|
|
134
|
+
return trimmed.length ? trimmed : void 0;
|
|
135
|
+
}
|
|
136
|
+
function buildFactoryOptions(provider, env) {
|
|
137
|
+
const apiKey = normalizeEnvValue(env[provider.apiKeyEnvVar]);
|
|
138
|
+
if (!apiKey) {
|
|
139
|
+
throw new Error(
|
|
140
|
+
`API key is missing in the resolved Opensteer environment. Set ${provider.apiKeyEnvVar} in your runtime environment or .env file under storage.rootDir.`
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
const baseURL = provider.baseUrlEnvVar ? normalizeEnvValue(env[provider.baseUrlEnvVar]) : void 0;
|
|
144
|
+
return {
|
|
145
|
+
apiKey,
|
|
146
|
+
...baseURL ? { baseURL } : {}
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
async function getModelProvider(modelStr, options = {}) {
|
|
150
|
+
const info = resolveProviderInfo(modelStr);
|
|
133
151
|
let mod;
|
|
134
152
|
try {
|
|
135
|
-
mod = await import(pkg);
|
|
153
|
+
mod = await import(info.pkg);
|
|
136
154
|
} catch {
|
|
137
155
|
throw new Error(
|
|
138
|
-
`To use AI resolution with model '${modelStr}', install 'ai' and '${pkg}' with your package manager.`
|
|
156
|
+
`To use AI resolution with model '${modelStr}', install 'ai' and '${info.pkg}' with your package manager.`
|
|
139
157
|
);
|
|
140
158
|
}
|
|
141
|
-
const
|
|
142
|
-
|
|
159
|
+
const providerExportName = options.env ? info.factoryFn : info.providerFn;
|
|
160
|
+
const providerExport = mod[providerExportName];
|
|
161
|
+
if (typeof providerExport !== "function") {
|
|
143
162
|
throw new Error(
|
|
144
|
-
`Provider '${
|
|
163
|
+
`Provider '${providerExportName}' not found in '${info.pkg}'. Ensure you have the latest version installed.`
|
|
145
164
|
);
|
|
146
165
|
}
|
|
147
166
|
const modelId = stripProviderPrefix(modelStr);
|
|
167
|
+
const provider = options.env != null ? providerExport(
|
|
168
|
+
buildFactoryOptions(info, options.env)
|
|
169
|
+
) : providerExport;
|
|
170
|
+
if (typeof provider !== "function") {
|
|
171
|
+
throw new Error(
|
|
172
|
+
`Provider '${providerExportName}' from '${info.pkg}' did not return a model factory function.`
|
|
173
|
+
);
|
|
174
|
+
}
|
|
148
175
|
return provider(modelId);
|
|
149
176
|
}
|
|
150
|
-
var PROVIDER_MAP;
|
|
177
|
+
var OPENAI_PROVIDER_INFO, ANTHROPIC_PROVIDER_INFO, GOOGLE_PROVIDER_INFO, XAI_PROVIDER_INFO, GROQ_PROVIDER_INFO, PROVIDER_MAP;
|
|
151
178
|
var init_model = __esm({
|
|
152
179
|
"src/ai/model.ts"() {
|
|
153
180
|
"use strict";
|
|
181
|
+
OPENAI_PROVIDER_INFO = {
|
|
182
|
+
pkg: "@ai-sdk/openai",
|
|
183
|
+
providerFn: "openai",
|
|
184
|
+
factoryFn: "createOpenAI",
|
|
185
|
+
apiKeyEnvVar: "OPENAI_API_KEY",
|
|
186
|
+
baseUrlEnvVar: "OPENAI_BASE_URL"
|
|
187
|
+
};
|
|
188
|
+
ANTHROPIC_PROVIDER_INFO = {
|
|
189
|
+
pkg: "@ai-sdk/anthropic",
|
|
190
|
+
providerFn: "anthropic",
|
|
191
|
+
factoryFn: "createAnthropic",
|
|
192
|
+
apiKeyEnvVar: "ANTHROPIC_API_KEY",
|
|
193
|
+
baseUrlEnvVar: "ANTHROPIC_BASE_URL"
|
|
194
|
+
};
|
|
195
|
+
GOOGLE_PROVIDER_INFO = {
|
|
196
|
+
pkg: "@ai-sdk/google",
|
|
197
|
+
providerFn: "google",
|
|
198
|
+
factoryFn: "createGoogleGenerativeAI",
|
|
199
|
+
apiKeyEnvVar: "GOOGLE_GENERATIVE_AI_API_KEY"
|
|
200
|
+
};
|
|
201
|
+
XAI_PROVIDER_INFO = {
|
|
202
|
+
pkg: "@ai-sdk/xai",
|
|
203
|
+
providerFn: "xai",
|
|
204
|
+
factoryFn: "createXai",
|
|
205
|
+
apiKeyEnvVar: "XAI_API_KEY"
|
|
206
|
+
};
|
|
207
|
+
GROQ_PROVIDER_INFO = {
|
|
208
|
+
pkg: "@ai-sdk/groq",
|
|
209
|
+
providerFn: "groq",
|
|
210
|
+
factoryFn: "createGroq",
|
|
211
|
+
apiKeyEnvVar: "GROQ_API_KEY"
|
|
212
|
+
};
|
|
154
213
|
PROVIDER_MAP = {
|
|
155
|
-
"openai/":
|
|
156
|
-
"anthropic/":
|
|
157
|
-
"google/":
|
|
158
|
-
"xai/":
|
|
159
|
-
"gpt-":
|
|
160
|
-
"o1-":
|
|
161
|
-
"o3-":
|
|
162
|
-
"o4-":
|
|
163
|
-
"claude-":
|
|
164
|
-
"gemini-":
|
|
165
|
-
"grok-":
|
|
166
|
-
"groq/":
|
|
214
|
+
"openai/": OPENAI_PROVIDER_INFO,
|
|
215
|
+
"anthropic/": ANTHROPIC_PROVIDER_INFO,
|
|
216
|
+
"google/": GOOGLE_PROVIDER_INFO,
|
|
217
|
+
"xai/": XAI_PROVIDER_INFO,
|
|
218
|
+
"gpt-": OPENAI_PROVIDER_INFO,
|
|
219
|
+
"o1-": OPENAI_PROVIDER_INFO,
|
|
220
|
+
"o3-": OPENAI_PROVIDER_INFO,
|
|
221
|
+
"o4-": OPENAI_PROVIDER_INFO,
|
|
222
|
+
"claude-": ANTHROPIC_PROVIDER_INFO,
|
|
223
|
+
"gemini-": GOOGLE_PROVIDER_INFO,
|
|
224
|
+
"grok-": XAI_PROVIDER_INFO,
|
|
225
|
+
"groq/": GROQ_PROVIDER_INFO
|
|
167
226
|
};
|
|
168
227
|
}
|
|
169
228
|
});
|
|
@@ -244,6 +303,7 @@ __export(resolver_exports, {
|
|
|
244
303
|
function createResolveCallback(model, options) {
|
|
245
304
|
const temperature = options?.temperature ?? 1;
|
|
246
305
|
const maxTokens = options?.maxTokens ?? null;
|
|
306
|
+
const env = options?.env;
|
|
247
307
|
return async (args) => {
|
|
248
308
|
let generateObject;
|
|
249
309
|
let z;
|
|
@@ -262,7 +322,7 @@ function createResolveCallback(model, options) {
|
|
|
262
322
|
`To use AI resolution with model '${model}', install 'zod' with your package manager.`
|
|
263
323
|
);
|
|
264
324
|
}
|
|
265
|
-
const modelProvider = await getModelProvider(model);
|
|
325
|
+
const modelProvider = await getModelProvider(model, { env });
|
|
266
326
|
const schema = z.object({
|
|
267
327
|
element: z.number().describe(
|
|
268
328
|
"Counter number of the matching element, or -1 if no match"
|
|
@@ -302,6 +362,7 @@ __export(extractor_exports, {
|
|
|
302
362
|
function createExtractCallback(model, options) {
|
|
303
363
|
const temperature = options?.temperature ?? 1;
|
|
304
364
|
const maxTokens = options?.maxTokens ?? null;
|
|
365
|
+
const env = options?.env;
|
|
305
366
|
return async (args) => {
|
|
306
367
|
let generateText;
|
|
307
368
|
try {
|
|
@@ -312,7 +373,7 @@ function createExtractCallback(model, options) {
|
|
|
312
373
|
`To use AI extraction with model '${model}', install 'ai' with your package manager.`
|
|
313
374
|
);
|
|
314
375
|
}
|
|
315
|
-
const modelProvider = await getModelProvider(model);
|
|
376
|
+
const modelProvider = await getModelProvider(model, { env });
|
|
316
377
|
const request = {
|
|
317
378
|
model: modelProvider,
|
|
318
379
|
system: buildExtractSystemPrompt(),
|
|
@@ -1345,7 +1406,7 @@ function resolveCloudSelection(config, env = process.env) {
|
|
|
1345
1406
|
source: "default"
|
|
1346
1407
|
};
|
|
1347
1408
|
}
|
|
1348
|
-
function
|
|
1409
|
+
function resolveConfigWithEnv(input = {}) {
|
|
1349
1410
|
const processEnv = process.env;
|
|
1350
1411
|
const debugHint = typeof input.debug === "boolean" ? input.debug : parseBool(processEnv.OPENSTEER_DEBUG) === true;
|
|
1351
1412
|
const initialRootDir = input.storage?.rootDir ?? process.cwd();
|
|
@@ -1438,7 +1499,10 @@ function resolveConfig(input = {}) {
|
|
|
1438
1499
|
baseUrl: envBaseUrl
|
|
1439
1500
|
};
|
|
1440
1501
|
}
|
|
1441
|
-
return
|
|
1502
|
+
return {
|
|
1503
|
+
config: resolved,
|
|
1504
|
+
env
|
|
1505
|
+
};
|
|
1442
1506
|
}
|
|
1443
1507
|
function resolveNamespace(config, rootDir) {
|
|
1444
1508
|
if (config.name && config.name.trim()) {
|
|
@@ -7033,7 +7097,9 @@ function minimizePathMatchClauses(path5, mode) {
|
|
|
7033
7097
|
(clause) => clause?.kind === "position"
|
|
7034
7098
|
);
|
|
7035
7099
|
let keptPositions = [];
|
|
7036
|
-
if (
|
|
7100
|
+
if (mode === "field") {
|
|
7101
|
+
keptPositions = pickMinimalPositionClauses(positionClauses);
|
|
7102
|
+
} else if (!attrClauses.length) {
|
|
7037
7103
|
keptPositions = pickMinimalPositionClauses(positionClauses);
|
|
7038
7104
|
} else if (mode === "item-root" && !isLast) {
|
|
7039
7105
|
keptPositions = [];
|
|
@@ -7127,7 +7193,7 @@ function relaxPathForSingleSample(path5, mode) {
|
|
|
7127
7193
|
const match = (node.match || []).filter((clause) => {
|
|
7128
7194
|
if (!clause || typeof clause !== "object") return false;
|
|
7129
7195
|
if (clause.kind === "position") {
|
|
7130
|
-
if (mode === "field") return
|
|
7196
|
+
if (mode === "field") return true;
|
|
7131
7197
|
return !isLast;
|
|
7132
7198
|
}
|
|
7133
7199
|
const key = String(clause.key || "").trim().toLowerCase();
|
|
@@ -7678,6 +7744,196 @@ function clonePersistedExtractNode(node) {
|
|
|
7678
7744
|
return JSON.parse(JSON.stringify(node));
|
|
7679
7745
|
}
|
|
7680
7746
|
|
|
7747
|
+
// src/extraction/array-field-validation.ts
|
|
7748
|
+
async function stripRedundantPositionClauses(payload, page) {
|
|
7749
|
+
const cloned = structuredClone(payload);
|
|
7750
|
+
await processObjectNode(cloned, page);
|
|
7751
|
+
return cloned;
|
|
7752
|
+
}
|
|
7753
|
+
async function processNode(node, page) {
|
|
7754
|
+
if (isPersistedArrayNode(node)) {
|
|
7755
|
+
await processArrayNode(node, page);
|
|
7756
|
+
return;
|
|
7757
|
+
}
|
|
7758
|
+
if (isPersistedObjectNode(node)) {
|
|
7759
|
+
await processObjectNode(node, page);
|
|
7760
|
+
}
|
|
7761
|
+
}
|
|
7762
|
+
async function processObjectNode(node, page) {
|
|
7763
|
+
for (const child of Object.values(node)) {
|
|
7764
|
+
await processNode(child, page);
|
|
7765
|
+
}
|
|
7766
|
+
}
|
|
7767
|
+
async function processArrayNode(node, page) {
|
|
7768
|
+
for (const variant of node.$array.variants) {
|
|
7769
|
+
try {
|
|
7770
|
+
await pruneVariantPositions(variant, page);
|
|
7771
|
+
} catch {
|
|
7772
|
+
}
|
|
7773
|
+
await processNode(variant.item, page);
|
|
7774
|
+
}
|
|
7775
|
+
}
|
|
7776
|
+
function collectValueNodes(node) {
|
|
7777
|
+
if (isPersistedValueNode(node)) {
|
|
7778
|
+
return [
|
|
7779
|
+
{
|
|
7780
|
+
path: node.$path,
|
|
7781
|
+
replacePath(path5) {
|
|
7782
|
+
node.$path = path5;
|
|
7783
|
+
}
|
|
7784
|
+
}
|
|
7785
|
+
];
|
|
7786
|
+
}
|
|
7787
|
+
if (!isPersistedObjectNode(node)) return [];
|
|
7788
|
+
const refs = [];
|
|
7789
|
+
const visit = (current) => {
|
|
7790
|
+
for (const [key, child] of Object.entries(current)) {
|
|
7791
|
+
if (isPersistedValueNode(child)) {
|
|
7792
|
+
refs.push({
|
|
7793
|
+
path: child.$path,
|
|
7794
|
+
replacePath(path5) {
|
|
7795
|
+
const next = current[key];
|
|
7796
|
+
if (!isPersistedValueNode(next)) return;
|
|
7797
|
+
next.$path = path5;
|
|
7798
|
+
}
|
|
7799
|
+
});
|
|
7800
|
+
continue;
|
|
7801
|
+
}
|
|
7802
|
+
if (isPersistedObjectNode(child)) {
|
|
7803
|
+
visit(child);
|
|
7804
|
+
}
|
|
7805
|
+
}
|
|
7806
|
+
};
|
|
7807
|
+
visit(node);
|
|
7808
|
+
return refs;
|
|
7809
|
+
}
|
|
7810
|
+
function hasPositionClause(path5) {
|
|
7811
|
+
return path5.nodes.some(
|
|
7812
|
+
(node) => (node.match || []).some((clause) => clause.kind === "position")
|
|
7813
|
+
);
|
|
7814
|
+
}
|
|
7815
|
+
function areArraysEqual(left, right) {
|
|
7816
|
+
if (left.length !== right.length) return false;
|
|
7817
|
+
for (let i = 0; i < left.length; i++) {
|
|
7818
|
+
if (left[i] !== right[i]) return false;
|
|
7819
|
+
}
|
|
7820
|
+
return true;
|
|
7821
|
+
}
|
|
7822
|
+
async function pruneVariantPositions(variant, page) {
|
|
7823
|
+
const refs = collectValueNodes(variant.item).filter(
|
|
7824
|
+
(ref) => hasPositionClause(ref.path)
|
|
7825
|
+
);
|
|
7826
|
+
if (!refs.length) return;
|
|
7827
|
+
const plans = refs.map((ref, index) => {
|
|
7828
|
+
const withPos = buildArrayFieldPathCandidates(ref.path);
|
|
7829
|
+
const strippedPath = stripPositionClauses2(ref.path);
|
|
7830
|
+
const withoutPos = buildArrayFieldPathCandidates(strippedPath);
|
|
7831
|
+
if (areArraysEqual(withPos, withoutPos)) return null;
|
|
7832
|
+
const plan = {
|
|
7833
|
+
key: String(index),
|
|
7834
|
+
strippedPath,
|
|
7835
|
+
replacePath: ref.replacePath,
|
|
7836
|
+
selectors: {
|
|
7837
|
+
withPos,
|
|
7838
|
+
withoutPos
|
|
7839
|
+
}
|
|
7840
|
+
};
|
|
7841
|
+
return plan;
|
|
7842
|
+
}).filter((plan) => !!plan);
|
|
7843
|
+
if (!plans.length) return;
|
|
7844
|
+
const selectorMap = {};
|
|
7845
|
+
for (const plan of plans) {
|
|
7846
|
+
selectorMap[plan.key] = plan.selectors;
|
|
7847
|
+
}
|
|
7848
|
+
const validatedKeys = new Set(plans.map((plan) => plan.key));
|
|
7849
|
+
const items = await queryAllByElementPath(page, variant.itemParentPath);
|
|
7850
|
+
if (!items.length) return;
|
|
7851
|
+
try {
|
|
7852
|
+
for (const item of items) {
|
|
7853
|
+
const results = await validateRowSelectors(item, selectorMap);
|
|
7854
|
+
const failedKeys = [];
|
|
7855
|
+
for (const key of validatedKeys) {
|
|
7856
|
+
if (results[key] === true) continue;
|
|
7857
|
+
failedKeys.push(key);
|
|
7858
|
+
}
|
|
7859
|
+
for (const key of failedKeys) {
|
|
7860
|
+
validatedKeys.delete(key);
|
|
7861
|
+
}
|
|
7862
|
+
if (!validatedKeys.size) break;
|
|
7863
|
+
}
|
|
7864
|
+
} finally {
|
|
7865
|
+
await Promise.all(
|
|
7866
|
+
items.map(async (item) => {
|
|
7867
|
+
try {
|
|
7868
|
+
await item.dispose();
|
|
7869
|
+
} catch {
|
|
7870
|
+
}
|
|
7871
|
+
})
|
|
7872
|
+
);
|
|
7873
|
+
}
|
|
7874
|
+
for (const plan of plans) {
|
|
7875
|
+
if (!validatedKeys.has(plan.key)) continue;
|
|
7876
|
+
plan.replacePath(plan.strippedPath);
|
|
7877
|
+
}
|
|
7878
|
+
}
|
|
7879
|
+
async function validateRowSelectors(item, fields) {
|
|
7880
|
+
return item.evaluate((element, selectorMap) => {
|
|
7881
|
+
const tryFirst = (root, selectors) => {
|
|
7882
|
+
let fallback = null;
|
|
7883
|
+
for (const selector of selectors) {
|
|
7884
|
+
if (!selector) continue;
|
|
7885
|
+
let matches = [];
|
|
7886
|
+
try {
|
|
7887
|
+
matches = Array.from(root.querySelectorAll(selector));
|
|
7888
|
+
} catch {
|
|
7889
|
+
matches = [];
|
|
7890
|
+
}
|
|
7891
|
+
if (!matches.length) continue;
|
|
7892
|
+
if (matches.length === 1) {
|
|
7893
|
+
return matches[0];
|
|
7894
|
+
}
|
|
7895
|
+
if (!fallback) {
|
|
7896
|
+
fallback = matches[0];
|
|
7897
|
+
}
|
|
7898
|
+
}
|
|
7899
|
+
return fallback;
|
|
7900
|
+
};
|
|
7901
|
+
const out = {};
|
|
7902
|
+
for (const [key, selectors] of Object.entries(selectorMap)) {
|
|
7903
|
+
const original = tryFirst(element, selectors.withPos);
|
|
7904
|
+
if (!original) {
|
|
7905
|
+
out[key] = false;
|
|
7906
|
+
continue;
|
|
7907
|
+
}
|
|
7908
|
+
let strippedUnique = null;
|
|
7909
|
+
for (const selector of selectors.withoutPos) {
|
|
7910
|
+
if (!selector) continue;
|
|
7911
|
+
let matches = [];
|
|
7912
|
+
try {
|
|
7913
|
+
matches = Array.from(element.querySelectorAll(selector));
|
|
7914
|
+
} catch {
|
|
7915
|
+
matches = [];
|
|
7916
|
+
}
|
|
7917
|
+
if (matches.length === 1) {
|
|
7918
|
+
strippedUnique = matches[0];
|
|
7919
|
+
break;
|
|
7920
|
+
}
|
|
7921
|
+
}
|
|
7922
|
+
out[key] = strippedUnique === original;
|
|
7923
|
+
}
|
|
7924
|
+
return out;
|
|
7925
|
+
}, fields);
|
|
7926
|
+
}
|
|
7927
|
+
function stripPositionClauses2(path5) {
|
|
7928
|
+
return {
|
|
7929
|
+
context: path5.context,
|
|
7930
|
+
nodes: path5.nodes.map((node) => ({
|
|
7931
|
+
...node,
|
|
7932
|
+
match: (node.match || []).filter((clause) => clause.kind !== "position")
|
|
7933
|
+
}))
|
|
7934
|
+
};
|
|
7935
|
+
}
|
|
7936
|
+
|
|
7681
7937
|
// src/cloud/contracts.ts
|
|
7682
7938
|
var cloudSessionContractVersion = "v3";
|
|
7683
7939
|
|
|
@@ -10080,6 +10336,7 @@ var CLOUD_INTERACTION_METHODS = /* @__PURE__ */ new Set([
|
|
|
10080
10336
|
]);
|
|
10081
10337
|
var Opensteer = class _Opensteer {
|
|
10082
10338
|
config;
|
|
10339
|
+
runtimeEnv;
|
|
10083
10340
|
aiResolve;
|
|
10084
10341
|
aiExtract;
|
|
10085
10342
|
namespace;
|
|
@@ -10093,14 +10350,17 @@ var Opensteer = class _Opensteer {
|
|
|
10093
10350
|
snapshotCache = null;
|
|
10094
10351
|
agentExecutionInFlight = false;
|
|
10095
10352
|
constructor(config = {}) {
|
|
10096
|
-
const
|
|
10353
|
+
const resolvedRuntime = resolveConfigWithEnv(config);
|
|
10354
|
+
const resolved = resolvedRuntime.config;
|
|
10355
|
+
const runtimeEnv = resolvedRuntime.env;
|
|
10097
10356
|
const cloudSelection = resolveCloudSelection({
|
|
10098
10357
|
cloud: resolved.cloud
|
|
10099
|
-
});
|
|
10358
|
+
}, runtimeEnv);
|
|
10100
10359
|
const model = resolved.model;
|
|
10101
10360
|
this.config = resolved;
|
|
10102
|
-
this.
|
|
10103
|
-
this.
|
|
10361
|
+
this.runtimeEnv = runtimeEnv;
|
|
10362
|
+
this.aiResolve = this.createLazyResolveCallback(model, runtimeEnv);
|
|
10363
|
+
this.aiExtract = this.createLazyExtractCallback(model, runtimeEnv);
|
|
10104
10364
|
const rootDir = resolved.storage?.rootDir || process.cwd();
|
|
10105
10365
|
this.namespace = resolveNamespace(resolved, rootDir);
|
|
10106
10366
|
this.storage = new LocalSelectorStorage(rootDir, this.namespace, {
|
|
@@ -10132,13 +10392,13 @@ var Opensteer = class _Opensteer {
|
|
|
10132
10392
|
`[opensteer] ${context}: ${normalized.message}${codeSuffix}`
|
|
10133
10393
|
);
|
|
10134
10394
|
}
|
|
10135
|
-
createLazyResolveCallback(model) {
|
|
10395
|
+
createLazyResolveCallback(model, env) {
|
|
10136
10396
|
let resolverPromise = null;
|
|
10137
10397
|
return async (...args) => {
|
|
10138
10398
|
try {
|
|
10139
10399
|
if (!resolverPromise) {
|
|
10140
10400
|
resolverPromise = Promise.resolve().then(() => (init_resolver(), resolver_exports)).then(
|
|
10141
|
-
(m) => m.createResolveCallback(model)
|
|
10401
|
+
(m) => m.createResolveCallback(model, { env })
|
|
10142
10402
|
);
|
|
10143
10403
|
}
|
|
10144
10404
|
const resolver = await resolverPromise;
|
|
@@ -10149,13 +10409,13 @@ var Opensteer = class _Opensteer {
|
|
|
10149
10409
|
}
|
|
10150
10410
|
};
|
|
10151
10411
|
}
|
|
10152
|
-
createLazyExtractCallback(model) {
|
|
10412
|
+
createLazyExtractCallback(model, env) {
|
|
10153
10413
|
let extractorPromise = null;
|
|
10154
10414
|
const extract = async (args) => {
|
|
10155
10415
|
try {
|
|
10156
10416
|
if (!extractorPromise) {
|
|
10157
10417
|
extractorPromise = Promise.resolve().then(() => (init_extractor(), extractor_exports)).then(
|
|
10158
|
-
(m) => m.createExtractCallback(model)
|
|
10418
|
+
(m) => m.createExtractCallback(model, { env })
|
|
10159
10419
|
);
|
|
10160
10420
|
}
|
|
10161
10421
|
const extractor = await extractorPromise;
|
|
@@ -10432,10 +10692,11 @@ var Opensteer = class _Opensteer {
|
|
|
10432
10692
|
this.snapshotCache = null;
|
|
10433
10693
|
}
|
|
10434
10694
|
static from(page, config = {}) {
|
|
10435
|
-
const
|
|
10695
|
+
const resolvedRuntime = resolveConfigWithEnv(config);
|
|
10696
|
+
const resolvedConfig = resolvedRuntime.config;
|
|
10436
10697
|
const cloudSelection = resolveCloudSelection({
|
|
10437
10698
|
cloud: resolvedConfig.cloud
|
|
10438
|
-
});
|
|
10699
|
+
}, resolvedRuntime.env);
|
|
10439
10700
|
if (cloudSelection.cloud) {
|
|
10440
10701
|
throw cloudUnsupportedMethodError(
|
|
10441
10702
|
"Opensteer.from(page)",
|
|
@@ -11410,7 +11671,7 @@ var Opensteer = class _Opensteer {
|
|
|
11410
11671
|
const data = await this.extractFields(fields);
|
|
11411
11672
|
if (storageKey && schemaHash && (!stored || stored.schemaHash !== schemaHash)) {
|
|
11412
11673
|
const persistedFields = await this.resolveFieldTargetsToPersistableFields(fields);
|
|
11413
|
-
this.persistExtractPaths(
|
|
11674
|
+
await this.persistExtractPaths(
|
|
11414
11675
|
storageKey,
|
|
11415
11676
|
options.description,
|
|
11416
11677
|
persistedFields,
|
|
@@ -11444,13 +11705,12 @@ var Opensteer = class _Opensteer {
|
|
|
11444
11705
|
const resolvedFields = await this.resolveFieldTargetsToPersistableFields(fields);
|
|
11445
11706
|
let persisted = false;
|
|
11446
11707
|
if (storageKey) {
|
|
11447
|
-
this.persistExtractPaths(
|
|
11708
|
+
persisted = await this.persistExtractPaths(
|
|
11448
11709
|
storageKey,
|
|
11449
11710
|
options.description,
|
|
11450
11711
|
resolvedFields,
|
|
11451
11712
|
schemaHash
|
|
11452
11713
|
);
|
|
11453
|
-
persisted = true;
|
|
11454
11714
|
}
|
|
11455
11715
|
return {
|
|
11456
11716
|
namespace: this.storage.getNamespace(),
|
|
@@ -11482,7 +11742,8 @@ var Opensteer = class _Opensteer {
|
|
|
11482
11742
|
agent(config) {
|
|
11483
11743
|
const resolvedAgentConfig = resolveAgentConfig({
|
|
11484
11744
|
agentConfig: config,
|
|
11485
|
-
fallbackModel: this.config.model
|
|
11745
|
+
fallbackModel: this.config.model,
|
|
11746
|
+
env: this.runtimeEnv
|
|
11486
11747
|
});
|
|
11487
11748
|
return {
|
|
11488
11749
|
execute: async (instructionOrOptions) => {
|
|
@@ -11911,7 +12172,7 @@ var Opensteer = class _Opensteer {
|
|
|
11911
12172
|
this.storage.saveRegistry(registry);
|
|
11912
12173
|
return true;
|
|
11913
12174
|
}
|
|
11914
|
-
persistExtractPaths(id, description, fields, schemaHash) {
|
|
12175
|
+
async persistExtractPaths(id, description, fields, schemaHash) {
|
|
11915
12176
|
const now = Date.now();
|
|
11916
12177
|
const safeFile = this.storage.getSelectorFileName(id);
|
|
11917
12178
|
const existing = this.storage.readSelector(id);
|
|
@@ -11932,11 +12193,19 @@ var Opensteer = class _Opensteer {
|
|
|
11932
12193
|
}
|
|
11933
12194
|
);
|
|
11934
12195
|
const persistedPayload = buildPersistedExtractPayload(normalizedFields);
|
|
12196
|
+
let validatedPayload = persistedPayload;
|
|
12197
|
+
try {
|
|
12198
|
+
validatedPayload = await stripRedundantPositionClauses(
|
|
12199
|
+
persistedPayload,
|
|
12200
|
+
this.page
|
|
12201
|
+
);
|
|
12202
|
+
} catch {
|
|
12203
|
+
}
|
|
11935
12204
|
const payload = {
|
|
11936
12205
|
id,
|
|
11937
12206
|
method: "extract",
|
|
11938
12207
|
description: description || "Extraction paths",
|
|
11939
|
-
path:
|
|
12208
|
+
path: validatedPayload,
|
|
11940
12209
|
schemaHash,
|
|
11941
12210
|
metadata: {
|
|
11942
12211
|
createdAt,
|
package/dist/cli/server.js
CHANGED