@sema-agent/core 2.0.1 → 2.2.0
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/agents/observer.d.ts +14 -0
- package/dist/agents/observer.js +66 -12
- package/dist/agents/send-message-tool.js +164 -88
- package/dist/agents/subagent.d.ts +11 -4
- package/dist/agents/subagent.js +166 -62
- package/dist/core/context-edit.js +16 -3
- package/dist/core/file-snapshot-store.js +10 -1
- package/dist/core/memory-engine/dual-root.js +2 -0
- package/dist/core/memory-engine/engine.d.ts +4 -0
- package/dist/core/memory-engine/engine.js +6 -1
- package/dist/core/runner/prepare-memory.d.ts +4 -0
- package/dist/core/runner/prepare-memory.js +4 -1
- package/dist/core/runner/prepare-task.d.ts +9 -2
- package/dist/core/runner/prepare-task.js +68 -13
- package/dist/core/runner/runtask.js +919 -865
- package/dist/core/runner/synthetic-tools.d.ts +1 -0
- package/dist/core/runner/synthetic-tools.js +18 -15
- package/dist/core/runner/turn-attachments.d.ts +27 -3
- package/dist/core/runner/turn-attachments.js +101 -12
- package/dist/core/task-registry-agent.d.ts +9 -1
- package/dist/core/task-registry-agent.js +23 -2
- package/dist/core/task-registry-monitor.js +79 -24
- package/dist/core/task-registry-shared.d.ts +13 -1
- package/dist/core/task-registry-shared.js +21 -0
- package/dist/core/task-registry.d.ts +2 -0
- package/dist/core/task-registry.js +24 -26
- package/dist/core/tool-result-budget.js +2 -2
- package/dist/core/tool-result-store.d.ts +2 -0
- package/dist/core/tool-result-store.js +27 -2
- package/dist/core/types.d.ts +4 -2
- package/dist/core/workflow-journal-store.d.ts +13 -0
- package/dist/engine/session/import-validate.js +29 -0
- package/dist/engine/session/memory-repo.js +5 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/orchestration/workflow-size-guideline.d.ts +6 -1
- package/dist/orchestration/workflow-size-guideline.js +19 -9
- package/dist/orchestration/workflow.d.ts +1 -0
- package/dist/orchestration/workflow.js +44 -1
- package/dist/prompt-assembly/assemble.js +3 -7
- package/dist/prompt-assembly/event-registry.js +1 -1
- package/dist/prompt-assembly/packs/sema-default.js +8 -5
- package/dist/prompts/coordinator.d.ts +1 -1
- package/dist/prompts/coordinator.js +45 -0
- package/dist/prompts/default.d.ts +4 -5
- package/dist/prompts/default.js +16 -18
- package/dist/prompts/simple-sections.d.ts +3 -1
- package/dist/prompts/simple-sections.js +11 -1
- package/dist/stores/cc/task-list-store.js +3 -3
- package/dist/stores/file/memory-store.d.ts +3 -0
- package/dist/stores/file/memory-store.js +39 -12
- package/dist/stores/file/tool-result-store.js +16 -2
- package/dist/stores/file/workflow-journal-store.d.ts +23 -0
- package/dist/stores/file/workflow-journal-store.js +140 -3
- package/dist/tools/fs/bash-readonly-classifier.js +21 -2
- package/dist/tools/fs/fs-bash.d.ts +1 -0
- package/dist/tools/fs/fs-bash.js +10 -3
- package/dist/tools/fs/fs-read.js +12 -12
- package/dist/tools/fs/fs-search-tools.js +42 -7
- package/dist/tools/fs/fs-write.js +18 -6
- package/dist/tools/fs/index.d.ts +1 -0
- package/dist/tools/fs/index.js +2 -1
- package/dist/tools/fs/safety.d.ts +4 -0
- package/dist/tools/fs/safety.js +113 -10
- package/dist/tools/fs/search.d.ts +1 -0
- package/dist/tools/fs/search.js +23 -3
- package/dist/tools/monitor.js +1 -1
- package/dist/tools/task-list.d.ts +1 -0
- package/dist/tools/task-list.js +13 -2
- package/dist/tools/web.js +36 -6
- package/package.json +3 -2
package/dist/tools/web.js
CHANGED
|
@@ -577,6 +577,13 @@ export function createWebFetchSummarizer(brain, model) {
|
|
|
577
577
|
const DEFAULT_SEARCH_TIMEOUT_MS = 30_000;
|
|
578
578
|
const SEARCH_ERROR_EXCERPT_CHARS = 2048;
|
|
579
579
|
const SEARCH_QUERY_MAX_CHARS = 2_000;
|
|
580
|
+
const DETAILS_QUERY_ECHO_MAX_CHARS = 500;
|
|
581
|
+
function clipQueryEcho(query) {
|
|
582
|
+
const cps = [...query];
|
|
583
|
+
return cps.length > DETAILS_QUERY_ECHO_MAX_CHARS
|
|
584
|
+
? cps.slice(0, DETAILS_QUERY_ECHO_MAX_CHARS).join("") + `…[${cps.length} chars total]`
|
|
585
|
+
: query;
|
|
586
|
+
}
|
|
580
587
|
function classifySearchFailure(message) {
|
|
581
588
|
const m = message.toLowerCase();
|
|
582
589
|
const status = /(?:\bhttp\b|\bstatus\b|\bcode\b|\berror\b)\D{0,12}?(\d{3})\b/.exec(m)?.[1];
|
|
@@ -619,6 +626,18 @@ function hostMatchesDomain(host, domain) {
|
|
|
619
626
|
return false;
|
|
620
627
|
return h === d || h.endsWith("." + d);
|
|
621
628
|
}
|
|
629
|
+
const URL_SCHEME_PREFIX = /^([a-z][a-z0-9+.-]*):/i;
|
|
630
|
+
function normalizeResultUrl(raw) {
|
|
631
|
+
const s = raw.trim();
|
|
632
|
+
if (!s)
|
|
633
|
+
return { url: raw, schemeAssumed: false };
|
|
634
|
+
if (s.startsWith("//"))
|
|
635
|
+
return { url: "https:" + s, schemeAssumed: true };
|
|
636
|
+
const scheme = URL_SCHEME_PREFIX.exec(s)?.[1];
|
|
637
|
+
if (scheme !== undefined && !scheme.includes("."))
|
|
638
|
+
return { url: s, schemeAssumed: false };
|
|
639
|
+
return { url: "https://" + s, schemeAssumed: true };
|
|
640
|
+
}
|
|
622
641
|
function webSearchResultAllowed(url, allowed, blocked) {
|
|
623
642
|
let host;
|
|
624
643
|
try {
|
|
@@ -662,7 +681,7 @@ export function createWebSearchTool(config) {
|
|
|
662
681
|
const startedAt = Date.now();
|
|
663
682
|
const failCard = (extra = {}) => ({
|
|
664
683
|
type: "web-search",
|
|
665
|
-
query,
|
|
684
|
+
query: clipQueryEcho(query),
|
|
666
685
|
results: [],
|
|
667
686
|
durationSeconds: (Date.now() - startedAt) / 1000,
|
|
668
687
|
searchCount: 0,
|
|
@@ -723,13 +742,18 @@ export function createWebSearchTool(config) {
|
|
|
723
742
|
clearTimeout(timer);
|
|
724
743
|
ctx.signal?.removeEventListener("abort", onOuterAbort);
|
|
725
744
|
}
|
|
726
|
-
const
|
|
727
|
-
|
|
745
|
+
const normalized = results.map((r) => {
|
|
746
|
+
const n = normalizeResultUrl(r.url);
|
|
747
|
+
return { ...r, url: n.url, schemeAssumed: n.schemeAssumed };
|
|
748
|
+
});
|
|
749
|
+
const usable = normalized.filter((r) => webSearchResultAllowed(r.url));
|
|
750
|
+
const droppedUnusable = normalized.length - usable.length;
|
|
728
751
|
const domainFiltered = usable.filter((r) => webSearchResultAllowed(r.url, allowed_domains, blocked_domains));
|
|
729
752
|
const droppedByDomain = usable.length - domainFiltered.length;
|
|
730
|
-
|
|
753
|
+
const kept = domainFiltered.slice(0, max);
|
|
754
|
+
const schemeAssumed = kept.filter((r) => r.schemeAssumed).length;
|
|
731
755
|
let clipped = false;
|
|
732
|
-
const shown =
|
|
756
|
+
const shown = kept.map((r) => {
|
|
733
757
|
const title = clipCodePoints(r.title, SEARCH_TITLE_MAX_CHARS);
|
|
734
758
|
const url = clipCodePoints(r.url, MAX_URL_LENGTH);
|
|
735
759
|
const snippet = clipCodePoints(r.snippet, SEARCH_SNIPPET_MAX_CHARS);
|
|
@@ -750,7 +774,13 @@ export function createWebSearchTool(config) {
|
|
|
750
774
|
const clipNote = clipped
|
|
751
775
|
? "\n\n[WebSearch: one or more result fields exceeded the display limits and were truncated — treat the text above as an excerpt, not the backend's full result.]"
|
|
752
776
|
: "";
|
|
753
|
-
const
|
|
777
|
+
const schemeNote = schemeAssumed > 0
|
|
778
|
+
? `\n\n[WebSearch: ${schemeAssumed} result(s) came back with no URL scheme (a bare domain or a protocol-relative URL) and are shown normalized to https:// — that scheme is this tool's assumption, not the backend's claim.]`
|
|
779
|
+
: "";
|
|
780
|
+
const tailReminder = shown.length > 0
|
|
781
|
+
? "REMINDER: You MUST include the sources above in your response to the user using markdown hyperlinks."
|
|
782
|
+
: "REMINDER: this search returned ZERO usable sources — there is nothing above to cite. Do not fabricate sources, URLs or citations; tell the user the search returned no usable results (the notes above say why, when there is a why) and answer from what you already know, or try a different query.";
|
|
783
|
+
const modelText = `${fenced}${dropNote}${domainNote}${schemeNote}${clipNote}\n\n${tailReminder}`;
|
|
754
784
|
return {
|
|
755
785
|
content: modelText,
|
|
756
786
|
details: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sema-agent/core",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Stateless, task-oriented AI agent core",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "BUSL-1.1",
|
|
@@ -56,7 +56,8 @@
|
|
|
56
56
|
"smoke": "tsx src/examples/smoke.ts",
|
|
57
57
|
"eval": "tsx eval/run.ts",
|
|
58
58
|
"prepare": "npm run build",
|
|
59
|
-
"prepublishOnly": "npm run build && npm run test"
|
|
59
|
+
"prepublishOnly": "npm run build && npm run test",
|
|
60
|
+
"gate:blackbox": "node scripts/run-blackbox-gate.mjs"
|
|
60
61
|
},
|
|
61
62
|
"dependencies": {
|
|
62
63
|
"@modelcontextprotocol/sdk": "1.29.0",
|