@capagents/forgeqe 1.1.2 → 1.1.4
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/HOW_TO_USE.md +5 -5
- package/README.md +8 -4
- package/browserstack.example.yaml +14 -0
- package/docs/security-data-flow.html +154 -86
- package/docs/user-guide.html +305 -131
- package/forgeqe.example.yaml +12 -6
- package/package.json +4 -2
- package/py/forgeqe_engine/browser.py +78 -11
- package/py/forgeqe_engine/service.py +13 -0
- package/src/auth/signin.ts +2 -2
- package/src/bi.ts +338 -243
- package/src/capabilities/guide.ts +322 -140
- package/src/capabilities/registry.ts +3 -3
- package/src/cli/help.ts +16 -7
- package/src/cli/index.ts +51 -9
- package/src/config.ts +115 -12
- package/src/heal/loop.ts +3 -1
- package/src/init.ts +18 -0
- package/src/mcp/tools.ts +26 -4
- package/src/monitor/run.ts +3 -1
- package/src/run.ts +9 -2
- package/src/suite/run.ts +3 -1
- package/testmu.example.yaml +13 -0
package/src/monitor/run.ts
CHANGED
|
@@ -3,7 +3,7 @@ import path from "node:path"
|
|
|
3
3
|
|
|
4
4
|
import type { Card } from "../card.ts"
|
|
5
5
|
import { loadCases, type TestCase } from "../cases/index.ts"
|
|
6
|
-
import type { AppConfig } from "../config.ts"
|
|
6
|
+
import type { AppConfig, BrowserProvider } from "../config.ts"
|
|
7
7
|
import { counts, suiteUsage } from "../suite/report.ts"
|
|
8
8
|
import { runSuite, type SuiteEvent, type SuiteOptions, type SuiteResult } from "../suite/run.ts"
|
|
9
9
|
import { formatDuration, formatTokens } from "../tui/theme.ts"
|
|
@@ -28,6 +28,7 @@ export type MonitorOptions = {
|
|
|
28
28
|
config: AppConfig
|
|
29
29
|
/** Test case sources; default monitor.checks. */
|
|
30
30
|
checks: string[]
|
|
31
|
+
browserProvider?: BrowserProvider
|
|
31
32
|
headed?: boolean
|
|
32
33
|
url?: string
|
|
33
34
|
/** Browser skills for every check (empty: none); unset: the engine picks once per check for the monitor's lifetime. */
|
|
@@ -67,6 +68,7 @@ export async function monitorRound(opts: MonitorOptions): Promise<RoundResult> {
|
|
|
67
68
|
suite = await runSuite({
|
|
68
69
|
config: { ...config, suite: { ...config.suite, outDir: m.outDir, code: false } },
|
|
69
70
|
cases,
|
|
71
|
+
browserProvider: opts.browserProvider,
|
|
70
72
|
parallel: Math.min(m.parallel, cases.length),
|
|
71
73
|
writeBack: m.writeBack,
|
|
72
74
|
replay: m.replay,
|
package/src/run.ts
CHANGED
|
@@ -5,7 +5,7 @@ import path from "node:path"
|
|
|
5
5
|
import { assertGoalUrlsAllowed, hostAllowed, normalizeHttpUrl } from "./guard.ts"
|
|
6
6
|
import { missingKey } from "./llm.ts"
|
|
7
7
|
import type { AgentEvent, ReplayMode, RunResult } from "./types.ts"
|
|
8
|
-
import type
|
|
8
|
+
import { browserConfigFor, type AppConfig, type BrowserProvider } from "./config.ts"
|
|
9
9
|
import { runEngine } from "./engine/bridge.ts"
|
|
10
10
|
import { MOCK_ENGINE } from "./engine/mock.ts"
|
|
11
11
|
import { ensureEngine } from "./engine/setup.ts"
|
|
@@ -23,6 +23,7 @@ import { knowledgeBlock, readKnowledge, relevantKnowledge } from "./knowledge.ts
|
|
|
23
23
|
export type ExecuteOptions = {
|
|
24
24
|
config: AppConfig
|
|
25
25
|
goal: string
|
|
26
|
+
browserProvider?: BrowserProvider
|
|
26
27
|
url?: string
|
|
27
28
|
headed?: boolean
|
|
28
29
|
maxSteps?: number
|
|
@@ -148,6 +149,7 @@ export async function executeRun(opts: ExecuteOptions): Promise<{ result: RunRes
|
|
|
148
149
|
|
|
149
150
|
const dir = opts.outDir || runDirectory(opts.config.export.outDir)
|
|
150
151
|
const maxSteps = opts.maxSteps || opts.config.browser.maxSteps
|
|
152
|
+
const browser = browserConfigFor(opts.config, opts.browserProvider)
|
|
151
153
|
const t0 = Date.now()
|
|
152
154
|
const withReport = (out: { result: RunResult; files: string[] }) => {
|
|
153
155
|
out.result.cost = costOf(out.result.usage, opts.config.llm.price)
|
|
@@ -179,6 +181,11 @@ export async function executeRun(opts: ExecuteOptions): Promise<{ result: RunRes
|
|
|
179
181
|
|
|
180
182
|
const missing = missingKey(opts.config.llm)
|
|
181
183
|
if (missing) throw new Error(missing)
|
|
184
|
+
// A remote grid's keys are checked here, before the engine starts, rather than failing inside it.
|
|
185
|
+
if (browser.remote) {
|
|
186
|
+
const unset = [browser.remote.usernameEnv, browser.remote.accessKeyEnv].filter((name) => !process.env[name]?.trim())
|
|
187
|
+
if (unset.length) throw new Error(`${browser.provider}: set ${unset.join(" and ")} in the environment, or save them with "forgeqe auth login ${browser.provider}".`)
|
|
188
|
+
}
|
|
182
189
|
const log = (text: string) => opts.onEvent?.({ type: "log", level: "info", text })
|
|
183
190
|
const python = await ensureEngine(log)
|
|
184
191
|
// The browser agent's added instructions: forgeqe.yaml's, prompts/browser-extra.md, and the product knowledge that matches the goal.
|
|
@@ -216,7 +223,7 @@ export async function executeRun(opts: ExecuteOptions): Promise<{ result: RunRes
|
|
|
216
223
|
headed: Boolean(opts.headed) || !opts.config.browser.headless,
|
|
217
224
|
maxSteps,
|
|
218
225
|
allowedHosts: allowed,
|
|
219
|
-
browser
|
|
226
|
+
browser,
|
|
220
227
|
extendSystemMessage: extend || undefined,
|
|
221
228
|
memory,
|
|
222
229
|
env,
|
package/src/suite/run.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { costOf } from "../cases/types.ts"
|
|
|
6
6
|
import { addUsage, NO_USAGE } from "../usage.ts"
|
|
7
7
|
import type { AgentEvent, CodeResult, ReplayMode, RunResult } from "../types.ts"
|
|
8
8
|
import { codeSkipReason, runCodeAgent } from "../code/index.ts"
|
|
9
|
-
import type { AppConfig } from "../config.ts"
|
|
9
|
+
import type { AppConfig, BrowserProvider } from "../config.ts"
|
|
10
10
|
import { fileBugs } from "../cases/bugs.ts"
|
|
11
11
|
import { classifyFailure, FAILURE_LABEL } from "../cases/failure.ts"
|
|
12
12
|
import { associateAdoAutomation, readMappings } from "../code/traceability.ts"
|
|
@@ -43,6 +43,7 @@ export type SuiteOptions = {
|
|
|
43
43
|
cases: TestCase[]
|
|
44
44
|
/** Repo for the coding agent; unset: browser runs only. */
|
|
45
45
|
repo?: string
|
|
46
|
+
browserProvider?: BrowserProvider
|
|
46
47
|
parallel?: number
|
|
47
48
|
outDir?: string
|
|
48
49
|
writeBack?: boolean
|
|
@@ -104,6 +105,7 @@ export async function runSuite(opts: SuiteOptions): Promise<SuiteResult> {
|
|
|
104
105
|
const { result } = await execute({
|
|
105
106
|
config,
|
|
106
107
|
goal: goalFor(tc),
|
|
108
|
+
browserProvider: opts.browserProvider,
|
|
107
109
|
url: tc.startUrl || opts.url,
|
|
108
110
|
headed: opts.headed,
|
|
109
111
|
maxSteps: opts.maxSteps,
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
provider: testmu
|
|
2
|
+
remote:
|
|
3
|
+
browser: Chrome
|
|
4
|
+
browser_version: latest
|
|
5
|
+
platform: Windows 11
|
|
6
|
+
username_env: LT_USERNAME
|
|
7
|
+
access_key_env: LT_ACCESS_KEY
|
|
8
|
+
project: ForgeQE
|
|
9
|
+
build: nightly
|
|
10
|
+
name: checkout smoke
|
|
11
|
+
local: false
|
|
12
|
+
extra: # merged into LT:Options, so keys go straight here
|
|
13
|
+
console: true
|