First running version
This commit is contained in:
109
reference_impl/agents/info-gathering/index.ts
Normal file
109
reference_impl/agents/info-gathering/index.ts
Normal file
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* 情報収集・分析 Agent
|
||||
*
|
||||
* accessiblePools: [info-pool]
|
||||
* 利用可能ツール: fetch_web_content (info-pool), call_external_api (info-pool),
|
||||
* query_crm (pool-less), query_erp (pool-less), query_hr (pool-less)
|
||||
*
|
||||
* タスク: 天気予報・在庫・顧客キャンセル傾向を収集し、分析サマリを返す
|
||||
*/
|
||||
import type { A2ATaskRequest, A2ATaskResponse } from '../platform-types.js';
|
||||
import { AgentBase } from '../agent-base.js';
|
||||
|
||||
export class InfoGatheringAgent extends AgentBase {
|
||||
readonly agentId = 'info-gathering-agent';
|
||||
readonly accessiblePools = ['info-pool'];
|
||||
|
||||
async handle(task: A2ATaskRequest): Promise<A2ATaskResponse> {
|
||||
const instruction = (task.payload.parameters['instruction'] as string | undefined) ?? '';
|
||||
const targetDate = new Date().toISOString().slice(0, 10);
|
||||
|
||||
try {
|
||||
// 1. Collect weather forecast
|
||||
const weather = await this.callTool('fetch_web_content', {
|
||||
source: 'weather_forecast',
|
||||
date: targetDate,
|
||||
});
|
||||
|
||||
// 2. Collect dessert inventory via external API
|
||||
const inventory = await this.callTool('call_external_api', {
|
||||
api: 'inventory',
|
||||
params: { item: 'dessert' },
|
||||
});
|
||||
|
||||
// 3. Query CRM for high-cancellation-tendency customers
|
||||
const customers = await this.callTool('query_crm', {
|
||||
entity: 'customers',
|
||||
filter: 'rain_cancel_tendency',
|
||||
});
|
||||
|
||||
// 4. Query reservations for tomorrow
|
||||
const reservations = await this.callTool('query_crm', {
|
||||
entity: 'reservations',
|
||||
filter: `date=${targetDate}`,
|
||||
});
|
||||
|
||||
// 5. Synthesize analysis
|
||||
const analysis = this.synthesize({ weather, inventory, customers, reservations, targetDate, instruction });
|
||||
|
||||
console.log(`[info-gathering] Analysis complete: ${analysis.summary}`);
|
||||
|
||||
return this.success(task, {
|
||||
analysis,
|
||||
rawData: { weather, inventory, customers, reservations },
|
||||
});
|
||||
} catch (err) {
|
||||
return this.error(task, (err as Error).message);
|
||||
}
|
||||
}
|
||||
|
||||
private synthesize(data: {
|
||||
weather: unknown;
|
||||
inventory: unknown;
|
||||
customers: unknown;
|
||||
reservations: unknown;
|
||||
targetDate: string;
|
||||
instruction: string;
|
||||
}): Record<string, unknown> {
|
||||
const wx = data.weather as { forecasts?: Array<{ condition?: string; summary?: string; precipitationProbability?: number }> };
|
||||
const forecast = wx?.forecasts?.[0];
|
||||
const isRainy = forecast?.condition === 'rainy';
|
||||
const precipProb = forecast?.precipitationProbability ?? 0;
|
||||
|
||||
const inv = data.inventory as { items?: Array<{ name?: string; stock?: number; category?: string }> };
|
||||
const desserts = (inv?.items ?? []).filter((i) => i.category === 'dessert');
|
||||
const hasDessertStock = desserts.some((d) => (d.stock ?? 0) > 0);
|
||||
|
||||
const cust = data.customers as { customers?: Array<unknown>; total?: number };
|
||||
const highCancelCount = cust?.total ?? (cust?.customers?.length ?? 0);
|
||||
|
||||
const res = data.reservations as { reservations?: Array<unknown>; total?: number };
|
||||
const reservationCount = res?.total ?? (res?.reservations?.length ?? 0);
|
||||
|
||||
const actionRecommended = isRainy && hasDessertStock && highCancelCount > 0;
|
||||
|
||||
return {
|
||||
targetDate: data.targetDate,
|
||||
weather: {
|
||||
condition: forecast?.condition ?? 'unknown',
|
||||
isRainy,
|
||||
precipitationProbability: precipProb,
|
||||
summary: forecast?.summary ?? '',
|
||||
},
|
||||
inventory: {
|
||||
hasDessertStock,
|
||||
dessertsAvailable: desserts.map((d) => ({ name: d.name, stock: d.stock })),
|
||||
},
|
||||
customers: {
|
||||
highCancelTendencyCount: highCancelCount,
|
||||
},
|
||||
reservations: {
|
||||
tomorrowCount: reservationCount,
|
||||
},
|
||||
actionRecommended,
|
||||
summary: actionRecommended
|
||||
? `明日は雨予報(${precipProb}%)で、デザート在庫あり、高キャンセル傾向顧客${highCancelCount}名・予約${reservationCount}件あり。無料デザートキャンペーンを推奨。`
|
||||
: `現時点でキャンペーン実施条件が揃っていません。`,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user