@granular-software/sdk 0.4.32 → 0.4.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -0
- package/dist/agent-evals.d.mts +1 -1
- package/dist/agent-evals.d.ts +1 -1
- package/dist/agent-evals.js +775 -307
- package/dist/agent-evals.js.map +1 -1
- package/dist/agent-evals.mjs +775 -307
- package/dist/agent-evals.mjs.map +1 -1
- package/dist/cli/index.js +744 -21
- package/dist/{client-C2Gk641P.d.mts → client-DTvI5MUG.d.mts} +129 -33
- package/dist/{client-C2Gk641P.d.ts → client-DTvI5MUG.d.ts} +129 -33
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +9293 -9125
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +9293 -9125
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -15222,7 +15222,8 @@ ${effectMetamodelTable}
|
|
|
15222
15222
|
| \`getDomain()\`, \`getDomainTypes()\`, \`getDomainDocs()\`, \`getDomainDocumentation()\` | Domain summary and generated TypeScript / docs. |
|
|
15223
15223
|
| \`getEffects()\` / \`getTools()\`, \`session.on("effects:changed", ...)\` | Effect catalog and live updates. |
|
|
15224
15224
|
| \`checkReadiness()\`, \`on('readiness', ...)\` | Runtime readiness. |
|
|
15225
|
-
| \`getHeap()\` |
|
|
15225
|
+
| \`document\`, \`getHeap()\` | Current live session state from the WebSocket. |
|
|
15226
|
+
| \`messages.list()\`, \`timeline.list()\`, \`jobs.list/get()\`, \`heap.entries.list/get()\`, \`heap.lists.list/get()\`, \`transcript.list()\` | Durable session history and saved artifacts. |
|
|
15226
15227
|
| \`disconnect()\` | Close the live runtime session. |
|
|
15227
15228
|
| \`rpc(method, params)\` | Low-level session RPC (advanced). |
|
|
15228
15229
|
| \`disconnect()\` | End the session. |
|
|
@@ -19413,6 +19414,540 @@ var JobImplementation = class {
|
|
|
19413
19414
|
}
|
|
19414
19415
|
};
|
|
19415
19416
|
|
|
19417
|
+
// src/job-presentation.ts
|
|
19418
|
+
var RESPONSE_KEYS = [
|
|
19419
|
+
"reply",
|
|
19420
|
+
"response",
|
|
19421
|
+
"text",
|
|
19422
|
+
"message",
|
|
19423
|
+
"summary",
|
|
19424
|
+
"answer"
|
|
19425
|
+
];
|
|
19426
|
+
var ENTRY_KEY_CANDIDATES = ["entryPath", "path"];
|
|
19427
|
+
var ENTRY_ARRAY_KEY_CANDIDATES = ["entryPaths", "paths"];
|
|
19428
|
+
var LIST_KEY_CANDIDATES = ["listName"];
|
|
19429
|
+
var LIST_ARRAY_KEY_CANDIDATES = ["listNames"];
|
|
19430
|
+
var VARIABLE_KEY_CANDIDATES = ["variableName"];
|
|
19431
|
+
var VARIABLE_ARRAY_KEY_CANDIDATES = ["variableNames"];
|
|
19432
|
+
var UI_CONTAINER_KEYS = ["show", "display", "present", "ui"];
|
|
19433
|
+
function asRecord2(value) {
|
|
19434
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
19435
|
+
return value;
|
|
19436
|
+
}
|
|
19437
|
+
function normalizeText(value) {
|
|
19438
|
+
if (typeof value !== "string") return null;
|
|
19439
|
+
const trimmed = value.trim();
|
|
19440
|
+
if (!trimmed) return null;
|
|
19441
|
+
if (trimmed.startsWith("{") && trimmed.endsWith("}") || trimmed.startsWith("[") && trimmed.endsWith("]")) {
|
|
19442
|
+
return null;
|
|
19443
|
+
}
|
|
19444
|
+
return trimmed;
|
|
19445
|
+
}
|
|
19446
|
+
function humanTextFromStdout(stdout) {
|
|
19447
|
+
for (const line of [...stdout].reverse()) {
|
|
19448
|
+
const normalized = normalizeText(line);
|
|
19449
|
+
if (!normalized) continue;
|
|
19450
|
+
if (/^[A-Z_]+:/.test(normalized)) continue;
|
|
19451
|
+
return normalized;
|
|
19452
|
+
}
|
|
19453
|
+
return null;
|
|
19454
|
+
}
|
|
19455
|
+
function pushString(target, value) {
|
|
19456
|
+
if (typeof value === "string" && value.trim()) {
|
|
19457
|
+
target.add(value.trim());
|
|
19458
|
+
}
|
|
19459
|
+
}
|
|
19460
|
+
function pushStringArray(target, value) {
|
|
19461
|
+
if (!Array.isArray(value)) return;
|
|
19462
|
+
for (const item of value) {
|
|
19463
|
+
pushString(target, item);
|
|
19464
|
+
}
|
|
19465
|
+
}
|
|
19466
|
+
function collectReferencesFromRecord(record, refs) {
|
|
19467
|
+
for (const key of ENTRY_KEY_CANDIDATES)
|
|
19468
|
+
pushString(refs.entryPaths, record[key]);
|
|
19469
|
+
for (const key of ENTRY_ARRAY_KEY_CANDIDATES)
|
|
19470
|
+
pushStringArray(refs.entryPaths, record[key]);
|
|
19471
|
+
for (const key of LIST_KEY_CANDIDATES)
|
|
19472
|
+
pushString(refs.listNames, record[key]);
|
|
19473
|
+
for (const key of LIST_ARRAY_KEY_CANDIDATES)
|
|
19474
|
+
pushStringArray(refs.listNames, record[key]);
|
|
19475
|
+
for (const key of VARIABLE_KEY_CANDIDATES)
|
|
19476
|
+
pushString(refs.variableNames, record[key]);
|
|
19477
|
+
for (const key of VARIABLE_ARRAY_KEY_CANDIDATES)
|
|
19478
|
+
pushStringArray(refs.variableNames, record[key]);
|
|
19479
|
+
}
|
|
19480
|
+
function scanForHeapReferences(value, heap, refs, depth = 0, seen = /* @__PURE__ */ new Set()) {
|
|
19481
|
+
if (value === null || value === void 0 || depth > 4 || seen.has(value))
|
|
19482
|
+
return;
|
|
19483
|
+
if (typeof value === "string") {
|
|
19484
|
+
const trimmed = value.trim();
|
|
19485
|
+
if (heap.entriesByPath?.[trimmed]) refs.entryPaths.add(trimmed);
|
|
19486
|
+
if (heap.listsByName?.[trimmed]) refs.listNames.add(trimmed);
|
|
19487
|
+
if (heap.variablesByName?.[trimmed]) refs.variableNames.add(trimmed);
|
|
19488
|
+
return;
|
|
19489
|
+
}
|
|
19490
|
+
if (Array.isArray(value)) {
|
|
19491
|
+
seen.add(value);
|
|
19492
|
+
for (const item of value.slice(0, 24)) {
|
|
19493
|
+
scanForHeapReferences(item, heap, refs, depth + 1, seen);
|
|
19494
|
+
}
|
|
19495
|
+
return;
|
|
19496
|
+
}
|
|
19497
|
+
const record = asRecord2(value);
|
|
19498
|
+
if (!record) return;
|
|
19499
|
+
seen.add(value);
|
|
19500
|
+
collectReferencesFromRecord(record, refs);
|
|
19501
|
+
for (const key of UI_CONTAINER_KEYS) {
|
|
19502
|
+
const nested = asRecord2(record[key]);
|
|
19503
|
+
if (nested) collectReferencesFromRecord(nested, refs);
|
|
19504
|
+
}
|
|
19505
|
+
for (const nested of Object.values(record).slice(0, 24)) {
|
|
19506
|
+
scanForHeapReferences(nested, heap, refs, depth + 1, seen);
|
|
19507
|
+
}
|
|
19508
|
+
}
|
|
19509
|
+
function resolveVariablesToReferences(variableNames, heap, refs) {
|
|
19510
|
+
for (const variableName of variableNames) {
|
|
19511
|
+
const variable = heap.variablesByName?.[variableName];
|
|
19512
|
+
if (!variable) continue;
|
|
19513
|
+
if (variable.kind === "entry" && variable.entryPath) {
|
|
19514
|
+
refs.entryPaths.add(variable.entryPath);
|
|
19515
|
+
}
|
|
19516
|
+
if (variable.kind === "list" && variable.listName) {
|
|
19517
|
+
refs.listNames.add(variable.listName);
|
|
19518
|
+
}
|
|
19519
|
+
}
|
|
19520
|
+
}
|
|
19521
|
+
function sortEntries(entries) {
|
|
19522
|
+
return [...entries].sort((a, b) => (b.updatedAt || 0) - (a.updatedAt || 0));
|
|
19523
|
+
}
|
|
19524
|
+
function sortLists(lists) {
|
|
19525
|
+
return [...lists].sort((a, b) => (b.updatedAt || 0) - (a.updatedAt || 0));
|
|
19526
|
+
}
|
|
19527
|
+
function dedupeEntries(entries) {
|
|
19528
|
+
const seen = /* @__PURE__ */ new Set();
|
|
19529
|
+
const result = [];
|
|
19530
|
+
for (const entry of entries) {
|
|
19531
|
+
if (!entry?.path || seen.has(entry.path)) continue;
|
|
19532
|
+
seen.add(entry.path);
|
|
19533
|
+
result.push(entry);
|
|
19534
|
+
}
|
|
19535
|
+
return result;
|
|
19536
|
+
}
|
|
19537
|
+
function dedupeLists(lists) {
|
|
19538
|
+
const seen = /* @__PURE__ */ new Set();
|
|
19539
|
+
const result = [];
|
|
19540
|
+
for (const list of lists) {
|
|
19541
|
+
if (!list?.name || seen.has(list.name)) continue;
|
|
19542
|
+
seen.add(list.name);
|
|
19543
|
+
result.push(list);
|
|
19544
|
+
}
|
|
19545
|
+
return result;
|
|
19546
|
+
}
|
|
19547
|
+
function extractResponseText(result, stdout) {
|
|
19548
|
+
const directText = normalizeText(result);
|
|
19549
|
+
if (directText) return directText;
|
|
19550
|
+
const record = asRecord2(result);
|
|
19551
|
+
if (record) {
|
|
19552
|
+
for (const key of RESPONSE_KEYS) {
|
|
19553
|
+
const normalized = normalizeText(record[key]);
|
|
19554
|
+
if (normalized) return normalized;
|
|
19555
|
+
}
|
|
19556
|
+
for (const containerKey of UI_CONTAINER_KEYS) {
|
|
19557
|
+
const nested = asRecord2(record[containerKey]);
|
|
19558
|
+
if (!nested) continue;
|
|
19559
|
+
for (const key of RESPONSE_KEYS) {
|
|
19560
|
+
const normalized = normalizeText(nested[key]);
|
|
19561
|
+
if (normalized) return normalized;
|
|
19562
|
+
}
|
|
19563
|
+
}
|
|
19564
|
+
}
|
|
19565
|
+
return humanTextFromStdout(stdout);
|
|
19566
|
+
}
|
|
19567
|
+
function fallbackResponseText(entries, lists) {
|
|
19568
|
+
if (entries.length > 0) {
|
|
19569
|
+
return entries.length === 1 ? "I found one relevant record." : `I found ${entries.length} relevant records.`;
|
|
19570
|
+
}
|
|
19571
|
+
if (lists.length > 0) {
|
|
19572
|
+
const emptyOnly = lists.every((list) => (list.paths || []).length === 0);
|
|
19573
|
+
if (emptyOnly) {
|
|
19574
|
+
return lists.length === 1 ? "I saved one empty result set." : `I saved ${lists.length} empty result sets.`;
|
|
19575
|
+
}
|
|
19576
|
+
return lists.length === 1 ? "I saved one result set." : `I saved ${lists.length} result sets.`;
|
|
19577
|
+
}
|
|
19578
|
+
return null;
|
|
19579
|
+
}
|
|
19580
|
+
function getJobRelatedEntries(heap, jobId) {
|
|
19581
|
+
return sortEntries(
|
|
19582
|
+
Object.values(heap.entriesByPath || {}).filter(
|
|
19583
|
+
(entry) => entry.relatedJobIds?.includes(jobId)
|
|
19584
|
+
)
|
|
19585
|
+
);
|
|
19586
|
+
}
|
|
19587
|
+
function getJobRelatedLists(heap, jobId) {
|
|
19588
|
+
return sortLists(
|
|
19589
|
+
Object.values(heap.listsByName || {}).filter(
|
|
19590
|
+
(list) => list.relatedJobIds?.includes(jobId)
|
|
19591
|
+
)
|
|
19592
|
+
);
|
|
19593
|
+
}
|
|
19594
|
+
function entriesFromLists(lists, heap) {
|
|
19595
|
+
const entries = [];
|
|
19596
|
+
for (const list of lists) {
|
|
19597
|
+
for (const path6 of list.paths || []) {
|
|
19598
|
+
const entry = heap.entriesByPath?.[path6];
|
|
19599
|
+
if (entry) entries.push(entry);
|
|
19600
|
+
}
|
|
19601
|
+
}
|
|
19602
|
+
return entries;
|
|
19603
|
+
}
|
|
19604
|
+
function resolveJobPresentation({
|
|
19605
|
+
jobId,
|
|
19606
|
+
result,
|
|
19607
|
+
stdout = [],
|
|
19608
|
+
sessionHeap,
|
|
19609
|
+
allowExplicitArtifacts = true
|
|
19610
|
+
}) {
|
|
19611
|
+
const refs = {
|
|
19612
|
+
entryPaths: /* @__PURE__ */ new Set(),
|
|
19613
|
+
listNames: /* @__PURE__ */ new Set(),
|
|
19614
|
+
variableNames: /* @__PURE__ */ new Set()
|
|
19615
|
+
};
|
|
19616
|
+
if (allowExplicitArtifacts) {
|
|
19617
|
+
scanForHeapReferences(result, sessionHeap, refs);
|
|
19618
|
+
resolveVariablesToReferences(refs.variableNames, sessionHeap, refs);
|
|
19619
|
+
}
|
|
19620
|
+
const referencedLists = sortLists(
|
|
19621
|
+
[...refs.listNames].map((name) => sessionHeap.listsByName?.[name]).filter((list) => Boolean(list))
|
|
19622
|
+
);
|
|
19623
|
+
const referencedEntries = sortEntries(
|
|
19624
|
+
[...refs.entryPaths].map((path6) => sessionHeap.entriesByPath?.[path6]).filter((entry) => Boolean(entry))
|
|
19625
|
+
);
|
|
19626
|
+
const jobLists = getJobRelatedLists(sessionHeap, jobId);
|
|
19627
|
+
const jobEntries = getJobRelatedEntries(sessionHeap, jobId);
|
|
19628
|
+
const changedEntries = dedupeEntries([
|
|
19629
|
+
...jobEntries,
|
|
19630
|
+
...entriesFromLists(jobLists, sessionHeap)
|
|
19631
|
+
]);
|
|
19632
|
+
const explicitLists = dedupeLists(referencedLists);
|
|
19633
|
+
const explicitEntries = dedupeEntries([
|
|
19634
|
+
...referencedEntries,
|
|
19635
|
+
...entriesFromLists(referencedLists, sessionHeap)
|
|
19636
|
+
]);
|
|
19637
|
+
const hasExplicitArtifacts = allowExplicitArtifacts && (explicitEntries.length > 0 || explicitLists.length > 0);
|
|
19638
|
+
const lists = hasExplicitArtifacts ? explicitLists : jobLists;
|
|
19639
|
+
const entries = hasExplicitArtifacts ? explicitEntries : changedEntries;
|
|
19640
|
+
const responseText = extractResponseText(result, stdout) || fallbackResponseText(entries, lists);
|
|
19641
|
+
return {
|
|
19642
|
+
responseText,
|
|
19643
|
+
entries,
|
|
19644
|
+
lists,
|
|
19645
|
+
changedEntries,
|
|
19646
|
+
changedLists: jobLists,
|
|
19647
|
+
hasExplicitArtifacts
|
|
19648
|
+
};
|
|
19649
|
+
}
|
|
19650
|
+
|
|
19651
|
+
// src/session-transcript.ts
|
|
19652
|
+
var EMPTY_HEAP = {
|
|
19653
|
+
entriesByPath: {},
|
|
19654
|
+
listsByName: {},
|
|
19655
|
+
variablesByName: {}};
|
|
19656
|
+
function asRecord3(value) {
|
|
19657
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
19658
|
+
return value;
|
|
19659
|
+
}
|
|
19660
|
+
function asArray(value) {
|
|
19661
|
+
return Array.isArray(value) ? value : [];
|
|
19662
|
+
}
|
|
19663
|
+
function asNumber(value) {
|
|
19664
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
19665
|
+
}
|
|
19666
|
+
function asString(value) {
|
|
19667
|
+
return typeof value === "string" ? value : void 0;
|
|
19668
|
+
}
|
|
19669
|
+
function trimString(value) {
|
|
19670
|
+
return typeof value === "string" ? value.trim() : "";
|
|
19671
|
+
}
|
|
19672
|
+
function normalizeShowRefs(value) {
|
|
19673
|
+
const record = asRecord3(value);
|
|
19674
|
+
if (!record) return void 0;
|
|
19675
|
+
const normalizeRefs = (input) => {
|
|
19676
|
+
if (!Array.isArray(input)) return void 0;
|
|
19677
|
+
const refs = Array.from(
|
|
19678
|
+
new Set(
|
|
19679
|
+
input.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean)
|
|
19680
|
+
)
|
|
19681
|
+
);
|
|
19682
|
+
return refs.length > 0 ? refs : void 0;
|
|
19683
|
+
};
|
|
19684
|
+
const show = {
|
|
19685
|
+
entryPaths: normalizeRefs(record.entryPaths),
|
|
19686
|
+
listNames: normalizeRefs(record.listNames),
|
|
19687
|
+
variableNames: normalizeRefs(record.variableNames)
|
|
19688
|
+
};
|
|
19689
|
+
return show.entryPaths || show.listNames || show.variableNames ? show : void 0;
|
|
19690
|
+
}
|
|
19691
|
+
function stringifyTranscriptValue(value, fallback2 = "") {
|
|
19692
|
+
if (typeof value === "string") {
|
|
19693
|
+
return value.trim() || fallback2;
|
|
19694
|
+
}
|
|
19695
|
+
if (typeof value === "boolean") {
|
|
19696
|
+
return value ? "Confirmed" : "Canceled";
|
|
19697
|
+
}
|
|
19698
|
+
if (value === void 0) {
|
|
19699
|
+
return fallback2;
|
|
19700
|
+
}
|
|
19701
|
+
try {
|
|
19702
|
+
const json = JSON.stringify(value, null, 2);
|
|
19703
|
+
if (!json || json === "undefined") return fallback2;
|
|
19704
|
+
return json.length > 2e3 ? `${json.slice(0, 2e3)}...` : json;
|
|
19705
|
+
} catch {
|
|
19706
|
+
return String(value);
|
|
19707
|
+
}
|
|
19708
|
+
}
|
|
19709
|
+
function buildArtifactHistory(show) {
|
|
19710
|
+
if (!show) return void 0;
|
|
19711
|
+
return `[Agent message]
|
|
19712
|
+
${stringifyTranscriptValue({ show }, "")}`;
|
|
19713
|
+
}
|
|
19714
|
+
function normalizeConversationMessage(raw) {
|
|
19715
|
+
const record = asRecord3(raw);
|
|
19716
|
+
if (!record) return null;
|
|
19717
|
+
const role = record.role === "user" ? "user" : record.role === "assistant" ? "assistant" : null;
|
|
19718
|
+
if (!role) return null;
|
|
19719
|
+
const content = trimString(
|
|
19720
|
+
record.content ?? record.reply ?? record.message ?? record.text
|
|
19721
|
+
);
|
|
19722
|
+
const show = normalizeShowRefs(record.show);
|
|
19723
|
+
const id = asString(record.id) || crypto.randomUUID();
|
|
19724
|
+
const timestamp = asNumber(record.timestamp) || asNumber(record.ts) || 0;
|
|
19725
|
+
if (!content && !show) return null;
|
|
19726
|
+
return {
|
|
19727
|
+
id,
|
|
19728
|
+
role,
|
|
19729
|
+
content,
|
|
19730
|
+
timestamp,
|
|
19731
|
+
jobId: asString(record.jobId),
|
|
19732
|
+
promptId: asString(record.promptId),
|
|
19733
|
+
show,
|
|
19734
|
+
historyContent: role === "assistant" ? content ? `[Assistant reply]
|
|
19735
|
+
${content}` : buildArtifactHistory(show) : void 0,
|
|
19736
|
+
source: "conversation"
|
|
19737
|
+
};
|
|
19738
|
+
}
|
|
19739
|
+
function normalizePromptEntries(jobId, rawPrompts, conversationPromptIds) {
|
|
19740
|
+
const promptsById = asRecord3(rawPrompts) || {};
|
|
19741
|
+
return Object.values(promptsById).map((value) => asRecord3(value)).filter((value) => Boolean(value)).sort(
|
|
19742
|
+
(left, right) => (asNumber(left.openedAt) || asNumber(left.answeredAt) || 0) - (asNumber(right.openedAt) || asNumber(right.answeredAt) || 0)
|
|
19743
|
+
).flatMap((prompt3) => {
|
|
19744
|
+
const promptId = asString(prompt3.promptId);
|
|
19745
|
+
if (!promptId || conversationPromptIds.has(promptId)) return [];
|
|
19746
|
+
const title = trimString(prompt3.title);
|
|
19747
|
+
const message = trimString(prompt3.message);
|
|
19748
|
+
const assistantContent = message || title || "Input required";
|
|
19749
|
+
const openedAt = asNumber(prompt3.openedAt) || 0;
|
|
19750
|
+
const answeredAt = asNumber(prompt3.answeredAt) || openedAt;
|
|
19751
|
+
const entries = [
|
|
19752
|
+
{
|
|
19753
|
+
id: `prompt:${promptId}:assistant`,
|
|
19754
|
+
role: "assistant",
|
|
19755
|
+
content: assistantContent,
|
|
19756
|
+
timestamp: openedAt,
|
|
19757
|
+
jobId,
|
|
19758
|
+
promptId,
|
|
19759
|
+
historyContent: `[Assistant reply]
|
|
19760
|
+
${assistantContent}`,
|
|
19761
|
+
source: "job_prompt"
|
|
19762
|
+
}
|
|
19763
|
+
];
|
|
19764
|
+
if (Object.prototype.hasOwnProperty.call(prompt3, "answer")) {
|
|
19765
|
+
entries.push({
|
|
19766
|
+
id: `prompt:${promptId}:user`,
|
|
19767
|
+
role: "user",
|
|
19768
|
+
content: stringifyTranscriptValue(prompt3.answer, ""),
|
|
19769
|
+
timestamp: answeredAt,
|
|
19770
|
+
jobId,
|
|
19771
|
+
promptId,
|
|
19772
|
+
source: "job_prompt"
|
|
19773
|
+
});
|
|
19774
|
+
}
|
|
19775
|
+
return entries;
|
|
19776
|
+
});
|
|
19777
|
+
}
|
|
19778
|
+
function normalizeAgentMessageEntries(jobId, rawMessages) {
|
|
19779
|
+
return asArray(rawMessages).map((value) => asRecord3(value)).filter((value) => Boolean(value)).sort(
|
|
19780
|
+
(left, right) => (asNumber(left.timestamp) || asNumber(left.ts) || 0) - (asNumber(right.timestamp) || asNumber(right.ts) || 0)
|
|
19781
|
+
).flatMap((message) => {
|
|
19782
|
+
const messageId = asString(message.messageId) || asString(message.id) || crypto.randomUUID();
|
|
19783
|
+
const timestamp = asNumber(message.timestamp) || asNumber(message.ts) || 0;
|
|
19784
|
+
const reply = trimString(
|
|
19785
|
+
message.reply ?? message.message ?? message.text ?? message.content
|
|
19786
|
+
);
|
|
19787
|
+
const show = normalizeShowRefs(message.show);
|
|
19788
|
+
const entries = [];
|
|
19789
|
+
if (reply) {
|
|
19790
|
+
entries.push({
|
|
19791
|
+
id: `agent:${messageId}:text`,
|
|
19792
|
+
role: "assistant",
|
|
19793
|
+
content: reply,
|
|
19794
|
+
timestamp,
|
|
19795
|
+
jobId,
|
|
19796
|
+
historyContent: `[Assistant reply]
|
|
19797
|
+
${reply}`,
|
|
19798
|
+
source: "job_agent_message"
|
|
19799
|
+
});
|
|
19800
|
+
}
|
|
19801
|
+
if (show) {
|
|
19802
|
+
entries.push({
|
|
19803
|
+
id: `agent:${messageId}:artifacts`,
|
|
19804
|
+
role: "assistant",
|
|
19805
|
+
content: "",
|
|
19806
|
+
timestamp,
|
|
19807
|
+
jobId,
|
|
19808
|
+
show,
|
|
19809
|
+
historyContent: buildArtifactHistory(show),
|
|
19810
|
+
source: "job_agent_message"
|
|
19811
|
+
});
|
|
19812
|
+
}
|
|
19813
|
+
return entries;
|
|
19814
|
+
});
|
|
19815
|
+
}
|
|
19816
|
+
function buildJobFallbackEntries(jobId, job2, sessionHeap) {
|
|
19817
|
+
const timestamp = asNumber(job2.finishedAt) || asNumber(job2.startedAt) || asNumber(job2.submittedAt) || 0;
|
|
19818
|
+
const resultPreview = stringifyTranscriptValue(
|
|
19819
|
+
job2.result,
|
|
19820
|
+
"No job result recorded."
|
|
19821
|
+
);
|
|
19822
|
+
const presentation = resolveJobPresentation({
|
|
19823
|
+
jobId,
|
|
19824
|
+
result: job2.result,
|
|
19825
|
+
stdout: [],
|
|
19826
|
+
sessionHeap
|
|
19827
|
+
});
|
|
19828
|
+
const entries = [];
|
|
19829
|
+
const responseText = presentation.responseText || "";
|
|
19830
|
+
if (responseText) {
|
|
19831
|
+
entries.push({
|
|
19832
|
+
id: `job:${jobId}:result-text`,
|
|
19833
|
+
role: "assistant",
|
|
19834
|
+
content: responseText,
|
|
19835
|
+
timestamp,
|
|
19836
|
+
jobId,
|
|
19837
|
+
historyContent: `[Assistant reply]
|
|
19838
|
+
${responseText}`,
|
|
19839
|
+
source: "job_result"
|
|
19840
|
+
});
|
|
19841
|
+
}
|
|
19842
|
+
const show = {
|
|
19843
|
+
entryPaths: presentation.entries.map((entry) => entry.path),
|
|
19844
|
+
listNames: presentation.lists.map((list) => list.name)
|
|
19845
|
+
};
|
|
19846
|
+
if (show.entryPaths && show.entryPaths.length > 0 || show.listNames && show.listNames.length > 0) {
|
|
19847
|
+
entries.push({
|
|
19848
|
+
id: `job:${jobId}:result-artifacts`,
|
|
19849
|
+
role: "assistant",
|
|
19850
|
+
content: "",
|
|
19851
|
+
timestamp,
|
|
19852
|
+
jobId,
|
|
19853
|
+
show,
|
|
19854
|
+
historyContent: buildArtifactHistory(show),
|
|
19855
|
+
source: "job_result"
|
|
19856
|
+
});
|
|
19857
|
+
}
|
|
19858
|
+
if (entries.length === 0 && trimString(job2.error)) {
|
|
19859
|
+
entries.push({
|
|
19860
|
+
id: `job:${jobId}:result-error`,
|
|
19861
|
+
role: "assistant",
|
|
19862
|
+
content: trimString(job2.error),
|
|
19863
|
+
timestamp,
|
|
19864
|
+
jobId,
|
|
19865
|
+
historyContent: `[Assistant reply]
|
|
19866
|
+
${trimString(job2.error)}`,
|
|
19867
|
+
source: "job_result"
|
|
19868
|
+
});
|
|
19869
|
+
}
|
|
19870
|
+
if (entries.length === 0 && resultPreview && resultPreview !== "No job result recorded.") {
|
|
19871
|
+
entries.push({
|
|
19872
|
+
id: `job:${jobId}:result-preview`,
|
|
19873
|
+
role: "assistant",
|
|
19874
|
+
content: resultPreview,
|
|
19875
|
+
timestamp,
|
|
19876
|
+
jobId,
|
|
19877
|
+
historyContent: `[Assistant reply]
|
|
19878
|
+
${resultPreview}`,
|
|
19879
|
+
source: "job_result"
|
|
19880
|
+
});
|
|
19881
|
+
}
|
|
19882
|
+
return entries;
|
|
19883
|
+
}
|
|
19884
|
+
function buildJobCodeEntry(jobId, job2) {
|
|
19885
|
+
const code = trimString(job2.source);
|
|
19886
|
+
if (!code) return null;
|
|
19887
|
+
const jobStatus = asString(job2.status);
|
|
19888
|
+
const error2 = jobStatus === "failed" || jobStatus === "canceled" || jobStatus === "timeout" ? trimString(job2.error) || `Job ${jobStatus}` : void 0;
|
|
19889
|
+
return {
|
|
19890
|
+
id: `job:${jobId}:code`,
|
|
19891
|
+
role: "assistant",
|
|
19892
|
+
content: "",
|
|
19893
|
+
timestamp: asNumber(job2.submittedAt) || asNumber(job2.startedAt) || asNumber(job2.finishedAt) || 0,
|
|
19894
|
+
jobId,
|
|
19895
|
+
code,
|
|
19896
|
+
jobStatus,
|
|
19897
|
+
jobResultPreview: stringifyTranscriptValue(job2.result, "No job result recorded."),
|
|
19898
|
+
error: error2,
|
|
19899
|
+
source: "job_code"
|
|
19900
|
+
};
|
|
19901
|
+
}
|
|
19902
|
+
function buildSessionTranscript(input) {
|
|
19903
|
+
const liveDoc = input.liveDoc || null;
|
|
19904
|
+
const sessionHeap = input.sessionHeap || EMPTY_HEAP;
|
|
19905
|
+
const transcript = [];
|
|
19906
|
+
const conversationMessages = asArray(asRecord3(liveDoc?.conversation)?.messages).map((message) => normalizeConversationMessage(message)).filter((message) => Boolean(message));
|
|
19907
|
+
const conversationPromptIds = new Set(
|
|
19908
|
+
conversationMessages.map((message) => message.promptId).filter((promptId) => Boolean(promptId))
|
|
19909
|
+
);
|
|
19910
|
+
const assistantConversationJobIds = new Set(
|
|
19911
|
+
conversationMessages.filter((message) => message.role === "assistant" && Boolean(message.jobId)).map((message) => message.jobId)
|
|
19912
|
+
);
|
|
19913
|
+
transcript.push(...conversationMessages);
|
|
19914
|
+
const jobsById = asRecord3(asRecord3(liveDoc?.jobs)?.byId) || {};
|
|
19915
|
+
const jobs = Object.values(jobsById).map((value) => asRecord3(value)).filter((value) => Boolean(value)).sort(
|
|
19916
|
+
(left, right) => (asNumber(left.submittedAt) || asNumber(left.startedAt) || asNumber(left.finishedAt) || 0) - (asNumber(right.submittedAt) || asNumber(right.startedAt) || asNumber(right.finishedAt) || 0)
|
|
19917
|
+
);
|
|
19918
|
+
for (const job2 of jobs) {
|
|
19919
|
+
const jobId = asString(job2.jobId);
|
|
19920
|
+
if (!jobId) continue;
|
|
19921
|
+
const codeEntry = buildJobCodeEntry(jobId, job2);
|
|
19922
|
+
if (codeEntry) {
|
|
19923
|
+
transcript.push(codeEntry);
|
|
19924
|
+
}
|
|
19925
|
+
transcript.push(
|
|
19926
|
+
...normalizePromptEntries(jobId, job2.prompts, conversationPromptIds)
|
|
19927
|
+
);
|
|
19928
|
+
if (!assistantConversationJobIds.has(jobId)) {
|
|
19929
|
+
const agentEntries = normalizeAgentMessageEntries(jobId, job2.agentMessages);
|
|
19930
|
+
if (agentEntries.length > 0) {
|
|
19931
|
+
transcript.push(...agentEntries);
|
|
19932
|
+
} else {
|
|
19933
|
+
transcript.push(
|
|
19934
|
+
...buildJobFallbackEntries(
|
|
19935
|
+
jobId,
|
|
19936
|
+
job2,
|
|
19937
|
+
sessionHeap
|
|
19938
|
+
)
|
|
19939
|
+
);
|
|
19940
|
+
}
|
|
19941
|
+
}
|
|
19942
|
+
}
|
|
19943
|
+
return transcript.sort((left, right) => {
|
|
19944
|
+
if (left.timestamp !== right.timestamp) {
|
|
19945
|
+
return left.timestamp - right.timestamp;
|
|
19946
|
+
}
|
|
19947
|
+
return left.id.localeCompare(right.id);
|
|
19948
|
+
});
|
|
19949
|
+
}
|
|
19950
|
+
|
|
19416
19951
|
// src/effect-runtime.ts
|
|
19417
19952
|
function computeEffectKey(effect) {
|
|
19418
19953
|
const attachedClass = effect.className?.trim();
|
|
@@ -20109,7 +20644,9 @@ var Environment = class {
|
|
|
20109
20644
|
{ target: targetPath }
|
|
20110
20645
|
);
|
|
20111
20646
|
if (result.errors?.length) {
|
|
20112
|
-
throw new Error(
|
|
20647
|
+
throw new Error(
|
|
20648
|
+
`attach failed: ${result.errors[0]?.message ?? "Unknown GraphQL error"}`
|
|
20649
|
+
);
|
|
20113
20650
|
}
|
|
20114
20651
|
}
|
|
20115
20652
|
/**
|
|
@@ -20144,7 +20681,9 @@ var Environment = class {
|
|
|
20144
20681
|
}`
|
|
20145
20682
|
);
|
|
20146
20683
|
if (result.errors?.length) {
|
|
20147
|
-
throw new Error(
|
|
20684
|
+
throw new Error(
|
|
20685
|
+
`detach failed: ${result.errors[0]?.message ?? "Unknown GraphQL error"}`
|
|
20686
|
+
);
|
|
20148
20687
|
}
|
|
20149
20688
|
}
|
|
20150
20689
|
/**
|
|
@@ -20266,7 +20805,9 @@ var Environment = class {
|
|
|
20266
20805
|
async _runGraphql(query, label) {
|
|
20267
20806
|
const result = await this.graphql(query);
|
|
20268
20807
|
if (result.errors?.length) {
|
|
20269
|
-
throw new Error(
|
|
20808
|
+
throw new Error(
|
|
20809
|
+
`${label}: ${result.errors[0]?.message ?? "Unknown GraphQL error"}`
|
|
20810
|
+
);
|
|
20270
20811
|
}
|
|
20271
20812
|
return result.data;
|
|
20272
20813
|
}
|
|
@@ -20801,6 +21342,9 @@ var EnvironmentSession = class extends Session {
|
|
|
20801
21342
|
get envName() {
|
|
20802
21343
|
return this.environment.envName;
|
|
20803
21344
|
}
|
|
21345
|
+
get tag() {
|
|
21346
|
+
return this.environment.tag;
|
|
21347
|
+
}
|
|
20804
21348
|
get versionId() {
|
|
20805
21349
|
return this.environment.versionId;
|
|
20806
21350
|
}
|
|
@@ -20820,12 +21364,171 @@ var EnvironmentSession = class extends Session {
|
|
|
20820
21364
|
return this.environment.feedback;
|
|
20821
21365
|
}
|
|
20822
21366
|
/**
|
|
20823
|
-
* Return a plain JS
|
|
21367
|
+
* Return a plain JS copy of the synced session heap.
|
|
20824
21368
|
*/
|
|
20825
21369
|
getHeap() {
|
|
20826
21370
|
const doc = this.document;
|
|
20827
21371
|
return normalizeHeapSnapshot(doc?.heap);
|
|
20828
21372
|
}
|
|
21373
|
+
async sessionDataRequest(path6, query) {
|
|
21374
|
+
const searchParams = new URLSearchParams();
|
|
21375
|
+
for (const [key, value] of Object.entries(query || {})) {
|
|
21376
|
+
if (value !== null && typeof value !== "undefined" && value !== "") {
|
|
21377
|
+
searchParams.set(key, String(value));
|
|
21378
|
+
}
|
|
21379
|
+
}
|
|
21380
|
+
const queryString = searchParams.toString();
|
|
21381
|
+
const response = await fetch(
|
|
21382
|
+
`${this.environment.runtimeBaseUrl}/orchestrator/ws/sessions/${encodeURIComponent(this.sessionId)}${path6}${queryString ? `?${queryString}` : ""}`,
|
|
21383
|
+
{
|
|
21384
|
+
method: "GET",
|
|
21385
|
+
headers: {
|
|
21386
|
+
Authorization: `Bearer ${this.environment.authToken}`,
|
|
21387
|
+
"Content-Type": "application/json"
|
|
21388
|
+
}
|
|
21389
|
+
}
|
|
21390
|
+
);
|
|
21391
|
+
if (!response.ok) {
|
|
21392
|
+
const errorText = await response.text();
|
|
21393
|
+
throw new Error(
|
|
21394
|
+
`Session data API Error (${response.status}): ${errorText}`
|
|
21395
|
+
);
|
|
21396
|
+
}
|
|
21397
|
+
return response.json();
|
|
21398
|
+
}
|
|
21399
|
+
async collectAllSessionItems(listPage) {
|
|
21400
|
+
const items = [];
|
|
21401
|
+
let cursor = null;
|
|
21402
|
+
do {
|
|
21403
|
+
const page = await listPage({ limit: 500, cursor });
|
|
21404
|
+
items.push(...page.items);
|
|
21405
|
+
cursor = page.nextCursor;
|
|
21406
|
+
} while (cursor);
|
|
21407
|
+
return items;
|
|
21408
|
+
}
|
|
21409
|
+
/**
|
|
21410
|
+
* Fetch the live session document from the runtime DO.
|
|
21411
|
+
*
|
|
21412
|
+
* For history and saved artifacts, prefer the collection APIs on
|
|
21413
|
+
* `messages`, `timeline`, `jobs`, and `heap`.
|
|
21414
|
+
*/
|
|
21415
|
+
async getDocument() {
|
|
21416
|
+
return this.sessionDataRequest("/document");
|
|
21417
|
+
}
|
|
21418
|
+
get messages() {
|
|
21419
|
+
return {
|
|
21420
|
+
list: (options = {}) => this.sessionDataRequest(
|
|
21421
|
+
"/messages",
|
|
21422
|
+
options
|
|
21423
|
+
)
|
|
21424
|
+
};
|
|
21425
|
+
}
|
|
21426
|
+
get timeline() {
|
|
21427
|
+
return {
|
|
21428
|
+
list: (options = {}) => this.sessionDataRequest(
|
|
21429
|
+
"/timeline",
|
|
21430
|
+
options
|
|
21431
|
+
)
|
|
21432
|
+
};
|
|
21433
|
+
}
|
|
21434
|
+
get jobs() {
|
|
21435
|
+
return {
|
|
21436
|
+
list: (options = {}) => this.sessionDataRequest(
|
|
21437
|
+
"/jobs",
|
|
21438
|
+
options
|
|
21439
|
+
),
|
|
21440
|
+
get: (jobId) => this.sessionDataRequest(
|
|
21441
|
+
`/jobs/${encodeURIComponent(jobId)}`
|
|
21442
|
+
)
|
|
21443
|
+
};
|
|
21444
|
+
}
|
|
21445
|
+
get heap() {
|
|
21446
|
+
return {
|
|
21447
|
+
entries: {
|
|
21448
|
+
list: (options = {}) => this.sessionDataRequest(
|
|
21449
|
+
"/heap/entries",
|
|
21450
|
+
options
|
|
21451
|
+
),
|
|
21452
|
+
get: (path6) => this.sessionDataRequest(
|
|
21453
|
+
`/heap/entries/${encodeURIComponent(path6)}`
|
|
21454
|
+
)
|
|
21455
|
+
},
|
|
21456
|
+
lists: {
|
|
21457
|
+
list: (options = {}) => this.sessionDataRequest(
|
|
21458
|
+
"/heap/lists",
|
|
21459
|
+
options
|
|
21460
|
+
),
|
|
21461
|
+
get: (name) => this.sessionDataRequest(
|
|
21462
|
+
`/heap/lists/${encodeURIComponent(name)}`
|
|
21463
|
+
)
|
|
21464
|
+
}
|
|
21465
|
+
};
|
|
21466
|
+
}
|
|
21467
|
+
get transcript() {
|
|
21468
|
+
return {
|
|
21469
|
+
list: async (options = {}) => {
|
|
21470
|
+
const [messages, jobs, entries, lists] = await Promise.all([
|
|
21471
|
+
this.collectAllSessionItems(this.messages.list),
|
|
21472
|
+
this.collectAllSessionItems(
|
|
21473
|
+
(pageOptions) => this.jobs.list({ ...pageOptions, status: "all" })
|
|
21474
|
+
),
|
|
21475
|
+
this.collectAllSessionItems(this.heap.entries.list),
|
|
21476
|
+
this.collectAllSessionItems(this.heap.lists.list)
|
|
21477
|
+
]);
|
|
21478
|
+
const liveDoc = {
|
|
21479
|
+
conversation: { messages },
|
|
21480
|
+
jobs: {
|
|
21481
|
+
byId: Object.fromEntries(
|
|
21482
|
+
jobs.map((job2) => {
|
|
21483
|
+
const record = job2 && typeof job2 === "object" ? job2 : null;
|
|
21484
|
+
const id = typeof record?.jobId === "string" ? record.jobId : typeof record?.id === "string" ? record.id : null;
|
|
21485
|
+
return id ? [id, record] : null;
|
|
21486
|
+
}).filter(
|
|
21487
|
+
(entry) => Boolean(entry)
|
|
21488
|
+
)
|
|
21489
|
+
)
|
|
21490
|
+
}
|
|
21491
|
+
};
|
|
21492
|
+
const heap = normalizeHeapSnapshot({
|
|
21493
|
+
entriesByPath: Object.fromEntries(
|
|
21494
|
+
entries.map((entry) => {
|
|
21495
|
+
return entry?.path ? [
|
|
21496
|
+
entry.path,
|
|
21497
|
+
entry
|
|
21498
|
+
] : null;
|
|
21499
|
+
}).filter(
|
|
21500
|
+
(entry) => Boolean(entry)
|
|
21501
|
+
)
|
|
21502
|
+
),
|
|
21503
|
+
listsByName: Object.fromEntries(
|
|
21504
|
+
lists.map((list) => {
|
|
21505
|
+
return list?.name ? [list.name, list] : null;
|
|
21506
|
+
}).filter(
|
|
21507
|
+
(entry) => Boolean(entry)
|
|
21508
|
+
)
|
|
21509
|
+
),
|
|
21510
|
+
variablesByName: this.getHeap().variablesByName,
|
|
21511
|
+
updatedAt: Date.now()
|
|
21512
|
+
});
|
|
21513
|
+
const allItems = buildSessionTranscript({
|
|
21514
|
+
liveDoc,
|
|
21515
|
+
sessionHeap: heap
|
|
21516
|
+
});
|
|
21517
|
+
const limit = Math.max(
|
|
21518
|
+
1,
|
|
21519
|
+
Math.min(500, Math.floor(options.limit ?? 100))
|
|
21520
|
+
);
|
|
21521
|
+
const offset = typeof options.cursor === "string" ? Number.parseInt(options.cursor, 10) || 0 : 0;
|
|
21522
|
+
const items = allItems.slice(offset, offset + limit);
|
|
21523
|
+
const nextOffset = offset + items.length;
|
|
21524
|
+
return {
|
|
21525
|
+
items,
|
|
21526
|
+
nextCursor: nextOffset < allItems.length ? String(nextOffset) : null,
|
|
21527
|
+
totalCount: allItems.length
|
|
21528
|
+
};
|
|
21529
|
+
}
|
|
21530
|
+
};
|
|
21531
|
+
}
|
|
20829
21532
|
async graphql(query, variables) {
|
|
20830
21533
|
return this.environment.graphql(query, variables);
|
|
20831
21534
|
}
|
|
@@ -22053,14 +22756,18 @@ async function resolveOntologyId(granular, ontology) {
|
|
|
22053
22756
|
const { config } = createGranularClient();
|
|
22054
22757
|
const requestedOntology = ontology ?? config.sandboxId;
|
|
22055
22758
|
if (!requestedOntology) {
|
|
22056
|
-
throw new Error(
|
|
22759
|
+
throw new Error(
|
|
22760
|
+
"No ontology configured. Run `granular init` first or pass `--ontology`."
|
|
22761
|
+
);
|
|
22057
22762
|
}
|
|
22058
22763
|
try {
|
|
22059
22764
|
const sandbox = await granular.sandboxes.get(requestedOntology);
|
|
22060
22765
|
return sandbox.sandboxId;
|
|
22061
22766
|
} catch {
|
|
22062
22767
|
const sandboxes = await granular.sandboxes.list();
|
|
22063
|
-
const existing = sandboxes.items.find(
|
|
22768
|
+
const existing = sandboxes.items.find(
|
|
22769
|
+
(item) => item.name === requestedOntology
|
|
22770
|
+
);
|
|
22064
22771
|
if (existing) {
|
|
22065
22772
|
return existing.sandboxId;
|
|
22066
22773
|
}
|
|
@@ -22068,7 +22775,8 @@ async function resolveOntologyId(granular, ontology) {
|
|
|
22068
22775
|
throw new Error(`Ontology not found: ${requestedOntology}`);
|
|
22069
22776
|
}
|
|
22070
22777
|
function matchesEnvironmentName(environment, requested) {
|
|
22071
|
-
|
|
22778
|
+
const managedPrefix = `__sdk__${requested}__`;
|
|
22779
|
+
return environment.environment === requested || environment.envName === requested || environment.environment?.startsWith(managedPrefix) || environment.envName?.startsWith(managedPrefix) || environment.tag?.name === requested || environment.buildPolicy?.tagName === requested || environment.tracking?.tagName === requested;
|
|
22072
22780
|
}
|
|
22073
22781
|
async function resolveEnvironmentData(granular, options) {
|
|
22074
22782
|
if (options.environmentId) {
|
|
@@ -22077,7 +22785,9 @@ async function resolveEnvironmentData(granular, options) {
|
|
|
22077
22785
|
const ontologyId = await resolveOntologyId(granular, options.ontology);
|
|
22078
22786
|
const environmentName = options.environment ?? "dev";
|
|
22079
22787
|
const environments = await granular.environments.list(ontologyId);
|
|
22080
|
-
const existing = environments.find(
|
|
22788
|
+
const existing = environments.find(
|
|
22789
|
+
(environment) => matchesEnvironmentName(environment, environmentName)
|
|
22790
|
+
);
|
|
22081
22791
|
if (existing) {
|
|
22082
22792
|
return existing;
|
|
22083
22793
|
}
|
|
@@ -22109,7 +22819,9 @@ async function listSessionsForEnvironment(granular, environmentId, status) {
|
|
|
22109
22819
|
async function connectRuntime(options) {
|
|
22110
22820
|
if (options.sessionId) {
|
|
22111
22821
|
const { granular: granular2 } = createGranularClient();
|
|
22112
|
-
const environment2 = await granular2.connectSession({
|
|
22822
|
+
const environment2 = await granular2.connectSession({
|
|
22823
|
+
sessionId: options.sessionId
|
|
22824
|
+
});
|
|
22113
22825
|
return {
|
|
22114
22826
|
granular: granular2,
|
|
22115
22827
|
environment: environment2,
|
|
@@ -22120,7 +22832,9 @@ async function connectRuntime(options) {
|
|
|
22120
22832
|
const { granular, config } = createGranularClient();
|
|
22121
22833
|
const ontologyId = options.ontology ?? config.sandboxId;
|
|
22122
22834
|
if (!ontologyId) {
|
|
22123
|
-
throw new Error(
|
|
22835
|
+
throw new Error(
|
|
22836
|
+
"No ontology configured. Run `granular init` first or pass `--ontology`."
|
|
22837
|
+
);
|
|
22124
22838
|
}
|
|
22125
22839
|
const environmentHandle = await granular.connect({
|
|
22126
22840
|
ontology: ontologyId,
|
|
@@ -22171,13 +22885,14 @@ function readJobCodeFromOptions(options) {
|
|
|
22171
22885
|
// src/cli/commands/connect.ts
|
|
22172
22886
|
async function connectTestCommand(options) {
|
|
22173
22887
|
const emitJson = options.json === true;
|
|
22888
|
+
const requestedEnvironment = options.environment ?? "dev";
|
|
22174
22889
|
if (!emitJson) {
|
|
22175
22890
|
printHeader();
|
|
22176
22891
|
}
|
|
22177
22892
|
await withRuntimeConnection(
|
|
22178
22893
|
{
|
|
22179
22894
|
ontology: options.ontology,
|
|
22180
|
-
environment:
|
|
22895
|
+
environment: requestedEnvironment,
|
|
22181
22896
|
userId: options.user,
|
|
22182
22897
|
permissions: normalizePermissions(options.permissions)
|
|
22183
22898
|
},
|
|
@@ -22187,7 +22902,7 @@ async function connectTestCommand(options) {
|
|
|
22187
22902
|
ontologyId,
|
|
22188
22903
|
sandboxId: environment.sandboxId,
|
|
22189
22904
|
environmentId: environment.environmentId,
|
|
22190
|
-
environment: environment.
|
|
22905
|
+
environment: environment.tag || requestedEnvironment,
|
|
22191
22906
|
sessionId: environment.sessionId,
|
|
22192
22907
|
subjectId: environment.subjectId,
|
|
22193
22908
|
versionId: environment.versionId
|
|
@@ -22200,7 +22915,7 @@ async function connectTestCommand(options) {
|
|
|
22200
22915
|
console.log();
|
|
22201
22916
|
keyValue({
|
|
22202
22917
|
"Ontology ID": payload.ontologyId,
|
|
22203
|
-
|
|
22918
|
+
Environment: payload.environment,
|
|
22204
22919
|
"Environment ID": payload.environmentId,
|
|
22205
22920
|
"Session ID": payload.sessionId,
|
|
22206
22921
|
"Subject ID": payload.subjectId,
|
|
@@ -22267,7 +22982,9 @@ async function sessionDocCommand(options) {
|
|
|
22267
22982
|
ontologyId,
|
|
22268
22983
|
sessionId: environment.sessionId,
|
|
22269
22984
|
environmentId: environment.environmentId,
|
|
22270
|
-
document: documentToJson(
|
|
22985
|
+
document: documentToJson(
|
|
22986
|
+
environment.document
|
|
22987
|
+
)
|
|
22271
22988
|
};
|
|
22272
22989
|
if (!emitJson) {
|
|
22273
22990
|
step("Session document");
|
|
@@ -22279,6 +22996,7 @@ async function sessionDocCommand(options) {
|
|
|
22279
22996
|
}
|
|
22280
22997
|
async function sessionCreateCommand(options) {
|
|
22281
22998
|
const emitJson = options.json === true;
|
|
22999
|
+
const requestedEnvironment = options.environment ?? "dev";
|
|
22282
23000
|
if (!emitJson) {
|
|
22283
23001
|
printHeader();
|
|
22284
23002
|
}
|
|
@@ -22286,7 +23004,7 @@ async function sessionCreateCommand(options) {
|
|
|
22286
23004
|
const permissions = normalizePermissions(options.permissions);
|
|
22287
23005
|
const envData = await resolveEnvironmentData(granular, {
|
|
22288
23006
|
ontology: options.ontology,
|
|
22289
|
-
environment:
|
|
23007
|
+
environment: requestedEnvironment,
|
|
22290
23008
|
environmentId: options.environmentId,
|
|
22291
23009
|
userId: options.user,
|
|
22292
23010
|
permissions,
|
|
@@ -22300,7 +23018,7 @@ async function sessionCreateCommand(options) {
|
|
|
22300
23018
|
ok: true,
|
|
22301
23019
|
ontologyId: envData.sandboxId,
|
|
22302
23020
|
environmentId: environment.environmentId,
|
|
22303
|
-
environment: environment.
|
|
23021
|
+
environment: environment.tag || envData.tag?.name || envData.buildPolicy.tagName || requestedEnvironment,
|
|
22304
23022
|
sessionId: environment.sessionId,
|
|
22305
23023
|
subjectId: environment.subjectId,
|
|
22306
23024
|
versionId: environment.versionId
|
|
@@ -22313,7 +23031,7 @@ async function sessionCreateCommand(options) {
|
|
|
22313
23031
|
console.log();
|
|
22314
23032
|
keyValue({
|
|
22315
23033
|
"Ontology ID": payload.ontologyId,
|
|
22316
|
-
|
|
23034
|
+
Environment: payload.environment,
|
|
22317
23035
|
"Environment ID": payload.environmentId,
|
|
22318
23036
|
"Session ID": payload.sessionId,
|
|
22319
23037
|
"Subject ID": payload.subjectId,
|
|
@@ -22331,21 +23049,26 @@ async function sessionCreateCommand(options) {
|
|
|
22331
23049
|
async function sessionListCommand(options) {
|
|
22332
23050
|
const emitJson = options.json === true;
|
|
22333
23051
|
const status = options.status ?? "active";
|
|
23052
|
+
const requestedEnvironment = options.environment ?? "dev";
|
|
22334
23053
|
if (!emitJson) {
|
|
22335
23054
|
printHeader();
|
|
22336
23055
|
}
|
|
22337
23056
|
const { granular } = createGranularClient();
|
|
22338
23057
|
const environmentData = await resolveEnvironmentData(granular, {
|
|
22339
23058
|
ontology: options.ontology,
|
|
22340
|
-
environment:
|
|
23059
|
+
environment: requestedEnvironment,
|
|
22341
23060
|
environmentId: options.environmentId,
|
|
22342
23061
|
createIfMissing: false
|
|
22343
23062
|
});
|
|
22344
|
-
const items = await listSessionsForEnvironment(
|
|
23063
|
+
const items = await listSessionsForEnvironment(
|
|
23064
|
+
granular,
|
|
23065
|
+
environmentData.environmentId,
|
|
23066
|
+
status
|
|
23067
|
+
);
|
|
22345
23068
|
const payload = {
|
|
22346
23069
|
ontologyId: environmentData.sandboxId,
|
|
22347
23070
|
environmentId: environmentData.environmentId,
|
|
22348
|
-
environment: environmentData.
|
|
23071
|
+
environment: environmentData.tag?.name || environmentData.buildPolicy.tagName || requestedEnvironment,
|
|
22349
23072
|
status,
|
|
22350
23073
|
items
|
|
22351
23074
|
};
|