agent-sin 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.
Files changed (150) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/LICENSE +21 -0
  3. package/README.md +81 -0
  4. package/assets/logo.png +0 -0
  5. package/builtin-skills/_shared/_models_lib.py +227 -0
  6. package/builtin-skills/_shared/_profile_lib.py +98 -0
  7. package/builtin-skills/_shared/_schedules_lib.py +313 -0
  8. package/builtin-skills/_shared/_skill_settings_lib.py +153 -0
  9. package/builtin-skills/_shared/i18n.py +26 -0
  10. package/builtin-skills/memo-delete/main.py +155 -0
  11. package/builtin-skills/memo-delete/skill.yaml +57 -0
  12. package/builtin-skills/memo-index/main.py +178 -0
  13. package/builtin-skills/memo-index/skill.yaml +53 -0
  14. package/builtin-skills/memo-save/README.md +5 -0
  15. package/builtin-skills/memo-save/main.py +74 -0
  16. package/builtin-skills/memo-save/skill.yaml +52 -0
  17. package/builtin-skills/memo-search/README.md +10 -0
  18. package/builtin-skills/memo-search/main.py +97 -0
  19. package/builtin-skills/memo-search/skill.yaml +51 -0
  20. package/builtin-skills/memo-vector-search/main.py +121 -0
  21. package/builtin-skills/memo-vector-search/skill.yaml +53 -0
  22. package/builtin-skills/model-add/main.py +180 -0
  23. package/builtin-skills/model-add/skill.yaml +112 -0
  24. package/builtin-skills/model-list/main.py +93 -0
  25. package/builtin-skills/model-list/skill.yaml +48 -0
  26. package/builtin-skills/model-set/main.py +123 -0
  27. package/builtin-skills/model-set/skill.yaml +69 -0
  28. package/builtin-skills/profile-delete/_profile_lib.py +98 -0
  29. package/builtin-skills/profile-delete/main.py +98 -0
  30. package/builtin-skills/profile-delete/skill.yaml +64 -0
  31. package/builtin-skills/profile-edit/_profile_lib.py +98 -0
  32. package/builtin-skills/profile-edit/main.py +97 -0
  33. package/builtin-skills/profile-edit/skill.yaml +72 -0
  34. package/builtin-skills/profile-save/main.py +52 -0
  35. package/builtin-skills/profile-save/skill.yaml +69 -0
  36. package/builtin-skills/schedule-add/_schedules_lib.py +303 -0
  37. package/builtin-skills/schedule-add/main.py +137 -0
  38. package/builtin-skills/schedule-add/skill.yaml +94 -0
  39. package/builtin-skills/schedule-list/_schedules_lib.py +303 -0
  40. package/builtin-skills/schedule-list/main.py +86 -0
  41. package/builtin-skills/schedule-list/skill.yaml +45 -0
  42. package/builtin-skills/schedule-remove/_schedules_lib.py +303 -0
  43. package/builtin-skills/schedule-remove/main.py +69 -0
  44. package/builtin-skills/schedule-remove/skill.yaml +49 -0
  45. package/builtin-skills/schedule-toggle/_schedules_lib.py +303 -0
  46. package/builtin-skills/schedule-toggle/main.py +78 -0
  47. package/builtin-skills/schedule-toggle/skill.yaml +61 -0
  48. package/builtin-skills/skills-disable/main.py +63 -0
  49. package/builtin-skills/skills-disable/skill.yaml +52 -0
  50. package/builtin-skills/skills-enable/main.py +62 -0
  51. package/builtin-skills/skills-enable/skill.yaml +51 -0
  52. package/builtin-skills/todo-add/main.py +68 -0
  53. package/builtin-skills/todo-add/skill.yaml +53 -0
  54. package/builtin-skills/todo-delete/main.py +65 -0
  55. package/builtin-skills/todo-delete/skill.yaml +47 -0
  56. package/builtin-skills/todo-done/main.py +75 -0
  57. package/builtin-skills/todo-done/skill.yaml +47 -0
  58. package/builtin-skills/todo-list/main.py +91 -0
  59. package/builtin-skills/todo-list/skill.yaml +48 -0
  60. package/builtin-skills/todo-tick/main.py +125 -0
  61. package/builtin-skills/todo-tick/skill.yaml +48 -0
  62. package/dist/builder/build-action-classifier.d.ts +18 -0
  63. package/dist/builder/build-action-classifier.js +142 -0
  64. package/dist/builder/build-commands.d.ts +19 -0
  65. package/dist/builder/build-commands.js +133 -0
  66. package/dist/builder/build-flow.d.ts +72 -0
  67. package/dist/builder/build-flow.js +416 -0
  68. package/dist/builder/builder-session.d.ts +117 -0
  69. package/dist/builder/builder-session.js +1129 -0
  70. package/dist/builder/conversation-router.d.ts +22 -0
  71. package/dist/builder/conversation-router.js +69 -0
  72. package/dist/builder/intent-runtime-store.d.ts +7 -0
  73. package/dist/builder/intent-runtime-store.js +60 -0
  74. package/dist/builder/progress-format.d.ts +7 -0
  75. package/dist/builder/progress-format.js +46 -0
  76. package/dist/cli/index.d.ts +2 -0
  77. package/dist/cli/index.js +2835 -0
  78. package/dist/cli/spinner.d.ts +30 -0
  79. package/dist/cli/spinner.js +164 -0
  80. package/dist/core/ai-provider.d.ts +75 -0
  81. package/dist/core/ai-provider.js +678 -0
  82. package/dist/core/builtin-skills.d.ts +27 -0
  83. package/dist/core/builtin-skills.js +120 -0
  84. package/dist/core/chat-engine.d.ts +70 -0
  85. package/dist/core/chat-engine.js +812 -0
  86. package/dist/core/config.d.ts +127 -0
  87. package/dist/core/config.js +1379 -0
  88. package/dist/core/daily-memory-promotion.d.ts +21 -0
  89. package/dist/core/daily-memory-promotion.js +422 -0
  90. package/dist/core/i18n.d.ts +23 -0
  91. package/dist/core/i18n.js +167 -0
  92. package/dist/core/info-lines.d.ts +5 -0
  93. package/dist/core/info-lines.js +39 -0
  94. package/dist/core/input-schema.d.ts +2 -0
  95. package/dist/core/input-schema.js +156 -0
  96. package/dist/core/intent-router.d.ts +27 -0
  97. package/dist/core/intent-router.js +160 -0
  98. package/dist/core/logger.d.ts +60 -0
  99. package/dist/core/logger.js +240 -0
  100. package/dist/core/memory.d.ts +10 -0
  101. package/dist/core/memory.js +72 -0
  102. package/dist/core/message-utils.d.ts +13 -0
  103. package/dist/core/message-utils.js +104 -0
  104. package/dist/core/notifier.d.ts +17 -0
  105. package/dist/core/notifier.js +424 -0
  106. package/dist/core/output-writer.d.ts +13 -0
  107. package/dist/core/output-writer.js +100 -0
  108. package/dist/core/plan-decision.d.ts +16 -0
  109. package/dist/core/plan-decision.js +88 -0
  110. package/dist/core/profile-memory.d.ts +17 -0
  111. package/dist/core/profile-memory.js +142 -0
  112. package/dist/core/runtime.d.ts +50 -0
  113. package/dist/core/runtime.js +187 -0
  114. package/dist/core/scheduler.d.ts +28 -0
  115. package/dist/core/scheduler.js +155 -0
  116. package/dist/core/secrets.d.ts +31 -0
  117. package/dist/core/secrets.js +214 -0
  118. package/dist/core/service.d.ts +35 -0
  119. package/dist/core/service.js +479 -0
  120. package/dist/core/skill-planner.d.ts +24 -0
  121. package/dist/core/skill-planner.js +100 -0
  122. package/dist/core/skill-registry.d.ts +98 -0
  123. package/dist/core/skill-registry.js +319 -0
  124. package/dist/core/skill-scaffold.d.ts +33 -0
  125. package/dist/core/skill-scaffold.js +256 -0
  126. package/dist/core/skill-settings.d.ts +11 -0
  127. package/dist/core/skill-settings.js +63 -0
  128. package/dist/core/transfer.d.ts +31 -0
  129. package/dist/core/transfer.js +270 -0
  130. package/dist/core/update-notifier.d.ts +2 -0
  131. package/dist/core/update-notifier.js +140 -0
  132. package/dist/discord/bot.d.ts +96 -0
  133. package/dist/discord/bot.js +2424 -0
  134. package/dist/runtimes/codex-app-server.d.ts +53 -0
  135. package/dist/runtimes/codex-app-server.js +305 -0
  136. package/dist/runtimes/python-runner.d.ts +7 -0
  137. package/dist/runtimes/python-runner.js +302 -0
  138. package/dist/runtimes/typescript-runner.d.ts +5 -0
  139. package/dist/runtimes/typescript-runner.js +172 -0
  140. package/dist/skills-sdk/types.d.ts +38 -0
  141. package/dist/skills-sdk/types.js +1 -0
  142. package/dist/telegram/bot.d.ts +94 -0
  143. package/dist/telegram/bot.js +1219 -0
  144. package/install.ps1 +132 -0
  145. package/install.sh +130 -0
  146. package/package.json +60 -0
  147. package/templates/skill-python/main.py +74 -0
  148. package/templates/skill-python/skill.yaml +48 -0
  149. package/templates/skill-typescript/main.ts +87 -0
  150. package/templates/skill-typescript/skill.yaml +42 -0
