@edihasaj/recall 0.5.7 → 0.6.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/dist/{chunk-K5FZ47NN.js → chunk-7XCLKPJ3.js} +6 -8
- package/dist/{chunk-K5FZ47NN.js.map → chunk-7XCLKPJ3.js.map} +1 -1
- package/dist/{chunk-A5UIRZU6.js → chunk-A6XEULA4.js} +3 -2
- package/dist/chunk-A6XEULA4.js.map +1 -0
- package/dist/{chunk-F56Y3SHS.js → chunk-E4HJDGCW.js} +7 -9
- package/dist/{chunk-F56Y3SHS.js.map → chunk-E4HJDGCW.js.map} +1 -1
- package/dist/{chunk-IILLSHLM.js → chunk-KAGIAOD7.js} +2583 -84
- package/dist/chunk-KAGIAOD7.js.map +1 -0
- package/dist/{chunk-FHKV6ELT.js → chunk-MJ4GGBTL.js} +11 -13
- package/dist/{chunk-FHKV6ELT.js.map → chunk-MJ4GGBTL.js.map} +1 -1
- package/dist/{chunk-LVQW6WHK.js → chunk-XUM7JEJU.js} +2 -2
- package/dist/{cleanup-TVOX2S2S.js → cleanup-MYSQ44EP.js} +4 -4
- package/dist/cli.js +206 -33
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +60 -49
- package/dist/daemon.js.map +1 -1
- package/dist/dispatcher-SUUX5AX6.js +16 -0
- package/dist/mcp.js +5 -5
- package/dist/{quality-Z7LPMMBC.js → quality-YTQKAEY6.js} +3 -3
- package/dist/{tasks-UOLSPXJQ.js → tasks-GSQUHD4F.js} +6 -3
- package/dist/{usage-CY3V72YN.js → usage-DU4TKVJH.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-A5UIRZU6.js.map +0 -1
- package/dist/chunk-GC5XMBG4.js +0 -551
- package/dist/chunk-GC5XMBG4.js.map +0 -1
- package/dist/chunk-IILLSHLM.js.map +0 -1
- package/dist/chunk-VEPXEHRZ.js +0 -1763
- package/dist/chunk-VEPXEHRZ.js.map +0 -1
- package/dist/dispatcher-UGMU6THT.js +0 -15
- /package/dist/{chunk-LVQW6WHK.js.map → chunk-XUM7JEJU.js.map} +0 -0
- /package/dist/{cleanup-TVOX2S2S.js.map → cleanup-MYSQ44EP.js.map} +0 -0
- /package/dist/{dispatcher-UGMU6THT.js.map → dispatcher-SUUX5AX6.js.map} +0 -0
- /package/dist/{quality-Z7LPMMBC.js.map → quality-YTQKAEY6.js.map} +0 -0
- /package/dist/{tasks-UOLSPXJQ.js.map → tasks-GSQUHD4F.js.map} +0 -0
- /package/dist/{usage-CY3V72YN.js.map → usage-DU4TKVJH.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/db/schema.ts"],"sourcesContent":["import { sqliteTable, text, integer, real, blob, index, uniqueIndex } from \"drizzle-orm/sqlite-core\";\n\nexport const memories = sqliteTable(\"memories\", {\n id: text(\"id\").primaryKey(),\n type: text(\"type\", {\n enum: [\"rule\", \"command\", \"gotcha\", \"decision\", \"review_pattern\"],\n }).notNull(),\n text: text(\"text\").notNull(),\n scope: text(\"scope\", {\n enum: [\"session\", \"path\", \"repo\", \"team\", \"global\"],\n }).notNull(),\n path_scope: text(\"path_scope\"),\n repo: text(\"repo\"),\n status: text(\"status\", {\n enum: [\"transient\", \"candidate\", \"active\", \"rejected\"],\n }).notNull(),\n confidence: real(\"confidence\").notNull().default(0),\n source: text(\"source\", {\n enum: [\n \"user_correction\",\n \"user_reported_review\",\n \"repo_scan\",\n \"config_parse\",\n ],\n }).notNull(),\n evidence: text(\"evidence\", { mode: \"json\" }).notNull().default(\"[]\"),\n capture_context: text(\"capture_context\", { mode: \"json\" }),\n supersedes: text(\"supersedes\"),\n dedupe_key: text(\"dedupe_key\"),\n created_at: text(\"created_at\").notNull(),\n updated_at: text(\"updated_at\").notNull(),\n last_validated_at: text(\"last_validated_at\"),\n last_injected_at: text(\"last_injected_at\"),\n injection_count: integer(\"injection_count\").notNull().default(0),\n override_count: integer(\"override_count\").notNull().default(0),\n repetition_count: integer(\"repetition_count\").notNull().default(0),\n // Phase 2: sync + embeddings\n team_id: text(\"team_id\"),\n sync_version: integer(\"sync_version\").notNull().default(0),\n // When false, the memory stays queryable via MCP but is excluded from the\n // auto-injected SessionStart context block. Used to suppress noisy\n // command-type memories that the agent re-derives from the repo anyway.\n auto_inject: integer(\"auto_inject\", { mode: \"boolean\" }).notNull().default(true),\n}, (table) => ([\n index(\"idx_memories_repo\").on(table.repo),\n index(\"idx_memories_status\").on(table.status),\n index(\"idx_memories_repo_status\").on(table.repo, table.status),\n index(\"idx_memories_team\").on(table.team_id),\n uniqueIndex(\"uq_memories_dedupe_key\").on(table.dedupe_key),\n]));\n\nexport const memoryEmbeddings = sqliteTable(\"memory_embeddings\", {\n memory_id: text(\"memory_id\")\n .primaryKey()\n .references(() => memories.id, { onDelete: \"cascade\" }),\n model: text(\"model\").notNull(),\n embedding_dimensions: integer(\"embedding_dimensions\").notNull(),\n index_dimensions: integer(\"index_dimensions\").notNull(),\n version: text(\"version\").notNull(),\n content_hash: text(\"content_hash\").notNull(),\n updated_at: text(\"updated_at\").notNull(),\n embedding: blob(\"embedding\", { mode: \"buffer\" }).notNull(),\n}, (table) => ([\n index(\"idx_memory_embeddings_model\").on(table.model),\n index(\"idx_memory_embeddings_updated\").on(table.updated_at),\n]));\n\nexport const historySnippets = sqliteTable(\"history_snippets\", {\n id: text(\"id\").primaryKey(),\n repo: text(\"repo\"),\n session_id: text(\"session_id\"),\n kind: text(\"kind\", {\n enum: [\"session_summary\", \"correction_summary\", \"decision_summary\", \"review_summary\", \"compile_summary\", \"repo_synthesis\"],\n }).notNull(),\n text: text(\"text\").notNull(),\n dedupe_key: text(\"dedupe_key\"),\n source_activity_ids: text(\"source_activity_ids\", { mode: \"json\" }).notNull().default(\"[]\"),\n created_at: text(\"created_at\").notNull(),\n updated_at: text(\"updated_at\").notNull(),\n}, (table) => ([\n index(\"idx_history_repo\").on(table.repo),\n index(\"idx_history_session\").on(table.session_id),\n index(\"idx_history_kind\").on(table.kind),\n index(\"idx_history_created\").on(table.created_at),\n uniqueIndex(\"uq_history_snippets_dedupe_key\").on(table.dedupe_key),\n]));\n\nexport const historySnippetEmbeddings = sqliteTable(\"history_snippet_embeddings\", {\n snippet_id: text(\"snippet_id\")\n .primaryKey()\n .references(() => historySnippets.id, { onDelete: \"cascade\" }),\n model: text(\"model\").notNull(),\n embedding_dimensions: integer(\"embedding_dimensions\").notNull(),\n index_dimensions: integer(\"index_dimensions\").notNull(),\n version: text(\"version\").notNull(),\n content_hash: text(\"content_hash\").notNull(),\n updated_at: text(\"updated_at\").notNull(),\n embedding: blob(\"embedding\", { mode: \"buffer\" }).notNull(),\n}, (table) => ([\n index(\"idx_history_embeddings_model\").on(table.model),\n index(\"idx_history_embeddings_updated\").on(table.updated_at),\n]));\n\nexport const historyInjections = sqliteTable(\"history_injections\", {\n id: text(\"id\").primaryKey(),\n snippet_id: text(\"snippet_id\")\n .notNull()\n .references(() => historySnippets.id, { onDelete: \"cascade\" }),\n session_id: text(\"session_id\").notNull(),\n repo: text(\"repo\"),\n injected_at: text(\"injected_at\").notNull(),\n}, (table) => ([\n index(\"idx_history_injections_snippet\").on(table.snippet_id),\n index(\"idx_history_injections_session\").on(table.session_id),\n index(\"idx_history_injections_repo\").on(table.repo),\n uniqueIndex(\"uq_history_injections_snippet_session\").on(table.snippet_id, table.session_id),\n]));\n\nexport const feedbackEvents = sqliteTable(\"feedback_events\", {\n id: text(\"id\").primaryKey(),\n memory_id: text(\"memory_id\")\n .notNull()\n .references(() => memories.id),\n session_id: text(\"session_id\").notNull(),\n injected: integer(\"injected\", { mode: \"boolean\" }).notNull(),\n outcome: text(\"outcome\", {\n enum: [\"followed\", \"overridden\", \"ignored\", \"contradicted\"],\n }).notNull(),\n timestamp: text(\"timestamp\").notNull(),\n}, (table) => ([\n index(\"idx_feedback_memory\").on(table.memory_id),\n index(\"idx_feedback_session\").on(table.session_id),\n]));\n\nexport const memoryInjections = sqliteTable(\"memory_injections\", {\n id: text(\"id\").primaryKey(),\n memory_id: text(\"memory_id\")\n .notNull()\n .references(() => memories.id, { onDelete: \"cascade\" }),\n session_id: text(\"session_id\").notNull(),\n repo: text(\"repo\"),\n injected_at: text(\"injected_at\").notNull(),\n outcome: text(\"outcome\", {\n enum: [\"followed\", \"overridden\", \"ignored\", \"contradicted\"],\n }),\n outcome_at: text(\"outcome_at\"),\n}, (table) => ([\n index(\"idx_memory_injections_memory\").on(table.memory_id),\n index(\"idx_memory_injections_session\").on(table.session_id),\n uniqueIndex(\"uq_memory_injections_memory_session\").on(table.memory_id, table.session_id),\n]));\n\n// Session/query activity log\nexport const activityEvents = sqliteTable(\"activity_events\", {\n id: text(\"id\").primaryKey(),\n session_id: text(\"session_id\"),\n repo: text(\"repo\"),\n path: text(\"path\"),\n // source is a free-form string tagged as \"<transport>[:<client>]\"\n // (e.g. \"mcp\", \"mcp:claude-code\", \"hook:codex\", \"cli\", \"daemon\").\n // The runtime regex in src/types.ts validates the shape.\n source: text(\"source\").notNull(),\n event_type: text(\"event_type\", {\n enum: [\n \"compile\",\n \"query\",\n \"scan\",\n \"correction\",\n \"review\",\n \"feedback\",\n \"signal\",\n \"session_start\",\n \"session_event\",\n \"session_end\",\n \"tool_call\",\n ],\n }).notNull(),\n memory_ids: text(\"memory_ids\", { mode: \"json\" }).notNull().default(\"[]\"),\n dedupe_key: text(\"dedupe_key\"),\n request: text(\"request\", { mode: \"json\" }).notNull().default(\"{}\"),\n result: text(\"result\", { mode: \"json\" }).notNull().default(\"{}\"),\n created_at: text(\"created_at\").notNull(),\n}, (table) => ([\n index(\"idx_activity_session\").on(table.session_id),\n index(\"idx_activity_repo\").on(table.repo),\n index(\"idx_activity_event_type\").on(table.event_type),\n index(\"idx_activity_created\").on(table.created_at),\n uniqueIndex(\"uq_activity_events_dedupe_key\").on(table.dedupe_key),\n]));\n\nexport const hookCalls = sqliteTable(\"hook_calls\", {\n id: text(\"id\").primaryKey(),\n event: text(\"event\", {\n enum: [\"session_started\", \"prompt_submitted\", \"tool_invoked\", \"session_ended\"],\n }).notNull(),\n agent: text(\"agent\").notNull(),\n dedupe_key: text(\"dedupe_key\"),\n duration_ms: integer(\"duration_ms\").notNull(),\n ok: integer(\"ok\", { mode: \"boolean\" }).notNull(),\n created_at: text(\"created_at\").notNull(),\n}, (table) => ([\n index(\"idx_hook_calls_event\").on(table.event),\n index(\"idx_hook_calls_agent\").on(table.agent),\n index(\"idx_hook_calls_created\").on(table.created_at),\n uniqueIndex(\"uq_hook_calls_dedupe_key\").on(table.dedupe_key),\n]));\n\n// Phase 2: sync state tracking\nexport const syncState = sqliteTable(\"sync_state\", {\n id: text(\"id\").primaryKey(), // \"local\" singleton\n remote_url: text(\"remote_url\"),\n team_id: text(\"team_id\"),\n last_push_at: text(\"last_push_at\"),\n last_pull_at: text(\"last_pull_at\"),\n last_push_version: integer(\"last_push_version\").notNull().default(0),\n last_pull_version: integer(\"last_pull_version\").notNull().default(0),\n});\n\n// Phase 2: evaluation sessions\nexport const evalSessions = sqliteTable(\"eval_sessions\", {\n id: text(\"id\").primaryKey(),\n repo: text(\"repo\").notNull(),\n started_at: text(\"started_at\").notNull(),\n ended_at: text(\"ended_at\"),\n memories_injected: integer(\"memories_injected\").notNull().default(0),\n memories_followed: integer(\"memories_followed\").notNull().default(0),\n memories_overridden: integer(\"memories_overridden\").notNull().default(0),\n user_corrections: integer(\"user_corrections\").notNull().default(0),\n test_passes: integer(\"test_passes\").notNull().default(0),\n test_failures: integer(\"test_failures\").notNull().default(0),\n}, (table) => ([\n index(\"idx_eval_repo\").on(table.repo),\n]));\n\n// Phase 3: policy rules\nexport const policyRules = sqliteTable(\"policy_rules\", {\n id: text(\"id\").primaryKey(),\n org_id: text(\"org_id\").notNull(),\n rule_type: text(\"rule_type\", {\n enum: [\n \"min_confidence\",\n \"require_approval\",\n \"allowed_sources\",\n \"blocked_scopes\",\n \"auto_approve_pattern\",\n \"max_active_per_repo\",\n \"require_evidence_count\",\n ],\n }).notNull(),\n config: text(\"config\", { mode: \"json\" }).notNull().default(\"{}\"),\n enabled: integer(\"enabled\", { mode: \"boolean\" }).notNull().default(true),\n created_at: text(\"created_at\").notNull(),\n updated_at: text(\"updated_at\").notNull(),\n}, (table) => ([\n index(\"idx_policy_org\").on(table.org_id),\n]));\n\n// Phase 3: approval queue\nexport const approvalRequests = sqliteTable(\"approval_requests\", {\n id: text(\"id\").primaryKey(),\n memory_id: text(\"memory_id\")\n .notNull()\n .references(() => memories.id),\n org_id: text(\"org_id\").notNull(),\n requested_by: text(\"requested_by\").notNull(),\n status: text(\"status\", {\n enum: [\"pending\", \"approved\", \"denied\"],\n }).notNull().default(\"pending\"),\n reviewed_by: text(\"reviewed_by\"),\n reason: text(\"reason\"),\n created_at: text(\"created_at\").notNull(),\n resolved_at: text(\"resolved_at\"),\n}, (table) => ([\n index(\"idx_approval_org\").on(table.org_id),\n index(\"idx_approval_status\").on(table.status),\n]));\n\n// Phase 3: contradictions\nexport const contradictions = sqliteTable(\"contradictions\", {\n id: text(\"id\").primaryKey(),\n memory_a_id: text(\"memory_a_id\")\n .notNull()\n .references(() => memories.id),\n memory_b_id: text(\"memory_b_id\")\n .notNull()\n .references(() => memories.id),\n contradiction_type: text(\"contradiction_type\", {\n enum: [\"direct_negation\", \"conflicting_rules\", \"scope_overlap\", \"superseded\"],\n }).notNull(),\n severity: text(\"severity\", { enum: [\"low\", \"medium\", \"high\"] }).notNull(),\n description: text(\"description\").notNull(),\n resolved: integer(\"resolved\", { mode: \"boolean\" }).notNull().default(false),\n resolution: text(\"resolution\"),\n detected_at: text(\"detected_at\").notNull(),\n resolved_at: text(\"resolved_at\"),\n}, (table) => ([\n index(\"idx_contradictions_resolved\").on(table.resolved),\n]));\n\n// Phase 3: audit trail\nexport const auditTrail = sqliteTable(\"audit_trail\", {\n id: text(\"id\").primaryKey(),\n memory_id: text(\"memory_id\").notNull(),\n action: text(\"action\", {\n enum: [\n \"created\", \"promoted\", \"demoted\", \"rejected\", \"confirmed\",\n \"reactivated\", \"edited\", \"pruned\", \"policy_applied\",\n \"approval_requested\", \"approval_resolved\",\n \"contradiction_detected\", \"contradiction_resolved\", \"rolled_back\",\n ],\n }).notNull(),\n actor: text(\"actor\").notNull(),\n before_snapshot: text(\"before_snapshot\"),\n after_snapshot: text(\"after_snapshot\"),\n reason: text(\"reason\"),\n timestamp: text(\"timestamp\").notNull(),\n}, (table) => ([\n index(\"idx_audit_memory\").on(table.memory_id),\n index(\"idx_audit_timestamp\").on(table.timestamp),\n]));\n\n// Tier-2 delegated maintenance tasks\nexport const memoryMaintenanceTasks = sqliteTable(\"memory_maintenance_tasks\", {\n id: text(\"id\").primaryKey(),\n kind: text(\"kind\", {\n enum: [\n \"summarize_history\",\n \"merge_duplicates\",\n \"refine_candidate\",\n \"summarize_session\",\n \"synthesize_repo\",\n \"verify_capture\",\n ],\n }).notNull(),\n status: text(\"status\", {\n enum: [\"pending\", \"claimed\", \"submitted\", \"completed\", \"abandoned\"],\n }).notNull(),\n priority: integer(\"priority\").notNull().default(0),\n repo: text(\"repo\"),\n target_key: text(\"target_key\").notNull(),\n payload: text(\"payload\", { mode: \"json\" }).notNull(),\n result: text(\"result\", { mode: \"json\" }),\n failure_reason: text(\"failure_reason\"),\n claimed_by: text(\"claimed_by\"),\n claimed_at: text(\"claimed_at\"),\n claim_expires_at: text(\"claim_expires_at\"),\n submitted_at: text(\"submitted_at\"),\n completed_at: text(\"completed_at\"),\n created_at: text(\"created_at\").notNull(),\n attempts: integer(\"attempts\").notNull().default(0),\n max_attempts: integer(\"max_attempts\").notNull().default(3),\n}, (table) => ([\n index(\"idx_mmt_status_priority\").on(table.status, table.priority, table.created_at),\n index(\"idx_mmt_repo_status\").on(table.repo, table.status),\n index(\"idx_mmt_claim_expires\").on(table.claim_expires_at),\n index(\"idx_mmt_kind_target\").on(table.kind, table.target_key),\n]));\n\n// Phase 2: implicit feedback signals\nexport const implicitSignals = sqliteTable(\"implicit_signals\", {\n id: text(\"id\").primaryKey(),\n memory_id: text(\"memory_id\")\n .notNull()\n .references(() => memories.id),\n session_id: text(\"session_id\").notNull(),\n signal_type: text(\"signal_type\", {\n enum: [\n \"test_pass\",\n \"test_fail\",\n \"file_unchanged\",\n \"file_rewritten\",\n \"task_accepted\",\n \"task_rejected\",\n ],\n }).notNull(),\n timestamp: text(\"timestamp\").notNull(),\n context: text(\"context\"),\n}, (table) => ([\n index(\"idx_implicit_memory\").on(table.memory_id),\n index(\"idx_implicit_session\").on(table.session_id),\n]));\n\n// LLM usage tracking for daemon-owned maintenance dispatcher\nexport const llmUsage = sqliteTable(\"llm_usage\", {\n id: text(\"id\").primaryKey(),\n provider: text(\"provider\").notNull(),\n model: text(\"model\").notNull(),\n task_kind: text(\"task_kind\").notNull(),\n task_id: text(\"task_id\"),\n repo: text(\"repo\"),\n prompt_tokens: integer(\"prompt_tokens\").notNull().default(0),\n completion_tokens: integer(\"completion_tokens\").notNull().default(0),\n total_tokens: integer(\"total_tokens\").notNull().default(0),\n cost_usd: real(\"cost_usd\"),\n duration_ms: integer(\"duration_ms\").notNull().default(0),\n ok: integer(\"ok\", { mode: \"boolean\" }).notNull().default(true),\n error: text(\"error\"),\n created_at: text(\"created_at\").notNull(),\n}, (table) => ([\n index(\"idx_llm_usage_created\").on(table.created_at),\n index(\"idx_llm_usage_provider_model\").on(table.provider, table.model),\n index(\"idx_llm_usage_task_kind\").on(table.task_kind),\n index(\"idx_llm_usage_repo\").on(table.repo),\n]));\n\n// Phase-4 quality snapshots — periodic sample of injection-outcome ratios\n// so we can compare followed-rate before/after cleanup tuning over weeks.\nexport const qualitySnapshots = sqliteTable(\"quality_snapshots\", {\n id: text(\"id\").primaryKey(),\n taken_at: text(\"taken_at\").notNull(),\n window_start: text(\"window_start\").notNull(),\n window_end: text(\"window_end\").notNull(),\n injections_total: integer(\"injections_total\").notNull(),\n injections_resolved: integer(\"injections_resolved\").notNull(),\n injections_followed: integer(\"injections_followed\").notNull(),\n injections_overridden: integer(\"injections_overridden\").notNull(),\n injections_contradicted: integer(\"injections_contradicted\").notNull(),\n injections_ignored: integer(\"injections_ignored\").notNull(),\n followed_rate_resolved: real(\"followed_rate_resolved\"),\n active_rule_count: integer(\"active_rule_count\").notNull(),\n active_command_count: integer(\"active_command_count\").notNull(),\n candidate_correction_count: integer(\"candidate_correction_count\").notNull(),\n history_injections_total: integer(\"history_injections_total\").notNull().default(0),\n history_snippets_injected: integer(\"history_snippets_injected\").notNull().default(0),\n notes: text(\"notes\"),\n}, (table) => ([\n index(\"idx_quality_snapshots_taken\").on(table.taken_at),\n]));\n\n// Phase-1 deterministic cleanup log (revertable, no LLM required)\nexport const maintenanceCleanupLog = sqliteTable(\"maintenance_cleanup_log\", {\n id: text(\"id\").primaryKey(),\n run_id: text(\"run_id\").notNull(),\n action: text(\"action\", {\n enum: [\n \"dedupe_exact_merge\",\n \"reject_fragment_candidate\",\n \"promote_repeat_correction\",\n \"suppress_unproductive_command\",\n \"globalize_cross_repo\",\n ],\n }).notNull(),\n memory_id: text(\"memory_id\").notNull(),\n related_memory_id: text(\"related_memory_id\"),\n before_snapshot: text(\"before_snapshot\", { mode: \"json\" }),\n after_snapshot: text(\"after_snapshot\", { mode: \"json\" }),\n details: text(\"details\", { mode: \"json\" }).notNull().default(\"{}\"),\n reverted: integer(\"reverted\", { mode: \"boolean\" }).notNull().default(false),\n reverted_at: text(\"reverted_at\"),\n created_at: text(\"created_at\").notNull(),\n}, (table) => ([\n index(\"idx_cleanup_log_run\").on(table.run_id),\n index(\"idx_cleanup_log_memory\").on(table.memory_id),\n index(\"idx_cleanup_log_action\").on(table.action),\n index(\"idx_cleanup_log_created\").on(table.created_at),\n]));\n"],"mappings":";;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAS,aAAa,MAAM,SAAS,MAAM,MAAM,OAAO,mBAAmB;AAEpE,IAAM,WAAW,YAAY,YAAY;AAAA,EAC9C,IAAI,KAAK,IAAI,EAAE,WAAW;AAAA,EAC1B,MAAM,KAAK,QAAQ;AAAA,IACjB,MAAM,CAAC,QAAQ,WAAW,UAAU,YAAY,gBAAgB;AAAA,EAClE,CAAC,EAAE,QAAQ;AAAA,EACX,MAAM,KAAK,MAAM,EAAE,QAAQ;AAAA,EAC3B,OAAO,KAAK,SAAS;AAAA,IACnB,MAAM,CAAC,WAAW,QAAQ,QAAQ,QAAQ,QAAQ;AAAA,EACpD,CAAC,EAAE,QAAQ;AAAA,EACX,YAAY,KAAK,YAAY;AAAA,EAC7B,MAAM,KAAK,MAAM;AAAA,EACjB,QAAQ,KAAK,UAAU;AAAA,IACrB,MAAM,CAAC,aAAa,aAAa,UAAU,UAAU;AAAA,EACvD,CAAC,EAAE,QAAQ;AAAA,EACX,YAAY,KAAK,YAAY,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAAA,EAClD,QAAQ,KAAK,UAAU;AAAA,IACrB,MAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC,EAAE,QAAQ;AAAA,EACX,UAAU,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EACnE,iBAAiB,KAAK,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAAA,EACzD,YAAY,KAAK,YAAY;AAAA,EAC7B,YAAY,KAAK,YAAY;AAAA,EAC7B,YAAY,KAAK,YAAY,EAAE,QAAQ;AAAA,EACvC,YAAY,KAAK,YAAY,EAAE,QAAQ;AAAA,EACvC,mBAAmB,KAAK,mBAAmB;AAAA,EAC3C,kBAAkB,KAAK,kBAAkB;AAAA,EACzC,iBAAiB,QAAQ,iBAAiB,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAAA,EAC/D,gBAAgB,QAAQ,gBAAgB,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAAA,EAC7D,kBAAkB,QAAQ,kBAAkB,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAAA;AAAA,EAEjE,SAAS,KAAK,SAAS;AAAA,EACvB,cAAc,QAAQ,cAAc,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAAA;AAAA;AAAA;AAAA,EAIzD,aAAa,QAAQ,eAAe,EAAE,MAAM,UAAU,CAAC,EAAE,QAAQ,EAAE,QAAQ,IAAI;AACjF,GAAG,CAAC,UAAW;AAAA,EACb,MAAM,mBAAmB,EAAE,GAAG,MAAM,IAAI;AAAA,EACxC,MAAM,qBAAqB,EAAE,GAAG,MAAM,MAAM;AAAA,EAC5C,MAAM,0BAA0B,EAAE,GAAG,MAAM,MAAM,MAAM,MAAM;AAAA,EAC7D,MAAM,mBAAmB,EAAE,GAAG,MAAM,OAAO;AAAA,EAC3C,YAAY,wBAAwB,EAAE,GAAG,MAAM,UAAU;AAC3D,CAAE;AAEK,IAAM,mBAAmB,YAAY,qBAAqB;AAAA,EAC/D,WAAW,KAAK,WAAW,EACxB,WAAW,EACX,WAAW,MAAM,SAAS,IAAI,EAAE,UAAU,UAAU,CAAC;AAAA,EACxD,OAAO,KAAK,OAAO,EAAE,QAAQ;AAAA,EAC7B,sBAAsB,QAAQ,sBAAsB,EAAE,QAAQ;AAAA,EAC9D,kBAAkB,QAAQ,kBAAkB,EAAE,QAAQ;AAAA,EACtD,SAAS,KAAK,SAAS,EAAE,QAAQ;AAAA,EACjC,cAAc,KAAK,cAAc,EAAE,QAAQ;AAAA,EAC3C,YAAY,KAAK,YAAY,EAAE,QAAQ;AAAA,EACvC,WAAW,KAAK,aAAa,EAAE,MAAM,SAAS,CAAC,EAAE,QAAQ;AAC3D,GAAG,CAAC,UAAW;AAAA,EACb,MAAM,6BAA6B,EAAE,GAAG,MAAM,KAAK;AAAA,EACnD,MAAM,+BAA+B,EAAE,GAAG,MAAM,UAAU;AAC5D,CAAE;AAEK,IAAM,kBAAkB,YAAY,oBAAoB;AAAA,EAC7D,IAAI,KAAK,IAAI,EAAE,WAAW;AAAA,EAC1B,MAAM,KAAK,MAAM;AAAA,EACjB,YAAY,KAAK,YAAY;AAAA,EAC7B,MAAM,KAAK,QAAQ;AAAA,IACjB,MAAM,CAAC,mBAAmB,sBAAsB,oBAAoB,kBAAkB,mBAAmB,gBAAgB;AAAA,EAC3H,CAAC,EAAE,QAAQ;AAAA,EACX,MAAM,KAAK,MAAM,EAAE,QAAQ;AAAA,EAC3B,YAAY,KAAK,YAAY;AAAA,EAC7B,qBAAqB,KAAK,uBAAuB,EAAE,MAAM,OAAO,CAAC,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EACzF,YAAY,KAAK,YAAY,EAAE,QAAQ;AAAA,EACvC,YAAY,KAAK,YAAY,EAAE,QAAQ;AACzC,GAAG,CAAC,UAAW;AAAA,EACb,MAAM,kBAAkB,EAAE,GAAG,MAAM,IAAI;AAAA,EACvC,MAAM,qBAAqB,EAAE,GAAG,MAAM,UAAU;AAAA,EAChD,MAAM,kBAAkB,EAAE,GAAG,MAAM,IAAI;AAAA,EACvC,MAAM,qBAAqB,EAAE,GAAG,MAAM,UAAU;AAAA,EAChD,YAAY,gCAAgC,EAAE,GAAG,MAAM,UAAU;AACnE,CAAE;AAEK,IAAM,2BAA2B,YAAY,8BAA8B;AAAA,EAChF,YAAY,KAAK,YAAY,EAC1B,WAAW,EACX,WAAW,MAAM,gBAAgB,IAAI,EAAE,UAAU,UAAU,CAAC;AAAA,EAC/D,OAAO,KAAK,OAAO,EAAE,QAAQ;AAAA,EAC7B,sBAAsB,QAAQ,sBAAsB,EAAE,QAAQ;AAAA,EAC9D,kBAAkB,QAAQ,kBAAkB,EAAE,QAAQ;AAAA,EACtD,SAAS,KAAK,SAAS,EAAE,QAAQ;AAAA,EACjC,cAAc,KAAK,cAAc,EAAE,QAAQ;AAAA,EAC3C,YAAY,KAAK,YAAY,EAAE,QAAQ;AAAA,EACvC,WAAW,KAAK,aAAa,EAAE,MAAM,SAAS,CAAC,EAAE,QAAQ;AAC3D,GAAG,CAAC,UAAW;AAAA,EACb,MAAM,8BAA8B,EAAE,GAAG,MAAM,KAAK;AAAA,EACpD,MAAM,gCAAgC,EAAE,GAAG,MAAM,UAAU;AAC7D,CAAE;AAEK,IAAM,oBAAoB,YAAY,sBAAsB;AAAA,EACjE,IAAI,KAAK,IAAI,EAAE,WAAW;AAAA,EAC1B,YAAY,KAAK,YAAY,EAC1B,QAAQ,EACR,WAAW,MAAM,gBAAgB,IAAI,EAAE,UAAU,UAAU,CAAC;AAAA,EAC/D,YAAY,KAAK,YAAY,EAAE,QAAQ;AAAA,EACvC,MAAM,KAAK,MAAM;AAAA,EACjB,aAAa,KAAK,aAAa,EAAE,QAAQ;AAC3C,GAAG,CAAC,UAAW;AAAA,EACb,MAAM,gCAAgC,EAAE,GAAG,MAAM,UAAU;AAAA,EAC3D,MAAM,gCAAgC,EAAE,GAAG,MAAM,UAAU;AAAA,EAC3D,MAAM,6BAA6B,EAAE,GAAG,MAAM,IAAI;AAAA,EAClD,YAAY,uCAAuC,EAAE,GAAG,MAAM,YAAY,MAAM,UAAU;AAC5F,CAAE;AAEK,IAAM,iBAAiB,YAAY,mBAAmB;AAAA,EAC3D,IAAI,KAAK,IAAI,EAAE,WAAW;AAAA,EAC1B,WAAW,KAAK,WAAW,EACxB,QAAQ,EACR,WAAW,MAAM,SAAS,EAAE;AAAA,EAC/B,YAAY,KAAK,YAAY,EAAE,QAAQ;AAAA,EACvC,UAAU,QAAQ,YAAY,EAAE,MAAM,UAAU,CAAC,EAAE,QAAQ;AAAA,EAC3D,SAAS,KAAK,WAAW;AAAA,IACvB,MAAM,CAAC,YAAY,cAAc,WAAW,cAAc;AAAA,EAC5D,CAAC,EAAE,QAAQ;AAAA,EACX,WAAW,KAAK,WAAW,EAAE,QAAQ;AACvC,GAAG,CAAC,UAAW;AAAA,EACb,MAAM,qBAAqB,EAAE,GAAG,MAAM,SAAS;AAAA,EAC/C,MAAM,sBAAsB,EAAE,GAAG,MAAM,UAAU;AACnD,CAAE;AAEK,IAAM,mBAAmB,YAAY,qBAAqB;AAAA,EAC/D,IAAI,KAAK,IAAI,EAAE,WAAW;AAAA,EAC1B,WAAW,KAAK,WAAW,EACxB,QAAQ,EACR,WAAW,MAAM,SAAS,IAAI,EAAE,UAAU,UAAU,CAAC;AAAA,EACxD,YAAY,KAAK,YAAY,EAAE,QAAQ;AAAA,EACvC,MAAM,KAAK,MAAM;AAAA,EACjB,aAAa,KAAK,aAAa,EAAE,QAAQ;AAAA,EACzC,SAAS,KAAK,WAAW;AAAA,IACvB,MAAM,CAAC,YAAY,cAAc,WAAW,cAAc;AAAA,EAC5D,CAAC;AAAA,EACD,YAAY,KAAK,YAAY;AAC/B,GAAG,CAAC,UAAW;AAAA,EACb,MAAM,8BAA8B,EAAE,GAAG,MAAM,SAAS;AAAA,EACxD,MAAM,+BAA+B,EAAE,GAAG,MAAM,UAAU;AAAA,EAC1D,YAAY,qCAAqC,EAAE,GAAG,MAAM,WAAW,MAAM,UAAU;AACzF,CAAE;AAGK,IAAM,iBAAiB,YAAY,mBAAmB;AAAA,EAC3D,IAAI,KAAK,IAAI,EAAE,WAAW;AAAA,EAC1B,YAAY,KAAK,YAAY;AAAA,EAC7B,MAAM,KAAK,MAAM;AAAA,EACjB,MAAM,KAAK,MAAM;AAAA;AAAA;AAAA;AAAA,EAIjB,QAAQ,KAAK,QAAQ,EAAE,QAAQ;AAAA,EAC/B,YAAY,KAAK,cAAc;AAAA,IAC7B,MAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC,EAAE,QAAQ;AAAA,EACX,YAAY,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EACvE,YAAY,KAAK,YAAY;AAAA,EAC7B,SAAS,KAAK,WAAW,EAAE,MAAM,OAAO,CAAC,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EACjE,QAAQ,KAAK,UAAU,EAAE,MAAM,OAAO,CAAC,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EAC/D,YAAY,KAAK,YAAY,EAAE,QAAQ;AACzC,GAAG,CAAC,UAAW;AAAA,EACb,MAAM,sBAAsB,EAAE,GAAG,MAAM,UAAU;AAAA,EACjD,MAAM,mBAAmB,EAAE,GAAG,MAAM,IAAI;AAAA,EACxC,MAAM,yBAAyB,EAAE,GAAG,MAAM,UAAU;AAAA,EACpD,MAAM,sBAAsB,EAAE,GAAG,MAAM,UAAU;AAAA,EACjD,YAAY,+BAA+B,EAAE,GAAG,MAAM,UAAU;AAClE,CAAE;AAEK,IAAM,YAAY,YAAY,cAAc;AAAA,EACjD,IAAI,KAAK,IAAI,EAAE,WAAW;AAAA,EAC1B,OAAO,KAAK,SAAS;AAAA,IACnB,MAAM,CAAC,mBAAmB,oBAAoB,gBAAgB,eAAe;AAAA,EAC/E,CAAC,EAAE,QAAQ;AAAA,EACX,OAAO,KAAK,OAAO,EAAE,QAAQ;AAAA,EAC7B,YAAY,KAAK,YAAY;AAAA,EAC7B,aAAa,QAAQ,aAAa,EAAE,QAAQ;AAAA,EAC5C,IAAI,QAAQ,MAAM,EAAE,MAAM,UAAU,CAAC,EAAE,QAAQ;AAAA,EAC/C,YAAY,KAAK,YAAY,EAAE,QAAQ;AACzC,GAAG,CAAC,UAAW;AAAA,EACb,MAAM,sBAAsB,EAAE,GAAG,MAAM,KAAK;AAAA,EAC5C,MAAM,sBAAsB,EAAE,GAAG,MAAM,KAAK;AAAA,EAC5C,MAAM,wBAAwB,EAAE,GAAG,MAAM,UAAU;AAAA,EACnD,YAAY,0BAA0B,EAAE,GAAG,MAAM,UAAU;AAC7D,CAAE;AAGK,IAAM,YAAY,YAAY,cAAc;AAAA,EACjD,IAAI,KAAK,IAAI,EAAE,WAAW;AAAA;AAAA,EAC1B,YAAY,KAAK,YAAY;AAAA,EAC7B,SAAS,KAAK,SAAS;AAAA,EACvB,cAAc,KAAK,cAAc;AAAA,EACjC,cAAc,KAAK,cAAc;AAAA,EACjC,mBAAmB,QAAQ,mBAAmB,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAAA,EACnE,mBAAmB,QAAQ,mBAAmB,EAAE,QAAQ,EAAE,QAAQ,CAAC;AACrE,CAAC;AAGM,IAAM,eAAe,YAAY,iBAAiB;AAAA,EACvD,IAAI,KAAK,IAAI,EAAE,WAAW;AAAA,EAC1B,MAAM,KAAK,MAAM,EAAE,QAAQ;AAAA,EAC3B,YAAY,KAAK,YAAY,EAAE,QAAQ;AAAA,EACvC,UAAU,KAAK,UAAU;AAAA,EACzB,mBAAmB,QAAQ,mBAAmB,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAAA,EACnE,mBAAmB,QAAQ,mBAAmB,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAAA,EACnE,qBAAqB,QAAQ,qBAAqB,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAAA,EACvE,kBAAkB,QAAQ,kBAAkB,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAAA,EACjE,aAAa,QAAQ,aAAa,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAAA,EACvD,eAAe,QAAQ,eAAe,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAC7D,GAAG,CAAC,UAAW;AAAA,EACb,MAAM,eAAe,EAAE,GAAG,MAAM,IAAI;AACtC,CAAE;AAGK,IAAM,cAAc,YAAY,gBAAgB;AAAA,EACrD,IAAI,KAAK,IAAI,EAAE,WAAW;AAAA,EAC1B,QAAQ,KAAK,QAAQ,EAAE,QAAQ;AAAA,EAC/B,WAAW,KAAK,aAAa;AAAA,IAC3B,MAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC,EAAE,QAAQ;AAAA,EACX,QAAQ,KAAK,UAAU,EAAE,MAAM,OAAO,CAAC,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EAC/D,SAAS,QAAQ,WAAW,EAAE,MAAM,UAAU,CAAC,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EACvE,YAAY,KAAK,YAAY,EAAE,QAAQ;AAAA,EACvC,YAAY,KAAK,YAAY,EAAE,QAAQ;AACzC,GAAG,CAAC,UAAW;AAAA,EACb,MAAM,gBAAgB,EAAE,GAAG,MAAM,MAAM;AACzC,CAAE;AAGK,IAAM,mBAAmB,YAAY,qBAAqB;AAAA,EAC/D,IAAI,KAAK,IAAI,EAAE,WAAW;AAAA,EAC1B,WAAW,KAAK,WAAW,EACxB,QAAQ,EACR,WAAW,MAAM,SAAS,EAAE;AAAA,EAC/B,QAAQ,KAAK,QAAQ,EAAE,QAAQ;AAAA,EAC/B,cAAc,KAAK,cAAc,EAAE,QAAQ;AAAA,EAC3C,QAAQ,KAAK,UAAU;AAAA,IACrB,MAAM,CAAC,WAAW,YAAY,QAAQ;AAAA,EACxC,CAAC,EAAE,QAAQ,EAAE,QAAQ,SAAS;AAAA,EAC9B,aAAa,KAAK,aAAa;AAAA,EAC/B,QAAQ,KAAK,QAAQ;AAAA,EACrB,YAAY,KAAK,YAAY,EAAE,QAAQ;AAAA,EACvC,aAAa,KAAK,aAAa;AACjC,GAAG,CAAC,UAAW;AAAA,EACb,MAAM,kBAAkB,EAAE,GAAG,MAAM,MAAM;AAAA,EACzC,MAAM,qBAAqB,EAAE,GAAG,MAAM,MAAM;AAC9C,CAAE;AAGK,IAAM,iBAAiB,YAAY,kBAAkB;AAAA,EAC1D,IAAI,KAAK,IAAI,EAAE,WAAW;AAAA,EAC1B,aAAa,KAAK,aAAa,EAC5B,QAAQ,EACR,WAAW,MAAM,SAAS,EAAE;AAAA,EAC/B,aAAa,KAAK,aAAa,EAC5B,QAAQ,EACR,WAAW,MAAM,SAAS,EAAE;AAAA,EAC/B,oBAAoB,KAAK,sBAAsB;AAAA,IAC7C,MAAM,CAAC,mBAAmB,qBAAqB,iBAAiB,YAAY;AAAA,EAC9E,CAAC,EAAE,QAAQ;AAAA,EACX,UAAU,KAAK,YAAY,EAAE,MAAM,CAAC,OAAO,UAAU,MAAM,EAAE,CAAC,EAAE,QAAQ;AAAA,EACxE,aAAa,KAAK,aAAa,EAAE,QAAQ;AAAA,EACzC,UAAU,QAAQ,YAAY,EAAE,MAAM,UAAU,CAAC,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EAC1E,YAAY,KAAK,YAAY;AAAA,EAC7B,aAAa,KAAK,aAAa,EAAE,QAAQ;AAAA,EACzC,aAAa,KAAK,aAAa;AACjC,GAAG,CAAC,UAAW;AAAA,EACb,MAAM,6BAA6B,EAAE,GAAG,MAAM,QAAQ;AACxD,CAAE;AAGK,IAAM,aAAa,YAAY,eAAe;AAAA,EACnD,IAAI,KAAK,IAAI,EAAE,WAAW;AAAA,EAC1B,WAAW,KAAK,WAAW,EAAE,QAAQ;AAAA,EACrC,QAAQ,KAAK,UAAU;AAAA,IACrB,MAAM;AAAA,MACJ;AAAA,MAAW;AAAA,MAAY;AAAA,MAAW;AAAA,MAAY;AAAA,MAC9C;AAAA,MAAe;AAAA,MAAU;AAAA,MAAU;AAAA,MACnC;AAAA,MAAsB;AAAA,MACtB;AAAA,MAA0B;AAAA,MAA0B;AAAA,IACtD;AAAA,EACF,CAAC,EAAE,QAAQ;AAAA,EACX,OAAO,KAAK,OAAO,EAAE,QAAQ;AAAA,EAC7B,iBAAiB,KAAK,iBAAiB;AAAA,EACvC,gBAAgB,KAAK,gBAAgB;AAAA,EACrC,QAAQ,KAAK,QAAQ;AAAA,EACrB,WAAW,KAAK,WAAW,EAAE,QAAQ;AACvC,GAAG,CAAC,UAAW;AAAA,EACb,MAAM,kBAAkB,EAAE,GAAG,MAAM,SAAS;AAAA,EAC5C,MAAM,qBAAqB,EAAE,GAAG,MAAM,SAAS;AACjD,CAAE;AAGK,IAAM,yBAAyB,YAAY,4BAA4B;AAAA,EAC5E,IAAI,KAAK,IAAI,EAAE,WAAW;AAAA,EAC1B,MAAM,KAAK,QAAQ;AAAA,IACjB,MAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC,EAAE,QAAQ;AAAA,EACX,QAAQ,KAAK,UAAU;AAAA,IACrB,MAAM,CAAC,WAAW,WAAW,aAAa,aAAa,WAAW;AAAA,EACpE,CAAC,EAAE,QAAQ;AAAA,EACX,UAAU,QAAQ,UAAU,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAAA,EACjD,MAAM,KAAK,MAAM;AAAA,EACjB,YAAY,KAAK,YAAY,EAAE,QAAQ;AAAA,EACvC,SAAS,KAAK,WAAW,EAAE,MAAM,OAAO,CAAC,EAAE,QAAQ;AAAA,EACnD,QAAQ,KAAK,UAAU,EAAE,MAAM,OAAO,CAAC;AAAA,EACvC,gBAAgB,KAAK,gBAAgB;AAAA,EACrC,YAAY,KAAK,YAAY;AAAA,EAC7B,YAAY,KAAK,YAAY;AAAA,EAC7B,kBAAkB,KAAK,kBAAkB;AAAA,EACzC,cAAc,KAAK,cAAc;AAAA,EACjC,cAAc,KAAK,cAAc;AAAA,EACjC,YAAY,KAAK,YAAY,EAAE,QAAQ;AAAA,EACvC,UAAU,QAAQ,UAAU,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAAA,EACjD,cAAc,QAAQ,cAAc,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAC3D,GAAG,CAAC,UAAW;AAAA,EACb,MAAM,yBAAyB,EAAE,GAAG,MAAM,QAAQ,MAAM,UAAU,MAAM,UAAU;AAAA,EAClF,MAAM,qBAAqB,EAAE,GAAG,MAAM,MAAM,MAAM,MAAM;AAAA,EACxD,MAAM,uBAAuB,EAAE,GAAG,MAAM,gBAAgB;AAAA,EACxD,MAAM,qBAAqB,EAAE,GAAG,MAAM,MAAM,MAAM,UAAU;AAC9D,CAAE;AAGK,IAAM,kBAAkB,YAAY,oBAAoB;AAAA,EAC7D,IAAI,KAAK,IAAI,EAAE,WAAW;AAAA,EAC1B,WAAW,KAAK,WAAW,EACxB,QAAQ,EACR,WAAW,MAAM,SAAS,EAAE;AAAA,EAC/B,YAAY,KAAK,YAAY,EAAE,QAAQ;AAAA,EACvC,aAAa,KAAK,eAAe;AAAA,IAC/B,MAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC,EAAE,QAAQ;AAAA,EACX,WAAW,KAAK,WAAW,EAAE,QAAQ;AAAA,EACrC,SAAS,KAAK,SAAS;AACzB,GAAG,CAAC,UAAW;AAAA,EACb,MAAM,qBAAqB,EAAE,GAAG,MAAM,SAAS;AAAA,EAC/C,MAAM,sBAAsB,EAAE,GAAG,MAAM,UAAU;AACnD,CAAE;AAGK,IAAM,WAAW,YAAY,aAAa;AAAA,EAC/C,IAAI,KAAK,IAAI,EAAE,WAAW;AAAA,EAC1B,UAAU,KAAK,UAAU,EAAE,QAAQ;AAAA,EACnC,OAAO,KAAK,OAAO,EAAE,QAAQ;AAAA,EAC7B,WAAW,KAAK,WAAW,EAAE,QAAQ;AAAA,EACrC,SAAS,KAAK,SAAS;AAAA,EACvB,MAAM,KAAK,MAAM;AAAA,EACjB,eAAe,QAAQ,eAAe,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAAA,EAC3D,mBAAmB,QAAQ,mBAAmB,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAAA,EACnE,cAAc,QAAQ,cAAc,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAAA,EACzD,UAAU,KAAK,UAAU;AAAA,EACzB,aAAa,QAAQ,aAAa,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAAA,EACvD,IAAI,QAAQ,MAAM,EAAE,MAAM,UAAU,CAAC,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EAC7D,OAAO,KAAK,OAAO;AAAA,EACnB,YAAY,KAAK,YAAY,EAAE,QAAQ;AACzC,GAAG,CAAC,UAAW;AAAA,EACb,MAAM,uBAAuB,EAAE,GAAG,MAAM,UAAU;AAAA,EAClD,MAAM,8BAA8B,EAAE,GAAG,MAAM,UAAU,MAAM,KAAK;AAAA,EACpE,MAAM,yBAAyB,EAAE,GAAG,MAAM,SAAS;AAAA,EACnD,MAAM,oBAAoB,EAAE,GAAG,MAAM,IAAI;AAC3C,CAAE;AAIK,IAAM,mBAAmB,YAAY,qBAAqB;AAAA,EAC/D,IAAI,KAAK,IAAI,EAAE,WAAW;AAAA,EAC1B,UAAU,KAAK,UAAU,EAAE,QAAQ;AAAA,EACnC,cAAc,KAAK,cAAc,EAAE,QAAQ;AAAA,EAC3C,YAAY,KAAK,YAAY,EAAE,QAAQ;AAAA,EACvC,kBAAkB,QAAQ,kBAAkB,EAAE,QAAQ;AAAA,EACtD,qBAAqB,QAAQ,qBAAqB,EAAE,QAAQ;AAAA,EAC5D,qBAAqB,QAAQ,qBAAqB,EAAE,QAAQ;AAAA,EAC5D,uBAAuB,QAAQ,uBAAuB,EAAE,QAAQ;AAAA,EAChE,yBAAyB,QAAQ,yBAAyB,EAAE,QAAQ;AAAA,EACpE,oBAAoB,QAAQ,oBAAoB,EAAE,QAAQ;AAAA,EAC1D,wBAAwB,KAAK,wBAAwB;AAAA,EACrD,mBAAmB,QAAQ,mBAAmB,EAAE,QAAQ;AAAA,EACxD,sBAAsB,QAAQ,sBAAsB,EAAE,QAAQ;AAAA,EAC9D,4BAA4B,QAAQ,4BAA4B,EAAE,QAAQ;AAAA,EAC1E,0BAA0B,QAAQ,0BAA0B,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAAA,EACjF,2BAA2B,QAAQ,2BAA2B,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAAA,EACnF,OAAO,KAAK,OAAO;AACrB,GAAG,CAAC,UAAW;AAAA,EACb,MAAM,6BAA6B,EAAE,GAAG,MAAM,QAAQ;AACxD,CAAE;AAGK,IAAM,wBAAwB,YAAY,2BAA2B;AAAA,EAC1E,IAAI,KAAK,IAAI,EAAE,WAAW;AAAA,EAC1B,QAAQ,KAAK,QAAQ,EAAE,QAAQ;AAAA,EAC/B,QAAQ,KAAK,UAAU;AAAA,IACrB,MAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC,EAAE,QAAQ;AAAA,EACX,WAAW,KAAK,WAAW,EAAE,QAAQ;AAAA,EACrC,mBAAmB,KAAK,mBAAmB;AAAA,EAC3C,iBAAiB,KAAK,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAAA,EACzD,gBAAgB,KAAK,kBAAkB,EAAE,MAAM,OAAO,CAAC;AAAA,EACvD,SAAS,KAAK,WAAW,EAAE,MAAM,OAAO,CAAC,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EACjE,UAAU,QAAQ,YAAY,EAAE,MAAM,UAAU,CAAC,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EAC1E,aAAa,KAAK,aAAa;AAAA,EAC/B,YAAY,KAAK,YAAY,EAAE,QAAQ;AACzC,GAAG,CAAC,UAAW;AAAA,EACb,MAAM,qBAAqB,EAAE,GAAG,MAAM,MAAM;AAAA,EAC5C,MAAM,wBAAwB,EAAE,GAAG,MAAM,SAAS;AAAA,EAClD,MAAM,wBAAwB,EAAE,GAAG,MAAM,MAAM;AAAA,EAC/C,MAAM,yBAAyB,EAAE,GAAG,MAAM,UAAU;AACtD,CAAE;","names":[]}
|
package/dist/chunk-GC5XMBG4.js
DELETED
|
@@ -1,551 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
TaskClaimConflictError,
|
|
3
|
-
claimTask,
|
|
4
|
-
listTasks,
|
|
5
|
-
releaseTask,
|
|
6
|
-
submitTask
|
|
7
|
-
} from "./chunk-IILLSHLM.js";
|
|
8
|
-
import {
|
|
9
|
-
llmUsage
|
|
10
|
-
} from "./chunk-A5UIRZU6.js";
|
|
11
|
-
import {
|
|
12
|
-
getProviderConfig,
|
|
13
|
-
hasProviderConfigured,
|
|
14
|
-
init_keychain
|
|
15
|
-
} from "./chunk-DNFKAHS6.js";
|
|
16
|
-
|
|
17
|
-
// src/llm/client.ts
|
|
18
|
-
init_keychain();
|
|
19
|
-
import { randomUUID } from "crypto";
|
|
20
|
-
var LlmCredentialError = class extends Error {
|
|
21
|
-
};
|
|
22
|
-
var LlmRequestError = class extends Error {
|
|
23
|
-
};
|
|
24
|
-
var DEFAULT_MODELS = {
|
|
25
|
-
openai: "gpt-4o-mini",
|
|
26
|
-
anthropic: "claude-haiku-4-5-20251001",
|
|
27
|
-
// For Azure the "model" is the deployment name, set by the user when they
|
|
28
|
-
// provisioned the deployment. We leave it empty so we always fall through
|
|
29
|
-
// to the deployment from AzureOpenAiConfig.
|
|
30
|
-
"azure-openai": ""
|
|
31
|
-
};
|
|
32
|
-
var COST_PER_M_TOKENS = {
|
|
33
|
-
"gpt-4o-mini": { input: 0.15, output: 0.6 },
|
|
34
|
-
"gpt-4o": { input: 2.5, output: 10 },
|
|
35
|
-
"claude-haiku-4-5-20251001": { input: 1, output: 5 },
|
|
36
|
-
"claude-sonnet-4-6": { input: 3, output: 15 },
|
|
37
|
-
"claude-opus-4-7": { input: 15, output: 75 }
|
|
38
|
-
};
|
|
39
|
-
async function callLlm(db, input) {
|
|
40
|
-
const provider = input.provider;
|
|
41
|
-
const config = getProviderConfig(provider);
|
|
42
|
-
if (!config) {
|
|
43
|
-
throw new LlmCredentialError(missingCredentialMessage(provider));
|
|
44
|
-
}
|
|
45
|
-
const model = input.model ?? (provider === "azure-openai" ? config.deployment : DEFAULT_MODELS[provider]);
|
|
46
|
-
const started = Date.now();
|
|
47
|
-
let result = null;
|
|
48
|
-
let errorMessage;
|
|
49
|
-
try {
|
|
50
|
-
if (provider === "openai") {
|
|
51
|
-
result = await callOpenAi(config.key, model, input);
|
|
52
|
-
} else if (provider === "anthropic") {
|
|
53
|
-
result = await callAnthropic(config.key, model, input);
|
|
54
|
-
} else {
|
|
55
|
-
result = await callAzureOpenAi(config, model, input);
|
|
56
|
-
}
|
|
57
|
-
return result;
|
|
58
|
-
} catch (err) {
|
|
59
|
-
errorMessage = err instanceof Error ? err.message : String(err);
|
|
60
|
-
throw err;
|
|
61
|
-
} finally {
|
|
62
|
-
try {
|
|
63
|
-
await recordUsage(db, {
|
|
64
|
-
provider,
|
|
65
|
-
model,
|
|
66
|
-
task_kind: input.task_kind,
|
|
67
|
-
task_id: input.task_id ?? null,
|
|
68
|
-
repo: input.repo ?? null,
|
|
69
|
-
usage: result?.usage ?? { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0, cost_usd: null },
|
|
70
|
-
duration_ms: Date.now() - started,
|
|
71
|
-
ok: Boolean(result),
|
|
72
|
-
error: errorMessage
|
|
73
|
-
});
|
|
74
|
-
} catch {
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
async function callOpenAi(apiKey, model, input) {
|
|
79
|
-
const started = Date.now();
|
|
80
|
-
const response = await fetch("https://api.openai.com/v1/chat/completions", {
|
|
81
|
-
method: "POST",
|
|
82
|
-
headers: {
|
|
83
|
-
"Content-Type": "application/json",
|
|
84
|
-
Authorization: `Bearer ${apiKey}`
|
|
85
|
-
},
|
|
86
|
-
body: JSON.stringify({
|
|
87
|
-
model,
|
|
88
|
-
messages: [
|
|
89
|
-
{ role: "system", content: input.system },
|
|
90
|
-
{ role: "user", content: input.user }
|
|
91
|
-
],
|
|
92
|
-
max_completion_tokens: input.max_output_tokens ?? 2048,
|
|
93
|
-
temperature: input.temperature ?? 0
|
|
94
|
-
})
|
|
95
|
-
});
|
|
96
|
-
if (!response.ok) {
|
|
97
|
-
const body = await safeText(response);
|
|
98
|
-
throw new LlmRequestError(`OpenAI ${response.status}: ${body.slice(0, 400)}`);
|
|
99
|
-
}
|
|
100
|
-
const payload = await response.json();
|
|
101
|
-
const text = payload.choices?.[0]?.message?.content?.trim() ?? "";
|
|
102
|
-
const prompt_tokens = payload.usage?.prompt_tokens ?? 0;
|
|
103
|
-
const completion_tokens = payload.usage?.completion_tokens ?? 0;
|
|
104
|
-
const total_tokens = payload.usage?.total_tokens ?? prompt_tokens + completion_tokens;
|
|
105
|
-
return {
|
|
106
|
-
text,
|
|
107
|
-
model,
|
|
108
|
-
provider: "openai",
|
|
109
|
-
duration_ms: Date.now() - started,
|
|
110
|
-
usage: {
|
|
111
|
-
prompt_tokens,
|
|
112
|
-
completion_tokens,
|
|
113
|
-
total_tokens,
|
|
114
|
-
cost_usd: computeCost(model, prompt_tokens, completion_tokens)
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
async function callAzureOpenAi(config, deployment, input) {
|
|
119
|
-
const started = Date.now();
|
|
120
|
-
const url = `${config.endpoint}/openai/deployments/${encodeURIComponent(deployment)}/chat/completions?api-version=${encodeURIComponent(config.api_version)}`;
|
|
121
|
-
const response = await fetch(url, {
|
|
122
|
-
method: "POST",
|
|
123
|
-
headers: {
|
|
124
|
-
"Content-Type": "application/json",
|
|
125
|
-
"api-key": config.key
|
|
126
|
-
},
|
|
127
|
-
body: JSON.stringify({
|
|
128
|
-
messages: [
|
|
129
|
-
{ role: "system", content: input.system },
|
|
130
|
-
{ role: "user", content: input.user }
|
|
131
|
-
],
|
|
132
|
-
max_completion_tokens: input.max_output_tokens ?? 2048,
|
|
133
|
-
temperature: input.temperature ?? 0
|
|
134
|
-
})
|
|
135
|
-
});
|
|
136
|
-
if (!response.ok) {
|
|
137
|
-
const body = await safeText(response);
|
|
138
|
-
throw new LlmRequestError(`Azure OpenAI ${response.status}: ${body.slice(0, 400)}`);
|
|
139
|
-
}
|
|
140
|
-
const payload = await response.json();
|
|
141
|
-
const text = payload.choices?.[0]?.message?.content?.trim() ?? "";
|
|
142
|
-
const prompt_tokens = payload.usage?.prompt_tokens ?? 0;
|
|
143
|
-
const completion_tokens = payload.usage?.completion_tokens ?? 0;
|
|
144
|
-
const total_tokens = payload.usage?.total_tokens ?? prompt_tokens + completion_tokens;
|
|
145
|
-
return {
|
|
146
|
-
text,
|
|
147
|
-
model: deployment,
|
|
148
|
-
provider: "azure-openai",
|
|
149
|
-
duration_ms: Date.now() - started,
|
|
150
|
-
usage: {
|
|
151
|
-
prompt_tokens,
|
|
152
|
-
completion_tokens,
|
|
153
|
-
total_tokens,
|
|
154
|
-
cost_usd: computeCost(deployment, prompt_tokens, completion_tokens)
|
|
155
|
-
}
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
async function callAnthropic(apiKey, model, input) {
|
|
159
|
-
const started = Date.now();
|
|
160
|
-
const response = await fetch("https://api.anthropic.com/v1/messages", {
|
|
161
|
-
method: "POST",
|
|
162
|
-
headers: {
|
|
163
|
-
"Content-Type": "application/json",
|
|
164
|
-
"x-api-key": apiKey,
|
|
165
|
-
"anthropic-version": "2023-06-01"
|
|
166
|
-
},
|
|
167
|
-
body: JSON.stringify({
|
|
168
|
-
model,
|
|
169
|
-
system: input.system,
|
|
170
|
-
messages: [{ role: "user", content: input.user }],
|
|
171
|
-
max_tokens: input.max_output_tokens ?? 2048,
|
|
172
|
-
temperature: input.temperature ?? 0
|
|
173
|
-
})
|
|
174
|
-
});
|
|
175
|
-
if (!response.ok) {
|
|
176
|
-
const body = await safeText(response);
|
|
177
|
-
throw new LlmRequestError(`Anthropic ${response.status}: ${body.slice(0, 400)}`);
|
|
178
|
-
}
|
|
179
|
-
const payload = await response.json();
|
|
180
|
-
const text = (payload.content ?? []).filter((block) => block.type === "text" && typeof block.text === "string").map((block) => block.text).join("").trim();
|
|
181
|
-
const prompt_tokens = payload.usage?.input_tokens ?? 0;
|
|
182
|
-
const completion_tokens = payload.usage?.output_tokens ?? 0;
|
|
183
|
-
return {
|
|
184
|
-
text,
|
|
185
|
-
model,
|
|
186
|
-
provider: "anthropic",
|
|
187
|
-
duration_ms: Date.now() - started,
|
|
188
|
-
usage: {
|
|
189
|
-
prompt_tokens,
|
|
190
|
-
completion_tokens,
|
|
191
|
-
total_tokens: prompt_tokens + completion_tokens,
|
|
192
|
-
cost_usd: computeCost(model, prompt_tokens, completion_tokens)
|
|
193
|
-
}
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
function computeCost(model, inputTokens, outputTokens) {
|
|
197
|
-
const rates = COST_PER_M_TOKENS[model];
|
|
198
|
-
if (!rates) return null;
|
|
199
|
-
return inputTokens / 1e6 * rates.input + outputTokens / 1e6 * rates.output;
|
|
200
|
-
}
|
|
201
|
-
async function recordUsage(db, row) {
|
|
202
|
-
await db.insert(llmUsage).values({
|
|
203
|
-
id: randomUUID(),
|
|
204
|
-
provider: row.provider,
|
|
205
|
-
model: row.model,
|
|
206
|
-
task_kind: row.task_kind,
|
|
207
|
-
task_id: row.task_id,
|
|
208
|
-
repo: row.repo,
|
|
209
|
-
prompt_tokens: row.usage.prompt_tokens,
|
|
210
|
-
completion_tokens: row.usage.completion_tokens,
|
|
211
|
-
total_tokens: row.usage.total_tokens,
|
|
212
|
-
cost_usd: row.usage.cost_usd ?? null,
|
|
213
|
-
duration_ms: row.duration_ms,
|
|
214
|
-
ok: row.ok,
|
|
215
|
-
error: row.error ?? null,
|
|
216
|
-
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
function missingCredentialMessage(provider) {
|
|
220
|
-
switch (provider) {
|
|
221
|
-
case "openai":
|
|
222
|
-
return `No API key for provider "openai". Set it via \`recall maintenance credentials set openai <key>\` or the OPENAI_API_KEY env var.`;
|
|
223
|
-
case "anthropic":
|
|
224
|
-
return `No API key for provider "anthropic". Set it via \`recall maintenance credentials set anthropic <key>\` or the ANTHROPIC_API_KEY env var.`;
|
|
225
|
-
case "azure-openai":
|
|
226
|
-
return `Azure OpenAI is not fully configured. Run \`recall maintenance credentials set azure --endpoint <url> --deployment <name> --api-version <version> <key>\` or set AZURE_OPENAI_{ENDPOINT,DEPLOYMENT,API_VERSION,API_KEY}.`;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
async function safeText(response) {
|
|
230
|
-
try {
|
|
231
|
-
return await response.text();
|
|
232
|
-
} catch {
|
|
233
|
-
return "";
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// src/maintenance/dispatcher.ts
|
|
238
|
-
init_keychain();
|
|
239
|
-
var DISPATCH_AGENT = "recall:dispatcher";
|
|
240
|
-
var DEFAULT_LEASE_SECONDS = 120;
|
|
241
|
-
async function dispatchPendingTasks(db, options = {}) {
|
|
242
|
-
const provider = resolveProvider(options.provider);
|
|
243
|
-
const report = {
|
|
244
|
-
provider,
|
|
245
|
-
model: null,
|
|
246
|
-
dry_run: Boolean(options.dryRun),
|
|
247
|
-
attempted: 0,
|
|
248
|
-
applied: 0,
|
|
249
|
-
rejected: 0,
|
|
250
|
-
released: 0,
|
|
251
|
-
outcomes: []
|
|
252
|
-
};
|
|
253
|
-
if (!provider) return report;
|
|
254
|
-
const pending = listTasks(db, {
|
|
255
|
-
status: "pending",
|
|
256
|
-
kinds: options.kinds,
|
|
257
|
-
repo: options.repo,
|
|
258
|
-
limit: options.maxTasks ?? 5
|
|
259
|
-
});
|
|
260
|
-
for (const task of pending) {
|
|
261
|
-
if (options.dryRun) {
|
|
262
|
-
report.outcomes.push({
|
|
263
|
-
task_id: task.id,
|
|
264
|
-
kind: task.kind,
|
|
265
|
-
repo: task.repo,
|
|
266
|
-
status: "skipped",
|
|
267
|
-
reason: "dry-run"
|
|
268
|
-
});
|
|
269
|
-
continue;
|
|
270
|
-
}
|
|
271
|
-
report.attempted += 1;
|
|
272
|
-
const outcome = await runSingle(db, task, provider, options.model);
|
|
273
|
-
report.outcomes.push(outcome);
|
|
274
|
-
if (outcome.status === "applied") report.applied += 1;
|
|
275
|
-
else if (outcome.status === "rejected") report.rejected += 1;
|
|
276
|
-
else if (outcome.status === "released") report.released += 1;
|
|
277
|
-
if (outcome.prompt_tokens != null && !report.model) {
|
|
278
|
-
const last = report.outcomes[report.outcomes.length - 1];
|
|
279
|
-
report.model = last.task_id ? options.model ?? null : null;
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
return report;
|
|
283
|
-
}
|
|
284
|
-
async function runSingle(db, task, provider, model) {
|
|
285
|
-
let claimed;
|
|
286
|
-
try {
|
|
287
|
-
const claim = claimTask(db, task.id, DISPATCH_AGENT, DEFAULT_LEASE_SECONDS);
|
|
288
|
-
claimed = claim.task;
|
|
289
|
-
} catch (err) {
|
|
290
|
-
if (err instanceof TaskClaimConflictError) {
|
|
291
|
-
return {
|
|
292
|
-
task_id: task.id,
|
|
293
|
-
kind: task.kind,
|
|
294
|
-
repo: task.repo,
|
|
295
|
-
status: "skipped",
|
|
296
|
-
reason: err.reason
|
|
297
|
-
};
|
|
298
|
-
}
|
|
299
|
-
throw err;
|
|
300
|
-
}
|
|
301
|
-
const prompt = buildPrompt(claimed);
|
|
302
|
-
if (!prompt) {
|
|
303
|
-
releaseTask(db, claimed.id, DISPATCH_AGENT);
|
|
304
|
-
return {
|
|
305
|
-
task_id: claimed.id,
|
|
306
|
-
kind: claimed.kind,
|
|
307
|
-
repo: claimed.repo,
|
|
308
|
-
status: "released",
|
|
309
|
-
reason: "no prompt builder"
|
|
310
|
-
};
|
|
311
|
-
}
|
|
312
|
-
try {
|
|
313
|
-
const llmResult = await callLlm(db, {
|
|
314
|
-
provider,
|
|
315
|
-
model,
|
|
316
|
-
system: prompt.system,
|
|
317
|
-
user: prompt.user,
|
|
318
|
-
max_output_tokens: prompt.max_output_tokens,
|
|
319
|
-
task_kind: claimed.kind,
|
|
320
|
-
task_id: claimed.id,
|
|
321
|
-
repo: claimed.repo
|
|
322
|
-
});
|
|
323
|
-
const parsed = parseJson(llmResult.text);
|
|
324
|
-
if (!parsed) {
|
|
325
|
-
releaseTask(db, claimed.id, DISPATCH_AGENT);
|
|
326
|
-
return {
|
|
327
|
-
task_id: claimed.id,
|
|
328
|
-
kind: claimed.kind,
|
|
329
|
-
repo: claimed.repo,
|
|
330
|
-
status: "released",
|
|
331
|
-
reason: "llm did not return valid JSON",
|
|
332
|
-
prompt_tokens: llmResult.usage.prompt_tokens,
|
|
333
|
-
completion_tokens: llmResult.usage.completion_tokens,
|
|
334
|
-
cost_usd: llmResult.usage.cost_usd,
|
|
335
|
-
duration_ms: llmResult.duration_ms
|
|
336
|
-
};
|
|
337
|
-
}
|
|
338
|
-
const submit = submitTask(db, claimed.id, DISPATCH_AGENT, parsed);
|
|
339
|
-
if (submit.status === "applied") {
|
|
340
|
-
return {
|
|
341
|
-
task_id: claimed.id,
|
|
342
|
-
kind: claimed.kind,
|
|
343
|
-
repo: claimed.repo,
|
|
344
|
-
status: "applied",
|
|
345
|
-
target_id: submit.target_id,
|
|
346
|
-
changed_fields: submit.changed_fields,
|
|
347
|
-
prompt_tokens: llmResult.usage.prompt_tokens,
|
|
348
|
-
completion_tokens: llmResult.usage.completion_tokens,
|
|
349
|
-
cost_usd: llmResult.usage.cost_usd,
|
|
350
|
-
duration_ms: llmResult.duration_ms
|
|
351
|
-
};
|
|
352
|
-
}
|
|
353
|
-
return {
|
|
354
|
-
task_id: claimed.id,
|
|
355
|
-
kind: claimed.kind,
|
|
356
|
-
repo: claimed.repo,
|
|
357
|
-
status: "rejected",
|
|
358
|
-
reason: submit.reason,
|
|
359
|
-
prompt_tokens: llmResult.usage.prompt_tokens,
|
|
360
|
-
completion_tokens: llmResult.usage.completion_tokens,
|
|
361
|
-
cost_usd: llmResult.usage.cost_usd,
|
|
362
|
-
duration_ms: llmResult.duration_ms
|
|
363
|
-
};
|
|
364
|
-
} catch (err) {
|
|
365
|
-
releaseTask(db, claimed.id, DISPATCH_AGENT);
|
|
366
|
-
const reason = err instanceof LlmCredentialError ? err.message : err instanceof Error ? err.message : String(err);
|
|
367
|
-
return {
|
|
368
|
-
task_id: claimed.id,
|
|
369
|
-
kind: claimed.kind,
|
|
370
|
-
repo: claimed.repo,
|
|
371
|
-
status: "released",
|
|
372
|
-
reason
|
|
373
|
-
};
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
function resolveProvider(preferred) {
|
|
377
|
-
const candidates = preferred ? [preferred] : ["anthropic", "azure-openai", "openai"];
|
|
378
|
-
for (const provider of candidates) {
|
|
379
|
-
if (hasProviderConfigured(provider)) return provider;
|
|
380
|
-
}
|
|
381
|
-
return null;
|
|
382
|
-
}
|
|
383
|
-
function parseJson(text) {
|
|
384
|
-
const trimmed = text.trim();
|
|
385
|
-
if (trimmed.length === 0) return null;
|
|
386
|
-
const stripped = trimmed.replace(/^```(?:json)?\s*/i, "").replace(/\s*```$/i, "").trim();
|
|
387
|
-
try {
|
|
388
|
-
return JSON.parse(stripped);
|
|
389
|
-
} catch {
|
|
390
|
-
const first = stripped.indexOf("{");
|
|
391
|
-
const last = stripped.lastIndexOf("}");
|
|
392
|
-
if (first >= 0 && last > first) {
|
|
393
|
-
try {
|
|
394
|
-
return JSON.parse(stripped.slice(first, last + 1));
|
|
395
|
-
} catch {
|
|
396
|
-
return null;
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
return null;
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
function buildPrompt(task) {
|
|
403
|
-
switch (task.kind) {
|
|
404
|
-
case "verify_capture":
|
|
405
|
-
return buildVerifyCapturePrompt(task);
|
|
406
|
-
case "refine_candidate":
|
|
407
|
-
return buildRefineCandidatePrompt(task);
|
|
408
|
-
case "summarize_history":
|
|
409
|
-
return buildSummarizeHistoryPrompt(task);
|
|
410
|
-
case "merge_duplicates":
|
|
411
|
-
return buildMergeDuplicatesPrompt(task);
|
|
412
|
-
case "summarize_session":
|
|
413
|
-
return buildSummarizeSessionPrompt(task);
|
|
414
|
-
case "synthesize_repo":
|
|
415
|
-
return buildSynthesizeRepoPrompt(task);
|
|
416
|
-
default:
|
|
417
|
-
return null;
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
function buildVerifyCapturePrompt(task) {
|
|
421
|
-
const payload = task.payload;
|
|
422
|
-
const system = [
|
|
423
|
-
"You verify a captured candidate rule for a coding-agent memory store.",
|
|
424
|
-
"Decide if it is a durable rule worth saving, salvageable but needs rewriting, or noise/narration.",
|
|
425
|
-
"Be strict \u2014 false positives produce wrong agent behavior. When unsure, prefer reject over save.",
|
|
426
|
-
"Reject voice transcripts, descriptive clauses about what the user does ('things I never use'), one-shot task chatter, and any text whose intent is unclear without surrounding context.",
|
|
427
|
-
"When rewriting, output a single canonical sentence in imperative mood. Keep scope as tight as the evidence supports.",
|
|
428
|
-
'Flag is_destructive_risky=true when the rule pairs a destructive verb (remove/delete/drop/wipe) with high-risk targets (settings/config/files/secrets/branches), OR when it is shaped as a literal-trigger rule ("when user says X, do Y") \u2014 both require explicit user confirm regardless.',
|
|
429
|
-
JSON_ONLY
|
|
430
|
-
].join(" ");
|
|
431
|
-
const user = [
|
|
432
|
-
`Candidate text: ${JSON.stringify(payload.text ?? "")}`,
|
|
433
|
-
`Inferred scope: ${payload.inferred_scope ?? "repo"}`,
|
|
434
|
-
`Inferred path_scope: ${JSON.stringify(payload.inferred_path_scope ?? null)}`,
|
|
435
|
-
`Repo: ${JSON.stringify(payload.repo ?? null)}`,
|
|
436
|
-
`Capture context: ${JSON.stringify(payload.capture_context ?? null)}`,
|
|
437
|
-
"",
|
|
438
|
-
'Return JSON: {"verdict": "save"|"rewrite"|"reject", "cleaned_text"?: string, "scope"?: "session"|"path"|"repo"|"team"|"global", "path_scope"?: string|null, "is_destructive_risky"?: boolean, "reason"?: string}'
|
|
439
|
-
].join("\n");
|
|
440
|
-
return { system, user };
|
|
441
|
-
}
|
|
442
|
-
var JSON_ONLY = "Respond with a single JSON object matching the required schema, no prose, no markdown fences.";
|
|
443
|
-
function buildRefineCandidatePrompt(task) {
|
|
444
|
-
const payload = task.payload;
|
|
445
|
-
const system = [
|
|
446
|
-
"You refine candidate memories in a coding-agent memory store.",
|
|
447
|
-
"Keep only durable rules/commands/gotchas. Clamp scope tighter when the evidence is path-specific.",
|
|
448
|
-
JSON_ONLY
|
|
449
|
-
].join(" ");
|
|
450
|
-
const user = [
|
|
451
|
-
`Current memory text: ${JSON.stringify(payload.text ?? "")}`,
|
|
452
|
-
`Current scope: ${payload.current_scope ?? "repo"}`,
|
|
453
|
-
`Current path_scope: ${JSON.stringify(payload.current_path_scope ?? null)}`,
|
|
454
|
-
`Repo: ${JSON.stringify(payload.repo ?? null)}`,
|
|
455
|
-
`Repetition count: ${payload.repetition_count ?? 0}`,
|
|
456
|
-
"",
|
|
457
|
-
'Return JSON: {"refined_text": string, "scope": "session"|"path"|"repo"|"team"|"global", "path_scope": string|null, "rationale": string, "verdict"?: "rewrite"|"reject"}'
|
|
458
|
-
].join("\n");
|
|
459
|
-
return { system, user };
|
|
460
|
-
}
|
|
461
|
-
function buildSummarizeHistoryPrompt(task) {
|
|
462
|
-
const payload = task.payload;
|
|
463
|
-
const system = [
|
|
464
|
-
"You compress activity snippets in a coding-agent memory store.",
|
|
465
|
-
"Keep the essential facts; drop filler. <= 3 short sentences.",
|
|
466
|
-
JSON_ONLY
|
|
467
|
-
].join(" ");
|
|
468
|
-
const user = [
|
|
469
|
-
`Kind: ${payload.kind ?? "unknown"}`,
|
|
470
|
-
`Repo: ${JSON.stringify(payload.repo ?? null)}`,
|
|
471
|
-
`Current text: ${JSON.stringify(payload.current_text ?? "")}`,
|
|
472
|
-
"",
|
|
473
|
-
'Return JSON: {"summary_text": string, "tags": [string, ...]}'
|
|
474
|
-
].join("\n");
|
|
475
|
-
return { system, user };
|
|
476
|
-
}
|
|
477
|
-
function buildMergeDuplicatesPrompt(task) {
|
|
478
|
-
const payload = task.payload;
|
|
479
|
-
const system = [
|
|
480
|
-
"You pick the best memory among near-duplicates in a coding-agent memory store.",
|
|
481
|
-
"Choose the single winning id. You may also rewrite the winner's text for clarity, and tighten its scope if evidence supports it.",
|
|
482
|
-
JSON_ONLY
|
|
483
|
-
].join(" ");
|
|
484
|
-
const user = [
|
|
485
|
-
`Repo: ${JSON.stringify(payload.repo ?? null)}`,
|
|
486
|
-
`Cluster:`,
|
|
487
|
-
JSON.stringify(payload.cluster ?? [], null, 2),
|
|
488
|
-
"",
|
|
489
|
-
'Return JSON: {"winner_id": uuid, "winner_text"?: string, "winner_scope"?: "session"|"path"|"repo"|"team", "winner_path_scope"?: string|null, "rationale"?: string}'
|
|
490
|
-
].join("\n");
|
|
491
|
-
return { system, user };
|
|
492
|
-
}
|
|
493
|
-
function buildSummarizeSessionPrompt(task) {
|
|
494
|
-
const payload = task.payload;
|
|
495
|
-
const system = [
|
|
496
|
-
"You condense a coding-agent session into a brief durable summary.",
|
|
497
|
-
"<= 5 short bullet points; no filler.",
|
|
498
|
-
JSON_ONLY
|
|
499
|
-
].join(" ");
|
|
500
|
-
const user = [
|
|
501
|
-
`Session: ${payload.session_id ?? "unknown"}`,
|
|
502
|
-
`Repo: ${JSON.stringify(payload.repo ?? null)}`,
|
|
503
|
-
`Events: ${JSON.stringify(payload.events ?? [], null, 2).slice(0, 12e3)}`,
|
|
504
|
-
"",
|
|
505
|
-
'Return JSON: {"summary_text": string}'
|
|
506
|
-
].join("\n");
|
|
507
|
-
return { system, user };
|
|
508
|
-
}
|
|
509
|
-
function buildSynthesizeRepoPrompt(task) {
|
|
510
|
-
const payload = task.payload;
|
|
511
|
-
const system = [
|
|
512
|
-
"You synthesize a concise repo-level summary from the stable memory set.",
|
|
513
|
-
"Focus on commands, rules, gotchas, and decisions that repeat across sessions.",
|
|
514
|
-
JSON_ONLY
|
|
515
|
-
].join(" ");
|
|
516
|
-
const user = [
|
|
517
|
-
`Repo: ${JSON.stringify(payload.repo ?? null)}`,
|
|
518
|
-
`Memory set: ${JSON.stringify(payload.memories ?? [], null, 2).slice(0, 12e3)}`,
|
|
519
|
-
"",
|
|
520
|
-
'Return JSON: {"summary_text": string}'
|
|
521
|
-
].join("\n");
|
|
522
|
-
return { system, user };
|
|
523
|
-
}
|
|
524
|
-
function formatDispatchReport(report) {
|
|
525
|
-
const lines = [
|
|
526
|
-
"# Recall Maintenance Dispatch",
|
|
527
|
-
`Provider: ${report.provider ?? "(none \u2014 no API key)"}`,
|
|
528
|
-
`Dry run: ${report.dry_run ? "yes" : "no"}`,
|
|
529
|
-
`Attempted: ${report.attempted}`,
|
|
530
|
-
`Applied: ${report.applied}`,
|
|
531
|
-
`Rejected: ${report.rejected}`,
|
|
532
|
-
`Released: ${report.released}`
|
|
533
|
-
];
|
|
534
|
-
if (report.outcomes.length > 0) {
|
|
535
|
-
lines.push("", "## Outcomes");
|
|
536
|
-
for (const o of report.outcomes) {
|
|
537
|
-
const cost = o.cost_usd != null ? ` $${o.cost_usd.toFixed(4)}` : "";
|
|
538
|
-
const tokens = o.prompt_tokens != null ? ` tokens=${(o.prompt_tokens ?? 0) + (o.completion_tokens ?? 0)}` : "";
|
|
539
|
-
const reason = o.reason ? ` \u2014 ${o.reason}` : "";
|
|
540
|
-
lines.push(` ${o.task_id.slice(0, 8)} ${o.kind.padEnd(20)} ${o.status.padEnd(10)}${tokens}${cost}${reason}`);
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
return lines.join("\n");
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
export {
|
|
547
|
-
dispatchPendingTasks,
|
|
548
|
-
buildPrompt,
|
|
549
|
-
formatDispatchReport
|
|
550
|
-
};
|
|
551
|
-
//# sourceMappingURL=chunk-GC5XMBG4.js.map
|