nexus-ai-pro 2.2.0 → 2.4.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 +225 -0
- package/CHANGELOG.md +325 -1
- package/README.md +20 -6
- package/SECURITY.md +140 -0
- package/dist/adapter-kit/contracts.d.ts +87 -0
- package/dist/adapter-kit/contracts.js +237 -0
- package/dist/adapter-kit/errors.d.ts +39 -0
- package/dist/adapter-kit/errors.js +52 -0
- package/dist/adapter-kit/index.d.ts +144 -0
- package/dist/adapter-kit/index.js +178 -0
- package/dist/adapter-kit/semver.d.ts +12 -0
- package/dist/adapter-kit/semver.js +55 -0
- 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 +142 -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/core/secure-stream.js +4 -3
- package/dist/deep-agent/index.d.ts +109 -0
- package/dist/deep-agent/index.js +216 -0
- package/dist/embeddings/adapters.js +2 -1
- package/dist/evals/judge.js +2 -5
- package/dist/evaluate/cache.d.ts +0 -14
- package/dist/evaluate/cache.js +0 -30
- package/dist/evaluate/file-cache.d.ts +15 -0
- package/dist/evaluate/file-cache.js +30 -0
- package/dist/evaluate/index.d.ts +2 -1
- package/dist/evaluate/index.js +2 -1
- package/dist/evaluate/review.js +2 -2
- package/dist/evaluate/run.js +2 -2
- package/dist/evaluate/version.js +3 -3
- package/dist/graph/functional.d.ts +9 -0
- package/dist/graph/functional.js +20 -3
- package/dist/graph/graph.js +27 -6
- package/dist/graph/lint.d.ts +4 -1
- package/dist/graph/lint.js +35 -0
- package/dist/graph/node-cache.js +3 -3
- package/dist/hallucination/rag.d.ts +4 -1
- package/dist/hallucination/rag.js +6 -1
- package/dist/images/asset-stores.js +2 -3
- package/dist/images/asset-support.js +2 -2
- package/dist/images/assets.js +1 -2
- package/dist/images/evals.js +4 -4
- package/dist/insights/proposals.js +1 -2
- package/dist/insights/regressions.d.ts +26 -2
- package/dist/insights/regressions.js +129 -3
- package/dist/loaders/git.js +8 -1
- package/dist/loaders/web.js +7 -1
- package/dist/mcp/client.d.ts +14 -0
- package/dist/mcp/client.js +59 -1
- package/dist/mcp/registry.d.ts +6 -0
- package/dist/mcp/registry.js +7 -0
- package/dist/postgres/fulltext.d.ts +67 -0
- package/dist/postgres/fulltext.js +91 -0
- package/dist/prompts/file.js +28 -11
- package/dist/protocols/a2a.d.ts +235 -0
- package/dist/protocols/a2a.js +386 -0
- package/dist/protocols/acp.d.ts +87 -0
- package/dist/protocols/acp.js +322 -0
- package/dist/protocols/ag-ui.d.ts +120 -0
- package/dist/protocols/ag-ui.js +180 -0
- package/dist/protocols/shared.d.ts +80 -0
- package/dist/protocols/shared.js +49 -0
- package/dist/providers/anthropic.js +1 -0
- package/dist/providers/cohere.js +2 -2
- package/dist/providers/google.js +2 -11
- package/dist/providers/openai.js +1 -0
- package/dist/rag/elasticsearch.d.ts +71 -0
- package/dist/rag/elasticsearch.js +130 -0
- package/dist/rag/file-ingestion.js +15 -9
- 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/runtime/detect.d.ts +17 -0
- package/dist/runtime/detect.js +16 -0
- package/dist/runtime/index.d.ts +19 -0
- package/dist/runtime/index.js +7 -0
- package/dist/security/injection-detector.d.ts +2 -0
- package/dist/security/injection-detector.js +7 -1
- package/dist/security/input-guard.js +5 -2
- package/dist/security/output-guard.js +8 -4
- package/dist/security/pii-detector.js +22 -6
- package/dist/security/prompt-hardening.js +6 -2
- package/dist/security/semantic-injection-classifier.d.ts +2 -1
- package/dist/security/semantic-injection-classifier.js +31 -35
- package/dist/security/upload-scanner.d.ts +8 -0
- package/dist/security/upload-scanner.js +51 -9
- package/dist/server/assistant.d.ts +5 -1
- package/dist/server/assistant.js +4 -2
- package/dist/server/auth.d.ts +250 -0
- package/dist/server/auth.js +392 -0
- package/dist/server/deployments.d.ts +63 -1
- package/dist/server/deployments.js +75 -2
- package/dist/server/runs.d.ts +9 -0
- package/dist/server/runs.js +20 -0
- package/dist/server/server.js +5 -0
- package/dist/store/memory.d.ts +10 -0
- package/dist/store/memory.js +10 -0
- package/dist/testing/record.js +2 -2
- package/dist/tracing/stores.js +2 -1
- package/dist/tracing/tracer.js +2 -2
- package/dist/types/config.d.ts +20 -0
- package/dist/types/graph.d.ts +38 -0
- package/dist/types/messages.d.ts +36 -2
- package/dist/types/principal.d.ts +21 -0
- package/dist/types/principal.js +1 -0
- package/dist/types/server.d.ts +8 -9
- package/dist/utils/base64.d.ts +4 -0
- package/dist/utils/base64.js +21 -0
- package/dist/utils/checksums.d.ts +22 -0
- package/dist/utils/checksums.js +39 -0
- package/dist/utils/ids.d.ts +8 -0
- package/dist/utils/ids.js +26 -2
- package/dist/utils/sha256.d.ts +22 -0
- package/dist/utils/sha256.js +120 -0
- package/dist/utils/tenant.d.ts +11 -0
- package/dist/utils/tenant.js +14 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist-cjs/adapter-kit/contracts.d.ts +87 -0
- package/dist-cjs/adapter-kit/contracts.js +243 -0
- package/dist-cjs/adapter-kit/errors.d.ts +39 -0
- package/dist-cjs/adapter-kit/errors.js +57 -0
- package/dist-cjs/adapter-kit/index.d.ts +144 -0
- package/dist-cjs/adapter-kit/index.js +194 -0
- package/dist-cjs/adapter-kit/semver.d.ts +12 -0
- package/dist-cjs/adapter-kit/semver.js +59 -0
- 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 +147 -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/core/secure-stream.js +4 -3
- package/dist-cjs/deep-agent/index.d.ts +109 -0
- package/dist-cjs/deep-agent/index.js +219 -0
- package/dist-cjs/embeddings/adapters.js +2 -1
- package/dist-cjs/evals/judge.js +2 -5
- package/dist-cjs/evaluate/cache.d.ts +0 -14
- package/dist-cjs/evaluate/cache.js +1 -65
- package/dist-cjs/evaluate/file-cache.d.ts +15 -0
- package/dist-cjs/evaluate/file-cache.js +67 -0
- package/dist-cjs/evaluate/index.d.ts +2 -1
- package/dist-cjs/evaluate/index.js +3 -2
- package/dist-cjs/evaluate/review.js +2 -2
- package/dist-cjs/evaluate/run.js +2 -2
- package/dist-cjs/evaluate/version.js +3 -3
- package/dist-cjs/graph/functional.d.ts +9 -0
- package/dist-cjs/graph/functional.js +20 -3
- package/dist-cjs/graph/graph.js +27 -6
- package/dist-cjs/graph/lint.d.ts +4 -1
- package/dist-cjs/graph/lint.js +35 -0
- package/dist-cjs/graph/node-cache.js +3 -3
- package/dist-cjs/hallucination/rag.d.ts +4 -1
- package/dist-cjs/hallucination/rag.js +6 -1
- package/dist-cjs/images/asset-stores.js +2 -3
- package/dist-cjs/images/asset-support.js +2 -2
- package/dist-cjs/images/assets.js +1 -2
- package/dist-cjs/images/evals.js +4 -4
- package/dist-cjs/insights/proposals.js +1 -2
- package/dist-cjs/insights/regressions.d.ts +26 -2
- package/dist-cjs/insights/regressions.js +129 -3
- package/dist-cjs/loaders/git.js +8 -1
- package/dist-cjs/loaders/web.js +7 -1
- package/dist-cjs/mcp/client.d.ts +14 -0
- package/dist-cjs/mcp/client.js +60 -1
- package/dist-cjs/mcp/registry.d.ts +6 -0
- package/dist-cjs/mcp/registry.js +7 -0
- package/dist-cjs/postgres/fulltext.d.ts +67 -0
- package/dist-cjs/postgres/fulltext.js +129 -0
- package/dist-cjs/prompts/file.js +28 -11
- package/dist-cjs/protocols/a2a.d.ts +235 -0
- package/dist-cjs/protocols/a2a.js +393 -0
- package/dist-cjs/protocols/acp.d.ts +87 -0
- package/dist-cjs/protocols/acp.js +326 -0
- package/dist-cjs/protocols/ag-ui.d.ts +120 -0
- package/dist-cjs/protocols/ag-ui.js +186 -0
- package/dist-cjs/protocols/shared.d.ts +80 -0
- package/dist-cjs/protocols/shared.js +59 -0
- package/dist-cjs/providers/anthropic.js +1 -0
- package/dist-cjs/providers/cohere.js +2 -2
- package/dist-cjs/providers/google.js +3 -12
- package/dist-cjs/providers/openai.js +1 -0
- package/dist-cjs/rag/elasticsearch.d.ts +71 -0
- package/dist-cjs/rag/elasticsearch.js +135 -0
- package/dist-cjs/rag/file-ingestion.js +14 -8
- 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/runtime/detect.d.ts +17 -0
- package/dist-cjs/runtime/detect.js +19 -0
- package/dist-cjs/runtime/index.d.ts +19 -0
- package/dist-cjs/runtime/index.js +31 -0
- package/dist-cjs/security/injection-detector.d.ts +2 -0
- package/dist-cjs/security/injection-detector.js +7 -1
- package/dist-cjs/security/input-guard.js +5 -2
- package/dist-cjs/security/output-guard.js +8 -4
- package/dist-cjs/security/pii-detector.js +22 -6
- package/dist-cjs/security/prompt-hardening.js +6 -2
- package/dist-cjs/security/semantic-injection-classifier.d.ts +2 -1
- package/dist-cjs/security/semantic-injection-classifier.js +31 -35
- package/dist-cjs/security/upload-scanner.d.ts +8 -0
- package/dist-cjs/security/upload-scanner.js +53 -9
- package/dist-cjs/server/assistant.d.ts +5 -1
- package/dist-cjs/server/assistant.js +4 -2
- package/dist-cjs/server/auth.d.ts +250 -0
- package/dist-cjs/server/auth.js +402 -0
- package/dist-cjs/server/deployments.d.ts +63 -1
- package/dist-cjs/server/deployments.js +75 -2
- package/dist-cjs/server/runs.d.ts +9 -0
- package/dist-cjs/server/runs.js +20 -0
- package/dist-cjs/server/server.js +5 -0
- package/dist-cjs/store/memory.d.ts +10 -0
- package/dist-cjs/store/memory.js +10 -0
- package/dist-cjs/testing/record.js +2 -2
- package/dist-cjs/tracing/stores.js +2 -1
- package/dist-cjs/tracing/tracer.js +2 -2
- package/dist-cjs/types/config.d.ts +20 -0
- package/dist-cjs/types/graph.d.ts +38 -0
- package/dist-cjs/types/messages.d.ts +36 -2
- package/dist-cjs/types/principal.d.ts +21 -0
- package/dist-cjs/types/principal.js +2 -0
- package/dist-cjs/types/server.d.ts +8 -9
- package/dist-cjs/utils/base64.d.ts +4 -0
- package/dist-cjs/utils/base64.js +25 -0
- package/dist-cjs/utils/checksums.d.ts +22 -0
- package/dist-cjs/utils/checksums.js +46 -0
- package/dist-cjs/utils/ids.d.ts +8 -0
- package/dist-cjs/utils/ids.js +28 -2
- package/dist-cjs/utils/sha256.d.ts +22 -0
- package/dist-cjs/utils/sha256.js +125 -0
- package/dist-cjs/utils/tenant.d.ts +11 -0
- package/dist-cjs/utils/tenant.js +15 -0
- package/dist-cjs/version.d.ts +1 -1
- package/dist-cjs/version.js +1 -1
- package/llms.txt +7 -3
- package/package.json +193 -6
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Regression, type RegressionMetric, type RunSample } from '../insights/regressions.js';
|
|
2
|
+
import type { EvaluationScore, Evaluator } from '../types/evaluate.js';
|
|
2
3
|
import type { DeploymentChange, DeploymentChangeRecord, DeploymentRecord, ReplicaReport, RevisionChoice, RevisionRequest, ServerAssistant, ServerDeployments, ServerStateStore } from '../types/server.js';
|
|
3
4
|
export type { DeploymentChange, DeploymentChangeRecord, DeploymentRecord, ReplicaReport, RevisionChoice, RevisionReason, RevisionRequest, RunRevision, } from '../types/server.js';
|
|
4
5
|
/** Options for `Deployments`. */
|
|
@@ -58,6 +59,30 @@ export interface RevisionStats {
|
|
|
58
59
|
/** Mean recorded cost of finished runs, in US dollars. */
|
|
59
60
|
meanCost?: number;
|
|
60
61
|
}
|
|
62
|
+
/** Options for `Deployments.evaluate()`. */
|
|
63
|
+
export interface RunEvaluationOptions {
|
|
64
|
+
/** What each run is scored by: evaluators from `nexus-ai-pro/evaluate`, such as an LLM judge. */
|
|
65
|
+
evaluators: ReadonlyArray<Evaluator>;
|
|
66
|
+
/** Only runs created from this time, such as the start of a canary. */
|
|
67
|
+
since?: string;
|
|
68
|
+
/** Only this revision's runs. Defaults to every revision's. */
|
|
69
|
+
revision?: string;
|
|
70
|
+
/** The share of runs scored, from 0 to 1, chosen by run id so every replica picks the same ones. Defaults to 1. */
|
|
71
|
+
sampleRate?: number;
|
|
72
|
+
/** How many recent runs are read. Defaults to 2,000. */
|
|
73
|
+
limit?: number;
|
|
74
|
+
/** Recorded as each score's source; a run already scored by this source is skipped. Defaults to `online-evaluation`. */
|
|
75
|
+
source?: string;
|
|
76
|
+
}
|
|
77
|
+
/** What `Deployments.evaluate()` did. */
|
|
78
|
+
export interface RunEvaluationReport {
|
|
79
|
+
/** Runs scored. */
|
|
80
|
+
evaluated: number;
|
|
81
|
+
/** Runs passed over because this source had already scored them. */
|
|
82
|
+
skipped: number;
|
|
83
|
+
/** Every score given. */
|
|
84
|
+
scores: EvaluationScore[];
|
|
85
|
+
}
|
|
61
86
|
/**
|
|
62
87
|
* Revisions, traffic splits, and replica health for the agent server, recorded in a shared store.
|
|
63
88
|
*
|
|
@@ -75,6 +100,8 @@ export interface RevisionStats {
|
|
|
75
100
|
export declare class Deployments implements ServerDeployments {
|
|
76
101
|
private readonly options;
|
|
77
102
|
private readonly state;
|
|
103
|
+
/** The change in progress per deployment, which the next one waits for. */
|
|
104
|
+
private readonly changing;
|
|
78
105
|
private readonly now;
|
|
79
106
|
private readonly registrations;
|
|
80
107
|
private readonly cache;
|
|
@@ -108,10 +135,16 @@ export declare class Deployments implements ServerDeployments {
|
|
|
108
135
|
* `expectedVersion` applies a change only to the version it was decided on, and throws
|
|
109
136
|
* `DEPLOYMENT_CONFLICT` otherwise, so two people — or a person and a canary guard — cannot undo each
|
|
110
137
|
* other without noticing.
|
|
138
|
+
*
|
|
139
|
+
* Changes to one deployment through this object apply one at a time, so two made at once on one
|
|
140
|
+
* replica both land, in order. The state store has no atomic compare-and-set, so two replicas
|
|
141
|
+
* changing one deployment in the same instant can still lose one change: make changes from one
|
|
142
|
+
* place, or pass `expectedVersion` and retry a conflict.
|
|
111
143
|
*/
|
|
112
144
|
change(assistant: string, change: DeploymentChange & {
|
|
113
145
|
expectedVersion?: number;
|
|
114
146
|
}, by?: string): Promise<DeploymentRecord>;
|
|
147
|
+
private applyChange;
|
|
115
148
|
/** Sets each revision's share of new runs. */
|
|
116
149
|
split(assistant: string, traffic: Record<string, number>, options?: {
|
|
117
150
|
by?: string;
|
|
@@ -159,6 +192,17 @@ export declare class Deployments implements ServerDeployments {
|
|
|
159
192
|
* expired run is an error, a cancelled one is left out.
|
|
160
193
|
*/
|
|
161
194
|
samples(assistant: string, revision: string, since?: string, limit?: number): Promise<RunSample[]>;
|
|
195
|
+
/**
|
|
196
|
+
* Online evaluation of the server's own runs: scores each finished run's output with evaluators
|
|
197
|
+
* from `nexus-ai-pro/evaluate`, and records the scores as the run's feedback. A canary guard given
|
|
198
|
+
* those keys in `feedback` then compares quality between revisions, beside errors, latency, and
|
|
199
|
+
* cost.
|
|
200
|
+
*
|
|
201
|
+
* A run is scored once per `source`, so calling this on a schedule never counts a run twice.
|
|
202
|
+
* Sampling is stable: the same run is always in or out of a sample, on every replica. Evaluators
|
|
203
|
+
* judge a run by its output, since a run record does not keep its input.
|
|
204
|
+
*/
|
|
205
|
+
evaluate(assistant: string, options: RunEvaluationOptions): Promise<RunEvaluationReport>;
|
|
162
206
|
/** The deployment the router uses, reusing a recent read. */
|
|
163
207
|
private current;
|
|
164
208
|
/** The deployment of a registered assistant before anything is recorded: its live revision, all traffic. */
|
|
@@ -201,8 +245,26 @@ export interface CanaryGuardOptions {
|
|
|
201
245
|
revision: string;
|
|
202
246
|
since: string;
|
|
203
247
|
}) => Promise<RunSample[]>;
|
|
204
|
-
/**
|
|
248
|
+
/**
|
|
249
|
+
* Feedback keys whose mean score is compared: the scores `Deployments.evaluate()` records from
|
|
250
|
+
* online evaluation, or any a person left through the feedback route. A canary that is worse on one
|
|
251
|
+
* is rolled back like one that fails more.
|
|
252
|
+
*/
|
|
205
253
|
feedback?: readonly string[];
|
|
254
|
+
/**
|
|
255
|
+
* Judges each metric as an evaluation comparison does, at this confidence, such as 0.95. A bootstrap
|
|
256
|
+
* interval must not reach zero, and the change must be at least the metric's minimum effect:
|
|
257
|
+
* `minErrorRateIncrease`, `latencyIncrease` with `minLatencyChangeMs`, `costIncrease`, and
|
|
258
|
+
* `minFeedbackDrop`. A real regression rolls back, and noise or a trivial change does not. Without
|
|
259
|
+
* it, the error rate uses a z-test at 95%, and latency and cost use their margins alone.
|
|
260
|
+
*/
|
|
261
|
+
confidence?: number;
|
|
262
|
+
/** The smallest rise in the error rate, absolute, that counts under `confidence`. Defaults to 0.02. */
|
|
263
|
+
minErrorRateIncrease?: number;
|
|
264
|
+
/** The smallest fall in a feedback score's mean, absolute, that counts under `confidence`. Defaults to 0.05. */
|
|
265
|
+
minFeedbackDrop?: number;
|
|
266
|
+
/** Bootstrap resamples under `confidence`. Defaults to 1,000. */
|
|
267
|
+
resamples?: number;
|
|
206
268
|
/** Recorded as who made a change. Defaults to `guard`. */
|
|
207
269
|
by?: string;
|
|
208
270
|
/** Hears every decision, including holds. */
|
|
@@ -7,6 +7,7 @@ const EPSILON = 1e-9;
|
|
|
7
7
|
export class Deployments {
|
|
8
8
|
options;
|
|
9
9
|
state;
|
|
10
|
+
changing = new Map();
|
|
10
11
|
now;
|
|
11
12
|
registrations = new Map();
|
|
12
13
|
cache = new Map();
|
|
@@ -81,6 +82,18 @@ export class Deployments {
|
|
|
81
82
|
return (await this.get(assistant))?.history ?? [];
|
|
82
83
|
}
|
|
83
84
|
async change(assistant, change, by) {
|
|
85
|
+
const previous = this.changing.get(assistant) ?? Promise.resolve();
|
|
86
|
+
const next = previous.catch(() => undefined).then(() => this.applyChange(assistant, change, by));
|
|
87
|
+
this.changing.set(assistant, next);
|
|
88
|
+
try {
|
|
89
|
+
return await next;
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
if (this.changing.get(assistant) === next)
|
|
93
|
+
this.changing.delete(assistant);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
async applyChange(assistant, change, by) {
|
|
84
97
|
const current = await this.get(assistant);
|
|
85
98
|
if (!current) {
|
|
86
99
|
throw new BadRequestError(`Assistant "${assistant}" has no deployment yet: serve it through Deployments.assistant() first`, 'UNKNOWN_DEPLOYMENT');
|
|
@@ -228,15 +241,67 @@ export class Deployments {
|
|
|
228
241
|
return (await this.runs(assistant, { since, limit }))
|
|
229
242
|
.filter((run) => (run.revision?.id ?? '') === revision)
|
|
230
243
|
.flatMap((run) => {
|
|
244
|
+
const feedback = run.feedback?.length ? { feedback: run.feedback } : {};
|
|
231
245
|
if (run.status === 'failed' || run.status === 'expired') {
|
|
232
|
-
return [{ status: 'error', latencyMs: run.durationMs, cost: run.cost }];
|
|
246
|
+
return [{ status: 'error', latencyMs: run.durationMs, cost: run.cost, ...feedback }];
|
|
233
247
|
}
|
|
234
248
|
if (run.status === 'succeeded' || run.status === 'awaiting_input') {
|
|
235
|
-
return [{ status: 'success', latencyMs: run.durationMs, cost: run.cost }];
|
|
249
|
+
return [{ status: 'success', latencyMs: run.durationMs, cost: run.cost, ...feedback }];
|
|
236
250
|
}
|
|
237
251
|
return [];
|
|
238
252
|
});
|
|
239
253
|
}
|
|
254
|
+
async evaluate(assistant, options) {
|
|
255
|
+
const source = options.source ?? 'online-evaluation';
|
|
256
|
+
const rate = options.sampleRate ?? 1;
|
|
257
|
+
const report = { evaluated: 0, skipped: 0, scores: [] };
|
|
258
|
+
for (const run of await this.runs(assistant, options)) {
|
|
259
|
+
if (run.status !== 'succeeded')
|
|
260
|
+
continue;
|
|
261
|
+
if (options.revision !== undefined && (run.revision?.id ?? '') !== options.revision)
|
|
262
|
+
continue;
|
|
263
|
+
if (rate < 1 && bucket(`evaluate:${run.id}`) >= rate)
|
|
264
|
+
continue;
|
|
265
|
+
if (run.feedback?.some((item) => item.source === source)) {
|
|
266
|
+
report.skipped += 1;
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
const scores = [];
|
|
270
|
+
for (const evaluator of options.evaluators) {
|
|
271
|
+
const value = await evaluator({
|
|
272
|
+
example: { id: run.id, inputs: undefined, ...(run.metadata ? { metadata: run.metadata } : {}) },
|
|
273
|
+
output: run.output,
|
|
274
|
+
latencyMs: run.durationMs ?? 0,
|
|
275
|
+
...(run.cost === undefined ? {} : { cost: run.cost }),
|
|
276
|
+
run: 0,
|
|
277
|
+
});
|
|
278
|
+
if (typeof value === 'number')
|
|
279
|
+
scores.push({ key: 'score', score: value });
|
|
280
|
+
else if (typeof value === 'boolean')
|
|
281
|
+
scores.push({ key: 'score', score: value ? 1 : 0, passed: value });
|
|
282
|
+
else
|
|
283
|
+
scores.push(...(Array.isArray(value) ? value : [value]));
|
|
284
|
+
}
|
|
285
|
+
const at = new Date().toISOString();
|
|
286
|
+
const latest = (await this.state.get(RUNS_NAMESPACE, run.id)) ?? run;
|
|
287
|
+
await this.state.put(RUNS_NAMESPACE, run.id, {
|
|
288
|
+
...latest,
|
|
289
|
+
feedback: [
|
|
290
|
+
...(latest.feedback ?? []),
|
|
291
|
+
...scores.map((score) => ({
|
|
292
|
+
key: score.key,
|
|
293
|
+
score: score.score,
|
|
294
|
+
...(score.comment ? { comment: score.comment } : {}),
|
|
295
|
+
source,
|
|
296
|
+
createdAt: at,
|
|
297
|
+
})),
|
|
298
|
+
].slice(-100),
|
|
299
|
+
});
|
|
300
|
+
report.evaluated += 1;
|
|
301
|
+
report.scores.push(...scores);
|
|
302
|
+
}
|
|
303
|
+
return report;
|
|
304
|
+
}
|
|
240
305
|
async current(assistant) {
|
|
241
306
|
const cached = this.cache.get(assistant);
|
|
242
307
|
if (cached && Date.now() - cached.at < (this.options.cacheMs ?? 2_000))
|
|
@@ -305,6 +370,14 @@ export function watchCanaries(options) {
|
|
|
305
370
|
latencyIncrease: options.latencyIncrease,
|
|
306
371
|
minLatencyChangeMs: options.minLatencyChangeMs ?? 50,
|
|
307
372
|
costIncrease: options.costIncrease,
|
|
373
|
+
...(options.confidence === undefined
|
|
374
|
+
? {}
|
|
375
|
+
: {
|
|
376
|
+
confidence: options.confidence,
|
|
377
|
+
minErrorRateIncrease: options.minErrorRateIncrease,
|
|
378
|
+
minFeedbackDrop: options.minFeedbackDrop,
|
|
379
|
+
resamples: options.resamples,
|
|
380
|
+
}),
|
|
308
381
|
});
|
|
309
382
|
if (regressions.length > 0) {
|
|
310
383
|
await deployments.change(deployment.assistant, {
|
package/dist/server/runs.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { OperationRunnerConfig } from '../types/operations.js';
|
|
2
|
+
import type { RunFeedback } from '../types/tracing.js';
|
|
2
3
|
import type { Principal, ReplicaReport, RunEventLog, RunRecord, ScalingSnapshot, ServerAssistant, ServerStateStore, TenantGate, ThreadBusyPolicy, ThreadRecord } from '../types/server.js';
|
|
3
4
|
import { ServerMetrics } from './metrics.js';
|
|
4
5
|
/** What a run needs to start. */
|
|
@@ -161,6 +162,14 @@ export declare class RunManager {
|
|
|
161
162
|
start(options: StartRunOptions): Promise<RunRecord>;
|
|
162
163
|
/** The rest of `start()`, once the thread, if any, is this run's. */
|
|
163
164
|
private startClaimed;
|
|
165
|
+
/**
|
|
166
|
+
* Leaves feedback on a run: a person's rating, or an online evaluator's score. A canary guard
|
|
167
|
+
* compares it between revisions as their quality. Another tenant's run is not found, and a run
|
|
168
|
+
* keeps its latest 100 pieces of feedback.
|
|
169
|
+
*/
|
|
170
|
+
addFeedback(runId: string, feedback: Omit<RunFeedback, 'createdAt'> & {
|
|
171
|
+
createdAt?: string;
|
|
172
|
+
}, principal?: Principal): Promise<RunRecord>;
|
|
164
173
|
/** Cancels a run, including one another replica is executing. */
|
|
165
174
|
cancel(runId: string, principal?: Principal, reason?: string): Promise<RunRecord>;
|
|
166
175
|
/**
|
package/dist/server/runs.js
CHANGED
|
@@ -177,6 +177,26 @@ export class RunManager {
|
|
|
177
177
|
throw error;
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
|
+
async addFeedback(runId, feedback, principal) {
|
|
181
|
+
const run = await this.run(runId, principal);
|
|
182
|
+
if (typeof feedback.key !== 'string' || !feedback.key.trim())
|
|
183
|
+
throw new BadRequestError('Feedback needs a key');
|
|
184
|
+
if (feedback.score !== undefined && !(typeof feedback.score === 'number' && Number.isFinite(feedback.score))) {
|
|
185
|
+
throw new BadRequestError('A feedback score is a finite number');
|
|
186
|
+
}
|
|
187
|
+
const at = this.now().toISOString();
|
|
188
|
+
const entry = {
|
|
189
|
+
key: feedback.key,
|
|
190
|
+
...(feedback.score === undefined ? {} : { score: feedback.score }),
|
|
191
|
+
...(feedback.value === undefined ? {} : { value: feedback.value }),
|
|
192
|
+
...(typeof feedback.comment === 'string' ? { comment: feedback.comment } : {}),
|
|
193
|
+
...(typeof feedback.source === 'string' ? { source: feedback.source } : {}),
|
|
194
|
+
createdAt: feedback.createdAt ?? at,
|
|
195
|
+
};
|
|
196
|
+
const next = { ...run, feedback: [...(run.feedback ?? []), entry].slice(-100), updatedAt: at };
|
|
197
|
+
await this.state.put(RUNS, runId, next);
|
|
198
|
+
return next;
|
|
199
|
+
}
|
|
180
200
|
async cancel(runId, principal, reason) {
|
|
181
201
|
const run = await this.run(runId, principal);
|
|
182
202
|
this.local.get(runId)?.cancel(reason);
|
package/dist/server/server.js
CHANGED
|
@@ -137,6 +137,11 @@ export function createAgentServer(options) {
|
|
|
137
137
|
const body = await readJson(request);
|
|
138
138
|
return json(await runs.cancel(params.runId, principal, body.reason));
|
|
139
139
|
});
|
|
140
|
+
write('POST', '/runs/:runId/feedback', async ({ request, params, principal }) => {
|
|
141
|
+
const body = await readJson(request);
|
|
142
|
+
const run = await runs.addFeedback(params.runId, { ...body, source: body.source ?? principal?.userId ?? 'api' }, principal);
|
|
143
|
+
return json({ runId: run.id, feedback: run.feedback?.at(-1) }, 201);
|
|
144
|
+
});
|
|
140
145
|
read('GET', '/runs/:runId/events', async ({ request, params, principal, url }) => {
|
|
141
146
|
await runs.run(params.runId, principal);
|
|
142
147
|
const header = request.headers.get('last-event-id') ?? url.searchParams.get('lastEventId');
|
package/dist/store/memory.d.ts
CHANGED
|
@@ -20,6 +20,10 @@ export declare class MemoryStore implements Store {
|
|
|
20
20
|
private readonly options;
|
|
21
21
|
private readonly items;
|
|
22
22
|
private readonly maxItems;
|
|
23
|
+
/** Whether any item was ever given a time to live; until one is, there is nothing to sweep. */
|
|
24
|
+
private expiring;
|
|
25
|
+
/** When expired items were last swept, in milliseconds. */
|
|
26
|
+
private sweptAt;
|
|
23
27
|
private readonly now;
|
|
24
28
|
constructor(options?: MemoryStoreOptions);
|
|
25
29
|
/** Stores an item, keeping its original `createdAt` when it replaces one. */
|
|
@@ -42,5 +46,11 @@ export declare class MemoryStore implements Store {
|
|
|
42
46
|
size(): number;
|
|
43
47
|
private embed;
|
|
44
48
|
private expired;
|
|
49
|
+
/**
|
|
50
|
+
* Drops expired items. Reads already skip them, so this only reclaims memory: it runs once any item
|
|
51
|
+
* has a time to live, and at most once a second, so a write stays constant-time however many items
|
|
52
|
+
* there are. A store that is full sweeps before it evicts, so a live item never makes way for an
|
|
53
|
+
* expired one.
|
|
54
|
+
*/
|
|
45
55
|
private sweep;
|
|
46
56
|
}
|
package/dist/store/memory.js
CHANGED
|
@@ -4,6 +4,8 @@ export class MemoryStore {
|
|
|
4
4
|
options;
|
|
5
5
|
items = new Map();
|
|
6
6
|
maxItems;
|
|
7
|
+
expiring = false;
|
|
8
|
+
sweptAt = Number.NEGATIVE_INFINITY;
|
|
7
9
|
now;
|
|
8
10
|
constructor(options = {}) {
|
|
9
11
|
this.options = options;
|
|
@@ -18,6 +20,8 @@ export class MemoryStore {
|
|
|
18
20
|
const timestamp = this.now().toISOString();
|
|
19
21
|
const existing = this.items.get(id);
|
|
20
22
|
const vector = await this.embed(value, options.index);
|
|
23
|
+
if (options.ttlMs !== undefined)
|
|
24
|
+
this.expiring = true;
|
|
21
25
|
this.items.delete(id);
|
|
22
26
|
this.items.set(id, {
|
|
23
27
|
namespace: [...namespace],
|
|
@@ -99,6 +103,12 @@ export class MemoryStore {
|
|
|
99
103
|
return item.expiresAt !== undefined && Date.parse(item.expiresAt) <= this.now().getTime();
|
|
100
104
|
}
|
|
101
105
|
sweep() {
|
|
106
|
+
if (!this.expiring)
|
|
107
|
+
return;
|
|
108
|
+
const now = this.now().getTime();
|
|
109
|
+
if (now - this.sweptAt < 1_000 && this.items.size <= this.maxItems)
|
|
110
|
+
return;
|
|
111
|
+
this.sweptAt = now;
|
|
102
112
|
for (const [id, item] of this.items)
|
|
103
113
|
if (this.expired(item))
|
|
104
114
|
this.items.delete(id);
|
package/dist/testing/record.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { sha256Hex } from '../utils/sha256.js';
|
|
2
2
|
import { mkdir, readdir, readFile, writeFile } from 'node:fs/promises';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
export class FixtureMissingError extends Error {
|
|
@@ -148,7 +148,7 @@ function defaultKey(input, ignoreBodyFields = []) {
|
|
|
148
148
|
}
|
|
149
149
|
catch {
|
|
150
150
|
}
|
|
151
|
-
return
|
|
151
|
+
return sha256Hex(`${input.method}\n${input.url}\n${body}`).slice(0, 16);
|
|
152
152
|
}
|
|
153
153
|
function canonical(value) {
|
|
154
154
|
if (Array.isArray(value))
|
package/dist/tracing/stores.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { utf8Length } from '../utils/ids.js';
|
|
1
2
|
import { appendFile, mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
2
3
|
import path from 'node:path';
|
|
3
4
|
import { applyQuery, assembleTree } from './query.js';
|
|
@@ -132,7 +133,7 @@ export class JsonlTraceStore {
|
|
|
132
133
|
catch {
|
|
133
134
|
return;
|
|
134
135
|
}
|
|
135
|
-
if (
|
|
136
|
+
if (utf8Length(content) <= this.maxBytes)
|
|
136
137
|
return;
|
|
137
138
|
const lines = content.split('\n').filter(Boolean);
|
|
138
139
|
await writeFile(this.file, `${lines.slice(Math.floor(lines.length / 2)).join('\n')}\n`, 'utf8');
|
package/dist/tracing/tracer.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { randomHex } from '../utils/ids.js';
|
|
1
2
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
-
import { randomBytes } from 'node:crypto';
|
|
3
3
|
export class Tracer {
|
|
4
4
|
options;
|
|
5
5
|
context = new AsyncLocalStorage();
|
|
@@ -194,7 +194,7 @@ export class Tracer {
|
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
196
|
function id(prefix) {
|
|
197
|
-
return `${prefix}-${
|
|
197
|
+
return `${prefix}-${randomHex(8)}`;
|
|
198
198
|
}
|
|
199
199
|
export function w3cTraceId(traceId) {
|
|
200
200
|
if (/^[0-9a-f]{32}$/.test(traceId))
|
package/dist/types/config.d.ts
CHANGED
|
@@ -25,6 +25,11 @@ export interface OpenAIProviderConfig {
|
|
|
25
25
|
apiKey: string;
|
|
26
26
|
/** API base URL. Point it at an OpenAI-compatible server to use that instead. */
|
|
27
27
|
baseUrl?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Replaces the global `fetch` for every request: a platform's bound fetch on an edge runtime, a
|
|
30
|
+
* proxy, or a stub in tests.
|
|
31
|
+
*/
|
|
32
|
+
fetch?: typeof globalThis.fetch;
|
|
28
33
|
/** OpenAI organization to bill. */
|
|
29
34
|
organization?: string;
|
|
30
35
|
/** Headers added to every request. */
|
|
@@ -59,6 +64,11 @@ export interface AnthropicProviderConfig {
|
|
|
59
64
|
apiKey: string;
|
|
60
65
|
/** API base URL. */
|
|
61
66
|
baseUrl?: string;
|
|
67
|
+
/**
|
|
68
|
+
* Replaces the global `fetch` for every request: a platform's bound fetch on an edge runtime, a
|
|
69
|
+
* proxy, or a stub in tests.
|
|
70
|
+
*/
|
|
71
|
+
fetch?: typeof globalThis.fetch;
|
|
62
72
|
/** Name this provider registers under. */
|
|
63
73
|
providerName?: string;
|
|
64
74
|
/** Model-name prefixes this provider answers for. */
|
|
@@ -75,6 +85,11 @@ export interface GoogleProviderConfig {
|
|
|
75
85
|
apiKey: string;
|
|
76
86
|
/** API base URL. */
|
|
77
87
|
baseUrl?: string;
|
|
88
|
+
/**
|
|
89
|
+
* Replaces the global `fetch` for every request: a platform's bound fetch on an edge runtime, a
|
|
90
|
+
* proxy, or a stub in tests.
|
|
91
|
+
*/
|
|
92
|
+
fetch?: typeof globalThis.fetch;
|
|
78
93
|
}
|
|
79
94
|
/** Configuration for a local Ollama server. */
|
|
80
95
|
export interface OllamaProviderConfig {
|
|
@@ -101,6 +116,11 @@ export interface CohereProviderConfig {
|
|
|
101
116
|
apiKey: string;
|
|
102
117
|
/** API base URL. */
|
|
103
118
|
baseUrl?: string;
|
|
119
|
+
/**
|
|
120
|
+
* Replaces the global `fetch` for every request: a platform's bound fetch on an edge runtime, a
|
|
121
|
+
* proxy, or a stub in tests.
|
|
122
|
+
*/
|
|
123
|
+
fetch?: typeof globalThis.fetch;
|
|
104
124
|
}
|
|
105
125
|
export interface OpenRouterProviderConfig {
|
|
106
126
|
apiKey: string;
|
package/dist/types/graph.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ import type { OperationLifecycleLike } from './lifecycle.js';
|
|
|
8
8
|
* is, so a different process can pick it up.
|
|
9
9
|
*/
|
|
10
10
|
import type { CacheAdapter } from '../cache/adapters.js';
|
|
11
|
+
import type { Principal } from './principal.js';
|
|
11
12
|
import type { Store } from './store.js';
|
|
12
13
|
/** Entry sentinel. An edge from `START` names the first node. */
|
|
13
14
|
export declare const START = "__start__";
|
|
@@ -243,6 +244,14 @@ export interface NodeOptions<S extends ChannelSchema = ChannelSchema> {
|
|
|
243
244
|
* that are not.
|
|
244
245
|
*/
|
|
245
246
|
idempotent?: boolean;
|
|
247
|
+
/**
|
|
248
|
+
* What the node does to the world, as capabilities: `payments:charge`, `network:api.stripe.com`,
|
|
249
|
+
* `filesystem:write`. Declared for the linter, which reports a node with effects that also
|
|
250
|
+
* interrupts, since the node runs again from the top when the answer comes.
|
|
251
|
+
*/
|
|
252
|
+
effects?: readonly string[];
|
|
253
|
+
/** True when the node may call `context.interrupt()`. Declared for the linter. */
|
|
254
|
+
interrupts?: boolean;
|
|
246
255
|
/**
|
|
247
256
|
* Nodes this one may reach through `Send` or a `Command`. Declaring them keeps compile-time
|
|
248
257
|
* reachability checks and diagrams exact, so a node reached only that way is not reported as
|
|
@@ -374,6 +383,8 @@ export interface NodeContext<S extends ChannelSchema> {
|
|
|
374
383
|
readonly threadId: string;
|
|
375
384
|
/** The tenant the run is for, when it has one. */
|
|
376
385
|
readonly tenantId?: string;
|
|
386
|
+
/** Who the run is for, when it was started with a principal: the caller the server authenticated. */
|
|
387
|
+
readonly principal?: Readonly<Principal>;
|
|
377
388
|
/** Identifies this task. Equal to `node` unless the task came from a `Send`. */
|
|
378
389
|
readonly taskId: string;
|
|
379
390
|
/** Input carried by a `Send`. Undefined for a node reached through an ordinary edge. */
|
|
@@ -577,6 +588,14 @@ export interface GraphRunOptions {
|
|
|
577
588
|
* `tenantId` is refused before anything runs. A run without one carries on the thread's tenant.
|
|
578
589
|
*/
|
|
579
590
|
tenantId?: string;
|
|
591
|
+
/**
|
|
592
|
+
* Who the run is for, such as the caller the server authenticated. Nodes read it as
|
|
593
|
+
* `context.principal`, and an agent hands it to every tool and middleware. Its `tenantId` is the
|
|
594
|
+
* run's tenant when `tenantId` is not given, and a run whose two tenants differ is refused. Its
|
|
595
|
+
* `userId` is recorded on every checkpoint as `metadata.userId`; the rest is never stored, so a
|
|
596
|
+
* resumed run carries the principal of whoever resumed it.
|
|
597
|
+
*/
|
|
598
|
+
principal?: Principal;
|
|
580
599
|
/** Overrides the compiled `maxConcurrency` for this run. */
|
|
581
600
|
maxConcurrency?: number;
|
|
582
601
|
/** Breakpoints for this run only, replacing the compiled ones. */
|
|
@@ -853,6 +872,10 @@ export interface GraphDescription {
|
|
|
853
872
|
idempotent?: boolean;
|
|
854
873
|
/** True when the node reuses results through `cache`. */
|
|
855
874
|
cache?: boolean;
|
|
875
|
+
/** The capabilities its work uses, when it declares them. */
|
|
876
|
+
effects?: string[];
|
|
877
|
+
/** True when it declares that it may interrupt. */
|
|
878
|
+
interrupts?: boolean;
|
|
856
879
|
/** The graph this node runs, when it is a compiled graph used through `asNode()`. */
|
|
857
880
|
subgraph?: GraphDescription;
|
|
858
881
|
}>;
|
|
@@ -876,6 +899,19 @@ export interface GraphDescription {
|
|
|
876
899
|
checkpointer?: 'memory' | 'custom' | 'none';
|
|
877
900
|
/** Tasks a superstep runs at once. */
|
|
878
901
|
maxConcurrency?: number;
|
|
902
|
+
/** The tools the graph's nodes call, when it was compiled with them, as an agent is. */
|
|
903
|
+
tools?: GraphToolDescription[];
|
|
904
|
+
}
|
|
905
|
+
/** A tool a graph calls, as the linter reads it. */
|
|
906
|
+
export interface GraphToolDescription {
|
|
907
|
+
/** The tool's name. */
|
|
908
|
+
name: string;
|
|
909
|
+
/** Its capabilities, when it declares a fixed list. */
|
|
910
|
+
capabilities?: string[];
|
|
911
|
+
/** True when it computes its capabilities from each call's arguments. */
|
|
912
|
+
dynamic?: boolean;
|
|
913
|
+
/** How its calls are approved: an interrupt for each, a permission policy, or not at all. */
|
|
914
|
+
approval: 'interrupt' | 'policy' | 'none';
|
|
879
915
|
}
|
|
880
916
|
/**
|
|
881
917
|
* Options applied when a graph is compiled: stores, breakpoints, concurrency, retries, and failure
|
|
@@ -898,6 +934,8 @@ export interface CompileOptions {
|
|
|
898
934
|
maxConcurrency?: number;
|
|
899
935
|
/** Default retry policy for every node. A node's own policy wins. */
|
|
900
936
|
retry?: RetryPolicy;
|
|
937
|
+
/** The tools the graph's nodes call, for `describe()` and the linter. `createAgent()` fills it. */
|
|
938
|
+
tools?: GraphToolDescription[];
|
|
901
939
|
/**
|
|
902
940
|
* Defaults for every node: a retry policy, timeouts, and an `onError`. A node's own options win,
|
|
903
941
|
* field by field. `retry` here is the same as `compile({ retry })`, and wins over it.
|
package/dist/types/messages.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { CacheTtl, ReasoningEffort } from './providers.js';
|
|
2
2
|
import type { AssetInput } from './images.js';
|
|
3
|
+
import type { Principal } from './principal.js';
|
|
4
|
+
import type { Store } from './store.js';
|
|
3
5
|
declare global {
|
|
4
6
|
namespace NodeJS {
|
|
5
7
|
/**
|
|
@@ -128,8 +130,19 @@ export interface ToolDefinition {
|
|
|
128
130
|
description: string;
|
|
129
131
|
/** JSON Schema for the arguments. */
|
|
130
132
|
parameters: Record<string, unknown>;
|
|
131
|
-
/**
|
|
132
|
-
|
|
133
|
+
/**
|
|
134
|
+
* Runs the tool, for the agent loop and executors that call tools automatically. An agent passes
|
|
135
|
+
* a `ToolContext` too: who the run is for, its thread and tenant, its signal, and its store.
|
|
136
|
+
*/
|
|
137
|
+
execute?: (args: Record<string, unknown>, context?: ToolContext) => Promise<unknown>;
|
|
138
|
+
/**
|
|
139
|
+
* What the tool does to the world, as capabilities a permission policy decides on:
|
|
140
|
+
* `filesystem:read` or `filesystem:write` with an optional path, `network` with an optional host,
|
|
141
|
+
* `shell` with an optional command, `code`, or a name of the application's own such as `payments`.
|
|
142
|
+
* A function computes them from each call's arguments, so a policy sees the path, host, or command
|
|
143
|
+
* the call actually uses. Never sent to a model.
|
|
144
|
+
*/
|
|
145
|
+
capabilities?: readonly string[] | ((args: Record<string, unknown>) => readonly string[]);
|
|
133
146
|
/**
|
|
134
147
|
* Ends a cacheable prefix after this tool. Only honored when the request sets
|
|
135
148
|
* `cache.mode: 'explicit'` and the provider accepts caller-placed breakpoints.
|
|
@@ -145,6 +158,27 @@ export interface ToolDefinition {
|
|
|
145
158
|
export type ToolChoice = 'auto' | 'none' | 'required' | {
|
|
146
159
|
name: string;
|
|
147
160
|
};
|
|
161
|
+
/**
|
|
162
|
+
* What a tool receives besides its arguments when an agent runs it. Every field is optional: a tool
|
|
163
|
+
* run outside an agent, or by an executor given nothing, sees none of them.
|
|
164
|
+
*/
|
|
165
|
+
export interface ToolContext {
|
|
166
|
+
/** The model's id for this call. */
|
|
167
|
+
toolCallId?: string;
|
|
168
|
+
/** The thread the run belongs to. */
|
|
169
|
+
threadId?: string;
|
|
170
|
+
/** The tenant the run is for. */
|
|
171
|
+
tenantId?: string;
|
|
172
|
+
/**
|
|
173
|
+
* Who the run is for: the caller the server authenticated, with their roles and scopes, so a
|
|
174
|
+
* tool can act as that user and nobody else.
|
|
175
|
+
*/
|
|
176
|
+
principal?: Readonly<Principal>;
|
|
177
|
+
/** Aborted when the run is cancelled or the step times out. A tool that waits should stop with it. */
|
|
178
|
+
signal?: AbortSignal;
|
|
179
|
+
/** Long-term memory. In a tenant's run, the tenant's view of it. */
|
|
180
|
+
store?: Store;
|
|
181
|
+
}
|
|
148
182
|
/** What a tool returned, correlated with the call that asked for it. */
|
|
149
183
|
export interface ToolCallResult {
|
|
150
184
|
/** The id of the call this answers. */
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Who a request, a run, or a tool call is for.
|
|
3
|
+
*
|
|
4
|
+
* One shape everywhere: the server's authentication hook returns it, a run carries it, graph nodes
|
|
5
|
+
* and workflow steps read it, tools and middleware receive it, and a permission policy can decide on
|
|
6
|
+
* it. Its tenant scopes threads, runs, budgets, and the store.
|
|
7
|
+
*/
|
|
8
|
+
export interface Principal {
|
|
9
|
+
/** Isolates threads, runs, and cron jobs. Requests only ever see their own tenant's resources. */
|
|
10
|
+
tenantId?: string;
|
|
11
|
+
/** Who the caller is: a token's subject, a key's owner. Recorded on what they create. */
|
|
12
|
+
userId?: string;
|
|
13
|
+
/** What the caller may do. A route that names a scope refuses a principal without it. */
|
|
14
|
+
scopes?: readonly string[];
|
|
15
|
+
/** The caller's roles, for policies and tools that decide by role rather than by scope. */
|
|
16
|
+
roles?: readonly string[];
|
|
17
|
+
/** How the caller was authenticated: `jwt`, `api-key`, `proxy`, or a name of your own. */
|
|
18
|
+
method?: string;
|
|
19
|
+
/** The verified claims or attributes the principal was built from, for anything the fields above leave out. */
|
|
20
|
+
claims?: Readonly<Record<string, unknown>>;
|
|
21
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/types/server.d.ts
CHANGED
|
@@ -6,15 +6,9 @@
|
|
|
6
6
|
* graph thread, so state, interrupts, and history come from the checkpointer; and an assistant is
|
|
7
7
|
* anything that can stream events for an input, which a compiled graph already does.
|
|
8
8
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
tenantId?: string;
|
|
13
|
-
/** Who the caller is, recorded on what they create. */
|
|
14
|
-
userId?: string;
|
|
15
|
-
/** What the caller may do. A route that names a scope refuses a principal without it. */
|
|
16
|
-
scopes?: readonly string[];
|
|
17
|
-
}
|
|
9
|
+
import type { Principal } from './principal.js';
|
|
10
|
+
import type { RunFeedback } from './tracing.js';
|
|
11
|
+
export type { Principal };
|
|
18
12
|
/** Where a run stands, as the server reports it. */
|
|
19
13
|
export type RunStatus = 'queued' | 'running' | 'awaiting_input' | 'succeeded' | 'failed' | 'cancelled' | 'expired';
|
|
20
14
|
/** What happens when a run is requested for a thread that is already running one. */
|
|
@@ -82,6 +76,11 @@ export interface RunRecord {
|
|
|
82
76
|
worker?: string;
|
|
83
77
|
/** Its latest attempt, starting at 1. */
|
|
84
78
|
attempt?: number;
|
|
79
|
+
/**
|
|
80
|
+
* Scores left on the run by people or by online evaluation, through `POST /runs/:runId/feedback`
|
|
81
|
+
* or `Deployments.evaluate()`. A canary guard compares them between revisions as its quality signal.
|
|
82
|
+
*/
|
|
83
|
+
feedback?: RunFeedback[];
|
|
85
84
|
}
|
|
86
85
|
/** Why a run got the revision it did. */
|
|
87
86
|
export type RevisionReason = 'split' | 'thread' | 'requested';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const host = () => globalThis.Buffer;
|
|
2
|
+
export function decodeBase64(data) {
|
|
3
|
+
const buffer = host();
|
|
4
|
+
if (buffer)
|
|
5
|
+
return new Uint8Array(buffer.from(data, 'base64'));
|
|
6
|
+
const binary = atob(data);
|
|
7
|
+
const bytes = new Uint8Array(binary.length);
|
|
8
|
+
for (let index = 0; index < binary.length; index += 1)
|
|
9
|
+
bytes[index] = binary.charCodeAt(index);
|
|
10
|
+
return bytes;
|
|
11
|
+
}
|
|
12
|
+
export function encodeBase64(bytes) {
|
|
13
|
+
const buffer = host();
|
|
14
|
+
if (buffer)
|
|
15
|
+
return buffer.from(bytes).toString('base64');
|
|
16
|
+
let binary = '';
|
|
17
|
+
for (let index = 0; index < bytes.length; index += 0x8000) {
|
|
18
|
+
binary += String.fromCharCode(...bytes.subarray(index, index + 0x8000));
|
|
19
|
+
}
|
|
20
|
+
return btoa(binary);
|
|
21
|
+
}
|