@granular-software/sdk 0.4.66 → 0.4.68
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 +2 -2
- package/dist/agent-evals.d.ts +2 -2
- package/dist/agent-evals.js +279 -36
- package/dist/agent-evals.js.map +1 -1
- package/dist/agent-evals.mjs +279 -36
- package/dist/agent-evals.mjs.map +1 -1
- package/dist/agent-harness.js +6 -0
- package/dist/agent-harness.js.map +1 -1
- package/dist/agent-harness.mjs +6 -0
- package/dist/agent-harness.mjs.map +1 -1
- package/dist/cli/index.js +274 -36
- package/dist/{client-CTpRnXpT.d.ts → client-BNpPrX2X.d.mts} +27 -9
- package/dist/{client-B8Ahz5yo.d.mts → client-C-GYQSJC.d.ts} +27 -9
- package/dist/index.d.mts +52 -4
- package/dist/index.d.ts +52 -4
- package/dist/index.js +535 -36
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +532 -37
- package/dist/index.mjs.map +1 -1
- package/dist/{spend-x-lpt8n1.d.mts → spend-BDGtgZtl.d.mts} +4 -2
- package/dist/{spend-x-lpt8n1.d.ts → spend-BDGtgZtl.d.ts} +4 -2
- package/dist/spend.d.mts +1 -1
- package/dist/spend.d.ts +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -14505,6 +14505,7 @@ function mergeClassSummaryPatch(target, patch) {
|
|
|
14505
14505
|
function mergePropertySummaryPatch(target, patch) {
|
|
14506
14506
|
pushUnique(target.notes, patch.notes || []);
|
|
14507
14507
|
if (patch.searchable !== void 0) target.searchable = patch.searchable;
|
|
14508
|
+
if (patch.format !== void 0) target.format = patch.format;
|
|
14508
14509
|
if (patch.searchablePhonetic !== void 0) {
|
|
14509
14510
|
target.searchablePhonetic = patch.searchablePhonetic;
|
|
14510
14511
|
}
|
|
@@ -16246,6 +16247,91 @@ var stateMachineMetamodelPackage = defineMetamodelPackage({
|
|
|
16246
16247
|
}
|
|
16247
16248
|
});
|
|
16248
16249
|
|
|
16250
|
+
// ../metamodel-temporal/src/index.ts
|
|
16251
|
+
function normalizeTemporalFormat(format) {
|
|
16252
|
+
return format === "date" || format === "date-time" ? format : null;
|
|
16253
|
+
}
|
|
16254
|
+
function buildTemporalFieldMutations(fieldPath, format) {
|
|
16255
|
+
const normalized = normalizeTemporalFormat(format);
|
|
16256
|
+
if (!normalized) return [];
|
|
16257
|
+
return [
|
|
16258
|
+
{
|
|
16259
|
+
label: `set temporal format on ${fieldPath}`,
|
|
16260
|
+
query: `mutation { at(path: ${JSON.stringify(fieldPath)}) { set_temporal_format(format: ${JSON.stringify(normalized)}) { format } } }`
|
|
16261
|
+
}
|
|
16262
|
+
];
|
|
16263
|
+
}
|
|
16264
|
+
var temporalMetamodelPackage = defineMetamodelPackage({
|
|
16265
|
+
id: "temporal",
|
|
16266
|
+
docs: {
|
|
16267
|
+
fieldRows: [
|
|
16268
|
+
{
|
|
16269
|
+
key: "format",
|
|
16270
|
+
description: "Temporal representation for date fields. Use `date` for a civil calendar date and `date-time` when the instant and time matter."
|
|
16271
|
+
}
|
|
16272
|
+
]
|
|
16273
|
+
},
|
|
16274
|
+
graphql: {
|
|
16275
|
+
typeDefs: [
|
|
16276
|
+
`
|
|
16277
|
+
type TemporalFormatMetamodel {
|
|
16278
|
+
model: Model!
|
|
16279
|
+
format: String!
|
|
16280
|
+
}
|
|
16281
|
+
|
|
16282
|
+
extend type Model {
|
|
16283
|
+
temporal_format: TemporalFormatMetamodel
|
|
16284
|
+
}
|
|
16285
|
+
|
|
16286
|
+
extend type ModelMutation {
|
|
16287
|
+
set_temporal_format(format: String!): TemporalFormatMetamodel
|
|
16288
|
+
}
|
|
16289
|
+
`
|
|
16290
|
+
],
|
|
16291
|
+
createResolvers({ run }) {
|
|
16292
|
+
return {
|
|
16293
|
+
TemporalFormatMetamodel: {
|
|
16294
|
+
model: (value) => value.model,
|
|
16295
|
+
format: (value) => value.format
|
|
16296
|
+
},
|
|
16297
|
+
Model: {
|
|
16298
|
+
temporal_format: async (ant) => await run(ant.temporal_format())
|
|
16299
|
+
},
|
|
16300
|
+
ModelMutation: {
|
|
16301
|
+
set_temporal_format: async (ant, { format }) => {
|
|
16302
|
+
if (format !== "date" && format !== "date-time") {
|
|
16303
|
+
throw new Error(`Unsupported temporal format: ${format}`);
|
|
16304
|
+
}
|
|
16305
|
+
return {
|
|
16306
|
+
model: await run(ant.set_temporal_format(format)),
|
|
16307
|
+
format
|
|
16308
|
+
};
|
|
16309
|
+
}
|
|
16310
|
+
}
|
|
16311
|
+
};
|
|
16312
|
+
}
|
|
16313
|
+
},
|
|
16314
|
+
manifest: {
|
|
16315
|
+
buildFieldMutations(fieldPath, spec) {
|
|
16316
|
+
return buildTemporalFieldMutations(fieldPath, spec.format);
|
|
16317
|
+
}
|
|
16318
|
+
},
|
|
16319
|
+
summary: {
|
|
16320
|
+
selections: {
|
|
16321
|
+
propertyFields: ["temporal_format { format }"]
|
|
16322
|
+
},
|
|
16323
|
+
readPropertySummary(rawProperty) {
|
|
16324
|
+
const format = rawProperty.temporal_format?.format;
|
|
16325
|
+
return format === "date" || format === "date-time" ? { format } : {};
|
|
16326
|
+
}
|
|
16327
|
+
},
|
|
16328
|
+
domain: {
|
|
16329
|
+
applyToPropertyIR(propertyIR, _propertySummary) {
|
|
16330
|
+
return propertyIR;
|
|
16331
|
+
}
|
|
16332
|
+
}
|
|
16333
|
+
});
|
|
16334
|
+
|
|
16249
16335
|
// ../metamodel-validation-rule/src/index.ts
|
|
16250
16336
|
function describeRule(rule) {
|
|
16251
16337
|
if (rule.message) return rule.message;
|
|
@@ -16417,6 +16503,7 @@ var DEFAULT_METAMODEL_PACKAGES = [
|
|
|
16417
16503
|
searchableMetamodelPackage,
|
|
16418
16504
|
validationRuleMetamodelPackage,
|
|
16419
16505
|
stateMachineMetamodelPackage,
|
|
16506
|
+
temporalMetamodelPackage,
|
|
16420
16507
|
effectBehaviorsMetamodelPackage,
|
|
16421
16508
|
policyMetamodelPackage
|
|
16422
16509
|
];
|
|
@@ -16551,6 +16638,7 @@ Each key under \`has\` is a **field name** on the class. Each value is a **field
|
|
|
16551
16638
|
| Property | Required? | Purpose |
|
|
16552
16639
|
|----------|-----------|---------|
|
|
16553
16640
|
| \`type\` | **Yes** for normal scalar fields | \`string\`, \`number\`, \`boolean\`, \`email\`, \`url\`, \`date\`, etc. |
|
|
16641
|
+
| \`format\` | For temporal fields | Use \`date\` for a civil calendar date; use \`date-time\` when the time and instant matter. |
|
|
16554
16642
|
| \`description\` | Strongly recommended | Used in docs and UX. |
|
|
16555
16643
|
| \`value\` | Optional | **Default** baked into the model (static metadata), not per-record data. Rare for entity fields. |
|
|
16556
16644
|
| \`ref\` | Optional | Advanced reference. Prefer \`defineRelationship\` for links between entities. |
|
|
@@ -20883,7 +20971,6 @@ var DEFAULT_RPC_TIMEOUT_MS = 3e4;
|
|
|
20883
20971
|
var DOMAIN_PACKAGE_RPC_TIMEOUT_MS = 12e4;
|
|
20884
20972
|
var EFFECT_CONTROL_RPC_TIMEOUT_MS = 12e4;
|
|
20885
20973
|
var HARNESS_RUN_RPC_TIMEOUT_MS = 6e5;
|
|
20886
|
-
var HEARTBEAT_RPC_TIMEOUT_MS = 15e3;
|
|
20887
20974
|
var DEFAULT_CONNECT_TIMEOUT_MS = 1e4;
|
|
20888
20975
|
var DEFAULT_RECONNECT_DELAY_MS = 3e3;
|
|
20889
20976
|
var DEFAULT_MAX_RECONNECT_ATTEMPTS = 5;
|
|
@@ -20929,8 +21016,6 @@ function rpcTimeoutMsForMethod(method) {
|
|
|
20929
21016
|
case "domain.fetchPackagePart":
|
|
20930
21017
|
case "domain.getSummary":
|
|
20931
21018
|
return DOMAIN_PACKAGE_RPC_TIMEOUT_MS;
|
|
20932
|
-
case "client.heartbeat":
|
|
20933
|
-
return HEARTBEAT_RPC_TIMEOUT_MS;
|
|
20934
21019
|
case "effects.publishCatalog":
|
|
20935
21020
|
case "effects.resetCatalog":
|
|
20936
21021
|
case "effects.addCatalog":
|
|
@@ -20950,6 +21035,7 @@ var WSClient = class {
|
|
|
20950
21035
|
sessionId;
|
|
20951
21036
|
token;
|
|
20952
21037
|
messageQueue = [];
|
|
21038
|
+
pendingRpcPeriodStartedAt = null;
|
|
20953
21039
|
rpcHandlers = /* @__PURE__ */ new Map();
|
|
20954
21040
|
eventHandlers = /* @__PURE__ */ new Map();
|
|
20955
21041
|
canonicalDocumentQuarantineHandlers = /* @__PURE__ */ new Set();
|
|
@@ -20964,6 +21050,7 @@ var WSClient = class {
|
|
|
20964
21050
|
cancelConnectAttempt = null;
|
|
20965
21051
|
documentRepairRequired = false;
|
|
20966
21052
|
canonicalDocumentActivated = false;
|
|
21053
|
+
lastInboundActivityAt = null;
|
|
20967
21054
|
options;
|
|
20968
21055
|
constructor(options) {
|
|
20969
21056
|
this.options = options;
|
|
@@ -20977,6 +21064,29 @@ var WSClient = class {
|
|
|
20977
21064
|
get currentSessionId() {
|
|
20978
21065
|
return this.sessionId;
|
|
20979
21066
|
}
|
|
21067
|
+
isTransportOpen() {
|
|
21068
|
+
return this.ws?.readyState === READY_STATE_OPEN;
|
|
21069
|
+
}
|
|
21070
|
+
hasPendingRpcRequests() {
|
|
21071
|
+
return this.messageQueue.length > 0;
|
|
21072
|
+
}
|
|
21073
|
+
hasRecentlyPendingRpcPeriod(maxAgeMs, now = Date.now()) {
|
|
21074
|
+
return this.messageQueue.length > 0 && this.pendingRpcPeriodStartedAt !== null && now - this.pendingRpcPeriodStartedAt <= maxAgeMs;
|
|
21075
|
+
}
|
|
21076
|
+
removePendingRpc(id) {
|
|
21077
|
+
this.messageQueue = this.messageQueue.filter(
|
|
21078
|
+
(pending) => pending.id !== id
|
|
21079
|
+
);
|
|
21080
|
+
if (this.messageQueue.length === 0) this.pendingRpcPeriodStartedAt = null;
|
|
21081
|
+
}
|
|
21082
|
+
/**
|
|
21083
|
+
* Whether the current socket has delivered any frame recently. SessionDO
|
|
21084
|
+
* broadcasts a one-way heartbeat every five seconds, so this measures the
|
|
21085
|
+
* transport without adding an RPC that can be delayed by application work.
|
|
21086
|
+
*/
|
|
21087
|
+
hasRecentInboundActivity(maxAgeMs, now = Date.now()) {
|
|
21088
|
+
return this.ws?.readyState === READY_STATE_OPEN && this.lastInboundActivityAt !== null && now - this.lastInboundActivityAt <= maxAgeMs;
|
|
21089
|
+
}
|
|
20980
21090
|
seedDocumentSnapshot(document) {
|
|
20981
21091
|
if (!document || typeof document !== "object" || Array.isArray(document)) {
|
|
20982
21092
|
return;
|
|
@@ -21128,6 +21238,7 @@ var WSClient = class {
|
|
|
21128
21238
|
const socket = this.ws;
|
|
21129
21239
|
this.connectionEpoch += 1;
|
|
21130
21240
|
this.ws = null;
|
|
21241
|
+
this.lastInboundActivityAt = null;
|
|
21131
21242
|
try {
|
|
21132
21243
|
socket?.close(4001, "Transport failure");
|
|
21133
21244
|
} catch {
|
|
@@ -21210,12 +21321,14 @@ var WSClient = class {
|
|
|
21210
21321
|
closeStaleSocket();
|
|
21211
21322
|
return;
|
|
21212
21323
|
}
|
|
21324
|
+
this.lastInboundActivityAt = Date.now();
|
|
21213
21325
|
this.reconnectAttempts = 0;
|
|
21214
21326
|
this.emit("open", {});
|
|
21215
21327
|
finish();
|
|
21216
21328
|
};
|
|
21217
21329
|
const handleMessage = (data) => {
|
|
21218
21330
|
if (!isCurrent()) return;
|
|
21331
|
+
this.lastInboundActivityAt = Date.now();
|
|
21219
21332
|
try {
|
|
21220
21333
|
const text = typeof data === "string" ? data : data && typeof data === "object" && "toString" in data ? String(data.toString()) : "";
|
|
21221
21334
|
this.handleMessage(JSON.parse(text));
|
|
@@ -21250,9 +21363,7 @@ var WSClient = class {
|
|
|
21250
21363
|
this.ws = null;
|
|
21251
21364
|
closeStaleSocket();
|
|
21252
21365
|
finish(
|
|
21253
|
-
new Error(
|
|
21254
|
-
`WebSocket connect timed out after ${connectTimeoutMs}ms`
|
|
21255
|
-
)
|
|
21366
|
+
new Error(`WebSocket connect timed out after ${connectTimeoutMs}ms`)
|
|
21256
21367
|
);
|
|
21257
21368
|
}, connectTimeoutMs);
|
|
21258
21369
|
signal?.addEventListener("abort", handleAbort, { once: true });
|
|
@@ -21292,6 +21403,7 @@ var WSClient = class {
|
|
|
21292
21403
|
pending.reject(error2);
|
|
21293
21404
|
});
|
|
21294
21405
|
this.messageQueue = [];
|
|
21406
|
+
this.pendingRpcPeriodStartedAt = null;
|
|
21295
21407
|
}
|
|
21296
21408
|
emitReconnectErrorMessage(error2, terminal2 = false) {
|
|
21297
21409
|
const reconnectInfo = {
|
|
@@ -21695,9 +21807,7 @@ var WSClient = class {
|
|
|
21695
21807
|
} else {
|
|
21696
21808
|
pending.resolve(response.result);
|
|
21697
21809
|
}
|
|
21698
|
-
this.
|
|
21699
|
-
(q) => q.id !== response.id
|
|
21700
|
-
);
|
|
21810
|
+
this.removePendingRpc(response.id);
|
|
21701
21811
|
}
|
|
21702
21812
|
return;
|
|
21703
21813
|
}
|
|
@@ -21735,16 +21845,24 @@ var WSClient = class {
|
|
|
21735
21845
|
const timeout = setTimeout(() => {
|
|
21736
21846
|
const pending = this.messageQueue.find((q) => q.id === id);
|
|
21737
21847
|
if (pending) {
|
|
21738
|
-
this.
|
|
21848
|
+
this.removePendingRpc(id);
|
|
21739
21849
|
reject(new Error(`RPC timeout: ${method}`));
|
|
21740
21850
|
}
|
|
21741
21851
|
}, timeoutMs);
|
|
21742
|
-
this.messageQueue.
|
|
21852
|
+
if (this.messageQueue.length === 0) {
|
|
21853
|
+
this.pendingRpcPeriodStartedAt = Date.now();
|
|
21854
|
+
}
|
|
21855
|
+
this.messageQueue.push({
|
|
21856
|
+
resolve: resolve2,
|
|
21857
|
+
reject,
|
|
21858
|
+
id,
|
|
21859
|
+
timeout
|
|
21860
|
+
});
|
|
21743
21861
|
try {
|
|
21744
21862
|
this.ws.send(JSON.stringify(request));
|
|
21745
21863
|
} catch (error2) {
|
|
21746
21864
|
clearTimeout(timeout);
|
|
21747
|
-
this.
|
|
21865
|
+
this.removePendingRpc(id);
|
|
21748
21866
|
reject(error2 instanceof Error ? error2 : new Error(String(error2)));
|
|
21749
21867
|
}
|
|
21750
21868
|
});
|
|
@@ -21849,6 +21967,7 @@ var WSClient = class {
|
|
|
21849
21967
|
this.cancelConnectAttempt?.();
|
|
21850
21968
|
this.cancelConnectAttempt = null;
|
|
21851
21969
|
this.connectionEpoch += 1;
|
|
21970
|
+
this.lastInboundActivityAt = null;
|
|
21852
21971
|
if (this.reconnectTimer) {
|
|
21853
21972
|
clearTimeout(this.reconnectTimer);
|
|
21854
21973
|
this.reconnectTimer = null;
|
|
@@ -25001,16 +25120,100 @@ function normalizeEnvironmentData(environment) {
|
|
|
25001
25120
|
setup: normalizeEnvironmentSetupSummary(environment.setup)
|
|
25002
25121
|
};
|
|
25003
25122
|
}
|
|
25123
|
+
function isGraphQLMutationDocument(query) {
|
|
25124
|
+
if (typeof query !== "string") return false;
|
|
25125
|
+
const tokens = [];
|
|
25126
|
+
for (let index = 0; index < query.length; ) {
|
|
25127
|
+
const character = query[index];
|
|
25128
|
+
if (/[,\s\ufeff]/.test(character)) {
|
|
25129
|
+
index += 1;
|
|
25130
|
+
continue;
|
|
25131
|
+
}
|
|
25132
|
+
if (character === "#") {
|
|
25133
|
+
while (index < query.length && !/[\r\n]/.test(query[index])) index += 1;
|
|
25134
|
+
continue;
|
|
25135
|
+
}
|
|
25136
|
+
if (character === '"') {
|
|
25137
|
+
const block = query.startsWith('"""', index);
|
|
25138
|
+
let closed = false;
|
|
25139
|
+
index += block ? 3 : 1;
|
|
25140
|
+
while (index < query.length) {
|
|
25141
|
+
if (block && query.startsWith('"""', index) && query[index - 1] !== "\\") {
|
|
25142
|
+
index += 3;
|
|
25143
|
+
closed = true;
|
|
25144
|
+
break;
|
|
25145
|
+
}
|
|
25146
|
+
if (!block && query[index] === '"') {
|
|
25147
|
+
index += 1;
|
|
25148
|
+
closed = true;
|
|
25149
|
+
break;
|
|
25150
|
+
}
|
|
25151
|
+
index += query[index] === "\\" && !block ? 2 : 1;
|
|
25152
|
+
}
|
|
25153
|
+
if (!closed) return true;
|
|
25154
|
+
continue;
|
|
25155
|
+
}
|
|
25156
|
+
const name = query.slice(index).match(/^[_A-Za-z][_0-9A-Za-z]*/)?.[0];
|
|
25157
|
+
if (name) {
|
|
25158
|
+
tokens.push(name);
|
|
25159
|
+
index += name.length;
|
|
25160
|
+
continue;
|
|
25161
|
+
}
|
|
25162
|
+
if ("{}()[]".includes(character)) tokens.push(character);
|
|
25163
|
+
index += 1;
|
|
25164
|
+
}
|
|
25165
|
+
const skipSelection = (start) => {
|
|
25166
|
+
let depth = 0;
|
|
25167
|
+
for (let index = start; index < tokens.length; index += 1) {
|
|
25168
|
+
if (tokens[index] === "{") depth += 1;
|
|
25169
|
+
if (tokens[index] === "}" && --depth === 0) return index + 1;
|
|
25170
|
+
}
|
|
25171
|
+
return null;
|
|
25172
|
+
};
|
|
25173
|
+
for (let index = 0; index < tokens.length; ) {
|
|
25174
|
+
const definition = tokens[index++];
|
|
25175
|
+
if (definition === "mutation") return true;
|
|
25176
|
+
if (definition === "{") {
|
|
25177
|
+
const nextDefinition2 = skipSelection(index - 1);
|
|
25178
|
+
if (nextDefinition2 === null) return true;
|
|
25179
|
+
index = nextDefinition2;
|
|
25180
|
+
continue;
|
|
25181
|
+
}
|
|
25182
|
+
if (!["query", "subscription", "fragment"].includes(definition || "")) {
|
|
25183
|
+
return true;
|
|
25184
|
+
}
|
|
25185
|
+
let parentheses = 0;
|
|
25186
|
+
let brackets = 0;
|
|
25187
|
+
while (index < tokens.length) {
|
|
25188
|
+
const token = tokens[index];
|
|
25189
|
+
if (token === "(") parentheses += 1;
|
|
25190
|
+
else if (token === ")") parentheses -= 1;
|
|
25191
|
+
else if (token === "[") brackets += 1;
|
|
25192
|
+
else if (token === "]") brackets -= 1;
|
|
25193
|
+
else if (token === "{" && parentheses === 0 && brackets === 0) break;
|
|
25194
|
+
index += 1;
|
|
25195
|
+
}
|
|
25196
|
+
if (index === tokens.length) return true;
|
|
25197
|
+
const nextDefinition = skipSelection(index);
|
|
25198
|
+
if (nextDefinition === null) return true;
|
|
25199
|
+
index = nextDefinition;
|
|
25200
|
+
}
|
|
25201
|
+
return false;
|
|
25202
|
+
}
|
|
25004
25203
|
var Environment = class _Environment {
|
|
25005
25204
|
granular;
|
|
25006
25205
|
envData;
|
|
25007
25206
|
_apiKey;
|
|
25008
25207
|
_apiEndpoint;
|
|
25009
|
-
|
|
25208
|
+
_tokenProvider;
|
|
25209
|
+
_beforeMutationSend;
|
|
25210
|
+
constructor(granular, envData, apiKey, apiEndpoint, tokenProvider, beforeMutationSend) {
|
|
25010
25211
|
this.granular = granular;
|
|
25011
25212
|
this.envData = envData;
|
|
25012
25213
|
this._apiKey = apiKey;
|
|
25013
25214
|
this._apiEndpoint = apiEndpoint;
|
|
25215
|
+
this._tokenProvider = tokenProvider;
|
|
25216
|
+
this._beforeMutationSend = beforeMutationSend;
|
|
25014
25217
|
}
|
|
25015
25218
|
/** The environment ID */
|
|
25016
25219
|
get environmentId() {
|
|
@@ -25076,6 +25279,15 @@ var Environment = class _Environment {
|
|
|
25076
25279
|
get authToken() {
|
|
25077
25280
|
return this._apiKey;
|
|
25078
25281
|
}
|
|
25282
|
+
resolveAuthToken() {
|
|
25283
|
+
if (!this._tokenProvider) return this._apiKey;
|
|
25284
|
+
return Promise.resolve(this._tokenProvider()).then((provided) => {
|
|
25285
|
+
if (typeof provided === "string" && provided.trim()) {
|
|
25286
|
+
this._apiKey = provided.trim();
|
|
25287
|
+
}
|
|
25288
|
+
return this._apiKey;
|
|
25289
|
+
});
|
|
25290
|
+
}
|
|
25079
25291
|
/** Base runtime URL derived from the GraphQL endpoint */
|
|
25080
25292
|
get runtimeBaseUrl() {
|
|
25081
25293
|
return this.getRuntimeBaseUrl();
|
|
@@ -25467,10 +25679,15 @@ var Environment = class _Environment {
|
|
|
25467
25679
|
async controlPlaneRequest(path7, options = {}) {
|
|
25468
25680
|
const runtimeBase = this.getRuntimeBaseUrl();
|
|
25469
25681
|
const url = `${runtimeBase}${path7}`;
|
|
25682
|
+
const authToken = await this.resolveAuthToken();
|
|
25683
|
+
const method = (options.method || "GET").toUpperCase();
|
|
25684
|
+
if (method !== "GET" && method !== "HEAD" && method !== "OPTIONS") {
|
|
25685
|
+
this._beforeMutationSend?.();
|
|
25686
|
+
}
|
|
25470
25687
|
const response = await fetch(url, {
|
|
25471
25688
|
...options,
|
|
25472
25689
|
headers: {
|
|
25473
|
-
Authorization: `Bearer ${
|
|
25690
|
+
Authorization: `Bearer ${authToken}`,
|
|
25474
25691
|
"Content-Type": "application/json",
|
|
25475
25692
|
...options.headers
|
|
25476
25693
|
}
|
|
@@ -25535,11 +25752,15 @@ var Environment = class _Environment {
|
|
|
25535
25752
|
* ```
|
|
25536
25753
|
*/
|
|
25537
25754
|
async graphql(query, variables) {
|
|
25755
|
+
const authToken = await this.resolveAuthToken();
|
|
25756
|
+
if (this._beforeMutationSend && isGraphQLMutationDocument(query)) {
|
|
25757
|
+
this._beforeMutationSend?.();
|
|
25758
|
+
}
|
|
25538
25759
|
const response = await fetch(this._apiEndpoint, {
|
|
25539
25760
|
method: "POST",
|
|
25540
25761
|
headers: {
|
|
25541
25762
|
"Content-Type": "application/json",
|
|
25542
|
-
Authorization: `Bearer ${
|
|
25763
|
+
Authorization: `Bearer ${authToken}`
|
|
25543
25764
|
},
|
|
25544
25765
|
body: JSON.stringify({
|
|
25545
25766
|
environmentId: this.environmentId,
|
|
@@ -26018,8 +26239,10 @@ var Environment = class _Environment {
|
|
|
26018
26239
|
eventType.payloadSchema.properties
|
|
26019
26240
|
)) {
|
|
26020
26241
|
const schema = propSchema;
|
|
26242
|
+
const format = schema.format === "date" || schema.format === "date-time" ? schema.format : void 0;
|
|
26021
26243
|
fieldSpecs[propName] = {
|
|
26022
26244
|
type: schema.type ?? "string",
|
|
26245
|
+
...format ? { format } : {},
|
|
26023
26246
|
description: schema.description
|
|
26024
26247
|
};
|
|
26025
26248
|
}
|
|
@@ -26441,40 +26664,36 @@ var EnvironmentSession = class extends Session {
|
|
|
26441
26664
|
environment;
|
|
26442
26665
|
sessionDataRoutePrefix;
|
|
26443
26666
|
sessionDataHeaders;
|
|
26667
|
+
beforeMutationSend;
|
|
26444
26668
|
heartbeatTimer = null;
|
|
26445
|
-
|
|
26446
|
-
/** The last known graph container status, updated by checkReadiness() or on heartbeat */
|
|
26669
|
+
/** The last known graph container status, updated by checkReadiness(). */
|
|
26447
26670
|
graphContainerStatus = null;
|
|
26448
26671
|
constructor(client, environment, clientId, options = {}) {
|
|
26449
26672
|
super(client, clientId, { initialQuota: options.initialQuota });
|
|
26450
26673
|
this.environment = environment;
|
|
26451
26674
|
this.sessionDataRoutePrefix = options.sessionDataRoutePrefix || "/orchestrator/ws/sessions";
|
|
26452
26675
|
this.sessionDataHeaders = options.sessionDataHeaders || {};
|
|
26676
|
+
this.beforeMutationSend = options.beforeMutationSend;
|
|
26453
26677
|
this.setFeedListTransport(
|
|
26454
26678
|
(feedOptions) => this.sessionDataRequest("/feed", feedOptions)
|
|
26455
26679
|
);
|
|
26456
26680
|
}
|
|
26457
26681
|
/**
|
|
26458
26682
|
* Keep the browser session transport observable from the client side.
|
|
26459
|
-
*
|
|
26460
|
-
*
|
|
26461
|
-
*
|
|
26462
|
-
*
|
|
26683
|
+
* SessionDO already broadcasts a heartbeat every five seconds. Treat that
|
|
26684
|
+
* and all other inbound frames as proof of life instead of issuing an RPC:
|
|
26685
|
+
* an application RPC may be delayed by Durable Object work even while the
|
|
26686
|
+
* underlying WebSocket is healthy.
|
|
26463
26687
|
*/
|
|
26464
26688
|
startHeartbeat() {
|
|
26465
26689
|
if (this.heartbeatTimer) return;
|
|
26466
26690
|
this.heartbeatTimer = setInterval(() => {
|
|
26467
|
-
if (this.
|
|
26468
|
-
this.
|
|
26469
|
-
|
|
26470
|
-
|
|
26471
|
-
|
|
26472
|
-
|
|
26473
|
-
}).catch((error2) => {
|
|
26474
|
-
this.client.reportTransportFailure(error2);
|
|
26475
|
-
}).finally(() => {
|
|
26476
|
-
this.heartbeatInFlight = false;
|
|
26477
|
-
});
|
|
26691
|
+
if (!this.client.isTransportOpen()) return;
|
|
26692
|
+
if (this.client.hasRecentInboundActivity(3e4)) return;
|
|
26693
|
+
if (this.client.hasRecentlyPendingRpcPeriod(6e4)) return;
|
|
26694
|
+
this.client.reportTransportFailure(
|
|
26695
|
+
new Error("No server activity received for 30 seconds")
|
|
26696
|
+
);
|
|
26478
26697
|
}, 5e3);
|
|
26479
26698
|
this.heartbeatTimer.unref?.();
|
|
26480
26699
|
}
|
|
@@ -26483,7 +26702,6 @@ var EnvironmentSession = class extends Session {
|
|
|
26483
26702
|
clearInterval(this.heartbeatTimer);
|
|
26484
26703
|
this.heartbeatTimer = null;
|
|
26485
26704
|
}
|
|
26486
|
-
this.heartbeatInFlight = false;
|
|
26487
26705
|
}
|
|
26488
26706
|
async hello() {
|
|
26489
26707
|
const result = await super.hello();
|
|
@@ -26544,7 +26762,13 @@ var EnvironmentSession = class extends Session {
|
|
|
26544
26762
|
for (let attempt = 1; attempt <= SESSION_DATA_REQUEST_RETRY_COUNT; attempt += 1) {
|
|
26545
26763
|
try {
|
|
26546
26764
|
const headers = new Headers(init2.headers);
|
|
26547
|
-
|
|
26765
|
+
const resolvedAuthToken = this.environment.resolveAuthToken();
|
|
26766
|
+
const authToken = typeof resolvedAuthToken === "string" ? resolvedAuthToken : await resolvedAuthToken;
|
|
26767
|
+
headers.set("Authorization", `Bearer ${authToken}`);
|
|
26768
|
+
const method = (init2.method || "GET").toUpperCase();
|
|
26769
|
+
if (method !== "GET" && method !== "HEAD" && method !== "OPTIONS") {
|
|
26770
|
+
this.beforeMutationSend?.();
|
|
26771
|
+
}
|
|
26548
26772
|
const response = await fetch(url, {
|
|
26549
26773
|
method: init2.method || "GET",
|
|
26550
26774
|
headers,
|
|
@@ -27003,7 +27227,7 @@ var EnvironmentSession = class extends Session {
|
|
|
27003
27227
|
method: "POST",
|
|
27004
27228
|
headers: {
|
|
27005
27229
|
"Content-Type": "application/json",
|
|
27006
|
-
Authorization: `Bearer ${this.environment.
|
|
27230
|
+
Authorization: `Bearer ${await this.environment.resolveAuthToken()}`
|
|
27007
27231
|
},
|
|
27008
27232
|
body: JSON.stringify({
|
|
27009
27233
|
reason: "sdk_disconnect_http_fallback",
|
|
@@ -27941,6 +28165,10 @@ var Granular = class _Granular {
|
|
|
27941
28165
|
});
|
|
27942
28166
|
}
|
|
27943
28167
|
async recordOpenAIUsageSpend(usage, context, options) {
|
|
28168
|
+
const providedToken = await this.tokenProvider?.();
|
|
28169
|
+
if (typeof providedToken === "string" && providedToken.trim()) {
|
|
28170
|
+
this.apiKey = providedToken.trim();
|
|
28171
|
+
}
|
|
27944
28172
|
return recordOpenAIUsageSpend({
|
|
27945
28173
|
apiUrl: this.apiUrl,
|
|
27946
28174
|
token: this.apiKey,
|
|
@@ -28113,7 +28341,13 @@ var Granular = class _Granular {
|
|
|
28113
28341
|
}
|
|
28114
28342
|
bindEnvironmentHandle(envData) {
|
|
28115
28343
|
const graphqlEndpoint = `${this.httpUrl}/orchestrator/graphql`;
|
|
28116
|
-
return new Environment(
|
|
28344
|
+
return new Environment(
|
|
28345
|
+
this,
|
|
28346
|
+
envData,
|
|
28347
|
+
this.apiKey,
|
|
28348
|
+
graphqlEndpoint,
|
|
28349
|
+
this.tokenProvider
|
|
28350
|
+
);
|
|
28117
28351
|
}
|
|
28118
28352
|
async bindWebSocketEnvironmentSession(environment, clientId, session2, transportOptions = {}) {
|
|
28119
28353
|
const client = new WSClient({
|
|
@@ -28997,6 +29231,10 @@ var Granular = class _Granular {
|
|
|
28997
29231
|
console.log(`[SDK] Requesting: ${url}`);
|
|
28998
29232
|
}
|
|
28999
29233
|
for (let attempt = 1; attempt <= LOCAL_CONTROL_REQUEST_RETRY_COUNT; attempt += 1) {
|
|
29234
|
+
const providedToken = await this.tokenProvider?.();
|
|
29235
|
+
if (typeof providedToken === "string" && providedToken.trim()) {
|
|
29236
|
+
this.apiKey = providedToken.trim();
|
|
29237
|
+
}
|
|
29000
29238
|
const response = await fetch(url, {
|
|
29001
29239
|
...options,
|
|
29002
29240
|
headers: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { df as WSClientOptions, a7 as SessionFeedApi, bb as GranularQuotaProgress, T as ToolWithHandler, q as PublishToolsResult, ch as Job, r as ToolHandler, I as InstanceToolHandler, ck as UserMessageInput, cl as UserMessageAppendResult, c4 as EffectInfo, n as Prompt, c3 as ToolInfo, c6 as EffectsChangedEvent, c5 as ToolsChangedEvent, D as DomainState, aa as FeedListTransport, aT as GranularOptions, dM as EnvironmentImporter, aW as RecordUserOptions, aV as User, aY as OpenEnvironmentOptions, E as EnvironmentData, aS as AccessTokenProvider, bl as BuildPolicy, dJ as EnvironmentSetupSummary, b2 as ConversationSessionListOptions, b0 as ConversationSessionInfo, b3 as ConversationSessionListResponse, a$ as CreateSessionOptions, h as RecordObjectOptions, dw as RecordObjectResult, dy as RecordObjectsOptions, dF as RecordImport, dB as RecordImportStatus, dE as RecordImportItem, a as EnvironmentRecordImportSummary, cf as EnvironmentFeedbackRecord, m as SessionHeapSnapshot, d3 as SessionDocumentResult, cm as AssistantReplyPublicationInput, cn as AssistantReplyPublicationResult, d4 as SessionCollectionListOptions, d6 as SessionCollectionListResult, cq as SessionTimelineEvent, d5 as SessionJobListOptions, cY as SessionJobRecord, bP as SessionMutationView, cz as SessionArtifactListOptions, cy as SessionArtifactRecord, cB as SessionArtifactRelationshipOptionsInput, cD as SessionArtifactRelationshipOptionsResult, cE as SessionArtifactRelationshipCreateInput, cA as SessionArtifactValidationResult, cG as SessionArtifactExecutionOptions, cF as SessionArtifactExecutionResult, cH as SessionArtifactApprovalOptions, cR as RecordManualActionInput, cT as ManualActionRecordResult, cU as ManualActionListOptions, cS as ManualActionOccurrence, cW as ManualActionSuggestionOptions, cV as ManualActionSuggestion, cK as ArtifactApprovalTaskListOptions, cJ as ArtifactApprovalTask, cL as ArtifactApprovalDecisionInput, cM as ArtifactApprovalDecisionResult, cu as SessionFileRecord, cX as SessionFileUploadOptions, S as SessionHeapEntry, k as SessionHeapList, c$ as SessionHeapVariable, o as SessionTranscriptEntry, ee as GraphQLResult, d1 as RecordSearchOptions, d0 as RecordSearchResult, d2 as RecordMentionInput, dp as DefineRelationshipOptions, dn as RelationshipInfo, dm as ModelRef, i as ManifestContent, dt as EnvironmentStateUpdateInput, dr as EnvironmentStateTarget, dv as EnvironmentStateProxy, dA as RecordImportOptions, db as UserEnvironmentStateOptions, da as UserEnvironmentState, dc as MarkUserEnvironmentReadOptions, d as ProjectionMapper, bI as EffectProjectionResult, bN as ExternalCommitOptions, C as CommitReceipt, bJ as TransitionProjectionResult, bO as ObservationReceipt, aZ as AdoptEnvironmentOptions, a_ as ConnectOptions, dH as RunEnvironmentImporterOptions, aF as OpenAIUsageSpendEvent, aE as GranularSpendContext, aH as RecordOpenAIUsageSpendResult, be as SandboxListResponse, bc as Sandbox, bd as CreateSandboxData, eg as DeleteResponse, bg as PermissionProfile, bh as CreatePermissionProfileData, bo as CreateEnvironmentData, eh as StreamEvent, ei as StreamSubscription, ej as StreamStats, aX as Subject, bk as AssignmentListResponse } from './spend-BDGtgZtl.mjs';
|
|
2
2
|
import * as Automerge from '@automerge/automerge';
|
|
3
3
|
import { Doc } from '@automerge/automerge/slim';
|
|
4
4
|
|
|
@@ -13,6 +13,7 @@ declare class WSClient {
|
|
|
13
13
|
private sessionId;
|
|
14
14
|
private token;
|
|
15
15
|
private messageQueue;
|
|
16
|
+
private pendingRpcPeriodStartedAt;
|
|
16
17
|
private rpcHandlers;
|
|
17
18
|
private eventHandlers;
|
|
18
19
|
private canonicalDocumentQuarantineHandlers;
|
|
@@ -27,9 +28,20 @@ declare class WSClient {
|
|
|
27
28
|
private cancelConnectAttempt;
|
|
28
29
|
private documentRepairRequired;
|
|
29
30
|
private canonicalDocumentActivated;
|
|
31
|
+
private lastInboundActivityAt;
|
|
30
32
|
private options;
|
|
31
33
|
constructor(options: WSClientOptions);
|
|
32
34
|
get currentSessionId(): string;
|
|
35
|
+
isTransportOpen(): boolean;
|
|
36
|
+
hasPendingRpcRequests(): boolean;
|
|
37
|
+
hasRecentlyPendingRpcPeriod(maxAgeMs: number, now?: number): boolean;
|
|
38
|
+
private removePendingRpc;
|
|
39
|
+
/**
|
|
40
|
+
* Whether the current socket has delivered any frame recently. SessionDO
|
|
41
|
+
* broadcasts a one-way heartbeat every five seconds, so this measures the
|
|
42
|
+
* transport without adding an RPC that can be delayed by application work.
|
|
43
|
+
*/
|
|
44
|
+
hasRecentInboundActivity(maxAgeMs: number, now?: number): boolean;
|
|
33
45
|
seedDocumentSnapshot(document: Record<string, unknown> | Uint8Array | null | undefined): void;
|
|
34
46
|
saveDocumentSnapshot(): Uint8Array;
|
|
35
47
|
private clearTokenRefreshTimer;
|
|
@@ -310,6 +322,7 @@ declare class Session {
|
|
|
310
322
|
type SessionFileUploadBody = Blob | ArrayBuffer | Uint8Array | string;
|
|
311
323
|
type SessionDataHeaders = any;
|
|
312
324
|
type EnvironmentImporterHandler = (importer: EnvironmentImporter) => Promise<void> | void;
|
|
325
|
+
declare function isGraphQLMutationDocument(query: unknown): boolean;
|
|
313
326
|
/**
|
|
314
327
|
* Environment is the sessionless handle for one resolved ontology environment.
|
|
315
328
|
*
|
|
@@ -322,7 +335,9 @@ declare class Environment {
|
|
|
322
335
|
private envData;
|
|
323
336
|
private _apiKey;
|
|
324
337
|
private _apiEndpoint;
|
|
325
|
-
|
|
338
|
+
private _tokenProvider?;
|
|
339
|
+
private _beforeMutationSend?;
|
|
340
|
+
constructor(granular: Granular, envData: EnvironmentData, apiKey: string, apiEndpoint: string, tokenProvider?: AccessTokenProvider, beforeMutationSend?: () => void);
|
|
326
341
|
/** The environment ID */
|
|
327
342
|
get environmentId(): string;
|
|
328
343
|
/** The sandbox ID */
|
|
@@ -355,6 +370,7 @@ declare class Environment {
|
|
|
355
370
|
get apiEndpoint(): string;
|
|
356
371
|
/** Internal auth token used for control-plane and runtime fallback requests */
|
|
357
372
|
get authToken(): string;
|
|
373
|
+
resolveAuthToken(): string | Promise<string>;
|
|
358
374
|
/** Base runtime URL derived from the GraphQL endpoint */
|
|
359
375
|
get runtimeBaseUrl(): string;
|
|
360
376
|
syncEnvironmentData(envData: EnvironmentData): void;
|
|
@@ -776,9 +792,9 @@ declare class EnvironmentSession extends Session {
|
|
|
776
792
|
readonly environment: Environment;
|
|
777
793
|
private readonly sessionDataRoutePrefix;
|
|
778
794
|
private readonly sessionDataHeaders;
|
|
795
|
+
private readonly beforeMutationSend?;
|
|
779
796
|
private heartbeatTimer;
|
|
780
|
-
|
|
781
|
-
/** The last known graph container status, updated by checkReadiness() or on heartbeat */
|
|
797
|
+
/** The last known graph container status, updated by checkReadiness(). */
|
|
782
798
|
graphContainerStatus: {
|
|
783
799
|
lastKeepAliveAt: number;
|
|
784
800
|
status: "warming" | "hot" | "unknown";
|
|
@@ -791,14 +807,16 @@ declare class EnvironmentSession extends Session {
|
|
|
791
807
|
* that initiated a user action when multiple tabs are connected.
|
|
792
808
|
*/
|
|
793
809
|
sessionDataHeaders?: SessionDataHeaders;
|
|
810
|
+
/** Browser-only readiness guard checked immediately before each write. */
|
|
811
|
+
beforeMutationSend?: () => void;
|
|
794
812
|
initialQuota?: GranularQuotaProgress | null;
|
|
795
813
|
});
|
|
796
814
|
/**
|
|
797
815
|
* Keep the browser session transport observable from the client side.
|
|
798
|
-
*
|
|
799
|
-
*
|
|
800
|
-
*
|
|
801
|
-
*
|
|
816
|
+
* SessionDO already broadcasts a heartbeat every five seconds. Treat that
|
|
817
|
+
* and all other inbound frames as proof of life instead of issuing an RPC:
|
|
818
|
+
* an application RPC may be delayed by Durable Object work even while the
|
|
819
|
+
* underlying WebSocket is healthy.
|
|
802
820
|
*/
|
|
803
821
|
private startHeartbeat;
|
|
804
822
|
private stopHeartbeat;
|
|
@@ -1336,4 +1354,4 @@ declare class Granular {
|
|
|
1336
1354
|
private request;
|
|
1337
1355
|
}
|
|
1338
1356
|
|
|
1339
|
-
export { Environment as E, Granular as G, OntologyHandle as O, Session as S, WSClient as W, EnvironmentSession as a };
|
|
1357
|
+
export { Environment as E, Granular as G, OntologyHandle as O, Session as S, WSClient as W, EnvironmentSession as a, isGraphQLMutationDocument as i };
|