@vibe-lark/larkpal 0.1.74 → 0.1.75

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/main.mjs +162 -6
  2. package/package.json +1 -1
package/dist/main.mjs CHANGED
@@ -3464,6 +3464,139 @@ function createChatAuthRouter() {
3464
3464
  return router;
3465
3465
  }
3466
3466
  //#endregion
3467
+ //#region src/gateway/runtime-context.ts
3468
+ const CLAUDE_MD_START = "<!-- LARKPAL_RUNTIME_INSTRUCTIONS_START -->";
3469
+ const CLAUDE_MD_END = "<!-- LARKPAL_RUNTIME_INSTRUCTIONS_END -->";
3470
+ function materializeRuntimeContext(params) {
3471
+ const instructions = normalizeRuntimeInstructions(params.instructions);
3472
+ const skills = normalizeRuntimeSkills(params.skills);
3473
+ if (instructions.length === 0 && skills.length === 0) return void 0;
3474
+ return {
3475
+ instructions: instructions.length > 0 ? writeRuntimeInstructions(params.cwd, instructions) : [],
3476
+ skills: skills.map((skill) => writeRuntimeSkill(params.cwd, skill))
3477
+ };
3478
+ }
3479
+ function normalizeRuntimeInstructions(value) {
3480
+ if (!Array.isArray(value)) return [];
3481
+ return value.map((item) => {
3482
+ if (!item || typeof item !== "object" || Array.isArray(item)) return null;
3483
+ const record = item;
3484
+ const id = readNonEmptyString(record.id);
3485
+ const content = readNonEmptyString(record.content);
3486
+ if (!id || !content) return null;
3487
+ return {
3488
+ id,
3489
+ content,
3490
+ scope: readScope(record.scope),
3491
+ version: readNonEmptyString(record.version)
3492
+ };
3493
+ }).filter((item) => item != null);
3494
+ }
3495
+ function normalizeRuntimeSkills(value) {
3496
+ if (!Array.isArray(value)) return [];
3497
+ return value.map((item) => {
3498
+ if (!item || typeof item !== "object" || Array.isArray(item)) return null;
3499
+ const record = item;
3500
+ const id = readNonEmptyString(record.id);
3501
+ const content = readNonEmptyString(record.content) || readNonEmptyString(record.skillMarkdown);
3502
+ if (!id || !content) return null;
3503
+ return {
3504
+ id,
3505
+ content,
3506
+ scope: readScope(record.scope),
3507
+ version: readNonEmptyString(record.version),
3508
+ name: readNonEmptyString(record.name),
3509
+ description: readNonEmptyString(record.description)
3510
+ };
3511
+ }).filter((item) => item != null);
3512
+ }
3513
+ function writeRuntimeInstructions(cwd, instructions) {
3514
+ const filePath = join(cwd, "CLAUDE.md");
3515
+ const body = [
3516
+ CLAUDE_MD_START,
3517
+ "# LarkPal Runtime Instructions",
3518
+ "",
3519
+ "The following instructions were injected by LarkPal for this agent session. Treat them as runtime context, not as user message content.",
3520
+ "",
3521
+ ...instructions.flatMap((instruction) => [
3522
+ `## ${instruction.id}`,
3523
+ "",
3524
+ instruction.content.trim(),
3525
+ ""
3526
+ ]),
3527
+ CLAUDE_MD_END,
3528
+ ""
3529
+ ].join("\n");
3530
+ const next = replaceManagedBlock(existsSync(filePath) ? readFileSync(filePath, "utf-8") : "", body);
3531
+ mkdirSync(dirname(filePath), { recursive: true });
3532
+ writeFileSync(filePath, next, "utf-8");
3533
+ return instructions.map((instruction) => ({
3534
+ id: instruction.id,
3535
+ scope: instruction.scope ?? "request",
3536
+ hash: hashContent(instruction.content),
3537
+ version: instruction.version,
3538
+ path: "CLAUDE.md"
3539
+ }));
3540
+ }
3541
+ function writeRuntimeSkill(cwd, skill) {
3542
+ const relativePath = `.claude/skills/${sanitizePathSegment(skill.id)}/SKILL.md`;
3543
+ const filePath = join(cwd, relativePath);
3544
+ const content = buildSkillContent(skill);
3545
+ mkdirSync(dirname(filePath), { recursive: true });
3546
+ writeFileSync(filePath, content, "utf-8");
3547
+ return {
3548
+ id: skill.id,
3549
+ scope: skill.scope ?? "request",
3550
+ hash: hashContent(content),
3551
+ version: skill.version,
3552
+ path: relativePath
3553
+ };
3554
+ }
3555
+ function buildSkillContent(skill) {
3556
+ const content = skill.content.trim();
3557
+ if (content.startsWith("---")) return `${content}\n`;
3558
+ const name = skill.name || skill.id;
3559
+ const description = skill.description || `Runtime skill injected by LarkPal: ${skill.id}`;
3560
+ return [
3561
+ "---",
3562
+ `name: ${yamlScalar(name)}`,
3563
+ `description: ${yamlScalar(description)}`,
3564
+ "---",
3565
+ "",
3566
+ content,
3567
+ ""
3568
+ ].join("\n");
3569
+ }
3570
+ function replaceManagedBlock(current, managedBlock) {
3571
+ const start = current.indexOf(CLAUDE_MD_START);
3572
+ const end = current.indexOf(CLAUDE_MD_END);
3573
+ if (start !== -1 && end !== -1 && end > start) {
3574
+ const before = current.slice(0, start).trimEnd();
3575
+ const after = current.slice(end + 41).trimStart();
3576
+ return [
3577
+ before,
3578
+ managedBlock.trimEnd(),
3579
+ after
3580
+ ].filter(Boolean).join("\n\n") + "\n";
3581
+ }
3582
+ return [current.trimEnd(), managedBlock.trimEnd()].filter(Boolean).join("\n\n") + "\n";
3583
+ }
3584
+ function hashContent(content) {
3585
+ return `sha256:${createHash("sha256").update(content).digest("hex")}`;
3586
+ }
3587
+ function sanitizePathSegment(value) {
3588
+ return value.replace(/[^A-Za-z0-9._-]/g, "_").replace(/^\.+$/, "skill") || "skill";
3589
+ }
3590
+ function readNonEmptyString(value) {
3591
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
3592
+ }
3593
+ function readScope(value) {
3594
+ return value === "app" || value === "session" || value === "request" ? value : "request";
3595
+ }
3596
+ function yamlScalar(value) {
3597
+ return JSON.stringify(value);
3598
+ }
3599
+ //#endregion
3467
3600
  //#region src/gateway/agent-context.ts
