@alwith-ai/dsh-agent 0.2.2 → 0.2.3

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/package.json +1 -1
  2. package/src/bridge.ts +39 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alwith-ai/dsh-agent",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "ACP v2 agent built on DeepSeek Harness: fixed plugin compositions (standard / minimal / anchored / code / cordis), streaming turns with direct state reporting, permissions, resume with replay, multi-provider credentials and subscription login",
5
5
  "license": "MIT",
6
6
  "repository": {
package/src/bridge.ts CHANGED
@@ -617,7 +617,13 @@ export function apply(ctx: Context, config: AcpConfig): void {
617
617
  protocolVersion: ACP_PROTOCOL_VERSION,
618
618
  info: { name: "dsh-agent", title: "ALwith dsh bridge", version: packageJson.version },
619
619
  authMethods: [],
620
- capabilities: { session: { prompt: {} } },
620
+ capabilities: {
621
+ session: { prompt: {} },
622
+ // seedHistory: a host that keeps its own transcript can continue it here —
623
+ // `session/new` with `_meta.dsh.seedHistory: [{role, text}]` injects it as
624
+ // model-facing context (agent.inject) before the first turn.
625
+ _meta: { dsh: { seedHistory: true } },
626
+ },
621
627
  }
622
628
  })
623
629
  .onRequest("session/new", async (context): Promise<NewSessionResponse> => {
@@ -646,6 +652,12 @@ export function apply(ctx: Context, config: AcpConfig): void {
646
652
  })
647
653
  const record = sessions.get(sessionId)
648
654
  if (record === undefined) throw internalError("session record vanished during session/new")
655
+ const seed = seedHistoryOf(params._meta)
656
+ if (seed.length > 0) {
657
+ record.agent.inject(
658
+ createUserMessage({ content: [{ type: "text", text: seedTranscript(seed) }], source: { kind: "user" } }),
659
+ )
660
+ }
649
661
  return { sessionId, configOptions: await modelConfigOptions(record) }
650
662
  })
651
663
  // v2 baseline: session/list is part of the `session: {}` surface, no capability key.
@@ -924,3 +936,29 @@ function validateSessionParams(params: NewSessionRequest): void {
924
936
  throw invalidParams("mcpServers is not supported")
925
937
  }
926
938
  }
939
+
940
+ export interface SeedMessage {
941
+ role: "user" | "assistant"
942
+ text: string
943
+ }
944
+
945
+ /** `session/new` `_meta.dsh.seedHistory`: prior conversation the host kept, to inject as model-facing context. */
946
+ export function seedHistoryOf(meta: NewSessionRequest["_meta"]): SeedMessage[] {
947
+ const raw = (meta as { dsh?: { seedHistory?: unknown } } | null | undefined)?.dsh?.seedHistory
948
+ if (raw === undefined || raw === null) return []
949
+ if (!Array.isArray(raw)) throw invalidParams("seedHistory must be an array of {role, text}")
950
+ return raw.map((entry, index) => {
951
+ const role = (entry as { role?: unknown })?.role
952
+ const text = (entry as { text?: unknown })?.text
953
+ if ((role !== "user" && role !== "assistant") || typeof text !== "string") {
954
+ throw invalidParams(`seedHistory[${index}] must be {role: "user" | "assistant", text: string}`)
955
+ }
956
+ return { role, text }
957
+ })
958
+ }
959
+
960
+ /** dsh injects one user-authored context message; the transcript is framed so the model reads it as history. */
961
+ export function seedTranscript(seed: readonly SeedMessage[]): string {
962
+ const lines = seed.map(message => `${message.role === "user" ? "User" : "Assistant"}: ${message.text}`)
963
+ return `<prior_conversation>\n${lines.join("\n\n")}\n</prior_conversation>`
964
+ }