@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/agent-evals.mjs
CHANGED
|
@@ -4547,6 +4547,7 @@ var Session = class {
|
|
|
4547
4547
|
client;
|
|
4548
4548
|
clientId;
|
|
4549
4549
|
jobsMap = /* @__PURE__ */ new Map();
|
|
4550
|
+
pendingAgentMessagesByJobId = /* @__PURE__ */ new Map();
|
|
4550
4551
|
eventListeners = /* @__PURE__ */ new Map();
|
|
4551
4552
|
toolHandlers = /* @__PURE__ */ new Map();
|
|
4552
4553
|
/** Tracks which tools are instance methods (className set, not static) */
|
|
@@ -4589,6 +4590,22 @@ var Session = class {
|
|
|
4589
4590
|
}
|
|
4590
4591
|
};
|
|
4591
4592
|
}
|
|
4593
|
+
stringifyConversationValue(value) {
|
|
4594
|
+
if (typeof value === "string") {
|
|
4595
|
+
return value;
|
|
4596
|
+
}
|
|
4597
|
+
if (typeof value === "boolean") {
|
|
4598
|
+
return value ? "Confirmed" : "Canceled";
|
|
4599
|
+
}
|
|
4600
|
+
if (value === void 0) {
|
|
4601
|
+
return "";
|
|
4602
|
+
}
|
|
4603
|
+
try {
|
|
4604
|
+
return JSON.stringify(value, null, 2);
|
|
4605
|
+
} catch {
|
|
4606
|
+
return String(value);
|
|
4607
|
+
}
|
|
4608
|
+
}
|
|
4592
4609
|
// --- Public API ---
|
|
4593
4610
|
get document() {
|
|
4594
4611
|
return this.client.doc;
|
|
@@ -4704,6 +4721,15 @@ var Session = class {
|
|
|
4704
4721
|
createdAt: Date.now()
|
|
4705
4722
|
});
|
|
4706
4723
|
this.jobsMap.set(result.jobId, job);
|
|
4724
|
+
const pendingAgentMessages = this.pendingAgentMessagesByJobId.get(
|
|
4725
|
+
result.jobId
|
|
4726
|
+
);
|
|
4727
|
+
if (pendingAgentMessages && pendingAgentMessages.length > 0) {
|
|
4728
|
+
this.pendingAgentMessagesByJobId.delete(result.jobId);
|
|
4729
|
+
for (const message of pendingAgentMessages) {
|
|
4730
|
+
job.replayAgentMessage(message);
|
|
4731
|
+
}
|
|
4732
|
+
}
|
|
4707
4733
|
return job;
|
|
4708
4734
|
}
|
|
4709
4735
|
/**
|
|
@@ -4730,6 +4756,20 @@ var Session = class {
|
|
|
4730
4756
|
answer: resolvedAnswer,
|
|
4731
4757
|
value: resolvedAnswer
|
|
4732
4758
|
});
|
|
4759
|
+
try {
|
|
4760
|
+
const content = this.stringifyConversationValue(resolvedAnswer);
|
|
4761
|
+
if (content.trim()) {
|
|
4762
|
+
await this.appendConversationMessage({
|
|
4763
|
+
role: "user",
|
|
4764
|
+
content,
|
|
4765
|
+
promptId
|
|
4766
|
+
});
|
|
4767
|
+
}
|
|
4768
|
+
} catch {
|
|
4769
|
+
}
|
|
4770
|
+
}
|
|
4771
|
+
async appendConversationMessage(input) {
|
|
4772
|
+
return this.client.call("conversation.append", input);
|
|
4733
4773
|
}
|
|
4734
4774
|
/**
|
|
4735
4775
|
* Get the current list of available effects.
|
|
@@ -5105,6 +5145,22 @@ import { ${allImports} } from "./sandbox-tools";
|
|
|
5105
5145
|
this.client.on("job.status", (data) => {
|
|
5106
5146
|
this.emit("job:status", data);
|
|
5107
5147
|
});
|
|
5148
|
+
this.client.on("job.agent_message", (data) => {
|
|
5149
|
+
const normalized = normalizeJobAgentMessageEnvelope(data);
|
|
5150
|
+
if (!normalized) return;
|
|
5151
|
+
if (this.jobsMap.has(normalized.jobId)) return;
|
|
5152
|
+
const pending = this.pendingAgentMessagesByJobId.get(normalized.jobId) || [];
|
|
5153
|
+
if (normalized.message.messageId && pending.some(
|
|
5154
|
+
(message) => message.messageId === normalized.message.messageId
|
|
5155
|
+
)) {
|
|
5156
|
+
return;
|
|
5157
|
+
}
|
|
5158
|
+
pending.push(normalized.message);
|
|
5159
|
+
this.pendingAgentMessagesByJobId.set(
|
|
5160
|
+
normalized.jobId,
|
|
5161
|
+
pending.slice(-25)
|
|
5162
|
+
);
|
|
5163
|
+
});
|
|
5108
5164
|
this.client.on("exec.completed", (data) => {
|
|
5109
5165
|
this.emit("exec:completed", data);
|
|
5110
5166
|
});
|
|
@@ -5229,6 +5285,22 @@ function sanitizeFeedbackValue(value, depth = 0, seen = /* @__PURE__ */ new Weak
|
|
|
5229
5285
|
}
|
|
5230
5286
|
return truncateFeedbackString(String(value));
|
|
5231
5287
|
}
|
|
5288
|
+
function normalizeJobAgentMessageEnvelope(data) {
|
|
5289
|
+
const d = data;
|
|
5290
|
+
if (typeof d?.jobId !== "string" || !d.jobId) {
|
|
5291
|
+
return null;
|
|
5292
|
+
}
|
|
5293
|
+
return {
|
|
5294
|
+
jobId: d.jobId,
|
|
5295
|
+
message: {
|
|
5296
|
+
messageId: d.messageId,
|
|
5297
|
+
kind: d.kind === "artifacts" ? "artifacts" : "text",
|
|
5298
|
+
reply: typeof d.reply === "string" ? d.reply : "",
|
|
5299
|
+
show: d.show,
|
|
5300
|
+
timestamp: d.timestamp || Date.now()
|
|
5301
|
+
}
|
|
5302
|
+
};
|
|
5303
|
+
}
|
|
5232
5304
|
var JobImplementation = class {
|
|
5233
5305
|
id;
|
|
5234
5306
|
client;
|
|
@@ -5237,6 +5309,8 @@ var JobImplementation = class {
|
|
|
5237
5309
|
_resolveResult;
|
|
5238
5310
|
_rejectResult;
|
|
5239
5311
|
eventListeners = /* @__PURE__ */ new Map();
|
|
5312
|
+
bufferedAgentMessages = [];
|
|
5313
|
+
bufferedAgentMessageIds = /* @__PURE__ */ new Set();
|
|
5240
5314
|
metadata;
|
|
5241
5315
|
constructor(id, client, initialState) {
|
|
5242
5316
|
this.id = id;
|
|
@@ -5395,14 +5469,9 @@ var JobImplementation = class {
|
|
|
5395
5469
|
}
|
|
5396
5470
|
});
|
|
5397
5471
|
this.client.on("job.agent_message", (data) => {
|
|
5398
|
-
const
|
|
5399
|
-
if (
|
|
5400
|
-
this.
|
|
5401
|
-
messageId: d.messageId,
|
|
5402
|
-
reply: typeof d.reply === "string" ? d.reply : "",
|
|
5403
|
-
show: d.show,
|
|
5404
|
-
timestamp: d.timestamp || Date.now()
|
|
5405
|
-
});
|
|
5472
|
+
const normalized = normalizeJobAgentMessageEnvelope(data);
|
|
5473
|
+
if (normalized?.jobId === id) {
|
|
5474
|
+
this.captureAgentMessage(normalized.message);
|
|
5406
5475
|
}
|
|
5407
5476
|
});
|
|
5408
5477
|
}
|
|
@@ -5429,6 +5498,14 @@ var JobImplementation = class {
|
|
|
5429
5498
|
this.eventListeners.set(event, []);
|
|
5430
5499
|
}
|
|
5431
5500
|
this.eventListeners.get(event).push(handler);
|
|
5501
|
+
if (event === "agentMessage" && this.bufferedAgentMessages.length > 0) {
|
|
5502
|
+
for (const message of this.bufferedAgentMessages) {
|
|
5503
|
+
handler(message);
|
|
5504
|
+
}
|
|
5505
|
+
}
|
|
5506
|
+
}
|
|
5507
|
+
replayAgentMessage(message) {
|
|
5508
|
+
this.captureAgentMessage(message);
|
|
5432
5509
|
}
|
|
5433
5510
|
buildFeedbackMetadata() {
|
|
5434
5511
|
const startedAt = this.metadata.startedAt;
|
|
@@ -5498,6 +5575,18 @@ var JobImplementation = class {
|
|
|
5498
5575
|
handlers.forEach((h) => h(data));
|
|
5499
5576
|
}
|
|
5500
5577
|
}
|
|
5578
|
+
captureAgentMessage(message) {
|
|
5579
|
+
if (message.messageId && this.bufferedAgentMessageIds.has(message.messageId)) {
|
|
5580
|
+
return;
|
|
5581
|
+
}
|
|
5582
|
+
if (message.messageId) {
|
|
5583
|
+
this.bufferedAgentMessageIds.add(message.messageId);
|
|
5584
|
+
}
|
|
5585
|
+
this.bufferedAgentMessages = [...this.bufferedAgentMessages, message].slice(
|
|
5586
|
+
-25
|
|
5587
|
+
);
|
|
5588
|
+
this.emit("agentMessage", message);
|
|
5589
|
+
}
|
|
5501
5590
|
};
|
|
5502
5591
|
|
|
5503
5592
|
// src/endpoints.ts
|
|
@@ -13552,14 +13641,22 @@ function reviewGeneratedJobCode(code) {
|
|
|
13552
13641
|
}
|
|
13553
13642
|
}
|
|
13554
13643
|
}
|
|
13555
|
-
const hasConversationalReturn = /return\s+[`'"]/.test(normalized) || /\breply\s*:/.test(normalized) || /\bagent_message\s*\(/.test(normalized);
|
|
13644
|
+
const hasConversationalReturn = /return\s+[`'"]/.test(normalized) || /\breply\s*:/.test(normalized) || /\bagent_message\s*\(/.test(normalized) || /\bagent_text_message\s*\(/.test(normalized);
|
|
13556
13645
|
const returnsObjectLiteral = /return\s+\{[\s\S]*?\}/.test(normalized);
|
|
13646
|
+
const returnsShowPayload = /return\s+\{[\s\S]*?\bshow\s*:/.test(normalized);
|
|
13557
13647
|
const closesLoop = /loop\.close_loop\s*\(/.test(normalized);
|
|
13558
13648
|
if (!hasConversationalReturn && returnsObjectLiteral && !closesLoop) {
|
|
13559
13649
|
issues.push({
|
|
13560
13650
|
code: "missing_user_reply",
|
|
13561
13651
|
severity: "error",
|
|
13562
|
-
message: "User-facing jobs must end with a natural-language answer. Return a short string, an object with a top-level `reply` string, or
|
|
13652
|
+
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."
|
|
13653
|
+
});
|
|
13654
|
+
}
|
|
13655
|
+
if (returnsShowPayload) {
|
|
13656
|
+
issues.push({
|
|
13657
|
+
code: "return_show_not_for_ui",
|
|
13658
|
+
severity: "error",
|
|
13659
|
+
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."
|
|
13563
13660
|
});
|
|
13564
13661
|
}
|
|
13565
13662
|
return issues;
|
|
@@ -14404,7 +14501,7 @@ ${loopBlock}
|
|
|
14404
14501
|
|
|
14405
14502
|
\u2500\u2500\u2500 CODE RULES \u2500\u2500\u2500
|
|
14406
14503
|
- Import from \`./sandbox-tools\`.
|
|
14407
|
-
- If you use \`heap\`, \`loop\`, or \`agent_message\`, import them explicitly from \`./sandbox-tools\`.
|
|
14504
|
+
- If you use \`heap\`, \`loop\`, \`agent_text_message\`, \`agent_heap_objects\`, or legacy \`agent_message\`, import them explicitly from \`./sandbox-tools\`.
|
|
14408
14505
|
- Write top-level executable code with \`await\` at top level.
|
|
14409
14506
|
- The generated job body must be plain runnable JavaScript. The DOMAIN TYPES block is only a reference for shapes and available methods.
|
|
14410
14507
|
- 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.
|
|
@@ -14446,21 +14543,31 @@ ${loopBlock}
|
|
|
14446
14543
|
- \`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.
|
|
14447
14544
|
- Avoid \`as any\` and other broad casts when the DOMAIN TYPES block already tells you the correct class or list type.
|
|
14448
14545
|
- Prefer manipulating heap-backed instances and typed lists instead of returning raw JSON blobs or object IDs unless the user explicitly asks for them.
|
|
14449
|
-
-
|
|
14450
|
-
-
|
|
14451
|
-
-
|
|
14452
|
-
- \`
|
|
14453
|
-
- \`
|
|
14454
|
-
-
|
|
14455
|
-
|
|
14456
|
-
-
|
|
14546
|
+
- 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(...)\`.
|
|
14547
|
+
- Use \`agent_text_message("...")\` for all user-visible text shown in the UI.
|
|
14548
|
+
- Use \`agent_heap_objects(...)\` only when you want the UI to render heap-backed records or lists.
|
|
14549
|
+
- If you want to show both text and records, call \`agent_text_message(...)\` and \`agent_heap_objects(...)\` separately in whatever order fits the interaction.
|
|
14550
|
+
- \`agent_text_message(...)\` should be used with a plain text string in normal generated code.
|
|
14551
|
+
- \`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(...)\`.
|
|
14552
|
+
- 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.
|
|
14553
|
+
- Do not assume heap changes will be displayed automatically. If records should appear in the UI, you must call \`agent_heap_objects(...)\`.
|
|
14554
|
+
- 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.
|
|
14555
|
+
- Do not rely on the final return value for user-visible output. A plain return value is not considered a displayed UI answer.
|
|
14556
|
+
- \`agent_message(...)\` remains available as a legacy compatibility alias, but prefer \`agent_text_message(...)\` and \`agent_heap_objects(...)\` in new code.
|
|
14457
14557
|
- Do not return bare structured JSON, low-level diagnostics, or database-shaped payloads as the final answer unless the user explicitly asks for them.
|
|
14458
14558
|
- 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.
|
|
14459
14559
|
- Use \`console.log()\` only for intermediate diagnostics, not for the final user-facing answer.`;
|
|
14460
14560
|
}
|
|
14461
14561
|
|
|
14462
14562
|
// src/job-presentation.ts
|
|
14463
|
-
var RESPONSE_KEYS = [
|
|
14563
|
+
var RESPONSE_KEYS = [
|
|
14564
|
+
"reply",
|
|
14565
|
+
"response",
|
|
14566
|
+
"text",
|
|
14567
|
+
"message",
|
|
14568
|
+
"summary",
|
|
14569
|
+
"answer"
|
|
14570
|
+
];
|
|
14464
14571
|
var ENTRY_KEY_CANDIDATES = ["entryPath", "path"];
|
|
14465
14572
|
var ENTRY_ARRAY_KEY_CANDIDATES = ["entryPaths", "paths"];
|
|
14466
14573
|
var LIST_KEY_CANDIDATES = ["listName"];
|
|
@@ -14502,15 +14609,22 @@ function pushStringArray(target, value) {
|
|
|
14502
14609
|
}
|
|
14503
14610
|
}
|
|
14504
14611
|
function collectReferencesFromRecord(record, refs) {
|
|
14505
|
-
for (const key of ENTRY_KEY_CANDIDATES)
|
|
14506
|
-
|
|
14507
|
-
for (const key of
|
|
14508
|
-
|
|
14509
|
-
for (const key of
|
|
14510
|
-
|
|
14612
|
+
for (const key of ENTRY_KEY_CANDIDATES)
|
|
14613
|
+
pushString(refs.entryPaths, record[key]);
|
|
14614
|
+
for (const key of ENTRY_ARRAY_KEY_CANDIDATES)
|
|
14615
|
+
pushStringArray(refs.entryPaths, record[key]);
|
|
14616
|
+
for (const key of LIST_KEY_CANDIDATES)
|
|
14617
|
+
pushString(refs.listNames, record[key]);
|
|
14618
|
+
for (const key of LIST_ARRAY_KEY_CANDIDATES)
|
|
14619
|
+
pushStringArray(refs.listNames, record[key]);
|
|
14620
|
+
for (const key of VARIABLE_KEY_CANDIDATES)
|
|
14621
|
+
pushString(refs.variableNames, record[key]);
|
|
14622
|
+
for (const key of VARIABLE_ARRAY_KEY_CANDIDATES)
|
|
14623
|
+
pushStringArray(refs.variableNames, record[key]);
|
|
14511
14624
|
}
|
|
14512
14625
|
function scanForHeapReferences(value, heap, refs, depth = 0, seen = /* @__PURE__ */ new Set()) {
|
|
14513
|
-
if (value === null || value === void 0 || depth > 4 || seen.has(value))
|
|
14626
|
+
if (value === null || value === void 0 || depth > 4 || seen.has(value))
|
|
14627
|
+
return;
|
|
14514
14628
|
if (typeof value === "string") {
|
|
14515
14629
|
const trimmed = value.trim();
|
|
14516
14630
|
if (heap.entriesByPath?.[trimmed]) refs.entryPaths.add(trimmed);
|
|
@@ -14606,12 +14720,16 @@ function fallbackResponseText(entries, lists) {
|
|
|
14606
14720
|
}
|
|
14607
14721
|
function getJobRelatedEntries(heap, jobId) {
|
|
14608
14722
|
return sortEntries(
|
|
14609
|
-
Object.values(heap.entriesByPath || {}).filter(
|
|
14723
|
+
Object.values(heap.entriesByPath || {}).filter(
|
|
14724
|
+
(entry) => entry.relatedJobIds?.includes(jobId)
|
|
14725
|
+
)
|
|
14610
14726
|
);
|
|
14611
14727
|
}
|
|
14612
14728
|
function getJobRelatedLists(heap, jobId) {
|
|
14613
14729
|
return sortLists(
|
|
14614
|
-
Object.values(heap.listsByName || {}).filter(
|
|
14730
|
+
Object.values(heap.listsByName || {}).filter(
|
|
14731
|
+
(list) => list.relatedJobIds?.includes(jobId)
|
|
14732
|
+
)
|
|
14615
14733
|
);
|
|
14616
14734
|
}
|
|
14617
14735
|
function entriesFromLists(lists, heap) {
|
|
@@ -14628,15 +14746,18 @@ function resolveJobPresentation({
|
|
|
14628
14746
|
jobId,
|
|
14629
14747
|
result,
|
|
14630
14748
|
stdout = [],
|
|
14631
|
-
sessionHeap
|
|
14749
|
+
sessionHeap,
|
|
14750
|
+
allowExplicitArtifacts = true
|
|
14632
14751
|
}) {
|
|
14633
14752
|
const refs = {
|
|
14634
14753
|
entryPaths: /* @__PURE__ */ new Set(),
|
|
14635
14754
|
listNames: /* @__PURE__ */ new Set(),
|
|
14636
14755
|
variableNames: /* @__PURE__ */ new Set()
|
|
14637
14756
|
};
|
|
14638
|
-
|
|
14639
|
-
|
|
14757
|
+
if (allowExplicitArtifacts) {
|
|
14758
|
+
scanForHeapReferences(result, sessionHeap, refs);
|
|
14759
|
+
resolveVariablesToReferences(refs.variableNames, sessionHeap, refs);
|
|
14760
|
+
}
|
|
14640
14761
|
const referencedLists = sortLists(
|
|
14641
14762
|
[...refs.listNames].map((name) => sessionHeap.listsByName?.[name]).filter((list) => Boolean(list))
|
|
14642
14763
|
);
|
|
@@ -14649,20 +14770,22 @@ function resolveJobPresentation({
|
|
|
14649
14770
|
...jobEntries,
|
|
14650
14771
|
...entriesFromLists(jobLists, sessionHeap)
|
|
14651
14772
|
]);
|
|
14652
|
-
const
|
|
14653
|
-
const
|
|
14773
|
+
const explicitLists = dedupeLists(referencedLists);
|
|
14774
|
+
const explicitEntries = dedupeEntries([
|
|
14654
14775
|
...referencedEntries,
|
|
14655
|
-
...entriesFromLists(referencedLists, sessionHeap)
|
|
14656
|
-
...jobEntries,
|
|
14657
|
-
...entriesFromLists(jobLists, sessionHeap)
|
|
14776
|
+
...entriesFromLists(referencedLists, sessionHeap)
|
|
14658
14777
|
]);
|
|
14778
|
+
const hasExplicitArtifacts = allowExplicitArtifacts && (explicitEntries.length > 0 || explicitLists.length > 0);
|
|
14779
|
+
const lists = hasExplicitArtifacts ? explicitLists : jobLists;
|
|
14780
|
+
const entries = hasExplicitArtifacts ? explicitEntries : changedEntries;
|
|
14659
14781
|
const responseText = extractResponseText(result, stdout) || fallbackResponseText(entries, lists);
|
|
14660
14782
|
return {
|
|
14661
14783
|
responseText,
|
|
14662
14784
|
entries,
|
|
14663
14785
|
lists,
|
|
14664
14786
|
changedEntries,
|
|
14665
|
-
changedLists: jobLists
|
|
14787
|
+
changedLists: jobLists,
|
|
14788
|
+
hasExplicitArtifacts
|
|
14666
14789
|
};
|
|
14667
14790
|
}
|
|
14668
14791
|
|