3468
3601
  const SENSITIVE_KEY_PATTERN = /(authorization|cookie|token|api[-_]?key|secret|password|credential)/i;
3469
3602
  const SAFE_KEY_PATTERN = /^(file[-_]?token|drive[-_]?file[-_]?token|doc[-_]?token|sheet[-_]?token|wiki[-_]?token|node[-_]?token)$/i;
@@ -3505,11 +3638,17 @@ function buildAgentRuntimeConfig(input) {
3505
3638
  const userId = requireContextField(input.identity?.userId || input.identity?.openId, "userId");
3506
3639
  const scenarioId = getScenarioId(input.scenarioId, input.metadata);
3507
3640
  const cwd = resolveAgentCwd(sessionId, input.cwd);
3641
+ const runtimeContext = materializeRuntimeContext({
3642
+ cwd,
3643
+ instructions: input.runtimeInstructions,
3644
+ skills: input.runtimeSkills
3645
+ });
3508
3646
  const metadata = buildRunMetadata(input.metadata, {
3509
3647
  conversationId,
3510
3648
  traceId,
3511
3649
  entrypoint: input.entrypoint,
3512
- scenarioId
3650
+ scenarioId,
3651
+ runtimeContext
3513
3652
  });
3514
3653
  const authHeaders = buildAuthHeaders({
3515
3654
  tenantKey,
@@ -3541,6 +3680,7 @@ function buildAgentRuntimeConfig(input) {
3541
3680
  authHeaders,
3542
3681
  attachments: input.attachments,
3543
3682
  sourceArtifacts: input.sourceArtifacts,
3683
+ runtimeContext,
3544
3684
  llmConfig: input.llmConfig,
3545
3685
  policy,
3546
3686
  metadata
@@ -3559,6 +3699,7 @@ function buildAgentRuntimeConfig(input) {
3559
3699
  authHeaders,
3560
3700
  attachments: input.attachments,
3561
3701
  sourceArtifacts: input.sourceArtifacts,
3702
+ runtimeContext,
3562
3703
  llmConfig: input.llmConfig,
3563
3704
  policy,
3564
3705
  requestContext,
@@ -3644,6 +3785,7 @@ function buildRunInputAuditMetadata(config) {
3644
3785
  const metadata = {};
3645
3786
  if (config.attachments !== void 0) metadata.attachments = summarizeForAudit(config.attachments);
3646
3787
  if (config.sourceArtifacts !== void 0) metadata.sourceArtifacts = summarizeForAudit(config.sourceArtifacts);
3788
+ if (config.runtimeContext !== void 0) metadata.runtimeContext = config.runtimeContext;
3647
3789
  return metadata;
3648
3790
  }
3649
3791
  function buildRuntimeEventAuditMetadata(event) {
@@ -3732,7 +3874,8 @@ function buildRunMetadata(metadata, context) {
3732
3874
  conversationId: context.conversationId,
3733
3875
  traceId: context.traceId,
3734
3876
  entrypoint: context.entrypoint,
3735
- ...context.scenarioId ? { scenarioId: context.scenarioId } : {}
3877
+ ...context.scenarioId ? { scenarioId: context.scenarioId } : {},
3878
+ ...context.runtimeContext ? { runtimeContext: context.runtimeContext } : {}
3736
3879
  };
3737
3880
  }
3738
3881
  function buildAuditMetadata(context, metadata) {
@@ -4470,6 +4613,8 @@ function createChatRouter(config) {
4470
4613
  const scenarioId = getScenarioId(body.options?.scenarioId, body.options?.metadata);
4471
4614
  const attachments = getRunInputValue(body.attachments, body.options?.attachments, body.options?.metadata?.attachments);
4472
4615
  const sourceArtifacts = getRunInputValue(body.sourceArtifacts, body.source_artifacts, body.options?.sourceArtifacts, body.options?.source_artifacts, body.options?.metadata?.sourceArtifacts, body.options?.metadata?.source_artifacts);
4616
+ const runtimeInstructions = getRunInputValue(body.runtimeInstructions, body.runtime_instructions, body.options?.runtimeInstructions, body.options?.runtime_instructions, body.options?.metadata?.runtimeInstructions, body.options?.metadata?.runtime_instructions);
4617
+ const runtimeSkills = getRunInputValue(body.runtimeSkills, body.runtime_skills, body.options?.runtimeSkills, body.options?.runtime_skills, body.options?.metadata?.runtimeSkills, body.options?.metadata?.runtime_skills);
4473
4618
  log$30.info("[stream] 收到流式对话请求", {
4474
4619
  userId,
4475
4620
  sessionId,
@@ -4478,6 +4623,8 @@ function createChatRouter(config) {
4478
4623
  scenarioId,
4479
4624
  hasAttachments: attachments !== void 0,
4480
4625
  hasSourceArtifacts: sourceArtifacts !== void 0,
4626
+ hasRuntimeInstructions: runtimeInstructions !== void 0,
4627
+ hasRuntimeSkills: runtimeSkills !== void 0,
4481
4628
  promptLength: body.prompt.length
4482
4629
  });
4483
4630
  if (!sessionId) {
@@ -4525,6 +4672,8 @@ function createChatRouter(config) {
4525
4672
  model: process.env.CLAUDE_MODEL || void 0,
4526
4673
  attachments,
4527
4674
  sourceArtifacts,
4675
+ runtimeInstructions,
4676
+ runtimeSkills,
4528
4677
  policy: body.options?.policy,
4529
4678
  metadata: body.options?.metadata,
4530
4679
  identity: {
@@ -4564,10 +4713,7 @@ function createChatRouter(config) {
4564
4713
  requestId,
4565
4714
  traceId,
4566
4715
  scenarioId,
4567
- ...buildRunInputAuditMetadata({
4568
- attachments,
4569
- sourceArtifacts
4570
- })
4716
+ ...buildRunInputAuditMetadata(runtimeConfig)
4571
4717
  }
4572
4718
  });
4573
4719
  } catch (err) {
@@ -6110,6 +6256,8 @@ async function handleExecute(req, res, processManager) {
6110
6256
  const scenarioId = getScenarioId(body.scenarioId || body.scenario_id, body.metadata);
6111
6257
  const attachments = getRunInputValue(body.attachments, body.metadata?.attachments);
6112
6258
  const sourceArtifacts = getRunInputValue(body.sourceArtifacts, body.source_artifacts, body.metadata?.sourceArtifacts, body.metadata?.source_artifacts);
6259
+ const runtimeInstructions = getRunInputValue(body.runtimeInstructions, body.runtime_instructions, body.metadata?.runtimeInstructions, body.metadata?.runtime_instructions);
6260
+ const runtimeSkills = getRunInputValue(body.runtimeSkills, body.runtime_skills, body.metadata?.runtimeSkills, body.metadata?.runtime_skills);
6113
6261
  const identity = resolveExecuteIdentity(req, body);
6114
6262
  const missingIdentityFields = getMissingIdentityFields(identity);
6115
6263
  if (missingIdentityFields.length > 0) {
@@ -6156,6 +6304,8 @@ async function handleExecute(req, res, processManager) {
6156
6304
  authHeaders: body.auth_headers,
6157
6305
  attachments,
6158
6306
  sourceArtifacts,
6307
+ runtimeInstructions,
6308
+ runtimeSkills,
6159
6309
  policy: body.policy,
6160
6310
  metadata: body.metadata,
6161
6311
  identity
@@ -6284,6 +6434,8 @@ async function handleBatchExecute(req, res, processManager) {
6284
6434
  const scenarioId = getScenarioId(body.scenarioId || body.scenario_id, body.metadata);
6285
6435
  const batchAttachments = getRunInputValue(body.attachments, body.metadata?.attachments);
6286
6436
  const batchSourceArtifacts = getRunInputValue(body.sourceArtifacts, body.source_artifacts, body.metadata?.sourceArtifacts, body.metadata?.source_artifacts);
6437
+ const batchRuntimeInstructions = getRunInputValue(body.runtimeInstructions, body.runtime_instructions, body.metadata?.runtimeInstructions, body.metadata?.runtime_instructions);
6438
+ const batchRuntimeSkills = getRunInputValue(body.runtimeSkills, body.runtime_skills, body.metadata?.runtimeSkills, body.metadata?.runtime_skills);
6287
6439
  const concurrency = body.concurrency ?? 3;
6288
6440
  const taskIds = [];
6289
6441
  const taskConfigs = [];
@@ -6299,6 +6451,8 @@ async function handleBatchExecute(req, res, processManager) {
6299
6451
  };
6300
6452
  const taskAttachments = getRunInputValue(task.attachments, task.metadata?.attachments, batchAttachments);
6301
6453
  const taskSourceArtifacts = getRunInputValue(task.sourceArtifacts, task.source_artifacts, task.metadata?.sourceArtifacts, task.metadata?.source_artifacts, batchSourceArtifacts);
6454
+ const taskRuntimeInstructions = getRunInputValue(task.runtimeInstructions, task.runtime_instructions, task.metadata?.runtimeInstructions, task.metadata?.runtime_instructions, batchRuntimeInstructions);
6455
+ const taskRuntimeSkills = getRunInputValue(task.runtimeSkills, task.runtime_skills, task.metadata?.runtimeSkills, task.metadata?.runtime_skills, batchRuntimeSkills);
6302
6456
  const config = buildAgentRuntimeConfig({
6303
6457
  requestId: `${batchRequestId}:${index}`,
6304
6458
  traceId,
@@ -6311,6 +6465,8 @@ async function handleBatchExecute(req, res, processManager) {
6311
6465
  authHeaders: body.auth_headers,
6312
6466
  attachments: taskAttachments,
6313
6467
  sourceArtifacts: taskSourceArtifacts,
6468
+ runtimeInstructions: taskRuntimeInstructions,
6469
+ runtimeSkills: taskRuntimeSkills,
6314
6470
  policy: body.policy,
6315
6471
  metadata: taskMetadata,
6316
6472
  identity
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibe-lark/larkpal",
3
- "version": "0.1.74",
3
+ "version": "0.1.75",
4
4
  "description": "LarkPal - Lark/Feishu bot service",
5
5
  "type": "module",
6
6
  "main": "./dist/main.mjs",