@kynver-app/mcp-agent-os 0.3.47 → 0.3.51
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/server.js +13 -0
- package/dist/tools/current-focus.d.ts +17 -0
- package/dist/tools/current-focus.js +126 -0
- package/dist/tools/kariad-marketing-loop.d.ts +21 -0
- package/dist/tools/kariad-marketing-loop.js +41 -0
- package/dist/tools/kariad-outcome-import.d.ts +17 -0
- package/dist/tools/kariad-outcome-import.js +37 -0
- package/dist/tools/macro-controls.d.ts +23 -0
- package/dist/tools/macro-controls.js +54 -0
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -27,6 +27,10 @@ import { registerSkillsTools } from "./tools/skills.js";
|
|
|
27
27
|
import { registerMemoryLedgerTools } from "./tools/memory-ledger.js";
|
|
28
28
|
import { registerMemoryVaultTools } from "./tools/memory-vault.js";
|
|
29
29
|
import { registerMonitorTools } from "./tools/monitor.js";
|
|
30
|
+
import { registerMacroControlsTools } from "./tools/macro-controls.js";
|
|
31
|
+
import { registerKariAdMarketingLoopTools } from "./tools/kariad-marketing-loop.js";
|
|
32
|
+
import { registerKariAdOutcomeImportTools } from "./tools/kariad-outcome-import.js";
|
|
33
|
+
import { registerCurrentFocusTools } from "./tools/current-focus.js";
|
|
30
34
|
import { readOwnPackageVersion } from "./lib/package-version.js";
|
|
31
35
|
const PACKAGE_VERSION = readOwnPackageVersion(import.meta.url);
|
|
32
36
|
function jsonResult(data) {
|
|
@@ -169,6 +173,7 @@ export function createAgentOsServer() {
|
|
|
169
173
|
memoryQuery: z.string().optional().describe("Override the memory search query. Defaults to a query derived from the anchor's title/summary."),
|
|
170
174
|
memoryLimit: z.number().optional().describe("Max memory hits (default 5, max 20). Set 0 to skip memory recall."),
|
|
171
175
|
sessionLimit: z.number().optional().describe("Max recent sessions (default 1, max 5). Set 0 to skip."),
|
|
176
|
+
resolveCurrentFocus: z.boolean().optional().describe("M2: when true and anchorType=session, resolve the most-recently-active non-terminal task as current focus. Read-only — never mutates task status. Use for agents (e.g. Hermes chat) that do not start from an explicit task anchor."),
|
|
172
177
|
surface: memorySurfaceField,
|
|
173
178
|
slug: slugField,
|
|
174
179
|
}, async (args) => {
|
|
@@ -182,6 +187,8 @@ export function createAgentOsServer() {
|
|
|
182
187
|
params.set("memoryLimit", String(args.memoryLimit));
|
|
183
188
|
if (args.sessionLimit !== undefined)
|
|
184
189
|
params.set("sessionLimit", String(args.sessionLimit));
|
|
190
|
+
if (args.resolveCurrentFocus)
|
|
191
|
+
params.set("resolveCurrentFocus", "true");
|
|
185
192
|
if (args.surface)
|
|
186
193
|
params.set("surface", args.surface);
|
|
187
194
|
return jsonResult(await get(`/agent-os/${s}/context-envelope?${params}`));
|
|
@@ -736,5 +743,11 @@ export function createAgentOsServer() {
|
|
|
736
743
|
registerMemoryLedgerTools({ register, resolveToolSlug, jsonResult });
|
|
737
744
|
registerMemoryVaultTools({ register, resolveToolSlug, jsonResult });
|
|
738
745
|
registerMonitorTools({ register, resolveToolSlug, jsonResult });
|
|
746
|
+
registerMacroControlsTools({ register, resolveToolSlug, jsonResult });
|
|
747
|
+
registerKariAdMarketingLoopTools({ register, resolveToolSlug, jsonResult });
|
|
748
|
+
// KariAd marketing loop — M6 outcome import (analytics feedback + memory learning).
|
|
749
|
+
registerKariAdOutcomeImportTools({ register, resolveToolSlug, jsonResult });
|
|
750
|
+
// M5: Kynver current-focus / todo adapter (agent-loop focus ≠ executor lease).
|
|
751
|
+
registerCurrentFocusTools({ register, resolveToolSlug, jsonResult, compact });
|
|
739
752
|
return server;
|
|
740
753
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kynver current-focus / todo-projection MCP tools (M5).
|
|
3
|
+
*
|
|
4
|
+
* kynver.focus.get → agent_os_focus_get
|
|
5
|
+
* kynver.focus.set → agent_os_focus_set
|
|
6
|
+
* kynver.focus.clear → agent_os_focus_clear
|
|
7
|
+
* kynver.todo.project → agent_os_todo_project
|
|
8
|
+
*
|
|
9
|
+
* CRITICAL INVARIANT:
|
|
10
|
+
* `in_progress` on a plan row = agent-loop current focus (set by these tools).
|
|
11
|
+
* `running` on a task = executor worker lease/heartbeat (never set here).
|
|
12
|
+
*
|
|
13
|
+
* Hermes `in_progress` maps ONLY to plan row `in_progress`. These tools never
|
|
14
|
+
* touch AgentTask.status — that is the dispatcher/executor's domain.
|
|
15
|
+
*/
|
|
16
|
+
import type { PlanToolDeps } from "./plans.js";
|
|
17
|
+
export declare function registerCurrentFocusTools({ register, resolveToolSlug, jsonResult, compact, }: PlanToolDeps): void;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kynver current-focus / todo-projection MCP tools (M5).
|
|
3
|
+
*
|
|
4
|
+
* kynver.focus.get → agent_os_focus_get
|
|
5
|
+
* kynver.focus.set → agent_os_focus_set
|
|
6
|
+
* kynver.focus.clear → agent_os_focus_clear
|
|
7
|
+
* kynver.todo.project → agent_os_todo_project
|
|
8
|
+
*
|
|
9
|
+
* CRITICAL INVARIANT:
|
|
10
|
+
* `in_progress` on a plan row = agent-loop current focus (set by these tools).
|
|
11
|
+
* `running` on a task = executor worker lease/heartbeat (never set here).
|
|
12
|
+
*
|
|
13
|
+
* Hermes `in_progress` maps ONLY to plan row `in_progress`. These tools never
|
|
14
|
+
* touch AgentTask.status — that is the dispatcher/executor's domain.
|
|
15
|
+
*/
|
|
16
|
+
import { z } from "zod";
|
|
17
|
+
import { get, post } from "../lib/kynver-client.js";
|
|
18
|
+
export function registerCurrentFocusTools({ register, resolveToolSlug, jsonResult, compact, }) {
|
|
19
|
+
const slugField = z
|
|
20
|
+
.string()
|
|
21
|
+
.optional()
|
|
22
|
+
.describe("AgentOS workspace slug. Omit to use env or the server-discovered primary.");
|
|
23
|
+
const roleLane = z
|
|
24
|
+
.enum([
|
|
25
|
+
"plan_author",
|
|
26
|
+
"plan_reviewer",
|
|
27
|
+
"implementer",
|
|
28
|
+
"report_reviewer",
|
|
29
|
+
"deep_reviewer",
|
|
30
|
+
"repair_implementer",
|
|
31
|
+
"runtime_verifier",
|
|
32
|
+
"user",
|
|
33
|
+
"system",
|
|
34
|
+
])
|
|
35
|
+
.optional()
|
|
36
|
+
.default("implementer")
|
|
37
|
+
.describe("Role lane making this focus change. Defaults to implementer.");
|
|
38
|
+
register("agent_os_focus_get", [
|
|
39
|
+
"Get the current agent-loop focus and active executor leases for this AgentOS workspace.",
|
|
40
|
+
"Returns two separate buckets:",
|
|
41
|
+
" agentLoopFocus — plan rows currently marked `in_progress` (agent/Hermes focus, NOT executor state).",
|
|
42
|
+
" executorLeases — tasks with status `running` and an active worker lease.",
|
|
43
|
+
"Never conflate the two: in_progress = current-focus intent; running = live executor heartbeat.",
|
|
44
|
+
"Pass todos=true to also receive a projected Hermes-like todo list.",
|
|
45
|
+
].join(" "), {
|
|
46
|
+
todos: z
|
|
47
|
+
.boolean()
|
|
48
|
+
.optional()
|
|
49
|
+
.describe("When true, also return a projected todo list of actionable tasks and in-progress rows."),
|
|
50
|
+
planId: z
|
|
51
|
+
.string()
|
|
52
|
+
.optional()
|
|
53
|
+
.describe("Scope the todo projection to a single plan. Has no effect unless todos=true."),
|
|
54
|
+
slug: slugField,
|
|
55
|
+
}, async (args) => {
|
|
56
|
+
const s = await resolveToolSlug(args.slug);
|
|
57
|
+
const params = new URLSearchParams();
|
|
58
|
+
if (args.todos)
|
|
59
|
+
params.set("todos", "true");
|
|
60
|
+
if (args.planId)
|
|
61
|
+
params.set("planId", args.planId);
|
|
62
|
+
const qs = params.toString();
|
|
63
|
+
return jsonResult(await get(`/agent-os/${s}/current-focus${qs ? `?${qs}` : ""}`));
|
|
64
|
+
});
|
|
65
|
+
register("agent_os_focus_set", [
|
|
66
|
+
"Set the agent-loop current focus to a specific plan progress row.",
|
|
67
|
+
"This marks the row as `in_progress` and updates AgentPlan.inProgressRowKey.",
|
|
68
|
+
"IMPORTANT: This does NOT set the task status to `running` — that is the executor lease.",
|
|
69
|
+
"Hermes `in_progress` semantics: focus intent, not worker heartbeat.",
|
|
70
|
+
"Any previously focused row on the same plan is demoted back to `todo`.",
|
|
71
|
+
"Precondition: the plan must have focus enabled (progressFocusEnabled not set to false in plan metadata).",
|
|
72
|
+
"When focus is disabled, returns applied:false with a reason — not an error, but the change was not applied.",
|
|
73
|
+
].join(" "), {
|
|
74
|
+
planId: z.string().describe("The plan that owns the row to focus."),
|
|
75
|
+
rowKey: z.string().optional().describe("Progress row key to focus. One of rowKey or rowId is required."),
|
|
76
|
+
rowId: z.string().optional().describe("Progress row DB id to focus. One of rowKey or rowId is required."),
|
|
77
|
+
taskId: z.string().optional().describe("Associate a task with this focus event (metadata only — does not change task status)."),
|
|
78
|
+
roleLane,
|
|
79
|
+
note: z.string().optional().describe("Optional note recorded on the focus event."),
|
|
80
|
+
slug: slugField,
|
|
81
|
+
}, async (args) => {
|
|
82
|
+
const s = await resolveToolSlug(args.slug);
|
|
83
|
+
const { slug, ...rest } = args;
|
|
84
|
+
return jsonResult(await post(`/agent-os/${s}/current-focus`, compact(rest)));
|
|
85
|
+
});
|
|
86
|
+
register("agent_os_focus_clear", [
|
|
87
|
+
"Clear the agent-loop current focus for a plan, moving the focused row back to `todo`.",
|
|
88
|
+
"Use when the session is done with a row but not marking it complete.",
|
|
89
|
+
"Does NOT cancel or abort the associated task — task lifecycle is separate.",
|
|
90
|
+
].join(" "), {
|
|
91
|
+
planId: z.string().describe("The plan whose current focus should be cleared."),
|
|
92
|
+
roleLane,
|
|
93
|
+
note: z.string().optional().describe("Optional note recorded on the clear event."),
|
|
94
|
+
slug: slugField,
|
|
95
|
+
}, async (args) => {
|
|
96
|
+
const s = await resolveToolSlug(args.slug);
|
|
97
|
+
const { slug, ...rest } = args;
|
|
98
|
+
// POST with clear=true — the route distinguishes set vs clear by presence
|
|
99
|
+
// of rowKey/rowId. No rowKey/rowId + clear=true = explicit clear.
|
|
100
|
+
return jsonResult(await post(`/agent-os/${s}/current-focus`, compact({ ...rest, clear: true })));
|
|
101
|
+
});
|
|
102
|
+
register("agent_os_todo_project", [
|
|
103
|
+
"Project the current AgentOS task board and plan progress rows into a Hermes-like todo list.",
|
|
104
|
+
"Returns KynverTodoItem entries with origin discriminants:",
|
|
105
|
+
" plan_row — an in_progress plan progress row (agent-loop focus).",
|
|
106
|
+
" task_ready — a task ready for dispatch.",
|
|
107
|
+
" task_blocked — a task blocked on external input.",
|
|
108
|
+
" task_needs_input — a task waiting on human decision.",
|
|
109
|
+
"Includes stale detection: items not updated within 48h are flagged stale=true.",
|
|
110
|
+
"Use this as the authoritative 'what is next' readback for Kynver sessions,",
|
|
111
|
+
"replacing stale Hermes-local todos with live board state.",
|
|
112
|
+
].join(" "), {
|
|
113
|
+
planId: z.string().optional().describe("Scope to a single plan. Omit for workspace-wide projection."),
|
|
114
|
+
limit: z.number().int().min(1).max(100).optional().describe("Max todo items (default 50, max 100)."),
|
|
115
|
+
slug: slugField,
|
|
116
|
+
}, async (args) => {
|
|
117
|
+
const s = await resolveToolSlug(args.slug);
|
|
118
|
+
const params = new URLSearchParams();
|
|
119
|
+
params.set("todos", "true");
|
|
120
|
+
if (args.planId)
|
|
121
|
+
params.set("planId", args.planId);
|
|
122
|
+
const qs = params.toString();
|
|
123
|
+
const result = await get(`/agent-os/${s}/current-focus?${qs}`);
|
|
124
|
+
return jsonResult(result.todoProjection ?? result);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KariAd campaign brief MCP tool (M4).
|
|
3
|
+
*
|
|
4
|
+
* agent_os_kariad_campaign_brief_create — fuse macro trends, Kynver goals,
|
|
5
|
+
* and KariAd deep memory into a cited RuntimeCampaignBrief.
|
|
6
|
+
* Does not publish or spend.
|
|
7
|
+
*/
|
|
8
|
+
type ToolResult = {
|
|
9
|
+
content: {
|
|
10
|
+
type: "text";
|
|
11
|
+
text: string;
|
|
12
|
+
}[];
|
|
13
|
+
structuredContent?: unknown;
|
|
14
|
+
};
|
|
15
|
+
export interface KariAdMarketingLoopToolDeps {
|
|
16
|
+
register: (name: string, description: string, inputSchema: Record<string, unknown>, cb: (args: any) => any) => void;
|
|
17
|
+
resolveToolSlug: (explicitSlug?: string) => Promise<string>;
|
|
18
|
+
jsonResult: (data: unknown) => ToolResult;
|
|
19
|
+
}
|
|
20
|
+
export declare function registerKariAdMarketingLoopTools({ register, resolveToolSlug, jsonResult, }: KariAdMarketingLoopToolDeps): void;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KariAd campaign brief MCP tool (M4).
|
|
3
|
+
*
|
|
4
|
+
* agent_os_kariad_campaign_brief_create — fuse macro trends, Kynver goals,
|
|
5
|
+
* and KariAd deep memory into a cited RuntimeCampaignBrief.
|
|
6
|
+
* Does not publish or spend.
|
|
7
|
+
*/
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
import { post } from "../lib/kynver-client.js";
|
|
10
|
+
const slugField = z
|
|
11
|
+
.string()
|
|
12
|
+
.optional()
|
|
13
|
+
.describe("AgentOS slug. Defaults to env/primary AgentOS.");
|
|
14
|
+
export function registerKariAdMarketingLoopTools({ register, resolveToolSlug, jsonResult, }) {
|
|
15
|
+
register("agent_os_kariad_campaign_brief_create", [
|
|
16
|
+
"Create a compact, cited RuntimeCampaignBrief by combining on-demand macro/social trend signals,",
|
|
17
|
+
"Kynver marketplace/runtime goals, and KariAd deep brand memory.",
|
|
18
|
+
"Returns content angles with source links, target audiences, selected brand/workspace, risk labels,",
|
|
19
|
+
"and recommended next KariAd actions.",
|
|
20
|
+
"Does NOT publish, schedule, or spend — approval is always required before KariAd execution tools (M5).",
|
|
21
|
+
"Call agent_os_macro_controls_get first when trend awareness matters for the marketing task.",
|
|
22
|
+
].join(" "), {
|
|
23
|
+
slug: slugField,
|
|
24
|
+
workspaceId: z.string().describe("KariAd workspace id (from kari_whoami / connection preflight)."),
|
|
25
|
+
brandId: z.string().describe("KariAd brand id for voice, audience, and calendar context."),
|
|
26
|
+
brandName: z.string().optional().describe("Optional display name when brand id is known."),
|
|
27
|
+
goalStatement: z
|
|
28
|
+
.string()
|
|
29
|
+
.optional()
|
|
30
|
+
.describe("Campaign goal override. When omitted, inferred from active Kynver goals/projects."),
|
|
31
|
+
}, async (args) => {
|
|
32
|
+
const s = await resolveToolSlug(args.slug);
|
|
33
|
+
const payload = await post(`/agent-os/${encodeURIComponent(s)}/kariad-marketing-loop/briefs`, {
|
|
34
|
+
workspaceId: args.workspaceId,
|
|
35
|
+
brandId: args.brandId,
|
|
36
|
+
...(args.brandName ? { brandName: args.brandName } : {}),
|
|
37
|
+
...(args.goalStatement ? { goalStatement: args.goalStatement } : {}),
|
|
38
|
+
});
|
|
39
|
+
return jsonResult(payload);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* M6 outcome import MCP tool — agent_os_kariad_outcome_import
|
|
3
|
+
*/
|
|
4
|
+
type ToolResult = {
|
|
5
|
+
content: {
|
|
6
|
+
type: "text";
|
|
7
|
+
text: string;
|
|
8
|
+
}[];
|
|
9
|
+
structuredContent?: unknown;
|
|
10
|
+
};
|
|
11
|
+
export interface KariAdOutcomeImportToolDeps {
|
|
12
|
+
register: (name: string, description: string, inputSchema: Record<string, unknown>, cb: (args: any) => any) => void;
|
|
13
|
+
resolveToolSlug: (explicitSlug?: string) => Promise<string>;
|
|
14
|
+
jsonResult: (data: unknown) => ToolResult;
|
|
15
|
+
}
|
|
16
|
+
export declare function registerKariAdOutcomeImportTools({ register, resolveToolSlug, jsonResult, }: KariAdOutcomeImportToolDeps): void;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* M6 outcome import MCP tool — agent_os_kariad_outcome_import
|
|
3
|
+
*/
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { post } from "../lib/kynver-client.js";
|
|
6
|
+
const slugField = z
|
|
7
|
+
.string()
|
|
8
|
+
.optional()
|
|
9
|
+
.describe("AgentOS slug. Defaults to env/primary AgentOS.");
|
|
10
|
+
export function registerKariAdOutcomeImportTools({ register, resolveToolSlug, jsonResult, }) {
|
|
11
|
+
register("agent_os_kariad_outcome_import", [
|
|
12
|
+
"Import KariAd campaign outcome summaries and produce separate KariAd vs Kynver memory proposals",
|
|
13
|
+
"with correct ownership, provider-quality metrics, and duplicate suppression.",
|
|
14
|
+
"Set writeback=true to route cleared proposals to KariAd submit_memory_proposal and Kynver MARM.",
|
|
15
|
+
"Requires planId + briefId from the marketing loop execution window.",
|
|
16
|
+
].join(" "), {
|
|
17
|
+
slug: slugField,
|
|
18
|
+
workspaceId: z.string().describe("KariAd workspace id."),
|
|
19
|
+
brandId: z.string().describe("KariAd brand id."),
|
|
20
|
+
planId: z.string().describe("KariAd execution plan id for attribution."),
|
|
21
|
+
briefId: z.string().describe("Runtime campaign brief id for attribution."),
|
|
22
|
+
writeback: z
|
|
23
|
+
.boolean()
|
|
24
|
+
.optional()
|
|
25
|
+
.describe("When true, persist proposals to KariAd/Kynver. Default dry-run."),
|
|
26
|
+
}, async (args) => {
|
|
27
|
+
const s = await resolveToolSlug(args.slug);
|
|
28
|
+
const payload = await post(`/agent-os/${encodeURIComponent(s)}/kariad-marketing-loop/outcomes/import`, {
|
|
29
|
+
workspaceId: args.workspaceId,
|
|
30
|
+
brandId: args.brandId,
|
|
31
|
+
planId: args.planId,
|
|
32
|
+
briefId: args.briefId,
|
|
33
|
+
writeback: args.writeback === true,
|
|
34
|
+
});
|
|
35
|
+
return jsonResult(payload);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Macro/social trend on-demand catch-up MCP tool.
|
|
3
|
+
*
|
|
4
|
+
* Runtime agents call agent_os_macro_controls_get before producing social media
|
|
5
|
+
* posts, ad copy, campaign briefs, launch announcements, or any trend-sensitive
|
|
6
|
+
* marketing content so they can adapt angle and tone to current signals.
|
|
7
|
+
*
|
|
8
|
+
* Read-only. Backed by GET /api/agent-os/{slug}/macro-controls.
|
|
9
|
+
*/
|
|
10
|
+
type ToolResult = {
|
|
11
|
+
content: {
|
|
12
|
+
type: "text";
|
|
13
|
+
text: string;
|
|
14
|
+
}[];
|
|
15
|
+
structuredContent?: unknown;
|
|
16
|
+
};
|
|
17
|
+
export interface MacroControlsToolDeps {
|
|
18
|
+
register: (name: string, description: string, inputSchema: Record<string, unknown>, cb: (args: any) => any) => void;
|
|
19
|
+
resolveToolSlug: (explicitSlug?: string) => Promise<string>;
|
|
20
|
+
jsonResult: (data: unknown) => ToolResult;
|
|
21
|
+
}
|
|
22
|
+
export declare function registerMacroControlsTools({ register, resolveToolSlug, jsonResult, }: MacroControlsToolDeps): void;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Macro/social trend on-demand catch-up MCP tool.
|
|
3
|
+
*
|
|
4
|
+
* Runtime agents call agent_os_macro_controls_get before producing social media
|
|
5
|
+
* posts, ad copy, campaign briefs, launch announcements, or any trend-sensitive
|
|
6
|
+
* marketing content so they can adapt angle and tone to current signals.
|
|
7
|
+
*
|
|
8
|
+
* Read-only. Backed by GET /api/agent-os/{slug}/macro-controls.
|
|
9
|
+
*/
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
import { get } from "../lib/kynver-client.js";
|
|
12
|
+
const slugField = z
|
|
13
|
+
.string()
|
|
14
|
+
.optional()
|
|
15
|
+
.describe("AgentOS slug. Defaults to env/primary AgentOS.");
|
|
16
|
+
export function registerMacroControlsTools({ register, resolveToolSlug, jsonResult, }) {
|
|
17
|
+
register("agent_os_macro_controls_get", [
|
|
18
|
+
"Fetch the current macro/social trend snapshot so you can adapt marketing content to active signals.",
|
|
19
|
+
"",
|
|
20
|
+
"WHEN TO CALL: before generating social media posts, ad copy, campaign briefs, launch announcements,",
|
|
21
|
+
"trend-reactive content, or any marketing material where current events could affect brand perception.",
|
|
22
|
+
"This is an on-demand catch-up step — call it at the START of social/content/marketing work, not on",
|
|
23
|
+
"every message.",
|
|
24
|
+
"",
|
|
25
|
+
"WHAT YOU GET: a compact MacroControlSnapshot with active MacroTrendSignals (topic, sensitivity,",
|
|
26
|
+
"summary, confidence, sourceLinks), a globalSensitivity aggregate ('safe'|'cautious'|'sensitive'|'blocked'),",
|
|
27
|
+
"isStale flag, and agentGuidance text you should incorporate into your content plan.",
|
|
28
|
+
"",
|
|
29
|
+
"GATING RULES:",
|
|
30
|
+
"- globalSensitivity='blocked': do NOT publish related content — surface the blocked topics to the",
|
|
31
|
+
" operator and wait for explicit approval before proceeding.",
|
|
32
|
+
"- globalSensitivity='sensitive': draft with extra care, avoid direct references to flagged topics,",
|
|
33
|
+
" prefer evergreen angles, and flag for human review before posting.",
|
|
34
|
+
"- globalSensitivity='cautious': note flagged topics in your plan; adjust tone but may proceed.",
|
|
35
|
+
"- globalSensitivity='safe' or isStale=true with no signals: proceed with standard brand voice.",
|
|
36
|
+
"",
|
|
37
|
+
"If isStale=true AND signals are present, treat the data as advisory only and note staleness in your",
|
|
38
|
+
"output so the operator knows to refresh. Read-only; safe for unattended invocation.",
|
|
39
|
+
].join("\n"), {
|
|
40
|
+
slug: slugField,
|
|
41
|
+
includeSensitiveSignals: z
|
|
42
|
+
.boolean()
|
|
43
|
+
.optional()
|
|
44
|
+
.describe("When true, include 'sensitive' and 'blocked' signals in full detail. " +
|
|
45
|
+
"Default true — omit only when generating a safe-for-display summary."),
|
|
46
|
+
}, async ({ slug, includeSensitiveSignals = true, }) => {
|
|
47
|
+
const s = await resolveToolSlug(slug);
|
|
48
|
+
const snapshot = await get(`/agent-os/${encodeURIComponent(s)}/macro-controls`);
|
|
49
|
+
if (!includeSensitiveSignals && Array.isArray(snapshot.signals)) {
|
|
50
|
+
snapshot.signals = snapshot.signals.filter((sig) => sig.sensitivity === "safe" || sig.sensitivity === "cautious");
|
|
51
|
+
}
|
|
52
|
+
return jsonResult(snapshot);
|
|
53
|
+
});
|
|
54
|
+
}
|
package/package.json
CHANGED