@sjawhar/opencode-legion-envoy 5.9.3 → 5.10.1
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/src/server.js
CHANGED
|
@@ -13564,6 +13564,7 @@ var DEFAULT_ISSUE_PAGE_LIMIT = 50;
|
|
|
13564
13564
|
var ASK_TURNS = ["human", "agent"];
|
|
13565
13565
|
var DELIVERY_CAPABILITIES = ["aside", "btw", "steer"];
|
|
13566
13566
|
var DELIVERY_DUPLICATE_WINDOW_MS = 72 * 60 * 60 * 1000;
|
|
13567
|
+
var SEARCH_DEGRADED_EMBEDDER_UNAVAILABLE = "embedder_unavailable";
|
|
13567
13568
|
var DispatchEventSchema = exports_external.object({
|
|
13568
13569
|
issue_key: exports_external.string().nullable(),
|
|
13569
13570
|
artifact_id: exports_external.string().nullish(),
|
|
@@ -15736,14 +15737,20 @@ function searchAnswer(search, query, offset, configUrl) {
|
|
|
15736
15737
|
const lines = results.map((result) => searchResultLine(result, configUrl));
|
|
15737
15738
|
const noun = count === 1 ? "result" : "results";
|
|
15738
15739
|
const noResults = `No results for "${query}".`;
|
|
15740
|
+
const degraded = search.degraded === SEARCH_DEGRADED_EMBEDDER_UNAVAILABLE ? "Searched by keyword only: meaning search was unavailable for this request." : undefined;
|
|
15739
15741
|
if (typeof search.total !== "number") {
|
|
15740
15742
|
if (offset !== undefined && offset > 0) {
|
|
15741
15743
|
throw new Error(`Dispatch answered without a total: it predates search paging and ignored offset ${offset}, so this would be its first page again.`);
|
|
15742
15744
|
}
|
|
15743
15745
|
return {
|
|
15744
|
-
text: count === 0 ? noResults
|
|
15746
|
+
text: count === 0 ? [noResults, ...degraded === undefined ? [] : [degraded]].join(`
|
|
15747
|
+
`) : [
|
|
15748
|
+
`${count} ${noun} for "${query}" (${search.took_ms} ms)`,
|
|
15749
|
+
...degraded === undefined ? [] : [degraded],
|
|
15750
|
+
...lines
|
|
15751
|
+
].join(`
|
|
15745
15752
|
`),
|
|
15746
|
-
details: { query, results }
|
|
15753
|
+
details: { query, results, ...degraded === undefined ? {} : { degraded: search.degraded } }
|
|
15747
15754
|
};
|
|
15748
15755
|
}
|
|
15749
15756
|
const { total, reachable, offset: pageOffset } = search;
|
|
@@ -15755,12 +15762,15 @@ function searchAnswer(search, query, offset, configUrl) {
|
|
|
15755
15762
|
total,
|
|
15756
15763
|
reachable,
|
|
15757
15764
|
offset: pageOffset,
|
|
15758
|
-
limit: search.limit
|
|
15765
|
+
limit: search.limit,
|
|
15766
|
+
...degraded === undefined ? {} : { degraded: search.degraded }
|
|
15759
15767
|
};
|
|
15760
15768
|
if (count === 0) {
|
|
15761
15769
|
return {
|
|
15762
|
-
text: total === 0 ? noResults : [
|
|
15770
|
+
text: total === 0 ? [noResults, ...degraded === undefined ? [] : [degraded]].join(`
|
|
15771
|
+
`) : [
|
|
15763
15772
|
`No results for "${query}" at offset ${pageOffset}: it matches ${total}, and the pages reach the first ${reachable}.`,
|
|
15773
|
+
...degraded === undefined ? [] : [degraded],
|
|
15764
15774
|
...cut === undefined ? [] : [cut]
|
|
15765
15775
|
].join(`
|
|
15766
15776
|
`),
|
|
@@ -15771,6 +15781,7 @@ function searchAnswer(search, query, offset, configUrl) {
|
|
|
15771
15781
|
return {
|
|
15772
15782
|
text: [
|
|
15773
15783
|
`${count} ${noun} for "${query}" (${showing}${search.took_ms} ms)`,
|
|
15784
|
+
...degraded === undefined ? [] : [degraded],
|
|
15774
15785
|
...cut === undefined ? [] : [cut],
|
|
15775
15786
|
...lines,
|
|
15776
15787
|
...end < reachable ? [`Next page: offset ${end}.`] : []
|
package/package.json
CHANGED
package/skills/dispatch/SKILL.md
CHANGED
|
@@ -164,14 +164,14 @@ do with each hit. What it leaves out:
|
|
|
164
164
|
dispatch_search({ query, project?, limit?, offset? })
|
|
165
165
|
```
|
|
166
166
|
Websearch syntax applies: `"merge queue"`, `-daemon`, `OR`. Issues, documents, asks, comments, and messages rank separately; the
|
|
167
|
-
merged page orders each kind's best in turn — issue, document, ask, comment, message — and a bare issue key ranks first.
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
Read them; reference the existing issue, or repeat the call with `force: true` when it is genuinely new work.
|
|
167
|
+
merged page orders each kind's best in turn — issue, document, ask, comment, message — and a bare issue key ranks first. Each
|
|
168
|
+
kind's list also merges a query embedding's meaning match with keyword hits (LEGION-549): a paraphrase with no shared word can
|
|
169
|
+
still match; without an embedder, it says so and ranks by keyword alone. A page holds `limit` hits (20 default, 50 max); the first
|
|
170
|
+
line gives the total (`showing 1-20 of 312`); see [Search paging](skill://dispatch/references/issues.md#search-paging) for more.
|
|
171
|
+
Queries over 1,000 characters are refused: use the few words `skill://dispatch-first` names, never a pasted passage. Issue hits
|
|
172
|
+
start with the issue key; document hits start with `dispatch://PROJECT/artifact/<slug>`, then the link. Cite the hit (`dispatch://KEY` or the doc ref) or say "no prior issue".
|
|
173
|
+
|
|
174
|
+
`dispatch_issue` refuses a title that near-duplicates an issue in the same project and returns the candidates (`POSSIBLE_DUPLICATE`). Read them; reference the existing issue, or repeat the call with `force: true` when it is genuinely new work.
|
|
175
175
|
The check compares title words only (shared stemmed terms), never meaning: "four tests that fail a
|
|
176
176
|
merge" pairs with "four CI gates that cannot fail a merge". So when you force past a candidate, give
|
|
177
177
|
the new issue a title that names what differs where you can, and open its spec with the
|
|
@@ -50,6 +50,11 @@ judgment across many files). Do not name any other agent.
|
|
|
50
50
|
| 3. Framework docs | `read` the library's documentation URL | [library] [topic] |
|
|
51
51
|
| 4. External practices | `web_search`, then `read` the primary source | Current best practices for [topic] |
|
|
52
52
|
|
|
53
|
+
Before relying on a step 1 hit, also search for `supersedes: docs/solutions/<its-path>` and
|
|
54
|
+
`Extends docs/solutions/<its-path>` naming it: a newer file may extend or supersede what you
|
|
55
|
+
found, and Legion runs no pass that reconciles these links, so following them is the only way to
|
|
56
|
+
know the hit is still current.
|
|
57
|
+
|
|
53
58
|
## Output
|
|
54
59
|
|
|
55
60
|
**Found:** Answer with source (file:line or URL)
|
|
@@ -67,13 +67,26 @@ Do not start retro before step 2 or skip it because the change seems mechanical;
|
|
|
67
67
|
## Durable outputs
|
|
68
68
|
|
|
69
69
|
Write the integrated learning as one or more discoverable documents under `docs/solutions/`.
|
|
70
|
-
Organize by reusable topic rather than by pull request
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
`
|
|
75
|
-
|
|
76
|
-
|
|
70
|
+
Organize by reusable topic rather than by pull request, but never edit a document you did not
|
|
71
|
+
write this retro — not its frontmatter, not its body. Two trees' retros can land within the same
|
|
72
|
+
hour, and an in-place edit (another `related_issues` entry, a sharpened sentence, a `status`
|
|
73
|
+
flip) conflicts with any other tree's edit to the same lines of the same file. Search
|
|
74
|
+
`docs/solutions/` for the topic first; before relying on a hit, also search for
|
|
75
|
+
`supersedes: docs/solutions/<its-path>` and `Extends docs/solutions/<its-path>` naming it —
|
|
76
|
+
Legion runs no pass that reconciles these links, so a newer file that extends or supersedes the
|
|
77
|
+
one you found is discoverable only by following them. Then write a new file of your own, named
|
|
78
|
+
`docs/solutions/<category>/<slug>-<LEGION_ISSUE>.md` so two trees never choose the same path:
|
|
79
|
+
|
|
80
|
+
- **A fresh topic:** state the rule in a few imperative lines; the incident goes in an Evidence
|
|
81
|
+
section below, never in the rule.
|
|
82
|
+
- **A topic an existing document already covers:** underneath its own H1 heading, the first line
|
|
83
|
+
reads `Extends docs/solutions/<existing-path>.md.`; the rule states only the delta.
|
|
84
|
+
- **A topic an existing document states wrongly:** frontmatter adds
|
|
85
|
+
`supersedes: docs/solutions/<existing-path>.md`; the first line under the H1 says why. Leave
|
|
86
|
+
the old file's frontmatter and body untouched: Legion runs no pass that reconciles it, so the
|
|
87
|
+
`supersedes:` link is the only thing that makes the correction discoverable from the old file.
|
|
88
|
+
|
|
89
|
+
Each document uses this front matter:
|
|
77
90
|
|
|
78
91
|
```yaml
|
|
79
92
|
---
|