@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
package/dist/types.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.unitsPerTokens = exports.wholeUnitsForGovernance = exports.toMeasurement = exports.vendorMetrics = exports.emptyTokenUsage = exports.entitlementRef = exports.entitlementKind = exports.entitlementId = void 0;
|
|
4
|
+
exports.entitlementError = entitlementError;
|
|
5
|
+
exports.usageValueError = usageValueError;
|
|
6
|
+
/**
|
|
7
|
+
* The vocabulary shared by the core, the engines and every binding, and the argument list of
|
|
8
|
+
* every call on the public surface.
|
|
9
|
+
*
|
|
10
|
+
* Terms follow Stigg governance rather than the draft design notes: provision/archive (not
|
|
11
|
+
* register/de-register), ingest (not report), assignment (not budget), dimensions (not tags).
|
|
12
|
+
*
|
|
13
|
+
* The imports below are all `import type`, so they are erased at compile time: this file pulls in
|
|
14
|
+
* no module at runtime and stays the leaf everything else can depend on.
|
|
15
|
+
*/
|
|
16
|
+
const errors_1 = require("./errors");
|
|
17
|
+
/** The id to send as `featureId`/`currencyId`, whichever kind the entitlement is. */
|
|
18
|
+
const entitlementId = (entitlement) => entitlement.currencyId ?? entitlement.featureId;
|
|
19
|
+
exports.entitlementId = entitlementId;
|
|
20
|
+
/** 'credit' targets read the customer's credit pool; 'feature' targets need an entitling subscription. */
|
|
21
|
+
const entitlementKind = (entitlement) => entitlement.currencyId ? 'credit' : 'feature';
|
|
22
|
+
exports.entitlementKind = entitlementKind;
|
|
23
|
+
/**
|
|
24
|
+
* The entitlement as every Stigg endpoint takes it: one of two mutually exclusive id fields,
|
|
25
|
+
* ready to spread.
|
|
26
|
+
*
|
|
27
|
+
* ```ts
|
|
28
|
+
* await client.v1Beta.customers.entitlements.check(customerId, { ...entitlementRef(entitlement), requestedUsage });
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* Narrowing on the property rather than through {@link entitlementKind} is the point: a function
|
|
32
|
+
* call cannot narrow a union, so every hand-written version of this needed a `!` on each branch -
|
|
33
|
+
* an assertion that the union already guarantees and that would survive the union changing.
|
|
34
|
+
*/
|
|
35
|
+
const entitlementRef = (entitlement) => entitlement.currencyId !== undefined ? { currencyId: entitlement.currencyId } : { featureId: entitlement.featureId };
|
|
36
|
+
exports.entitlementRef = entitlementRef;
|
|
37
|
+
/**
|
|
38
|
+
* Why an entitlement cannot be billed against, if one was named at all.
|
|
39
|
+
*
|
|
40
|
+
* Naming none is legal: it is how a caller asks for metering without enforcement, so undefined is
|
|
41
|
+
* not an error here. The one place an entitlement is genuinely required is an assignment, which is
|
|
42
|
+
* written over `(entity x entitlement)` - and `register` refuses that case itself, because only it
|
|
43
|
+
* knows the agent to name in the message.
|
|
44
|
+
*
|
|
45
|
+
* What stays refused is an entitlement that is named and names nothing. The union permits
|
|
46
|
+
* `{ currencyId: '' }`, and an empty currency is falsy - so it classifies as a feature and every
|
|
47
|
+
* branch downstream then asks for a `featureId` that is not there. An empty id is a typo rather
|
|
48
|
+
* than an intention, and letting it through meters a run against nothing while it still looks
|
|
49
|
+
* enforced.
|
|
50
|
+
*/
|
|
51
|
+
function entitlementError(entitlement) {
|
|
52
|
+
if (!entitlement)
|
|
53
|
+
return undefined;
|
|
54
|
+
if ((0, exports.entitlementId)(entitlement)?.trim())
|
|
55
|
+
return undefined;
|
|
56
|
+
return new Error('a run needs a non-empty currencyId or featureId - an empty one bills against nothing.');
|
|
57
|
+
}
|
|
58
|
+
const emptyTokenUsage = () => ({ input: 0, output: 0, cacheRead: 0, cacheCreate: 0 });
|
|
59
|
+
exports.emptyTokenUsage = emptyTokenUsage;
|
|
60
|
+
/** What a run reports when nobody says otherwise: exactly what the vendor stated. */
|
|
61
|
+
const vendorMetrics = (measurement) => measurement.metrics ?? {};
|
|
62
|
+
exports.vendorMetrics = vendorMetrics;
|
|
63
|
+
/** A binding may report either shape; `TokenUsage` is the common case and stays terse. */
|
|
64
|
+
const toMeasurement = (value) => 'input' in value ? { usage: value } : value;
|
|
65
|
+
exports.toMeasurement = toMeasurement;
|
|
66
|
+
/**
|
|
67
|
+
* The amount to report when this run is attributed to a governance entity.
|
|
68
|
+
*
|
|
69
|
+
* Governance counts in whole units and cannot be made to count otherwise from here: its ingest
|
|
70
|
+
* schema is `z.number().int()`, and the counter behind it is a Redis `HINCRBY`, which takes an
|
|
71
|
+
* integer delta. A fractional amount is rejected at that boundary - the wallet still moves, the
|
|
72
|
+
* per-entity counter does not, and nothing in the response says so. An agent's budget silently
|
|
73
|
+
* stops advancing while its spend carries on.
|
|
74
|
+
*
|
|
75
|
+
* So an attributed run rounds up, and only an attributed run: a run that names no entity reports
|
|
76
|
+
* what its mapper produced, because the wallet takes fractions and nothing downstream of it
|
|
77
|
+
* counts in whole units.
|
|
78
|
+
*
|
|
79
|
+
* Rounding *up* rather than to nearest, because a call that happened must cost something: at any
|
|
80
|
+
* sane denomination most calls are worth less than one unit, and rounding to nearest would bill
|
|
81
|
+
* nothing for nearly all of them.
|
|
82
|
+
*
|
|
83
|
+
* TODO: delete this, and the call sites that use it, once governance counts fractional usage.
|
|
84
|
+
* The platform fix is to scale internally - store micro-units and accept fractions at the API
|
|
85
|
+
* boundary - which keeps `HINCRBY` working and is the only way an agent budget can be
|
|
86
|
+
* denominated finely enough to price a call worth a tenth of a cent. Until then this is a
|
|
87
|
+
* deliberate overcharge on small calls, which is why it is announced rather than silent.
|
|
88
|
+
*/
|
|
89
|
+
const wholeUnitsForGovernance = (value) => Math.ceil(value);
|
|
90
|
+
exports.wholeUnitsForGovernance = wholeUnitsForGovernance;
|
|
91
|
+
/**
|
|
92
|
+
* Why a measured value cannot be reported, if it cannot.
|
|
93
|
+
*
|
|
94
|
+
* Zero is not an error - a cached refusal or an empty stream is a normal turn - but a mapper
|
|
95
|
+
* dividing by an unset config returns NaN or Infinity, and reading those as "nothing was used"
|
|
96
|
+
* meters the run at zero while every call still reports success. Those are refused everywhere.
|
|
97
|
+
*
|
|
98
|
+
* A fraction is refused on one path only, and the rule is the endpoint's rather than this SDK's:
|
|
99
|
+
*
|
|
100
|
+
* - **The wallet** takes them. `credits.consumption.consume` and its async twin accept a
|
|
101
|
+
* fractional `amount`, and balances are fractional too - which they have to be, or a currency
|
|
102
|
+
* could never be denominated finely enough to price a call worth a tenth of a cent.
|
|
103
|
+
* - **An event** takes them. The number rides as a dimension and a meter sums what it finds,
|
|
104
|
+
* which is the only way a gateway's `cost` reports honestly.
|
|
105
|
+
* - **The usage report** does not: `POST /api/v1/usage` answers
|
|
106
|
+
* `400 Expected integer, received float`. That is the one case refused here, where the caller
|
|
107
|
+
* can still see which metric it was - metering failures are swallowed into `onError`, so a 400
|
|
108
|
+
* three frames down is a silent gap rather than an error anyone reads.
|
|
109
|
+
*
|
|
110
|
+
* Shared, because every path that reports usage has to answer this the same way.
|
|
111
|
+
*/
|
|
112
|
+
function usageValueError(value, mode = 'sync',
|
|
113
|
+
// Whether this metric draws the credit wallet rather than reporting a feature. The wallet takes
|
|
114
|
+
// fractions in both modes, so what the ingest mode decides does not apply to it.
|
|
115
|
+
drawsWallet = false) {
|
|
116
|
+
if (!Number.isFinite(value) || value < 0) {
|
|
117
|
+
return new errors_1.EngineError('ingest', `usage value must be a finite non-negative number, got ${value}`);
|
|
118
|
+
}
|
|
119
|
+
if (mode === 'async' || drawsWallet || Number.isInteger(value))
|
|
120
|
+
return undefined;
|
|
121
|
+
return new errors_1.EngineError('ingest', `usage value must be a whole number to report against a feature, got ${value}. The usage ` +
|
|
122
|
+
'report takes integers; a credit currency takes fractions, and so does an event under ' +
|
|
123
|
+
"`ingest: 'async'`.");
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* One metric, summed from every token class and divided by the unit size.
|
|
127
|
+
*
|
|
128
|
+
* The mapper for an application that prices tokens itself. Named for what it produces - units
|
|
129
|
+
* under an id - rather than for credits, because it does not deduct any: it reports a number, and
|
|
130
|
+
* that number draws the wallet only when the id happens to name a credit currency. Which it is
|
|
131
|
+
* decides the whole ingest path, so a mapper that claimed to know was the wrong place to look.
|
|
132
|
+
*
|
|
133
|
+
* **Prefer reporting the raw counters and converting in Stigg.** A consumption mapping on the plan
|
|
134
|
+
* does the same arithmetic where a pricing change does not need a deploy, and it is the only place
|
|
135
|
+
* that can weight cache reads cheaper. Reach for this when the application deliberately prices
|
|
136
|
+
* itself.
|
|
137
|
+
*
|
|
138
|
+
* The division is reported as it comes out. A credit currency takes fractions, so a call worth
|
|
139
|
+
* four fifths of a unit costs four fifths of one - rounding it up here would be this SDK's
|
|
140
|
+
* arithmetic on someone else's price. A **feature** is the exception: `POST /api/v1/usage` takes
|
|
141
|
+
* integers, so pick a `tokensPerUnit` that divides, or round in your own mapper.
|
|
142
|
+
*
|
|
143
|
+
* @param id The Stigg feature id or credit currency id to report under.
|
|
144
|
+
* @param tokensPerUnit How many tokens make one unit.
|
|
145
|
+
*/
|
|
146
|
+
const unitsPerTokens = (id, tokensPerUnit = 1) => ({ usage }) => usage ? { [id]: (usage.input + usage.output + usage.cacheRead + usage.cacheCreate) / tokensPerUnit } : {};
|
|
147
|
+
exports.unitsPerTokens = unitsPerTokens;
|
package/package.json
CHANGED
|
@@ -1,6 +1,92 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stigg/agent-sdk-js",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Stigg agent SDK (JS) - run-lifecycle governance for agentic stacks, with examples per layer",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"typings": "dist/index.d.ts",
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public",
|
|
9
|
+
"main": "dist/index.js",
|
|
10
|
+
"typings": "dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./internal": {
|
|
17
|
+
"types": "./dist/internal.d.ts",
|
|
18
|
+
"default": "./dist/internal.js"
|
|
19
|
+
},
|
|
20
|
+
"./package.json": "./package.json"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "https://github.com/stiggio/stigg-sdk.git",
|
|
27
|
+
"directory": "packages/agent-sdk/agent-sdk-js"
|
|
28
|
+
},
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "rm -rf dist && yarn run -T tsc -p tsconfig.json --noEmit && yarn run -T tsc -p tsconfig.build.json",
|
|
31
|
+
"lint": "yarn run -T eslint \"{src,examples,test,testing}/**/*.ts\"",
|
|
32
|
+
"test": "tsx --test test/*.test.ts",
|
|
33
|
+
"example-setup": "tsx examples/shared/setup-governance.ts",
|
|
34
|
+
"example-client": "tsx examples/client/anthropic.ts",
|
|
35
|
+
"example-client-anthropic": "tsx examples/client/anthropic.ts",
|
|
36
|
+
"example-client-openai": "tsx examples/client/openai.ts",
|
|
37
|
+
"example-client-gemini": "tsx examples/client/gemini.ts",
|
|
38
|
+
"example-client-groq": "tsx examples/client/groq.ts",
|
|
39
|
+
"example-client-mistral": "tsx examples/client/mistral.ts",
|
|
40
|
+
"example-client-ollama": "tsx examples/client/ollama.ts",
|
|
41
|
+
"example-client-openrouter": "tsx examples/client/openrouter.ts",
|
|
42
|
+
"example-client-litellm": "tsx examples/client/litellm.ts",
|
|
43
|
+
"example-client-typesafe": "tsx examples/client/typesafe.ts",
|
|
44
|
+
"example-two-agents": "tsx examples/client/two-agents.ts",
|
|
45
|
+
"example-gateway": "tsx examples/gateway/openrouter.ts",
|
|
46
|
+
"example-gateway-openrouter": "tsx examples/gateway/openrouter.ts",
|
|
47
|
+
"example-gateway-litellm": "tsx examples/gateway/litellm.ts",
|
|
48
|
+
"example-gateway-bedrock": "tsx examples/gateway/bedrock.ts"
|
|
49
|
+
},
|
|
50
|
+
"nx": {
|
|
51
|
+
"includedScripts": [
|
|
52
|
+
"build",
|
|
53
|
+
"lint",
|
|
54
|
+
"test"
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
"files": [
|
|
58
|
+
"dist/**/*"
|
|
59
|
+
],
|
|
60
|
+
"engines": {
|
|
61
|
+
"node": ">=22"
|
|
62
|
+
},
|
|
63
|
+
"dependencies": {
|
|
64
|
+
"@stigg/node-server-sdk": "6.1.0",
|
|
65
|
+
"@stigg/typescript": "0.1.0-beta.55",
|
|
66
|
+
"zod": "^4.6.1"
|
|
67
|
+
},
|
|
68
|
+
"devDependencies": {
|
|
69
|
+
"@anthropic-ai/sdk": "^0.124.0",
|
|
70
|
+
"@aws-sdk/client-bedrock-runtime": "^3.1150.0",
|
|
71
|
+
"@google/genai": "^2.28.0",
|
|
72
|
+
"@mistralai/mistralai": "^2.7.0",
|
|
73
|
+
"@openrouter/sdk": "^1.4.25",
|
|
74
|
+
"@typesafe-ai/sdk": "^0.6.0",
|
|
75
|
+
"dotenv": "^17.4.2",
|
|
76
|
+
"groq-sdk": "^1.6.0",
|
|
77
|
+
"ollama": "^0.6.4",
|
|
78
|
+
"openai": "^7.13.0",
|
|
79
|
+
"tsx": "^4.23.13"
|
|
80
|
+
},
|
|
81
|
+
"exports": {
|
|
82
|
+
".": {
|
|
83
|
+
"types": "./dist/index.d.ts",
|
|
84
|
+
"default": "./dist/index.js"
|
|
85
|
+
},
|
|
86
|
+
"./internal": {
|
|
87
|
+
"types": "./dist/internal.d.ts",
|
|
88
|
+
"default": "./dist/internal.js"
|
|
89
|
+
},
|
|
90
|
+
"./package.json": "./package.json"
|
|
91
|
+
}
|
|
6
92
|
}
|