@lazyingart/agintiflow 0.2.0 → 0.4.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.
@@ -0,0 +1,85 @@
1
+ export const TASK_PROFILES = {
2
+ auto: {
3
+ id: "auto",
4
+ label: "Auto",
5
+ prompt:
6
+ "Infer the task type from the user request. Prefer the smallest safe tool sequence, preserve workspace files, and summarize what changed.",
7
+ tools: ["browser", "shell", "files", "canvas"],
8
+ },
9
+ code: {
10
+ id: "code",
11
+ label: "Code writing",
12
+ prompt:
13
+ "Act like a coding agent: inspect files first, make targeted workspace-local edits, run relevant checks, and report changed files and residual risks.",
14
+ tools: ["files", "shell", "sandbox"],
15
+ },
16
+ writing: {
17
+ id: "writing",
18
+ label: "Book/script writing",
19
+ prompt:
20
+ "Create structured drafts with outlines, sections, and revision notes. Use files for long-form output and canvas for important drafts.",
21
+ tools: ["files", "canvas"],
22
+ },
23
+ design: {
24
+ id: "design",
25
+ label: "Design docs",
26
+ prompt:
27
+ "Produce concise design documents with goals, constraints, options, tradeoffs, implementation steps, and verification criteria.",
28
+ tools: ["files", "canvas"],
29
+ },
30
+ python: {
31
+ id: "python",
32
+ label: "Python",
33
+ prompt:
34
+ "For Python tasks, create small scripts or notebooks as files, prefer virtual environments or Docker for package setup, and run smoke checks when shell is enabled.",
35
+ tools: ["files", "shell", "sandbox"],
36
+ },
37
+ shell: {
38
+ id: "shell",
39
+ label: "Shell",
40
+ prompt:
41
+ "For shell tasks, use allowlisted commands, explain blocked commands, avoid destructive operations, and keep outputs concise.",
42
+ tools: ["shell", "sandbox"],
43
+ },
44
+ node: {
45
+ id: "node",
46
+ label: "Node",
47
+ prompt:
48
+ "For Node.js tasks, inspect package scripts, use npm checks/tests when safe, and keep generated files inside the project workspace.",
49
+ tools: ["files", "shell", "sandbox"],
50
+ },
51
+ aaps: {
52
+ id: "aaps",
53
+ label: "AAPS",
54
+ prompt:
55
+ "For AAPS tasks, recognize .aaps folders and @lazyingart/aaps package workflows. Prefer project-local config, safe publish preparation, and explicit secret handling.",
56
+ tools: ["files", "shell", "sandbox"],
57
+ },
58
+ latex: {
59
+ id: "latex",
60
+ label: "LaTeX",
61
+ prompt:
62
+ "For LaTeX/PDF tasks, create source and figures in a subfolder, compile when a TeX toolchain is available, and send the PDF through the canvas tunnel.",
63
+ tools: ["files", "shell", "canvas", "sandbox"],
64
+ },
65
+ maintenance: {
66
+ id: "maintenance",
67
+ label: "System maintenance",
68
+ prompt:
69
+ "For system maintenance, diagnose first, prefer idempotent scripts, ask for approval before privileged or destructive operations, and avoid leaking credentials.",
70
+ tools: ["shell", "sandbox", "files"],
71
+ },
72
+ };
73
+
74
+ export function listTaskProfiles() {
75
+ return Object.values(TASK_PROFILES);
76
+ }
77
+
78
+ export function normalizeTaskProfile(value = "auto") {
79
+ const key = String(value || "auto").trim().toLowerCase();
80
+ return TASK_PROFILES[key] ? key : "auto";
81
+ }
82
+
83
+ export function getTaskProfile(value = "auto") {
84
+ return TASK_PROFILES[normalizeTaskProfile(value)];
85
+ }
package/src/web-db.js CHANGED
@@ -3,7 +3,7 @@ import path from "node:path";
3
3
  import { DatabaseSync } from "node:sqlite";
