@qilin-agent/tools 0.0.0-stage → 3.1.3

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.
@@ -0,0 +1,367 @@
1
+ /**
2
+ * Tool render-intent vocabulary: the provider-neutral types a tool declares via
3
+ * `ToolDefinition.presentCall`/`ToolDefinition.presentResult` to say how one of its calls
4
+ * renders in a UI (an editor's tool-call card, a CLI log line).
5
+ * @module @qilin-agent/tools/src/presentation
6
+ */
7
+ import type { ContentBlock } from '@qilin-agent/llm';
8
+ /**
9
+ * Category of a tool call, used by a UI to pick an icon or treatment. The
10
+ * provider-neutral vocabulary lets tools describe themselves without depending
11
+ * on a particular client; `other` is the default.
12
+ */
13
+ export type ToolCallKind = 'read' | 'edit' | 'delete' | 'move' | 'search' | 'execute' | 'fetch' | 'other';
14
+ /**
15
+ * A file location a tool reads or modifies, so a capable UI can "follow along" —
16
+ * highlight or jump to the file (and line) as the tool runs. `path` is what the
17
+ * tool operated on (the model-facing path); `line` is an optional 1-based line
18
+ * to focus (e.g. a read's offset).
19
+ */
20
+ export interface FileLocation {
21
+ path: string;
22
+ line?: number;
23
+ }
24
+ /**
25
+ * A single-file change a tool is about to make, for a UI that renders inline
26
+ * diffs. `oldText` is `null` for a new-file create (nothing to diff against);
27
+ * an overwrite also uses `null`, because a call-time presenter has no access to
28
+ * the file's prior content.
29
+ */
30
+ export interface FileDiff {
31
+ path: string;
32
+ /** Prior content, or `null` for a new file / an overwrite (no prior content available at call time). */
33
+ oldText: string | null;
34
+ /** Content after the change. */
35
+ newText: string;
36
+ }
37
+ /**
38
+ * Provider-neutral pending-call presentation. Tools declare one tagged intent;
39
+ * UI bridges map it without special-casing tool names.
40
+ */
41
+ export type ToolCallView = GenericCallView | TerminalCallView | DiffCallView;
42
+ /**
43
+ * The default card: a titled tool-call row with an optional category icon, a
44
+ * salient raw input, extra content blocks, and follow-along file locations. Any
45
+ * tool whose call is not a terminal or a diff uses this.
46
+ */
47
+ export interface GenericCallView {
48
+ card: 'generic';
49
+ /**
50
+ * Human-readable, always-visible label describing what THIS call does. Keep it
51
+ * short — a UI shows it as a card header / log line.
52
+ */
53
+ title: string;
54
+ /** Category for icon/treatment; defaults to `other` when omitted. */
55
+ kind?: ToolCallKind;
56
+ /**
57
+ * The salient input to show in a detail/expanded view (e.g. a background
58
+ * job id). Omit to show nothing; a string renders as-is, an object as pretty
59
+ * JSON. NOT the full raw args object unless that is genuinely what a reader wants.
60
+ */
61
+ rawInput?: unknown;
62
+ /**
63
+ * UI-facing content blocks to show on the pending call alongside the title.
64
+ * Omit to show none. A UI maps these to its own content blocks.
65
+ */
66
+ content?: ContentBlock[];
67
+ /** Files this call reads/modifies, for editor follow-along. Omit for a call that touches no file. */
68
+ locations?: FileLocation[];
69
+ }
70
+ /**
71
+ * A call that IS a shell command running in a working directory: a capable UI
72
+ * renders it as a terminal card (cwd-headed, with the command as the title and
73
+ * live/afterward output from the {@link TerminalResultView}); an incapable UI
74
+ * falls back to a generic card whose body is the fenced command output. Set by a
75
+ * tool whose call is a foreground command (e.g. `bash`).
76
+ */
77
+ export interface TerminalCallView {
78
+ card: 'terminal';
79
+ /** The command, shown as the terminal card's title / header line. */
80
+ title: string;
81
+ /**
82
+ * A human-readable one-line summary of what the command does, rendered ABOVE
83
+ * the terminal card (the card itself has no description slot). Omit for none.
84
+ */
85
+ description?: string;
86
+ /**
87
+ * Working directory the command runs in, shown as the terminal header. An
88
+ * ABSOLUTE path is used as-is; a RELATIVE path is resolved by the UI bridge
89
+ * against the session workspace (the pure presenter can't see the session cwd).
90
+ * Omit entirely to let the bridge use the session workspace.
91
+ */
92
+ cwd?: string;
93
+ }
94
+ /**
95
+ * A call that creates or modifies files, rendered as an inline diff card by a
96
+ * capable UI. Set by a tool whose call writes/edits a file (e.g. `write`,
97
+ * `edit`). The diffs are derived from the call ARGUMENTS (a create's `oldText` is
98
+ * `null`); the tool emits a separate {@link DiffResultView} after `execute` — the
99
+ * applied change (an edit/overwrite hunk with context, or a whole-file diff for a
100
+ * create).
101
+ */
102
+ export interface DiffCallView {
103
+ card: 'diff';
104
+ /** Card header (e.g. `Write foo.txt`). */
105
+ title: string;
106
+ /** One entry per file the call changes. */
107
+ diffs: FileDiff[];
108
+ /** Files this call modifies, for editor follow-along (usually the diffs' paths). */
109
+ locations?: FileLocation[];
110
+ }
111
+ /**
112
+ * One numbered line of a file, the unit a {@link ReadResultView} carries so a
113
+ * capable UI can render a syntax-highlighted, line-numbered code view. `number`
114
+ * is the 1-based line number in the file (a window past `offset` keeps the file's
115
+ * own numbering, not a 1-based re-count); `text` is the line without its trailing
116
+ * newline, already truncated to the read tool's per-line cap.
117
+ */
118
+ export interface ReadFileLine {
119
+ number: number;
120
+ text: string;
121
+ }
122
+ /**
123
+ * How a tool wants the COMPLETED call shown — the *result* state, after `execute`
124
+ * returns. A `card`-tagged union mirroring {@link ToolCallView}: a UI switches on
125
+ * `card`. Lets the tool reformat its result for a UI distinctly from the
126
+ * model-facing text it returned from `execute`. Returned by
127
+ * `ToolDefinition.presentResult`; omitting the method keeps the pending
128
+ * title and renders the raw result content.
129
+ */
130
+ export type ToolResultView = GenericResultView | TerminalResultView | DiffResultView | SearchResultView | ReadResultView | WebResultView;
131
+ /**
132
+ * The default completed card: an optional replacement title and reformatted
133
+ * content. Omit a field to keep the pending title / render the raw result content.
134
+ */
135
+ export interface GenericResultView {
136
+ card: 'generic';
137
+ /** Replacement title for the completed call. Omit to keep the pending-state title. */
138
+ title?: string;
139
+ /**
140
+ * UI-facing result content (harness {@link ContentBlock}s), reformatted from
141
+ * the model-facing result. Omit to let the UI render the raw result content.
142
+ */
143
+ content?: ContentBlock[];
144
+ }
145
+ /**
146
+ * The completed state of a {@link TerminalCallView}: the captured output and exit
147
+ * status. A capable UI renders `output` in the terminal card and shows an
148
+ * exit-status pill; an incapable UI gets a fenced ```console fallback the BRIDGE
149
+ * derives from `output` (the tool does not double-encode it).
150
+ */
151
+ export interface TerminalResultView {
152
+ card: 'terminal';
153
+ /** Replacement title for the completed call. Omit to keep the pending-state title. */
154
+ title?: string;
155
+ /** Captured command output (stdout+stderr as the tool chooses to combine them). */
156
+ output?: string;
157
+ /**
158
+ * Process exit code, when the run ended by exiting (not a signal). Lets a
159
+ * capable UI show an exit-status pill. Omit when killed by a signal or unknown.
160
+ */
161
+ exitCode?: number;
162
+ /** Signal name that killed the process (e.g. `SIGTERM`). Mutually exclusive with `exitCode`. */
163
+ signal?: string;
164
+ }
165
+ /**
166
+ * A completed file mutation rendered as an inline diff card, the result-time
167
+ * analogue of {@link DiffCallView}. Because a completed UI update replaces the
168
+ * pending card content, mutation tools return this even when it repeats the
169
+ * call-time diff; otherwise raw result text would replace the diff.
170
+ */
171
+ export interface DiffResultView {
172
+ card: 'diff';
173
+ /** Replacement title for the completed call. Omit to keep the pending-state title. */
174
+ title?: string;
175
+ /** The change to show, in file order — applied contextual hunks, or a whole-file diff when there is no before-image. */
176
+ diffs: FileDiff[];
177
+ }
178
+ /** One matched line inside a {@link SearchFileMatches} group: its 1-based line number and text. */
179
+ export interface SearchLineMatch {
180
+ /** 1-based line number of the match within its file. */
181
+ lineNumber: number;
182
+ /** The matched line text, as the tool surfaced it (the per-line preview budget already applied). */
183
+ line: string;
184
+ }
185
+ /** One file's grouped content matches for a {@link SearchMatchesResultView}, in first-seen file order. */
186
+ export interface SearchFileMatches {
187
+ /** The file the matches belong to (the model-facing display path). */
188
+ path: string;
189
+ /** The file's matched lines, in output order. */
190
+ matches: SearchLineMatch[];
191
+ }
192
+ /**
193
+ * A completed content search (`grep`) rendered as a search card whose matches are
194
+ * grouped by file, so a capable UI can list each file as an expandable group of
195
+ * its matched lines. `shape: 'matches'` discriminates this variant from the path
196
+ * variant ({@link SearchPathsResultView}) within {@link SearchResultView}. The
197
+ * discriminant is `shape`, not `kind`, so it never collides with the
198
+ * {@link ToolCallKind} `kind` an icon-picking bridge reads off a call view.
199
+ */
200
+ export interface SearchMatchesResultView {
201
+ card: 'search';
202
+ shape: 'matches';
203
+ /** Replacement title for the completed call. Omit to keep the pending-state title. */
204
+ title?: string;
205
+ /** Matched lines grouped by file, in first-seen file order. */
206
+ files: SearchFileMatches[];
207
+ /**
208
+ * Whether the tool capped the inline result: `files` carries only the retained
209
+ * matches, not every match the search found. A UI shows a capped indicator so it
210
+ * never presents a partial group as complete.
211
+ */
212
+ truncated: boolean;
213
+ /** Total matches the search found before capping (equals the retained count when not `truncated`). */
214
+ total: number;
215
+ }
216
+ /**
217
+ * A completed path search (`glob`) rendered as a search card whose result is a flat
218
+ * path list. `shape: 'paths'` discriminates this variant from the grouped-matches
219
+ * variant ({@link SearchMatchesResultView}) within {@link SearchResultView}.
220
+ */
221
+ export interface SearchPathsResultView {
222
+ card: 'search';
223
+ shape: 'paths';
224
+ /** Replacement title for the completed call. Omit to keep the pending-state title. */
225
+ title?: string;
226
+ /** The discovered paths, in the tool's result order (the retained page when `truncated`). */
227
+ paths: string[];
228
+ /**
229
+ * Whether the tool capped the inline result: `paths` carries only the retained
230
+ * page, not every path the search found. A UI shows a capped indicator so it
231
+ * never presents a partial list as complete.
232
+ */
233
+ truncated: boolean;
234
+ /** Total paths the search found before capping (equals `paths.length` when not `truncated`). */
235
+ total: number;
236
+ }
237
+ /**
238
+ * A completed search rendered as a search card, the result-time view a discovery
239
+ * tool (`grep`, `glob`) returns from `presentResult`. One `card: 'search'` view
240
+ * with two `shape`-discriminated variants: grouped-by-file content matches
241
+ * ({@link SearchMatchesResultView}) and a flat path list
242
+ * ({@link SearchPathsResultView}). Both carry a `truncated`/`total` signal so a UI
243
+ * never presents a capped result as complete. The view carries no result text: a
244
+ * UI without a search card falls back to the raw `tool/result` content. There is
245
+ * no call-time analogue: a search call stays a {@link GenericCallView}
246
+ * (`kind: 'search'`) because the pending state has no matches or paths to show —
247
+ * the structured shape exists only after `execute`.
248
+ */
249
+ export type SearchResultView = SearchMatchesResultView | SearchPathsResultView;
250
+ /**
251
+ * A completed file read rendered as a line-numbered, optionally syntax-highlighted
252
+ * code view by a capable UI. Set by a tool whose call reads file text (e.g.
253
+ * `read`); the pending state stays a {@link GenericCallView} (`kind: 'read'`)
254
+ * because a call carries no content until `execute` returns. The structured
255
+ * `lines`/`path`/`lang`/`totalLines` fields cannot be reconstructed from the
256
+ * model-facing result text alone, so the read tool projects them through its
257
+ * `output.presentationMeta` (persisted with the session log) and `presentResult`
258
+ * narrows that metadata back into this view on live and replay paths alike. A UI
259
+ * without the read capability falls back to `content` (the model-facing text with
260
+ * its envelope stripped), so this view degrades to the generic text card.
261
+ */
262
+ export interface ReadResultView {
263
+ card: 'read';
264
+ /** Replacement title for the completed call. Omit to keep the pending-state title. */
265
+ title?: string;
266
+ /** The read file's path (the model-facing path; the bridge relativizes it). */
267
+ path: string;
268
+ /**
269
+ * The 1-based first line the window requested, preserved even when `lines` is
270
+ * empty (a byte cap below the first selected line yields an empty window) so a
271
+ * UI knows where the window starts and where a continuation resumes.
272
+ */
273
+ offset: number;
274
+ /** The returned window's lines, in file order, each keeping its file line number. */
275
+ lines: ReadFileLine[];
276
+ /** Exact total line count in the file, so a UI can show a "showing N of M" affordance. */
277
+ totalLines: number;
278
+ /**
279
+ * A syntax-highlighting language hint derived from the file extension (e.g.
280
+ * `ts`, `py`), or omitted when the extension maps to no known language so a UI
281
+ * renders the lines as plain text.
282
+ */
283
+ lang?: string;
284
+ /**
285
+ * The model-facing result content with its envelope stripped, for a UI without
286
+ * the read capability. Omit to let such a UI render the raw result content.
287
+ */
288
+ content?: ContentBlock[];
289
+ }
290
+ /**
291
+ * One citeable source in a completed {@link WebSearchResultView}, the faithful
292
+ * projection of one web-search source. The presentation projection of `qilin-web`'s
293
+ * `WebSearchSource`: that Service Definition type is authoritative (core cannot depend
294
+ * on the web Service Definition, so the two are declared separately and MUST evolve together).
295
+ * A web tool projects this shape through `output.presentationMeta` because the
296
+ * render text cannot losslessly carry it (see the web-result-card Agent Note); its
297
+ * `presentResult` reads it back.
298
+ */
299
+ export interface WebSource {
300
+ /** The source URL. */
301
+ url: string;
302
+ /** The source title, when the provider returned one. */
303
+ title?: string;
304
+ /** A short excerpt or summary, when the provider returned one. */
305
+ snippet?: string;
306
+ /** Publication/crawl timestamp as a provider-supplied ISO-8601 string, when present. */
307
+ publishedAt?: string;
308
+ }
309
+ /**
310
+ * A completed web retrieval rendered as a structured card by a capable UI. Set
311
+ * by a web tool whose call retrieves from the web (`web_search`, `web_fetch`).
312
+ * One `kind`-tagged union carries both shapes because both are web retrieval and
313
+ * a UI renders them with one component family; a UI switches on `kind`. An
314
+ * incapable UI falls back to the raw `tool/result` content (this view carries no
315
+ * `content` copy — see the web-result-card Agent Note). This is the result-time
316
+ * analogue of the `web_search`/`web_fetch` calls' generic call views
317
+ * (`kind: 'search'`/`'fetch'`); those tools keep their generic pending card and
318
+ * add only this completed card.
319
+ *
320
+ * The `kind` field here is this union's own discriminant, NOT a
321
+ * {@link ToolCallKind}: the two values deliberately match the tools' pending
322
+ * `ToolCallKind` (`'search'`/`'fetch'`) so a call and its result read as one
323
+ * category, but a new arm is a union edit plus a consumer branch, not any
324
+ * arbitrary `ToolCallKind` value.
325
+ */
326
+ export type WebResultView = WebSearchResultView | WebFetchResultView;
327
+ /**
328
+ * The completed state of a `web_search` call: the structured sources the model
329
+ * cited, an optional provider answer, and whether the source list was cut to the
330
+ * result cap. A capable UI renders the sources as a citation list; a UI without
331
+ * the `web` capability falls back to the raw `tool/result` content.
332
+ */
333
+ export interface WebSearchResultView {
334
+ card: 'web';
335
+ kind: 'search';
336
+ /** Replacement title for the completed call. Omit to keep the pending-state title. */
337
+ title?: string;
338
+ /** The faithful, structured sources — the field render text cannot losslessly carry. */
339
+ sources: WebSource[];
340
+ /** The provider-generated answer text, when any. */
341
+ answer?: string;
342
+ /** True when the web service cut the source list to honor the result cap. */
343
+ truncated: boolean;
344
+ }
345
+ /**
346
+ * The completed state of a `web_fetch` call: the fetched URL, its HTTP status,
347
+ * and whether the content was cut. The body itself is already markdown in the
348
+ * raw `tool/result` content, so this card carries only the retrieval summary and
349
+ * a UI without the `web` capability falls back to that content.
350
+ */
351
+ export interface WebFetchResultView {
352
+ card: 'web';
353
+ kind: 'fetch';
354
+ /** Replacement title for the completed call. Omit to keep the pending-state title. */
355
+ title?: string;
356
+ /** The final URL after allowed redirects. */
357
+ url: string;
358
+ /** HTTP status code of the fetched response. */
359
+ statusCode: number;
360
+ /**
361
+ * True when the provider capped the decoded body, or the output cap or a
362
+ * pre-conversion source cut trimmed the rendered text (the effective
363
+ * truncation the model-facing text also reflects).
364
+ */
365
+ truncated: boolean;
366
+ }
367
+ //# sourceMappingURL=presentation.d.ts.map
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Tool render-intent vocabulary: the provider-neutral types a tool declares via
3
+ * `ToolDefinition.presentCall`/`ToolDefinition.presentResult` to say how one of its calls
4
+ * renders in a UI (an editor's tool-call card, a CLI log line).
5
+ * @module @qilin-agent/tools/src/presentation
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=presentation.js.map
@@ -0,0 +1,80 @@
1
+ /**
2
+ * PTC mode `run_code` transport. Programs call the registry's agent-visible
3
+ * tools through nested executions scheduled under the native concurrency
4
+ * contract; each sub-dispatch is logged for reconstruction, while only the
5
+ * outer curated result enters model history.
6
+ * @module @qilin-agent/tools/src/ptc
7
+ */
8
+ import { HarnessError } from '@qilin-agent/llm';
9
+ declare module '@qilin-agent/llm' {
10
+ interface MessageSourceMap {
11
+ /** Images deferred from a successful PTC subcall's final result. */
12
+ 'ptc-mode': {
13
+ kind: 'ptc-mode';
14
+ };
15
+ }
16
+ }
17
+ import type { ContentBlock } from '@qilin-agent/llm';
18
+ import type { PtcRuntime } from '@qilin-agent/ptc-runtime';
19
+ import type { SandboxExecutionPolicy } from '@qilin-agent/sandbox';
20
+ import type { ApprovalService } from '@qilin-agent/user-approval';
21
+ import type { PtcDispatchLog, ToolDefinition, ToolRuntime, ToolRunContext } from './index.ts';
22
+ /** The model-facing name of the PTC mode tool. */
23
+ export declare const RUN_CODE_NAME = "run_code";
24
+ /**
25
+ * The languages PTC mode ships a presentation for. Both per-language tables —
26
+ * {@link RUN_CODE_FLAVORS} here and `SDK_RENDERERS` in {@link ./index.ts} — are
27
+ * checked against this union with `satisfies`, so a language added to one and
28
+ * not the other fails `typecheck` instead of waiting for a runtime that reports
29
+ * it. The tables stay declared `Record<string, …>` because `PtcRuntime.language`
30
+ * is an unconstrained `string`: this union pins what the harness ships, while the
31
+ * `Object.hasOwn` guards reject what a mounted runtime may report.
32
+ */
33
+ export type PtcSdkLanguage = 'typescript' | 'python';
34
+ /**
35
+ * Thrown by `run_code` when the program run itself failed — a program
36
+ * exception, a budget expiry, an abort, or substrate death. Extends
37
+ * {@link HarnessError} (`code: 'CODE_RUN_FAILED'`); the registry's execution
38
+ * pipeline converts it into a structured `isError` result whose text carries
39
+ * the failure kind plus the captured logs, so the model can self-correct.
40
+ */
41
+ export declare class CodeRunFailedError extends HarnessError {
42
+ constructor(message: string);
43
+ }
44
+ /**
45
+ * Registry-private capabilities the bridge receives at construction — the
46
+ * `requireRuntime` idiom: operations only the owning registry can mint stay
47
+ * off its public service API and flow here as closures instead.
48
+ */
49
+ export interface RunCodeBridgeOptions {
50
+ /** Reads the approval channel when a program requests a wider sandbox mode. */
51
+ peekApprover: () => ApprovalService | undefined;
52
+ /** Resolves standing Session authority only for a runtime that enforces file policy. */
53
+ resolveSandboxPolicy: (exec: ToolRunContext) => SandboxExecutionPolicy;
54
+ /** Resolves `ctx.ptcRuntime` or throws the loud misconfiguration error (shared with the registry's assembly-time checks). */
55
+ requireRuntime: () => PtcRuntime;
56
+ /**
57
+ * Reads `ctx.ptcRuntime` without throwing: `undefined` when none is mounted.
58
+ * Lets schema emission tell "no runtime" (degrade to TS; the readers that
59
+ * reach it are {@link resolveFlavor}'s) apart from "unknown language" (fail
60
+ * loud).
61
+ */
62
+ peekRuntime: () => PtcRuntime | undefined;
63
+ /** The run's overlap cap for parallel-classified sub-calls (the registry passes its validated `maxParallelSubCalls`). */
64
+ maxParallel: number;
65
+ /** Runs the contained `tools/ptc-dispatch-log` waterfall over one settled sub-dispatch (the registry's private invoker). */
66
+ shapeDispatchLog: (dispatch: PtcDispatchLog) => Promise<ContentBlock[]>;
67
+ }
68
+ /**
69
+ * Build the `run_code` {@link ToolDefinition}: required `description` and
70
+ * `code` parameters, executed through the dispatch bridge described
71
+ * above. The
72
+ * registry reserves it as presentation infrastructure under non-native modes,
73
+ * outside the filterable global/scoped capability layers.
74
+ * @param registry - the owning registry (sub-calls go through its `execute`,
75
+ * bindings cover its registered tools).
76
+ * @param options - the registry-private capabilities described above.
77
+ * @returns the registry-ready definition.
78
+ */
79
+ export declare function createRunCodeTool(registry: ToolRuntime, options: RunCodeBridgeOptions): ToolDefinition;
80
+ //# sourceMappingURL=ptc.d.ts.map