oasis_test 0.1.43 → 0.1.45

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 (2) hide show
  1. package/dist/index.js +271 -7
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -34318,14 +34318,159 @@ ${input.description}
34318
34318
  }
34319
34319
  });
34320
34320
 
34321
+ // ../server/src/domains/actors/model-pricing.ts
34322
+ function priceForModel(model) {
34323
+ if (!model) return null;
34324
+ const normalized = model.trim().toLowerCase();
34325
+ if (!normalized) return null;
34326
+ const candidates = [
34327
+ normalized,
34328
+ normalized.includes(":") ? normalized.slice(normalized.lastIndexOf(":") + 1) : "",
34329
+ normalized.includes("/") ? normalized.slice(normalized.lastIndexOf("/") + 1) : ""
34330
+ ].filter(Boolean);
34331
+ for (const candidate of candidates) {
34332
+ const exact = MODEL_PRICES[candidate];
34333
+ if (exact) return exact;
34334
+ }
34335
+ const prefix = PREFIX_PRICES.find((p2) => candidates.some((candidate) => candidate.startsWith(`${p2}-`) || candidate.startsWith(`${p2}:`)));
34336
+ return prefix ? MODEL_PRICES[prefix] : null;
34337
+ }
34338
+ function estimateRowCost(row) {
34339
+ return estimateUsageCost(row.effectiveModel, row);
34340
+ }
34341
+ function estimateUsageCost(model, usage) {
34342
+ const price = priceForModel(model);
34343
+ if (!price) return null;
34344
+ const inputTokens = Math.max(usage.inputTokens ?? 0, 0);
34345
+ const outputTokens = Math.max(usage.outputTokens ?? 0, 0);
34346
+ const cacheReadTokens = Math.max(usage.cacheReadTokens ?? 0, 0);
34347
+ const cacheCreationTokens = Math.max(usage.cacheCreationTokens ?? 0, 0);
34348
+ const cost = (inputTokens + cacheCreationTokens) * price.inputPerMillion / 1e6 + outputTokens * price.outputPerMillion / 1e6 + cacheReadTokens * (price.cachedInputPerMillion ?? price.inputPerMillion) / 1e6;
34349
+ return { currency: price.currency, micros: Math.round(cost * 1e6) };
34350
+ }
34351
+ var FOREIGN_MODEL_MARKUP, usd, cny, MODEL_PRICES, PREFIX_PRICES;
34352
+ var init_model_pricing = __esm({
34353
+ "../server/src/domains/actors/model-pricing.ts"() {
34354
+ "use strict";
34355
+ FOREIGN_MODEL_MARKUP = 1.08;
34356
+ usd = (inputPerMillion, outputPerMillion, cachedInputPerMillion) => ({
34357
+ currency: "USD",
34358
+ inputPerMillion: inputPerMillion * FOREIGN_MODEL_MARKUP,
34359
+ outputPerMillion: outputPerMillion * FOREIGN_MODEL_MARKUP,
34360
+ ...cachedInputPerMillion !== void 0 ? { cachedInputPerMillion: cachedInputPerMillion * FOREIGN_MODEL_MARKUP } : {}
34361
+ });
34362
+ cny = (inputPerMillion, outputPerMillion, cachedInputPerMillion) => ({
34363
+ currency: "CNY",
34364
+ inputPerMillion,
34365
+ outputPerMillion,
34366
+ ...cachedInputPerMillion !== void 0 ? { cachedInputPerMillion } : {}
34367
+ });
34368
+ MODEL_PRICES = {
34369
+ "gpt-5.5": usd(5, 30, 0.5),
34370
+ "gpt-5.5-pro": usd(30, 180),
34371
+ "chat-latest": usd(5, 30, 0.5),
34372
+ "gpt-5.4-mini": usd(0.75, 4.5, 0.075),
34373
+ "gpt-5.4-nano": usd(0.2, 1.25, 0.02),
34374
+ "gpt-5.4": usd(2.5, 15, 0.25),
34375
+ "gpt-5.4-pro": usd(30, 180),
34376
+ "gpt-5.3-codex": usd(1.75, 14, 0.175),
34377
+ "gpt-5.2": usd(1.75, 14, 0.175),
34378
+ "gpt-5.2-chat-latest": usd(1.75, 14, 0.175),
34379
+ "gpt-5.2-pro": usd(21, 168),
34380
+ "gpt-5.2-codex": usd(1.75, 14, 0.175),
34381
+ "gpt-5.1": usd(1.25, 10, 0.125),
34382
+ "gpt-5.1-chat-latest": usd(1.25, 10, 0.125),
34383
+ "gpt-5.1-codex": usd(1.25, 10, 0.125),
34384
+ "gpt-5.1-codex-max": usd(1.25, 10, 0.125),
34385
+ "gpt-5.1-codex-mini": usd(0.25, 2, 0.025),
34386
+ "gpt-5-pro": usd(15, 120),
34387
+ "gpt-5-codex": usd(1.25, 10, 0.125),
34388
+ "gpt-5-search-api": usd(1.25, 10, 0.125),
34389
+ "gpt-5": usd(1.25, 10, 0.125),
34390
+ "gpt-5-mini": usd(0.25, 2, 0.025),
34391
+ "gpt-5-nano": usd(0.05, 0.4, 5e-3),
34392
+ "gpt-5-chat-latest": usd(1.25, 10, 0.125),
34393
+ "gpt-4.1": usd(2, 8, 0.5),
34394
+ "gpt-4.1-2025-04-14": usd(2, 8, 0.5),
34395
+ "gpt-4.1-mini": usd(0.4, 1.6, 0.1),
34396
+ "gpt-4.1-mini-2025-04-14": usd(0.4, 1.6, 0.1),
34397
+ "gpt-4.1-nano": usd(0.1, 0.4, 0.025),
34398
+ "gpt-4.1-nano-2025-04-14": usd(0.1, 0.4, 0.025),
34399
+ "o4-mini": usd(1.1, 4.4, 0.275),
34400
+ "claude-fable-5": usd(10, 50),
34401
+ "claude-mythos-5": usd(10, 50),
34402
+ "claude-opus-4-8": usd(5, 25),
34403
+ "claude-opus-4-7": usd(5, 25),
34404
+ "claude-sonnet-5": usd(2, 10),
34405
+ "claude-sonnet-4-6": usd(3, 15),
34406
+ "claude-opus-4-6": usd(5, 25),
34407
+ "claude-opus-4-5-20251101": usd(5, 25),
34408
+ "claude-sonnet-4-5-20250929": usd(3, 15),
34409
+ "claude-opus-4-1-20250805": usd(15, 75),
34410
+ "claude-opus-4-20250514": usd(15, 75),
34411
+ "claude-sonnet-4-20250514": usd(3, 15),
34412
+ "claude-3-7-sonnet-20250219": usd(3, 15),
34413
+ "claude-3-5-sonnet-20241022": usd(3, 15),
34414
+ "claude-3-5-sonnet-20240620": usd(3, 15),
34415
+ "claude-3-sonnet-20240229": usd(3, 15),
34416
+ "claude-haiku-4-5-20251001": usd(1, 5),
34417
+ "gemini-3.5-flash": usd(1.5, 9),
34418
+ "gemini-3.1-pro-preview": usd(2, 12),
34419
+ "gemini-3.1-pro-preview-customtools": usd(2, 12),
34420
+ "gemini-3.1-flash-lite-preview": usd(0.25, 1.5),
34421
+ "gemini-3-flash-preview": usd(0.5, 3),
34422
+ "gemini-2.5-pro": usd(1.25, 10),
34423
+ "gemini-2.5-flash": usd(0.3, 2.5),
34424
+ "gemini-2.5-flash-lite": usd(0.1, 0.4),
34425
+ "gemini-2.5-flash-preview-09-2025": usd(0.3, 2.5),
34426
+ "gemini-2.0-flash": usd(0.1, 0.4),
34427
+ "deepseek-v4-flash": cny(1, 2, 0.02),
34428
+ "deepseek-v4-pro": cny(3, 6, 0.025),
34429
+ "deepseek-chat": cny(2, 3),
34430
+ "deepseek-reasoner": cny(2, 3),
34431
+ "deepseek-v3.2": cny(2, 3),
34432
+ "deepseek-coder": cny(2, 3),
34433
+ "deepseek-r1": cny(4, 16),
34434
+ "deepseek-r1-0528": cny(4, 16),
34435
+ "deepseek-v3": cny(2, 8),
34436
+ "deepseek-v3-0324": cny(2, 8),
34437
+ "deepseek-v3.1": cny(4, 12),
34438
+ "qwen3-max": cny(6, 24),
34439
+ "qwen3-max-preview": cny(6, 24),
34440
+ "qwen3-coder-plus": cny(4, 16),
34441
+ "qwen3-235b-a22b": cny(4, 40),
34442
+ "qwen3-32b": cny(2, 20),
34443
+ "qwen3-30b-a3b": cny(1.5, 15),
34444
+ "qwen3-14b": cny(1, 10),
34445
+ "qwen3-8b": cny(0.5, 5),
34446
+ "qwen3-4b": cny(0.3, 3),
34447
+ "qwen3-1.7b": cny(0.3, 3),
34448
+ "qwen3-0.6b": cny(0.3, 3),
34449
+ "qwq-plus": cny(1.6, 4),
34450
+ "qwq-plus-latest": cny(1.6, 4),
34451
+ "qwq-plus-2025-03-05": cny(1.6, 4),
34452
+ "kimi-k2.7-code": cny(6.5, 27),
34453
+ "kimi-k2.6": cny(6.5, 27),
34454
+ "kimi-k2.5": cny(4, 21),
34455
+ "kimi-k2-0905-preview": cny(4, 16),
34456
+ "kimi-k2-0711-preview": cny(4, 16),
34457
+ "kimi-k2-turbo-preview": cny(8, 58)
34458
+ };
34459
+ PREFIX_PRICES = Object.keys(MODEL_PRICES).sort((a, b2) => b2.length - a.length);
34460
+ }
34461
+ });
34462
+
34321
34463
  // ../server/src/domains/actors/stats.ts
