@sjawhar/pi-envoy 10.22.0 → 10.23.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/dist/dispatch.js +63 -10
- package/dist/envoy.js +24 -5
- package/dist/skills/dispatch/references/reading.md +2 -1
- package/package.json +1 -1
package/dist/dispatch.js
CHANGED
|
@@ -13576,6 +13576,7 @@ var DispatchServerStartedPayloadSchema = exports_external.strictObject({
|
|
|
13576
13576
|
commit: exports_external.string().min(1),
|
|
13577
13577
|
started_at: exports_external.iso.datetime()
|
|
13578
13578
|
});
|
|
13579
|
+
var DEFAULT_ISSUE_READ_EVENTS = 10;
|
|
13579
13580
|
var DispatchEventSchema = exports_external.object({
|
|
13580
13581
|
issue_key: exports_external.string().nullable(),
|
|
13581
13582
|
artifact_id: exports_external.string().nullish(),
|
|
@@ -14353,13 +14354,15 @@ var dispatchToolSpecs = [
|
|
|
14353
14354
|
{
|
|
14354
14355
|
name: "dispatch_read",
|
|
14355
14356
|
example: { issue: "DSP-1" },
|
|
14356
|
-
description: "Read an issue or document summary, targeted ask, or targeted comment reply chain, or the conversation " + "a message belongs to. Do not use it for document contents; use dispatch doc-read instead. Supply ref, issue, " + "issue plus artifact (one of its documents), or project plus artifact; or message alone, which reads a human's direct message to this session and every " + "reply to it (they belong to no issue). A document summary names its issue, reference, versions and approval. " + "An anchored comment or ask also says where its quote sits, as `Position:`: the block's path from the top, " + "and in a table the row (0 is the header), the cells before the anchored one, and the column's header; " + "`Position: unavailable (<code>)` when Dispatch could not read the document: `DOC_SERVICE_UNAVAILABLE` " + "(try again shortly), `DOC_SCHEMA` (the document needs repair), `DOCUMENT_UNLOADABLE` (the document " + "needs a rebuild) or `INTERNAL`. " + "An issue read carries a `Progress:` line, `tasks 3/7, children 2/5`: its spec's task-list items " + "(`- [ ]` / `- [x]`, nested lists included) and its direct children, each done of total and each only " + "when it has any (`Progress: none` otherwise). " + "Every read ends with `Referenced by:` (what cites or hangs off this node, each with its dispatch:// address, " + "an excerpt, and when) and `Links:` (what it cites), so tracing provenance is one call. " + "The pictures the shown messages, asks and comments embed come back as images you see, newest first, at most 8 " + "and 10 MiB of them per read, each a PNG, JPEG, GIF or WebP of at most 3,750,000 bytes (5 MB of base64); a `Pictures:` section names each " + "one shown, in order, and the rest by reference, for dispatch doc-read. A picture this session was already shown is named, not sent again " + "(every request carries the session's history, and the provider refuses one over 32 MB); dispatch doc-read shows it again. " + OWNER_REFERENCE,
|
|
14357
|
+
description: "Read an issue or document summary, targeted ask, or targeted comment reply chain, or the conversation " + "a message belongs to. Do not use it for document contents; use dispatch doc-read instead. Supply ref, issue, " + "issue plus artifact (one of its documents), or project plus artifact; or message alone, which reads a human's direct message to this session and every " + "reply to it (they belong to no issue). A document summary names its issue, reference, versions and approval. " + "An anchored comment or ask also says where its quote sits, as `Position:`: the block's path from the top, " + "and in a table the row (0 is the header), the cells before the anchored one, and the column's header; " + "`Position: unavailable (<code>)` when Dispatch could not read the document: `DOC_SERVICE_UNAVAILABLE` " + "(try again shortly), `DOC_SCHEMA` (the document needs repair), `DOCUMENT_UNLOADABLE` (the document " + "needs a rebuild) or `INTERNAL`. " + "An issue read carries a `Progress:` line, `tasks 3/7, children 2/5`: its spec's task-list items " + "(`- [ ]` / `- [x]`, nested lists included) and its direct children, each done of total and each only " + "when it has any (`Progress: none` otherwise). " + `An issue read, and its dispatch://KEY/log, lists the issue's last ${DEFAULT_ISSUE_READ_EVENTS} events, oldest first; ` + "--events N lists the last N, and --all-events every one. " + "Every read ends with `Referenced by:` (what cites or hangs off this node, each with its dispatch:// address, " + "an excerpt, and when) and `Links:` (what it cites), so tracing provenance is one call. " + "The pictures the shown messages, asks and comments embed come back as images you see, newest first, at most 8 " + "and 10 MiB of them per read, each a PNG, JPEG, GIF or WebP of at most 3,750,000 bytes (5 MB of base64); a `Pictures:` section names each " + "one shown, in order, and the rest by reference, for dispatch doc-read. A picture this session was already shown is named, not sent again " + "(every request carries the session's history, and the provider refuses one over 32 MB); dispatch doc-read shows it again. " + OWNER_REFERENCE,
|
|
14357
14358
|
arguments: (z2) => ({
|
|
14358
14359
|
issue: z2.string().describe(ISSUE_REFERENCE).optional(),
|
|
14359
14360
|
project: z2.string().describe("Project key owning the document.").optional(),
|
|
14360
14361
|
artifact: z2.string().describe("Document artifact id, slug, or filename: one of the issue's, or a project document.").optional(),
|
|
14361
14362
|
ref: z2.string().describe("Optional dispatch:// issue or document reference.").optional(),
|
|
14362
|
-
message: z2.string().describe("A message id (uuid): reads the conversation it belongs to, the root message and every " + "reply. Name nothing else with it.").optional()
|
|
14363
|
+
message: z2.string().describe("A message id (uuid): reads the conversation it belongs to, the root message and every " + "reply. Name nothing else with it.").optional(),
|
|
14364
|
+
events: z2.number({ int: true, min: 1 }).describe(`How many of the issue's newest events an issue read or its dispatch://KEY/log lists, oldest first; default ${DEFAULT_ISSUE_READ_EVENTS}. Name no --all-events with it.`).optional(),
|
|
14365
|
+
all_events: z2.boolean().describe(`List every one of the issue's events, oldest first, on an issue read or its dispatch://KEY/log, in place of the last ${DEFAULT_ISSUE_READ_EVENTS}. Name no --events with it.`).optional()
|
|
14363
14366
|
}),
|
|
14364
14367
|
validation: readValidation
|
|
14365
14368
|
},
|
|
@@ -15161,6 +15164,7 @@ function asErrorShape(value) {
|
|
|
15161
15164
|
function isJson(response) {
|
|
15162
15165
|
return response.headers.get("content-type")?.includes("application/json") ?? false;
|
|
15163
15166
|
}
|
|
15167
|
+
var ISSUE_EVENTS_PAGE_MAX = 200;
|
|
15164
15168
|
var DISPATCH_TOOL_DEADLINE_MS = 60000;
|
|
15165
15169
|
function requestSignal(signal) {
|
|
15166
15170
|
const deadline = AbortSignal.timeout(DISPATCH_TOOL_DEADLINE_MS);
|
|
@@ -15302,13 +15306,28 @@ class DispatchClient {
|
|
|
15302
15306
|
async releaseIssueClaim(issue2, input = {}) {
|
|
15303
15307
|
return this.#json("DELETE", ["api", "v1", "issues", await this.#resolveIssue(issue2), "claim"], input);
|
|
15304
15308
|
}
|
|
15305
|
-
async getIssueEvents(issue2, after = 0, limit =
|
|
15309
|
+
async getIssueEvents(issue2, after = 0, limit = ISSUE_EVENTS_PAGE_MAX) {
|
|
15306
15310
|
return this.#json("GET", ["api", "v1", "issues", await this.#resolveIssue(issue2), "events"], undefined, { after, limit });
|
|
15307
15311
|
}
|
|
15308
|
-
async read(issueReference) {
|
|
15312
|
+
async read(issueReference, options = {}) {
|
|
15309
15313
|
const issueKey = await this.#resolveIssue(issueReference);
|
|
15310
15314
|
const issue2 = await this.getIssue(issueKey);
|
|
15311
|
-
const
|
|
15315
|
+
const requested = options.events;
|
|
15316
|
+
const count = requested === undefined ? DEFAULT_ISSUE_READ_EVENTS : requested === "all" ? issue2.last_seq : Math.min(requested, issue2.last_seq);
|
|
15317
|
+
const events = [];
|
|
15318
|
+
let after = Math.max(0, issue2.last_seq - count);
|
|
15319
|
+
while (events.length < count) {
|
|
15320
|
+
const limit = Math.min(ISSUE_EVENTS_PAGE_MAX, count - events.length);
|
|
15321
|
+
const page = await this.getIssueEvents(issueKey, after, limit);
|
|
15322
|
+
events.push(...page);
|
|
15323
|
+
const last = page.at(-1);
|
|
15324
|
+
if (page.length < limit || last === undefined || events.length >= count)
|
|
15325
|
+
break;
|
|
15326
|
+
if (last.seq <= after) {
|
|
15327
|
+
throw new Error(`GET /api/v1/issues/${issueKey}/events?after=${after} answered no event after seq ${after}`);
|
|
15328
|
+
}
|
|
15329
|
+
after = last.seq;
|
|
15330
|
+
}
|
|
15312
15331
|
return { issue: issue2, events };
|
|
15313
15332
|
}
|
|
15314
15333
|
async ask(issue2, input) {
|
|
@@ -16659,6 +16678,16 @@ function argumentProblems(tool, args) {
|
|
|
16659
16678
|
if (message !== undefined && messageIdOf(message) === undefined) {
|
|
16660
16679
|
problems.push("message must be a full message id (uuid) or a dispatch://KEY/message/<id> reference");
|
|
16661
16680
|
}
|
|
16681
|
+
const events = optionalNumber(args, "events");
|
|
16682
|
+
const allEvents = optionalBoolean(args, "all_events") === true;
|
|
16683
|
+
if (events !== undefined && allEvents) {
|
|
16684
|
+
problems.push("--events and --all-events both say how many events the read lists: name one, --events N for the last N or --all-events for every one");
|
|
16685
|
+
}
|
|
16686
|
+
const count = events !== undefined ? "--events" : allEvents ? "--all-events" : undefined;
|
|
16687
|
+
const eventless = count === undefined ? undefined : readWithoutEvents(args);
|
|
16688
|
+
if (eventless !== undefined) {
|
|
16689
|
+
problems.push(`${count} lists an issue's events, which dispatch read prints only for an issue or its dispatch://KEY/log, not for ${eventless}: drop ${count}`);
|
|
16690
|
+
}
|
|
16662
16691
|
break;
|
|
16663
16692
|
}
|
|
16664
16693
|
case "dispatch_doc_read": {
|
|
@@ -16670,6 +16699,27 @@ function argumentProblems(tool, args) {
|
|
|
16670
16699
|
}
|
|
16671
16700
|
return problems;
|
|
16672
16701
|
}
|
|
16702
|
+
function readWithoutEvents(args) {
|
|
16703
|
+
if (optionalString(args, "message") !== undefined)
|
|
16704
|
+
return "a message's conversation";
|
|
16705
|
+
const ref = optionalString(args, "ref");
|
|
16706
|
+
switch (ref === undefined ? undefined : parseDispatchRef(ref)?.kind) {
|
|
16707
|
+
case "ask":
|
|
16708
|
+
return "an ask";
|
|
16709
|
+
case "comment":
|
|
16710
|
+
return "a comment";
|
|
16711
|
+
case "message":
|
|
16712
|
+
return "a message's conversation";
|
|
16713
|
+
case "children":
|
|
16714
|
+
return "the issue's children";
|
|
16715
|
+
case "log":
|
|
16716
|
+
return;
|
|
16717
|
+
}
|
|
16718
|
+
if (optionalString(args, "artifact") !== undefined || optionalString(args, "project") !== undefined) {
|
|
16719
|
+
return "a document summary";
|
|
16720
|
+
}
|
|
16721
|
+
return;
|
|
16722
|
+
}
|
|
16673
16723
|
function dispatchRefFromUrl(value, serverUrl) {
|
|
16674
16724
|
let url2;
|
|
16675
16725
|
let origin;
|
|
@@ -18581,8 +18631,11 @@ ${trailer.join(`
|
|
|
18581
18631
|
};
|
|
18582
18632
|
}
|
|
18583
18633
|
const issueKey = issue2();
|
|
18634
|
+
const readEvents = {
|
|
18635
|
+
events: optionalBoolean(args, "all_events") === true ? "all" : optionalNumber(args, "events")
|
|
18636
|
+
};
|
|
18584
18637
|
if (ownerArguments.ref?.kind === "log") {
|
|
18585
|
-
const read2 = await client.read(issueKey);
|
|
18638
|
+
const read2 = await client.read(issueKey, readEvents);
|
|
18586
18639
|
const pictures3 = await picturesOf(read2.events.flatMap(eventTexts));
|
|
18587
18640
|
return {
|
|
18588
18641
|
text: [logSummary(read2.issue, read2.events), ...pictures3.lines].join(`
|
|
@@ -18592,13 +18645,13 @@ ${trailer.join(`
|
|
|
18592
18645
|
};
|
|
18593
18646
|
}
|
|
18594
18647
|
if (ownerArguments.ref?.kind === "children") {
|
|
18595
|
-
const
|
|
18648
|
+
const parent = await client.getIssue(issueKey);
|
|
18596
18649
|
return {
|
|
18597
|
-
text: childrenSummary(
|
|
18598
|
-
details: { issue:
|
|
18650
|
+
text: childrenSummary(parent),
|
|
18651
|
+
details: { issue: parent.key }
|
|
18599
18652
|
};
|
|
18600
18653
|
}
|
|
18601
|
-
const readPromise = client.read(issueKey);
|
|
18654
|
+
const readPromise = client.read(issueKey, readEvents);
|
|
18602
18655
|
const referencesPromise = issueReferencesOrUnavailable(client, issueKey);
|
|
18603
18656
|
const read = await readPromise;
|
|
18604
18657
|
const [references, graph, titles, pictures2] = await Promise.all([
|
package/dist/envoy.js
CHANGED
|
@@ -29665,6 +29665,7 @@ var DispatchServerStartedPayloadSchema = exports_external.strictObject({
|
|
|
29665
29665
|
commit: exports_external.string().min(1),
|
|
29666
29666
|
started_at: exports_external.iso.datetime()
|
|
29667
29667
|
});
|
|
29668
|
+
var DEFAULT_ISSUE_READ_EVENTS = 10;
|
|
29668
29669
|
var DispatchEventSchema = exports_external.object({
|
|
29669
29670
|
issue_key: exports_external.string().nullable(),
|
|
29670
29671
|
artifact_id: exports_external.string().nullish(),
|
|
@@ -30340,13 +30341,15 @@ var dispatchToolSpecs = [
|
|
|
30340
30341
|
{
|
|
30341
30342
|
name: "dispatch_read",
|
|
30342
30343
|
example: { issue: "DSP-1" },
|
|
30343
|
-
description: "Read an issue or document summary, targeted ask, or targeted comment reply chain, or the conversation " + "a message belongs to. Do not use it for document contents; use dispatch doc-read instead. Supply ref, issue, " + "issue plus artifact (one of its documents), or project plus artifact; or message alone, which reads a human's direct message to this session and every " + "reply to it (they belong to no issue). A document summary names its issue, reference, versions and approval. " + "An anchored comment or ask also says where its quote sits, as `Position:`: the block's path from the top, " + "and in a table the row (0 is the header), the cells before the anchored one, and the column's header; " + "`Position: unavailable (<code>)` when Dispatch could not read the document: `DOC_SERVICE_UNAVAILABLE` " + "(try again shortly), `DOC_SCHEMA` (the document needs repair), `DOCUMENT_UNLOADABLE` (the document " + "needs a rebuild) or `INTERNAL`. " + "An issue read carries a `Progress:` line, `tasks 3/7, children 2/5`: its spec's task-list items " + "(`- [ ]` / `- [x]`, nested lists included) and its direct children, each done of total and each only " + "when it has any (`Progress: none` otherwise). " + "Every read ends with `Referenced by:` (what cites or hangs off this node, each with its dispatch:// address, " + "an excerpt, and when) and `Links:` (what it cites), so tracing provenance is one call. " + "The pictures the shown messages, asks and comments embed come back as images you see, newest first, at most 8 " + "and 10 MiB of them per read, each a PNG, JPEG, GIF or WebP of at most 3,750,000 bytes (5 MB of base64); a `Pictures:` section names each " + "one shown, in order, and the rest by reference, for dispatch doc-read. A picture this session was already shown is named, not sent again " + "(every request carries the session's history, and the provider refuses one over 32 MB); dispatch doc-read shows it again. " + OWNER_REFERENCE,
|
|
30344
|
+
description: "Read an issue or document summary, targeted ask, or targeted comment reply chain, or the conversation " + "a message belongs to. Do not use it for document contents; use dispatch doc-read instead. Supply ref, issue, " + "issue plus artifact (one of its documents), or project plus artifact; or message alone, which reads a human's direct message to this session and every " + "reply to it (they belong to no issue). A document summary names its issue, reference, versions and approval. " + "An anchored comment or ask also says where its quote sits, as `Position:`: the block's path from the top, " + "and in a table the row (0 is the header), the cells before the anchored one, and the column's header; " + "`Position: unavailable (<code>)` when Dispatch could not read the document: `DOC_SERVICE_UNAVAILABLE` " + "(try again shortly), `DOC_SCHEMA` (the document needs repair), `DOCUMENT_UNLOADABLE` (the document " + "needs a rebuild) or `INTERNAL`. " + "An issue read carries a `Progress:` line, `tasks 3/7, children 2/5`: its spec's task-list items " + "(`- [ ]` / `- [x]`, nested lists included) and its direct children, each done of total and each only " + "when it has any (`Progress: none` otherwise). " + `An issue read, and its dispatch://KEY/log, lists the issue's last ${DEFAULT_ISSUE_READ_EVENTS} events, oldest first; ` + "--events N lists the last N, and --all-events every one. " + "Every read ends with `Referenced by:` (what cites or hangs off this node, each with its dispatch:// address, " + "an excerpt, and when) and `Links:` (what it cites), so tracing provenance is one call. " + "The pictures the shown messages, asks and comments embed come back as images you see, newest first, at most 8 " + "and 10 MiB of them per read, each a PNG, JPEG, GIF or WebP of at most 3,750,000 bytes (5 MB of base64); a `Pictures:` section names each " + "one shown, in order, and the rest by reference, for dispatch doc-read. A picture this session was already shown is named, not sent again " + "(every request carries the session's history, and the provider refuses one over 32 MB); dispatch doc-read shows it again. " + OWNER_REFERENCE,
|
|
30344
30345
|
arguments: (z2) => ({
|
|
30345
30346
|
issue: z2.string().describe(ISSUE_REFERENCE).optional(),
|
|
30346
30347
|
project: z2.string().describe("Project key owning the document.").optional(),
|
|
30347
30348
|
artifact: z2.string().describe("Document artifact id, slug, or filename: one of the issue's, or a project document.").optional(),
|
|
30348
30349
|
ref: z2.string().describe("Optional dispatch:// issue or document reference.").optional(),
|
|
30349
|
-
message: z2.string().describe("A message id (uuid): reads the conversation it belongs to, the root message and every " + "reply. Name nothing else with it.").optional()
|
|
30350
|
+
message: z2.string().describe("A message id (uuid): reads the conversation it belongs to, the root message and every " + "reply. Name nothing else with it.").optional(),
|
|
30351
|
+
events: z2.number({ int: true, min: 1 }).describe(`How many of the issue's newest events an issue read or its dispatch://KEY/log lists, oldest first; default ${DEFAULT_ISSUE_READ_EVENTS}. Name no --all-events with it.`).optional(),
|
|
30352
|
+
all_events: z2.boolean().describe(`List every one of the issue's events, oldest first, on an issue read or its dispatch://KEY/log, in place of the last ${DEFAULT_ISSUE_READ_EVENTS}. Name no --events with it.`).optional()
|
|
30350
30353
|
}),
|
|
30351
30354
|
validation: readValidation
|
|
30352
30355
|
},
|
|
@@ -32705,6 +32708,7 @@ function asErrorShape(value) {
|
|
|
32705
32708
|
function isJson(response) {
|
|
32706
32709
|
return response.headers.get("content-type")?.includes("application/json") ?? false;
|
|
32707
32710
|
}
|
|
32711
|
+
var ISSUE_EVENTS_PAGE_MAX = 200;
|
|
32708
32712
|
var DISPATCH_TOOL_DEADLINE_MS = 60000;
|
|
32709
32713
|
function requestSignal(signal) {
|
|
32710
32714
|
const deadline = AbortSignal.timeout(DISPATCH_TOOL_DEADLINE_MS);
|
|
@@ -32846,13 +32850,28 @@ class DispatchClient {
|
|
|
32846
32850
|
async releaseIssueClaim(issue2, input = {}) {
|
|
32847
32851
|
return this.#json("DELETE", ["api", "v1", "issues", await this.#resolveIssue(issue2), "claim"], input);
|
|
32848
32852
|
}
|
|
32849
|
-
async getIssueEvents(issue2, after = 0, limit =
|
|
32853
|
+
async getIssueEvents(issue2, after = 0, limit = ISSUE_EVENTS_PAGE_MAX) {
|
|
32850
32854
|
return this.#json("GET", ["api", "v1", "issues", await this.#resolveIssue(issue2), "events"], undefined, { after, limit });
|
|
32851
32855
|
}
|
|
32852
|
-
async read(issueReference) {
|
|
32856
|
+
async read(issueReference, options = {}) {
|
|
32853
32857
|
const issueKey = await this.#resolveIssue(issueReference);
|
|
32854
32858
|
const issue2 = await this.getIssue(issueKey);
|
|
32855
|
-
const
|
|
32859
|
+
const requested = options.events;
|
|
32860
|
+
const count = requested === undefined ? DEFAULT_ISSUE_READ_EVENTS : requested === "all" ? issue2.last_seq : Math.min(requested, issue2.last_seq);
|
|
32861
|
+
const events = [];
|
|
32862
|
+
let after = Math.max(0, issue2.last_seq - count);
|
|
32863
|
+
while (events.length < count) {
|
|
32864
|
+
const limit = Math.min(ISSUE_EVENTS_PAGE_MAX, count - events.length);
|
|
32865
|
+
const page = await this.getIssueEvents(issueKey, after, limit);
|
|
32866
|
+
events.push(...page);
|
|
32867
|
+
const last = page.at(-1);
|
|
32868
|
+
if (page.length < limit || last === undefined || events.length >= count)
|
|
32869
|
+
break;
|
|
32870
|
+
if (last.seq <= after) {
|
|
32871
|
+
throw new Error(`GET /api/v1/issues/${issueKey}/events?after=${after} answered no event after seq ${after}`);
|
|
32872
|
+
}
|
|
32873
|
+
after = last.seq;
|
|
32874
|
+
}
|
|
32856
32875
|
return { issue: issue2, events };
|
|
32857
32876
|
}
|
|
32858
32877
|
async ask(issue2, input) {
|
|
@@ -4,7 +4,8 @@ Read this to catch up after a restart, read a node, trace what cites it, or writ
|
|
|
4
4
|
|
|
5
5
|
## What comes back
|
|
6
6
|
|
|
7
|
-
- After a restart, catch up with `dispatch read --issue <KEY>` (or `--artifact` with `--issue` or `--project`, or `--ref`). It prints the issue's summary, open asks, references and
|
|
7
|
+
- After a restart, catch up with `dispatch read --issue <KEY>` (or `--artifact` with `--issue` or `--project`, or `--ref`). It prints the issue's summary, open asks, references and last 10 events, a document's summary (its issue, reference, versions and approval), or an ask's, comment's or message's thread. Reads do not subscribe. Use `dispatch doc-read` for document text.
|
|
8
|
+
- To audit an issue's history (who asked what, which ask was answered), add `--events N` for the last N events or `--all-events` for every one. Both work on `--ref dispatch://KEY/log` too.
|
|
8
9
|
- An anchored comment or ask prints `Position:`, where its quote's block stands. `unavailable (DOC_SERVICE_UNAVAILABLE)` means try again shortly. `unavailable (DOC_SCHEMA)` means the document needs repair.
|
|
9
10
|
- The API gives the same facts as `anchor_block` (or `anchor_block_error`) on `GET /api/v1/comments/{id}` and `GET /api/v1/asks/{id}`. `GET /api/v1/artifacts/{id}/blocks/{block_id}` gives them for any block.
|
|
10
11
|
- Each read ends with `Referenced by:` (what cites the node) and `Links:` (what it cites), across projects. "What led to this decision" is one read on the ask.
|