@alisio/core 0.1.0-alpha.9 → 0.1.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/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 +306 -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
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The agent definition service every surface (web server, TUI) uses: CRUD over the project and
|
|
3
|
+
* global `.agents/agents` scopes, the merged listing (a project agent overrides the global one
|
|
4
|
+
* with the same id) and the hot-reload of the runtime agent registry after each write.
|
|
5
|
+
*
|
|
6
|
+
* The runtime registry belongs to the subagents plugin (it discovers agent files at setup and
|
|
7
|
+
* publishes them through plugin state). After a write the service asks it to rediscover and then
|
|
8
|
+
* checks whether the saved file is actually loaded, so callers report `live: true` only when the
|
|
9
|
+
* change is usable by the next prompt; otherwise they must tell the user to restart.
|
|
10
|
+
*/
|
|
11
|
+
import type { AgentDefinitionInfo, AgentDefinitionInput, AgentScope } from "@alisio/sdk";
|
|
12
|
+
/** The runtime registry the service refreshes (implemented by the application). */
|
|
13
|
+
export interface AgentRegistry {
|
|
14
|
+
/** Rediscovers agent files; false when no registry can reload (e.g. subagents plugin off). */
|
|
15
|
+
reload(): Promise<boolean>;
|
|
16
|
+
/** Absolute paths of the agent files currently loaded, or undefined when unknown. */
|
|
17
|
+
loadedPaths(): string[] | undefined;
|
|
18
|
+
}
|
|
19
|
+
export interface AgentChange<T> {
|
|
20
|
+
result: T;
|
|
21
|
+
/**
|
|
22
|
+
* The runtime registry reflects the change now (new prompts use it). False: the file is saved,
|
|
23
|
+
* but Alisio must restart (or the workspace must be trusted / the plugin enabled) to use it.
|
|
24
|
+
*/
|
|
25
|
+
live: boolean;
|
|
26
|
+
}
|
|
27
|
+
export interface AgentDefinitionServiceOptions {
|
|
28
|
+
/** Workspace root; without it only the global scope exists. */
|
|
29
|
+
workspace?: string;
|
|
30
|
+
/** Home directory of the global scope (`os.homedir()`). */
|
|
31
|
+
home: string;
|
|
32
|
+
registry?: AgentRegistry;
|
|
33
|
+
now?: () => number;
|
|
34
|
+
}
|
|
35
|
+
/** Applies the project-over-global precedence and marks both sides of an override. */
|
|
36
|
+
export declare function mergeAgentScopes(project: AgentDefinitionInfo[], global: AgentDefinitionInfo[]): AgentDefinitionInfo[];
|
|
37
|
+
export declare class AgentDefinitionService {
|
|
38
|
+
private readonly options;
|
|
39
|
+
private readonly stores;
|
|
40
|
+
constructor(options: AgentDefinitionServiceOptions);
|
|
41
|
+
/** Scopes available here: `project` only with a workspace. */
|
|
42
|
+
get scopes(): AgentScope[];
|
|
43
|
+
/** The scope new agents default to: the project when a workspace is open. */
|
|
44
|
+
get defaultScope(): AgentScope;
|
|
45
|
+
dir(scope: AgentScope): string;
|
|
46
|
+
private store;
|
|
47
|
+
list(): Promise<AgentDefinitionInfo[]>;
|
|
48
|
+
get(scope: AgentScope, id: string): Promise<AgentDefinitionInfo | undefined>;
|
|
49
|
+
create(scope: AgentScope, input: AgentDefinitionInput): Promise<AgentChange<AgentDefinitionInfo>>;
|
|
50
|
+
update(scope: AgentScope, id: string, input: AgentDefinitionInput): Promise<AgentChange<AgentDefinitionInfo>>;
|
|
51
|
+
delete(scope: AgentScope, id: string): Promise<AgentChange<boolean>>;
|
|
52
|
+
/** Asks the runtime registry to rediscover agent files (false: nothing could reload). */
|
|
53
|
+
reload(): Promise<boolean>;
|
|
54
|
+
/** Whether the runtime registry has `path` loaded (false when unknown). */
|
|
55
|
+
isLoaded(path: string): boolean;
|
|
56
|
+
private settle;
|
|
57
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { AgentNotFoundError, AgentScopeStore, agentScopeDir } from "./definitions.js";
|
|
2
|
+
/** Applies the project-over-global precedence and marks both sides of an override. */
|
|
3
|
+
export function mergeAgentScopes(project, global) {
|
|
4
|
+
const projectIds = new Set(project.map((a) => a.id));
|
|
5
|
+
const globalIds = new Set(global.map((a) => a.id));
|
|
6
|
+
const byName = (a, b) => a.name.localeCompare(b.name) || (a.scope === b.scope ? 0 : a.scope === "project" ? -1 : 1);
|
|
7
|
+
return [
|
|
8
|
+
...project.map((a) => (globalIds.has(a.id) ? { ...a, overridesGlobal: true } : a)),
|
|
9
|
+
...global.map((a) => (projectIds.has(a.id) ? { ...a, overriddenByProject: true } : a)),
|
|
10
|
+
].sort(byName);
|
|
11
|
+
}
|
|
12
|
+
export class AgentDefinitionService {
|
|
13
|
+
options;
|
|
14
|
+
stores = {};
|
|
15
|
+
constructor(options) {
|
|
16
|
+
this.options = options;
|
|
17
|
+
this.stores.global = new AgentScopeStore("global", agentScopeDir("global", options), options.now);
|
|
18
|
+
if (options.workspace)
|
|
19
|
+
this.stores.project = new AgentScopeStore("project", agentScopeDir("project", options), options.now);
|
|
20
|
+
}
|
|
21
|
+
/** Scopes available here: `project` only with a workspace. */
|
|
22
|
+
get scopes() {
|
|
23
|
+
return this.stores.project ? ["project", "global"] : ["global"];
|
|
24
|
+
}
|
|
25
|
+
/** The scope new agents default to: the project when a workspace is open. */
|
|
26
|
+
get defaultScope() {
|
|
27
|
+
return this.stores.project ? "project" : "global";
|
|
28
|
+
}
|
|
29
|
+
dir(scope) {
|
|
30
|
+
return this.store(scope).dir;
|
|
31
|
+
}
|
|
32
|
+
store(scope) {
|
|
33
|
+
const store = this.stores[scope];
|
|
34
|
+
if (!store)
|
|
35
|
+
throw new Error(`The ${scope} scope is not available without a workspace`);
|
|
36
|
+
return store;
|
|
37
|
+
}
|
|
38
|
+
async list() {
|
|
39
|
+
const [project, global] = await Promise.all([
|
|
40
|
+
this.stores.project?.list() ?? Promise.resolve([]),
|
|
41
|
+
this.store("global").list(),
|
|
42
|
+
]);
|
|
43
|
+
return mergeAgentScopes(project, global);
|
|
44
|
+
}
|
|
45
|
+
async get(scope, id) {
|
|
46
|
+
const all = await this.list();
|
|
47
|
+
return all.find((a) => a.scope === scope && a.id === id);
|
|
48
|
+
}
|
|
49
|
+
async create(scope, input) {
|
|
50
|
+
const created = await this.store(scope).create(input);
|
|
51
|
+
return this.settle(created.id, scope, created.path, true);
|
|
52
|
+
}
|
|
53
|
+
async update(scope, id, input) {
|
|
54
|
+
const updated = await this.store(scope).update(id, input);
|
|
55
|
+
return this.settle(updated.id, scope, updated.path, true);
|
|
56
|
+
}
|
|
57
|
+
async delete(scope, id) {
|
|
58
|
+
const store = this.store(scope);
|
|
59
|
+
const existing = await store.get(id);
|
|
60
|
+
if (!existing)
|
|
61
|
+
throw new AgentNotFoundError(scope, id);
|
|
62
|
+
const deleted = await store.delete(id);
|
|
63
|
+
const live = (await this.reload()) && !this.isLoaded(existing.path);
|
|
64
|
+
return { result: deleted, live };
|
|
65
|
+
}
|
|
66
|
+
/** Asks the runtime registry to rediscover agent files (false: nothing could reload). */
|
|
67
|
+
async reload() {
|
|
68
|
+
if (!this.options.registry)
|
|
69
|
+
return false;
|
|
70
|
+
try {
|
|
71
|
+
return await this.options.registry.reload();
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/** Whether the runtime registry has `path` loaded (false when unknown). */
|
|
78
|
+
isLoaded(path) {
|
|
79
|
+
return !!this.options.registry?.loadedPaths()?.includes(path);
|
|
80
|
+
}
|
|
81
|
+
async settle(id, scope, path, mustBeLoaded) {
|
|
82
|
+
const reloaded = await this.reload();
|
|
83
|
+
const result = (await this.get(scope, id));
|
|
84
|
+
return { result, live: reloaded && this.isLoaded(path) === mustBeLoaded };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Predefined starting points for new agents, shared by the web Agents window (served by
|
|
3
|
+
* `GET /api/agents/templates`) and the TUI `/agents` manager. A template never chooses a model:
|
|
4
|
+
* the editor starts from the active one.
|
|
5
|
+
*/
|
|
6
|
+
import type { AgentTemplateInfo } from "@alisio/sdk";
|
|
7
|
+
export declare const AGENT_TEMPLATES: readonly AgentTemplateInfo[];
|
|
8
|
+
export declare function agentTemplate(id: string): AgentTemplateInfo | undefined;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
const lines = (...parts) => parts.join("\n");
|
|
2
|
+
export const AGENT_TEMPLATES = [
|
|
3
|
+
{
|
|
4
|
+
id: "code-reviewer",
|
|
5
|
+
name: "Code Reviewer",
|
|
6
|
+
description: "Reads a diff or a set of files and reports bugs, risky changes and missing tests, ordered by severity.",
|
|
7
|
+
instructions: lines("You are a meticulous code reviewer working inside the user's repository.", "", "- Start from the change under review (git diff, the files named by the user) and read the surrounding code before judging it.", "- Report correctness bugs first, then security and data-loss risks, then maintainability. Skip pure style nits unless asked.", "- For every finding give the file and line, why it is a problem, and a concrete fix.", "- Say explicitly when you found nothing serious; never invent issues to fill a report.", "- Do not edit files unless the user asks you to apply a fix."),
|
|
8
|
+
reasoning: { effort: "high", summary: "auto" },
|
|
9
|
+
text: { format: { type: "text" }, verbosity: "medium" },
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
id: "test-writer",
|
|
13
|
+
name: "Test Writer",
|
|
14
|
+
description: "Adds focused tests for existing behavior or a new change, following the project's test framework and conventions.",
|
|
15
|
+
instructions: lines("You write automated tests for this project.", "", "- Detect the test framework, file layout and helpers already in use and follow them.", "- Test observable behavior at module boundaries; avoid snapshots that only restate the implementation.", "- Cover the happy path, edge cases and failure modes. Keep each test small and named after the behavior it proves.", "- Run the tests you add and report the command and its result. If a test fails because of a real bug, say so instead of weakening the assertion."),
|
|
16
|
+
reasoning: { effort: "medium", summary: "auto" },
|
|
17
|
+
text: { format: { type: "text" }, verbosity: "low" },
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: "refactoring-assistant",
|
|
21
|
+
name: "Refactoring Assistant",
|
|
22
|
+
description: "Improves the structure of existing code in small, behavior-preserving steps verified by the test suite.",
|
|
23
|
+
instructions: lines("You refactor code without changing its behavior.", "", "- Before editing, explain the smell you are addressing and the target shape in a few lines.", "- Work in small steps; run the relevant tests after each meaningful step.", "- Keep public interfaces stable unless the user agrees to change them, and update every caller when they do change.", "- Do not mix refactoring with feature work or formatting churn.", "- Finish with a short summary of what moved where and how it was verified."),
|
|
24
|
+
reasoning: { effort: "high", summary: "auto" },
|
|
25
|
+
text: { format: { type: "text" }, verbosity: "medium" },
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
id: "documentation-writer",
|
|
29
|
+
name: "Documentation Writer",
|
|
30
|
+
description: "Writes and updates READMEs, guides and API docs that match the code as it is today.",
|
|
31
|
+
instructions: lines("You write clear technical documentation for this project.", "", "- Read the code first; document what it actually does, not what it was meant to do.", "- Lead with the task the reader wants to accomplish, then details. Prefer short sections, lists and runnable examples.", "- Keep commands, flags and configuration keys exact, and keep every translated copy of a page in sync.", "- Flag behavior that looks wrong instead of documenting it as intended."),
|
|
32
|
+
reasoning: { effort: "low", summary: "auto" },
|
|
33
|
+
text: { format: { type: "text" }, verbosity: "medium" },
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: "security-auditor",
|
|
37
|
+
name: "Security Auditor",
|
|
38
|
+
description: "Looks for vulnerabilities such as injection, secret leaks, unsafe defaults and weak access control, with evidence.",
|
|
39
|
+
instructions: lines("You audit code for security problems.", "", "- Trace untrusted input from where it enters (HTTP, CLI arguments, files, environment) to where it is used.", "- Look for injection, path traversal, unsafe deserialization, missing authorization, secrets in code or logs, and insecure defaults.", "- Rate every finding (critical, high, medium, low) and include the exploit path, the affected code and a fix.", "- Distinguish confirmed issues from hypotheses. Never run destructive commands or exfiltrate data while testing."),
|
|
40
|
+
reasoning: { effort: "high", summary: "detailed" },
|
|
41
|
+
text: { format: { type: "text" }, verbosity: "high" },
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: "debugger",
|
|
45
|
+
name: "Bug Triage & Debugger",
|
|
46
|
+
description: "Reproduces a reported failure, isolates the root cause and proposes the smallest safe fix.",
|
|
47
|
+
instructions: lines("You debug problems reported by the user.", "", "1. Restate the symptom and gather facts: error output, logs, recent changes, versions.", "2. Reproduce it with the smallest possible command or test before changing anything.", "3. Form hypotheses and test them one at a time; record what each experiment ruled out.", "4. Fix the root cause, not the symptom, and add a regression test when the project has tests.", "", "If you cannot reproduce the issue, say what you tried and what information would unblock you."),
|
|
48
|
+
reasoning: { effort: "high", summary: "auto" },
|
|
49
|
+
text: { format: { type: "text" }, verbosity: "medium" },
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: "migration-assistant",
|
|
53
|
+
name: "Migration Assistant",
|
|
54
|
+
description: "Plans and carries out upgrades of frameworks, libraries or APIs across the codebase, one verified batch at a time.",
|
|
55
|
+
instructions: lines("You migrate this codebase from one version, library or API to another.", "", "- Read the official migration notes for the target version when they are available and list the breaking changes that apply here.", "- Inventory every affected call site before editing, then migrate in batches that keep the build green.", "- Run the type checker and tests after each batch and report anything you had to leave behind.", "- Never silence errors with casts or disabled checks just to finish a batch."),
|
|
56
|
+
reasoning: { effort: "high", summary: "auto" },
|
|
57
|
+
text: { format: { type: "text" }, verbosity: "medium" },
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: "research-agent",
|
|
61
|
+
name: "Research Agent",
|
|
62
|
+
description: "Investigates a question across the web, documentation and local data, and returns a sourced, structured report.",
|
|
63
|
+
instructions: lines("You are a research assistant.", "", "- Clarify the question and the decision it supports before searching.", "- Gather evidence from several independent sources; prefer primary documentation and data over summaries.", "- Organize the answer as: summary, key findings, evidence (with links or file paths), open questions.", "- Mark uncertainty explicitly and never present a guess as a sourced fact."),
|
|
64
|
+
reasoning: { effort: "medium", summary: "concise" },
|
|
65
|
+
text: { format: { type: "text" }, verbosity: "high" },
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
id: "customer-support-agent",
|
|
69
|
+
name: "Customer Support Agent",
|
|
70
|
+
description: "Answers customer requests politely, checks the account details it is given and hands off what it cannot resolve.",
|
|
71
|
+
instructions: lines("You help customers resolve their requests.", "", "- Be warm, concise and specific. Confirm what the customer is asking before acting.", "- Use only the account information and tools you are given; never guess balances, orders or personal data.", "- Follow the documented policies. When a request needs a human (refunds above policy, legal or safety issues, angry escalations), say so and summarize the case for the hand-off.", "- End each reply with the next step for the customer."),
|
|
72
|
+
reasoning: { effort: "low", summary: "none" },
|
|
73
|
+
text: { format: { type: "text" }, verbosity: "low" },
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
id: "devops-assistant",
|
|
77
|
+
name: "DevOps Assistant",
|
|
78
|
+
description: "Helps with deployments, CI pipelines, incident response and infrastructure troubleshooting.",
|
|
79
|
+
instructions: lines("You are a DevOps and site-reliability assistant.", "", "- During an incident, focus on impact and mitigation first, then root cause.", "- Read configuration, pipeline definitions and logs before proposing changes; quote the lines that matter.", "- Prefer reversible, incremental changes. Spell out the exact commands and how to roll them back.", "- Ask before running anything that touches production, deletes resources or rotates credentials."),
|
|
80
|
+
reasoning: { effort: "medium", summary: "auto" },
|
|
81
|
+
text: { format: { type: "text" }, verbosity: "medium" },
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
id: "meeting-assistant",
|
|
85
|
+
name: "Meeting Assistant",
|
|
86
|
+
description: "Turns meeting transcripts or notes into decisions, action items with owners and a short summary.",
|
|
87
|
+
instructions: lines("You process meeting transcripts and notes.", "", "Produce, in this order:", "1. A summary of three to five sentences.", "2. Decisions made.", "3. Action items as `owner — task — due date` (write `unassigned` or `no date` when missing).", "4. Open questions and risks.", "", "Use only what the transcript says; do not invent owners or dates."),
|
|
88
|
+
reasoning: { effort: "low", summary: "none" },
|
|
89
|
+
text: { format: { type: "text" }, verbosity: "low" },
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
id: "analytics-agent",
|
|
93
|
+
name: "Analytics Agent",
|
|
94
|
+
description: "Queries data, builds reports and explains trends and anomalies in plain language.",
|
|
95
|
+
instructions: lines("You are a data analyst.", "", "- Confirm the metric definitions, filters and time range before querying.", "- Show the query or computation you used so the result can be reproduced.", "- Explain what changed, by how much, and the most likely drivers; separate correlation from causation.", "- Call out data quality problems (gaps, duplicates, outliers) instead of hiding them."),
|
|
96
|
+
reasoning: { effort: "medium", summary: "auto" },
|
|
97
|
+
text: { format: { type: "text" }, verbosity: "medium" },
|
|
98
|
+
},
|
|
99
|
+
];
|
|
100
|
+
export function agentTemplate(id) {
|
|
101
|
+
return AGENT_TEMPLATES.find((template) => template.id === id);
|
|
102
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persisted capability decisions (`capability_grants`). A `session` allow of the ROOT session is
|
|
3
|
+
* the only state that grants anything; `once` allows and every `deny` are audit rows only (a deny
|
|
4
|
+
* is never sticky: the next call asks again). Revoking stamps `revoked_at`; nothing is deleted.
|
|
5
|
+
*/
|
|
6
|
+
import type { AnalysisCapability, CapabilityGrantWire, SqlDatabase } from "@alisio/sdk";
|
|
7
|
+
export type GrantSource = CapabilityGrantWire["source"];
|
|
8
|
+
export interface GrantRecord extends CapabilityGrantWire {
|
|
9
|
+
workspace: string;
|
|
10
|
+
callId?: string;
|
|
11
|
+
runId?: string;
|
|
12
|
+
correlationId?: string;
|
|
13
|
+
revokedBy?: string;
|
|
14
|
+
}
|
|
15
|
+
/** Wire shape (no workspace path or call ids). */
|
|
16
|
+
export declare const toGrantWire: (record: GrantRecord) => CapabilityGrantWire;
|
|
17
|
+
export declare class CapabilityGrants {
|
|
18
|
+
private options;
|
|
19
|
+
constructor(options: {
|
|
20
|
+
db: SqlDatabase;
|
|
21
|
+
/** Root of a session (grants always belong to the root). */
|
|
22
|
+
rootOf: (sessionId: string) => string;
|
|
23
|
+
now?: () => number;
|
|
24
|
+
});
|
|
25
|
+
rootOf(sessionId: string): string;
|
|
26
|
+
/** The live `session` allow of `capability` for the root of `sessionId`, if any. */
|
|
27
|
+
active(capability: AnalysisCapability, sessionId: string): GrantRecord | undefined;
|
|
28
|
+
granted(capability: AnalysisCapability, sessionId: string): boolean;
|
|
29
|
+
/** Records one decision (audit row; a `session` allow is also the live grant). */
|
|
30
|
+
record(input: {
|
|
31
|
+
capability: AnalysisCapability;
|
|
32
|
+
sessionId: string;
|
|
33
|
+
workspace: string;
|
|
34
|
+
scope: "once" | "session";
|
|
35
|
+
decision: "allow" | "deny";
|
|
36
|
+
source: GrantSource;
|
|
37
|
+
callId?: string;
|
|
38
|
+
runId?: string;
|
|
39
|
+
correlationId?: string;
|
|
40
|
+
}): GrantRecord;
|
|
41
|
+
get(id: string): GrantRecord | undefined;
|
|
42
|
+
/** Live session grants first, then the latest `limit` audit rows of the root session. */
|
|
43
|
+
list(sessionId: string, limit?: number): GrantRecord[];
|
|
44
|
+
/** Live grants of the root session only. */
|
|
45
|
+
live(sessionId: string): GrantRecord[];
|
|
46
|
+
/** Revokes a live grant of `sessionId`'s root. False when unknown, foreign or already revoked. */
|
|
47
|
+
revoke(sessionId: string, grantId: string, by: string): boolean;
|
|
48
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { newId } from "../runtime/ids.js";
|
|
2
|
+
const toRecord = (r) => ({
|
|
3
|
+
id: String(r.id),
|
|
4
|
+
capability: String(r.capability),
|
|
5
|
+
sessionId: String(r.session),
|
|
6
|
+
workspace: String(r.workspace),
|
|
7
|
+
scope: String(r.scope),
|
|
8
|
+
decision: String(r.decision),
|
|
9
|
+
source: String(r.source),
|
|
10
|
+
createdAt: Number(r.created_at),
|
|
11
|
+
...(r.revoked_at != null ? { revokedAt: Number(r.revoked_at) } : {}),
|
|
12
|
+
...(r.revoked_by != null ? { revokedBy: String(r.revoked_by) } : {}),
|
|
13
|
+
...(r.call_id != null ? { callId: String(r.call_id) } : {}),
|
|
14
|
+
...(r.run_id != null ? { runId: String(r.run_id) } : {}),
|
|
15
|
+
...(r.correlation_id != null ? { correlationId: String(r.correlation_id) } : {}),
|
|
16
|
+
});
|
|
17
|
+
/** Wire shape (no workspace path or call ids). */
|
|
18
|
+
export const toGrantWire = (record) => ({
|
|
19
|
+
id: record.id,
|
|
20
|
+
capability: record.capability,
|
|
21
|
+
sessionId: record.sessionId,
|
|
22
|
+
scope: record.scope,
|
|
23
|
+
decision: record.decision,
|
|
24
|
+
source: record.source,
|
|
25
|
+
createdAt: record.createdAt,
|
|
26
|
+
...(record.revokedAt !== undefined ? { revokedAt: record.revokedAt } : {}),
|
|
27
|
+
});
|
|
28
|
+
export class CapabilityGrants {
|
|
29
|
+
options;
|
|
30
|
+
constructor(options) {
|
|
31
|
+
this.options = options;
|
|
32
|
+
}
|
|
33
|
+
rootOf(sessionId) {
|
|
34
|
+
return this.options.rootOf(sessionId);
|
|
35
|
+
}
|
|
36
|
+
/** The live `session` allow of `capability` for the root of `sessionId`, if any. */
|
|
37
|
+
active(capability, sessionId) {
|
|
38
|
+
const row = this.options.db
|
|
39
|
+
.prepare(`SELECT * FROM capability_grants WHERE capability=? AND session=? AND scope='session'
|
|
40
|
+
AND decision='allow' AND revoked_at IS NULL ORDER BY created_at DESC LIMIT 1`)
|
|
41
|
+
.get(capability, this.rootOf(sessionId));
|
|
42
|
+
return row ? toRecord(row) : undefined;
|
|
43
|
+
}
|
|
44
|
+
granted(capability, sessionId) {
|
|
45
|
+
return !!this.active(capability, sessionId);
|
|
46
|
+
}
|
|
47
|
+
/** Records one decision (audit row; a `session` allow is also the live grant). */
|
|
48
|
+
record(input) {
|
|
49
|
+
const id = newId("grant");
|
|
50
|
+
const createdAt = (this.options.now ?? Date.now)();
|
|
51
|
+
this.options.db
|
|
52
|
+
.prepare(`INSERT INTO capability_grants(id,capability,session,workspace,scope,decision,source,call_id,
|
|
53
|
+
run_id,correlation_id,created_at) VALUES(?,?,?,?,?,?,?,?,?,?,?)`)
|
|
54
|
+
.run(id, input.capability, this.rootOf(input.sessionId), input.workspace, input.scope, input.decision, input.source, input.callId ?? null, input.runId ?? null, input.correlationId ?? null, createdAt);
|
|
55
|
+
return this.get(id);
|
|
56
|
+
}
|
|
57
|
+
get(id) {
|
|
58
|
+
const row = this.options.db.prepare("SELECT * FROM capability_grants WHERE id=?").get(id);
|
|
59
|
+
return row ? toRecord(row) : undefined;
|
|
60
|
+
}
|
|
61
|
+
/** Live session grants first, then the latest `limit` audit rows of the root session. */
|
|
62
|
+
list(sessionId, limit = 50) {
|
|
63
|
+
const root = this.rootOf(sessionId);
|
|
64
|
+
const live = this.options.db
|
|
65
|
+
.prepare(`SELECT * FROM capability_grants WHERE session=? AND scope='session' AND decision='allow'
|
|
66
|
+
AND revoked_at IS NULL ORDER BY created_at DESC`)
|
|
67
|
+
.all(root).map(toRecord);
|
|
68
|
+
const ids = new Set(live.map((g) => g.id));
|
|
69
|
+
const audit = this.options.db
|
|
70
|
+
.prepare("SELECT * FROM capability_grants WHERE session=? ORDER BY created_at DESC LIMIT ?")
|
|
71
|
+
.all(root, limit)
|
|
72
|
+
.map(toRecord)
|
|
73
|
+
.filter((g) => !ids.has(g.id));
|
|
74
|
+
return [...live, ...audit];
|
|
75
|
+
}
|
|
76
|
+
/** Live grants of the root session only. */
|
|
77
|
+
live(sessionId) {
|
|
78
|
+
return this.list(sessionId, 0).filter((g) => g.revokedAt === undefined && g.scope === "session");
|
|
79
|
+
}
|
|
80
|
+
/** Revokes a live grant of `sessionId`'s root. False when unknown, foreign or already revoked. */
|
|
81
|
+
revoke(sessionId, grantId, by) {
|
|
82
|
+
const grant = this.get(grantId);
|
|
83
|
+
if (!grant || grant.sessionId !== this.rootOf(sessionId) || grant.revokedAt !== undefined)
|
|
84
|
+
return false;
|
|
85
|
+
this.options.db
|
|
86
|
+
.prepare("UPDATE capability_grants SET revoked_at=?, revoked_by=? WHERE id=?")
|
|
87
|
+
.run((this.options.now ?? Date.now)(), by, grantId);
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Streaming CSV/TSV parser (RFC 4180, spec §17.2): quoted fields, doubled quotes, line breaks
|
|
3
|
+
* inside quotes, CRLF/LF/CR rows. No dependencies and no I/O: callers push decoded text chunks
|
|
4
|
+
* (any split, even inside a quote or between CR and LF) and receive rows through a callback.
|
|
5
|
+
* Blank lines are skipped. Lenient on purpose: a stray quote inside an unquoted field is literal
|
|
6
|
+
* and text after a closing quote is appended.
|
|
7
|
+
*/
|
|
8
|
+
export declare class CsvError extends Error {
|
|
9
|
+
readonly code: "cell_too_large";
|
|
10
|
+
constructor(message: string, code: "cell_too_large");
|
|
11
|
+
}
|
|
12
|
+
export declare class CsvParser {
|
|
13
|
+
private readonly onRow;
|
|
14
|
+
private readonly maxCellChars;
|
|
15
|
+
private state;
|
|
16
|
+
private field;
|
|
17
|
+
private fields;
|
|
18
|
+
private skipLineFeed;
|
|
19
|
+
/** The current field was opened with a quote (so `""` is a value, not a blank line). */
|
|
20
|
+
private quotedField;
|
|
21
|
+
private readonly delimiter;
|
|
22
|
+
/** Rows delivered so far (blank lines excluded). */
|
|
23
|
+
rows: number;
|
|
24
|
+
constructor(delimiter: string, onRow: (fields: string[]) => void, maxCellChars?: number);
|
|
25
|
+
private add;
|
|
26
|
+
private endField;
|
|
27
|
+
private endRow;
|
|
28
|
+
write(chunk: string): void;
|
|
29
|
+
/** Flushes the last row when the input has no final line break. */
|
|
30
|
+
end(): void;
|
|
31
|
+
}
|
|
32
|
+
/** Parses a whole string (tests and small inputs). */
|
|
33
|
+
export declare function parseCsv(text: string, delimiter?: string): string[][];
|
|
34
|
+
/**
|
|
35
|
+
* Detects the delimiter from a text sample (the first 64 KiB): the candidate that splits most
|
|
36
|
+
* rows into the same number (> 1) of fields wins; ties keep the order `,` `;` TAB `|`.
|
|
37
|
+
*/
|
|
38
|
+
export declare function detectDelimiter(sample: string): string;
|
|
39
|
+
/**
|
|
40
|
+
* Decodes a byte sample as the ingestion does: UTF-8 (BOM removed), UTF-16 by BOM, or
|
|
41
|
+
* windows-1252 when the bytes are not valid UTF-8. A sample cut inside a character is tolerated.
|
|
42
|
+
*/
|
|
43
|
+
export declare function decodeTextBytes(bytes: Uint8Array, truncated?: boolean): {
|
|
44
|
+
text: string;
|
|
45
|
+
encoding: string;
|
|
46
|
+
};
|