@@ -0,0 +1,22 @@
1
+ import { type ChatProgressEvent, type ChatTurn } from "../core/chat-engine.js";
2
+ import type { AppConfig } from "../core/config.js";
3
+ import type { AiImagePart, AiProgressHandler } from "../core/ai-provider.js";
4
+ import { type IntentRuntime } from "./build-flow.js";
5
+ export interface BuildProgressReporter {
6
+ onProgress: AiProgressHandler;
7
+ flush(): Promise<void>;
8
+ }
9
+ export interface RouteConversationMessageOptions {
10
+ config: AppConfig;
11
+ text: string;
12
+ history: ChatTurn[];
13
+ intentRuntime: IntentRuntime;
14
+ eventSource: "discord" | "telegram";
15
+ images?: AiImagePart[];
16
+ createBuildProgress(): BuildProgressReporter;
17
+ onBuildStart?(): Promise<void>;
18
+ onBuildDone?(): Promise<void>;
19
+ onChatProgress?(event: ChatProgressEvent): void;
20
+ onAiProgress?: AiProgressHandler;
21
+ }
22
+ export declare function routeConversationMessage(options: RouteConversationMessageOptions): Promise<string[]>;
@@ -0,0 +1,69 @@
1
+ import { chatRespond, } from "../core/chat-engine.js";
2
+ import { classifyPendingHandoff, enterBuildMode, handleBuildModeMessage, } from "./build-flow.js";
3
+ import { l } from "../core/i18n.js";
4
+ export async function routeConversationMessage(options) {
5
+ const { config, text, history, intentRuntime, eventSource, images = [], } = options;
6
+ if (intentRuntime.mode === "build") {
7
+ await options.onBuildStart?.();
8
+ const buildProgress = options.createBuildProgress();
9
+ const lines = await handleBuildModeMessage(config, text, intentRuntime, {
10
+ suggestExitOnOffTopic: true,
11
+ onProgress: buildProgress.onProgress,
12
+ history,
13
+ }, eventSource);
14
+ await buildProgress.flush();
15
+ await options.onBuildDone?.();
16
+ if (lines !== null) {
17
+ return lines;
18
+ }
19
+ // lines === null means handleBuildModeMessage auto-exited build mode;
20
+ // fall through so the normal chat engine (with skills) handles this turn.
21
+ }
22
+ if (intentRuntime.pending && !text.startsWith("/")) {
23
+ const approval = await classifyPendingHandoff(config, text, history, intentRuntime);
24
+ if (approval.decision === "approve") {
25
+ await options.onBuildStart?.();
26
+ const buildProgress = options.createBuildProgress();
27
+ const lines = await enterBuildMode(config, history, intentRuntime, { onProgress: buildProgress.onProgress }, approval.carry_over_text, eventSource);
28
+ await buildProgress.flush();
29
+ await options.onBuildDone?.();
30
+ return lines;
31
+ }
32
+ if (approval.decision === "reject") {
33
+ intentRuntime.pending = null;
34
+ await options.onBuildDone?.();
35
+ return [l("OK. Continuing in chat.", "わかりました。チャットを続けます。")];
36
+ }
37
+ // "discuss" → keep pending, fall through to chatRespond.
38
+ }
39
+ let modelFailed = false;
40
+ const lines = await chatRespond(config, text, history, {
41
+ eventSource,
42
+ preferredSkillId: intentRuntime.preferred_skill_id || undefined,
43
+ userImages: images,
44
+ onChatProgress: (event) => {
45
+ if (event.kind === "model_failed") {
46
+ modelFailed = true;
47
+ }
48
+ options.onChatProgress?.(event);
49
+ },
50
+ onAiProgress: options.onAiProgress,
51
+ onBuildSuggestion: (suggestion) => setPendingBuildSuggestion(intentRuntime, suggestion, text),
52
+ });
53
+ intentRuntime.preferred_skill_id = null;
54
+ if (modelFailed && lines.length === 0) {
55
+ return [l("The model call failed.", "モデル呼び出しでエラーになりました。")];
56
+ }
57
+ return lines;
58
+ }
59
+ function setPendingBuildSuggestion(intentRuntime, suggestion, userText) {
60
+ if (!intentRuntime.enabled || intentRuntime.mode !== "chat")
61
+ return;
62
+ intentRuntime.pending = {
63
+ type: suggestion.type,
64
+ skill_id: suggestion.skill_id,
65
+ original_text: userText,
66
+ reason: suggestion.reason || "chat build suggestion",
67
+ };
68
+ intentRuntime.pending_exit = null;
69
+ }
@@ -0,0 +1,7 @@
1
+ import type { IntentRuntime } from "./build-flow.js";
2
+ type RuntimeRootKey = "channels" | "chats";
3
+ export declare function loadIntentRuntimeMap(filePath: string, rootKey: RuntimeRootKey): Promise<Map<string, IntentRuntime>>;
4
+ export declare function saveIntentRuntimeMap(filePath: string, rootKey: RuntimeRootKey, runtimes: Map<string, IntentRuntime>): Promise<void>;
5
+ export declare function restoreIntentRuntime(runtime: IntentRuntime): IntentRuntime;
6
+ export declare function isEmptyIntentRuntime(runtime: IntentRuntime): boolean;
7
+ export {};
@@ -0,0 +1,60 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ export async function loadIntentRuntimeMap(filePath, rootKey) {
4
+ try {
5
+ const raw = await readFile(filePath, "utf8");
6
+ const data = JSON.parse(raw);
7
+ const entries = data[rootKey];
8
+ const map = new Map();
9
+ if (entries && typeof entries === "object") {
10
+ for (const [key, runtime] of Object.entries(entries)) {
11
+ if (!runtime || typeof runtime !== "object")
12
+ continue;
13
+ map.set(key, restoreIntentRuntime(runtime));
14
+ }
15
+ }
16
+ return map;
17
+ }
18
+ catch {
19
+ return new Map();
20
+ }
21
+ }
22
+ export async function saveIntentRuntimeMap(filePath, rootKey, runtimes) {
23
+ await mkdir(path.dirname(filePath), { recursive: true });
24
+ const values = {};
25
+ for (const [key, runtime] of runtimes) {
26
+ if (!isEmptyIntentRuntime(runtime)) {
27
+ values[key] = runtime;
28
+ }
29
+ }
30
+ await writeFile(filePath, `${JSON.stringify({ [rootKey]: values, saved_at: new Date().toISOString() }, null, 2)}\n`, "utf8");
31
+ }
32
+ export function restoreIntentRuntime(runtime) {
33
+ const runtimeRecord = runtime;
34
+ const restoredBuild = runtime.build
35
+ ? {
36
+ ...runtime.build,
37
+ context_seed: [],
38
+ context_consumed: true,
39
+ }
40
+ : null;
41
+ return {
42
+ enabled: runtime.enabled !== false,
43
+ mode: runtime.mode === "build" ? "build" : "chat",
44
+ pending: runtime.pending ?? null,
45
+ pending_exit: runtimeRecord.pending_exit && typeof runtimeRecord.pending_exit === "object"
46
+ ? runtimeRecord.pending_exit
47
+ : null,
48
+ preferred_skill_id: typeof runtimeRecord.preferred_skill_id === "string" ? runtimeRecord.preferred_skill_id : null,
49
+ progress_detail: runtimeRecord.progress_detail === true,
50
+ build: restoredBuild,
51
+ };
52
+ }
53
+ export function isEmptyIntentRuntime(runtime) {
54
+ return (runtime.mode === "chat" &&
55
+ !runtime.pending &&
56
+ !runtime.build &&
57
+ !runtime.pending_exit &&
58
+ !runtime.preferred_skill_id &&
59
+ !runtime.progress_detail);
60
+ }
@@ -0,0 +1,7 @@
1
+ import type { AiProgressEvent } from "../core/ai-provider.js";
2
+ export declare function progressIntervalMs(envName: string, fallback?: number): number;
3
+ export declare function formatBuildProgress(event: AiProgressEvent, options?: {
4
+ detail?: boolean;
5
+ }): string | null;
6
+ export declare function formatDetailedBuildProgress(event: AiProgressEvent): string | null;
7
+ export declare function cleanProgressText(text: string): string;
@@ -0,0 +1,46 @@
1
+ import { l } from "../core/i18n.js";
2
+ export function progressIntervalMs(envName, fallback = 12000) {
3
+ const raw = Number.parseInt(process.env[envName] || "", 10);
4
+ if (Number.isFinite(raw) && raw >= 1000) {
5
+ return raw;
6
+ }
7
+ return fallback;
8
+ }
9
+ export function formatBuildProgress(event, options = {}) {
10
+ if (!options.detail) {
11
+ return null;
12
+ }
13
+ return formatDetailedBuildProgress(event);
14
+ }
15
+ export function formatDetailedBuildProgress(event) {
16
+ switch (event.kind) {
17
+ case "info":
18
+ return l(`Working: ${cleanProgressText(event.text)}`, `進めています: ${cleanProgressText(event.text)}`);
19
+ case "thinking": {
20
+ const detail = cleanProgressText(event.text || "");
21
+ return detail ? l(`Thinking: ${detail}`, `考えています: ${detail}`) : l("Thinking", "考えています");
22
+ }
23
+ case "tool": {
24
+ const name = cleanProgressText(event.name || "tool");
25
+ const detail = cleanProgressText(event.text || "");
26
+ return detail ? l(`Running tool: ${name} - ${detail}`, `ツール実行中: ${name} - ${detail}`) : l(`Running tool: ${name}`, `ツール実行中: ${name}`);
27
+ }
28
+ case "stderr": {
29
+ const detail = cleanProgressText(event.text);
30
+ return detail ? l(`Checking tool output: ${detail}`, `ツール出力を確認中: ${detail}`) : l("Checking tool output", "ツール出力を確認中");
31
+ }
32
+ case "message":
33
+ return l("Preparing response", "応答を整理しています");
34
+ default:
35
+ return null;
36
+ }
37
+ }
38
+ export function cleanProgressText(text) {
39
+ return text
40
+ .replace(/```/g, "")
41
+ .replace(/`/g, "'")
42
+ .replace(/@/g, "@\u200b")
43
+ .replace(/\s+/g, " ")
44
+ .trim()
45
+ .slice(0, 140);
46
+ }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};