4
4
  import { getModelPresets } from "./model-routing.js";
5
5
 
6
- const PREFERENCES_SCHEMA_VERSION = 2;
6
+ const PREFERENCES_SCHEMA_VERSION = 3;
7
7
 
8
8
  function defaultPreferences(baseDir) {
9
9
  const presets = getModelPresets();
@@ -16,7 +16,7 @@ function defaultPreferences(baseDir) {
16
16
  maxSteps: 15,
17
17
  startUrl: "",
18
18
  allowedDomains: "",
19
- commandCwd: path.resolve(baseDir, ".."),
19
+ commandCwd: path.resolve(baseDir),
20
20
  allowShellTool: true,
21
21
  allowFileTools: true,
22
22
  allowWrapperTools: false,
@@ -29,6 +29,7 @@ function defaultPreferences(baseDir) {
29
29
  allowPasswords: false,
30
30
  allowDestructive: false,
31
31
  language: "en",
32
+ taskProfile: "auto",
32
33
  };
33
34
  }
34
35
 
@@ -81,6 +82,9 @@ export class WebDatabase {
81
82
  };
82
83
  if ((parsed.preferencesSchemaVersion || 1) < PREFERENCES_SCHEMA_VERSION) {
83
84
  preferences.preferencesSchemaVersion = PREFERENCES_SCHEMA_VERSION;
85
+ if (!parsed.commandCwd || parsed.commandCwd === path.resolve(this.baseDir, "..")) {
86
+ preferences.commandCwd = path.resolve(this.baseDir);
87
+ }
84
88
  if (["host", "docker-readonly"].includes(parsed.sandboxMode || "")) {
85
89
  preferences.sandboxMode = "docker-workspace";
86
90
  preferences.useDockerSandbox = true;
package/web.js CHANGED
@@ -11,6 +11,8 @@ import { listAgentWrappers, normalizeWrapperName } from "./src/tool-wrappers.js"
11
11
  import { getDockerSandboxStatus, getSandboxLogs, runDockerPreflight } from "./src/docker-sandbox.js";
12
12
  import { normalizePackageInstallPolicy, normalizeSandboxMode } from "./src/command-policy.js";
13
13
  import { summarizeWorkspaceTools, WORKSPACE_TOOL_NAMES } from "./src/workspace-tools.js";
14
+ import { listTaskProfiles, normalizeTaskProfile } from "./src/task-profiles.js";
15
+ import { loadProjectEnv, projectPaths, providerKeyStatus, setProviderKey } from "./src/project.js";
14
16
  import {
15
17
  buildArtifacts,
16
18
  countUnreadArtifacts,
@@ -24,6 +26,7 @@ const __dirname = path.dirname(__filename);
24
26
  const packageDir = __dirname;
25
27
  const baseDir = path.resolve(process.env.AGINTIFLOW_RUNTIME_DIR || process.cwd());
26
28
  const sessionsDir = path.join(baseDir, ".sessions");
29
+ loadProjectEnv(baseDir);
27
30
 
28
31
  const app = express();
29
32
  const port = Number(process.env.PORT || 3210);
@@ -132,7 +135,8 @@ function normalizePreferencePayload(body = {}, current = db.getPreferences()) {
132
135
  commandCwd:
133
136
  typeof body.commandCwd === "string" && body.commandCwd.trim()
134
137
  ? body.commandCwd.trim()
135
- : current.commandCwd || path.resolve(baseDir, ".."),
138
+ : current.commandCwd || baseDir,
139
+ taskProfile: normalizeTaskProfile(body.taskProfile || current.taskProfile || "auto"),
136
140
  allowShellTool: typeof body.allowShellTool === "boolean" ? body.allowShellTool : Boolean(current.allowShellTool),
137
141
  allowFileTools: typeof body.allowFileTools === "boolean" ? body.allowFileTools : current.allowFileTools !== false,
138
142
  allowWrapperTools:
@@ -172,6 +176,17 @@ function publicProviderDefault(provider) {
172
176
  };
173
177
  }
174
178
 
179
+ function publicKeyStatus(projectRoot = baseDir) {
180
+ const status = providerKeyStatus(projectRoot);
181
+ return {
182
+ openai: status.openai,
183
+ deepseek: status.deepseek,
184
+ mock: true,
185
+ localEnv: status.localEnv,
186
+ envVars: status.envVars,
187
+ };
188
+ }
189
+
175
190
  function buildRunConfig(body, overrides = {}) {
176
191
  const preferences = normalizePreferencePayload(body, db.getPreferences());
177
192
  const merged = {
@@ -208,6 +223,7 @@ function buildRunConfig(body, overrides = {}) {
208
223
  useDockerSandbox: merged.useDockerSandbox,
209
224
  dockerSandboxImage: merged.dockerSandboxImage,
210
225
  commandCwd: merged.commandCwd,
226
+ taskProfile: merged.taskProfile,
211
227
  baseDir,
212
228
  packageDir,
213
229
  sessionId: overrides.sessionId,
@@ -485,7 +501,17 @@ app.get("/api/config", async (_req, res) => {
485
501
  await syncStoredSessions();
486
502
  const preferences = normalizePreferencePayload({}, db.getPreferences());
487
503
  const config = buildRunConfig({ ...preferences, goal: "" });
504
+ const paths = projectPaths(baseDir);
505
+ const keyStatus = publicKeyStatus(baseDir);
488
506
  res.json({
507
+ project: {
508
+ root: paths.root,
509
+ commandCwd: config.commandCwd,
510
+ sessionsDir,
511
+ sessionDbPath: paths.sessionDbPath,
512
+ sharedSessionFolder: path.resolve(config.sessionsDir) === path.resolve(sessionsDir),
513
+ localEnvPresent: keyStatus.localEnv,
514
+ },
489
515
  defaults: {
490
516
  openai: publicProviderDefault("openai"),
491
517
  deepseek: publicProviderDefault("deepseek"),
@@ -493,6 +519,7 @@ app.get("/api/config", async (_req, res) => {
493
519
  headless: true,
494
520
  maxSteps: 15,
495
521
  },
522
+ taskProfiles: listTaskProfiles(),
496
523
  routing: {
497
524
  modes: ["smart", "fast", "complex", "manual"],
498
525
  presets: getModelPresets(),
@@ -503,15 +530,29 @@ app.get("/api/config", async (_req, res) => {
503
530
  },
504
531
  workspace: summarizeWorkspaceTools(config),
505
532
  preferences,
506
- keyStatus: {
507
- openai: Boolean(process.env.OPENAI_API_KEY),
508
- deepseek: Boolean(process.env.DEEPSEEK_API_KEY),
509
- mock: true,
510
- },
533
+ keyStatus,
511
534
  sessions: db.listSessions(100),
512
535
  });
513
536
  });
514
537
 
538
+ app.get("/api/keys/status", (_req, res) => {
539
+ res.json({ ok: true, keyStatus: publicKeyStatus(baseDir) });
540
+ });
541
+
542
+ app.post("/api/keys/:provider", async (req, res) => {
543
+ try {
544
+ const result = await setProviderKey(baseDir, req.params.provider, req.body?.apiKey || req.body?.key || "");
545
+ res.json({
546
+ ok: true,
547
+ provider: result.provider,
548
+ keyName: result.keyName,
549
+ keyStatus: publicKeyStatus(baseDir),
550
+ });
551
+ } catch (error) {
552
+ res.status(400).json({ error: error instanceof Error ? error.message : String(error) });
553
+ }
554
+ });
555
+
515
556
  app.get("/api/sandbox/status", async (_req, res) => {
516
557
  const config = buildRunConfig({ ...db.getPreferences(), goal: "" });
517
558
  const status = await getDockerSandboxStatus(config);