@t4h/agent-runtime 0.1.1 → 0.3.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.
Files changed (57) hide show
  1. package/README.md +94 -5
  2. package/catalog/agents.catalog.yaml +123 -0
  3. package/dist/brain.d.ts +8 -0
  4. package/dist/brain.js +11 -0
  5. package/dist/brain.js.map +1 -1
  6. package/dist/catalog.d.ts +13 -0
  7. package/dist/catalog.js +39 -0
  8. package/dist/catalog.js.map +1 -0
  9. package/dist/cli.js +33 -8
  10. package/dist/cli.js.map +1 -1
  11. package/dist/connector.d.ts +13 -0
  12. package/dist/connector.js +208 -0
  13. package/dist/connector.js.map +1 -0
  14. package/dist/env.d.ts +59 -0
  15. package/dist/env.js +138 -0
  16. package/dist/env.js.map +1 -0
  17. package/dist/evals.js +1 -1
  18. package/dist/gateway.d.ts +5 -1
  19. package/dist/gateway.js +4 -2
  20. package/dist/gateway.js.map +1 -1
  21. package/dist/host.d.ts +111 -13
  22. package/dist/host.js +251 -43
  23. package/dist/host.js.map +1 -1
  24. package/dist/index.d.ts +18 -4
  25. package/dist/index.js +11 -2
  26. package/dist/index.js.map +1 -1
  27. package/dist/model-auth.d.ts +83 -0
  28. package/dist/model-auth.js +231 -0
  29. package/dist/model-auth.js.map +1 -0
  30. package/dist/notifier.d.ts +1 -1
  31. package/dist/policy.js +12 -1
  32. package/dist/policy.js.map +1 -1
  33. package/dist/prompt.d.ts +8 -0
  34. package/dist/prompt.js +10 -3
  35. package/dist/prompt.js.map +1 -1
  36. package/dist/round.js +2 -1
  37. package/dist/round.js.map +1 -1
  38. package/dist/runtime-tools.d.ts +1 -1
  39. package/dist/runtime-tools.js +3 -3
  40. package/dist/runtime-tools.js.map +1 -1
  41. package/dist/signature.d.ts +34 -0
  42. package/dist/signature.js +87 -0
  43. package/dist/signature.js.map +1 -0
  44. package/dist/start.d.ts +31 -0
  45. package/dist/start.js +110 -0
  46. package/dist/start.js.map +1 -0
  47. package/dist/store/long-term.d.ts +63 -3
  48. package/dist/store/long-term.js +71 -11
  49. package/dist/store/long-term.js.map +1 -1
  50. package/dist/store/migrations.d.ts +1 -1
  51. package/dist/store/migrations.js +24 -0
  52. package/dist/store/migrations.js.map +1 -1
  53. package/dist/wiring.d.ts +11 -0
  54. package/dist/wiring.js +32 -0
  55. package/dist/wiring.js.map +1 -0
  56. package/package.json +13 -6
  57. package/proto/t4h/agents/v1/agents.proto +176 -0
package/README.md CHANGED
@@ -1,10 +1,12 @@
1
1
  # @t4h/agent-runtime
2
2
 
3
3
  Runtime dos **colaboradores digitais** da Tech for Humans. Um agente é uma pasta
4
- (`agent.yaml`, `persona.md`, `skills/`, `evals/`); este pacote faz o resto:
4
+ (`agent.yaml`, `persona.md`, `skills/`, `evals/`); este pacote faz o resto, como o
5
+ `@t4h/mcp-provider-sdk` faz para os providers:
5
6
 
6
7
  - valida o `agent.yaml` (schema v1 em `schema/agent.schema.json` + regras entre campos);
7
- - caixa de entrada no Postgres: junta eventos por assunto, descarta repetido, ordena por prioridade;
8
+ - caixa de entrada no Postgres: junta eventos por assunto, descarta repetido (por fonte),
9
+ ordena por prioridade; evento novo acorda o agente, e o cron fica como rede de segurança;
8
10
  - rodadas com lock, teto de itens e de tempo, backoff e exceção para o DRI;
