@granular-software/sdk 0.4.37 → 0.4.39
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 +17 -3
- package/dist/agent-evals.d.ts +17 -3
- package/dist/agent-evals.js +1067 -153
- package/dist/agent-evals.js.map +1 -1
- package/dist/agent-evals.mjs +1066 -154
- package/dist/agent-evals.mjs.map +1 -1
- package/dist/agent-harness.d.mts +9 -2
- package/dist/agent-harness.d.ts +9 -2
- package/dist/agent-harness.js +273 -5
- package/dist/agent-harness.js.map +1 -1
- package/dist/agent-harness.mjs +271 -6
- package/dist/agent-harness.mjs.map +1 -1
- package/dist/cli/index.js +293 -34
- package/dist/client-BZ8NuQ_e.d.ts +1080 -0
- package/dist/client-CBQFvuKf.d.mts +1080 -0
- package/dist/index.d.mts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +668 -39
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +659 -40
- package/dist/index.mjs.map +1 -1
- package/dist/spend-tAz2a16I.d.mts +1593 -0
- package/dist/spend-tAz2a16I.d.ts +1593 -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
|
@@ -18991,7 +18991,10 @@ var WSClient = class {
|
|
|
18991
18991
|
if (!expiresAt) {
|
|
18992
18992
|
return;
|
|
18993
18993
|
}
|
|
18994
|
-
const refreshInMs = Math.max(
|
|
18994
|
+
const refreshInMs = Math.max(
|
|
18995
|
+
1e3,
|
|
18996
|
+
expiresAt - Date.now() - TOKEN_REFRESH_LEEWAY_MS
|
|
18997
|
+
);
|
|
18995
18998
|
const delay = Math.min(refreshInMs, MAX_TIMER_DELAY_MS);
|
|
18996
18999
|
this.tokenRefreshTimer = setTimeout(() => {
|
|
18997
19000
|
void this.refreshTokenInBackground();
|
|
@@ -19037,7 +19040,10 @@ var WSClient = class {
|
|
|
19037
19040
|
return refreshedToken;
|
|
19038
19041
|
} catch (error2) {
|
|
19039
19042
|
if (expiresAt > Date.now()) {
|
|
19040
|
-
console.warn(
|
|
19043
|
+
console.warn(
|
|
19044
|
+
"[Granular] Token refresh failed, using current token:",
|
|
19045
|
+
error2
|
|
19046
|
+
);
|
|
19041
19047
|
return this.token;
|
|
19042
19048
|
}
|
|
19043
19049
|
throw error2;
|
|
@@ -19064,7 +19070,9 @@ var WSClient = class {
|
|
|
19064
19070
|
}
|
|
19065
19071
|
}
|
|
19066
19072
|
if (!WebSocketClass) {
|
|
19067
|
-
throw new Error(
|
|
19073
|
+
throw new Error(
|
|
19074
|
+
'No WebSocket implementation found. If using Node.js, please install "ws" and pass the constructor to the SDK options: { WebSocketCtor: WebSocket }.'
|
|
19075
|
+
);
|
|
19068
19076
|
}
|
|
19069
19077
|
return new Promise((resolve2, reject) => {
|
|
19070
19078
|
try {
|
|
@@ -19196,7 +19204,10 @@ var WSClient = class {
|
|
|
19196
19204
|
try {
|
|
19197
19205
|
this.options.onUnexpectedClose(info2);
|
|
19198
19206
|
} catch (callbackError) {
|
|
19199
|
-
console.error(
|
|
19207
|
+
console.error(
|
|
19208
|
+
"[Granular] onUnexpectedClose callback failed:",
|
|
19209
|
+
callbackError
|
|
19210
|
+
);
|
|
19200
19211
|
}
|
|
19201
19212
|
}
|
|
19202
19213
|
this.reconnectTimer = setTimeout(() => {
|
|
@@ -19213,7 +19224,10 @@ var WSClient = class {
|
|
|
19213
19224
|
try {
|
|
19214
19225
|
this.options.onReconnectError(reconnectInfo);
|
|
19215
19226
|
} catch (callbackError) {
|
|
19216
|
-
console.error(
|
|
19227
|
+
console.error(
|
|
19228
|
+
"[Granular] onReconnectError callback failed:",
|
|
19229
|
+
callbackError
|
|
19230
|
+
);
|
|
19217
19231
|
}
|
|
19218
19232
|
}
|
|
19219
19233
|
});
|
|
@@ -19222,7 +19236,10 @@ var WSClient = class {
|
|
|
19222
19236
|
}
|
|
19223
19237
|
handleMessage(message) {
|
|
19224
19238
|
if (typeof message !== "object" || message === null) return;
|
|
19225
|
-
debugWs(
|
|
19239
|
+
debugWs(
|
|
19240
|
+
"[Granular DEBUG] Received message:",
|
|
19241
|
+
JSON.stringify(message).slice(0, 500)
|
|
19242
|
+
);
|
|
19226
19243
|
if ("type" in message && message.type === "sync") {
|
|
19227
19244
|
const syncMessage = message;
|
|
19228
19245
|
let bytes;
|
|
@@ -19252,21 +19269,39 @@ var WSClient = class {
|
|
|
19252
19269
|
this.syncState = newSyncState;
|
|
19253
19270
|
const docAny = this.doc;
|
|
19254
19271
|
if (docAny.catalog) {
|
|
19255
|
-
debugWs(
|
|
19256
|
-
|
|
19272
|
+
debugWs(
|
|
19273
|
+
"[Granular DEBUG] Doc catalog sync applied. Keys in catalog:",
|
|
19274
|
+
Object.keys(docAny.catalog || {})
|
|
19275
|
+
);
|
|
19276
|
+
debugWs(
|
|
19277
|
+
"[Granular DEBUG] RawToolCatalogs:",
|
|
19278
|
+
Object.keys(docAny.catalog.rawToolCatalogs || {})
|
|
19279
|
+
);
|
|
19257
19280
|
} else {
|
|
19258
|
-
debugWs(
|
|
19281
|
+
debugWs(
|
|
19282
|
+
"[Granular DEBUG] Doc synced but no catalog yet. Keys in doc:",
|
|
19283
|
+
Object.keys(docAny)
|
|
19284
|
+
);
|
|
19259
19285
|
}
|
|
19260
19286
|
this.emit("sync", this.doc);
|
|
19261
19287
|
} catch (e) {
|
|
19262
19288
|
try {
|
|
19263
|
-
debugWs(
|
|
19289
|
+
debugWs(
|
|
19290
|
+
"[Granular DEBUG] receiveSyncMessage failed, trying applyChanges..."
|
|
19291
|
+
);
|
|
19264
19292
|
const [newDoc] = Automerge__namespace.applyChanges(this.doc, [bytes]);
|
|
19265
19293
|
this.doc = newDoc;
|
|
19266
19294
|
this.emit("sync", this.doc);
|
|
19267
|
-
debugWs(
|
|
19295
|
+
debugWs(
|
|
19296
|
+
"[Granular DEBUG] applyChanges succeeded. Doc:",
|
|
19297
|
+
JSON.stringify(Automerge__namespace.toJS(this.doc))
|
|
19298
|
+
);
|
|
19268
19299
|
} catch (applyError) {
|
|
19269
|
-
console.warn(
|
|
19300
|
+
console.warn(
|
|
19301
|
+
"[Granular] Failed to apply sync message (both sync & applyChanges)",
|
|
19302
|
+
e,
|
|
19303
|
+
applyError
|
|
19304
|
+
);
|
|
19270
19305
|
}
|
|
19271
19306
|
}
|
|
19272
19307
|
return;
|
|
@@ -19275,10 +19310,16 @@ var WSClient = class {
|
|
|
19275
19310
|
const snapshotMessage = message;
|
|
19276
19311
|
try {
|
|
19277
19312
|
const bytes = new Uint8Array(snapshotMessage.data);
|
|
19278
|
-
debugWs(
|
|
19313
|
+
debugWs(
|
|
19314
|
+
"[Granular DEBUG] Loading Automerge session snapshot bytes:",
|
|
19315
|
+
bytes.length
|
|
19316
|
+
);
|
|
19279
19317
|
this.doc = Automerge__namespace.load(bytes);
|
|
19280
19318
|
this.emit("sync", this.doc);
|
|
19281
|
-
debugWs(
|
|
19319
|
+
debugWs(
|
|
19320
|
+
"[Granular DEBUG] Automerge session snapshot loaded. Doc:",
|
|
19321
|
+
JSON.stringify(Automerge__namespace.toJS(this.doc))
|
|
19322
|
+
);
|
|
19282
19323
|
} catch (e) {
|
|
19283
19324
|
console.warn("[Granular] Failed to load snapshot message", e);
|
|
19284
19325
|
}
|
|
@@ -19290,6 +19331,7 @@ var WSClient = class {
|
|
|
19290
19331
|
const bytes = new Uint8Array(changeMessage.data);
|
|
19291
19332
|
const [newDoc] = Automerge__namespace.applyChanges(this.doc, [bytes]);
|
|
19292
19333
|
this.doc = newDoc;
|
|
19334
|
+
this.emit("change", changeMessage);
|
|
19293
19335
|
this.emit("sync", this.doc);
|
|
19294
19336
|
} catch (e) {
|
|
19295
19337
|
console.warn("[Granular] Failed to apply change message", e);
|
|
@@ -19302,12 +19344,16 @@ var WSClient = class {
|
|
|
19302
19344
|
if (pending) {
|
|
19303
19345
|
if (response.type === "rpc_error") {
|
|
19304
19346
|
pending.reject(
|
|
19305
|
-
new Error(
|
|
19347
|
+
new Error(
|
|
19348
|
+
`RPC error: ${response.error?.message || "Unknown error"}`
|
|
19349
|
+
)
|
|
19306
19350
|
);
|
|
19307
19351
|
} else {
|
|
19308
19352
|
pending.resolve(response.result);
|
|
19309
19353
|
}
|
|
19310
|
-
this.messageQueue = this.messageQueue.filter(
|
|
19354
|
+
this.messageQueue = this.messageQueue.filter(
|
|
19355
|
+
(q) => q.id !== response.id
|
|
19356
|
+
);
|
|
19311
19357
|
}
|
|
19312
19358
|
return;
|
|
19313
19359
|
}
|
|
@@ -19590,6 +19636,7 @@ function withPromptTranscriptTimeout(promise) {
|
|
|
19590
19636
|
var Session = class {
|
|
19591
19637
|
client;
|
|
19592
19638
|
clientId;
|
|
19639
|
+
initialQuota;
|
|
19593
19640
|
jobsMap = /* @__PURE__ */ new Map();
|
|
19594
19641
|
pendingAgentMessagesByJobId = /* @__PURE__ */ new Map();
|
|
19595
19642
|
eventListeners = /* @__PURE__ */ new Map();
|
|
@@ -19605,9 +19652,10 @@ var Session = class {
|
|
|
19605
19652
|
promptCache = /* @__PURE__ */ new Map();
|
|
19606
19653
|
/** Prompt ids locally answered before the document sync catches up. */
|
|
19607
19654
|
hiddenPromptIds = /* @__PURE__ */ new Set();
|
|
19608
|
-
constructor(client, clientId) {
|
|
19655
|
+
constructor(client, clientId, options = {}) {
|
|
19609
19656
|
this.client = client;
|
|
19610
19657
|
this.clientId = clientId || `client_${Date.now()}`;
|
|
19658
|
+
this.initialQuota = options.initialQuota || null;
|
|
19611
19659
|
this.setupEventHandlers();
|
|
19612
19660
|
this.setupToolInvokeHandler();
|
|
19613
19661
|
}
|
|
@@ -19656,6 +19704,16 @@ var Session = class {
|
|
|
19656
19704
|
get document() {
|
|
19657
19705
|
return this.client.doc;
|
|
19658
19706
|
}
|
|
19707
|
+
get quota() {
|
|
19708
|
+
return this.getQuota();
|
|
19709
|
+
}
|
|
19710
|
+
getQuota() {
|
|
19711
|
+
const quota = this.client.doc.billing?.quota;
|
|
19712
|
+
if (quota && typeof quota === "object") {
|
|
19713
|
+
return quota;
|
|
19714
|
+
}
|
|
19715
|
+
return this.initialQuota;
|
|
19716
|
+
}
|
|
19659
19717
|
get sessionId() {
|
|
19660
19718
|
return this.client.currentSessionId;
|
|
19661
19719
|
}
|
|
@@ -21084,9 +21142,10 @@ function normalizeShowRefs(value) {
|
|
|
21084
21142
|
const show = {
|
|
21085
21143
|
entryPaths: normalizeRefs(record.entryPaths),
|
|
21086
21144
|
listNames: normalizeRefs(record.listNames),
|
|
21087
|
-
variableNames: normalizeRefs(record.variableNames)
|
|
21145
|
+
variableNames: normalizeRefs(record.variableNames),
|
|
21146
|
+
fileIds: normalizeRefs(record.fileIds)
|
|
21088
21147
|
};
|
|
21089
|
-
return show.entryPaths || show.listNames || show.variableNames ? show : void 0;
|
|
21148
|
+
return show.entryPaths || show.listNames || show.variableNames || show.fileIds ? show : void 0;
|
|
21090
21149
|
}
|
|
21091
21150
|
function stringifyTranscriptValue(value, fallback2 = "") {
|
|
21092
21151
|
if (typeof value === "string") {
|
|
@@ -21294,7 +21353,10 @@ function buildJobCodeEntry(jobId, job2) {
|
|
|
21294
21353
|
jobId,
|
|
21295
21354
|
code,
|
|
21296
21355
|
jobStatus,
|
|
21297
|
-
jobResultPreview: stringifyTranscriptValue(
|
|
21356
|
+
jobResultPreview: stringifyTranscriptValue(
|
|
21357
|
+
job2.result,
|
|
21358
|
+
"No job result recorded."
|
|
21359
|
+
),
|
|
21298
21360
|
error: error2,
|
|
21299
21361
|
source: "job_code"
|
|
21300
21362
|
};
|
|
@@ -21303,12 +21365,16 @@ function buildSessionTranscript(input) {
|
|
|
21303
21365
|
const liveDoc = input.liveDoc || null;
|
|
21304
21366
|
const sessionHeap = input.sessionHeap || EMPTY_HEAP;
|
|
21305
21367
|
const transcript = [];
|
|
21306
|
-
const conversationMessages = asArray(
|
|
21368
|
+
const conversationMessages = asArray(
|
|
21369
|
+
asRecord3(liveDoc?.conversation)?.messages
|
|
21370
|
+
).map((message) => normalizeConversationMessage(message)).filter((message) => Boolean(message));
|
|
21307
21371
|
const conversationPromptIds = new Set(
|
|
21308
21372
|
conversationMessages.map((message) => message.promptId).filter((promptId) => Boolean(promptId))
|
|
21309
21373
|
);
|
|
21310
21374
|
const assistantConversationJobIds = new Set(
|
|
21311
|
-
conversationMessages.filter(
|
|
21375
|
+
conversationMessages.filter(
|
|
21376
|
+
(message) => message.role === "assistant" && Boolean(message.jobId)
|
|
21377
|
+
).map((message) => message.jobId)
|
|
21312
21378
|
);
|
|
21313
21379
|
transcript.push(...conversationMessages);
|
|
21314
21380
|
const jobsById = asRecord3(asRecord3(liveDoc?.jobs)?.byId) || {};
|
|
@@ -21326,7 +21392,10 @@ function buildSessionTranscript(input) {
|
|
|
21326
21392
|
...normalizePromptEntries(jobId, job2.prompts, conversationPromptIds)
|
|
21327
21393
|
);
|
|
21328
21394
|
if (!assistantConversationJobIds.has(jobId)) {
|
|
21329
|
-
const agentEntries = normalizeAgentMessageEntries(
|
|
21395
|
+
const agentEntries = normalizeAgentMessageEntries(
|
|
21396
|
+
jobId,
|
|
21397
|
+
job2.agentMessages
|
|
21398
|
+
);
|
|
21330
21399
|
if (agentEntries.length > 0) {
|
|
21331
21400
|
transcript.push(...agentEntries);
|
|
21332
21401
|
} else {
|
|
@@ -21511,6 +21580,110 @@ async function invokeRegisteredEffect(effectMap, request) {
|
|
|
21511
21580
|
return resolved.handler(request.input, context);
|
|
21512
21581
|
}
|
|
21513
21582
|
|
|
21583
|
+
// src/spend.ts
|
|
21584
|
+
function toGranularHttpBase(apiUrl) {
|
|
21585
|
+
const url = new URL(apiUrl);
|
|
21586
|
+
if (url.protocol === "ws:") {
|
|
21587
|
+
url.protocol = "http:";
|
|
21588
|
+
} else if (url.protocol === "wss:") {
|
|
21589
|
+
url.protocol = "https:";
|
|
21590
|
+
}
|
|
21591
|
+
url.pathname = url.pathname.replace(/\/ws\/connect$/, "").replace(/\/ws$/, "");
|
|
21592
|
+
if (!url.pathname || url.pathname === "/") {
|
|
21593
|
+
url.pathname = "/granular";
|
|
21594
|
+
}
|
|
21595
|
+
url.search = "";
|
|
21596
|
+
url.hash = "";
|
|
21597
|
+
return url.toString().replace(/\/$/, "");
|
|
21598
|
+
}
|
|
21599
|
+
function cleanIdPart(value) {
|
|
21600
|
+
return value.replace(/[^a-zA-Z0-9_-]+/g, "_").replace(/^_+|_+$/g, "");
|
|
21601
|
+
}
|
|
21602
|
+
function buildOpenAISpendEventId(usage, context = {}) {
|
|
21603
|
+
const requestId = usage.requestId?.trim();
|
|
21604
|
+
if (!requestId) return void 0;
|
|
21605
|
+
const scope = context.sessionId || context.environmentId || context.subjectId || context.sandboxId || "global";
|
|
21606
|
+
return ["spend", "openai", scope, requestId].map(cleanIdPart).join("_");
|
|
21607
|
+
}
|
|
21608
|
+
function pricingEffectiveAtSeconds(value) {
|
|
21609
|
+
if (!value) return null;
|
|
21610
|
+
const parsed = Date.parse(value);
|
|
21611
|
+
return Number.isFinite(parsed) ? Math.floor(parsed / 1e3) : null;
|
|
21612
|
+
}
|
|
21613
|
+
function compactContext(context) {
|
|
21614
|
+
return Object.fromEntries(
|
|
21615
|
+
Object.entries(context).filter(
|
|
21616
|
+
([, value]) => value != null && value !== ""
|
|
21617
|
+
)
|
|
21618
|
+
);
|
|
21619
|
+
}
|
|
21620
|
+
function omitTenantId(context) {
|
|
21621
|
+
const scopedContext = { ...context };
|
|
21622
|
+
delete scopedContext.tenantId;
|
|
21623
|
+
return scopedContext;
|
|
21624
|
+
}
|
|
21625
|
+
async function recordOpenAIUsageSpend(options) {
|
|
21626
|
+
const usageContext = compactContext({
|
|
21627
|
+
...options.usage.usageContext || {},
|
|
21628
|
+
...options.context || {}
|
|
21629
|
+
});
|
|
21630
|
+
const context = omitTenantId(usageContext);
|
|
21631
|
+
const spendEventId = options.usage.spendEventId || buildOpenAISpendEventId(options.usage, context);
|
|
21632
|
+
const metadata = {
|
|
21633
|
+
...options.metadata || {},
|
|
21634
|
+
...options.usage.rawUsage !== void 0 ? { openaiUsage: options.usage.rawUsage } : {},
|
|
21635
|
+
usageContext: context
|
|
21636
|
+
};
|
|
21637
|
+
const response = await fetch(
|
|
21638
|
+
`${toGranularHttpBase(options.apiUrl)}/control/spend/events`,
|
|
21639
|
+
{
|
|
21640
|
+
method: "POST",
|
|
21641
|
+
cache: "no-store",
|
|
21642
|
+
headers: {
|
|
21643
|
+
Authorization: `Bearer ${options.token}`,
|
|
21644
|
+
"Content-Type": "application/json"
|
|
21645
|
+
},
|
|
21646
|
+
body: JSON.stringify({
|
|
21647
|
+
...spendEventId ? { spendEventId } : {},
|
|
21648
|
+
sandboxId: context.sandboxId || null,
|
|
21649
|
+
environmentId: context.environmentId || null,
|
|
21650
|
+
sessionId: context.sessionId || null,
|
|
21651
|
+
subjectId: context.subjectId || null,
|
|
21652
|
+
permissionProfileId: context.permissionProfileId || null,
|
|
21653
|
+
source: "openai",
|
|
21654
|
+
lineItemType: "llm_tokens",
|
|
21655
|
+
provider: options.usage.provider,
|
|
21656
|
+
model: options.usage.model,
|
|
21657
|
+
operation: options.usage.operation || "chat.completions",
|
|
21658
|
+
requestId: options.usage.requestId || null,
|
|
21659
|
+
inputTokens: options.usage.inputTokens,
|
|
21660
|
+
outputTokens: options.usage.outputTokens,
|
|
21661
|
+
cachedInputTokens: options.usage.cachedInputTokens,
|
|
21662
|
+
reasoningTokens: options.usage.reasoningTokens,
|
|
21663
|
+
quantity: options.usage.totalTokens,
|
|
21664
|
+
quantityUnit: "tokens",
|
|
21665
|
+
inputPricePerMillionMicros: options.usage.inputPricePerMillionMicros,
|
|
21666
|
+
cachedInputPricePerMillionMicros: options.usage.cachedInputPricePerMillionMicros,
|
|
21667
|
+
outputPricePerMillionMicros: options.usage.outputPricePerMillionMicros,
|
|
21668
|
+
amountMicros: options.usage.amountMicros,
|
|
21669
|
+
currency: options.usage.currency,
|
|
21670
|
+
pricingSource: options.usage.pricingSource,
|
|
21671
|
+
pricingEffectiveAt: pricingEffectiveAtSeconds(
|
|
21672
|
+
options.usage.pricingEffectiveAt
|
|
21673
|
+
),
|
|
21674
|
+
estimated: false,
|
|
21675
|
+
metadata
|
|
21676
|
+
})
|
|
21677
|
+
}
|
|
21678
|
+
);
|
|
21679
|
+
if (!response.ok) {
|
|
21680
|
+
throw new Error(
|
|
21681
|
+
`Granular spend event failed (${response.status}): ${await response.text()}`
|
|
21682
|
+
);
|
|
21683
|
+
}
|
|
21684
|
+
return response.json();
|
|
21685
|
+
}
|
|
21686
|
+
|
|
21514
21687
|
// src/manifest-metamodels.ts
|
|
21515
21688
|
function buildFieldMetamodelMutations(fieldPath, spec) {
|
|
21516
21689
|
return DEFAULT_METAMODEL_PACKAGES.flatMap(
|
|
@@ -21575,6 +21748,25 @@ var LOCAL_CONTROL_REQUEST_RETRY_DELAY_MS = 500;
|
|
|
21575
21748
|
var SESSION_DATA_REQUEST_RETRY_COUNT = 4;
|
|
21576
21749
|
var SESSION_DATA_REQUEST_RETRY_DELAY_MS = 500;
|
|
21577
21750
|
var EFFECT_HOST_CONNECT_TIMEOUT_MS = 15e3;
|
|
21751
|
+
function filenameFromUploadBody(body) {
|
|
21752
|
+
const maybe = body;
|
|
21753
|
+
return typeof maybe.name === "string" && maybe.name.trim() ? maybe.name.trim() : null;
|
|
21754
|
+
}
|
|
21755
|
+
function contentTypeFromUploadBody(body) {
|
|
21756
|
+
const maybe = body;
|
|
21757
|
+
return typeof maybe.type === "string" && maybe.type.trim() ? maybe.type.trim() : null;
|
|
21758
|
+
}
|
|
21759
|
+
function bodyInitFromSessionFileUpload(body) {
|
|
21760
|
+
if (typeof body === "string") return body;
|
|
21761
|
+
if (body instanceof ArrayBuffer) return body;
|
|
21762
|
+
if (ArrayBuffer.isView(body)) {
|
|
21763
|
+
return body.buffer.slice(
|
|
21764
|
+
body.byteOffset,
|
|
21765
|
+
body.byteOffset + body.byteLength
|
|
21766
|
+
);
|
|
21767
|
+
}
|
|
21768
|
+
return body;
|
|
21769
|
+
}
|
|
21578
21770
|
var EFFECT_CATALOG_SYNC_TIMEOUT_MS = 3e4;
|
|
21579
21771
|
var EFFECT_CATALOG_SYNC_RETRY_COUNT = 3;
|
|
21580
21772
|
var EFFECT_CATALOG_SYNC_RETRY_DELAY_MS = 1e3;
|
|
@@ -23012,7 +23204,7 @@ var EnvironmentSession = class extends Session {
|
|
|
23012
23204
|
/** The last known graph container status, updated by checkReadiness() or on heartbeat */
|
|
23013
23205
|
graphContainerStatus = null;
|
|
23014
23206
|
constructor(client, environment, clientId, options = {}) {
|
|
23015
|
-
super(client, clientId);
|
|
23207
|
+
super(client, clientId, { initialQuota: options.initialQuota });
|
|
23016
23208
|
this.environment = environment;
|
|
23017
23209
|
this.sessionDataRoutePrefix = options.sessionDataRoutePrefix || "/orchestrator/ws/sessions";
|
|
23018
23210
|
}
|
|
@@ -23059,7 +23251,7 @@ var EnvironmentSession = class extends Session {
|
|
|
23059
23251
|
const doc = this.document;
|
|
23060
23252
|
return normalizeHeapSnapshot(doc?.heap);
|
|
23061
23253
|
}
|
|
23062
|
-
|
|
23254
|
+
buildSessionDataUrl(path7, query) {
|
|
23063
23255
|
const searchParams = new URLSearchParams();
|
|
23064
23256
|
for (const [key, value] of Object.entries(query || {})) {
|
|
23065
23257
|
if (value !== null && typeof value !== "undefined" && value !== "") {
|
|
@@ -23067,20 +23259,21 @@ var EnvironmentSession = class extends Session {
|
|
|
23067
23259
|
}
|
|
23068
23260
|
}
|
|
23069
23261
|
const queryString = searchParams.toString();
|
|
23070
|
-
|
|
23071
|
-
|
|
23262
|
+
return `${this.environment.runtimeBaseUrl}${this.sessionDataRoutePrefix}/${encodeURIComponent(this.sessionId)}${path7}${queryString ? `?${queryString}` : ""}`;
|
|
23263
|
+
}
|
|
23264
|
+
async sessionDataFetch(path7, query, init2 = {}) {
|
|
23265
|
+
const url = this.buildSessionDataUrl(path7, query);
|
|
23072
23266
|
for (let attempt = 1; attempt <= SESSION_DATA_REQUEST_RETRY_COUNT; attempt += 1) {
|
|
23073
23267
|
try {
|
|
23268
|
+
const headers = new Headers(init2.headers);
|
|
23269
|
+
headers.set("Authorization", `Bearer ${this.environment.authToken}`);
|
|
23074
23270
|
const response = await fetch(url, {
|
|
23075
23271
|
method: init2.method || "GET",
|
|
23076
|
-
headers
|
|
23077
|
-
|
|
23078
|
-
"Content-Type": "application/json"
|
|
23079
|
-
},
|
|
23080
|
-
...typeof body === "undefined" ? {} : { body }
|
|
23272
|
+
headers,
|
|
23273
|
+
...typeof init2.body === "undefined" ? {} : { body: init2.body }
|
|
23081
23274
|
});
|
|
23082
23275
|
if (response.ok) {
|
|
23083
|
-
return response
|
|
23276
|
+
return response;
|
|
23084
23277
|
}
|
|
23085
23278
|
const errorText = await response.text();
|
|
23086
23279
|
const error2 = new Error(
|
|
@@ -23101,6 +23294,15 @@ var EnvironmentSession = class extends Session {
|
|
|
23101
23294
|
}
|
|
23102
23295
|
throw new Error(`Session data API Error: exhausted retries for ${url}`);
|
|
23103
23296
|
}
|
|
23297
|
+
async sessionDataRequest(path7, query, init2 = {}) {
|
|
23298
|
+
const body = typeof init2.body === "undefined" ? void 0 : JSON.stringify(init2.body);
|
|
23299
|
+
const response = await this.sessionDataFetch(path7, query, {
|
|
23300
|
+
method: init2.method || "GET",
|
|
23301
|
+
headers: { "Content-Type": "application/json" },
|
|
23302
|
+
...typeof body === "undefined" ? {} : { body }
|
|
23303
|
+
});
|
|
23304
|
+
return response.json();
|
|
23305
|
+
}
|
|
23104
23306
|
async collectAllSessionItems(listPage) {
|
|
23105
23307
|
const items = [];
|
|
23106
23308
|
let cursor = null;
|
|
@@ -23141,6 +23343,53 @@ var EnvironmentSession = class extends Session {
|
|
|
23141
23343
|
)
|
|
23142
23344
|
};
|
|
23143
23345
|
}
|
|
23346
|
+
get files() {
|
|
23347
|
+
return {
|
|
23348
|
+
list: (options = {}) => this.sessionDataRequest(
|
|
23349
|
+
"/files",
|
|
23350
|
+
options
|
|
23351
|
+
),
|
|
23352
|
+
get: (fileId) => this.sessionDataRequest(
|
|
23353
|
+
`/files/${encodeURIComponent(fileId)}`
|
|
23354
|
+
),
|
|
23355
|
+
upload: async (body, options = {}) => {
|
|
23356
|
+
const headers = new Headers({
|
|
23357
|
+
"Content-Type": options.contentType || contentTypeFromUploadBody(body) || "application/octet-stream",
|
|
23358
|
+
"x-granular-filename": options.filename || filenameFromUploadBody(body) || "upload",
|
|
23359
|
+
"x-granular-file-source": options.source || "sdk"
|
|
23360
|
+
});
|
|
23361
|
+
if (options.parentFileIds?.length) {
|
|
23362
|
+
headers.set(
|
|
23363
|
+
"x-granular-parent-file-ids",
|
|
23364
|
+
JSON.stringify(options.parentFileIds)
|
|
23365
|
+
);
|
|
23366
|
+
}
|
|
23367
|
+
if (options.metadata) {
|
|
23368
|
+
headers.set(
|
|
23369
|
+
"x-granular-file-metadata",
|
|
23370
|
+
JSON.stringify(options.metadata)
|
|
23371
|
+
);
|
|
23372
|
+
}
|
|
23373
|
+
const response = await this.sessionDataFetch("/files", void 0, {
|
|
23374
|
+
method: "POST",
|
|
23375
|
+
headers,
|
|
23376
|
+
body: bodyInitFromSessionFileUpload(body)
|
|
23377
|
+
});
|
|
23378
|
+
return response.json();
|
|
23379
|
+
},
|
|
23380
|
+
download: async (fileId) => {
|
|
23381
|
+
const response = await this.sessionDataFetch(
|
|
23382
|
+
`/files/${encodeURIComponent(fileId)}/content`
|
|
23383
|
+
);
|
|
23384
|
+
return response.arrayBuffer();
|
|
23385
|
+
},
|
|
23386
|
+
delete: (fileId) => this.sessionDataRequest(
|
|
23387
|
+
`/files/${encodeURIComponent(fileId)}`,
|
|
23388
|
+
void 0,
|
|
23389
|
+
{ method: "DELETE" }
|
|
23390
|
+
)
|
|
23391
|
+
};
|
|
23392
|
+
}
|
|
23144
23393
|
get heap() {
|
|
23145
23394
|
return {
|
|
23146
23395
|
entries: {
|
|
@@ -23811,6 +24060,15 @@ var Granular = class _Granular {
|
|
|
23811
24060
|
const environment = this.bindEnvironmentHandle(envData);
|
|
23812
24061
|
return this.bindWebSocketEnvironmentSession(environment, clientId, minted);
|
|
23813
24062
|
}
|
|
24063
|
+
async recordOpenAIUsageSpend(usage, context, options) {
|
|
24064
|
+
return recordOpenAIUsageSpend({
|
|
24065
|
+
apiUrl: this.apiUrl,
|
|
24066
|
+
token: this.apiKey,
|
|
24067
|
+
usage,
|
|
24068
|
+
context,
|
|
24069
|
+
metadata: options?.metadata
|
|
24070
|
+
});
|
|
24071
|
+
}
|
|
23814
24072
|
/**
|
|
23815
24073
|
* Mark a session closed in the control plane. If `environment` is the connected handle for that
|
|
23816
24074
|
* `sessionId`, disconnects the WebSocket so the runtime tears down cleanly.
|
|
@@ -23965,7 +24223,8 @@ var Granular = class _Granular {
|
|
|
23965
24223
|
const environmentSession = new EnvironmentSession(
|
|
23966
24224
|
client,
|
|
23967
24225
|
environment,
|
|
23968
|
-
clientId
|
|
24226
|
+
clientId,
|
|
24227
|
+
{ initialQuota: session2.quota || null }
|
|
23969
24228
|
);
|
|
23970
24229
|
await environmentSession.hello();
|
|
23971
24230
|
return environmentSession;
|