34322
- async function actorStats(oplog, actorId) {
34464
+ async function actorStats(oplog, actorId, opts = {}) {
34323
34465
  const myRevisions = /* @__PURE__ */ new Set();
34324
34466
  const mergedTargets = /* @__PURE__ */ new Set();
34325
34467
  let produced = 0;
34326
34468
  let reviewsGiven = 0;
34327
34469
  let approvalsGiven = 0;
34328
34470
  let reworkReceived = 0;
34471
+ const now = opts.now ?? /* @__PURE__ */ new Date();
34472
+ const from = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1e3).toISOString();
34473
+ const to = now.toISOString();
34329
34474
  for await (const { op } of oplog.readAll()) {
34330
34475
  if (op.kind === "propose_revision" && op.actor === actorId) {
34331
34476
  produced++;
@@ -34345,18 +34490,99 @@ async function actorStats(oplog, actorId) {
34345
34490
  }
34346
34491
  let merged = 0;
34347
34492
  for (const rev of myRevisions) if (mergedTargets.has(rev)) merged++;
34493
+ const weeklyUsage = opts.usage?.listRuns ? summarizeWeeklyRuns(await listWeeklyRuns(opts.usage, actorId, from, to)) : summarizeWeeklyUsage(opts.usage?.queryUsageStats ? await opts.usage.queryUsageStats({
34494
+ actorIds: [actorId],
34495
+ from,
34496
+ to,
34497
+ granularity: "hour"
34498
+ }) : []);
34348
34499
  return {
34349
34500
  actorId,
34350
34501
  produced,
34351
34502
  merged,
34352
34503
  reviewsGiven,
34353
34504
  approveRateGiven: reviewsGiven === 0 ? null : approvalsGiven / reviewsGiven,
34354
- reworkReceived
34505
+ reworkReceived,
34506
+ tokenWeek: weeklyUsage.tokenWeek,
34507
+ costWeekUsdMicros: weeklyUsage.costWeekUsdMicros,
34508
+ costWeekCnyMicros: weeklyUsage.costWeekCnyMicros,
34509
+ usageWindow: { from, to },
34510
+ unpricedModels: weeklyUsage.unpricedModels
34511
+ };
34512
+ }
34513
+ async function listWeeklyRuns(trace, actorId, from, to) {
34514
+ const out = [];
34515
+ let cursor;
34516
+ do {
34517
+ const page = await trace.listRuns({ actorId, from, to, limit: 500, ...cursor ? { cursor } : {} });
34518
+ out.push(...page.items);
34519
+ cursor = page.nextCursor ?? void 0;
34520
+ } while (cursor);
34521
+ return out;
34522
+ }
34523
+ function summarizeWeeklyRuns(runs) {
34524
+ let tokenWeek = 0;
34525
+ let costWeekUsdMicros = 0;
34526
+ let costWeekCnyMicros = 0;
34527
+ const unpriced = /* @__PURE__ */ new Set();
34528
+ for (const run of runs) {
34529
+ const usage = run.usage;
34530
+ if (!usage) continue;
34531
+ const input = Math.max(usage.inputTokens ?? 0, 0);
34532
+ const output = Math.max(usage.outputTokens ?? 0, 0);
34533
+ tokenWeek += input + output;
34534
+ const estimated = estimateUsageCost(run.effectiveModel, usage);
34535
+ if (estimated) {
34536
+ if (estimated.currency === "USD") costWeekUsdMicros += estimated.micros;
34537
+ else costWeekCnyMicros += estimated.micros;
34538
+ continue;
34539
+ }
34540
+ const storedCost = Math.max(usage.costUsdMicros ?? 0, 0);
34541
+ if (storedCost > 0) {
34542
+ costWeekUsdMicros += storedCost;
34543
+ } else if (input + output > 0) {
34544
+ unpriced.add(run.effectiveModel ?? "unknown");
34545
+ }
34546
+ }
34547
+ return {
34548
+ tokenWeek,
34549
+ costWeekUsdMicros,
34550
+ costWeekCnyMicros,
34551
+ unpricedModels: [...unpriced].sort()
34552
+ };
34553
+ }
34554
+ function summarizeWeeklyUsage(rows) {
34555
+ let tokenWeek = 0;
34556
+ let costWeekUsdMicros = 0;
34557
+ let costWeekCnyMicros = 0;
34558
+ const unpriced = /* @__PURE__ */ new Set();
34559
+ for (const row of rows) {
34560
+ const input = Math.max(row.inputTokens, 0);
34561
+ const output = Math.max(row.outputTokens, 0);
34562
+ tokenWeek += input + output;
34563
+ const estimated = estimateRowCost(row);
34564
+ if (estimated) {
34565
+ if (estimated.currency === "USD") costWeekUsdMicros += estimated.micros;
34566
+ else costWeekCnyMicros += estimated.micros;
34567
+ continue;
34568
+ }
34569
+ if (row.costUsdMicros > 0) {
34570
+ costWeekUsdMicros += row.costUsdMicros;
34571
+ } else if (input + output > 0) {
34572
+ unpriced.add(row.effectiveModel ?? "unknown");
34573
+ }
34574
+ }
34575
+ return {
34576
+ tokenWeek,
34577
+ costWeekUsdMicros,
34578
+ costWeekCnyMicros,
34579
+ unpricedModels: [...unpriced].sort()
34355
34580
  };
34356
34581
  }
34357
34582
  var init_stats = __esm({
34358
34583
  "../server/src/domains/actors/stats.ts"() {
34359
34584
  "use strict";
34585
+ init_model_pricing();
34360
34586
  }
34361
34587
  });
34362
34588
 
@@ -34894,7 +35120,10 @@ function actorsDomain(opts) {
34894
35120
  router.get("/api/actors/:id/stats", async (req) => {
34895
35121
  const { oplog } = await resolveCtx(req.auth.companyId);
34896
35122
  if (!oplog) throw new ApiError(501, "NOT_IMPLEMENTED", "\u7EDF\u8BA1\u6570\u636E\u6E90\u672A\u63A5\u5165");
34897
- return { status: 200, body: await actorStats(oplog, req.params.id) };
35123
+ return {
35124
+ status: 200,
35125
+ body: await actorStats(oplog, req.params.id, { usage: opts.trace?.() })
35126
+ };
34898
35127
  });
34899
35128
  router.get("/api/actors/:id/activity", async (req) => {
34900
35129
  const { oplog } = await resolveCtx(req.auth.companyId);
@@ -35043,7 +35272,7 @@ function createActorsDomain(opts) {
35043
35272
  return {
35044
35273
  service: defaultCtx.service,
35045
35274
  resolveCtx,
35046
- register: actorsDomain({ resolveCtx, ...opts.listBuiltinSkills ? { listBuiltinSkills: opts.listBuiltinSkills } : {} })
35275
+ register: actorsDomain({ resolveCtx, ...opts.trace ? { trace: opts.trace } : {}, ...opts.listBuiltinSkills ? { listBuiltinSkills: opts.listBuiltinSkills } : {} })
35047
35276
  };
35048
35277
  }
35049
35278
  var import_node_crypto8;
@@ -38870,6 +39099,19 @@ function parseArgsJSON(argsText) {
38870
39099
  function extractSessionID(result) {
38871
39100
  return result?.sessionId ?? "";
38872
39101
  }
39102
+ function extractCurrentModelID(result) {
39103
+ const r = record4(result);
39104
+ const models = record4(r?.["models"]);
39105
+ return firstString(
39106
+ models?.["currentModelId"],
39107
+ models?.["current_model_id"],
39108
+ r?.["currentModelId"],
39109
+ r?.["current_model_id"],
39110
+ r?.["modelId"],
39111
+ r?.["model_id"],
39112
+ r?.["model"]
39113
+ );
39114
+ }
38873
39115
  function extractStopReason(result) {
38874
39116
  return result?.stopReason ?? "";
38875
39117
  }
@@ -39002,6 +39244,7 @@ async function runACPSession(job, cfg) {
39002
39244
  ...resolvedModel ? { model: resolvedModel } : {}
39003
39245
  });
39004
39246
  sessionId = extractSessionID(resumeRes);
39247
+ actualModel = resolvedModel ?? extractCurrentModelID(resumeRes) ?? actualModel;
39005
39248
  if (!sessionId) {
39006
39249
  sessionId = job.runtimeSessionId;
39007
39250
  ambiguousResume = true;
@@ -39017,6 +39260,7 @@ async function runACPSession(job, cfg) {
39017
39260
  ...resolvedModel ? { model: resolvedModel } : {}
39018
39261
  });
39019
39262
  sessionId = extractSessionID(sessionRes);
39263
+ actualModel = resolvedModel ?? extractCurrentModelID(sessionRes) ?? actualModel;
39020
39264
  if (!sessionId) throw new Error("session/new returned no sessionId");
39021
39265
  }
39022
39266
  capturedSessionId = sessionId;
@@ -39029,6 +39273,20 @@ async function runACPSession(job, cfg) {
39029
39273
  ---
39030
39274
 
39031
39275
  ${task}` : task;
39276
+ if (job.resumeRuntimeSession && job.runtimeSessionId && advertisedLoadSession) {
39277
+ const start = Date.now();
39278
+ let lastCount = client.notificationCount;
39279
+ let lastChange = start;
39280
+ while (Date.now() - start < 1200) {
39281
+ await new Promise((r) => setTimeout(r, 25));
39282
+ if (client.notificationCount !== lastCount) {
39283
+ lastCount = client.notificationCount;
39284
+ lastChange = Date.now();
39285
+ } else if (Date.now() - lastChange >= 250) {
39286
+ break;
39287
+ }
39288
+ }
39289
+ }
39032
39290
  streamingCurrentTurn = true;
39033
39291
  let promptResult = await client.request("session/prompt", {
39034
39292
  sessionId,
@@ -39041,6 +39299,7 @@ ${task}` : task;
39041
39299
  ...resolvedModel ? { model: resolvedModel } : {}
39042
39300
  });
39043
39301
  sessionId = extractSessionID(sessionRes);
39302
+ actualModel = resolvedModel ?? extractCurrentModelID(sessionRes) ?? actualModel;
39044
39303
  if (!sessionId) throw new Error("session/new returned no sessionId");
39045
39304
  capturedSessionId = sessionId;
39046
39305
  promptResult = await client.request("session/prompt", {
@@ -39177,7 +39436,9 @@ var init_acp = __esm({
39177
39436
  const params = raw["params"];
39178
39437
  if (!params?.update) return;
39179
39438
  const [updateType, updateData] = normalizeACPUpdate(params.update);
39180
- if (!updateType || !this.acceptNotification()) return;
39439
+ if (!updateType) return;
39440
+ this.notificationCount++;
39441
+ if (!this.acceptNotification()) return;
39181
39442
  switch (updateType) {
39182
39443
  case "agent_message_chunk":
39183
39444
  this.handleAgentMessage(updateData);
@@ -39228,9 +39489,9 @@ var init_acp = __esm({
39228
39489
  this.onTelemetry({ kind, payload, seq: ++this.seq, ts: (/* @__PURE__ */ new Date()).toISOString() });
39229
39490
  }
39230
39491
  appendText(kind, text) {
39231
- if (kind === "message") this.onOutput(text);
39232
39492
  const other = kind === "message" ? "thought" : "message";
39233
39493
  this.flushTextBuffer(other);
39494
+ if (kind === "message") this.onOutput(text);
39234
39495
  const existing = this.textBuffers.get(kind);
39235
39496
  if (existing) existing.text += text;
39236
39497
  else this.textBuffers.set(kind, { text, startedAt: (/* @__PURE__ */ new Date()).toISOString() });
@@ -54917,11 +55178,13 @@ async function startServe(opts) {
54917
55178
  let getEngine = async () => {
54918
55179
  throw new Error("company engine router not initialized");
54919
55180
  };
55181
+ let traceStoreForActors;
54920
55182
  const actors = createActorsDomain({
54921
55183
  store: registryStore,
54922
55184
  oplog,
54923
55185
  kernel,
54924
55186
  blobs: assets,
55187
+ trace: () => traceStoreForActors,
54925
55188
  audit: registryAudit,
54926
55189
  // CO-302 数据面隔离(actors 域试点):按当前公司取其引擎,用各自 registry 服务该域请求。
54927
55190
  // engineRouter 在下方(行 ~411)以 const 声明;此箭头只在请求时调用,那时已初始化,闭包引用合法
@@ -55000,6 +55263,7 @@ async function startServe(opts) {
55000
55263
  traceStore = await FileTraceStore.open(path16.join(opts.dir, "trace"));
55001
55264
  console.log("[serve] \u8FD0\u884C\u8F68\u8FF9\u4F53\u7CFB\uFF1A\u672C\u5730 ndjson dev store");
55002
55265
  }
55266
+ traceStoreForActors = traceStore;
55003
55267
  const trace = createTraceDomain({ store: traceStore });
55004
55268
  const traceStoreSink = new TraceStoreSink({ store: traceStore, runtimeKind: "auto" });
55005
55269
  const automationStore = pgPool ? await PostgresAutomationStore.open(pgPool, pgSchema) : new MemoryAutomationStore();
@@ -58146,7 +58410,7 @@ ${res.warning}`);
58146
58410
  }
58147
58411
 
58148
58412
  // src/index.ts
58149
- var PKG_VERSION = true ? "0.1.43" : "dev";
58413
+ var PKG_VERSION = true ? "0.1.45" : "dev";
58150
58414
  var OASIS_DIR = path18.join(os10.homedir(), ".oasis");
58151
58415
  var CONFIG_FILE = path18.join(OASIS_DIR, "node-config.json");
58152
58416
  var PID_FILE = path18.join(OASIS_DIR, "node.pid");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oasis_test",
3
- "version": "0.1.43",
3
+ "version": "0.1.45",
4
4
  "description": "Oasis node daemon + CLI — background daemon, auto-start, full server CLI",
5
5
  "bin": {
6
6
  "oasis": "./dist/index.js"