9
11
  - portão de política em toda chamada de ferramenta: nível por rotina (shadow, copilot,
10
12
  agent, autonomous), proibidas, motivo obrigatório, idempotência, janela e teto por hora;
@@ -12,13 +14,100 @@ Runtime dos **colaboradores digitais** da Tech for Humans. Um agente é uma past
12
14
  - memória curta (SQLite, uma execução) e longa (Postgres);
13
15
  - acesso aos sistemas só pelo Enterprise MCP Gateway, com a identidade própria do agente
14
16
  (client do Keycloak com service account);
15
- - cérebro: Claude Agent SDK isolado (sem ferramentas built-in, sem config do disco).
17
+ - cérebro: Claude Agent SDK isolado (sem ferramentas built-in, sem config do disco);
18
+ - o conector `agents_<círculo>` (proto, handlers e catálogo base, versionados juntos),
19
+ o ambiente validado no boot e o processo inteiro em `startAgents()`.
16
20
 
17
- O template de repositório de agentes e o agente de referência vivem em
18
- [`t4h-agents`](https://github.com/tech4humans-brasil/t4h-agents).
21
+ Cada círculo cria o seu repositório de agentes a partir de um template (ver
22
+ [Usar como template](../../web/src/content/agents/01-usar-como-template.md)). A documentação
23
+ completa está na seção **Agentes** do site do gateway.
19
24
 
20
25
  ```bash
21
26
  pnpm --filter @t4h/agent-runtime build
22
27
  pnpm --filter @t4h/agent-runtime test # sem modelo: ScriptedBrain + PGlite
23
28
  t4h-agent validate agents/ # valida os agent.yaml de um repositório
29
+ t4h-agent catalog financeiro --endpoint agentes-financeiro.example.com:443 > catalog.yaml
24
30
  ```
31
+
32
+ ## Entrypoint de um repositório de agentes
33
+
34
+ ```ts
35
+ import { startAgents } from '@t4h/agent-runtime';
36
+
37
+ await startAgents({ agentsDir: 'agents', pluginsDir: process.env.PLUGINS_DIR });
38
+ ```
39
+
40
+ `startAgents` carrega os agentes, valida o ambiente (`loadAgentEnv`), abre o banco e roda
41
+ as migrações, sobe o webhook de eventos, o cron e o conector gRPC (`createProviderServer`
42
+ do SDK, auditoria em JSON no stdout) e trata SIGINT/SIGTERM parando na ordem: entrada,
43
+ conector, conversas em andamento, banco. Opções: `wiring` (substitui o gateway por um stub
44
+ local; recusado em produção), `notifier`, `brain`. Fora de produção, sem as variáveis do
45
+ passaporte, sobe sem o conector (com aviso).
46
+
47
+ ## Conector `agents_<círculo>`
48
+
49
+ Contrato em `proto/t4h/agents/v1/agents.proto` (`AGENTS_SERVICE_FQN`, `agentsProtoPath()`),
50
+ handlers em `agentsConnectorHandlers(host)` e catálogo base em
51
+ `catalog/agents.catalog.yaml` (`agentsCatalog({ circle, endpoint })` ou
52
+ `t4h-agent catalog`). O slug segue `^agents_[a-z0-9_]+$`. Os grants são por tabela:
53
+
54
+ | Tabela | Tools | Quem recebe |
55
+ |---|---|---|
56
+ | `agente` | `agents_list`, `agent_ask`, `agent_answer` | quem pode ver e conversar com os agentes |
57
+ | `acao` | `agent_explain`, `action_correct` | quem audita e corrige |
58
+ | `proposta` | `agent_proposals`, `proposal_decide` | quem aprova (líder do time, DRI) |
59
+ | `controle` | `agent_block`, `routine_cap` | só Segurança e o DRI |
60
+
61
+ A conversa é assíncrona: o gateway corta a chamada ao provider em
62
+ `PROVIDER_CALL_TIMEOUT_MS` (30 s por padrão). `agent_ask` espera até `AGENTS_ASK_WAIT_MS`
63
+ (20 s) e, se a resposta não veio, devolve `running` com o `ask_id`; `agent_answer` busca
64
+ depois, de qualquer réplica, e só para quem perguntou.
65
+
66
+ ## Eventos
67
+
68
+ `POST /agents/:id/events` com `x-t4h-source: <fonte>` e
69
+ `x-t4h-signature: t=<unix s>,v1=<hex>`, onde `v1 = HMAC-SHA256(segredo da fonte, "<t>.<corpo cru>")`
70
+ (`signEvent()` monta o header). Tolerância de 300 s. O id do evento é gravado como
71
+ `<fonte>:<id>`. `POST /agents/:id/rounds` só existe fora de produção.
72
+
73
+ ## Ambiente
74
+
75
+ | Variável | Produção | Padrão / fora de produção |
76
+ |---|---|---|
77
+ | `DATABASE_URL` | `postgres://…` obrigatório | `pglite:<pasta>` ou em memória |
78
+ | `EVENTS_HMAC_SECRETS` | `fonte=segredo,…`, ao menos uma | sem: aceita sem assinatura |
79
+ | `EVENTS_PORT` / `EVENTS_WAKE_DEBOUNCE_MS` | | 8080 / 10000 |
80
+ | `GATEWAY_URL`, `KEYCLOAK_ISSUER` | obrigatórios | sem `GATEWAY_URL`: `wiring` local |
81
+ | `AGENT_<ID>_CLIENT_SECRET` | um por agente (hífen vira `_`) | |
82
+ | `GATEWAY_DEV_TOKEN` | proibido | token fixo no lugar do Keycloak |
83
+ | `ANTHROPIC_ORGANIZATION_ID`, `ANTHROPIC_FEDERATION_RULE_ID`, `ANTHROPIC_SERVICE_ACCOUNT_ID` (`ANTHROPIC_WORKSPACE_ID`) | credencial do modelo por federação (ou `ANTHROPIC_API_KEY`) | no GitHub Actions, a identidade é o OIDC do job |
84
+ | `ANTHROPIC_IDENTITY_SOURCE` / `ANTHROPIC_KEYCLOAK_SCOPE` / `ANTHROPIC_OIDC_AUDIENCE` | | `keycloak` (`github-actions` no Actions) / `aud-claude-console` / `https://api.anthropic.com` |
85
+ | `AGENTS_ASK_WAIT_MS` | | 20000, abaixo de `PROVIDER_CALL_TIMEOUT_MS` (30000) |
86
+ | `PORT`, `GATEWAY_JWKS_URL`, `GATEWAY_ISSUER`, `SERVICE_AUDIENCE`, mTLS | como em `loadProviderEnv()` | sem passaporte: sem conector |
87
+
88
+ ## Credencial do modelo sem API key (0.3)
89
+
90
+ Com os IDs de Workload Identity Federation da Anthropic no ambiente, o runtime troca um JWT
91
+ por um token curto da API e o entrega ao Claude Code de cada execução
92
+ (`ANTHROPIC_AUTH_TOKEN`). A troca é feita uma vez, no runtime, e não em cada processo: o JWT
93
+ tem `jti` de uso único, e cada troca pede um JWT novo.
94
+
95
+ - **Aplicação (`keycloak`):** o client do próprio agente (`agent-<id>`) faz
96
+ `client_credentials` no escopo `aud-claude-console`. O agente usa o modelo com a mesma
97
+ identidade com que usa o gateway.
98
+ - **CI dos evals (`github-actions`):** o token OIDC do job (`permissions: id-token: write`),
99
+ sem segredo no repositório. É o padrão quando `ACTIONS_ID_TOKEN_REQUEST_URL` existe.
100
+ - `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, profile ou Bedrock/Vertex continuam valendo
101
+ (o Claude Code resolve sozinho). Uma API key junto com os IDs da federação falha no boot,
102
+ porque a key venceria em silêncio.
103
+
104
+ ## Da 0.1 para a 0.2
105
+
106
+ - O conector (proto, handlers, catálogo) e o wiring do gateway saíram do template e
107
+ vieram para cá; o template deixa de depender de `@t4h/mcp-provider-sdk` e `@grpc/grpc-js`.
108
+ - `AskAgent` agora devolve `ask_id`/`status` e ganhou `GetAnswer`; `conversation_id` virou
109
+ `thread_id`. RPCs novas: `SetBlocked` e `CapRoutine` (tabela `controle`).
110
+ - `host.listen(port, secret)` virou `host.listen(port, { secrets, allowManualRounds, production })`;
111
+ `EVENTS_HMAC_SECRET` virou `EVENTS_HMAC_SECRETS` (por fonte, com timestamp) e
112
+ `verifySignature` saiu (use `verifyEventSignature`).
113
+ - Migração aditiva: tabela `agent_conversation` e coluna `agent_event.source`.
@@ -0,0 +1,123 @@
1
+ # Catálogo do conector de agentes de um círculo, gerado por
2
+ # t4h-agent catalog {{circle}} --endpoint {{endpoint}}
3
+ # a partir do catálogo base do @t4h/agent-runtime (versionado junto do proto). Não edite à
4
+ # mão: gere de novo com a versão do runtime que o círculo usa.
5
+ #
6
+ # Cada chave de inputSchema.properties é um campo do request no proto (snake_case). Grants
7
+ # (URN `agents_{{circle}}:<resourceTable>:<campo>`) seguem o fluxo de permissões da
8
+ # plataforma, nunca este arquivo:
9
+ # agente: agents, agent_id, ask_id, status, answer, error quem pode ver e conversar com os agentes
10
+ # acao: actions, action_id, status, routine_level quem audita e corrige
11
+ # proposta: proposals, action_id, status, result_json quem aprova (líder do time, DRI)
12
+ # controle: agent_id, blocked, routine, level só Segurança e o DRI
13
+ subservice: agents_{{circle}}
14
+ endpoints:
15
+ local: '{{local_endpoint}}'
16
+ production: '{{endpoint}}'
17
+ tools:
18
+ - name: agents_list
19
+ rpc: ListAgents
20
+ description: 'Lista os colaboradores digitais deste círculo: o que cada um faz, o nível de cada rotina agora (e por que desceu, se desceu), DRI, time e se está bloqueado.'
21
+ resourceTable: agente
22
+ readOnly: true
23
+ inputSchema: { type: object, properties: {} }
24
+
25
+ - name: agent_ask
26
+ rpc: AskAgent
27
+ description: 'Conversa com um agente. Ele só lê, com o acesso dele. Se a resposta vier com status "running", chame agent_answer com o ask_id em alguns segundos; se vier "error", agent_answer traz o motivo. Cada pessoa tem um teto de perguntas em andamento com o mesmo agente. Para pedir uma ação, abra a demanda pelo canal normal.'
28
+ resourceTable: agente
29
+ readOnly: false
30
+ inputSchema:
31
+ type: object
32
+ properties:
33
+ agent_id: { type: string }
34
+ message: { type: string }
35
+ thread_id: { type: string, description: 'Opcional: para continuar uma conversa, passe o ask_id da primeira pergunta (ou um id seu: até 64 letras, dígitos, "_" ou "-"). O agente recebe as últimas trocas desse fio feitas por você.' }
36
+ required: [agent_id, message]
37
+
38
+ - name: agent_answer
39
+ rpc: GetAnswer
40
+ description: 'Busca a resposta de uma pergunta feita com agent_ask. Enquanto vier "running", espere alguns segundos e chame de novo. Só quem perguntou lê a resposta.'
41
+ resourceTable: agente
42
+ readOnly: true
43
+ inputSchema:
44
+ type: object
45
+ properties:
46
+ ask_id: { type: string }
47
+ required: [ask_id]
48
+
49
+ - name: agent_explain
50
+ rpc: ExplainActions
51
+ description: 'Mostra o que um agente fez, em que modo (executou, propôs, só registrou, foi barrado) e com que motivo. Filtra por assunto (ex.: ticket:123).'
52
+ resourceTable: acao
53
+ readOnly: true
54
+ inputSchema:
55
+ type: object
56
+ properties:
57
+ agent_id: { type: string }
58
+ subject: { type: string }
59
+ limit: { type: integer, minimum: 1, maximum: 100 }
60
+ required: [agent_id]
61
+
62
+ - name: agent_proposals
63
+ rpc: ListProposals
64
+ description: 'Propostas de um agente esperando aprovação de uma pessoa (rotinas no nível Copiloto).'
65
+ resourceTable: proposta
66
+ readOnly: true
67
+ inputSchema:
68
+ type: object
69
+ properties:
70
+ agent_id: { type: string }
71
+ required: [agent_id]
72
+
73
+ - name: proposal_decide
74
+ rpc: DecideProposal
75
+ description: 'Aprova ou recusa uma proposta. Aprovada, a ação roda na hora com a identidade do agente e fica registrada com quem aprovou.'
76
+ resourceTable: proposta
77
+ readOnly: false
78
+ inputSchema:
79
+ type: object
80
+ properties:
81
+ action_id: { type: integer }
82
+ approve: { type: boolean }
83
+ note: { type: string }
84
+ required: [action_id, approve]
85
+
86
+ - name: action_correct
87
+ rpc: CorrectAction
88
+ description: 'Corrige uma ação que o agente executou: diga o que estava errado e o certo. Vira aprendizado e conta no disjuntor, que desce o nível da rotina se os erros passarem do limite.'
89
+ resourceTable: acao
90
+ readOnly: false
91
+ inputSchema:
92
+ type: object
93
+ properties:
94
+ action_id: { type: integer }
95
+ note: { type: string }
96
+ required: [action_id, note]
97
+
98
+ - name: agent_block
99
+ rpc: SetBlocked
100
+ description: 'Bloqueio de emergência: blocked=true para tudo o que o agente faz na hora, sem deploy (motivo obrigatório); blocked=false libera. Avisa o DRI e Segurança.'
101
+ resourceTable: controle
102
+ readOnly: false
103
+ inputSchema:
104
+ type: object
105
+ properties:
106
+ agent_id: { type: string }
107
+ blocked: { type: boolean }
108
+ reason: { type: string }
109
+ required: [agent_id, blocked]
110
+
111
+ - name: routine_cap
112
+ rpc: CapRoutine
113
+ description: 'Limita o nível de uma rotina do agente (shadow, copilot ou agent), com motivo. Com level vazio, tira o teto e volta a valer o nível do manifesto. Avisa o DRI e Segurança.'
114
+ resourceTable: controle
115
+ readOnly: false
116
+ inputSchema:
117
+ type: object
118
+ properties:
119
+ agent_id: { type: string }
120
+ routine: { type: string }
121
+ level: { type: string, enum: ['', shadow, copilot, agent] }
122
+ reason: { type: string }
123
+ required: [agent_id, routine, level]
package/dist/brain.d.ts CHANGED
@@ -14,6 +14,7 @@
14
14
  */
15
15
  import { type McpServerConfig } from '@anthropic-ai/claude-agent-sdk';
16
16
  import type { LoadedAgent } from './manifest.js';
17
+ import { type ModelAuth } from './model-auth.js';
17
18
  import type { PolicyGate } from './policy.js';
18
19
  import type { ResolvedSkills } from './plugins.js';
19
20
  import type { RuntimeTools } from './runtime-tools.js';
@@ -41,8 +42,15 @@ export interface Brain {
41
42
  }
42
43
  export declare class ClaudeBrain implements Brain {
43
44
  private readonly opts;
45
+ private readonly modelAuth;
46
+ /**
47
+ * `modelAuth`: de onde vem a credencial do modelo. Padrão: do ambiente
48
+ * (`modelAuthFromEnv`), o que cobre a federação pelo Keycloak na aplicação e pelo OIDC do
49
+ * GitHub nos evals da CI. `null`: deixa o Claude Code resolver sozinho.
50
+ */
44
51
  constructor(opts?: {
45
52
  debug?: boolean;
53
+ modelAuth?: ModelAuth | null;
46
54
  });
47
55
  run(task: BrainTask): Promise<BrainResult>;
48
56
  }
package/dist/brain.js CHANGED
@@ -13,13 +13,21 @@
13
13
  * Os testes usam um Brain roteirizado que chama o mesmo portão, sem modelo.
14
14
  */
15
15
  import { query } from '@anthropic-ai/claude-agent-sdk';
16
+ import { childEnv, modelAuthFromEnv } from './model-auth.js';
16
17
  function isErrorResponse(r) {
17
18
  return typeof r === 'object' && r !== null && r.isError === true;
18
19
  }
19
20
  export class ClaudeBrain {
20
21
  opts;
22
+ modelAuth;
23
+ /**
24
+ * `modelAuth`: de onde vem a credencial do modelo. Padrão: do ambiente
25
+ * (`modelAuthFromEnv`), o que cobre a federação pelo Keycloak na aplicação e pelo OIDC do
26
+ * GitHub nos evals da CI. `null`: deixa o Claude Code resolver sozinho.
27
+ */
21
28
  constructor(opts = {}) {
22
29
  this.opts = opts;
30
+ this.modelAuth = opts.modelAuth === undefined ? modelAuthFromEnv() : (opts.modelAuth ?? undefined);
23
31
  }
24
32
  async run(task) {
25
33
  const { gate } = task;
@@ -53,6 +61,8 @@ export class ClaudeBrain {
53
61
  return d.allow ? { behavior: 'allow', updatedInput: input } : { behavior: 'deny', message: d.message };
54
62
  };
55
63
  const m = task.agent.manifest;
64
+ // Token curto do modelo, trocado pelo runtime (federação); sem ele, o Claude Code resolve.
65
+ const auth = this.modelAuth ? await this.modelAuth.env(task.agent) : undefined;
56
66
  let text = '';
57
67
  let costUsd = 0;
58
68
  let turns = 0;
@@ -80,6 +90,7 @@ export class ClaudeBrain {
80
90
  ...(task.budgetUsd ? { maxBudgetUsd: task.budgetUsd } : {}),
81
91
  persistSession: false,
82
92
  abortController,
93
+ ...(auth ? { env: childEnv(process.env, auth) } : {}),
83
94
  ...(this.opts.debug ? { stderr: (s) => process.stderr.write(s) } : {}),
84
95
  },
85
96
  });
package/dist/brain.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"brain.js","sourceRoot":"","sources":["../src/brain.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"brain.js","sourceRoot":"","sources":["../src/brain.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /** `agents_<círculo>`: o schema do catálogo não aceita hífen no subservice. */
2
+ export declare const AGENTS_SLUG_PATTERN: RegExp;
3
+ export declare function agentsCatalogPath(): string;
4
+ export interface AgentsCatalogOptions {
5
+ /** Nome do círculo em minúsculas, com `_` no lugar de hífen: `financeiro`, `dados_bi`. */
6
+ circle: string;
7
+ /** Endpoint gRPC de produção do conector (`host:porta`). */
8
+ endpoint: string;
9
+ /** Endpoint para TARGET_ENV=local. Padrão: o mesmo de `endpoint`. */
10
+ localEndpoint?: string;
11
+ }
12
+ /** O catálogo de `agents_<círculo>` em YAML, pronto para o repositório de catálogos. */
13
+ export declare function agentsCatalog(o: AgentsCatalogOptions): string;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Catálogo do conector `agents_<círculo>`: o base (`catalog/agents.catalog.yaml`) mora
3
+ * aqui, versionado junto do proto, para tool e RPC nunca se desencontrarem. O repositório
4
+ * de catálogos do gateway gera o de cada círculo com `t4h-agent catalog`, sem escrever à mão.
5
+ */
6
+ import { readFileSync } from 'node:fs';
7
+ import { fileURLToPath } from 'node:url';
8
+ import { parse as parseYaml } from 'yaml';
9
+ /** `agents_<círculo>`: o schema do catálogo não aceita hífen no subservice. */
10
+ export const AGENTS_SLUG_PATTERN = /^agents_[a-z0-9_]+$/;
11
+ /** Mesmo padrão de endpoint do schema do catálogo (`host:porta`). */
12
+ const ENDPOINT_PATTERN = /^[a-zA-Z0-9.-]+:[0-9]{1,5}$/;
13
+ /** O subservice tem no máximo 50 caracteres (schema do catálogo). */
14
+ const MAX_SUBSERVICE = 50;
15
+ export function agentsCatalogPath() {
16
+ return fileURLToPath(new URL('../catalog/agents.catalog.yaml', import.meta.url));
17
+ }
18
+ /** O catálogo de `agents_<círculo>` em YAML, pronto para o repositório de catálogos. */
19
+ export function agentsCatalog(o) {
20
+ const slug = `agents_${o.circle}`;
21
+ if (!AGENTS_SLUG_PATTERN.test(slug) || slug.length > MAX_SUBSERVICE) {
22
+ throw new Error(`círculo "${o.circle}" inválido: use minúsculas, dígitos e _ (o slug ${slug} precisa casar ${AGENTS_SLUG_PATTERN} e ter até ${MAX_SUBSERVICE} caracteres)`);
23
+ }
24
+ const local = o.localEndpoint ?? o.endpoint;
25
+ for (const e of [o.endpoint, local]) {
26
+ if (!ENDPOINT_PATTERN.test(e))
27
+ throw new Error(`endpoint "${e}" inválido: use host:porta`);
28
+ }
29
+ const yaml = readFileSync(agentsCatalogPath(), 'utf8')
30
+ .replaceAll('{{circle}}', o.circle)
31
+ .replaceAll('{{local_endpoint}}', local)
32
+ .replaceAll('{{endpoint}}', o.endpoint);
33
+ // Falha aqui, e não no apply, se a substituição quebrar o YAML.
34
+ const parsed = parseYaml(yaml);
35
+ if (parsed.subservice !== slug)
36
+ throw new Error(`catálogo base gerou subservice "${parsed.subservice}", esperado ${slug}`);
37
+ return yaml;
38
+ }
39
+ //# sourceMappingURL=catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAE1C,+EAA+E;AAC/E,MAAM,CAAC,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AAEzD,qEAAqE;AACrE,MAAM,gBAAgB,GAAG,6BAA6B,CAAC;AAEvD,qEAAqE;AACrE,MAAM,cAAc,GAAG,EAAE,CAAC;AAE1B,MAAM,UAAU,iBAAiB;IAC/B,OAAO,aAAa,CAAC,IAAI,GAAG,CAAC,gCAAgC,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACnF,CAAC;AAWD,wFAAwF;AACxF,MAAM,UAAU,aAAa,CAAC,CAAuB;IACnD,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,MAAM,EAAE,CAAC;IAClC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,cAAc,EAAE,CAAC;QACpE,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC,MAAM,mDAAmD,IAAI,kBAAkB,mBAAmB,cAAc,cAAc,cAAc,CAAC,CAAC;IAC9K,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,QAAQ,CAAC;IAC5C,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC;QACpC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,4BAA4B,CAAC,CAAC;IAC7F,CAAC;IACD,MAAM,IAAI,GAAG,YAAY,CAAC,iBAAiB,EAAE,EAAE,MAAM,CAAC;SACnD,UAAU,CAAC,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC;SAClC,UAAU,CAAC,oBAAoB,EAAE,KAAK,CAAC;SACvC,UAAU,CAAC,cAAc,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC1C,gEAAgE;IAChE,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAA4B,CAAC;IAC1D,IAAI,MAAM,CAAC,UAAU,KAAK,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,MAAM,CAAC,UAAU,eAAe,IAAI,EAAE,CAAC,CAAC;IAC3H,OAAO,IAAI,CAAC;AACd,CAAC"}
package/dist/cli.js CHANGED
@@ -1,14 +1,16 @@
1
1
  /**
2
- * t4h-agent validate <pasta agents/> valida todos os agent.yaml (schema + regras)
2
+ * t4h-agent validate [pasta agents/] valida todos os agent.yaml (schema + regras)
3
+ * t4h-agent catalog <círculo> --endpoint <host:porta> imprime o catálogo de agents_<círculo>
4
+ * [--local-endpoint <host:porta>]
3
5
  */
4
- import { loadAgents } from './manifest.js';
6
+ import { parseArgs } from 'node:util';
7
+ import { agentsCatalog } from './catalog.js';
5
8
  import { effectiveLevel } from './levels.js';
6
- const [cmd, dir = 'agents'] = process.argv.slice(2);
7
- if (cmd !== 'validate') {
8
- console.error('uso: t4h-agent validate [pasta]');
9
- process.exit(2);
10
- }
11
- try {
9
+ import { loadAgents } from './manifest.js';
10
+ const USAGE = `uso:
11
+ t4h-agent validate [pasta]
12
+ t4h-agent catalog <círculo> --endpoint <host:porta> [--local-endpoint <host:porta>]`;
13
+ function validate(dir = 'agents') {
12
14
  const agents = loadAgents(dir);
13
15
  for (const a of agents) {
14
16
  const m = a.manifest;
@@ -20,6 +22,29 @@ try {
20
22
  }
21
23
  console.info(`\n${agents.length} agente(s) válido(s).`);
22
24
  }
25
+ function catalog(args) {
26
+ const { values, positionals } = parseArgs({
27
+ args,
28
+ allowPositionals: true,
29
+ options: { endpoint: { type: 'string' }, 'local-endpoint': { type: 'string' } },
30
+ });
31
+ const [circle] = positionals;
32
+ if (!circle || !values.endpoint || positionals.length > 1)
33
+ throw new Error(USAGE);
34
+ // Só o YAML no stdout: dá para redirecionar direto para o catalog.yaml.
35
+ process.stdout.write(agentsCatalog({ circle, endpoint: values.endpoint, ...(values['local-endpoint'] ? { localEndpoint: values['local-endpoint'] } : {}) }));
36
+ }
37
+ const [cmd, ...rest] = process.argv.slice(2);
38
+ try {
39
+ if (cmd === 'validate')
40
+ validate(rest[0]);
41
+ else if (cmd === 'catalog')
42
+ catalog(rest);
43
+ else {
44
+ console.error(USAGE);
45
+ process.exit(2);
46
+ }
47
+ }
23
48
  catch (e) {
24
49
  console.error(e.message);
25
50
  process.exit(1);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEpD,IAAI,GAAG,KAAK,UAAU,EAAE,CAAC;IACvB,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,CAAC;IACH,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAC/B,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,cAAc,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QAChF,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnD,MAAM,GAAG,GAAG,cAAc,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;YACvE,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACvH,CAAC;IACH,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,MAAM,uBAAuB,CAAC,CAAC;AAC1D,CAAC;AAAC,OAAO,CAAC,EAAE,CAAC;IACX,OAAO,CAAC,KAAK,CAAE,CAAW,CAAC,OAAO,CAAC,CAAC;IACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { type ProviderHandlers } from '@t4h/mcp-provider-sdk';
2
+ import { type AgentHost } from './host.js';
3
+ export declare const AGENTS_SERVICE_FQN = "t4h.agents.v1.AgentsService";
4
+ /** O proto do conector, publicado com o pacote (o gateway o puxa por reflection). */
5
+ export declare function agentsProtoPath(): string;
6
+ export interface AgentsConnectorOptions {
7
+ /** Quantas ações `ExplainActions` devolve sem `limit` (padrão 20) e no máximo (100). */
8
+ historyLimit?: {
9
+ default: number;
10
+ max: number;
11
+ };
12
+ }
13
+ export declare function agentsConnectorHandlers(host: AgentHost, opts?: AgentsConnectorOptions): ProviderHandlers;