opensteer 0.5.5 → 0.5.6
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 +2 -0
- 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/CHANGELOG.md
CHANGED
|
@@ -27,6 +27,8 @@
|
|
|
27
27
|
- Cloud mode now falls back to `OPENSTEER_API_KEY` when `cloud.apiKey` is omitted.
|
|
28
28
|
- Added automatic `.env` loading from `storage.rootDir` (default `process.cwd()`) so constructor config can consume env vars without requiring `import 'dotenv/config'`.
|
|
29
29
|
- `.env` autoload follows common precedence (`.env.<NODE_ENV>.local`, `.env.local`, `.env.<NODE_ENV>`, `.env`) with `.env.local` skipped in `test`, does not overwrite existing env values, and can be disabled via `OPENSTEER_DISABLE_DOTENV_AUTOLOAD`.
|
|
30
|
+
- Opensteer now reuses one resolved runtime env snapshot for config, CUA provider key resolution, and built-in AI resolve/extract provider setup; dotenv loading still does not mutate global `process.env`.
|
|
31
|
+
- AI helper exports now accept optional `env` maps (`getModelProvider`, `createResolveCallback`, `createExtractCallback`) for deterministic provider initialization without relying on ambient process env state.
|
|
30
32
|
- Mutating actions now include smart best-effort post-action wait with per-action
|
|
31
33
|
profiles and optional per-call overrides via `wait`.
|
|
32
34
|
- Added structured interaction diagnostics via `OpensteerActionError` for
|
|
@@ -5,12 +5,13 @@ import {
|
|
|
5
5
|
buildExtractSystemPrompt,
|
|
6
6
|
buildExtractUserPrompt,
|
|
7
7
|
getModelProvider
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-FAHE5DB2.js";
|
|
9
9
|
|
|
10
10
|
// src/ai/extractor.ts
|
|
11
11
|
function createExtractCallback(model, options) {
|
|
12
12
|
const temperature = options?.temperature ?? 1;
|
|
13
13
|
const maxTokens = options?.maxTokens ?? null;
|
|
14
|
+
const env = options?.env;
|
|
14
15
|
return async (args) => {
|
|
15
16
|
let generateText;
|
|
16
17
|
try {
|
|
@@ -21,7 +22,7 @@ function createExtractCallback(model, options) {
|
|
|
21
22
|
`To use AI extraction with model '${model}', install 'ai' with your package manager.`
|
|
22
23
|
);
|
|
23
24
|
}
|
|
24
|
-
const modelProvider = await getModelProvider(model);
|
|
25
|
+
const modelProvider = await getModelProvider(model, { env });
|
|
25
26
|
const request = {
|
|
26
27
|
model: modelProvider,
|
|
27
28
|
system: buildExtractSystemPrompt(),
|
|
@@ -2,12 +2,13 @@ import {
|
|
|
2
2
|
buildResolveSystemPrompt,
|
|
3
3
|
buildResolveUserPrompt,
|
|
4
4
|
getModelProvider
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-FAHE5DB2.js";
|
|
6
6
|
|
|
7
7
|
// src/ai/resolver.ts
|
|
8
8
|
function createResolveCallback(model, options) {
|
|
9
9
|
const temperature = options?.temperature ?? 1;
|
|
10
10
|
const maxTokens = options?.maxTokens ?? null;
|
|
11
|
+
const env = options?.env;
|
|
11
12
|
return async (args) => {
|
|
12
13
|
let generateObject;
|
|
13
14
|
let z;
|
|
@@ -26,7 +27,7 @@ function createResolveCallback(model, options) {
|
|
|
26
27
|
`To use AI resolution with model '${model}', install 'zod' with your package manager.`
|
|
27
28
|
);
|
|
28
29
|
}
|
|
29
|
-
const modelProvider = await getModelProvider(model);
|
|
30
|
+
const modelProvider = await getModelProvider(model, { env });
|
|
30
31
|
const schema = z.object({
|
|
31
32
|
element: z.number().describe(
|
|
32
33
|
"Counter number of the matching element, or -1 if no match"
|
|
@@ -1,17 +1,49 @@
|
|
|
1
1
|
// src/ai/model.ts
|
|
2
|
+
var OPENAI_PROVIDER_INFO = {
|
|
3
|
+
pkg: "@ai-sdk/openai",
|
|
4
|
+
providerFn: "openai",
|
|
5
|
+
factoryFn: "createOpenAI",
|
|
6
|
+
apiKeyEnvVar: "OPENAI_API_KEY",
|
|
7
|
+
baseUrlEnvVar: "OPENAI_BASE_URL"
|
|
8
|
+
};
|
|
9
|
+
var ANTHROPIC_PROVIDER_INFO = {
|
|
10
|
+
pkg: "@ai-sdk/anthropic",
|
|
11
|
+
providerFn: "anthropic",
|
|
12
|
+
factoryFn: "createAnthropic",
|
|
13
|
+
apiKeyEnvVar: "ANTHROPIC_API_KEY",
|
|
14
|
+
baseUrlEnvVar: "ANTHROPIC_BASE_URL"
|
|
15
|
+
};
|
|
16
|
+
var GOOGLE_PROVIDER_INFO = {
|
|
17
|
+
pkg: "@ai-sdk/google",
|
|
18
|
+
providerFn: "google",
|
|
19
|
+
factoryFn: "createGoogleGenerativeAI",
|
|
20
|
+
apiKeyEnvVar: "GOOGLE_GENERATIVE_AI_API_KEY"
|
|
21
|
+
};
|
|
22
|
+
var XAI_PROVIDER_INFO = {
|
|
23
|
+
pkg: "@ai-sdk/xai",
|
|
24
|
+
providerFn: "xai",
|
|
25
|
+
factoryFn: "createXai",
|
|
26
|
+
apiKeyEnvVar: "XAI_API_KEY"
|
|
27
|
+
};
|
|
28
|
+
var GROQ_PROVIDER_INFO = {
|
|
29
|
+
pkg: "@ai-sdk/groq",
|
|
30
|
+
providerFn: "groq",
|
|
31
|
+
factoryFn: "createGroq",
|
|
32
|
+
apiKeyEnvVar: "GROQ_API_KEY"
|
|
33
|
+
};
|
|
2
34
|
var PROVIDER_MAP = {
|
|
3
|
-
"openai/":
|
|
4
|
-
"anthropic/":
|
|
5
|
-
"google/":
|
|
6
|
-
"xai/":
|
|
7
|
-
"gpt-":
|
|
8
|
-
"o1-":
|
|
9
|
-
"o3-":
|
|
10
|
-
"o4-":
|
|
11
|
-
"claude-":
|
|
12
|
-
"gemini-":
|
|
13
|
-
"grok-":
|
|
14
|
-
"groq/":
|
|
35
|
+
"openai/": OPENAI_PROVIDER_INFO,
|
|
36
|
+
"anthropic/": ANTHROPIC_PROVIDER_INFO,
|
|
37
|
+
"google/": GOOGLE_PROVIDER_INFO,
|
|
38
|
+
"xai/": XAI_PROVIDER_INFO,
|
|
39
|
+
"gpt-": OPENAI_PROVIDER_INFO,
|
|
40
|
+
"o1-": OPENAI_PROVIDER_INFO,
|
|
41
|
+
"o3-": OPENAI_PROVIDER_INFO,
|
|
42
|
+
"o4-": OPENAI_PROVIDER_INFO,
|
|
43
|
+
"claude-": ANTHROPIC_PROVIDER_INFO,
|
|
44
|
+
"gemini-": GOOGLE_PROVIDER_INFO,
|
|
45
|
+
"grok-": XAI_PROVIDER_INFO,
|
|
46
|
+
"groq/": GROQ_PROVIDER_INFO
|
|
15
47
|
};
|
|
16
48
|
function resolveProviderInfo(modelStr) {
|
|
17
49
|
for (const [prefix, info] of Object.entries(PROVIDER_MAP)) {
|
|
@@ -28,7 +60,7 @@ function resolveProviderInfo(modelStr) {
|
|
|
28
60
|
);
|
|
29
61
|
}
|
|
30
62
|
}
|
|
31
|
-
return
|
|
63
|
+
return OPENAI_PROVIDER_INFO;
|
|
32
64
|
}
|
|
33
65
|
function stripProviderPrefix(modelStr) {
|
|
34
66
|
const slash = modelStr.indexOf("/");
|
|
@@ -39,23 +71,50 @@ function stripProviderPrefix(modelStr) {
|
|
|
39
71
|
}
|
|
40
72
|
return modelStr;
|
|
41
73
|
}
|
|
42
|
-
|
|
43
|
-
|
|
74
|
+
function normalizeEnvValue(value) {
|
|
75
|
+
if (typeof value !== "string") return void 0;
|
|
76
|
+
const trimmed = value.trim();
|
|
77
|
+
return trimmed.length ? trimmed : void 0;
|
|
78
|
+
}
|
|
79
|
+
function buildFactoryOptions(provider, env) {
|
|
80
|
+
const apiKey = normalizeEnvValue(env[provider.apiKeyEnvVar]);
|
|
81
|
+
if (!apiKey) {
|
|
82
|
+
throw new Error(
|
|
83
|
+
`API key is missing in the resolved Opensteer environment. Set ${provider.apiKeyEnvVar} in your runtime environment or .env file under storage.rootDir.`
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
const baseURL = provider.baseUrlEnvVar ? normalizeEnvValue(env[provider.baseUrlEnvVar]) : void 0;
|
|
87
|
+
return {
|
|
88
|
+
apiKey,
|
|
89
|
+
...baseURL ? { baseURL } : {}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
async function getModelProvider(modelStr, options = {}) {
|
|
93
|
+
const info = resolveProviderInfo(modelStr);
|
|
44
94
|
let mod;
|
|
45
95
|
try {
|
|
46
|
-
mod = await import(pkg);
|
|
96
|
+
mod = await import(info.pkg);
|
|
47
97
|
} catch {
|
|
48
98
|
throw new Error(
|
|
49
|
-
`To use AI resolution with model '${modelStr}', install 'ai' and '${pkg}' with your package manager.`
|
|
99
|
+
`To use AI resolution with model '${modelStr}', install 'ai' and '${info.pkg}' with your package manager.`
|
|
50
100
|
);
|
|
51
101
|
}
|
|
52
|
-
const
|
|
53
|
-
|
|
102
|
+
const providerExportName = options.env ? info.factoryFn : info.providerFn;
|
|
103
|
+
const providerExport = mod[providerExportName];
|
|
104
|
+
if (typeof providerExport !== "function") {
|
|
54
105
|
throw new Error(
|
|
55
|
-
`Provider '${
|
|
106
|
+
`Provider '${providerExportName}' not found in '${info.pkg}'. Ensure you have the latest version installed.`
|
|
56
107
|
);
|
|
57
108
|
}
|
|
58
109
|
const modelId = stripProviderPrefix(modelStr);
|
|
110
|
+
const provider = options.env != null ? providerExport(
|
|
111
|
+
buildFactoryOptions(info, options.env)
|
|
112
|
+
) : providerExport;
|
|
113
|
+
if (typeof provider !== "function") {
|
|
114
|
+
throw new Error(
|
|
115
|
+
`Provider '${providerExportName}' from '${info.pkg}' did not return a model factory function.`
|
|
116
|
+
);
|
|
117
|
+
}
|
|
59
118
|
return provider(modelId);
|
|
60
119
|
}
|
|
61
120
|
|
|
@@ -8196,7 +8196,7 @@ function resolveCloudSelection(config, env = process.env) {
|
|
|
8196
8196
|
source: "default"
|
|
8197
8197
|
};
|
|
8198
8198
|
}
|
|
8199
|
-
function
|
|
8199
|
+
function resolveConfigWithEnv(input = {}) {
|
|
8200
8200
|
const processEnv = process.env;
|
|
8201
8201
|
const debugHint = typeof input.debug === "boolean" ? input.debug : parseBool(processEnv.OPENSTEER_DEBUG) === true;
|
|
8202
8202
|
const initialRootDir = input.storage?.rootDir ?? process.cwd();
|
|
@@ -8289,7 +8289,10 @@ function resolveConfig(input = {}) {
|
|
|
8289
8289
|
baseUrl: envBaseUrl
|
|
8290
8290
|
};
|
|
8291
8291
|
}
|
|
8292
|
-
return
|
|
8292
|
+
return {
|
|
8293
|
+
config: resolved,
|
|
8294
|
+
env
|
|
8295
|
+
};
|
|
8293
8296
|
}
|
|
8294
8297
|
function resolveNamespace(config, rootDir) {
|
|
8295
8298
|
if (config.name && config.name.trim()) {
|
|
@@ -9036,7 +9039,9 @@ function minimizePathMatchClauses(path5, mode) {
|
|
|
9036
9039
|
(clause) => clause?.kind === "position"
|
|
9037
9040
|
);
|
|
9038
9041
|
let keptPositions = [];
|
|
9039
|
-
if (
|
|
9042
|
+
if (mode === "field") {
|
|
9043
|
+
keptPositions = pickMinimalPositionClauses(positionClauses);
|
|
9044
|
+
} else if (!attrClauses.length) {
|
|
9040
9045
|
keptPositions = pickMinimalPositionClauses(positionClauses);
|
|
9041
9046
|
} else if (mode === "item-root" && !isLast) {
|
|
9042
9047
|
keptPositions = [];
|
|
@@ -9130,7 +9135,7 @@ function relaxPathForSingleSample(path5, mode) {
|
|
|
9130
9135
|
const match = (node.match || []).filter((clause) => {
|
|
9131
9136
|
if (!clause || typeof clause !== "object") return false;
|
|
9132
9137
|
if (clause.kind === "position") {
|
|
9133
|
-
if (mode === "field") return
|
|
9138
|
+
if (mode === "field") return true;
|
|
9134
9139
|
return !isLast;
|
|
9135
9140
|
}
|
|
9136
9141
|
const key = String(clause.key || "").trim().toLowerCase();
|
|
@@ -9681,6 +9686,196 @@ function clonePersistedExtractNode(node) {
|
|
|
9681
9686
|
return JSON.parse(JSON.stringify(node));
|
|
9682
9687
|
}
|
|
9683
9688
|
|
|
9689
|
+
// src/extraction/array-field-validation.ts
|
|
9690
|
+
async function stripRedundantPositionClauses(payload, page) {
|
|
9691
|
+
const cloned = structuredClone(payload);
|
|
9692
|
+
await processObjectNode(cloned, page);
|
|
9693
|
+
return cloned;
|
|
9694
|
+
}
|
|
9695
|
+
async function processNode(node, page) {
|
|
9696
|
+
if (isPersistedArrayNode(node)) {
|
|
9697
|
+
await processArrayNode(node, page);
|
|
9698
|
+
return;
|
|
9699
|
+
}
|
|
9700
|
+
if (isPersistedObjectNode(node)) {
|
|
9701
|
+
await processObjectNode(node, page);
|
|
9702
|
+
}
|
|
9703
|
+
}
|
|
9704
|
+
async function processObjectNode(node, page) {
|
|
9705
|
+
for (const child of Object.values(node)) {
|
|
9706
|
+
await processNode(child, page);
|
|
9707
|
+
}
|
|
9708
|
+
}
|
|
9709
|
+
async function processArrayNode(node, page) {
|
|
9710
|
+
for (const variant of node.$array.variants) {
|
|
9711
|
+
try {
|
|
9712
|
+
await pruneVariantPositions(variant, page);
|
|
9713
|
+
} catch {
|
|
9714
|
+
}
|
|
9715
|
+
await processNode(variant.item, page);
|
|
9716
|
+
}
|
|
9717
|
+
}
|
|
9718
|
+
function collectValueNodes(node) {
|
|
9719
|
+
if (isPersistedValueNode(node)) {
|
|
9720
|
+
return [
|
|
9721
|
+
{
|
|
9722
|
+
path: node.$path,
|
|
9723
|
+
replacePath(path5) {
|
|
9724
|
+
node.$path = path5;
|
|
9725
|
+
}
|
|
9726
|
+
}
|
|
9727
|
+
];
|
|
9728
|
+
}
|
|
9729
|
+
if (!isPersistedObjectNode(node)) return [];
|
|
9730
|
+
const refs = [];
|
|
9731
|
+
const visit = (current) => {
|
|
9732
|
+
for (const [key, child] of Object.entries(current)) {
|
|
9733
|
+
if (isPersistedValueNode(child)) {
|
|
9734
|
+
refs.push({
|
|
9735
|
+
path: child.$path,
|
|
9736
|
+
replacePath(path5) {
|
|
9737
|
+
const next = current[key];
|
|
9738
|
+
if (!isPersistedValueNode(next)) return;
|
|
9739
|
+
next.$path = path5;
|
|
9740
|
+
}
|
|
9741
|
+
});
|
|
9742
|
+
continue;
|
|
9743
|
+
}
|
|
9744
|
+
if (isPersistedObjectNode(child)) {
|
|
9745
|
+
visit(child);
|
|
9746
|
+
}
|
|
9747
|
+
}
|
|
9748
|
+
};
|
|
9749
|
+
visit(node);
|
|
9750
|
+
return refs;
|
|
9751
|
+
}
|
|
9752
|
+
function hasPositionClause(path5) {
|
|
9753
|
+
return path5.nodes.some(
|
|
9754
|
+
(node) => (node.match || []).some((clause) => clause.kind === "position")
|
|
9755
|
+
);
|
|
9756
|
+
}
|
|
9757
|
+
function areArraysEqual(left, right) {
|
|
9758
|
+
if (left.length !== right.length) return false;
|
|
9759
|
+
for (let i = 0; i < left.length; i++) {
|
|
9760
|
+
if (left[i] !== right[i]) return false;
|
|
9761
|
+
}
|
|
9762
|
+
return true;
|
|
9763
|
+
}
|
|
9764
|
+
async function pruneVariantPositions(variant, page) {
|
|
9765
|
+
const refs = collectValueNodes(variant.item).filter(
|
|
9766
|
+
(ref) => hasPositionClause(ref.path)
|
|
9767
|
+
);
|
|
9768
|
+
if (!refs.length) return;
|
|
9769
|
+
const plans = refs.map((ref, index) => {
|
|
9770
|
+
const withPos = buildArrayFieldPathCandidates(ref.path);
|
|
9771
|
+
const strippedPath = stripPositionClauses2(ref.path);
|
|
9772
|
+
const withoutPos = buildArrayFieldPathCandidates(strippedPath);
|
|
9773
|
+
if (areArraysEqual(withPos, withoutPos)) return null;
|
|
9774
|
+
const plan = {
|
|
9775
|
+
key: String(index),
|
|
9776
|
+
strippedPath,
|
|
9777
|
+
replacePath: ref.replacePath,
|
|
9778
|
+
selectors: {
|
|
9779
|
+
withPos,
|
|
9780
|
+
withoutPos
|
|
9781
|
+
}
|
|
9782
|
+
};
|
|
9783
|
+
return plan;
|
|
9784
|
+
}).filter((plan) => !!plan);
|
|
9785
|
+
if (!plans.length) return;
|
|
9786
|
+
const selectorMap = {};
|
|
9787
|
+
for (const plan of plans) {
|
|
9788
|
+
selectorMap[plan.key] = plan.selectors;
|
|
9789
|
+
}
|
|
9790
|
+
const validatedKeys = new Set(plans.map((plan) => plan.key));
|
|
9791
|
+
const items = await queryAllByElementPath(page, variant.itemParentPath);
|
|
9792
|
+
if (!items.length) return;
|
|
9793
|
+
try {
|
|
9794
|
+
for (const item of items) {
|
|
9795
|
+
const results = await validateRowSelectors(item, selectorMap);
|
|
9796
|
+
const failedKeys = [];
|
|
9797
|
+
for (const key of validatedKeys) {
|
|
9798
|
+
if (results[key] === true) continue;
|
|
9799
|
+
failedKeys.push(key);
|
|
9800
|
+
}
|
|
9801
|
+
for (const key of failedKeys) {
|
|
9802
|
+
validatedKeys.delete(key);
|
|
9803
|
+
}
|
|
9804
|
+
if (!validatedKeys.size) break;
|
|
9805
|
+
}
|
|
9806
|
+
} finally {
|
|
9807
|
+
await Promise.all(
|
|
9808
|
+
items.map(async (item) => {
|
|
9809
|
+
try {
|
|
9810
|
+
await item.dispose();
|
|
9811
|
+
} catch {
|
|
9812
|
+
}
|
|
9813
|
+
})
|
|
9814
|
+
);
|
|
9815
|
+
}
|
|
9816
|
+
for (const plan of plans) {
|
|
9817
|
+
if (!validatedKeys.has(plan.key)) continue;
|
|
9818
|
+
plan.replacePath(plan.strippedPath);
|
|
9819
|
+
}
|
|
9820
|
+
}
|
|
9821
|
+
async function validateRowSelectors(item, fields) {
|
|
9822
|
+
return item.evaluate((element, selectorMap) => {
|
|
9823
|
+
const tryFirst = (root, selectors) => {
|
|
9824
|
+
let fallback = null;
|
|
9825
|
+
for (const selector of selectors) {
|
|
9826
|
+
if (!selector) continue;
|
|
9827
|
+
let matches = [];
|
|
9828
|
+
try {
|
|
9829
|
+
matches = Array.from(root.querySelectorAll(selector));
|
|
9830
|
+
} catch {
|
|
9831
|
+
matches = [];
|
|
9832
|
+
}
|
|
9833
|
+
if (!matches.length) continue;
|
|
9834
|
+
if (matches.length === 1) {
|
|
9835
|
+
return matches[0];
|
|
9836
|
+
}
|
|
9837
|
+
if (!fallback) {
|
|
9838
|
+
fallback = matches[0];
|
|
9839
|
+
}
|
|
9840
|
+
}
|
|
9841
|
+
return fallback;
|
|
9842
|
+
};
|
|
9843
|
+
const out = {};
|
|
9844
|
+
for (const [key, selectors] of Object.entries(selectorMap)) {
|
|
9845
|
+
const original = tryFirst(element, selectors.withPos);
|
|
9846
|
+
if (!original) {
|
|
9847
|
+
out[key] = false;
|
|
9848
|
+
continue;
|
|
9849
|
+
}
|
|
9850
|
+
let strippedUnique = null;
|
|
9851
|
+
for (const selector of selectors.withoutPos) {
|
|
9852
|
+
if (!selector) continue;
|
|
9853
|
+
let matches = [];
|
|
9854
|
+
try {
|
|
9855
|
+
matches = Array.from(element.querySelectorAll(selector));
|
|
9856
|
+
} catch {
|
|
9857
|
+
matches = [];
|
|
9858
|
+
}
|
|
9859
|
+
if (matches.length === 1) {
|
|
9860
|
+
strippedUnique = matches[0];
|
|
9861
|
+
break;
|
|
9862
|
+
}
|
|
9863
|
+
}
|
|
9864
|
+
out[key] = strippedUnique === original;
|
|
9865
|
+
}
|
|
9866
|
+
return out;
|
|
9867
|
+
}, fields);
|
|
9868
|
+
}
|
|
9869
|
+
function stripPositionClauses2(path5) {
|
|
9870
|
+
return {
|
|
9871
|
+
context: path5.context,
|
|
9872
|
+
nodes: path5.nodes.map((node) => ({
|
|
9873
|
+
...node,
|
|
9874
|
+
match: (node.match || []).filter((clause) => clause.kind !== "position")
|
|
9875
|
+
}))
|
|
9876
|
+
};
|
|
9877
|
+
}
|
|
9878
|
+
|
|
9684
9879
|
// src/cloud/runtime.ts
|
|
9685
9880
|
var DEFAULT_CLOUD_BASE_URL = "https://api.opensteer.com";
|
|
9686
9881
|
function createCloudRuntimeState(key, baseUrl = resolveCloudBaseUrl(), authScheme = "api-key") {
|
|
@@ -9727,6 +9922,7 @@ var CLOUD_INTERACTION_METHODS = /* @__PURE__ */ new Set([
|
|
|
9727
9922
|
]);
|
|
9728
9923
|
var Opensteer = class _Opensteer {
|
|
9729
9924
|
config;
|
|
9925
|
+
runtimeEnv;
|
|
9730
9926
|
aiResolve;
|
|
9731
9927
|
aiExtract;
|
|
9732
9928
|
namespace;
|
|
@@ -9740,14 +9936,17 @@ var Opensteer = class _Opensteer {
|
|
|
9740
9936
|
snapshotCache = null;
|
|
9741
9937
|
agentExecutionInFlight = false;
|
|
9742
9938
|
constructor(config = {}) {
|
|
9743
|
-
const
|
|
9939
|
+
const resolvedRuntime = resolveConfigWithEnv(config);
|
|
9940
|
+
const resolved = resolvedRuntime.config;
|
|
9941
|
+
const runtimeEnv = resolvedRuntime.env;
|
|
9744
9942
|
const cloudSelection = resolveCloudSelection({
|
|
9745
9943
|
cloud: resolved.cloud
|
|
9746
|
-
});
|
|
9944
|
+
}, runtimeEnv);
|
|
9747
9945
|
const model = resolved.model;
|
|
9748
9946
|
this.config = resolved;
|
|
9749
|
-
this.
|
|
9750
|
-
this.
|
|
9947
|
+
this.runtimeEnv = runtimeEnv;
|
|
9948
|
+
this.aiResolve = this.createLazyResolveCallback(model, runtimeEnv);
|
|
9949
|
+
this.aiExtract = this.createLazyExtractCallback(model, runtimeEnv);
|
|
9751
9950
|
const rootDir = resolved.storage?.rootDir || process.cwd();
|
|
9752
9951
|
this.namespace = resolveNamespace(resolved, rootDir);
|
|
9753
9952
|
this.storage = new LocalSelectorStorage(rootDir, this.namespace, {
|
|
@@ -9779,13 +9978,13 @@ var Opensteer = class _Opensteer {
|
|
|
9779
9978
|
`[opensteer] ${context}: ${normalized.message}${codeSuffix}`
|
|
9780
9979
|
);
|
|
9781
9980
|
}
|
|
9782
|
-
createLazyResolveCallback(model) {
|
|
9981
|
+
createLazyResolveCallback(model, env) {
|
|
9783
9982
|
let resolverPromise = null;
|
|
9784
9983
|
return async (...args) => {
|
|
9785
9984
|
try {
|
|
9786
9985
|
if (!resolverPromise) {
|
|
9787
|
-
resolverPromise = import("./resolver-
|
|
9788
|
-
(m) => m.createResolveCallback(model)
|
|
9986
|
+
resolverPromise = import("./resolver-MGN64KCP.js").then(
|
|
9987
|
+
(m) => m.createResolveCallback(model, { env })
|
|
9789
9988
|
);
|
|
9790
9989
|
}
|
|
9791
9990
|
const resolver = await resolverPromise;
|
|
@@ -9796,13 +9995,13 @@ var Opensteer = class _Opensteer {
|
|
|
9796
9995
|
}
|
|
9797
9996
|
};
|
|
9798
9997
|
}
|
|
9799
|
-
createLazyExtractCallback(model) {
|
|
9998
|
+
createLazyExtractCallback(model, env) {
|
|
9800
9999
|
let extractorPromise = null;
|
|
9801
10000
|
const extract = async (args) => {
|
|
9802
10001
|
try {
|
|
9803
10002
|
if (!extractorPromise) {
|
|
9804
|
-
extractorPromise = import("./extractor-
|
|
9805
|
-
(m) => m.createExtractCallback(model)
|
|
10003
|
+
extractorPromise = import("./extractor-4Q3TFZJB.js").then(
|
|
10004
|
+
(m) => m.createExtractCallback(model, { env })
|
|
9806
10005
|
);
|
|
9807
10006
|
}
|
|
9808
10007
|
const extractor = await extractorPromise;
|
|
@@ -10079,10 +10278,11 @@ var Opensteer = class _Opensteer {
|
|
|
10079
10278
|
this.snapshotCache = null;
|
|
10080
10279
|
}
|
|
10081
10280
|
static from(page, config = {}) {
|
|
10082
|
-
const
|
|
10281
|
+
const resolvedRuntime = resolveConfigWithEnv(config);
|
|
10282
|
+
const resolvedConfig = resolvedRuntime.config;
|
|
10083
10283
|
const cloudSelection = resolveCloudSelection({
|
|
10084
10284
|
cloud: resolvedConfig.cloud
|
|
10085
|
-
});
|
|
10285
|
+
}, resolvedRuntime.env);
|
|
10086
10286
|
if (cloudSelection.cloud) {
|
|
10087
10287
|
throw cloudUnsupportedMethodError(
|
|
10088
10288
|
"Opensteer.from(page)",
|
|
@@ -11057,7 +11257,7 @@ var Opensteer = class _Opensteer {
|
|
|
11057
11257
|
const data = await this.extractFields(fields);
|
|
11058
11258
|
if (storageKey && schemaHash && (!stored || stored.schemaHash !== schemaHash)) {
|
|
11059
11259
|
const persistedFields = await this.resolveFieldTargetsToPersistableFields(fields);
|
|
11060
|
-
this.persistExtractPaths(
|
|
11260
|
+
await this.persistExtractPaths(
|
|
11061
11261
|
storageKey,
|
|
11062
11262
|
options.description,
|
|
11063
11263
|
persistedFields,
|
|
@@ -11091,13 +11291,12 @@ var Opensteer = class _Opensteer {
|
|
|
11091
11291
|
const resolvedFields = await this.resolveFieldTargetsToPersistableFields(fields);
|
|
11092
11292
|
let persisted = false;
|
|
11093
11293
|
if (storageKey) {
|
|
11094
|
-
this.persistExtractPaths(
|
|
11294
|
+
persisted = await this.persistExtractPaths(
|
|
11095
11295
|
storageKey,
|
|
11096
11296
|
options.description,
|
|
11097
11297
|
resolvedFields,
|
|
11098
11298
|
schemaHash
|
|
11099
11299
|
);
|
|
11100
|
-
persisted = true;
|
|
11101
11300
|
}
|
|
11102
11301
|
return {
|
|
11103
11302
|
namespace: this.storage.getNamespace(),
|
|
@@ -11129,7 +11328,8 @@ var Opensteer = class _Opensteer {
|
|
|
11129
11328
|
agent(config) {
|
|
11130
11329
|
const resolvedAgentConfig = resolveAgentConfig({
|
|
11131
11330
|
agentConfig: config,
|
|
11132
|
-
fallbackModel: this.config.model
|
|
11331
|
+
fallbackModel: this.config.model,
|
|
11332
|
+
env: this.runtimeEnv
|
|
11133
11333
|
});
|
|
11134
11334
|
return {
|
|
11135
11335
|
execute: async (instructionOrOptions) => {
|
|
@@ -11558,7 +11758,7 @@ var Opensteer = class _Opensteer {
|
|
|
11558
11758
|
this.storage.saveRegistry(registry);
|
|
11559
11759
|
return true;
|
|
11560
11760
|
}
|
|
11561
|
-
persistExtractPaths(id, description, fields, schemaHash) {
|
|
11761
|
+
async persistExtractPaths(id, description, fields, schemaHash) {
|
|
11562
11762
|
const now = Date.now();
|
|
11563
11763
|
const safeFile = this.storage.getSelectorFileName(id);
|
|
11564
11764
|
const existing = this.storage.readSelector(id);
|
|
@@ -11579,11 +11779,19 @@ var Opensteer = class _Opensteer {
|
|
|
11579
11779
|
}
|
|
11580
11780
|
);
|
|
11581
11781
|
const persistedPayload = buildPersistedExtractPayload(normalizedFields);
|
|
11782
|
+
let validatedPayload = persistedPayload;
|
|
11783
|
+
try {
|
|
11784
|
+
validatedPayload = await stripRedundantPositionClauses(
|
|
11785
|
+
persistedPayload,
|
|
11786
|
+
this.page
|
|
11787
|
+
);
|
|
11788
|
+
} catch {
|
|
11789
|
+
}
|
|
11582
11790
|
const payload = {
|
|
11583
11791
|
id,
|
|
11584
11792
|
method: "extract",
|
|
11585
11793
|
description: description || "Extraction paths",
|
|
11586
|
-
path:
|
|
11794
|
+
path: validatedPayload,
|
|
11587
11795
|
schemaHash,
|
|
11588
11796
|
metadata: {
|
|
11589
11797
|
createdAt,
|
|
@@ -12282,6 +12490,8 @@ export {
|
|
|
12282
12490
|
extractArrayWithPaths,
|
|
12283
12491
|
extractArrayRowsWithPaths,
|
|
12284
12492
|
countArrayItemsWithPath,
|
|
12493
|
+
queryAllByElementPath,
|
|
12494
|
+
buildArrayFieldPathCandidates,
|
|
12285
12495
|
listTabs,
|
|
12286
12496
|
createTab,
|
|
12287
12497
|
switchTab,
|