Files
krowworkforce_controltower/base44/functions/reviewOutcomes/entry.ts
2026-08-17 19:45:29 +05:30

104 lines
3.7 KiB
TypeScript

import { createClientFromRequest } from 'npm:@base44/sdk@0.8.31';
Deno.serve(async (req) => {
try {
const base44 = createClientFromRequest(req);
const user = await base44.auth.me();
if (!user) return Response.json({ error: 'Unauthorized' }, { status: 401 });
if (user.role !== 'admin') return Response.json({ error: 'Forbidden — admin only' }, { status: 403 });
const entities = base44.asServiceRole.entities;
// Fetch memories with pending outcomes (executed but not yet learned)
const pendingMemories = await entities.OperationalMemory.filter(
{ status: 'outcome_pending' },
'-created_date',
50
);
let learned = 0;
let stillPending = 0;
for (const memory of pendingMemories) {
try {
// Re-query the graph to see what happened since the decision was made
const graphRes = await base44.asServiceRole.functions.invoke('queryWorkforceGraph', {
query_type: 'subgraph',
entity_type: memory.context_snapshot?.metadata?.subject_entity_type || 'Order',
entity_id: memory.context_snapshot?.metadata?.subject_entity_id || memory.trigger_event_id
});
const currentGraph = graphRes.data?.graph || {};
// Ask the LLM to evaluate the outcome
const prompt = `You are evaluating the outcome of a past KROW AI decision.
ORIGINAL EVENT: ${memory.trigger_event_type}
ORIGINAL DECISION: ${memory.decision?.recommendation || 'N/A'}
ORIGINAL PREDICTION: ${memory.decision?.prediction || 'N/A'}
CURRENT STATE (after decision):
${JSON.stringify(currentGraph, null, 2).substring(0, 2000)}
ORIGINAL CONTEXT (at decision time):
${JSON.stringify(memory.context_snapshot?.graph || {}, null, 2).substring(0, 2000)}
Evaluate: Did the decision help? Did the prediction come true? What was the outcome?
Respond as JSON:
{
"outcome": "Description of what actually happened",
"outcome_score": -100 to 100 (negative = made things worse, 0 = no effect, positive = helped),
"outcome_metrics": {"key_metric": value}
}`;
const evalResponse = await base44.asServiceRole.integrations.Core.InvokeLLM({
prompt,
response_json_schema: {
type: 'object',
properties: {
outcome: { type: 'string' },
outcome_score: { type: 'number' },
outcome_metrics: { type: 'object', additionalProperties: true }
}
}
});
const evaluation = typeof evalResponse === 'string' ? JSON.parse(evalResponse) : evalResponse;
await entities.OperationalMemory.update(memory.id, {
outcome: evaluation.outcome,
outcome_score: evaluation.outcome_score,
outcome_metrics: evaluation.outcome_metrics,
status: 'learned',
learned_at: new Date().toISOString()
});
// Log learning activity
await entities.AgentActivity.create({
agent_name: memory.agent_name || 'system',
department: memory.department || 'operations',
activity_type: 'learning_completed',
memory_id: memory.id,
summary: `Learned from ${memory.trigger_event_type}: outcome score ${evaluation.outcome_score}`,
details: evaluation,
impact_level: evaluation.outcome_score > 50 ? 'high' : (evaluation.outcome_score > 0 ? 'medium' : 'low'),
entities_affected: []
});
learned++;
} catch (e) {
console.log(`Failed to evaluate memory ${memory.id}:`, e.message);
stillPending++;
}
}
return Response.json({
success: true,
reviewed: pendingMemories.length,
learned,
still_pending: stillPending
});
} catch (error) {
return Response.json({ error: error.message }, { status: 500 });
}
});