@granular-software/sdk 0.4.37 → 0.4.38
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/dist/agent-evals.d.mts +16 -3
- package/dist/agent-evals.d.ts +16 -3
- package/dist/agent-evals.js +341 -105
- package/dist/agent-evals.js.map +1 -1
- package/dist/agent-evals.mjs +340 -105
- package/dist/agent-evals.mjs.map +1 -1
- package/dist/cli/index.js +129 -3
- package/dist/client-BNbWA9jQ.d.ts +1064 -0
- package/dist/client-HDJgcJC5.d.mts +1064 -0
- package/dist/index.d.mts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +231 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +225 -4
- package/dist/index.mjs.map +1 -1
- package/dist/spend-rzS1rlFr.d.mts +1559 -0
- package/dist/spend-rzS1rlFr.d.ts +1559 -0
- package/dist/spend.d.mts +2 -0
- package/dist/spend.d.ts +2 -0
- package/dist/spend.js +111 -0
- package/dist/spend.js.map +1 -0
- package/dist/spend.mjs +107 -0
- package/dist/spend.mjs.map +1 -0
- package/package.json +7 -1
- package/dist/client-eE9nTfvp.d.mts +0 -2483
- package/dist/client-eE9nTfvp.d.ts +0 -2483
package/dist/cli/index.js
CHANGED
|
@@ -19590,6 +19590,7 @@ function withPromptTranscriptTimeout(promise) {
|
|
|
19590
19590
|
var Session = class {
|
|
19591
19591
|
client;
|
|
19592
19592
|
clientId;
|
|
19593
|
+
initialQuota;
|
|
19593
19594
|
jobsMap = /* @__PURE__ */ new Map();
|
|
19594
19595
|
pendingAgentMessagesByJobId = /* @__PURE__ */ new Map();
|
|
19595
19596
|
eventListeners = /* @__PURE__ */ new Map();
|
|
@@ -19605,9 +19606,10 @@ var Session = class {
|
|
|
19605
19606
|
promptCache = /* @__PURE__ */ new Map();
|
|
19606
19607
|
/** Prompt ids locally answered before the document sync catches up. */
|
|
19607
19608
|
hiddenPromptIds = /* @__PURE__ */ new Set();
|
|
19608
|
-
constructor(client, clientId) {
|
|
19609
|
+
constructor(client, clientId, options = {}) {
|
|
19609
19610
|
this.client = client;
|
|
19610
19611
|
this.clientId = clientId || `client_${Date.now()}`;
|
|
19612
|
+
this.initialQuota = options.initialQuota || null;
|
|
19611
19613
|
this.setupEventHandlers();
|
|
19612
19614
|
this.setupToolInvokeHandler();
|
|
19613
19615
|
}
|
|
@@ -19656,6 +19658,16 @@ var Session = class {
|
|
|
19656
19658
|
get document() {
|
|
19657
19659
|
return this.client.doc;
|
|
19658
19660
|
}
|
|
19661
|
+
get quota() {
|
|
19662
|
+
return this.getQuota();
|
|
19663
|
+
}
|
|
19664
|
+
getQuota() {
|
|
19665
|
+
const quota = this.client.doc.billing?.quota;
|
|
19666
|
+
if (quota && typeof quota === "object") {
|
|
19667
|
+
return quota;
|
|
19668
|
+
}
|
|
19669
|
+
return this.initialQuota;
|
|
19670
|
+
}
|
|
19659
19671
|
get sessionId() {
|
|
19660
19672
|
return this.client.currentSessionId;
|
|
19661
19673
|
}
|
|
@@ -21511,6 +21523,110 @@ async function invokeRegisteredEffect(effectMap, request) {
|
|
|
21511
21523
|
return resolved.handler(request.input, context);
|
|
21512
21524
|
}
|
|
21513
21525
|
|
|
21526
|
+
// src/spend.ts
|
|
21527
|
+
function toGranularHttpBase(apiUrl) {
|
|
21528
|
+
const url = new URL(apiUrl);
|
|
21529
|
+
if (url.protocol === "ws:") {
|
|
21530
|
+
url.protocol = "http:";
|
|
21531
|
+
} else if (url.protocol === "wss:") {
|
|
21532
|
+
url.protocol = "https:";
|
|
21533
|
+
}
|
|
21534
|
+
url.pathname = url.pathname.replace(/\/ws\/connect$/, "").replace(/\/ws$/, "");
|
|
21535
|
+
if (!url.pathname || url.pathname === "/") {
|
|
21536
|
+
url.pathname = "/granular";
|
|
21537
|
+
}
|
|
21538
|
+
url.search = "";
|
|
21539
|
+
url.hash = "";
|
|
21540
|
+
return url.toString().replace(/\/$/, "");
|
|
21541
|
+
}
|
|
21542
|
+
function cleanIdPart(value) {
|
|
21543
|
+
return value.replace(/[^a-zA-Z0-9_-]+/g, "_").replace(/^_+|_+$/g, "");
|
|
21544
|
+
}
|
|
21545
|
+
function buildOpenAISpendEventId(usage, context = {}) {
|
|
21546
|
+
const requestId = usage.requestId?.trim();
|
|
21547
|
+
if (!requestId) return void 0;
|
|
21548
|
+
const scope = context.sessionId || context.environmentId || context.subjectId || context.sandboxId || "global";
|
|
21549
|
+
return ["spend", "openai", scope, requestId].map(cleanIdPart).join("_");
|
|
21550
|
+
}
|
|
21551
|
+
function pricingEffectiveAtSeconds(value) {
|
|
21552
|
+
if (!value) return null;
|
|
21553
|
+
const parsed = Date.parse(value);
|
|
21554
|
+
return Number.isFinite(parsed) ? Math.floor(parsed / 1e3) : null;
|
|
21555
|
+
}
|
|
21556
|
+
function compactContext(context) {
|
|
21557
|
+
return Object.fromEntries(
|
|
21558
|
+
Object.entries(context).filter(
|
|
21559
|
+
([, value]) => value != null && value !== ""
|
|
21560
|
+
)
|
|
21561
|
+
);
|
|
21562
|
+
}
|
|
21563
|
+
function omitTenantId(context) {
|
|
21564
|
+
const scopedContext = { ...context };
|
|
21565
|
+
delete scopedContext.tenantId;
|
|
21566
|
+
return scopedContext;
|
|
21567
|
+
}
|
|
21568
|
+
async function recordOpenAIUsageSpend(options) {
|
|
21569
|
+
const usageContext = compactContext({
|
|
21570
|
+
...options.usage.usageContext || {},
|
|
21571
|
+
...options.context || {}
|
|
21572
|
+
});
|
|
21573
|
+
const context = omitTenantId(usageContext);
|
|
21574
|
+
const spendEventId = options.usage.spendEventId || buildOpenAISpendEventId(options.usage, context);
|
|
21575
|
+
const metadata = {
|
|
21576
|
+
...options.metadata || {},
|
|
21577
|
+
...options.usage.rawUsage !== void 0 ? { openaiUsage: options.usage.rawUsage } : {},
|
|
21578
|
+
usageContext: context
|
|
21579
|
+
};
|
|
21580
|
+
const response = await fetch(
|
|
21581
|
+
`${toGranularHttpBase(options.apiUrl)}/control/spend/events`,
|
|
21582
|
+
{
|
|
21583
|
+
method: "POST",
|
|
21584
|
+
cache: "no-store",
|
|
21585
|
+
headers: {
|
|
21586
|
+
Authorization: `Bearer ${options.token}`,
|
|
21587
|
+
"Content-Type": "application/json"
|
|
21588
|
+
},
|
|
21589
|
+
body: JSON.stringify({
|
|
21590
|
+
...spendEventId ? { spendEventId } : {},
|
|
21591
|
+
sandboxId: context.sandboxId || null,
|
|
21592
|
+
environmentId: context.environmentId || null,
|
|
21593
|
+
sessionId: context.sessionId || null,
|
|
21594
|
+
subjectId: context.subjectId || null,
|
|
21595
|
+
permissionProfileId: context.permissionProfileId || null,
|
|
21596
|
+
source: "openai",
|
|
21597
|
+
lineItemType: "llm_tokens",
|
|
21598
|
+
provider: options.usage.provider,
|
|
21599
|
+
model: options.usage.model,
|
|
21600
|
+
operation: options.usage.operation || "chat.completions",
|
|
21601
|
+
requestId: options.usage.requestId || null,
|
|
21602
|
+
inputTokens: options.usage.inputTokens,
|
|
21603
|
+
outputTokens: options.usage.outputTokens,
|
|
21604
|
+
cachedInputTokens: options.usage.cachedInputTokens,
|
|
21605
|
+
reasoningTokens: options.usage.reasoningTokens,
|
|
21606
|
+
quantity: options.usage.totalTokens,
|
|
21607
|
+
quantityUnit: "tokens",
|
|
21608
|
+
inputPricePerMillionMicros: options.usage.inputPricePerMillionMicros,
|
|
21609
|
+
cachedInputPricePerMillionMicros: options.usage.cachedInputPricePerMillionMicros,
|
|
21610
|
+
outputPricePerMillionMicros: options.usage.outputPricePerMillionMicros,
|
|
21611
|
+
amountMicros: options.usage.amountMicros,
|
|
21612
|
+
currency: options.usage.currency,
|
|
21613
|
+
pricingSource: options.usage.pricingSource,
|
|
21614
|
+
pricingEffectiveAt: pricingEffectiveAtSeconds(
|
|
21615
|
+
options.usage.pricingEffectiveAt
|
|
21616
|
+
),
|
|
21617
|
+
estimated: false,
|
|
21618
|
+
metadata
|
|
21619
|
+
})
|
|
21620
|
+
}
|
|
21621
|
+
);
|
|
21622
|
+
if (!response.ok) {
|
|
21623
|
+
throw new Error(
|
|
21624
|
+
`Granular spend event failed (${response.status}): ${await response.text()}`
|
|
21625
|
+
);
|
|
21626
|
+
}
|
|
21627
|
+
return response.json();
|
|
21628
|
+
}
|
|
21629
|
+
|
|
21514
21630
|
// src/manifest-metamodels.ts
|
|
21515
21631
|
function buildFieldMetamodelMutations(fieldPath, spec) {
|
|
21516
21632
|
return DEFAULT_METAMODEL_PACKAGES.flatMap(
|
|
@@ -23012,7 +23128,7 @@ var EnvironmentSession = class extends Session {
|
|
|
23012
23128
|
/** The last known graph container status, updated by checkReadiness() or on heartbeat */
|
|
23013
23129
|
graphContainerStatus = null;
|
|
23014
23130
|
constructor(client, environment, clientId, options = {}) {
|
|
23015
|
-
super(client, clientId);
|
|
23131
|
+
super(client, clientId, { initialQuota: options.initialQuota });
|
|
23016
23132
|
this.environment = environment;
|
|
23017
23133
|
this.sessionDataRoutePrefix = options.sessionDataRoutePrefix || "/orchestrator/ws/sessions";
|
|
23018
23134
|
}
|
|
@@ -23811,6 +23927,15 @@ var Granular = class _Granular {
|
|
|
23811
23927
|
const environment = this.bindEnvironmentHandle(envData);
|
|
23812
23928
|
return this.bindWebSocketEnvironmentSession(environment, clientId, minted);
|
|
23813
23929
|
}
|
|
23930
|
+
async recordOpenAIUsageSpend(usage, context, options) {
|
|
23931
|
+
return recordOpenAIUsageSpend({
|
|
23932
|
+
apiUrl: this.apiUrl,
|
|
23933
|
+
token: this.apiKey,
|
|
23934
|
+
usage,
|
|
23935
|
+
context,
|
|
23936
|
+
metadata: options?.metadata
|
|
23937
|
+
});
|
|
23938
|
+
}
|
|
23814
23939
|
/**
|
|
23815
23940
|
* Mark a session closed in the control plane. If `environment` is the connected handle for that
|
|
23816
23941
|
* `sessionId`, disconnects the WebSocket so the runtime tears down cleanly.
|
|
@@ -23965,7 +24090,8 @@ var Granular = class _Granular {
|
|
|
23965
24090
|
const environmentSession = new EnvironmentSession(
|
|
23966
24091
|
client,
|
|
23967
24092
|
environment,
|
|
23968
|
-
clientId
|
|
24093
|
+
clientId,
|
|
24094
|
+
{ initialQuota: session2.quota || null }
|
|
23969
24095
|
);
|
|
23970
24096
|
await environmentSession.hello();
|
|
23971
24097
|
return environmentSession;
|