openpondai/agents/my-openpond
OpenTool app
typescript
import type { ToolProfile } from "opentool";
import { store } from "opentool/store";
import {
buildDigestBriefing,
extractImportantDatesSection,
extractNewsSection,
extractStrategies,
fetchDigestHistory,
formatDigest,
type JsonValue,
type DailySummarySubAgentResult,
} from "../src/daily-summary";
import {
type DailySummaryConfig,
MY_OPENPOND_TEMPLATE_CONFIG,
readConfig,
resolveConnectedApps,
resolveScheduleConfig,
} from "../src/config";
import {
openpondRequest,
unwrapOpenpondExecuteResponse,
} from "../src/openpond";
const scheduleConfig = resolveScheduleConfig();
export const profile: ToolProfile = {
description: "Daily OpenPond summary (performance + add-on tools).",
category: "orchestrator",
schedule: {
cron: scheduleConfig.cron,
enabled: scheduleConfig.enabled,
notifyEmail: scheduleConfig.notifyEmail,
},
connectedApps: resolveConnectedApps(),
templateConfig: MY_OPENPOND_TEMPLATE_CONFIG,
};
type DailySummaryResponse = JsonValue;
type ConfiguredSubAgent = NonNullable<DailySummaryConfig["subAgents"]>[number];
const DAILY_SUMMARY_ENABLED_SUBAGENT_TOOL_NAMES = new Set<string>([
"news-intelligence-roundup",
"important-dates-roundup",
]);
const SUBAGENT_EXECUTION_TIMEOUT_MS = 30_000;
function buildDailySummaryImportantDatesBody() {
return {
title: "Important Upcoming Dates",
daysAhead: 14,
limit: 3,
category: "macro",
series: ["CPI", "Core PCE", "PCE", "Jobs Report", "FOMC", "GDP", "Retail Sales"],
summaryMaxEvents: 3,
};
}
function isMissing(response: Awaited<ReturnType<typeof openpondRequest>>) {
const data = response.data;
if (response.status === 404) return true;
if (!data || typeof data !== "object") return false;
return (data as Record<string, unknown>).error === "Not Found";
}
function buildPersistedMetadata(params: {
runAt: string;
briefing: Awaited<ReturnType<typeof buildDigestBriefing>>["briefing"];
strategies: ReturnType<typeof extractStrategies>;
strategyChanges: Awaited<ReturnType<typeof buildDigestBriefing>>["strategyChanges"];
news: ReturnType<typeof extractNewsSection>;
importantDates: ReturnType<typeof extractImportantDatesSection>;
}) {
return {
runAt: params.runAt,
briefing: params.briefing,
strategies: params.strategies,
strategyChanges: params.strategyChanges,
news: params.news,
importantDates: params.importantDates,
};
}
function normalizeToolKey(value: string) {
return value.trim().toLowerCase();
}
function resolveSubAgentMethod(agent: ConfiguredSubAgent) {
return agent.method ?? "POST";
}
function resolveSubAgentBody(agent: ConfiguredSubAgent, method: "GET" | "POST") {
if (method !== "POST") {
return undefined;
}
const toolKey = normalizeToolKey(agent.toolName);
if (toolKey === "important-dates-roundup") {
return buildDailySummaryImportantDatesBody();
}
return agent.body;
}
function normalizeConfiguredSubAgents(config: DailySummaryConfig) {
const subAgents = Array.isArray(config.subAgents) ? config.subAgents : [];
const seenToolNames = new Set<string>();
return subAgents.filter((agent) => {
const toolKey = normalizeToolKey(agent.toolName);
if (
!toolKey ||
seenToolNames.has(toolKey) ||
!DAILY_SUMMARY_ENABLED_SUBAGENT_TOOL_NAMES.has(toolKey)
) {
return false;
}
seenToolNames.add(toolKey);
return true;
});
}
export async function GET(_req: Request) {
const runAt = new Date().toISOString();
const config = await readConfig();
const configuredSubAgents = normalizeConfiguredSubAgents(config);
const performanceResponse = await openpondRequest("/apps/performance", {
method: "GET",
});
const performance = isMissing(performanceResponse)
? null
: (performanceResponse.data as JsonValue | null);
const subAgentResults = configuredSubAgents.length
? await Promise.all(
configuredSubAgents.map(async (agent) => {
const method = resolveSubAgentMethod(agent);
const body = resolveSubAgentBody(agent, method);
const executeForTarget = async (params: {
appId: string;
deploymentId: string;
}) => {
const controller = new AbortController();
const timeout = setTimeout(
() => controller.abort("daily-summary-subagent-timeout"),
SUBAGENT_EXECUTION_TIMEOUT_MS,
);
const requestBody =
method === "POST" || body !== undefined
? {
appId: params.appId,
deploymentId: params.deploymentId,
toolName: agent.toolName,
method,
...(body !== undefined ? { body } : {}),
}
: {
appId: params.appId,
deploymentId: params.deploymentId,
toolName: agent.toolName,
method,
};
try {
return await openpondRequest("/apps/tools/execute", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(requestBody),
signal: controller.signal,
});
} finally {
clearTimeout(timeout);
}
};
const configuredTarget =
agent.appId.trim() && agent.deploymentId.trim()
? {
appId: agent.appId,
deploymentId: agent.deploymentId,
}
: null;
let executedResponse:
| ReturnType<typeof unwrapOpenpondExecuteResponse>
| null = null;
let response = null as Awaited<ReturnType<typeof openpondRequest>> | null;
if (configuredTarget) {
try {
response = await executeForTarget(configuredTarget);
executedResponse = unwrapOpenpondExecuteResponse(response);
} catch {
response = null;
executedResponse = null;
}
}
if (!configuredTarget) {
return {
name: agent.displayName ?? agent.toolName,
ok: false,
data: { error: "configured_target_missing" },
missing: true,
} satisfies DailySummarySubAgentResult;
}
return {
name: agent.displayName ?? agent.toolName,
ok: executedResponse?.ok ?? false,
data: (executedResponse?.data as DailySummaryResponse | null) ?? null,
missing: response ? isMissing(response) : false,
} satisfies DailySummarySubAgentResult;
}),
)
: [];
const historyItems = await fetchDigestHistory(config.historyLimit ?? 3);
const strategies = extractStrategies(performance);
const news = extractNewsSection(subAgentResults);
const importantDates = extractImportantDatesSection(subAgentResults);
const { briefing, strategyChanges } = await buildDigestBriefing({
runAt,
config,
performance,
currentStrategies: strategies,
subAgentResults,
news,
importantDates,
historyItems,
});
const content = formatDigest({
runAt,
briefing,
performance,
strategies,
strategyChanges,
subAgentResults,
news,
importantDates,
});
const persistedMetadata = buildPersistedMetadata({
runAt,
briefing,
strategies,
strategyChanges,
news,
importantDates,
});
const conversationPersistResponse = await openpondRequest(
"/apps/agent/conversation-message",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
content,
runAt,
metadata: persistedMetadata,
}),
}
);
if (!conversationPersistResponse.ok) {
throw new Error(
`Daily summary conversation persist failed (${conversationPersistResponse.status})`
);
}
await store({
source: "daily-summary",
ref: `daily-summary-${runAt}`,
status: "info",
action: "digest",
metadata: {
content,
...persistedMetadata,
},
});
return Response.json({
ok: true,
runAt,
briefing,
content,
performance,
strategies,
strategyChanges,
news,
importantDates,
subAgents: subAgentResults,
});
}