@open-everywhere/create 0.6.0 → 0.8.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/README.md +6 -4
- package/package.json +3 -3
- package/src/scaffold.ts +2 -2
- package/src/steps/build-deploy.ts +2 -2
- package/template/.dockerignore +35 -0
- package/template/AGENTS.md +7 -0
- package/template/Dockerfile +60 -0
- package/template/README.md +13 -0
- package/template/agent/access/a2a-inbound.ts +69 -0
- package/template/agent/agent.ts +25 -8
- package/template/agent/google-chat/policy.ts +34 -0
- package/template/agent/instructions.md +35 -20
- package/template/agent/lib/register-config.ts +20 -1
- package/template/agent/meetings/policy.ts +2 -4
- package/template/agent/memory/config/domains/org.ts +2 -2
- package/template/agent/model/models.ts +17 -0
- package/template/agent/model/stacks.ts +23 -6
- package/template/agent/routines/collectors.ts +28 -0
- package/template/agent/settings/settings.ts +21 -2
- package/template/agent/spend/model-pricing.ts +3 -1
- package/template/claude/skills/quickstart-open-everywhere/SKILL.md +96 -9
- package/template/claude/skills/upgrade-open-everywhere/SKILL.md +17 -4
- package/template/deploy/egress-proxy/Dockerfile +30 -0
- package/template/deploy/egress-proxy/control/acl.ts +228 -0
- package/template/deploy/egress-proxy/control/handlers.ts +174 -0
- package/template/deploy/egress-proxy/control/helper.cjs +108 -0
- package/template/deploy/egress-proxy/control/server.ts +122 -0
- package/template/deploy/egress-proxy/entrypoint.sh +62 -0
- package/template/deploy/egress-proxy/gen-ca.sh +42 -0
- package/template/deploy/egress-proxy/install-ca.sh +39 -0
- package/template/deploy/egress-proxy/squid.conf +93 -0
- package/template/deploy/egress-proxy/tier-b.conf +42 -0
- package/template/docker-compose.yml +135 -0
- package/template/gitignore +4 -0
- package/template/package.json +5 -3
- package/template/roster.config.ts +2 -2
- package/template/roster.lock.json +14 -1
- package/template/scripts/goldens/roster-plan.txt +13 -0
- package/template/scripts/model-config-check.ts +81 -0
- package/template/scripts/ops-mcp.ts +1 -1
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// THE LIVE MODEL CONFIG CHECK — `npm run check:model-config` (OPE-2556).
|
|
2
|
+
//
|
|
3
|
+
// npm run check:model-config check this app's resolved models against its models.targets and models.dataPolicy
|
|
4
|
+
// npm run check:model-config -- --json the same, as one JSON object
|
|
5
|
+
//
|
|
6
|
+
// It loads the app's own config (settings, stack, domains, roles), lists the models the deployment can resolve (the stack
|
|
7
|
+
// roles, the gateway transcription routes, the domain and role routes, models.force, and each declared subagent's
|
|
8
|
+
// bare model id on the target it goes through), and
|
|
9
|
+
// reads the gateway's PUBLIC `/v1/models/<id>/endpoints` for each one. A `models.dataPolicy` row or a `providers.only`
|
|
10
|
+
// row that no provider can meet is named, for example "region eu: no provider for deepseek/deepseek-v4-flash-0731".
|
|
11
|
+
// Run it BEFORE a deploy that changes either setting: under such a row every call of that model fails closed.
|
|
12
|
+
//
|
|
13
|
+
// 🔴 TWO COPIES, ONE TEXT (OPE-2563). The repository runs this file, and the scaffold template ships the same bytes
|
|
14
|
+
// at the same app-relative path, so a scaffolded app runs the check before its first deploy and the setup skill
|
|
15
|
+
// names one command in both homes. `test:scaffold` refuses a copy that drifts.
|
|
16
|
+
//
|
|
17
|
+
// It needs the network and no credential: the endpoints read is unauthenticated. So it is NOT in the `npm test` chain.
|
|
18
|
+
// The same check runs on a deployment, in the `model-route` row of `GET /eve/v1/oe/status` (adapters gateway-probe.ts),
|
|
19
|
+
// which `npx @open-everywhere/create --check --host <url>` reports.
|
|
20
|
+
//
|
|
21
|
+
// A bare model id that no stack role names goes through the primary role's target (OPE-2566). The check names each
|
|
22
|
+
// such id, so a subagent that would leave its role's target is visible before a deploy.
|
|
23
|
+
//
|
|
24
|
+
// Exit: 0 when every demand can be served or a part is unknown (printed), 1 when a demand cannot be served, or when a
|
|
25
|
+
// role names a target other than `gateway` and the app does not register its roles for bare ids.
|
|
26
|
+
|
|
27
|
+
import { getConfig } from "@open-everywhere/core/agent/access/config.js";
|
|
28
|
+
import { getSettings } from "@open-everywhere/core/agent/settings/settings.js";
|
|
29
|
+
import { modelTargetFor, resolvableModels } from "@open-everywhere/core/agent/model/targets.js";
|
|
30
|
+
import { bareModelFallbacks, bareModelRoutes, bareModelRoutesUnregistered, bareModelVia } from "@open-everywhere/core/agent/model/bare-model-via.js";
|
|
31
|
+
import { declaredSubagentModels } from "@open-everywhere/core/agent/ops/sovereignty-facts.js";
|
|
32
|
+
import { importAppModule, resolveAppRoot } from "@open-everywhere/core/agent/scaffold/app-root.js";
|
|
33
|
+
import { checkModelConfig, configCheckSummary } from "@open-everywhere/adapters/agent/model/model-config-check.js";
|
|
34
|
+
import { targetBaseUrl } from "@open-everywhere/adapters/agent/model/target-url.js";
|
|
35
|
+
|
|
36
|
+
// The deployer's app config loads from the app root (`OE_APP_ROOT`, else the directory npm ran in — OPE-2195).
|
|
37
|
+
const APP_ROOT = resolveAppRoot();
|
|
38
|
+
await importAppModule("agent/lib/register-config.ts", APP_ROOT);
|
|
39
|
+
const { MODELS, TRANSCRIPTION_ROLE } = await importAppModule<typeof import("../agent/model/models.js")>("agent/model/models.ts", APP_ROOT);
|
|
40
|
+
|
|
41
|
+
const settings = getSettings().models;
|
|
42
|
+
// The gateway transcription routes carry the `gateway` target's rows too, so they are checked with the roles.
|
|
43
|
+
const transcription = [TRANSCRIPTION_ROLE.primary, TRANSCRIPTION_ROLE.fallback].flatMap((r) => (r?.via === "gateway" ? [{ id: r.id }] : []));
|
|
44
|
+
// A declared subagent's bare id is checked on the target it goes through: its role's, else the primary role's.
|
|
45
|
+
const routes = bareModelRoutes(Object.values(MODELS));
|
|
46
|
+
// The app's `agent/model/models.ts` registers the roles at load (the import above ran it). An app scaffolded before
|
|
47
|
+
// 0.8.0 does not, so at run time every bare id still goes through `gateway`, whatever this check computes.
|
|
48
|
+
// That matters only when a role names a target other than `gateway`: then a bare id leaves the role's target.
|
|
49
|
+
const unregisteredLeak = bareModelRoutesUnregistered(routes);
|
|
50
|
+
const declared = (await declaredSubagentModels(APP_ROOT)) ?? [];
|
|
51
|
+
// A subagent whose module did not load has an unknown model: it is named, and the check cannot read it.
|
|
52
|
+
const unloaded = declared.filter((b) => b.id === undefined).map((b) => b.where);
|
|
53
|
+
const subagents = declared.flatMap((b) => (b.id === undefined ? [] : [{ where: b.where, id: b.id }]));
|
|
54
|
+
const bare = subagents.map((b) => ({ id: b.id, via: bareModelVia(b.id, routes).via }));
|
|
55
|
+
const fallbacks = bareModelFallbacks(subagents, routes);
|
|
56
|
+
const models = resolvableModels([...Object.values(MODELS), ...transcription, ...bare], getConfig().loadDomains(), getConfig().loadRoles?.() ?? [], settings.force);
|
|
57
|
+
const result = await checkModelConfig({
|
|
58
|
+
models,
|
|
59
|
+
targets: settings.targets,
|
|
60
|
+
policy: settings.dataPolicy,
|
|
61
|
+
baseUrlFor: (via) => targetBaseUrl(via, modelTargetFor(via, settings.targets)),
|
|
62
|
+
timeoutMs: 15_000,
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
if (process.argv.includes("--json")) {
|
|
66
|
+
console.log(JSON.stringify({ met: result.met, checked: result.checked, models, findings: result.findings, bareRoutesUnregistered: unregisteredLeak, bareDefaultVia: routes.fallback, bareFallbacks: fallbacks, unloadedSubagents: unloaded }, null, 2));
|
|
67
|
+
} else {
|
|
68
|
+
console.log(configCheckSummary(result));
|
|
69
|
+
for (const f of result.findings) console.log(` ${f.met === "no" ? "✗" : "?"} ${f.detail}`);
|
|
70
|
+
if (unregisteredLeak) {
|
|
71
|
+
console.log(" ✗ agent/model/models.ts does not call registerBareModelRoutes, so every bare id goes via gateway, not the targets below. Add the line from the 0.8.0 template.");
|
|
72
|
+
}
|
|
73
|
+
// Every declared subagent, with the target its bare id goes through; then the target of any other bare id.
|
|
74
|
+
for (const b of subagents) {
|
|
75
|
+
const r = bareModelVia(b.id, routes);
|
|
76
|
+
console.log(r.source === "role" ? ` · ${b.where}: via ${r.via}, its role's target` : ` · ${b.where}: no role names ${b.id}, so it goes via ${r.via}, the primary role's target`);
|
|
77
|
+
}
|
|
78
|
+
for (const w of unloaded) console.log(` ? ${w}: model unknown, its module did not load, so it was not checked`);
|
|
79
|
+
console.log(` · any other bare id (eve evaluate()): via ${routes.fallback}, the primary role's target`);
|
|
80
|
+
}
|
|
81
|
+
process.exit(result.met === "no" || unregisteredLeak ? 1 : 0);
|
|
@@ -47,5 +47,5 @@ registerSurfaceTrustPreflight();
|
|
|
47
47
|
const server = buildOpsServer();
|
|
48
48
|
await server.connect(new StdioServerTransport());
|
|
49
49
|
process.stderr.write(
|
|
50
|
-
"open-everywhere-ops MCP server ready on stdio (preflight · surface_manifest · surface_app_package · scaffold_env · scaffold_credential_key · secret_set/list/rm)\n",
|
|
50
|
+
"open-everywhere-ops MCP server ready on stdio (preflight · surface_manifest · surface_app_package · surface_app_create · scaffold_env · scaffold_credential_key · secret_set/list/rm)\n",
|
|
51
51
|
);
|