nexus-ai-pro 2.0.0 → 2.2.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/API_STABILITY.md +65 -0
- package/CHANGELOG.md +267 -1
- package/MIGRATING.md +1 -1
- package/README.md +17 -8
- package/dist/agent/create-agent.d.ts +9 -1
- package/dist/agent/create-agent.js +40 -1
- package/dist/cache/memory-cache.d.ts +8 -0
- package/dist/cache/memory-cache.js +9 -0
- package/dist/cache/semantic-cache.d.ts +6 -3
- package/dist/cache/semantic-cache.js +5 -2
- package/dist/cli/args.js +3 -0
- package/dist/cli/db.d.ts +16 -4
- package/dist/cli/db.js +169 -22
- package/dist/cli/doctor.d.ts +17 -0
- package/dist/cli/doctor.js +53 -0
- package/dist/cli/graph.d.ts +9 -0
- package/dist/cli/graph.js +47 -0
- package/dist/cli.js +21 -2
- package/dist/core/lifecycle.js +11 -6
- package/dist/core/nexus.d.ts +12 -2
- package/dist/core/nexus.js +106 -23
- package/dist/doctor/index.d.ts +90 -0
- package/dist/doctor/index.js +237 -0
- package/dist/evals/judge.d.ts +11 -0
- package/dist/evals/judge.js +33 -0
- package/dist/evaluate/index.d.ts +1 -0
- package/dist/evaluate/index.js +1 -0
- package/dist/evaluate/provenance.d.ts +22 -0
- package/dist/evaluate/provenance.js +10 -0
- package/dist/evaluate/run.js +20 -4
- package/dist/graph/durability.d.ts +27 -0
- package/dist/graph/durability.js +66 -0
- package/dist/graph/errors.d.ts +30 -4
- package/dist/graph/errors.js +18 -2
- package/dist/graph/event-stream.d.ts +75 -0
- package/dist/graph/event-stream.js +289 -0
- package/dist/graph/functional.d.ts +80 -7
- package/dist/graph/functional.js +138 -35
- package/dist/graph/graph.d.ts +56 -8
- package/dist/graph/graph.js +331 -49
- package/dist/graph/index.d.ts +4 -2
- package/dist/graph/index.js +3 -1
- package/dist/graph/lint.d.ts +57 -0
- package/dist/graph/lint.js +141 -0
- package/dist/graph/run-control.d.ts +28 -0
- package/dist/graph/run-control.js +26 -0
- package/dist/images/evals.js +4 -2
- package/dist/operations/adapters.d.ts +52 -4
- package/dist/operations/adapters.js +194 -7
- package/dist/operations/runner.js +14 -15
- package/dist/operations/stats.js +8 -1
- package/dist/operations/store.d.ts +5 -1
- package/dist/operations/store.js +7 -0
- package/dist/ops/circuit-breaker.d.ts +52 -0
- package/dist/ops/circuit-breaker.js +4 -0
- package/dist/ops/circuit-store.d.ts +13 -2
- package/dist/ops/circuit-store.js +68 -0
- package/dist/ops/circuit-sync.d.ts +17 -0
- package/dist/ops/circuit-sync.js +86 -0
- package/dist/ops/health.d.ts +24 -0
- package/dist/ops/health.js +38 -10
- package/dist/ops/index.d.ts +1 -1
- package/dist/ops/index.js +1 -1
- package/dist/ops/rate-limit-adapters.d.ts +23 -0
- package/dist/ops/rate-limit-adapters.js +34 -0
- package/dist/ops/rate-limiter.d.ts +14 -2
- package/dist/ops/rate-limiter.js +31 -0
- package/dist/postgres/circuits.d.ts +21 -4
- package/dist/postgres/circuits.js +65 -4
- package/dist/postgres/client.d.ts +0 -2
- package/dist/postgres/client.js +0 -4
- package/dist/postgres/evaluate.d.ts +16 -4
- package/dist/postgres/evaluate.js +17 -5
- package/dist/postgres/index.d.ts +32 -11
- package/dist/postgres/index.js +65 -31
- package/dist/postgres/migrations.d.ts +60 -0
- package/dist/postgres/migrations.js +121 -0
- package/dist/postgres/operations.d.ts +14 -3
- package/dist/postgres/operations.js +45 -15
- package/dist/postgres/prompts.d.ts +11 -2
- package/dist/postgres/prompts.js +14 -3
- package/dist/postgres/rollups.d.ts +35 -0
- package/dist/postgres/rollups.js +129 -0
- package/dist/postgres/store.d.ts +11 -2
- package/dist/postgres/store.js +14 -3
- package/dist/postgres/traces.d.ts +13 -3
- package/dist/postgres/traces.js +25 -3
- package/dist/postgres/vectors.d.ts +11 -2
- package/dist/postgres/vectors.js +14 -3
- package/dist/router/auto-router.d.ts +34 -7
- package/dist/router/auto-router.js +201 -68
- package/dist/server/assistant.d.ts +44 -0
- package/dist/server/assistant.js +39 -0
- package/dist/server/errors.d.ts +12 -0
- package/dist/server/errors.js +7 -0
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/runs.d.ts +28 -1
- package/dist/server/runs.js +110 -14
- package/dist/sqlite/index.d.ts +16 -3
- package/dist/sqlite/index.js +16 -3
- package/dist/sqlite/migrations.d.ts +26 -0
- package/dist/sqlite/migrations.js +63 -0
- package/dist/sqlite/operations.d.ts +14 -3
- package/dist/sqlite/operations.js +42 -15
- package/dist/sqlite/store.d.ts +9 -2
- package/dist/sqlite/store.js +13 -3
- package/dist/sqlite/vectors.d.ts +11 -2
- package/dist/sqlite/vectors.js +13 -2
- package/dist/store/tenant.d.ts +12 -0
- package/dist/store/tenant.js +29 -0
- package/dist/tenancy/index.d.ts +113 -0
- package/dist/tenancy/index.js +233 -0
- package/dist/testing/record.d.ts +42 -0
- package/dist/testing/record.js +57 -5
- package/dist/tracing/index.d.ts +3 -3
- package/dist/tracing/index.js +2 -2
- package/dist/tracing/instrument.js +30 -0
- package/dist/tracing/otlp.d.ts +91 -0
- package/dist/tracing/otlp.js +124 -0
- package/dist/tracing/rollups.d.ts +100 -0
- package/dist/tracing/rollups.js +139 -0
- package/dist/tracing/stores.d.ts +17 -0
- package/dist/tracing/stores.js +23 -0
- package/dist/tracing/tracer.d.ts +50 -4
- package/dist/tracing/tracer.js +85 -6
- package/dist/types/config.d.ts +33 -2
- package/dist/types/evaluate.d.ts +37 -0
- package/dist/types/graph.d.ts +354 -9
- package/dist/types/graph.js +3 -1
- package/dist/types/messages.d.ts +5 -0
- package/dist/types/operations.d.ts +22 -2
- package/dist/types/response.d.ts +20 -0
- package/dist/types/server.d.ts +18 -0
- package/dist/types/tracing.d.ts +11 -0
- package/dist/utils/schema-migrations.d.ts +97 -0
- package/dist/utils/schema-migrations.js +91 -0
- package/dist/utils/signals.d.ts +17 -0
- package/dist/utils/signals.js +26 -0
- package/dist/utils/tenant.d.ts +14 -0
- package/dist/utils/tenant.js +16 -0
- package/dist/version.d.ts +5 -0
- package/dist/version.js +1 -0
- package/dist-cjs/agent/create-agent.d.ts +9 -1
- package/dist-cjs/agent/create-agent.js +40 -1
- package/dist-cjs/cache/memory-cache.d.ts +8 -0
- package/dist-cjs/cache/memory-cache.js +9 -0
- package/dist-cjs/cache/semantic-cache.d.ts +6 -3
- package/dist-cjs/cache/semantic-cache.js +5 -2
- package/dist-cjs/cli/args.js +3 -0
- package/dist-cjs/cli/db.d.ts +16 -4
- package/dist-cjs/cli/db.js +200 -20
- package/dist-cjs/cli/doctor.d.ts +17 -0
- package/dist-cjs/cli/doctor.js +56 -0
- package/dist-cjs/cli/graph.d.ts +9 -0
- package/dist-cjs/cli/graph.js +50 -0
- package/dist-cjs/core/lifecycle.js +11 -6
- package/dist-cjs/core/nexus.d.ts +12 -2
- package/dist-cjs/core/nexus.js +106 -23
- package/dist-cjs/doctor/index.d.ts +90 -0
- package/dist-cjs/doctor/index.js +276 -0
- package/dist-cjs/evals/judge.d.ts +11 -0
- package/dist-cjs/evals/judge.js +33 -0
- package/dist-cjs/evaluate/index.d.ts +1 -0
- package/dist-cjs/evaluate/index.js +3 -1
- package/dist-cjs/evaluate/provenance.d.ts +22 -0
- package/dist-cjs/evaluate/provenance.js +14 -0
- package/dist-cjs/evaluate/run.js +20 -4
- package/dist-cjs/graph/durability.d.ts +27 -0
- package/dist-cjs/graph/durability.js +70 -0
- package/dist-cjs/graph/errors.d.ts +30 -4
- package/dist-cjs/graph/errors.js +20 -3
- package/dist-cjs/graph/event-stream.d.ts +75 -0
- package/dist-cjs/graph/event-stream.js +295 -0
- package/dist-cjs/graph/functional.d.ts +80 -7
- package/dist-cjs/graph/functional.js +137 -34
- package/dist-cjs/graph/graph.d.ts +56 -8
- package/dist-cjs/graph/graph.js +330 -48
- package/dist-cjs/graph/index.d.ts +4 -2
- package/dist-cjs/graph/index.js +7 -1
- package/dist-cjs/graph/lint.d.ts +57 -0
- package/dist-cjs/graph/lint.js +144 -0
- package/dist-cjs/graph/run-control.d.ts +28 -0
- package/dist-cjs/graph/run-control.js +30 -0
- package/dist-cjs/images/evals.js +4 -2
- package/dist-cjs/operations/adapters.d.ts +52 -4
- package/dist-cjs/operations/adapters.js +193 -6
- package/dist-cjs/operations/runner.js +14 -15
- package/dist-cjs/operations/stats.js +8 -1
- package/dist-cjs/operations/store.d.ts +5 -1
- package/dist-cjs/operations/store.js +7 -0
- package/dist-cjs/ops/circuit-breaker.d.ts +52 -0
- package/dist-cjs/ops/circuit-breaker.js +4 -0
- package/dist-cjs/ops/circuit-store.d.ts +13 -2
- package/dist-cjs/ops/circuit-store.js +68 -0
- package/dist-cjs/ops/circuit-sync.d.ts +17 -0
- package/dist-cjs/ops/circuit-sync.js +87 -0
- package/dist-cjs/ops/health.d.ts +24 -0
- package/dist-cjs/ops/health.js +38 -10
- package/dist-cjs/ops/index.d.ts +1 -1
- package/dist-cjs/ops/rate-limit-adapters.d.ts +23 -0
- package/dist-cjs/ops/rate-limit-adapters.js +35 -1
- package/dist-cjs/ops/rate-limiter.d.ts +14 -2
- package/dist-cjs/ops/rate-limiter.js +32 -0
- package/dist-cjs/postgres/circuits.d.ts +21 -4
- package/dist-cjs/postgres/circuits.js +98 -3
- package/dist-cjs/postgres/client.d.ts +0 -2
- package/dist-cjs/postgres/client.js +0 -5
- package/dist-cjs/postgres/evaluate.d.ts +16 -4
- package/dist-cjs/postgres/evaluate.js +50 -4
- package/dist-cjs/postgres/index.d.ts +32 -11
- package/dist-cjs/postgres/index.js +69 -20
- package/dist-cjs/postgres/migrations.d.ts +60 -0
- package/dist-cjs/postgres/migrations.js +129 -0
- package/dist-cjs/postgres/operations.d.ts +14 -3
- package/dist-cjs/postgres/operations.js +78 -14
- package/dist-cjs/postgres/prompts.d.ts +11 -2
- package/dist-cjs/postgres/prompts.js +47 -2
- package/dist-cjs/postgres/rollups.d.ts +35 -0
- package/dist-cjs/postgres/rollups.js +168 -0
- package/dist-cjs/postgres/store.d.ts +11 -2
- package/dist-cjs/postgres/store.js +47 -2
- package/dist-cjs/postgres/traces.d.ts +13 -3
- package/dist-cjs/postgres/traces.js +58 -2
- package/dist-cjs/postgres/vectors.d.ts +11 -2
- package/dist-cjs/postgres/vectors.js +47 -2
- package/dist-cjs/router/auto-router.d.ts +34 -7
- package/dist-cjs/router/auto-router.js +201 -68
- package/dist-cjs/server/assistant.d.ts +44 -0
- package/dist-cjs/server/assistant.js +39 -0
- package/dist-cjs/server/errors.d.ts +12 -0
- package/dist-cjs/server/errors.js +9 -1
- package/dist-cjs/server/index.d.ts +1 -1
- package/dist-cjs/server/index.js +2 -1
- package/dist-cjs/server/runs.d.ts +28 -1
- package/dist-cjs/server/runs.js +109 -13
- package/dist-cjs/sqlite/index.d.ts +16 -3
- package/dist-cjs/sqlite/index.js +31 -10
- package/dist-cjs/sqlite/migrations.d.ts +26 -0
- package/dist-cjs/sqlite/migrations.js +71 -0
- package/dist-cjs/sqlite/operations.d.ts +14 -3
- package/dist-cjs/sqlite/operations.js +76 -15
- package/dist-cjs/sqlite/store.d.ts +9 -2
- package/dist-cjs/sqlite/store.js +47 -3
- package/dist-cjs/sqlite/vectors.d.ts +11 -2
- package/dist-cjs/sqlite/vectors.js +47 -2
- package/dist-cjs/store/tenant.d.ts +12 -0
- package/dist-cjs/store/tenant.js +33 -0
- package/dist-cjs/tenancy/index.d.ts +113 -0
- package/dist-cjs/tenancy/index.js +250 -0
- package/dist-cjs/testing/record.d.ts +42 -0
- package/dist-cjs/testing/record.js +57 -5
- package/dist-cjs/tracing/index.d.ts +3 -3
- package/dist-cjs/tracing/index.js +4 -1
- package/dist-cjs/tracing/instrument.js +30 -0
- package/dist-cjs/tracing/otlp.d.ts +91 -0
- package/dist-cjs/tracing/otlp.js +129 -0
- package/dist-cjs/tracing/rollups.d.ts +100 -0
- package/dist-cjs/tracing/rollups.js +147 -0
- package/dist-cjs/tracing/stores.d.ts +17 -0
- package/dist-cjs/tracing/stores.js +24 -0
- package/dist-cjs/tracing/tracer.d.ts +50 -4
- package/dist-cjs/tracing/tracer.js +87 -6
- package/dist-cjs/types/config.d.ts +33 -2
- package/dist-cjs/types/evaluate.d.ts +37 -0
- package/dist-cjs/types/graph.d.ts +354 -9
- package/dist-cjs/types/graph.js +3 -1
- package/dist-cjs/types/messages.d.ts +5 -0
- package/dist-cjs/types/operations.d.ts +22 -2
- package/dist-cjs/types/response.d.ts +20 -0
- package/dist-cjs/types/server.d.ts +18 -0
- package/dist-cjs/types/tracing.d.ts +11 -0
- package/dist-cjs/utils/schema-migrations.d.ts +97 -0
- package/dist-cjs/utils/schema-migrations.js +102 -0
- package/dist-cjs/utils/signals.d.ts +17 -0
- package/dist-cjs/utils/signals.js +29 -0
- package/dist-cjs/utils/tenant.d.ts +14 -0
- package/dist-cjs/utils/tenant.js +22 -0
- package/dist-cjs/version.d.ts +5 -0
- package/dist-cjs/version.js +4 -0
- package/llms.txt +4 -3
- package/package.json +110 -2
package/dist/cli/db.d.ts
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
import { type ParsedArgs } from './args.js';
|
|
2
2
|
/**
|
|
3
|
-
* `nexus db sql
|
|
3
|
+
* `nexus db sql | status | migrate`.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* `sql` prints the Postgres schema, so the CLI needs no driver and the schema can go through the
|
|
6
|
+
* application's own review and tooling: `nexus db sql | psql "$URL"`. `status` and `migrate` reach
|
|
7
|
+
* the database through a module the application writes, which exports its own client:
|
|
8
|
+
*
|
|
9
|
+
* ```js
|
|
10
|
+
* // db.mjs
|
|
11
|
+
* import pg from 'pg';
|
|
12
|
+
* export const client = new pg.Pool({ connectionString: process.env.DATABASE_URL });
|
|
13
|
+
* export const close = () => client.end();
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* The module may also export `dialect` (`postgres` or `sqlite`), a `transaction` function (see
|
|
17
|
+
* `PostgresMigrateOptions`), and `migrations`, a list replacing the bundled ones, for stores on
|
|
18
|
+
* custom tables.
|
|
7
19
|
*/
|
|
8
|
-
export declare function runDbCommand(subcommand: string | undefined,
|
|
20
|
+
export declare function runDbCommand(subcommand: string | undefined, args: ParsedArgs): Promise<void>;
|
package/dist/cli/db.js
CHANGED
|
@@ -1,28 +1,175 @@
|
|
|
1
|
-
import { postgresMigration } from '../postgres/index.js';
|
|
2
|
-
import { CliUsageError, listFlag, numberFlag } from './args.js';
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
'
|
|
6
|
-
|
|
7
|
-
'
|
|
8
|
-
|
|
9
|
-
'
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
if (subcommand !== 'sql')
|
|
14
|
-
throw new CliUsageError(`Unknown db command "${subcommand ?? ''}". Use sql.`);
|
|
15
|
-
const adapters = listFlag(flags, 'adapters');
|
|
16
|
-
const unknown = adapters?.filter((adapter) => !ADAPTERS.includes(adapter));
|
|
17
|
-
if (unknown?.length) {
|
|
18
|
-
throw new CliUsageError(`Unknown adapter ${unknown.join(', ')}. Choose from ${ADAPTERS.join(', ')}.`);
|
|
19
|
-
}
|
|
1
|
+
import { POSTGRES_ADAPTERS, postgresMigration, postgresMigrations } from '../postgres/index.js';
|
|
2
|
+
import { CliUsageError, flagBool, listFlag, loadModule, numberFlag, printTable, stringFlag, writeJson, } from './args.js';
|
|
3
|
+
const SQLITE_ADAPTERS = ['operations', 'store', 'vectors'];
|
|
4
|
+
export async function runDbCommand(subcommand, args) {
|
|
5
|
+
if (subcommand === 'sql')
|
|
6
|
+
return printSql(args);
|
|
7
|
+
if (subcommand === 'status' || subcommand === 'migrate')
|
|
8
|
+
return withDatabase(subcommand, args);
|
|
9
|
+
throw new CliUsageError(`Unknown db command "${subcommand ?? ''}". Use sql, status, or migrate.`);
|
|
10
|
+
}
|
|
11
|
+
function printSql({ flags }) {
|
|
12
|
+
const adapters = postgresAdapters(flags);
|
|
20
13
|
const vectorDimensions = numberFlag(flags, 'vector-dimensions');
|
|
21
|
-
if (adapters?.includes('vectors') && vectorDimensions === undefined) {
|
|
22
|
-
throw new CliUsageError('The vectors adapter needs --vector-dimensions.');
|
|
23
|
-
}
|
|
24
14
|
process.stdout.write(postgresMigration({
|
|
25
15
|
...(adapters ? { adapters } : {}),
|
|
26
16
|
...(vectorDimensions === undefined ? {} : { vectorDimensions }),
|
|
17
|
+
...(flagBool(flags, 'record') ? { record: true } : {}),
|
|
27
18
|
}));
|
|
28
19
|
}
|
|
20
|
+
function postgresAdapters(flags) {
|
|
21
|
+
const adapters = listFlag(flags, 'adapters');
|
|
22
|
+
const unknown = adapters?.filter((adapter) => !POSTGRES_ADAPTERS.includes(adapter));
|
|
23
|
+
if (unknown?.length) {
|
|
24
|
+
throw new CliUsageError(`Unknown adapter ${unknown.join(', ')}. Choose from ${POSTGRES_ADAPTERS.join(', ')}.`);
|
|
25
|
+
}
|
|
26
|
+
if (adapters?.includes('vectors') && numberFlag(flags, 'vector-dimensions') === undefined) {
|
|
27
|
+
throw new CliUsageError('The vectors adapter needs --vector-dimensions.');
|
|
28
|
+
}
|
|
29
|
+
return adapters;
|
|
30
|
+
}
|
|
31
|
+
async function withDatabase(command, { flags }) {
|
|
32
|
+
const location = stringFlag(flags, 'client');
|
|
33
|
+
if (!location)
|
|
34
|
+
throw new CliUsageError(`nexus db ${command} needs --client <db.mjs>, a module exporting \`client\`.`);
|
|
35
|
+
const database = await openDatabase(location, stringFlag(flags, 'dialect'));
|
|
36
|
+
try {
|
|
37
|
+
const migrations = database.migrations ?? (await bundledMigrations(database.dialect, flags));
|
|
38
|
+
const table = stringFlag(flags, 'table');
|
|
39
|
+
if (command === 'status') {
|
|
40
|
+
const status = await statusOf(database, migrations, table);
|
|
41
|
+
if (flagBool(flags, 'json'))
|
|
42
|
+
writeJson(status);
|
|
43
|
+
else
|
|
44
|
+
printStatus(status);
|
|
45
|
+
if (flagBool(flags, 'check') && !status.current)
|
|
46
|
+
process.exitCode = 1;
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const result = await migrate(database, migrations, { dryRun: flagBool(flags, 'dry-run'), table });
|
|
50
|
+
if (flagBool(flags, 'json'))
|
|
51
|
+
writeJson(result);
|
|
52
|
+
else
|
|
53
|
+
printResult(result);
|
|
54
|
+
}
|
|
55
|
+
finally {
|
|
56
|
+
await database.close?.();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async function openDatabase(location, dialectFlag) {
|
|
60
|
+
const loaded = await loadModule(location);
|
|
61
|
+
const client = loaded.client ?? loaded.default;
|
|
62
|
+
if (!client || typeof client !== 'object') {
|
|
63
|
+
throw new CliUsageError(`${location} must export a database client as \`client\`.`);
|
|
64
|
+
}
|
|
65
|
+
const candidate = client;
|
|
66
|
+
const dialect = (dialectFlag ?? loaded.dialect);
|
|
67
|
+
const detected = dialect ??
|
|
68
|
+
(typeof candidate.query === 'function'
|
|
69
|
+
? 'postgres'
|
|
70
|
+
: typeof candidate.prepare === 'function' || typeof candidate.exec === 'function'
|
|
71
|
+
? 'sqlite'
|
|
72
|
+
: undefined);
|
|
73
|
+
if (detected !== 'postgres' && detected !== 'sqlite') {
|
|
74
|
+
throw new CliUsageError(`${location} exports a client this CLI cannot recognize. Export \`dialect\` as "postgres" or "sqlite".`);
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
dialect: detected,
|
|
78
|
+
client,
|
|
79
|
+
...(typeof loaded.transaction === 'function'
|
|
80
|
+
? { transaction: loaded.transaction }
|
|
81
|
+
: {}),
|
|
82
|
+
...(Array.isArray(loaded.migrations) ? { migrations: loaded.migrations } : {}),
|
|
83
|
+
...(typeof loaded.close === 'function' ? { close: loaded.close } : {}),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
async function bundledMigrations(dialect, flags) {
|
|
87
|
+
if (dialect === 'postgres') {
|
|
88
|
+
const adapters = postgresAdapters(flags);
|
|
89
|
+
const vectorDimensions = numberFlag(flags, 'vector-dimensions');
|
|
90
|
+
return postgresMigrations({
|
|
91
|
+
...(adapters ? { adapters } : {}),
|
|
92
|
+
...(vectorDimensions === undefined ? {} : { vectorDimensions }),
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
const adapters = listFlag(flags, 'adapters');
|
|
96
|
+
const unknown = adapters?.filter((adapter) => !SQLITE_ADAPTERS.includes(adapter));
|
|
97
|
+
if (unknown?.length) {
|
|
98
|
+
throw new CliUsageError(`Unknown SQLite adapter ${unknown.join(', ')}. Choose from ${SQLITE_ADAPTERS.join(', ')}.`);
|
|
99
|
+
}
|
|
100
|
+
const { sqliteMigrations } = await import('../sqlite/index.js');
|
|
101
|
+
return sqliteMigrations(adapters ? { adapters } : {});
|
|
102
|
+
}
|
|
103
|
+
async function statusOf(database, migrations, table) {
|
|
104
|
+
const options = table ? { table } : {};
|
|
105
|
+
if (database.dialect === 'postgres') {
|
|
106
|
+
const { postgresMigrationStatus } = await import('../postgres/migrations.js');
|
|
107
|
+
return postgresMigrationStatus(database.client, migrations, options);
|
|
108
|
+
}
|
|
109
|
+
const { sqliteMigrationStatus } = await import('../sqlite/migrations.js');
|
|
110
|
+
return sqliteMigrationStatus(database.client, migrations, options);
|
|
111
|
+
}
|
|
112
|
+
async function migrate(database, migrations, options) {
|
|
113
|
+
const common = { dryRun: options.dryRun, ...(options.table ? { table: options.table } : {}) };
|
|
114
|
+
if (database.dialect === 'postgres') {
|
|
115
|
+
const { applyPostgresMigrations } = await import('../postgres/migrations.js');
|
|
116
|
+
return applyPostgresMigrations(database.client, migrations, {
|
|
117
|
+
...common,
|
|
118
|
+
...(database.transaction ? { transaction: database.transaction } : {}),
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
const { applySqliteMigrations } = await import('../sqlite/migrations.js');
|
|
122
|
+
return applySqliteMigrations(database.client, migrations, common);
|
|
123
|
+
}
|
|
124
|
+
function printStatus(status) {
|
|
125
|
+
const changed = new Set(status.changed.map(({ migration }) => `${migration.component}@${migration.version}`));
|
|
126
|
+
const rows = [
|
|
127
|
+
...status.applied
|
|
128
|
+
.filter((row) => !status.unknown.includes(row))
|
|
129
|
+
.map((row) => {
|
|
130
|
+
const key = `${row.component}@${row.version}`;
|
|
131
|
+
return {
|
|
132
|
+
component: row.component,
|
|
133
|
+
version: String(row.version),
|
|
134
|
+
name: row.name,
|
|
135
|
+
state: changed.has(key) ? 'changed' : 'applied',
|
|
136
|
+
applied: row.appliedAt,
|
|
137
|
+
};
|
|
138
|
+
}),
|
|
139
|
+
...status.unknown.map((row) => ({
|
|
140
|
+
component: row.component,
|
|
141
|
+
version: String(row.version),
|
|
142
|
+
name: row.name,
|
|
143
|
+
state: 'newer release',
|
|
144
|
+
applied: row.appliedAt,
|
|
145
|
+
})),
|
|
146
|
+
...status.pending.map((migration) => ({
|
|
147
|
+
component: migration.component,
|
|
148
|
+
version: String(migration.version),
|
|
149
|
+
name: migration.name,
|
|
150
|
+
state: 'pending',
|
|
151
|
+
applied: '',
|
|
152
|
+
})),
|
|
153
|
+
];
|
|
154
|
+
if (rows.length === 0) {
|
|
155
|
+
console.log('No migrations known or recorded.');
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
printTable(rows, ['component', 'version', 'name', 'state', 'applied']);
|
|
159
|
+
console.log(status.current
|
|
160
|
+
? '\nUp to date.'
|
|
161
|
+
: `\n${status.pending.length} pending${status.changed.length ? `, ${status.changed.length} changed after they ran` : ''}. Run: nexus db migrate`);
|
|
162
|
+
}
|
|
163
|
+
function printResult(result) {
|
|
164
|
+
if (result.applied.length === 0) {
|
|
165
|
+
console.log('Nothing to apply: the database is up to date.');
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
const verb = result.dryRun ? 'Would apply' : 'Applied';
|
|
169
|
+
for (const migration of result.applied)
|
|
170
|
+
console.log(`${verb} ${migration.component} v${migration.version}: ${migration.name}`);
|
|
171
|
+
if (result.dryRun) {
|
|
172
|
+
console.log('\n-- The statements, in order:\n');
|
|
173
|
+
console.log(`${result.statements.join(';\n\n')};`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type ParsedArgs } from './args.js';
|
|
2
|
+
/**
|
|
3
|
+
* `nexus doctor` checks a deployment and exits 1 when a check fails, or with `--strict` when one
|
|
4
|
+
* warns. Without `--module` it checks what it can see from the shell: Node.js, packages, credentials,
|
|
5
|
+
* and the model registry. A module reaches the rest, exporting any of:
|
|
6
|
+
*
|
|
7
|
+
* ```js
|
|
8
|
+
* // doctor.mjs
|
|
9
|
+
* export const database = { client: pool }; // or `client` alone, as for nexus db
|
|
10
|
+
* export const redis = new Redis(process.env.REDIS_URL);
|
|
11
|
+
* export const operations = new PostgresOperationStore(pool);
|
|
12
|
+
* export const ai = client;
|
|
13
|
+
* export const deployment = { replicas: 3, stores: { checkpointer, state, tenantUsage } };
|
|
14
|
+
* export const close = async () => { await pool.end(); redis.disconnect(); };
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare function runDoctorCommand({ flags }: ParsedArgs): Promise<void>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { diagnose } from '../doctor/index.js';
|
|
2
|
+
import { flagBool, isRecord, loadModule, numberFlag, stringFlag, writeJson } from './args.js';
|
|
3
|
+
const LABELS = { ok: 'ok ', warn: 'warn', fail: 'FAIL', skip: 'skip' };
|
|
4
|
+
export async function runDoctorCommand({ flags }) {
|
|
5
|
+
const location = stringFlag(flags, 'module');
|
|
6
|
+
const loaded = location ? await loadModule(location) : {};
|
|
7
|
+
const options = {};
|
|
8
|
+
const source = isRecord(loaded.database) ? loaded.database : loaded.client ? loaded : undefined;
|
|
9
|
+
if (source?.client) {
|
|
10
|
+
options.database = {
|
|
11
|
+
client: source.client,
|
|
12
|
+
...(source.dialect === 'postgres' || source.dialect === 'sqlite' ? { dialect: source.dialect } : {}),
|
|
13
|
+
...(Array.isArray(source.migrations) ? { migrations: source.migrations } : {}),
|
|
14
|
+
...(typeof source.table === 'string' ? { table: source.table } : {}),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
if (loaded.redis)
|
|
18
|
+
options.redis = loaded.redis;
|
|
19
|
+
if (loaded.operations)
|
|
20
|
+
options.operations = loaded.operations;
|
|
21
|
+
if (loaded.ai)
|
|
22
|
+
options.ai = loaded.ai;
|
|
23
|
+
if (isRecord(loaded.deployment))
|
|
24
|
+
options.deployment = loaded.deployment;
|
|
25
|
+
const replicas = numberFlag(flags, 'replicas');
|
|
26
|
+
if (replicas !== undefined)
|
|
27
|
+
options.deployment = { ...options.deployment, replicas };
|
|
28
|
+
const maxQueueAgeMs = numberFlag(flags, 'max-queue-age-ms');
|
|
29
|
+
if (maxQueueAgeMs !== undefined)
|
|
30
|
+
options.maxQueueAgeMs = maxQueueAgeMs;
|
|
31
|
+
let report;
|
|
32
|
+
try {
|
|
33
|
+
report = await diagnose(options);
|
|
34
|
+
}
|
|
35
|
+
finally {
|
|
36
|
+
if (typeof loaded.close === 'function')
|
|
37
|
+
await loaded.close();
|
|
38
|
+
}
|
|
39
|
+
if (flagBool(flags, 'json'))
|
|
40
|
+
writeJson(report);
|
|
41
|
+
else
|
|
42
|
+
print(report);
|
|
43
|
+
if (!report.ok || (flagBool(flags, 'strict') && report.warnings > 0))
|
|
44
|
+
process.exitCode = 1;
|
|
45
|
+
}
|
|
46
|
+
function print(report) {
|
|
47
|
+
for (const check of report.checks) {
|
|
48
|
+
console.log(`${LABELS[check.status]} ${check.title}: ${check.detail}`);
|
|
49
|
+
if (check.hint && (check.status === 'fail' || check.status === 'warn'))
|
|
50
|
+
console.log(` ${check.hint}`);
|
|
51
|
+
}
|
|
52
|
+
console.log(`\n${report.failures} failed, ${report.warnings} warned, ${report.checks.length - report.failures - report.warnings} passed or skipped.`);
|
|
53
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type ParsedArgs } from './args.js';
|
|
2
|
+
/**
|
|
3
|
+
* `nexus graph lint <module>[#export]`.
|
|
4
|
+
*
|
|
5
|
+
* The module exports a compiled graph, or a description of one as `describe()` returns it, as the
|
|
6
|
+
* named export, as `graph`, or as its default. Exits 1 when a finding is an error, or with `--strict`
|
|
7
|
+
* when any finding is a warning too.
|
|
8
|
+
*/
|
|
9
|
+
export declare function runGraphCommand(subcommand: string | undefined, args: ParsedArgs): Promise<void>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { lintGraph } from '../graph/lint.js';
|
|
2
|
+
import { CliUsageError, flagBool, isRecord, listFlag, loadModule, printTable, writeJson, } from './args.js';
|
|
3
|
+
export async function runGraphCommand(subcommand, args) {
|
|
4
|
+
if (subcommand !== 'lint') {
|
|
5
|
+
throw new CliUsageError(`Unknown graph command "${subcommand ?? ''}". Use lint.`);
|
|
6
|
+
}
|
|
7
|
+
const [target] = args.positionals;
|
|
8
|
+
if (!target)
|
|
9
|
+
throw new CliUsageError('nexus graph lint needs a module: nexus graph lint ./graph.mjs[#exportName].');
|
|
10
|
+
const [file, exportName] = target.split('#');
|
|
11
|
+
const loaded = await loadModule(file);
|
|
12
|
+
const graph = (exportName ? loaded[exportName] : (loaded.graph ?? loaded.default ?? loaded));
|
|
13
|
+
if (!isLintable(graph)) {
|
|
14
|
+
throw new CliUsageError(`${target} must export a compiled graph, or a graph description, ${exportName ? `as "${exportName}"` : 'as `graph` or its default'}.`);
|
|
15
|
+
}
|
|
16
|
+
const findings = lintGraph(graph, {
|
|
17
|
+
deployed: flagBool(args.flags, 'deployed'),
|
|
18
|
+
ignore: listFlag(args.flags, 'ignore'),
|
|
19
|
+
});
|
|
20
|
+
const failing = findings.filter((finding) => finding.severity === 'error' || (flagBool(args.flags, 'strict') && finding.severity === 'warning'));
|
|
21
|
+
if (flagBool(args.flags, 'json')) {
|
|
22
|
+
writeJson({ findings, failed: failing.length > 0 });
|
|
23
|
+
}
|
|
24
|
+
else if (findings.length === 0) {
|
|
25
|
+
console.log('No findings.');
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
printTable(findings.map((finding) => ({
|
|
29
|
+
severity: finding.severity,
|
|
30
|
+
code: finding.code,
|
|
31
|
+
node: finding.node ?? '',
|
|
32
|
+
message: finding.message,
|
|
33
|
+
})), ['severity', 'code', 'node', 'message']);
|
|
34
|
+
console.log('');
|
|
35
|
+
for (const finding of findings)
|
|
36
|
+
console.log(`${finding.code}: ${finding.fix}`);
|
|
37
|
+
}
|
|
38
|
+
if (failing.length > 0)
|
|
39
|
+
process.exitCode = 1;
|
|
40
|
+
}
|
|
41
|
+
function isLintable(value) {
|
|
42
|
+
if (!isRecord(value))
|
|
43
|
+
return false;
|
|
44
|
+
if (typeof value.describe === 'function')
|
|
45
|
+
return true;
|
|
46
|
+
return Array.isArray(value.nodes) && Array.isArray(value.edges) && Array.isArray(value.dynamic);
|
|
47
|
+
}
|
package/dist/cli.js
CHANGED
|
@@ -43,6 +43,11 @@ async function main() {
|
|
|
43
43
|
await runTracesCommand(subcommand, { positionals: args, flags: parsed.flags });
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
|
+
case 'doctor': {
|
|
47
|
+
const { runDoctorCommand } = await import('./cli/doctor.js');
|
|
48
|
+
await runDoctorCommand({ positionals: parsed.positionals.slice(1), flags: parsed.flags });
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
46
51
|
case 'db': {
|
|
47
52
|
const [subcommand, ...args] = parsed.positionals;
|
|
48
53
|
const { runDbCommand } = await import('./cli/db.js');
|
|
@@ -54,6 +59,12 @@ async function main() {
|
|
|
54
59
|
await runMigrateCommand(parsed);
|
|
55
60
|
return;
|
|
56
61
|
}
|
|
62
|
+
case 'graph': {
|
|
63
|
+
const [subcommand, ...args] = parsed.positionals;
|
|
64
|
+
const { runGraphCommand } = await import('./cli/graph.js');
|
|
65
|
+
await runGraphCommand(subcommand, { positionals: args, flags: parsed.flags });
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
57
68
|
case 'deploy': {
|
|
58
69
|
const [subcommand, ...args] = parsed.positionals;
|
|
59
70
|
const { runDeployCommand } = await import('./cli/deploy.js');
|
|
@@ -400,8 +411,12 @@ Usage:
|
|
|
400
411
|
[--min-cost n] [--feedback-key k] [--limit 20] [--offset n] [--json]
|
|
401
412
|
nexus traces show <traceId> --store <runs.jsonl|store.mjs> [--json]
|
|
402
413
|
nexus traces export --store <runs.jsonl|store.mjs> [--out runs.jsonl] [same filters as list]
|
|
403
|
-
nexus db sql [--adapters operations,store,traces,evaluation,circuits,prompts] [--vector-dimensions 1536]
|
|
414
|
+
nexus db sql [--adapters operations,store,traces,evaluation,circuits,prompts,rollups] [--vector-dimensions 1536] [--record]
|
|
415
|
+
nexus db status --client <db.mjs> [--adapters ...] [--dialect postgres|sqlite] [--table t] [--check] [--json]
|
|
416
|
+
nexus db migrate --client <db.mjs> [--dry-run] [--adapters ...] [--dialect postgres|sqlite] [--table t] [--json]
|
|
404
417
|
nexus migrate [paths...] [--write] [--check] [--json]
|
|
418
|
+
nexus doctor [--module doctor.mjs] [--replicas n] [--max-queue-age-ms n] [--strict] [--json]
|
|
419
|
+
nexus graph lint <module>[#export] [--deployed] [--strict] [--ignore CODE,CODE] [--json]
|
|
405
420
|
nexus deploy status [assistant] --url <server> [--token t] [--json]
|
|
406
421
|
nexus deploy canary <assistant> <revision> <percent> --url <server> [--reason r] [--version n]
|
|
407
422
|
nexus deploy promote <assistant> <revision> --url <server> [--reason r] [--version n]
|
|
@@ -412,8 +427,12 @@ Eval files can export { cases, client } or { cases, config }. JSON cases may use
|
|
|
412
427
|
Evaluation modules for "eval run" export { target, dataset, evaluators, summary?, options? }.
|
|
413
428
|
"eval gate" exits 1 when a metric got worse beyond noise, a new failure appeared, or the datasets differ.
|
|
414
429
|
Trace store modules export any TraceStore as { store }, such as a PostgresTraceStore over the application's own pool.
|
|
430
|
+
Database modules for "db status" and "db migrate" export { client }, and optionally { dialect, transaction, migrations, close }.
|
|
431
|
+
"db status --check" exits 1 while a migration is pending or changed.
|
|
432
|
+
"doctor" exits 1 when a check fails, or with --strict when one warns. Its module exports any of { database, client, redis, operations, ai, deployment, close }.
|
|
415
433
|
"deploy" reads NEXUS_SERVER_URL and NEXUS_SERVER_TOKEN when --url and --token are not given.
|
|
416
|
-
"migrate" moves 1.x root imports to their 2.0 subpaths and reports removed options; --check exits 1 while any remain
|
|
434
|
+
"migrate" moves 1.x root imports to their 2.0 subpaths and reports removed options; --check exits 1 while any remain.
|
|
435
|
+
"graph lint" reads a compiled graph's shape and exits 1 on an error finding, or on a warning with --strict.`);
|
|
417
436
|
}
|
|
418
437
|
main().catch((error) => {
|
|
419
438
|
const message = error instanceof Error ? error.message : String(error);
|
package/dist/core/lifecycle.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NexusRateLimitError } from '../ops/rate-limiter.js';
|
|
2
2
|
import { generateRequestId } from '../utils/ids.js';
|
|
3
|
+
import { linkSignals } from '../utils/signals.js';
|
|
3
4
|
export const LIFECYCLE_STAGES = [
|
|
4
5
|
'validate',
|
|
5
6
|
'authorize',
|
|
@@ -43,14 +44,15 @@ export class OperationLifecycle {
|
|
|
43
44
|
const startedAt = Date.now();
|
|
44
45
|
const timeoutMs = options.timeoutMs ?? this.runtime.timeoutMs;
|
|
45
46
|
const deadline = timeoutMs !== undefined && Number.isFinite(timeoutMs) && timeoutMs > 0 ? startedAt + timeoutMs : undefined;
|
|
47
|
+
const call = callSignal(options.signal, deadline === undefined ? undefined : deadline - startedAt);
|
|
46
48
|
const context = {
|
|
47
49
|
requestId: descriptor.requestId,
|
|
48
|
-
signal:
|
|
50
|
+
signal: call.signal,
|
|
49
51
|
...(deadline !== undefined ? { deadline } : {}),
|
|
50
52
|
...(options.traceContext ? { traceContext: options.traceContext } : {}),
|
|
51
53
|
...(options.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : {}),
|
|
52
54
|
};
|
|
53
|
-
const ticket = new Ticket(this.runtime, descriptor, context, startedAt);
|
|
55
|
+
const ticket = new Ticket(this.runtime, descriptor, context, startedAt, call.dispose);
|
|
54
56
|
try {
|
|
55
57
|
await this.runtime.metrics?.recordRequest(labelsOf(descriptor));
|
|
56
58
|
await this.checkRateLimit(descriptor);
|
|
@@ -105,6 +107,7 @@ export class OperationLifecycle {
|
|
|
105
107
|
const bucket = {
|
|
106
108
|
model: descriptor.model ?? `${descriptor.family}:${descriptor.operation}`,
|
|
107
109
|
userId: descriptor.userId,
|
|
110
|
+
tenantId: descriptor.tenantId,
|
|
108
111
|
};
|
|
109
112
|
if (rateLimit.store)
|
|
110
113
|
await rateLimiter.checkAsync(bucket, rateLimit);
|
|
@@ -135,13 +138,15 @@ class Ticket {
|
|
|
135
138
|
descriptor;
|
|
136
139
|
context;
|
|
137
140
|
startedAt;
|
|
141
|
+
release;
|
|
138
142
|
reservation;
|
|
139
143
|
finished = false;
|
|
140
|
-
constructor(runtime, descriptor, context, startedAt) {
|
|
144
|
+
constructor(runtime, descriptor, context, startedAt, release = () => undefined) {
|
|
141
145
|
this.runtime = runtime;
|
|
142
146
|
this.descriptor = descriptor;
|
|
143
147
|
this.context = context;
|
|
144
148
|
this.startedAt = startedAt;
|
|
149
|
+
this.release = release;
|
|
145
150
|
}
|
|
146
151
|
async reserve(estimate) {
|
|
147
152
|
const budget = this.runtime.config?.budget;
|
|
@@ -211,14 +216,14 @@ class Ticket {
|
|
|
211
216
|
});
|
|
212
217
|
}
|
|
213
218
|
async finish(outcome) {
|
|
219
|
+
this.release();
|
|
214
220
|
await runHook(() => this.runtime.config?.hooks?.onFinish?.(this.descriptor, outcome));
|
|
215
221
|
}
|
|
216
222
|
}
|
|
217
223
|
function callSignal(signal, timeoutMs) {
|
|
218
224
|
if (timeoutMs === undefined)
|
|
219
|
-
return signal ?? new AbortController().signal;
|
|
220
|
-
|
|
221
|
-
return signal ? AbortSignal.any([signal, timeout]) : timeout;
|
|
225
|
+
return { signal: signal ?? new AbortController().signal, dispose: () => undefined };
|
|
226
|
+
return linkSignals([signal, AbortSignal.timeout(timeoutMs)]);
|
|
222
227
|
}
|
|
223
228
|
function outcomeOf(error, signal) {
|
|
224
229
|
if (error instanceof OperationDeniedError ||
|
package/dist/core/nexus.d.ts
CHANGED
|
@@ -248,9 +248,13 @@ export declare class NexusAI {
|
|
|
248
248
|
/** Health of every provider seen so far, when health tracking is on. */
|
|
249
249
|
getProviderHealth(): import("../ops/health.js").ProviderHealthSnapshot[];
|
|
250
250
|
/**
|
|
251
|
-
* Calls each provider's health check and records the result.
|
|
251
|
+
* Calls each provider's health check and records the result. With `staleOnly`, only the providers
|
|
252
|
+
* whose health is `unknown` are checked: never called, or not since `health.observationTtlMs`. Run
|
|
253
|
+
* it on a schedule to keep an idle provider's health current.
|
|
252
254
|
*/
|
|
253
|
-
checkProviders(
|
|
255
|
+
checkProviders(options?: {
|
|
256
|
+
staleOnly?: boolean;
|
|
257
|
+
}): Promise<Array<{
|
|
254
258
|
providerName: string;
|
|
255
259
|
ok: boolean;
|
|
256
260
|
error?: string;
|
|
@@ -314,6 +318,12 @@ export declare class NexusAI {
|
|
|
314
318
|
private attachTrace;
|
|
315
319
|
private usesSemanticCache;
|
|
316
320
|
private loadSemanticCache;
|
|
321
|
+
/**
|
|
322
|
+
* Where a request's cached response lives: its key, its namespace, and the scope a semantic match
|
|
323
|
+
* must share, which is always at least the request's tenant.
|
|
324
|
+
*/
|
|
325
|
+
private cachePlan;
|
|
326
|
+
/** Looks a request up in the cache. A cache that fails is reported as an `error` outcome and treated as a miss. */
|
|
317
327
|
private getCachedResponse;
|
|
318
328
|
private setCachedResponse;
|
|
319
329
|
private estimateRequestCost;
|