@granular-software/sdk 0.4.24 → 0.4.25
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 +131 -38
- package/dist/agent-evals.js.map +1 -1
- package/dist/agent-evals.mjs +131 -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 +67 -8
- package/dist/{client-CQFKsCTd.d.mts → client-BeKRGMoT.d.mts} +1 -0
- package/dist/{client-CQFKsCTd.d.ts → client-BeKRGMoT.d.ts} +1 -0
- package/dist/index.d.mts +5 -3
- package/dist/index.d.ts +5 -3
- package/dist/index.js +131 -38
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +131 -38
- 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) */
|
|
@@ -4702,6 +4703,15 @@ var Session = class {
|
|
|
4702
4703
|
createdAt: Date.now()
|
|
4703
4704
|
});
|
|
4704
4705
|
this.jobsMap.set(result.jobId, job);
|
|
4706
|
+
const pendingAgentMessages = this.pendingAgentMessagesByJobId.get(
|
|
4707
|
+
result.jobId
|
|
4708
|
+
);
|
|
4709
|
+
if (pendingAgentMessages && pendingAgentMessages.length > 0) {
|
|
4710
|
+
this.pendingAgentMessagesByJobId.delete(result.jobId);
|
|
4711
|
+
for (const message of pendingAgentMessages) {
|
|
4712
|
+
job.replayAgentMessage(message);
|
|
4713
|
+
}
|
|
4714
|
+
}
|
|
4705
4715
|
return job;
|
|
4706
4716
|
}
|
|
4707
4717
|
/**
|
|
@@ -5103,6 +5113,22 @@ import { ${allImports} } from "./sandbox-tools";
|
|
|
5103
5113
|
this.client.on("job.status", (data) => {
|
|
5104
5114
|
this.emit("job:status", data);
|
|
5105
5115
|
});
|
|
5116
|
+
this.client.on("job.agent_message", (data) => {
|
|
5117
|
+
const normalized = normalizeJobAgentMessageEnvelope(data);
|
|
5118
|
+
if (!normalized) return;
|
|
5119
|
+
if (this.jobsMap.has(normalized.jobId)) return;
|
|
5120
|
+
const pending = this.pendingAgentMessagesByJobId.get(normalized.jobId) || [];
|
|
5121
|
+
if (normalized.message.messageId && pending.some(
|
|
5122
|
+
(message) => message.messageId === normalized.message.messageId
|
|
5123
|
+
)) {
|
|
5124
|
+
return;
|
|
5125
|
+
}
|
|
5126
|
+
pending.push(normalized.message);
|
|
5127
|
+
this.pendingAgentMessagesByJobId.set(
|
|
5128
|
+
normalized.jobId,
|
|
5129
|
+
pending.slice(-25)
|
|
5130
|
+
);
|
|
5131
|
+
});
|
|
5106
5132
|
this.client.on("exec.completed", (data) => {
|
|
5107
5133
|
this.emit("exec:completed", data);
|
|
5108
5134
|
});
|
|
@@ -5227,6 +5253,22 @@ function sanitizeFeedbackValue(value, depth = 0, seen = /* @__PURE__ */ new Weak
|
|
|
5227
5253
|
}
|
|
5228
5254
|
return truncateFeedbackString(String(value));
|
|
5229
5255
|
}
|
|
5256
|
+
function normalizeJobAgentMessageEnvelope(data) {
|
|
5257
|
+
const d = data;
|
|
5258
|
+
if (typeof d?.jobId !== "string" || !d.jobId) {
|
|
5259
|
+
return null;
|
|
5260
|
+
}
|
|
5261
|
+
return {
|
|
5262
|
+
jobId: d.jobId,
|
|
5263
|
+
message: {
|
|
5264
|
+
messageId: d.messageId,
|
|
5265
|
+
kind: d.kind === "artifacts" ? "artifacts" : "text",
|
|
5266
|
+
reply: typeof d.reply === "string" ? d.reply : "",
|
|
5267
|
+
show: d.show,
|
|
5268
|
+
timestamp: d.timestamp || Date.now()
|
|
5269
|
+
}
|
|
5270
|
+
};
|
|
5271
|
+
}
|
|
5230
5272
|
var JobImplementation = class {
|
|
5231
5273
|
id;
|
|
5232
5274
|
client;
|
|
@@ -5235,6 +5277,8 @@ var JobImplementation = class {
|
|
|
5235
5277
|
_resolveResult;
|
|
5236
5278
|
_rejectResult;
|
|
5237
5279
|
eventListeners = /* @__PURE__ */ new Map();
|
|
5280
|
+
bufferedAgentMessages = [];
|
|
5281
|
+
bufferedAgentMessageIds = /* @__PURE__ */ new Set();
|
|
5238
5282
|
metadata;
|
|
5239
5283
|
constructor(id, client, initialState) {
|
|
5240
5284
|
this.id = id;
|
|
@@ -5393,14 +5437,9 @@ var JobImplementation = class {
|
|
|
5393
5437
|
}
|
|
5394
5438
|
});
|
|
5395
5439
|
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
|
-
});
|
|
5440
|
+
const normalized = normalizeJobAgentMessageEnvelope(data);
|
|
5441
|
+
if (normalized?.jobId === id) {
|
|
5442
|
+
this.captureAgentMessage(normalized.message);
|
|
5404
5443
|
}
|
|
5405
5444
|
});
|
|
5406
5445
|
}
|
|
@@ -5427,6 +5466,14 @@ var JobImplementation = class {
|
|
|
5427
5466
|
this.eventListeners.set(event, []);
|
|
5428
5467
|
}
|
|
5429
5468
|
this.eventListeners.get(event).push(handler);
|
|
5469
|
+
if (event === "agentMessage" && this.bufferedAgentMessages.length > 0) {
|
|
5470
|
+
for (const message of this.bufferedAgentMessages) {
|
|
5471
|
+
handler(message);
|
|
5472
|
+
}
|
|
5473
|
+
}
|
|
5474
|
+
}
|
|
5475
|
+
replayAgentMessage(message) {
|
|
5476
|
+
this.captureAgentMessage(message);
|
|
5430
5477
|
}
|
|
5431
5478
|
buildFeedbackMetadata() {
|
|
5432
5479
|
const startedAt = this.metadata.startedAt;
|
|
@@ -5496,6 +5543,18 @@ var JobImplementation = class {
|
|
|
5496
5543
|
handlers.forEach((h) => h(data));
|
|
5497
5544
|
}
|
|
5498
5545
|
}
|
|
5546
|
+
captureAgentMessage(message) {
|
|
5547
|
+
if (message.messageId && this.bufferedAgentMessageIds.has(message.messageId)) {
|
|
5548
|
+
return;
|
|
5549
|
+
}
|
|
5550
|
+
if (message.messageId) {
|
|
5551
|
+
this.bufferedAgentMessageIds.add(message.messageId);
|
|
5552
|
+
}
|
|
5553
|
+
this.bufferedAgentMessages = [...this.bufferedAgentMessages, message].slice(
|
|
5554
|
+
-25
|
|
5555
|
+
);
|
|
5556
|
+
this.emit("agentMessage", message);
|
|
5557
|
+
}
|
|
5499
5558
|
};
|
|
5500
5559
|
|
|
5501
5560
|
// src/endpoints.ts
|
|
@@ -13550,14 +13609,22 @@ function reviewGeneratedJobCode(code) {
|
|
|
13550
13609
|
}
|
|
13551
13610
|
}
|
|
13552
13611
|
}
|
|
13553
|
-
const hasConversationalReturn = /return\s+[`'"]/.test(normalized) || /\breply\s*:/.test(normalized) || /\bagent_message\s*\(/.test(normalized);
|
|
13612
|
+
const hasConversationalReturn = /return\s+[`'"]/.test(normalized) || /\breply\s*:/.test(normalized) || /\bagent_message\s*\(/.test(normalized) || /\bagent_text_message\s*\(/.test(normalized);
|
|
13554
13613
|
const returnsObjectLiteral = /return\s+\{[\s\S]*?\}/.test(normalized);
|
|
13614
|
+
const returnsShowPayload = /return\s+\{[\s\S]*?\bshow\s*:/.test(normalized);
|
|
13555
13615
|
const closesLoop = /loop\.close_loop\s*\(/.test(normalized);
|
|
13556
13616
|
if (!hasConversationalReturn && returnsObjectLiteral && !closesLoop) {
|
|
13557
13617
|
issues.push({
|
|
13558
13618
|
code: "missing_user_reply",
|
|
13559
13619
|
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
|
|
13620
|
+
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."
|
|
13621
|
+
});
|
|
13622
|
+
}
|
|
13623
|
+
if (returnsShowPayload) {
|
|
13624
|
+
issues.push({
|
|
13625
|
+
code: "return_show_not_for_ui",
|
|
13626
|
+
severity: "error",
|
|
13627
|
+
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
13628
|
});
|
|
13562
13629
|
}
|
|
13563
13630
|
return issues;
|
|
@@ -14407,7 +14474,7 @@ ${loopBlock}
|
|
|
14407
14474
|
|
|
14408
14475
|
\u2500\u2500\u2500 CODE RULES \u2500\u2500\u2500
|
|
14409
14476
|
- Import from \`./sandbox-tools\`.
|
|
14410
|
-
- If you use \`heap\`, \`loop\`, or \`agent_message\`, import them explicitly from \`./sandbox-tools\`.
|
|
14477
|
+
- If you use \`heap\`, \`loop\`, \`agent_text_message\`, \`agent_heap_objects\`, or legacy \`agent_message\`, import them explicitly from \`./sandbox-tools\`.
|
|
14411
14478
|
- Write top-level executable code with \`await\` at top level.
|
|
14412
14479
|
- The generated job body must be plain runnable JavaScript. The DOMAIN TYPES block is only a reference for shapes and available methods.
|
|
14413
14480
|
- 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 +14516,31 @@ ${loopBlock}
|
|
|
14449
14516
|
- \`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
14517
|
- Avoid \`as any\` and other broad casts when the DOMAIN TYPES block already tells you the correct class or list type.
|
|
14451
14518
|
- 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
|
-
-
|
|
14519
|
+
- 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(...)\`.
|
|
14520
|
+
- Use \`agent_text_message("...")\` for all user-visible text shown in the UI.
|
|
14521
|
+
- Use \`agent_heap_objects(...)\` only when you want the UI to render heap-backed records or lists.
|
|
14522
|
+
- If you want to show both text and records, call \`agent_text_message(...)\` and \`agent_heap_objects(...)\` separately in whatever order fits the interaction.
|
|
14523
|
+
- \`agent_text_message(...)\` should be used with a plain text string in normal generated code.
|
|
14524
|
+
- \`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(...)\`.
|
|
14525
|
+
- 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.
|
|
14526
|
+
- Do not assume heap changes will be displayed automatically. If records should appear in the UI, you must call \`agent_heap_objects(...)\`.
|
|
14527
|
+
- 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.
|
|
14528
|
+
- Do not rely on the final return value for user-visible output. A plain return value is not considered a displayed UI answer.
|
|
14529
|
+
- \`agent_message(...)\` remains available as a legacy compatibility alias, but prefer \`agent_text_message(...)\` and \`agent_heap_objects(...)\` in new code.
|
|
14460
14530
|
- 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
14531
|
- 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
14532
|
- Use \`console.log()\` only for intermediate diagnostics, not for the final user-facing answer.`;
|
|
14463
14533
|
}
|
|
14464
14534
|
|
|
14465
14535
|
// src/job-presentation.ts
|
|
14466
|
-
var RESPONSE_KEYS = [
|
|
14536
|
+
var RESPONSE_KEYS = [
|
|
14537
|
+
"reply",
|
|
14538
|
+
"response",
|
|
14539
|
+
"text",
|
|
14540
|
+
"message",
|
|
14541
|
+
"summary",
|
|
14542
|
+
"answer"
|
|
14543
|
+
];
|
|
14467
14544
|
var ENTRY_KEY_CANDIDATES = ["entryPath", "path"];
|
|
14468
14545
|
var ENTRY_ARRAY_KEY_CANDIDATES = ["entryPaths", "paths"];
|
|
14469
14546
|
var LIST_KEY_CANDIDATES = ["listName"];
|
|
@@ -14505,15 +14582,22 @@ function pushStringArray(target, value) {
|
|
|
14505
14582
|
}
|
|
14506
14583
|
}
|
|
14507
14584
|
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
|
-
|
|
14585
|
+
for (const key of ENTRY_KEY_CANDIDATES)
|
|
14586
|
+
pushString(refs.entryPaths, record[key]);
|
|
14587
|
+
for (const key of ENTRY_ARRAY_KEY_CANDIDATES)
|
|
14588
|
+
pushStringArray(refs.entryPaths, record[key]);
|
|
14589
|
+
for (const key of LIST_KEY_CANDIDATES)
|
|
14590
|
+
pushString(refs.listNames, record[key]);
|
|
14591
|
+
for (const key of LIST_ARRAY_KEY_CANDIDATES)
|
|
14592
|
+
pushStringArray(refs.listNames, record[key]);
|
|
14593
|
+
for (const key of VARIABLE_KEY_CANDIDATES)
|
|
14594
|
+
pushString(refs.variableNames, record[key]);
|
|
14595
|
+
for (const key of VARIABLE_ARRAY_KEY_CANDIDATES)
|
|
14596
|
+
pushStringArray(refs.variableNames, record[key]);
|
|
14514
14597
|
}
|
|
14515
14598
|
function scanForHeapReferences(value, heap, refs, depth = 0, seen = /* @__PURE__ */ new Set()) {
|
|
14516
|
-
if (value === null || value === void 0 || depth > 4 || seen.has(value))
|
|
14599
|
+
if (value === null || value === void 0 || depth > 4 || seen.has(value))
|
|
14600
|
+
return;
|
|
14517
14601
|
if (typeof value === "string") {
|
|
14518
14602
|
const trimmed = value.trim();
|
|
14519
14603
|
if (heap.entriesByPath?.[trimmed]) refs.entryPaths.add(trimmed);
|
|
@@ -14609,12 +14693,16 @@ function fallbackResponseText(entries, lists) {
|
|
|
14609
14693
|
}
|
|
14610
14694
|
function getJobRelatedEntries(heap, jobId) {
|
|
14611
14695
|
return sortEntries(
|
|
14612
|
-
Object.values(heap.entriesByPath || {}).filter(
|
|
14696
|
+
Object.values(heap.entriesByPath || {}).filter(
|
|
14697
|
+
(entry) => entry.relatedJobIds?.includes(jobId)
|
|
14698
|
+
)
|
|
14613
14699
|
);
|
|
14614
14700
|
}
|
|
14615
14701
|
function getJobRelatedLists(heap, jobId) {
|
|
14616
14702
|
return sortLists(
|
|
14617
|
-
Object.values(heap.listsByName || {}).filter(
|
|
14703
|
+
Object.values(heap.listsByName || {}).filter(
|
|
14704
|
+
(list) => list.relatedJobIds?.includes(jobId)
|
|
14705
|
+
)
|
|
14618
14706
|
);
|
|
14619
14707
|
}
|
|
14620
14708
|
function entriesFromLists(lists, heap) {
|
|
@@ -14631,15 +14719,18 @@ function resolveJobPresentation({
|
|
|
14631
14719
|
jobId,
|
|
14632
14720
|
result,
|
|
14633
14721
|
stdout = [],
|
|
14634
|
-
sessionHeap
|
|
14722
|
+
sessionHeap,
|
|
14723
|
+
allowExplicitArtifacts = true
|
|
14635
14724
|
}) {
|
|
14636
14725
|
const refs = {
|
|
14637
14726
|
entryPaths: /* @__PURE__ */ new Set(),
|
|
14638
14727
|
listNames: /* @__PURE__ */ new Set(),
|
|
14639
14728
|
variableNames: /* @__PURE__ */ new Set()
|
|
14640
14729
|
};
|
|
14641
|
-
|
|
14642
|
-
|
|
14730
|
+
if (allowExplicitArtifacts) {
|
|
14731
|
+
scanForHeapReferences(result, sessionHeap, refs);
|
|
14732
|
+
resolveVariablesToReferences(refs.variableNames, sessionHeap, refs);
|
|
14733
|
+
}
|
|
14643
14734
|
const referencedLists = sortLists(
|
|
14644
14735
|
[...refs.listNames].map((name) => sessionHeap.listsByName?.[name]).filter((list) => Boolean(list))
|
|
14645
14736
|
);
|
|
@@ -14652,20 +14743,22 @@ function resolveJobPresentation({
|
|
|
14652
14743
|
...jobEntries,
|
|
14653
14744
|
...entriesFromLists(jobLists, sessionHeap)
|
|
14654
14745
|
]);
|
|
14655
|
-
const
|
|
14656
|
-
const
|
|
14746
|
+
const explicitLists = dedupeLists(referencedLists);
|
|
14747
|
+
const explicitEntries = dedupeEntries([
|
|
14657
14748
|
...referencedEntries,
|
|
14658
|
-
...entriesFromLists(referencedLists, sessionHeap)
|
|
14659
|
-
...jobEntries,
|
|
14660
|
-
...entriesFromLists(jobLists, sessionHeap)
|
|
14749
|
+
...entriesFromLists(referencedLists, sessionHeap)
|
|
14661
14750
|
]);
|
|
14751
|
+
const hasExplicitArtifacts = allowExplicitArtifacts && (explicitEntries.length > 0 || explicitLists.length > 0);
|
|
14752
|
+
const lists = hasExplicitArtifacts ? explicitLists : jobLists;
|
|
14753
|
+
const entries = hasExplicitArtifacts ? explicitEntries : changedEntries;
|
|
14662
14754
|
const responseText = extractResponseText(result, stdout) || fallbackResponseText(entries, lists);
|
|
14663
14755
|
return {
|
|
14664
14756
|
responseText,
|
|
14665
14757
|
entries,
|
|
14666
14758
|
lists,
|
|
14667
14759
|
changedEntries,
|
|
14668
|
-
changedLists: jobLists
|
|
14760
|
+
changedLists: jobLists,
|
|
14761
|
+
hasExplicitArtifacts
|
|
14669
14762
|
};
|
|
14670
14763
|
}
|
|
14671
14764
|
|