@alisio/core 0.1.0-alpha.9 → 0.1.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/README.md +52 -7
- package/dist/agents/active.d.ts +99 -0
- package/dist/agents/active.js +218 -0
- package/dist/agents/capabilities.d.ts +26 -0
- package/dist/agents/capabilities.js +120 -0
- package/dist/agents/create-agent-skill.d.ts +11 -0
- package/dist/agents/create-agent-skill.js +60 -0
- package/dist/agents/definitions.d.ts +88 -0
- package/dist/agents/definitions.js +404 -0
- package/dist/agents/draft.d.ts +41 -0
- package/dist/agents/draft.js +133 -0
- package/dist/agents/service.d.ts +57 -0
- package/dist/agents/service.js +86 -0
- package/dist/agents/templates.d.ts +8 -0
- package/dist/agents/templates.js +102 -0
- package/dist/analysis/capabilities.d.ts +48 -0
- package/dist/analysis/capabilities.js +90 -0
- package/dist/analysis/data/csv.d.ts +46 -0
- package/dist/analysis/data/csv.js +240 -0
- package/dist/analysis/data/datasets.d.ts +132 -0
- package/dist/analysis/data/datasets.js +441 -0
- package/dist/analysis/data/describe.d.ts +27 -0
- package/dist/analysis/data/describe.js +103 -0
- package/dist/analysis/data/engine-client.d.ts +58 -0
- package/dist/analysis/data/engine-client.js +304 -0
- package/dist/analysis/data/engine-entry.d.ts +1 -0
- package/dist/analysis/data/engine-entry.js +59 -0
- package/dist/analysis/data/engine-source.d.ts +4 -0
- package/dist/analysis/data/engine-source.js +6 -0
- package/dist/analysis/data/engine-types.d.ts +86 -0
- package/dist/analysis/data/engine-types.js +7 -0
- package/dist/analysis/data/infer.d.ts +42 -0
- package/dist/analysis/data/infer.js +118 -0
- package/dist/analysis/data/ingest-worker.d.ts +17 -0
- package/dist/analysis/data/ingest-worker.js +365 -0
- package/dist/analysis/data/json.d.ts +19 -0
- package/dist/analysis/data/json.js +44 -0
- package/dist/analysis/data/query-worker.d.ts +12 -0
- package/dist/analysis/data/query-worker.js +75 -0
- package/dist/analysis/data/rows.d.ts +39 -0
- package/dist/analysis/data/rows.js +120 -0
- package/dist/analysis/data/sql-guard.d.ts +20 -0
- package/dist/analysis/data/sql-guard.js +129 -0
- package/dist/analysis/data/stats.d.ts +18 -0
- package/dist/analysis/data/stats.js +77 -0
- package/dist/analysis/install-hints.d.ts +33 -0
- package/dist/analysis/install-hints.js +144 -0
- package/dist/analysis/janitor.d.ts +60 -0
- package/dist/analysis/janitor.js +264 -0
- package/dist/analysis/jobs.d.ts +94 -0
- package/dist/analysis/jobs.js +165 -0
- package/dist/analysis/oci.d.ts +129 -0
- package/dist/analysis/oci.js +330 -0
- package/dist/analysis/python/sources.d.ts +2 -0
- package/dist/analysis/python/sources.js +10 -0
- package/dist/analysis/requirements.d.ts +32 -0
- package/dist/analysis/requirements.js +73 -0
- package/dist/analysis/rerun.d.ts +40 -0
- package/dist/analysis/rerun.js +136 -0
- package/dist/analysis/runtime-manager.d.ts +146 -0
- package/dist/analysis/runtime-manager.js +472 -0
- package/dist/analysis/status.d.ts +21 -0
- package/dist/analysis/status.js +52 -0
- package/dist/application.d.ts +105 -3
- package/dist/application.js +446 -18
- package/dist/artifacts/kinds.d.ts +35 -0
- package/dist/artifacts/kinds.js +177 -0
- package/dist/artifacts/publisher.d.ts +7 -0
- package/dist/artifacts/publisher.js +29 -0
- package/dist/artifacts/store.d.ts +119 -0
- package/dist/artifacts/store.js +581 -0
- package/dist/background/janitor.d.ts +22 -0
- package/dist/background/janitor.js +62 -0
- package/dist/background/mirror.d.ts +14 -0
- package/dist/background/mirror.js +41 -0
- package/dist/background/notify.d.ts +58 -0
- package/dist/background/notify.js +172 -0
- package/dist/background/output.d.ts +46 -0
- package/dist/background/output.js +179 -0
- package/dist/background/service.d.ts +137 -0
- package/dist/background/service.js +410 -0
- package/dist/background/store.d.ts +103 -0
- package/dist/background/store.js +195 -0
- package/dist/changelog/data.d.ts +6 -0
- package/dist/changelog/data.js +293 -0
- package/dist/changelog/index.d.ts +5 -0
- package/dist/changelog/index.js +7 -0
- package/dist/changelog/parse.d.ts +53 -0
- package/dist/changelog/parse.js +160 -0
- package/dist/commands/builtins.d.ts +10 -0
- package/dist/commands/builtins.js +161 -0
- package/dist/commands/catalog.d.ts +86 -0
- package/dist/commands/catalog.js +304 -0
- package/dist/config.d.ts +206 -6
- package/dist/config.js +426 -20
- package/dist/core/compaction.js +13 -2
- package/dist/core/contracts.d.ts +180 -3
- package/dist/core/opt-in.d.ts +12 -0
- package/dist/core/opt-in.js +12 -0
- package/dist/core/output-limit.d.ts +34 -0
- package/dist/core/output-limit.js +39 -0
- package/dist/core/run-stats.d.ts +16 -0
- package/dist/core/run-stats.js +8 -0
- package/dist/core/runner.d.ts +134 -4
- package/dist/core/runner.js +780 -138
- package/dist/core/timeout.d.ts +15 -0
- package/dist/core/timeout.js +61 -0
- package/dist/core/truncation.d.ts +30 -0
- package/dist/core/truncation.js +83 -0
- package/dist/goal/blockers.d.ts +45 -0
- package/dist/goal/blockers.js +51 -0
- package/dist/goal/budget.d.ts +24 -0
- package/dist/goal/budget.js +53 -0
- package/dist/goal/command.d.ts +36 -0
- package/dist/goal/command.js +98 -0
- package/dist/goal/format.d.ts +19 -0
- package/dist/goal/format.js +102 -0
- package/dist/goal/host.d.ts +29 -0
- package/dist/goal/host.js +42 -0
- package/dist/goal/index.d.ts +9 -0
- package/dist/goal/index.js +9 -0
- package/dist/goal/machine.d.ts +186 -0
- package/dist/goal/machine.js +344 -0
- package/dist/goal/prompts.d.ts +10 -0
- package/dist/goal/prompts.js +75 -0
- package/dist/goal/service.d.ts +113 -0
- package/dist/goal/service.js +273 -0
- package/dist/goal/store.d.ts +59 -0
- package/dist/goal/store.js +184 -0
- package/dist/index.d.ts +50 -5
- package/dist/index.js +49 -4
- package/dist/mcp/connector.js +38 -6
- package/dist/mcp/rich.d.ts +41 -0
- package/dist/mcp/rich.js +362 -0
- package/dist/permissions/modes.d.ts +72 -0
- package/dist/permissions/modes.js +98 -0
- package/dist/plan/exit-plan.d.ts +25 -0
- package/dist/plan/exit-plan.js +130 -0
- package/dist/plan/state.d.ts +102 -0
- package/dist/plan/state.js +165 -0
- package/dist/plugins/host.d.ts +34 -1
- package/dist/plugins/host.js +143 -9
- package/dist/providers/settings.d.ts +15 -0
- package/dist/providers/settings.js +38 -0
- package/dist/reload.d.ts +75 -0
- package/dist/reload.js +204 -0
- package/dist/resources/context.js +6 -1
- package/dist/runtime/access.d.ts +62 -0
- package/dist/runtime/access.js +115 -0
- package/dist/runtime/blobs.d.ts +51 -0
- package/dist/runtime/blobs.js +177 -0
- package/dist/runtime/diff.d.ts +23 -0
- package/dist/runtime/diff.js +154 -0
- package/dist/runtime/ids.d.ts +8 -0
- package/dist/runtime/ids.js +32 -0
- package/dist/runtime/paths.d.ts +11 -0
- package/dist/runtime/paths.js +17 -1
- package/dist/runtime/process.d.ts +22 -0
- package/dist/runtime/process.js +100 -15
- package/dist/runtime/sqlite.d.ts +2 -0
- package/dist/runtime/sqlite.js +18 -0
- package/dist/runtime/store.d.ts +91 -3
- package/dist/runtime/store.js +465 -11
- package/dist/runtime/zip.d.ts +24 -0
- package/dist/runtime/zip.js +126 -0
- package/dist/sessions/children.js +17 -1
- package/dist/sessions/side-questions.d.ts +57 -0
- package/dist/sessions/side-questions.js +161 -0
- package/dist/tools/analysis.d.ts +37 -0
- package/dist/tools/analysis.js +573 -0
- package/dist/tools/artifacts.d.ts +14 -0
- package/dist/tools/artifacts.js +143 -0
- package/dist/tools/background.d.ts +7 -0
- package/dist/tools/background.js +165 -0
- package/dist/tools/data.d.ts +7 -0
- package/dist/tools/data.js +160 -0
- package/dist/tools/execute.d.ts +5 -0
- package/dist/tools/execute.js +15 -3
- package/dist/tools/goal.d.ts +19 -0
- package/dist/tools/goal.js +126 -0
- package/dist/tools/search.d.ts +17 -3
- package/dist/tools/search.js +153 -0
- package/dist/tools/standard.d.ts +4 -1
- package/dist/tools/standard.js +99 -18
- package/dist/version.d.ts +5 -3
- package/dist/version.js +35 -6
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,9 +1,24 @@
|
|
|
1
1
|
# @alisio/core
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
**The embeddable core of [Alisio](https://github.com/GustavoGutierrez/alisio): a provider-agnostic
|
|
4
|
+
agent you can drive from your own program.** No TUI, no CLI — just the tool loop, compaction, MCP
|
|
5
|
+
and plugin host as a library.
|
|
6
|
+
|
|
7
|
+
## What it is
|
|
8
|
+
|
|
9
|
+
`@alisio/core` wires the agent tool loop, structured context compaction, the OpenAI-compatible
|
|
10
|
+
provider (Chat Completions and Responses), local tools behind explicit permissions, the MCP client,
|
|
11
|
+
the plugin host (hook timeouts and failure isolation) and a SQLite session store into one
|
|
12
|
+
`createApplication` entry point. It runs on Node.js >= 22.16 (`node:sqlite` with FTS5) and on Bun,
|
|
13
|
+
and uses only portable Node APIs.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
npm i @alisio/core # or: pnpm add @alisio/core · bun add @alisio/core
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick start
|
|
7
22
|
|
|
8
23
|
```ts
|
|
9
24
|
import { createApplication } from "@alisio/core";
|
|
@@ -18,8 +33,38 @@ try {
|
|
|
18
33
|
}
|
|
19
34
|
```
|
|
20
35
|
|
|
36
|
+
## What you get
|
|
37
|
+
|
|
38
|
+
- **Runner**: `AgentRunner` with turn limits, timeouts, token budgets and versioned `RunEvent`
|
|
39
|
+
output (`schemaVersion: 1`).
|
|
40
|
+
- **Context compaction**: `planCompaction`, `summarize`, `renderCheckpoint`,
|
|
41
|
+
`shouldCompactContext` and checkpoint helpers; memory plugins hook in via `CompactionHooks`.
|
|
42
|
+
- **Providers**: `ProviderRegistry` / `ActiveProvider` for OpenAI-compatible, DeepSeek, OpenCode
|
|
43
|
+
Console and OpenCode Go; `ProviderSettingsStore` for non-secret profiles plus a separate
|
|
44
|
+
credentials store.
|
|
45
|
+
- **Local tools**: reads by default, `--allow-write`/`--allow-process`-style policy, path checks
|
|
46
|
+
and standard tools (`ToolRegistry`, `registerStandard`).
|
|
47
|
+
- **MCP**: `McpConnector`, server discovery and tool projection.
|
|
48
|
+
- **Plugin host**: `PluginHost` with built-in plugin catalogs, npm install (`installPlugin`,
|
|
49
|
+
`cliInstall`), hook timeouts and failure isolation.
|
|
50
|
+
- **Sessions**: `SQLiteStore` with reconciliation and crash recovery.
|
|
51
|
+
- **Skills and prompts**: `Skills`, `ProjectContext` (`AGENTS.md`), `loadPromptTemplates`.
|
|
52
|
+
- **Trust**: `resolveTrust` / `setTrust` / `listTrust` for per-directory project trust.
|
|
53
|
+
- **Startup screen**: reusable `renderStartup` sections and the default mascot.
|
|
54
|
+
|
|
21
55
|
Built-in plugins are opt-in for embedders: pass `builtins` (the `alisio` CLI wires
|
|
22
|
-
`@alisio/plugin-memory`
|
|
23
|
-
|
|
56
|
+
`@alisio/plugin-memory` and `@alisio/plugin-subagents`).
|
|
57
|
+
|
|
58
|
+
## Docs
|
|
59
|
+
|
|
60
|
+
Architecture: <https://gustavogutierrez.github.io/alisio/architecture> ·
|
|
61
|
+
Configuration: <https://gustavogutierrez.github.io/alisio/configuration>.
|
|
62
|
+
|
|
63
|
+
## Requirements
|
|
64
|
+
|
|
65
|
+
Node.js **>= 22.16** or Bun **>= 1.4.2**.
|
|
66
|
+
|
|
67
|
+
## License
|
|
24
68
|
|
|
25
|
-
|
|
69
|
+
MIT. Maintained by Gustavo Gutiérrez Mercado. Source: <https://github.com/GustavoGutierrez/alisio> ·
|
|
70
|
+
npm: <https://www.npmjs.com/settings/alisio/packages>.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure logic for the ACTIVE (main-session) agent: the built-in catalog, user/plugin
|
|
3
|
+
* contributions, resolution and the per-run options an agent implies. No terminal or pi-tui
|
|
4
|
+
* imports here — the Picker and status-line rendering live in each surface (e.g. the TUI shell).
|
|
5
|
+
*
|
|
6
|
+
* The active agent drives the MAIN session (its `instructions` are appended per run and an
|
|
7
|
+
* agent-specific `model` is offered on selection). This is deliberately separate from the
|
|
8
|
+
* delegated child-session agents of the subagents plugin: a subagent definition becomes a main
|
|
9
|
+
* agent only when it is marked main-capable (`mode: primary|all`), which the subagents plugin
|
|
10
|
+
* publishes for the host to read.
|
|
11
|
+
*/
|
|
12
|
+
import type { CommandDescriptor } from "@alisio/sdk";
|
|
13
|
+
export interface ActiveAgent {
|
|
14
|
+
/** Stable id, also the persisted `agents.active` value. */
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
description: string;
|
|
18
|
+
/** System prompt appended to the main session's instructions on every run. */
|
|
19
|
+
instructions?: string;
|
|
20
|
+
/** Optional default model selector (`provider/model` or an unambiguous model id). */
|
|
21
|
+
model?: string;
|
|
22
|
+
/** Read-only agents run with write/process/external tools disabled and approvals off. */
|
|
23
|
+
readOnly?: boolean;
|
|
24
|
+
/** Default reasoning effort (`alisio.reasoning.effort`); an explicit session/user effort wins. */
|
|
25
|
+
effort?: string;
|
|
26
|
+
/** Definition file of a contributed agent (shows its Project/Global scope). */
|
|
27
|
+
path?: string;
|
|
28
|
+
/** Product built-ins are shown as built-in and never shadowed by contributed definitions. */
|
|
29
|
+
source: "builtin" | "user" | "plugin";
|
|
30
|
+
}
|
|
31
|
+
export declare const DEFAULT_AGENT_ID = "build";
|
|
32
|
+
export declare const PLAN_AGENT_ID = "plan";
|
|
33
|
+
/** Product built-ins. `build` keeps the CURRENT behavior exactly: no added persona, full power. */
|
|
34
|
+
export declare const BUILTIN_AGENTS: ActiveAgent[];
|
|
35
|
+
export interface MainCapableAgentRecord {
|
|
36
|
+
name: string;
|
|
37
|
+
description: string;
|
|
38
|
+
prompt: string;
|
|
39
|
+
model?: string;
|
|
40
|
+
readOnly?: boolean;
|
|
41
|
+
effort?: string;
|
|
42
|
+
source: string;
|
|
43
|
+
path?: string;
|
|
44
|
+
}
|
|
45
|
+
/** Maps a main-capable definition published by the subagents plugin to an active agent. */
|
|
46
|
+
export declare function mainAgentFromRecord(record: MainCapableAgentRecord): ActiveAgent;
|
|
47
|
+
/** Builds the selectable catalog from the subagents plugin's published state (best-effort). */
|
|
48
|
+
export declare function agentCatalogFromState(untrusted: unknown): ActiveAgent[];
|
|
49
|
+
/**
|
|
50
|
+
* The full selectable catalog: built-ins first, then contributed main-capable definitions.
|
|
51
|
+
* A contributed definition may never shadow a built-in id; later duplicates of a contributed id
|
|
52
|
+
* are dropped (the subagents plugin already resolved precedence by its own discovery order).
|
|
53
|
+
*/
|
|
54
|
+
export declare function activeAgentCatalog(contributions?: ActiveAgent[]): ActiveAgent[];
|
|
55
|
+
/**
|
|
56
|
+
* The agents Shift+Tab (and the web selector) cycles through, in a STABLE order: `build`, then
|
|
57
|
+
* `plan`, then every other main-capable agent (`mode: primary|all`) by name. The catalog order of
|
|
58
|
+
* contributed agents follows plugin discovery and is not stable across reloads, so cycling never
|
|
59
|
+
* relies on it. Duplicated ids are dropped.
|
|
60
|
+
*/
|
|
61
|
+
export declare function cycleableAgents(agents: ActiveAgent[]): ActiveAgent[];
|
|
62
|
+
/**
|
|
63
|
+
* The agent after (`step` 1) or before (`step` -1) `currentId` in the cycle, wrapping around. An
|
|
64
|
+
* unknown current id starts the cycle at its first agent (`build`). An empty list yields undefined.
|
|
65
|
+
*/
|
|
66
|
+
export declare function nextAgent(agents: ActiveAgent[], currentId: string | undefined, step?: 1 | -1): ActiveAgent | undefined;
|
|
67
|
+
/** Resolves the persisted agent id; unknown ids fall back to the built-in default (`build`). */
|
|
68
|
+
export declare function resolveActiveAgent(agents: ActiveAgent[], id: string | undefined): ActiveAgent;
|
|
69
|
+
/** The run options an active agent implies. An undefined agent yields the current behavior. */
|
|
70
|
+
export declare function agentRunOptions(agent: ActiveAgent | undefined): {
|
|
71
|
+
instructions?: string;
|
|
72
|
+
policy?: {
|
|
73
|
+
write: false;
|
|
74
|
+
process: false;
|
|
75
|
+
external: false;
|
|
76
|
+
};
|
|
77
|
+
approvals?: false;
|
|
78
|
+
reasoningEffort?: string;
|
|
79
|
+
optInTools?: string[];
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Every loaded agent is also a slash command `/agent:<id>` that activates it. The `agent:`
|
|
83
|
+
* namespace keeps these commands from ever colliding with built-ins, plugin commands, prompt
|
|
84
|
+
* templates or `skill:<id>` entries; when a higher-precedence source already owns the exact name
|
|
85
|
+
* (e.g. a plugin with id `agent`), the agent command is skipped.
|
|
86
|
+
*/
|
|
87
|
+
export declare const AGENT_COMMAND_PREFIX = "agent:";
|
|
88
|
+
export declare const agentCommandName: (id: string) => string;
|
|
89
|
+
/** The agent id a `/agent:<id>` command names, or undefined for any other command. */
|
|
90
|
+
export declare function agentIdFromCommand(name: string): string | undefined;
|
|
91
|
+
/** `/agent:<id>` descriptors for `agents`, skipping names already in `taken`. */
|
|
92
|
+
export declare function agentCommandDescriptors(agents: ActiveAgent[], taken?: ReadonlySet<string>): CommandDescriptor[];
|
|
93
|
+
export interface AgentPickerItem {
|
|
94
|
+
value: string;
|
|
95
|
+
label: string;
|
|
96
|
+
description: string;
|
|
97
|
+
}
|
|
98
|
+
/** Picker rows for `/agents`: name with (current), built-in/default and read-only markers. */
|
|
99
|
+
export declare function agentPickerItems(agents: ActiveAgent[], activeId: string): AgentPickerItem[];
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { EXIT_PLAN_TOOL } from "../core/opt-in.js";
|
|
2
|
+
export const DEFAULT_AGENT_ID = "build";
|
|
3
|
+
export const PLAN_AGENT_ID = "plan";
|
|
4
|
+
const PLAN_INSTRUCTIONS = `You are the "plan" agent: a read-only planning assistant for this main session.
|
|
5
|
+
|
|
6
|
+
Your job is analysis and planning only. Investigate the repository with read-only tools
|
|
7
|
+
(list_files, search_text, read_file, git_status, git_diff) and return a concrete, ordered plan:
|
|
8
|
+
files to change, functions to touch, risks and verification steps. You may run context and
|
|
9
|
+
inspection tools that do not modify anything.
|
|
10
|
+
|
|
11
|
+
You never edit, write or delete files, and you never start processes that change the workspace
|
|
12
|
+
or the network. If a task requires changes, hand back a precise plan (and the exact commands)
|
|
13
|
+
instead of making them. You do not implement the plan yourself, even when the user approves it:
|
|
14
|
+
approval hands the plan to the build agent.
|
|
15
|
+
|
|
16
|
+
When the plan is complete, finish by calling \`exit_plan\` exactly once with the whole plan in
|
|
17
|
+
Markdown (and a short \`title\`). Do not paste the plan in your reply first: exit_plan shows it to
|
|
18
|
+
the user and asks for a decision. Write the plan with these sections, in this order:
|
|
19
|
+
|
|
20
|
+
# <Title>
|
|
21
|
+
## Goal
|
|
22
|
+
What will be true when this is done, in one or two sentences.
|
|
23
|
+
## Context
|
|
24
|
+
What you found in the repository that the plan relies on (files, functions, conventions).
|
|
25
|
+
## Steps
|
|
26
|
+
A numbered, ordered list. Each step names the files and functions to change and what changes.
|
|
27
|
+
## Risks
|
|
28
|
+
What could go wrong, what is uncertain, and what you did not verify.
|
|
29
|
+
## Verification
|
|
30
|
+
The exact commands and checks that prove the work is done.
|
|
31
|
+
|
|
32
|
+
Read the tool result: "approved" means the build agent will implement the plan, so reply with one
|
|
33
|
+
short sentence and stop. "skipped" means stay in plan mode and do not call exit_plan again unless
|
|
34
|
+
asked. "feedback" carries extra context from the user: revise the plan and call exit_plan again
|
|
35
|
+
with the complete updated plan.`;
|
|
36
|
+
/** Product built-ins. `build` keeps the CURRENT behavior exactly: no added persona, full power. */
|
|
37
|
+
export const BUILTIN_AGENTS = [
|
|
38
|
+
{
|
|
39
|
+
id: DEFAULT_AGENT_ID,
|
|
40
|
+
name: "build",
|
|
41
|
+
description: "Default full-power agent: edits code and files, runs processes and verifies its work through the normal permission flow.",
|
|
42
|
+
source: "builtin",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: PLAN_AGENT_ID,
|
|
46
|
+
name: "plan",
|
|
47
|
+
description: "Read-only planning agent: analyzes the codebase and returns an implementation plan without modifying anything.",
|
|
48
|
+
instructions: PLAN_INSTRUCTIONS,
|
|
49
|
+
readOnly: true,
|
|
50
|
+
source: "builtin",
|
|
51
|
+
},
|
|
52
|
+
];
|
|
53
|
+
/** Maps a main-capable definition published by the subagents plugin to an active agent. */
|
|
54
|
+
export function mainAgentFromRecord(record) {
|
|
55
|
+
const source = String(record.source ?? "");
|
|
56
|
+
return {
|
|
57
|
+
id: record.name,
|
|
58
|
+
name: record.name,
|
|
59
|
+
description: record.description,
|
|
60
|
+
...(record.prompt ? { instructions: record.prompt } : {}),
|
|
61
|
+
...(record.model ? { model: record.model } : {}),
|
|
62
|
+
...(record.readOnly ? { readOnly: true } : {}),
|
|
63
|
+
...(typeof record.effort === "string" && record.effort ? { effort: record.effort } : {}),
|
|
64
|
+
...(typeof record.path === "string" && record.path ? { path: record.path } : {}),
|
|
65
|
+
...(source.startsWith("plugin:")
|
|
66
|
+
? { source: "plugin" }
|
|
67
|
+
: { source: "user" }),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/** Builds the selectable catalog from the subagents plugin's published state (best-effort). */
|
|
71
|
+
export function agentCatalogFromState(untrusted) {
|
|
72
|
+
if (!Array.isArray(untrusted))
|
|
73
|
+
return activeAgentCatalog([]);
|
|
74
|
+
const records = untrusted.filter((entry) => !!entry &&
|
|
75
|
+
typeof entry === "object" &&
|
|
76
|
+
typeof entry.name === "string" &&
|
|
77
|
+
typeof entry.description === "string" &&
|
|
78
|
+
entry.description.length > 0 &&
|
|
79
|
+
typeof entry.prompt === "string");
|
|
80
|
+
return activeAgentCatalog(records.map(mainAgentFromRecord));
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* The full selectable catalog: built-ins first, then contributed main-capable definitions.
|
|
84
|
+
* A contributed definition may never shadow a built-in id; later duplicates of a contributed id
|
|
85
|
+
* are dropped (the subagents plugin already resolved precedence by its own discovery order).
|
|
86
|
+
*/
|
|
87
|
+
export function activeAgentCatalog(contributions = []) {
|
|
88
|
+
const seen = new Set();
|
|
89
|
+
const out = [];
|
|
90
|
+
for (const agent of [...BUILTIN_AGENTS, ...contributions]) {
|
|
91
|
+
if (seen.has(agent.id))
|
|
92
|
+
continue;
|
|
93
|
+
seen.add(agent.id);
|
|
94
|
+
out.push(agent);
|
|
95
|
+
}
|
|
96
|
+
return out;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* The agents Shift+Tab (and the web selector) cycles through, in a STABLE order: `build`, then
|
|
100
|
+
* `plan`, then every other main-capable agent (`mode: primary|all`) by name. The catalog order of
|
|
101
|
+
* contributed agents follows plugin discovery and is not stable across reloads, so cycling never
|
|
102
|
+
* relies on it. Duplicated ids are dropped.
|
|
103
|
+
*/
|
|
104
|
+
export function cycleableAgents(agents) {
|
|
105
|
+
const builtinRank = new Map(BUILTIN_AGENTS.map((agent, index) => [agent.id, index]));
|
|
106
|
+
const seen = new Set();
|
|
107
|
+
const unique = agents.filter((agent) => {
|
|
108
|
+
if (seen.has(agent.id))
|
|
109
|
+
return false;
|
|
110
|
+
seen.add(agent.id);
|
|
111
|
+
return true;
|
|
112
|
+
});
|
|
113
|
+
const byName = (a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase()) || a.id.localeCompare(b.id);
|
|
114
|
+
return [
|
|
115
|
+
...unique
|
|
116
|
+
.filter((agent) => builtinRank.has(agent.id))
|
|
117
|
+
.sort((a, b) => (builtinRank.get(a.id) ?? 0) - (builtinRank.get(b.id) ?? 0)),
|
|
118
|
+
...unique.filter((agent) => !builtinRank.has(agent.id)).sort(byName),
|
|
119
|
+
];
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* The agent after (`step` 1) or before (`step` -1) `currentId` in the cycle, wrapping around. An
|
|
123
|
+
* unknown current id starts the cycle at its first agent (`build`). An empty list yields undefined.
|
|
124
|
+
*/
|
|
125
|
+
export function nextAgent(agents, currentId, step = 1) {
|
|
126
|
+
const cycle = cycleableAgents(agents);
|
|
127
|
+
if (!cycle.length)
|
|
128
|
+
return undefined;
|
|
129
|
+
const index = cycle.findIndex((agent) => agent.id === currentId);
|
|
130
|
+
if (index < 0)
|
|
131
|
+
return cycle[0];
|
|
132
|
+
return cycle[(index + step + cycle.length) % cycle.length];
|
|
133
|
+
}
|
|
134
|
+
/** Resolves the persisted agent id; unknown ids fall back to the built-in default (`build`). */
|
|
135
|
+
export function resolveActiveAgent(agents, id) {
|
|
136
|
+
const found = id ? agents.find((a) => a.id === id) : undefined;
|
|
137
|
+
if (found)
|
|
138
|
+
return found;
|
|
139
|
+
return agents.find((a) => a.id === DEFAULT_AGENT_ID) ?? agents[0] ?? BUILTIN_AGENTS[0];
|
|
140
|
+
}
|
|
141
|
+
/** The run options an active agent implies. An undefined agent yields the current behavior. */
|
|
142
|
+
export function agentRunOptions(agent) {
|
|
143
|
+
if (!agent)
|
|
144
|
+
return {};
|
|
145
|
+
return {
|
|
146
|
+
...(agent.instructions ? { instructions: agent.instructions } : {}),
|
|
147
|
+
// `exit_plan` exists for the built-in plan agent only (it is hidden from every other run).
|
|
148
|
+
...(agent.id === PLAN_AGENT_ID && agent.source === "builtin"
|
|
149
|
+
? { optInTools: [EXIT_PLAN_TOOL] }
|
|
150
|
+
: {}),
|
|
151
|
+
...(agent.effort ? { reasoningEffort: agent.effort } : {}),
|
|
152
|
+
...(agent.readOnly
|
|
153
|
+
? {
|
|
154
|
+
policy: { write: false, process: false, external: false },
|
|
155
|
+
approvals: false,
|
|
156
|
+
}
|
|
157
|
+
: {}),
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Every loaded agent is also a slash command `/agent:<id>` that activates it. The `agent:`
|
|
162
|
+
* namespace keeps these commands from ever colliding with built-ins, plugin commands, prompt
|
|
163
|
+
* templates or `skill:<id>` entries; when a higher-precedence source already owns the exact name
|
|
164
|
+
* (e.g. a plugin with id `agent`), the agent command is skipped.
|
|
165
|
+
*/
|
|
166
|
+
export const AGENT_COMMAND_PREFIX = "agent:";
|
|
167
|
+
const COMMAND_SAFE_ID = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;
|
|
168
|
+
export const agentCommandName = (id) => `${AGENT_COMMAND_PREFIX}${id}`;
|
|
169
|
+
/** The agent id a `/agent:<id>` command names, or undefined for any other command. */
|
|
170
|
+
export function agentIdFromCommand(name) {
|
|
171
|
+
if (!name.startsWith(AGENT_COMMAND_PREFIX))
|
|
172
|
+
return undefined;
|
|
173
|
+
const id = name.slice(AGENT_COMMAND_PREFIX.length);
|
|
174
|
+
return COMMAND_SAFE_ID.test(id) ? id : undefined;
|
|
175
|
+
}
|
|
176
|
+
/** `/agent:<id>` descriptors for `agents`, skipping names already in `taken`. */
|
|
177
|
+
export function agentCommandDescriptors(agents, taken = new Set()) {
|
|
178
|
+
const out = [];
|
|
179
|
+
const seen = new Set(taken);
|
|
180
|
+
for (const agent of agents) {
|
|
181
|
+
if (!COMMAND_SAFE_ID.test(agent.id))
|
|
182
|
+
continue;
|
|
183
|
+
const name = agentCommandName(agent.id);
|
|
184
|
+
if (seen.has(name))
|
|
185
|
+
continue;
|
|
186
|
+
seen.add(name);
|
|
187
|
+
out.push({
|
|
188
|
+
name,
|
|
189
|
+
description: `Activate the ${agent.name} agent${agent.id === DEFAULT_AGENT_ID ? " (default)" : ""}: ${agent.description}`,
|
|
190
|
+
source: "agent",
|
|
191
|
+
owner: agent.source,
|
|
192
|
+
surfaces: ["tui", "web", "api"],
|
|
193
|
+
execution: "surface",
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
return out;
|
|
197
|
+
}
|
|
198
|
+
/** Picker rows for `/agents`: name with (current), built-in/default and read-only markers. */
|
|
199
|
+
export function agentPickerItems(agents, activeId) {
|
|
200
|
+
return agents.map((agent) => ({
|
|
201
|
+
value: agent.id,
|
|
202
|
+
label: [
|
|
203
|
+
agent.name,
|
|
204
|
+
agent.id === activeId ? "(current)" : undefined,
|
|
205
|
+
agent.id === DEFAULT_AGENT_ID ? "(default)" : undefined,
|
|
206
|
+
agent.readOnly ? "read-only" : undefined,
|
|
207
|
+
]
|
|
208
|
+
.filter(Boolean)
|
|
209
|
+
.join(" · "),
|
|
210
|
+
description: [
|
|
211
|
+
agent.description,
|
|
212
|
+
agent.model ? `default model: ${agent.model}` : undefined,
|
|
213
|
+
agent.instructions ? "injects its system prompt from the next prompt" : undefined,
|
|
214
|
+
]
|
|
215
|
+
.filter(Boolean)
|
|
216
|
+
.join(" · "),
|
|
217
|
+
}));
|
|
218
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capability-driven agent settings: which reasoning, summary, verbosity and text-format options a
|
|
3
|
+
* model supports, derived only from its catalog metadata (`ModelInfo.effort`, `inputModalities`,
|
|
4
|
+
* `capabilities`). Providers that declare nothing (most OpenAI-compatible `GET /models` answers)
|
|
5
|
+
* get a permissive default: every option is offered and `known` is false, so surfaces can say the
|
|
6
|
+
* support is unverified. Explicit `false` metadata always hides an option.
|
|
7
|
+
*/
|
|
8
|
+
import type { AgentDefinitionInput, AgentModelCapabilities, AgentModelOption, AvailableProviderModel, ModelInfo } from "@alisio/sdk";
|
|
9
|
+
/** Levels offered when a reasoning model does not list its own. */
|
|
10
|
+
export declare const DEFAULT_EFFORT_LEVELS: string[];
|
|
11
|
+
/** What `model` supports for the agent editor (permissive when the catalog says nothing). */
|
|
12
|
+
export declare function agentModelCapabilities(model: ModelInfo | undefined): AgentModelCapabilities;
|
|
13
|
+
/** Short labels such as "Reasoning · Tools · Vision", only for declared support. */
|
|
14
|
+
export declare function agentModelLabels(capabilities: AgentModelCapabilities): string[];
|
|
15
|
+
/** The editor's model options from the configured catalogs; `active` marks the running model. */
|
|
16
|
+
export declare function agentModelOptions(available: AvailableProviderModel[], active?: {
|
|
17
|
+
profile?: string;
|
|
18
|
+
provider?: string;
|
|
19
|
+
model: string;
|
|
20
|
+
}): AgentModelOption[];
|
|
21
|
+
/**
|
|
22
|
+
* Drops or replaces settings `capabilities` does not support: unsupported reasoning settings are
|
|
23
|
+
* removed, an unknown effort level falls back to the model default (or is removed), an unsupported
|
|
24
|
+
* text format becomes `text`, unsupported verbosity is removed.
|
|
25
|
+
*/
|
|
26
|
+
export declare function fitAgentSettings<T extends Pick<AgentDefinitionInput, "reasoning" | "text">>(settings: T, capabilities: AgentModelCapabilities): T;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/** Levels offered when a reasoning model does not list its own. */
|
|
2
|
+
export const DEFAULT_EFFORT_LEVELS = ["low", "medium", "high"];
|
|
3
|
+
const flag = (capabilities, keys) => {
|
|
4
|
+
if (!capabilities)
|
|
5
|
+
return undefined;
|
|
6
|
+
for (const key of keys) {
|
|
7
|
+
const value = capabilities[key];
|
|
8
|
+
if (typeof value === "boolean")
|
|
9
|
+
return value;
|
|
10
|
+
if (value === "true" || value === "supported")
|
|
11
|
+
return true;
|
|
12
|
+
if (value === "false" || value === "unsupported")
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
return undefined;
|
|
16
|
+
};
|
|
17
|
+
/** What `model` supports for the agent editor (permissive when the catalog says nothing). */
|
|
18
|
+
export function agentModelCapabilities(model) {
|
|
19
|
+
const caps = model?.capabilities;
|
|
20
|
+
const levels = model?.effort?.supportedLevels?.filter(Boolean) ?? [];
|
|
21
|
+
const declaredReasoning = flag(caps, ["reasoning", "reasoning_effort", "thinking"]);
|
|
22
|
+
const reasoning = levels.length > 0 || declaredReasoning !== false;
|
|
23
|
+
const summary = reasoning && flag(caps, ["reasoning_summary", "reasoningSummary"]) !== false;
|
|
24
|
+
const verbosity = flag(caps, ["verbosity", "text_verbosity"]) !== false;
|
|
25
|
+
const json = flag(caps, ["json_mode", "json_object", "response_format"]);
|
|
26
|
+
const schema = flag(caps, ["structured_outputs", "json_schema", "structuredOutputs"]);
|
|
27
|
+
const textFormats = ["text"];
|
|
28
|
+
if (json !== false)
|
|
29
|
+
textFormats.push("json_object");
|
|
30
|
+
if (schema !== false)
|
|
31
|
+
textFormats.push("json_schema");
|
|
32
|
+
const tools = flag(caps, ["tools", "tool_calling", "function_calling", "toolCalling"]);
|
|
33
|
+
const vision = model?.inputModalities?.includes("image") ||
|
|
34
|
+
model?.modalities?.includes("image") ||
|
|
35
|
+
flag(caps, ["vision", "image_input"]) === true
|
|
36
|
+
? true
|
|
37
|
+
: flag(caps, ["vision", "image_input"]);
|
|
38
|
+
const known = !!levels.length ||
|
|
39
|
+
!!model?.inputModalities?.length ||
|
|
40
|
+
!!model?.modalities?.length ||
|
|
41
|
+
!!(caps && Object.keys(caps).length);
|
|
42
|
+
return {
|
|
43
|
+
known,
|
|
44
|
+
reasoning,
|
|
45
|
+
effortLevels: reasoning ? (levels.length ? levels : DEFAULT_EFFORT_LEVELS) : [],
|
|
46
|
+
...(reasoning && model?.effort?.defaultLevel
|
|
47
|
+
? { defaultEffort: model.effort.defaultLevel }
|
|
48
|
+
: {}),
|
|
49
|
+
summary,
|
|
50
|
+
verbosity,
|
|
51
|
+
textFormats,
|
|
52
|
+
...(tools !== undefined ? { tools } : {}),
|
|
53
|
+
...(vision !== undefined ? { vision } : {}),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/** Short labels such as "Reasoning · Tools · Vision", only for declared support. */
|
|
57
|
+
export function agentModelLabels(capabilities) {
|
|
58
|
+
if (!capabilities.known)
|
|
59
|
+
return [];
|
|
60
|
+
return [
|
|
61
|
+
capabilities.reasoning ? "Reasoning" : undefined,
|
|
62
|
+
capabilities.tools ? "Tools" : undefined,
|
|
63
|
+
capabilities.vision ? "Vision" : undefined,
|
|
64
|
+
capabilities.textFormats.includes("json_schema") ? "Structured output" : undefined,
|
|
65
|
+
].filter((label) => !!label);
|
|
66
|
+
}
|
|
67
|
+
/** The editor's model options from the configured catalogs; `active` marks the running model. */
|
|
68
|
+
export function agentModelOptions(available, active) {
|
|
69
|
+
return available.map((entry) => {
|
|
70
|
+
const capabilities = agentModelCapabilities(entry.model);
|
|
71
|
+
return {
|
|
72
|
+
reference: entry.reference,
|
|
73
|
+
provider: entry.provider,
|
|
74
|
+
profile: entry.profile,
|
|
75
|
+
providerName: entry.providerName,
|
|
76
|
+
id: entry.model.id,
|
|
77
|
+
...(entry.model.name ? { name: entry.model.name } : {}),
|
|
78
|
+
active: !!active &&
|
|
79
|
+
entry.model.id === active.model &&
|
|
80
|
+
(active.profile ? entry.profile === active.profile : entry.provider === active.provider),
|
|
81
|
+
capabilities,
|
|
82
|
+
labels: agentModelLabels(capabilities),
|
|
83
|
+
};
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Drops or replaces settings `capabilities` does not support: unsupported reasoning settings are
|
|
88
|
+
* removed, an unknown effort level falls back to the model default (or is removed), an unsupported
|
|
89
|
+
* text format becomes `text`, unsupported verbosity is removed.
|
|
90
|
+
*/
|
|
91
|
+
export function fitAgentSettings(settings, capabilities) {
|
|
92
|
+
const reasoning = { ...(settings.reasoning ?? {}) };
|
|
93
|
+
if (!capabilities.reasoning) {
|
|
94
|
+
delete reasoning.effort;
|
|
95
|
+
delete reasoning.summary;
|
|
96
|
+
}
|
|
97
|
+
else if (reasoning.effort && !capabilities.effortLevels.includes(reasoning.effort)) {
|
|
98
|
+
if (capabilities.defaultEffort)
|
|
99
|
+
reasoning.effort = capabilities.defaultEffort;
|
|
100
|
+
else
|
|
101
|
+
delete reasoning.effort;
|
|
102
|
+
}
|
|
103
|
+
if (!capabilities.summary)
|
|
104
|
+
delete reasoning.summary;
|
|
105
|
+
const text = { ...(settings.text ?? {}) };
|
|
106
|
+
if (text.format && !capabilities.textFormats.includes(text.format.type))
|
|
107
|
+
text.format = { type: "text" };
|
|
108
|
+
if (!capabilities.verbosity)
|
|
109
|
+
delete text.verbosity;
|
|
110
|
+
const out = { ...settings };
|
|
111
|
+
if (Object.keys(reasoning).length)
|
|
112
|
+
out.reasoning = reasoning;
|
|
113
|
+
else
|
|
114
|
+
delete out.reasoning;
|
|
115
|
+
if (Object.keys(text).length)
|
|
116
|
+
out.text = text;
|
|
117
|
+
else
|
|
118
|
+
delete out.text;
|
|
119
|
+
return out;
|
|
120
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The bundled `create-agent` skill: agent-authoring standards the ACTIVE model follows when it
|
|
3
|
+
* writes or refines an agent's instructions (assisted creation in the web Agents window and the
|
|
4
|
+
* TUI `/agents` manager). A user or project skill named `create-agent` (or `agent-creator`)
|
|
5
|
+
* replaces it, so teams can encode their own conventions.
|
|
6
|
+
*/
|
|
7
|
+
/** Skill names that override the bundled guidance, in order of preference. */
|
|
8
|
+
export declare const AGENT_AUTHORING_SKILL_NAMES: readonly ["create-agent", "agent-creator"];
|
|
9
|
+
export declare const CREATE_AGENT_SKILL = "---\nname: create-agent\ndescription: Standards for writing the system prompt (instructions) of an Alisio agent.\n---\n# Writing agent instructions\n\nAn agent's instructions are its system prompt. They are read on every turn, so every line must\nearn its place. Write them in Markdown, in the second person (\"You ...\"), in English unless the\nuser asks otherwise.\n\n## Required sections\n\n1. **Role** \u2014 one or two sentences: who the agent is and who it serves.\n2. **Goal** \u2014 the outcome a successful turn produces, stated so it can be checked.\n3. **Scope** \u2014 what the agent handles and, explicitly, what it must decline or hand back.\n4. **How to work** \u2014 an ordered method for the typical task (investigate, act, verify, report).\n5. **Tool usage** \u2014 when to read, search, edit or run processes; prefer reading before editing;\n verify changes (tests, type checks) before claiming success; ask before destructive,\n irreversible or external actions (deleting data, deploying, spending money, contacting people).\n6. **Constraints** \u2014 hard rules: safety, privacy, secrets never echoed, repository conventions,\n performance or style limits. Phrase them as testable rules, not vague values.\n7. **Output format** \u2014 the exact shape of the final answer (headings, lists, tables, JSON keys,\n length). Match the agent's text format setting.\n8. **Examples** (optional) \u2014 one short input \u2192 output pair when the format or tone is unusual.\n\n## Quality bar\n\n- Be specific to the described job; remove generic filler (\"be helpful\", \"be accurate\").\n- Prefer short imperative bullets over paragraphs. Target 150\u2013600 words.\n- Never invent tools, files, APIs or data the agent does not have; tell it to say when it lacks\n information instead of guessing.\n- Keep the agent honest: report what was verified and what was not.\n- When refining an existing definition, keep what already works, apply the user's requested\n changes, and fill any missing required section.\n\n## Settings to suggest\n\n- Reasoning effort: `high` for analysis, debugging, security or multi-step refactors; `medium`\n for general engineering; `low` for formatting, summaries and support replies.\n- Reasoning summary: `auto` by default; `none` for short conversational agents; `detailed` when\n the user audits the reasoning.\n- Verbosity: `low` for terse operational agents, `medium` by default, `high` for reports.\n- Text format: `text` unless the agent must return machine-readable output (`json_object`,\n or `json_schema` when a strict schema is given).\n";
|
|
10
|
+
/** The skill body without the loader preamble and frontmatter (what is sent as guidance). */
|
|
11
|
+
export declare function skillBody(text: string): string;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The bundled `create-agent` skill: agent-authoring standards the ACTIVE model follows when it
|
|
3
|
+
* writes or refines an agent's instructions (assisted creation in the web Agents window and the
|
|
4
|
+
* TUI `/agents` manager). A user or project skill named `create-agent` (or `agent-creator`)
|
|
5
|
+
* replaces it, so teams can encode their own conventions.
|
|
6
|
+
*/
|
|
7
|
+
/** Skill names that override the bundled guidance, in order of preference. */
|
|
8
|
+
export const AGENT_AUTHORING_SKILL_NAMES = ["create-agent", "agent-creator"];
|
|
9
|
+
export const CREATE_AGENT_SKILL = `---
|
|
10
|
+
name: create-agent
|
|
11
|
+
description: Standards for writing the system prompt (instructions) of an Alisio agent.
|
|
12
|
+
---
|
|
13
|
+
# Writing agent instructions
|
|
14
|
+
|
|
15
|
+
An agent's instructions are its system prompt. They are read on every turn, so every line must
|
|
16
|
+
earn its place. Write them in Markdown, in the second person ("You ..."), in English unless the
|
|
17
|
+
user asks otherwise.
|
|
18
|
+
|
|
19
|
+
## Required sections
|
|
20
|
+
|
|
21
|
+
1. **Role** — one or two sentences: who the agent is and who it serves.
|
|
22
|
+
2. **Goal** — the outcome a successful turn produces, stated so it can be checked.
|
|
23
|
+
3. **Scope** — what the agent handles and, explicitly, what it must decline or hand back.
|
|
24
|
+
4. **How to work** — an ordered method for the typical task (investigate, act, verify, report).
|
|
25
|
+
5. **Tool usage** — when to read, search, edit or run processes; prefer reading before editing;
|
|
26
|
+
verify changes (tests, type checks) before claiming success; ask before destructive,
|
|
27
|
+
irreversible or external actions (deleting data, deploying, spending money, contacting people).
|
|
28
|
+
6. **Constraints** — hard rules: safety, privacy, secrets never echoed, repository conventions,
|
|
29
|
+
performance or style limits. Phrase them as testable rules, not vague values.
|
|
30
|
+
7. **Output format** — the exact shape of the final answer (headings, lists, tables, JSON keys,
|
|
31
|
+
length). Match the agent's text format setting.
|
|
32
|
+
8. **Examples** (optional) — one short input → output pair when the format or tone is unusual.
|
|
33
|
+
|
|
34
|
+
## Quality bar
|
|
35
|
+
|
|
36
|
+
- Be specific to the described job; remove generic filler ("be helpful", "be accurate").
|
|
37
|
+
- Prefer short imperative bullets over paragraphs. Target 150–600 words.
|
|
38
|
+
- Never invent tools, files, APIs or data the agent does not have; tell it to say when it lacks
|
|
39
|
+
information instead of guessing.
|
|
40
|
+
- Keep the agent honest: report what was verified and what was not.
|
|
41
|
+
- When refining an existing definition, keep what already works, apply the user's requested
|
|
42
|
+
changes, and fill any missing required section.
|
|
43
|
+
|
|
44
|
+
## Settings to suggest
|
|
45
|
+
|
|
46
|
+
- Reasoning effort: \`high\` for analysis, debugging, security or multi-step refactors; \`medium\`
|
|
47
|
+
for general engineering; \`low\` for formatting, summaries and support replies.
|
|
48
|
+
- Reasoning summary: \`auto\` by default; \`none\` for short conversational agents; \`detailed\` when
|
|
49
|
+
the user audits the reasoning.
|
|
50
|
+
- Verbosity: \`low\` for terse operational agents, \`medium\` by default, \`high\` for reports.
|
|
51
|
+
- Text format: \`text\` unless the agent must return machine-readable output (\`json_object\`,
|
|
52
|
+
or \`json_schema\` when a strict schema is given).
|
|
53
|
+
`;
|
|
54
|
+
/** The skill body without the loader preamble and frontmatter (what is sent as guidance). */
|
|
55
|
+
export function skillBody(text) {
|
|
56
|
+
return text
|
|
57
|
+
.replace(/^Skill root:.*\r?\n(?:Use skill_resource.*\r?\n)?/, "")
|
|
58
|
+
.replace(/^---\r?\n[\s\S]*?\r?\n---[ \t]*\r?\n?/, "")
|
|
59
|
+
.trim();
|
|
60
|
+
}
|