@t4h/agent-runtime 0.0.0-stage → 0.1.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/README.md +23 -2
- package/bin/t4h-agent.mjs +2 -0
- package/dist/brain.d.ts +48 -0
- package/dist/brain.js +99 -0
- package/dist/brain.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +27 -0
- package/dist/cli.js.map +1 -0
- package/dist/evals.d.ts +38 -0
- package/dist/evals.js +95 -0
- package/dist/evals.js.map +1 -0
- package/dist/gateway.d.ts +61 -0
- package/dist/gateway.js +93 -0
- package/dist/gateway.js.map +1 -0
- package/dist/host.d.ts +76 -0
- package/dist/host.js +267 -0
- package/dist/host.js.map +1 -0
- package/dist/inbox.d.ts +23 -0
- package/dist/inbox.js +29 -0
- package/dist/inbox.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/levels.d.ts +48 -0
- package/dist/levels.js +73 -0
- package/dist/levels.js.map +1 -0
- package/dist/manifest.d.ts +111 -0
- package/dist/manifest.js +172 -0
- package/dist/manifest.js.map +1 -0
- package/dist/notifier.d.ts +26 -0
- package/dist/notifier.js +13 -0
- package/dist/notifier.js.map +1 -0
- package/dist/plugins.d.ts +8 -0
- package/dist/plugins.js +73 -0
- package/dist/plugins.js.map +1 -0
- package/dist/policy.d.ts +71 -0
- package/dist/policy.js +210 -0
- package/dist/policy.js.map +1 -0
- package/dist/prompt.d.ts +24 -0
- package/dist/prompt.js +84 -0
- package/dist/prompt.js.map +1 -0
- package/dist/round.d.ts +34 -0
- package/dist/round.js +108 -0
- package/dist/round.js.map +1 -0
- package/dist/runtime-tools.d.ts +75 -0
- package/dist/runtime-tools.js +114 -0
- package/dist/runtime-tools.js.map +1 -0
- package/dist/short-term.d.ts +16 -0
- package/dist/short-term.js +60 -0
- package/dist/short-term.js.map +1 -0
- package/dist/store/long-term.d.ts +136 -0
- package/dist/store/long-term.js +206 -0
- package/dist/store/long-term.js.map +1 -0
- package/dist/store/migrations.d.ts +5 -0
- package/dist/store/migrations.js +104 -0
- package/dist/store/migrations.js.map +1 -0
- package/dist/store/sql.d.ts +18 -0
- package/dist/store/sql.js +67 -0
- package/dist/store/sql.js.map +1 -0
- package/package.json +48 -4
- package/schema/agent.schema.json +236 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memória de longo prazo (Postgres): o que ele fez e o que está pendente.
|
|
3
|
+
*
|
|
4
|
+
* Caixa de entrada, itens, histórico de ações com o motivo, propostas esperando uma
|
|
5
|
+
* pessoa, correções recebidas, teto de nível do disjuntor e o lock da rodada. Tudo que
|
|
6
|
+
* precisa sobreviver de uma rodada para outra mora aqui, nunca no SQLite.
|
|
7
|
+
*/
|
|
8
|
+
import type { EffectiveLevel, OutcomeStatus } from '../levels.js';
|
|
9
|
+
import { type EventKind, type IncomingEvent } from '../inbox.js';
|
|
10
|
+
import type { Sql } from './sql.js';
|
|
11
|
+
export interface ItemRow {
|
|
12
|
+
id: number;
|
|
13
|
+
agent_id: string;
|
|
14
|
+
subject: string;
|
|
15
|
+
priority: number;
|
|
16
|
+
status: string;
|
|
17
|
+
attempts: number;
|
|
18
|
+
/** Status antes de entrar na rodada: `waiting` aqui quer dizer prazo vencido. */
|
|
19
|
+
prev_status?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface EventRow {
|
|
22
|
+
id: number;
|
|
23
|
+
type: string;
|
|
24
|
+
kind: EventKind;
|
|
25
|
+
subject: string;
|
|
26
|
+
payload: Record<string, unknown>;
|
|
27
|
+
received_at: string;
|
|
28
|
+
}
|
|
29
|
+
export type ActionMode = 'executed' | 'proposed' | 'shadow' | 'denied';
|
|
30
|
+
export type ActionStatus = 'pending' | 'ok' | 'error' | 'approved' | 'rejected' | 'corrected';
|
|
31
|
+
export interface ActionRow {
|
|
32
|
+
id: number;
|
|
33
|
+
agent_id: string;
|
|
34
|
+
item_id: number | null;
|
|
35
|
+
routine: string;
|
|
36
|
+
tool: string;
|
|
37
|
+
input: Record<string, unknown>;
|
|
38
|
+
reason: string | null;
|
|
39
|
+
mode: ActionMode;
|
|
40
|
+
status: ActionStatus;
|
|
41
|
+
level: EffectiveLevel;
|
|
42
|
+
idempotency_key: string;
|
|
43
|
+
tool_use_id: string | null;
|
|
44
|
+
result: unknown;
|
|
45
|
+
decided_by: string | null;
|
|
46
|
+
note: string | null;
|
|
47
|
+
created_at: string;
|
|
48
|
+
subject?: string | null;
|
|
49
|
+
}
|
|
50
|
+
export declare class LongTermStore {
|
|
51
|
+
private readonly sql;
|
|
52
|
+
constructor(sql: Sql);
|
|
53
|
+
migrate(): Promise<void>;
|
|
54
|
+
close(): Promise<void>;
|
|
55
|
+
/** Grava o evento e junta no item aberto do mesmo assunto. Repetido não entra. */
|
|
56
|
+
enqueue(agentId: string, ev: IncomingEvent, kind: EventKind): Promise<{
|
|
57
|
+
itemId: number | null;
|
|
58
|
+
duplicate: boolean;
|
|
59
|
+
}>;
|
|
60
|
+
/**
|
|
61
|
+
* Pega o próximo lote na ordem de prioridade. `SKIP LOCKED` deixa duas réplicas
|
|
62
|
+
* dividirem a fila sem pegar o mesmo item; o lock da rodada já evita isso no caso comum.
|
|
63
|
+
*/
|
|
64
|
+
leaseBatch(agentId: string, limit: number): Promise<Array<ItemRow & {
|
|
65
|
+
events: EventRow[];
|
|
66
|
+
}>>;
|
|
67
|
+
/**
|
|
68
|
+
* Fecha o item. Se chegou evento novo enquanto ele estava na rodada, o item volta para
|
|
69
|
+
* a fila em vez de fechar: o evento não pode se perder.
|
|
70
|
+
*/
|
|
71
|
+
finishItem(itemId: number, seenEventIds: number[], outcome: {
|
|
72
|
+
status: 'done' | 'waiting';
|
|
73
|
+
summary?: string;
|
|
74
|
+
waitUntil?: Date;
|
|
75
|
+
}): Promise<void>;
|
|
76
|
+
/** Falhou, volta: espera um pouco mais a cada tentativa; depois de N, vira exceção. */
|
|
77
|
+
failItem(itemId: number, error: string, maxAttempts: number): Promise<'retry' | 'exception'>;
|
|
78
|
+
/** Reprocessar agora, sem esperar o backoff (operação manual). */
|
|
79
|
+
retryNow(itemId: number): Promise<void>;
|
|
80
|
+
queueDepth(agentId: string): Promise<number>;
|
|
81
|
+
getItem(itemId: number): Promise<ItemRow & {
|
|
82
|
+
summary: string | null;
|
|
83
|
+
last_error: string | null;
|
|
84
|
+
}>;
|
|
85
|
+
/** Uma rodada por vez: se a anterior ainda roda (lock válido), a próxima espera. */
|
|
86
|
+
tryLock(agentId: string, holder: string, ttlSec: number): Promise<boolean>;
|
|
87
|
+
unlock(agentId: string, holder: string): Promise<void>;
|
|
88
|
+
startRound(agentId: string): Promise<number>;
|
|
89
|
+
finishRound(roundId: number, items: number, costUsd: number, error?: string): Promise<void>;
|
|
90
|
+
/** Registra a ação. `duplicate` = a mesma ação já foi feita ou proposta antes. */
|
|
91
|
+
recordAction(a: {
|
|
92
|
+
agentId: string;
|
|
93
|
+
itemId: number | null;
|
|
94
|
+
routine: string;
|
|
95
|
+
tool: string;
|
|
96
|
+
input: Record<string, unknown>;
|
|
97
|
+
reason: string | null;
|
|
98
|
+
mode: ActionMode;
|
|
99
|
+
status: ActionStatus;
|
|
100
|
+
level: EffectiveLevel;
|
|
101
|
+
idempotencyKey: string;
|
|
102
|
+
toolUseId?: string;
|
|
103
|
+
note?: string;
|
|
104
|
+
}): Promise<{
|
|
105
|
+
id: number | null;
|
|
106
|
+
duplicate: boolean;
|
|
107
|
+
}>;
|
|
108
|
+
completeAction(id: number, status: 'ok' | 'error', result: unknown): Promise<void>;
|
|
109
|
+
getAction(id: number): Promise<ActionRow | undefined>;
|
|
110
|
+
decideProposal(id: number, decision: 'approved' | 'rejected', by: string, note?: string): Promise<ActionRow | undefined>;
|
|
111
|
+
setProposalResult(id: number, status: 'ok' | 'error', result: unknown): Promise<void>;
|
|
112
|
+
/** Uma pessoa corrigiu o que ele fez. É assim que ele aprende, e conta no disjuntor. */
|
|
113
|
+
correctAction(id: number, by: string, note: string): Promise<ActionRow | undefined>;
|
|
114
|
+
executedSince(agentId: string, routine: string, since: Date): Promise<number>;
|
|
115
|
+
/** Desfechos das execuções mais recentes da rotina, mais novo primeiro. */
|
|
116
|
+
recentOutcomes(agentId: string, routine: string, n: number): Promise<OutcomeStatus[]>;
|
|
117
|
+
history(agentId: string, opts?: {
|
|
118
|
+
subject?: string;
|
|
119
|
+
status?: ActionStatus;
|
|
120
|
+
mode?: ActionMode;
|
|
121
|
+
limit?: number;
|
|
122
|
+
}): Promise<ActionRow[]>;
|
|
123
|
+
levelCaps(agentId: string): Promise<Map<string, {
|
|
124
|
+
cap: EffectiveLevel;
|
|
125
|
+
reason: string;
|
|
126
|
+
}>>;
|
|
127
|
+
setLevelCap(agentId: string, routine: string, cap: EffectiveLevel, reason: string): Promise<void>;
|
|
128
|
+
/** Volta a valer o nível do manifesto (decisão de pessoa, depois de tratar a causa). */
|
|
129
|
+
clearLevelCap(agentId: string, routine: string): Promise<void>;
|
|
130
|
+
killSwitch(agentId: string): Promise<{
|
|
131
|
+
reason: string;
|
|
132
|
+
set_by: string;
|
|
133
|
+
} | undefined>;
|
|
134
|
+
setKillSwitch(agentId: string, reason: string, by: string): Promise<void>;
|
|
135
|
+
clearKillSwitch(agentId: string): Promise<void>;
|
|
136
|
+
}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { PRIORITY } from '../inbox.js';
|
|
2
|
+
import { MIGRATIONS } from './migrations.js';
|
|
3
|
+
const num = (v) => Number(v);
|
|
4
|
+
export class LongTermStore {
|
|
5
|
+
sql;
|
|
6
|
+
constructor(sql) {
|
|
7
|
+
this.sql = sql;
|
|
8
|
+
}
|
|
9
|
+
async migrate() {
|
|
10
|
+
await this.sql.exec(MIGRATIONS);
|
|
11
|
+
}
|
|
12
|
+
close() {
|
|
13
|
+
return this.sql.close();
|
|
14
|
+
}
|
|
15
|
+
// ── caixa de entrada ────────────────────────────────────────────────────────────
|
|
16
|
+
/** Grava o evento e junta no item aberto do mesmo assunto. Repetido não entra. */
|
|
17
|
+
async enqueue(agentId, ev, kind) {
|
|
18
|
+
return this.sql.transaction(async (tx) => {
|
|
19
|
+
if (ev.id) {
|
|
20
|
+
const seen = await tx.query('SELECT 1 FROM agent_event WHERE agent_id = $1 AND source_id = $2', [agentId, ev.id]);
|
|
21
|
+
if (seen.length)
|
|
22
|
+
return { itemId: null, duplicate: true };
|
|
23
|
+
}
|
|
24
|
+
const [item] = await tx.query(`INSERT INTO agent_item (agent_id, subject, priority, status)
|
|
25
|
+
VALUES ($1, $2, $3, 'queued')
|
|
26
|
+
ON CONFLICT (agent_id, subject) WHERE status IN ('queued', 'working', 'waiting')
|
|
27
|
+
DO UPDATE SET
|
|
28
|
+
priority = LEAST(agent_item.priority, EXCLUDED.priority),
|
|
29
|
+
-- resposta chegou para quem estava esperando: volta para a fila agora
|
|
30
|
+
status = CASE WHEN agent_item.status = 'waiting' THEN 'queued' ELSE agent_item.status END,
|
|
31
|
+
not_before = CASE WHEN agent_item.status = 'waiting' THEN now() ELSE agent_item.not_before END,
|
|
32
|
+
updated_at = now()
|
|
33
|
+
RETURNING id`, [agentId, ev.subject, PRIORITY[kind]]);
|
|
34
|
+
const inserted = await tx.query(`INSERT INTO agent_event (agent_id, source_id, type, kind, subject, payload, item_id)
|
|
35
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
|
36
|
+
ON CONFLICT (agent_id, source_id) WHERE source_id IS NOT NULL DO NOTHING
|
|
37
|
+
RETURNING id`, [agentId, ev.id ?? null, ev.type, kind, ev.subject, JSON.stringify(ev.payload ?? {}), item.id]);
|
|
38
|
+
if (!inserted.length)
|
|
39
|
+
return { itemId: null, duplicate: true };
|
|
40
|
+
return { itemId: num(item.id), duplicate: false };
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Pega o próximo lote na ordem de prioridade. `SKIP LOCKED` deixa duas réplicas
|
|
45
|
+
* dividirem a fila sem pegar o mesmo item; o lock da rodada já evita isso no caso comum.
|
|
46
|
+
*/
|
|
47
|
+
async leaseBatch(agentId, limit) {
|
|
48
|
+
const items = await this.sql.query(`WITH picked AS (
|
|
49
|
+
SELECT id, status AS prev_status FROM agent_item
|
|
50
|
+
WHERE agent_id = $1 AND status IN ('queued', 'waiting') AND not_before <= now()
|
|
51
|
+
ORDER BY priority, created_at
|
|
52
|
+
LIMIT $2
|
|
53
|
+
FOR UPDATE SKIP LOCKED
|
|
54
|
+
)
|
|
55
|
+
UPDATE agent_item i SET status = 'working', updated_at = now()
|
|
56
|
+
FROM picked WHERE i.id = picked.id
|
|
57
|
+
RETURNING i.id, i.agent_id, i.subject, i.priority, i.status, i.attempts, picked.prev_status`, [agentId, limit]);
|
|
58
|
+
if (!items.length)
|
|
59
|
+
return [];
|
|
60
|
+
const events = await this.sql.query(`SELECT id, item_id, type, kind, subject, payload, received_at FROM agent_event
|
|
61
|
+
WHERE item_id = ANY($1::bigint[]) AND processed_at IS NULL ORDER BY id`, [items.map((i) => i.id)]);
|
|
62
|
+
return items
|
|
63
|
+
.map((i) => ({ ...i, id: num(i.id), events: events.filter((e) => num(e.item_id) === num(i.id)).map((e) => ({ ...e, id: num(e.id) })) }))
|
|
64
|
+
.sort((a, b) => a.priority - b.priority || a.id - b.id);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Fecha o item. Se chegou evento novo enquanto ele estava na rodada, o item volta para
|
|
68
|
+
* a fila em vez de fechar: o evento não pode se perder.
|
|
69
|
+
*/
|
|
70
|
+
async finishItem(itemId, seenEventIds, outcome) {
|
|
71
|
+
await this.sql.transaction(async (tx) => {
|
|
72
|
+
if (seenEventIds.length) {
|
|
73
|
+
await tx.query('UPDATE agent_event SET processed_at = now() WHERE id = ANY($1::bigint[])', [seenEventIds]);
|
|
74
|
+
}
|
|
75
|
+
const [{ pending }] = (await tx.query('SELECT count(*)::int AS pending FROM agent_event WHERE item_id = $1 AND processed_at IS NULL', [itemId]));
|
|
76
|
+
const status = pending > 0 ? 'queued' : outcome.status;
|
|
77
|
+
await tx.query(`UPDATE agent_item SET status = $2, summary = coalesce($3, summary), attempts = 0, last_error = NULL,
|
|
78
|
+
not_before = coalesce($4, now()), updated_at = now() WHERE id = $1`, [itemId, status, outcome.summary ?? null, outcome.status === 'waiting' ? outcome.waitUntil ?? null : null]);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/** Falhou, volta: espera um pouco mais a cada tentativa; depois de N, vira exceção. */
|
|
82
|
+
async failItem(itemId, error, maxAttempts) {
|
|
83
|
+
const [row] = await this.sql.query(`UPDATE agent_item SET
|
|
84
|
+
attempts = attempts + 1,
|
|
85
|
+
last_error = $2,
|
|
86
|
+
status = CASE WHEN attempts + 1 >= $3 THEN 'exception' ELSE 'queued' END,
|
|
87
|
+
not_before = now() + make_interval(secs => 30 * power(2, attempts)),
|
|
88
|
+
updated_at = now()
|
|
89
|
+
WHERE id = $1 RETURNING status`, [itemId, error.slice(0, 2000), maxAttempts]);
|
|
90
|
+
return row?.status === 'exception' ? 'exception' : 'retry';
|
|
91
|
+
}
|
|
92
|
+
/** Reprocessar agora, sem esperar o backoff (operação manual). */
|
|
93
|
+
async retryNow(itemId) {
|
|
94
|
+
await this.sql.query(`UPDATE agent_item SET not_before = now(), updated_at = now() WHERE id = $1 AND status = 'queued'`, [itemId]);
|
|
95
|
+
}
|
|
96
|
+
async queueDepth(agentId) {
|
|
97
|
+
const [r] = await this.sql.query(`SELECT count(*)::int AS n FROM agent_item WHERE agent_id = $1 AND status IN ('queued', 'waiting') AND not_before <= now()`, [agentId]);
|
|
98
|
+
return r?.n ?? 0;
|
|
99
|
+
}
|
|
100
|
+
async getItem(itemId) {
|
|
101
|
+
const [r] = await this.sql.query('SELECT * FROM agent_item WHERE id = $1', [itemId]);
|
|
102
|
+
if (!r)
|
|
103
|
+
throw new Error(`item ${itemId} não existe`);
|
|
104
|
+
return { ...r, id: num(r.id) };
|
|
105
|
+
}
|
|
106
|
+
// ── rodada ──────────────────────────────────────────────────────────────────────
|
|
107
|
+
/** Uma rodada por vez: se a anterior ainda roda (lock válido), a próxima espera. */
|
|
108
|
+
async tryLock(agentId, holder, ttlSec) {
|
|
109
|
+
const rows = await this.sql.query(`INSERT INTO agent_lock (agent_id, holder, until) VALUES ($1, $2, now() + make_interval(secs => $3))
|
|
110
|
+
ON CONFLICT (agent_id) DO UPDATE SET holder = EXCLUDED.holder, until = EXCLUDED.until
|
|
111
|
+
WHERE agent_lock.until < now() OR agent_lock.holder = EXCLUDED.holder
|
|
112
|
+
RETURNING agent_id`, [agentId, holder, ttlSec]);
|
|
113
|
+
return rows.length > 0;
|
|
114
|
+
}
|
|
115
|
+
async unlock(agentId, holder) {
|
|
116
|
+
await this.sql.query('DELETE FROM agent_lock WHERE agent_id = $1 AND holder = $2', [agentId, holder]);
|
|
117
|
+
}
|
|
118
|
+
async startRound(agentId) {
|
|
119
|
+
const [r] = await this.sql.query('INSERT INTO agent_round (agent_id) VALUES ($1) RETURNING id', [agentId]);
|
|
120
|
+
return num(r.id);
|
|
121
|
+
}
|
|
122
|
+
async finishRound(roundId, items, costUsd, error) {
|
|
123
|
+
await this.sql.query('UPDATE agent_round SET finished_at = now(), items = $2, cost_usd = $3, error = $4 WHERE id = $1', [roundId, items, costUsd, error ?? null]);
|
|
124
|
+
}
|
|
125
|
+
// ── ações ───────────────────────────────────────────────────────────────────────
|
|
126
|
+
/** Registra a ação. `duplicate` = a mesma ação já foi feita ou proposta antes. */
|
|
127
|
+
async recordAction(a) {
|
|
128
|
+
const rows = await this.sql.query(`INSERT INTO agent_action (agent_id, item_id, routine, tool, input, reason, mode, status, level, idempotency_key, tool_use_id, note)
|
|
129
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
|
|
130
|
+
ON CONFLICT (agent_id, idempotency_key) WHERE mode IN ('executed', 'proposed') AND status IN ('pending', 'ok', 'approved')
|
|
131
|
+
DO NOTHING RETURNING id`, [
|
|
132
|
+
a.agentId, a.itemId, a.routine, a.tool, JSON.stringify(a.input), a.reason, a.mode, a.status, a.level,
|
|
133
|
+
a.idempotencyKey, a.toolUseId ?? null, a.note ?? null,
|
|
134
|
+
]);
|
|
135
|
+
return rows.length ? { id: num(rows[0].id), duplicate: false } : { id: null, duplicate: true };
|
|
136
|
+
}
|
|
137
|
+
async completeAction(id, status, result) {
|
|
138
|
+
await this.sql.query('UPDATE agent_action SET status = $2, result = $3 WHERE id = $1', [id, status, JSON.stringify(result ?? null)]);
|
|
139
|
+
}
|
|
140
|
+
async getAction(id) {
|
|
141
|
+
const [r] = await this.sql.query('SELECT * FROM agent_action WHERE id = $1', [id]);
|
|
142
|
+
return r ? { ...r, id: num(r.id) } : undefined;
|
|
143
|
+
}
|
|
144
|
+
async decideProposal(id, decision, by, note) {
|
|
145
|
+
const [r] = await this.sql.query(`UPDATE agent_action SET status = $2, decided_by = $3, decided_at = now(), note = coalesce($4, note)
|
|
146
|
+
WHERE id = $1 AND mode = 'proposed' AND status = 'pending' RETURNING *`, [id, decision, by, note ?? null]);
|
|
147
|
+
return r ? { ...r, id: num(r.id) } : undefined;
|
|
148
|
+
}
|
|
149
|
+
async setProposalResult(id, status, result) {
|
|
150
|
+
// A proposta aprovada vira uma ação executada: é ela que conta no disjuntor.
|
|
151
|
+
await this.sql.query(`UPDATE agent_action SET mode = 'executed', status = $2, result = $3 WHERE id = $1`, [id, status, JSON.stringify(result ?? null)]);
|
|
152
|
+
}
|
|
153
|
+
/** Uma pessoa corrigiu o que ele fez. É assim que ele aprende, e conta no disjuntor. */
|
|
154
|
+
async correctAction(id, by, note) {
|
|
155
|
+
const [r] = await this.sql.query(`UPDATE agent_action SET status = 'corrected', decided_by = $2, decided_at = now(), note = $3
|
|
156
|
+
WHERE id = $1 AND mode = 'executed' RETURNING *`, [id, by, note]);
|
|
157
|
+
return r ? { ...r, id: num(r.id) } : undefined;
|
|
158
|
+
}
|
|
159
|
+
async executedSince(agentId, routine, since) {
|
|
160
|
+
const [r] = await this.sql.query(`SELECT count(*)::int AS n FROM agent_action
|
|
161
|
+
WHERE agent_id = $1 AND routine = $2 AND mode = 'executed' AND created_at >= $3`, [agentId, routine, since]);
|
|
162
|
+
return r?.n ?? 0;
|
|
163
|
+
}
|
|
164
|
+
/** Desfechos das execuções mais recentes da rotina, mais novo primeiro. */
|
|
165
|
+
async recentOutcomes(agentId, routine, n) {
|
|
166
|
+
const rows = await this.sql.query(`SELECT status FROM agent_action
|
|
167
|
+
WHERE agent_id = $1 AND routine = $2 AND mode = 'executed' AND status IN ('ok', 'error', 'corrected')
|
|
168
|
+
ORDER BY created_at DESC, id DESC LIMIT $3`, [agentId, routine, n]);
|
|
169
|
+
return rows.map((r) => r.status);
|
|
170
|
+
}
|
|
171
|
+
async history(agentId, opts = {}) {
|
|
172
|
+
const rows = await this.sql.query(`SELECT a.*, i.subject FROM agent_action a LEFT JOIN agent_item i ON i.id = a.item_id
|
|
173
|
+
WHERE a.agent_id = $1
|
|
174
|
+
AND ($2::text IS NULL OR i.subject = $2)
|
|
175
|
+
AND ($3::text IS NULL OR a.status = $3)
|
|
176
|
+
AND ($4::text IS NULL OR a.mode = $4)
|
|
177
|
+
ORDER BY a.created_at DESC, a.id DESC LIMIT $5`, [agentId, opts.subject ?? null, opts.status ?? null, opts.mode ?? null, opts.limit ?? 50]);
|
|
178
|
+
return rows.map((r) => ({ ...r, id: num(r.id) }));
|
|
179
|
+
}
|
|
180
|
+
// ── nível ───────────────────────────────────────────────────────────────────────
|
|
181
|
+
async levelCaps(agentId) {
|
|
182
|
+
const rows = await this.sql.query('SELECT routine, level_cap, reason FROM agent_routine_state WHERE agent_id = $1', [agentId]);
|
|
183
|
+
return new Map(rows.map((r) => [r.routine, { cap: r.level_cap, reason: r.reason }]));
|
|
184
|
+
}
|
|
185
|
+
async setLevelCap(agentId, routine, cap, reason) {
|
|
186
|
+
await this.sql.query(`INSERT INTO agent_routine_state (agent_id, routine, level_cap, reason) VALUES ($1, $2, $3, $4)
|
|
187
|
+
ON CONFLICT (agent_id, routine) DO UPDATE SET level_cap = $3, reason = $4, changed_at = now()`, [agentId, routine, cap, reason]);
|
|
188
|
+
}
|
|
189
|
+
/** Volta a valer o nível do manifesto (decisão de pessoa, depois de tratar a causa). */
|
|
190
|
+
async clearLevelCap(agentId, routine) {
|
|
191
|
+
await this.sql.query('DELETE FROM agent_routine_state WHERE agent_id = $1 AND routine = $2', [agentId, routine]);
|
|
192
|
+
}
|
|
193
|
+
// ── bloqueio de emergência ──────────────────────────────────────────────────────
|
|
194
|
+
async killSwitch(agentId) {
|
|
195
|
+
const [r] = await this.sql.query('SELECT reason, set_by FROM agent_kill_switch WHERE agent_id = $1', [agentId]);
|
|
196
|
+
return r;
|
|
197
|
+
}
|
|
198
|
+
async setKillSwitch(agentId, reason, by) {
|
|
199
|
+
await this.sql.query(`INSERT INTO agent_kill_switch (agent_id, reason, set_by) VALUES ($1, $2, $3)
|
|
200
|
+
ON CONFLICT (agent_id) DO UPDATE SET reason = $2, set_by = $3, set_at = now()`, [agentId, reason, by]);
|
|
201
|
+
}
|
|
202
|
+
async clearKillSwitch(agentId) {
|
|
203
|
+
await this.sql.query('DELETE FROM agent_kill_switch WHERE agent_id = $1', [agentId]);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=long-term.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"long-term.js","sourceRoot":"","sources":["../../src/store/long-term.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,QAAQ,EAAsC,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AA8C7C,MAAM,GAAG,GAAG,CAAC,CAAU,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAEtC,MAAM,OAAO,aAAa;IACK;IAA7B,YAA6B,GAAQ;QAAR,QAAG,GAAH,GAAG,CAAK;IAAG,CAAC;IAEzC,KAAK,CAAC,OAAO;QACX,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAClC,CAAC;IAED,KAAK;QACH,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;IAC1B,CAAC;IAED,mFAAmF;IAEnF,kFAAkF;IAClF,KAAK,CAAC,OAAO,CAAC,OAAe,EAAE,EAAiB,EAAE,IAAe;QAC/D,OAAO,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;YACvC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;gBACV,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,kEAAkE,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;gBAClH,IAAI,IAAI,CAAC,MAAM;oBAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;YAC5D,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,EAAE,CAAC,KAAK,CAC3B;;;;;;;;;sBASc,EACd,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CACtC,CAAC;YACF,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,KAAK,CAC7B;;;sBAGc,EACd,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,IAAK,CAAC,EAAE,CAAC,CAChG,CAAC;YACF,IAAI,CAAC,QAAQ,CAAC,MAAM;gBAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;YAC/D,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,IAAK,CAAC,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;QACrD,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,UAAU,CAAC,OAAe,EAAE,KAAa;QAC7C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAChC;;;;;;;;;mGAS6F,EAC7F,CAAC,OAAO,EAAE,KAAK,CAAC,CACjB,CAAC;QACF,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,OAAO,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CACjC;+EACyE,EACzE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CACzB,CAAC;QACF,OAAO,KAAK;aACT,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;aACvI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,UAAU,CACd,MAAc,EACd,YAAsB,EACtB,OAA2E;QAE3E,MAAM,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;YACtC,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;gBACxB,MAAM,EAAE,CAAC,KAAK,CAAC,0EAA0E,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;YAC7G,CAAC;YACD,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,KAAK,CACnC,8FAA8F,EAC9F,CAAC,MAAM,CAAC,CACT,CAA0B,CAAC;YAC5B,MAAM,MAAM,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;YACvD,MAAM,EAAE,CAAC,KAAK,CACZ;mFAC2E,EAC3E,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,OAAO,IAAI,IAAI,EAAE,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAC3G,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED,uFAAuF;IACvF,KAAK,CAAC,QAAQ,CAAC,MAAc,EAAE,KAAa,EAAE,WAAmB;QAC/D,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAChC;;;;;;sCAMgC,EAChC,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,WAAW,CAAC,CAC5C,CAAC;QACF,OAAO,GAAG,EAAE,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC;IAC7D,CAAC;IAED,kEAAkE;IAClE,KAAK,CAAC,QAAQ,CAAC,MAAc;QAC3B,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,kGAAkG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IACrI,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,OAAe;QAC9B,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAC9B,2HAA2H,EAC3H,CAAC,OAAO,CAAC,CACV,CAAC;QACF,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAAc;QAC1B,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAC9B,wCAAwC,EACxC,CAAC,MAAM,CAAC,CACT,CAAC;QACF,IAAI,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,MAAM,aAAa,CAAC,CAAC;QACrD,OAAO,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACjC,CAAC;IAED,mFAAmF;IAEnF,oFAAoF;IACpF,KAAK,CAAC,OAAO,CAAC,OAAe,EAAE,MAAc,EAAE,MAAc;QAC3D,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAC/B;;;0BAGoB,EACpB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAC1B,CAAC;QACF,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAe,EAAE,MAAc;QAC1C,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,4DAA4D,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;IACxG,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,OAAe;QAC9B,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAiB,6DAA6D,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAC3H,OAAO,GAAG,CAAC,CAAE,CAAC,EAAE,CAAC,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAAe,EAAE,KAAa,EAAE,OAAe,EAAE,KAAc;QAC/E,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAClB,iGAAiG,EACjG,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,IAAI,IAAI,CAAC,CACzC,CAAC;IACJ,CAAC;IAED,mFAAmF;IAEnF,kFAAkF;IAClF,KAAK,CAAC,YAAY,CAAC,CAalB;QACC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAC/B;;;+BAGyB,EACzB;YACE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK;YACpG,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,SAAS,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI;SACtD,CACF,CAAC;QACF,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAClG,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,EAAU,EAAE,MAAsB,EAAE,MAAe;QACtE,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,gEAAgE,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;IACvI,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,EAAU;QACxB,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAY,0CAA0C,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9F,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,EAAU,EAAE,QAAiC,EAAE,EAAU,EAAE,IAAa;QAC3F,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAC9B;+EACyE,EACzE,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,IAAI,IAAI,CAAC,CACjC,CAAC;QACF,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,EAAU,EAAE,MAAsB,EAAE,MAAe;QACzE,6EAA6E;QAC7E,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAClB,mFAAmF,EACnF,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAC7C,CAAC;IACJ,CAAC;IAED,wFAAwF;IACxF,KAAK,CAAC,aAAa,CAAC,EAAU,EAAE,EAAU,EAAE,IAAY;QACtD,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAC9B;wDACkD,EAClD,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,CACf,CAAC;QACF,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,OAAe,EAAE,OAAe,EAAE,KAAW;QAC/D,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAC9B;wFACkF,EAClF,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAC1B,CAAC;QACF,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;IAED,2EAA2E;IAC3E,KAAK,CAAC,cAAc,CAAC,OAAe,EAAE,OAAe,EAAE,CAAS;QAC9D,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAC/B;;mDAE6C,EAC7C,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CACtB,CAAC;QACF,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAe,EAAE,OAAuF,EAAE;QACtH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAC/B;;;;;uDAKiD,EACjD,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,IAAI,EAAE,IAAI,CAAC,MAAM,IAAI,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAC1F,CAAC;QACF,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACpD,CAAC;IAED,mFAAmF;IAEnF,KAAK,CAAC,SAAS,CAAC,OAAe;QAC7B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAC/B,gFAAgF,EAChF,CAAC,OAAO,CAAC,CACV,CAAC;QACF,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;IACvF,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAAe,EAAE,OAAe,EAAE,GAAmB,EAAE,MAAc;QACrF,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAClB;qGAC+F,EAC/F,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,CAChC,CAAC;IACJ,CAAC;IAED,wFAAwF;IACxF,KAAK,CAAC,aAAa,CAAC,OAAe,EAAE,OAAe;QAClD,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,sEAAsE,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IACnH,CAAC;IAED,mFAAmF;IAEnF,KAAK,CAAC,UAAU,CAAC,OAAe;QAC9B,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAC9B,kEAAkE,EAClE,CAAC,OAAO,CAAC,CACV,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,OAAe,EAAE,MAAc,EAAE,EAAU;QAC7D,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAClB;qFAC+E,EAC/E,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,CACtB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,OAAe;QACnC,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,mDAAmD,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IACvF,CAAC;CACF"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tabelas da memória de longo prazo. Um banco por repositório de círculo; toda linha
|
|
3
|
+
* leva o agent_id. Idempotente: roda no boot.
|
|
4
|
+
*/
|
|
5
|
+
export declare const MIGRATIONS = "\nCREATE TABLE IF NOT EXISTS agent_item (\n id BIGSERIAL PRIMARY KEY,\n agent_id TEXT NOT NULL,\n subject TEXT NOT NULL,\n priority INT NOT NULL,\n -- queued: na fila | working: numa rodada | waiting: esperando resposta (not_before = prazo)\n -- done: fechado | exception: falhou demais e foi para o DRI\n status TEXT NOT NULL,\n attempts INT NOT NULL DEFAULT 0,\n not_before TIMESTAMPTZ NOT NULL DEFAULT now(),\n summary TEXT,\n last_error TEXT,\n created_at TIMESTAMPTZ NOT NULL DEFAULT now(),\n updated_at TIMESTAMPTZ NOT NULL DEFAULT now()\n);\n-- Um item aberto por assunto: \u00E9 isso que junta eventos do mesmo chamado num item s\u00F3.\nCREATE UNIQUE INDEX IF NOT EXISTS agent_item_open_subject\n ON agent_item (agent_id, subject) WHERE status IN ('queued', 'working', 'waiting');\nCREATE INDEX IF NOT EXISTS agent_item_queue ON agent_item (agent_id, status, priority, not_before);\n\nCREATE TABLE IF NOT EXISTS agent_event (\n id BIGSERIAL PRIMARY KEY,\n agent_id TEXT NOT NULL,\n source_id TEXT,\n type TEXT NOT NULL,\n kind TEXT NOT NULL,\n subject TEXT NOT NULL,\n payload JSONB NOT NULL DEFAULT '{}',\n item_id BIGINT REFERENCES agent_item(id),\n received_at TIMESTAMPTZ NOT NULL DEFAULT now(),\n processed_at TIMESTAMPTZ\n);\nCREATE UNIQUE INDEX IF NOT EXISTS agent_event_dedup ON agent_event (agent_id, source_id) WHERE source_id IS NOT NULL;\nCREATE INDEX IF NOT EXISTS agent_event_item ON agent_event (item_id) WHERE processed_at IS NULL;\n\nCREATE TABLE IF NOT EXISTS agent_action (\n id BIGSERIAL PRIMARY KEY,\n agent_id TEXT NOT NULL,\n item_id BIGINT,\n routine TEXT NOT NULL,\n tool TEXT NOT NULL,\n input JSONB NOT NULL DEFAULT '{}',\n reason TEXT,\n -- executed: rodou | proposed: espera uma pessoa | shadow: s\u00F3 registro | denied: barrado\n mode TEXT NOT NULL,\n -- pending | ok | error | approved | rejected | corrected\n status TEXT NOT NULL,\n level TEXT NOT NULL,\n idempotency_key TEXT NOT NULL,\n tool_use_id TEXT,\n result JSONB,\n decided_by TEXT,\n decided_at TIMESTAMPTZ,\n note TEXT,\n created_at TIMESTAMPTZ NOT NULL DEFAULT now()\n);\n-- Nada se repete: a mesma a\u00E7\u00E3o no mesmo item e rotina s\u00F3 existe uma vez enquanto viva.\nCREATE UNIQUE INDEX IF NOT EXISTS agent_action_once\n ON agent_action (agent_id, idempotency_key)\n WHERE mode IN ('executed', 'proposed') AND status IN ('pending', 'ok', 'approved');\nCREATE INDEX IF NOT EXISTS agent_action_routine ON agent_action (agent_id, routine, created_at DESC);\n\n-- Teto de n\u00EDvel gravado pelo disjuntor (ou por uma pessoa num incidente).\nCREATE TABLE IF NOT EXISTS agent_routine_state (\n agent_id TEXT NOT NULL,\n routine TEXT NOT NULL,\n level_cap TEXT NOT NULL,\n reason TEXT NOT NULL,\n changed_at TIMESTAMPTZ NOT NULL DEFAULT now(),\n PRIMARY KEY (agent_id, routine)\n);\n\n-- Uma rodada por vez por agente, entre r\u00E9plicas.\nCREATE TABLE IF NOT EXISTS agent_lock (\n agent_id TEXT PRIMARY KEY,\n holder TEXT NOT NULL,\n until TIMESTAMPTZ NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS agent_round (\n id BIGSERIAL PRIMARY KEY,\n agent_id TEXT NOT NULL,\n started_at TIMESTAMPTZ NOT NULL DEFAULT now(),\n finished_at TIMESTAMPTZ,\n items INT NOT NULL DEFAULT 0,\n cost_usd NUMERIC(12, 6) NOT NULL DEFAULT 0,\n error TEXT\n);\n\n-- Bloqueio de emerg\u00EAncia: para tudo na hora, sem deploy. O gateway tamb\u00E9m precisa barrar\n-- a identidade; isto aqui \u00E9 o lado do runtime.\nCREATE TABLE IF NOT EXISTS agent_kill_switch (\n agent_id TEXT PRIMARY KEY,\n reason TEXT NOT NULL,\n set_by TEXT NOT NULL,\n set_at TIMESTAMPTZ NOT NULL DEFAULT now()\n);\n";
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tabelas da memória de longo prazo. Um banco por repositório de círculo; toda linha
|
|
3
|
+
* leva o agent_id. Idempotente: roda no boot.
|
|
4
|
+
*/
|
|
5
|
+
export const MIGRATIONS = /* sql */ `
|
|
6
|
+
CREATE TABLE IF NOT EXISTS agent_item (
|
|
7
|
+
id BIGSERIAL PRIMARY KEY,
|
|
8
|
+
agent_id TEXT NOT NULL,
|
|
9
|
+
subject TEXT NOT NULL,
|
|
10
|
+
priority INT NOT NULL,
|
|
11
|
+
-- queued: na fila | working: numa rodada | waiting: esperando resposta (not_before = prazo)
|
|
12
|
+
-- done: fechado | exception: falhou demais e foi para o DRI
|
|
13
|
+
status TEXT NOT NULL,
|
|
14
|
+
attempts INT NOT NULL DEFAULT 0,
|
|
15
|
+
not_before TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
16
|
+
summary TEXT,
|
|
17
|
+
last_error TEXT,
|
|
18
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
19
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
20
|
+
);
|
|
21
|
+
-- Um item aberto por assunto: é isso que junta eventos do mesmo chamado num item só.
|
|
22
|
+
CREATE UNIQUE INDEX IF NOT EXISTS agent_item_open_subject
|
|
23
|
+
ON agent_item (agent_id, subject) WHERE status IN ('queued', 'working', 'waiting');
|
|
24
|
+
CREATE INDEX IF NOT EXISTS agent_item_queue ON agent_item (agent_id, status, priority, not_before);
|
|
25
|
+
|
|
26
|
+
CREATE TABLE IF NOT EXISTS agent_event (
|
|
27
|
+
id BIGSERIAL PRIMARY KEY,
|
|
28
|
+
agent_id TEXT NOT NULL,
|
|
29
|
+
source_id TEXT,
|
|
30
|
+
type TEXT NOT NULL,
|
|
31
|
+
kind TEXT NOT NULL,
|
|
32
|
+
subject TEXT NOT NULL,
|
|
33
|
+
payload JSONB NOT NULL DEFAULT '{}',
|
|
34
|
+
item_id BIGINT REFERENCES agent_item(id),
|
|
35
|
+
received_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
36
|
+
processed_at TIMESTAMPTZ
|
|
37
|
+
);
|
|
38
|
+
CREATE UNIQUE INDEX IF NOT EXISTS agent_event_dedup ON agent_event (agent_id, source_id) WHERE source_id IS NOT NULL;
|
|
39
|
+
CREATE INDEX IF NOT EXISTS agent_event_item ON agent_event (item_id) WHERE processed_at IS NULL;
|
|
40
|
+
|
|
41
|
+
CREATE TABLE IF NOT EXISTS agent_action (
|
|
42
|
+
id BIGSERIAL PRIMARY KEY,
|
|
43
|
+
agent_id TEXT NOT NULL,
|
|
44
|
+
item_id BIGINT,
|
|
45
|
+
routine TEXT NOT NULL,
|
|
46
|
+
tool TEXT NOT NULL,
|
|
47
|
+
input JSONB NOT NULL DEFAULT '{}',
|
|
48
|
+
reason TEXT,
|
|
49
|
+
-- executed: rodou | proposed: espera uma pessoa | shadow: só registro | denied: barrado
|
|
50
|
+
mode TEXT NOT NULL,
|
|
51
|
+
-- pending | ok | error | approved | rejected | corrected
|
|
52
|
+
status TEXT NOT NULL,
|
|
53
|
+
level TEXT NOT NULL,
|
|
54
|
+
idempotency_key TEXT NOT NULL,
|
|
55
|
+
tool_use_id TEXT,
|
|
56
|
+
result JSONB,
|
|
57
|
+
decided_by TEXT,
|
|
58
|
+
decided_at TIMESTAMPTZ,
|
|
59
|
+
note TEXT,
|
|
60
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
61
|
+
);
|
|
62
|
+
-- Nada se repete: a mesma ação no mesmo item e rotina só existe uma vez enquanto viva.
|
|
63
|
+
CREATE UNIQUE INDEX IF NOT EXISTS agent_action_once
|
|
64
|
+
ON agent_action (agent_id, idempotency_key)
|
|
65
|
+
WHERE mode IN ('executed', 'proposed') AND status IN ('pending', 'ok', 'approved');
|
|
66
|
+
CREATE INDEX IF NOT EXISTS agent_action_routine ON agent_action (agent_id, routine, created_at DESC);
|
|
67
|
+
|
|
68
|
+
-- Teto de nível gravado pelo disjuntor (ou por uma pessoa num incidente).
|
|
69
|
+
CREATE TABLE IF NOT EXISTS agent_routine_state (
|
|
70
|
+
agent_id TEXT NOT NULL,
|
|
71
|
+
routine TEXT NOT NULL,
|
|
72
|
+
level_cap TEXT NOT NULL,
|
|
73
|
+
reason TEXT NOT NULL,
|
|
74
|
+
changed_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
75
|
+
PRIMARY KEY (agent_id, routine)
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
-- Uma rodada por vez por agente, entre réplicas.
|
|
79
|
+
CREATE TABLE IF NOT EXISTS agent_lock (
|
|
80
|
+
agent_id TEXT PRIMARY KEY,
|
|
81
|
+
holder TEXT NOT NULL,
|
|
82
|
+
until TIMESTAMPTZ NOT NULL
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
CREATE TABLE IF NOT EXISTS agent_round (
|
|
86
|
+
id BIGSERIAL PRIMARY KEY,
|
|
87
|
+
agent_id TEXT NOT NULL,
|
|
88
|
+
started_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
89
|
+
finished_at TIMESTAMPTZ,
|
|
90
|
+
items INT NOT NULL DEFAULT 0,
|
|
91
|
+
cost_usd NUMERIC(12, 6) NOT NULL DEFAULT 0,
|
|
92
|
+
error TEXT
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
-- Bloqueio de emergência: para tudo na hora, sem deploy. O gateway também precisa barrar
|
|
96
|
+
-- a identidade; isto aqui é o lado do runtime.
|
|
97
|
+
CREATE TABLE IF NOT EXISTS agent_kill_switch (
|
|
98
|
+
agent_id TEXT PRIMARY KEY,
|
|
99
|
+
reason TEXT NOT NULL,
|
|
100
|
+
set_by TEXT NOT NULL,
|
|
101
|
+
set_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
102
|
+
);
|
|
103
|
+
`;
|
|
104
|
+
//# sourceMappingURL=migrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/store/migrations.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkGnC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Acesso ao Postgres por uma interface mínima, para o mesmo código rodar em produção
|
|
3
|
+
* (`pg`) e localmente ou nos testes (PGlite: Postgres de verdade, em processo, sem Docker).
|
|
4
|
+
*/
|
|
5
|
+
export interface Queryable {
|
|
6
|
+
query<T = Record<string, unknown>>(text: string, params?: unknown[]): Promise<T[]>;
|
|
7
|
+
}
|
|
8
|
+
export interface Sql extends Queryable {
|
|
9
|
+
/** Executa várias instruções sem parâmetros (migrações). */
|
|
10
|
+
exec(text: string): Promise<void>;
|
|
11
|
+
transaction<T>(fn: (tx: Queryable) => Promise<T>): Promise<T>;
|
|
12
|
+
close(): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
export declare function pgSql(connectionString: string): Promise<Sql>;
|
|
15
|
+
/** `dataDir` ausente = banco em memória (some ao fechar). */
|
|
16
|
+
export declare function pgliteSql(dataDir?: string): Promise<Sql>;
|
|
17
|
+
/** DATABASE_URL `postgres://...` usa `pg`; `pglite:<pasta>` (ou ausente) usa PGlite. */
|
|
18
|
+
export declare function sqlFromUrl(url: string | undefined): Promise<Sql>;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export async function pgSql(connectionString) {
|
|
2
|
+
const { default: pg } = await import('pg');
|
|
3
|
+
const pool = new pg.Pool({ connectionString, max: 5 });
|
|
4
|
+
return {
|
|
5
|
+
async query(text, params) {
|
|
6
|
+
const res = await pool.query(text, params);
|
|
7
|
+
return res.rows;
|
|
8
|
+
},
|
|
9
|
+
async exec(text) {
|
|
10
|
+
await pool.query(text);
|
|
11
|
+
},
|
|
12
|
+
async transaction(fn) {
|
|
13
|
+
const client = await pool.connect();
|
|
14
|
+
try {
|
|
15
|
+
await client.query('BEGIN');
|
|
16
|
+
const out = await fn({
|
|
17
|
+
async query(text, params) {
|
|
18
|
+
const res = await client.query(text, params);
|
|
19
|
+
return res.rows;
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
await client.query('COMMIT');
|
|
23
|
+
return out;
|
|
24
|
+
}
|
|
25
|
+
catch (e) {
|
|
26
|
+
await client.query('ROLLBACK');
|
|
27
|
+
throw e;
|
|
28
|
+
}
|
|
29
|
+
finally {
|
|
30
|
+
client.release();
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
close: () => pool.end(),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/** `dataDir` ausente = banco em memória (some ao fechar). */
|
|
37
|
+
export async function pgliteSql(dataDir) {
|
|
38
|
+
const { PGlite } = await import('@electric-sql/pglite');
|
|
39
|
+
const db = dataDir ? new PGlite(dataDir) : new PGlite();
|
|
40
|
+
await db.waitReady;
|
|
41
|
+
return {
|
|
42
|
+
async query(text, params) {
|
|
43
|
+
const res = await db.query(text, params);
|
|
44
|
+
return res.rows;
|
|
45
|
+
},
|
|
46
|
+
async exec(text) {
|
|
47
|
+
await db.exec(text);
|
|
48
|
+
},
|
|
49
|
+
transaction(fn) {
|
|
50
|
+
return db.transaction((tx) => fn({
|
|
51
|
+
async query(text, params) {
|
|
52
|
+
const res = await tx.query(text, params);
|
|
53
|
+
return res.rows;
|
|
54
|
+
},
|
|
55
|
+
}));
|
|
56
|
+
},
|
|
57
|
+
close: () => db.close(),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/** DATABASE_URL `postgres://...` usa `pg`; `pglite:<pasta>` (ou ausente) usa PGlite. */
|
|
61
|
+
export async function sqlFromUrl(url) {
|
|
62
|
+
if (url && /^postgres(ql)?:\/\//.test(url))
|
|
63
|
+
return pgSql(url);
|
|
64
|
+
const dir = url?.startsWith('pglite:') ? url.slice('pglite:'.length) : undefined;
|
|
65
|
+
return pgliteSql(dir || undefined);
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=sql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql.js","sourceRoot":"","sources":["../../src/store/sql.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,50 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@t4h/agent-runtime",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Runtime dos colaboradores digitais (agentes de IA) da Tech for Humans: manifesto agent.yaml, caixa de entrada de eventos, rodadas, níveis de autonomia por rotina com disjuntor, memória curta (SQLite) e longa (Postgres), e acesso aos sistemas pelo Enterprise MCP Gateway com a identidade própria do agente.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=24"
|
|
8
|
+
},
|
|
9
|
+
"main": "dist/index.js",
|
|
10
|
+
"types": "dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./schema/agent.schema.json": "./schema/agent.schema.json"
|
|
17
|
+
},
|
|
18
|
+
"bin": {
|
|
19
|
+
"t4h-agent": "bin/t4h-agent.mjs"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"schema",
|
|
24
|
+
"bin"
|
|
25
|
+
],
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsc -p tsconfig.json",
|
|
28
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
29
|
+
"test": "vitest run"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@anthropic-ai/claude-agent-sdk": "0.3.310",
|
|
33
|
+
"@electric-sql/pglite": "^0.5.11",
|
|
34
|
+
"ajv": "^8.20.0",
|
|
35
|
+
"croner": "^10.0.1",
|
|
36
|
+
"pg": "^8.23.1",
|
|
37
|
+
"yaml": "^2.9.1",
|
|
38
|
+
"zod": "^4.1.0"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/node": "^24.19.2",
|
|
42
|
+
"@types/pg": "^8.15.0",
|
|
43
|
+
"typescript": "^5.7.2",
|
|
44
|
+
"vitest": "^3.2.7",
|
|
45
|
+
"tsx": "^4.19.2"
|
|
46
|
+
},
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
}
|
|
50
|
+
}
|