@ace-sdk/core
v3.2.3
Published
ACE Core - Shared library for ACE pattern learning (HTTP client, caching, config, types)
Downloads
1,730
Maintainers
Readme
@ace-sdk/core
Core ACE client library for pattern learning — ACE 1.5.
Installation
npm install @ace-sdk/coreWhat's new in ACE 1.5
ACE 1.5 is a clean-break MAJOR release. There is no 1.0 backward-compat shim in the write path.
- Native reward model. Tier counters (
n_hot/warm/cold_pos/neg),cumulative_v15_reward,isAtRiskflag, andeffectiveness.recommendationare now the primary quality signal.helpful/harmfulbecome deprecated derived read-only getters (cold weight = 0.1). - MatchFactors on search results. Each
/patterns/searchresult carriesmatch_factorswithsemantic_score,ucb_score(when LinUCB warm),bandit_rank, and a per-pattern integerretrieval_log_id. - F-080 feedback loop.
searchPatterns()returns a top-levelretrieval_idUUID. Submit it back onstoreExecutionTrace()withapplied_log_ids(theretrieval_log_idintegers of patterns the agent applied) to close the bandit feedback loop. - SQLite graph cache + automatic populate path.
GraphCacheServicereplaces the old 5-min KV cache with a 7-day TTL graph cache — the data source for ace-desktop Brain-Graphs. Schema is byte-identical across all language SDKs. EverysearchPatterns()call automatically upserts results, throttles a liveGET /patterns/graphedge refresh (default: once per hour), and attachesresult.expanded— id-only 2-hop neighbor stubs.better-sqlite3is optional; the cache degrades gracefully to RAM-only when absent. NewAceClientOptions:cacheDir,fetchFn,graphEdgesThrottleMs. session_idon search. Passsession_idinsearchPatterns()to stampretrieval_log_v15.session_idat retrieval time, linking the search to the later trace/learn for F-080 session-scoped credit.task_intent+ exploration controls. Passtask_intent(refactor | routine | explore | spec_strict) andexploration_enabled/exploration_rateon search to influence bandit routing.
Features
- ACE Client: HTTP client for ACE Server API with native ACE 1.5 reward model;
AceClientOptions.cacheDir,fetchFn, andgraphEdgesThrottleMsfor test isolation - Graph Cache: SQLite with 7-day TTL, 2-hop neighbors, per-(org,project) isolation; automatic populate path on
searchPatterns()(pattern upsert + throttled edge refresh +expandedneighbors) - Expanded Neighbors:
searchPatterns()returnsresult.expanded— token-efficient 2-hop graph neighbors from the local cache, deduped against primary results. Opt out withexpandNeighbors: false - Optional deps:
better-sqlite3andlinguist-jsare optional — cache degrades gracefully to RAM-only when absent (no crash) - F-080 Loop:
retrieval_id+applied_log_idson traces close the bandit feedback cycle - Configuration: Flexible config resolution (CLI args → env vars → files)
- TypeScript Types: Full definitions for patterns, reward model, MatchFactors, traces
Quick Start (ACE 1.5)
import {
AceClient,
createContext,
decodePattern,
decodeMatchFactors,
getRecommendation,
} from '@ace-sdk/core';
import type { ExecutionTrace, MatchFactors } from '@ace-sdk/core';
// Create context
const context = await createContext({
org: process.env.ACE_ORG_ID,
project: process.env.ACE_PROJECT_ID,
});
const client = new AceClient(context);
// --- Search with ACE 1.5 controls ---
const results = await client.searchPatterns({
query: 'authentication JWT',
task_intent: 'refactor',
exploration_enabled: true,
exploration_rate: 0.2,
session_id: 'cc-session-abc', // optional — stamps retrieval row for F-080 session credit
});
// Capture F-080 identifiers
const retrieval_id = results.retrieval_id;
const applied_log_ids: number[] = [];
for (const raw of results.similar_patterns) {
const pattern = decodePattern(raw);
const mf: MatchFactors | null = decodeMatchFactors(raw.match_factors);
// ACE 1.5 reward model — PRIMARY
console.log(`${pattern.content}`);
console.log(` reward: ${pattern.cumulative_v15_reward ?? 'legacy'}`);
console.log(` at-risk: ${pattern.isAtRisk}`);
console.log(` recommendation: ${getRecommendation(pattern.effectiveness)}`);
// Deprecated derived score (read-only, cold=0.1)
// console.log(` helpful (deprecated): ${pattern.helpful}`);
if (mf) {
console.log(` semantic_score: ${mf.semantic_score}`);
if (mf.retrieval_log_id != null) {
applied_log_ids.push(mf.retrieval_log_id); // collect for F-080
}
}
}
// --- Submit trace with F-080 fields ---
const trace: ExecutionTrace = {
task: 'Implemented JWT rotation',
trajectory: [
{ step: 1, action: 'Write', args: { file: 'src/auth/middleware.ts' }, result: 'ok' }
],
result: { success: true, output: 'Token rotation middleware added' },
playbook_used: [],
timestamp: new Date().toISOString(),
retrieval_id, // from searchPatterns() — closes F-080 loop
applied_log_ids, // integers from match_factors.retrieval_log_id
};
await client.storeExecutionTrace(trace);GraphCacheService (ACE 1.5)
import { GraphCacheService } from '@ace-sdk/core';
import type { GraphRefreshConfig } from '@ace-sdk/core';
const cache = new GraphCacheService({
orgId: 'my-org',
projectId: 'my-project',
// cacheDir defaults to ~/.ace-cache
});
// Seed edges from the server (GET /patterns/graph?min_weight=5)
// Best-effort — never throws; leaves cache intact on any error
const cfg: GraphRefreshConfig = {
token: process.env.ACE_API_TOKEN!,
serverUrl: 'https://ace-api.code-engine.app',
};
const { edgesUpserted, truncated } = await cache.refreshFromServer(cfg);
// edgesUpserted ≈ 11,500 for a warm project; truncated=true means server capped at 50k
// 2-hop neighbors, weight >= 5 — populated from server edges after refreshFromServer()
const neighbors = cache.neighbors('pattern-id', 2, 5);
// Retrieve a pattern (7-day TTL, lazy-prune on miss)
const row = cache.getPattern('pattern-id');
// Prune all expired rows
cache.prune();
cache.close();Cache file: ~/.ace-cache/<org>__<project>.db (double underscore). Schema is the ace-desktop Brain-Graph data source — byte-identical across all language SDKs.
Org Usage Analytics
getOrgUsageHourly
getOrgUsageHourly(orgId: string, window: UsageWindow, projectId?: string): Promise<UsageHistoryResponse>Fetch hourly/daily usage buckets for a specific org. Valid UsageWindow values: '1h', '6h', '12h', '1d', '7d', '14d', '30d'. Calls GET /api/v1/usage/history.
const resp = await client.getOrgUsageHourly('org_abc', '1d');
const first = resp.buckets[0];
console.log(`${first.period}: ${first.api_calls_total}`);Migrating from ACE 1.0
| 1.0 pattern | ACE 1.5 replacement |
|---|---|
| pattern.helpful / pattern.harmful as primary signal | Use pattern.cumulative_v15_reward, pattern.isAtRisk, getRecommendation(pattern.effectiveness) |
| No match_factors on search results | decodeMatchFactors(raw.match_factors) — null = cold/shadow, never throws |
| No retrieval_id / applied_log_ids on traces | Capture results.retrieval_id; collect mf.retrieval_log_id for applied patterns; pass both to storeExecutionTrace |
| 5-min KV SQLite cache | GraphCacheService — 7-day TTL, ~/.ace-cache/<org>__<project>.db |
| No task_intent on search | Pass task_intent, exploration_enabled, exploration_rate when available; omit otherwise |
Read decoders (decodePattern, decodeMatchFactors) tolerate legacy 1.0 wire responses — missing 1.5 fields default to undefined/null, never throw.
Used By
- @ace-sdk/cli - Command-line tool
- @ace-sdk/mcp - MCP Server for any MCP-compatible client
Documentation
Full documentation: sdks/typescript/core/docs
License
MIT © CE.NET Team
