@granular-software/sdk 0.4.65 → 0.4.67
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 +282 -36
- package/dist/agent-evals.js.map +1 -1
- package/dist/agent-evals.mjs +282 -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 +277 -36
- package/dist/{client-S-z8bri1.d.mts → client-BT1DJddL.d.ts} +27 -9
- package/dist/{client-z6shQivt.d.ts → client-BkX2cb20.d.mts} +27 -9
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +283 -36
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +283 -37
- package/dist/index.mjs.map +1 -1
- package/dist/{spend-CESUvrZC.d.mts → spend-D4r0SA-H.d.mts} +9 -1
- package/dist/{spend-CESUvrZC.d.ts → spend-D4r0SA-H.d.ts} +9 -1
- package/dist/spend.d.mts +1 -1
- package/dist/spend.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5303,7 +5303,6 @@ var DEFAULT_RPC_TIMEOUT_MS = 3e4;
|
|
|
5303
5303
|
var DOMAIN_PACKAGE_RPC_TIMEOUT_MS = 12e4;
|
|
5304
5304
|
var EFFECT_CONTROL_RPC_TIMEOUT_MS = 12e4;
|
|
5305
5305
|
var HARNESS_RUN_RPC_TIMEOUT_MS = 6e5;
|
|
5306
|
-
var HEARTBEAT_RPC_TIMEOUT_MS = 15e3;
|
|
5307
5306
|
var DEFAULT_CONNECT_TIMEOUT_MS = 1e4;
|
|
5308
5307
|
var DEFAULT_RECONNECT_DELAY_MS = 3e3;
|
|
5309
5308
|
var DEFAULT_MAX_RECONNECT_ATTEMPTS = 5;
|
|
@@ -5349,8 +5348,6 @@ function rpcTimeoutMsForMethod(method) {
|
|
|
5349
5348
|
case "domain.fetchPackagePart":
|
|
5350
5349
|
case "domain.getSummary":
|
|
5351
5350
|
return DOMAIN_PACKAGE_RPC_TIMEOUT_MS;
|
|
5352
|
-
case "client.heartbeat":
|
|
5353
|
-
return HEARTBEAT_RPC_TIMEOUT_MS;
|
|
5354
5351
|
case "effects.publishCatalog":
|
|
5355
5352
|
case "effects.resetCatalog":
|
|
5356
5353
|
case "effects.addCatalog":
|
|
@@ -5370,6 +5367,7 @@ var WSClient = class {
|
|
|
5370
5367
|
sessionId;
|
|
5371
5368
|
token;
|
|
5372
5369
|
messageQueue = [];
|
|
5370
|
+
pendingRpcPeriodStartedAt = null;
|
|
5373
5371
|
rpcHandlers = /* @__PURE__ */ new Map();
|
|
5374
5372
|
eventHandlers = /* @__PURE__ */ new Map();
|
|
5375
5373
|
canonicalDocumentQuarantineHandlers = /* @__PURE__ */ new Set();
|
|
@@ -5384,6 +5382,7 @@ var WSClient = class {
|
|
|
5384
5382
|
cancelConnectAttempt = null;
|
|
5385
5383
|
documentRepairRequired = false;
|
|
5386
5384
|
canonicalDocumentActivated = false;
|
|
5385
|
+
lastInboundActivityAt = null;
|
|
5387
5386
|
options;
|
|
5388
5387
|
constructor(options) {
|
|
5389
5388
|
this.options = options;
|
|
@@ -5397,6 +5396,29 @@ var WSClient = class {
|
|
|
5397
5396
|
get currentSessionId() {
|
|
5398
5397
|
return this.sessionId;
|
|
5399
5398
|
}
|
|
5399
|
+
isTransportOpen() {
|
|
5400
|
+
return this.ws?.readyState === READY_STATE_OPEN;
|
|
5401
|
+
}
|
|
5402
|
+
hasPendingRpcRequests() {
|
|
5403
|
+
return this.messageQueue.length > 0;
|
|
5404
|
+
}
|
|
5405
|
+
hasRecentlyPendingRpcPeriod(maxAgeMs, now = Date.now()) {
|
|
5406
|
+
return this.messageQueue.length > 0 && this.pendingRpcPeriodStartedAt !== null && now - this.pendingRpcPeriodStartedAt <= maxAgeMs;
|
|
5407
|
+
}
|
|
5408
|
+
removePendingRpc(id) {
|
|
5409
|
+
this.messageQueue = this.messageQueue.filter(
|
|
5410
|
+
(pending) => pending.id !== id
|
|
5411
|
+
);
|
|
5412
|
+
if (this.messageQueue.length === 0) this.pendingRpcPeriodStartedAt = null;
|
|
5413
|
+
}
|
|
5414
|
+
/**
|
|
5415
|
+
* Whether the current socket has delivered any frame recently. SessionDO
|
|
5416
|
+
* broadcasts a one-way heartbeat every five seconds, so this measures the
|
|
5417
|
+
* transport without adding an RPC that can be delayed by application work.
|
|
5418
|
+
*/
|
|
5419
|
+
hasRecentInboundActivity(maxAgeMs, now = Date.now()) {
|
|
5420
|
+
return this.ws?.readyState === READY_STATE_OPEN && this.lastInboundActivityAt !== null && now - this.lastInboundActivityAt <= maxAgeMs;
|
|
5421
|
+
}
|
|
5400
5422
|
seedDocumentSnapshot(document) {
|
|
5401
5423
|
if (!document || typeof document !== "object" || Array.isArray(document)) {
|
|
5402
5424
|
return;
|
|
@@ -5548,6 +5570,7 @@ var WSClient = class {
|
|
|
5548
5570
|
const socket = this.ws;
|
|
5549
5571
|
this.connectionEpoch += 1;
|
|
5550
5572
|
this.ws = null;
|
|
5573
|
+
this.lastInboundActivityAt = null;
|
|
5551
5574
|
try {
|
|
5552
5575
|
socket?.close(4001, "Transport failure");
|
|
5553
5576
|
} catch {
|
|
@@ -5630,12 +5653,14 @@ var WSClient = class {
|
|
|
5630
5653
|
closeStaleSocket();
|
|
5631
5654
|
return;
|
|
5632
5655
|
}
|
|
5656
|
+
this.lastInboundActivityAt = Date.now();
|
|
5633
5657
|
this.reconnectAttempts = 0;
|
|
5634
5658
|
this.emit("open", {});
|
|
5635
5659
|
finish();
|
|
5636
5660
|
};
|
|
5637
5661
|
const handleMessage = (data) => {
|
|
5638
5662
|
if (!isCurrent()) return;
|
|
5663
|
+
this.lastInboundActivityAt = Date.now();
|
|
5639
5664
|
try {
|
|
5640
5665
|
const text = typeof data === "string" ? data : data && typeof data === "object" && "toString" in data ? String(data.toString()) : "";
|
|
5641
5666
|
this.handleMessage(JSON.parse(text));
|
|
@@ -5670,9 +5695,7 @@ var WSClient = class {
|
|
|
5670
5695
|
this.ws = null;
|
|
5671
5696
|
closeStaleSocket();
|
|
5672
5697
|
finish(
|
|
5673
|
-
new Error(
|
|
5674
|
-
`WebSocket connect timed out after ${connectTimeoutMs}ms`
|
|
5675
|
-
)
|
|
5698
|
+
new Error(`WebSocket connect timed out after ${connectTimeoutMs}ms`)
|
|
5676
5699
|
);
|
|
5677
5700
|
}, connectTimeoutMs);
|
|
5678
5701
|
signal?.addEventListener("abort", handleAbort, { once: true });
|
|
@@ -5712,6 +5735,7 @@ var WSClient = class {
|
|
|
5712
5735
|
pending.reject(error);
|
|
5713
5736
|
});
|
|
5714
5737
|
this.messageQueue = [];
|
|
5738
|
+
this.pendingRpcPeriodStartedAt = null;
|
|
5715
5739
|
}
|
|
5716
5740
|
emitReconnectErrorMessage(error, terminal = false) {
|
|
5717
5741
|
const reconnectInfo = {
|
|
@@ -6115,9 +6139,7 @@ var WSClient = class {
|
|
|
6115
6139
|
} else {
|
|
6116
6140
|
pending.resolve(response.result);
|
|
6117
6141
|
}
|
|
6118
|
-
this.
|
|
6119
|
-
(q) => q.id !== response.id
|
|
6120
|
-
);
|
|
6142
|
+
this.removePendingRpc(response.id);
|
|
6121
6143
|
}
|
|
6122
6144
|
return;
|
|
6123
6145
|
}
|
|
@@ -6155,16 +6177,24 @@ var WSClient = class {
|
|
|
6155
6177
|
const timeout = setTimeout(() => {
|
|
6156
6178
|
const pending = this.messageQueue.find((q) => q.id === id);
|
|
6157
6179
|
if (pending) {
|
|
6158
|
-
this.
|
|
6180
|
+
this.removePendingRpc(id);
|
|
6159
6181
|
reject(new Error(`RPC timeout: ${method}`));
|
|
6160
6182
|
}
|
|
6161
6183
|
}, timeoutMs);
|
|
6162
|
-
this.messageQueue.
|
|
6184
|
+
if (this.messageQueue.length === 0) {
|
|
6185
|
+
this.pendingRpcPeriodStartedAt = Date.now();
|
|
6186
|
+
}
|
|
6187
|
+
this.messageQueue.push({
|
|
6188
|
+
resolve,
|
|
6189
|
+
reject,
|
|
6190
|
+
id,
|
|
6191
|
+
timeout
|
|
6192
|
+
});
|
|
6163
6193
|
try {
|
|
6164
6194
|
this.ws.send(JSON.stringify(request));
|
|
6165
6195
|
} catch (error) {
|
|
6166
6196
|
clearTimeout(timeout);
|
|
6167
|
-
this.
|
|
6197
|
+
this.removePendingRpc(id);
|
|
6168
6198
|
reject(error instanceof Error ? error : new Error(String(error)));
|
|
6169
6199
|
}
|
|
6170
6200
|
});
|
|
@@ -6269,6 +6299,7 @@ var WSClient = class {
|
|
|
6269
6299
|
this.cancelConnectAttempt?.();
|
|
6270
6300
|
this.cancelConnectAttempt = null;
|
|
6271
6301
|
this.connectionEpoch += 1;
|
|
6302
|
+
this.lastInboundActivityAt = null;
|
|
6272
6303
|
if (this.reconnectTimer) {
|
|
6273
6304
|
clearTimeout(this.reconnectTimer);
|
|
6274
6305
|
this.reconnectTimer = null;
|
|
@@ -12685,6 +12716,7 @@ function mergeClassSummaryPatch(target, patch) {
|
|
|
12685
12716
|
function mergePropertySummaryPatch(target, patch) {
|
|
12686
12717
|
pushUnique(target.notes, patch.notes || []);
|
|
12687
12718
|
if (patch.searchable !== void 0) target.searchable = patch.searchable;
|
|
12719
|
+
if (patch.format !== void 0) target.format = patch.format;
|
|
12688
12720
|
if (patch.searchablePhonetic !== void 0) {
|
|
12689
12721
|
target.searchablePhonetic = patch.searchablePhonetic;
|
|
12690
12722
|
}
|
|
@@ -15572,6 +15604,91 @@ var stateMachineMetamodelPackage = defineMetamodelPackage({
|
|
|
15572
15604
|
}
|
|
15573
15605
|
});
|
|
15574
15606
|
|
|
15607
|
+
// ../metamodel-temporal/src/index.ts
|
|
15608
|
+
function normalizeTemporalFormat(format) {
|
|
15609
|
+
return format === "date" || format === "date-time" ? format : null;
|
|
15610
|
+
}
|
|
15611
|
+
function buildTemporalFieldMutations(fieldPath, format) {
|
|
15612
|
+
const normalized = normalizeTemporalFormat(format);
|
|
15613
|
+
if (!normalized) return [];
|
|
15614
|
+
return [
|
|
15615
|
+
{
|
|
15616
|
+
label: `set temporal format on ${fieldPath}`,
|
|
15617
|
+
query: `mutation { at(path: ${JSON.stringify(fieldPath)}) { set_temporal_format(format: ${JSON.stringify(normalized)}) { format } } }`
|
|
15618
|
+
}
|
|
15619
|
+
];
|
|
15620
|
+
}
|
|
15621
|
+
var temporalMetamodelPackage = defineMetamodelPackage({
|
|
15622
|
+
id: "temporal",
|
|
15623
|
+
docs: {
|
|
15624
|
+
fieldRows: [
|
|
15625
|
+
{
|
|
15626
|
+
key: "format",
|
|
15627
|
+
description: "Temporal representation for date fields. Use `date` for a civil calendar date and `date-time` when the instant and time matter."
|
|
15628
|
+
}
|
|
15629
|
+
]
|
|
15630
|
+
},
|
|
15631
|
+
graphql: {
|
|
15632
|
+
typeDefs: [
|
|
15633
|
+
`
|
|
15634
|
+
type TemporalFormatMetamodel {
|
|
15635
|
+
model: Model!
|
|
15636
|
+
format: String!
|
|
15637
|
+
}
|
|
15638
|
+
|
|
15639
|
+
extend type Model {
|
|
15640
|
+
temporal_format: TemporalFormatMetamodel
|
|
15641
|
+
}
|
|
15642
|
+
|
|
15643
|
+
extend type ModelMutation {
|
|
15644
|
+
set_temporal_format(format: String!): TemporalFormatMetamodel
|
|
15645
|
+
}
|
|
15646
|
+
`
|
|
15647
|
+
],
|
|
15648
|
+
createResolvers({ run }) {
|
|
15649
|
+
return {
|
|
15650
|
+
TemporalFormatMetamodel: {
|
|
15651
|
+
model: (value) => value.model,
|
|
15652
|
+
format: (value) => value.format
|
|
15653
|
+
},
|
|
15654
|
+
Model: {
|
|
15655
|
+
temporal_format: async (ant) => await run(ant.temporal_format())
|
|
15656
|
+
},
|
|
15657
|
+
ModelMutation: {
|
|
15658
|
+
set_temporal_format: async (ant, { format }) => {
|
|
15659
|
+
if (format !== "date" && format !== "date-time") {
|
|
15660
|
+
throw new Error(`Unsupported temporal format: ${format}`);
|
|
15661
|
+
}
|
|
15662
|
+
return {
|
|
15663
|
+
model: await run(ant.set_temporal_format(format)),
|
|
15664
|
+
format
|
|
15665
|
+
};
|
|
15666
|
+
}
|
|
15667
|
+
}
|
|
15668
|
+
};
|
|
15669
|
+
}
|
|
15670
|
+
},
|
|
15671
|
+
manifest: {
|
|
15672
|
+
buildFieldMutations(fieldPath, spec) {
|
|
15673
|
+
return buildTemporalFieldMutations(fieldPath, spec.format);
|
|
15674
|
+
}
|
|
15675
|
+
},
|
|
15676
|
+
summary: {
|
|
15677
|
+
selections: {
|
|
15678
|
+
propertyFields: ["temporal_format { format }"]
|
|
15679
|
+
},
|
|
15680
|
+
readPropertySummary(rawProperty) {
|
|
15681
|
+
const format = rawProperty.temporal_format?.format;
|
|
15682
|
+
return format === "date" || format === "date-time" ? { format } : {};
|
|
15683
|
+
}
|
|
15684
|
+
},
|
|
15685
|
+
domain: {
|
|
15686
|
+
applyToPropertyIR(propertyIR, _propertySummary) {
|
|
15687
|
+
return propertyIR;
|
|
15688
|
+
}
|
|
15689
|
+
}
|
|
15690
|
+
});
|
|
15691
|
+
|
|
15575
15692
|
// ../metamodel-validation-rule/src/index.ts
|
|
15576
15693
|
function describeRule(rule) {
|
|
15577
15694
|
if (rule.message) return rule.message;
|
|
@@ -15841,6 +15958,7 @@ var DEFAULT_METAMODEL_PACKAGES = [
|
|
|
15841
15958
|
searchableMetamodelPackage,
|
|
15842
15959
|
validationRuleMetamodelPackage,
|
|
15843
15960
|
stateMachineMetamodelPackage,
|
|
15961
|
+
temporalMetamodelPackage,
|
|
15844
15962
|
effectBehaviorsMetamodelPackage,
|
|
15845
15963
|
policyMetamodelPackage
|
|
15846
15964
|
];
|
|
@@ -16163,16 +16281,100 @@ function normalizeEnvironmentData(environment) {
|
|
|
16163
16281
|
setup: normalizeEnvironmentSetupSummary(environment.setup)
|
|
16164
16282
|
};
|
|
16165
16283
|
}
|
|
16284
|
+
function isGraphQLMutationDocument(query) {
|
|
16285
|
+
if (typeof query !== "string") return false;
|
|
16286
|
+
const tokens = [];
|
|
16287
|
+
for (let index = 0; index < query.length; ) {
|
|
16288
|
+
const character = query[index];
|
|
16289
|
+
if (/[,\s\ufeff]/.test(character)) {
|
|
16290
|
+
index += 1;
|
|
16291
|
+
continue;
|
|
16292
|
+
}
|
|
16293
|
+
if (character === "#") {
|
|
16294
|
+
while (index < query.length && !/[\r\n]/.test(query[index])) index += 1;
|
|
16295
|
+
continue;
|
|
16296
|
+
}
|
|
16297
|
+
if (character === '"') {
|
|
16298
|
+
const block = query.startsWith('"""', index);
|
|
16299
|
+
let closed = false;
|
|
16300
|
+
index += block ? 3 : 1;
|
|
16301
|
+
while (index < query.length) {
|
|
16302
|
+
if (block && query.startsWith('"""', index) && query[index - 1] !== "\\") {
|
|
16303
|
+
index += 3;
|
|
16304
|
+
closed = true;
|
|
16305
|
+
break;
|
|
16306
|
+
}
|
|
16307
|
+
if (!block && query[index] === '"') {
|
|
16308
|
+
index += 1;
|
|
16309
|
+
closed = true;
|
|
16310
|
+
break;
|
|
16311
|
+
}
|
|
16312
|
+
index += query[index] === "\\" && !block ? 2 : 1;
|
|
16313
|
+
}
|
|
16314
|
+
if (!closed) return true;
|
|
16315
|
+
continue;
|
|
16316
|
+
}
|
|
16317
|
+
const name = query.slice(index).match(/^[_A-Za-z][_0-9A-Za-z]*/)?.[0];
|
|
16318
|
+
if (name) {
|
|
16319
|
+
tokens.push(name);
|
|
16320
|
+
index += name.length;
|
|
16321
|
+
continue;
|
|
16322
|
+
}
|
|
16323
|
+
if ("{}()[]".includes(character)) tokens.push(character);
|
|
16324
|
+
index += 1;
|
|
16325
|
+
}
|
|
16326
|
+
const skipSelection = (start) => {
|
|
16327
|
+
let depth = 0;
|
|
16328
|
+
for (let index = start; index < tokens.length; index += 1) {
|
|
16329
|
+
if (tokens[index] === "{") depth += 1;
|
|
16330
|
+
if (tokens[index] === "}" && --depth === 0) return index + 1;
|
|
16331
|
+
}
|
|
16332
|
+
return null;
|
|
16333
|
+
};
|
|
16334
|
+
for (let index = 0; index < tokens.length; ) {
|
|
16335
|
+
const definition = tokens[index++];
|
|
16336
|
+
if (definition === "mutation") return true;
|
|
16337
|
+
if (definition === "{") {
|
|
16338
|
+
const nextDefinition2 = skipSelection(index - 1);
|
|
16339
|
+
if (nextDefinition2 === null) return true;
|
|
16340
|
+
index = nextDefinition2;
|
|
16341
|
+
continue;
|
|
16342
|
+
}
|
|
16343
|
+
if (!["query", "subscription", "fragment"].includes(definition || "")) {
|
|
16344
|
+
return true;
|
|
16345
|
+
}
|
|
16346
|
+
let parentheses = 0;
|
|
16347
|
+
let brackets = 0;
|
|
16348
|
+
while (index < tokens.length) {
|
|
16349
|
+
const token = tokens[index];
|
|
16350
|
+
if (token === "(") parentheses += 1;
|
|
16351
|
+
else if (token === ")") parentheses -= 1;
|
|
16352
|
+
else if (token === "[") brackets += 1;
|
|
16353
|
+
else if (token === "]") brackets -= 1;
|
|
16354
|
+
else if (token === "{" && parentheses === 0 && brackets === 0) break;
|
|
16355
|
+
index += 1;
|
|
16356
|
+
}
|
|
16357
|
+
if (index === tokens.length) return true;
|
|
16358
|
+
const nextDefinition = skipSelection(index);
|
|
16359
|
+
if (nextDefinition === null) return true;
|
|
16360
|
+
index = nextDefinition;
|
|
16361
|
+
}
|
|
16362
|
+
return false;
|
|
16363
|
+
}
|
|
16166
16364
|
var Environment = class _Environment {
|
|
16167
16365
|
granular;
|
|
16168
16366
|
envData;
|
|
16169
16367
|
_apiKey;
|
|
16170
16368
|
_apiEndpoint;
|
|
16171
|
-
|
|
16369
|
+
_tokenProvider;
|
|
16370
|
+
_beforeMutationSend;
|
|
16371
|
+
constructor(granular, envData, apiKey, apiEndpoint, tokenProvider, beforeMutationSend) {
|
|
16172
16372
|
this.granular = granular;
|
|
16173
16373
|
this.envData = envData;
|
|
16174
16374
|
this._apiKey = apiKey;
|
|
16175
16375
|
this._apiEndpoint = apiEndpoint;
|
|
16376
|
+
this._tokenProvider = tokenProvider;
|
|
16377
|
+
this._beforeMutationSend = beforeMutationSend;
|
|
16176
16378
|
}
|
|
16177
16379
|
/** The environment ID */
|
|
16178
16380
|
get environmentId() {
|
|
@@ -16238,6 +16440,15 @@ var Environment = class _Environment {
|
|
|
16238
16440
|
get authToken() {
|
|
16239
16441
|
return this._apiKey;
|
|
16240
16442
|
}
|
|
16443
|
+
resolveAuthToken() {
|
|
16444
|
+
if (!this._tokenProvider) return this._apiKey;
|
|
16445
|
+
return Promise.resolve(this._tokenProvider()).then((provided) => {
|
|
16446
|
+
if (typeof provided === "string" && provided.trim()) {
|
|
16447
|
+
this._apiKey = provided.trim();
|
|
16448
|
+
}
|
|
16449
|
+
return this._apiKey;
|
|
16450
|
+
});
|
|
16451
|
+
}
|
|
16241
16452
|
/** Base runtime URL derived from the GraphQL endpoint */
|
|
16242
16453
|
get runtimeBaseUrl() {
|
|
16243
16454
|
return this.getRuntimeBaseUrl();
|
|
@@ -16629,10 +16840,15 @@ var Environment = class _Environment {
|
|
|
16629
16840
|
async controlPlaneRequest(path, options = {}) {
|
|
16630
16841
|
const runtimeBase = this.getRuntimeBaseUrl();
|
|
16631
16842
|
const url = `${runtimeBase}${path}`;
|
|
16843
|
+
const authToken = await this.resolveAuthToken();
|
|
16844
|
+
const method = (options.method || "GET").toUpperCase();
|
|
16845
|
+
if (method !== "GET" && method !== "HEAD" && method !== "OPTIONS") {
|
|
16846
|
+
this._beforeMutationSend?.();
|
|
16847
|
+
}
|
|
16632
16848
|
const response = await fetch(url, {
|
|
16633
16849
|
...options,
|
|
16634
16850
|
headers: {
|
|
16635
|
-
Authorization: `Bearer ${
|
|
16851
|
+
Authorization: `Bearer ${authToken}`,
|
|
16636
16852
|
"Content-Type": "application/json",
|
|
16637
16853
|
...options.headers
|
|
16638
16854
|
}
|
|
@@ -16697,11 +16913,15 @@ var Environment = class _Environment {
|
|
|
16697
16913
|
* ```
|
|
16698
16914
|
*/
|
|
16699
16915
|
async graphql(query, variables) {
|
|
16916
|
+
const authToken = await this.resolveAuthToken();
|
|
16917
|
+
if (this._beforeMutationSend && isGraphQLMutationDocument(query)) {
|
|
16918
|
+
this._beforeMutationSend?.();
|
|
16919
|
+
}
|
|
16700
16920
|
const response = await fetch(this._apiEndpoint, {
|
|
16701
16921
|
method: "POST",
|
|
16702
16922
|
headers: {
|
|
16703
16923
|
"Content-Type": "application/json",
|
|
16704
|
-
Authorization: `Bearer ${
|
|
16924
|
+
Authorization: `Bearer ${authToken}`
|
|
16705
16925
|
},
|
|
16706
16926
|
body: JSON.stringify({
|
|
16707
16927
|
environmentId: this.environmentId,
|
|
@@ -17180,8 +17400,10 @@ var Environment = class _Environment {
|
|
|
17180
17400
|
eventType.payloadSchema.properties
|
|
17181
17401
|
)) {
|
|
17182
17402
|
const schema = propSchema;
|
|
17403
|
+
const format = schema.format === "date" || schema.format === "date-time" ? schema.format : void 0;
|
|
17183
17404
|
fieldSpecs[propName] = {
|
|
17184
17405
|
type: schema.type ?? "string",
|
|
17406
|
+
...format ? { format } : {},
|
|
17185
17407
|
description: schema.description
|
|
17186
17408
|
};
|
|
17187
17409
|
}
|
|
@@ -17603,40 +17825,36 @@ var EnvironmentSession = class extends Session {
|
|
|
17603
17825
|
environment;
|
|
17604
17826
|
sessionDataRoutePrefix;
|
|
17605
17827
|
sessionDataHeaders;
|
|
17828
|
+
beforeMutationSend;
|
|
17606
17829
|
heartbeatTimer = null;
|
|
17607
|
-
|
|
17608
|
-
/** The last known graph container status, updated by checkReadiness() or on heartbeat */
|
|
17830
|
+
/** The last known graph container status, updated by checkReadiness(). */
|
|
17609
17831
|
graphContainerStatus = null;
|
|
17610
17832
|
constructor(client, environment, clientId, options = {}) {
|
|
17611
17833
|
super(client, clientId, { initialQuota: options.initialQuota });
|
|
17612
17834
|
this.environment = environment;
|
|
17613
17835
|
this.sessionDataRoutePrefix = options.sessionDataRoutePrefix || "/orchestrator/ws/sessions";
|
|
17614
17836
|
this.sessionDataHeaders = options.sessionDataHeaders || {};
|
|
17837
|
+
this.beforeMutationSend = options.beforeMutationSend;
|
|
17615
17838
|
this.setFeedListTransport(
|
|
17616
17839
|
(feedOptions) => this.sessionDataRequest("/feed", feedOptions)
|
|
17617
17840
|
);
|
|
17618
17841
|
}
|
|
17619
17842
|
/**
|
|
17620
17843
|
* Keep the browser session transport observable from the client side.
|
|
17621
|
-
*
|
|
17622
|
-
*
|
|
17623
|
-
*
|
|
17624
|
-
*
|
|
17844
|
+
* SessionDO already broadcasts a heartbeat every five seconds. Treat that
|
|
17845
|
+
* and all other inbound frames as proof of life instead of issuing an RPC:
|
|
17846
|
+
* an application RPC may be delayed by Durable Object work even while the
|
|
17847
|
+
* underlying WebSocket is healthy.
|
|
17625
17848
|
*/
|
|
17626
17849
|
startHeartbeat() {
|
|
17627
17850
|
if (this.heartbeatTimer) return;
|
|
17628
17851
|
this.heartbeatTimer = setInterval(() => {
|
|
17629
|
-
if (this.
|
|
17630
|
-
this.
|
|
17631
|
-
|
|
17632
|
-
|
|
17633
|
-
|
|
17634
|
-
|
|
17635
|
-
}).catch((error) => {
|
|
17636
|
-
this.client.reportTransportFailure(error);
|
|
17637
|
-
}).finally(() => {
|
|
17638
|
-
this.heartbeatInFlight = false;
|
|
17639
|
-
});
|
|
17852
|
+
if (!this.client.isTransportOpen()) return;
|
|
17853
|
+
if (this.client.hasRecentInboundActivity(3e4)) return;
|
|
17854
|
+
if (this.client.hasRecentlyPendingRpcPeriod(6e4)) return;
|
|
17855
|
+
this.client.reportTransportFailure(
|
|
17856
|
+
new Error("No server activity received for 30 seconds")
|
|
17857
|
+
);
|
|
17640
17858
|
}, 5e3);
|
|
17641
17859
|
this.heartbeatTimer.unref?.();
|
|
17642
17860
|
}
|
|
@@ -17645,7 +17863,6 @@ var EnvironmentSession = class extends Session {
|
|
|
17645
17863
|
clearInterval(this.heartbeatTimer);
|
|
17646
17864
|
this.heartbeatTimer = null;
|
|
17647
17865
|
}
|
|
17648
|
-
this.heartbeatInFlight = false;
|
|
17649
17866
|
}
|
|
17650
17867
|
async hello() {
|
|
17651
17868
|
const result = await super.hello();
|
|
@@ -17706,7 +17923,13 @@ var EnvironmentSession = class extends Session {
|
|
|
17706
17923
|
for (let attempt = 1; attempt <= SESSION_DATA_REQUEST_RETRY_COUNT; attempt += 1) {
|
|
17707
17924
|
try {
|
|
17708
17925
|
const headers = new Headers(init2.headers);
|
|
17709
|
-
|
|
17926
|
+
const resolvedAuthToken = this.environment.resolveAuthToken();
|
|
17927
|
+
const authToken = typeof resolvedAuthToken === "string" ? resolvedAuthToken : await resolvedAuthToken;
|
|
17928
|
+
headers.set("Authorization", `Bearer ${authToken}`);
|
|
17929
|
+
const method = (init2.method || "GET").toUpperCase();
|
|
17930
|
+
if (method !== "GET" && method !== "HEAD" && method !== "OPTIONS") {
|
|
17931
|
+
this.beforeMutationSend?.();
|
|
17932
|
+
}
|
|
17710
17933
|
const response = await fetch(url, {
|
|
17711
17934
|
method: init2.method || "GET",
|
|
17712
17935
|
headers,
|
|
@@ -18165,7 +18388,7 @@ var EnvironmentSession = class extends Session {
|
|
|
18165
18388
|
method: "POST",
|
|
18166
18389
|
headers: {
|
|
18167
18390
|
"Content-Type": "application/json",
|
|
18168
|
-
Authorization: `Bearer ${this.environment.
|
|
18391
|
+
Authorization: `Bearer ${await this.environment.resolveAuthToken()}`
|
|
18169
18392
|
},
|
|
18170
18393
|
body: JSON.stringify({
|
|
18171
18394
|
reason: "sdk_disconnect_http_fallback",
|
|
@@ -18957,6 +19180,9 @@ var Granular = class _Granular {
|
|
|
18957
19180
|
if (typeof options.limit === "number") {
|
|
18958
19181
|
query.set("limit", String(options.limit));
|
|
18959
19182
|
}
|
|
19183
|
+
if (options.consistency === "refresh") {
|
|
19184
|
+
query.set("consistency", "refresh");
|
|
19185
|
+
}
|
|
18960
19186
|
const state = await this.request(
|
|
18961
19187
|
`/sdk/user-environment-state?${query.toString()}`
|
|
18962
19188
|
);
|
|
@@ -19100,6 +19326,10 @@ var Granular = class _Granular {
|
|
|
19100
19326
|
});
|
|
19101
19327
|
}
|
|
19102
19328
|
async recordOpenAIUsageSpend(usage, context, options) {
|
|
19329
|
+
const providedToken = await this.tokenProvider?.();
|
|
19330
|
+
if (typeof providedToken === "string" && providedToken.trim()) {
|
|
19331
|
+
this.apiKey = providedToken.trim();
|
|
19332
|
+
}
|
|
19103
19333
|
return recordOpenAIUsageSpend({
|
|
19104
19334
|
apiUrl: this.apiUrl,
|
|
19105
19335
|
token: this.apiKey,
|
|
@@ -19272,7 +19502,13 @@ var Granular = class _Granular {
|
|
|
19272
19502
|
}
|
|
19273
19503
|
bindEnvironmentHandle(envData) {
|
|
19274
19504
|
const graphqlEndpoint = `${this.httpUrl}/orchestrator/graphql`;
|
|
19275
|
-
return new Environment(
|
|
19505
|
+
return new Environment(
|
|
19506
|
+
this,
|
|
19507
|
+
envData,
|
|
19508
|
+
this.apiKey,
|
|
19509
|
+
graphqlEndpoint,
|
|
19510
|
+
this.tokenProvider
|
|
19511
|
+
);
|
|
19276
19512
|
}
|
|
19277
19513
|
async bindWebSocketEnvironmentSession(environment, clientId, session, transportOptions = {}) {
|
|
19278
19514
|
const client = new WSClient({
|
|
@@ -20156,6 +20392,10 @@ var Granular = class _Granular {
|
|
|
20156
20392
|
console.log(`[SDK] Requesting: ${url}`);
|
|
20157
20393
|
}
|
|
20158
20394
|
for (let attempt = 1; attempt <= LOCAL_CONTROL_REQUEST_RETRY_COUNT; attempt += 1) {
|
|
20395
|
+
const providedToken = await this.tokenProvider?.();
|
|
20396
|
+
if (typeof providedToken === "string" && providedToken.trim()) {
|
|
20397
|
+
this.apiKey = providedToken.trim();
|
|
20398
|
+
}
|
|
20159
20399
|
const response = await fetch(url, {
|
|
20160
20400
|
...options,
|
|
20161
20401
|
headers: {
|
|
@@ -22367,6 +22607,10 @@ function jsonSchemaTypeName(schema) {
|
|
|
22367
22607
|
const record = normalizeJsonSchema(schema);
|
|
22368
22608
|
if (!record) return "unknown";
|
|
22369
22609
|
const type = record.type;
|
|
22610
|
+
if (record.format === "date-time") return "date-time";
|
|
22611
|
+
if (record.format === "date" || type === "date" || Array.isArray(type) && type.includes("date")) {
|
|
22612
|
+
return "date";
|
|
22613
|
+
}
|
|
22370
22614
|
if (typeof type === "string") {
|
|
22371
22615
|
if (type === "array") return "array";
|
|
22372
22616
|
if (type === "object") return "object";
|
|
@@ -22868,6 +23112,8 @@ ${actionIndex}
|
|
|
22868
23112
|
- A suggestion is a recommendation button: \`await stateHandle.suggest(message)\`. A prepared action is the editable form the user can review/run: \`const action = stateHandle.reach(); const prepared = await action.open()\`.
|
|
22869
23113
|
- Use suggestions when the user asks "what can I do next?", asks for options, or gives an unclear intent. Prefer 2 to 5 concrete suggestions and keep text short.
|
|
22870
23114
|
- Opening a prepared action does not execute the underlying mutation. Use \`.open()\` only when the user asks to prepare, review, show, or edit an action before running it, when a new record must be prepared, or when a reviewable form must collect missing editable inputs. Prefill only grounded values and leave unknown fields empty.
|
|
23115
|
+
- For creation inputs, use the declared action schema and its field descriptions as the mapping authority. Copy every compatible value explicitly present in the current request, conversation, selected/saved object, file, fresh read, or declared ontology default, including values for fields with arbitrary names. Omit only values for which that context provides no evidence.
|
|
23116
|
+
- Never fill an input because of its field name, a regular expression or other string pattern, its primitive type, a schema minimum, an example value, or the first enum option. If the evidence is ambiguous, leave the field unresolved or ask the user.
|
|
22871
23117
|
- When the user explicitly commands an existing-record mutation such as approve, reject, block, route, send, or update, and one visible domain action uniquely matches, call that domain action directly. Do not substitute a state-handle \`.open()\` artifact for execution. If runtime policy requires confirmation, invoke the action once and let the runtime pause and resume that same invocation.
|
|
22872
23118
|
- When a grounded related/context record can satisfy the prepared action through declared relationships, use those relationships to fill required relationship inputs before opening or updating the action. If a required relationship remains empty, continue through declared relationship chains from the grounded object when the next hop can fill that slot. Do not only save the context record in memory while leaving derivable relationship slots blank.
|
|
22873
23119
|
- A derived intermediate relationship is not enough when another required relationship is still reachable from it. For example, if a team gives a cost center and the action also requires a budget, traverse the cost center's declared budget relationship before opening the action.
|
|
@@ -23521,6 +23767,7 @@ exports.hasOpenPrompt = hasOpenPrompt;
|
|
|
23521
23767
|
exports.hashHarnessTemplateValue = hashHarnessTemplateValue;
|
|
23522
23768
|
exports.invokeRegisteredEffect = invokeRegisteredEffect;
|
|
23523
23769
|
exports.isCanonicalSessionFeedDocument = isCanonicalSessionFeedDocument;
|
|
23770
|
+
exports.isGraphQLMutationDocument = isGraphQLMutationDocument;
|
|
23524
23771
|
exports.isLocalApiUrl = isLocalApiUrl;
|
|
23525
23772
|
exports.listHarnessTemplates = listHarnessTemplates;
|
|
23526
23773
|
exports.mergeFeedItemsBySequence = mergeFeedItemsBySequence;
|