@orkastery/cli 0.4.2 → 0.5.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/adapters/README.md +11 -0
- package/adapters/claude-code/.claude-plugin/plugin.json +3 -1
- package/adapters/claude-code/agents/ork-check.md +1 -1
- package/adapters/claude-code/agents/ork-go.md +2 -2
- package/adapters/claude-code/agents/ork-goal.md +1 -1
- package/adapters/claude-code/agents/ork-master.md +1 -1
- package/adapters/claude-code/agents/ork-plan.md +1 -1
- package/adapters/claude-code/agents/ork-ship.md +1 -1
- package/adapters/claude-code/commands/master.md +11 -8
- package/adapters/claude-code/commands/ork.md +8 -0
- package/adapters/claude-code/commands/ship.md +2 -2
- package/adapters/codex/skills/ork/SKILL.md +12 -1
- package/adapters/hermes/README.md +3 -0
- package/adapters/hermes/bin/ork-abrir-thread.sh +17 -2
- package/adapters/hermes/bin/ork-brain.sh +3 -0
- package/adapters/hermes/bin/ork-maestro.sh +4 -1
- package/adapters/hermes/bin/ork-network-roadmap.sh +11 -0
- package/adapters/hermes/bin/ork-roadmap-status.sh +9 -0
- package/adapters/hermes/hermes.plugin.json +2 -0
- package/adapters/hermes/hitl-ingress/__init__.py +36 -3
- package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +19 -20
- package/adapters/openclaw/README.md +34 -3
- package/adapters/openclaw/dist/hitl-ingress.js +37 -3
- package/adapters/openclaw/dist/index.js +92 -39
- package/adapters/openclaw/openclaw.plugin.json +10 -3
- package/adapters/openclaw/package.json +2 -2
- package/adapters/openclaw/src/hitl-ingress.ts +32 -3
- package/adapters/openclaw/src/index.ts +108 -41
- package/assets/docs/padroes/documentacao-de-produto.md +2 -2
- package/assets/docs/padroes/roadmap-de-produto.md +1 -1
- package/assets/docs/produto/_modelo-feature.md +2 -0
- package/assets/orkmind_bridge.py +214 -1
- package/dist/adapters/claude-bg.js +88 -9
- package/dist/adapters/codex-events.js +3 -1
- package/dist/board.js +74 -0
- package/dist/branch-de-estado.js +5 -4
- package/dist/busca-semantica.js +161 -0
- package/dist/ci.js +141 -10
- package/dist/company-brain-cli.js +27 -2
- package/dist/company-brain-context.js +132 -0
- package/dist/company-brain-dossie.js +376 -0
- package/dist/company-brain-mcp.js +4 -1
- package/dist/conducao.js +117 -31
- package/dist/decisao-autonoma.js +42 -0
- package/dist/docs.js +64 -22
- package/dist/doctor.js +33 -0
- package/dist/entrega-pr.js +109 -5
- package/dist/experiencia-instalacao.js +256 -0
- package/dist/experiencia.js +72 -0
- package/dist/fabrica-estado.js +43 -10
- package/dist/fechamento.js +105 -0
- package/dist/fix.js +1 -1
- package/dist/forja.js +435 -0
- package/dist/gates.js +10 -1
- package/dist/hitl-classificacao.js +11 -1
- package/dist/hitl-contract.js +50 -7
- package/dist/hitl-curto.js +158 -0
- package/dist/hitl-gates.js +67 -1
- package/dist/hitl-lote.js +30 -15
- package/dist/hitl-presentation.js +10 -7
- package/dist/hitl-resumo.js +33 -12
- package/dist/hitl-texto-livre.js +150 -0
- package/dist/hosts.js +86 -1
- package/dist/index.js +605 -41
- package/dist/indice-vetorial.js +317 -0
- package/dist/init.js +13 -0
- package/dist/integracoes-locais.js +1 -1
- package/dist/intelligence-benchmark-contract.js +570 -0
- package/dist/intelligence-graph-cli.js +430 -0
- package/dist/intelligence-graph-contract.js +577 -0
- package/dist/intelligence-graph-extract-md.js +469 -0
- package/dist/intelligence-graph-extract-ts.js +810 -0
- package/dist/intelligence-graph-extract.js +369 -0
- package/dist/intelligence-graph-index.js +512 -0
- package/dist/intelligence-graph-parsers.js +327 -0
- package/dist/intelligence-graph-query.js +344 -0
- package/dist/intelligence-graph-repo.js +187 -0
- package/dist/leases.js +84 -0
- package/dist/ledger.js +14 -0
- package/dist/maestro-cli.js +10 -1
- package/dist/maestro-contract.js +5 -1
- package/dist/maestro-discovery.js +16 -2
- package/dist/maestro-snapshot.js +6 -2
- package/dist/manifest.js +142 -5
- package/dist/master-batch.js +3 -2
- package/dist/master-digest.js +2 -2
- package/dist/master-nota.js +203 -0
- package/dist/master.js +4 -0
- package/dist/mcp-experiencia.js +164 -0
- package/dist/mcp-git.js +36 -10
- package/dist/mcp-install.js +3 -1
- package/dist/mcp-maestro.js +3 -2
- package/dist/mcp-server.js +84 -5
- package/dist/memoria.js +147 -1
- package/dist/network-roadmap.js +907 -0
- package/dist/ocupacao.js +38 -2
- package/dist/onboarding.js +113 -7
- package/dist/orkmind.js +165 -9
- package/dist/phase.js +166 -13
- package/dist/policies.js +2 -0
- package/dist/projeto-alvo.js +551 -0
- package/dist/prompts.js +1 -1
- package/dist/pulse-consentimento.js +4 -2
- package/dist/pulse-delivery.js +5 -0
- package/dist/pulse-resposta.js +674 -49
- package/dist/pulse.js +21 -0
- package/dist/ratelimit.js +3 -2
- package/dist/retry.js +230 -9
- package/dist/roadmap-reservas.js +262 -20
- package/dist/roadmap-status.js +213 -0
- package/dist/runtime-ambiente.js +12 -1
- package/dist/session-watcher-claude.js +26 -0
- package/dist/sessoes.js +49 -15
- package/dist/thread-close.js +3 -0
- package/dist/verify.js +5 -4
- package/dist/worktree.js +77 -0
- package/eval/casos/orchestration-experience-pt-br.json +48 -0
- package/eval/casos/orchestration-experience.json +48 -0
- package/package.json +1 -1
- package/schemas/code-artifact-graph.v1.schema.json +581 -0
- package/schemas/graph-benchmark.v1.schema.json +2240 -0
- package/schemas/maestro-snapshot.schema.json +23 -0
- package/skills/README.md +7 -5
- package/skills/core/onboarding/SKILL.md +7 -0
- package/skills/core/orchestration-experience/SKILL.md +113 -0
- package/skills/core/orchestration-experience-pt-br/SKILL.md +112 -0
- package/skills/core/orkastery-bootstrap/SKILL.md +2 -2
- package/skills/phases/go-implementation/SKILL.md +2 -0
package/dist/pulse.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.JANELA_DAS_DECISOES_MS = exports.CONTRATO_PULSE = void 0;
|
|
4
|
+
exports.apresentacaoCurtaDoItem = apresentacaoCurtaDoItem;
|
|
4
5
|
exports.comporPulse = comporPulse;
|
|
5
6
|
exports.montarPulse = montarPulse;
|
|
6
7
|
exports.textoDoPulse = textoDoPulse;
|
|
@@ -20,6 +21,7 @@ const util_1 = require("./util");
|
|
|
20
21
|
const horario_1 = require("./horario");
|
|
21
22
|
const hitl_presentation_1 = require("./hitl-presentation");
|
|
22
23
|
const hitl_contract_1 = require("./hitl-contract");
|
|
24
|
+
const hitl_curto_1 = require("./hitl-curto");
|
|
23
25
|
const decisao_autonoma_1 = require("./decisao-autonoma");
|
|
24
26
|
const docs_1 = require("./docs");
|
|
25
27
|
const conducao_1 = require("./conducao");
|
|
@@ -30,6 +32,18 @@ exports.JANELA_DAS_DECISOES_MS = 7 * 24 * 60 * 60 * 1000;
|
|
|
30
32
|
const impacto = (fase) => types_1.FASES.indexOf(fase) + 1;
|
|
31
33
|
const ordenar = (a, b) => (b.paradaHaMin ?? -1) - (a.paradaHaMin ?? -1) || b.impacto - a.impacto || a.id.localeCompare(b.id);
|
|
32
34
|
const minutos = (desde, quando) => desde && Number.isFinite(Date.parse(desde)) ? Math.max(0, Math.floor((Date.parse(quando) - Date.parse(desde)) / 60000)) : null;
|
|
35
|
+
/**
|
|
36
|
+
* RM-048 (D1 e D4): o texto curto de uma pergunta v2 de gate e a linha com o codigo estavel.
|
|
37
|
+
* Pedido sem codigo (v1, sessao) continua com o comando de antes: nada e inventado para ele.
|
|
38
|
+
*/
|
|
39
|
+
function apresentacaoCurtaDoItem(pedido, desde, quando) {
|
|
40
|
+
if (!(0, hitl_contract_1.ehV2)(pedido) || pedido.classe !== 'pergunta' || pedido.alvo.tipo !== 'gate')
|
|
41
|
+
return undefined;
|
|
42
|
+
const curto = (0, hitl_curto_1.montarPedidoCurto)((0, hitl_curto_1.entradaDoPedido)(pedido, desde ?? pedido.criadoEm), { quando, responder: { tipo: 'codigo', codigo: pedido.codigo } });
|
|
43
|
+
const recomendada = pedido.alternativas.find(a => a.recomendada)?.letra ?? 'a';
|
|
44
|
+
return { textos: { telegram: (0, hitl_curto_1.textoDoPedidoCurto)(curto, 'telegram'), terminal: (0, hitl_curto_1.textoDoPedidoCurto)(curto, 'terminal') },
|
|
45
|
+
comando: `${pedido.codigo} ${recomendada}` };
|
|
46
|
+
}
|
|
33
47
|
function comporPulse(carregado, entrada) {
|
|
34
48
|
const { radar, monitor, batch, orfas } = entrada, quando = radar.consultadoEm;
|
|
35
49
|
const humanos = [], automaticas = [];
|
|
@@ -186,6 +200,13 @@ function comporPulse(carregado, entrada) {
|
|
|
186
200
|
item.opcoes = (0, hitl_contract_1.escolhasDoPedido)(pedido).map(o => `${(0, hitl_contract_1.chaveDaEscolha)(pedido, o.numero)}. ${o.texto}`);
|
|
187
201
|
item.recomendacao = (0, hitl_contract_1.recomendacaoDoPedido)(pedido);
|
|
188
202
|
item.comandoResposta = `/ork ${(0, hitl_contract_1.alvoDoPedido)(pedido)?.tipo === 'session' ? 'session' : 'gate'} ${pedido.thread} ${pedido.id} <resposta>`;
|
|
203
|
+
// RM-048 (D1 e D4): a pergunta v2 de gate sai pelo contrato curto, e a linha que o dono
|
|
204
|
+
// recebe e o codigo estavel ("DE6H a"), nao o identificador que muda a cada renovacao.
|
|
205
|
+
const curta = apresentacaoCurtaDoItem(pedido, item.desdeEm, quando);
|
|
206
|
+
if (curta) {
|
|
207
|
+
item.apresentacaoCurta = curta.textos;
|
|
208
|
+
item.comandoResposta = curta.comando;
|
|
209
|
+
}
|
|
189
210
|
// O Pulse nao e uma conexao MCP: nenhum canal mcp-local sai `disponivel` daqui.
|
|
190
211
|
item.canais = (0, hitl_presentation_1.ofertaDoPedido)(pedido);
|
|
191
212
|
}
|
package/dist/ratelimit.js
CHANGED
|
@@ -144,7 +144,7 @@ function enfileirar(carregado, novo, agoraMs = Date.now()) {
|
|
|
144
144
|
* ela, a janela padrao do manifesto (estimativa declarada, nunca chute). Auth ausente: sem prazo.
|
|
145
145
|
*/
|
|
146
146
|
function prazoDaConta(manifesto, falha, agoraMs = Date.now()) {
|
|
147
|
-
if (falha.motivo
|
|
147
|
+
if (falha.motivo !== 'runtime.quota-exhausted')
|
|
148
148
|
return null;
|
|
149
149
|
// A10: horario dito que ja passou nao devolve o perfil ao rodizio na hora: vale a janela padrao.
|
|
150
150
|
if (falha.resetEm !== null && Date.parse(falha.resetEm) > agoraMs)
|
|
@@ -153,7 +153,8 @@ function prazoDaConta(manifesto, falha, agoraMs = Date.now()) {
|
|
|
153
153
|
}
|
|
154
154
|
/** Marca no store o perfil que falhou pela conta. Sem perfil (ambiente do processo), nada a marcar. */
|
|
155
155
|
function marcarContaDaFalha(carregado, perfil, falha, agoraMs = Date.now()) {
|
|
156
|
-
|
|
156
|
+
// RM-037 (defeitosdeco D-6): modelo inacessivel nao e falha da conta inteira; o perfil fica no rodizio.
|
|
157
|
+
if (!perfil || falha.motivo === 'runtime.model-unavailable')
|
|
157
158
|
return null;
|
|
158
159
|
const esgotado = falha.motivo === 'runtime.quota-exhausted';
|
|
159
160
|
return (0, runtime_profiles_1.marcarFalhaDePerfil)(carregado.raiz, perfil.id, { estado: esgotado ? 'esgotado' : 'sem-auth',
|
package/dist/retry.js
CHANGED
|
@@ -93,6 +93,7 @@ const policies_1 = require("./policies");
|
|
|
93
93
|
const ratelimit_1 = require("./ratelimit");
|
|
94
94
|
const session_watcher_claude_1 = require("./session-watcher-claude");
|
|
95
95
|
const runtime_profiles_1 = require("./runtime-profiles");
|
|
96
|
+
const modos_1 = require("./modos");
|
|
96
97
|
const thread_1 = require("./thread");
|
|
97
98
|
const tokens_1 = require("./tokens");
|
|
98
99
|
const util_1 = require("./util");
|
|
@@ -241,6 +242,15 @@ exports.POLITICA_DE_RETRY = {
|
|
|
241
242
|
porque: 'a conta do runtime perdeu a autenticacao: o perfil nunca mais recebe despacho ate o login ser refeito pelo proprio CLI, e o MESMO prompt segue no proximo perfil ou no runtime de fallback',
|
|
242
243
|
correcao: 'ork accounts check confere o login de cada perfil; ork retry run <thread> rotaciona o prompt ja gravado',
|
|
243
244
|
},
|
|
245
|
+
// RM-037 (defeitosdeco D-6): o modelo e que falta, nao a conta. Repetir o mesmo modelo na mesma conta
|
|
246
|
+
// so repete a recusa; o perfil continua no rodizio para os outros modelos.
|
|
247
|
+
'runtime.model-unavailable': {
|
|
248
|
+
motivo: 'runtime.model-unavailable',
|
|
249
|
+
acao: 'reexecutar',
|
|
250
|
+
automatica: true,
|
|
251
|
+
porque: 'o modelo pedido nao existe ou a conta nao tem acesso a ele: o MESMO prompt, com o mesmo sha256, segue no proximo perfil do mesmo runtime com o mesmo modelo e depois no fallback do bloco, nunca de novo no par que ja recusou',
|
|
252
|
+
correcao: 'ork retry run <thread> troca o destino; sem destino, ork setup <modo> --bloco N --model <modelo acessivel> ou --fallback runtime:modelo',
|
|
253
|
+
},
|
|
244
254
|
'tree.blocked': {
|
|
245
255
|
motivo: 'tree.blocked',
|
|
246
256
|
acao: 'sincronizar-worktree',
|
|
@@ -472,10 +482,29 @@ function escalarEsforco(base, degraus) {
|
|
|
472
482
|
* de provider pago enquanto a fase esperava, a retomada recusa em vez de gastar.
|
|
473
483
|
*/
|
|
474
484
|
function redespachar(carregado, thread, fase, promptRelativo, sha, opcoes = {}) {
|
|
475
|
-
const run = () => redespacharSobLock(carregado, (0, thread_1.lerThread)(carregado.raiz, thread.id), fase, promptRelativo, sha, opcoes);
|
|
476
|
-
|
|
485
|
+
const run = (retida) => redespacharSobLock(carregado, (0, thread_1.lerThread)(carregado.raiz, thread.id), fase, promptRelativo, sha, opcoes, retida);
|
|
486
|
+
if (opcoes.dryRun)
|
|
487
|
+
return run();
|
|
488
|
+
// RM-037 (defeito 1; A2, G1 e N3 do CHECK 1 e 2, B-1 e A-1r do CHECK 4): o fallback do bloco leva a
|
|
489
|
+
// retomada ao codex. O redespacho pede a baseline depois das guardas baratas, RETENDO a conducao tomada; ela
|
|
490
|
+
// e gravada aqui, fora do lock HITL, como reentrada dessa tomada, e a retomada repete uma vez com ela.
|
|
491
|
+
const r = (0, hitl_gates_1.comLockHitl)(carregado.raiz, thread.id, () => run());
|
|
492
|
+
const retida = r.retida;
|
|
493
|
+
if (!retida)
|
|
494
|
+
return r;
|
|
495
|
+
delete r.retida;
|
|
496
|
+
try {
|
|
497
|
+
(0, phase_1.garantirBaselineDoDespacho)(carregado, thread.id, { fase, prompt: '', runtime: opcoes.runtime ?? undefined,
|
|
498
|
+
model: opcoes.model ?? undefined, effort: opcoes.effort ?? undefined, ...(opcoes.canal ? { canal: opcoes.canal } : {}) }, retida.identidade);
|
|
499
|
+
return (0, hitl_gates_1.comLockHitl)(carregado.raiz, thread.id, () => run(retida));
|
|
500
|
+
}
|
|
501
|
+
finally {
|
|
502
|
+
retida.devolver();
|
|
503
|
+
}
|
|
477
504
|
}
|
|
478
|
-
function redespacharSobLock(carregado, thread, fase, promptRelativo, sha, opcoes = {}
|
|
505
|
+
function redespacharSobLock(carregado, thread, fase, promptRelativo, sha, opcoes = {},
|
|
506
|
+
/** A tomada que a primeira passada reteve para a baseline; com ela, esta e a repeticao. */
|
|
507
|
+
tomadaPrevia) {
|
|
479
508
|
const { raiz, manifesto } = carregado;
|
|
480
509
|
const absoluto = path.isAbsolute(promptRelativo)
|
|
481
510
|
? promptRelativo
|
|
@@ -526,13 +555,24 @@ function redespacharSobLock(carregado, thread, fase, promptRelativo, sha, opcoes
|
|
|
526
555
|
// I-36 (T6): validado o pedido, a retomada toma a conducao antes de redespachar, como o
|
|
527
556
|
// `ork phase run`. A mesma fase com o mesmo prompt de quem ja conduz nao abre sessao nova;
|
|
528
557
|
// outro pedido espera a vez.
|
|
529
|
-
const identidade = (0, runtime_context_1.novaIdentidadeDeDespacho)(thread.id, fase)
|
|
558
|
+
const identidade = tomadaPrevia ? { ...(0, runtime_context_1.novaIdentidadeDeDespacho)(thread.id, fase), dispatchId: tomadaPrevia.identidade }
|
|
559
|
+
: (0, runtime_context_1.novaIdentidadeDeDespacho)(thread.id, fase);
|
|
530
560
|
const canal = opcoes.canal ?? (0, conducao_1.canalDoProcesso)();
|
|
531
561
|
const doBlocoDaConducao = (0, setup_1.limitesDoBloco)(manifesto, (0, setup_1.lerSetup)(raiz), thread.modo, fase);
|
|
532
562
|
const pedidoDeConducao = { canal, correlacao: null, operacao: 'retry.run', fase, promptSha256: sha,
|
|
533
563
|
identidade: identidade.dispatchId, prazoMs: (0, phase_1.prazoDaSessao)(doBlocoDaConducao) };
|
|
534
564
|
let conducao = null;
|
|
535
|
-
if (
|
|
565
|
+
if (tomadaPrevia) {
|
|
566
|
+
// R5-B1 do CHECK 5: a sucedida que o dono respondeu durante a baseline recebe o lease de volta.
|
|
567
|
+
if (!tomadaPrevia.sucessaoAindaVale()) {
|
|
568
|
+
tomadaPrevia.devolver();
|
|
569
|
+
const recusa = (0, conducao_1.recusaDeConducao)(thread.id, (0, conducao_1.conducaoDaThread)(raiz, thread.id), pedidoDeConducao);
|
|
570
|
+
(0, conducao_1.registrarRecusa)(raiz, recusa);
|
|
571
|
+
return { ...vazio, ok: false, motivo: 'conducao.em-andamento', detalhe: recusa.texto, dryRun: false };
|
|
572
|
+
}
|
|
573
|
+
conducao = tomadaPrevia;
|
|
574
|
+
}
|
|
575
|
+
else if (!opcoes.dryRun) {
|
|
536
576
|
const tomada = (0, conducao_1.tomarConducao)(raiz, thread.id, pedidoDeConducao);
|
|
537
577
|
if (!tomada.ok) {
|
|
538
578
|
if (tomada.idempotente && tomada.atual) {
|
|
@@ -561,6 +601,17 @@ function redespacharSobLock(carregado, thread, fase, promptRelativo, sha, opcoes
|
|
|
561
601
|
effort: opcoes.effort ?? undefined,
|
|
562
602
|
}, doBloco);
|
|
563
603
|
const rt = (0, runtimes_1.resolverRuntime)(runtime);
|
|
604
|
+
if (!opcoes.dryRun && (0, phase_1.baselineDoDespachoNecessaria)(carregado, thread.id, { fase, prompt: '', runtime, model, effort })) {
|
|
605
|
+
// Na primeira passada a tomada fica retida para a baseline (o `finally` nao a solta); na repeticao, o
|
|
606
|
+
// `finally` devolve o que a tomada consumiu (A-1 do CHECK 3).
|
|
607
|
+
const pendente = { ...vazio, ok: false, motivo: 'runtime.unavailable', dryRun: false,
|
|
608
|
+
detalhe: `baseline.pendente: o bloco com GO no ${runtime} precisa da baseline antes da retomada` };
|
|
609
|
+
if (!tomadaPrevia && conducao) {
|
|
610
|
+
pendente.retida = conducao;
|
|
611
|
+
conducao = null;
|
|
612
|
+
}
|
|
613
|
+
return pendente;
|
|
614
|
+
}
|
|
564
615
|
// D14 (GO-FIX 2): a retomada claude-bg abre com a mesma colaboração e o mesmo contexto de
|
|
565
616
|
// runtime do `ork phase run`; sem eles, o PLAN retomado saía sem negar Edit, Write e
|
|
566
617
|
// NotebookEdit e sem a allowlist do núcleo. O ramo Codex não muda.
|
|
@@ -605,7 +656,8 @@ function redespacharSobLock(carregado, thread, fase, promptRelativo, sha, opcoes
|
|
|
605
656
|
logDir: path.join((0, thread_1.dirThread)(raiz, thread.id), 'sessoes'),
|
|
606
657
|
vinculo: { thread: thread.id, fase, promptSha256: sha },
|
|
607
658
|
...(perfil ? { perfil } : {}),
|
|
608
|
-
|
|
659
|
+
// RM-037 (defeito 2): o modo plano segue a mesma regra do `ork phase run`, pelo bloco.
|
|
660
|
+
...(runtime === 'claude-bg' ? { contextoRuntime, ...((0, phase_1.modoDaSessaoDoBloco)(thread, fase).plano ? { colaboracao: 'plan' } : {}) } : {}),
|
|
609
661
|
// I-36 (D4): a sessao retomada herda a identidade do despacho e o canal, como no `ork phase run`.
|
|
610
662
|
ambienteExtra: (0, conducao_1.ambienteDaConducao)(identidade.dispatchId, thread.id, canal),
|
|
611
663
|
});
|
|
@@ -685,8 +737,9 @@ function redespacharSobLock(carregado, thread, fase, promptRelativo, sha, opcoes
|
|
|
685
737
|
};
|
|
686
738
|
}
|
|
687
739
|
finally {
|
|
688
|
-
// Retomada que nao virou sessao devolve a conducao; a que virou ja a
|
|
689
|
-
|
|
740
|
+
// Retomada que nao virou sessao devolve a conducao, com o que a tomada consumiu; a que virou ja a
|
|
741
|
+
// entregou a sessao, e devolver entao nao faz nada.
|
|
742
|
+
conducao?.devolver();
|
|
690
743
|
}
|
|
691
744
|
}
|
|
692
745
|
// ---------------------------------------------------------------------------
|
|
@@ -1218,6 +1271,9 @@ function executarRetry(carregado, threadId, opcoes = {}) {
|
|
|
1218
1271
|
if (plano.motivo === 'runtime.quota-exhausted' || plano.motivo === 'runtime.auth-missing') {
|
|
1219
1272
|
return rotacionarConta(carregado, thread, plano, opcoes, vazio, registrarTentativa);
|
|
1220
1273
|
}
|
|
1274
|
+
if (plano.motivo === 'runtime.model-unavailable') {
|
|
1275
|
+
return trocarDestinoDoModelo(carregado, thread, plano, opcoes, vazio, registrarTentativa);
|
|
1276
|
+
}
|
|
1221
1277
|
// `reexecutar` e `escalar-esforco`: o MESMO prompt volta ao runtime.
|
|
1222
1278
|
const falho = ultimoDespachoFalho(raiz, threadId, plano.fase, plano.motivo === 'runtime.silencio');
|
|
1223
1279
|
if (!falho || typeof falho.promptPath !== 'string' || typeof falho.promptSha256 !== 'string') {
|
|
@@ -1337,7 +1393,10 @@ function rotacionarConta(carregado, thread, plano, opcoes, vazio, registrarTenta
|
|
|
1337
1393
|
else
|
|
1338
1394
|
implicitos.push(alvo.runtime);
|
|
1339
1395
|
atual = { runtime: alvo.runtime, perfil: alvo.perfil };
|
|
1340
|
-
|
|
1396
|
+
// GO-FIX (R4b): destino que recusou o MODELO sai da rotacao, mas a falha que manda (e o motivo da
|
|
1397
|
+
// fila) continua sendo a da conta; o modelo inacessivel tem troca propria (trocarDestinoDoModelo).
|
|
1398
|
+
if (ultimo.falhaDeConta?.motivo !== 'runtime.model-unavailable')
|
|
1399
|
+
falhaAtual = ultimo.falhaDeConta ?? falhaAtual;
|
|
1341
1400
|
if (tentativas >= plano.limite) {
|
|
1342
1401
|
return escalar('limite de tentativas na rotacao', `${tentativas} tentativa(s) de rotacao por ${motivo} em ${fase}, no limite de ` +
|
|
1343
1402
|
`${plano.limite} do manifesto: escalacao tipada pausa qualquer modo`);
|
|
@@ -1369,6 +1428,168 @@ function rotacionarConta(carregado, thread, plano, opcoes, vazio, registrarTenta
|
|
|
1369
1428
|
registrarTentativa(true, `fila duravel: pedido ${pedido.id} libera em ${pedido.liberaEm}`);
|
|
1370
1429
|
return { ...vazio, executada: true, fila: [pedido], redespacho: ultimo, detalhe: `pedido ${pedido.id} na fila ate ${pedido.liberaEm}` };
|
|
1371
1430
|
}
|
|
1431
|
+
/** RM-037 (defeitosdeco D-6): chave de um destino (runtime, perfil, modelo) que recusou o modelo. */
|
|
1432
|
+
function chaveDoModelo(runtime, perfil, model) {
|
|
1433
|
+
return `${runtime}|${perfil ?? ''}|${model ?? ''}`;
|
|
1434
|
+
}
|
|
1435
|
+
/**
|
|
1436
|
+
* D-6: todo destino que ja recusou o modelo nesta fase, lido do ledger. O gate do observador traz o
|
|
1437
|
+
* `sessionId` (o modelo vem do `phase_dispatch` dele); o do despacho sincrono, o ultimo
|
|
1438
|
+
* `phase_dispatch_failed` da fase antes dele.
|
|
1439
|
+
*/
|
|
1440
|
+
function destinosQueRecusaramOModelo(eventos, fase) {
|
|
1441
|
+
const chaves = [];
|
|
1442
|
+
const chaveDo = (origem) => {
|
|
1443
|
+
if (typeof origem.runtime !== 'string')
|
|
1444
|
+
return null;
|
|
1445
|
+
let perfil = null;
|
|
1446
|
+
try {
|
|
1447
|
+
perfil = perfilDoEvento(origem);
|
|
1448
|
+
}
|
|
1449
|
+
catch { /* perfil ilegivel nao exclui ninguem */ }
|
|
1450
|
+
return chaveDoModelo(origem.runtime, perfil?.id ?? null, typeof origem.model === 'string' ? origem.model : null);
|
|
1451
|
+
};
|
|
1452
|
+
eventos.forEach((e, i) => {
|
|
1453
|
+
// GO-FIX (R4a): a recusa sincrona do redespacho (nada rodou) so grava `phase_dispatch_failed`.
|
|
1454
|
+
if (e.tipo === ledger_1.TIPOS_DE_EVENTO.despachoFalhou && e.fase === fase && String(e.erro ?? '').startsWith('runtime.model-unavailable')) {
|
|
1455
|
+
const chave = chaveDo(e);
|
|
1456
|
+
if (chave)
|
|
1457
|
+
chaves.push(chave);
|
|
1458
|
+
return;
|
|
1459
|
+
}
|
|
1460
|
+
if (e.tipo !== ledger_1.TIPOS_DE_EVENTO.gateBloqueado || e.fase !== fase || e.motivo !== 'runtime.model-unavailable')
|
|
1461
|
+
return;
|
|
1462
|
+
const origem = typeof e.sessionId === 'string'
|
|
1463
|
+
? eventos.filter(d => d.tipo === ledger_1.TIPOS_DE_EVENTO.faseDespachada && d.sessionId === e.sessionId).at(-1)
|
|
1464
|
+
: eventos.slice(0, i).filter(d => d.tipo === ledger_1.TIPOS_DE_EVENTO.despachoFalhou && d.fase === fase).at(-1);
|
|
1465
|
+
const chave = origem ? chaveDo(origem) : null;
|
|
1466
|
+
if (chave)
|
|
1467
|
+
chaves.push(chave);
|
|
1468
|
+
});
|
|
1469
|
+
return chaves;
|
|
1470
|
+
}
|
|
1471
|
+
/**
|
|
1472
|
+
* D-6: o proximo destino do MESMO prompt depois de `runtime.model-unavailable`. Primeiro outro perfil do
|
|
1473
|
+
* mesmo runtime com o MESMO modelo (outra conta pode ter acesso), depois cada runtime da ordem de
|
|
1474
|
+
* fallback do bloco com o modelo dele. Perfil fora do rodizio (esgotado, sem login, desativado, pago)
|
|
1475
|
+
* nao entra, e nenhum destino que ja recusou volta. Sem destino, `null`.
|
|
1476
|
+
*/
|
|
1477
|
+
function proximoDestinoDoModelo(raiz, runtime, model, fallback, recusados) {
|
|
1478
|
+
const store = (0, runtime_profiles_1.lerPerfisComContas)(raiz);
|
|
1479
|
+
const utilizavel = (p) => !['desativado', 'provider-pago', 'sem-auth'].includes(p.estado) && (0, runtime_profiles_1.perfilDisponivel)(p);
|
|
1480
|
+
const mesmo = (0, runtime_profiles_1.perfisDoRuntime)(store, runtime).find(p => utilizavel(p) && !recusados.has(chaveDoModelo(runtime, p.id, model)));
|
|
1481
|
+
if (mesmo)
|
|
1482
|
+
return { runtime, perfil: (0, runtime_profiles_1.perfilDeDespacho)(mesmo), model, effort: null };
|
|
1483
|
+
for (const f of fallback) {
|
|
1484
|
+
const perfis = (0, runtime_profiles_1.perfisDoRuntime)(store, f.runtime);
|
|
1485
|
+
if (perfis.length) {
|
|
1486
|
+
const p = perfis.find(x => utilizavel(x) && !recusados.has(chaveDoModelo(f.runtime, x.id, f.model)));
|
|
1487
|
+
if (p)
|
|
1488
|
+
return { runtime: f.runtime, perfil: (0, runtime_profiles_1.perfilDeDespacho)(p), model: f.model, effort: f.effort ?? null };
|
|
1489
|
+
continue;
|
|
1490
|
+
}
|
|
1491
|
+
if (!recusados.has(chaveDoModelo(f.runtime, null, f.model)))
|
|
1492
|
+
return { runtime: f.runtime, perfil: null, model: f.model, effort: f.effort ?? null };
|
|
1493
|
+
}
|
|
1494
|
+
return null;
|
|
1495
|
+
}
|
|
1496
|
+
/** D-6: a correcao exata quando nenhum destino tem o modelo: o bloco do setup que conduz a fase. */
|
|
1497
|
+
function correcaoDoModelo(thread, fase) {
|
|
1498
|
+
const indice = modos_1.MODOS[thread.modo]?.blocos.findIndex(b => b.fases.includes(fase)) ?? -1;
|
|
1499
|
+
const bloco = indice >= 0 ? String(indice + 1) : 'N';
|
|
1500
|
+
return `ork setup ${thread.modo} --bloco ${bloco} --model <modelo acessivel>, ou declare no mesmo bloco --fallback runtime:modelo`;
|
|
1501
|
+
}
|
|
1502
|
+
/**
|
|
1503
|
+
* RM-037 (defeitosdeco D-6): troca de destino depois de `runtime.model-unavailable`. O modelo pedido nao
|
|
1504
|
+
* existe ou a conta nao tem acesso a ele (`model_not_found` na transcricao); o perfil continua no
|
|
1505
|
+
* rodizio e o MESMO prompt segue no proximo destino (`proximoDestinoDoModelo`). Producao no intervalo
|
|
1506
|
+
* escala ao humano, como na rotacao por conta. Recusa do modelo no redespacho (nada rodou) continua a
|
|
1507
|
+
* troca na mesma chamada, dentro do limite de tentativas. Sem destino, o humano recebe a correcao exata.
|
|
1508
|
+
*/
|
|
1509
|
+
function trocarDestinoDoModelo(carregado, thread, plano, opcoes, vazio, registrarTentativa) {
|
|
1510
|
+
const { raiz, manifesto } = carregado;
|
|
1511
|
+
const dir = (0, thread_1.dirThread)(raiz, thread.id);
|
|
1512
|
+
const fase = plano.fase;
|
|
1513
|
+
const motivo = 'runtime.model-unavailable';
|
|
1514
|
+
const eventos = (0, ledger_1.lerLedger)(dir);
|
|
1515
|
+
const gate = ultimaReprovacao(raiz, thread.id);
|
|
1516
|
+
const despacho = despachoDaFalha(eventos, gate, fase);
|
|
1517
|
+
const escalar = (razao, diagnostico) => {
|
|
1518
|
+
if (!opcoes.dryRun) {
|
|
1519
|
+
(0, gates_1.registrarGateBloqueado)(dir, thread.id, { gate: 'phase.dispatch', motivo: 'human.pending', modo: thread.modo, detalhe: diagnostico,
|
|
1520
|
+
diagnostico, correcao: `ork gate request ${thread.id}`, fase, origem: 'retry.modelo', pausaQualquerModo: true });
|
|
1521
|
+
(0, ledger_1.registrar)(dir, thread.id, ledger_1.TIPOS_DE_EVENTO.retryEscalado, { fase, motivo, origem: 'retry.modelo', acao: plano.acao,
|
|
1522
|
+
tentativas: plano.tentativas, limite: plano.limite, modo: thread.modo, razao });
|
|
1523
|
+
}
|
|
1524
|
+
return { ...vazio, detalhe: diagnostico };
|
|
1525
|
+
};
|
|
1526
|
+
if (!despacho || typeof despacho.promptPath !== 'string' || typeof despacho.promptSha256 !== 'string') {
|
|
1527
|
+
const detalhe = `nao ha despacho com prompt gravado para ${motivo} em ${fase}: rode a fase de novo com ork phase run`;
|
|
1528
|
+
registrarTentativa(false, detalhe);
|
|
1529
|
+
return { ...vazio, detalhe };
|
|
1530
|
+
}
|
|
1531
|
+
const runtime = typeof despacho.runtime === 'string' ? despacho.runtime : manifesto.runtime.adapter;
|
|
1532
|
+
const model = typeof despacho.model === 'string' ? despacho.model : null;
|
|
1533
|
+
const rotulo = model ?? '(padrao do runtime)';
|
|
1534
|
+
let perfil;
|
|
1535
|
+
try {
|
|
1536
|
+
perfil = typeof gate?.sessionId === 'string'
|
|
1537
|
+
? (0, runtime_profiles_1.perfilDoRegistro)(eventos, { sessionId: gate.sessionId, despachadaEm: typeof gate.despachoEm === 'string' ? gate.despachoEm : undefined })
|
|
1538
|
+
: perfilDoEvento(despacho);
|
|
1539
|
+
}
|
|
1540
|
+
catch (e) {
|
|
1541
|
+
return escalar('perfil registrado invalido', `troca de destino recusada: ${e.message}`);
|
|
1542
|
+
}
|
|
1543
|
+
if (typeof gate?.sessionId === 'string' && typeof gate.despachoEm === 'string') {
|
|
1544
|
+
const producao = producaoNoIntervalo(raiz, thread, { sessionId: gate.sessionId, fase, despachadaEm: gate.despachoEm }, eventos);
|
|
1545
|
+
if (producao.produziu) {
|
|
1546
|
+
return escalar('producao parcial com modelo inacessivel', `producao parcial com o modelo ${rotulo} inacessivel: ${producao.evidencia}; ` +
|
|
1547
|
+
'a sessao nao e redespachada sobre a worktree alterada e a fase nao conclui sem o humano');
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
const recusados = new Set([...destinosQueRecusaramOModelo(eventos, fase), chaveDoModelo(runtime, perfil?.id ?? null, model)]);
|
|
1551
|
+
const doBloco = (0, setup_1.configDoBloco)((0, setup_1.lerSetup)(raiz), thread.modo, fase);
|
|
1552
|
+
const fallback = alvosDeFallback(doBloco, doBloco?.runtime ?? manifesto.runtime.adapter);
|
|
1553
|
+
let atual = { runtime, perfil, model };
|
|
1554
|
+
let tentativas = plano.tentativas;
|
|
1555
|
+
for (;;) {
|
|
1556
|
+
const alvo = proximoDestinoDoModelo(raiz, runtime, model, fallback, recusados);
|
|
1557
|
+
if (!alvo)
|
|
1558
|
+
break;
|
|
1559
|
+
if (!opcoes.dryRun)
|
|
1560
|
+
(0, ledger_1.registrar)(dir, thread.id, ledger_1.TIPOS_DE_EVENTO.perfilRotacionado, { fase, motivo, origem: 'retry.modelo',
|
|
1561
|
+
de: { runtime: atual.runtime, perfil: atual.perfil?.id ?? null, model: atual.model },
|
|
1562
|
+
para: { runtime: alvo.runtime, perfil: alvo.perfil?.id ?? null, model: alvo.model },
|
|
1563
|
+
razao: alvo.runtime === runtime ? 'outro perfil do mesmo runtime com o mesmo modelo' : 'fallback de runtime pela ordem do bloco',
|
|
1564
|
+
promptSha256: despacho.promptSha256, modo: thread.modo,
|
|
1565
|
+
autorizadoPor: `politica de retry da RM-037 (D-6), bloco sem pausa ou delegado no modo ${thread.modo}` });
|
|
1566
|
+
const mudouRuntime = alvo.runtime !== runtime;
|
|
1567
|
+
const r = redespachar(carregado, thread, fase, despacho.promptPath, despacho.promptSha256, {
|
|
1568
|
+
runtime: alvo.runtime, perfil: alvo.perfil?.id ?? null, model: alvo.model,
|
|
1569
|
+
effort: mudouRuntime ? alvo.effort ?? (typeof despacho.effort === 'string' ? despacho.effort : null) : plano.effort,
|
|
1570
|
+
origem: 'retry.modelo', dryRun: opcoes.dryRun,
|
|
1571
|
+
});
|
|
1572
|
+
if (opcoes.dryRun)
|
|
1573
|
+
return { ...vazio, redespacho: r, detalhe: `ensaio: o mesmo prompt iria a ${alvo.runtime}` +
|
|
1574
|
+
`${alvo.perfil ? ` (perfil ${alvo.perfil.id})` : ''} com o modelo ${alvo.model ?? '(padrao do runtime)'}; ${r.detalhe}` };
|
|
1575
|
+
registrarTentativa(r.ok, r.detalhe);
|
|
1576
|
+
tentativas += 1;
|
|
1577
|
+
if (r.ok)
|
|
1578
|
+
return { ...vazio, executada: true, redespacho: r, detalhe: r.detalhe };
|
|
1579
|
+
// So a recusa do MODELO no redespacho (nada rodou) continua a troca; outra falha para aqui.
|
|
1580
|
+
if (r.falhaDeConta?.motivo !== 'runtime.model-unavailable')
|
|
1581
|
+
return { ...vazio, redespacho: r, detalhe: r.detalhe };
|
|
1582
|
+
recusados.add(chaveDoModelo(alvo.runtime, alvo.perfil?.id ?? null, alvo.model));
|
|
1583
|
+
atual = { runtime: alvo.runtime, perfil: alvo.perfil, model: alvo.model };
|
|
1584
|
+
if (tentativas >= plano.limite) {
|
|
1585
|
+
return escalar('limite de tentativas na troca de modelo', `${tentativas} tentativa(s) de troca por ${motivo} em ${fase}, no limite de ` +
|
|
1586
|
+
`${plano.limite} do manifesto: escalacao tipada pausa qualquer modo`);
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1589
|
+
const tentados = [...recusados].map(k => { const [rt, p, m] = k.split('|'); return `${rt}${p ? `/${p}` : ''}:${m || '(padrao)'}`; });
|
|
1590
|
+
return escalar('modelo inacessivel sem outro destino', `o modelo ${rotulo} nao esta acessivel em ${tentados.join(', ')} e o bloco ` +
|
|
1591
|
+
`nao tem outro destino: ${correcaoDoModelo(thread, fase)}`);
|
|
1592
|
+
}
|
|
1372
1593
|
/** Texto de `ork retry plan`. */
|
|
1373
1594
|
function textoDoPlano(p) {
|
|
1374
1595
|
const linhas = [];
|