tamash-playwright 0.11.0-beta.3 → 0.11.0-beta.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/.env.example +11 -1
- package/CHANGELOG.md +9 -0
- package/README.md +23 -1
- package/RELEASE-TESTING.md +1 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +4 -3
- package/dist/cli/doctor.js.map +1 -1
- package/dist/healer/providers/index.d.ts.map +1 -1
- package/dist/healer/providers/index.js +4 -0
- package/dist/healer/providers/index.js.map +1 -1
- package/dist/healer/providers/ollama-local.d.ts +3 -0
- package/dist/healer/providers/ollama-local.d.ts.map +1 -0
- package/dist/healer/providers/ollama-local.js +194 -0
- package/dist/healer/providers/ollama-local.js.map +1 -0
- package/package.json +1 -1
- package/usage.md +22 -2
package/.env.example
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Master on/off switch for self-healing. Unset or anything other than false/0 leaves it on.
|
|
2
2
|
HEALER_ENABLED=true
|
|
3
3
|
|
|
4
|
-
# Which AI provider backs self-healing: ollama | openai | anthropic | gemini | claude-subscription | copilot-subscription | tamash
|
|
4
|
+
# Which AI provider backs self-healing: ollama | ollama-local | openai | anthropic | gemini | claude-subscription | copilot-subscription | tamash
|
|
5
5
|
# Unset, unknown, or a provider whose key/model below is missing disables self-healing —
|
|
6
6
|
# a failed action just fails normally, since there's no AI model configured to recover it.
|
|
7
7
|
# claude-subscription/copilot-subscription don't need an API key at all — they use an existing
|
|
@@ -14,6 +14,16 @@ OLLAMA_MODEL=gpt-oss:120b
|
|
|
14
14
|
OLLAMA_API_KEY=
|
|
15
15
|
# OLLAMA_BASE_URL=https://ollama.com
|
|
16
16
|
|
|
17
|
+
# --- Ollama, self-hosted/internal server (a separate provider from Ollama Cloud above) ---
|
|
18
|
+
# For your own `ollama serve` instance, or an internal deployment your company hosts. A bare
|
|
19
|
+
# `ollama serve` has no auth at all -- leave OLLAMA_LOCAL_API_KEY unset. If your deployment sits
|
|
20
|
+
# behind a reverse proxy or API gateway that requires a bearer token, set it and it's sent as
|
|
21
|
+
# `Authorization: Bearer <token>`; no other auth scheme is currently supported.
|
|
22
|
+
# HEALER_PROVIDER=ollama-local
|
|
23
|
+
# OLLAMA_LOCAL_MODEL=gpt-oss:120b
|
|
24
|
+
# OLLAMA_LOCAL_BASE_URL=http://localhost:11434
|
|
25
|
+
# OLLAMA_LOCAL_API_KEY=
|
|
26
|
+
|
|
17
27
|
# --- OpenAI ---
|
|
18
28
|
# OPENAI_MODEL=gpt-4.1-mini
|
|
19
29
|
# OPENAI_API_KEY=
|
package/CHANGELOG.md
CHANGED
|
@@ -52,6 +52,15 @@ All notable changes to this project are documented here. Format loosely follows
|
|
|
52
52
|
*why* an action failed, which is inference this provider deliberately doesn't attempt) — a fast,
|
|
53
53
|
free, fully deterministic first line of defense, best suited to well-`.describe()`d,
|
|
54
54
|
Page-Object-style suites.
|
|
55
|
+
- **A new `ollama-local` heal provider for self-hosted Ollama servers.** `HEALER_PROVIDER=ollama-local`
|
|
56
|
+
targets your own `ollama serve` instance or an internal company deployment, instead of Ollama
|
|
57
|
+
Cloud — a deliberately separate provider from `ollama`, not a flag on it, since the two have
|
|
58
|
+
genuinely different auth defaults: Ollama Cloud always requires `OLLAMA_API_KEY`, while
|
|
59
|
+
`OLLAMA_LOCAL_API_KEY` is optional, since a bare `ollama serve` has no authentication at all. Set
|
|
60
|
+
it only if your internal deployment sits behind a reverse proxy or API gateway that requires a
|
|
61
|
+
bearer token — verified against a real HTTP server both ways, confirming the `Authorization`
|
|
62
|
+
header is omitted entirely when no key is set, and sent correctly when one is. Prompted by a real
|
|
63
|
+
support request from a team wanting to use their own internally-hosted `gpt-oss:120b`.
|
|
55
64
|
- **Undescribed, POM-style locator variables now get a real description automatically.** When
|
|
56
65
|
`.describe()` was never called, the healer already fell back to the locator's own variable/
|
|
57
66
|
property name (`txtEmployeeId`) as its best guess at intent — now that raw identifier is decoded
|
package/README.md
CHANGED
|
@@ -40,13 +40,19 @@ Create a file named `.env` in your project folder:
|
|
|
40
40
|
# Master on/off switch. Leave this as true, or remove the line entirely.
|
|
41
41
|
HEALER_ENABLED=true
|
|
42
42
|
|
|
43
|
-
# Pick one: ollama | openai | anthropic | gemini | claude-subscription | copilot-subscription | tamash
|
|
43
|
+
# Pick one: ollama | ollama-local | openai | anthropic | gemini | claude-subscription | copilot-subscription | tamash
|
|
44
44
|
HEALER_PROVIDER=ollama
|
|
45
45
|
|
|
46
46
|
# --- Ollama Cloud (https://ollama.com) ---
|
|
47
47
|
OLLAMA_MODEL=gpt-oss:120b
|
|
48
48
|
OLLAMA_API_KEY=
|
|
49
49
|
|
|
50
|
+
# --- Ollama, self-hosted/internal server (a separate provider from Ollama Cloud above) ---
|
|
51
|
+
# HEALER_PROVIDER=ollama-local
|
|
52
|
+
# OLLAMA_LOCAL_MODEL=gpt-oss:120b
|
|
53
|
+
# OLLAMA_LOCAL_BASE_URL=http://localhost:11434
|
|
54
|
+
# OLLAMA_LOCAL_API_KEY=
|
|
55
|
+
|
|
50
56
|
# --- OpenAI ---
|
|
51
57
|
# OPENAI_MODEL=gpt-4.1-mini
|
|
52
58
|
# OPENAI_API_KEY=
|
|
@@ -87,6 +93,22 @@ OLLAMA_API_KEY=paste_your_key_here
|
|
|
87
93
|
|
|
88
94
|
That's all you need — no other variables required.
|
|
89
95
|
|
|
96
|
+
### Using your own self-hosted Ollama server instead of Ollama Cloud
|
|
97
|
+
|
|
98
|
+
If your team already runs its own Ollama server internally (self-hosted, same model — e.g. `gpt-oss:120b`), point at it directly instead of Ollama Cloud with the separate `ollama-local` provider:
|
|
99
|
+
|
|
100
|
+
```sh
|
|
101
|
+
HEALER_PROVIDER=ollama-local
|
|
102
|
+
OLLAMA_LOCAL_MODEL=gpt-oss:120b
|
|
103
|
+
OLLAMA_LOCAL_BASE_URL=http://your-internal-ollama-host:11434
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
This is a distinct provider from `ollama` above, not a flag on it — the two have genuinely different auth defaults, not just different default hosts:
|
|
107
|
+
|
|
108
|
+
- **A bare `ollama serve` has no authentication at all.** Leave `OLLAMA_LOCAL_API_KEY` unset and it won't send an `Authorization` header — a self-hosted server doesn't need one, and there's no cloud account to authenticate against.
|
|
109
|
+
- **If your deployment sits behind a reverse proxy or API gateway that does require a token**, set `OLLAMA_LOCAL_API_KEY` and it's sent the same way as the cloud provider's key (`Authorization: Bearer <token>`). No other auth scheme (Basic auth, a custom header, mTLS) is currently supported — open an issue if you need one.
|
|
110
|
+
- `OLLAMA_LOCAL_BASE_URL` defaults to `http://localhost:11434` (a plain local `ollama serve`) if you don't set it.
|
|
111
|
+
|
|
90
112
|
### Using your Claude or GitHub Copilot subscription instead of an API key
|
|
91
113
|
|
|
92
114
|
If you don't have an API key issued to you but do have a personal Claude (Pro/Max/Team/Enterprise) or GitHub Copilot subscription (including the free tier), you can use that instead — no billing setup, no key to paste anywhere.
|
package/RELEASE-TESTING.md
CHANGED
|
@@ -33,6 +33,7 @@ currently covered · N/A not applicable to that column.
|
|
|
33
33
|
| `doctor` CLI | Pre-flight checks: provider connectivity, `actionTimeout`, vision capability, missing `.describe()`, inline locators. | ✅ Run live against every provider including `tamash` this session | ❌ Not run as part of either CI workflow |
|
|
34
34
|
| `getDurable()` | Resolves any locator (e.g. `aria-ref=...`) to a durable, reusable equivalent. | ✅ e2e (`get-durable-*-repro`, 4 specs incl. concurrency) | ❌ No CI sample test calls it directly |
|
|
35
35
|
| Provider: `ollama` | API-key provider, Ollama Cloud. | ✅ Verified this session (live calls, real token counts) | ✅ Both CI workflows now run a `test-ollama` job, confirmed green |
|
|
36
|
+
| Provider: `ollama-local` | Self-hosted Ollama server; `OLLAMA_LOCAL_API_KEY` optional, unlike `ollama`'s required key. | ✅ Verified against a genuine local Ollama installation this session (real `ollama serve`, `qwen2.5:0.5b` pulled and warmed) — confirmed the default `OLLAMA_LOCAL_BASE_URL`, real request/response round-trip (including correct token-usage extraction), and that the real server both works with no `Authorization` header and tolerates one being sent unnecessarily; also confirmed end-to-end via the real `doctor` CLI, not just a direct provider call. (A synthetic fake-HTTP-server test preceded this and is superseded by it.) | ❌ Not used in either CI workflow (no self-hosted Ollama instance available in CI) |
|
|
36
37
|
| Provider: `openai` | API-key provider. | ✅ Re-verified live this release (`doctor` connectivity, real key) | ❌ Not used in either CI workflow |
|
|
37
38
|
| Provider: `anthropic` | API-key provider. | ✅ Re-verified live this release (`doctor` connectivity, real key) | ❌ Not used in either CI workflow |
|
|
38
39
|
| Provider: `gemini` | API-key provider. | ⚠️ Key authenticates and the model responds correctly (verified with a raw request, real `200 OK`), but `gemini-3.6-flash` took 50+ seconds to answer a trivial prompt — far beyond `doctor`'s 15s timeout and this repo's real `actionTimeout: 8000`ms, so it fails both `doctor` and real healing as currently configured, despite the key itself being valid | ❌ Not used in either CI workflow |
|
package/dist/cli/doctor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"AA0MA,wBAAsB,SAAS,CAAC,IAAI,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BlE"}
|
package/dist/cli/doctor.js
CHANGED
|
@@ -48,9 +48,10 @@ async function checkProviderConnectivity() {
|
|
|
48
48
|
if (!providerName) {
|
|
49
49
|
console.log(` ${TAG_WARN} HEALER_PROVIDER is not set. No AI provider is configured, so self-healing will never`);
|
|
50
50
|
console.log(' recover a failed action — it will just fail normally.');
|
|
51
|
-
console.log(' Set HEALER_PROVIDER (ollama | openai | anthropic | gemini |
|
|
52
|
-
console.log(' copilot-subscription | tamash) plus its API key/model (or, for
|
|
53
|
-
console.log(' copilot-subscription, a subscription login; tamash needs neither —
|
|
51
|
+
console.log(' Set HEALER_PROVIDER (ollama | ollama-local | openai | anthropic | gemini |');
|
|
52
|
+
console.log(' claude-subscription | copilot-subscription | tamash) plus its API key/model (or, for');
|
|
53
|
+
console.log(' claude-subscription/copilot-subscription, a subscription login; tamash needs neither —');
|
|
54
|
+
console.log(' see its own docs).');
|
|
54
55
|
record('AI Provider', 'WARN', 'HEALER_PROVIDER is not set');
|
|
55
56
|
return;
|
|
56
57
|
}
|
package/dist/cli/doctor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAwB;AACxB,oDAA4B;AAC5B,mDAAsD;AACtD,sCAA6C;AAC7C,mFAA0F;AAC1F,iDAA2E;AAC3E,2DAAyD;AACzD,mDAAwH;AAExH,gBAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;AAE7D,MAAM,uBAAuB,GAAG,KAAK,CAAC;AACtC,MAAM,qBAAqB,GAAG,8DAA8D,CAAC;AAE7F,MAAM,MAAM,GAAG,IAAA,qBAAK,EAAC,MAAM,CAAC,CAAC;AAC7B,MAAM,QAAQ,GAAG,IAAA,sBAAM,EAAC,QAAQ,CAAC,CAAC;AAClC,MAAM,QAAQ,GAAG,IAAA,mBAAG,EAAC,QAAQ,CAAC,CAAC;AAC/B,MAAM,QAAQ,GAAG,IAAA,oBAAI,EAAC,QAAQ,CAAC,CAAC;AAChC,MAAM,QAAQ,GAAG,IAAA,mBAAG,EAAC,QAAQ,CAAC,CAAC;AAC/B,MAAM,OAAO,GAAG,IAAA,mBAAG,EAAC,QAAQ,CAAC,CAAC;AAG9B,MAAM,YAAY,GAA0C;IAC1D,EAAE,EAAE,qBAAK;IACT,IAAI,EAAE,sBAAM;IACZ,IAAI,EAAE,mBAAG;IACT,IAAI,EAAE,oBAAI;IACV,GAAG,EAAE,mBAAG;CACT,CAAC;AAMF,MAAM,OAAO,GAAkB,EAAE,CAAC;AAClC,SAAS,MAAM,CAAC,KAAa,EAAE,MAAc,EAAE,MAAc;IAC3D,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,YAAY;IACnB,IAAA,uBAAO,EAAC,SAAS,CAAC,CAAC;IACnB,IAAA,2BAAW,EACT,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAC7B,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAA,2BAAW,EAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAC3F,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,yBAAyB;IACtC,IAAA,uBAAO,EAAC,aAAa,CAAC,CAAC;IACvB,OAAO,CAAC,GAAG,CAAC,qBAAqB,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,IAAA,mBAAG,EAAC,4BAA4B,CAAC,EAAE,CAAC,CAAC;IACpG,IAAI,CAAC,IAAA,yBAAgB,GAAE,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,8FAA8F,CAAC,CAAC;QAC5G,MAAM,CAAC,aAAa,EAAE,KAAK,EAAE,yCAAyC,CAAC,CAAC;QACxE,OAAO;IACT,CAAC;IAED,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IACjD,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,KAAK,QAAQ,uFAAuF,CAAC,CAAC;QAClH,OAAO,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAC;QAC9E,OAAO,CAAC,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/healer/providers/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/healer/providers/index.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAYlH,wBAAgB,eAAe,IAAI,YAAY,GAAG,IAAI,CAmCrD"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getHealProvider = getHealProvider;
|
|
4
4
|
const ollama_1 = require("./ollama");
|
|
5
|
+
const ollama_local_1 = require("./ollama-local");
|
|
5
6
|
const openai_1 = require("./openai");
|
|
6
7
|
const anthropic_1 = require("./anthropic");
|
|
7
8
|
const gemini_1 = require("./gemini");
|
|
@@ -25,6 +26,9 @@ function getHealProvider() {
|
|
|
25
26
|
case 'ollama':
|
|
26
27
|
cachedProvider = (0, ollama_1.createOllamaProvider)();
|
|
27
28
|
break;
|
|
29
|
+
case 'ollama-local':
|
|
30
|
+
cachedProvider = (0, ollama_local_1.createOllamaLocalProvider)();
|
|
31
|
+
break;
|
|
28
32
|
case 'openai':
|
|
29
33
|
cachedProvider = (0, openai_1.createOpenAIProvider)();
|
|
30
34
|
break;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/healer/providers/index.ts"],"names":[],"mappings":";;;AAAA,qCAAgD;AAChD,qCAAgD;AAChD,2CAAsD;AACtD,qCAAgD;AAChD,+DAAyE;AACzE,iEAA2E;AAC3E,2DAAoE;AAKpE,IAAI,cAA+C,CAAC;AAEpD,uFAAuF;AACvF,qFAAqF;AACrF,oFAAoF;AACpF,8FAA8F;AAC9F,4FAA4F;AAC5F,6FAA6F;AAC7F,gGAAgG;AAChG,uEAAuE;AACvE;IACE,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;QACjC,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,QAAQ,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC;QACpC,KAAK,QAAQ;YACX,cAAc,GAAG,IAAA,6BAAoB,GAAE,CAAC;YACxC,MAAM;QACR,KAAK,QAAQ;YACX,cAAc,GAAG,IAAA,6BAAoB,GAAE,CAAC;YACxC,MAAM;QACR,KAAK,WAAW;YACd,cAAc,GAAG,IAAA,mCAAuB,GAAE,CAAC;YAC3C,MAAM;QACR,KAAK,QAAQ;YACX,cAAc,GAAG,IAAA,6BAAoB,GAAE,CAAC;YACxC,MAAM;QACR,KAAK,qBAAqB;YACxB,cAAc,GAAG,IAAA,sDAAgC,GAAE,CAAC;YACpD,MAAM;QACR,KAAK,sBAAsB;YACzB,cAAc,GAAG,IAAA,wDAAiC,GAAE,CAAC;YACrD,MAAM;QACR,KAAK,QAAQ;YACX,cAAc,GAAG,IAAA,iDAA6B,GAAE,CAAC;YACjD,MAAM;QACR;YACE,cAAc,GAAG,IAAI,CAAC;IAC1B,CAAC;IAED,OAAO,cAAc,CAAC;AACxB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/healer/providers/index.ts"],"names":[],"mappings":";;;AAAA,qCAAgD;AAChD,iDAA2D;AAC3D,qCAAgD;AAChD,2CAAsD;AACtD,qCAAgD;AAChD,+DAAyE;AACzE,iEAA2E;AAC3E,2DAAoE;AAKpE,IAAI,cAA+C,CAAC;AAEpD,uFAAuF;AACvF,qFAAqF;AACrF,oFAAoF;AACpF,8FAA8F;AAC9F,4FAA4F;AAC5F,6FAA6F;AAC7F,gGAAgG;AAChG,uEAAuE;AACvE;IACE,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;QACjC,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,QAAQ,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC;QACpC,KAAK,QAAQ;YACX,cAAc,GAAG,IAAA,6BAAoB,GAAE,CAAC;YACxC,MAAM;QACR,KAAK,cAAc;YACjB,cAAc,GAAG,IAAA,wCAAyB,GAAE,CAAC;YAC7C,MAAM;QACR,KAAK,QAAQ;YACX,cAAc,GAAG,IAAA,6BAAoB,GAAE,CAAC;YACxC,MAAM;QACR,KAAK,WAAW;YACd,cAAc,GAAG,IAAA,mCAAuB,GAAE,CAAC;YAC3C,MAAM;QACR,KAAK,QAAQ;YACX,cAAc,GAAG,IAAA,6BAAoB,GAAE,CAAC;YACxC,MAAM;QACR,KAAK,qBAAqB;YACxB,cAAc,GAAG,IAAA,sDAAgC,GAAE,CAAC;YACpD,MAAM;QACR,KAAK,sBAAsB;YACzB,cAAc,GAAG,IAAA,wDAAiC,GAAE,CAAC;YACrD,MAAM;QACR,KAAK,QAAQ;YACX,cAAc,GAAG,IAAA,iDAA6B,GAAE,CAAC;YACjD,MAAM;QACR;YACE,cAAc,GAAG,IAAI,CAAC;IAC1B,CAAC;IAED,OAAO,cAAc,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ollama-local.d.ts","sourceRoot":"","sources":["../../../src/healer/providers/ollama-local.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,YAAY,EAAsH,MAAM,SAAS,CAAC;AAiBpL,wBAAgB,yBAAyB,IAAI,YAAY,GAAG,IAAI,CAuM/D"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createOllamaLocalProvider = createOllamaLocalProvider;
|
|
4
|
+
const prompt_1 = require("./prompt");
|
|
5
|
+
const vision_models_1 = require("./vision-models");
|
|
6
|
+
// Fallback only — normally overridden by SuggestSelectorInput.timeoutMs, which mirrors the
|
|
7
|
+
// Playwright project's configured actionTimeout so the healer never outlasts the action budget.
|
|
8
|
+
const REQUEST_TIMEOUT_MS = 15000;
|
|
9
|
+
// A deliberately separate provider from `ollama` (ollama.ts), not a flag on it -- the two have
|
|
10
|
+
// genuinely different auth defaults, not just different default hosts. Ollama Cloud always
|
|
11
|
+
// requires OLLAMA_API_KEY; a self-hosted/internal Ollama server reached via OLLAMA_LOCAL_BASE_URL
|
|
12
|
+
// varies by deployment -- a bare `ollama serve` has no auth at all, but plenty of real internal
|
|
13
|
+
// deployments sit behind a reverse proxy or API gateway that does require a bearer token. Rather
|
|
14
|
+
// than guess either way, OLLAMA_LOCAL_API_KEY is optional: attach it when the deployment needs
|
|
15
|
+
// one, leave it unset when it doesn't. Keeping this as its own provider name (rather than making
|
|
16
|
+
// ollama.ts's own key optional) means the cloud provider's real requirement is never weakened,
|
|
17
|
+
// and `doctor`/reports/logs can tell at a glance which kind of endpoint actually served a heal.
|
|
18
|
+
function createOllamaLocalProvider() {
|
|
19
|
+
const apiKey = process.env.OLLAMA_LOCAL_API_KEY;
|
|
20
|
+
const model = process.env.OLLAMA_LOCAL_MODEL;
|
|
21
|
+
if (!model) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
const baseUrl = (process.env.OLLAMA_LOCAL_BASE_URL ?? 'http://localhost:11434').replace(/\/+$/, '');
|
|
25
|
+
const supportsVision = (0, vision_models_1.isVisionCapableModel)('ollama', model);
|
|
26
|
+
const headers = { 'content-type': 'application/json' };
|
|
27
|
+
if (apiKey) {
|
|
28
|
+
headers.authorization = `Bearer ${apiKey}`;
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
name: `ollama-local:${model}`,
|
|
32
|
+
supportsVision,
|
|
33
|
+
async suggestSelector(input) {
|
|
34
|
+
const controller = new AbortController();
|
|
35
|
+
const timeout = setTimeout(() => controller.abort(), input.timeoutMs ?? REQUEST_TIMEOUT_MS);
|
|
36
|
+
try {
|
|
37
|
+
// Ollama's native endpoint (`/api/chat`), not the OpenAI-compatible `/v1/chat/completions`
|
|
38
|
+
// path -- same reasoning as ollama.ts: this is what a real Ollama server (cloud or local)
|
|
39
|
+
// actually serves.
|
|
40
|
+
const response = await fetch(`${baseUrl}/api/chat`, {
|
|
41
|
+
method: 'POST',
|
|
42
|
+
signal: controller.signal,
|
|
43
|
+
headers,
|
|
44
|
+
body: JSON.stringify({
|
|
45
|
+
model,
|
|
46
|
+
stream: false,
|
|
47
|
+
format: 'json',
|
|
48
|
+
options: { temperature: 0 },
|
|
49
|
+
messages: [
|
|
50
|
+
{ role: 'system', content: prompt_1.SYSTEM_PROMPT },
|
|
51
|
+
{ role: 'user', content: (0, prompt_1.buildUserPrompt)(input) },
|
|
52
|
+
],
|
|
53
|
+
}),
|
|
54
|
+
});
|
|
55
|
+
if (!response.ok) {
|
|
56
|
+
console.warn(`[self-healer] Ollama (local) request failed: ${response.status} ${response.statusText}`);
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
const payload = await response.json();
|
|
60
|
+
const content = payload.message?.content;
|
|
61
|
+
if (!content) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
const suggestion = (0, prompt_1.parseSuggestion)(content);
|
|
65
|
+
if (!suggestion) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
const inputTokens = payload.prompt_eval_count;
|
|
69
|
+
const outputTokens = payload.eval_count;
|
|
70
|
+
return {
|
|
71
|
+
suggestion,
|
|
72
|
+
usage: {
|
|
73
|
+
inputTokens,
|
|
74
|
+
outputTokens,
|
|
75
|
+
totalTokens: inputTokens !== undefined && outputTokens !== undefined ? inputTokens + outputTokens : undefined,
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
81
|
+
console.warn(`[self-healer] Ollama (local) provider error: ${reason}`);
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
finally {
|
|
85
|
+
clearTimeout(timeout);
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
async suggestSelectorFromImage(input) {
|
|
89
|
+
const controller = new AbortController();
|
|
90
|
+
const timeout = setTimeout(() => controller.abort(), input.timeoutMs ?? REQUEST_TIMEOUT_MS);
|
|
91
|
+
try {
|
|
92
|
+
const response = await fetch(`${baseUrl}/api/chat`, {
|
|
93
|
+
method: 'POST',
|
|
94
|
+
signal: controller.signal,
|
|
95
|
+
headers,
|
|
96
|
+
body: JSON.stringify({
|
|
97
|
+
model,
|
|
98
|
+
stream: false,
|
|
99
|
+
format: 'json',
|
|
100
|
+
options: { temperature: 0 },
|
|
101
|
+
messages: [
|
|
102
|
+
{ role: 'system', content: prompt_1.VISION_SYSTEM_PROMPT },
|
|
103
|
+
{ role: 'user', content: (0, prompt_1.buildVisionUserPrompt)(input), images: [input.imageBase64] },
|
|
104
|
+
],
|
|
105
|
+
}),
|
|
106
|
+
});
|
|
107
|
+
if (!response.ok) {
|
|
108
|
+
console.warn(`[self-healer] Ollama (local) vision request failed: ${response.status} ${response.statusText}`);
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
const payload = await response.json();
|
|
112
|
+
const content = payload.message?.content;
|
|
113
|
+
if (!content) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
const point = (0, prompt_1.parseVisionSuggestion)(content);
|
|
117
|
+
if (!point) {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
const inputTokens = payload.prompt_eval_count;
|
|
121
|
+
const outputTokens = payload.eval_count;
|
|
122
|
+
return {
|
|
123
|
+
point,
|
|
124
|
+
usage: {
|
|
125
|
+
inputTokens,
|
|
126
|
+
outputTokens,
|
|
127
|
+
totalTokens: inputTokens !== undefined && outputTokens !== undefined ? inputTokens + outputTokens : undefined,
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
133
|
+
console.warn(`[self-healer] Ollama (local) vision provider error: ${reason}`);
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
finally {
|
|
137
|
+
clearTimeout(timeout);
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
async suggestActionTactic(input) {
|
|
141
|
+
const controller = new AbortController();
|
|
142
|
+
const timeout = setTimeout(() => controller.abort(), input.timeoutMs ?? REQUEST_TIMEOUT_MS);
|
|
143
|
+
try {
|
|
144
|
+
const response = await fetch(`${baseUrl}/api/chat`, {
|
|
145
|
+
method: 'POST',
|
|
146
|
+
signal: controller.signal,
|
|
147
|
+
headers,
|
|
148
|
+
body: JSON.stringify({
|
|
149
|
+
model,
|
|
150
|
+
stream: false,
|
|
151
|
+
format: 'json',
|
|
152
|
+
options: { temperature: 0 },
|
|
153
|
+
messages: [
|
|
154
|
+
{ role: 'system', content: prompt_1.ACTION_RECOVERY_SYSTEM_PROMPT },
|
|
155
|
+
{ role: 'user', content: (0, prompt_1.buildActionRecoveryUserPrompt)(input) },
|
|
156
|
+
],
|
|
157
|
+
}),
|
|
158
|
+
});
|
|
159
|
+
if (!response.ok) {
|
|
160
|
+
console.warn(`[self-healer] Ollama (local) action-recovery request failed: ${response.status} ${response.statusText}`);
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
const payload = await response.json();
|
|
164
|
+
const content = payload.message?.content;
|
|
165
|
+
if (!content) {
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
const tactic = (0, prompt_1.parseActionTacticSuggestion)(content);
|
|
169
|
+
if (!tactic) {
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
const inputTokens = payload.prompt_eval_count;
|
|
173
|
+
const outputTokens = payload.eval_count;
|
|
174
|
+
return {
|
|
175
|
+
tactic,
|
|
176
|
+
usage: {
|
|
177
|
+
inputTokens,
|
|
178
|
+
outputTokens,
|
|
179
|
+
totalTokens: inputTokens !== undefined && outputTokens !== undefined ? inputTokens + outputTokens : undefined,
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
185
|
+
console.warn(`[self-healer] Ollama (local) action-recovery provider error: ${reason}`);
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
finally {
|
|
189
|
+
clearTimeout(timeout);
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=ollama-local.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ollama-local.js","sourceRoot":"","sources":["../../../src/healer/providers/ollama-local.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tamash-playwright",
|
|
3
|
-
"version": "0.11.0-beta.
|
|
3
|
+
"version": "0.11.0-beta.4",
|
|
4
4
|
"description": "Plug and Play Self-healing for Playwright and automatically recovers broken selectors using an AI model (Ollama, OpenAI, Anthropic, Gemini, or a Claude/GitHub Copilot subscription).",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
package/usage.md
CHANGED
|
@@ -51,13 +51,19 @@ That's the whole install. No config files created, no postinstall scripts.
|
|
|
51
51
|
# Master on/off switch. Leave this as true, or remove the line entirely.
|
|
52
52
|
HEALER_ENABLED=true
|
|
53
53
|
|
|
54
|
-
# Pick one: ollama | openai | anthropic | gemini | claude-subscription | copilot-subscription | tamash
|
|
54
|
+
# Pick one: ollama | ollama-local | openai | anthropic | gemini | claude-subscription | copilot-subscription | tamash
|
|
55
55
|
HEALER_PROVIDER=ollama
|
|
56
56
|
|
|
57
57
|
# --- Ollama Cloud (https://ollama.com) ---
|
|
58
58
|
OLLAMA_MODEL=gpt-oss:120b
|
|
59
59
|
OLLAMA_API_KEY=
|
|
60
60
|
|
|
61
|
+
# --- Ollama, self-hosted/internal server (separate from Ollama Cloud above) ---
|
|
62
|
+
# HEALER_PROVIDER=ollama-local
|
|
63
|
+
# OLLAMA_LOCAL_MODEL=gpt-oss:120b
|
|
64
|
+
# OLLAMA_LOCAL_BASE_URL=http://localhost:11434
|
|
65
|
+
# OLLAMA_LOCAL_API_KEY=
|
|
66
|
+
|
|
61
67
|
# --- OpenAI ---
|
|
62
68
|
# OPENAI_MODEL=gpt-4.1-mini
|
|
63
69
|
# OPENAI_API_KEY=
|
|
@@ -79,6 +85,19 @@ Fill in the API key and model for whichever provider you pick, and leave the res
|
|
|
79
85
|
2. Go to [ollama.com/settings/keys](https://ollama.com/settings/keys) and create a new API key.
|
|
80
86
|
3. Paste it into `.env` as `OLLAMA_API_KEY`. `HEALER_PROVIDER=ollama` and `OLLAMA_MODEL=gpt-oss:120b` above are already set — nothing else is required.
|
|
81
87
|
|
|
88
|
+
### Self-hosted Ollama: `HEALER_PROVIDER=ollama-local`
|
|
89
|
+
|
|
90
|
+
A distinct provider from `ollama` above, not a flag on it — the auth default is genuinely different, not just the default host:
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
HEALER_PROVIDER=ollama-local
|
|
94
|
+
OLLAMA_LOCAL_MODEL=gpt-oss:120b
|
|
95
|
+
OLLAMA_LOCAL_BASE_URL=http://your-internal-ollama-host:11434 # defaults to http://localhost:11434
|
|
96
|
+
# OLLAMA_LOCAL_API_KEY= # only if your deployment requires one — see below
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
A bare `ollama serve` has no authentication at all, so `OLLAMA_LOCAL_API_KEY` is optional — leave it unset and no `Authorization` header is sent. If your internal deployment sits behind a reverse proxy or API gateway that does require a bearer token, set it there and it's sent the same way the cloud provider's key is (`Authorization: Bearer <token>`). No other auth scheme (Basic auth, a custom header, mTLS) is currently supported.
|
|
100
|
+
|
|
82
101
|
### No AI at all: `HEALER_PROVIDER=tamash`
|
|
83
102
|
|
|
84
103
|
```sh
|
|
@@ -532,8 +551,9 @@ The same detail prints to the console as it happens:
|
|
|
532
551
|
| Variable | Default | Purpose |
|
|
533
552
|
|----------|---------|---------|
|
|
534
553
|
| `HEALER_ENABLED` | `true` | Master on/off switch. Any value other than `false`/`0` leaves healing on. |
|
|
535
|
-
| `HEALER_PROVIDER` | unset | `ollama` \| `openai` \| `anthropic` \| `gemini` \| `claude-subscription` \| `copilot-subscription` \| `tamash` (no AI, see above). Unset or missing key/model still allows cache hits, just no fresh AI calls. |
|
|
554
|
+
| `HEALER_PROVIDER` | unset | `ollama` \| `ollama-local` \| `openai` \| `anthropic` \| `gemini` \| `claude-subscription` \| `copilot-subscription` \| `tamash` (no AI, see above). Unset or missing key/model still allows cache hits, just no fresh AI calls. |
|
|
536
555
|
| `OLLAMA_MODEL` / `OLLAMA_API_KEY` | — | Ollama Cloud provider config. |
|
|
556
|
+
| `OLLAMA_LOCAL_MODEL` / `OLLAMA_LOCAL_BASE_URL` / `OLLAMA_LOCAL_API_KEY` | — / `http://localhost:11434` / — | Self-hosted Ollama provider config. The API key is optional — only set it if your deployment sits behind an auth gateway. |
|
|
537
557
|
| `OPENAI_MODEL` / `OPENAI_API_KEY` | — | OpenAI provider config. |
|
|
538
558
|
| `ANTHROPIC_MODEL` / `ANTHROPIC_API_KEY` | — | Anthropic (Claude) provider config. |
|
|
539
559
|
| `GEMINI_MODEL` / `GEMINI_API_KEY` | — | Google Gemini provider config. |
|