@granular-software/sdk 0.4.24 → 0.4.26
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 +1 -1
- package/dist/agent-evals.d.ts +1 -1
- package/dist/agent-evals.js +161 -38
- package/dist/agent-evals.js.map +1 -1
- package/dist/agent-evals.mjs +161 -38
- package/dist/agent-evals.mjs.map +1 -1
- package/dist/agent-harness.d.mts +1 -1
- package/dist/agent-harness.d.ts +1 -1
- package/dist/agent-harness.js +22 -11
- package/dist/agent-harness.js.map +1 -1
- package/dist/agent-harness.mjs +22 -11
- package/dist/agent-harness.mjs.map +1 -1
- package/dist/cli/index.js +97 -8
- package/dist/{client-CQFKsCTd.d.mts → client-Zoo8YITZ.d.mts} +39 -1
- package/dist/{client-CQFKsCTd.d.ts → client-Zoo8YITZ.d.ts} +39 -1
- package/dist/index.d.mts +11 -4
- package/dist/index.d.ts +11 -4
- package/dist/index.js +462 -38
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +462 -39
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -4545,6 +4545,7 @@ var Session = class {
|
|
|
4545
4545
|
client;
|
|
4546
4546
|
clientId;
|
|
4547
4547
|
jobsMap = /* @__PURE__ */ new Map();
|
|
4548
|
+
pendingAgentMessagesByJobId = /* @__PURE__ */ new Map();
|
|
4548
4549
|
eventListeners = /* @__PURE__ */ new Map();
|
|
4549
4550
|
toolHandlers = /* @__PURE__ */ new Map();
|
|
4550
4551
|
/** Tracks which tools are instance methods (className set, not static) */
|
|
@@ -4587,6 +4588,22 @@ var Session = class {
|
|
|
4587
4588
|
}
|
|
4588
4589
|
};
|
|
4589
4590
|
}
|
|
4591
|
+
stringifyConversationValue(value) {
|
|
4592
|
+
if (typeof value === "string") {
|
|
4593
|
+
return value;
|
|
4594
|
+
}
|
|
4595
|
+
if (typeof value === "boolean") {
|
|
4596
|
+
return value ? "Confirmed" : "Canceled";
|
|
4597
|
+
}
|
|
4598
|
+
if (value === void 0) {
|
|
4599
|
+
return "";
|
|
4600
|
+
}
|
|
4601
|
+
try {
|
|
4602
|
+
return JSON.stringify(value, null, 2);
|
|
4603
|
+
} catch {
|
|
4604
|
+
return String(value);
|
|
4605
|
+
}
|
|
4606
|
+
}
|
|
4590
4607
|
// --- Public API ---
|
|
4591
4608
|
get document() {
|
|
4592
4609
|
return this.client.doc;
|
|
@@ -4702,6 +4719,15 @@ var Session = class {
|
|
|
4702
4719
|
createdAt: Date.now()
|
|
4703
4720
|
});
|
|
4704
4721
|
this.jobsMap.set(result.jobId, job);
|
|
4722
|
+
const pendingAgentMessages = this.pendingAgentMessagesByJobId.get(
|
|
4723
|
+
result.jobId
|
|
4724
|
+
);
|
|
4725
|
+
if (pendingAgentMessages && pendingAgentMessages.length > 0) {
|
|
4726
|
+
this.pendingAgentMessagesByJobId.delete(result.jobId);
|
|
4727
|
+
for (const message of pendingAgentMessages) {
|
|
4728
|
+
job.replayAgentMessage(message);
|
|
4729
|
+
}
|
|
4730
|
+
}
|
|
4705
4731
|
return job;
|
|
4706
4732
|
}
|
|
4707
4733
|
/**
|
|
@@ -4728,6 +4754,20 @@ var Session = class {
|
|
|
4728
4754
|
answer: resolvedAnswer,
|
|
4729
4755
|
value: resolvedAnswer
|
|
4730
4756
|
});
|
|
4757
|
+
try {
|
|
4758
|
+
const content = this.stringifyConversationValue(resolvedAnswer);
|
|
4759
|
+
if (content.trim()) {
|
|
4760
|
+
await this.appendConversationMessage({
|
|
4761
|
+
role: "user",
|
|
4762
|
+
content,
|
|
4763
|
+
promptId
|
|
4764
|
+
});
|
|
4765
|
+
}
|
|
4766
|
+
} catch {
|
|
4767
|
+
}
|
|
4768
|
+
}
|
|
4769
|
+
async appendConversationMessage(input) {
|
|
4770
|
+
return this.client.call("conversation.append", input);
|
|
4731
4771
|
}
|
|
4732
4772
|
/**
|
|
4733
4773
|
* Get the current list of available effects.
|
|
@@ -5103,6 +5143,22 @@ import { ${allImports} } from "./sandbox-tools";
|
|
|
5103
5143
|
this.client.on("job.status", (data) => {
|
|
5104
5144
|
this.emit("job:status", data);
|
|
5105
5145
|
});
|
|
5146
|
+
this.client.on("job.agent_message", (data) => {
|
|
5147
|
+
const normalized = normalizeJobAgentMessageEnvelope(data);
|
|
5148
|
+
if (!normalized) return;
|
|
5149
|
+
if (this.jobsMap.has(normalized.jobId)) return;
|
|
5150
|
+
const pending = this.pendingAgentMessagesByJobId.get(normalized.jobId) || [];
|
|
5151
|
+
if (normalized.message.messageId && pending.some(
|
|
5152
|
+
(message) => message.messageId === normalized.message.messageId
|
|
5153
|
+
)) {
|
|
5154
|
+
return;
|
|
5155
|
+
}
|
|
5156
|
+
pending.push(normalized.message);
|
|
5157
|
+
this.pendingAgentMessagesByJobId.set(
|
|
5158
|
+
normalized.jobId,
|
|
5159
|
+
pending.slice(-25)
|
|
5160
|
+
);
|
|
5161
|
+
});
|
|
5106
5162
|
this.client.on("exec.completed", (data) => {
|
|
5107
5163
|
this.emit("exec:completed", data);
|
|
5108
5164
|
});
|
|
@@ -5227,6 +5283,22 @@ function sanitizeFeedbackValue(value, depth = 0, seen = /* @__PURE__ */ new Weak
|
|
|
5227
5283
|
}
|
|
5228
5284
|
return truncateFeedbackString(String(value));
|
|
5229
5285
|
}
|
|
5286
|
+
function normalizeJobAgentMessageEnvelope(data) {
|
|
5287
|
+
const d = data;
|
|
5288
|
+
if (typeof d?.jobId !== "string" || !d.jobId) {
|
|
5289
|
+
return null;
|
|
5290
|
+
}
|
|
5291
|
+
return {
|
|
5292
|
+
jobId: d.jobId,
|
|
5293
|
+
message: {
|
|
5294
|
+
messageId: d.messageId,
|
|
5295
|
+
kind: d.kind === "artifacts" ? "artifacts" : "text",
|
|
5296
|
+
reply: typeof d.reply === "string" ? d.reply : "",
|
|
5297
|
+
show: d.show,
|
|
5298
|
+
timestamp: d.timestamp || Date.now()
|
|
5299
|
+
}
|
|
5300
|
+
};
|
|
5301
|
+
}
|
|
5230
5302
|
var JobImplementation = class {
|
|
5231
5303
|
id;
|
|
5232
5304
|
client;
|
|
@@ -5235,6 +5307,8 @@ var JobImplementation = class {
|
|
|
5235
5307
|
_resolveResult;
|
|
5236
5308
|
_rejectResult;
|
|
5237
5309
|
eventListeners = /* @__PURE__ */ new Map();
|
|
5310
|
+
bufferedAgentMessages = [];
|
|
5311
|
+
bufferedAgentMessageIds = /* @__PURE__ */ new Set();
|
|
5238
5312
|
metadata;
|
|
5239
5313
|
constructor(id, client, initialState) {
|
|
5240
5314
|
this.id = id;
|
|
@@ -5393,14 +5467,9 @@ var JobImplementation = class {
|
|
|
5393
5467
|
}
|
|
5394
5468
|
});
|
|
5395
5469
|
this.client.on("job.agent_message", (data) => {
|
|
5396
|
-
const
|
|
5397
|
-
if (
|
|
5398
|
-
this.
|
|
5399
|
-
messageId: d.messageId,
|
|
5400
|
-
reply: typeof d.reply === "string" ? d.reply : "",
|
|
5401
|
-
show: d.show,
|
|
5402
|
-
timestamp: d.timestamp || Date.now()
|
|
5403
|
-
});
|
|
5470
|
+
const normalized = normalizeJobAgentMessageEnvelope(data);
|
|
5471
|
+
if (normalized?.jobId === id) {
|
|
5472
|
+
this.captureAgentMessage(normalized.message);
|
|
5404
5473
|
}
|
|
5405
5474
|
});
|
|
5406
5475
|
}
|
|
@@ -5427,6 +5496,14 @@ var JobImplementation = class {
|
|
|
5427
5496
|
this.eventListeners.set(event, []);
|
|
5428
5497
|
}
|
|
5429
5498
|
this.eventListeners.get(event).push(handler);
|
|
5499
|
+
if (event === "agentMessage" && this.bufferedAgentMessages.length > 0) {
|
|
5500
|
+
for (const message of this.bufferedAgentMessages) {
|
|
5501
|
+
handler(message);
|
|
5502
|
+
}
|
|
5503
|
+
}
|
|
5504
|
+
}
|
|
5505
|
+
replayAgentMessage(message) {
|
|
5506
|
+
this.captureAgentMessage(message);
|
|
5430
5507
|
}
|
|
5431
5508
|
buildFeedbackMetadata() {
|
|
5432
5509
|
const startedAt = this.metadata.startedAt;
|
|
@@ -5496,6 +5573,18 @@ var JobImplementation = class {
|
|
|
5496
5573
|
handlers.forEach((h) => h(data));
|
|
5497
5574
|
}
|
|
5498
5575
|
}
|
|
5576
|
+
captureAgentMessage(message) {
|
|
5577
|
+
if (message.messageId && this.bufferedAgentMessageIds.has(message.messageId)) {
|
|
5578
|
+
return;
|
|
5579
|
+
}
|
|
5580
|
+
if (message.messageId) {
|
|
5581
|
+
this.bufferedAgentMessageIds.add(message.messageId);
|
|
5582
|
+
}
|
|
5583
|
+
this.bufferedAgentMessages = [...this.bufferedAgentMessages, message].slice(
|
|
5584
|
+
-25
|
|
5585
|
+
);
|
|
5586
|
+
this.emit("agentMessage", message);
|
|
5587
|
+
}
|
|
5499
5588
|
};
|
|
5500
5589
|
|
|
5501
5590
|
// src/endpoints.ts
|
|
@@ -13550,14 +13639,22 @@ function reviewGeneratedJobCode(code) {
|
|
|
13550
13639
|
}
|
|
13551
13640
|
}
|
|
13552
13641
|
}
|
|
13553
|
-
const hasConversationalReturn = /return\s+[`'"]/.test(normalized) || /\breply\s*:/.test(normalized) || /\bagent_message\s*\(/.test(normalized);
|
|
13642
|
+
const hasConversationalReturn = /return\s+[`'"]/.test(normalized) || /\breply\s*:/.test(normalized) || /\bagent_message\s*\(/.test(normalized) || /\bagent_text_message\s*\(/.test(normalized);
|
|
13554
13643
|
const returnsObjectLiteral = /return\s+\{[\s\S]*?\}/.test(normalized);
|
|
13644
|
+
const returnsShowPayload = /return\s+\{[\s\S]*?\bshow\s*:/.test(normalized);
|
|
13555
13645
|
const closesLoop = /loop\.close_loop\s*\(/.test(normalized);
|
|
13556
13646
|
if (!hasConversationalReturn && returnsObjectLiteral && !closesLoop) {
|
|
13557
13647
|
issues.push({
|
|
13558
13648
|
code: "missing_user_reply",
|
|
13559
13649
|
severity: "error",
|
|
13560
|
-
message: "User-facing jobs must end with a natural-language answer. Return a short string, an object with a top-level `reply` string, or
|
|
13650
|
+
message: "User-facing jobs must end with a natural-language answer. Return a short string, an object with a top-level `reply` string, or post text with agent_text_message(...). Do not end with bare structured JSON."
|
|
13651
|
+
});
|
|
13652
|
+
}
|
|
13653
|
+
if (returnsShowPayload) {
|
|
13654
|
+
issues.push({
|
|
13655
|
+
code: "return_show_not_for_ui",
|
|
13656
|
+
severity: "error",
|
|
13657
|
+
message: "Do not use the final return value to send UI record refs through `show`. Use agent_heap_objects(...) for heap-backed UI, then return plain text if you still want a final textual answer."
|
|
13561
13658
|
});
|
|
13562
13659
|
}
|
|
13563
13660
|
return issues;
|
|
@@ -14407,7 +14504,7 @@ ${loopBlock}
|
|
|
14407
14504
|
|
|
14408
14505
|
\u2500\u2500\u2500 CODE RULES \u2500\u2500\u2500
|
|
14409
14506
|
- Import from \`./sandbox-tools\`.
|
|
14410
|
-
- If you use \`heap\`, \`loop\`, or \`agent_message\`, import them explicitly from \`./sandbox-tools\`.
|
|
14507
|
+
- If you use \`heap\`, \`loop\`, \`agent_text_message\`, \`agent_heap_objects\`, or legacy \`agent_message\`, import them explicitly from \`./sandbox-tools\`.
|
|
14411
14508
|
- Write top-level executable code with \`await\` at top level.
|
|
14412
14509
|
- The generated job body must be plain runnable JavaScript. The DOMAIN TYPES block is only a reference for shapes and available methods.
|
|
14413
14510
|
- Do not write TypeScript-only syntax in executable code: no type annotations, no interfaces, no enums, no \`as Type\` casts, no \`satisfies\`, and no generic type parameters in code.
|
|
@@ -14449,21 +14546,31 @@ ${loopBlock}
|
|
|
14449
14546
|
- \`loop.close_loop(...)\`: record the current workflow outcome with a short summary before stopping. Do not call it in the same job that opens a new user prompt unless the workflow is explicitly blocked. This does not end the session forever.
|
|
14450
14547
|
- Avoid \`as any\` and other broad casts when the DOMAIN TYPES block already tells you the correct class or list type.
|
|
14451
14548
|
- Prefer manipulating heap-backed instances and typed lists instead of returning raw JSON blobs or object IDs unless the user explicitly asks for them.
|
|
14452
|
-
-
|
|
14453
|
-
-
|
|
14454
|
-
-
|
|
14455
|
-
- \`
|
|
14456
|
-
- \`
|
|
14457
|
-
-
|
|
14458
|
-
|
|
14459
|
-
-
|
|
14549
|
+
- Every job that intends to answer the user must emit at least one explicit UI message with \`agent_text_message(...)\` and/or \`agent_heap_objects(...)\`.
|
|
14550
|
+
- Use \`agent_text_message("...")\` for all user-visible text shown in the UI.
|
|
14551
|
+
- Use \`agent_heap_objects(...)\` only when you want the UI to render heap-backed records or lists.
|
|
14552
|
+
- If you want to show both text and records, call \`agent_text_message(...)\` and \`agent_heap_objects(...)\` separately in whatever order fits the interaction.
|
|
14553
|
+
- \`agent_text_message(...)\` should be used with a plain text string in normal generated code.
|
|
14554
|
+
- \`agent_heap_objects(...)\` should point at heap-backed values: explicit \`entryPaths\` / \`listNames\` / \`variableNames\`, a named list saved with \`saveAs\`, or values read back from \`heap.getVar(...)\`.
|
|
14555
|
+
- If you just fetched records and want to show them in the UI, save or reference them through the heap first, then call \`agent_heap_objects(...)\`. Do not try to hand-build UI payloads in job code.
|
|
14556
|
+
- Do not assume heap changes will be displayed automatically. If records should appear in the UI, you must call \`agent_heap_objects(...)\`.
|
|
14557
|
+
- Never write \`return { reply, show }\` or \`return { show: ... }\` for UI. If you want the UI to render records or lists, call \`agent_heap_objects(...)\` instead.
|
|
14558
|
+
- Do not rely on the final return value for user-visible output. A plain return value is not considered a displayed UI answer.
|
|
14559
|
+
- \`agent_message(...)\` remains available as a legacy compatibility alias, but prefer \`agent_text_message(...)\` and \`agent_heap_objects(...)\` in new code.
|
|
14460
14560
|
- Do not return bare structured JSON, low-level diagnostics, or database-shaped payloads as the final answer unless the user explicitly asks for them.
|
|
14461
14561
|
- Prefer simple executable JavaScript over clever interpolation. Avoid nested template literals or unusually dense inline expressions when a small temporary variable or string concatenation would be clearer and safer.
|
|
14462
14562
|
- Use \`console.log()\` only for intermediate diagnostics, not for the final user-facing answer.`;
|
|
14463
14563
|
}
|
|
14464
14564
|
|
|
14465
14565
|
// src/job-presentation.ts
|
|
14466
|
-
var RESPONSE_KEYS = [
|
|
14566
|
+
var RESPONSE_KEYS = [
|
|
14567
|
+
"reply",
|
|
14568
|
+
"response",
|
|
14569
|
+
"text",
|
|
14570
|
+
"message",
|
|
14571
|
+
"summary",
|
|
14572
|
+
"answer"
|
|
14573
|
+
];
|
|
14467
14574
|
var ENTRY_KEY_CANDIDATES = ["entryPath", "path"];
|
|
14468
14575
|
var ENTRY_ARRAY_KEY_CANDIDATES = ["entryPaths", "paths"];
|
|
14469
14576
|
var LIST_KEY_CANDIDATES = ["listName"];
|
|
@@ -14505,15 +14612,22 @@ function pushStringArray(target, value) {
|
|
|
14505
14612
|
}
|
|
14506
14613
|
}
|
|
14507
14614
|
function collectReferencesFromRecord(record, refs) {
|
|
14508
|
-
for (const key of ENTRY_KEY_CANDIDATES)
|
|
14509
|
-
|
|
14510
|
-
for (const key of
|
|
14511
|
-
|
|
14512
|
-
for (const key of
|
|
14513
|
-
|
|
14615
|
+
for (const key of ENTRY_KEY_CANDIDATES)
|
|
14616
|
+
pushString(refs.entryPaths, record[key]);
|
|
14617
|
+
for (const key of ENTRY_ARRAY_KEY_CANDIDATES)
|
|
14618
|
+
pushStringArray(refs.entryPaths, record[key]);
|
|
14619
|
+
for (const key of LIST_KEY_CANDIDATES)
|
|
14620
|
+
pushString(refs.listNames, record[key]);
|
|
14621
|
+
for (const key of LIST_ARRAY_KEY_CANDIDATES)
|
|
14622
|
+
pushStringArray(refs.listNames, record[key]);
|
|
14623
|
+
for (const key of VARIABLE_KEY_CANDIDATES)
|
|
14624
|
+
pushString(refs.variableNames, record[key]);
|
|
14625
|
+
for (const key of VARIABLE_ARRAY_KEY_CANDIDATES)
|
|
14626
|
+
pushStringArray(refs.variableNames, record[key]);
|
|
14514
14627
|
}
|
|
14515
14628
|
function scanForHeapReferences(value, heap, refs, depth = 0, seen = /* @__PURE__ */ new Set()) {
|
|
14516
|
-
if (value === null || value === void 0 || depth > 4 || seen.has(value))
|
|
14629
|
+
if (value === null || value === void 0 || depth > 4 || seen.has(value))
|
|
14630
|
+
return;
|
|
14517
14631
|
if (typeof value === "string") {
|
|
14518
14632
|
const trimmed = value.trim();
|
|
14519
14633
|
if (heap.entriesByPath?.[trimmed]) refs.entryPaths.add(trimmed);
|
|
@@ -14609,12 +14723,16 @@ function fallbackResponseText(entries, lists) {
|
|
|
14609
14723
|
}
|
|
14610
14724
|
function getJobRelatedEntries(heap, jobId) {
|
|
14611
14725
|
return sortEntries(
|
|
14612
|
-
Object.values(heap.entriesByPath || {}).filter(
|
|
14726
|
+
Object.values(heap.entriesByPath || {}).filter(
|
|
14727
|
+
(entry) => entry.relatedJobIds?.includes(jobId)
|
|
14728
|
+
)
|
|
14613
14729
|
);
|
|
14614
14730
|
}
|
|
14615
14731
|
function getJobRelatedLists(heap, jobId) {
|
|
14616
14732
|
return sortLists(
|
|
14617
|
-
Object.values(heap.listsByName || {}).filter(
|
|
14733
|
+
Object.values(heap.listsByName || {}).filter(
|
|
14734
|
+
(list) => list.relatedJobIds?.includes(jobId)
|
|
14735
|
+
)
|
|
14618
14736
|
);
|
|
14619
14737
|
}
|
|
14620
14738
|
function entriesFromLists(lists, heap) {
|
|
@@ -14631,15 +14749,18 @@ function resolveJobPresentation({
|
|
|
14631
14749
|
jobId,
|
|
14632
14750
|
result,
|
|
14633
14751
|
stdout = [],
|
|
14634
|
-
sessionHeap
|
|
14752
|
+
sessionHeap,
|
|
14753
|
+
allowExplicitArtifacts = true
|
|
14635
14754
|
}) {
|
|
14636
14755
|
const refs = {
|
|
14637
14756
|
entryPaths: /* @__PURE__ */ new Set(),
|
|
14638
14757
|
listNames: /* @__PURE__ */ new Set(),
|
|
14639
14758
|
variableNames: /* @__PURE__ */ new Set()
|
|
14640
14759
|
};
|
|
14641
|
-
|
|
14642
|
-
|
|
14760
|
+
if (allowExplicitArtifacts) {
|
|
14761
|
+
scanForHeapReferences(result, sessionHeap, refs);
|
|
14762
|
+
resolveVariablesToReferences(refs.variableNames, sessionHeap, refs);
|
|
14763
|
+
}
|
|
14643
14764
|
const referencedLists = sortLists(
|
|
14644
14765
|
[...refs.listNames].map((name) => sessionHeap.listsByName?.[name]).filter((list) => Boolean(list))
|
|
14645
14766
|
);
|
|
@@ -14652,23 +14773,325 @@ function resolveJobPresentation({
|
|
|
14652
14773
|
...jobEntries,
|
|
14653
14774
|
...entriesFromLists(jobLists, sessionHeap)
|
|
14654
14775
|
]);
|
|
14655
|
-
const
|
|
14656
|
-
const
|
|
14776
|
+
const explicitLists = dedupeLists(referencedLists);
|
|
14777
|
+
const explicitEntries = dedupeEntries([
|
|
14657
14778
|
...referencedEntries,
|
|
14658
|
-
...entriesFromLists(referencedLists, sessionHeap)
|
|
14659
|
-
...jobEntries,
|
|
14660
|
-
...entriesFromLists(jobLists, sessionHeap)
|
|
14779
|
+
...entriesFromLists(referencedLists, sessionHeap)
|
|
14661
14780
|
]);
|
|
14781
|
+
const hasExplicitArtifacts = allowExplicitArtifacts && (explicitEntries.length > 0 || explicitLists.length > 0);
|
|
14782
|
+
const lists = hasExplicitArtifacts ? explicitLists : jobLists;
|
|
14783
|
+
const entries = hasExplicitArtifacts ? explicitEntries : changedEntries;
|
|
14662
14784
|
const responseText = extractResponseText(result, stdout) || fallbackResponseText(entries, lists);
|
|
14663
14785
|
return {
|
|
14664
14786
|
responseText,
|
|
14665
14787
|
entries,
|
|
14666
14788
|
lists,
|
|
14667
14789
|
changedEntries,
|
|
14668
|
-
changedLists: jobLists
|
|
14790
|
+
changedLists: jobLists,
|
|
14791
|
+
hasExplicitArtifacts
|
|
14792
|
+
};
|
|
14793
|
+
}
|
|
14794
|
+
|
|
14795
|
+
// src/session-transcript.ts
|
|
14796
|
+
var EMPTY_HEAP = {
|
|
14797
|
+
entriesByPath: {},
|
|
14798
|
+
listsByName: {},
|
|
14799
|
+
variablesByName: {}};
|
|
14800
|
+
function asRecord4(value) {
|
|
14801
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
14802
|
+
return value;
|
|
14803
|
+
}
|
|
14804
|
+
function asArray2(value) {
|
|
14805
|
+
return Array.isArray(value) ? value : [];
|
|
14806
|
+
}
|
|
14807
|
+
function asNumber(value) {
|
|
14808
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
14809
|
+
}
|
|
14810
|
+
function asString(value) {
|
|
14811
|
+
return typeof value === "string" ? value : void 0;
|
|
14812
|
+
}
|
|
14813
|
+
function trimString(value) {
|
|
14814
|
+
return typeof value === "string" ? value.trim() : "";
|
|
14815
|
+
}
|
|
14816
|
+
function normalizeShowRefs(value) {
|
|
14817
|
+
const record = asRecord4(value);
|
|
14818
|
+
if (!record) return void 0;
|
|
14819
|
+
const normalizeRefs = (input) => {
|
|
14820
|
+
if (!Array.isArray(input)) return void 0;
|
|
14821
|
+
const refs = Array.from(
|
|
14822
|
+
new Set(
|
|
14823
|
+
input.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean)
|
|
14824
|
+
)
|
|
14825
|
+
);
|
|
14826
|
+
return refs.length > 0 ? refs : void 0;
|
|
14827
|
+
};
|
|
14828
|
+
const show = {
|
|
14829
|
+
entryPaths: normalizeRefs(record.entryPaths),
|
|
14830
|
+
listNames: normalizeRefs(record.listNames),
|
|
14831
|
+
variableNames: normalizeRefs(record.variableNames)
|
|
14832
|
+
};
|
|
14833
|
+
return show.entryPaths || show.listNames || show.variableNames ? show : void 0;
|
|
14834
|
+
}
|
|
14835
|
+
function stringifyTranscriptValue(value, fallback = "") {
|
|
14836
|
+
if (typeof value === "string") {
|
|
14837
|
+
return value.trim() || fallback;
|
|
14838
|
+
}
|
|
14839
|
+
if (typeof value === "boolean") {
|
|
14840
|
+
return value ? "Confirmed" : "Canceled";
|
|
14841
|
+
}
|
|
14842
|
+
if (value === void 0) {
|
|
14843
|
+
return fallback;
|
|
14844
|
+
}
|
|
14845
|
+
try {
|
|
14846
|
+
const json = JSON.stringify(value, null, 2);
|
|
14847
|
+
if (!json || json === "undefined") return fallback;
|
|
14848
|
+
return json.length > 2e3 ? `${json.slice(0, 2e3)}...` : json;
|
|
14849
|
+
} catch {
|
|
14850
|
+
return String(value);
|
|
14851
|
+
}
|
|
14852
|
+
}
|
|
14853
|
+
function buildArtifactHistory(show) {
|
|
14854
|
+
if (!show) return void 0;
|
|
14855
|
+
return `[Agent message]
|
|
14856
|
+
${stringifyTranscriptValue({ show }, "")}`;
|
|
14857
|
+
}
|
|
14858
|
+
function normalizeConversationMessage(raw) {
|
|
14859
|
+
const record = asRecord4(raw);
|
|
14860
|
+
if (!record) return null;
|
|
14861
|
+
const role = record.role === "user" ? "user" : record.role === "assistant" ? "assistant" : null;
|
|
14862
|
+
if (!role) return null;
|
|
14863
|
+
const content = trimString(
|
|
14864
|
+
record.content ?? record.reply ?? record.message ?? record.text
|
|
14865
|
+
);
|
|
14866
|
+
const show = normalizeShowRefs(record.show);
|
|
14867
|
+
const id = asString(record.id) || crypto.randomUUID();
|
|
14868
|
+
const timestamp = asNumber(record.timestamp) || asNumber(record.ts) || 0;
|
|
14869
|
+
if (!content && !show) return null;
|
|
14870
|
+
return {
|
|
14871
|
+
id,
|
|
14872
|
+
role,
|
|
14873
|
+
content,
|
|
14874
|
+
timestamp,
|
|
14875
|
+
jobId: asString(record.jobId),
|
|
14876
|
+
promptId: asString(record.promptId),
|
|
14877
|
+
show,
|
|
14878
|
+
historyContent: role === "assistant" ? content ? `[Assistant reply]
|
|
14879
|
+
${content}` : buildArtifactHistory(show) : void 0,
|
|
14880
|
+
source: "conversation"
|
|
14669
14881
|
};
|
|
14670
14882
|
}
|
|
14883
|
+
function normalizePromptEntries(jobId, rawPrompts, conversationPromptIds) {
|
|
14884
|
+
const promptsById = asRecord4(rawPrompts) || {};
|
|
14885
|
+
return Object.values(promptsById).map((value) => asRecord4(value)).filter((value) => Boolean(value)).sort(
|
|
14886
|
+
(left, right) => (asNumber(left.openedAt) || asNumber(left.answeredAt) || 0) - (asNumber(right.openedAt) || asNumber(right.answeredAt) || 0)
|
|
14887
|
+
).flatMap((prompt) => {
|
|
14888
|
+
const promptId = asString(prompt.promptId);
|
|
14889
|
+
if (!promptId || conversationPromptIds.has(promptId)) return [];
|
|
14890
|
+
const title = trimString(prompt.title);
|
|
14891
|
+
const message = trimString(prompt.message);
|
|
14892
|
+
const assistantContent = message || title || "Input required";
|
|
14893
|
+
const openedAt = asNumber(prompt.openedAt) || 0;
|
|
14894
|
+
const answeredAt = asNumber(prompt.answeredAt) || openedAt;
|
|
14895
|
+
const entries = [
|
|
14896
|
+
{
|
|
14897
|
+
id: `prompt:${promptId}:assistant`,
|
|
14898
|
+
role: "assistant",
|
|
14899
|
+
content: assistantContent,
|
|
14900
|
+
timestamp: openedAt,
|
|
14901
|
+
jobId,
|
|
14902
|
+
promptId,
|
|
14903
|
+
historyContent: `[Assistant reply]
|
|
14904
|
+
${assistantContent}`,
|
|
14905
|
+
source: "job_prompt"
|
|
14906
|
+
}
|
|
14907
|
+
];
|
|
14908
|
+
if (Object.prototype.hasOwnProperty.call(prompt, "answer")) {
|
|
14909
|
+
entries.push({
|
|
14910
|
+
id: `prompt:${promptId}:user`,
|
|
14911
|
+
role: "user",
|
|
14912
|
+
content: stringifyTranscriptValue(prompt.answer, ""),
|
|
14913
|
+
timestamp: answeredAt,
|
|
14914
|
+
jobId,
|
|
14915
|
+
promptId,
|
|
14916
|
+
source: "job_prompt"
|
|
14917
|
+
});
|
|
14918
|
+
}
|
|
14919
|
+
return entries;
|
|
14920
|
+
});
|
|
14921
|
+
}
|
|
14922
|
+
function normalizeAgentMessageEntries(jobId, rawMessages) {
|
|
14923
|
+
return asArray2(rawMessages).map((value) => asRecord4(value)).filter((value) => Boolean(value)).sort(
|
|
14924
|
+
(left, right) => (asNumber(left.timestamp) || asNumber(left.ts) || 0) - (asNumber(right.timestamp) || asNumber(right.ts) || 0)
|
|
14925
|
+
).flatMap((message) => {
|
|
14926
|
+
const messageId = asString(message.messageId) || asString(message.id) || crypto.randomUUID();
|
|
14927
|
+
const timestamp = asNumber(message.timestamp) || asNumber(message.ts) || 0;
|
|
14928
|
+
const reply = trimString(
|
|
14929
|
+
message.reply ?? message.message ?? message.text ?? message.content
|
|
14930
|
+
);
|
|
14931
|
+
const show = normalizeShowRefs(message.show);
|
|
14932
|
+
const entries = [];
|
|
14933
|
+
if (reply) {
|
|
14934
|
+
entries.push({
|
|
14935
|
+
id: `agent:${messageId}:text`,
|
|
14936
|
+
role: "assistant",
|
|
14937
|
+
content: reply,
|
|
14938
|
+
timestamp,
|
|
14939
|
+
jobId,
|
|
14940
|
+
historyContent: `[Assistant reply]
|
|
14941
|
+
${reply}`,
|
|
14942
|
+
source: "job_agent_message"
|
|
14943
|
+
});
|
|
14944
|
+
}
|
|
14945
|
+
if (show) {
|
|
14946
|
+
entries.push({
|
|
14947
|
+
id: `agent:${messageId}:artifacts`,
|
|
14948
|
+
role: "assistant",
|
|
14949
|
+
content: "",
|
|
14950
|
+
timestamp,
|
|
14951
|
+
jobId,
|
|
14952
|
+
show,
|
|
14953
|
+
historyContent: buildArtifactHistory(show),
|
|
14954
|
+
source: "job_agent_message"
|
|
14955
|
+
});
|
|
14956
|
+
}
|
|
14957
|
+
return entries;
|
|
14958
|
+
});
|
|
14959
|
+
}
|
|
14960
|
+
function buildJobFallbackEntries(jobId, job, sessionHeap) {
|
|
14961
|
+
const timestamp = asNumber(job.finishedAt) || asNumber(job.startedAt) || asNumber(job.submittedAt) || 0;
|
|
14962
|
+
const resultPreview = stringifyTranscriptValue(
|
|
14963
|
+
job.result,
|
|
14964
|
+
"No job result recorded."
|
|
14965
|
+
);
|
|
14966
|
+
const presentation = resolveJobPresentation({
|
|
14967
|
+
jobId,
|
|
14968
|
+
result: job.result,
|
|
14969
|
+
stdout: [],
|
|
14970
|
+
sessionHeap
|
|
14971
|
+
});
|
|
14972
|
+
const entries = [];
|
|
14973
|
+
const responseText = presentation.responseText || "";
|
|
14974
|
+
if (responseText) {
|
|
14975
|
+
entries.push({
|
|
14976
|
+
id: `job:${jobId}:result-text`,
|
|
14977
|
+
role: "assistant",
|
|
14978
|
+
content: responseText,
|
|
14979
|
+
timestamp,
|
|
14980
|
+
jobId,
|
|
14981
|
+
historyContent: `[Assistant reply]
|
|
14982
|
+
${responseText}`,
|
|
14983
|
+
source: "job_result"
|
|
14984
|
+
});
|
|
14985
|
+
}
|
|
14986
|
+
const show = {
|
|
14987
|
+
entryPaths: presentation.entries.map((entry) => entry.path),
|
|
14988
|
+
listNames: presentation.lists.map((list) => list.name)
|
|
14989
|
+
};
|
|
14990
|
+
if (show.entryPaths && show.entryPaths.length > 0 || show.listNames && show.listNames.length > 0) {
|
|
14991
|
+
entries.push({
|
|
14992
|
+
id: `job:${jobId}:result-artifacts`,
|
|
14993
|
+
role: "assistant",
|
|
14994
|
+
content: "",
|
|
14995
|
+
timestamp,
|
|
14996
|
+
jobId,
|
|
14997
|
+
show,
|
|
14998
|
+
historyContent: buildArtifactHistory(show),
|
|
14999
|
+
source: "job_result"
|
|
15000
|
+
});
|
|
15001
|
+
}
|
|
15002
|
+
if (entries.length === 0 && trimString(job.error)) {
|
|
15003
|
+
entries.push({
|
|
15004
|
+
id: `job:${jobId}:result-error`,
|
|
15005
|
+
role: "assistant",
|
|
15006
|
+
content: trimString(job.error),
|
|
15007
|
+
timestamp,
|
|
15008
|
+
jobId,
|
|
15009
|
+
historyContent: `[Assistant reply]
|
|
15010
|
+
${trimString(job.error)}`,
|
|
15011
|
+
source: "job_result"
|
|
15012
|
+
});
|
|
15013
|
+
}
|
|
15014
|
+
if (entries.length === 0 && resultPreview && resultPreview !== "No job result recorded.") {
|
|
15015
|
+
entries.push({
|
|
15016
|
+
id: `job:${jobId}:result-preview`,
|
|
15017
|
+
role: "assistant",
|
|
15018
|
+
content: resultPreview,
|
|
15019
|
+
timestamp,
|
|
15020
|
+
jobId,
|
|
15021
|
+
historyContent: `[Assistant reply]
|
|
15022
|
+
${resultPreview}`,
|
|
15023
|
+
source: "job_result"
|
|
15024
|
+
});
|
|
15025
|
+
}
|
|
15026
|
+
return entries;
|
|
15027
|
+
}
|
|
15028
|
+
function buildJobCodeEntry(jobId, job) {
|
|
15029
|
+
const code = trimString(job.source);
|
|
15030
|
+
if (!code) return null;
|
|
15031
|
+
const jobStatus = asString(job.status);
|
|
15032
|
+
const error = jobStatus === "failed" || jobStatus === "canceled" || jobStatus === "timeout" ? trimString(job.error) || `Job ${jobStatus}` : void 0;
|
|
15033
|
+
return {
|
|
15034
|
+
id: `job:${jobId}:code`,
|
|
15035
|
+
role: "assistant",
|
|
15036
|
+
content: "",
|
|
15037
|
+
timestamp: asNumber(job.submittedAt) || asNumber(job.startedAt) || asNumber(job.finishedAt) || 0,
|
|
15038
|
+
jobId,
|
|
15039
|
+
code,
|
|
15040
|
+
jobStatus,
|
|
15041
|
+
jobResultPreview: stringifyTranscriptValue(job.result, "No job result recorded."),
|
|
15042
|
+
error,
|
|
15043
|
+
source: "job_code"
|
|
15044
|
+
};
|
|
15045
|
+
}
|
|
15046
|
+
function buildSessionTranscript(input) {
|
|
15047
|
+
const liveDoc = input.liveDoc || null;
|
|
15048
|
+
const sessionHeap = input.sessionHeap || EMPTY_HEAP;
|
|
15049
|
+
const transcript = [];
|
|
15050
|
+
const conversationMessages = asArray2(asRecord4(liveDoc?.conversation)?.messages).map((message) => normalizeConversationMessage(message)).filter((message) => Boolean(message));
|
|
15051
|
+
const conversationPromptIds = new Set(
|
|
15052
|
+
conversationMessages.map((message) => message.promptId).filter((promptId) => Boolean(promptId))
|
|
15053
|
+
);
|
|
15054
|
+
const assistantConversationJobIds = new Set(
|
|
15055
|
+
conversationMessages.filter((message) => message.role === "assistant" && Boolean(message.jobId)).map((message) => message.jobId)
|
|
15056
|
+
);
|
|
15057
|
+
transcript.push(...conversationMessages);
|
|
15058
|
+
const jobsById = asRecord4(asRecord4(liveDoc?.jobs)?.byId) || {};
|
|
15059
|
+
const jobs = Object.values(jobsById).map((value) => asRecord4(value)).filter((value) => Boolean(value)).sort(
|
|
15060
|
+
(left, right) => (asNumber(left.submittedAt) || asNumber(left.startedAt) || asNumber(left.finishedAt) || 0) - (asNumber(right.submittedAt) || asNumber(right.startedAt) || asNumber(right.finishedAt) || 0)
|
|
15061
|
+
);
|
|
15062
|
+
for (const job of jobs) {
|
|
15063
|
+
const jobId = asString(job.jobId);
|
|
15064
|
+
if (!jobId) continue;
|
|
15065
|
+
const codeEntry = buildJobCodeEntry(jobId, job);
|
|
15066
|
+
if (codeEntry) {
|
|
15067
|
+
transcript.push(codeEntry);
|
|
15068
|
+
}
|
|
15069
|
+
transcript.push(
|
|
15070
|
+
...normalizePromptEntries(jobId, job.prompts, conversationPromptIds)
|
|
15071
|
+
);
|
|
15072
|
+
if (!assistantConversationJobIds.has(jobId)) {
|
|
15073
|
+
const agentEntries = normalizeAgentMessageEntries(jobId, job.agentMessages);
|
|
15074
|
+
if (agentEntries.length > 0) {
|
|
15075
|
+
transcript.push(...agentEntries);
|
|
15076
|
+
} else {
|
|
15077
|
+
transcript.push(
|
|
15078
|
+
...buildJobFallbackEntries(
|
|
15079
|
+
jobId,
|
|
15080
|
+
job,
|
|
15081
|
+
sessionHeap
|
|
15082
|
+
)
|
|
15083
|
+
);
|
|
15084
|
+
}
|
|
15085
|
+
}
|
|
15086
|
+
}
|
|
15087
|
+
return transcript.sort((left, right) => {
|
|
15088
|
+
if (left.timestamp !== right.timestamp) {
|
|
15089
|
+
return left.timestamp - right.timestamp;
|
|
15090
|
+
}
|
|
15091
|
+
return left.id.localeCompare(right.id);
|
|
15092
|
+
});
|
|
15093
|
+
}
|
|
14671
15094
|
|
|
14672
|
-
export { Environment, Granular, Session, WSClient, buildContinuationInstruction, buildGranularAgentCheckpointBlock, buildGranularAgentDomainBlock, buildGranularAgentHeapBlock, buildGranularAgentLoopBlock, buildGranularAgentSessionBlock, buildGranularAgentSystemPrompt, buildGranularAgentToolBlock, buildGranularAgentWorkflowBlock, createHarnessVerifierSnapshot, evaluateContinuation, extractPromptTokens, getCurrentClosureId, getExclusivePromptTarget, hasOpenPrompt, invokeRegisteredEffect, isLocalApiUrl, normalizeEffectBehaviors, normalizePrompt, normalizePromptText, normalizePromptType, projectHeapSummary, projectLoopSummary, projectWorkflowFocus, projectWorkflowSummary, resolveApiUrl, resolveAuthTokenForApiUrl, resolveJobPresentation, resolvePromptAnswer, reviewGeneratedJobCode, scorePromptChoiceMatch };
|
|
15095
|
+
export { Environment, Granular, Session, WSClient, buildContinuationInstruction, buildGranularAgentCheckpointBlock, buildGranularAgentDomainBlock, buildGranularAgentHeapBlock, buildGranularAgentLoopBlock, buildGranularAgentSessionBlock, buildGranularAgentSystemPrompt, buildGranularAgentToolBlock, buildGranularAgentWorkflowBlock, buildSessionTranscript, createHarnessVerifierSnapshot, evaluateContinuation, extractPromptTokens, getCurrentClosureId, getExclusivePromptTarget, hasOpenPrompt, invokeRegisteredEffect, isLocalApiUrl, normalizeEffectBehaviors, normalizePrompt, normalizePromptText, normalizePromptType, projectHeapSummary, projectLoopSummary, projectWorkflowFocus, projectWorkflowSummary, resolveApiUrl, resolveAuthTokenForApiUrl, resolveJobPresentation, resolvePromptAnswer, reviewGeneratedJobCode, scorePromptChoiceMatch };
|
|
14673
15096
|
//# sourceMappingURL=index.mjs.map
|
|
14674
15097
|
//# sourceMappingURL=index.mjs.map
|