nexus-ai-pro 2.1.0 → 2.3.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 +77 -0
- package/CHANGELOG.md +286 -1
- package/README.md +19 -9
- package/dist/agent/capabilities.d.ts +39 -0
- package/dist/agent/capabilities.js +36 -0
- package/dist/agent/create-agent.d.ts +61 -11
- package/dist/agent/create-agent.js +136 -22
- package/dist/agent/index.d.ts +3 -2
- package/dist/agent/index.js +1 -1
- package/dist/agent/middleware/approval.d.ts +26 -0
- package/dist/agent/middleware/approval.js +23 -0
- package/dist/agent/{middleware.d.ts → middleware/basic.d.ts} +5 -4
- package/dist/agent/{middleware.js → middleware/basic.js} +3 -5
- package/dist/agent/middleware/context-editor.d.ts +52 -0
- package/dist/agent/middleware/context-editor.js +66 -0
- package/dist/agent/middleware/filesystem.d.ts +44 -0
- package/dist/agent/middleware/filesystem.js +83 -0
- package/dist/agent/middleware/index.d.ts +19 -0
- package/dist/agent/middleware/index.js +9 -0
- package/dist/agent/middleware/limits.d.ts +42 -0
- package/dist/agent/middleware/limits.js +52 -0
- package/dist/agent/middleware/models.d.ts +48 -0
- package/dist/agent/middleware/models.js +44 -0
- package/dist/agent/middleware/pii.d.ts +67 -0
- package/dist/agent/middleware/pii.js +173 -0
- package/dist/agent/middleware/retry.d.ts +66 -0
- package/dist/agent/middleware/retry.js +59 -0
- package/dist/agent/middleware/shared.d.ts +41 -0
- package/dist/agent/middleware/shared.js +73 -0
- package/dist/agent/middleware/tool-selector.d.ts +64 -0
- package/dist/agent/middleware/tool-selector.js +106 -0
- package/dist/agent/permissions.d.ts +113 -0
- package/dist/agent/permissions.js +180 -0
- package/dist/agent/sandbox.d.ts +151 -0
- package/dist/agent/sandbox.js +257 -0
- package/dist/agent/tool.d.ts +8 -3
- package/dist/agent/tool.js +14 -3
- 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.js +12 -1
- package/dist/core/lifecycle.js +11 -6
- package/dist/core/nexus.d.ts +6 -0
- package/dist/core/nexus.js +103 -22
- package/dist/deep-agent/index.d.ts +109 -0
- package/dist/deep-agent/index.js +216 -0
- package/dist/doctor/index.d.ts +90 -0
- package/dist/doctor/index.js +237 -0
- package/dist/graph/functional.d.ts +89 -7
- package/dist/graph/functional.js +156 -36
- package/dist/graph/graph.d.ts +15 -5
- package/dist/graph/graph.js +95 -22
- package/dist/graph/lint.d.ts +4 -1
- package/dist/graph/lint.js +35 -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 +1 -0
- 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/rate-limiter.d.ts +2 -0
- package/dist/ops/rate-limiter.js +2 -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/fulltext.d.ts +67 -0
- package/dist/postgres/fulltext.js +91 -0
- 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/rag/elasticsearch.d.ts +71 -0
- package/dist/rag/elasticsearch.js +130 -0
- package/dist/rag/pipeline.d.ts +140 -0
- package/dist/rag/pipeline.js +187 -0
- package/dist/rag/rerankers.d.ts +92 -0
- package/dist/rag/rerankers.js +97 -0
- package/dist/rag/retrievers.d.ts +12 -1
- package/dist/router/auto-router.d.ts +34 -7
- package/dist/router/auto-router.js +201 -68
- package/dist/server/assistant.d.ts +9 -1
- package/dist/server/assistant.js +10 -0
- package/dist/server/auth.d.ts +250 -0
- package/dist/server/auth.js +392 -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 +24 -1
- package/dist/server/runs.js +90 -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/memory.d.ts +10 -0
- package/dist/store/memory.js +10 -0
- 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/tracing/instrument.js +2 -0
- package/dist/types/config.d.ts +24 -2
- package/dist/types/graph.d.ts +49 -1
- package/dist/types/messages.d.ts +41 -2
- package/dist/types/operations.d.ts +6 -0
- package/dist/types/principal.d.ts +21 -0
- package/dist/types/principal.js +1 -0
- package/dist/types/response.d.ts +20 -0
- package/dist/types/server.d.ts +12 -10
- 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 +25 -0
- package/dist/utils/tenant.js +30 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist-cjs/agent/capabilities.d.ts +39 -0
- package/dist-cjs/agent/capabilities.js +41 -0
- package/dist-cjs/agent/create-agent.d.ts +61 -11
- package/dist-cjs/agent/create-agent.js +136 -22
- package/dist-cjs/agent/index.d.ts +3 -2
- package/dist-cjs/agent/index.js +4 -4
- package/dist-cjs/agent/middleware/approval.d.ts +26 -0
- package/dist-cjs/agent/middleware/approval.js +26 -0
- package/dist-cjs/agent/{middleware.d.ts → middleware/basic.d.ts} +5 -4
- package/dist-cjs/agent/{middleware.js → middleware/basic.js} +3 -5
- package/dist-cjs/agent/middleware/context-editor.d.ts +52 -0
- package/dist-cjs/agent/middleware/context-editor.js +70 -0
- package/dist-cjs/agent/middleware/filesystem.d.ts +44 -0
- package/dist-cjs/agent/middleware/filesystem.js +86 -0
- package/dist-cjs/agent/middleware/index.d.ts +19 -0
- package/dist-cjs/agent/middleware/index.js +28 -0
- package/dist-cjs/agent/middleware/limits.d.ts +42 -0
- package/dist-cjs/agent/middleware/limits.js +57 -0
- package/dist-cjs/agent/middleware/models.d.ts +48 -0
- package/dist-cjs/agent/middleware/models.js +48 -0
- package/dist-cjs/agent/middleware/pii.d.ts +67 -0
- package/dist-cjs/agent/middleware/pii.js +178 -0
- package/dist-cjs/agent/middleware/retry.d.ts +66 -0
- package/dist-cjs/agent/middleware/retry.js +63 -0
- package/dist-cjs/agent/middleware/shared.d.ts +41 -0
- package/dist-cjs/agent/middleware/shared.js +83 -0
- package/dist-cjs/agent/middleware/tool-selector.d.ts +64 -0
- package/dist-cjs/agent/middleware/tool-selector.js +109 -0
- package/dist-cjs/agent/permissions.d.ts +113 -0
- package/dist-cjs/agent/permissions.js +189 -0
- package/dist-cjs/agent/sandbox.d.ts +151 -0
- package/dist-cjs/agent/sandbox.js +297 -0
- package/dist-cjs/agent/tool.d.ts +8 -3
- package/dist-cjs/agent/tool.js +14 -3
- 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/core/lifecycle.js +11 -6
- package/dist-cjs/core/nexus.d.ts +6 -0
- package/dist-cjs/core/nexus.js +103 -22
- package/dist-cjs/deep-agent/index.d.ts +109 -0
- package/dist-cjs/deep-agent/index.js +219 -0
- package/dist-cjs/doctor/index.d.ts +90 -0
- package/dist-cjs/doctor/index.js +276 -0
- package/dist-cjs/graph/functional.d.ts +89 -7
- package/dist-cjs/graph/functional.js +155 -35
- package/dist-cjs/graph/graph.d.ts +15 -5
- package/dist-cjs/graph/graph.js +95 -22
- package/dist-cjs/graph/lint.d.ts +4 -1
- package/dist-cjs/graph/lint.js +35 -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 +1 -0
- 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/rate-limiter.d.ts +2 -0
- package/dist-cjs/ops/rate-limiter.js +2 -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/fulltext.d.ts +67 -0
- package/dist-cjs/postgres/fulltext.js +129 -0
- 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/rag/elasticsearch.d.ts +71 -0
- package/dist-cjs/rag/elasticsearch.js +135 -0
- package/dist-cjs/rag/pipeline.d.ts +140 -0
- package/dist-cjs/rag/pipeline.js +191 -0
- package/dist-cjs/rag/rerankers.d.ts +92 -0
- package/dist-cjs/rag/rerankers.js +107 -0
- package/dist-cjs/rag/retrievers.d.ts +12 -1
- 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 +9 -1
- package/dist-cjs/server/assistant.js +10 -0
- package/dist-cjs/server/auth.d.ts +250 -0
- package/dist-cjs/server/auth.js +402 -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 +24 -1
- package/dist-cjs/server/runs.js +89 -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/memory.d.ts +10 -0
- package/dist-cjs/store/memory.js +10 -0
- 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/tracing/instrument.js +2 -0
- package/dist-cjs/types/config.d.ts +24 -2
- package/dist-cjs/types/graph.d.ts +49 -1
- package/dist-cjs/types/messages.d.ts +41 -2
- package/dist-cjs/types/operations.d.ts +6 -0
- package/dist-cjs/types/principal.d.ts +21 -0
- package/dist-cjs/types/principal.js +2 -0
- package/dist-cjs/types/response.d.ts +20 -0
- package/dist-cjs/types/server.d.ts +12 -10
- 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 +25 -0
- package/dist-cjs/utils/tenant.js +37 -0
- package/dist-cjs/version.d.ts +1 -1
- package/dist-cjs/version.js +1 -1
- package/llms.txt +6 -4
- package/package.json +188 -2
package/API_STABILITY.md
CHANGED
|
@@ -41,6 +41,83 @@ Both are covered by this policy:
|
|
|
41
41
|
Deep imports into `dist`, `dist-cjs`, or `src` are not supported. Import only from `nexus-ai-pro` or
|
|
42
42
|
one of its explicit subpaths.
|
|
43
43
|
|
|
44
|
+
## 2.3 stage (2.3.0)
|
|
45
|
+
|
|
46
|
+
Everything 2.3 adds is stable from the start and additive: no default changes meaning.
|
|
47
|
+
|
|
48
|
+
- `ToolDefinition.capabilities` and the capability grammar; `permissionPolicy()`, `PermissionPolicy`,
|
|
49
|
+
`PermissionRules`, `PermissionRequest`, `PermissionVerdict`, `PermissionDecision`,
|
|
50
|
+
`PermissionPolicyLike`, `parseCapability()`, `capabilitiesOf()`, `isSensitiveCapability()`, and
|
|
51
|
+
`normalizePath()` (`nexus-ai-pro/agent/permissions`); `CreateAgentOptions.permissions`;
|
|
52
|
+
- the sandbox contract: `Sandbox`, its option, result, and isolation types, `sandboxTools()`,
|
|
53
|
+
`runSandboxConformance()` and its report types, `SandboxPathError` (`nexus-ai-pro/agent/sandbox`).
|
|
54
|
+
`processSandbox()` is a development reference and may change; conformance checks may be added;
|
|
55
|
+
- `NodeOptions.effects` and `interrupts`, `CompileOptions.tools`, `GraphToolDescription`, and the lint
|
|
56
|
+
codes `SENSITIVE_TOOL_WITHOUT_APPROVAL`, `UNDECLARED_TOOL_CAPABILITIES`, and
|
|
57
|
+
`SIDE_EFFECT_BEFORE_INTERRUPT`;
|
|
58
|
+
- `nexus-ai-pro/agent/middleware` and every middleware and option type on it;
|
|
59
|
+
`AgentMiddleware.wrapModelCall`, `AgentMiddlewareContext`, `AgentModelCallContext`, the third
|
|
60
|
+
argument of `wrapToolCall`, `next(call)`, and `AgentStopReason` `'stopped'`. The PII patterns
|
|
61
|
+
may be tightened in a minor release to cut false positives, and new `PiiKind` members may be
|
|
62
|
+
added;
|
|
63
|
+
- `nexus-ai-pro/server/auth`: `jwtAuth()`, `apiKeyAuth()`, `trustedProxyAuth()`, `anyAuth()`,
|
|
64
|
+
`createJwtVerifier()`, `hashApiKey()`, `JwtError` and its codes, and every option type. New
|
|
65
|
+
`JwtAlgorithm` and `JwtErrorCode` members may be added;
|
|
66
|
+
- `Principal.roles`, `method`, and `claims`; `GraphRunOptions.principal`, `NodeContext.principal`,
|
|
67
|
+
`WorkflowRunOptions.principal`, and `WorkflowContext.principal`; `ToolContext` and the second
|
|
68
|
+
argument of `ToolDefinition.execute`; `AgentMiddlewareContext.principal` and
|
|
69
|
+
`PermissionRequest.principal`. A checkpoint's `metadata.userId` is recorded when a run has a
|
|
70
|
+
principal with a subject;
|
|
71
|
+
- `SparseRetriever`; `PostgresKeywordIndex` and `keywordIndexMigrations()`
|
|
72
|
+
(`nexus-ai-pro/postgres/fulltext`); `ElasticsearchKeywordIndex` and `ElasticsearchError`
|
|
73
|
+
(`nexus-ai-pro/rag/elasticsearch`); and every reranker and option type on
|
|
74
|
+
`nexus-ai-pro/rag/rerankers`. The default endpoints of hosted rerankers follow their providers'
|
|
75
|
+
current API versions;
|
|
76
|
+
- `nexus-ai-pro/rag/pipeline`: `createIngestionPipeline()`, `ingestionExecutor()`, and their types.
|
|
77
|
+
The manifest's layout under `['nexus', 'ingestion', <name>]` is stable: a later release reads a
|
|
78
|
+
manifest an earlier one wrote;
|
|
79
|
+
- `nexus-ai-pro/deep-agent`: `createDeepAgent()`, `DeepAgentOptions`, `DeepSubagent`, and
|
|
80
|
+
`DeepSkill`, and the names and arguments of the tools it gives the model (`write_todos`,
|
|
81
|
+
`delegate`, `load_skill`, `edit_file`). The wording of its system prompt may change in any release.
|
|
82
|
+
|
|
83
|
+
## 2.2 stage (2.2.0)
|
|
84
|
+
|
|
85
|
+
Everything 2.2 adds is stable from the start and additive: no default changes meaning.
|
|
86
|
+
|
|
87
|
+
- versioned migrations: `SchemaMigration`, `AppliedMigration`, `MigrationStatus`, `MigrationResult`,
|
|
88
|
+
`SchemaMigrationError`, `migrationChecksum()`, `applyPostgresMigrations()`,
|
|
89
|
+
`postgresMigrationStatus()`, `postgresMigrations()`, `PostgresMigrateOptions`, every adapter's
|
|
90
|
+
`…Migrations()`, and the SQLite twins (`nexus-ai-pro/postgres`, `nexus-ai-pro/postgres/migrations`,
|
|
91
|
+
`nexus-ai-pro/sqlite`, `nexus-ai-pro/sqlite/migrations`). A migration, once released, never
|
|
92
|
+
changes; later releases add versions. `migrate()` now resolves to a `MigrationResult` instead of
|
|
93
|
+
nothing;
|
|
94
|
+
- `nexus db status` and `nexus db migrate`, and `nexus db sql --record`;
|
|
95
|
+
- `RedisOperationStoreOptions.index` and `reindex()`;
|
|
96
|
+
- `CircuitBreakerConfig.shareObservations`, `CircuitStateStore.observe()`, `CircuitObservation`,
|
|
97
|
+
`CircuitWindow`, and `CircuitSnapshot.shared`;
|
|
98
|
+
- `PostgresRollupStore` (`nexus-ai-pro/postgres/rollups`);
|
|
99
|
+
- the tenant model (`nexus-ai-pro/tenancy`): every `tenant…()` view, `tenantScope()`,
|
|
100
|
+
`TenantAssetStore`, `TenantStores`, `assertTenantId()`, `TenantIdError`, and `TENANT_NAMESPACE`.
|
|
101
|
+
The prefix a view stores names under (`tenant/<id>/`) is part of the contract and does not change
|
|
102
|
+
within 2.x; `GraphRunOptions.tenantId`, `NodeContext.tenantId`, the `tenantId` options of `state()`,
|
|
103
|
+
`history()`, `fork()`, and `updateState()`, `OperationRecord.tenantId`,
|
|
104
|
+
`OperationSubmitOptions.tenantId`, `OperationStoreFilter.tenantId`, `RateLimitedRequest.tenantId`,
|
|
105
|
+
and `rateLimit.key: 'tenantId'`;
|
|
106
|
+
- `CacheConfig.namespace`, `CacheNamespace`, `CacheOutcome` and `ResponseMeta.cache`,
|
|
107
|
+
`CompletionRequest.responseCache`, `MemoryCache.lookup()`, and the `scope` of `SemanticCache`'s
|
|
108
|
+
`get()` and `set()`;
|
|
109
|
+
- `diagnose()` and its types (`nexus-ai-pro/doctor`), and `nexus doctor`. Checks may be added in a
|
|
110
|
+
minor release; a check's id and what makes it fail do not change within 2.x;
|
|
111
|
+
- workflow steps' `timeout`, `onError`, `StepTimeout`, `StepFailure`, `StepRecovery`,
|
|
112
|
+
`StepContext.heartbeat()`, `WorkflowOptions.stepDefaults`, `WorkflowRunOptions.control` and
|
|
113
|
+
`tenantId`, `WorkflowContext.tenantId`, and `WorkflowStepTimeoutError.kind`;
|
|
114
|
+
- `RunHandOffError`, `AssistantRunContext.saveProgress()` and `progress`.
|
|
115
|
+
|
|
116
|
+
Three races are closed rather than added: a busy thread is claimed atomically, and the in-memory and
|
|
117
|
+
Redis operation stores refuse a second record under a held idempotency key, as the SQL stores
|
|
118
|
+
already did. The semantic cache no longer matches across tenants, and a failing response cache no
|
|
119
|
+
longer fails a request.
|
|
120
|
+
|
|
44
121
|
## 2.1 stage (2.1.0)
|
|
45
122
|
|
|
46
123
|
Everything 2.1 adds is stable from the start and additive: no default changes meaning.
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,289 @@ Notable changes to this project are recorded here. The format follows [Keep a Ch
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [2.3.0] - 2026-10-06
|
|
8
|
+
|
|
9
|
+
Agents that act safely, on production retrieval.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **Capabilities and permission policies.** A tool declares what each call does —
|
|
14
|
+
`filesystem:write:<path>`, `network:<host>`, `shell:<command>`, `code`, or an effect of the
|
|
15
|
+
application's own — as a list or a function of its arguments. `permissionPolicy()`, on the new
|
|
16
|
+
`nexus-ai-pro/agent/permissions`, grants filesystem globs, network hosts, and shell command
|
|
17
|
+
prefixes, and decides each call: allow, deny, or ask. Paths are normalized before any grant sees
|
|
18
|
+
them, and a command that chains, pipes, or substitutes is never granted by a prefix.
|
|
19
|
+
`createAgent({ permissions })` enforces it before a tool runs: a denied call never runs, an `ask`
|
|
20
|
+
interrupts as `interruptOn` does, and arguments an approver edits are decided again.
|
|
21
|
+
- **A sandbox contract**, on the new `nexus-ai-pro/agent/sandbox`: the `Sandbox` interface a
|
|
22
|
+
container, VM, or hosted interpreter fills; `sandboxTools()`, whose calls declare exactly the
|
|
23
|
+
command or path they use; `runSandboxConformance()`, which proves any sandbox against the
|
|
24
|
+
contract; and `processSandbox()`, a reference for development that is never a security boundary
|
|
25
|
+
and says so.
|
|
26
|
+
- **The linter reads capabilities.** `SENSITIVE_TOOL_WITHOUT_APPROVAL` reports a tool that writes, runs
|
|
27
|
+
commands or code, or reaches the network with neither approval nor a policy;
|
|
28
|
+
`UNDECLARED_TOOL_CAPABILITIES` a tool whose effects cannot be judged; and
|
|
29
|
+
`SIDE_EFFECT_BEFORE_INTERRUPT` a node that declares `effects` and `interrupts`. An agent's graph
|
|
30
|
+
describes its tools for it.
|
|
31
|
+
- **A middleware catalog**, on the new `nexus-ai-pro/agent/middleware`, each a separate import:
|
|
32
|
+
`modelRetry()`, `modelFallback()` (to another model or another client), `dynamicModel()`,
|
|
33
|
+
`toolRetry()` (which by default repeats only a call that cannot have changed anything),
|
|
34
|
+
`toolSelector()` (by rule, embedding similarity, or both), `contextEditor()` (clears old tool
|
|
35
|
+
results in batches, so a prompt cache keeps working), `piiMiddleware()` (validated card numbers
|
|
36
|
+
and IBANs; redact, mask, hash, or block), `humanApproval()` (per call, in band or out of band),
|
|
37
|
+
`modelCallLimit()` (per run and per thread, the thread count shared through the store), and
|
|
38
|
+
`filesystemContext()` (instruction files in, large results out to a file). The three existing
|
|
39
|
+
middleware are there too.
|
|
40
|
+
- **A wider middleware seam.** `wrapModelCall` wraps the model call itself, and may call `next()`
|
|
41
|
+
again to retry or fall back. Every hook receives an `AgentMiddlewareContext`: the state, the
|
|
42
|
+
store, the thread and tenant, the run's signal, and `interrupt()`. `context.stop()` ends a run
|
|
43
|
+
with an answer and the new `stopReason: 'stopped'`. A `wrapToolCall` can pass `next()` changed
|
|
44
|
+
arguments, which the permission policy decides again.
|
|
45
|
+
- **Server authentication**, on the new `nexus-ai-pro/server/auth`. It is built on Web Crypto, with no
|
|
46
|
+
dependency:
|
|
47
|
+
- `jwtAuth()` takes an identity provider's key set (cached, and refetched when a token names a new
|
|
48
|
+
key), a public key, or a shared secret, and checks issuer, audience, expiry, and age. It refuses
|
|
49
|
+
`alg: none` and key confusion, and requires an audience with a key set.
|
|
50
|
+
- `apiKeyAuth()` compares keys by their SHA-256 hash, from `hashApiKey()`.
|
|
51
|
+
- `trustedProxyAuth()` refuses to exist without proof that the proxy sent the request.
|
|
52
|
+
- `anyAuth()` combines hooks.
|
|
53
|
+
- `createJwtVerifier()` verifies tokens outside the server.
|
|
54
|
+
- **One Principal, everywhere a run goes.** It gains `roles`, `method`, and `claims`.
|
|
55
|
+
- Graph and workflow runs take a `principal`, which nodes read as `context.principal`. Its tenant
|
|
56
|
+
becomes the run's, and its subject is recorded on every checkpoint and in the run's trace.
|
|
57
|
+
- `graphAssistant()` passes the authenticated caller on.
|
|
58
|
+
- Tools receive a `ToolContext` as the second argument of `execute`: the principal, the thread
|
|
59
|
+
and tenant, the run's signal, and the tenant's store.
|
|
60
|
+
- Middleware and permission policies see the principal too.
|
|
61
|
+
- **Sparse retrieval as a contract.** A `SparseRetriever` is keyword search that takes writes, so it
|
|
62
|
+
fuses with vector search and stays in step with a vector store. `KeywordIndex` is one. Two more
|
|
63
|
+
ship:
|
|
64
|
+
- `PostgresKeywordIndex` (`nexus-ai-pro/postgres/fulltext`) uses Postgres full-text search, with a
|
|
65
|
+
GIN index and ranking in the database. With `shared`, it searches a pgvector table through a
|
|
66
|
+
generated column, so hybrid search keeps one copy of the data.
|
|
67
|
+
- `ElasticsearchKeywordIndex` (`nexus-ai-pro/rag/elasticsearch`) works with Elasticsearch or
|
|
68
|
+
OpenSearch over the REST API, with no client library.
|
|
69
|
+
- **Rerankers**, on the new `nexus-ai-pro/rag/rerankers`, with no SDK:
|
|
70
|
+
- `cohereReranker()`, `voyageReranker()`, and `jinaReranker()` for hosted APIs;
|
|
71
|
+
- `teiReranker()` for a self-hosted cross-encoder;
|
|
72
|
+
- `httpReranker()` for any other API;
|
|
73
|
+
- `crossEncoderReranker()` for a model run in process.
|
|
74
|
+
- **Durable ingestion**, on the new `nexus-ai-pro/rag/pipeline`. `createIngestionPipeline()` keeps a
|
|
75
|
+
manifest in any `Store`: each document's content version, its chunking, the embedding model, and
|
|
76
|
+
each chunk's version. A run:
|
|
77
|
+
- embeds only new and changed chunks; chunks are named by their text, so one that only moved keeps
|
|
78
|
+
its embedding;
|
|
79
|
+
- deletes the chunks and documents that are gone;
|
|
80
|
+
- keeps keyword indexes in step;
|
|
81
|
+
- writes to the stores before the manifest.
|
|
82
|
+
|
|
83
|
+
`ingestionExecutor()` runs it as a durable operation, and a retry starts at the document the
|
|
84
|
+
failed attempt stopped on.
|
|
85
|
+
- **A deep-agent preset**, on the new `nexus-ai-pro/deep-agent`. `createDeepAgent()` is
|
|
86
|
+
`createAgent()` composed with:
|
|
87
|
+
- a plan, kept in the transcript;
|
|
88
|
+
- a sandboxed workspace, with `edit_file` for precise changes and commands granted by name;
|
|
89
|
+
- helpers behind one `delegate` tool, which never get a tool that needs approval;
|
|
90
|
+
- skills loaded on demand;
|
|
91
|
+
- instruction files and context offloading;
|
|
92
|
+
- context editing, optional tool selection, and a default permission policy.
|
|
93
|
+
|
|
94
|
+
It returns the same compiled graph as any agent; it is not a new engine.
|
|
95
|
+
- `processSandbox()` loads Node's modules when first used, so `nexus-ai-pro/agent/sandbox`, and a
|
|
96
|
+
deep agent over a container sandbox, import on any runtime.
|
|
97
|
+
|
|
98
|
+
### Fixed
|
|
99
|
+
|
|
100
|
+
- `MemoryStore` swept every item for expiry on every write, so writing n items took time
|
|
101
|
+
proportional to n². It now sweeps only once an item has a time to live, and at most once a second.
|
|
102
|
+
Expired items were already hidden from reads.
|
|
103
|
+
|
|
104
|
+
- `limitToolCalls()` counted calls in memory shared by every run of an agent, so one thread's calls
|
|
105
|
+
used up another's limit, and the count never reset. It now counts per run from the transcript.
|
|
106
|
+
- A subgraph run through `asNode()` now runs for its parent's tenant, so its store is the tenant's
|
|
107
|
+
view, as the parent's is.
|
|
108
|
+
- `sandboxTools()` file tools accept a path that names the mount, such as `/workspace/notes.txt`,
|
|
109
|
+
as well as one relative to it, and say in their descriptions which to use.
|
|
110
|
+
|
|
111
|
+
### Proof
|
|
112
|
+
|
|
113
|
+
- In a real agent tool loop, a write outside the workspace and a request to an unlisted host are
|
|
114
|
+
refused before their tools run, and a granted command that needs approval waits for a person.
|
|
115
|
+
- The process sandbox passes the conformance suite, and a sandbox that leaks the host's environment
|
|
116
|
+
and writes outside its root fails exactly those two checks.
|
|
117
|
+
- An agent over 150 tools completes 40 tasks, a third of them needing two tools, with
|
|
118
|
+
`toolSelector()` at equal quality: every task succeeds either way. Input tokens per task fall from
|
|
119
|
+
about 64,000 to about 5,200, and latency by about 70%: the model's time computed from
|
|
120
|
+
each request's size, plus the agent's own measured time. Two experiments, reported by
|
|
121
|
+
`compareExperiments()`, show it.
|
|
122
|
+
- Each middleware is proved in a real agent loop. For example:
|
|
123
|
+
- a charge that timed out is never retried;
|
|
124
|
+
- an approver who raises a refund past what the policy allows has the edit refused;
|
|
125
|
+
- two agents sharing a store share one thread budget;
|
|
126
|
+
- a 45,000-character tool result reaches the transcript as a preview and a file.
|
|
127
|
+
- A JWT from a test identity provider is verified against its key set and reaches an agent's tool
|
|
128
|
+
call as a `Principal` with its subject, tenant, roles, and scopes.
|
|
129
|
+
- The tool's writes land in that tenant's view of the store.
|
|
130
|
+
- The checkpoint records who ran the step.
|
|
131
|
+
- Another tenant's token gets 404 for the thread.
|
|
132
|
+
- Expired, wrong-audience, wrong-issuer, unsigned, and forged tokens are refused.
|
|
133
|
+
- The provider rotates its key with one refetch.
|
|
134
|
+
- On the stored support dataset, on real Postgres with full-text search and pgvector, hybrid retrieval
|
|
135
|
+
beats vector-only: recall@5 0.71 → 0.97 and mean reciprocal rank 0.51 → 0.71, both with a 95%
|
|
136
|
+
interval above zero. A hosted reranker and a local cross-encoder, compared in the same experiment,
|
|
137
|
+
each lift mean reciprocal rank to 0.97. One contract test runs against all four keyword indexes.
|
|
138
|
+
- An ingestion of 100,000 documents dies halfway inside a durable operation. Its retry starts at the
|
|
139
|
+
document the first attempt stopped on, and embeds no chunk that had finished. A second run after
|
|
140
|
+
ten documents are edited embeds exactly ten chunks and deletes their old versions.
|
|
141
|
+
- A deep agent completes a multi-step task on a fixture repository inside the reference sandbox. It
|
|
142
|
+
plans, runs the failing test, reads and edits the bug, verifies the fix, has a helper review it,
|
|
143
|
+
loads a skill, and records the change; the test then passes outside the agent. Along the way, a
|
|
144
|
+
30,000-character log is offloaded to a file. The default policy refuses an unlisted command, a
|
|
145
|
+
chained command, a write outside the workspace, and an ungranted tool.
|
|
146
|
+
|
|
147
|
+
## [2.2.0] - 2026-10-05
|
|
148
|
+
|
|
149
|
+
Production scale and safe upgrades. Every database schema is versioned, so an upgrade applies only
|
|
150
|
+
what changed, and a worker of the previous release keeps running beside the new one. A claim costs
|
|
151
|
+
the same however long the queue is, routing costs the same however many models are configured, a
|
|
152
|
+
circuit breaker counts every worker's failures, and work that several replicas race for is taken by
|
|
153
|
+
exactly one. One tenant model reaches every store, and a deployment can check itself. Nothing
|
|
154
|
+
changes until it is opted into, except races and leaks that are now closed.
|
|
155
|
+
|
|
156
|
+
### Added
|
|
157
|
+
|
|
158
|
+
- **Versioned migrations.** Every Postgres and SQLite adapter's schema is a list of numbered
|
|
159
|
+
`SchemaMigration`s, recorded in `nexus_schema_migrations` with a checksum. `migrate()` applies what
|
|
160
|
+
is pending, under a lock that holds through a connection pool, and refuses a migration whose
|
|
161
|
+
statements changed after it ran (`SchemaMigrationError`). Version 1 is the schema 2.0 created, so an
|
|
162
|
+
existing database is recognized as it is. `applyPostgresMigrations()`, `postgresMigrationStatus()`,
|
|
163
|
+
`postgresMigrations()`, and their SQLite twins work on any list, from `nexus-ai-pro/postgres`,
|
|
164
|
+
`nexus-ai-pro/sqlite`, and the new `nexus-ai-pro/postgres/migrations` and
|
|
165
|
+
`nexus-ai-pro/sqlite/migrations`. `PostgresMigrateOptions.transaction` runs each migration in one
|
|
166
|
+
transaction on one connection, and `postgresMigration({ record: true })` records what the script
|
|
167
|
+
creates.
|
|
168
|
+
- **`nexus db status` and `nexus db migrate`**, through a module that exports your own client:
|
|
169
|
+
applied, pending, changed, and newer migrations, `--check` for a deploy step, and `--dry-run`.
|
|
170
|
+
- **Indexed dispatch.** Version 2 of the Postgres and SQLite operation schemas indexes queued work by
|
|
171
|
+
age, so a claim reads the oldest few rows instead of sorting the queue, and version 3 by tenant.
|
|
172
|
+
`RedisOperationStore` takes `index: true`: queued work in a sorted set by age and leased work in one
|
|
173
|
+
by lease expiry, kept in the same Lua call as the record, with `reindex()` to index what is already
|
|
174
|
+
stored. A claim reads the same handful of records with 100,000 operations queued as with 1,000.
|
|
175
|
+
- **A circuit breaker that counts across workers.** `shareObservations: true` adds each worker's
|
|
176
|
+
calls to a rolling window in the shared store, so nine failures over three workers count as nine
|
|
177
|
+
and the circuit opens on all of them. Checks stay synchronous; a worker learns the shared count on
|
|
178
|
+
its next sync. `CircuitStateStore.observe()` is implemented by the memory, Redis, and Postgres
|
|
179
|
+
stores, and `CircuitSnapshot.shared` reports the window.
|
|
180
|
+
- **`PostgresRollupStore`**, on the new `nexus-ai-pro/postgres/rollups`: hourly rollups beside the
|
|
181
|
+
traces, summed in one statement so two workers adding to one hour both count.
|
|
182
|
+
- **A routing index.** The auto-router plans once per configuration — candidates, allow and deny
|
|
183
|
+
lists, capability requirements as bitmasks, and strategy scores — and a request pays only for open
|
|
184
|
+
circuits and health. Over 1,000 models a warm route takes about 15 µs at p50 and 23 µs at p99.
|
|
185
|
+
- **One tenant model**, on the new `nexus-ai-pro/tenancy`: a tenant's view of every store —
|
|
186
|
+
`tenantStore()`, `tenantTraceStore()`, `tenantOperationStore()`, `tenantPromptStore()` (and with it
|
|
187
|
+
the context hub), `tenantDatasetStore()`, `tenantExperimentStore()`, `tenantVectorStore()`,
|
|
188
|
+
`tenantCache()`, `tenantAssetStore()`, `tenantRollupStore()` — each implementing the store's own
|
|
189
|
+
contract over any backend, and `tenantScope()` for all of them at once. Graph runs take a
|
|
190
|
+
`tenantId`: recorded on every checkpoint, read as `context.tenantId`, scoping `context.store`, and
|
|
191
|
+
refusing another tenant's resume, continue, fork, or edit. `graphAssistant()` passes the
|
|
192
|
+
principal's tenant. Operations carry `tenantId`, and `OperationStoreFilter.tenantId` narrows queue
|
|
193
|
+
reads. Model calls are traced with their `tenantId`, so rollups count model spend per tenant, and
|
|
194
|
+
`rateLimit.key: 'tenantId'` gives each tenant its own share of a client's rate limit.
|
|
195
|
+
- **Cache namespaces and outcomes.** `cache.namespace` keeps responses apart by tenant, environment,
|
|
196
|
+
model revision, and context version. Every response reports `meta.cache` — `hit`, `miss`, `stale`,
|
|
197
|
+
`bypass`, or `error`, with its layer and reason — and the request's trace records it.
|
|
198
|
+
`CompletionRequest.responseCache` skips the cache (`bypass`) or refreshes it (`refresh`).
|
|
199
|
+
- **`nexus doctor`**, and `diagnose()` on the new `nexus-ai-pro/doctor`: the Node.js version,
|
|
200
|
+
optional packages, provider credentials (by name only), database connectivity and pending or
|
|
201
|
+
changed migrations, Redis, lapsed leases and a stalled queue, the registry's age, stale provider
|
|
202
|
+
health, and process-local stores behind several replicas. It exits 1 on a failure, or with
|
|
203
|
+
`--strict` on a warning.
|
|
204
|
+
- **Runtime budgets.** `npm run bench:runtime`, part of the release gate, times fourteen paths — graph
|
|
205
|
+
creation, a 1,000-node compile, `Send`, checkpoints, routing at three registry sizes, a
|
|
206
|
+
20-middleware agent, traces, the event stream, server event fan-out, claims, and cache lookups —
|
|
207
|
+
as ratios to a calibration loop, so a budget holds across machines, and checks that 100,000
|
|
208
|
+
checkpoints and 10,000 runs leave the heap where it was.
|
|
209
|
+
- **Workflow steps have what graph nodes have.** `timeout: { runMs, idleMs }` with
|
|
210
|
+
`context.heartbeat()`, an `onError` that decides once retries run out — recorded as `recovered`,
|
|
211
|
+
so a resume repeats neither the step nor its recovery — `stepDefaults`, a `control` that drains
|
|
212
|
+
between steps and ends in `GraphDrainedError`, and `tenantId`. A workflow the agent server serves
|
|
213
|
+
is handed off on a drain like a graph.
|
|
214
|
+
- **A function assistant hands its run off on a drain**: it checks `context.control?.draining`,
|
|
215
|
+
saves how far it got with `context.saveProgress()`, and throws `RunHandOffError`; the next worker
|
|
216
|
+
reads `context.progress` and carries on.
|
|
217
|
+
|
|
218
|
+
### Changed
|
|
219
|
+
|
|
220
|
+
- `migrate()` on every Postgres and SQLite adapter resolves to a `MigrationResult` instead of
|
|
221
|
+
nothing, records what it applied, and loads the migration runner only when called.
|
|
222
|
+
- `nexus db sql` and `postgresMigration()` include the rollups table and the new indexes by
|
|
223
|
+
default; every statement stays idempotent.
|
|
224
|
+
- The root import grew by 11 KB, to 336 KB, with the routing plan, cache outcomes, and linked
|
|
225
|
+
signals; `nexus-ai-pro/graph` by 5 KB, to 78 KB, with tenant runs; and
|
|
226
|
+
`nexus-ai-pro/graph/functional` by 6 KB, to 32 KB, with step timeouts, recovery, drain, and
|
|
227
|
+
tenants.
|
|
228
|
+
|
|
229
|
+
### Fixed
|
|
230
|
+
|
|
231
|
+
- **Two replicas could both start a run on one busy thread.** The busy check read and wrote
|
|
232
|
+
separately. A thread is now claimed through the operation store under a unique key with
|
|
233
|
+
compare-and-set, so exactly one run proceeds and the rest meet the busy policy. An `enqueue` start
|
|
234
|
+
still busy when `queueTimeoutMs` runs out is refused instead of running beside the other.
|
|
235
|
+
- **Two submissions under one idempotency key could both run** on the in-memory and Redis operation
|
|
236
|
+
stores, which overwrote the key's owner. Both now refuse a second record under a key another record
|
|
237
|
+
holds, as Postgres and SQLite do, and Redis checks and writes in one Lua call.
|
|
238
|
+
- A circuit breaker's calls recorded before its shared-state module finished loading were not
|
|
239
|
+
shared.
|
|
240
|
+
- **Security: the semantic response cache answered one tenant with another's response** when their
|
|
241
|
+
questions were alike, because it compared every entry regardless of tenant. A semantic match is
|
|
242
|
+
now kept to the request's tenant and cache namespace.
|
|
243
|
+
- A response cache that threw failed the request, and one that failed to store an answer failed it
|
|
244
|
+
after the provider had answered. Both are now reported in `meta.cache`, and the request goes on.
|
|
245
|
+
- The auto-router rebuilt the model registry for every candidate on every request: over 1,000 models
|
|
246
|
+
a request took most of a second.
|
|
247
|
+
- **Memory grew with every run that shared a signal.** `AbortSignal.any()`, which composed each task
|
|
248
|
+
attempt's signal, keeps a reference per call for as long as any source lives in Node 22, so a
|
|
249
|
+
server's or a worker's long-lived signal held about 5 KB per graph run, and every client operation
|
|
250
|
+
with a deadline held one too. Signals are now linked and released when their work ends; 10,000
|
|
251
|
+
runs leave the heap within 0.3 MB of where it started, down from 52 MB.
|
|
252
|
+
|
|
253
|
+
### Proof
|
|
254
|
+
|
|
255
|
+
- A database created by the published 2.0.0 package upgrades with 2.2's migrations, on Postgres and
|
|
256
|
+
SQLite, and a published 2.1.0 worker and a 2.2 worker drain one queue together, nothing run twice.
|
|
257
|
+
- Ten workers race one thread, one idempotency key, one queue, one tenant's slots and budget, and one
|
|
258
|
+
circuit, on every shared store, and every invariant holds.
|
|
259
|
+
- A Redis claim reads the same number of records at 1,000 and 100,000 queued; Postgres and SQLite
|
|
260
|
+
plan a claim through the age index with no sort.
|
|
261
|
+
- The Redis stores' Lua runs for real in the tests, in a Lua VM over an in-memory Redis.
|
|
262
|
+
- The routing index decides exactly as the published 2.1.0 router on 300 random configurations, and
|
|
263
|
+
a warm route over 1,000 models stays under 100 µs at p50 and 1 ms at p99.
|
|
264
|
+
- A tenant-isolation suite runs against every storage adapter — memory, Redis, Postgres, SQLite, and
|
|
265
|
+
files — and fails on any cross-tenant get, list, search, delete, fork, resume, trace query, vector
|
|
266
|
+
search, or cache hit.
|
|
267
|
+
- `nexus doctor` reports each misconfiguration a fixture deployment is seeded with — an old Node.js,
|
|
268
|
+
no credentials, an old registry, pending migrations, an unreachable Redis, a lapsed lease and a
|
|
269
|
+
stalled queue, stale health, and memory stores behind three replicas — and passes it once fixed.
|
|
270
|
+
- A workflow and a function assistant are each drained on one worker and finished on the next, with
|
|
271
|
+
every step and every item run exactly once.
|
|
272
|
+
|
|
273
|
+
### Not in this release, and why
|
|
274
|
+
|
|
275
|
+
- **The migration lock is a row with a lease, not a session advisory lock.** A session lock does not
|
|
276
|
+
hold through a connection pool or a serverless driver, where each statement may reach another
|
|
277
|
+
connection; a lease row does, everywhere. Without a `transaction` function, statements run one at a
|
|
278
|
+
time, which is safe because every bundled statement is idempotent.
|
|
279
|
+
- **The Redis dispatch index is opt-in**, since a 2.1 worker writes records without index entries;
|
|
280
|
+
`stats()` on Redis still reads every record.
|
|
281
|
+
- **Consecutive failures across workers are counted as failures since any worker's last success.**
|
|
282
|
+
Calls are reported in batches, so two workers' failures and successes in the same second may be
|
|
283
|
+
ordered differently than they happened.
|
|
284
|
+
- **Tenant views scope by prefix and stamp, not by a column**, so they work over every backend
|
|
285
|
+
unchanged; data written before a view was used is not the tenant's until it is copied under its
|
|
286
|
+
prefix.
|
|
287
|
+
- **Runtime budgets compare ratios to a calibration loop**, which catches a cliff, not a 10% drift;
|
|
288
|
+
the tolerance is three times the recorded ratio.
|
|
289
|
+
|
|
7
290
|
## [2.1.0] - 2026-10-04
|
|
8
291
|
|
|
9
292
|
Fault-tolerant graphs and crash-safe observability. A graph now chooses when its checkpoints are
|
|
@@ -1494,7 +1777,9 @@ shared policy vocabulary is in place for a future release that revisits this.
|
|
|
1494
1777
|
- URL fetching rejects unsafe private-network targets and limits response reads.
|
|
1495
1778
|
- CLI and audit findings no longer disclose detected secret values.
|
|
1496
1779
|
|
|
1497
|
-
[Unreleased]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v2.
|
|
1780
|
+
[Unreleased]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v2.3.0...HEAD
|
|
1781
|
+
[2.3.0]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v2.2.0...v2.3.0
|
|
1782
|
+
[2.2.0]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v2.1.0...v2.2.0
|
|
1498
1783
|
[2.1.0]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v2.0.0...v2.1.0
|
|
1499
1784
|
[2.0.0]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v1.25.0...v2.0.0
|
|
1500
1785
|
[1.25.0]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v1.24.0...v1.25.0
|
package/README.md
CHANGED
|
@@ -8,12 +8,12 @@ team can share.
|
|
|
8
8
|
Import only what you use. The root import is the client and nothing else, and every other capability
|
|
9
9
|
has its own entry point with a size budget CI enforces; [the packaging guide](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/packaging.md)
|
|
10
10
|
publishes what each one costs. The package has no required dependencies: a graph-only application
|
|
11
|
-
loads
|
|
11
|
+
loads 80 KB, and installs nothing but this package.
|
|
12
12
|
|
|
13
13
|
- NPM: https://www.npmjs.com/package/nexus-ai-pro
|
|
14
14
|
- GitHub: https://github.com/mkhitar-abrahamyan/nexus-ai
|
|
15
15
|
- Contributing, testing, and release procedure: [CONTRIBUTING.md](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/CONTRIBUTING.md)
|
|
16
|
-
-
|
|
16
|
+
- What is planned next: [ROADMAP.md](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/ROADMAP.md)
|
|
17
17
|
- For AI assistants: [llms.txt](https://raw.githubusercontent.com/mkhitar-abrahamyan/nexus-ai/main/llms.txt) indexes every guide, and [llms-full.txt](https://raw.githubusercontent.com/mkhitar-abrahamyan/nexus-ai/main/llms-full.txt) holds them all in one file
|
|
18
18
|
|
|
19
19
|
## Install
|
|
@@ -132,7 +132,8 @@ from the doc comments. The guides live in the repository, so these links go to G
|
|
|
132
132
|
| [Providers and routing](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/providers.md) | The twelve completion providers, routing and failover, the model registry |
|
|
133
133
|
| [Guardrails](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/security.md) | Injection, PII, secrets, schema validation, output redaction |
|
|
134
134
|
| [Graphs](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/graphs.md) | Parallel branches, interrupts, checkpoints, time travel, subgraphs, caching, diagrams |
|
|
135
|
-
| [Agents and tools](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/agents.md) | Graph-based agents with approvals and middleware, and the simple tool loop |
|
|
135
|
+
| [Agents and tools](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/agents.md) | Graph-based agents with approvals, capabilities and permission policies, a sandbox contract, the middleware catalog, and the simple tool loop |
|
|
136
|
+
| [The deep-agent preset](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/deep-agents.md) | Long, multi-step agents: a plan, a sandboxed workspace, helpers, skills, and a context that stays small |
|
|
136
137
|
| [Long-term memory](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/memory.md) | Namespaced memory with semantic search, in memory or Redis |
|
|
137
138
|
| [MCP](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/mcp.md) | Borrowing tools from MCP servers, a registry of many, and serving your own |
|
|
138
139
|
| [Traces](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/tracing.md) | Run trees, queries, feedback, comparison, and alerts |
|
|
@@ -158,6 +159,7 @@ from the doc comments. The guides live in the repository, so these links go to G
|
|
|
158
159
|
| [Studio](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/studio.md) | A shared UI for traces, threads, approvals, experiments, prompts, deployments, costs, and health, as a separate package |
|
|
159
160
|
| [Agent server](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/server.md) | Self-hosted HTTP server for assistants: threads, durable runs, resumable streams, cron, a worker queue, and metrics |
|
|
160
161
|
| [Deployments](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/deployments.md) | Revisions and canaries with automatic rollback, autoscaling on Kubernetes and Helm, and per-tenant limits |
|
|
162
|
+
| [Tenancy](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/tenancy.md) | One tenant model: a tenant's view of every store, tenant graph runs, and the isolation suite |
|
|
161
163
|
| [Workflows](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/workflows.md) | Ready-made chains and domain workflows |
|
|
162
164
|
| [Command line](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/cli.md) | The `nexus` command |
|
|
163
165
|
| [Packaging and install weight](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/packaging.md) | Every entry point and what it costs |
|
|
@@ -200,7 +202,8 @@ npm run check:release
|
|
|
200
202
|
|
|
201
203
|
`check` runs formatting and lint gates, source/test/example type checks, the build, unit and mock
|
|
202
204
|
conformance tests, coverage thresholds, package import checks, and an external type-consumer test.
|
|
203
|
-
`check:release` additionally
|
|
205
|
+
`check:release` additionally holds the scheduling and runtime budgets — speed against a calibration
|
|
206
|
+
loop, and memory by retention — and verifies the dry-run tarball and a clean packed-package install.
|
|
204
207
|
|
|
205
208
|
`npm run docs:check` fails when any public export, or any public member of an exported class,
|
|
206
209
|
interface, or enum, has no doc comment, and `npm run docs:guides` fails when a guide does not name
|
|
@@ -216,8 +219,8 @@ npm run test:vectors:live
|
|
|
216
219
|
|
|
217
220
|
## Roadmap
|
|
218
221
|
|
|
219
|
-
See [ROADMAP.md](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/ROADMAP.md) for what
|
|
220
|
-
|
|
222
|
+
See [ROADMAP.md](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/ROADMAP.md) for what is
|
|
223
|
+
planned, and [CHANGELOG.md](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/CHANGELOG.md) for what has shipped. It is a design proposal, not a compatibility promise; the guarantees
|
|
221
224
|
live in [API_STABILITY.md](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/API_STABILITY.md).
|
|
222
225
|
|
|
223
226
|
Shipped so far:
|
|
@@ -246,12 +249,19 @@ Shipped so far:
|
|
|
246
249
|
every provider;
|
|
247
250
|
- 2.1 fault tolerance and crash-safe observability: checkpoints written on your terms, recovery after
|
|
248
251
|
retries, idle timeouts and a clean drain, traces that survive a crash and reach any OpenTelemetry
|
|
249
|
-
backend, one event stream, and dashboard rollups
|
|
252
|
+
backend, one event stream, and dashboard rollups;
|
|
253
|
+
- 2.2 production scale and safe upgrades: versioned database migrations, queue claims and routing
|
|
254
|
+
that cost the same at any size, a circuit breaker that counts across workers, one tenant model
|
|
255
|
+
across every store, and `nexus doctor` to check a deployment before it serves traffic;
|
|
256
|
+
- 2.3 agents that act safely, on production retrieval: capabilities and permission policies, a
|
|
257
|
+
sandbox contract, a middleware catalog, server authentication with one principal on every run,
|
|
258
|
+
keyword search in Postgres and Elasticsearch with rerankers, durable ingestion, and a deep-agent
|
|
259
|
+
preset.
|
|
250
260
|
|
|
251
261
|
Upgrading from 1.x: `npx nexus migrate src --write` moves your imports, and
|
|
252
262
|
[MIGRATING.md](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/MIGRATING.md) covers the rest.
|
|
253
|
-
Next, 2.
|
|
254
|
-
|
|
263
|
+
Next, 2.4 takes the experimental surfaces out of experimental with evidence, adds an adapter kit, and
|
|
264
|
+
speaks the agent protocols beyond MCP from a portable kernel. The [roadmap](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/ROADMAP.md) lists the
|
|
255
265
|
releases after it.
|
|
256
266
|
|
|
257
267
|
## Before Production
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ToolDefinition } from '../types/messages.js';
|
|
2
|
+
/**
|
|
3
|
+
* Capabilities: what a tool does to the world, written as strings a policy can decide on.
|
|
4
|
+
*
|
|
5
|
+
* | Capability | Means |
|
|
6
|
+
* | --- | --- |
|
|
7
|
+
* | `filesystem:read`, `filesystem:read:<path>` | Reads files, or one path |
|
|
8
|
+
* | `filesystem:write`, `filesystem:write:<path>` | Writes, creates, or deletes files |
|
|
9
|
+
* | `network`, `network:<host or URL>` | Opens a network connection, to a host when given |
|
|
10
|
+
* | `shell`, `shell:<command line>` | Runs a shell command |
|
|
11
|
+
* | `code` | Runs code it was given, as an interpreter does |
|
|
12
|
+
* | `<name>`, `<name>:<detail>` | Anything the application names, such as `payments:refund` |
|
|
13
|
+
*
|
|
14
|
+
* A tool that declares `capabilities: []` does nothing to the world; one that declares none at all
|
|
15
|
+
* is undeclared, and a policy decides on it as such.
|
|
16
|
+
*/
|
|
17
|
+
/** One capability, split into its parts. */
|
|
18
|
+
export interface ParsedCapability {
|
|
19
|
+
/** `filesystem`, `network`, `shell`, `code`, or the application's own name. */
|
|
20
|
+
kind: string;
|
|
21
|
+
/** `read` or `write`, for the filesystem. */
|
|
22
|
+
access?: 'read' | 'write';
|
|
23
|
+
/** The path, host, command, or detail, when the capability names one. */
|
|
24
|
+
target?: string;
|
|
25
|
+
}
|
|
26
|
+
/** Splits a capability string into its kind, access, and target. */
|
|
27
|
+
export declare function parseCapability(capability: string): ParsedCapability;
|
|
28
|
+
/**
|
|
29
|
+
* The capabilities one call of a tool declares: its static list, or what its function computes from
|
|
30
|
+
* the call's arguments. `undefined` means undeclared — no list, or a function that threw — which is
|
|
31
|
+
* not the same as `[]`, a tool that declares it does nothing to the world.
|
|
32
|
+
*/
|
|
33
|
+
export declare function capabilitiesOf(tool: Pick<ToolDefinition, 'capabilities'> | undefined, args: Record<string, unknown>): string[] | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Whether a capability is sensitive: anything but reading files. A pure tool declares
|
|
36
|
+
* `capabilities: []`; whatever it does declare, a write, a command, code, the network, or an
|
|
37
|
+
* effect of the application's own such as `payments`, changes the world or leaves the process.
|
|
38
|
+
*/
|
|
39
|
+
export declare function isSensitiveCapability(capability: string): boolean;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export function parseCapability(capability) {
|
|
2
|
+
const text = capability.trim();
|
|
3
|
+
const colon = text.indexOf(':');
|
|
4
|
+
const kind = (colon < 0 ? text : text.slice(0, colon)).toLowerCase();
|
|
5
|
+
const rest = colon < 0 ? undefined : text.slice(colon + 1);
|
|
6
|
+
if (kind === 'filesystem') {
|
|
7
|
+
if (!rest)
|
|
8
|
+
return { kind };
|
|
9
|
+
const [access, ...path] = rest.split(':');
|
|
10
|
+
const parsed = { kind };
|
|
11
|
+
if (access === 'read' || access === 'write')
|
|
12
|
+
parsed.access = access;
|
|
13
|
+
const target = parsed.access ? path.join(':') : rest;
|
|
14
|
+
if (target)
|
|
15
|
+
parsed.target = target;
|
|
16
|
+
return parsed;
|
|
17
|
+
}
|
|
18
|
+
return rest === undefined || rest === '' ? { kind } : { kind, target: rest };
|
|
19
|
+
}
|
|
20
|
+
export function capabilitiesOf(tool, args) {
|
|
21
|
+
const declared = tool?.capabilities;
|
|
22
|
+
if (!declared)
|
|
23
|
+
return undefined;
|
|
24
|
+
if (typeof declared !== 'function')
|
|
25
|
+
return [...declared];
|
|
26
|
+
try {
|
|
27
|
+
return [...declared(args)];
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export function isSensitiveCapability(capability) {
|
|
34
|
+
const parsed = parseCapability(capability);
|
|
35
|
+
return !(parsed.kind === 'filesystem' && parsed.access === 'read');
|
|
36
|
+
}
|