@sjawhar/pi-legion-envoy 5.30.6 → 5.30.8
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/dist/envoy.js +17 -8
- package/dist/legion.js +10 -8
- package/dist/skills/dispatch/SKILL.md +10 -10
- package/package.json +1 -1
package/dist/envoy.js
CHANGED
|
@@ -34081,17 +34081,19 @@ async function refuseRemovingOpenDecisionBlocks(client, tool, resolved, ops) {
|
|
|
34081
34081
|
].join(`
|
|
34082
34082
|
`));
|
|
34083
34083
|
}
|
|
34084
|
-
function refusalWithCode(error48,
|
|
34084
|
+
function refusalWithCode(error48, ...clauses) {
|
|
34085
|
+
const suffix = clauses.filter((clause) => clause !== "").join("; ");
|
|
34086
|
+
const joined = suffix === "" ? "" : `; ${suffix}`;
|
|
34085
34087
|
if (error48 instanceof DispatchGatewayError) {
|
|
34086
34088
|
let told = error48.message;
|
|
34087
|
-
if (
|
|
34088
|
-
told = error48.mayHaveReachedDispatch ? `${error48.answer}${
|
|
34089
|
+
if (joined !== "") {
|
|
34090
|
+
told = error48.mayHaveReachedDispatch ? `${error48.answer}${joined}` : `${error48.answer}, so ${error48.advice}${joined}`;
|
|
34089
34091
|
}
|
|
34090
34092
|
return new DispatchGatewayError(error48.status, error48.answer, error48.advice, `${error48.code}: ${told}`);
|
|
34091
34093
|
}
|
|
34092
34094
|
if (!(error48 instanceof DispatchServiceError))
|
|
34093
34095
|
return error48;
|
|
34094
|
-
return new DispatchServiceError(error48.code, error48.status, `${error48.code}: ${error48.message}${
|
|
34096
|
+
return new DispatchServiceError(error48.code, error48.status, `${error48.code}: ${error48.message}${joined}`, error48.candidates, error48.current, error48.mismatches);
|
|
34095
34097
|
}
|
|
34096
34098
|
function dispatchAnswered(error48, status) {
|
|
34097
34099
|
return error48 instanceof DispatchServiceError && error48.fromDispatch && error48.status === status;
|
|
@@ -34277,7 +34279,7 @@ async function executeDispatchTool(input) {
|
|
|
34277
34279
|
} catch (error48) {
|
|
34278
34280
|
const told = writeMayHaveLanded(error48) ? "the reason may or may not have been posted, and the close was not sent: read the issue's messages before retrying, since retrying this call posts its reason again" : "the reason was not posted, so the close was not sent";
|
|
34279
34281
|
if (error48 instanceof DispatchServiceError)
|
|
34280
|
-
throw refusalWithCode(error48,
|
|
34282
|
+
throw refusalWithCode(error48, told);
|
|
34281
34283
|
throw withAccount(error48, told);
|
|
34282
34284
|
}
|
|
34283
34285
|
}
|
|
@@ -34297,14 +34299,14 @@ async function executeDispatchTool(input) {
|
|
|
34297
34299
|
actor
|
|
34298
34300
|
});
|
|
34299
34301
|
} catch (error48) {
|
|
34300
|
-
const taken = dispatchAnswered(error48, 500) && newLinks.length > 0 ?
|
|
34302
|
+
const taken = dispatchAnswered(error48, 500) && newLinks.length > 0 ? `one of ${newLinks.join(", ")} may already be linked from another issue (a URL links exactly one issue)` : "";
|
|
34301
34303
|
if (closingNote === undefined)
|
|
34302
34304
|
throw refusalWithCode(error48, taken);
|
|
34303
34305
|
const posted = `the reason already landed as message ${closingNote.id} (${closingNote.ref})`;
|
|
34304
34306
|
const fix = error48 instanceof DispatchGatewayError && error48.transient ? "" : "fix what refused the close, then ";
|
|
34305
34307
|
const landed = writeMayHaveLanded(error48) ? `${posted}, and the close may or may not have taken effect. Read the issue's status before retrying: done means it closed; otherwise retry with a reason that points at message ${closingNote.id}, since retrying this call posts its reason again` : `${posted} but the issue did not close. Retrying this call posts its reason again, so ${fix}retry with a reason that points at message ${closingNote.id}`;
|
|
34306
34308
|
if (error48 instanceof DispatchServiceError)
|
|
34307
|
-
throw refusalWithCode(error48,
|
|
34309
|
+
throw refusalWithCode(error48, taken, landed);
|
|
34308
34310
|
throw withAccount(error48, landed);
|
|
34309
34311
|
}
|
|
34310
34312
|
const linkCount = `(${after.external_links.length} ${after.external_links.length === 1 ? "link" : "links"})`;
|
|
@@ -35997,6 +35999,12 @@ async function copySessionID(copyToClipboard2, sessionID) {
|
|
|
35997
35999
|
var codec2 = import_nats2.StringCodec();
|
|
35998
36000
|
var NATS_RETRY_INTERVAL_MS = 15000;
|
|
35999
36001
|
var CAPABILITIES_WITHOUT_BTW = DELIVERY_CAPABILITIES.filter((capability) => capability !== "btw");
|
|
36002
|
+
var ClaimIdentitySchema = DedupeIdentitySchema.extend({
|
|
36003
|
+
event_id: DedupeIdentitySchema.shape.event_id.catch(undefined),
|
|
36004
|
+
dedupe_key: DedupeIdentitySchema.shape.dedupe_key.catch(undefined),
|
|
36005
|
+
source: DedupeIdentitySchema.shape.source.catch(undefined),
|
|
36006
|
+
source_event_id: DedupeIdentitySchema.shape.source_event_id.catch(undefined)
|
|
36007
|
+
});
|
|
36000
36008
|
var ROLE_CLAIM_ENTRY = "envoy-role-claim";
|
|
36001
36009
|
var OPEN_ASKS_TIMEOUT_MS = 3000;
|
|
36002
36010
|
var USER_TURN_ACCEPT_TIMEOUT_MS = 1e4;
|
|
@@ -36252,7 +36260,8 @@ function envoyExtension(pi) {
|
|
|
36252
36260
|
}
|
|
36253
36261
|
for (const topic of subscriptionRemovedTopics(raw, sessionID) ?? [])
|
|
36254
36262
|
closeIntentionally(topic);
|
|
36255
|
-
const
|
|
36263
|
+
const dedupeIdentity = ClaimIdentitySchema.safeParse(rendered.envelope);
|
|
36264
|
+
const claim2 = rendered.skip ? undefined : delivered.claim(dedupeIdentity.success ? dedupeIdentity.data : undefined);
|
|
36256
36265
|
if (claim2 !== undefined) {
|
|
36257
36266
|
const envelope2 = rendered.envelope;
|
|
36258
36267
|
if (envelope2 !== undefined) {
|
package/dist/legion.js
CHANGED
|
@@ -32949,17 +32949,19 @@ async function refuseRemovingOpenDecisionBlocks(client, tool, resolved, ops) {
|
|
|
32949
32949
|
].join(`
|
|
32950
32950
|
`));
|
|
32951
32951
|
}
|
|
32952
|
-
function refusalWithCode(error48,
|
|
32952
|
+
function refusalWithCode(error48, ...clauses) {
|
|
32953
|
+
const suffix = clauses.filter((clause) => clause !== "").join("; ");
|
|
32954
|
+
const joined = suffix === "" ? "" : `; ${suffix}`;
|
|
32953
32955
|
if (error48 instanceof DispatchGatewayError) {
|
|
32954
32956
|
let told = error48.message;
|
|
32955
|
-
if (
|
|
32956
|
-
told = error48.mayHaveReachedDispatch ? `${error48.answer}${
|
|
32957
|
+
if (joined !== "") {
|
|
32958
|
+
told = error48.mayHaveReachedDispatch ? `${error48.answer}${joined}` : `${error48.answer}, so ${error48.advice}${joined}`;
|
|
32957
32959
|
}
|
|
32958
32960
|
return new DispatchGatewayError(error48.status, error48.answer, error48.advice, `${error48.code}: ${told}`);
|
|
32959
32961
|
}
|
|
32960
32962
|
if (!(error48 instanceof DispatchServiceError))
|
|
32961
32963
|
return error48;
|
|
32962
|
-
return new DispatchServiceError(error48.code, error48.status, `${error48.code}: ${error48.message}${
|
|
32964
|
+
return new DispatchServiceError(error48.code, error48.status, `${error48.code}: ${error48.message}${joined}`, error48.candidates, error48.current, error48.mismatches);
|
|
32963
32965
|
}
|
|
32964
32966
|
function dispatchAnswered(error48, status) {
|
|
32965
32967
|
return error48 instanceof DispatchServiceError && error48.fromDispatch && error48.status === status;
|
|
@@ -33145,7 +33147,7 @@ async function executeDispatchTool(input) {
|
|
|
33145
33147
|
} catch (error48) {
|
|
33146
33148
|
const told = writeMayHaveLanded(error48) ? "the reason may or may not have been posted, and the close was not sent: read the issue's messages before retrying, since retrying this call posts its reason again" : "the reason was not posted, so the close was not sent";
|
|
33147
33149
|
if (error48 instanceof DispatchServiceError)
|
|
33148
|
-
throw refusalWithCode(error48,
|
|
33150
|
+
throw refusalWithCode(error48, told);
|
|
33149
33151
|
throw withAccount(error48, told);
|
|
33150
33152
|
}
|
|
33151
33153
|
}
|
|
@@ -33165,14 +33167,14 @@ async function executeDispatchTool(input) {
|
|
|
33165
33167
|
actor
|
|
33166
33168
|
});
|
|
33167
33169
|
} catch (error48) {
|
|
33168
|
-
const taken = dispatchAnswered(error48, 500) && newLinks.length > 0 ?
|
|
33170
|
+
const taken = dispatchAnswered(error48, 500) && newLinks.length > 0 ? `one of ${newLinks.join(", ")} may already be linked from another issue (a URL links exactly one issue)` : "";
|
|
33169
33171
|
if (closingNote === undefined)
|
|
33170
33172
|
throw refusalWithCode(error48, taken);
|
|
33171
33173
|
const posted = `the reason already landed as message ${closingNote.id} (${closingNote.ref})`;
|
|
33172
33174
|
const fix = error48 instanceof DispatchGatewayError && error48.transient ? "" : "fix what refused the close, then ";
|
|
33173
33175
|
const landed = writeMayHaveLanded(error48) ? `${posted}, and the close may or may not have taken effect. Read the issue's status before retrying: done means it closed; otherwise retry with a reason that points at message ${closingNote.id}, since retrying this call posts its reason again` : `${posted} but the issue did not close. Retrying this call posts its reason again, so ${fix}retry with a reason that points at message ${closingNote.id}`;
|
|
33174
33176
|
if (error48 instanceof DispatchServiceError)
|
|
33175
|
-
throw refusalWithCode(error48,
|
|
33177
|
+
throw refusalWithCode(error48, taken, landed);
|
|
33176
33178
|
throw withAccount(error48, landed);
|
|
33177
33179
|
}
|
|
33178
33180
|
const linkCount = `(${after.external_links.length} ${after.external_links.length === 1 ? "link" : "links"})`;
|
|
@@ -33826,7 +33828,7 @@ import { logger } from "@oh-my-pi/pi-utils";
|
|
|
33826
33828
|
// package.json
|
|
33827
33829
|
var package_default = {
|
|
33828
33830
|
name: "@sjawhar/pi-legion-envoy",
|
|
33829
|
-
version: "5.30.
|
|
33831
|
+
version: "5.30.8",
|
|
33830
33832
|
type: "module",
|
|
33831
33833
|
omp: {
|
|
33832
33834
|
extensions: [
|
|
@@ -84,7 +84,7 @@ a new version that keeps the human's own text, never a second "spec" artifact be
|
|
|
84
84
|
versions keep the history.
|
|
85
85
|
- **No placeholders.** No TBD, TODO, or hedging ("might", "could consider"): an open item is a
|
|
86
86
|
decision block, a technical decision your lane makes and records in the text, or, for a
|
|
87
|
-
contract between two lanes
|
|
87
|
+
contract between two lanes, a question for the platform PO (see
|
|
88
88
|
[Before you ask](#before-you-ask) under Asking).
|
|
89
89
|
- **No progress.** The spec records the design and its decisions, never status, timestamps, an
|
|
90
90
|
"Update HH:MMZ" section, a pull-request list, or handoff notes. Progress is not a Dispatch
|
|
@@ -208,10 +208,11 @@ Every `dispatch_ask` passes four gates first:
|
|
|
208
208
|
1. **Does it need his authority, taste, or risk appetite?** This is the bar for a decision
|
|
209
209
|
written as an `:::ask` block in context ([Decision blocks](#decision-blocks)). Technical
|
|
210
210
|
decisions inside your outcome do not: schema shapes, table layouts, field names, and migration
|
|
211
|
-
internals are your lane's to decide and record in the spec.
|
|
212
|
-
platform PO over Envoy
|
|
213
|
-
deletion or exposure of production data, anything that reaches a customer)
|
|
214
|
-
|
|
211
|
+
internals are your lane's to decide and record in the spec. A contract between two lanes still
|
|
212
|
+
goes to the platform PO over Envoy, and you open no ask for it. A halt condition (a change to
|
|
213
|
+
IAM, deletion or exposure of production data, anything that reaches a customer) passes this
|
|
214
|
+
gate: it is your own `dispatch_ask` to Sami on your own issue, never routed through the
|
|
215
|
+
platform PO.
|
|
215
216
|
2. **Is there genuine uncertainty, and have you measured what you can?** If there is none, it is
|
|
216
217
|
a plan you execute. The one legitimate ask without uncertainty is permission for an action
|
|
217
218
|
only a human can authorise — a production write, an external send, a console action — and then
|
|
@@ -242,9 +243,9 @@ Every `dispatch_ask` passes four gates first:
|
|
|
242
243
|
is not what this forbids; changing something else is. An ask that turns his complaint about
|
|
243
244
|
one control into a choice about another does not address what he asked, and changing that
|
|
244
245
|
other control is a change he never asked for. What is still an ask the moment you know it,
|
|
245
|
-
even before delivery, is anything "Anything
|
|
246
|
-
lists that the delivery waits on — including a conflict between what he asked
|
|
247
|
-
of his rules, which this gate would otherwise bury as settled.
|
|
246
|
+
even before delivery, is anything "Anything you are blocked on a human for is an open ask"
|
|
247
|
+
(further down) lists that the delivery waits on — including a conflict between what he asked
|
|
248
|
+
for and another of his rules, which this gate would otherwise bury as settled.
|
|
248
249
|
|
|
249
250
|
The platform PO audits open asks. One that fails a gate — or that points at another message in
|
|
250
251
|
prose instead of carrying its content (below) — is retracted, with the PO's answer as the record.
|
|
@@ -314,8 +315,7 @@ Before saying you are waiting for human input, call `dispatch_open_asks`. With n
|
|
|
314
315
|
**Anything you are blocked on a human for is an open ask.** An agent waits on a human only through
|
|
315
316
|
an open ask. An approval, a credential or grant to renew, a setting only they can change, a review
|
|
316
317
|
click, a decision, or a conflict between two of their own rules: open a `dispatch_ask` the moment
|
|
317
|
-
you know, the action as the question.
|
|
318
|
-
ask](#before-you-ask) gate 1, which goes to the platform PO over Envoy instead. Never write it
|
|
318
|
+
you know, the action as the question. Never write it
|
|
319
319
|
into a spec, a comment reply, a message, or a pull-request body: nothing in those paths reaches
|
|
320
320
|
the human's Inbox, and a human who is not reading your document does not know they are the
|
|
321
321
|
blocker. Before asking, try to remove the step: a value already on the machine, a permission you
|