@stigg/agent-sdk-js 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1296 -2
- package/dist/bindings/client/core/registry.d.ts +12 -0
- package/dist/bindings/client/core/registry.js +22 -0
- package/dist/bindings/client/core/types.d.ts +117 -0
- package/dist/bindings/client/core/types.js +13 -0
- package/dist/bindings/client/core/wrap-client.d.ts +6 -0
- package/dist/bindings/client/core/wrap-client.js +258 -0
- package/dist/bindings/client/gateways/bedrock/bedrock-recipe.d.ts +17 -0
- package/dist/bindings/client/gateways/bedrock/bedrock-recipe.js +134 -0
- package/dist/bindings/client/gateways/bedrock/types.d.ts +13 -0
- package/dist/bindings/client/gateways/bedrock/types.js +2 -0
- package/dist/bindings/client/gateways/litellm/litellm-recipe.d.ts +17 -0
- package/dist/bindings/client/gateways/litellm/litellm-recipe.js +171 -0
- package/dist/bindings/client/gateways/litellm/types.d.ts +30 -0
- package/dist/bindings/client/gateways/litellm/types.js +2 -0
- package/dist/bindings/client/gateways/openrouter/openrouter-recipe.d.ts +20 -0
- package/dist/bindings/client/gateways/openrouter/openrouter-recipe.js +244 -0
- package/dist/bindings/client/gateways/openrouter/sdk-usage.d.ts +37 -0
- package/dist/bindings/client/gateways/openrouter/sdk-usage.js +63 -0
- package/dist/bindings/client/gateways/openrouter/types.d.ts +78 -0
- package/dist/bindings/client/gateways/openrouter/types.js +2 -0
- package/dist/bindings/client/providers/anthropic/anthropic-recipe.d.ts +34 -0
- package/dist/bindings/client/providers/anthropic/anthropic-recipe.js +169 -0
- package/dist/bindings/client/providers/gemini/gemini-recipe.d.ts +54 -0
- package/dist/bindings/client/providers/gemini/gemini-recipe.js +243 -0
- package/dist/bindings/client/providers/groq/groq-recipe.d.ts +20 -0
- package/dist/bindings/client/providers/groq/groq-recipe.js +101 -0
- package/dist/bindings/client/providers/mistral/mistral-recipe.d.ts +22 -0
- package/dist/bindings/client/providers/mistral/mistral-recipe.js +114 -0
- package/dist/bindings/client/providers/mistral/types.d.ts +38 -0
- package/dist/bindings/client/providers/mistral/types.js +2 -0
- package/dist/bindings/client/providers/ollama/ollama-recipe.d.ts +31 -0
- package/dist/bindings/client/providers/ollama/ollama-recipe.js +107 -0
- package/dist/bindings/client/providers/ollama/types.d.ts +24 -0
- package/dist/bindings/client/providers/ollama/types.js +2 -0
- package/dist/bindings/client/providers/openai/openai-recipe.d.ts +71 -0
- package/dist/bindings/client/providers/openai/openai-recipe.js +122 -0
- package/dist/bindings/client/providers/typesafe/typesafe-recipe.d.ts +44 -0
- package/dist/bindings/client/providers/typesafe/typesafe-recipe.js +83 -0
- package/dist/bindings/proxy/headers.d.ts +6 -0
- package/dist/bindings/proxy/headers.js +12 -0
- package/dist/bindings/proxy/index.d.ts +21 -0
- package/dist/bindings/proxy/index.js +18 -0
- package/dist/bindings/proxy/types.d.ts +8 -0
- package/dist/bindings/proxy/types.js +2 -0
- package/dist/bindings/shared/estimate.d.ts +27 -0
- package/dist/bindings/shared/estimate.js +38 -0
- package/dist/bindings/shared/meter-stream.d.ts +18 -0
- package/dist/bindings/shared/meter-stream.js +151 -0
- package/dist/bindings/shared/token-usage.d.ts +240 -0
- package/dist/bindings/shared/token-usage.js +574 -0
- package/dist/bindings/shared/types.d.ts +129 -0
- package/dist/bindings/shared/types.js +2 -0
- package/dist/bindings/shared/weighted-metrics.d.ts +37 -0
- package/dist/bindings/shared/weighted-metrics.js +47 -0
- package/dist/config.d.ts +145 -0
- package/dist/config.js +99 -0
- package/dist/core/context.d.ts +160 -0
- package/dist/core/context.js +221 -0
- package/dist/core/dimensions.d.ts +22 -0
- package/dist/core/dimensions.js +47 -0
- package/dist/core/hooks.d.ts +21 -0
- package/dist/core/hooks.js +47 -0
- package/dist/core/session.d.ts +190 -0
- package/dist/core/session.js +448 -0
- package/dist/decision-text.d.ts +15 -0
- package/dist/decision-text.js +54 -0
- package/dist/engine/composite-engine.d.ts +72 -0
- package/dist/engine/composite-engine.js +135 -0
- package/dist/engine/create-engine.d.ts +16 -0
- package/dist/engine/create-engine.js +93 -0
- package/dist/engine/decision.d.ts +42 -0
- package/dist/engine/decision.js +135 -0
- package/dist/engine/engine.d.ts +166 -0
- package/dist/engine/engine.js +11 -0
- package/dist/engine/node-sdk-engine.d.ts +125 -0
- package/dist/engine/node-sdk-engine.js +262 -0
- package/dist/engine/report.d.ts +106 -0
- package/dist/engine/report.js +188 -0
- package/dist/engine/rest-governance-engine.d.ts +47 -0
- package/dist/engine/rest-governance-engine.js +220 -0
- package/dist/errors.d.ts +86 -0
- package/dist/errors.js +161 -0
- package/dist/headers.d.ts +40 -0
- package/dist/headers.js +82 -0
- package/dist/index.d.ts +57 -0
- package/dist/index.js +106 -0
- package/dist/internal.d.ts +33 -0
- package/dist/internal.js +87 -0
- package/dist/logger.d.ts +15 -0
- package/dist/logger.js +20 -0
- package/dist/sdk-identity.d.ts +36 -0
- package/dist/sdk-identity.js +43 -0
- package/dist/stigg-agent-sdk.d.ts +300 -0
- package/dist/stigg-agent-sdk.js +656 -0
- package/dist/types.d.ts +642 -0
- package/dist/types.js +147 -0
- package/package.json +89 -3
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a Stigg deployment can tell this SDK's traffic apart from everything else's.
|
|
3
|
+
*
|
|
4
|
+
* There is no analytics pipeline here and this is not one: nothing is emitted, nothing is batched,
|
|
5
|
+
* nothing fires on a schedule. Adoption is read off the requests the SDK was already making, which
|
|
6
|
+
* is the same answer the Node server SDK and the sidecar give - identity rides along on headers,
|
|
7
|
+
* so there is no second network path to fail, no payload to review for what it collects, and
|
|
8
|
+
* nothing to disable.
|
|
9
|
+
*
|
|
10
|
+
* Without this, an agent-sdk install is invisible: its GraphQL half reports as a plain
|
|
11
|
+
* `node-server-sdk` client, and its REST half carries no Stigg identity at all.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* This package's own version, read from its manifest rather than restated here - a constant would
|
|
15
|
+
* have to be remembered on every release, and the one release where it is not is the release the
|
|
16
|
+
* numbers quietly stop meaning anything.
|
|
17
|
+
*
|
|
18
|
+
* `dist/sdk-identity.js` and `src/sdk-identity.ts` both sit one directory under the package root,
|
|
19
|
+
* so the same relative path works built and from source.
|
|
20
|
+
*/
|
|
21
|
+
export declare const AGENT_SDK_VERSION: string;
|
|
22
|
+
/**
|
|
23
|
+
* Deliberately not `SourceType.AgentSdk`: that enum lives in Stigg's GraphQL schema, the API
|
|
24
|
+
* groups on it, and there is no member for this SDK. Adding one is a server change that has to
|
|
25
|
+
* land first, so the client name is what carries the distinction in the meantime - exactly the
|
|
26
|
+
* trade the sidecar made when it started naming itself.
|
|
27
|
+
*/
|
|
28
|
+
export declare const AGENT_SDK_CLIENT_NAME = "agent-sdk-js";
|
|
29
|
+
/**
|
|
30
|
+
* The REST client's equivalent, since it has no client-awareness convention of its own.
|
|
31
|
+
*
|
|
32
|
+
* Named into the `X-SDK-` family the GraphQL transport already sends, so both halves of one
|
|
33
|
+
* agent-sdk process are recognizable the same way. Nothing on the server branches on these; they
|
|
34
|
+
* arrive as trace tags, which is all identity needs to be.
|
|
35
|
+
*/
|
|
36
|
+
export declare const AGENT_SDK_REST_HEADERS: Record<string, string>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* How a Stigg deployment can tell this SDK's traffic apart from everything else's.
|
|
4
|
+
*
|
|
5
|
+
* There is no analytics pipeline here and this is not one: nothing is emitted, nothing is batched,
|
|
6
|
+
* nothing fires on a schedule. Adoption is read off the requests the SDK was already making, which
|
|
7
|
+
* is the same answer the Node server SDK and the sidecar give - identity rides along on headers,
|
|
8
|
+
* so there is no second network path to fail, no payload to review for what it collects, and
|
|
9
|
+
* nothing to disable.
|
|
10
|
+
*
|
|
11
|
+
* Without this, an agent-sdk install is invisible: its GraphQL half reports as a plain
|
|
12
|
+
* `node-server-sdk` client, and its REST half carries no Stigg identity at all.
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.AGENT_SDK_REST_HEADERS = exports.AGENT_SDK_CLIENT_NAME = exports.AGENT_SDK_VERSION = void 0;
|
|
16
|
+
/**
|
|
17
|
+
* This package's own version, read from its manifest rather than restated here - a constant would
|
|
18
|
+
* have to be remembered on every release, and the one release where it is not is the release the
|
|
19
|
+
* numbers quietly stop meaning anything.
|
|
20
|
+
*
|
|
21
|
+
* `dist/sdk-identity.js` and `src/sdk-identity.ts` both sit one directory under the package root,
|
|
22
|
+
* so the same relative path works built and from source.
|
|
23
|
+
*/
|
|
24
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
25
|
+
exports.AGENT_SDK_VERSION = require('../package.json').version;
|
|
26
|
+
/**
|
|
27
|
+
* Deliberately not `SourceType.AgentSdk`: that enum lives in Stigg's GraphQL schema, the API
|
|
28
|
+
* groups on it, and there is no member for this SDK. Adding one is a server change that has to
|
|
29
|
+
* land first, so the client name is what carries the distinction in the meantime - exactly the
|
|
30
|
+
* trade the sidecar made when it started naming itself.
|
|
31
|
+
*/
|
|
32
|
+
exports.AGENT_SDK_CLIENT_NAME = 'agent-sdk-js';
|
|
33
|
+
/**
|
|
34
|
+
* The REST client's equivalent, since it has no client-awareness convention of its own.
|
|
35
|
+
*
|
|
36
|
+
* Named into the `X-SDK-` family the GraphQL transport already sends, so both halves of one
|
|
37
|
+
* agent-sdk process are recognizable the same way. Nothing on the server branches on these; they
|
|
38
|
+
* arrive as trace tags, which is all identity needs to be.
|
|
39
|
+
*/
|
|
40
|
+
exports.AGENT_SDK_REST_HEADERS = {
|
|
41
|
+
'X-SDK-CLIENT-NAME': exports.AGENT_SDK_CLIENT_NAME,
|
|
42
|
+
'X-SDK-CLIENT-VERSION': exports.AGENT_SDK_VERSION,
|
|
43
|
+
};
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import { type ResolvedConfig, type StiggAgentSDKOptions } from './config';
|
|
2
|
+
import { type EngineResolution, type GovernanceEngine } from './engine/engine';
|
|
3
|
+
import type { StiggContext } from './core/context';
|
|
4
|
+
import type { SessionSummary } from './core/session';
|
|
5
|
+
import type { Metrics, ClientOptions, DeregisterInput, AccessDecision, WrappedClient, PathsOf, IngestContext, IngestResult, RegisterInput } from './types';
|
|
6
|
+
import type { GovernanceHeaders } from './headers';
|
|
7
|
+
/**
|
|
8
|
+
* Recipes are data - method paths and usage extractors - so wiring them here costs nothing at
|
|
9
|
+
* runtime and pulls in no vendor package. An orchestration adapter is different: it needs its
|
|
10
|
+
* framework loaded, so it stays an explicit subpath import.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Order matters: the gateways are matched before the plain OpenAI adapter, because every one of
|
|
14
|
+
* them *is* an OpenAI client by shape and only the base URL says which. The bare adapter would
|
|
15
|
+
* otherwise claim them and lose what only a gateway knows - the model that actually served after
|
|
16
|
+
* routing, and the gateway's own request id.
|
|
17
|
+
*
|
|
18
|
+
* Matching them costs nothing in units: they report what the gateway stated and leave what it is
|
|
19
|
+
* worth to the run's mapper, like every other vendor. Billing the `cost` they add rather than the
|
|
20
|
+
* tokens is that mapper's business, and stays the caller's to decide.
|
|
21
|
+
*/
|
|
22
|
+
export declare const DEFAULT_RECIPES: ({
|
|
23
|
+
vendor: string;
|
|
24
|
+
metrics: readonly ["input_tokens", "output_tokens", "cache_read_input_tokens", "cache_creation_input_tokens", "total_tokens"];
|
|
25
|
+
totalTokensMetric: "total_tokens";
|
|
26
|
+
matches: (client: unknown) => boolean;
|
|
27
|
+
methods: {
|
|
28
|
+
path: string[];
|
|
29
|
+
extractUsage: (result: any) => {
|
|
30
|
+
metrics: Metrics;
|
|
31
|
+
usage: import("./types").TokenUsage;
|
|
32
|
+
raw: any;
|
|
33
|
+
} | undefined;
|
|
34
|
+
attachStream: (stream: any, ingest: (measurement: import("./types").Measurement) => void) => void;
|
|
35
|
+
}[];
|
|
36
|
+
} | {
|
|
37
|
+
vendor: string;
|
|
38
|
+
metrics: readonly ["promptTokenCount", "candidatesTokenCount", "cachedContentTokenCount", "thoughtsTokenCount", "toolUsePromptTokenCount", "totalTokenCount"];
|
|
39
|
+
totalTokensMetric: "totalTokenCount";
|
|
40
|
+
matches: (client: unknown) => boolean;
|
|
41
|
+
methods: ({
|
|
42
|
+
path: readonly ["models", "generateContent"];
|
|
43
|
+
extractUsage: (result: any) => import("./types").Measurement | undefined;
|
|
44
|
+
attachStream: (stream: any, ingest: (measurement: import("./types").Measurement) => void) => void;
|
|
45
|
+
} | {
|
|
46
|
+
path: readonly ["models", "generateContentStream"];
|
|
47
|
+
extractUsage: (result: any) => import("./types").Measurement | undefined;
|
|
48
|
+
attachStream: (stream: any, ingest: (measurement: import("./types").Measurement) => void) => void;
|
|
49
|
+
})[];
|
|
50
|
+
} | {
|
|
51
|
+
vendor: string;
|
|
52
|
+
metrics: readonly ["promptTokenCount", "candidatesTokenCount", "cachedContentTokenCount", "thoughtsTokenCount", "toolUsePromptTokenCount", "totalTokenCount"];
|
|
53
|
+
totalTokensMetric: "totalTokenCount";
|
|
54
|
+
matches: (client: unknown) => boolean;
|
|
55
|
+
methods: ({
|
|
56
|
+
path: readonly ["sendMessage"];
|
|
57
|
+
event: string;
|
|
58
|
+
extractUsage: (result: any) => import("./types").Measurement | undefined;
|
|
59
|
+
attachStream: (stream: any, ingest: (measurement: import("./types").Measurement) => void) => void;
|
|
60
|
+
} | {
|
|
61
|
+
path: readonly ["sendMessageStream"];
|
|
62
|
+
event: string;
|
|
63
|
+
extractUsage: (result: any) => import("./types").Measurement | undefined;
|
|
64
|
+
attachStream: (stream: any, ingest: (measurement: import("./types").Measurement) => void) => void;
|
|
65
|
+
})[];
|
|
66
|
+
} | {
|
|
67
|
+
vendor: string;
|
|
68
|
+
metrics: readonly ["prompt_tokens", "completion_tokens", "input_tokens", "output_tokens", "cached_tokens", "total_tokens"];
|
|
69
|
+
totalTokensMetric: "total_tokens";
|
|
70
|
+
matches: (client: unknown) => boolean;
|
|
71
|
+
methods: {
|
|
72
|
+
path: ("create" | "chat" | "completions" | "responses")[];
|
|
73
|
+
extractUsage: (result: any) => {
|
|
74
|
+
metrics: Metrics;
|
|
75
|
+
usage: import("./types").TokenUsage;
|
|
76
|
+
raw: any;
|
|
77
|
+
} | undefined;
|
|
78
|
+
attachStream: (stream: any, ingest: (measurement: import("./types").Measurement) => void) => void;
|
|
79
|
+
}[];
|
|
80
|
+
} | import("./bindings/client/core/types").ClientRecipe<"cached_tokens" | "prompt_tokens" | "completion_tokens" | "input_tokens" | "output_tokens" | "total_tokens" | "cost"> | {
|
|
81
|
+
vendor: string;
|
|
82
|
+
metrics: readonly ["prompt_tokens", "completion_tokens", "cached_tokens", "total_tokens"];
|
|
83
|
+
totalTokensMetric: "total_tokens";
|
|
84
|
+
matches: (client: unknown) => boolean;
|
|
85
|
+
methods: {
|
|
86
|
+
path: ("create" | "chat" | "completions")[];
|
|
87
|
+
extractUsage: (result: any) => {
|
|
88
|
+
metrics: Metrics;
|
|
89
|
+
usage: import("./types").TokenUsage;
|
|
90
|
+
raw: any;
|
|
91
|
+
} | undefined;
|
|
92
|
+
attachStream: (stream: any, ingest: (measurement: import("./types").Measurement) => void) => void;
|
|
93
|
+
}[];
|
|
94
|
+
} | {
|
|
95
|
+
vendor: string;
|
|
96
|
+
metrics: readonly ["prompt_tokens", "completion_tokens", "total_tokens"];
|
|
97
|
+
totalTokensMetric: "total_tokens";
|
|
98
|
+
matches: (client: unknown) => boolean;
|
|
99
|
+
methods: ({
|
|
100
|
+
path: ("stream" | "chat" | "complete" | "parse" | "parseStream" | "fim" | "agents")[];
|
|
101
|
+
attachStream: (stream: unknown, ingest: (measurement: import("./types").Measurement) => void) => void;
|
|
102
|
+
extractUsage?: undefined;
|
|
103
|
+
} | {
|
|
104
|
+
path: ("stream" | "chat" | "complete" | "parse" | "parseStream" | "fim" | "agents")[];
|
|
105
|
+
extractUsage: (result: import("./bindings/client/providers/mistral/types").MistralCompletionResponse | undefined) => import("./types").Measurement | undefined;
|
|
106
|
+
attachStream?: undefined;
|
|
107
|
+
})[];
|
|
108
|
+
} | {
|
|
109
|
+
vendor: string;
|
|
110
|
+
metrics: readonly ["prompt_eval_count", "eval_count", "total_tokens"];
|
|
111
|
+
totalTokensMetric: "total_tokens";
|
|
112
|
+
matches: (client: unknown) => boolean;
|
|
113
|
+
methods: ({
|
|
114
|
+
path: readonly ["chat"];
|
|
115
|
+
extractUsage: (result: import("./bindings/client/providers/ollama/types").OllamaResponse | undefined) => import("./types").Measurement | undefined;
|
|
116
|
+
attachStream: (stream: unknown, ingest: (measurement: import("./types").Measurement) => void) => void;
|
|
117
|
+
} | {
|
|
118
|
+
path: readonly ["generate"];
|
|
119
|
+
extractUsage: (result: import("./bindings/client/providers/ollama/types").OllamaResponse | undefined) => import("./types").Measurement | undefined;
|
|
120
|
+
attachStream: (stream: unknown, ingest: (measurement: import("./types").Measurement) => void) => void;
|
|
121
|
+
})[];
|
|
122
|
+
} | import("./bindings/client/core/types").ClientRecipe<"totalTokens" | "inputTokens" | "outputTokens" | "cacheReadInputTokens" | "cacheWriteInputTokens"> | {
|
|
123
|
+
vendor: string;
|
|
124
|
+
metrics: readonly ["input_tokens", "output_tokens", "total_tokens"];
|
|
125
|
+
totalTokensMetric: "total_tokens";
|
|
126
|
+
matches: (client: unknown) => boolean;
|
|
127
|
+
methods: {
|
|
128
|
+
path: string[];
|
|
129
|
+
extractUsage: (result: any) => {
|
|
130
|
+
metrics: Metrics;
|
|
131
|
+
usage: import("./types").TokenUsage;
|
|
132
|
+
raw: any;
|
|
133
|
+
} | undefined;
|
|
134
|
+
}[];
|
|
135
|
+
})[];
|
|
136
|
+
export declare class StiggAgentSDK {
|
|
137
|
+
readonly config: ResolvedConfig;
|
|
138
|
+
private readonly clients;
|
|
139
|
+
/** Every session this SDK handed out, so `flush()` can drain all of them at once. */
|
|
140
|
+
private readonly sessions;
|
|
141
|
+
/** The session the no-client paths share. Built on first use. */
|
|
142
|
+
private loose?;
|
|
143
|
+
/**
|
|
144
|
+
* `customer:agent` -> what was last said about that agent, so a repeat of the same description
|
|
145
|
+
* is not written again per run. The value is a fingerprint of the describable attributes, not
|
|
146
|
+
* an id: the id is in the key.
|
|
147
|
+
*/
|
|
148
|
+
private readonly registered;
|
|
149
|
+
/**
|
|
150
|
+
* Bare registrations still on the wire, so the burst of runs that opens a process writes once
|
|
151
|
+
* rather than once each. Only the memoized path is shared - see `register`.
|
|
152
|
+
*/
|
|
153
|
+
private readonly registering;
|
|
154
|
+
private started?;
|
|
155
|
+
/**
|
|
156
|
+
* When the attempt currently in `started` rejected, or undefined while it is pending or has
|
|
157
|
+
* resolved. What makes a failed probe expire rather than persist - see `ensureStarted`.
|
|
158
|
+
*/
|
|
159
|
+
private startFailedAt?;
|
|
160
|
+
private engineState?;
|
|
161
|
+
/**
|
|
162
|
+
* Synchronous - nothing here touches the network. The engine is built on the first call that
|
|
163
|
+
* needs it, so there is no awaited setup step to forget; `await init()` forces it early.
|
|
164
|
+
*
|
|
165
|
+
* Where this SDK sends its traffic comes first, because it is the only thing that cannot be
|
|
166
|
+
* inferred: a server key, a `{ baseUrl }` target that needs none, or nothing at all to read
|
|
167
|
+
* `STIGG_SERVER_API_KEY`. A key that belongs to somewhere other than
|
|
168
|
+
* the hosted API names that URL second - the two together are one idea, so neither is buried
|
|
169
|
+
* among the tuning knobs that follow.
|
|
170
|
+
*
|
|
171
|
+
* Construct one per environment and share it - the engine's cache and its connection pool are
|
|
172
|
+
* per instance, so a second one for the same environment is wasted rather than wrong.
|
|
173
|
+
*/
|
|
174
|
+
constructor(options?: StiggAgentSDKOptions);
|
|
175
|
+
/** The shorthand, for a server key with nothing else to say about where it points. */
|
|
176
|
+
constructor(apiKey: string, options?: Omit<StiggAgentSDKOptions, 'apiKey'>);
|
|
177
|
+
/** Releases what this SDK's engine holds open. */
|
|
178
|
+
close(): Promise<void>;
|
|
179
|
+
/**
|
|
180
|
+
* Forces the engine to resolve now and reports which client serves what. Optional - every
|
|
181
|
+
* async call below does it anyway - but useful when you want the answer before the first run.
|
|
182
|
+
*/
|
|
183
|
+
init(): Promise<EngineResolution>;
|
|
184
|
+
/** Undefined until the engine has resolved. `init()` returns it directly. */
|
|
185
|
+
get resolution(): EngineResolution | undefined;
|
|
186
|
+
/** Available after the engine has resolved; the bindings that need it only run after that. */
|
|
187
|
+
get engine(): GovernanceEngine;
|
|
188
|
+
/**
|
|
189
|
+
* Gives the agent an identity, a budget, and a place in the tree, and returns the agent id to
|
|
190
|
+
* open a run against.
|
|
191
|
+
*
|
|
192
|
+
* The id is the one you passed: nothing about the run depends on this call having happened, so
|
|
193
|
+
* returning it is a convenience rather than a handle. Skip `register` entirely and the agent
|
|
194
|
+
* has no entity - the run still works, and checks and usage apply to the customer instead.
|
|
195
|
+
*
|
|
196
|
+
* Idempotent, and remembered per process: an upsert is cheap, but it is still a write, so
|
|
197
|
+
* calling this on a hot path does not repeat it. A call carrying a budget or a parent always
|
|
198
|
+
* writes, because that is a deliberate change rather than a formality.
|
|
199
|
+
*
|
|
200
|
+
* `run.start(runOptions, agentOptions)` calls this for you with the run's own scope, which is
|
|
201
|
+
* the usual way in; reach for it directly to provision an agent no run is about to use.
|
|
202
|
+
*/
|
|
203
|
+
register(input: RegisterInput): Promise<string>;
|
|
204
|
+
/**
|
|
205
|
+
* Removes the agent's entity. Optional, mirrors `register`, and never relied on: it may never
|
|
206
|
+
* fire - a crash, an abandoned stream, an interrupt that is never resumed - which is why warm
|
|
207
|
+
* state has a TTL rather than waiting to be released.
|
|
208
|
+
*/
|
|
209
|
+
deregister(input: DeregisterInput): Promise<void>;
|
|
210
|
+
/**
|
|
211
|
+
* Governs a vendor client and hands back a copy whose calls are checked and metered.
|
|
212
|
+
*
|
|
213
|
+
* The whole lifecycle, in one step. `stiggContext` here is the default for every call through
|
|
214
|
+
* this client; any single call overrides it by putting its own `stiggContext` in the vendor's
|
|
215
|
+
* parameters. The client you passed is never mutated, so it keeps working ungoverned.
|
|
216
|
+
*
|
|
217
|
+
* The vendor is recognised from the client's own shape and base URL rather than named; pass
|
|
218
|
+
* `recipe` only for a vendor the built-ins cannot identify.
|
|
219
|
+
*
|
|
220
|
+
* Warms the entitlement cache before returning when the context names both a customer and an
|
|
221
|
+
* entitlement, so the calls that follow read local state. Nothing is cached in this package -
|
|
222
|
+
* see {@link GovernanceSession.warmUp} for which cache that is and when there is one at all.
|
|
223
|
+
*/
|
|
224
|
+
wrap<T extends object, O extends ClientOptions>(client: T, options?: O): WrappedClient<T, O['stiggContext'], PathsOf<O['recipe'], T>>;
|
|
225
|
+
/**
|
|
226
|
+
* Hangs the governance handle off the wrapped client. Refuses to overwrite a `stigg` the vendor
|
|
227
|
+
* already has: silently replacing one of its own properties would be a worse surprise.
|
|
228
|
+
*/
|
|
229
|
+
private attachGovernance;
|
|
230
|
+
/**
|
|
231
|
+
* The gate, with no client to wrap - what a framework binding reaches for, and what the gateway
|
|
232
|
+
* example checks with before it proxies.
|
|
233
|
+
*/
|
|
234
|
+
check(context: StiggContext, requestedUsage?: number): Promise<AccessDecision>;
|
|
235
|
+
/** The meter, with no client to wrap. Metrics already in Stigg's own vocabulary. */
|
|
236
|
+
report(context: StiggContext, metrics: Metrics): Promise<IngestResult>;
|
|
237
|
+
/** The `x-stigg-*` attribution for work continuing in another process, with no client involved. */
|
|
238
|
+
governanceHeaders(context: StiggContext): GovernanceHeaders;
|
|
239
|
+
/**
|
|
240
|
+
* The policy a context falls back to when neither the call nor `wrap` named one.
|
|
241
|
+
*
|
|
242
|
+
* Both fields are always set - the config schema defaults them - so this is the one place a
|
|
243
|
+
* constructor option becomes the behaviour of a call. Before it existed the options were parsed,
|
|
244
|
+
* stored, and never read: every context fell through to the context module's own defaults, and a
|
|
245
|
+
* client constructed with `checkErrorAction: 'deny'` failed open on every call it gated.
|
|
246
|
+
*/
|
|
247
|
+
private get contextDefaults();
|
|
248
|
+
private newSession;
|
|
249
|
+
/** The session the no-client paths share, built on first use so an unused SDK builds none. */
|
|
250
|
+
private standalone;
|
|
251
|
+
/**
|
|
252
|
+
* Returns the decision when `err` is a governance refusal, so a catch block is one line and the
|
|
253
|
+
* caller needs no import to tell a denial from a real failure.
|
|
254
|
+
*/
|
|
255
|
+
denial(err: unknown): AccessDecision | undefined;
|
|
256
|
+
/**
|
|
257
|
+
* The gateway side of the split lifecycle: ingest usage a proxy observed, attributed from the
|
|
258
|
+
* headers the application sent with the request. Ingest only - a gateway sees requests, not
|
|
259
|
+
* runs, so there is nothing here to check against.
|
|
260
|
+
*/
|
|
261
|
+
ingestFromHeaders(headers: Record<string, string | string[] | undefined>, input: IngestContext & {
|
|
262
|
+
usage: unknown;
|
|
263
|
+
idempotencyKey: string;
|
|
264
|
+
/** This report's outcome, including a failed one. The gateway's stand-in for a run hook. */
|
|
265
|
+
onIngest?: (result: IngestResult) => void;
|
|
266
|
+
}): Promise<IngestResult>;
|
|
267
|
+
/**
|
|
268
|
+
* A probe that failed with nobody waiting on it.
|
|
269
|
+
*
|
|
270
|
+
* `wrap()` returns before the engine resolves, so this is the one path where a startup failure
|
|
271
|
+
* has no caller to reject towards. Swallowing it silently would leave a client that looks
|
|
272
|
+
* governed and cannot check; letting it reject unobserved ends the process.
|
|
273
|
+
*/
|
|
274
|
+
private reportStartupFailure;
|
|
275
|
+
/** `onError` is the application's too, and there is nowhere left to report its failure to. */
|
|
276
|
+
private reportIngestFailure;
|
|
277
|
+
/**
|
|
278
|
+
* Drains every wrapped client's in-flight ingests. Explicit because an exit hook does not fire
|
|
279
|
+
* in a request-scoped or serverless runtime.
|
|
280
|
+
*
|
|
281
|
+
* A single client drains on its own with `client.stigg.flush()`; this is the process-wide one,
|
|
282
|
+
* for a shutdown that does not know which clients exist.
|
|
283
|
+
*/
|
|
284
|
+
flush(options?: {
|
|
285
|
+
close?: boolean;
|
|
286
|
+
}): Promise<SessionSummary[]>;
|
|
287
|
+
/**
|
|
288
|
+
* Builds the engine once, on first need. Concurrent callers share the same attempt.
|
|
289
|
+
*
|
|
290
|
+
* A *failed* attempt is shared too, but only for {@link RETRY_START_AFTER_MS}. A rejected
|
|
291
|
+
* promise is still a promise, so memoizing one unconditionally outlives the failure that caused
|
|
292
|
+
* it: under the default `checkErrorAction: 'allow'` the process stops enforcing any budget at
|
|
293
|
+
* all, and under `'deny'` it refuses every call - neither saying anything a log would show.
|
|
294
|
+
*
|
|
295
|
+
* Holding the failure briefly rather than discarding it on sight is the other half: callers
|
|
296
|
+
* inside the window get the same rejection immediately and their own `checkErrorAction` decides
|
|
297
|
+
* the outcome, so an outage is re-probed on a timer instead of once per request.
|
|
298
|
+
*/
|
|
299
|
+
private ensureStarted;
|
|
300
|
+
}
|